eyeling 1.22.8 → 1.22.10

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.
@@ -511,6 +511,7 @@
511
511
  internLiteral,
512
512
  PrefixEnv,
513
513
  literalParts,
514
+ copyQuotedGraphMetadata,
514
515
  } = require('./prelude');
515
516
 
516
517
  const { decodeN3StringEscapes } = require('./lexer');
@@ -813,8 +814,9 @@
813
814
  for (const tr of triples) __builtinCollectVarsInTriple(tr, out);
814
815
  }
815
816
 
816
- function __existentializeBlankTerm(t, mapping, varGen) {
817
+ function __existentializeBlankTerm(t, mapping, varGen, localBlankLabels) {
817
818
  if (t instanceof Blank) {
819
+ if (localBlankLabels instanceof Set && !localBlankLabels.has(t.label)) return t;
818
820
  let v = mapping[t.label];
819
821
  if (v === undefined) {
820
822
  const n =
@@ -827,34 +829,48 @@
827
829
  if (t instanceof ListTerm) return t;
828
830
  if (t instanceof OpenListTerm) return t;
829
831
  if (t instanceof GraphTerm) {
832
+ const nestedLocalBlankLabels =
833
+ Object.prototype.hasOwnProperty.call(t, '__quotedLocalBlankLabels') &&
834
+ t.__quotedLocalBlankLabels instanceof Set
835
+ ? t.__quotedLocalBlankLabels
836
+ : localBlankLabels;
830
837
  let changed = false;
831
838
  const triples = t.triples.map((tr) => {
832
- const s2 = __existentializeBlankTerm(tr.s, mapping, varGen);
833
- const p2 = __existentializeBlankTerm(tr.p, mapping, varGen);
834
- const o2 = __existentializeBlankTerm(tr.o, mapping, varGen);
839
+ const s2 = __existentializeBlankTerm(tr.s, mapping, varGen, nestedLocalBlankLabels);
840
+ const p2 = __existentializeBlankTerm(tr.p, mapping, varGen, nestedLocalBlankLabels);
841
+ const o2 = __existentializeBlankTerm(tr.o, mapping, varGen, nestedLocalBlankLabels);
835
842
  if (s2 !== tr.s || p2 !== tr.p || o2 !== tr.o) changed = true;
836
843
  return s2 === tr.s && p2 === tr.p && o2 === tr.o ? tr : new Triple(s2, p2, o2);
837
844
  });
838
- return changed ? new GraphTerm(triples) : t;
845
+ return changed ? copyQuotedGraphMetadata(t, new GraphTerm(triples)) : t;
839
846
  }
840
847
  return t;
841
848
  }
842
849
 
843
- function __existentializeBlankTriples(triples, varGen) {
850
+ function __existentializeBlankTriples(rawGraphOrTriples, varGen) {
851
+ const triples =
852
+ rawGraphOrTriples instanceof GraphTerm ? Array.from(rawGraphOrTriples.triples) : Array.from(rawGraphOrTriples);
853
+ const localBlankLabels =
854
+ rawGraphOrTriples instanceof GraphTerm &&
855
+ Object.prototype.hasOwnProperty.call(rawGraphOrTriples, '__quotedLocalBlankLabels') &&
856
+ rawGraphOrTriples.__quotedLocalBlankLabels instanceof Set
857
+ ? rawGraphOrTriples.__quotedLocalBlankLabels
858
+ : null;
859
+
844
860
  const mapping = Object.create(null);
845
861
  let changed = false;
846
862
  const out = triples.map((tr) => {
847
- const s2 = __existentializeBlankTerm(tr.s, mapping, varGen);
848
- const p2 = __existentializeBlankTerm(tr.p, mapping, varGen);
849
- const o2 = __existentializeBlankTerm(tr.o, mapping, varGen);
863
+ const s2 = __existentializeBlankTerm(tr.s, mapping, varGen, localBlankLabels);
864
+ const p2 = __existentializeBlankTerm(tr.p, mapping, varGen, localBlankLabels);
865
+ const o2 = __existentializeBlankTerm(tr.o, mapping, varGen, localBlankLabels);
850
866
  if (s2 !== tr.s || p2 !== tr.p || o2 !== tr.o) changed = true;
851
867
  return s2 === tr.s && p2 === tr.p && o2 === tr.o ? tr : new Triple(s2, p2, o2);
852
868
  });
853
869
  return changed ? out : triples;
854
870
  }
855
871
 
856
- function __prepareQuotedPatternTriples(rawTriples, subst, varGen) {
857
- const ex = __existentializeBlankTriples(Array.from(rawTriples), varGen);
872
+ function __prepareQuotedPatternTriples(rawGraphOrTriples, subst, varGen) {
873
+ const ex = __existentializeBlankTriples(rawGraphOrTriples, varGen);
858
874
  let changed = false;
859
875
  const out = ex.map((tr) => {
860
876
  const tr2 = applySubstTriple(tr, subst);
@@ -4126,7 +4142,7 @@
4126
4142
  const keepVars = new Set();
4127
4143
  if (g.s instanceof GraphTerm) __builtinCollectVarsInTriples(g.s.triples, keepVars);
4128
4144
 
4129
- const goalTriples = __prepareQuotedPatternTriples(goal.o.triples, subst, varGen);
4145
+ const goalTriples = __prepareQuotedPatternTriples(goal.o, subst, varGen);
4130
4146
  const goalVariants = __expandScopedVarPredicateGoals(goalTriples);
4131
4147
  const out = [];
4132
4148
  for (const variant of goalVariants) {
@@ -4209,7 +4225,7 @@
4209
4225
 
4210
4226
  const visited2 = [];
4211
4227
  const sols = proveGoals(
4212
- __prepareQuotedPatternTriples(goal.o.triples, subst, varGen),
4228
+ __prepareQuotedPatternTriples(goal.o, subst, varGen),
4213
4229
  { ...subst },
4214
4230
  scopeFacts,
4215
4231
  scopeBackRules,
@@ -4306,8 +4322,8 @@
4306
4322
  const rawClauseTerm = goal.s instanceof ListTerm ? goal.s.elems[1] : clauseTerm;
4307
4323
  const clauseGoals =
4308
4324
  rawClauseTerm instanceof GraphTerm
4309
- ? __prepareQuotedPatternTriples(rawClauseTerm.triples, subst, varGen)
4310
- : __prepareQuotedPatternTriples(clauseTerm.triples, subst, varGen);
4325
+ ? __prepareQuotedPatternTriples(rawClauseTerm, subst, varGen)
4326
+ : __prepareQuotedPatternTriples(clauseTerm, subst, varGen);
4311
4327
  const sols = proveGoals(clauseGoals, {}, scopeFacts, scopeBackRules, depth + 1, visited2, varGen);
4312
4328
 
4313
4329
  const collected = sols.map((sBody) => applySubstTerm(valueTempl, sBody));
@@ -4365,12 +4381,12 @@
4365
4381
  const rawThenClause = goal.s instanceof ListTerm ? goal.s.elems[1] : thenClause;
4366
4382
  const whereGoals =
4367
4383
  rawWhereClause instanceof GraphTerm
4368
- ? __prepareQuotedPatternTriples(rawWhereClause.triples, subst, varGen)
4369
- : __prepareQuotedPatternTriples(whereClause.triples, subst, varGen);
4384
+ ? __prepareQuotedPatternTriples(rawWhereClause, subst, varGen)
4385
+ : __prepareQuotedPatternTriples(whereClause, subst, varGen);
4370
4386
  const thenGoals =
4371
4387
  rawThenClause instanceof GraphTerm
4372
- ? __prepareQuotedPatternTriples(rawThenClause.triples, subst, varGen)
4373
- : __prepareQuotedPatternTriples(thenClause.triples, subst, varGen);
4388
+ ? __prepareQuotedPatternTriples(rawThenClause, subst, varGen)
4389
+ : __prepareQuotedPatternTriples(thenClause, subst, varGen);
4374
4390
 
4375
4391
  const visited1 = [];
4376
4392
  const sols1 = proveGoals(whereGoals, {}, scopeFacts, scopeBackRules, depth + 1, visited1, varGen);
@@ -4777,7 +4793,7 @@
4777
4793
  if (s2 !== tr.s || p2 !== tr.p || o2 !== tr.o) changed = true;
4778
4794
  return s2 === tr.s && p2 === tr.p && o2 === tr.o ? tr : new Triple(s2, p2, o2);
4779
4795
  });
4780
- return changed ? new GraphTerm(triples2) : t;
4796
+ return changed ? copyQuotedGraphMetadata(t, new GraphTerm(triples2)) : t;
4781
4797
  }
4782
4798
  return t;
4783
4799
  }
@@ -4835,7 +4851,7 @@
4835
4851
  if (s2 !== tr.s || p2 !== tr.p || o2 !== tr.o) changed = true;
4836
4852
  return s2 === tr.s && p2 === tr.p && o2 === tr.o ? tr : new Triple(s2, p2, o2);
4837
4853
  });
4838
- return changed ? new GraphTerm(triples2) : t;
4854
+ return changed ? copyQuotedGraphMetadata(t, new GraphTerm(triples2)) : t;
4839
4855
  }
4840
4856
  return t;
4841
4857
  }
@@ -5839,6 +5855,7 @@
5839
5855
  DerivedFact,
5840
5856
  internIri,
5841
5857
  collectBlankLabelsInTriples,
5858
+ copyQuotedGraphMetadata,
5842
5859
  } = require('./prelude');
5843
5860
 
5844
5861
  // In N3/Turtle, rdf:nil is the canonical IRI for the empty RDF list.
@@ -7577,7 +7594,7 @@
7577
7594
  out.push(v);
7578
7595
  }
7579
7596
  }
7580
- return out ? new GraphTerm(out) : t;
7597
+ return out ? copyQuotedGraphMetadata(t, new GraphTerm(out)) : t;
7581
7598
  }
7582
7599
 
7583
7600
  return t;
@@ -10526,6 +10543,7 @@ ${triples.map((tr) => ` ${tripleToN3(tr, prefixes)}`).join('\n')}
10526
10543
  isLogImplies,
10527
10544
  isLogImpliedBy,
10528
10545
  isLogQuery,
10546
+ annotateQuotedGraphTerm,
10529
10547
  } = require('./prelude');
10530
10548
 
10531
10549
  const { N3SyntaxError } = require('./lexer');
@@ -11073,7 +11091,7 @@ ${triples.map((tr) => ` ${tripleToN3(tr, prefixes)}`).join('\n')}
11073
11091
  }
11074
11092
  }
11075
11093
  this.next(); // consume '}'
11076
- return new GraphTerm(triples);
11094
+ return annotateQuotedGraphTerm(new GraphTerm(triples));
11077
11095
  }
11078
11096
 
11079
11097
  parseStatementVerb() {
@@ -11744,6 +11762,32 @@ ${triples.map((tr) => ` ${tripleToN3(tr, prefixes)}`).join('\n')}
11744
11762
  return acc;
11745
11763
  }
11746
11764
 
11765
+ function annotateQuotedGraphTerm(graph) {
11766
+ if (!(graph instanceof GraphTerm)) return graph;
11767
+ const labels = collectBlankLabelsInTriples(graph.triples);
11768
+ Object.defineProperty(graph, '__quotedLocalBlankLabels', {
11769
+ value: labels,
11770
+ enumerable: false,
11771
+ writable: true,
11772
+ configurable: true,
11773
+ });
11774
+ return graph;
11775
+ }
11776
+
11777
+ function copyQuotedGraphMetadata(src, dst) {
11778
+ if (!(src instanceof GraphTerm) || !(dst instanceof GraphTerm)) return dst;
11779
+ if (!Object.prototype.hasOwnProperty.call(src, '__quotedLocalBlankLabels')) return dst;
11780
+
11781
+ const labels = src.__quotedLocalBlankLabels;
11782
+ Object.defineProperty(dst, '__quotedLocalBlankLabels', {
11783
+ value: labels instanceof Set ? new Set(labels) : labels,
11784
+ enumerable: false,
11785
+ writable: true,
11786
+ configurable: true,
11787
+ });
11788
+ return dst;
11789
+ }
11790
+
11747
11791
  module.exports = {
11748
11792
  RDF_NS,
11749
11793
  RDFS_NS,
@@ -11783,6 +11827,8 @@ ${triples.map((tr) => ` ${tripleToN3(tr, prefixes)}`).join('\n')}
11783
11827
  collectIrisInTerm,
11784
11828
  varsInRule,
11785
11829
  collectBlankLabelsInTriples,
11830
+ annotateQuotedGraphTerm,
11831
+ copyQuotedGraphMetadata,
11786
11832
  };
11787
11833
  };
11788
11834
  __modules['lib/printing.js'] = function (require, module, exports) {
@@ -12960,7 +13006,7 @@ ${triples.map((tr) => ` ${tripleToN3(tr, prefixes)}`).join('\n')}
12960
13006
 
12961
13007
  'use strict';
12962
13008
 
12963
- const { Var, Blank, ListTerm, OpenListTerm, GraphTerm, Triple } = require('./prelude');
13009
+ const { Var, Blank, ListTerm, OpenListTerm, GraphTerm, Triple, copyQuotedGraphMetadata } = require('./prelude');
12964
13010
 
12965
13011
  function liftBlankRuleVars(premise, conclusion) {
12966
13012
  // Map blank labels to stable rule-local variable names.
@@ -12988,7 +13034,7 @@ ${triples.map((tr) => ` ${tripleToN3(tr, prefixes)}`).join('\n')}
12988
13034
  const triples = t.triples.map(
12989
13035
  (tr) => new Triple(copyQuotedTerm(tr.s), copyQuotedTerm(tr.p), copyQuotedTerm(tr.o)),
12990
13036
  );
12991
- return new GraphTerm(triples);
13037
+ return copyQuotedGraphMetadata(t, new GraphTerm(triples));
12992
13038
  }
12993
13039
  return t;
12994
13040
  }
package/eyeling.js CHANGED
@@ -507,6 +507,7 @@ const {
507
507
  internLiteral,
508
508
  PrefixEnv,
509
509
  literalParts,
510
+ copyQuotedGraphMetadata,
510
511
  } = require('./prelude');
511
512
 
512
513
  const { decodeN3StringEscapes } = require('./lexer');
@@ -809,8 +810,9 @@ function __builtinCollectVarsInTriples(triples, out) {
809
810
  for (const tr of triples) __builtinCollectVarsInTriple(tr, out);
810
811
  }
811
812
 
812
- function __existentializeBlankTerm(t, mapping, varGen) {
813
+ function __existentializeBlankTerm(t, mapping, varGen, localBlankLabels) {
813
814
  if (t instanceof Blank) {
815
+ if (localBlankLabels instanceof Set && !localBlankLabels.has(t.label)) return t;
814
816
  let v = mapping[t.label];
815
817
  if (v === undefined) {
816
818
  const n = Array.isArray(varGen) && typeof varGen[0] === 'number' ? varGen[0]++ : Object.keys(mapping).length + 1;
@@ -822,34 +824,47 @@ function __existentializeBlankTerm(t, mapping, varGen) {
822
824
  if (t instanceof ListTerm) return t;
823
825
  if (t instanceof OpenListTerm) return t;
824
826
  if (t instanceof GraphTerm) {
827
+ const nestedLocalBlankLabels =
828
+ Object.prototype.hasOwnProperty.call(t, '__quotedLocalBlankLabels') && t.__quotedLocalBlankLabels instanceof Set
829
+ ? t.__quotedLocalBlankLabels
830
+ : localBlankLabels;
825
831
  let changed = false;
826
832
  const triples = t.triples.map((tr) => {
827
- const s2 = __existentializeBlankTerm(tr.s, mapping, varGen);
828
- const p2 = __existentializeBlankTerm(tr.p, mapping, varGen);
829
- const o2 = __existentializeBlankTerm(tr.o, mapping, varGen);
833
+ const s2 = __existentializeBlankTerm(tr.s, mapping, varGen, nestedLocalBlankLabels);
834
+ const p2 = __existentializeBlankTerm(tr.p, mapping, varGen, nestedLocalBlankLabels);
835
+ const o2 = __existentializeBlankTerm(tr.o, mapping, varGen, nestedLocalBlankLabels);
830
836
  if (s2 !== tr.s || p2 !== tr.p || o2 !== tr.o) changed = true;
831
837
  return s2 === tr.s && p2 === tr.p && o2 === tr.o ? tr : new Triple(s2, p2, o2);
832
838
  });
833
- return changed ? new GraphTerm(triples) : t;
839
+ return changed ? copyQuotedGraphMetadata(t, new GraphTerm(triples)) : t;
834
840
  }
835
841
  return t;
836
842
  }
837
843
 
838
- function __existentializeBlankTriples(triples, varGen) {
844
+ function __existentializeBlankTriples(rawGraphOrTriples, varGen) {
845
+ const triples =
846
+ rawGraphOrTriples instanceof GraphTerm ? Array.from(rawGraphOrTriples.triples) : Array.from(rawGraphOrTriples);
847
+ const localBlankLabels =
848
+ rawGraphOrTriples instanceof GraphTerm &&
849
+ Object.prototype.hasOwnProperty.call(rawGraphOrTriples, '__quotedLocalBlankLabels') &&
850
+ rawGraphOrTriples.__quotedLocalBlankLabels instanceof Set
851
+ ? rawGraphOrTriples.__quotedLocalBlankLabels
852
+ : null;
853
+
839
854
  const mapping = Object.create(null);
840
855
  let changed = false;
841
856
  const out = triples.map((tr) => {
842
- const s2 = __existentializeBlankTerm(tr.s, mapping, varGen);
843
- const p2 = __existentializeBlankTerm(tr.p, mapping, varGen);
844
- const o2 = __existentializeBlankTerm(tr.o, mapping, varGen);
857
+ const s2 = __existentializeBlankTerm(tr.s, mapping, varGen, localBlankLabels);
858
+ const p2 = __existentializeBlankTerm(tr.p, mapping, varGen, localBlankLabels);
859
+ const o2 = __existentializeBlankTerm(tr.o, mapping, varGen, localBlankLabels);
845
860
  if (s2 !== tr.s || p2 !== tr.p || o2 !== tr.o) changed = true;
846
861
  return s2 === tr.s && p2 === tr.p && o2 === tr.o ? tr : new Triple(s2, p2, o2);
847
862
  });
848
863
  return changed ? out : triples;
849
864
  }
850
865
 
851
- function __prepareQuotedPatternTriples(rawTriples, subst, varGen) {
852
- const ex = __existentializeBlankTriples(Array.from(rawTriples), varGen);
866
+ function __prepareQuotedPatternTriples(rawGraphOrTriples, subst, varGen) {
867
+ const ex = __existentializeBlankTriples(rawGraphOrTriples, varGen);
853
868
  let changed = false;
854
869
  const out = ex.map((tr) => {
855
870
  const tr2 = applySubstTriple(tr, subst);
@@ -4112,7 +4127,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen, maxResults) {
4112
4127
  const keepVars = new Set();
4113
4128
  if (g.s instanceof GraphTerm) __builtinCollectVarsInTriples(g.s.triples, keepVars);
4114
4129
 
4115
- const goalTriples = __prepareQuotedPatternTriples(goal.o.triples, subst, varGen);
4130
+ const goalTriples = __prepareQuotedPatternTriples(goal.o, subst, varGen);
4116
4131
  const goalVariants = __expandScopedVarPredicateGoals(goalTriples);
4117
4132
  const out = [];
4118
4133
  for (const variant of goalVariants) {
@@ -4195,7 +4210,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen, maxResults) {
4195
4210
 
4196
4211
  const visited2 = [];
4197
4212
  const sols = proveGoals(
4198
- __prepareQuotedPatternTriples(goal.o.triples, subst, varGen),
4213
+ __prepareQuotedPatternTriples(goal.o, subst, varGen),
4199
4214
  { ...subst },
4200
4215
  scopeFacts,
4201
4216
  scopeBackRules,
@@ -4292,8 +4307,8 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen, maxResults) {
4292
4307
  const rawClauseTerm = goal.s instanceof ListTerm ? goal.s.elems[1] : clauseTerm;
4293
4308
  const clauseGoals =
4294
4309
  rawClauseTerm instanceof GraphTerm
4295
- ? __prepareQuotedPatternTriples(rawClauseTerm.triples, subst, varGen)
4296
- : __prepareQuotedPatternTriples(clauseTerm.triples, subst, varGen);
4310
+ ? __prepareQuotedPatternTriples(rawClauseTerm, subst, varGen)
4311
+ : __prepareQuotedPatternTriples(clauseTerm, subst, varGen);
4297
4312
  const sols = proveGoals(clauseGoals, {}, scopeFacts, scopeBackRules, depth + 1, visited2, varGen);
4298
4313
 
4299
4314
  const collected = sols.map((sBody) => applySubstTerm(valueTempl, sBody));
@@ -4351,12 +4366,12 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen, maxResults) {
4351
4366
  const rawThenClause = goal.s instanceof ListTerm ? goal.s.elems[1] : thenClause;
4352
4367
  const whereGoals =
4353
4368
  rawWhereClause instanceof GraphTerm
4354
- ? __prepareQuotedPatternTriples(rawWhereClause.triples, subst, varGen)
4355
- : __prepareQuotedPatternTriples(whereClause.triples, subst, varGen);
4369
+ ? __prepareQuotedPatternTriples(rawWhereClause, subst, varGen)
4370
+ : __prepareQuotedPatternTriples(whereClause, subst, varGen);
4356
4371
  const thenGoals =
4357
4372
  rawThenClause instanceof GraphTerm
4358
- ? __prepareQuotedPatternTriples(rawThenClause.triples, subst, varGen)
4359
- : __prepareQuotedPatternTriples(thenClause.triples, subst, varGen);
4373
+ ? __prepareQuotedPatternTriples(rawThenClause, subst, varGen)
4374
+ : __prepareQuotedPatternTriples(thenClause, subst, varGen);
4360
4375
 
4361
4376
  const visited1 = [];
4362
4377
  const sols1 = proveGoals(whereGoals, {}, scopeFacts, scopeBackRules, depth + 1, visited1, varGen);
@@ -4763,7 +4778,7 @@ function standardizeTermApart(term, gen) {
4763
4778
  if (s2 !== tr.s || p2 !== tr.p || o2 !== tr.o) changed = true;
4764
4779
  return s2 === tr.s && p2 === tr.p && o2 === tr.o ? tr : new Triple(s2, p2, o2);
4765
4780
  });
4766
- return changed ? new GraphTerm(triples2) : t;
4781
+ return changed ? copyQuotedGraphMetadata(t, new GraphTerm(triples2)) : t;
4767
4782
  }
4768
4783
  return t;
4769
4784
  }
@@ -4821,7 +4836,7 @@ function standardizeRule(rule, gen) {
4821
4836
  if (s2 !== tr.s || p2 !== tr.p || o2 !== tr.o) changed = true;
4822
4837
  return s2 === tr.s && p2 === tr.p && o2 === tr.o ? tr : new Triple(s2, p2, o2);
4823
4838
  });
4824
- return changed ? new GraphTerm(triples2) : t;
4839
+ return changed ? copyQuotedGraphMetadata(t, new GraphTerm(triples2)) : t;
4825
4840
  }
4826
4841
  return t;
4827
4842
  }
@@ -5822,6 +5837,7 @@ const {
5822
5837
  DerivedFact,
5823
5838
  internIri,
5824
5839
  collectBlankLabelsInTriples,
5840
+ copyQuotedGraphMetadata,
5825
5841
  } = require('./prelude');
5826
5842
 
5827
5843
  // In N3/Turtle, rdf:nil is the canonical IRI for the empty RDF list.
@@ -7558,7 +7574,7 @@ function applySubstTerm(t, s) {
7558
7574
  out.push(v);
7559
7575
  }
7560
7576
  }
7561
- return out ? new GraphTerm(out) : t;
7577
+ return out ? copyQuotedGraphMetadata(t, new GraphTerm(out)) : t;
7562
7578
  }
7563
7579
 
7564
7580
  return t;
@@ -10495,6 +10511,7 @@ const {
10495
10511
  isLogImplies,
10496
10512
  isLogImpliedBy,
10497
10513
  isLogQuery,
10514
+ annotateQuotedGraphTerm,
10498
10515
  } = require('./prelude');
10499
10516
 
10500
10517
  const { N3SyntaxError } = require('./lexer');
@@ -11042,7 +11059,7 @@ class Parser {
11042
11059
  }
11043
11060
  }
11044
11061
  this.next(); // consume '}'
11045
- return new GraphTerm(triples);
11062
+ return annotateQuotedGraphTerm(new GraphTerm(triples));
11046
11063
  }
11047
11064
 
11048
11065
  parseStatementVerb() {
@@ -11714,6 +11731,32 @@ function collectBlankLabelsInTriples(triples) {
11714
11731
  return acc;
11715
11732
  }
11716
11733
 
11734
+ function annotateQuotedGraphTerm(graph) {
11735
+ if (!(graph instanceof GraphTerm)) return graph;
11736
+ const labels = collectBlankLabelsInTriples(graph.triples);
11737
+ Object.defineProperty(graph, '__quotedLocalBlankLabels', {
11738
+ value: labels,
11739
+ enumerable: false,
11740
+ writable: true,
11741
+ configurable: true,
11742
+ });
11743
+ return graph;
11744
+ }
11745
+
11746
+ function copyQuotedGraphMetadata(src, dst) {
11747
+ if (!(src instanceof GraphTerm) || !(dst instanceof GraphTerm)) return dst;
11748
+ if (!Object.prototype.hasOwnProperty.call(src, '__quotedLocalBlankLabels')) return dst;
11749
+
11750
+ const labels = src.__quotedLocalBlankLabels;
11751
+ Object.defineProperty(dst, '__quotedLocalBlankLabels', {
11752
+ value: labels instanceof Set ? new Set(labels) : labels,
11753
+ enumerable: false,
11754
+ writable: true,
11755
+ configurable: true,
11756
+ });
11757
+ return dst;
11758
+ }
11759
+
11717
11760
  module.exports = {
11718
11761
  RDF_NS,
11719
11762
  RDFS_NS,
@@ -11753,6 +11796,8 @@ module.exports = {
11753
11796
  collectIrisInTerm,
11754
11797
  varsInRule,
11755
11798
  collectBlankLabelsInTriples,
11799
+ annotateQuotedGraphTerm,
11800
+ copyQuotedGraphMetadata,
11756
11801
  };
11757
11802
 
11758
11803
  };
@@ -12920,7 +12965,7 @@ module.exports = {
12920
12965
 
12921
12966
  'use strict';
12922
12967
 
12923
- const { Var, Blank, ListTerm, OpenListTerm, GraphTerm, Triple } = require('./prelude');
12968
+ const { Var, Blank, ListTerm, OpenListTerm, GraphTerm, Triple, copyQuotedGraphMetadata } = require('./prelude');
12924
12969
 
12925
12970
  function liftBlankRuleVars(premise, conclusion) {
12926
12971
  // Map blank labels to stable rule-local variable names.
@@ -12948,7 +12993,7 @@ function liftBlankRuleVars(premise, conclusion) {
12948
12993
  const triples = t.triples.map(
12949
12994
  (tr) => new Triple(copyQuotedTerm(tr.s), copyQuotedTerm(tr.p), copyQuotedTerm(tr.o)),
12950
12995
  );
12951
- return new GraphTerm(triples);
12996
+ return copyQuotedGraphMetadata(t, new GraphTerm(triples));
12952
12997
  }
12953
12998
  return t;
12954
12999
  }
package/lib/builtins.js CHANGED
@@ -28,6 +28,7 @@ const {
28
28
  internLiteral,
29
29
  PrefixEnv,
30
30
  literalParts,
31
+ copyQuotedGraphMetadata,
31
32
  } = require('./prelude');
32
33
 
33
34
  const { decodeN3StringEscapes } = require('./lexer');
@@ -330,8 +331,9 @@ function __builtinCollectVarsInTriples(triples, out) {
330
331
  for (const tr of triples) __builtinCollectVarsInTriple(tr, out);
331
332
  }
332
333
 
333
- function __existentializeBlankTerm(t, mapping, varGen) {
334
+ function __existentializeBlankTerm(t, mapping, varGen, localBlankLabels) {
334
335
  if (t instanceof Blank) {
336
+ if (localBlankLabels instanceof Set && !localBlankLabels.has(t.label)) return t;
335
337
  let v = mapping[t.label];
336
338
  if (v === undefined) {
337
339
  const n = Array.isArray(varGen) && typeof varGen[0] === 'number' ? varGen[0]++ : Object.keys(mapping).length + 1;
@@ -343,34 +345,47 @@ function __existentializeBlankTerm(t, mapping, varGen) {
343
345
  if (t instanceof ListTerm) return t;
344
346
  if (t instanceof OpenListTerm) return t;
345
347
  if (t instanceof GraphTerm) {
348
+ const nestedLocalBlankLabels =
349
+ Object.prototype.hasOwnProperty.call(t, '__quotedLocalBlankLabels') && t.__quotedLocalBlankLabels instanceof Set
350
+ ? t.__quotedLocalBlankLabels
351
+ : localBlankLabels;
346
352
  let changed = false;
347
353
  const triples = t.triples.map((tr) => {
348
- const s2 = __existentializeBlankTerm(tr.s, mapping, varGen);
349
- const p2 = __existentializeBlankTerm(tr.p, mapping, varGen);
350
- const o2 = __existentializeBlankTerm(tr.o, mapping, varGen);
354
+ const s2 = __existentializeBlankTerm(tr.s, mapping, varGen, nestedLocalBlankLabels);
355
+ const p2 = __existentializeBlankTerm(tr.p, mapping, varGen, nestedLocalBlankLabels);
356
+ const o2 = __existentializeBlankTerm(tr.o, mapping, varGen, nestedLocalBlankLabels);
351
357
  if (s2 !== tr.s || p2 !== tr.p || o2 !== tr.o) changed = true;
352
358
  return s2 === tr.s && p2 === tr.p && o2 === tr.o ? tr : new Triple(s2, p2, o2);
353
359
  });
354
- return changed ? new GraphTerm(triples) : t;
360
+ return changed ? copyQuotedGraphMetadata(t, new GraphTerm(triples)) : t;
355
361
  }
356
362
  return t;
357
363
  }
358
364
 
359
- function __existentializeBlankTriples(triples, varGen) {
365
+ function __existentializeBlankTriples(rawGraphOrTriples, varGen) {
366
+ const triples =
367
+ rawGraphOrTriples instanceof GraphTerm ? Array.from(rawGraphOrTriples.triples) : Array.from(rawGraphOrTriples);
368
+ const localBlankLabels =
369
+ rawGraphOrTriples instanceof GraphTerm &&
370
+ Object.prototype.hasOwnProperty.call(rawGraphOrTriples, '__quotedLocalBlankLabels') &&
371
+ rawGraphOrTriples.__quotedLocalBlankLabels instanceof Set
372
+ ? rawGraphOrTriples.__quotedLocalBlankLabels
373
+ : null;
374
+
360
375
  const mapping = Object.create(null);
361
376
  let changed = false;
362
377
  const out = triples.map((tr) => {
363
- const s2 = __existentializeBlankTerm(tr.s, mapping, varGen);
364
- const p2 = __existentializeBlankTerm(tr.p, mapping, varGen);
365
- const o2 = __existentializeBlankTerm(tr.o, mapping, varGen);
378
+ const s2 = __existentializeBlankTerm(tr.s, mapping, varGen, localBlankLabels);
379
+ const p2 = __existentializeBlankTerm(tr.p, mapping, varGen, localBlankLabels);
380
+ const o2 = __existentializeBlankTerm(tr.o, mapping, varGen, localBlankLabels);
366
381
  if (s2 !== tr.s || p2 !== tr.p || o2 !== tr.o) changed = true;
367
382
  return s2 === tr.s && p2 === tr.p && o2 === tr.o ? tr : new Triple(s2, p2, o2);
368
383
  });
369
384
  return changed ? out : triples;
370
385
  }
371
386
 
372
- function __prepareQuotedPatternTriples(rawTriples, subst, varGen) {
373
- const ex = __existentializeBlankTriples(Array.from(rawTriples), varGen);
387
+ function __prepareQuotedPatternTriples(rawGraphOrTriples, subst, varGen) {
388
+ const ex = __existentializeBlankTriples(rawGraphOrTriples, varGen);
374
389
  let changed = false;
375
390
  const out = ex.map((tr) => {
376
391
  const tr2 = applySubstTriple(tr, subst);
@@ -3633,7 +3648,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen, maxResults) {
3633
3648
  const keepVars = new Set();
3634
3649
  if (g.s instanceof GraphTerm) __builtinCollectVarsInTriples(g.s.triples, keepVars);
3635
3650
 
3636
- const goalTriples = __prepareQuotedPatternTriples(goal.o.triples, subst, varGen);
3651
+ const goalTriples = __prepareQuotedPatternTriples(goal.o, subst, varGen);
3637
3652
  const goalVariants = __expandScopedVarPredicateGoals(goalTriples);
3638
3653
  const out = [];
3639
3654
  for (const variant of goalVariants) {
@@ -3716,7 +3731,7 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen, maxResults) {
3716
3731
 
3717
3732
  const visited2 = [];
3718
3733
  const sols = proveGoals(
3719
- __prepareQuotedPatternTriples(goal.o.triples, subst, varGen),
3734
+ __prepareQuotedPatternTriples(goal.o, subst, varGen),
3720
3735
  { ...subst },
3721
3736
  scopeFacts,
3722
3737
  scopeBackRules,
@@ -3813,8 +3828,8 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen, maxResults) {
3813
3828
  const rawClauseTerm = goal.s instanceof ListTerm ? goal.s.elems[1] : clauseTerm;
3814
3829
  const clauseGoals =
3815
3830
  rawClauseTerm instanceof GraphTerm
3816
- ? __prepareQuotedPatternTriples(rawClauseTerm.triples, subst, varGen)
3817
- : __prepareQuotedPatternTriples(clauseTerm.triples, subst, varGen);
3831
+ ? __prepareQuotedPatternTriples(rawClauseTerm, subst, varGen)
3832
+ : __prepareQuotedPatternTriples(clauseTerm, subst, varGen);
3818
3833
  const sols = proveGoals(clauseGoals, {}, scopeFacts, scopeBackRules, depth + 1, visited2, varGen);
3819
3834
 
3820
3835
  const collected = sols.map((sBody) => applySubstTerm(valueTempl, sBody));
@@ -3872,12 +3887,12 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen, maxResults) {
3872
3887
  const rawThenClause = goal.s instanceof ListTerm ? goal.s.elems[1] : thenClause;
3873
3888
  const whereGoals =
3874
3889
  rawWhereClause instanceof GraphTerm
3875
- ? __prepareQuotedPatternTriples(rawWhereClause.triples, subst, varGen)
3876
- : __prepareQuotedPatternTriples(whereClause.triples, subst, varGen);
3890
+ ? __prepareQuotedPatternTriples(rawWhereClause, subst, varGen)
3891
+ : __prepareQuotedPatternTriples(whereClause, subst, varGen);
3877
3892
  const thenGoals =
3878
3893
  rawThenClause instanceof GraphTerm
3879
- ? __prepareQuotedPatternTriples(rawThenClause.triples, subst, varGen)
3880
- : __prepareQuotedPatternTriples(thenClause.triples, subst, varGen);
3894
+ ? __prepareQuotedPatternTriples(rawThenClause, subst, varGen)
3895
+ : __prepareQuotedPatternTriples(thenClause, subst, varGen);
3881
3896
 
3882
3897
  const visited1 = [];
3883
3898
  const sols1 = proveGoals(whereGoals, {}, scopeFacts, scopeBackRules, depth + 1, visited1, varGen);
@@ -4284,7 +4299,7 @@ function standardizeTermApart(term, gen) {
4284
4299
  if (s2 !== tr.s || p2 !== tr.p || o2 !== tr.o) changed = true;
4285
4300
  return s2 === tr.s && p2 === tr.p && o2 === tr.o ? tr : new Triple(s2, p2, o2);
4286
4301
  });
4287
- return changed ? new GraphTerm(triples2) : t;
4302
+ return changed ? copyQuotedGraphMetadata(t, new GraphTerm(triples2)) : t;
4288
4303
  }
4289
4304
  return t;
4290
4305
  }
@@ -4342,7 +4357,7 @@ function standardizeRule(rule, gen) {
4342
4357
  if (s2 !== tr.s || p2 !== tr.p || o2 !== tr.o) changed = true;
4343
4358
  return s2 === tr.s && p2 === tr.p && o2 === tr.o ? tr : new Triple(s2, p2, o2);
4344
4359
  });
4345
- return changed ? new GraphTerm(triples2) : t;
4360
+ return changed ? copyQuotedGraphMetadata(t, new GraphTerm(triples2)) : t;
4346
4361
  }
4347
4362
  return t;
4348
4363
  }
package/lib/engine.js CHANGED
@@ -27,6 +27,7 @@ const {
27
27
  DerivedFact,
28
28
  internIri,
29
29
  collectBlankLabelsInTriples,
30
+ copyQuotedGraphMetadata,
30
31
  } = require('./prelude');
31
32
 
32
33
  // In N3/Turtle, rdf:nil is the canonical IRI for the empty RDF list.
@@ -1763,7 +1764,7 @@ function applySubstTerm(t, s) {
1763
1764
  out.push(v);
1764
1765
  }
1765
1766
  }
1766
- return out ? new GraphTerm(out) : t;
1767
+ return out ? copyQuotedGraphMetadata(t, new GraphTerm(out)) : t;
1767
1768
  }
1768
1769
 
1769
1770
  return t;
package/lib/parser.js CHANGED
@@ -26,6 +26,7 @@ const {
26
26
  isLogImplies,
27
27
  isLogImpliedBy,
28
28
  isLogQuery,
29
+ annotateQuotedGraphTerm,
29
30
  } = require('./prelude');
30
31
 
31
32
  const { N3SyntaxError } = require('./lexer');
@@ -573,7 +574,7 @@ class Parser {
573
574
  }
574
575
  }
575
576
  this.next(); // consume '}'
576
- return new GraphTerm(triples);
577
+ return annotateQuotedGraphTerm(new GraphTerm(triples));
577
578
  }
578
579
 
579
580
  parseStatementVerb() {
package/lib/prelude.js CHANGED
@@ -501,6 +501,32 @@ function collectBlankLabelsInTriples(triples) {
501
501
  return acc;
502
502
  }
503
503
 
504
+ function annotateQuotedGraphTerm(graph) {
505
+ if (!(graph instanceof GraphTerm)) return graph;
506
+ const labels = collectBlankLabelsInTriples(graph.triples);
507
+ Object.defineProperty(graph, '__quotedLocalBlankLabels', {
508
+ value: labels,
509
+ enumerable: false,
510
+ writable: true,
511
+ configurable: true,
512
+ });
513
+ return graph;
514
+ }
515
+
516
+ function copyQuotedGraphMetadata(src, dst) {
517
+ if (!(src instanceof GraphTerm) || !(dst instanceof GraphTerm)) return dst;
518
+ if (!Object.prototype.hasOwnProperty.call(src, '__quotedLocalBlankLabels')) return dst;
519
+
520
+ const labels = src.__quotedLocalBlankLabels;
521
+ Object.defineProperty(dst, '__quotedLocalBlankLabels', {
522
+ value: labels instanceof Set ? new Set(labels) : labels,
523
+ enumerable: false,
524
+ writable: true,
525
+ configurable: true,
526
+ });
527
+ return dst;
528
+ }
529
+
504
530
  module.exports = {
505
531
  RDF_NS,
506
532
  RDFS_NS,
@@ -540,4 +566,6 @@ module.exports = {
540
566
  collectIrisInTerm,
541
567
  varsInRule,
542
568
  collectBlankLabelsInTriples,
569
+ annotateQuotedGraphTerm,
570
+ copyQuotedGraphMetadata,
543
571
  };
package/lib/rules.js CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  'use strict';
9
9
 
10
- const { Var, Blank, ListTerm, OpenListTerm, GraphTerm, Triple } = require('./prelude');
10
+ const { Var, Blank, ListTerm, OpenListTerm, GraphTerm, Triple, copyQuotedGraphMetadata } = require('./prelude');
11
11
 
12
12
  function liftBlankRuleVars(premise, conclusion) {
13
13
  // Map blank labels to stable rule-local variable names.
@@ -35,7 +35,7 @@ function liftBlankRuleVars(premise, conclusion) {
35
35
  const triples = t.triples.map(
36
36
  (tr) => new Triple(copyQuotedTerm(tr.s), copyQuotedTerm(tr.p), copyQuotedTerm(tr.o)),
37
37
  );
38
- return new GraphTerm(triples);
38
+ return copyQuotedGraphMetadata(t, new GraphTerm(triples));
39
39
  }
40
40
  return t;
41
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.22.8",
3
+ "version": "1.22.10",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [
package/test/api.test.js CHANGED
@@ -2095,6 +2095,29 @@ _:x :hates { _:foo :making :mess }.
2095
2095
  /:result\s+:status\s+:matched\s*\./,
2096
2096
  ],
2097
2097
  },
2098
+
2099
+ {
2100
+ name: '243aa regression: collectAllIn keeps outer blank-node bindings fixed in quoted formulas',
2101
+ opt: { proofComments: false },
2102
+ input: `@prefix log: <http://www.w3.org/2000/10/swap/log#> .
2103
+ @prefix ex: <http://example.org/> .
2104
+
2105
+ ex:a a ex:Person ; ex:name "A" .
2106
+ _:b a ex:Person ; ex:name "B" .
2107
+
2108
+ {
2109
+ ?person a ex:Person .
2110
+ (?x { ?person ex:name ?x } ?xs) log:collectAllIn ?SCOPE .
2111
+ }
2112
+ =>
2113
+ {
2114
+ ?person ex:names ?xs .
2115
+ } .
2116
+ `,
2117
+ expect: [/ex:a\s+ex:names\s+\("A"\)\s*\./, /_:[^\s]+\s+ex:names\s+\("B"\)\s*\./],
2118
+ notExpect: [/_:[^\s]+\s+ex:names\s+\("A"\s+"B"\)\s*\./, /_:[^\s]+\s+ex:names\s+\("B"\s+"A"\)\s*\./],
2119
+ },
2120
+
2098
2121
  {
2099
2122
  name: '243a regression: collectAllIn treats quoted-formula blanks existentially',
2100
2123
  opt: { proofComments: false },