eyeling 1.26.1 → 1.26.3
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 +154 -372
- package/eyeling.js +154 -372
- package/lib/engine.js +154 -372
- package/package.json +1 -1
package/lib/engine.js
CHANGED
|
@@ -43,7 +43,7 @@ const EMPTY_LIST_TERM = new ListTerm([]);
|
|
|
43
43
|
const { lex, N3SyntaxError } = require('./lexer');
|
|
44
44
|
const { Parser } = require('./parser');
|
|
45
45
|
const { liftBlankRuleVars } = require('./rules');
|
|
46
|
-
const {
|
|
46
|
+
const { parseN3SourceList, parseN3Text } = require('./multisource');
|
|
47
47
|
|
|
48
48
|
const {
|
|
49
49
|
makeBuiltins,
|
|
@@ -100,6 +100,10 @@ function __cloneSubst(subst) {
|
|
|
100
100
|
return out;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
function __defineHiddenWritable(obj, name, value) {
|
|
104
|
+
Object.defineProperty(obj, name, { value, enumerable: false, writable: true });
|
|
105
|
+
}
|
|
106
|
+
|
|
103
107
|
let version = 'dev';
|
|
104
108
|
try {
|
|
105
109
|
// Node: keep package.json version if available
|
|
@@ -411,44 +415,29 @@ function __logNaturalPriorityFromTerm(t) {
|
|
|
411
415
|
function __computeMaxScopedClosurePriorityNeeded(forwardRules, backRules) {
|
|
412
416
|
let maxP = 0;
|
|
413
417
|
|
|
418
|
+
function bumpMaxPriority(term) {
|
|
419
|
+
if (term instanceof GraphTerm) return;
|
|
420
|
+
if (term instanceof Var) {
|
|
421
|
+
if (maxP < 1) maxP = 1;
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
const p0 = __logNaturalPriorityFromTerm(term);
|
|
425
|
+
const priority = p0 !== null ? p0 : 1;
|
|
426
|
+
if (priority > maxP) maxP = priority;
|
|
427
|
+
}
|
|
428
|
+
|
|
414
429
|
function scanTriple(tr) {
|
|
415
430
|
if (!(tr && tr.p instanceof Iri)) return;
|
|
416
431
|
const pv = tr.p.value;
|
|
417
432
|
|
|
418
433
|
// log:collectAllIn / log:forAllIn use the object position for the priority.
|
|
419
434
|
if (pv === LOG_NS + 'collectAllIn' || pv === LOG_NS + 'forAllIn') {
|
|
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
|
-
}
|
|
435
|
+
bumpMaxPriority(tr.o);
|
|
433
436
|
return;
|
|
434
437
|
}
|
|
435
438
|
|
|
436
439
|
// log:includes / log:notIncludes use the subject position for the priority.
|
|
437
|
-
if (pv === LOG_NS + 'includes' || pv === LOG_NS + 'notIncludes')
|
|
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
|
-
}
|
|
440
|
+
if (pv === LOG_NS + 'includes' || pv === LOG_NS + 'notIncludes') bumpMaxPriority(tr.s);
|
|
452
441
|
}
|
|
453
442
|
|
|
454
443
|
for (const r of forwardRules) {
|
|
@@ -485,7 +474,6 @@ function __varOccursElsewhereInPremise(premise, name, idx, field) {
|
|
|
485
474
|
return false;
|
|
486
475
|
}
|
|
487
476
|
|
|
488
|
-
|
|
489
477
|
function __scopedPriorityForTerm(t) {
|
|
490
478
|
if (t instanceof GraphTerm) return 0;
|
|
491
479
|
const p0 = __logNaturalPriorityFromTerm(t);
|
|
@@ -627,7 +615,6 @@ function __computeForwardRuleScopedStrata(forwardRules) {
|
|
|
627
615
|
if (!changed) break;
|
|
628
616
|
}
|
|
629
617
|
|
|
630
|
-
|
|
631
618
|
maxLevel = 0;
|
|
632
619
|
for (let i = 0; i < forwardRules.length; i++) {
|
|
633
620
|
__setForwardRuleScopedStratumInfo(forwardRules[i], levels[i]);
|
|
@@ -641,42 +628,33 @@ function __computeForwardRuleScopedSkipInfo(rule) {
|
|
|
641
628
|
let needsSnap = false;
|
|
642
629
|
let requiredLevel = 0;
|
|
643
630
|
|
|
631
|
+
function addScopedUse(scopeTerm, idx, field) {
|
|
632
|
+
if (scopeTerm instanceof GraphTerm) return true; // explicit scope
|
|
633
|
+
|
|
634
|
+
// If scope term is a Var that appears elsewhere, it might be bound to a GraphTerm.
|
|
635
|
+
// Be conservative and do not skip in that case.
|
|
636
|
+
if (scopeTerm instanceof Var) {
|
|
637
|
+
if (__varOccursElsewhereInPremise(rule.premise, scopeTerm.name, idx, field)) return false;
|
|
638
|
+
needsSnap = true;
|
|
639
|
+
requiredLevel = Math.max(requiredLevel, 1);
|
|
640
|
+
return true;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
needsSnap = true;
|
|
644
|
+
const p0 = __logNaturalPriorityFromTerm(scopeTerm);
|
|
645
|
+
requiredLevel = Math.max(requiredLevel, p0 !== null ? p0 : 1);
|
|
646
|
+
return true;
|
|
647
|
+
}
|
|
648
|
+
|
|
644
649
|
for (let i = 0; i < rule.premise.length; i++) {
|
|
645
650
|
const tr = rule.premise[i];
|
|
646
651
|
if (!(tr && tr.p instanceof Iri)) continue;
|
|
647
652
|
const pv = tr.p.value;
|
|
648
653
|
|
|
649
654
|
if (pv === LOG_NS + 'collectAllIn' || pv === LOG_NS + 'forAllIn') {
|
|
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
|
-
}
|
|
655
|
+
if (!addScopedUse(tr.o, i, 'o')) return null;
|
|
656
|
+
} else if (pv === LOG_NS + 'includes' || pv === LOG_NS + 'notIncludes') {
|
|
657
|
+
if (!addScopedUse(tr.s, i, 's')) return null;
|
|
680
658
|
}
|
|
681
659
|
}
|
|
682
660
|
|
|
@@ -859,140 +837,70 @@ function skolemizeTripleForHeadBlanks(tr, headBlankLabels, mapping, skCounter, f
|
|
|
859
837
|
// Alpha equivalence helpers
|
|
860
838
|
// ===========================================================================
|
|
861
839
|
|
|
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);
|
|
840
|
+
function __isRdfNilEmptyListPair(a, b) {
|
|
841
|
+
return a instanceof Iri && a.value === RDF_NIL_IRI && b instanceof ListTerm && b.elems.length === 0;
|
|
842
|
+
}
|
|
883
843
|
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
if (ai.kind === 'bigint' && bi.kind === 'bigint') return ai.value === bi.value;
|
|
844
|
+
function __numericInfosSameDatatypeEqual(ai, bi, exactDecimal) {
|
|
845
|
+
if (!ai || !bi || ai.dt !== bi.dt) return false;
|
|
846
|
+
if (ai.kind === 'bigint' && bi.kind === 'bigint') return ai.value === bi.value;
|
|
888
847
|
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
848
|
+
if (exactDecimal && ai.dt === XSD_NS + 'decimal') {
|
|
849
|
+
const da = parseXsdDecimalToBigIntScale(ai.lexStr);
|
|
850
|
+
const db = parseXsdDecimalToBigIntScale(bi.lexStr);
|
|
851
|
+
if (da && db) {
|
|
852
|
+
const scale = Math.max(da.scale, db.scale);
|
|
853
|
+
return da.num * pow10n(scale - da.scale) === db.num * pow10n(scale - db.scale);
|
|
893
854
|
}
|
|
894
|
-
|
|
895
|
-
return false;
|
|
896
855
|
}
|
|
897
856
|
|
|
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
|
-
}
|
|
857
|
+
const an = ai.kind === 'bigint' ? Number(ai.value) : ai.value;
|
|
858
|
+
const bn = bi.kind === 'bigint' ? Number(bi.value) : bi.value;
|
|
859
|
+
return !Number.isNaN(an) && !Number.isNaN(bn) && an === bn;
|
|
860
|
+
}
|
|
908
861
|
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
}
|
|
915
|
-
return true;
|
|
916
|
-
}
|
|
862
|
+
function __literalsEqual(a, b, exactDecimal) {
|
|
863
|
+
if (a.value === b.value) return true;
|
|
864
|
+
if (literalsEquivalentAsXsdString(a.value, b.value)) return true;
|
|
865
|
+
return __numericInfosSameDatatypeEqual(parseNumericLiteralInfo(a), parseNumericLiteralInfo(b), exactDecimal);
|
|
866
|
+
}
|
|
917
867
|
|
|
918
|
-
|
|
919
|
-
|
|
868
|
+
function __termArraysEqual(xs, ys, eq) {
|
|
869
|
+
if (xs.length !== ys.length) return false;
|
|
870
|
+
for (let i = 0; i < xs.length; i++) {
|
|
871
|
+
if (!eq(xs[i], ys[i])) return false;
|
|
920
872
|
}
|
|
921
|
-
|
|
922
|
-
return false;
|
|
873
|
+
return true;
|
|
923
874
|
}
|
|
924
875
|
|
|
925
|
-
function
|
|
876
|
+
function __termsEqual(a, b, exactDecimal) {
|
|
926
877
|
if (a === b) return true;
|
|
927
878
|
if (!a || !b) return false;
|
|
928
879
|
if (a.__tid && b.__tid && a.__tid === b.__tid) return true;
|
|
929
880
|
|
|
930
881
|
// 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;
|
|
882
|
+
if (__isRdfNilEmptyListPair(a, b) || __isRdfNilEmptyListPair(b, a)) return true;
|
|
933
883
|
if (a.constructor !== b.constructor) return false;
|
|
934
884
|
|
|
935
885
|
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
|
-
|
|
886
|
+
if (a instanceof Literal) return __literalsEqual(a, b, exactDecimal);
|
|
971
887
|
if (a instanceof Var) return a.name === b.name;
|
|
972
888
|
if (a instanceof Blank) return a.label === b.label;
|
|
889
|
+
if (a instanceof ListTerm) return __termArraysEqual(a.elems, b.elems, (x, y) => __termsEqual(x, y, exactDecimal));
|
|
890
|
+
if (a instanceof OpenListTerm)
|
|
891
|
+
return a.tailVar === b.tailVar && __termArraysEqual(a.prefix, b.prefix, (x, y) => __termsEqual(x, y, exactDecimal));
|
|
892
|
+
if (a instanceof GraphTerm) return alphaEqGraphTriples(a.triples, b.triples);
|
|
893
|
+
return false;
|
|
894
|
+
}
|
|
973
895
|
|
|
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
|
-
}
|
|
896
|
+
function termsEqual(a, b) {
|
|
897
|
+
// Keep in sync with unifyTerm(): numeric-value equality, datatype-aware.
|
|
898
|
+
return __termsEqual(a, b, false);
|
|
899
|
+
}
|
|
994
900
|
|
|
995
|
-
|
|
901
|
+
function termsEqualNoIntDecimal(a, b) {
|
|
902
|
+
// Numeric equality ONLY when datatypes agree; decimals are compared exactly.
|
|
903
|
+
return __termsEqual(a, b, true);
|
|
996
904
|
}
|
|
997
905
|
|
|
998
906
|
function triplesEqual(a, b) {
|
|
@@ -1352,66 +1260,18 @@ function ensureFactIndexes(facts) {
|
|
|
1352
1260
|
)
|
|
1353
1261
|
return;
|
|
1354
1262
|
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
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
|
-
});
|
|
1263
|
+
__defineHiddenWritable(facts, '__byPred', new Map());
|
|
1264
|
+
__defineHiddenWritable(facts, '__byPS', new Map());
|
|
1265
|
+
__defineHiddenWritable(facts, '__byPO', new Map());
|
|
1266
|
+
__defineHiddenWritable(facts, '__byPNonFastS', new Map());
|
|
1267
|
+
__defineHiddenWritable(facts, '__byPNonFastO', new Map());
|
|
1268
|
+
__defineHiddenWritable(facts, '__varPred', []);
|
|
1269
|
+
__defineHiddenWritable(facts, '__varPredPS', new Map());
|
|
1270
|
+
__defineHiddenWritable(facts, '__varPredPO', new Map());
|
|
1271
|
+
__defineHiddenWritable(facts, '__varPredNonFastS', []);
|
|
1272
|
+
__defineHiddenWritable(facts, '__varPredNonFastO', []);
|
|
1273
|
+
__defineHiddenWritable(facts, '__keySet', new Set());
|
|
1274
|
+
__defineHiddenWritable(facts, '__keySetComplete', false);
|
|
1415
1275
|
|
|
1416
1276
|
// Build lookup indexes eagerly, but do not populate the duplicate-detection
|
|
1417
1277
|
// string Set for every input fact. The predicate/subject/object indexes are
|
|
@@ -1439,45 +1299,21 @@ function cloneFactIndexesForSnapshot(src, dest) {
|
|
|
1439
1299
|
return out;
|
|
1440
1300
|
}
|
|
1441
1301
|
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
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 });
|
|
1302
|
+
__defineHiddenWritable(dest, '__byPred', cloneArrayMap(src.__byPred));
|
|
1303
|
+
__defineHiddenWritable(dest, '__byPS', cloneNestedArrayMap(src.__byPS));
|
|
1304
|
+
__defineHiddenWritable(dest, '__byPO', cloneNestedArrayMap(src.__byPO));
|
|
1305
|
+
__defineHiddenWritable(dest, '__byPNonFastS', cloneArrayMap(src.__byPNonFastS));
|
|
1306
|
+
__defineHiddenWritable(dest, '__byPNonFastO', cloneArrayMap(src.__byPNonFastO));
|
|
1307
|
+
__defineHiddenWritable(dest, '__varPred', src.__varPred.slice());
|
|
1308
|
+
__defineHiddenWritable(dest, '__varPredPS', cloneArrayMap(src.__varPredPS));
|
|
1309
|
+
__defineHiddenWritable(dest, '__varPredPO', cloneArrayMap(src.__varPredPO));
|
|
1310
|
+
__defineHiddenWritable(dest, '__varPredNonFastS', src.__varPredNonFastS.slice());
|
|
1311
|
+
__defineHiddenWritable(dest, '__varPredNonFastO', src.__varPredNonFastO.slice());
|
|
1312
|
+
__defineHiddenWritable(dest, '__keySet', new Set(src.__keySet));
|
|
1313
|
+
__defineHiddenWritable(dest, '__keySetComplete', !!src.__keySetComplete);
|
|
1478
1314
|
}
|
|
1479
1315
|
|
|
1480
|
-
function
|
|
1316
|
+
function pushMapArray(map, key, value) {
|
|
1481
1317
|
let bucket = map.get(key);
|
|
1482
1318
|
if (!bucket) {
|
|
1483
1319
|
bucket = [];
|
|
@@ -1486,6 +1322,15 @@ function addToIndexArrayMap(map, key, value) {
|
|
|
1486
1322
|
bucket.push(value);
|
|
1487
1323
|
}
|
|
1488
1324
|
|
|
1325
|
+
function getOrCreateMap(map, key) {
|
|
1326
|
+
let inner = map.get(key);
|
|
1327
|
+
if (!inner) {
|
|
1328
|
+
inner = new Map();
|
|
1329
|
+
map.set(key, inner);
|
|
1330
|
+
}
|
|
1331
|
+
return inner;
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1489
1334
|
function indexFact(facts, tr, idx, addKeySet = true) {
|
|
1490
1335
|
const sk = termLookupKey(tr.s);
|
|
1491
1336
|
const ok = termLookupKey(tr.o);
|
|
@@ -1496,45 +1341,30 @@ function indexFact(facts, tr, idx, addKeySet = true) {
|
|
|
1496
1341
|
const pk = tr.p.__tid;
|
|
1497
1342
|
pkForKey = pk;
|
|
1498
1343
|
|
|
1499
|
-
|
|
1500
|
-
if (!pb) {
|
|
1501
|
-
pb = [];
|
|
1502
|
-
facts.__byPred.set(pk, pb);
|
|
1503
|
-
}
|
|
1504
|
-
pb.push(idx);
|
|
1344
|
+
pushMapArray(facts.__byPred, pk, idx);
|
|
1505
1345
|
|
|
1506
1346
|
if (sk !== null) {
|
|
1507
|
-
|
|
1508
|
-
if (!ps) {
|
|
1509
|
-
ps = new Map();
|
|
1510
|
-
facts.__byPS.set(pk, ps);
|
|
1511
|
-
}
|
|
1512
|
-
addToIndexArrayMap(ps, sk, idx);
|
|
1347
|
+
pushMapArray(getOrCreateMap(facts.__byPS, pk), sk, idx);
|
|
1513
1348
|
} else {
|
|
1514
|
-
|
|
1349
|
+
pushMapArray(facts.__byPNonFastS, pk, idx);
|
|
1515
1350
|
}
|
|
1516
1351
|
|
|
1517
1352
|
if (ok !== null) {
|
|
1518
|
-
|
|
1519
|
-
if (!po) {
|
|
1520
|
-
po = new Map();
|
|
1521
|
-
facts.__byPO.set(pk, po);
|
|
1522
|
-
}
|
|
1523
|
-
addToIndexArrayMap(po, ok, idx);
|
|
1353
|
+
pushMapArray(getOrCreateMap(facts.__byPO, pk), ok, idx);
|
|
1524
1354
|
} else {
|
|
1525
|
-
|
|
1355
|
+
pushMapArray(facts.__byPNonFastO, pk, idx);
|
|
1526
1356
|
}
|
|
1527
1357
|
} else if (tr.p instanceof Var) {
|
|
1528
1358
|
facts.__varPred.push(idx);
|
|
1529
1359
|
|
|
1530
1360
|
if (sk !== null) {
|
|
1531
|
-
|
|
1361
|
+
pushMapArray(facts.__varPredPS, sk, idx);
|
|
1532
1362
|
} else {
|
|
1533
1363
|
facts.__varPredNonFastS.push(idx);
|
|
1534
1364
|
}
|
|
1535
1365
|
|
|
1536
1366
|
if (ok !== null) {
|
|
1537
|
-
|
|
1367
|
+
pushMapArray(facts.__varPredPO, ok, idx);
|
|
1538
1368
|
} else {
|
|
1539
1369
|
facts.__varPredNonFastO.push(idx);
|
|
1540
1370
|
}
|
|
@@ -1688,16 +1518,8 @@ function makeDerivedRecord(fact, rule, premises, subst, captureExplanations) {
|
|
|
1688
1518
|
function ensureBackRuleIndexes(backRules) {
|
|
1689
1519
|
if (backRules.__byHeadPred && backRules.__wildHeadPred) return;
|
|
1690
1520
|
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
enumerable: false,
|
|
1694
|
-
writable: true,
|
|
1695
|
-
});
|
|
1696
|
-
Object.defineProperty(backRules, '__wildHeadPred', {
|
|
1697
|
-
value: [],
|
|
1698
|
-
enumerable: false,
|
|
1699
|
-
writable: true,
|
|
1700
|
-
});
|
|
1521
|
+
__defineHiddenWritable(backRules, '__byHeadPred', new Map());
|
|
1522
|
+
__defineHiddenWritable(backRules, '__wildHeadPred', []);
|
|
1701
1523
|
|
|
1702
1524
|
for (const r of backRules) indexBackRule(backRules, r);
|
|
1703
1525
|
}
|
|
@@ -1706,13 +1528,7 @@ function indexBackRule(backRules, r) {
|
|
|
1706
1528
|
if (!r || !r.conclusion || r.conclusion.length !== 1) return;
|
|
1707
1529
|
const head = r.conclusion[0];
|
|
1708
1530
|
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);
|
|
1531
|
+
pushMapArray(backRules.__byHeadPred, head.p.__tid, r);
|
|
1716
1532
|
} else {
|
|
1717
1533
|
backRules.__wildHeadPred.push(r);
|
|
1718
1534
|
}
|
|
@@ -1747,12 +1563,11 @@ function isSinglePremiseAgendaRuleSafe(r, backRules) {
|
|
|
1747
1563
|
return backRules.__wildHeadPred.length === 0;
|
|
1748
1564
|
}
|
|
1749
1565
|
|
|
1750
|
-
function mergeSinglePremiseAgendaBuckets() {
|
|
1566
|
+
function mergeSinglePremiseAgendaBuckets(...buckets) {
|
|
1751
1567
|
let out = null;
|
|
1752
1568
|
let seen = null;
|
|
1753
1569
|
|
|
1754
|
-
for (
|
|
1755
|
-
const bucket = arguments[i];
|
|
1570
|
+
for (const bucket of buckets) {
|
|
1756
1571
|
if (!bucket || bucket.length === 0) continue;
|
|
1757
1572
|
|
|
1758
1573
|
if (out === null) {
|
|
@@ -1762,8 +1577,7 @@ function mergeSinglePremiseAgendaBuckets() {
|
|
|
1762
1577
|
}
|
|
1763
1578
|
|
|
1764
1579
|
if (!seen) seen = new Set(out);
|
|
1765
|
-
for (
|
|
1766
|
-
const entry = bucket[j];
|
|
1580
|
+
for (const entry of bucket) {
|
|
1767
1581
|
if (seen.has(entry)) continue;
|
|
1768
1582
|
seen.add(entry);
|
|
1769
1583
|
out.push(entry);
|
|
@@ -1773,14 +1587,14 @@ function mergeSinglePremiseAgendaBuckets() {
|
|
|
1773
1587
|
return out;
|
|
1774
1588
|
}
|
|
1775
1589
|
|
|
1776
|
-
function
|
|
1590
|
+
function termContainsVar(t) {
|
|
1777
1591
|
if (t instanceof Var) return true;
|
|
1778
|
-
if (t instanceof ListTerm) return t.elems.some(
|
|
1592
|
+
if (t instanceof ListTerm) return t.elems.some(termContainsVar);
|
|
1779
1593
|
if (t instanceof OpenListTerm) return true;
|
|
1780
1594
|
if (t instanceof GraphTerm)
|
|
1781
1595
|
return t.triples.some(
|
|
1782
1596
|
(tr) =>
|
|
1783
|
-
|
|
1597
|
+
termContainsVar(tr.s) || termContainsVar(tr.p) || termContainsVar(tr.o),
|
|
1784
1598
|
);
|
|
1785
1599
|
return false;
|
|
1786
1600
|
}
|
|
@@ -1799,15 +1613,6 @@ function makeSinglePremiseAgendaIndex(forwardRules, backRules) {
|
|
|
1799
1613
|
size: 0,
|
|
1800
1614
|
};
|
|
1801
1615
|
|
|
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
1616
|
for (let i = 0; i < forwardRules.length; i++) {
|
|
1812
1617
|
const r = forwardRules[i];
|
|
1813
1618
|
if (!isSinglePremiseAgendaRuleSafe(r, backRules)) continue;
|
|
@@ -1833,29 +1638,15 @@ function makeSinglePremiseAgendaIndex(forwardRules, backRules) {
|
|
|
1833
1638
|
index.size += 1;
|
|
1834
1639
|
|
|
1835
1640
|
if (entry.goalPredTid !== null) {
|
|
1836
|
-
|
|
1641
|
+
pushMapArray(index.byPredAll, entry.goalPredTid, entry);
|
|
1837
1642
|
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
|
-
}
|
|
1643
|
+
if (entry.goalSKey === null && entry.goalOKey === null) pushMapArray(index.byPred, entry.goalPredTid, entry);
|
|
1644
|
+
if (entry.goalSKey !== null) pushMapArray(getOrCreateMap(index.byPS, entry.goalPredTid), entry.goalSKey, entry);
|
|
1645
|
+
if (entry.goalOKey !== null) pushMapArray(getOrCreateMap(index.byPO, entry.goalPredTid), entry.goalOKey, entry);
|
|
1855
1646
|
} else {
|
|
1856
1647
|
if (entry.goalSKey === null && entry.goalOKey === null) index.wildPred.push(entry);
|
|
1857
|
-
if (entry.goalSKey !== null)
|
|
1858
|
-
if (entry.goalOKey !== null)
|
|
1648
|
+
if (entry.goalSKey !== null) pushMapArray(index.wildPS, entry.goalSKey, entry);
|
|
1649
|
+
if (entry.goalOKey !== null) pushMapArray(index.wildPO, entry.goalOKey, entry);
|
|
1859
1650
|
}
|
|
1860
1651
|
}
|
|
1861
1652
|
|
|
@@ -1871,7 +1662,7 @@ function getSinglePremiseAgendaCandidates(index, fact) {
|
|
|
1871
1662
|
let exact = null;
|
|
1872
1663
|
if (fact.p instanceof Iri) {
|
|
1873
1664
|
const pk = fact.p.__tid;
|
|
1874
|
-
if ((sk === null &&
|
|
1665
|
+
if ((sk === null && termContainsVar(fact.s)) || (ok === null && termContainsVar(fact.o))) {
|
|
1875
1666
|
// A fact with a variable-bearing subject/object (most importantly a
|
|
1876
1667
|
// top-level variable fact such as `?S :p ?O.`) can match rules whose
|
|
1877
1668
|
// premise is fixed in that position. The ordinary `(p,s)` / `(p,o)` lookup
|
|
@@ -2226,16 +2017,8 @@ function unifyOpenWithList(prefix, tailv, ys, subst) {
|
|
|
2226
2017
|
}
|
|
2227
2018
|
|
|
2228
2019
|
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
2020
|
for (const tr of triples) {
|
|
2238
|
-
if (
|
|
2021
|
+
if (termContainsVar(tr.s) || termContainsVar(tr.p) || termContainsVar(tr.o)) return true;
|
|
2239
2022
|
}
|
|
2240
2023
|
return false;
|
|
2241
2024
|
}
|
|
@@ -3952,12 +3735,22 @@ function reasonStream(input, opts = {}) {
|
|
|
3952
3735
|
skipUnsupportedRdfJs = false,
|
|
3953
3736
|
builtinModules = null,
|
|
3954
3737
|
rdf = false,
|
|
3738
|
+
sourceLabel = '<input>',
|
|
3955
3739
|
} = opts;
|
|
3956
3740
|
|
|
3957
3741
|
const useRdfCompatibility = !!rdf;
|
|
3958
3742
|
|
|
3959
3743
|
const parsedSourceList = parseN3SourceList(input, { baseIri, rdf: useRdfCompatibility, sourceLocations: proof });
|
|
3960
|
-
const
|
|
3744
|
+
const parsedTextInput = (!parsedSourceList && proof && typeof input === 'string')
|
|
3745
|
+
? parseN3Text(input, {
|
|
3746
|
+
baseIri: baseIri || '',
|
|
3747
|
+
label: sourceLabel || '<input>',
|
|
3748
|
+
keepSourceArtifacts: false,
|
|
3749
|
+
sourceLocations: true,
|
|
3750
|
+
rdf: useRdfCompatibility,
|
|
3751
|
+
})
|
|
3752
|
+
: null;
|
|
3753
|
+
const parsedInput = parsedSourceList || parsedTextInput || normalizeParsedReasonerInputSync(input);
|
|
3961
3754
|
const rdfFactory = rdfjs ? getDataFactory(dataFactory) : null;
|
|
3962
3755
|
|
|
3963
3756
|
const __oldEnforceHttps = deref.getEnforceHttpsEnabled();
|
|
@@ -3992,22 +3785,11 @@ function reasonStream(input, opts = {}) {
|
|
|
3992
3785
|
if (baseIri) prefixes.setBase(baseIri);
|
|
3993
3786
|
} else {
|
|
3994
3787
|
const n3Text = normalizeReasonerInputSync(input);
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
baseIri: baseIri || '',
|
|
3999
|
-
keepSourceArtifacts: false,
|
|
4000
|
-
sourceLocations: true,
|
|
4001
|
-
rdf: useRdfCompatibility,
|
|
4002
|
-
});
|
|
4003
|
-
({ prefixes, triples, frules, brules, logQueryRules } = parsed);
|
|
4004
|
-
} else {
|
|
4005
|
-
const toks = lex(n3Text, { rdf: useRdfCompatibility });
|
|
4006
|
-
const parser = new Parser(toks);
|
|
4007
|
-
if (baseIri) parser.prefixes.setBase(baseIri);
|
|
3788
|
+
const toks = lex(n3Text, { rdf: useRdfCompatibility });
|
|
3789
|
+
const parser = new Parser(toks);
|
|
3790
|
+
if (baseIri) parser.prefixes.setBase(baseIri);
|
|
4008
3791
|
|
|
4009
|
-
|
|
4010
|
-
}
|
|
3792
|
+
[prefixes, triples, frules, brules, logQueryRules] = parser.parseDocument();
|
|
4011
3793
|
}
|
|
4012
3794
|
// Make the parsed prefixes available to log:trace output
|
|
4013
3795
|
trace.setTracePrefixes(prefixes);
|