eyeling 1.6.19 → 1.6.20
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/eyeling.js +109 -46
- package/package.json +1 -1
package/eyeling.js
CHANGED
|
@@ -62,9 +62,9 @@ function termToJsonText(t) {
|
|
|
62
62
|
function makeRdfJsonLiteral(jsonText) {
|
|
63
63
|
// Prefer a readable long literal when safe; fall back to short if needed.
|
|
64
64
|
if (!jsonText.includes('"""')) {
|
|
65
|
-
return
|
|
65
|
+
return internLiteral('"""' + jsonText + '"""^^<' + RDF_JSON_DT + '>');
|
|
66
66
|
}
|
|
67
|
-
return
|
|
67
|
+
return internLiteral(JSON.stringify(jsonText) + '^^<' + RDF_JSON_DT + '>');
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
// For a single reasoning run, this maps a canonical representation
|
|
@@ -212,6 +212,37 @@ class Var extends Term {
|
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
+
// ===========================================================================
|
|
216
|
+
// Term interning
|
|
217
|
+
// ===========================================================================
|
|
218
|
+
|
|
219
|
+
// Intern IRIs and literals by their raw lexical string.
|
|
220
|
+
// This reduces allocations when the same terms repeat and can improve performance.
|
|
221
|
+
//
|
|
222
|
+
// NOTE: Terms are treated as immutable. Do NOT mutate .value on interned objects.
|
|
223
|
+
const __iriIntern = new Map();
|
|
224
|
+
const __literalIntern = new Map();
|
|
225
|
+
|
|
226
|
+
/** @param {string} value */
|
|
227
|
+
function internIri(value) {
|
|
228
|
+
let t = __iriIntern.get(value);
|
|
229
|
+
if (!t) {
|
|
230
|
+
t = new Iri(value);
|
|
231
|
+
__iriIntern.set(value, t);
|
|
232
|
+
}
|
|
233
|
+
return t;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/** @param {string} value */
|
|
237
|
+
function internLiteral(value) {
|
|
238
|
+
let t = __literalIntern.get(value);
|
|
239
|
+
if (!t) {
|
|
240
|
+
t = new Literal(value);
|
|
241
|
+
__literalIntern.set(value, t);
|
|
242
|
+
}
|
|
243
|
+
return t;
|
|
244
|
+
}
|
|
245
|
+
|
|
215
246
|
class Blank extends Term {
|
|
216
247
|
constructor(label) {
|
|
217
248
|
super();
|
|
@@ -976,23 +1007,23 @@ class Parser {
|
|
|
976
1007
|
const val = tok.value;
|
|
977
1008
|
|
|
978
1009
|
if (typ === 'Equals') {
|
|
979
|
-
return
|
|
1010
|
+
return internIri(OWL_NS + 'sameAs');
|
|
980
1011
|
}
|
|
981
1012
|
|
|
982
1013
|
if (typ === 'IriRef') {
|
|
983
1014
|
const base = this.prefixes.map[''] || '';
|
|
984
|
-
return
|
|
1015
|
+
return internIri(resolveIriRef(val || '', base));
|
|
985
1016
|
}
|
|
986
1017
|
if (typ === 'Ident') {
|
|
987
1018
|
const name = val || '';
|
|
988
1019
|
if (name === 'a') {
|
|
989
|
-
return
|
|
1020
|
+
return internIri(RDF_NS + 'type');
|
|
990
1021
|
} else if (name.startsWith('_:')) {
|
|
991
1022
|
return new Blank(name);
|
|
992
1023
|
} else if (name.includes(':')) {
|
|
993
|
-
return
|
|
1024
|
+
return internIri(this.prefixes.expandQName(name));
|
|
994
1025
|
} else {
|
|
995
|
-
return
|
|
1026
|
+
return internIri(name);
|
|
996
1027
|
}
|
|
997
1028
|
}
|
|
998
1029
|
|
|
@@ -1030,7 +1061,7 @@ class Parser {
|
|
|
1030
1061
|
}
|
|
1031
1062
|
s = `${s}^^<${dtIri}>`;
|
|
1032
1063
|
}
|
|
1033
|
-
return
|
|
1064
|
+
return internLiteral(s);
|
|
1034
1065
|
}
|
|
1035
1066
|
|
|
1036
1067
|
if (typ === 'Var') return new Var(val || '');
|
|
@@ -1069,7 +1100,7 @@ class Parser {
|
|
|
1069
1100
|
let invert = false;
|
|
1070
1101
|
if (this.peek().typ === 'Ident' && (this.peek().value || '') === 'a') {
|
|
1071
1102
|
this.next();
|
|
1072
|
-
pred =
|
|
1103
|
+
pred = internIri(RDF_NS + 'type');
|
|
1073
1104
|
} else if (this.peek().typ === 'OpPredInvert') {
|
|
1074
1105
|
this.next(); // consume "<-"
|
|
1075
1106
|
pred = this.parseTerm();
|
|
@@ -1113,7 +1144,7 @@ class Parser {
|
|
|
1113
1144
|
if (this.peek().typ === 'OpImplies') {
|
|
1114
1145
|
this.next();
|
|
1115
1146
|
const right = this.parseTerm();
|
|
1116
|
-
const pred =
|
|
1147
|
+
const pred = internIri(LOG_NS + 'implies');
|
|
1117
1148
|
triples.push(new Triple(left, pred, right));
|
|
1118
1149
|
if (this.peek().typ === 'Dot') this.next();
|
|
1119
1150
|
else if (this.peek().typ === 'RBrace') {
|
|
@@ -1124,7 +1155,7 @@ class Parser {
|
|
|
1124
1155
|
} else if (this.peek().typ === 'OpImpliedBy') {
|
|
1125
1156
|
this.next();
|
|
1126
1157
|
const right = this.parseTerm();
|
|
1127
|
-
const pred =
|
|
1158
|
+
const pred = internIri(LOG_NS + 'impliedBy');
|
|
1128
1159
|
triples.push(new Triple(left, pred, right));
|
|
1129
1160
|
if (this.peek().typ === 'Dot') this.next();
|
|
1130
1161
|
else if (this.peek().typ === 'RBrace') {
|
|
@@ -1172,7 +1203,7 @@ class Parser {
|
|
|
1172
1203
|
|
|
1173
1204
|
if (this.peek().typ === 'Ident' && (this.peek().value || '') === 'a') {
|
|
1174
1205
|
this.next();
|
|
1175
|
-
verb =
|
|
1206
|
+
verb = internIri(RDF_NS + 'type');
|
|
1176
1207
|
} else if (this.peek().typ === 'OpPredInvert') {
|
|
1177
1208
|
this.next(); // "<-"
|
|
1178
1209
|
verb = this.parseTerm();
|
|
@@ -1669,13 +1700,18 @@ function tripleFastKey(tr) {
|
|
|
1669
1700
|
}
|
|
1670
1701
|
|
|
1671
1702
|
function ensureFactIndexes(facts) {
|
|
1672
|
-
if (facts.__byPred && facts.__byPO && facts.__keySet) return;
|
|
1703
|
+
if (facts.__byPred && facts.__byPS && facts.__byPO && facts.__keySet) return;
|
|
1673
1704
|
|
|
1674
1705
|
Object.defineProperty(facts, '__byPred', {
|
|
1675
1706
|
value: new Map(),
|
|
1676
1707
|
enumerable: false,
|
|
1677
1708
|
writable: true,
|
|
1678
1709
|
});
|
|
1710
|
+
Object.defineProperty(facts, '__byPS', {
|
|
1711
|
+
value: new Map(),
|
|
1712
|
+
enumerable: false,
|
|
1713
|
+
writable: true,
|
|
1714
|
+
});
|
|
1679
1715
|
Object.defineProperty(facts, '__byPO', {
|
|
1680
1716
|
value: new Map(),
|
|
1681
1717
|
enumerable: false,
|
|
@@ -1701,6 +1737,21 @@ function indexFact(facts, tr) {
|
|
|
1701
1737
|
}
|
|
1702
1738
|
pb.push(tr);
|
|
1703
1739
|
|
|
1740
|
+
const sk = termFastKey(tr.s);
|
|
1741
|
+
if (sk !== null) {
|
|
1742
|
+
let ps = facts.__byPS.get(pk);
|
|
1743
|
+
if (!ps) {
|
|
1744
|
+
ps = new Map();
|
|
1745
|
+
facts.__byPS.set(pk, ps);
|
|
1746
|
+
}
|
|
1747
|
+
let psb = ps.get(sk);
|
|
1748
|
+
if (!psb) {
|
|
1749
|
+
psb = [];
|
|
1750
|
+
ps.set(sk, psb);
|
|
1751
|
+
}
|
|
1752
|
+
psb.push(tr);
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1704
1755
|
const ok = termFastKey(tr.o);
|
|
1705
1756
|
if (ok !== null) {
|
|
1706
1757
|
let po = facts.__byPO.get(pk);
|
|
@@ -1727,15 +1778,27 @@ function candidateFacts(facts, goal) {
|
|
|
1727
1778
|
if (goal.p instanceof Iri) {
|
|
1728
1779
|
const pk = goal.p.value;
|
|
1729
1780
|
|
|
1781
|
+
const sk = termFastKey(goal.s);
|
|
1730
1782
|
const ok = termFastKey(goal.o);
|
|
1783
|
+
|
|
1784
|
+
/** @type {Triple[] | null} */
|
|
1785
|
+
let byPS = null;
|
|
1786
|
+
if (sk !== null) {
|
|
1787
|
+
const ps = facts.__byPS.get(pk);
|
|
1788
|
+
if (ps) byPS = ps.get(sk) || null;
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
/** @type {Triple[] | null} */
|
|
1792
|
+
let byPO = null;
|
|
1731
1793
|
if (ok !== null) {
|
|
1732
1794
|
const po = facts.__byPO.get(pk);
|
|
1733
|
-
if (po)
|
|
1734
|
-
const pob = po.get(ok);
|
|
1735
|
-
if (pob) return pob;
|
|
1736
|
-
}
|
|
1795
|
+
if (po) byPO = po.get(ok) || null;
|
|
1737
1796
|
}
|
|
1738
1797
|
|
|
1798
|
+
if (byPS && byPO) return byPS.length <= byPO.length ? byPS : byPO;
|
|
1799
|
+
if (byPS) return byPS;
|
|
1800
|
+
if (byPO) return byPO;
|
|
1801
|
+
|
|
1739
1802
|
return facts.__byPred.get(pk) || [];
|
|
1740
1803
|
}
|
|
1741
1804
|
|
|
@@ -2332,7 +2395,7 @@ function termToJsString(t) {
|
|
|
2332
2395
|
function makeStringLiteral(str) {
|
|
2333
2396
|
// JSON.stringify gives us a valid N3/Turtle-style quoted string
|
|
2334
2397
|
// (with proper escaping for quotes, backslashes, newlines, …).
|
|
2335
|
-
return
|
|
2398
|
+
return internLiteral(JSON.stringify(str));
|
|
2336
2399
|
}
|
|
2337
2400
|
|
|
2338
2401
|
function termToJsStringDecoded(t) {
|
|
@@ -2381,8 +2444,8 @@ function jsonPointerUnescape(seg) {
|
|
|
2381
2444
|
function jsonToTerm(v) {
|
|
2382
2445
|
if (v === null) return makeStringLiteral('null');
|
|
2383
2446
|
if (typeof v === 'string') return makeStringLiteral(v);
|
|
2384
|
-
if (typeof v === 'number') return
|
|
2385
|
-
if (typeof v === 'boolean') return
|
|
2447
|
+
if (typeof v === 'number') return internLiteral(String(v));
|
|
2448
|
+
if (typeof v === 'boolean') return internLiteral(v ? 'true' : 'false');
|
|
2386
2449
|
if (Array.isArray(v)) return new ListTerm(v.map(jsonToTerm));
|
|
2387
2450
|
|
|
2388
2451
|
if (v && typeof v === 'object') {
|
|
@@ -2855,7 +2918,7 @@ function formatDurationLiteralFromSeconds(secs) {
|
|
|
2855
2918
|
const neg = secs < 0;
|
|
2856
2919
|
const days = Math.round(Math.abs(secs) / 86400.0);
|
|
2857
2920
|
const literalLex = neg ? `"-P${days}D"` : `"P${days}D"`;
|
|
2858
|
-
return
|
|
2921
|
+
return internLiteral(`${literalLex}^^<${XSD_NS}duration>`);
|
|
2859
2922
|
}
|
|
2860
2923
|
function numEqualTerm(t, n, eps = 1e-9) {
|
|
2861
2924
|
const v = parseNum(t);
|
|
@@ -2967,21 +3030,21 @@ function commonNumericDatatype(terms, outTerm) {
|
|
|
2967
3030
|
|
|
2968
3031
|
function makeNumericOutputLiteral(val, dt) {
|
|
2969
3032
|
if (dt === XSD_INTEGER_DT) {
|
|
2970
|
-
if (typeof val === 'bigint') return
|
|
2971
|
-
if (Number.isInteger(val)) return
|
|
3033
|
+
if (typeof val === 'bigint') return internLiteral(val.toString());
|
|
3034
|
+
if (Number.isInteger(val)) return internLiteral(String(val));
|
|
2972
3035
|
// If a non-integer sneaks in, promote to decimal.
|
|
2973
|
-
return
|
|
3036
|
+
return internLiteral(`"${formatNum(val)}"^^<${XSD_DECIMAL_DT}>`);
|
|
2974
3037
|
}
|
|
2975
3038
|
|
|
2976
3039
|
if (dt === XSD_FLOAT_DT || dt === XSD_DOUBLE_DT) {
|
|
2977
3040
|
const sp = formatXsdFloatSpecialLex(val);
|
|
2978
3041
|
const lex = sp !== null ? sp : formatNum(val);
|
|
2979
|
-
return
|
|
3042
|
+
return internLiteral(`"${lex}"^^<${dt}>`);
|
|
2980
3043
|
}
|
|
2981
3044
|
|
|
2982
3045
|
// decimal
|
|
2983
3046
|
const lex = typeof val === 'bigint' ? val.toString() : formatNum(val);
|
|
2984
|
-
return
|
|
3047
|
+
return internLiteral(`"${lex}"^^<${dt}>`);
|
|
2985
3048
|
}
|
|
2986
3049
|
|
|
2987
3050
|
function evalUnaryMathRel(g, subst, forwardFn, inverseFn /* may be null */) {
|
|
@@ -3229,7 +3292,7 @@ function hashLiteralTerm(t, algo) {
|
|
|
3229
3292
|
const input = stripQuotes(lex);
|
|
3230
3293
|
try {
|
|
3231
3294
|
const digest = nodeCrypto.createHash(algo).update(input, 'utf8').digest('hex');
|
|
3232
|
-
return
|
|
3295
|
+
return internLiteral(JSON.stringify(digest));
|
|
3233
3296
|
} catch (e) {
|
|
3234
3297
|
return null;
|
|
3235
3298
|
}
|
|
@@ -3429,7 +3492,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
3429
3492
|
if (secs !== null) {
|
|
3430
3493
|
const outSecs = aDt.getTime() / 1000.0 - secs;
|
|
3431
3494
|
const lex = utcIsoDateTimeStringFromEpochSeconds(outSecs);
|
|
3432
|
-
const lit =
|
|
3495
|
+
const lit = internLiteral(`"${lex}"^^<${XSD_NS}dateTime>`);
|
|
3433
3496
|
if (g.o instanceof Var) {
|
|
3434
3497
|
const s2 = { ...subst };
|
|
3435
3498
|
s2[g.o.name] = lit;
|
|
@@ -3445,7 +3508,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
3445
3508
|
const bi = parseIntLiteral(b0);
|
|
3446
3509
|
if (ai !== null && bi !== null) {
|
|
3447
3510
|
const ci = ai - bi;
|
|
3448
|
-
const lit =
|
|
3511
|
+
const lit = internLiteral(ci.toString());
|
|
3449
3512
|
if (g.o instanceof Var) {
|
|
3450
3513
|
const s2 = { ...subst };
|
|
3451
3514
|
s2[g.o.name] = lit;
|
|
@@ -3480,7 +3543,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
3480
3543
|
}
|
|
3481
3544
|
|
|
3482
3545
|
// Fallback (if you *don’t* have those helpers yet):
|
|
3483
|
-
const lit =
|
|
3546
|
+
const lit = internLiteral(formatNum(c));
|
|
3484
3547
|
if (g.o instanceof Var) {
|
|
3485
3548
|
const s2 = { ...subst };
|
|
3486
3549
|
s2[g.o.name] = lit;
|
|
@@ -3531,7 +3594,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
3531
3594
|
if (ai !== null && bi !== null) {
|
|
3532
3595
|
if (bi === 0n) return [];
|
|
3533
3596
|
const q = ai / bi; // BigInt division truncates toward zero
|
|
3534
|
-
const lit =
|
|
3597
|
+
const lit = internLiteral(q.toString());
|
|
3535
3598
|
if (g.o instanceof Var) {
|
|
3536
3599
|
const s2 = { ...subst };
|
|
3537
3600
|
s2[g.o.name] = lit;
|
|
@@ -3560,7 +3623,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
3560
3623
|
if (!Number.isInteger(a) || !Number.isInteger(b)) return [];
|
|
3561
3624
|
|
|
3562
3625
|
const q = Math.trunc(a / b);
|
|
3563
|
-
const lit =
|
|
3626
|
+
const lit = internLiteral(String(q));
|
|
3564
3627
|
if (g.o instanceof Var) {
|
|
3565
3628
|
const s2 = { ...subst };
|
|
3566
3629
|
s2[g.o.name] = lit;
|
|
@@ -3758,7 +3821,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
3758
3821
|
if (Number.isNaN(a)) return [];
|
|
3759
3822
|
|
|
3760
3823
|
const rVal = Math.round(a); // ties go toward +∞ in JS (e.g., -1.5 -> -1)
|
|
3761
|
-
const lit =
|
|
3824
|
+
const lit = internLiteral(String(rVal)); // integer token
|
|
3762
3825
|
|
|
3763
3826
|
if (g.o instanceof Var) {
|
|
3764
3827
|
const s2 = { ...subst };
|
|
@@ -3786,7 +3849,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
3786
3849
|
|
|
3787
3850
|
if (g.o instanceof Var) {
|
|
3788
3851
|
const s2 = { ...subst };
|
|
3789
|
-
s2[g.o.name] =
|
|
3852
|
+
s2[g.o.name] = internLiteral(`"${now}"^^<${XSD_NS}dateTime>`);
|
|
3790
3853
|
return [s2];
|
|
3791
3854
|
}
|
|
3792
3855
|
if (g.o instanceof Literal) {
|
|
@@ -3848,7 +3911,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
3848
3911
|
const outs = [];
|
|
3849
3912
|
|
|
3850
3913
|
for (let i = 0; i < xs.length; i++) {
|
|
3851
|
-
const idxLit =
|
|
3914
|
+
const idxLit = internLiteral(String(i)); // 0-based
|
|
3852
3915
|
const val = xs[i];
|
|
3853
3916
|
|
|
3854
3917
|
// Fast path: object is exactly a 2-element list (idx, value)
|
|
@@ -3904,7 +3967,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
3904
3967
|
const outs = [];
|
|
3905
3968
|
|
|
3906
3969
|
for (let i = 0; i < xs.length; i++) {
|
|
3907
|
-
const idxLit =
|
|
3970
|
+
const idxLit = internLiteral(String(i)); // index starts at 0
|
|
3908
3971
|
|
|
3909
3972
|
// --- index side: strict if ground, otherwise unify/bind
|
|
3910
3973
|
let s1 = null;
|
|
@@ -3980,7 +4043,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
3980
4043
|
// list:length (strict: do not accept integer<->decimal matches for a ground object)
|
|
3981
4044
|
if (pv === LIST_NS + 'length') {
|
|
3982
4045
|
if (!(g.s instanceof ListTerm)) return [];
|
|
3983
|
-
const nTerm =
|
|
4046
|
+
const nTerm = internLiteral(String(g.s.elems.length));
|
|
3984
4047
|
|
|
3985
4048
|
const o2 = applySubstTerm(g.o, subst);
|
|
3986
4049
|
if (isGroundTerm(o2)) {
|
|
@@ -4092,7 +4155,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
4092
4155
|
if (!(inputTerm instanceof ListTerm)) return [];
|
|
4093
4156
|
const inputList = inputTerm.elems;
|
|
4094
4157
|
if (!(predTerm instanceof Iri)) return [];
|
|
4095
|
-
const pred =
|
|
4158
|
+
const pred = internIri(predTerm.value);
|
|
4096
4159
|
if (!isBuiltinPred(pred)) return [];
|
|
4097
4160
|
if (!inputList.every((e) => isGroundTerm(e))) return [];
|
|
4098
4161
|
|
|
@@ -4185,8 +4248,8 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
4185
4248
|
}
|
|
4186
4249
|
|
|
4187
4250
|
if (oDt !== null) {
|
|
4188
|
-
const strLit = isQuotedLexical(oLex) ?
|
|
4189
|
-
const subjList = new ListTerm([strLit,
|
|
4251
|
+
const strLit = isQuotedLexical(oLex) ? internLiteral(oLex) : makeStringLiteral(String(oLex));
|
|
4252
|
+
const subjList = new ListTerm([strLit, internIri(oDt)]);
|
|
4190
4253
|
const s2 = unifyTerm(goal.s, subjList, subst);
|
|
4191
4254
|
if (s2 !== null) results.push(s2);
|
|
4192
4255
|
}
|
|
@@ -4205,7 +4268,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
4205
4268
|
if (okString) {
|
|
4206
4269
|
const dtIri = b.value;
|
|
4207
4270
|
// For xsd:string, prefer the plain string literal form.
|
|
4208
|
-
const outLit = dtIri === XSD_NS + 'string' ?
|
|
4271
|
+
const outLit = dtIri === XSD_NS + 'string' ? internLiteral(sLex) : internLiteral(`${sLex}^^<${dtIri}>`);
|
|
4209
4272
|
const s2 = unifyTerm(goal.o, outLit, subst);
|
|
4210
4273
|
if (s2 !== null) results.push(s2);
|
|
4211
4274
|
}
|
|
@@ -4241,7 +4304,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
4241
4304
|
const tag = extractLangTag(g.o.value);
|
|
4242
4305
|
if (tag !== null) {
|
|
4243
4306
|
const [oLex] = literalParts(g.o.value); // strips @lang into lexical part
|
|
4244
|
-
const strLit = isQuotedLexical(oLex) ?
|
|
4307
|
+
const strLit = isQuotedLexical(oLex) ? internLiteral(oLex) : makeStringLiteral(String(oLex));
|
|
4245
4308
|
const langLit = makeStringLiteral(tag);
|
|
4246
4309
|
const subjList = new ListTerm([strLit, langLit]);
|
|
4247
4310
|
const s2 = unifyTerm(goal.s, subjList, subst);
|
|
@@ -4261,7 +4324,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
4261
4324
|
if (okString && okLang) {
|
|
4262
4325
|
const tag = stripQuotes(langLex);
|
|
4263
4326
|
if (LANG_RE.test(tag)) {
|
|
4264
|
-
const outLit =
|
|
4327
|
+
const outLit = internLiteral(`${sLex}@${tag}`);
|
|
4265
4328
|
const s2 = unifyTerm(goal.o, outLit, subst);
|
|
4266
4329
|
if (s2 !== null) results.push(s2);
|
|
4267
4330
|
}
|
|
@@ -4283,7 +4346,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
4283
4346
|
const r = standardizeRule(r0, varGen);
|
|
4284
4347
|
|
|
4285
4348
|
const premF = new FormulaTerm(r.premise);
|
|
4286
|
-
const concTerm = r0.isFuse ?
|
|
4349
|
+
const concTerm = r0.isFuse ? internLiteral('false') : new FormulaTerm(r.conclusion);
|
|
4287
4350
|
|
|
4288
4351
|
// unify subject with the premise formula
|
|
4289
4352
|
let s2 = unifyTerm(goal.s, premF, subst);
|
|
@@ -4420,7 +4483,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
4420
4483
|
let iri = skolemCache.get(key);
|
|
4421
4484
|
if (!iri) {
|
|
4422
4485
|
const id = deterministicSkolemIdFromKey(key);
|
|
4423
|
-
iri =
|
|
4486
|
+
iri = internIri(SKOLEM_NS + id);
|
|
4424
4487
|
skolemCache.set(key, iri);
|
|
4425
4488
|
}
|
|
4426
4489
|
|
|
@@ -4442,7 +4505,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
4442
4505
|
if (g.o instanceof Literal) {
|
|
4443
4506
|
const uriStr = termToJsString(g.o); // JS string from the literal
|
|
4444
4507
|
if (uriStr === null) return [];
|
|
4445
|
-
const iri =
|
|
4508
|
+
const iri = internIri(uriStr);
|
|
4446
4509
|
const s2 = unifyTerm(goal.s, iri, subst);
|
|
4447
4510
|
return s2 !== null ? [s2] : [];
|
|
4448
4511
|
}
|