Skip to content

Commit e3a5944

Browse files
committed
Added (currently unused) grouping and sort keys
1 parent 2d551a3 commit e3a5944

File tree

8 files changed

+115
-21
lines changed

8 files changed

+115
-21
lines changed

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
"keywords": [],
88
"packageManager": "[email protected]",
99
"scripts": {
10-
"devdebug": "yarn solves -s ./test/social-golfer.yml",
11-
"devdebug2": "yarn solves -s ./test/sample-spec.yml",
12-
"devdebug3": "yarn solves -s ./test/cnf-sat.yml",
13-
"devdebug3alt": "yarn solves -s ./test/cnf-sat-alt.yml",
14-
"devdebug4": "yarn solves -s ./test/vertex-cover.yml",
10+
"devdebug": "yarn solves -s ./sample-specs/social-golfer.yml",
11+
"devdebug2": "yarn solves -s ./sample-specs/graph-colouring.yml",
12+
"devdebug3": "yarn solves -s ./sample-specs/cnf-sat.yml",
13+
"devdebug3alt": "yarn solves -s ./sample-specs/cnf-sat-alt.yml",
14+
"devdebug4": "yarn solves -s ./sample-specs/vertex-cover.yml",
1515
"test": "yarn workspace solves test",
1616
"build": "yarn workspace solves build",
1717
"compile": "yarn workspace solves compile",
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ output:
4949
- Variable
5050
- Dummy1
5151
- Dummy2
52+
format:
53+
groupBy: []
54+
sortBy: []
5255

5356
constraints: |
5457
sign(pos).
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ output:
3232
title: Assignment
3333
fieldLabels:
3434
- Variable
35+
format:
36+
groupBy: []
37+
sortBy: []
3538

3639
constraints: |
3740
sign(pos).
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ output:
3939
fieldLabels:
4040
- Vertex
4141
- Colour
42+
format:
43+
groupBy: []
44+
sortBy: []
4245

4346
constraints: |
4447
domainok(edge(V1,V2)) :- base(vertex,V1), base(vertex,V2), V1 != V2, instance(edge(V1,V2)).
Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,23 @@ output:
5050
assign:
5151
title: Selection
5252
fieldLabels:
53-
- Player
5453
- Round
5554
- Group
55+
- Players
56+
format:
57+
groupBy:
58+
- Round
59+
- Group
60+
sortBy:
61+
- Round
62+
- Group
5663

5764
constraints: |
58-
domainok(disallowed(P1,P2)) :- base(player,P1), base(player,P2), P1 != P2, instance(disallowed(P1,P2)).
65+
domainok(disallowed(P1,P2)) :-
66+
base(player,P1),
67+
base(player,P2),
68+
P1 != P2,
69+
instance(disallowed(P1,P2)).
5970
6071
encoding: |
6172
round(1..R) :- integer(rounds,R).
@@ -67,8 +78,10 @@ encoding: |
6778
:- same(P1,P2, R), instance(disallowed(P1,P2)).
6879
:- same(P1,P2, R), instance(disallowed(P2,P1)).
6980
70-
:- same(P1, P2, R), same(P1, P2, S), R < S. %%% satisfaction constraint
71-
%#minimize { 1,P1,P2,R,S : same(P1, P2, R), same(P1, P2, S), R < S }. %%% optimization constraint
81+
%%% satisfaction constraint
82+
:- same(P1, P2, R), same(P1, P2, S), R < S.
83+
%%% optimization constraint
84+
%#minimize { 1,P1,P2,R,S : same(P1, P2, R), same(P1, P2, S), R < S }.
7285
73-
solution(assign(P,R,G)) :- assign(P,R,G).
86+
solution(assign(R,G,P)) :- assign(P,R,G).
7487

solves/src/spec-parse.ts

Lines changed: 83 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,22 @@ function ensureInt(obj: any, argName: string): number {
2525
throw new Error(`'${argName}' spec key is not a safe integer.`);
2626
return obj;
2727
}
28+
function ensureUniqueStrArray(obj: any, argName: string): string[] {
29+
if (!Array.isArray(obj)) {
30+
throw new Error(`'${argName}' spec key is not an array of strings.`);
31+
}
32+
const newArr: string[] = [];
33+
for (const e of obj) {
34+
if (typeof e !== "string") {
35+
throw new Error(`'${argName}' spec key must be an array of strings.`);
36+
}
37+
newArr.push(e);
38+
}
39+
if ((new Set(newArr)).size !== newArr.length) {
40+
throw new Error(`'${argName}' spec key must contain unique strings.`);
41+
}
42+
return newArr;
43+
}
2844
//function ensureNum(obj: any, argName: string): number {
2945
// if (typeof obj === "number") return obj;
3046
// throw new Error(`'${argName}' spec key is not a number.`);
@@ -60,12 +76,30 @@ function inputIntegerTransform(obj: any): InputIntegerPartialSpec {
6076
};
6177
}
6278

