@fraczak/k 4.0.3 → 5.0.0
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/BIG_PICTURE.md +28 -21
- package/README.md +158 -154
- package/TODO.md +18 -0
- package/TYPING.md +2 -2
- package/export.mjs +177 -0
- package/index.mjs +3 -15
- package/k-repl.cast +1913 -0
- package/k.cast +618 -0
- package/package.json +1 -1
- package/patterns.mjs +22 -8
- package/pretty.mjs +26 -41
- package/repl.mjs +47 -28
- package/run.mjs +5 -1
- package/TYPES.md +0 -32
- package/demo.cast +0 -1772
- package/demo.gif +0 -0
- package/demo2.cast +0 -1705
- package/demo_optimized.gif +0 -0
- package/sc.py +0 -25
package/export.mjs
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
|
|
2
|
+
import { prettyRel, patterns2filters } from "./pretty.mjs";
|
|
3
|
+
import { hash } from "./hash.mjs";
|
|
4
|
+
|
|
5
|
+
function simplifyRel(relDef) {
|
|
6
|
+
// remove filters and codes
|
|
7
|
+
const prune = (rel) => {
|
|
8
|
+
const newRel = {...rel};
|
|
9
|
+
switch (rel.op) {
|
|
10
|
+
case "product":
|
|
11
|
+
newRel.product = rel.product.map(({label, exp}) => ({label, exp: prune(exp)}));
|
|
12
|
+
break;
|
|
13
|
+
case "union":
|
|
14
|
+
newRel.union = rel.union.map(exp => prune(exp));
|
|
15
|
+
break;
|
|
16
|
+
case "comp":
|
|
17
|
+
newRel.comp = rel.comp.reduce((list, exp) => {
|
|
18
|
+
const newExp = prune(exp);
|
|
19
|
+
if (newExp.op != "identity")
|
|
20
|
+
list.push(newExp);
|
|
21
|
+
return list;
|
|
22
|
+
},[]);
|
|
23
|
+
if (newRel.comp.length == 0)
|
|
24
|
+
newRel.op = "identity";
|
|
25
|
+
break;
|
|
26
|
+
case "vector":
|
|
27
|
+
newRel.vector = rel.vector.map(exp => prune(exp));
|
|
28
|
+
break;
|
|
29
|
+
case "caret":
|
|
30
|
+
newRel.caret = prune(rel.caret);
|
|
31
|
+
break;
|
|
32
|
+
case 'code':
|
|
33
|
+
case 'filter':
|
|
34
|
+
newRel.op = "identity";
|
|
35
|
+
default:
|
|
36
|
+
break;
|
|
37
|
+
};
|
|
38
|
+
return newRel;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const rel = relDef.def;
|
|
42
|
+
const filters = patterns2filters(relDef.typePatternGraph, ...rel.patterns).map( filter =>
|
|
43
|
+
({op: "filter", filter: filter}));
|
|
44
|
+
const newRel = prune(rel);
|
|
45
|
+
let resultRel = {...newRel};
|
|
46
|
+
if (newRel.op == "identity")
|
|
47
|
+
return filters[0];
|
|
48
|
+
|
|
49
|
+
if (newRel.op == "comp") {
|
|
50
|
+
resultRel.comp = [ filters[0], ...newRel.comp, filters[1] ];
|
|
51
|
+
return resultRel;
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
op: "comp",
|
|
55
|
+
comp: [filters[0], newRel, filters[1] ]
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
function theID(alias, rel, scc, name) {
|
|
61
|
+
const sccNames = new Set(scc);
|
|
62
|
+
const auxNames = {[name]: "X0"};
|
|
63
|
+
// rename and remove filters and codes
|
|
64
|
+
const reNameX = (rel) => {
|
|
65
|
+
const newRel = {...rel};
|
|
66
|
+
switch (rel.op) {
|
|
67
|
+
case "product":
|
|
68
|
+
newRel.product = rel.product.map(({label, exp}) => ({label, exp: reNameX(exp)}));
|
|
69
|
+
break;
|
|
70
|
+
case "union":
|
|
71
|
+
newRel.union = rel.union.map(exp => reNameX(exp));
|
|
72
|
+
break;
|
|
73
|
+
case "comp":
|
|
74
|
+
newRel.comp = rel.comp.map(exp => reNameX(exp));
|
|
75
|
+
break;
|
|
76
|
+
case "vector":
|
|
77
|
+
newRel.vector = rel.vector.map(exp => reNameX(exp));
|
|
78
|
+
break;
|
|
79
|
+
case "caret":
|
|
80
|
+
newRel.caret = reNameX(rel.caret);
|
|
81
|
+
break;
|
|
82
|
+
case "ref": {
|
|
83
|
+
const n = rel.ref;
|
|
84
|
+
if (alias[n] != undefined) {
|
|
85
|
+
newRel.ref = alias[n];
|
|
86
|
+
} else if (auxNames[n] != undefined) {
|
|
87
|
+
newRel.ref = auxNames[n];
|
|
88
|
+
} else if (sccNames.has(n)) {
|
|
89
|
+
auxNames[n] = `X${Object.keys(auxNames).length}`;
|
|
90
|
+
newRel.ref = auxNames[n];
|
|
91
|
+
};
|
|
92
|
+
}; break;
|
|
93
|
+
default:
|
|
94
|
+
break;
|
|
95
|
+
};
|
|
96
|
+
return newRel;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const newRel = reNameX(rel);
|
|
100
|
+
const resultRelStr = prettyRel(newRel);
|
|
101
|
+
// console.log(` ${name} = ${resultRelStr}`);
|
|
102
|
+
const newName = hash(resultRelStr);
|
|
103
|
+
return newName;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
function assignCanonicalNames(scc, rels, relAlias) {
|
|
107
|
+
const newAlias = scc.reduce( (newAlias,relName) => {
|
|
108
|
+
const relDef = rels[relName];
|
|
109
|
+
if (relDef.def.op == "ref" && rels[relDef.def.ref] != undefined) {
|
|
110
|
+
// inlining if direct alias to a non built-in relation
|
|
111
|
+
relDef.simplified = simplifyRel(rels[relDef.def.ref]);
|
|
112
|
+
} else {
|
|
113
|
+
relDef.simplified = simplifyRel(relDef);
|
|
114
|
+
}
|
|
115
|
+
newAlias[relName] = theID(relAlias, relDef.simplified, scc, relName);
|
|
116
|
+
return newAlias;
|
|
117
|
+
}, {});
|
|
118
|
+
const newNames = [...new Set(Object.values(newAlias))];
|
|
119
|
+
// console.log(` --- SCC: {${scc.join(",")}} ---`);
|
|
120
|
+
|
|
121
|
+
const sccCanonicalName = newNames.sort().join(":");
|
|
122
|
+
for (let relName in newAlias) {
|
|
123
|
+
if (newNames.length > 1)
|
|
124
|
+
relAlias[relName] = hash(newAlias[relName]+":"+sccCanonicalName);
|
|
125
|
+
else
|
|
126
|
+
relAlias[relName] = newAlias[relName];
|
|
127
|
+
// console.log(` ${relName} -> ${relAlias[relName]}`);
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function exportRelation(rels, alias, name) {
|
|
132
|
+
const queue = [name];
|
|
133
|
+
const inQueue = { [name]: true };
|
|
134
|
+
const result = {};
|
|
135
|
+
const reName = (rel) => {
|
|
136
|
+
const newRel = {...rel};
|
|
137
|
+
switch (rel.op) {
|
|
138
|
+
case "product":
|
|
139
|
+
newRel.product = rel.product.map(({label, exp}) => ({label, exp: reName(exp)}));
|
|
140
|
+
break;
|
|
141
|
+
case "union":
|
|
142
|
+
newRel.union = rel.union.map(exp => reName(exp));
|
|
143
|
+
break;
|
|
144
|
+
case "comp":
|
|
145
|
+
newRel.comp = rel.comp.map(exp => reName(exp));
|
|
146
|
+
break;
|
|
147
|
+
case "vector":
|
|
148
|
+
newRel.vector = rel.vector.map(exp => reName(exp));
|
|
149
|
+
break;
|
|
150
|
+
case "caret":
|
|
151
|
+
newRel.caret = reName(rel.caret);
|
|
152
|
+
break;
|
|
153
|
+
case "ref": {
|
|
154
|
+
const n = rel.ref;
|
|
155
|
+
if (alias[n] == undefined) // built-in
|
|
156
|
+
return newRel;
|
|
157
|
+
newRel.ref = alias[n];
|
|
158
|
+
if (! inQueue[n]) {
|
|
159
|
+
inQueue[n] = true;
|
|
160
|
+
queue.push(n);
|
|
161
|
+
}
|
|
162
|
+
}; break;
|
|
163
|
+
default:
|
|
164
|
+
break;
|
|
165
|
+
};
|
|
166
|
+
return newRel;
|
|
167
|
+
};
|
|
168
|
+
while (queue.length > 0 ) {
|
|
169
|
+
const name = queue.shift();
|
|
170
|
+
const canonicalName = alias[name];
|
|
171
|
+
result[canonicalName] = {...rels[name], def: reName(rels[name].def), name: name};
|
|
172
|
+
}
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export default { assignCanonicalNames, exportRelation };
|
|
177
|
+
export { assignCanonicalNames, exportRelation };
|
package/index.mjs
CHANGED
|
@@ -4,19 +4,7 @@ import run from "./run.mjs";
|
|
|
4
4
|
import t from "./codes.mjs";
|
|
5
5
|
|
|
6
6
|
function compile(script) {
|
|
7
|
-
|
|
8
|
-
run.defs = annotate(script);
|
|
9
|
-
} catch (e) {
|
|
10
|
-
console.error(e.message);
|
|
11
|
-
console.error("WARN: Recompiling without type reconciliation due to the type error above.");
|
|
12
|
-
const { defs, exp } = parse(script);
|
|
13
|
-
const { codes, representatives } = t.finalize(defs.codes);
|
|
14
|
-
run.defs = {
|
|
15
|
-
rels: {...defs.rels, "__main__": {def: exp}},
|
|
16
|
-
codes, representatives
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
}
|
|
7
|
+
run.defs = annotate(script);
|
|
20
8
|
return run.bind(null, run.defs.rels.__main__.def);
|
|
21
9
|
}
|
|
22
10
|
|
|
@@ -35,9 +23,9 @@ function annotate(script) {
|
|
|
35
23
|
const representatives = t.register(defs.codes);
|
|
36
24
|
const rels = {...defs.rels, "__main__": {def: exp}};
|
|
37
25
|
|
|
38
|
-
patterns(representatives, rels);
|
|
26
|
+
const relAlias = patterns(representatives, rels);
|
|
39
27
|
|
|
40
|
-
return {rels, representatives}
|
|
28
|
+
return {rels, representatives, relAlias};
|
|
41
29
|
}
|
|
42
30
|
annotate.doc = "Annotate all the script expressions with patterns";
|
|
43
31
|
|