eyeling 1.26.2 → 1.26.4
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/browser/eyeling.browser.js +195 -533
- package/eyeling.js +195 -533
- package/lib/engine.js +195 -533
- package/package.json +1 -1
package/lib/engine.js
CHANGED
|
@@ -40,6 +40,27 @@ const INFERENCE_FUSE_EXIT_CODE = 65;
|
|
|
40
40
|
const RDF_NIL_IRI = RDF_NS + 'nil';
|
|
41
41
|
const EMPTY_LIST_TERM = new ListTerm([]);
|
|
42
42
|
|
|
43
|
+
const LOG_COLLECT_ALL_IN_IRI = LOG_NS + 'collectAllIn';
|
|
44
|
+
const LOG_FOR_ALL_IN_IRI = LOG_NS + 'forAllIn';
|
|
45
|
+
const LOG_INCLUDES_IRI = LOG_NS + 'includes';
|
|
46
|
+
const LOG_NOT_INCLUDES_IRI = LOG_NS + 'notIncludes';
|
|
47
|
+
const LOG_IMPLIES_IRI = LOG_NS + 'implies';
|
|
48
|
+
const LOG_IMPLIED_BY_IRI = LOG_NS + 'impliedBy';
|
|
49
|
+
|
|
50
|
+
const MATH_BUILTINS_SATISFIABLE_WHEN_FULLY_UNBOUND = new Set([
|
|
51
|
+
MATH_NS + 'sin',
|
|
52
|
+
MATH_NS + 'cos',
|
|
53
|
+
MATH_NS + 'tan',
|
|
54
|
+
MATH_NS + 'asin',
|
|
55
|
+
MATH_NS + 'acos',
|
|
56
|
+
MATH_NS + 'atan',
|
|
57
|
+
MATH_NS + 'sinh',
|
|
58
|
+
MATH_NS + 'cosh',
|
|
59
|
+
MATH_NS + 'tanh',
|
|
60
|
+
MATH_NS + 'degrees',
|
|
61
|
+
MATH_NS + 'negation',
|
|
62
|
+
]);
|
|
63
|
+
|
|
43
64
|
const { lex, N3SyntaxError } = require('./lexer');
|
|
44
65
|
const { Parser } = require('./parser');
|
|
45
66
|
const { liftBlankRuleVars } = require('./rules');
|
|
@@ -100,6 +121,29 @@ function __cloneSubst(subst) {
|
|
|
100
121
|
return out;
|
|
101
122
|
}
|
|
102
123
|
|
|
124
|
+
function __defineHidden(obj, name, value, writable) {
|
|
125
|
+
Object.defineProperty(obj, name, { value, enumerable: false, writable, configurable: true });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function __defineHiddenValue(obj, name, value) {
|
|
129
|
+
__defineHidden(obj, name, value, false);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function __defineHiddenWritable(obj, name, value) {
|
|
133
|
+
__defineHidden(obj, name, value, true);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function __setHiddenWritable(obj, name, value) {
|
|
137
|
+
if (hasOwn.call(obj, name)) obj[name] = value;
|
|
138
|
+
else __defineHiddenWritable(obj, name, value);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const FACT_INDEX_ARRAY_FIELDS = ['__varPred', '__varPredNonFastS', '__varPredNonFastO'];
|
|
142
|
+
const FACT_INDEX_ARRAY_MAP_FIELDS = ['__byPred', '__byPNonFastS', '__byPNonFastO', '__varPredPS', '__varPredPO'];
|
|
143
|
+
const FACT_INDEX_NESTED_ARRAY_MAP_FIELDS = ['__byPS', '__byPO'];
|
|
144
|
+
const FACT_INDEX_MAP_FIELDS = FACT_INDEX_ARRAY_MAP_FIELDS.concat(FACT_INDEX_NESTED_ARRAY_MAP_FIELDS);
|
|
145
|
+
const FACT_INDEX_REQUIRED_FIELDS = FACT_INDEX_ARRAY_FIELDS.concat(FACT_INDEX_MAP_FIELDS, ['__keySet']);
|
|
146
|
+
|
|
103
147
|
let version = 'dev';
|
|
104
148
|
try {
|
|
105
149
|
// Node: keep package.json version if available
|
|
@@ -323,14 +367,13 @@ function __firingKey(ruleIndex, instantiatedPremises) {
|
|
|
323
367
|
// -----------------------------------------------------------------------------
|
|
324
368
|
function __ensureRuleKeySet(rules) {
|
|
325
369
|
if (!hasOwn.call(rules, '__ruleKeySet')) {
|
|
326
|
-
|
|
327
|
-
|
|
370
|
+
__defineHiddenValue(
|
|
371
|
+
rules,
|
|
372
|
+
'__ruleKeySet',
|
|
373
|
+
new Set(
|
|
328
374
|
rules.map((r) => __ruleKey(r.isForward, r.isFuse, r.premise, r.conclusion, r.__dynamicConclusionTerm || null)),
|
|
329
375
|
),
|
|
330
|
-
|
|
331
|
-
writable: false,
|
|
332
|
-
configurable: true,
|
|
333
|
-
});
|
|
376
|
+
);
|
|
334
377
|
}
|
|
335
378
|
return rules.__ruleKeySet;
|
|
336
379
|
}
|
|
@@ -348,28 +391,13 @@ function __computeHeadIsStrictGround(r) {
|
|
|
348
391
|
function __prepareForwardRule(r) {
|
|
349
392
|
if (!hasOwn.call(r, '__scopedSkipInfo')) {
|
|
350
393
|
const info = __computeForwardRuleScopedSkipInfo(r);
|
|
351
|
-
|
|
352
|
-
value: info,
|
|
353
|
-
enumerable: false,
|
|
354
|
-
writable: false,
|
|
355
|
-
configurable: true,
|
|
356
|
-
});
|
|
394
|
+
__defineHiddenValue(r, '__scopedSkipInfo', info);
|
|
357
395
|
}
|
|
358
396
|
if (!hasOwn.call(r, '__headIsStrictGround')) {
|
|
359
|
-
|
|
360
|
-
value: __computeHeadIsStrictGround(r),
|
|
361
|
-
enumerable: false,
|
|
362
|
-
writable: false,
|
|
363
|
-
configurable: true,
|
|
364
|
-
});
|
|
397
|
+
__defineHiddenValue(r, '__headIsStrictGround', __computeHeadIsStrictGround(r));
|
|
365
398
|
}
|
|
366
399
|
if (!hasOwn.call(r, '__needsForwardSkipCheck')) {
|
|
367
|
-
|
|
368
|
-
value: !!(r.__headIsStrictGround || (r.__scopedSkipInfo && r.__scopedSkipInfo.needsSnap)),
|
|
369
|
-
enumerable: false,
|
|
370
|
-
writable: false,
|
|
371
|
-
configurable: true,
|
|
372
|
-
});
|
|
400
|
+
__defineHiddenValue(r, '__needsForwardSkipCheck', !!(r.__headIsStrictGround || (r.__scopedSkipInfo && r.__scopedSkipInfo.needsSnap)));
|
|
373
401
|
}
|
|
374
402
|
}
|
|
375
403
|
|
|
@@ -411,44 +439,29 @@ function __logNaturalPriorityFromTerm(t) {
|
|
|
411
439
|
function __computeMaxScopedClosurePriorityNeeded(forwardRules, backRules) {
|
|
412
440
|
let maxP = 0;
|
|
413
441
|
|
|
442
|
+
function bumpMaxPriority(term) {
|
|
443
|
+
if (term instanceof GraphTerm) return;
|
|
444
|
+
if (term instanceof Var) {
|
|
445
|
+
if (maxP < 1) maxP = 1;
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
const p0 = __logNaturalPriorityFromTerm(term);
|
|
449
|
+
const priority = p0 !== null ? p0 : 1;
|
|
450
|
+
if (priority > maxP) maxP = priority;
|
|
451
|
+
}
|
|
452
|
+
|
|
414
453
|
function scanTriple(tr) {
|
|
415
454
|
if (!(tr && tr.p instanceof Iri)) return;
|
|
416
455
|
const pv = tr.p.value;
|
|
417
456
|
|
|
418
457
|
// log:collectAllIn / log:forAllIn use the object position for the priority.
|
|
419
|
-
if (pv ===
|
|
420
|
-
|
|
421
|
-
if (tr.o instanceof GraphTerm) return;
|
|
422
|
-
// Variable or non-numeric object => default priority 1 (if used).
|
|
423
|
-
if (tr.o instanceof Var) {
|
|
424
|
-
if (maxP < 1) maxP = 1;
|
|
425
|
-
return;
|
|
426
|
-
}
|
|
427
|
-
const p0 = __logNaturalPriorityFromTerm(tr.o);
|
|
428
|
-
if (p0 !== null) {
|
|
429
|
-
if (p0 > maxP) maxP = p0;
|
|
430
|
-
} else {
|
|
431
|
-
if (maxP < 1) maxP = 1;
|
|
432
|
-
}
|
|
458
|
+
if (pv === LOG_COLLECT_ALL_IN_IRI || pv === LOG_FOR_ALL_IN_IRI) {
|
|
459
|
+
bumpMaxPriority(tr.o);
|
|
433
460
|
return;
|
|
434
461
|
}
|
|
435
462
|
|
|
436
463
|
// log:includes / log:notIncludes use the subject position for the priority.
|
|
437
|
-
if (pv ===
|
|
438
|
-
// Explicit scope graphs are immediate and do not require a closure.
|
|
439
|
-
if (tr.s instanceof GraphTerm) return;
|
|
440
|
-
// Variable or non-numeric subject => default priority 1 (if used).
|
|
441
|
-
if (tr.s instanceof Var) {
|
|
442
|
-
if (maxP < 1) maxP = 1;
|
|
443
|
-
return;
|
|
444
|
-
}
|
|
445
|
-
const p0 = __logNaturalPriorityFromTerm(tr.s);
|
|
446
|
-
if (p0 !== null) {
|
|
447
|
-
if (p0 > maxP) maxP = p0;
|
|
448
|
-
} else {
|
|
449
|
-
if (maxP < 1) maxP = 1;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
464
|
+
if (pv === LOG_INCLUDES_IRI || pv === LOG_NOT_INCLUDES_IRI) bumpMaxPriority(tr.s);
|
|
452
465
|
}
|
|
453
466
|
|
|
454
467
|
for (const r of forwardRules) {
|
|
@@ -460,17 +473,6 @@ function __computeMaxScopedClosurePriorityNeeded(forwardRules, backRules) {
|
|
|
460
473
|
return maxP;
|
|
461
474
|
}
|
|
462
475
|
|
|
463
|
-
function __termContainsVarName(t, name) {
|
|
464
|
-
if (t instanceof Var) return t.name === name;
|
|
465
|
-
if (t instanceof ListTerm) return t.elems.some((e) => __termContainsVarName(e, name));
|
|
466
|
-
if (t instanceof OpenListTerm) return t.tailVar === name || t.prefix.some((e) => __termContainsVarName(e, name));
|
|
467
|
-
if (t instanceof GraphTerm)
|
|
468
|
-
return t.triples.some(
|
|
469
|
-
(tr) =>
|
|
470
|
-
__termContainsVarName(tr.s, name) || __termContainsVarName(tr.p, name) || __termContainsVarName(tr.o, name),
|
|
471
|
-
);
|
|
472
|
-
return false;
|
|
473
|
-
}
|
|
474
476
|
|
|
475
477
|
function __varOccursElsewhereInPremise(premise, name, idx, field) {
|
|
476
478
|
for (let i = 0; i < premise.length; i++) {
|
|
@@ -478,14 +480,13 @@ function __varOccursElsewhereInPremise(premise, name, idx, field) {
|
|
|
478
480
|
if (!(tr && tr.s && tr.p && tr.o)) continue;
|
|
479
481
|
|
|
480
482
|
// Skip the specific scope/priority occurrence we are analyzing.
|
|
481
|
-
if (!(i === idx && field === 's') &&
|
|
482
|
-
if (!(i === idx && field === 'p') &&
|
|
483
|
-
if (!(i === idx && field === 'o') &&
|
|
483
|
+
if (!(i === idx && field === 's') && containsVarTerm(tr.s, name)) return true;
|
|
484
|
+
if (!(i === idx && field === 'p') && containsVarTerm(tr.p, name)) return true;
|
|
485
|
+
if (!(i === idx && field === 'o') && containsVarTerm(tr.o, name)) return true;
|
|
484
486
|
}
|
|
485
487
|
return false;
|
|
486
488
|
}
|
|
487
489
|
|
|
488
|
-
|
|
489
490
|
function __scopedPriorityForTerm(t) {
|
|
490
491
|
if (t instanceof GraphTerm) return 0;
|
|
491
492
|
const p0 = __logNaturalPriorityFromTerm(t);
|
|
@@ -512,7 +513,7 @@ function __analyzeForwardRuleScopedUse(rule) {
|
|
|
512
513
|
if (!(tr && tr.p instanceof Iri)) continue;
|
|
513
514
|
const pv = tr.p.value;
|
|
514
515
|
|
|
515
|
-
if (pv ===
|
|
516
|
+
if (pv === LOG_INCLUDES_IRI || pv === LOG_NOT_INCLUDES_IRI) {
|
|
516
517
|
// Explicit quoted scopes are local formulas, not snapshots of the global closure.
|
|
517
518
|
if (tr.s instanceof GraphTerm) continue;
|
|
518
519
|
|
|
@@ -526,7 +527,7 @@ function __analyzeForwardRuleScopedUse(rule) {
|
|
|
526
527
|
continue;
|
|
527
528
|
}
|
|
528
529
|
|
|
529
|
-
if (pv ===
|
|
530
|
+
if (pv === LOG_COLLECT_ALL_IN_IRI) {
|
|
530
531
|
if (tr.o instanceof GraphTerm) continue;
|
|
531
532
|
|
|
532
533
|
out.needsSnap = true;
|
|
@@ -538,7 +539,7 @@ function __analyzeForwardRuleScopedUse(rule) {
|
|
|
538
539
|
continue;
|
|
539
540
|
}
|
|
540
541
|
|
|
541
|
-
if (pv ===
|
|
542
|
+
if (pv === LOG_FOR_ALL_IN_IRI) {
|
|
542
543
|
if (tr.o instanceof GraphTerm) continue;
|
|
543
544
|
|
|
544
545
|
out.needsSnap = true;
|
|
@@ -580,16 +581,7 @@ function __setForwardRuleScopedStratumInfo(rule, level) {
|
|
|
580
581
|
? { needsSnap: true, requiredLevel: level, exactLevel: true }
|
|
581
582
|
: { needsSnap: false, requiredLevel: 0, exactLevel: false };
|
|
582
583
|
|
|
583
|
-
|
|
584
|
-
Object.defineProperty(rule, '__scopedStratumInfo', {
|
|
585
|
-
value,
|
|
586
|
-
enumerable: false,
|
|
587
|
-
writable: true,
|
|
588
|
-
configurable: true,
|
|
589
|
-
});
|
|
590
|
-
} else {
|
|
591
|
-
rule.__scopedStratumInfo = value;
|
|
592
|
-
}
|
|
584
|
+
__setHiddenWritable(rule, '__scopedStratumInfo', value);
|
|
593
585
|
}
|
|
594
586
|
|
|
595
587
|
function __computeForwardRuleScopedStrata(forwardRules) {
|
|
@@ -627,7 +619,6 @@ function __computeForwardRuleScopedStrata(forwardRules) {
|
|
|
627
619
|
if (!changed) break;
|
|
628
620
|
}
|
|
629
621
|
|
|
630
|
-
|
|
631
622
|
maxLevel = 0;
|
|
632
623
|
for (let i = 0; i < forwardRules.length; i++) {
|
|
633
624
|
__setForwardRuleScopedStratumInfo(forwardRules[i], levels[i]);
|
|
@@ -641,42 +632,33 @@ function __computeForwardRuleScopedSkipInfo(rule) {
|
|
|
641
632
|
let needsSnap = false;
|
|
642
633
|
let requiredLevel = 0;
|
|
643
634
|
|
|
635
|
+
function addScopedUse(scopeTerm, idx, field) {
|
|
636
|
+
if (scopeTerm instanceof GraphTerm) return true; // explicit scope
|
|
637
|
+
|
|
638
|
+
// If scope term is a Var that appears elsewhere, it might be bound to a GraphTerm.
|
|
639
|
+
// Be conservative and do not skip in that case.
|
|
640
|
+
if (scopeTerm instanceof Var) {
|
|
641
|
+
if (__varOccursElsewhereInPremise(rule.premise, scopeTerm.name, idx, field)) return false;
|
|
642
|
+
needsSnap = true;
|
|
643
|
+
requiredLevel = Math.max(requiredLevel, 1);
|
|
644
|
+
return true;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
needsSnap = true;
|
|
648
|
+
const p0 = __logNaturalPriorityFromTerm(scopeTerm);
|
|
649
|
+
requiredLevel = Math.max(requiredLevel, p0 !== null ? p0 : 1);
|
|
650
|
+
return true;
|
|
651
|
+
}
|
|
652
|
+
|
|
644
653
|
for (let i = 0; i < rule.premise.length; i++) {
|
|
645
654
|
const tr = rule.premise[i];
|
|
646
655
|
if (!(tr && tr.p instanceof Iri)) continue;
|
|
647
656
|
const pv = tr.p.value;
|
|
648
657
|
|
|
649
|
-
if (pv ===
|
|
650
|
-
if (tr.o
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
if (tr.o instanceof Var) {
|
|
654
|
-
if (__varOccursElsewhereInPremise(rule.premise, tr.o.name, i, 'o')) return null;
|
|
655
|
-
needsSnap = true;
|
|
656
|
-
requiredLevel = Math.max(requiredLevel, 1);
|
|
657
|
-
} else {
|
|
658
|
-
needsSnap = true;
|
|
659
|
-
let prio = 1;
|
|
660
|
-
const p0 = __logNaturalPriorityFromTerm(tr.o);
|
|
661
|
-
if (p0 !== null) prio = p0;
|
|
662
|
-
requiredLevel = Math.max(requiredLevel, prio);
|
|
663
|
-
}
|
|
664
|
-
continue;
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
if (pv === LOG_NS + 'includes' || pv === LOG_NS + 'notIncludes') {
|
|
668
|
-
if (tr.s instanceof GraphTerm) continue; // explicit scope
|
|
669
|
-
if (tr.s instanceof Var) {
|
|
670
|
-
if (__varOccursElsewhereInPremise(rule.premise, tr.s.name, i, 's')) return null;
|
|
671
|
-
needsSnap = true;
|
|
672
|
-
requiredLevel = Math.max(requiredLevel, 1);
|
|
673
|
-
} else {
|
|
674
|
-
needsSnap = true;
|
|
675
|
-
let prio = 1;
|
|
676
|
-
const p0 = __logNaturalPriorityFromTerm(tr.s);
|
|
677
|
-
if (p0 !== null) prio = p0;
|
|
678
|
-
requiredLevel = Math.max(requiredLevel, prio);
|
|
679
|
-
}
|
|
658
|
+
if (pv === LOG_COLLECT_ALL_IN_IRI || pv === LOG_FOR_ALL_IN_IRI) {
|
|
659
|
+
if (!addScopedUse(tr.o, i, 'o')) return null;
|
|
660
|
+
} else if (pv === LOG_INCLUDES_IRI || pv === LOG_NOT_INCLUDES_IRI) {
|
|
661
|
+
if (!addScopedUse(tr.s, i, 's')) return null;
|
|
680
662
|
}
|
|
681
663
|
}
|
|
682
664
|
|
|
@@ -859,140 +841,70 @@ function skolemizeTripleForHeadBlanks(tr, headBlankLabels, mapping, skCounter, f
|
|
|
859
841
|
// Alpha equivalence helpers
|
|
860
842
|
// ===========================================================================
|
|
861
843
|
|
|
862
|
-
function
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
if (a.__tid && b.__tid && a.__tid === b.__tid) return true;
|
|
866
|
-
|
|
867
|
-
// rdf:nil is equivalent to the empty list ()
|
|
868
|
-
if (a instanceof Iri && a.value === RDF_NIL_IRI && b instanceof ListTerm && b.elems.length === 0) return true;
|
|
869
|
-
if (b instanceof Iri && b.value === RDF_NIL_IRI && a instanceof ListTerm && a.elems.length === 0) return true;
|
|
870
|
-
if (a.constructor !== b.constructor) return false;
|
|
871
|
-
|
|
872
|
-
if (a instanceof Iri) return a.value === b.value;
|
|
873
|
-
|
|
874
|
-
if (a instanceof Literal) {
|
|
875
|
-
if (a.value === b.value) return true;
|
|
876
|
-
|
|
877
|
-
// Plain "abc" == "abc"^^xsd:string (but not language-tagged strings)
|
|
878
|
-
if (literalsEquivalentAsXsdString(a.value, b.value)) return true;
|
|
879
|
-
|
|
880
|
-
// Keep in sync with unifyTerm(): numeric-value equality, datatype-aware.
|
|
881
|
-
const ai = parseNumericLiteralInfo(a);
|
|
882
|
-
const bi = parseNumericLiteralInfo(b);
|
|
844
|
+
function __isRdfNilEmptyListPair(a, b) {
|
|
845
|
+
return a instanceof Iri && a.value === RDF_NIL_IRI && b instanceof ListTerm && b.elems.length === 0;
|
|
846
|
+
}
|
|
883
847
|
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
if (ai.kind === 'bigint' && bi.kind === 'bigint') return ai.value === bi.value;
|
|
848
|
+
function __numericInfosSameDatatypeEqual(ai, bi, exactDecimal) {
|
|
849
|
+
if (!ai || !bi || ai.dt !== bi.dt) return false;
|
|
850
|
+
if (ai.kind === 'bigint' && bi.kind === 'bigint') return ai.value === bi.value;
|
|
888
851
|
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
852
|
+
if (exactDecimal && ai.dt === XSD_NS + 'decimal') {
|
|
853
|
+
const da = parseXsdDecimalToBigIntScale(ai.lexStr);
|
|
854
|
+
const db = parseXsdDecimalToBigIntScale(bi.lexStr);
|
|
855
|
+
if (da && db) {
|
|
856
|
+
const scale = Math.max(da.scale, db.scale);
|
|
857
|
+
return da.num * pow10n(scale - da.scale) === db.num * pow10n(scale - db.scale);
|
|
893
858
|
}
|
|
894
|
-
|
|
895
|
-
return false;
|
|
896
859
|
}
|
|
897
860
|
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
if (a.elems.length !== b.elems.length) return false;
|
|
903
|
-
for (let i = 0; i < a.elems.length; i++) {
|
|
904
|
-
if (!termsEqual(a.elems[i], b.elems[i])) return false;
|
|
905
|
-
}
|
|
906
|
-
return true;
|
|
907
|
-
}
|
|
861
|
+
const an = ai.kind === 'bigint' ? Number(ai.value) : ai.value;
|
|
862
|
+
const bn = bi.kind === 'bigint' ? Number(bi.value) : bi.value;
|
|
863
|
+
return !Number.isNaN(an) && !Number.isNaN(bn) && an === bn;
|
|
864
|
+
}
|
|
908
865
|
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
}
|
|
915
|
-
return true;
|
|
916
|
-
}
|
|
866
|
+
function __literalsEqual(a, b, exactDecimal) {
|
|
867
|
+
if (a.value === b.value) return true;
|
|
868
|
+
if (literalsEquivalentAsXsdString(a.value, b.value)) return true;
|
|
869
|
+
return __numericInfosSameDatatypeEqual(parseNumericLiteralInfo(a), parseNumericLiteralInfo(b), exactDecimal);
|
|
870
|
+
}
|
|
917
871
|
|
|
918
|
-
|
|
919
|
-
|
|
872
|
+
function __termArraysEqual(xs, ys, eq) {
|
|
873
|
+
if (xs.length !== ys.length) return false;
|
|
874
|
+
for (let i = 0; i < xs.length; i++) {
|
|
875
|
+
if (!eq(xs[i], ys[i])) return false;
|
|
920
876
|
}
|
|
921
|
-
|
|
922
|
-
return false;
|
|
877
|
+
return true;
|
|
923
878
|
}
|
|
924
879
|
|
|
925
|
-
function
|
|
880
|
+
function __termsEqual(a, b, exactDecimal) {
|
|
926
881
|
if (a === b) return true;
|
|
927
882
|
if (!a || !b) return false;
|
|
928
883
|
if (a.__tid && b.__tid && a.__tid === b.__tid) return true;
|
|
929
884
|
|
|
930
885
|
// rdf:nil is equivalent to the empty list ()
|
|
931
|
-
if (a
|
|
932
|
-
if (b instanceof Iri && b.value === RDF_NIL_IRI && a instanceof ListTerm && a.elems.length === 0) return true;
|
|
886
|
+
if (__isRdfNilEmptyListPair(a, b) || __isRdfNilEmptyListPair(b, a)) return true;
|
|
933
887
|
if (a.constructor !== b.constructor) return false;
|
|
934
888
|
|
|
935
889
|
if (a instanceof Iri) return a.value === b.value;
|
|
936
|
-
|
|
937
|
-
if (a instanceof Literal) {
|
|
938
|
-
if (a.value === b.value) return true;
|
|
939
|
-
|
|
940
|
-
// Plain "abc" == "abc"^^xsd:string (but not language-tagged)
|
|
941
|
-
if (literalsEquivalentAsXsdString(a.value, b.value)) return true;
|
|
942
|
-
|
|
943
|
-
// Numeric equality ONLY when datatypes agree (no integer<->decimal here)
|
|
944
|
-
const ai = parseNumericLiteralInfo(a);
|
|
945
|
-
const bi = parseNumericLiteralInfo(b);
|
|
946
|
-
if (ai && bi && ai.dt === bi.dt) {
|
|
947
|
-
// integer: exact bigint
|
|
948
|
-
if (ai.kind === 'bigint' && bi.kind === 'bigint') return ai.value === bi.value;
|
|
949
|
-
|
|
950
|
-
// decimal: compare exactly via num/scale if possible
|
|
951
|
-
if (ai.dt === XSD_NS + 'decimal') {
|
|
952
|
-
const da = parseXsdDecimalToBigIntScale(ai.lexStr);
|
|
953
|
-
const db = parseXsdDecimalToBigIntScale(bi.lexStr);
|
|
954
|
-
if (da && db) {
|
|
955
|
-
const scale = Math.max(da.scale, db.scale);
|
|
956
|
-
const na = da.num * pow10n(scale - da.scale);
|
|
957
|
-
const nb = db.num * pow10n(scale - db.scale);
|
|
958
|
-
return na === nb;
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
// double/float-ish: JS number (same as your normal same-dt path)
|
|
963
|
-
const an = ai.kind === 'bigint' ? Number(ai.value) : ai.value;
|
|
964
|
-
const bn = bi.kind === 'bigint' ? Number(bi.value) : bi.value;
|
|
965
|
-
return !Number.isNaN(an) && !Number.isNaN(bn) && an === bn;
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
return false;
|
|
969
|
-
}
|
|
970
|
-
|
|
890
|
+
if (a instanceof Literal) return __literalsEqual(a, b, exactDecimal);
|
|
971
891
|
if (a instanceof Var) return a.name === b.name;
|
|
972
892
|
if (a instanceof Blank) return a.label === b.label;
|
|
893
|
+
if (a instanceof ListTerm) return __termArraysEqual(a.elems, b.elems, (x, y) => __termsEqual(x, y, exactDecimal));
|
|
894
|
+
if (a instanceof OpenListTerm)
|
|
895
|
+
return a.tailVar === b.tailVar && __termArraysEqual(a.prefix, b.prefix, (x, y) => __termsEqual(x, y, exactDecimal));
|
|
896
|
+
if (a instanceof GraphTerm) return alphaEqGraphTriples(a.triples, b.triples);
|
|
897
|
+
return false;
|
|
898
|
+
}
|
|
973
899
|
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
}
|
|
979
|
-
return true;
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
if (a instanceof OpenListTerm) {
|
|
983
|
-
if (a.tailVar !== b.tailVar) return false;
|
|
984
|
-
if (a.prefix.length !== b.prefix.length) return false;
|
|
985
|
-
for (let i = 0; i < a.prefix.length; i++) {
|
|
986
|
-
if (!termsEqualNoIntDecimal(a.prefix[i], b.prefix[i])) return false;
|
|
987
|
-
}
|
|
988
|
-
return true;
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
if (a instanceof GraphTerm) {
|
|
992
|
-
return alphaEqGraphTriples(a.triples, b.triples);
|
|
993
|
-
}
|
|
900
|
+
function termsEqual(a, b) {
|
|
901
|
+
// Keep in sync with unifyTerm(): numeric-value equality, datatype-aware.
|
|
902
|
+
return __termsEqual(a, b, false);
|
|
903
|
+
}
|
|
994
904
|
|
|
995
|
-
|
|
905
|
+
function termsEqualNoIntDecimal(a, b) {
|
|
906
|
+
// Numeric equality ONLY when datatypes agree; decimals are compared exactly.
|
|
907
|
+
return __termsEqual(a, b, true);
|
|
996
908
|
}
|
|
997
909
|
|
|
998
910
|
function triplesEqual(a, b) {
|
|
@@ -1337,81 +1249,12 @@ function tripleFastKey(tr) {
|
|
|
1337
1249
|
}
|
|
1338
1250
|
|
|
1339
1251
|
function ensureFactIndexes(facts) {
|
|
1340
|
-
if (
|
|
1341
|
-
facts.__byPred &&
|
|
1342
|
-
facts.__byPS &&
|
|
1343
|
-
facts.__byPO &&
|
|
1344
|
-
facts.__byPNonFastS &&
|
|
1345
|
-
facts.__byPNonFastO &&
|
|
1346
|
-
facts.__varPred &&
|
|
1347
|
-
facts.__varPredPS &&
|
|
1348
|
-
facts.__varPredPO &&
|
|
1349
|
-
facts.__varPredNonFastS &&
|
|
1350
|
-
facts.__varPredNonFastO &&
|
|
1351
|
-
facts.__keySet
|
|
1352
|
-
)
|
|
1353
|
-
return;
|
|
1252
|
+
if (FACT_INDEX_REQUIRED_FIELDS.every((name) => facts[name])) return;
|
|
1354
1253
|
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
});
|
|
1360
|
-
Object.defineProperty(facts, '__byPS', {
|
|
1361
|
-
value: new Map(),
|
|
1362
|
-
enumerable: false,
|
|
1363
|
-
writable: true,
|
|
1364
|
-
});
|
|
1365
|
-
Object.defineProperty(facts, '__byPO', {
|
|
1366
|
-
value: new Map(),
|
|
1367
|
-
enumerable: false,
|
|
1368
|
-
writable: true,
|
|
1369
|
-
});
|
|
1370
|
-
Object.defineProperty(facts, '__byPNonFastS', {
|
|
1371
|
-
value: new Map(),
|
|
1372
|
-
enumerable: false,
|
|
1373
|
-
writable: true,
|
|
1374
|
-
});
|
|
1375
|
-
Object.defineProperty(facts, '__byPNonFastO', {
|
|
1376
|
-
value: new Map(),
|
|
1377
|
-
enumerable: false,
|
|
1378
|
-
writable: true,
|
|
1379
|
-
});
|
|
1380
|
-
Object.defineProperty(facts, '__varPred', {
|
|
1381
|
-
value: [],
|
|
1382
|
-
enumerable: false,
|
|
1383
|
-
writable: true,
|
|
1384
|
-
});
|
|
1385
|
-
Object.defineProperty(facts, '__varPredPS', {
|
|
1386
|
-
value: new Map(),
|
|
1387
|
-
enumerable: false,
|
|
1388
|
-
writable: true,
|
|
1389
|
-
});
|
|
1390
|
-
Object.defineProperty(facts, '__varPredPO', {
|
|
1391
|
-
value: new Map(),
|
|
1392
|
-
enumerable: false,
|
|
1393
|
-
writable: true,
|
|
1394
|
-
});
|
|
1395
|
-
Object.defineProperty(facts, '__varPredNonFastS', {
|
|
1396
|
-
value: [],
|
|
1397
|
-
enumerable: false,
|
|
1398
|
-
writable: true,
|
|
1399
|
-
});
|
|
1400
|
-
Object.defineProperty(facts, '__varPredNonFastO', {
|
|
1401
|
-
value: [],
|
|
1402
|
-
enumerable: false,
|
|
1403
|
-
writable: true,
|
|
1404
|
-
});
|
|
1405
|
-
Object.defineProperty(facts, '__keySet', {
|
|
1406
|
-
value: new Set(),
|
|
1407
|
-
enumerable: false,
|
|
1408
|
-
writable: true,
|
|
1409
|
-
});
|
|
1410
|
-
Object.defineProperty(facts, '__keySetComplete', {
|
|
1411
|
-
value: false,
|
|
1412
|
-
enumerable: false,
|
|
1413
|
-
writable: true,
|
|
1414
|
-
});
|
|
1254
|
+
for (const name of FACT_INDEX_MAP_FIELDS) __defineHiddenWritable(facts, name, new Map());
|
|
1255
|
+
for (const name of FACT_INDEX_ARRAY_FIELDS) __defineHiddenWritable(facts, name, []);
|
|
1256
|
+
__defineHiddenWritable(facts, '__keySet', new Set());
|
|
1257
|
+
__defineHiddenWritable(facts, '__keySetComplete', false);
|
|
1415
1258
|
|
|
1416
1259
|
// Build lookup indexes eagerly, but do not populate the duplicate-detection
|
|
1417
1260
|
// string Set for every input fact. The predicate/subject/object indexes are
|
|
@@ -1439,45 +1282,14 @@ function cloneFactIndexesForSnapshot(src, dest) {
|
|
|
1439
1282
|
return out;
|
|
1440
1283
|
}
|
|
1441
1284
|
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
enumerable: false,
|
|
1448
|
-
writable: true,
|
|
1449
|
-
});
|
|
1450
|
-
Object.defineProperty(dest, '__byPNonFastO', {
|
|
1451
|
-
value: cloneArrayMap(src.__byPNonFastO),
|
|
1452
|
-
enumerable: false,
|
|
1453
|
-
writable: true,
|
|
1454
|
-
});
|
|
1455
|
-
Object.defineProperty(dest, '__varPred', { value: src.__varPred.slice(), enumerable: false, writable: true });
|
|
1456
|
-
Object.defineProperty(dest, '__varPredPS', {
|
|
1457
|
-
value: cloneArrayMap(src.__varPredPS),
|
|
1458
|
-
enumerable: false,
|
|
1459
|
-
writable: true,
|
|
1460
|
-
});
|
|
1461
|
-
Object.defineProperty(dest, '__varPredPO', {
|
|
1462
|
-
value: cloneArrayMap(src.__varPredPO),
|
|
1463
|
-
enumerable: false,
|
|
1464
|
-
writable: true,
|
|
1465
|
-
});
|
|
1466
|
-
Object.defineProperty(dest, '__varPredNonFastS', {
|
|
1467
|
-
value: src.__varPredNonFastS.slice(),
|
|
1468
|
-
enumerable: false,
|
|
1469
|
-
writable: true,
|
|
1470
|
-
});
|
|
1471
|
-
Object.defineProperty(dest, '__varPredNonFastO', {
|
|
1472
|
-
value: src.__varPredNonFastO.slice(),
|
|
1473
|
-
enumerable: false,
|
|
1474
|
-
writable: true,
|
|
1475
|
-
});
|
|
1476
|
-
Object.defineProperty(dest, '__keySet', { value: new Set(src.__keySet), enumerable: false, writable: true });
|
|
1477
|
-
Object.defineProperty(dest, '__keySetComplete', { value: !!src.__keySetComplete, enumerable: false, writable: true });
|
|
1285
|
+
for (const name of FACT_INDEX_ARRAY_MAP_FIELDS) __defineHiddenWritable(dest, name, cloneArrayMap(src[name]));
|
|
1286
|
+
for (const name of FACT_INDEX_NESTED_ARRAY_MAP_FIELDS) __defineHiddenWritable(dest, name, cloneNestedArrayMap(src[name]));
|
|
1287
|
+
for (const name of FACT_INDEX_ARRAY_FIELDS) __defineHiddenWritable(dest, name, src[name].slice());
|
|
1288
|
+
__defineHiddenWritable(dest, '__keySet', new Set(src.__keySet));
|
|
1289
|
+
__defineHiddenWritable(dest, '__keySetComplete', !!src.__keySetComplete);
|
|
1478
1290
|
}
|
|
1479
1291
|
|
|
1480
|
-
function
|
|
1292
|
+
function pushMapArray(map, key, value) {
|
|
1481
1293
|
let bucket = map.get(key);
|
|
1482
1294
|
if (!bucket) {
|
|
1483
1295
|
bucket = [];
|
|
@@ -1486,6 +1298,15 @@ function addToIndexArrayMap(map, key, value) {
|
|
|
1486
1298
|
bucket.push(value);
|
|
1487
1299
|
}
|
|
1488
1300
|
|
|
1301
|
+
function getOrCreateMap(map, key) {
|
|
1302
|
+
let inner = map.get(key);
|
|
1303
|
+
if (!inner) {
|
|
1304
|
+
inner = new Map();
|
|
1305
|
+
map.set(key, inner);
|
|
1306
|
+
}
|
|
1307
|
+
return inner;
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1489
1310
|
function indexFact(facts, tr, idx, addKeySet = true) {
|
|
1490
1311
|
const sk = termLookupKey(tr.s);
|
|
1491
1312
|
const ok = termLookupKey(tr.o);
|
|
@@ -1496,45 +1317,30 @@ function indexFact(facts, tr, idx, addKeySet = true) {
|
|
|
1496
1317
|
const pk = tr.p.__tid;
|
|
1497
1318
|
pkForKey = pk;
|
|
1498
1319
|
|
|
1499
|
-
|
|
1500
|
-
if (!pb) {
|
|
1501
|
-
pb = [];
|
|
1502
|
-
facts.__byPred.set(pk, pb);
|
|
1503
|
-
}
|
|
1504
|
-
pb.push(idx);
|
|
1320
|
+
pushMapArray(facts.__byPred, pk, idx);
|
|
1505
1321
|
|
|
1506
1322
|
if (sk !== null) {
|
|
1507
|
-
|
|
1508
|
-
if (!ps) {
|
|
1509
|
-
ps = new Map();
|
|
1510
|
-
facts.__byPS.set(pk, ps);
|
|
1511
|
-
}
|
|
1512
|
-
addToIndexArrayMap(ps, sk, idx);
|
|
1323
|
+
pushMapArray(getOrCreateMap(facts.__byPS, pk), sk, idx);
|
|
1513
1324
|
} else {
|
|
1514
|
-
|
|
1325
|
+
pushMapArray(facts.__byPNonFastS, pk, idx);
|
|
1515
1326
|
}
|
|
1516
1327
|
|
|
1517
1328
|
if (ok !== null) {
|
|
1518
|
-
|
|
1519
|
-
if (!po) {
|
|
1520
|
-
po = new Map();
|
|
1521
|
-
facts.__byPO.set(pk, po);
|
|
1522
|
-
}
|
|
1523
|
-
addToIndexArrayMap(po, ok, idx);
|
|
1329
|
+
pushMapArray(getOrCreateMap(facts.__byPO, pk), ok, idx);
|
|
1524
1330
|
} else {
|
|
1525
|
-
|
|
1331
|
+
pushMapArray(facts.__byPNonFastO, pk, idx);
|
|
1526
1332
|
}
|
|
1527
1333
|
} else if (tr.p instanceof Var) {
|
|
1528
1334
|
facts.__varPred.push(idx);
|
|
1529
1335
|
|
|
1530
1336
|
if (sk !== null) {
|
|
1531
|
-
|
|
1337
|
+
pushMapArray(facts.__varPredPS, sk, idx);
|
|
1532
1338
|
} else {
|
|
1533
1339
|
facts.__varPredNonFastS.push(idx);
|
|
1534
1340
|
}
|
|
1535
1341
|
|
|
1536
1342
|
if (ok !== null) {
|
|
1537
|
-
|
|
1343
|
+
pushMapArray(facts.__varPredPO, ok, idx);
|
|
1538
1344
|
} else {
|
|
1539
1345
|
facts.__varPredNonFastO.push(idx);
|
|
1540
1346
|
}
|
|
@@ -1688,16 +1494,8 @@ function makeDerivedRecord(fact, rule, premises, subst, captureExplanations) {
|
|
|
1688
1494
|
function ensureBackRuleIndexes(backRules) {
|
|
1689
1495
|
if (backRules.__byHeadPred && backRules.__wildHeadPred) return;
|
|
1690
1496
|
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
enumerable: false,
|
|
1694
|
-
writable: true,
|
|
1695
|
-
});
|
|
1696
|
-
Object.defineProperty(backRules, '__wildHeadPred', {
|
|
1697
|
-
value: [],
|
|
1698
|
-
enumerable: false,
|
|
1699
|
-
writable: true,
|
|
1700
|
-
});
|
|
1497
|
+
__defineHiddenWritable(backRules, '__byHeadPred', new Map());
|
|
1498
|
+
__defineHiddenWritable(backRules, '__wildHeadPred', []);
|
|
1701
1499
|
|
|
1702
1500
|
for (const r of backRules) indexBackRule(backRules, r);
|
|
1703
1501
|
}
|
|
@@ -1706,13 +1504,7 @@ function indexBackRule(backRules, r) {
|
|
|
1706
1504
|
if (!r || !r.conclusion || r.conclusion.length !== 1) return;
|
|
1707
1505
|
const head = r.conclusion[0];
|
|
1708
1506
|
if (head && head.p instanceof Iri) {
|
|
1709
|
-
|
|
1710
|
-
let bucket = backRules.__byHeadPred.get(k);
|
|
1711
|
-
if (!bucket) {
|
|
1712
|
-
bucket = [];
|
|
1713
|
-
backRules.__byHeadPred.set(k, bucket);
|
|
1714
|
-
}
|
|
1715
|
-
bucket.push(r);
|
|
1507
|
+
pushMapArray(backRules.__byHeadPred, head.p.__tid, r);
|
|
1716
1508
|
} else {
|
|
1717
1509
|
backRules.__wildHeadPred.push(r);
|
|
1718
1510
|
}
|
|
@@ -1747,12 +1539,11 @@ function isSinglePremiseAgendaRuleSafe(r, backRules) {
|
|
|
1747
1539
|
return backRules.__wildHeadPred.length === 0;
|
|
1748
1540
|
}
|
|
1749
1541
|
|
|
1750
|
-
function mergeSinglePremiseAgendaBuckets() {
|
|
1542
|
+
function mergeSinglePremiseAgendaBuckets(...buckets) {
|
|
1751
1543
|
let out = null;
|
|
1752
1544
|
let seen = null;
|
|
1753
1545
|
|
|
1754
|
-
for (
|
|
1755
|
-
const bucket = arguments[i];
|
|
1546
|
+
for (const bucket of buckets) {
|
|
1756
1547
|
if (!bucket || bucket.length === 0) continue;
|
|
1757
1548
|
|
|
1758
1549
|
if (out === null) {
|
|
@@ -1762,8 +1553,7 @@ function mergeSinglePremiseAgendaBuckets() {
|
|
|
1762
1553
|
}
|
|
1763
1554
|
|
|
1764
1555
|
if (!seen) seen = new Set(out);
|
|
1765
|
-
for (
|
|
1766
|
-
const entry = bucket[j];
|
|
1556
|
+
for (const entry of bucket) {
|
|
1767
1557
|
if (seen.has(entry)) continue;
|
|
1768
1558
|
seen.add(entry);
|
|
1769
1559
|
out.push(entry);
|
|
@@ -1773,18 +1563,6 @@ function mergeSinglePremiseAgendaBuckets() {
|
|
|
1773
1563
|
return out;
|
|
1774
1564
|
}
|
|
1775
1565
|
|
|
1776
|
-
function termContainsVarForAgenda(t) {
|
|
1777
|
-
if (t instanceof Var) return true;
|
|
1778
|
-
if (t instanceof ListTerm) return t.elems.some(termContainsVarForAgenda);
|
|
1779
|
-
if (t instanceof OpenListTerm) return true;
|
|
1780
|
-
if (t instanceof GraphTerm)
|
|
1781
|
-
return t.triples.some(
|
|
1782
|
-
(tr) =>
|
|
1783
|
-
termContainsVarForAgenda(tr.s) || termContainsVarForAgenda(tr.p) || termContainsVarForAgenda(tr.o),
|
|
1784
|
-
);
|
|
1785
|
-
return false;
|
|
1786
|
-
}
|
|
1787
|
-
|
|
1788
1566
|
function makeSinglePremiseAgendaIndex(forwardRules, backRules) {
|
|
1789
1567
|
const index = {
|
|
1790
1568
|
byPred: new Map(),
|
|
@@ -1799,15 +1577,6 @@ function makeSinglePremiseAgendaIndex(forwardRules, backRules) {
|
|
|
1799
1577
|
size: 0,
|
|
1800
1578
|
};
|
|
1801
1579
|
|
|
1802
|
-
function addToMapArray(m, k, v) {
|
|
1803
|
-
let bucket = m.get(k);
|
|
1804
|
-
if (!bucket) {
|
|
1805
|
-
bucket = [];
|
|
1806
|
-
m.set(k, bucket);
|
|
1807
|
-
}
|
|
1808
|
-
bucket.push(v);
|
|
1809
|
-
}
|
|
1810
|
-
|
|
1811
1580
|
for (let i = 0; i < forwardRules.length; i++) {
|
|
1812
1581
|
const r = forwardRules[i];
|
|
1813
1582
|
if (!isSinglePremiseAgendaRuleSafe(r, backRules)) continue;
|
|
@@ -1833,29 +1602,15 @@ function makeSinglePremiseAgendaIndex(forwardRules, backRules) {
|
|
|
1833
1602
|
index.size += 1;
|
|
1834
1603
|
|
|
1835
1604
|
if (entry.goalPredTid !== null) {
|
|
1836
|
-
|
|
1605
|
+
pushMapArray(index.byPredAll, entry.goalPredTid, entry);
|
|
1837
1606
|
index.allIriPred.push(entry);
|
|
1838
|
-
if (entry.goalSKey === null && entry.goalOKey === null)
|
|
1839
|
-
if (entry.goalSKey !== null)
|
|
1840
|
-
|
|
1841
|
-
if (!ps) {
|
|
1842
|
-
ps = new Map();
|
|
1843
|
-
index.byPS.set(entry.goalPredTid, ps);
|
|
1844
|
-
}
|
|
1845
|
-
addToMapArray(ps, entry.goalSKey, entry);
|
|
1846
|
-
}
|
|
1847
|
-
if (entry.goalOKey !== null) {
|
|
1848
|
-
let po = index.byPO.get(entry.goalPredTid);
|
|
1849
|
-
if (!po) {
|
|
1850
|
-
po = new Map();
|
|
1851
|
-
index.byPO.set(entry.goalPredTid, po);
|
|
1852
|
-
}
|
|
1853
|
-
addToMapArray(po, entry.goalOKey, entry);
|
|
1854
|
-
}
|
|
1607
|
+
if (entry.goalSKey === null && entry.goalOKey === null) pushMapArray(index.byPred, entry.goalPredTid, entry);
|
|
1608
|
+
if (entry.goalSKey !== null) pushMapArray(getOrCreateMap(index.byPS, entry.goalPredTid), entry.goalSKey, entry);
|
|
1609
|
+
if (entry.goalOKey !== null) pushMapArray(getOrCreateMap(index.byPO, entry.goalPredTid), entry.goalOKey, entry);
|
|
1855
1610
|
} else {
|
|
1856
1611
|
if (entry.goalSKey === null && entry.goalOKey === null) index.wildPred.push(entry);
|
|
1857
|
-
if (entry.goalSKey !== null)
|
|
1858
|
-
if (entry.goalOKey !== null)
|
|
1612
|
+
if (entry.goalSKey !== null) pushMapArray(index.wildPS, entry.goalSKey, entry);
|
|
1613
|
+
if (entry.goalOKey !== null) pushMapArray(index.wildPO, entry.goalOKey, entry);
|
|
1859
1614
|
}
|
|
1860
1615
|
}
|
|
1861
1616
|
|
|
@@ -1871,7 +1626,7 @@ function getSinglePremiseAgendaCandidates(index, fact) {
|
|
|
1871
1626
|
let exact = null;
|
|
1872
1627
|
if (fact.p instanceof Iri) {
|
|
1873
1628
|
const pk = fact.p.__tid;
|
|
1874
|
-
if ((sk === null &&
|
|
1629
|
+
if ((sk === null && containsVarTerm(fact.s)) || (ok === null && containsVarTerm(fact.o))) {
|
|
1875
1630
|
// A fact with a variable-bearing subject/object (most importantly a
|
|
1876
1631
|
// top-level variable fact such as `?S :p ?O.`) can match rules whose
|
|
1877
1632
|
// premise is fixed in that position. The ordinary `(p,s)` / `(p,o)` lookup
|
|
@@ -1916,11 +1671,11 @@ function getSinglePremiseAgendaCandidates(index, fact) {
|
|
|
1916
1671
|
// ===========================================================================
|
|
1917
1672
|
|
|
1918
1673
|
function isLogImplies(p) {
|
|
1919
|
-
return p instanceof Iri && p.value ===
|
|
1674
|
+
return p instanceof Iri && p.value === LOG_IMPLIES_IRI;
|
|
1920
1675
|
}
|
|
1921
1676
|
|
|
1922
1677
|
function isLogImpliedBy(p) {
|
|
1923
|
-
return p instanceof Iri && p.value ===
|
|
1678
|
+
return p instanceof Iri && p.value === LOG_IMPLIED_BY_IRI;
|
|
1924
1679
|
}
|
|
1925
1680
|
|
|
1926
1681
|
// ===========================================================================
|
|
@@ -1953,16 +1708,7 @@ function __makeGoalTable() {
|
|
|
1953
1708
|
|
|
1954
1709
|
function __attachGoalTable(scopeCarrier, goalTable) {
|
|
1955
1710
|
if (!scopeCarrier) return goalTable;
|
|
1956
|
-
|
|
1957
|
-
Object.defineProperty(scopeCarrier, 'goalTable', {
|
|
1958
|
-
value: goalTable,
|
|
1959
|
-
enumerable: false,
|
|
1960
|
-
writable: true,
|
|
1961
|
-
configurable: true,
|
|
1962
|
-
});
|
|
1963
|
-
} else {
|
|
1964
|
-
scopeCarrier.goalTable = goalTable;
|
|
1965
|
-
}
|
|
1711
|
+
__setHiddenWritable(scopeCarrier, 'goalTable', goalTable);
|
|
1966
1712
|
return goalTable;
|
|
1967
1713
|
}
|
|
1968
1714
|
|
|
@@ -2017,11 +1763,10 @@ function __canStoreGoalMemo(visited, maxResults) {
|
|
|
2017
1763
|
// Unification + substitution
|
|
2018
1764
|
// ===========================================================================
|
|
2019
1765
|
|
|
2020
|
-
function containsVarTerm(t, v) {
|
|
2021
|
-
if (t instanceof
|
|
2022
|
-
if (t instanceof Var) return t.name === v;
|
|
1766
|
+
function containsVarTerm(t, v = null) {
|
|
1767
|
+
if (t instanceof Var) return v === null || t.name === v;
|
|
2023
1768
|
if (t instanceof ListTerm) return t.elems.some((e) => containsVarTerm(e, v));
|
|
2024
|
-
if (t instanceof OpenListTerm) return t.prefix.some((e) => containsVarTerm(e, v)) || t.tailVar === v;
|
|
1769
|
+
if (t instanceof OpenListTerm) return t.prefix.some((e) => containsVarTerm(e, v)) || v === null || t.tailVar === v;
|
|
2025
1770
|
if (t instanceof GraphTerm)
|
|
2026
1771
|
return t.triples.some((tr) => containsVarTerm(tr.s, v) || containsVarTerm(tr.p, v) || containsVarTerm(tr.o, v));
|
|
2027
1772
|
return false;
|
|
@@ -2226,16 +1971,8 @@ function unifyOpenWithList(prefix, tailv, ys, subst) {
|
|
|
2226
1971
|
}
|
|
2227
1972
|
|
|
2228
1973
|
function graphTriplesContainVars(triples) {
|
|
2229
|
-
function termHasVar(t) {
|
|
2230
|
-
if (t instanceof Var) return true;
|
|
2231
|
-
if (t instanceof ListTerm) return t.elems.some(termHasVar);
|
|
2232
|
-
if (t instanceof OpenListTerm) return t.prefix.some(termHasVar) || true;
|
|
2233
|
-
if (t instanceof GraphTerm) return t.triples.some((tr) => termHasVar(tr.s) || termHasVar(tr.p) || termHasVar(tr.o));
|
|
2234
|
-
return false;
|
|
2235
|
-
}
|
|
2236
|
-
|
|
2237
1974
|
for (const tr of triples) {
|
|
2238
|
-
if (
|
|
1975
|
+
if (containsVarTerm(tr.s) || containsVarTerm(tr.p) || containsVarTerm(tr.o)) return true;
|
|
2239
1976
|
}
|
|
2240
1977
|
return false;
|
|
2241
1978
|
}
|
|
@@ -2520,19 +2257,7 @@ function __tripleHasVarOrBlank(tr) {
|
|
|
2520
2257
|
}
|
|
2521
2258
|
|
|
2522
2259
|
function __builtinIsSatisfiableWhenFullyUnbound(pIriVal) {
|
|
2523
|
-
return (
|
|
2524
|
-
pIriVal === MATH_NS + 'sin' ||
|
|
2525
|
-
pIriVal === MATH_NS + 'cos' ||
|
|
2526
|
-
pIriVal === MATH_NS + 'tan' ||
|
|
2527
|
-
pIriVal === MATH_NS + 'asin' ||
|
|
2528
|
-
pIriVal === MATH_NS + 'acos' ||
|
|
2529
|
-
pIriVal === MATH_NS + 'atan' ||
|
|
2530
|
-
pIriVal === MATH_NS + 'sinh' ||
|
|
2531
|
-
pIriVal === MATH_NS + 'cosh' ||
|
|
2532
|
-
pIriVal === MATH_NS + 'tanh' ||
|
|
2533
|
-
pIriVal === MATH_NS + 'degrees' ||
|
|
2534
|
-
pIriVal === MATH_NS + 'negation'
|
|
2535
|
-
);
|
|
2260
|
+
return MATH_BUILTINS_SATISFIABLE_WHEN_FULLY_UNBOUND.has(pIriVal);
|
|
2536
2261
|
}
|
|
2537
2262
|
|
|
2538
2263
|
function proveGoals(goals, subst, facts, backRules, depth, visited, varGen, maxResults, opts) {
|
|
@@ -3167,12 +2892,7 @@ function __proofTripleKey(tr) {
|
|
|
3167
2892
|
|
|
3168
2893
|
function __copyProofSource(from, to) {
|
|
3169
2894
|
if (from && to && Object.prototype.hasOwnProperty.call(from, '__source')) {
|
|
3170
|
-
|
|
3171
|
-
value: from.__source,
|
|
3172
|
-
enumerable: false,
|
|
3173
|
-
writable: false,
|
|
3174
|
-
configurable: true,
|
|
3175
|
-
});
|
|
2895
|
+
__defineHiddenValue(to, '__source', from.__source);
|
|
3176
2896
|
}
|
|
3177
2897
|
return to;
|
|
3178
2898
|
}
|
|
@@ -3184,12 +2904,7 @@ function __annotateProofVarSourceNames(rule) {
|
|
|
3184
2904
|
const m = /^(.*)__\d+$/.exec(name);
|
|
3185
2905
|
sourceNames[name] = m ? m[1] : name;
|
|
3186
2906
|
}
|
|
3187
|
-
|
|
3188
|
-
value: sourceNames,
|
|
3189
|
-
enumerable: false,
|
|
3190
|
-
writable: false,
|
|
3191
|
-
configurable: true,
|
|
3192
|
-
});
|
|
2907
|
+
__defineHiddenValue(rule, '__proofVarSourceNames', sourceNames);
|
|
3193
2908
|
return rule;
|
|
3194
2909
|
}
|
|
3195
2910
|
|
|
@@ -3395,45 +3110,16 @@ function forwardChain(facts, forwardRules, backRules, onDerived /* optional */,
|
|
|
3395
3110
|
// until a scoped snapshot exists (or a given closure level is reached).
|
|
3396
3111
|
// Helper functions are module-scoped: __computeForwardRuleScopedSkipInfo, etc.
|
|
3397
3112
|
function setScopedSnapshot(snap, level) {
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
value: snap,
|
|
3401
|
-
enumerable: false,
|
|
3402
|
-
writable: true,
|
|
3403
|
-
configurable: true,
|
|
3404
|
-
});
|
|
3405
|
-
} else {
|
|
3406
|
-
facts.__scopedSnapshot = snap;
|
|
3407
|
-
}
|
|
3408
|
-
|
|
3409
|
-
if (!hasOwn.call(facts, '__scopedClosureLevel')) {
|
|
3410
|
-
Object.defineProperty(facts, '__scopedClosureLevel', {
|
|
3411
|
-
value: level,
|
|
3412
|
-
enumerable: false,
|
|
3413
|
-
writable: true,
|
|
3414
|
-
configurable: true,
|
|
3415
|
-
});
|
|
3416
|
-
} else {
|
|
3417
|
-
facts.__scopedClosureLevel = level;
|
|
3418
|
-
}
|
|
3113
|
+
__setHiddenWritable(facts, '__scopedSnapshot', snap);
|
|
3114
|
+
__setHiddenWritable(facts, '__scopedClosureLevel', level);
|
|
3419
3115
|
}
|
|
3420
3116
|
|
|
3421
3117
|
function makeScopedSnapshot() {
|
|
3422
3118
|
const snap = facts.slice();
|
|
3423
3119
|
cloneFactIndexesForSnapshot(facts, snap);
|
|
3424
|
-
|
|
3425
|
-
value: snap,
|
|
3426
|
-
enumerable: false,
|
|
3427
|
-
writable: true,
|
|
3428
|
-
configurable: true,
|
|
3429
|
-
});
|
|
3120
|
+
__defineHiddenWritable(snap, '__scopedSnapshot', snap);
|
|
3430
3121
|
// Propagate closure level so nested scoped builtins can see it.
|
|
3431
|
-
|
|
3432
|
-
value: scopedClosureLevel,
|
|
3433
|
-
enumerable: false,
|
|
3434
|
-
writable: true,
|
|
3435
|
-
configurable: true,
|
|
3436
|
-
});
|
|
3122
|
+
__defineHiddenWritable(snap, '__scopedClosureLevel', scopedClosureLevel);
|
|
3437
3123
|
return snap;
|
|
3438
3124
|
}
|
|
3439
3125
|
|
|
@@ -3781,36 +3467,12 @@ function __withScopedSnapshotForQueries(facts, fn) {
|
|
|
3781
3467
|
// Create a frozen snapshot of the saturated closure.
|
|
3782
3468
|
const snap = facts.slice();
|
|
3783
3469
|
ensureFactIndexes(snap);
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
enumerable: false,
|
|
3787
|
-
writable: true,
|
|
3788
|
-
configurable: true,
|
|
3789
|
-
});
|
|
3790
|
-
Object.defineProperty(snap, '__scopedClosureLevel', {
|
|
3791
|
-
value: Number.MAX_SAFE_INTEGER,
|
|
3792
|
-
enumerable: false,
|
|
3793
|
-
writable: true,
|
|
3794
|
-
configurable: true,
|
|
3795
|
-
});
|
|
3470
|
+
__defineHiddenWritable(snap, '__scopedSnapshot', snap);
|
|
3471
|
+
__defineHiddenWritable(snap, '__scopedClosureLevel', Number.MAX_SAFE_INTEGER);
|
|
3796
3472
|
|
|
3797
3473
|
// Ensure the live facts array exposes the snapshot/level for builtins.
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
value: null,
|
|
3801
|
-
enumerable: false,
|
|
3802
|
-
writable: true,
|
|
3803
|
-
configurable: true,
|
|
3804
|
-
});
|
|
3805
|
-
}
|
|
3806
|
-
if (!hasOwn.call(facts, '__scopedClosureLevel')) {
|
|
3807
|
-
Object.defineProperty(facts, '__scopedClosureLevel', {
|
|
3808
|
-
value: 0,
|
|
3809
|
-
enumerable: false,
|
|
3810
|
-
writable: true,
|
|
3811
|
-
configurable: true,
|
|
3812
|
-
});
|
|
3813
|
-
}
|
|
3474
|
+
__setHiddenWritable(facts, '__scopedSnapshot', null);
|
|
3475
|
+
__setHiddenWritable(facts, '__scopedClosureLevel', 0);
|
|
3814
3476
|
|
|
3815
3477
|
facts.__scopedSnapshot = snap;
|
|
3816
3478
|
facts.__scopedClosureLevel = Number.MAX_SAFE_INTEGER;
|