@fraczak/k 5.1.2 → 6.0.1

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.
Files changed (115) hide show
  1. package/.codex +0 -0
  2. package/Code-derivation-tests/blowup.mjs +3 -3
  3. package/Code-derivation-tests/bnat.mjs +2 -2
  4. package/Code-derivation-tests/codec-witness-pattern.mjs +50 -0
  5. package/Code-derivation-tests/convergence-strategy.mjs +24 -0
  6. package/Code-derivation-tests/dot.mjs +12 -9
  7. package/Code-derivation-tests/filter-syntax.mjs +21 -0
  8. package/Code-derivation-tests/loop.mjs +8 -2
  9. package/Code-derivation-tests/nat.mjs +1 -1
  10. package/Code-derivation-tests/not-not.mjs +3 -3
  11. package/Code-derivation-tests/pattern-envelope.mjs +68 -0
  12. package/Code-derivation-tests/rlz.mjs +2 -2
  13. package/{BIG_PICTURE.md → DOCS/BIG_PICTURE.md} +103 -50
  14. package/DOCS/REPL.md +191 -0
  15. package/DOCS/a.html +398 -0
  16. package/DOCS/book/01-introduction.md +51 -0
  17. package/DOCS/book/02-syntax-and-values.md +111 -0
  18. package/DOCS/book/03-types-as-finite-automata.md +156 -0
  19. package/DOCS/book/04-partial-functions-and-composition.md +146 -0
  20. package/DOCS/book/05-typing-filters-and-normalization.md +111 -0
  21. package/DOCS/book-combined.html +3798 -0
  22. package/DOCS/book-combined.md +3745 -0
  23. package/DOCS/book-combined.pdf +0 -0
  24. package/DOCS/book-combined.tex +5682 -0
  25. package/DOCS/book.html +65 -0
  26. package/DOCS/book.md +54 -0
  27. package/DOCS/book.pdf +0 -0
  28. package/DOCS/book.tex +150 -0
  29. package/NAT.k~ +452 -0
  30. package/README.md +204 -508
  31. package/TypeGraph.mjs +43 -0
  32. package/TypePatternGraph.mjs +251 -0
  33. package/Value.mjs +192 -0
  34. package/augmentation.mjs +198 -0
  35. package/codecs/BINARY_FORMAT.html +471 -0
  36. package/codecs/BINARY_FORMAT.md +53 -0
  37. package/codecs/POLYMORPHIC_BINARY_FORMAT.html +355 -0
  38. package/codecs/POLYMORPHIC_BINARY_FORMAT.md +303 -0
  39. package/codecs/README.md +215 -0
  40. package/codecs/example-pipeline.mjs +149 -0
  41. package/codecs/ieee.mjs +140 -0
  42. package/codecs/int.mjs +104 -0
  43. package/codecs/json-codec.mjs +215 -0
  44. package/codecs/json.mjs +40 -0
  45. package/codecs/k-parse.mjs +90 -0
  46. package/codecs/k-pattern.mjs +75 -0
  47. package/codecs/k-print.mjs +46 -0
  48. package/codecs/runtime/codec.mjs +768 -0
  49. package/codecs/runtime/ieee-pattern.mjs +30 -0
  50. package/codecs/runtime/pattern-json.mjs +96 -0
  51. package/codecs/runtime/prefix-codec.mjs +425 -0
  52. package/codecs/runtime/show-value.mjs +68 -0
  53. package/codecs/runtime/typeFromValue.mjs +34 -0
  54. package/codecs/runtime/unicode-string.mjs +220 -0
  55. package/codecs/show.mjs +41 -0
  56. package/codecs/string-codec.mjs +80 -0
  57. package/codecs/unit.mjs +51 -0
  58. package/codecs/utf16.mjs +66 -0
  59. package/codecs/utf8.mjs +37 -0
  60. package/codes.mjs +146 -44
  61. package/compiler.mjs +111 -0
  62. package/convergence.mjs +197 -0
  63. package/core.k +197 -0
  64. package/export.mjs +22 -32
  65. package/hash.mjs +29 -31
  66. package/ieee.klib +0 -0
  67. package/index.mjs +41 -15
  68. package/k-vscode/.vscode/launch.json +14 -0
  69. package/k-vscode/README.md +65 -0
  70. package/k-vscode/language-configuration.json +42 -0
  71. package/k-vscode/package-lock.json +4176 -0
  72. package/k-vscode/package.json +57 -0
  73. package/k-vscode/snippets/k.json +92 -0
  74. package/k-vscode/syntaxes/k.tmLanguage.json +243 -0
  75. package/k.mjs +56 -54
  76. package/object.mjs +517 -0
  77. package/objects/README.md +38 -0
  78. package/objects/compile-lib.mjs +42 -0
  79. package/objects/compile.mjs +42 -0
  80. package/objects/decompile.mjs +32 -0
  81. package/package.json +13 -6
  82. package/parser.jison +27 -46
  83. package/parser.mjs +68 -100
  84. package/pretty.mjs +21 -40
  85. package/repl2.mjs +662 -0
  86. package/run.mjs +264 -231
  87. package/symbol-table.mjs +3 -17
  88. package/test-fingerprint.mjs +7 -7
  89. package/test-hash-fuzz.mjs +107 -0
  90. package/test-hash-normalization.mjs +134 -0
  91. package/test-k-object.mjs +74 -0
  92. package/test-repl2.mjs +106 -0
  93. package/test.mjs +45 -70
  94. package/tests.sh +10 -1
  95. package/type_registry/registry.mjs~ +105 -0
  96. package/type_registry/typeParser.jison~ +132 -0
  97. package/typing.mjs +129 -676
  98. package/unification.mjs +157 -0
  99. package/valueIO.mjs +54 -0
  100. package/valueParser.jison +143 -0
  101. package/valueParser.mjs +713 -0
  102. package/Code-derivation-tests/built-in.mjs +0 -19
  103. package/Code-derivation-tests/vector.mjs +0 -19
  104. package/Filters/bug.k +0 -3
  105. package/Filters/composing.k +0 -15
  106. package/Filters/filter.k +0 -9
  107. package/TODO.md +0 -53
  108. package/TYPING.md +0 -365
  109. package/k-repl.cast +0 -1913
  110. package/k.cast +0 -618
  111. package/my-objects.json +0 -6
  112. package/patterns.mjs +0 -543
  113. package/repl.mjs +0 -213
  114. package/test-filters.mjs +0 -45
  115. package/typing-test.mjs +0 -40
