@suss/datalog 0.21.1 → 0.22.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/README.md +18 -0
- package/dist/index.cjs +7 -1
- package/dist/index.d.cts +20 -1
- package/dist/index.d.ts +20 -1
- package/dist/index.js +7 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -313,6 +313,24 @@ Keep the facts you add and the facts the rules derive in separate
|
|
|
313
313
|
relations. Taking a conclusion back cannot tell one from the other, and
|
|
314
314
|
splitting them is how people normally write Datalog anyway.
|
|
315
315
|
|
|
316
|
+
### Reading what the rules are waiting on
|
|
317
|
+
|
|
318
|
+
Demand is also something a caller can read. `program.demands` lists
|
|
319
|
+
each demand relation with the relation it is for and which of that
|
|
320
|
+
relation's columns a demand row fixes, in column order:
|
|
321
|
+
|
|
322
|
+
```ts
|
|
323
|
+
program.demands;
|
|
324
|
+
// [{ relation: "reaches", bound: [true, false], demand: "wanted:reaches" }]
|
|
325
|
+
db.facts("wanted:reaches"); // [["a"], ["b"], ["c"]]
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
A caller that loads its base facts lazily uses this to find out what to
|
|
329
|
+
load next. Evaluate, read the demand rows on the relation whose base
|
|
330
|
+
facts come from somewhere else, fetch those, evaluate again, and stop
|
|
331
|
+
when no demand row is new. The rules then decide what gets loaded, and
|
|
332
|
+
the caller never has to guess how far a chain runs.
|
|
333
|
+
|
|
316
334
|
Extraction-scale fact sets run to thousands of tuples. If that changes,
|
|
317
335
|
the rule data model is the part that stays and this evaluator is the
|
|
318
336
|
part you replace.
|
package/dist/index.cjs
CHANGED
|
@@ -117,6 +117,7 @@ function deriveOnDemand(rules, complete) {
|
|
|
117
117
|
const demandOn = (relation, adornment) => `wanted:${nameOf(relation, adornment)}`;
|
|
118
118
|
const rewritten = [];
|
|
119
119
|
const demandDriven = /* @__PURE__ */ new Set();
|
|
120
|
+
const demands = [];
|
|
120
121
|
const already = /* @__PURE__ */ new Set();
|
|
121
122
|
const emit = (r) => {
|
|
122
123
|
const key = JSON.stringify(r);
|
|
@@ -129,6 +130,11 @@ function deriveOnDemand(rules, complete) {
|
|
|
129
130
|
if (anyBound(adorned.adornment)) {
|
|
130
131
|
demandDriven.add(nameOf(adorned.relation, adorned.adornment));
|
|
131
132
|
demandDriven.add(demandOn(adorned.relation, adorned.adornment));
|
|
133
|
+
demands.push({
|
|
134
|
+
relation: adorned.relation,
|
|
135
|
+
bound: adorned.adornment,
|
|
136
|
+
demand: demandOn(adorned.relation, adorned.adornment)
|
|
137
|
+
});
|
|
132
138
|
}
|
|
133
139
|
for (const written of rulesByHead.get(adorned.relation) ?? []) {
|
|
134
140
|
const r = boundFirst(written, adorned.adornment);
|
|
@@ -169,7 +175,7 @@ function deriveOnDemand(rules, complete) {
|
|
|
169
175
|
}
|
|
170
176
|
}
|
|
171
177
|
demandRewrites.add(rewritten);
|
|
172
|
-
return { rules: rewritten, demandDriven: [...demandDriven] };
|
|
178
|
+
return { rules: rewritten, demandDriven: [...demandDriven], demands };
|
|
173
179
|
}
|
|
174
180
|
var sameLiteral = (premises, conclusion) => premises.length === 1 && JSON.stringify(premises[0]) === JSON.stringify(conclusion);
|
|
175
181
|
function boundFirst(r, headAdornment) {
|
package/dist/index.d.cts
CHANGED
|
@@ -31,6 +31,18 @@ declare function confidenceWith(levelOf: (rule: Rule) => ConfidenceLevel | undef
|
|
|
31
31
|
/** The confidence algebra with every rule counted as exact. */
|
|
32
32
|
declare const confidence: TagAlgebra<ConfidenceLevel>;
|
|
33
33
|
|
|
34
|
+
/** One demand relation the rewrite created, and what its rows say. */
|
|
35
|
+
interface Demand {
|
|
36
|
+
/** The relation whose rows are being waited on. */
|
|
37
|
+
relation: string;
|
|
38
|
+
/** Which columns of that relation a demand row fixes. */
|
|
39
|
+
bound: readonly boolean[];
|
|
40
|
+
/**
|
|
41
|
+
* The demand relation's name. Each of its rows lists the bound
|
|
42
|
+
* columns' values, in the relation's column order.
|
|
43
|
+
*/
|
|
44
|
+
demand: string;
|
|
45
|
+
}
|
|
34
46
|
/** A rewritten rule set, and which of its relations demand restricts. */
|
|
35
47
|
interface OnDemandRules {
|
|
36
48
|
/** The rewritten rules, ready to evaluate. */
|
|
@@ -43,6 +55,13 @@ interface OnDemandRules {
|
|
|
43
55
|
* answers.
|
|
44
56
|
*/
|
|
45
57
|
demandDriven: string[];
|
|
58
|
+
/**
|
|
59
|
+
* The demand relations by what they ask for, so a caller can read
|
|
60
|
+
* what the rules are waiting on and go and get it: a store that
|
|
61
|
+
* loads facts lazily reads the demand on a module's exports and
|
|
62
|
+
* extracts that module.
|
|
63
|
+
*/
|
|
64
|
+
demands: Demand[];
|
|
46
65
|
}
|
|
47
66
|
/**
|
|
48
67
|
* Rewrite `rules` so the relations listed in `complete` still come out
|
|
@@ -419,4 +438,4 @@ declare function evaluate<Tag = never>(db: Database, rules: Rule[], algebra?: Ta
|
|
|
419
438
|
*/
|
|
420
439
|
declare function clearRelations(db: Database, rules: Rule[], relations: readonly string[]): void;
|
|
421
440
|
|
|
422
|
-
export { type AddOutcome, type Atom, type BodyMatch, type ConfidenceLevel, Database, type Derivation, type EvaluationProfile, type Literal, type OnDemandRules, type Proof, type ProofDerived, type ProofOptions, type Rule, type RuleCost, type TagAlgebra, type Term, type Tuple, Witness, type WitnessTag, clearRelations, confidence, confidenceWith, constant, deriveOnDemand, evaluate, formatProfile, lit, notLit, profileEvaluation, profileEvaluationAsync, proofOf, rule, ruleLabel, stratify, tupleKey, tupleKeyParts, variable, witnesses };
|
|
441
|
+
export { type AddOutcome, type Atom, type BodyMatch, type ConfidenceLevel, Database, type Demand, type Derivation, type EvaluationProfile, type Literal, type OnDemandRules, type Proof, type ProofDerived, type ProofOptions, type Rule, type RuleCost, type TagAlgebra, type Term, type Tuple, Witness, type WitnessTag, clearRelations, confidence, confidenceWith, constant, deriveOnDemand, evaluate, formatProfile, lit, notLit, profileEvaluation, profileEvaluationAsync, proofOf, rule, ruleLabel, stratify, tupleKey, tupleKeyParts, variable, witnesses };
|
package/dist/index.d.ts
CHANGED
|
@@ -31,6 +31,18 @@ declare function confidenceWith(levelOf: (rule: Rule) => ConfidenceLevel | undef
|
|
|
31
31
|
/** The confidence algebra with every rule counted as exact. */
|
|
32
32
|
declare const confidence: TagAlgebra<ConfidenceLevel>;
|
|
33
33
|
|
|
34
|
+
/** One demand relation the rewrite created, and what its rows say. */
|
|
35
|
+
interface Demand {
|
|
36
|
+
/** The relation whose rows are being waited on. */
|
|
37
|
+
relation: string;
|
|
38
|
+
/** Which columns of that relation a demand row fixes. */
|
|
39
|
+
bound: readonly boolean[];
|
|
40
|
+
/**
|
|
41
|
+
* The demand relation's name. Each of its rows lists the bound
|
|
42
|
+
* columns' values, in the relation's column order.
|
|
43
|
+
*/
|
|
44
|
+
demand: string;
|
|
45
|
+
}
|
|
34
46
|
/** A rewritten rule set, and which of its relations demand restricts. */
|
|
35
47
|
interface OnDemandRules {
|
|
36
48
|
/** The rewritten rules, ready to evaluate. */
|
|
@@ -43,6 +55,13 @@ interface OnDemandRules {
|
|
|
43
55
|
* answers.
|
|
44
56
|
*/
|
|
45
57
|
demandDriven: string[];
|
|
58
|
+
/**
|
|
59
|
+
* The demand relations by what they ask for, so a caller can read
|
|
60
|
+
* what the rules are waiting on and go and get it: a store that
|
|
61
|
+
* loads facts lazily reads the demand on a module's exports and
|
|
62
|
+
* extracts that module.
|
|
63
|
+
*/
|
|
64
|
+
demands: Demand[];
|
|
46
65
|
}
|
|
47
66
|
/**
|
|
48
67
|
* Rewrite `rules` so the relations listed in `complete` still come out
|
|
@@ -419,4 +438,4 @@ declare function evaluate<Tag = never>(db: Database, rules: Rule[], algebra?: Ta
|
|
|
419
438
|
*/
|
|
420
439
|
declare function clearRelations(db: Database, rules: Rule[], relations: readonly string[]): void;
|
|
421
440
|
|
|
422
|
-
export { type AddOutcome, type Atom, type BodyMatch, type ConfidenceLevel, Database, type Derivation, type EvaluationProfile, type Literal, type OnDemandRules, type Proof, type ProofDerived, type ProofOptions, type Rule, type RuleCost, type TagAlgebra, type Term, type Tuple, Witness, type WitnessTag, clearRelations, confidence, confidenceWith, constant, deriveOnDemand, evaluate, formatProfile, lit, notLit, profileEvaluation, profileEvaluationAsync, proofOf, rule, ruleLabel, stratify, tupleKey, tupleKeyParts, variable, witnesses };
|
|
441
|
+
export { type AddOutcome, type Atom, type BodyMatch, type ConfidenceLevel, Database, type Demand, type Derivation, type EvaluationProfile, type Literal, type OnDemandRules, type Proof, type ProofDerived, type ProofOptions, type Rule, type RuleCost, type TagAlgebra, type Term, type Tuple, Witness, type WitnessTag, clearRelations, confidence, confidenceWith, constant, deriveOnDemand, evaluate, formatProfile, lit, notLit, profileEvaluation, profileEvaluationAsync, proofOf, rule, ruleLabel, stratify, tupleKey, tupleKeyParts, variable, witnesses };
|
package/dist/index.js
CHANGED
|
@@ -71,6 +71,7 @@ function deriveOnDemand(rules, complete) {
|
|
|
71
71
|
const demandOn = (relation, adornment) => `wanted:${nameOf(relation, adornment)}`;
|
|
72
72
|
const rewritten = [];
|
|
73
73
|
const demandDriven = /* @__PURE__ */ new Set();
|
|
74
|
+
const demands = [];
|
|
74
75
|
const already = /* @__PURE__ */ new Set();
|
|
75
76
|
const emit = (r) => {
|
|
76
77
|
const key = JSON.stringify(r);
|
|
@@ -83,6 +84,11 @@ function deriveOnDemand(rules, complete) {
|
|
|
83
84
|
if (anyBound(adorned.adornment)) {
|
|
84
85
|
demandDriven.add(nameOf(adorned.relation, adorned.adornment));
|
|
85
86
|
demandDriven.add(demandOn(adorned.relation, adorned.adornment));
|
|
87
|
+
demands.push({
|
|
88
|
+
relation: adorned.relation,
|
|
89
|
+
bound: adorned.adornment,
|
|
90
|
+
demand: demandOn(adorned.relation, adorned.adornment)
|
|
91
|
+
});
|
|
86
92
|
}
|
|
87
93
|
for (const written of rulesByHead.get(adorned.relation) ?? []) {
|
|
88
94
|
const r = boundFirst(written, adorned.adornment);
|
|
@@ -123,7 +129,7 @@ function deriveOnDemand(rules, complete) {
|
|
|
123
129
|
}
|
|
124
130
|
}
|
|
125
131
|
demandRewrites.add(rewritten);
|
|
126
|
-
return { rules: rewritten, demandDriven: [...demandDriven] };
|
|
132
|
+
return { rules: rewritten, demandDriven: [...demandDriven], demands };
|
|
127
133
|
}
|
|
128
134
|
var sameLiteral = (premises, conclusion) => premises.length === 1 && JSON.stringify(premises[0]) === JSON.stringify(conclusion);
|
|
129
135
|
function boundFirst(r, headAdornment) {
|
package/package.json
CHANGED