Остання активність 1738868695

Версія 462fcc3641bc074a123fd85aba5c1f182636cd66

compiled_query.js Неформатований 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 Неформатований Playground
1function 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}
103