package/my-objects.json DELETED
@@ -1,6 +0,0 @@
1
- ####################################################
2
- # empty lines and lines starting with # are ignored
3
- {"y": 123, "x": 432,"others": "..."}
4
- {"x":987}
5
- {"z":123}
6
- ####################################################
package/patterns.mjs DELETED
@@ -1,543 +0,0 @@
1
-
2
- import hash from "./hash.mjs";
3
- import { TypePatternGraph } from "./typing.mjs";
4
- import { Graph, sccs, topoOrder } from "./Graph.mjs";
5
- import codes from "./codes.mjs";
6
- import { assignCanonicalNames } from "./export.mjs";
7
-
8
- const unitCode = codes.unitCode;
9
-
10
- function relDefToString(relDef) {
11
- const start = new Date().getTime();
12
- const dumpPatterns = (rel) => {
13
- switch (rel.op) {
14
- case "product":
15
- return [].concat(rel.patterns, ...rel.product.map(({exp}) => dumpPatterns(exp)));
16
- case "union":
17
- return [].concat(rel.patterns, ...rel.union.map(exp => dumpPatterns(exp)));
18
- case "comp":
19
- return [].concat(rel.patterns, ...rel.comp.map(exp => dumpPatterns(exp)));
20
- case "vector":
21
- return [].concat(rel.patterns, ...rel.vector.map(exp => dumpPatterns(exp)));
22
- case "caret":
23
- return [].concat(rel.patterns, dumpPatterns(rel.caret));
24
- case "ref":
25
- case "int":
26
- case "str":
27
- case "identity":
28
- case "dot":
29
- case "code":
30
- case "pipe":
31
- case "filter":
32
- return [...rel.patterns];
33
- }
34
- throw new Error("NOT EXPECTED OP:", JSON.stringify(rel, null, 2));
35
- };
36
-
37
- // console.log("SIZE", relDef.typePatternGraph.size());
38
- // console.log(relDef.typePatternGraph.patterns.nodes);
39
- // console.log(relDef.typePatternGraph.edges);
40
- // console.log(relDef.def);
41
-
42
- const result = JSON.stringify(dumpPatterns(relDef.def).map((x) => {
43
- const { pattern, fields, type} = relDef.typePatternGraph.get_pattern(x);
44
- return {pattern, fields, type};
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;
52
- }
53
-
54
- function compactRel(relDef, name = "") {
55
- const start = new Date().getTime();
56
- const {def, typePatternGraph, varRefs } = relDef;
57
- // console.log("COMPACTING typePatternGraph of size", typePatternGraph.size());
58
-
59
- const {typePatternGraph : newTypePatternGraph, remapping: renumbering} = typePatternGraph.getCompressed();
60
-
61
- const copyRel = (rel) => {
62
- const newRel = {...rel, patterns:[renumbering[rel.patterns[0]], renumbering[rel.patterns[1]]]};
63
- switch (rel.op) {
64
- case "product":
65
- newRel.product = rel.product.map(({label, exp}) => ({label, exp: copyRel(exp)}));
66
- break;
67
- case "union":
68
- newRel.union = rel.union.map(exp => copyRel(exp));
69
- break;
70
- case "comp":
71
- newRel.comp = rel.comp.map(exp => copyRel(exp));
72
- break;
73
- case "vector":
74
- newRel.vector = rel.vector.map(exp => copyRel(exp));
75
- break;
76
- case "caret":
77
- newRel.caret = copyRel(rel.caret);
78
- break;
79
- case "ref":
80
- case "int":
81
- case "str":
82
- case "identity":
83
- case "dot":
84
- case "code":
85
- case "pipe":
86
- case "filter":
87
- break;
88
- default:
89
- console.error("NOT EXPECTED OP:", JSON.stringify(rel, null, 2));
90
- break;
91
- };
92
- return newRel;
93
- };
94
- const newDef = copyRel(def);
95
- const newVarRefs = varRefs.map(x => ({
96
- ...x,
97
- inputPatternId: renumbering[x.inputPatternId],
98
- outputPatternId: renumbering[x.outputPatternId]
99
- }));;
100
-
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
- }
105
- return {def: newDef, typePatternGraph: newTypePatternGraph, varRefs: newVarRefs};
106
- }
107
-
108
- function patterns(representatives, rels) {
109
- // INPUT:
110
- // codes: {"KL": {"code": "product", "product": {}}, ...}
111
- // representatives:{"{}": "KL", ...}
112
- // rels: {"rlz": [{op: comp,...}, ...], ...}
113
-
114
- const relAlias = {};
115
-
116
- // 1 INITIALIZATION
117
- // 1.1 initialize patternNodes and rels
118
-
119
- function augment(rel, rootDef) {
120
- try {
121
- switch (rel.op) {
122
- case "product":
123
- rel["product"].forEach(({label, exp}) => {
124
- augment(exp, rootDef)
125
- });
126
- augmentProduct(rel,rootDef);
127
- break;
128
- case "union":
129
- rel["union"].forEach((exp) => {
130
- augment(exp,rootDef);
131
- });
132
- augmentUnion(rel,rootDef);
133
- break;
134
- case "comp":
135
- rel["comp"].forEach((exp) => {
136
- augment(exp,rootDef);
137
- });
138
- augmentComp(rel,rootDef);
139
- break;
140
- case "vector":
141
- rel["vector"].forEach((exp) => {
142
- augment(exp,rootDef);
143
- });
144
- augmentVector(rel,rootDef);
145
- break;
146
- case "code":
147
- rel["code"] = representatives[rel.code] || rel.code;
148
- rel.patterns = [];
149
- rel.patterns[0] = rootDef.typePatternGraph.getTypeId(rel["code"]);
150
- rel.patterns[1] = rel.patterns[0];
151
- break;
152
- case "caret":
153
- augment(rel.caret,rootDef);
154
- rel.patterns = [
155
- rel.caret.patterns[0],
156
- rootDef.typePatternGraph.addNewNode(
157
- {pattern: '[]'},
158
- {"vector-member": [rel.caret.patterns[1]]})
159
- ];
160
- break;
161
- case "pipe":
162
- rel.patterns = [];
163
- rel.patterns[1] = rootDef.typePatternGraph.addNewNode();
164
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode(
165
- {pattern: '[]'},
166
- {"vector-member": [rel.patterns[1]]});
167
- break;
168
-
169
- case "ref":
170
- augmentRef(rel, rootDef);
171
- break;
172
- //----------------
173
-
174
- case "int":
175
- rel.patterns = [];
176
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode();
177
- rel.patterns[1] = rootDef.typePatternGraph.getTypeId('@int');
178
- break;
179
- case "str":
180
- rel.patterns = [];
181
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode();
182
- rel.patterns[1] = rootDef.typePatternGraph.getTypeId('@string');
183
- break;
184
- case "identity":
185
- rel.patterns = [];
186
- rel.patterns[0] = rel.patterns[1] = rootDef.typePatternGraph.addNewNode();
187
- break;
188
- case "dot":
189
- rel.patterns = [];
190
- rel.patterns[1] = rootDef.typePatternGraph.addNewNode();
191
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode({pattern: '(...)'}, { [rel.dot]: [rel.patterns[1]] });
192
- break;
193
- case "filter":
194
- rel.patterns = [];
195
- rel.patterns[1] = rel.patterns[0] = filterToPattern(rel.filter, rootDef);
196
- break;
197
- default:
198
- console.error("NOT EXPECTED OP for aumentation:", JSON.stringify(rel, null, 2));
199
- break;
200
- }
201
- } catch (e) {
202
- e.message = `Type Error in '${rel.op}' (lines ${rel.start?.line}:${rel.start?.column}...${rel.end?.line}:${rel.end?.column})\n - ${e.message}`;
203
- throw e;
204
- }
205
- }
206
-
207
- function filterToPattern(filter, rootDef) {
208
- const context = rootDef.patternVars;
209
- const getFields = () =>
210
- Object.keys(filter.fields || {}).reduce( (fields, label) => {
211
- const patternId = filterToPattern(filter.fields[label], rootDef);
212
- fields[label] = [patternId];
213
- return fields;
214
- }, {});
215
- if (filter.name && ! (filter.name in context)) {
216
- context[filter.name] = rootDef.typePatternGraph.addNewNode();
217
- }
218
- let newPatternId = null;
219
- switch (filter.type) {
220
- case "name":
221
- newPatternId = context[filter.name];
222
- break;
223
- case "code":
224
- newPatternId = rootDef.typePatternGraph.getTypeId(representatives[filter.code] || filter.code);
225
- break;
226
- case "union":
227
- newPatternId = rootDef.typePatternGraph.addNewNode(
228
- {pattern: filter.open ? '<...>' : '<>', fields:Object.keys(filter.fields || {})},
229
- getFields());
230
- break;
231
- case "product":
232
- newPatternId = rootDef.typePatternGraph.addNewNode(
233
- {pattern: filter.open ? '{...}' : '{}', fields:Object.keys(filter.fields || {})},
234
- getFields());
235
- break;
236
- case "vector": {
237
- const vector = filterToPattern(filter.vector, rootDef);
238
- newPatternId = rootDef.typePatternGraph.addNewNode(
239
- {pattern: '[]', fields: ["vector-member"]},
240
- {"vector-member": [vector]});
241
- };
242
- break;
243
- default:
244
- newPatternId = rootDef.typePatternGraph.addNewNode(
245
- {pattern: filter.open ? '(...)' : '()'},
246
- getFields());
247
- }
248
- if (filter.name) {
249
- rootDef.typePatternGraph.unify(`filter: ${filter.name}`, newPatternId, context[filter.name]);
250
- }
251
-
252
- return newPatternId;
253
- }
254
-
255
- function augmentProduct(rel,rootDef) {
256
- rel.patterns = [];
257
- switch (rel.product.length) {
258
- case 0: 
259
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode();
260
- rel.patterns[1] = rootDef.typePatternGraph.getTypeId(unitCode);
261
- break;
262
- case 1:
263
- // union/variant constructor: %old_i { %exp_i exp %exp_o field } %old_o
264
- rel.patterns[0] = rel.product[0].exp.patterns[0];
265
- rel.patterns[1] = rootDef.typePatternGraph.addNewNode({pattern: '<...>'},
266
- {[rel.product[0].label]: [rel.product[0].exp.patterns[1]]});
267
- break;
268
- default:
269
- // product constructor %old_i { %exp0_i exp0 %exp0_o field0, ... %expk_i expk %expk_o fieldk } %old_o
270
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode();
271
- rootDef.typePatternGraph.unify(
272
- "product:input",
273
- rel.patterns[0],
274
- ...rel.product.map(({exp}) => exp.patterns[0]));
275
-
276
- rel.patterns[1] = rootDef.typePatternGraph.addNewNode({pattern: '{}'},
277
- rel.product.reduce((edges, {label, exp}) => {
278
- edges[label] = [exp.patterns[1]];
279
- return edges;
280
- }, {})
281
- );
282
- };
283
- }
284
-
285
- function augmentUnion(rel,rootDef) {
286
- rel.patterns = [];
287
- if (rel.union.length == 0) {
288
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode();
289
- rel.patterns[1] = rootDef.typePatternGraph.addNewNode();
290
- } else {
291
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode();
292
- rootDef.typePatternGraph.unify(
293
- "union:input",
294
- rel.patterns[0],
295
- ...rel.union.map(exp => exp.patterns[0]));
296
-
297
- rel.patterns[1] = rootDef.typePatternGraph.addNewNode();
298
- rootDef.typePatternGraph.unify(
299
- "union:output",
300
- rel.patterns[1],
301
- ...rel.union.map(exp => exp.patterns[1]));
302
- }
303
- }
304
-
305
- function augmentComp(rel,rootDef) {
306
- rel.patterns = [];
307
- if (rel.comp.length == 0) {
308
- rel.patterns[0] = rel.patterns[1] = rootDef.typePatternGraph.addNewNode();
309
- } else {
310
-
311
- for (let i = 0; i < rel.comp.length - 1; i++) {
312
- rootDef.typePatternGraph.unify(
313
- "comp:chain",
314
- rel.comp[i].patterns[1],
315
- rel.comp[i+1].patterns[0]
316
- );
317
- }
318
-
319
- rel.patterns[0] = rel.comp[0].patterns[0];
320
- rel.patterns[1] = rel.comp[rel.comp.length - 1].patterns[1];
321
- }
322
- }
323
-
324
- function augmentVector(rel,rootDef) {
325
- rel.patterns = [];
326
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode();
327
- rootDef.typePatternGraph.unify(
328
- "vector:input",
329
- rel.patterns[0],
330
- ...rel.vector.map(exp => exp.patterns[0]));
331
-
332
- let member = rootDef.typePatternGraph.addNewNode();
333
- rootDef.typePatternGraph.unify(
334
- "vector:output",
335
- member,
336
- ...rel.vector.map(exp => exp.patterns[1])
337
- );
338
- rel.patterns[1] = rootDef.typePatternGraph.addNewNode({pattern: '[]'}, {"vector-member": [member]});
339
- }
340
-
341
- function augmentRef(rel,rootDef) {
342
- rel.patterns = [];
343
- if (rel.ref in rels) {
344
- rel.patterns = [rootDef.typePatternGraph.addNewNode(), rootDef.typePatternGraph.addNewNode()];
345
- rootDef.varRefs.push( {
346
- varName: rel.ref,
347
- inputPatternId: rel.patterns[0],
348
- outputPatternId: rel.patterns[1],
349
- start: rel.start,
350
- end: rel.end
351
- });
352
- return;
353
- }
354
- // it is built-in
355
- switch (rel.ref) {
356
- case "_log!":
357
- rel.patterns[0] = rel.patterns[1] = rootDef.typePatternGraph.addNewNode();
358
- break;
359
- case "true":
360
- case "false":
361
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode();
362
- rel.patterns[1] = rootDef.typePatternGraph.getTypeId('@bool');
363
- break;
364
- case "PLUS":
365
- case "TIMES":
366
- rel.patterns[1] = rootDef.typePatternGraph.getTypeId('@int');
367
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode({pattern: '[]'}, {"vector-member": [rel.patterns[1]]});
368
- break;
369
- case "CONCAT":
370
- rel.patterns[1] = rootDef.typePatternGraph.getTypeId('@string');
371
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode({pattern: '[]'}, {"vector-member": [rel.patterns[1]]});
372
- break;
373
- case "toVEC":
374
- rel.patterns[0] = rootDef.typePatternGraph.getTypeId('@string')
375
- rel.patterns[1] = rootDef.typePatternGraph.addNewNode({pattern: '[]'}, {"vector-member": [rel.patterns[0]]});
376
- break;
377
- case "toDateMsec":
378
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode();
379
- rel.patterns[1] = rootDef.typePatternGraph.getTypeId('@int');
380
- break;
381
- case "toJSON":
382
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode();
383
- rel.patterns[1] = rootDef.typePatternGraph.getTypeId('@string');
384
- break;
385
- case "toDateStr":
386
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode();
387
- rel.patterns[1] = rootDef.typePatternGraph.getTypeId('@string');
388
- break;
389
- case "GT":
390
- case "EQ":
391
- rel.patterns[0] = rel.patterns[1] = rootDef.typePatternGraph.addNewNode({pattern: '[]'}, {"vector-member": [rootDef.typePatternGraph.addNewNode()]});
392
- break;
393
- case "fromJSON":
394
- rel.patterns[0] = rootDef.typePatternGraph.getTypeId('@string');
395
- rel.patterns[1] = rootDef.typePatternGraph.addNewNode();
396
- break;
397
- case "CONS": {
398
- const member = rootDef.typePatternGraph.addNewNode();
399
- rel.patterns[1] = rootDef.typePatternGraph.addNewNode({pattern: '[]'}, {"vector-member": [member]});
400
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode({pattern: '{}'}, {"car": [member], "cdr": [rel.patterns[1]]});
401
- }; break;
402
- case "SNOC": {
403
- const member = rootDef.typePatternGraph.addNewNode();
404
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode({pattern: '[]'}, {"vector-member": [member]});
405
- rel.patterns[1] = rootDef.typePatternGraph.addNewNode({pattern: '{}'}, {"car": [member], "cdr": [rel.patterns[0]]});
406
- }; break;
407
- case "DIV": {
408
- const intId = rootDef.typePatternGraph.getTypeId('@int');
409
- rel.patterns[0] = rootDef.typePatternGraph.addNewNode({pattern: '[]'}, {"vector-member": [intId]});
410
- rel.patterns[1] = rootDef.typePatternGraph.addNewNode({pattern: '{}'}, {"div": [intId], "rem": [intId]});
411
- }; break;
412
- break;
413
- // TO DO
414
- case "FDIV":
415
- case "null":
416
- rel.patterns = [rootDef.typePatternGraph.addNewNode(), rootDef.typePatternGraph.addNewNode()];
417
- break;
418
- default:
419
- throw new Error(`No definition found for '${rel.ref}'`);
420
- }
421
- }
422
-
423
- // ==================================================================================
424
- // ----------------------------------------------------------------------------------
425
- // 1. Initialize the typePatternGraph and varRefs for each relation
426
-
427
- for (const relName in rels) {
428
- const rootDef = rels[relName];
429
- rootDef.typePatternGraph = new TypePatternGraph();
430
- rootDef.varRefs = []; // the list of references to non-builtin rels as pointers to AST nodes
431
- rootDef.patternVars = {};
432
- augment(rootDef.def, rootDef);
433
- delete rootDef.patternVars;
434
- }
435
-
436
-
437
- // 2. Compute DAG of strongly connected components in varRefs
438
- // A rel_1 -> rel_2 if rel1,varRefs contains a reference to {op: "ref", ref: rel_2}
439
-
440
- const graph = new Graph(
441
- // 1st argument: edges
442
- [].concat(...Object.keys(rels).map( relName =>
443
- rels[relName].varRefs.map( ({varName}) =>
444
- ({src: relName, dst: varName})))),
445
- // 2nd argument: vertices
446
- rels
447
- );
448
-
449
- const sccs_ = sccs(graph);
450
-
451
- const DAGnodes = sccs_.reduce ((nodes, scc) =>
452
- ({...nodes, [scc[0]]: {scc}}), {});
453
- const fromRelNameToDAGnode = Object.keys(DAGnodes).reduce((map, node) =>
454
- DAGnodes[node].scc.reduce((map, relName) => ({...map, [relName]: node}), map), {});
455
- const DAGedges = [].concat(
456
- ...Object.keys(rels).map( x =>
457
- rels[x].varRefs.map(({ varName }) =>
458
- ({src: fromRelNameToDAGnode[x], dst: fromRelNameToDAGnode[varName]})
459
- ) // don't forget to remove loops
460
- .filter(({src, dst}) => src !== dst )
461
- )
462
- );
463
- const DAG = new Graph(DAGedges, DAGnodes);
464
-
465
- // 3. Topological sort of the DAG
466
-
467
- const sccInOrder = topoOrder(DAG).reverse();
468
-
469
- // 4. For each strongly connected component C in a bottom-up order
470
-
471
- // we will also generate the canonical representation of the relations in C and replace
472
- // the name to the relation by the hash of the canonical representation
473
-
474
- // console.log("- SCC in order", sccInOrder);
475
-
476
- for (const scc of sccInOrder) {
477
-
478
- const maxNumberOfIterations = 10;
479
-
480
- for (let iteration = 1; iteration <= maxNumberOfIterations; iteration++) {
481
-
482
- // console.log(`-- Iteration ${iteration}/${maxNumberOfIterations} for SCC: { ${DAGnodes[scc].scc} }`);
483
- // 4.1 For every r in C, compute the new typePatternGraph of r, i.e.:
484
-
485
- let before = JSON.stringify(DAGnodes[scc].scc.map( relName => {
486
- const relDef = rels[relName];
487
- // console.log("-----------------------------------");
488
- // console.log(relDefToString(relDef));
489
- rels[relName] = compactRel(relDef,relName);
490
- // console.log(relDefToString(rels[relName]));
491
- return relDefToString(rels[relName]);
492
- }));
493
-
494
- let after = JSON.stringify(DAGnodes[scc].scc.map( relName => {
495
- const relDef = compactRel(rels[relName],relName);
496
- for (let i = 0; i < relDef.varRefs.length; i++) {
497
- const start = new Date().getTime();
498
- let varRel = relDef.varRefs[i];
499
- let { varName } = varRel;
500
- try {
501
- let varRootDef = rels[varName];
502
- let varInputPatternId = varRootDef.typePatternGraph.find(varRootDef.def.patterns[0]);
503
- let varOutputPatternId = varRootDef.typePatternGraph.find(varRootDef.def.patterns[1]);
504
- let cloned = varRootDef.typePatternGraph.clone([varInputPatternId, varOutputPatternId], relDef.typePatternGraph);
505
- relDef.typePatternGraph.unify(`ref:input ${relName}(${varName})`, varRel.inputPatternId, cloned[varInputPatternId]);
506
- relDef.typePatternGraph.unify("ref:output", varRel.outputPatternId, cloned[varOutputPatternId]);
507
- } catch (e) {
508
- e.message =
509
- `Type Error in definition of '${relName}' at call to '${varName}': lines ${varRel.start?.line}:${varRel.start?.column}...${varRel.end?.line}:${varRel.end?.column}):
510
- - ${e.message}`;
511
- throw e;
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
- }
517
- }
518
- rels[relName] = compactRel(relDef,relName);
519
- return relDefToString(rels[relName]);
520
- }));
521
-
522
- if (before == after) {
523
- // console.log("SUCCESS!");
524
- break;
525
- }
526
- } // end of iteration loop
527
-
528
- DAGnodes[scc].scc.forEach( relName => {
529
- const relDef = rels[relName];
530
- const canonical = relDefToString(relDef);
531
- const h = hash(canonical);
532
- relAlias[relName] = h;
533
- });
534
-
535
- assignCanonicalNames(DAGnodes[scc].scc, rels, relAlias);
536
-
537
- }
538
- return relAlias;
539
- }
540
-
541
- export default { patterns };
542
- export { patterns };
543
-