63-
/********************************************************************/
79+
function fieldLabelsToIndices(
80+
arr: string[],
81+
reference: string[],
82+
argName: string,
83+
refName: string,
84+
): number[] {
85+
const indices: number[] = arr.map(x => reference.indexOf(x));
86+
if (indices.some(x => (x < 0))) {
87+
throw new Error(`'${argName}' spec key must contain strings found in ${refName}.`);
88+
}
6489

65-
interface OutputFieldSpec {
66-
label: string;
90+
// Sanity checks
91+
if ((new Set(indices)).size !== indices.length) {
92+
throw new Error(`Critical bug: arr must map to unique indices.`);
93+
}
94+
if (indices.some(x => x >= reference.length)) {
95+
throw new Error(`Critical bug: arr must map to indices within range.`);
96+
}
97+
98+
return indices;
6799
}
68100

101+
/********************************************************************/
102+
69103
interface InputPartialSpec {
70104
title: string;
71105
parameters: number;
@@ -78,11 +112,27 @@ interface InputIntegerPartialSpec {
78112
initial: number;
79113
}
80114

115+
/*** ***/
116+
117+
//type OutputFieldSortBy = "ascending" | "descending";
118+
119+
interface OutputFieldSpec {
120+
label: string;
121+
122+
//sortBy: OutputFieldSortBy; // We are always ascending for now
123+
}
124+
81125
interface OutputPartialSpec {
82126
title: string;
83127
fields: OutputFieldSpec[];
128+
129+
// Formatting
130+
groupPriority: number[]; // closer to front = higher-priority
131+
sortPriority: number[]; // closer to front = higher-priority
84132
}
85133

134+
/*** ***/
135+
86136
export interface SpecValues {
87137
name: string;
88138
appTitle: string;
@@ -157,17 +207,39 @@ export function getSpecValues(specPath: string): SpecValues {
157207

158208
output: objectValueMap(output, (obj: any) => {
159209
const title: string = ensureStr(obj.title, "output[].title");
160-
const fieldLabels: any = obj.fieldLabels;
161-
if (!Array.isArray(fieldLabels)) {
162-
throw new Error(`Output ${obj.title} must provide a fields specification array.`);
163-
}
210+
const fieldLabels: string[] = ensureUniqueStrArray(
211+
obj.fieldLabels, "output[].fieldLabels",
212+
);
213+
const groupBy: string[] = ensureUniqueStrArray(
214+
obj.format?.groupBy, "output[].format.groupBy",
215+
);
216+
const sortBy: string[] = ensureUniqueStrArray(
217+
obj.format?.sortBy, "output[].format.sortBy",
218+
);
219+
220+
const fields: OutputFieldSpec[] = fieldLabels.map(x => ({label: x}));
164221

165-
const fields: OutputFieldSpec[] = fieldLabels.map(
166-
x => ({label: ensureStr(x, `output[].fields[].label`)})
222+
const groupPriority: number[] = fieldLabelsToIndices(
223+
groupBy,
224+
fieldLabels,
225+
"output[].format.groupBy",
226+
"output[].fieldLabels",
167227
);
228+
const sortPriority: number[] = fieldLabelsToIndices(
229+
sortBy,
230+
fieldLabels,
231+
"output[].format.sortBy",
232+
"output[].fieldLabels",
233+
);
234+
235+
// We want to sort all fields, so we fill more values
236+
for (let i = 0; i < fieldLabels.length; ++i) {
237+
if (!sortPriority.includes(i)) sortPriority.push(i);
238+
}
239+
console.log(groupPriority);
240+
console.log(sortPriority);
168241

169-
const outputObj = {title, fields};
170-
return outputObj;
242+
return {title, fields, groupPriority, sortPriority};
171243
}),
172244
};
173245
}

0 commit comments

Comments
 (0)