Ostatnio aktywny 1738868695

Rewizja 5ee71533fa33fcf8e6fbfef7edec8bf93ec407a6

compiled_query.js Surowy Playground
1/*
2|
3lightning 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
14plans._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
31plans._something_is_at_x_y = function (match, patterns) {
32 for(let [_something, _x, _y] of patterns._something_is_at_x_y) {
33 match.state._something_is_at_x_y = true;
34 match.vars._something = _something;
35 match.vars._x = _x;
36 match.vars._y = _y;
37 if (
38 match.state._something_has_inventory_inventory || plans._something_has_inventory_inventory(match, p
39atterns) &&
40 match.state._lightning_struck_x_y || plans._lightning_struck_x_y(match, patterns)
41
42 ) {
43 return true;
44 } else { return false; }
45 }
46}
47
48
49
50
51plans._something_has_inventory_inventory = function (match, patterns) {
52 for(let [_something, _inventory] of patterns._something_has_inventory_inventory) {
53 match.state._something_has_inventory_inventory = true;
54 match.vars._something = _something;
55 match.vars._inventory = _inventory;
56 if (
57 match.state._something_is_at_x_y || plans._something_is_at_x_y(match, patterns) &&
58 match.state._inventory_has_item_item || plans._inventory_has_item_item(match, patterns)
59
60 ) {
61 return true;
62 } else { return false; }
63 }
64}
65
66
67
68
69plans._inventory_has_item_item = function (match, patterns) {
70 for(let [_inventory, _item] of patterns._inventory_has_item_item) {
71 match.state._inventory_has_item_item = true;
72 match.vars._inventory = _inventory;
73 match.vars._item = _item;
74 if (
75 match.state._something_has_inventory_inventory || plans._something_has_inventory_inventory(match, p
76atterns) &&
77 match.state._item_is_class || plans._item_is_class(match, patterns)
78
79 ) {
80 return true;
81 } else { return false; }
82 }
83}
84
85
86
87
88plans._item_is_class = function (match, patterns) {
89 for(let [_item, _class] of patterns._item_is_class) {
90 match.state._item_is_class = true;
91 match.vars._item = _item;
92 match.vars._class = _class;
93 if (
94 match.state._inventory_has_item_item || plans._inventory_has_item_item(match, patterns) &&
95 match.state._class_is_conductive || plans._class_is_conductive(match, patterns)
96
97 ) {
98 return true;
99 } else { return false; }
100 }
101}
102
103
104
105
106plans._class_is_conductive = function (match, patterns) {
107 for(let [_class] of patterns._class_is_conductive) {
108 match.state._class_is_conductive = true;
109 match.vars._class = _class;
110 if (
111 match.state._item_is_class || plans._item_is_class(match, patterns)
112
113 ) {
114 return true;
115 } else { return false; }
116 }
117}
118
119
query_compiler.js Surowy Playground
1export 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
12export 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
36function 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
43function compileRule(ruleTokens, predicates) {
44 // TODO: compile condiitions into predicates (if they don't match an existing predicate)
45 // and check predicates for non-standard cost models
46 // (port with custom costs, constant counters, etc)
47 let rule = {
48 predicateIds: [],
49 predicates: [],
50 queryPlan: null,
51 predicateNames: new Map(),
52 consequenceFn: null,
53 usedVars: new Set(),
54 };
55
56 for (let c of ruleTokens.condition) {
57 let { patt: predKey, vars: pattVars } = generalizePattern(c);
58 pattVars.forEach((pv) => rule.usedVars.add(pv));
59
60
61 if (predicates.lookup(predKey)) {
62 // rule.predicateNames.set(predKey, n);
63 rule.predicateIds.push(predicates.indexOf(predKey));
64 } else {
65 console.log("NEW");
66 let { name: n, code: predFn } = makeBasicPatternPredicate(c);
67 rule.predicateNames.set(predKey, n);
68 predicates.store(predKey, { code: predFn, vars: pattVars });
69 rule.predicateIds.push(predicates.indexOf(predKey));
70 }
71 rule.predicates.push({
72 idx: predicates.indexOf(predKey),
73 name: rule.predicateNames.get(predKey),
74 pred: predicates.lookup(predKey),
75 varsForPred: pattVars,
76 })
77 }
78 console.log(["XXX", rule.predicateNames]);
79
80 let hyperEdges = new EnsureMap();
81
82 for (let predicate of rule.predicates) {
83 for (let v of predicate.varsForPred) {
84 hyperEdges.ensureGet(v, new Set()).add(predicate);
85 }
86 }
87
88 // console.log(hyperEdges);
89
90 let matchObjParts = ["let match = {\n"];
91 let plan_fns = [];
92 for (let predicate of rule.predicates) {
93 matchObjParts.push(predicate.name, ": false,\n");
94
95 let plan_fn_parts= ["plans.", slug(predicate.name) ," = function ", "(match, patterns) {\n"];
96
97 plan_fn_parts.push("\tfor(let ");;
98 if (predicate.varsForPred.length > 0) {
99 plan_fn_parts.push("[");
100 for (let v of predicate.varsForPred) {
101 plan_fn_parts.push(slug(v), ", ");
102 }
103 plan_fn_parts.pop();
104 plan_fn_parts.push("] ");
105 } else {
106 plan_fn_parts.push("_ ");
107 }
108 plan_fn_parts.push("of patterns.", slug(predicate.name), ") {\n");
109 plan_fn_parts.push("\t\tmatch.state.", slug(predicate.name), " = true;\n");
110
111 for (let v of predicate.varsForPred) {
112 plan_fn_parts.push("\t\tmatch.vars.", slug(v), " = ", slug(v), ";\n");
113 }
114
115 let seenPredicates = new Set();
116 plan_fn_parts.push("\t\tif (\n");
117 let shouldPop = false;
118 for (let v of predicate.varsForPred) {
119 for (let otherPred of hyperEdges.get(v)) {
120 // console.log({ a: otherPred.idx, b: predicate.idx });
121 if (otherPred.idx !== predicate.idx && !seenPredicates.has(otherPred.idx)) {
122 shouldPop = true;
123 seenPredicates.add(otherPred.idx);
124 // TODO thing
125 plan_fn_parts.push(
126 "\t\t\tmatch.state.", slug(otherPred.name),
127 " || plans.", slug(otherPred.name), "(match, patterns)", " && \n" );
128 }
129 }
130 // console.log("---");
131 }
132 if (shouldPop) {
133 plan_fn_parts.pop();
134 plan_fn_parts.push("\n");
135 }
136 plan_fn_parts.push("\n\t\t) {\n\t\t\t return true; \n\t\t} else { return false; }\n");
137 plan_fn_parts.push("\t}\n}\n\n\n");
138
139 plan_fns.push(plan_fn_parts.join(""));
140 }
141 rule.queryPlan = plan_fns;
142
143 return rule;
144}
145