eyeling 1.28.2 → 1.28.4

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 CHANGED
@@ -9796,11 +9796,18 @@ function reasonStream(input, opts = {}) {
9796
9796
  if (baseIri) prefixes.setBase(baseIri);
9797
9797
  } else {
9798
9798
  const n3Text = normalizeReasonerInputSync(input);
9799
- const toks = lex(n3Text, { rdf: useRdfCompatibility });
9800
- const parser = new Parser(toks);
9801
- if (baseIri) parser.prefixes.setBase(baseIri);
9802
-
9803
- [prefixes, triples, frules, brules, logQueryRules] = parser.parseDocument();
9799
+ const directDoc = parseN3Text(n3Text, {
9800
+ baseIri: baseIri || '',
9801
+ label: sourceLabel || '<input>',
9802
+ keepSourceArtifacts: false,
9803
+ sourceLocations: proof,
9804
+ rdf: useRdfCompatibility,
9805
+ });
9806
+ prefixes = directDoc.prefixes;
9807
+ triples = directDoc.triples;
9808
+ frules = directDoc.frules;
9809
+ brules = directDoc.brules;
9810
+ logQueryRules = directDoc.logQueryRules;
9804
9811
  }
9805
9812
  // Make the parsed prefixes available to log:trace output
9806
9813
  trace.setTracePrefixes(prefixes);
@@ -10621,6 +10628,460 @@ ${proofBody}
10621
10628
 
10622
10629
  module.exports = { makeExplain };
10623
10630
 
10631
+ };
10632
+ __modules["lib/fast_rdf.js"] = function(require, module, exports){
10633
+ /**
10634
+ * Fast RDF compatibility parser for line-oriented RDF inputs.
10635
+ *
10636
+ * This is deliberately conservative. It directly builds Eyeling AST terms for
10637
+ * common RDF parser workloads (N-Triples-style Turtle, simple prefixed triples,
10638
+ * N-Quads, and RDF Message Logs) and returns null for richer N3/Turtle/TriG
10639
+ * constructs so the full lexer/parser remains the source of truth.
10640
+ */
10641
+
10642
+ 'use strict';
10643
+
10644
+ const { N3SyntaxError, decodeN3StringEscapes } = require('./lexer');
10645
+ const {
10646
+ RDF_NS,
10647
+ LOG_NS,
10648
+ XSD_NS,
10649
+ Blank,
10650
+ GraphTerm,
10651
+ ListTerm,
10652
+ Triple,
10653
+ PrefixEnv,
10654
+ internIri,
10655
+ internLiteral,
10656
+ resolveIriRef,
10657
+ annotateQuotedGraphTerm,
10658
+ } = require('./prelude');
10659
+
10660
+ const RDF_TYPE = internIri(RDF_NS + 'type');
10661
+ const LOG_NAME_OF = internIri(LOG_NS + 'nameOf');
10662
+ const XSD_INTEGER_IRI = XSD_NS + 'integer';
10663
+ const XSD_INTEGER_LITERAL_SUFFIX = `^^<${XSD_INTEGER_IRI}>`;
10664
+
10665
+ const EYMSG_NS = 'https://eyereasoner.github.io/eyeling/vocab/message#';
10666
+ const EYMSG_IRIS = Object.freeze({
10667
+ RDFMessageStream: internIri(`${EYMSG_NS}RDFMessageStream`),
10668
+ MessageEnvelope: internIri(`${EYMSG_NS}MessageEnvelope`),
10669
+ envelope: internIri(`${EYMSG_NS}envelope`),
10670
+ firstEnvelope: internIri(`${EYMSG_NS}firstEnvelope`),
10671
+ lastEnvelope: internIri(`${EYMSG_NS}lastEnvelope`),
10672
+ orderedEnvelopes: internIri(`${EYMSG_NS}orderedEnvelopes`),
10673
+ messageCount: internIri(`${EYMSG_NS}messageCount`),
10674
+ offset: internIri(`${EYMSG_NS}offset`),
10675
+ nextEnvelope: internIri(`${EYMSG_NS}nextEnvelope`),
10676
+ payloadGraph: internIri(`${EYMSG_NS}payloadGraph`),
10677
+ payloadKind: internIri(`${EYMSG_NS}payloadKind`),
10678
+ empty: internIri(`${EYMSG_NS}empty`),
10679
+ nonEmpty: internIri(`${EYMSG_NS}nonEmpty`),
10680
+ });
10681
+
10682
+ const VERSION_LINE_RE = /^\s*(?:@version|VERSION)\s+(["'])(?:1\.1|1\.2|1\.2-basic)(?:-messages)?\1\s*\.?\s*(?:#.*)?$/im;
10683
+ const MESSAGE_VERSION_LINE_RE = /^\s*(?:@version|VERSION)\s+(["'])(?:1\.1|1\.2|1\.2-basic)-messages\1\s*\.?\s*(?:#.*)?$/im;
10684
+ const MESSAGE_LINE_RE = /^\s*(?:MESSAGE\b|@message\s*\.?)\s*(?:#.*)?$/i;
10685
+
10686
+ function simpleHashText(s) {
10687
+ let h = 0x811c9dc5;
10688
+ for (let i = 0; i < s.length; i += 1) {
10689
+ h ^= s.charCodeAt(i);
10690
+ h = Math.imul(h, 0x01000193) >>> 0;
10691
+ }
10692
+ return h.toString(16).padStart(8, '0');
10693
+ }
10694
+
10695
+ function addOffset(obj, offset) {
10696
+ if (!obj || typeof offset !== 'number') return obj;
10697
+ Object.defineProperty(obj, '__sourceOffset', {
10698
+ value: offset,
10699
+ enumerable: false,
10700
+ writable: false,
10701
+ configurable: true,
10702
+ });
10703
+ return obj;
10704
+ }
10705
+
10706
+ function skipWs(s, i) {
10707
+ while (i < s.length) {
10708
+ const code = s.charCodeAt(i);
10709
+ if (code !== 0x20 && code !== 0x09 && code !== 0x0a && code !== 0x0d && code !== 0x0c) break;
10710
+ i += 1;
10711
+ }
10712
+ return i;
10713
+ }
10714
+
10715
+ function maybeDecodeIriRef(raw, offset, prefixes) {
10716
+ const iri = raw.includes('\\') ? decodeN3StringEscapes(raw, offset) : raw;
10717
+ if (!prefixes.baseIri || /^[A-Za-z][A-Za-z0-9+.-]*:/.test(iri)) return iri;
10718
+ return resolveIriRef(iri, prefixes.baseIri || '');
10719
+ }
10720
+
10721
+ function readIriRef(s, i) {
10722
+ if (s[i] !== '<' || s[i + 1] === '<') return null;
10723
+ let j = i + 1;
10724
+ while (j < s.length) {
10725
+ const ch = s[j];
10726
+ if (ch === '\\') {
10727
+ j += 2;
10728
+ continue;
10729
+ }
10730
+ if (ch === '>') return { raw: s.slice(i + 1, j), end: j + 1 };
10731
+ j += 1;
10732
+ }
10733
+ throw new N3SyntaxError('Unterminated IRI <...>', i);
10734
+ }
10735
+
10736
+ function readQuoted(s, i) {
10737
+ const quote = s[i];
10738
+ if (quote !== '"' && quote !== "'") return null;
10739
+ const long = s.startsWith(quote.repeat(3), i);
10740
+ const start = i;
10741
+ if (long) {
10742
+ i += 3;
10743
+ const contentStart = i;
10744
+ let hasEscape = false;
10745
+ while (i < s.length) {
10746
+ if (s.startsWith(quote.repeat(3), i)) {
10747
+ return { text: s.slice(contentStart, i), end: i + 3, hasEscape };
10748
+ }
10749
+ const ch = s[i];
10750
+ if (ch === '\\') {
10751
+ hasEscape = true;
10752
+ i += 2;
10753
+ } else {
10754
+ i += 1;
10755
+ }
10756
+ }
10757
+ throw new N3SyntaxError(`Unterminated long string literal ${quote.repeat(3)}...${quote.repeat(3)}`, start);
10758
+ }
10759
+
10760
+ i += 1;
10761
+ const contentStart = i;
10762
+ let hasEscape = false;
10763
+ while (i < s.length) {
10764
+ const ch = s[i];
10765
+ if (ch === '\\') {
10766
+ hasEscape = true;
10767
+ i += 2;
10768
+ continue;
10769
+ }
10770
+ if (ch === quote) return { text: s.slice(contentStart, i), end: i + 1, hasEscape };
10771
+ i += 1;
10772
+ }
10773
+ throw new N3SyntaxError(`Unterminated string literal ${quote}...${quote}`, start);
10774
+ }
10775
+
10776
+ function readToken(s, i) {
10777
+ const start = i;
10778
+ while (i < s.length) {
10779
+ const ch = s[i];
10780
+ if (/\s/.test(ch) || ch === '.' || ch === ',' || ch === ';' || ch === '[' || ch === ']' || ch === '{' || ch === '}' || ch === '(' || ch === ')') break;
10781
+ i += 1;
10782
+ }
10783
+ if (i === start) return null;
10784
+ return { text: s.slice(start, i), end: i };
10785
+ }
10786
+
10787
+ function expandQNameToken(token, prefixes, usedPrefixes) {
10788
+ if (token === 'a') return RDF_NS + 'type';
10789
+ const sep = token.indexOf(':');
10790
+ if (sep < 0) return null;
10791
+ if (sep === 1 && token.charCodeAt(0) === 95) return null;
10792
+ const pfx = token.slice(0, sep);
10793
+ const local = token.slice(sep + 1);
10794
+ const base = prefixes.map[pfx] || '';
10795
+ if (!base && pfx !== '') return null;
10796
+ if (usedPrefixes && pfx) usedPrefixes.add(pfx);
10797
+ return base ? base + local : token;
10798
+ }
10799
+
10800
+ function parseIriOrQName(s, i, prefixes, usedPrefixes) {
10801
+ i = skipWs(s, i);
10802
+ const iri = readIriRef(s, i);
10803
+ if (iri) {
10804
+ return { term: internIri(maybeDecodeIriRef(iri.raw, i, prefixes)), end: iri.end };
10805
+ }
10806
+ const tok = readToken(s, i);
10807
+ if (!tok) return null;
10808
+ const expanded = expandQNameToken(tok.text, prefixes, usedPrefixes);
10809
+ if (expanded === null) return null;
10810
+ return { term: internIri(expanded), end: tok.end };
10811
+ }
10812
+
10813
+ function parseTerm(s, i, prefixes, usedPrefixes, blankPrefix = '') {
10814
+ i = skipWs(s, i);
10815
+ if (i >= s.length) return null;
10816
+ const ch = s[i];
10817
+
10818
+ if (ch === '<') return parseIriOrQName(s, i, prefixes, usedPrefixes);
10819
+
10820
+ if (ch === '_' && s[i + 1] === ':') {
10821
+ const tok = readToken(s, i);
10822
+ if (!tok) return null;
10823
+ let label = tok.text;
10824
+ if (blankPrefix) label = blankPrefix + label.slice(2).replace(/[^A-Za-z0-9_]/g, '_');
10825
+ return { term: new Blank(label), end: tok.end };
10826
+ }
10827
+
10828
+ if (ch === '"' || ch === "'") {
10829
+ const q = readQuoted(s, i);
10830
+ let end = q.end;
10831
+ const rawText = q.text;
10832
+ let value = q.hasEscape ? JSON.stringify(decodeN3StringEscapes(rawText, i)) : `"${rawText}"`;
10833
+
10834
+ if (s[end] === '@') {
10835
+ let j = end + 1;
10836
+ if (!/[A-Za-z]/.test(s[j] || '')) return null;
10837
+ while (j < s.length && /[A-Za-z0-9-]/.test(s[j])) j += 1;
10838
+ if (s[j] === '-' && s[j + 1] === '-') {
10839
+ const dir = s.slice(j + 2, j + 5);
10840
+ if ((dir === 'ltr' || dir === 'rtl') && !/[A-Za-z0-9-]/.test(s[j + 5] || '')) j += 5;
10841
+ }
10842
+ value += s.slice(end, j);
10843
+ end = j;
10844
+ } else if (s.startsWith('^^', end)) {
10845
+ const dt = parseIriOrQName(s, end + 2, prefixes, usedPrefixes);
10846
+ if (!dt || !(dt.term && typeof dt.term.value === 'string')) return null;
10847
+ value += `^^<${dt.term.value}>`;
10848
+ end = dt.end;
10849
+ }
10850
+
10851
+ return { term: internLiteral(value), end };
10852
+ }
10853
+
10854
+ if (ch === '(') {
10855
+ let pos = i + 1;
10856
+ const items = [];
10857
+ for (;;) {
10858
+ pos = skipWs(s, pos);
10859
+ if (pos >= s.length) throw new N3SyntaxError('Unterminated collection (...)', i);
10860
+ if (s[pos] === ')') return { term: new ListTerm(items), end: pos + 1 };
10861
+ const item = parseTerm(s, pos, prefixes, usedPrefixes, blankPrefix);
10862
+ if (!item) return null;
10863
+ items.push(item.term);
10864
+ pos = item.end;
10865
+ }
10866
+ }
10867
+
10868
+ if (ch === '[' || ch === '{') return null;
10869
+
10870
+ const tok = readToken(s, i);
10871
+ if (!tok) return null;
10872
+ const word = tok.text;
10873
+ if (word === 'true' || word === 'false' || /^-?(?:[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?|\.[0-9]+(?:[eE][+-]?[0-9]+)?)$/.test(word)) {
10874
+ return { term: internLiteral(word), end: tok.end };
10875
+ }
10876
+
10877
+ const expanded = expandQNameToken(word, prefixes, usedPrefixes);
10878
+ if (expanded !== null) return { term: internIri(expanded), end: tok.end };
10879
+ return null;
10880
+ }
10881
+
10882
+ function parseDirective(line, prefixes, usedPrefixes) {
10883
+ let m = /^\s*@prefix\s+([^\s]+)\s+<([^>]*)>\s*\.\s*(?:#.*)?$/i.exec(line);
10884
+ if (!m) m = /^\s*PREFIX\s+([^\s]+)\s+<([^>]*)>\s*\.?\s*(?:#.*)?$/i.exec(line);
10885
+ if (m) {
10886
+ const raw = m[1];
10887
+ if (!raw.endsWith(':')) throw new N3SyntaxError("Invalid @prefix directive: prefix name must end with ':'");
10888
+ const pfx = raw.slice(0, -1);
10889
+ prefixes.set(pfx, maybeDecodeIriRef(m[2], 0, prefixes));
10890
+ if (usedPrefixes && pfx) usedPrefixes.add(pfx);
10891
+ return true;
10892
+ }
10893
+
10894
+ m = /^\s*@base\s+<([^>]*)>\s*\.\s*(?:#.*)?$/i.exec(line);
10895
+ if (!m) m = /^\s*BASE\s+<([^>]*)>\s*\.?\s*(?:#.*)?$/i.exec(line);
10896
+ if (m) {
10897
+ prefixes.setBase(maybeDecodeIriRef(m[1], 0, prefixes));
10898
+ return true;
10899
+ }
10900
+
10901
+ return false;
10902
+ }
10903
+
10904
+ function parseFastStatement(line, prefixes, usedPrefixes, blankPrefix, sourceOffset = null) {
10905
+ let s = String(line || '');
10906
+ const leading = s.length - s.trimStart().length;
10907
+ s = s.slice(leading);
10908
+ if (!s || s[0] === '#') return [];
10909
+ if (VERSION_LINE_RE.test(s)) return [];
10910
+ if (MESSAGE_LINE_RE.test(s)) return '__MESSAGE__';
10911
+ if (parseDirective(s, prefixes, usedPrefixes)) return [];
10912
+
10913
+ let pos = 0;
10914
+ const subj = parseTerm(s, pos, prefixes, usedPrefixes, blankPrefix);
10915
+ if (!subj) return null;
10916
+ pos = subj.end;
10917
+ const pred = parseIriOrQName(s, pos, prefixes, usedPrefixes);
10918
+ if (!pred) return null;
10919
+ pos = pred.end;
10920
+ const obj = parseTerm(s, pos, prefixes, usedPrefixes, blankPrefix);
10921
+ if (!obj) return null;
10922
+ pos = skipWs(s, obj.end);
10923
+
10924
+ let graph = null;
10925
+ if (s[pos] !== '.') {
10926
+ const graphTerm = parseIriOrQName(s, pos, prefixes, usedPrefixes);
10927
+ if (!graphTerm) return null;
10928
+ graph = graphTerm.term;
10929
+ pos = skipWs(s, graphTerm.end);
10930
+ }
10931
+ if (s[pos] !== '.') return null;
10932
+ pos = skipWs(s, pos + 1);
10933
+ if (pos !== s.length && s[pos] !== '#') return null;
10934
+
10935
+ const triple = addOffset(new Triple(subj.term, pred.term, obj.term), typeof sourceOffset === 'number' ? sourceOffset + leading : sourceOffset);
10936
+ if (!graph) return [triple];
10937
+ return [addOffset(new Triple(graph, LOG_NAME_OF, annotateQuotedGraphTerm(new GraphTerm([triple]))), sourceOffset)];
10938
+ }
10939
+
10940
+ function lineIterator(text) {
10941
+ const s = String(text ?? '');
10942
+ let start = 0;
10943
+ return {
10944
+ *[Symbol.iterator]() {
10945
+ for (let i = 0; i <= s.length; i += 1) {
10946
+ if (i === s.length || s[i] === '\n' || s[i] === '\r') {
10947
+ const line = s.slice(start, i);
10948
+ const offset = start;
10949
+ if (i < s.length && s[i] === '\r' && s[i + 1] === '\n') i += 1;
10950
+ start = i + 1;
10951
+ yield { line, offset };
10952
+ }
10953
+ }
10954
+ },
10955
+ };
10956
+ }
10957
+
10958
+ function makeDoc(prefixes, triples, label, usedPrefixes) {
10959
+ const doc = {
10960
+ prefixes,
10961
+ triples,
10962
+ frules: [],
10963
+ brules: [],
10964
+ logQueryRules: [],
10965
+ label,
10966
+ };
10967
+ Object.defineProperty(doc, 'usedPrefixes', {
10968
+ value: usedPrefixes,
10969
+ enumerable: false,
10970
+ writable: false,
10971
+ configurable: true,
10972
+ });
10973
+ Object.defineProperty(doc, '__fastRdf', {
10974
+ value: true,
10975
+ enumerable: false,
10976
+ writable: false,
10977
+ configurable: true,
10978
+ });
10979
+ return doc;
10980
+ }
10981
+
10982
+ function parseLineOrAbort(line, prefixes, usedPrefixes, blankPrefix, sourceOffset) {
10983
+ const parsed = parseFastStatement(line, prefixes, usedPrefixes, blankPrefix, sourceOffset);
10984
+ if (parsed === null || parsed === '__MESSAGE__') return parsed;
10985
+ return parsed;
10986
+ }
10987
+
10988
+ function parseFastRdfText(text, opts = {}) {
10989
+ const source = String(text ?? '');
10990
+ // Try the fast line parser directly. It returns null on richer multi-line
10991
+ // Turtle/N3 constructs, so ordinary complex programs still fall back safely.
10992
+ const prefixes = PrefixEnv.newDefault();
10993
+ if (opts.baseIri) prefixes.setBase(opts.baseIri);
10994
+ const triples = [];
10995
+ const usedPrefixes = new Set();
10996
+ let sawUsefulLine = false;
10997
+
10998
+ for (const { line, offset } of lineIterator(source)) {
10999
+ const parsed = parseLineOrAbort(line, prefixes, usedPrefixes, '', offset);
11000
+ if (parsed === null || parsed === '__MESSAGE__') return null;
11001
+ if (parsed.length) sawUsefulLine = true;
11002
+ triples.push(...parsed);
11003
+ }
11004
+
11005
+ if (!sawUsefulLine && !/^\s*(?:@prefix|PREFIX|@base|BASE|@version|VERSION)\b/im.test(source)) return null;
11006
+ return makeDoc(prefixes, triples, opts.label || '<input>', usedPrefixes);
11007
+ }
11008
+
11009
+ function parseFastRdfMessageLog(text, opts = {}) {
11010
+ const source = String(text ?? '');
11011
+ if (!MESSAGE_VERSION_LINE_RE.test(source)) return null;
11012
+
11013
+ const prefixes = PrefixEnv.newDefault();
11014
+ if (opts.baseIri) prefixes.setBase(opts.baseIri);
11015
+ const usedPrefixes = new Set();
11016
+ const payloads = [[]];
11017
+ let current = payloads[0];
11018
+ let messageIndex = 1;
11019
+ let sawVersion = false;
11020
+
11021
+ for (const { line, offset } of lineIterator(source)) {
11022
+ const stripped = String(line || '').trimStart();
11023
+ if (!stripped || stripped[0] === '#') continue;
11024
+ if (MESSAGE_VERSION_LINE_RE.test(stripped)) {
11025
+ sawVersion = true;
11026
+ continue;
11027
+ }
11028
+ if (VERSION_LINE_RE.test(stripped)) continue;
11029
+ if (MESSAGE_LINE_RE.test(stripped)) {
11030
+ payloads.push([]);
11031
+ current = payloads[payloads.length - 1];
11032
+ messageIndex += 1;
11033
+ continue;
11034
+ }
11035
+
11036
+ const blankPrefix = `_:eyeling_m${String(messageIndex).padStart(3, '0')}_`;
11037
+ const parsed = parseLineOrAbort(line, prefixes, usedPrefixes, blankPrefix, offset);
11038
+ if (parsed === null || parsed === '__MESSAGE__') return null;
11039
+ current.push(...parsed);
11040
+ }
11041
+
11042
+ if (!sawVersion) return null;
11043
+
11044
+ const hash = simpleHashText(source);
11045
+ const base = `urn:eyeling:message-log:${hash}`;
11046
+ const stream = internIri(`${base}#stream`);
11047
+ const envelopes = payloads.map((unused, idx) => internIri(`${base}#m${String(idx + 1).padStart(3, '0')}`));
11048
+ const payloadIris = payloads.map((unused, idx) => internIri(`${base}#m${String(idx + 1).padStart(3, '0')}/payload`));
11049
+ const triples = [];
11050
+
11051
+ triples.push(new Triple(stream, RDF_TYPE, EYMSG_IRIS.RDFMessageStream));
11052
+ triples.push(new Triple(stream, EYMSG_IRIS.messageCount, internLiteral(`"${payloads.length}"${XSD_INTEGER_LITERAL_SUFFIX}`)));
11053
+ if (envelopes.length) {
11054
+ triples.push(new Triple(stream, EYMSG_IRIS.orderedEnvelopes, new ListTerm(envelopes)));
11055
+ triples.push(new Triple(stream, EYMSG_IRIS.firstEnvelope, envelopes[0]));
11056
+ triples.push(new Triple(stream, EYMSG_IRIS.lastEnvelope, envelopes[envelopes.length - 1]));
11057
+ }
11058
+
11059
+ for (let idx = 0; idx < payloads.length; idx += 1) {
11060
+ const envelope = envelopes[idx];
11061
+ const payload = payloadIris[idx];
11062
+ const bodyTriples = payloads[idx];
11063
+ const hasBody = bodyTriples.length > 0;
11064
+
11065
+ triples.push(new Triple(stream, EYMSG_IRIS.envelope, envelope));
11066
+ triples.push(new Triple(envelope, RDF_TYPE, EYMSG_IRIS.MessageEnvelope));
11067
+ triples.push(new Triple(envelope, EYMSG_IRIS.offset, internLiteral(`"${idx + 1}"${XSD_INTEGER_LITERAL_SUFFIX}`)));
11068
+ triples.push(new Triple(envelope, EYMSG_IRIS.payloadKind, hasBody ? EYMSG_IRIS.nonEmpty : EYMSG_IRIS.empty));
11069
+ if (idx + 1 < envelopes.length) triples.push(new Triple(envelope, EYMSG_IRIS.nextEnvelope, envelopes[idx + 1]));
11070
+ if (hasBody) {
11071
+ triples.push(new Triple(envelope, EYMSG_IRIS.payloadGraph, payload));
11072
+ triples.push(new Triple(payload, LOG_NAME_OF, annotateQuotedGraphTerm(new GraphTerm(bodyTriples))));
11073
+ }
11074
+ }
11075
+
11076
+ return makeDoc(prefixes, triples, opts.label || '<input>', usedPrefixes);
11077
+ }
11078
+
11079
+ function tryParseFastRdfText(text, opts = {}) {
11080
+ return parseFastRdfMessageLog(text, opts) || parseFastRdfText(text, opts);
11081
+ }
11082
+
11083
+ module.exports = { tryParseFastRdfText, parseFastRdfText, parseFastRdfMessageLog };
11084
+
10624
11085
  };
10625
11086
  __modules["lib/lexer.js"] = function(require, module, exports){
10626
11087
  /**
@@ -12553,6 +13014,7 @@ module.exports = { Token, N3SyntaxError, lex, normalizeRdfCompatibility, decodeN
12553
13014
 
12554
13015
  const { lex } = require('./lexer');
12555
13016
  const { Parser } = require('./parser');
13017
+ const { tryParseFastRdfText } = require('./fast_rdf');
12556
13018
  const {
12557
13019
  Blank,
12558
13020
  ListTerm,
@@ -12715,6 +13177,16 @@ function parseN3Text(text, opts = {}) {
12715
13177
  sourceLocations = false,
12716
13178
  rdf = false,
12717
13179
  } = opts || {};
13180
+
13181
+ if (rdf) {
13182
+ const fastDoc = tryParseFastRdfText(text, { baseIri, label });
13183
+ if (fastDoc) {
13184
+ if (sourceLocations) annotateParsedSourceLocations(fastDoc, text, label);
13185
+ if (keepSourceArtifacts) fastDoc.text = text;
13186
+ return fastDoc;
13187
+ }
13188
+ }
13189
+
12718
13190
  const tokens = lex(text, { rdf });
12719
13191
  const parser = new Parser(tokens);
12720
13192
  if (baseIri) parser.prefixes.setBase(baseIri);
@@ -15917,11 +16389,18 @@ function liftBlankRuleVars(premise, conclusion) {
15917
16389
  const mapping = Object.create(null);
15918
16390
  let counter = 0;
15919
16391
 
16392
+ // These variables are implementation details used to correlate one blank
16393
+ // node across the lifted rule body. Their names must not be spellable by
16394
+ // user input; otherwise a user variable such as ?_b1 can capture the
16395
+ // lifted blank node and leak it into the rule head. U+E000 is a private-use
16396
+ // code point and is not accepted by the lexer as part of a variable name.
16397
+ const INTERNAL_BLANK_VAR_PREFIX = '\uE000eyeling_b';
16398
+
15920
16399
  function blankToVar(label) {
15921
16400
  let name = mapping[label];
15922
16401
  if (name === undefined) {
15923
16402
  counter += 1;
15924
- name = `_b${counter}`;
16403
+ name = `${INTERNAL_BLANK_VAR_PREFIX}${counter}`;
15925
16404
  mapping[label] = name;
15926
16405
  }
15927
16406
  return new Var(name);
@@ -15973,7 +16452,7 @@ function liftBlankRuleVars(premise, conclusion) {
15973
16452
  // consumed by the builtin rather than ordinary triple patterns. Keep their
15974
16453
  // local blank nodes as Blank terms so the builtin can treat them as local
15975
16454
  // existentials, and bindings returned from an explicit scope are blank nodes
15976
- // instead of synthetic rule variables such as ?_b1.
16455
+ // instead of synthetic rule variables.
15977
16456
  const keepFormulaBlanks = isLogIncludesLikePredicate(tr.p);
15978
16457
  return new Triple(
15979
16458
  keepFormulaBlanks && tr.s instanceof GraphTerm ? copyQuotedTerm(tr.s) : convertTerm(tr.s, true),
package/lib/engine.js CHANGED
@@ -3672,11 +3672,18 @@ function reasonStream(input, opts = {}) {
3672
3672
  if (baseIri) prefixes.setBase(baseIri);
3673
3673
  } else {
3674
3674
  const n3Text = normalizeReasonerInputSync(input);
3675
- const toks = lex(n3Text, { rdf: useRdfCompatibility });
3676
- const parser = new Parser(toks);
3677
- if (baseIri) parser.prefixes.setBase(baseIri);
3678
-
3679
- [prefixes, triples, frules, brules, logQueryRules] = parser.parseDocument();
3675
+ const directDoc = parseN3Text(n3Text, {
3676
+ baseIri: baseIri || '',
3677
+ label: sourceLabel || '<input>',
3678
+ keepSourceArtifacts: false,
3679
+ sourceLocations: proof,
3680
+ rdf: useRdfCompatibility,
3681
+ });
3682
+ prefixes = directDoc.prefixes;
3683
+ triples = directDoc.triples;
3684
+ frules = directDoc.frules;
3685
+ brules = directDoc.brules;
3686
+ logQueryRules = directDoc.logQueryRules;
3680
3687
  }
3681
3688
  // Make the parsed prefixes available to log:trace output
3682
3689
  trace.setTracePrefixes(prefixes);