eyeling 1.6.8 → 1.6.9
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 +92 -24
- package/package.json +1 -1
package/eyeling.js
CHANGED
|
@@ -1285,20 +1285,6 @@ function termsEqual(a, b) {
|
|
|
1285
1285
|
const bn = bi.kind === 'bigint' ? Number(bi.value) : bi.value;
|
|
1286
1286
|
return !Number.isNaN(an) && !Number.isNaN(bn) && an === bn;
|
|
1287
1287
|
}
|
|
1288
|
-
|
|
1289
|
-
// integer <-> decimal: allow exact equality (but NOT with double)
|
|
1290
|
-
const intDt = XSD_NS + 'integer';
|
|
1291
|
-
const decDt = XSD_NS + 'decimal';
|
|
1292
|
-
if ((ai.dt === intDt && bi.dt === decDt) || (ai.dt === decDt && bi.dt === intDt)) {
|
|
1293
|
-
const intInfo = ai.dt === intDt ? ai : bi;
|
|
1294
|
-
const decInfo = ai.dt === decDt ? ai : bi;
|
|
1295
|
-
|
|
1296
|
-
const dec = parseXsdDecimalToBigIntScale(decInfo.lexStr);
|
|
1297
|
-
if (dec) {
|
|
1298
|
-
const scaledInt = intInfo.value * pow10n(dec.scale);
|
|
1299
|
-
return scaledInt === dec.num;
|
|
1300
|
-
}
|
|
1301
|
-
}
|
|
1302
1288
|
}
|
|
1303
1289
|
|
|
1304
1290
|
return false;
|
|
@@ -2014,14 +2000,97 @@ function unifyTerm(a, b, subst) {
|
|
|
2014
2000
|
if (!Number.isNaN(an) && !Number.isNaN(bn) && an === bn) return { ...subst };
|
|
2015
2001
|
}
|
|
2016
2002
|
}
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
// Open list vs concrete list
|
|
2007
|
+
if (a instanceof OpenListTerm && b instanceof ListTerm) {
|
|
2008
|
+
return unifyOpenWithList(a.prefix, a.tailVar, b.elems, subst);
|
|
2009
|
+
}
|
|
2010
|
+
if (a instanceof ListTerm && b instanceof OpenListTerm) {
|
|
2011
|
+
return unifyOpenWithList(b.prefix, b.tailVar, a.elems, subst);
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
// Open list vs open list (same tail var)
|
|
2015
|
+
if (a instanceof OpenListTerm && b instanceof OpenListTerm) {
|
|
2016
|
+
if (a.tailVar !== b.tailVar || a.prefix.length !== b.prefix.length) return null;
|
|
2017
|
+
let s2 = { ...subst };
|
|
2018
|
+
for (let i = 0; i < a.prefix.length; i++) {
|
|
2019
|
+
s2 = unifyTerm(a.prefix[i], b.prefix[i], s2);
|
|
2020
|
+
if (s2 === null) return null;
|
|
2021
|
+
}
|
|
2022
|
+
return s2;
|
|
2023
|
+
}
|
|
2024
|
+
|
|
2025
|
+
// List terms
|
|
2026
|
+
if (a instanceof ListTerm && b instanceof ListTerm) {
|
|
2027
|
+
if (a.elems.length !== b.elems.length) return null;
|
|
2028
|
+
let s2 = { ...subst };
|
|
2029
|
+
for (let i = 0; i < a.elems.length; i++) {
|
|
2030
|
+
s2 = unifyTerm(a.elems[i], b.elems[i], s2);
|
|
2031
|
+
if (s2 === null) return null;
|
|
2032
|
+
}
|
|
2033
|
+
return s2;
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
// Formulas:
|
|
2037
|
+
// 1) If they are alpha-equivalent, succeed without leaking internal bindings.
|
|
2038
|
+
// 2) Otherwise fall back to full unification (may bind vars).
|
|
2039
|
+
if (a instanceof FormulaTerm && b instanceof FormulaTerm) {
|
|
2040
|
+
if (alphaEqFormulaTriples(a.triples, b.triples)) return { ...subst };
|
|
2041
|
+
return unifyFormulaTriples(a.triples, b.triples, subst);
|
|
2042
|
+
}
|
|
2043
|
+
return null;
|
|
2044
|
+
}
|
|
2045
|
+
|
|
2046
|
+
function unifyTermListAppend(a, b, subst) {
|
|
2047
|
+
a = applySubstTerm(a, subst);
|
|
2048
|
+
b = applySubstTerm(b, subst);
|
|
2049
|
+
|
|
2050
|
+
// Variable binding (same as unifyTerm)
|
|
2051
|
+
if (a instanceof Var) {
|
|
2052
|
+
const v = a.name;
|
|
2053
|
+
const t = b;
|
|
2054
|
+
if (t instanceof Var && t.name === v) return { ...subst };
|
|
2055
|
+
if (containsVarTerm(t, v)) return null;
|
|
2056
|
+
const s2 = { ...subst };
|
|
2057
|
+
s2[v] = t;
|
|
2058
|
+
return s2;
|
|
2059
|
+
}
|
|
2060
|
+
if (b instanceof Var) return unifyTermListAppend(b, a, subst);
|
|
2061
|
+
|
|
2062
|
+
// Exact matches
|
|
2063
|
+
if (a instanceof Iri && b instanceof Iri && a.value === b.value) return { ...subst };
|
|
2064
|
+
if (a instanceof Literal && b instanceof Literal && a.value === b.value) return { ...subst };
|
|
2065
|
+
if (a instanceof Blank && b instanceof Blank && a.label === b.label) return { ...subst };
|
|
2066
|
+
|
|
2067
|
+
// Plain string vs xsd:string equivalence
|
|
2068
|
+
if (a instanceof Literal && b instanceof Literal) {
|
|
2069
|
+
if (literalsEquivalentAsXsdString(a.value, b.value)) return { ...subst };
|
|
2070
|
+
}
|
|
2071
|
+
|
|
2072
|
+
// Numeric match: same-dt OR integer<->decimal exact equality (for list:append only)
|
|
2073
|
+
if (a instanceof Literal && b instanceof Literal) {
|
|
2074
|
+
const ai = parseNumericLiteralInfo(a);
|
|
2075
|
+
const bi = parseNumericLiteralInfo(b);
|
|
2076
|
+
if (ai && bi) {
|
|
2077
|
+
// same datatype
|
|
2078
|
+
if (ai.dt === bi.dt) {
|
|
2079
|
+
if (ai.kind === 'bigint' && bi.kind === 'bigint') {
|
|
2080
|
+
if (ai.value === bi.value) return { ...subst };
|
|
2081
|
+
} else {
|
|
2082
|
+
const an = ai.kind === 'bigint' ? Number(ai.value) : ai.value;
|
|
2083
|
+
const bn = bi.kind === 'bigint' ? Number(bi.value) : bi.value;
|
|
2084
|
+
if (!Number.isNaN(an) && !Number.isNaN(bn) && an === bn) return { ...subst };
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2017
2087
|
|
|
2018
|
-
// integer <-> decimal
|
|
2088
|
+
// integer <-> decimal exact equality
|
|
2019
2089
|
const intDt = XSD_NS + 'integer';
|
|
2020
2090
|
const decDt = XSD_NS + 'decimal';
|
|
2021
2091
|
if ((ai.dt === intDt && bi.dt === decDt) || (ai.dt === decDt && bi.dt === intDt)) {
|
|
2022
2092
|
const intInfo = ai.dt === intDt ? ai : bi;
|
|
2023
2093
|
const decInfo = ai.dt === decDt ? ai : bi;
|
|
2024
|
-
|
|
2025
2094
|
const dec = parseXsdDecimalToBigIntScale(decInfo.lexStr);
|
|
2026
2095
|
if (dec) {
|
|
2027
2096
|
const scaledInt = intInfo.value * pow10n(dec.scale);
|
|
@@ -2039,12 +2108,12 @@ function unifyTerm(a, b, subst) {
|
|
|
2039
2108
|
return unifyOpenWithList(b.prefix, b.tailVar, a.elems, subst);
|
|
2040
2109
|
}
|
|
2041
2110
|
|
|
2042
|
-
// Open list vs open list
|
|
2111
|
+
// Open list vs open list
|
|
2043
2112
|
if (a instanceof OpenListTerm && b instanceof OpenListTerm) {
|
|
2044
2113
|
if (a.tailVar !== b.tailVar || a.prefix.length !== b.prefix.length) return null;
|
|
2045
2114
|
let s2 = { ...subst };
|
|
2046
2115
|
for (let i = 0; i < a.prefix.length; i++) {
|
|
2047
|
-
s2 =
|
|
2116
|
+
s2 = unifyTermListAppend(a.prefix[i], b.prefix[i], s2);
|
|
2048
2117
|
if (s2 === null) return null;
|
|
2049
2118
|
}
|
|
2050
2119
|
return s2;
|
|
@@ -2055,19 +2124,18 @@ function unifyTerm(a, b, subst) {
|
|
|
2055
2124
|
if (a.elems.length !== b.elems.length) return null;
|
|
2056
2125
|
let s2 = { ...subst };
|
|
2057
2126
|
for (let i = 0; i < a.elems.length; i++) {
|
|
2058
|
-
s2 =
|
|
2127
|
+
s2 = unifyTermListAppend(a.elems[i], b.elems[i], s2);
|
|
2059
2128
|
if (s2 === null) return null;
|
|
2060
2129
|
}
|
|
2061
2130
|
return s2;
|
|
2062
2131
|
}
|
|
2063
2132
|
|
|
2064
|
-
// Formulas
|
|
2065
|
-
// 1) If they are alpha-equivalent, succeed without leaking internal bindings.
|
|
2066
|
-
// 2) Otherwise fall back to full unification (may bind vars).
|
|
2133
|
+
// Formulas
|
|
2067
2134
|
if (a instanceof FormulaTerm && b instanceof FormulaTerm) {
|
|
2068
2135
|
if (alphaEqFormulaTriples(a.triples, b.triples)) return { ...subst };
|
|
2069
2136
|
return unifyFormulaTriples(a.triples, b.triples, subst);
|
|
2070
2137
|
}
|
|
2138
|
+
|
|
2071
2139
|
return null;
|
|
2072
2140
|
}
|
|
2073
2141
|
|
|
@@ -2720,7 +2788,7 @@ function listAppendSplit(parts, resElems, subst) {
|
|
|
2720
2788
|
const n = resElems.length;
|
|
2721
2789
|
for (let k = 0; k <= n; k++) {
|
|
2722
2790
|
const left = new ListTerm(resElems.slice(0, k));
|
|
2723
|
-
let s1 =
|
|
2791
|
+
let s1 = unifyTermListAppend(parts[0], left, subst);
|
|
2724
2792
|
if (s1 === null) continue;
|
|
2725
2793
|
const restElems = resElems.slice(k);
|
|
2726
2794
|
out.push(...listAppendSplit(parts.slice(1), restElems, s1));
|
|
@@ -2789,7 +2857,7 @@ function parseNumericLiteralInfo(t) {
|
|
|
2789
2857
|
if (Number.isNaN(num)) return null;
|
|
2790
2858
|
|
|
2791
2859
|
// allow +/-Infinity for float/double
|
|
2792
|
-
if (
|
|
2860
|
+
if (dt2 === XSD_DECIMAL_DT && !Number.isFinite(num)) return null;
|
|
2793
2861
|
|
|
2794
2862
|
return { dt: dt2, kind: 'number', value: num, lexStr };
|
|
2795
2863
|
}
|