eyeling 1.24.2 → 1.24.3

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
@@ -4547,6 +4547,7 @@ function main() {
4547
4547
  ` -e, --enforce-https Rewrite http:// IRIs to https:// for log dereferencing builtins.\n` +
4548
4548
  ` -h, --help Show this help and exit.\n` +
4549
4549
  ` -p, --proof-comments Enable proof explanations.\n` +
4550
+ ` -r, --rdf Enable RDF/TriG input/output compatibility.\n` +
4550
4551
  ` -s, --super-restricted Disable all builtins except => and <=.\n` +
4551
4552
  ` -t, --stream Stream derived triples as soon as they are derived.\n` +
4552
4553
  ` -v, --version Print version and exit.\n`;
@@ -4588,6 +4589,7 @@ function main() {
4588
4589
 
4589
4590
  const showAst = argv.includes('--ast') || argv.includes('-a');
4590
4591
  const streamMode = argv.includes('--stream') || argv.includes('-t');
4592
+ const rdfMode = argv.includes('--rdf') || argv.includes('-r');
4591
4593
 
4592
4594
  // --enforce-https: rewrite http:// -> https:// for log dereferencing builtins
4593
4595
  if (argv.includes('--enforce-https') || argv.includes('-e')) {
@@ -4650,6 +4652,7 @@ function main() {
4650
4652
  label: sourceLabel,
4651
4653
  collectUsedPrefixes: true,
4652
4654
  keepSourceArtifacts: false,
4655
+ rdf: rdfMode,
4653
4656
  }),
4654
4657
  );
4655
4658
  } catch (e) {
@@ -4762,10 +4765,10 @@ function main() {
4762
4765
  (df) => {
4763
4766
  if (engine.getProofCommentsEnabled()) {
4764
4767
  engine.printExplanation(df, outPrefixes);
4765
- console.log(engine.tripleToN3(df.fact, outPrefixes));
4768
+ console.log(rdfMode ? engine.tripleToRdfCompatible(df.fact, outPrefixes) : engine.tripleToN3(df.fact, outPrefixes));
4766
4769
  console.log();
4767
4770
  } else {
4768
- console.log(engine.tripleToN3(df.fact, outPrefixes));
4771
+ console.log(rdfMode ? engine.tripleToRdfCompatible(df.fact, outPrefixes) : engine.tripleToN3(df.fact, outPrefixes));
4769
4772
  }
4770
4773
  },
4771
4774
  { captureExplanations: engine.getProofCommentsEnabled(), prefixes: outPrefixes },
@@ -4801,7 +4804,24 @@ function main() {
4801
4804
  return;
4802
4805
  }
4803
4806
 
4804
- const usedPrefixes = prefixes.prefixesUsedForOutput(outTriples);
4807
+ let bodyText = '';
4808
+ if (rdfMode && !engine.getProofCommentsEnabled()) {
4809
+ bodyText = outTriples.map((tr) => engine.tripleToRdfCompatible(tr, prefixes)).join('\n');
4810
+ } else if (hasQueries && !engine.getProofCommentsEnabled()) {
4811
+ // In log:query mode, when proof comments are disabled, pretty-print blank-node
4812
+ // shaped outputs as Turtle property lists ("[ ... ] .") for readability.
4813
+ bodyText = engine.prettyPrintQueryTriples(outTriples, prefixes);
4814
+ }
4815
+
4816
+ let usedPrefixes = prefixes.prefixesUsedForOutput(outTriples);
4817
+ if (rdfMode && bodyText) {
4818
+ usedPrefixes = usedPrefixes.filter(([pfx]) => pfx === '' || bodyText.includes(pfx + ':'));
4819
+ }
4820
+
4821
+ if (rdfMode && bodyText.includes('<<(')) {
4822
+ console.log('VERSION "1.2"');
4823
+ console.log();
4824
+ }
4805
4825
 
4806
4826
  for (const [pfx, base] of usedPrefixes) {
4807
4827
  if (pfx === '') console.log(`@prefix : <${base}> .`);
@@ -4809,21 +4829,18 @@ function main() {
4809
4829
  }
4810
4830
  if (outTriples.length && usedPrefixes.length) console.log();
4811
4831
 
4812
- // In log:query mode, when proof comments are disabled, pretty-print blank-node
4813
- // shaped outputs as Turtle property lists ("[ ... ] .") for readability.
4814
- if (hasQueries && !engine.getProofCommentsEnabled()) {
4815
- const s = engine.prettyPrintQueryTriples(outTriples, prefixes);
4816
- if (s) process.stdout.write(String(s).replace(/\s*$/g, '') + '\n');
4832
+ if (bodyText) {
4833
+ process.stdout.write(String(bodyText).replace(/\s*$/g, '') + '\n');
4817
4834
  return;
4818
4835
  }
4819
4836
 
4820
4837
  for (const df of outDerived) {
4821
4838
  if (engine.getProofCommentsEnabled()) {
4822
4839
  engine.printExplanation(df, prefixes);
4823
- console.log(engine.tripleToN3(df.fact, prefixes));
4840
+ console.log(rdfMode ? engine.tripleToRdfCompatible(df.fact, prefixes) : engine.tripleToN3(df.fact, prefixes));
4824
4841
  console.log();
4825
4842
  } else {
4826
- console.log(engine.tripleToN3(df.fact, prefixes));
4843
+ console.log(rdfMode ? engine.tripleToRdfCompatible(df.fact, prefixes) : engine.tripleToN3(df.fact, prefixes));
4827
4844
  }
4828
4845
  }
4829
4846
  }
@@ -5356,7 +5373,12 @@ const {
5356
5373
 
5357
5374
  const { makeExplain } = require('./explain');
5358
5375
 
5359
- const { termToN3, tripleToN3, prettyPrintQueryTriples } = require('./printing');
5376
+ const {
5377
+ termToN3,
5378
+ tripleToN3,
5379
+ prettyPrintQueryTriples,
5380
+ tripleToRdfCompatible,
5381
+ } = require('./printing');
5360
5382
  const {
5361
5383
  getDataFactory,
5362
5384
  internalTripleToRdfJsQuad,
@@ -8669,9 +8691,12 @@ function reasonStream(input, opts = {}) {
8669
8691
  dataFactory = null,
8670
8692
  skipUnsupportedRdfJs = false,
8671
8693
  builtinModules = null,
8694
+ rdf = false,
8672
8695
  } = opts;
8673
8696
 
8674
- const parsedSourceList = parseN3SourceList(input, { baseIri });
8697
+ const useRdfCompatibility = !!rdf;
8698
+
8699
+ const parsedSourceList = parseN3SourceList(input, { baseIri, rdf: useRdfCompatibility });
8675
8700
  const parsedInput = parsedSourceList || normalizeParsedReasonerInputSync(input);
8676
8701
  const rdfFactory = rdfjs ? getDataFactory(dataFactory) : null;
8677
8702
 
@@ -8707,7 +8732,7 @@ function reasonStream(input, opts = {}) {
8707
8732
  if (baseIri) prefixes.setBase(baseIri);
8708
8733
  } else {
8709
8734
  const n3Text = normalizeReasonerInputSync(input);
8710
- const toks = lex(n3Text);
8735
+ const toks = lex(n3Text, { rdf: useRdfCompatibility });
8711
8736
  const parser = new Parser(toks);
8712
8737
  if (baseIri) parser.prefixes.setBase(baseIri);
8713
8738
 
@@ -8741,7 +8766,7 @@ function reasonStream(input, opts = {}) {
8741
8766
  // query-selected triples (not all derived facts).
8742
8767
  if (typeof onDerived === 'function') {
8743
8768
  for (const qdf of queryDerived) {
8744
- const payload = { triple: tripleToN3(qdf.fact, prefixes), df: qdf };
8769
+ const payload = { triple: useRdfCompatibility ? tripleToRdfCompatible(qdf.fact, prefixes) : tripleToN3(qdf.fact, prefixes), df: qdf };
8745
8770
  if (rdfFactory) {
8746
8771
  const quad = maybeTripleToRdfJsQuad(qdf.fact, rdfFactory, skipUnsupportedRdfJs);
8747
8772
  if (quad) payload.quad = quad;
@@ -8758,7 +8783,7 @@ function reasonStream(input, opts = {}) {
8758
8783
  (df) => {
8759
8784
  if (typeof onDerived === 'function') {
8760
8785
  const payload = {
8761
- triple: tripleToN3(df.fact, prefixes),
8786
+ triple: useRdfCompatibility ? tripleToRdfCompatible(df.fact, prefixes) : tripleToN3(df.fact, prefixes),
8762
8787
  df,
8763
8788
  };
8764
8789
  if (rdfFactory) {
@@ -8779,8 +8804,9 @@ function reasonStream(input, opts = {}) {
8779
8804
  ? facts
8780
8805
  : derived.map((d) => d.fact);
8781
8806
 
8782
- const closureN3 =
8783
- Array.isArray(logQueryRules) && logQueryRules.length && !proof
8807
+ const closureN3 = useRdfCompatibility
8808
+ ? closureTriples.map((t) => tripleToRdfCompatible(t, prefixes)).join('\n')
8809
+ : Array.isArray(logQueryRules) && logQueryRules.length && !proof
8784
8810
  ? prettyPrintQueryTriples(closureTriples, prefixes)
8785
8811
  : closureTriples.map((t) => tripleToN3(t, prefixes)).join('\n');
8786
8812
 
@@ -8921,6 +8947,7 @@ module.exports = {
8921
8947
  printExplanation,
8922
8948
  // used by demo worker to stringify derived triples with prefixes
8923
8949
  tripleToN3,
8950
+ tripleToRdfCompatible,
8924
8951
  // pretty log:query output (when proof comments are disabled)
8925
8952
  prettyPrintQueryTriples,
8926
8953
  getEnforceHttpsEnabled,
@@ -9556,45 +9583,62 @@ function stripQuotes(lex) {
9556
9583
  }
9557
9584
 
9558
9585
 
9559
- // RDF 1.2 triple terms use <<( s p o )>>. Eyeling's N3 engine does not
9560
- // implement a new RDF 1.2 term kind; instead, it accepts this syntax as a
9561
- // compatibility surface and normalizes it to the existing N3 singleton quoted
9562
- // graph term { s p o }. This keeps ordinary N3 reasoning unchanged while making
9563
- // RDF 1.2 examples parseable by the current engine.
9564
- function normalizeRdf12TripleTerms(inputText) {
9565
- const text = String(inputText ?? '');
9566
- let i = 0;
9586
+ // RDF/TriG compatibility is an opt-in syntax-normalization layer, not a new
9587
+ // reasoning model. Eyeling remains strict N3 by default and N3 internally:
9588
+ // - RDF 1.2 triple terms <<( s p o )>> become singleton graph terms { s p o }.
9589
+ // - TriG named graph blocks g { ... } become g log:nameOf { ... } .
9590
+ // - A top-level default graph block { ... } is unwrapped into ordinary triples.
9591
+ // This mirrors tools/n3gen.js and keeps all downstream parsing/reasoning N3-only.
9592
+ const LOG_NAME_OF_IRI = '<http://www.w3.org/2000/10/swap/log#nameOf>';
9593
+
9594
+ function normalizeRdfCompatibility(inputText) {
9595
+ let text = String(inputText ?? '');
9596
+
9597
+ // Fast path: most Eyeling inputs are ordinary N3 and do not need RDF/TriG
9598
+ // surface-syntax normalization. Avoid scanning large files character-by-character
9599
+ // unless they actually contain RDF 1.2 triple terms, VERSION directives, or a
9600
+ // plausible top-level TriG named graph block.
9601
+ const hasTripleTerms = text.includes('<<(');
9602
+ const hasVersionDirective = /^\s*(?:@version|VERSION)\s+(["'])1\.2\1\s*\.?\s*(?:#.*)?$/im.test(text);
9603
+ const hasNamedGraphCandidate = /(?:^|[.\r\n])\s*(?:GRAPH\s+)?(?:<[^>\r\n]*>|_:[A-Za-z][A-Za-z0-9_-]*|[A-Za-z][A-Za-z0-9_-]*:[^\s{};,.()[\]]*)\s*\{/m.test(text);
9567
9604
 
9568
- function startsAt(needle, at = i) {
9569
- return text.startsWith(needle, at);
9605
+ if (!hasTripleTerms && !hasVersionDirective && !hasNamedGraphCandidate) return text;
9606
+
9607
+ function isWordChar(ch) {
9608
+ return ch != null && /[A-Za-z0-9_:-]/.test(ch);
9570
9609
  }
9571
9610
 
9572
- function readString() {
9573
- const quote = text[i];
9611
+ function startsWordAt(s, word, at) {
9612
+ return s.startsWith(word, at) && !isWordChar(s[at - 1]) && !isWordChar(s[at + word.length]);
9613
+ }
9614
+
9615
+ function readStringAt(s, at) {
9616
+ const quote = s[at];
9617
+ let i = at;
9574
9618
  let out = quote;
9575
- const long = text.startsWith(quote.repeat(3), i);
9619
+ const long = s.startsWith(quote.repeat(3), i);
9576
9620
  if (long) {
9577
9621
  out = quote.repeat(3);
9578
9622
  i += 3;
9579
- while (i < text.length) {
9580
- if (text.startsWith(quote.repeat(3), i)) {
9623
+ while (i < s.length) {
9624
+ if (s.startsWith(quote.repeat(3), i)) {
9581
9625
  out += quote.repeat(3);
9582
9626
  i += 3;
9583
- return out;
9627
+ return { text: out, end: i };
9584
9628
  }
9585
- if (text[i] === '\\' && i + 1 < text.length) {
9586
- out += text.slice(i, i + 2);
9629
+ if (s[i] === '\\' && i + 1 < s.length) {
9630
+ out += s.slice(i, i + 2);
9587
9631
  i += 2;
9588
9632
  } else {
9589
- out += text[i++];
9633
+ out += s[i++];
9590
9634
  }
9591
9635
  }
9592
- return out;
9636
+ return { text: out, end: i };
9593
9637
  }
9594
9638
  i += 1;
9595
9639
  let escaped = false;
9596
- while (i < text.length) {
9597
- const ch = text[i++];
9640
+ while (i < s.length) {
9641
+ const ch = s[i++];
9598
9642
  out += ch;
9599
9643
  if (escaped) {
9600
9644
  escaped = false;
@@ -9604,61 +9648,234 @@ function normalizeRdf12TripleTerms(inputText) {
9604
9648
  break;
9605
9649
  }
9606
9650
  }
9607
- return out;
9651
+ return { text: out, end: i };
9608
9652
  }
9609
9653
 
9610
- function readIri() {
9611
- let out = text[i++];
9612
- while (i < text.length) {
9613
- const ch = text[i++];
9654
+ function readIriAt(s, at) {
9655
+ let i = at + 1;
9656
+ let out = '<';
9657
+ while (i < s.length) {
9658
+ const ch = s[i++];
9614
9659
  out += ch;
9615
9660
  if (ch === '>') break;
9616
9661
  }
9617
- return out;
9662
+ return { text: out, end: i };
9618
9663
  }
9619
9664
 
9620
- function convertUntil(stopToken) {
9621
- let out = '';
9622
- while (i < text.length) {
9623
- if (stopToken && startsAt(stopToken)) {
9624
- i += stopToken.length;
9625
- return out;
9665
+ function convertTripleTerms(s) {
9666
+ let i = 0;
9667
+
9668
+ function startsAt(needle, at = i) {
9669
+ return s.startsWith(needle, at);
9670
+ }
9671
+
9672
+ function convertUntil(stopToken) {
9673
+ let out = '';
9674
+ while (i < s.length) {
9675
+ if (stopToken && startsAt(stopToken)) {
9676
+ i += stopToken.length;
9677
+ return out;
9678
+ }
9679
+ if (startsAt('<<(')) {
9680
+ i += 3;
9681
+ out += '{ ' + convertUntil(')>>').trim() + ' }';
9682
+ continue;
9683
+ }
9684
+ const ch = s[i];
9685
+ if (ch === '"' || ch === "'") {
9686
+ const str = readStringAt(s, i);
9687
+ out += str.text;
9688
+ i = str.end;
9689
+ continue;
9690
+ }
9691
+ if (ch === '<') {
9692
+ const iri = readIriAt(s, i);
9693
+ out += iri.text;
9694
+ i = iri.end;
9695
+ continue;
9696
+ }
9697
+ if (ch === '#') {
9698
+ while (i < s.length) {
9699
+ const c = s[i++];
9700
+ out += c;
9701
+ if (c === '\n' || c === '\r') break;
9702
+ }
9703
+ continue;
9704
+ }
9705
+ out += ch;
9706
+ i += 1;
9626
9707
  }
9627
- if (startsAt('<<(')) {
9628
- i += 3;
9629
- out += '{ ' + convertUntil(')>>').trim() + ' }';
9708
+ if (stopToken) throw new N3SyntaxError(`Unterminated RDF 1.2 triple term, expected ${stopToken}`);
9709
+ return out;
9710
+ }
9711
+
9712
+ return convertUntil(null);
9713
+ }
9714
+
9715
+ function stripVersionDirectives(s) {
9716
+ return s.replace(/^\s*(?:@version|VERSION)\s+(["'])1\.2\1\s*\.?\s*(?:#.*)?$/gim, '');
9717
+ }
9718
+
9719
+ function skipWsAndComments(s, at) {
9720
+ let i = at;
9721
+ while (i < s.length) {
9722
+ if (/\s/.test(s[i])) {
9723
+ i += 1;
9724
+ continue;
9725
+ }
9726
+ if (s[i] === '#') {
9727
+ while (i < s.length && s[i] !== '\n' && s[i] !== '\r') i += 1;
9630
9728
  continue;
9631
9729
  }
9632
- const ch = text[i];
9730
+ break;
9731
+ }
9732
+ return i;
9733
+ }
9734
+
9735
+ function readTermAt(s, at) {
9736
+ if (s[at] === '<') return readIriAt(s, at);
9737
+ let i = at;
9738
+ while (i < s.length && !/\s/.test(s[i]) && !'{}[](),;.'.includes(s[i])) i += 1;
9739
+ if (i === at) return null;
9740
+ const value = s.slice(at, i);
9741
+ if (!value || value.startsWith('@')) return null;
9742
+ return { text: value, end: i };
9743
+ }
9744
+
9745
+ function readBalancedBlock(s, at) {
9746
+ if (s[at] !== '{') return null;
9747
+ let i = at;
9748
+ let depth = 0;
9749
+ while (i < s.length) {
9750
+ const ch = s[i];
9633
9751
  if (ch === '"' || ch === "'") {
9634
- out += readString();
9752
+ i = readStringAt(s, i).end;
9635
9753
  continue;
9636
9754
  }
9637
9755
  if (ch === '<') {
9638
- out += readIri();
9756
+ i = readIriAt(s, i).end;
9639
9757
  continue;
9640
9758
  }
9641
9759
  if (ch === '#') {
9642
- while (i < text.length) {
9643
- const c = text[i++];
9644
- out += c;
9645
- if (c === '\n' || c === '\r') break;
9646
- }
9760
+ while (i < s.length && s[i] !== '\n' && s[i] !== '\r') i += 1;
9761
+ continue;
9762
+ }
9763
+ if (ch === '{') depth += 1;
9764
+ if (ch === '}') {
9765
+ depth -= 1;
9766
+ i += 1;
9767
+ if (depth === 0) return { text: s.slice(at, i), inner: s.slice(at + 1, i - 1), end: i };
9647
9768
  continue;
9648
9769
  }
9649
- out += ch;
9650
9770
  i += 1;
9651
9771
  }
9652
- if (stopToken) throw new N3SyntaxError(`Unterminated RDF 1.2 triple term, expected ${stopToken}`);
9772
+ throw new N3SyntaxError('Unterminated RDF/TriG graph block, expected }');
9773
+ }
9774
+
9775
+ function normalizeNamedGraphs(s) {
9776
+ let out = '';
9777
+ let i = 0;
9778
+ let statementStart = true;
9779
+ let braceDepth = 0;
9780
+
9781
+ while (i < s.length) {
9782
+ if (statementStart && braceDepth === 0) {
9783
+ const termStart = skipWsAndComments(s, i);
9784
+ out += s.slice(i, termStart);
9785
+ i = termStart;
9786
+
9787
+ // Top-level TriG default graph block: { ... } .
9788
+ if (s[i] === '{') {
9789
+ const block = readBalancedBlock(s, i);
9790
+ const after = skipWsAndComments(s, block.end);
9791
+ if (after >= s.length || s[after] === '.') {
9792
+ out += block.inner.trim();
9793
+ if (block.inner.trim() && !/\n$/.test(block.inner)) out += '\n';
9794
+ i = after < s.length && s[after] === '.' ? after + 1 : after;
9795
+ statementStart = true;
9796
+ continue;
9797
+ }
9798
+ // It is an ordinary N3 formula subject, not a TriG default graph.
9799
+ out += block.text;
9800
+ i = block.end;
9801
+ statementStart = false;
9802
+ continue;
9803
+ }
9804
+
9805
+ let graphKeyword = false;
9806
+ if (startsWordAt(s, 'GRAPH', i)) {
9807
+ graphKeyword = true;
9808
+ i += 'GRAPH'.length;
9809
+ i = skipWsAndComments(s, i);
9810
+ }
9811
+
9812
+ const term = readTermAt(s, i);
9813
+ if (term && !['@prefix', '@base', 'PREFIX', 'BASE', 'VERSION'].includes(term.text)) {
9814
+ const afterTerm = skipWsAndComments(s, term.end);
9815
+ if (s[afterTerm] === '{') {
9816
+ const block = readBalancedBlock(s, afterTerm);
9817
+ const afterBlock = skipWsAndComments(s, block.end);
9818
+ out += `${term.text} ${LOG_NAME_OF_IRI} ${block.text} .`;
9819
+ i = afterBlock < s.length && s[afterBlock] === '.' ? afterBlock + 1 : block.end;
9820
+ statementStart = true;
9821
+ continue;
9822
+ }
9823
+ }
9824
+
9825
+ // Not TriG named-graph syntax after all; copy the first character and
9826
+ // continue as ordinary N3.
9827
+ if (graphKeyword) {
9828
+ out += 'GRAPH ';
9829
+ statementStart = false;
9830
+ } else if (i < s.length) {
9831
+ const copied = s[i++];
9832
+ out += copied;
9833
+ if (!/\s/.test(copied)) statementStart = false;
9834
+ }
9835
+ } else {
9836
+ const ch = s[i];
9837
+ out += ch;
9838
+ if (ch === '"' || ch === "'") {
9839
+ const str = readStringAt(s, i);
9840
+ out = out.slice(0, -1) + str.text;
9841
+ i = str.end;
9842
+ continue;
9843
+ }
9844
+ if (ch === '<') {
9845
+ const iri = readIriAt(s, i);
9846
+ out = out.slice(0, -1) + iri.text;
9847
+ i = iri.end;
9848
+ continue;
9849
+ }
9850
+ if (ch === '#') {
9851
+ i += 1;
9852
+ while (i < s.length) {
9853
+ const c = s[i++];
9854
+ out += c;
9855
+ if (c === '\n' || c === '\r') break;
9856
+ }
9857
+ continue;
9858
+ }
9859
+ if (ch === '{') braceDepth += 1;
9860
+ else if (ch === '}' && braceDepth > 0) braceDepth -= 1;
9861
+ else if (ch === '.' && braceDepth === 0) statementStart = true;
9862
+ else if (!/\s/.test(ch)) statementStart = false;
9863
+ i += 1;
9864
+ }
9865
+ }
9866
+
9653
9867
  return out;
9654
9868
  }
9655
9869
 
9656
- const converted = convertUntil(null);
9657
- return converted.replace(/^\s*(?:@version|VERSION)\s+(["'])1\.2\1\s*\.?\s*(?:#.*)?$/gim, '');
9870
+ if (hasTripleTerms) text = convertTripleTerms(text);
9871
+ if (hasVersionDirective) text = stripVersionDirectives(text);
9872
+ if (hasVersionDirective || hasNamedGraphCandidate) text = normalizeNamedGraphs(text);
9873
+ return text;
9658
9874
  }
9659
9875
 
9660
- function lex(inputText) {
9661
- inputText = normalizeRdf12TripleTerms(inputText);
9876
+ function lex(inputText, opts = {}) {
9877
+ const rdf = !!(opts && opts.rdf);
9878
+ if (rdf) inputText = normalizeRdfCompatibility(inputText);
9662
9879
  const chars = Array.from(inputText);
9663
9880
  const n = chars.length;
9664
9881
  let i = 0;
@@ -10119,7 +10336,7 @@ function lex(inputText) {
10119
10336
  return tokens;
10120
10337
  }
10121
10338
 
10122
- module.exports = { Token, N3SyntaxError, lex, decodeN3StringEscapes };
10339
+ module.exports = { Token, N3SyntaxError, lex, normalizeRdfCompatibility, decodeN3StringEscapes };
10123
10340
 
10124
10341
  };
10125
10342
  __modules["lib/multisource.js"] = function(require, module, exports){
@@ -10228,8 +10445,14 @@ function prefixesUsedInTokens(tokens, prefEnv) {
10228
10445
  }
10229
10446
 
10230
10447
  function parseN3Text(text, opts = {}) {
10231
- const { baseIri = '', label = '<input>', keepSourceArtifacts = true, collectUsedPrefixes = false } = opts || {};
10232
- const tokens = lex(text);
10448
+ const {
10449
+ baseIri = '',
10450
+ label = '<input>',
10451
+ keepSourceArtifacts = true,
10452
+ collectUsedPrefixes = false,
10453
+ rdf = false,
10454
+ } = opts || {};
10455
+ const tokens = lex(text, { rdf });
10233
10456
  const parser = new Parser(tokens);
10234
10457
  if (baseIri) parser.prefixes.setBase(baseIri);
10235
10458
  const [prefixes, triples, frules, brules, logQueryRules] = parser.parseDocument();
@@ -10423,6 +10646,7 @@ function parseN3SourceList(input, opts = {}) {
10423
10646
  baseIri: source.baseIri || (sources.length === 1 ? defaultBaseIri : ''),
10424
10647
  collectUsedPrefixes: true,
10425
10648
  keepSourceArtifacts: !!opts.keepSourceArtifacts,
10649
+ rdf: !!opts.rdf,
10426
10650
  }),
10427
10651
  );
10428
10652
  return mergeParsedDocuments(parsed, {
@@ -11813,6 +12037,7 @@ const {
11813
12037
  isOwlSameAsPred,
11814
12038
  isLogImplies,
11815
12039
  isLogImpliedBy,
12040
+ LOG_NS,
11816
12041
  } = require('./prelude');
11817
12042
 
11818
12043
  function stripQuotes(lex) {
@@ -12142,7 +12367,111 @@ function prettyPrintQueryTriples(triples, prefixes) {
12142
12367
  return blocks.join('\n');
12143
12368
  }
12144
12369
 
12145
- module.exports = { termToN3, tripleToN3, prettyPrintQueryTriples };
12370
+
12371
+ // ---------------------------------------------------------------------------
12372
+ // RDF compatibility output
12373
+ // ---------------------------------------------------------------------------
12374
+
12375
+ function isRdfTripleTermSubject(t) {
12376
+ return t instanceof Iri || t instanceof Blank;
12377
+ }
12378
+
12379
+ function isRdfTripleTermPredicate(t) {
12380
+ return t instanceof Iri;
12381
+ }
12382
+
12383
+ function isRdfTripleTermObject(t) {
12384
+ return t instanceof Iri || t instanceof Blank || t instanceof Literal;
12385
+ }
12386
+
12387
+ function isRdfTripleTermGraph(t) {
12388
+ if (!(t instanceof GraphTerm)) return false;
12389
+ if (!Array.isArray(t.triples) || t.triples.length !== 1) return false;
12390
+ const tr = t.triples[0];
12391
+ return isRdfTripleTermSubject(tr.s) && isRdfTripleTermPredicate(tr.p) && isRdfTripleTermObject(tr.o);
12392
+ }
12393
+
12394
+
12395
+ function isLogNameOfPred(p) {
12396
+ return p instanceof Iri && p.value === LOG_NS + 'nameOf';
12397
+ }
12398
+
12399
+ function isRdfNamedGraphLabel(t) {
12400
+ return t instanceof Iri || t instanceof Blank;
12401
+ }
12402
+
12403
+ function rdfCompatibleGraphBlock(graph, prefixes) {
12404
+ const indent = ' ';
12405
+ const indentBlock = (str) =>
12406
+ str
12407
+ .split(/\r?\n/)
12408
+ .map((ln) => (ln.length ? indent + ln : ln))
12409
+ .join('\n');
12410
+
12411
+ let s = '{\n';
12412
+ for (const inner of graph.triples || []) {
12413
+ const block = tripleToRdfCompatible(inner, prefixes).trimEnd();
12414
+ if (block) s += indentBlock(block) + '\n';
12415
+ }
12416
+ s += '}';
12417
+ return s;
12418
+ }
12419
+
12420
+ function rdfPredicateToText(p, prefixes) {
12421
+ return isRdfTypePred(p) ? 'a' : termToN3(p, prefixes);
12422
+ }
12423
+
12424
+ function termToRdfCompatible(t, pref) {
12425
+ if (isRdfTripleTermGraph(t)) {
12426
+ const tr = t.triples[0];
12427
+ const s = termToN3(tr.s, pref);
12428
+ const p = rdfPredicateToText(tr.p, pref);
12429
+ const o = termToN3(tr.o, pref);
12430
+ return `<<( ${s} ${p} ${o} )>>`;
12431
+ }
12432
+ return termToN3(t, pref);
12433
+ }
12434
+
12435
+ function tripleToRdfCompatible(tr, prefixes) {
12436
+ if (isLogNameOfPred(tr.p) && isRdfNamedGraphLabel(tr.s) && tr.o instanceof GraphTerm) {
12437
+ return `${termToN3(tr.s, prefixes)} ${rdfCompatibleGraphBlock(tr.o, prefixes)}`;
12438
+ }
12439
+
12440
+ if (isLogImplies(tr.p)) {
12441
+ const s = termToRdfCompatible(tr.s, prefixes);
12442
+ const o = termToRdfCompatible(tr.o, prefixes);
12443
+ return `${s} => ${o} .`;
12444
+ }
12445
+
12446
+ if (isLogImpliedBy(tr.p)) {
12447
+ const s = termToRdfCompatible(tr.s, prefixes);
12448
+ const o = termToRdfCompatible(tr.o, prefixes);
12449
+ return `${s} <= ${o} .`;
12450
+ }
12451
+
12452
+ const s = termToRdfCompatible(tr.s, prefixes);
12453
+ const p = isRdfTypePred(tr.p) ? 'a' : isOwlSameAsPred(tr.p) ? '=' : termToN3(tr.p, prefixes);
12454
+ const o = termToRdfCompatible(tr.o, prefixes);
12455
+ return `${s} ${p} ${o} .`;
12456
+ }
12457
+
12458
+ function prettyPrintQueryTriplesRdfCompatible(triples, prefixes) {
12459
+ return triples.map((tr) => tripleToRdfCompatible(tr, prefixes)).join('\n');
12460
+ }
12461
+
12462
+ function needsRdf12Version(text) {
12463
+ return typeof text === 'string' && text.includes('<<(');
12464
+ }
12465
+
12466
+ module.exports = {
12467
+ termToN3,
12468
+ tripleToN3,
12469
+ prettyPrintQueryTriples,
12470
+ termToRdfCompatible,
12471
+ tripleToRdfCompatible,
12472
+ prettyPrintQueryTriplesRdfCompatible,
12473
+ needsRdf12Version,
12474
+ };
12146
12475
 
12147
12476
  };
12148
12477
  __modules["lib/rdfjs.js"] = function(require, module, exports){
package/index.js CHANGED
@@ -37,6 +37,8 @@ function reason(opt = {}, input = '') {
37
37
  else args.push('--no-proof-comments');
38
38
  }
39
39
 
40
+ if (opt.rdf) args.push('--rdf');
41
+
40
42
  if (Array.isArray(opt.args)) args.push(...opt.args);
41
43
 
42
44
  const builtinModules = Array.isArray(opt.builtinModules)