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.
Files changed (2) hide show
  1. package/eyeling.js +92 -24
  2. 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: allow exact equality (but NOT with double)
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 (same tail var)
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 = unifyTerm(a.prefix[i], b.prefix[i], 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 = unifyTerm(a.elems[i], b.elems[i], 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 = unifyTerm(parts[0], left, subst);
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 ((dt2 === XSD_DECIMAL_DT) && !Number.isFinite(num)) return null;
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.6.8",
3
+ "version": "1.6.9",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [