eyeling 1.16.0 → 1.16.1

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 (3) hide show
  1. package/eyeling.js +60 -12
  2. package/lib/builtins.js +60 -12
  3. package/package.json +1 -1
package/eyeling.js CHANGED
@@ -135,6 +135,33 @@ function __builtinCollectVarsInTriple(tr, out) {
135
135
  __builtinCollectVarsInTerm(tr.o, out);
136
136
  }
137
137
 
138
+ function __isRuleFormulaLikeTerm(t) {
139
+ return t instanceof GraphTerm || (t instanceof Literal && (t.value === 'true' || t.value === 'false'));
140
+ }
141
+
142
+ function __expandScopedVarPredicateGoals(goals) {
143
+ if (!Array.isArray(goals) || goals.length === 0) return [{ goals, bind: null }];
144
+
145
+ let variants = [{ goals: goals.slice(), bind: null }];
146
+ const impliesIri = internIri(LOG_NS + 'implies');
147
+
148
+ for (let i = 0; i < goals.length; i++) {
149
+ const tr = goals[i];
150
+ if (!(tr.p instanceof Var)) continue;
151
+ if (!__isRuleFormulaLikeTerm(tr.s) && !__isRuleFormulaLikeTerm(tr.o)) continue;
152
+
153
+ const next = variants.slice();
154
+ for (const v of variants) {
155
+ const altGoals = v.goals.slice();
156
+ altGoals[i] = new Triple(altGoals[i].s, impliesIri, altGoals[i].o);
157
+ const altBind = { ...(v.bind || {}), [tr.p.name]: impliesIri };
158
+ next.push({ goals: altGoals, bind: altBind });
159
+ }
160
+ variants = next;
161
+ }
162
+ return variants;
163
+ }
164
+
138
165
  function __builtinCollectVarsInTriples(triples, out) {
139
166
  for (const tr of triples) __builtinCollectVarsInTriple(tr, out);
140
167
  }
@@ -3071,18 +3098,39 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen, maxResults) {
3071
3098
  const visited2 = [];
3072
3099
  const keepVars = new Set();
3073
3100
  if (g.s instanceof GraphTerm) __builtinCollectVarsInTriples(g.s.triples, keepVars);
3074
- // Start from the incoming substitution so bindings flow outward.
3075
- return proveGoals(
3076
- Array.from(g.o.triples),
3077
- { ...subst },
3078
- scopeFacts,
3079
- scopeBackRules,
3080
- depth + 1,
3081
- visited2,
3082
- varGen,
3083
- maxResults,
3084
- keepVars.size ? { keepVars } : undefined,
3085
- );
3101
+
3102
+ const goalVariants = __expandScopedVarPredicateGoals(Array.from(g.o.triples));
3103
+ const out = [];
3104
+ for (const variant of goalVariants) {
3105
+ const sols = proveGoals(
3106
+ variant.goals,
3107
+ { ...subst },
3108
+ scopeFacts,
3109
+ scopeBackRules,
3110
+ depth + 1,
3111
+ visited2,
3112
+ varGen,
3113
+ maxResults,
3114
+ keepVars.size ? { keepVars } : undefined,
3115
+ );
3116
+ for (const s2 of sols) {
3117
+ const merged = { ...s2 };
3118
+ let ok = true;
3119
+ if (variant.bind) {
3120
+ for (const [k, v] of Object.entries(variant.bind)) {
3121
+ if (Object.prototype.hasOwnProperty.call(merged, k) && !termsEqual(merged[k], v)) {
3122
+ ok = false;
3123
+ break;
3124
+ }
3125
+ merged[k] = v;
3126
+ }
3127
+ }
3128
+ if (!ok) continue;
3129
+ out.push(merged);
3130
+ if (typeof maxResults === 'number' && maxResults > 0 && out.length >= maxResults) return out;
3131
+ }
3132
+ }
3133
+ return out;
3086
3134
  }
