Последняя активность 1738868695

yumaikas's Avatar yumaikas ревизий этого фрагмента 1738868695. К ревизии

1 file changed, 42 insertions

query_compiler.js

@@ -1,3 +1,45 @@
1 + export class EnsureMap extends Map {
2 + ensureGet(key, value) {
3 + if (this.has(key)) {
4 + return this.get(key);
5 + }
6 + this.set(key, value);
7 + return value;
8 + }
9 +
10 + }
11 +
12 + export function PredicateMap() {
13 + let patIdx = 0;
14 + let predicateStore = new Map();
15 + let idxStore = new Map();
16 + return {
17 + entries() {
18 + return predicateStore.entries();
19 + },
20 + lookup(pattern) {
21 + return predicateStore.get(pattern);
22 + },
23 + indexOf(pattern) {
24 + return idxStore.get(pattern);
25 + },
26 + store(pattern, predicate) {
27 + if (!predicateStore.has(pattern)) {
28 + predicateStore.set(pattern, predicate);
29 + idxStore.set(pattern, patIdx);
30 + patIdx++;
31 + }
32 + },
33 + }
34 + }
35 +
36 + function generalizePattern(pattern) {
37 + let vars = [];
38 + let patt = pattern.map(x => /^\$/.test(x) ? (vars.push(x.slice(1)),'*') : x).join(" ");
39 + vars = vars.map(x => /\?$/.test(x) ? x.slice(0,-1) : x);
40 + return {vars:vars, patt:patt};
41 + }
42 +
1 43 function compileRule(ruleTokens, predicates) {
2 44 // TODO: compile condiitions into predicates (if they don't match an existing predicate)
3 45 // and check predicates for non-standard cost models

yumaikas's Avatar yumaikas ревизий этого фрагмента 1738868646. К ревизии

1 file changed, 102 insertions

query_compiler.js(файл создан)

@@ -0,0 +1,102 @@
1 + function compileRule(ruleTokens, predicates) {
2 + // TODO: compile condiitions into predicates (if they don't match an existing predicate)
3 + // and check predicates for non-standard cost models
4 + // (port with custom costs, constant counters, etc)
5 + let rule = {
6 + predicateIds: [],
7 + predicates: [],
8 + queryPlan: null,
9 + predicateNames: new Map(),
10 + consequenceFn: null,
11 + usedVars: new Set(),
12 + };
13 +
14 + for (let c of ruleTokens.condition) {
15 + let { patt: predKey, vars: pattVars } = generalizePattern(c);
16 + pattVars.forEach((pv) => rule.usedVars.add(pv));
17 +
18 +
19 + if (predicates.lookup(predKey)) {
20 + // rule.predicateNames.set(predKey, n);
21 + rule.predicateIds.push(predicates.indexOf(predKey));
22 + } else {
23 + console.log("NEW");
24 + let { name: n, code: predFn } = makeBasicPatternPredicate(c);
25 + rule.predicateNames.set(predKey, n);
26 + predicates.store(predKey, { code: predFn, vars: pattVars });
27 + rule.predicateIds.push(predicates.indexOf(predKey));
28 + }
29 + rule.predicates.push({
30 + idx: predicates.indexOf(predKey),
31 + name: rule.predicateNames.get(predKey),
32 + pred: predicates.lookup(predKey),
33 + varsForPred: pattVars,
34 + })
35 + }
36 + console.log(["XXX", rule.predicateNames]);
37 +
38 + let hyperEdges = new EnsureMap();
39 +
40 + for (let predicate of rule.predicates) {
41 + for (let v of predicate.varsForPred) {
42 + hyperEdges.ensureGet(v, new Set()).add(predicate);
43 + }
44 + }
45 +
46 + // console.log(hyperEdges);
47 +
48 + let matchObjParts = ["let match = {\n"];
49 + let plan_fns = [];
50 + for (let predicate of rule.predicates) {
51 + matchObjParts.push(predicate.name, ": false,\n");
52 +
53 + let plan_fn_parts= ["plans.", slug(predicate.name) ," = function ", "(match, patterns) {\n"];
54 +
55 + plan_fn_parts.push("\tfor(let ");;
56 + if (predicate.varsForPred.length > 0) {
57 + plan_fn_parts.push("[");
58 + for (let v of predicate.varsForPred) {
59 + plan_fn_parts.push(slug(v), ", ");
60 + }
61 + plan_fn_parts.pop();
62 + plan_fn_parts.push("] ");
63 + } else {
64 + plan_fn_parts.push("_ ");
65 + }
66 + plan_fn_parts.push("of patterns.", slug(predicate.name), ") {\n");
67 + plan_fn_parts.push("\t\tmatch.state.", slug(predicate.name), " = true;\n");
68 +
69 + for (let v of predicate.varsForPred) {
70 + plan_fn_parts.push("\t\tmatch.vars.", slug(v), " = ", slug(v), ";\n");
71 + }
72 +
73 + let seenPredicates = new Set();
74 + plan_fn_parts.push("\t\tif (\n");
75 + let shouldPop = false;
76 + for (let v of predicate.varsForPred) {
77 + for (let otherPred of hyperEdges.get(v)) {
78 + // console.log({ a: otherPred.idx, b: predicate.idx });
79 + if (otherPred.idx !== predicate.idx && !seenPredicates.has(otherPred.idx)) {
80 + shouldPop = true;
81 + seenPredicates.add(otherPred.idx);
82 + // TODO thing
83 + plan_fn_parts.push(
84 + "\t\t\tmatch.state.", slug(otherPred.name),
85 + " || plans.", slug(otherPred.name), "(match, patterns)", " && \n" );
86 + }
87 + }
88 + // console.log("---");
89 + }
90 + if (shouldPop) {
91 + plan_fn_parts.pop();
92 + plan_fn_parts.push("\n");
93 + }
94 + plan_fn_parts.push("\n\t\t) {\n\t\t\t return true; \n\t\t} else { return false; }\n");
95 + plan_fn_parts.push("\t}\n}\n\n\n");
96 +
97 + plan_fns.push(plan_fn_parts.join(""));
98 + }
99 + rule.queryPlan = plan_fns;
100 +
101 + return rule;
102 + }

yumaikas's Avatar yumaikas ревизий этого фрагмента 1738868601. К ревизии

1 file changed, 10 insertions, 8 deletions

compiled_query.js

@@ -17,7 +17,7 @@ plans._lightning_struck_x_y = function (match, patterns) {
17 17 match.vars._x = _x;
18 18 match.vars._y = _y;
19 19 if (
20 - match.state._something_is_at_x_y || plans._something_is_at_x_y(match, patterns) &&
20 + match.state._something_is_at_x_y || plans._something_is_at_x_y(match, patterns)
21 21
22 22 ) {
23 23 return true;
@@ -35,8 +35,9 @@ plans._something_is_at_x_y = function (match, patterns) {
35 35 match.vars._x = _x;
36 36 match.vars._y = _y;
37 37 if (
38 - match.state._something_has_inventory_inventory || plans._something_has_inventory_inventory(match, patterns) &&
39 - match.state._lightning_struck_x_y || plans._lightning_struck_x_y(match, patterns) &&
38 + match.state._something_has_inventory_inventory || plans._something_has_inventory_inventory(match, p
39 + atterns) &&
40 + match.state._lightning_struck_x_y || plans._lightning_struck_x_y(match, patterns)
40 41
41 42 ) {
42 43 return true;
@@ -54,7 +55,7 @@ plans._something_has_inventory_inventory = function (match, patterns) {
54 55 match.vars._inventory = _inventory;
55 56 if (
56 57 match.state._something_is_at_x_y || plans._something_is_at_x_y(match, patterns) &&
57 - match.state._inventory_has_item_item || plans._inventory_has_item_item(match, patterns) &&
58 + match.state._inventory_has_item_item || plans._inventory_has_item_item(match, patterns)
58 59
59 60 ) {
60 61 return true;
@@ -71,8 +72,9 @@ plans._inventory_has_item_item = function (match, patterns) {
71 72 match.vars._inventory = _inventory;
72 73 match.vars._item = _item;
73 74 if (
74 - match.state._something_has_inventory_inventory || plans._something_has_inventory_inventory(match, patterns) &&
75 - match.state._item_is_class || plans._item_is_class(match, patterns) &&
75 + match.state._something_has_inventory_inventory || plans._something_has_inventory_inventory(match, p
76 + atterns) &&
77 + match.state._item_is_class || plans._item_is_class(match, patterns)
76 78
77 79 ) {
78 80 return true;
@@ -90,7 +92,7 @@ plans._item_is_class = function (match, patterns) {
90 92 match.vars._class = _class;
91 93 if (
92 94 match.state._inventory_has_item_item || plans._inventory_has_item_item(match, patterns) &&
93 - match.state._class_is_conductive || plans._class_is_conductive(match, patterns) &&
95 + match.state._class_is_conductive || plans._class_is_conductive(match, patterns)
94 96
95 97 ) {
96 98 return true;
@@ -106,7 +108,7 @@ plans._class_is_conductive = function (match, patterns) {
106 108 match.state._class_is_conductive = true;
107 109 match.vars._class = _class;
108 110 if (
109 - match.state._item_is_class || plans._item_is_class(match, patterns) &&
111 + match.state._item_is_class || plans._item_is_class(match, patterns)
110 112
111 113 ) {
112 114 return true;

yumaikas's Avatar yumaikas ревизий этого фрагмента 1738868383. К ревизии

1 file changed, 7 insertions

compiled_query.js

@@ -22,6 +22,7 @@ plans._lightning_struck_x_y = function (match, patterns) {
22 22 ) {
23 23 return true;
24 24 } else { return false; }
25 + }
25 26 }
26 27
27 28
@@ -40,6 +41,7 @@ plans._something_is_at_x_y = function (match, patterns) {
40 41 ) {
41 42 return true;
42 43 } else { return false; }
44 + }
43 45 }
44 46
45 47
@@ -57,6 +59,7 @@ plans._something_has_inventory_inventory = function (match, patterns) {
57 59 ) {
58 60 return true;
59 61 } else { return false; }
62 + }
60 63 }
61 64
62 65
@@ -74,6 +77,7 @@ plans._inventory_has_item_item = function (match, patterns) {
74 77 ) {
75 78 return true;
76 79 } else { return false; }
80 + }
77 81 }
78 82
79 83
@@ -91,6 +95,7 @@ plans._item_is_class = function (match, patterns) {
91 95 ) {
92 96 return true;
93 97 } else { return false; }
98 + }
94 99 }
95 100
96 101
@@ -106,4 +111,6 @@ plans._class_is_conductive = function (match, patterns) {
106 111 ) {
107 112 return true;
108 113 } else { return false; }
114 + }
109 115 }
116 +

yumaikas's Avatar yumaikas ревизий этого фрагмента 1738868247. К ревизии

1 file changed, 109 insertions

compiled_query.js(файл создан)

@@ -0,0 +1,109 @@
1 + /*
2 + |
3 + lightning struck $x $y
4 + , $something is at $x $y?
5 + , $something has inventory $inventory?
6 + , $inventory has item $item?
7 + , $item is $class?
8 + , $class is conductive?
9 + |
10 + $something is struck by lightning
11 +
12 + */
13 +
14 + plans._lightning_struck_x_y = function (match, patterns) {
15 + for(let [_x, _y] of patterns._lightning_struck_x_y) {
16 + match.state._lightning_struck_x_y = true;
17 + match.vars._x = _x;
18 + match.vars._y = _y;
19 + if (
20 + match.state._something_is_at_x_y || plans._something_is_at_x_y(match, patterns) &&
21 +
22 + ) {
23 + return true;
24 + } else { return false; }
25 + }
26 +
27 +
28 +
29 +
30 + plans._something_is_at_x_y = function (match, patterns) {
31 + for(let [_something, _x, _y] of patterns._something_is_at_x_y) {
32 + match.state._something_is_at_x_y = true;
33 + match.vars._something = _something;
34 + match.vars._x = _x;
35 + match.vars._y = _y;
36 + if (
37 + match.state._something_has_inventory_inventory || plans._something_has_inventory_inventory(match, patterns) &&
38 + match.state._lightning_struck_x_y || plans._lightning_struck_x_y(match, patterns) &&
39 +
40 + ) {
41 + return true;
42 + } else { return false; }
43 + }
44 +
45 +
46 +
47 +
48 + plans._something_has_inventory_inventory = function (match, patterns) {
49 + for(let [_something, _inventory] of patterns._something_has_inventory_inventory) {
50 + match.state._something_has_inventory_inventory = true;
51 + match.vars._something = _something;
52 + match.vars._inventory = _inventory;
53 + if (
54 + match.state._something_is_at_x_y || plans._something_is_at_x_y(match, patterns) &&
55 + match.state._inventory_has_item_item || plans._inventory_has_item_item(match, patterns) &&
56 +
57 + ) {
58 + return true;
59 + } else { return false; }
60 + }
61 +
62 +
63 +
64 +
65 + plans._inventory_has_item_item = function (match, patterns) {
66 + for(let [_inventory, _item] of patterns._inventory_has_item_item) {
67 + match.state._inventory_has_item_item = true;
68 + match.vars._inventory = _inventory;
69 + match.vars._item = _item;
70 + if (
71 + match.state._something_has_inventory_inventory || plans._something_has_inventory_inventory(match, patterns) &&
72 + match.state._item_is_class || plans._item_is_class(match, patterns) &&
73 +
74 + ) {
75 + return true;
76 + } else { return false; }
77 + }
78 +
79 +
80 +
81 +
82 + plans._item_is_class = function (match, patterns) {
83 + for(let [_item, _class] of patterns._item_is_class) {
84 + match.state._item_is_class = true;
85 + match.vars._item = _item;
86 + match.vars._class = _class;
87 + if (
88 + match.state._inventory_has_item_item || plans._inventory_has_item_item(match, patterns) &&
89 + match.state._class_is_conductive || plans._class_is_conductive(match, patterns) &&
90 +
91 + ) {
92 + return true;
93 + } else { return false; }
94 + }
95 +
96 +
97 +
98 +
99 + plans._class_is_conductive = function (match, patterns) {
100 + for(let [_class] of patterns._class_is_conductive) {
101 + match.state._class_is_conductive = true;
102 + match.vars._class = _class;
103 + if (
104 + match.state._item_is_class || plans._item_is_class(match, patterns) &&
105 +
106 + ) {
107 + return true;
108 + } else { return false; }
109 + }
Новее Позже