@suss/datalog 0.31.1 → 0.32.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/dist/index.cjs +102 -81
- package/dist/index.js +102 -81
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -77,6 +77,7 @@ function deriveOnDemand(rules, complete) {
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
const derives = (relation) => rulesByHead.has(relation);
|
|
80
|
+
const labels = labelColumns(rules, derives);
|
|
80
81
|
const asked = /* @__PURE__ */ new Map();
|
|
81
82
|
const pending = [];
|
|
82
83
|
const want = (adorned) => {
|
|
@@ -98,7 +99,7 @@ function deriveOnDemand(rules, complete) {
|
|
|
98
99
|
while (pending.length > 0) {
|
|
99
100
|
const adorned = pending.pop();
|
|
100
101
|
for (const written of rulesByHead.get(adorned.relation) ?? []) {
|
|
101
|
-
const r = boundFirst(written, adorned.adornment);
|
|
102
|
+
const r = boundFirst(written, adorned.adornment, labels);
|
|
102
103
|
const adornments = bodyAdornments(r, adorned.adornment, derives);
|
|
103
104
|
r.body.forEach((literal, at) => {
|
|
104
105
|
const adornment = adornments[at];
|
|
@@ -141,7 +142,7 @@ function deriveOnDemand(rules, complete) {
|
|
|
141
142
|
});
|
|
142
143
|
}
|
|
143
144
|
for (const written of rulesByHead.get(adorned.relation) ?? []) {
|
|
144
|
-
const r = boundFirst(written, adorned.adornment);
|
|
145
|
+
const r = boundFirst(written, adorned.adornment, labels);
|
|
145
146
|
const guard = anyBound(adorned.adornment) ? [
|
|
146
147
|
positiveLiteral(
|
|
147
148
|
demandOn(adorned.relation, adorned.adornment),
|
|
@@ -182,7 +183,30 @@ function deriveOnDemand(rules, complete) {
|
|
|
182
183
|
return { rules: rewritten, demandDriven: [...demandDriven], demands };
|
|
183
184
|
}
|
|
184
185
|
var sameLiteral = (premises, conclusion) => premises.length === 1 && JSON.stringify(premises[0]) === JSON.stringify(conclusion);
|
|
185
|
-
function
|
|
186
|
+
function labelColumns(rules, derives) {
|
|
187
|
+
const labels = /* @__PURE__ */ new Map();
|
|
188
|
+
const note = ({
|
|
189
|
+
relation,
|
|
190
|
+
terms
|
|
191
|
+
}) => {
|
|
192
|
+
if (!derives(relation)) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
terms.forEach((term, column) => {
|
|
196
|
+
if (term.type === "constant") {
|
|
197
|
+
const columns = labels.get(relation) ?? /* @__PURE__ */ new Set();
|
|
198
|
+
columns.add(column);
|
|
199
|
+
labels.set(relation, columns);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
};
|
|
203
|
+
for (const r of rules) {
|
|
204
|
+
note(r.head);
|
|
205
|
+
r.body.forEach(note);
|
|
206
|
+
}
|
|
207
|
+
return labels;
|
|
208
|
+
}
|
|
209
|
+
function boundFirst(r, headAdornment, labels) {
|
|
186
210
|
const bound = /* @__PURE__ */ new Set();
|
|
187
211
|
r.head.terms.forEach((term, column) => {
|
|
188
212
|
if (headAdornment[column] && term.type === "variable") {
|
|
@@ -190,7 +214,7 @@ function boundFirst(r, headAdornment) {
|
|
|
190
214
|
}
|
|
191
215
|
});
|
|
192
216
|
const boundColumns = (literal) => literal.terms.filter(
|
|
193
|
-
(term) => term.type === "constant" || bound.has(term.name)
|
|
217
|
+
(term, column) => !labels.get(literal.relation)?.has(column) && (term.type === "constant" || bound.has(term.name))
|
|
194
218
|
).length;
|
|
195
219
|
const remaining = [...r.body];
|
|
196
220
|
const body = [];
|
|
@@ -838,65 +862,18 @@ function headTuple(head, bindings) {
|
|
|
838
862
|
return bound;
|
|
839
863
|
});
|
|
840
864
|
}
|
|
841
|
-
var
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
const known = byDelta.get(deltaIndex);
|
|
850
|
-
if (known !== void 0) {
|
|
851
|
-
return known;
|
|
852
|
-
}
|
|
853
|
-
const positives = r.body.map((literal, index) => literal.negated ? -1 : index).filter((index) => index !== -1);
|
|
854
|
-
const deltaAt = positives[deltaIndex] ?? -1;
|
|
855
|
-
const computed = { deltaAt, order: planBodyOrder(r, deltaAt) };
|
|
856
|
-
byDelta.set(deltaIndex, computed);
|
|
857
|
-
return computed;
|
|
858
|
-
}
|
|
859
|
-
function planBodyOrder(r, deltaAt) {
|
|
860
|
-
const natural = r.body.map((_, i) => i);
|
|
861
|
-
if (deltaAt <= 0) {
|
|
862
|
-
return natural;
|
|
863
|
-
}
|
|
864
|
-
const taken = r.body.map(() => false);
|
|
865
|
-
const bound = /* @__PURE__ */ new Set();
|
|
866
|
-
const order = [];
|
|
867
|
-
const take = (index) => {
|
|
868
|
-
taken[index] = true;
|
|
869
|
-
order.push(index);
|
|
870
|
-
for (const name of variablesOf(r.body[index])) {
|
|
871
|
-
bound.add(name);
|
|
872
|
-
}
|
|
873
|
-
};
|
|
874
|
-
const firstWhere = (want) => natural.find((index) => !taken[index] && want(index)) ?? -1;
|
|
875
|
-
const nextLiteral = () => {
|
|
876
|
-
const ready = firstWhere(
|
|
877
|
-
(i) => r.body[i].negated && variablesOf(r.body[i]).every((name) => bound.has(name))
|
|
878
|
-
);
|
|
879
|
-
if (ready !== -1) {
|
|
880
|
-
return ready;
|
|
881
|
-
}
|
|
882
|
-
const joined = firstWhere(
|
|
883
|
-
(i) => !r.body[i].negated && variablesOf(r.body[i]).some((name) => bound.has(name))
|
|
884
|
-
);
|
|
885
|
-
if (joined !== -1) {
|
|
886
|
-
return joined;
|
|
887
|
-
}
|
|
888
|
-
const disconnected = firstWhere((i) => !r.body[i].negated);
|
|
889
|
-
if (disconnected !== -1) {
|
|
890
|
-
return disconnected;
|
|
891
|
-
}
|
|
892
|
-
return firstWhere(() => true);
|
|
893
|
-
};
|
|
894
|
-
take(deltaAt);
|
|
895
|
-
while (order.length < r.body.length) {
|
|
896
|
-
take(nextLiteral());
|
|
897
|
-
}
|
|
898
|
-
return order;
|
|
865
|
+
var positiveLiterals = /* @__PURE__ */ new WeakMap();
|
|
866
|
+
function deltaLiteral(r, deltaIndex) {
|
|
867
|
+
let positives = positiveLiterals.get(r);
|
|
868
|
+
if (positives === void 0) {
|
|
869
|
+
positives = r.body.map((literal, index) => literal.negated ? -1 : index).filter((index) => index !== -1);
|
|
870
|
+
positiveLiterals.set(r, positives);
|
|
871
|
+
}
|
|
872
|
+
return positives[deltaIndex] ?? -1;
|
|
899
873
|
}
|
|
874
|
+
var allBound = (literal, bindings) => literal.terms.every(
|
|
875
|
+
(term) => term.type === "constant" || boundValue(bindings, term.name) !== void 0
|
|
876
|
+
);
|
|
900
877
|
var rowBudget = (limit) => ({
|
|
901
878
|
examined: 0,
|
|
902
879
|
limit
|
|
@@ -914,21 +891,11 @@ var BudgetExhausted = class extends Error {
|
|
|
914
891
|
};
|
|
915
892
|
function evaluateRule(db, deltas, r, deltaIndex, budget) {
|
|
916
893
|
const results = [];
|
|
917
|
-
const
|
|
918
|
-
const
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
}
|
|
923
|
-
const literalIndex = order[orderIndex];
|
|
924
|
-
const literal = r.body[literalIndex];
|
|
925
|
-
if (literal.negated) {
|
|
926
|
-
if (!db.has(literal.relation, groundNegated(literal, bindings))) {
|
|
927
|
-
step(orderIndex + 1, bindings);
|
|
928
|
-
}
|
|
929
|
-
return;
|
|
930
|
-
}
|
|
931
|
-
const source = literalIndex === deltaAt ? deltas.get(literal.relation) ?? [] : boundSource(db, literal, bindings);
|
|
894
|
+
const body = r.body;
|
|
895
|
+
const deltaAt = deltaLiteral(r, deltaIndex);
|
|
896
|
+
const whole = 2 ** body.length - 1;
|
|
897
|
+
const walk2 = (index, source, taken, bindings) => {
|
|
898
|
+
const literal = body[index];
|
|
932
899
|
for (const tuple of source) {
|
|
933
900
|
budget.examined++;
|
|
934
901
|
if (budget.examined > budget.limit) {
|
|
@@ -936,14 +903,68 @@ function evaluateRule(db, deltas, r, deltaIndex, budget) {
|
|
|
936
903
|
}
|
|
937
904
|
const next = unify(literal, tuple, bindings);
|
|
938
905
|
if (next !== NO_MATCH) {
|
|
939
|
-
step(
|
|
906
|
+
step(taken | 1 << index, next);
|
|
940
907
|
}
|
|
941
908
|
}
|
|
942
909
|
};
|
|
943
|
-
step(
|
|
910
|
+
const step = (taken, bindings) => {
|
|
911
|
+
if (taken === whole) {
|
|
912
|
+
results.push(headTuple(r.head, bindings));
|
|
913
|
+
return;
|
|
914
|
+
}
|
|
915
|
+
let pick = -1;
|
|
916
|
+
let narrowest = null;
|
|
917
|
+
for (let index = 0; index < body.length; index++) {
|
|
918
|
+
if (taken & 1 << index) {
|
|
919
|
+
continue;
|
|
920
|
+
}
|
|
921
|
+
const literal = body[index];
|
|
922
|
+
if (literal.negated) {
|
|
923
|
+
if (allBound(literal, bindings)) {
|
|
924
|
+
if (!db.has(literal.relation, groundNegated(literal, bindings))) {
|
|
925
|
+
step(taken | 1 << index, bindings);
|
|
926
|
+
}
|
|
927
|
+
return;
|
|
928
|
+
}
|
|
929
|
+
continue;
|
|
930
|
+
}
|
|
931
|
+
const source = narrowedSource(db, literal, bindings);
|
|
932
|
+
if (source === null) {
|
|
933
|
+
continue;
|
|
934
|
+
}
|
|
935
|
+
if (source.length === 0) {
|
|
936
|
+
return;
|
|
937
|
+
}
|
|
938
|
+
if (narrowest === null || source.length < narrowest.length) {
|
|
939
|
+
pick = index;
|
|
940
|
+
narrowest = source;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
if (narrowest !== null) {
|
|
944
|
+
walk2(pick, narrowest, taken, bindings);
|
|
945
|
+
return;
|
|
946
|
+
}
|
|
947
|
+
for (let index = 0; index < body.length; index++) {
|
|
948
|
+
if (!(taken & 1 << index) && !body[index].negated) {
|
|
949
|
+
walk2(index, db.facts(body[index].relation), taken, bindings);
|
|
950
|
+
return;
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
for (let index = 0; index < body.length; index++) {
|
|
954
|
+
if (!(taken & 1 << index)) {
|
|
955
|
+
groundNegated(body[index], bindings);
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
};
|
|
959
|
+
if (deltaAt === -1) {
|
|
960
|
+
step(0, null);
|
|
961
|
+
} else {
|
|
962
|
+
walk2(deltaAt, deltas.get(body[deltaAt].relation) ?? [], 0, null);
|
|
963
|
+
}
|
|
944
964
|
return results;
|
|
945
965
|
}
|
|
946
|
-
|
|
966
|
+
var boundSource = (db, literal, bindings) => narrowedSource(db, literal, bindings) ?? db.facts(literal.relation);
|
|
967
|
+
function narrowedSource(db, literal, bindings) {
|
|
947
968
|
let narrowest = null;
|
|
948
969
|
for (let column = 0; column < literal.terms.length; column++) {
|
|
949
970
|
const term = literal.terms[column];
|
|
@@ -959,7 +980,7 @@ function boundSource(db, literal, bindings) {
|
|
|
959
980
|
narrowest = bucket;
|
|
960
981
|
}
|
|
961
982
|
}
|
|
962
|
-
return narrowest
|
|
983
|
+
return narrowest;
|
|
963
984
|
}
|
|
964
985
|
var EMPTY_TAGS = [];
|
|
965
986
|
function evaluateRuleTagged(db, deltas, r, deltaIndex, algebra, budget) {
|
package/dist/index.js
CHANGED
|
@@ -27,6 +27,7 @@ function deriveOnDemand(rules, complete) {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
const derives = (relation) => rulesByHead.has(relation);
|
|
30
|
+
const labels = labelColumns(rules, derives);
|
|
30
31
|
const asked = /* @__PURE__ */ new Map();
|
|
31
32
|
const pending = [];
|
|
32
33
|
const want = (adorned) => {
|
|
@@ -48,7 +49,7 @@ function deriveOnDemand(rules, complete) {
|
|
|
48
49
|
while (pending.length > 0) {
|
|
49
50
|
const adorned = pending.pop();
|
|
50
51
|
for (const written of rulesByHead.get(adorned.relation) ?? []) {
|
|
51
|
-
const r = boundFirst(written, adorned.adornment);
|
|
52
|
+
const r = boundFirst(written, adorned.adornment, labels);
|
|
52
53
|
const adornments = bodyAdornments(r, adorned.adornment, derives);
|
|
53
54
|
r.body.forEach((literal, at) => {
|
|
54
55
|
const adornment = adornments[at];
|
|
@@ -91,7 +92,7 @@ function deriveOnDemand(rules, complete) {
|
|
|
91
92
|
});
|
|
92
93
|
}
|
|
93
94
|
for (const written of rulesByHead.get(adorned.relation) ?? []) {
|
|
94
|
-
const r = boundFirst(written, adorned.adornment);
|
|
95
|
+
const r = boundFirst(written, adorned.adornment, labels);
|
|
95
96
|
const guard = anyBound(adorned.adornment) ? [
|
|
96
97
|
positiveLiteral(
|
|
97
98
|
demandOn(adorned.relation, adorned.adornment),
|
|
@@ -132,7 +133,30 @@ function deriveOnDemand(rules, complete) {
|
|
|
132
133
|
return { rules: rewritten, demandDriven: [...demandDriven], demands };
|
|
133
134
|
}
|
|
134
135
|
var sameLiteral = (premises, conclusion) => premises.length === 1 && JSON.stringify(premises[0]) === JSON.stringify(conclusion);
|
|
135
|
-
function
|
|
136
|
+
function labelColumns(rules, derives) {
|
|
137
|
+
const labels = /* @__PURE__ */ new Map();
|
|
138
|
+
const note = ({
|
|
139
|
+
relation,
|
|
140
|
+
terms
|
|
141
|
+
}) => {
|
|
142
|
+
if (!derives(relation)) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
terms.forEach((term, column) => {
|
|
146
|
+
if (term.type === "constant") {
|
|
147
|
+
const columns = labels.get(relation) ?? /* @__PURE__ */ new Set();
|
|
148
|
+
columns.add(column);
|
|
149
|
+
labels.set(relation, columns);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
};
|
|
153
|
+
for (const r of rules) {
|
|
154
|
+
note(r.head);
|
|
155
|
+
r.body.forEach(note);
|
|
156
|
+
}
|
|
157
|
+
return labels;
|
|
158
|
+
}
|
|
159
|
+
function boundFirst(r, headAdornment, labels) {
|
|
136
160
|
const bound = /* @__PURE__ */ new Set();
|
|
137
161
|
r.head.terms.forEach((term, column) => {
|
|
138
162
|
if (headAdornment[column] && term.type === "variable") {
|
|
@@ -140,7 +164,7 @@ function boundFirst(r, headAdornment) {
|
|
|
140
164
|
}
|
|
141
165
|
});
|
|
142
166
|
const boundColumns = (literal) => literal.terms.filter(
|
|
143
|
-
(term) => term.type === "constant" || bound.has(term.name)
|
|
167
|
+
(term, column) => !labels.get(literal.relation)?.has(column) && (term.type === "constant" || bound.has(term.name))
|
|
144
168
|
).length;
|
|
145
169
|
const remaining = [...r.body];
|
|
146
170
|
const body = [];
|
|
@@ -788,65 +812,18 @@ function headTuple(head, bindings) {
|
|
|
788
812
|
return bound;
|
|
789
813
|
});
|
|
790
814
|
}
|
|
791
|
-
var
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
const known = byDelta.get(deltaIndex);
|
|
800
|
-
if (known !== void 0) {
|
|
801
|
-
return known;
|
|
802
|
-
}
|
|
803
|
-
const positives = r.body.map((literal, index) => literal.negated ? -1 : index).filter((index) => index !== -1);
|
|
804
|
-
const deltaAt = positives[deltaIndex] ?? -1;
|
|
805
|
-
const computed = { deltaAt, order: planBodyOrder(r, deltaAt) };
|
|
806
|
-
byDelta.set(deltaIndex, computed);
|
|
807
|
-
return computed;
|
|
808
|
-
}
|
|
809
|
-
function planBodyOrder(r, deltaAt) {
|
|
810
|
-
const natural = r.body.map((_, i) => i);
|
|
811
|
-
if (deltaAt <= 0) {
|
|
812
|
-
return natural;
|
|
813
|
-
}
|
|
814
|
-
const taken = r.body.map(() => false);
|
|
815
|
-
const bound = /* @__PURE__ */ new Set();
|
|
816
|
-
const order = [];
|
|
817
|
-
const take = (index) => {
|
|
818
|
-
taken[index] = true;
|
|
819
|
-
order.push(index);
|
|
820
|
-
for (const name of variablesOf(r.body[index])) {
|
|
821
|
-
bound.add(name);
|
|
822
|
-
}
|
|
823
|
-
};
|
|
824
|
-
const firstWhere = (want) => natural.find((index) => !taken[index] && want(index)) ?? -1;
|
|
825
|
-
const nextLiteral = () => {
|
|
826
|
-
const ready = firstWhere(
|
|
827
|
-
(i) => r.body[i].negated && variablesOf(r.body[i]).every((name) => bound.has(name))
|
|
828
|
-
);
|
|
829
|
-
if (ready !== -1) {
|
|
830
|
-
return ready;
|
|
831
|
-
}
|
|
832
|
-
const joined = firstWhere(
|
|
833
|
-
(i) => !r.body[i].negated && variablesOf(r.body[i]).some((name) => bound.has(name))
|
|
834
|
-
);
|
|
835
|
-
if (joined !== -1) {
|
|
836
|
-
return joined;
|
|
837
|
-
}
|
|
838
|
-
const disconnected = firstWhere((i) => !r.body[i].negated);
|
|
839
|
-
if (disconnected !== -1) {
|
|
840
|
-
return disconnected;
|
|
841
|
-
}
|
|
842
|
-
return firstWhere(() => true);
|
|
843
|
-
};
|
|
844
|
-
take(deltaAt);
|
|
845
|
-
while (order.length < r.body.length) {
|
|
846
|
-
take(nextLiteral());
|
|
847
|
-
}
|
|
848
|
-
return order;
|
|
815
|
+
var positiveLiterals = /* @__PURE__ */ new WeakMap();
|
|
816
|
+
function deltaLiteral(r, deltaIndex) {
|
|
817
|
+
let positives = positiveLiterals.get(r);
|
|
818
|
+
if (positives === void 0) {
|
|
819
|
+
positives = r.body.map((literal, index) => literal.negated ? -1 : index).filter((index) => index !== -1);
|
|
820
|
+
positiveLiterals.set(r, positives);
|
|
821
|
+
}
|
|
822
|
+
return positives[deltaIndex] ?? -1;
|
|
849
823
|
}
|
|
824
|
+
var allBound = (literal, bindings) => literal.terms.every(
|
|
825
|
+
(term) => term.type === "constant" || boundValue(bindings, term.name) !== void 0
|
|
826
|
+
);
|
|
850
827
|
var rowBudget = (limit) => ({
|
|
851
828
|
examined: 0,
|
|
852
829
|
limit
|
|
@@ -864,21 +841,11 @@ var BudgetExhausted = class extends Error {
|
|
|
864
841
|
};
|
|
865
842
|
function evaluateRule(db, deltas, r, deltaIndex, budget) {
|
|
866
843
|
const results = [];
|
|
867
|
-
const
|
|
868
|
-
const
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
}
|
|
873
|
-
const literalIndex = order[orderIndex];
|
|
874
|
-
const literal = r.body[literalIndex];
|
|
875
|
-
if (literal.negated) {
|
|
876
|
-
if (!db.has(literal.relation, groundNegated(literal, bindings))) {
|
|
877
|
-
step(orderIndex + 1, bindings);
|
|
878
|
-
}
|
|
879
|
-
return;
|
|
880
|
-
}
|
|
881
|
-
const source = literalIndex === deltaAt ? deltas.get(literal.relation) ?? [] : boundSource(db, literal, bindings);
|
|
844
|
+
const body = r.body;
|
|
845
|
+
const deltaAt = deltaLiteral(r, deltaIndex);
|
|
846
|
+
const whole = 2 ** body.length - 1;
|
|
847
|
+
const walk2 = (index, source, taken, bindings) => {
|
|
848
|
+
const literal = body[index];
|
|
882
849
|
for (const tuple of source) {
|
|
883
850
|
budget.examined++;
|
|
884
851
|
if (budget.examined > budget.limit) {
|
|
@@ -886,14 +853,68 @@ function evaluateRule(db, deltas, r, deltaIndex, budget) {
|
|
|
886
853
|
}
|
|
887
854
|
const next = unify(literal, tuple, bindings);
|
|
888
855
|
if (next !== NO_MATCH) {
|
|
889
|
-
step(
|
|
856
|
+
step(taken | 1 << index, next);
|
|
890
857
|
}
|
|
891
858
|
}
|
|
892
859
|
};
|
|
893
|
-
step(
|
|
860
|
+
const step = (taken, bindings) => {
|
|
861
|
+
if (taken === whole) {
|
|
862
|
+
results.push(headTuple(r.head, bindings));
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
let pick = -1;
|
|
866
|
+
let narrowest = null;
|
|
867
|
+
for (let index = 0; index < body.length; index++) {
|
|
868
|
+
if (taken & 1 << index) {
|
|
869
|
+
continue;
|
|
870
|
+
}
|
|
871
|
+
const literal = body[index];
|
|
872
|
+
if (literal.negated) {
|
|
873
|
+
if (allBound(literal, bindings)) {
|
|
874
|
+
if (!db.has(literal.relation, groundNegated(literal, bindings))) {
|
|
875
|
+
step(taken | 1 << index, bindings);
|
|
876
|
+
}
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
continue;
|
|
880
|
+
}
|
|
881
|
+
const source = narrowedSource(db, literal, bindings);
|
|
882
|
+
if (source === null) {
|
|
883
|
+
continue;
|
|
884
|
+
}
|
|
885
|
+
if (source.length === 0) {
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
if (narrowest === null || source.length < narrowest.length) {
|
|
889
|
+
pick = index;
|
|
890
|
+
narrowest = source;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
if (narrowest !== null) {
|
|
894
|
+
walk2(pick, narrowest, taken, bindings);
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
for (let index = 0; index < body.length; index++) {
|
|
898
|
+
if (!(taken & 1 << index) && !body[index].negated) {
|
|
899
|
+
walk2(index, db.facts(body[index].relation), taken, bindings);
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
for (let index = 0; index < body.length; index++) {
|
|
904
|
+
if (!(taken & 1 << index)) {
|
|
905
|
+
groundNegated(body[index], bindings);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
};
|
|
909
|
+
if (deltaAt === -1) {
|
|
910
|
+
step(0, null);
|
|
911
|
+
} else {
|
|
912
|
+
walk2(deltaAt, deltas.get(body[deltaAt].relation) ?? [], 0, null);
|
|
913
|
+
}
|
|
894
914
|
return results;
|
|
895
915
|
}
|
|
896
|
-
|
|
916
|
+
var boundSource = (db, literal, bindings) => narrowedSource(db, literal, bindings) ?? db.facts(literal.relation);
|
|
917
|
+
function narrowedSource(db, literal, bindings) {
|
|
897
918
|
let narrowest = null;
|
|
898
919
|
for (let column = 0; column < literal.terms.length; column++) {
|
|
899
920
|
const term = literal.terms[column];
|
|
@@ -909,7 +930,7 @@ function boundSource(db, literal, bindings) {
|
|
|
909
930
|
narrowest = bucket;
|
|
910
931
|
}
|
|
911
932
|
}
|
|
912
|
-
return narrowest
|
|
933
|
+
return narrowest;
|
|
913
934
|
}
|
|
914
935
|
var EMPTY_TAGS = [];
|
|
915
936
|
function evaluateRuleTagged(db, deltas, r, deltaIndex, algebra, budget) {
|
package/package.json
CHANGED