3087
3135
 
3088
3136
  // log:notIncludes
package/lib/builtins.js CHANGED
@@ -123,6 +123,33 @@ function __builtinCollectVarsInTriple(tr, out) {
123
123
  __builtinCollectVarsInTerm(tr.o, out);
124
124
  }
125
125
 
126
+ function __isRuleFormulaLikeTerm(t) {
127
+ return t instanceof GraphTerm || (t instanceof Literal && (t.value === 'true' || t.value === 'false'));
128
+ }
129
+
130
+ function __expandScopedVarPredicateGoals(goals) {
131
+ if (!Array.isArray(goals) || goals.length === 0) return [{ goals, bind: null }];
132
+
133
+ let variants = [{ goals: goals.slice(), bind: null }];
134
+ const impliesIri = internIri(LOG_NS + 'implies');
135
+
136
+ for (let i = 0; i < goals.length; i++) {
137
+ const tr = goals[i];
138
+ if (!(tr.p instanceof Var)) continue;
139
+ if (!__isRuleFormulaLikeTerm(tr.s) && !__isRuleFormulaLikeTerm(tr.o)) continue;
140
+
141
+ const next = variants.slice();
142
+ for (const v of variants) {
143
+ const altGoals = v.goals.slice();
144
+ altGoals[i] = new Triple(altGoals[i].s, impliesIri, altGoals[i].o);
145
+ const altBind = { ...(v.bind || {}), [tr.p.name]: impliesIri };
146
+ next.push({ goals: altGoals, bind: altBind });
147
+ }
148
+ variants = next;
149
+ }
150
+ return variants;
151
+ }
152
+
126
153
  function __builtinCollectVarsInTriples(triples, out) {
127
154
  for (const tr of triples) __builtinCollectVarsInTriple(tr, out);
128
155
  }
@@ -3059,18 +3086,39 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen, maxResults) {
3059
3086
  const visited2 = [];
3060
3087
  const keepVars = new Set();
3061
3088
  if (g.s instanceof GraphTerm) __builtinCollectVarsInTriples(g.s.triples, keepVars);
3062
- // Start from the incoming substitution so bindings flow outward.
3063
- return proveGoals(
3064
- Array.from(g.o.triples),
3065
- { ...subst },
3066
- scopeFacts,
3067
- scopeBackRules,
3068
- depth + 1,
3069
- visited2,
3070
- varGen,
3071
- maxResults,
3072
- keepVars.size ? { keepVars } : undefined,
3073
- );
3089
+
3090
+ const goalVariants = __expandScopedVarPredicateGoals(Array.from(g.o.triples));
3091
+ const out = [];
3092
+ for (const variant of goalVariants) {
3093
+ const sols = proveGoals(
3094
+ variant.goals,
3095
+ { ...subst },
3096
+ scopeFacts,
3097
+ scopeBackRules,
3098
+ depth + 1,
3099
+ visited2,
3100
+ varGen,
3101
+ maxResults,
3102
+ keepVars.size ? { keepVars } : undefined,
3103
+ );
3104
+ for (const s2 of sols) {
3105
+ const merged = { ...s2 };
3106
+ let ok = true;
3107
+ if (variant.bind) {
3108
+ for (const [k, v] of Object.entries(variant.bind)) {
3109
+ if (Object.prototype.hasOwnProperty.call(merged, k) && !termsEqual(merged[k], v)) {
3110
+ ok = false;
3111
+ break;
3112
+ }
3113
+ merged[k] = v;
3114
+ }
3115
+ }
3116
+ if (!ok) continue;
3117
+ out.push(merged);
3118
+ if (typeof maxResults === 'number' && maxResults > 0 && out.length >= maxResults) return out;
3119
+ }
3120
+ }
3121
+ return out;
3074
3122
  }
3075
3123
 
3076
3124
  // log:notIncludes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.16.0",
3
+ "version": "1.16.1",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [