@fraczak/k 5.0.1 → 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -60
- package/package.json +1 -1
- package/patterns.mjs +21 -9
- package/typing.mjs +47 -30
package/README.md
CHANGED
|
@@ -54,7 +54,7 @@ the property doesn't exist. E.g.,
|
|
|
54
54
|
|
|
55
55
|
There are three ways of combining functions:
|
|
56
56
|
|
|
57
|
-
1. **
|
|
57
|
+
1. **Composition**: `(f1 f2 ...)`, e.g. `(.toto .titi)` extracts
|
|
58
58
|
nested field.
|
|
59
59
|
|
|
60
60
|
```text
|
|
@@ -64,7 +64,7 @@ There are three ways of combining functions:
|
|
|
64
64
|
{"other": {}} ... undefined
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
2. **
|
|
67
|
+
2. **Merge**: `< f1, f2,... >`, e.g., `<.toto, .titi>` extracts field
|
|
68
68
|
`toto` if present; otherwise extracts `titi`.
|
|
69
69
|
|
|
70
70
|
```text
|
|
@@ -74,7 +74,7 @@ There are three ways of combining functions:
|
|
|
74
74
|
{"x":{"o":{}}, "z": {"o":{}}} ... undefined
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
3. **
|
|
77
|
+
3. **Product**: `{ f1 label1, f2 label2, ...}`, e.g., `{.toto TOTO,
|
|
78
78
|
.titi TITI}` extracts two fields and builds a record out of them.
|
|
79
79
|
|
|
80
80
|
```text
|
|
@@ -86,9 +86,9 @@ There are three ways of combining functions:
|
|
|
86
86
|
|
|
87
87
|
**QUIZ**: What is:
|
|
88
88
|
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
89
|
+
- Empty composition: `()` ?
|
|
90
|
+
- Empty merge: `<>` ?
|
|
91
|
+
- Empty product: `{}` ?
|
|
92
92
|
- `{{{{} s} s} s}` ?
|
|
93
93
|
- `({{{() a} b} c} .c .b .a)` ?
|
|
94
94
|
|
|
@@ -96,9 +96,9 @@ There are three ways of combining functions:
|
|
|
96
96
|
|
|
97
97
|
### Syntactic sugar
|
|
98
98
|
|
|
99
|
-
-
|
|
100
|
-
- dot (`.`) in "projection" acts as a separator so the
|
|
101
|
-
can be omitted.
|
|
99
|
+
- Parenthesis can be omitted, except for the empty composition `()`,
|
|
100
|
+
- dot (`.`) in "projection" acts as a separator, so the surrounding
|
|
101
|
+
space can be omitted.
|
|
102
102
|
|
|
103
103
|
For example, `(.toto .titi (.0 .1))` can be written as `.toto.titi.0.1`.
|
|
104
104
|
|
|
@@ -148,8 +148,8 @@ projection, via (`.`), to the canonical string representation of the value, e.g.
|
|
|
148
148
|
|
|
149
149
|
#### Vector product
|
|
150
150
|
|
|
151
|
-
|
|
152
|
-
have the same type, and the
|
|
151
|
+
The vector product can be seen as a shorthand for a product in which all fields
|
|
152
|
+
have the same type, and the field names are integers starting from zero.
|
|
153
153
|
E.g., `{.toto 0, .titi 1, 123 2}` can be written as
|
|
154
154
|
`[.toto, .titi, 123]`.
|
|
155
155
|
|
|
@@ -531,7 +531,7 @@ For example:
|
|
|
531
531
|
|
|
532
532
|
## k-REPL (Read-Evaluate-Print Loop)
|
|
533
533
|
|
|
534
|
-
Also there is a REPL, `k-repl` (`./node_modules/.bin/k-repl`),
|
|
534
|
+
Also, there is a REPL, `k-repl` (`./node_modules/.bin/k-repl`),
|
|
535
535
|
which acts like a toy shell for the language.
|
|
536
536
|
|
|
537
537
|
```k-repl
|
|
@@ -552,72 +552,74 @@ Very! experimental repl shell for 'k-language'...
|
|
|
552
552
|
|
|
553
553
|
## Using `k` from `javascript`
|
|
554
554
|
|
|
555
|
-
|
|
555
|
+
```javascript
|
|
556
|
+
import k from "@fraczak/k";
|
|
556
557
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
558
|
+
let k_expression = '()';
|
|
559
|
+
k.run(k_expression,"ANYTHING...");
|
|
560
|
+
// RETURNS: "ANYTHING..."
|
|
560
561
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
562
|
+
k_expression = '{"ala" name, 23 age}';
|
|
563
|
+
k.run(k_expression,"ANYTHING...");
|
|
564
|
+
// RETURNS: {"name":"ala","age":23}
|
|
564
565
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
566
|
+
k_expression = '[.year, .age]';
|
|
567
|
+
k.run(k_expression,{"year":2002,"age":19});
|
|
568
|
+
// RETURNS: [2002,19]
|
|
568
569
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
570
|
+
k_expression = '[(), ()]';
|
|
571
|
+
k.run(k_expression,"duplicate me");
|
|
572
|
+
// RETURNS: ["duplicate me","duplicate me"]
|
|
572
573
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
574
|
+
k_expression = '[[[()]]]';
|
|
575
|
+
k.run(k_expression,"nesting");
|
|
576
|
+
// RETURNS: [[["nesting"]]]
|
|
576
577
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
578
|
+
k_expression = '[[()]] {() nested, .0.0 val}';
|
|
579
|
+
k.run(k_expression,"nesting and accessing");
|
|
580
|
+
// RETURNS: {"nested":[["nesting and accessing"]],"val":"nesting and accessing"}
|
|
580
581
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
582
|
+
k_expression = '0000';
|
|
583
|
+
k.run(k_expression,{"test":"parse integer"});
|
|
584
|
+
// RETURNS: 0
|
|
584
585
|
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
586
|
+
k_expression = '[.y,.x] PLUS';
|
|
587
|
+
k.run(k_expression,{"x":3,"y":4});
|
|
588
|
+
// RETURNS: 7
|
|
588
589
|
|
|
589
|
-
|
|
590
|
+
var k_fn = k.compile('{.name nom, <[.age, 18] GT .0, [.age, 12] GT "ado", "enfant"> age}');
|
|
590
591
|
|
|
591
|
-
|
|
592
|
-
|
|
592
|
+
k_fn({"age":23,"name":"Emily"});
|
|
593
|
+
// RETURNS: {"nom":"Emily","age":23}
|
|
593
594
|
|
|
594
|
-
|
|
595
|
-
|
|
595
|
+
k_fn({"age":16,"name":"Katrina"});
|
|
596
|
+
// RETURNS: {"nom":"Katrina","age":"ado"}
|
|
596
597
|
|
|
597
|
-
|
|
598
|
-
|
|
598
|
+
k_fn({"age":2,"name":"Mark"});
|
|
599
|
+
// RETURNS: {"nom":"Mark","age":"enfant"}
|
|
599
600
|
|
|
600
|
-
|
|
601
|
+
k_fn = k.compile('$t = < i: int, t: [ t ] > ; <$t, $int>');
|
|
601
602
|
|
|
602
|
-
|
|
603
|
-
|
|
603
|
+
k_fn(1);
|
|
604
|
+
// RETURNS: 1
|
|
604
605
|
|
|
605
|
-
|
|
606
|
-
|
|
606
|
+
k_fn({"i":1});
|
|
607
|
+
// RETURNS: {"i":1}
|
|
607
608
|
|
|
608
|
-
|
|
609
|
-
|
|
609
|
+
k_fn([{"i":2},{"i":3},{"t":[]}]);
|
|
610
|
+
// RETURNS: undefined
|
|
610
611
|
|
|
611
|
-
|
|
612
|
-
|
|
612
|
+
k_fn({"t":[{"i":2},{"i":3},{"t":[]}]});
|
|
613
|
+
// RETURNS: {"t":[{"i":2},{"i":3},{"t":[]}]}
|
|
613
614
|
|
|
614
|
-
|
|
615
|
+
k_fn = k.compile('$ < < [ int ] ints, [ bool ] bools > list, string None>');
|
|
615
616
|
|
|
616
|
-
|
|
617
|
-
|
|
617
|
+
k_fn({"None":"None"});
|
|
618
|
+
// RETURNS: {"None":"None"}
|
|
618
619
|
|
|
619
|
-
|
|
620
|
-
|
|
620
|
+
k_fn({"list":{"ints":[]}});
|
|
621
|
+
// RETURNS: {"list":{"ints":[]}}
|
|
621
622
|
|
|
622
|
-
|
|
623
|
-
|
|
623
|
+
k_fn({"list":{"ints":[1,2,3]}});
|
|
624
|
+
// RETURNS: {"list":{"ints":[1,2,3]}}
|
|
625
|
+
```
|
package/package.json
CHANGED
package/patterns.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import { assignCanonicalNames } from "./export.mjs";
|
|
|
8
8
|
const unitCode = codes.unitCode;
|
|
9
9
|
|
|
10
10
|
function relDefToString(relDef) {
|
|
11
|
-
|
|
11
|
+
const start = new Date().getTime();
|
|
12
12
|
const dumpPatterns = (rel) => {
|
|
13
13
|
switch (rel.op) {
|
|
14
14
|
case "product":
|
|
@@ -39,14 +39,20 @@ function relDefToString(relDef) {
|
|
|
39
39
|
// console.log(relDef.typePatternGraph.edges);
|
|
40
40
|
// console.log(relDef.def);
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
const result = JSON.stringify(dumpPatterns(relDef.def).map((x) => {
|
|
43
43
|
const { pattern, fields, type} = relDef.typePatternGraph.get_pattern(x);
|
|
44
44
|
return {pattern, fields, type};
|
|
45
45
|
}));
|
|
46
|
+
|
|
47
|
+
let took = new Date().getTime() - start;
|
|
48
|
+
if (took > 200) {
|
|
49
|
+
console.log(` -- RelDefToString: size=${result.length}, took ${took} msecs`);
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
function compactRel(relDef, name = "") {
|
|
49
|
-
|
|
55
|
+
const start = new Date().getTime();
|
|
50
56
|
const {def, typePatternGraph, varRefs } = relDef;
|
|
51
57
|
// console.log("COMPACTING typePatternGraph of size", typePatternGraph.size());
|
|
52
58
|
|
|
@@ -92,7 +98,10 @@ function compactRel(relDef, name = "") {
|
|
|
92
98
|
outputPatternId: renumbering[x.outputPatternId]
|
|
93
99
|
}));;
|
|
94
100
|
|
|
95
|
-
|
|
101
|
+
const time = new Date().getTime() - start;
|
|
102
|
+
if (time > 500 ) {
|
|
103
|
+
console.log(`[${new Date().getTime() - start} msecs] - COMPACTED ${name}.typePatternGraph [${typePatternGraph.size()}->${newTypePatternGraph.size()}]`);
|
|
104
|
+
}
|
|
96
105
|
return {def: newDef, typePatternGraph: newTypePatternGraph, varRefs: newVarRefs};
|
|
97
106
|
}
|
|
98
107
|
|
|
@@ -462,7 +471,7 @@ function patterns(representatives, rels) {
|
|
|
462
471
|
// we will also generate the canonical representation of the relations in C and replace
|
|
463
472
|
// the name to the relation by the hash of the canonical representation
|
|
464
473
|
|
|
465
|
-
// console.log("
|
|
474
|
+
// console.log("- SCC in order", sccInOrder);
|
|
466
475
|
|
|
467
476
|
for (const scc of sccInOrder) {
|
|
468
477
|
|
|
@@ -470,7 +479,7 @@ function patterns(representatives, rels) {
|
|
|
470
479
|
|
|
471
480
|
for (let iteration = 1; iteration <= maxNumberOfIterations; iteration++) {
|
|
472
481
|
|
|
473
|
-
// console.log(
|
|
482
|
+
// console.log(`-- Iteration ${iteration}/${maxNumberOfIterations} for SCC: { ${DAGnodes[scc].scc} }`);
|
|
474
483
|
// 4.1 For every r in C, compute the new typePatternGraph of r, i.e.:
|
|
475
484
|
|
|
476
485
|
let before = JSON.stringify(DAGnodes[scc].scc.map( relName => {
|
|
@@ -481,11 +490,11 @@ function patterns(representatives, rels) {
|
|
|
481
490
|
// console.log(relDefToString(rels[relName]));
|
|
482
491
|
return relDefToString(rels[relName]);
|
|
483
492
|
}));
|
|
484
|
-
|
|
493
|
+
|
|
485
494
|
let after = JSON.stringify(DAGnodes[scc].scc.map( relName => {
|
|
486
495
|
const relDef = compactRel(rels[relName],relName);
|
|
487
496
|
for (let i = 0; i < relDef.varRefs.length; i++) {
|
|
488
|
-
|
|
497
|
+
const start = new Date().getTime();
|
|
489
498
|
let varRel = relDef.varRefs[i];
|
|
490
499
|
let { varName } = varRel;
|
|
491
500
|
try {
|
|
@@ -493,7 +502,6 @@ function patterns(representatives, rels) {
|
|
|
493
502
|
let varInputPatternId = varRootDef.typePatternGraph.find(varRootDef.def.patterns[0]);
|
|
494
503
|
let varOutputPatternId = varRootDef.typePatternGraph.find(varRootDef.def.patterns[1]);
|
|
495
504
|
let cloned = varRootDef.typePatternGraph.clone([varInputPatternId, varOutputPatternId], relDef.typePatternGraph);
|
|
496
|
-
|
|
497
505
|
relDef.typePatternGraph.unify(`ref:input ${relName}(${varName})`, varRel.inputPatternId, cloned[varInputPatternId]);
|
|
498
506
|
relDef.typePatternGraph.unify("ref:output", varRel.outputPatternId, cloned[varOutputPatternId]);
|
|
499
507
|
} catch (e) {
|
|
@@ -502,6 +510,10 @@ function patterns(representatives, rels) {
|
|
|
502
510
|
- ${e.message}`;
|
|
503
511
|
throw e;
|
|
504
512
|
}
|
|
513
|
+
const tookMs = new Date().getTime() - start;
|
|
514
|
+
if (tookMs > 200) {
|
|
515
|
+
console.log(` ---- Processing ${relName}(.., x${i}=${relDef.varRefs[i].varName}, ..) took: ${tookMs} ms`);
|
|
516
|
+
}
|
|
505
517
|
}
|
|
506
518
|
rels[relName] = compactRel(relDef,relName);
|
|
507
519
|
return relDefToString(rels[relName]);
|
package/typing.mjs
CHANGED
|
@@ -3,20 +3,36 @@ import codes from "./codes.mjs";
|
|
|
3
3
|
|
|
4
4
|
const unitCode = codes.unitCode;
|
|
5
5
|
|
|
6
|
-
function
|
|
7
|
-
return
|
|
6
|
+
function asSet(vector) {
|
|
7
|
+
return Array.from(new Set(vector));
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
function setUnion(...vectors) {
|
|
11
|
-
|
|
11
|
+
const unionSet = new Set();
|
|
12
|
+
for (const v of vectors) {
|
|
13
|
+
for (const element of v) {
|
|
14
|
+
unionSet.add(element);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return Array.from(unionSet);
|
|
12
18
|
}
|
|
13
19
|
|
|
14
20
|
function subsetP(v1,v2) {
|
|
15
|
-
const v2Set =
|
|
16
|
-
return
|
|
21
|
+
const v2Set = new Set(v2);
|
|
22
|
+
return v1.every(x => v2Set.has(x));
|
|
17
23
|
}
|
|
24
|
+
|
|
18
25
|
function eqsetP(v1,v2) {
|
|
19
|
-
|
|
26
|
+
const v1Set = new Set(v1);
|
|
27
|
+
const v2Set = new Set(v2);
|
|
28
|
+
if (v1Set.size != v2Set.size) return false;
|
|
29
|
+
|
|
30
|
+
for (const value of v1Set) {
|
|
31
|
+
if (!v2Set.has(value)) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
20
36
|
}
|
|
21
37
|
|
|
22
38
|
const matchAllPattern = {pattern: '(...)', fields: []};
|
|
@@ -76,7 +92,7 @@ class TypePatternForest {
|
|
|
76
92
|
// const node = {...flatTypePattern, _id: id};
|
|
77
93
|
const node = {...flatTypePattern}
|
|
78
94
|
that.nodes.push(node);
|
|
79
|
-
|
|
95
|
+
Array.from(new Set(children.map(that.find.bind(that))))
|
|
80
96
|
.forEach(rep => {that.parent[rep] = id});
|
|
81
97
|
return id;
|
|
82
98
|
}
|
|
@@ -139,7 +155,6 @@ class TypePatternGraph {
|
|
|
139
155
|
for( const id of singletonPatterns) {
|
|
140
156
|
this.unify('singleton', id, this.getTypeId(representatives[`-${id}-`]));
|
|
141
157
|
}
|
|
142
|
-
|
|
143
158
|
}
|
|
144
159
|
|
|
145
160
|
|
|
@@ -165,27 +180,29 @@ class TypePatternGraph {
|
|
|
165
180
|
)
|
|
166
181
|
);
|
|
167
182
|
|
|
168
|
-
const gEdgesWithoutParrallelEdges =
|
|
169
|
-
|
|
183
|
+
const gEdgesWithoutParrallelEdges = Array.from(new Set(gEdges));
|
|
170
184
|
const gGraph = new Graph(gEdgesWithoutParrallelEdges);
|
|
171
185
|
const queue = gNodes.filter(x =>
|
|
172
186
|
this.patterns.nodes[x].pattern in {'()':1, '(...)':1,'{...}':1, '<...>':1});
|
|
173
|
-
const
|
|
187
|
+
const excludedSet = new Set(queue);
|
|
188
|
+
|
|
174
189
|
while (queue.length > 0) {
|
|
175
190
|
const x = queue.pop();
|
|
176
191
|
for (const e of gGraph.dst[x] || []) {
|
|
177
192
|
const y = gGraph.edges[e].src;
|
|
178
|
-
if (y
|
|
179
|
-
|
|
193
|
+
if (excludedSet.has(y)) continue;
|
|
194
|
+
excludedSet.add(y);
|
|
180
195
|
queue.push(y);
|
|
181
196
|
}
|
|
182
197
|
}
|
|
183
|
-
|
|
198
|
+
|
|
199
|
+
return gNodes.filter(x => !((excludedSet.has(x)) || (this.patterns.nodes[x].pattern == 'type')));
|
|
184
200
|
}
|
|
185
201
|
|
|
186
202
|
getCompressed() {
|
|
187
203
|
const newTypePatternGraph = new TypePatternGraph();
|
|
188
204
|
const renamed = this.cloneAll(newTypePatternGraph);
|
|
205
|
+
|
|
189
206
|
newTypePatternGraph.turnSingletonPatternsIntoCodes();
|
|
190
207
|
|
|
191
208
|
Object.keys(renamed).forEach( id => {
|
|
@@ -223,7 +240,9 @@ class TypePatternGraph {
|
|
|
223
240
|
|
|
224
241
|
// console.log("equivalence", equivalence);
|
|
225
242
|
|
|
243
|
+
let count = 0;
|
|
226
244
|
const areDifferent = (i1,i2) => {
|
|
245
|
+
count++;
|
|
227
246
|
const p1 = newTypePatternGraph.get_pattern(i1);
|
|
228
247
|
const p2 = newTypePatternGraph.get_pattern(i2);
|
|
229
248
|
if (p1.pattern != p2.pattern) return true;
|
|
@@ -239,7 +258,9 @@ class TypePatternGraph {
|
|
|
239
258
|
return false;
|
|
240
259
|
}
|
|
241
260
|
let changed = true;
|
|
261
|
+
let count2 = 0;
|
|
242
262
|
while (changed) {
|
|
263
|
+
count2++;
|
|
243
264
|
changed = false;
|
|
244
265
|
const equivalenceSize = equivalence.length;
|
|
245
266
|
for (let eqClassPos = 0; eqClassPos < equivalenceSize; eqClassPos++) {
|
|
@@ -285,7 +306,7 @@ class TypePatternGraph {
|
|
|
285
306
|
for (const oldId in newIds) {
|
|
286
307
|
const newId = newIds[oldId];
|
|
287
308
|
const pattern = newTypePatternGraph.get_pattern(oldId);
|
|
288
|
-
const newPattern = compressedTypePatternGraph.get_pattern(newId);
|
|
309
|
+
// const newPattern = compressedTypePatternGraph.get_pattern(newId);
|
|
289
310
|
// console.log("patterns", pattern, newPattern);
|
|
290
311
|
if (pattern.pattern == 'type')
|
|
291
312
|
continue;
|
|
@@ -294,7 +315,7 @@ class TypePatternGraph {
|
|
|
294
315
|
compressedTypePatternGraph.edges[newId] = {};
|
|
295
316
|
for (const lab in edges) {
|
|
296
317
|
// console.log("edges[lab]", edges[lab]);
|
|
297
|
-
compressedTypePatternGraph.edges[newId][lab] =
|
|
318
|
+
compressedTypePatternGraph.edges[newId][lab] = asSet(edges[lab].map(x =>
|
|
298
319
|
newIds[reps[newTypePatternGraph.find(x)][0]]));
|
|
299
320
|
}
|
|
300
321
|
}
|
|
@@ -308,6 +329,7 @@ class TypePatternGraph {
|
|
|
308
329
|
// console.log("nodes", compressedTypePatternGraph.patterns.nodes);
|
|
309
330
|
// console.log("edges", compressedTypePatternGraph.edges);
|
|
310
331
|
// console.log("--------------------")
|
|
332
|
+
|
|
311
333
|
return {typePatternGraph: compressedTypePatternGraph, remapping};
|
|
312
334
|
}
|
|
313
335
|
|
|
@@ -343,7 +365,7 @@ class TypePatternGraph {
|
|
|
343
365
|
const new_id = result[i];
|
|
344
366
|
targetGraph.edges[new_id] = {};
|
|
345
367
|
for (const lab in edges) {
|
|
346
|
-
targetGraph.edges[new_id][lab] =
|
|
368
|
+
targetGraph.edges[new_id][lab] = asSet(edges[lab].map(x => result[find(x)]));
|
|
347
369
|
}
|
|
348
370
|
}
|
|
349
371
|
return result;
|
|
@@ -584,7 +606,7 @@ class TypePatternGraph {
|
|
|
584
606
|
|
|
585
607
|
unify(rule, ...ids) {
|
|
586
608
|
const find = (x) => this.find(x);
|
|
587
|
-
const reps =
|
|
609
|
+
const reps = Array.from(new Set(ids.map(find)));
|
|
588
610
|
if (reps.length < 2) return false;
|
|
589
611
|
const rep_patters = reps.map(x => {
|
|
590
612
|
const pattern = this.get_pattern(x);
|
|
@@ -615,8 +637,8 @@ class TypePatternGraph {
|
|
|
615
637
|
for (const lab in edges) {
|
|
616
638
|
// if the pattern is [] all labels are treated as 'vector-member'
|
|
617
639
|
const new_lab = new_pattern.pattern == '[]' ? 'vector-member' : lab;
|
|
618
|
-
const dests =
|
|
619
|
-
this.edges[new_id][new_lab] =
|
|
640
|
+
const dests = asSet(edges[lab].map(find));
|
|
641
|
+
this.edges[new_id][new_lab] = asSet([...(this.edges[new_id][new_lab] || []), ...dests]);
|
|
620
642
|
}
|
|
621
643
|
}
|
|
622
644
|
// add stuff for types
|
|
@@ -629,7 +651,7 @@ class TypePatternGraph {
|
|
|
629
651
|
// all edges are goin to unit type
|
|
630
652
|
const unit_id = this.getTypeId(unitCode);
|
|
631
653
|
for (const lab in this.edges[new_id]) {
|
|
632
|
-
this.edges[new_id][lab]
|
|
654
|
+
this.edges[new_id][lab] = asSet([unit_id]);
|
|
633
655
|
}
|
|
634
656
|
}; break;
|
|
635
657
|
case 'product':
|
|
@@ -637,7 +659,7 @@ class TypePatternGraph {
|
|
|
637
659
|
const type_fields = Object.keys(code[code.code]);
|
|
638
660
|
for (const lab of type_fields) {
|
|
639
661
|
const target_type_id = this.getTypeId(code[code.code][lab]);
|
|
640
|
-
this.edges[new_id][lab]=
|
|
662
|
+
this.edges[new_id][lab]= asSet([...(this.edges[new_id][lab] ||[]), target_type_id]);
|
|
641
663
|
}
|
|
642
664
|
}; break;
|
|
643
665
|
case 'vector': {
|
|
@@ -645,18 +667,13 @@ class TypePatternGraph {
|
|
|
645
667
|
const target_type_id = this.getTypeId(code.vector);
|
|
646
668
|
|
|
647
669
|
this.edges[new_id] = {
|
|
648
|
-
'vector-member':
|
|
649
|
-
[target_type_id]: target_type_id,
|
|
650
|
-
...asMapSet(
|
|
651
|
-
setUnion(...Object.values(this.edges[new_id]).map(aSet => Object.values(aSet)))
|
|
652
|
-
)
|
|
653
|
-
}
|
|
670
|
+
'vector-member': asSet([ target_type_id, ...Object.values(this.edges[new_id])])
|
|
654
671
|
}
|
|
655
672
|
}
|
|
656
673
|
}
|
|
657
674
|
}
|
|
658
675
|
for ( const lab of Object.keys(this.edges[new_id]) ) {
|
|
659
|
-
this.unify(rule+'.', ...
|
|
676
|
+
this.unify(rule+'.', ...this.edges[new_id][lab]);
|
|
660
677
|
}
|
|
661
678
|
|
|
662
679
|
return true;
|
|
@@ -667,7 +684,7 @@ class TypePatternGraph {
|
|
|
667
684
|
const find = (x) => this.patterns.find(x);
|
|
668
685
|
this.edges[id] = {};
|
|
669
686
|
for (const [lab,dest] of Object.entries(fields)) {
|
|
670
|
-
this.edges[id][lab] =
|
|
687
|
+
this.edges[id][lab] = asSet(dest.map(find));
|
|
671
688
|
}
|
|
672
689
|
return id;
|
|
673
690
|
}
|