eyeling 1.24.1 → 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/HANDBOOK.md +134 -0
- package/dist/browser/eyeling.browser.js +454 -22
- package/eyeling.js +454 -22
- package/index.js +2 -0
- package/lib/cli.js +27 -10
- package/lib/engine.js +17 -7
- package/lib/lexer.js +295 -2
- package/lib/multisource.js +9 -2
- package/lib/printing.js +106 -1
- package/package.json +1 -1
- package/see/README.md +4 -0
- package/see/examples/_see.js +33 -2
- package/see/examples/age.js +27 -1
- package/see/examples/annotation.js +27 -1
- package/see/examples/backward.js +27 -1
- package/see/examples/backward_recursion.js +27 -1
- package/see/examples/bayes_diagnosis.js +27 -1
- package/see/examples/bayes_therapy.js +27 -1
- package/see/examples/bmi.js +27 -1
- package/see/examples/builtin_coverage.js +27 -1
- package/see/examples/collection.js +27 -1
- package/see/examples/complex.js +27 -1
- package/see/examples/complex_matrix_stability.js +27 -1
- package/see/examples/composition_of_injective_functions_is_injective.js +27 -1
- package/see/examples/control_system.js +27 -1
- package/see/examples/crypto_builtins_tests.js +27 -1
- package/see/examples/delfour.js +27 -1
- package/see/examples/digital_product_passport.js +27 -1
- package/see/examples/dijkstra.js +27 -1
- package/see/examples/dijkstra_risk_path.js +27 -1
- package/see/examples/doc/rdf_dataset.md +26 -0
- package/see/examples/doc/triple_terms.md +26 -0
- package/see/examples/dog.js +27 -1
- package/see/examples/eco_route_insight.js +27 -1
- package/see/examples/equals.js +27 -1
- package/see/examples/equivalence_classes_overlap_implies_same_class.js +27 -1
- package/see/examples/euler_identity.js +27 -1
- package/see/examples/ev_roundtrip_planner.js +27 -1
- package/see/examples/existential_rule.js +27 -1
- package/see/examples/expression_eval.js +27 -1
- package/see/examples/family_cousins.js +27 -1
- package/see/examples/fastpow.js +27 -1
- package/see/examples/fibonacci.js +27 -1
- package/see/examples/french_cities.js +27 -1
- package/see/examples/fundamental_theorem_arithmetic.js +27 -1
- package/see/examples/genetic_knapsack_selection.js +27 -1
- package/see/examples/goldbach_1000.js +27 -1
- package/see/examples/good_cobbler.js +27 -1
- package/see/examples/gps.js +27 -1
- package/see/examples/gray_code_counter.js +27 -1
- package/see/examples/greatest_lower_bound_uniqueness.js +27 -1
- package/see/examples/group_inverse_uniqueness.js +27 -1
- package/see/examples/hadamard_approx.js +27 -1
- package/see/examples/hanoi.js +27 -1
- package/see/examples/input/rdf_dataset.trig +34 -0
- package/see/examples/input/triple_terms.trig +28 -0
- package/see/examples/n3/rdf_dataset.n3 +34 -0
- package/see/examples/n3/triple_terms.n3 +23 -0
- package/see/examples/odrl_dpv_risk_ranked.js +27 -1
- package/see/examples/output/rdf_dataset.md +54 -0
- package/see/examples/output/triple_terms.md +53 -0
- package/see/examples/path_discovery.js +27 -1
- package/see/examples/rc_discharge_envelope.js +27 -1
- package/see/examples/rdf_dataset.js +1512 -0
- package/see/examples/rdf_message_flow.js +27 -1
- package/see/examples/rdf_messages.js +27 -1
- package/see/examples/school_placement_audit.js +27 -1
- package/see/examples/smoke_arithmetic.js +27 -1
- package/see/examples/socrates.js +27 -1
- package/see/examples/triple_terms.js +1442 -0
- package/see/examples/wind_turbine.js +27 -1
- package/see/examples/witch.js +27 -1
- package/see/see.js +101 -4
- package/test/api.test.js +86 -0
- package/test/see.test.js +0 -0
- package/tools/bundle.js +0 -0
- package/tools/n3gen.js +0 -0
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
|
-
|
|
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
|
-
|
|
4813
|
-
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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,
|
|
@@ -9555,7 +9582,300 @@ function stripQuotes(lex) {
|
|
|
9555
9582
|
return lex;
|
|
9556
9583
|
}
|
|
9557
9584
|
|
|
9558
|
-
|
|
9585
|
+
|
|
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);
|
|
9604
|
+
|
|
9605
|
+
if (!hasTripleTerms && !hasVersionDirective && !hasNamedGraphCandidate) return text;
|
|
9606
|
+
|
|
9607
|
+
function isWordChar(ch) {
|
|
9608
|
+
return ch != null && /[A-Za-z0-9_:-]/.test(ch);
|
|
9609
|
+
}
|
|
9610
|
+
|
|
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;
|
|
9618
|
+
let out = quote;
|
|
9619
|
+
const long = s.startsWith(quote.repeat(3), i);
|
|
9620
|
+
if (long) {
|
|
9621
|
+
out = quote.repeat(3);
|
|
9622
|
+
i += 3;
|
|
9623
|
+
while (i < s.length) {
|
|
9624
|
+
if (s.startsWith(quote.repeat(3), i)) {
|
|
9625
|
+
out += quote.repeat(3);
|
|
9626
|
+
i += 3;
|
|
9627
|
+
return { text: out, end: i };
|
|
9628
|
+
}
|
|
9629
|
+
if (s[i] === '\\' && i + 1 < s.length) {
|
|
9630
|
+
out += s.slice(i, i + 2);
|
|
9631
|
+
i += 2;
|
|
9632
|
+
} else {
|
|
9633
|
+
out += s[i++];
|
|
9634
|
+
}
|
|
9635
|
+
}
|
|
9636
|
+
return { text: out, end: i };
|
|
9637
|
+
}
|
|
9638
|
+
i += 1;
|
|
9639
|
+
let escaped = false;
|
|
9640
|
+
while (i < s.length) {
|
|
9641
|
+
const ch = s[i++];
|
|
9642
|
+
out += ch;
|
|
9643
|
+
if (escaped) {
|
|
9644
|
+
escaped = false;
|
|
9645
|
+
} else if (ch === '\\') {
|
|
9646
|
+
escaped = true;
|
|
9647
|
+
} else if (ch === quote) {
|
|
9648
|
+
break;
|
|
9649
|
+
}
|
|
9650
|
+
}
|
|
9651
|
+
return { text: out, end: i };
|
|
9652
|
+
}
|
|
9653
|
+
|
|
9654
|
+
function readIriAt(s, at) {
|
|
9655
|
+
let i = at + 1;
|
|
9656
|
+
let out = '<';
|
|
9657
|
+
while (i < s.length) {
|
|
9658
|
+
const ch = s[i++];
|
|
9659
|
+
out += ch;
|
|
9660
|
+
if (ch === '>') break;
|
|
9661
|
+
}
|
|
9662
|
+
return { text: out, end: i };
|
|
9663
|
+
}
|
|
9664
|
+
|
|
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;
|
|
9707
|
+
}
|
|
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;
|
|
9728
|
+
continue;
|
|
9729
|
+
}
|
|
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];
|
|
9751
|
+
if (ch === '"' || ch === "'") {
|
|
9752
|
+
i = readStringAt(s, i).end;
|
|
9753
|
+
continue;
|
|
9754
|
+
}
|
|
9755
|
+
if (ch === '<') {
|
|
9756
|
+
i = readIriAt(s, i).end;
|
|
9757
|
+
continue;
|
|
9758
|
+
}
|
|
9759
|
+
if (ch === '#') {
|
|
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 };
|
|
9768
|
+
continue;
|
|
9769
|
+
}
|
|
9770
|
+
i += 1;
|
|
9771
|
+
}
|
|
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
|
+
|
|
9867
|
+
return out;
|
|
9868
|
+
}
|
|
9869
|
+
|
|
9870
|
+
if (hasTripleTerms) text = convertTripleTerms(text);
|
|
9871
|
+
if (hasVersionDirective) text = stripVersionDirectives(text);
|
|
9872
|
+
if (hasVersionDirective || hasNamedGraphCandidate) text = normalizeNamedGraphs(text);
|
|
9873
|
+
return text;
|
|
9874
|
+
}
|
|
9875
|
+
|
|
9876
|
+
function lex(inputText, opts = {}) {
|
|
9877
|
+
const rdf = !!(opts && opts.rdf);
|
|
9878
|
+
if (rdf) inputText = normalizeRdfCompatibility(inputText);
|
|
9559
9879
|
const chars = Array.from(inputText);
|
|
9560
9880
|
const n = chars.length;
|
|
9561
9881
|
let i = 0;
|
|
@@ -10016,7 +10336,7 @@ function lex(inputText) {
|
|
|
10016
10336
|
return tokens;
|
|
10017
10337
|
}
|
|
10018
10338
|
|
|
10019
|
-
module.exports = { Token, N3SyntaxError, lex, decodeN3StringEscapes };
|
|
10339
|
+
module.exports = { Token, N3SyntaxError, lex, normalizeRdfCompatibility, decodeN3StringEscapes };
|
|
10020
10340
|
|
|
10021
10341
|
};
|
|
10022
10342
|
__modules["lib/multisource.js"] = function(require, module, exports){
|
|
@@ -10125,8 +10445,14 @@ function prefixesUsedInTokens(tokens, prefEnv) {
|
|
|
10125
10445
|
}
|
|
10126
10446
|
|
|
10127
10447
|
function parseN3Text(text, opts = {}) {
|
|
10128
|
-
const {
|
|
10129
|
-
|
|
10448
|
+
const {
|
|
10449
|
+
baseIri = '',
|
|
10450
|
+
label = '<input>',
|
|
10451
|
+
keepSourceArtifacts = true,
|
|
10452
|
+
collectUsedPrefixes = false,
|
|
10453
|
+
rdf = false,
|
|
10454
|
+
} = opts || {};
|
|
10455
|
+
const tokens = lex(text, { rdf });
|
|
10130
10456
|
const parser = new Parser(tokens);
|
|
10131
10457
|
if (baseIri) parser.prefixes.setBase(baseIri);
|
|
10132
10458
|
const [prefixes, triples, frules, brules, logQueryRules] = parser.parseDocument();
|
|
@@ -10320,6 +10646,7 @@ function parseN3SourceList(input, opts = {}) {
|
|
|
10320
10646
|
baseIri: source.baseIri || (sources.length === 1 ? defaultBaseIri : ''),
|
|
10321
10647
|
collectUsedPrefixes: true,
|
|
10322
10648
|
keepSourceArtifacts: !!opts.keepSourceArtifacts,
|
|
10649
|
+
rdf: !!opts.rdf,
|
|
10323
10650
|
}),
|
|
10324
10651
|
);
|
|
10325
10652
|
return mergeParsedDocuments(parsed, {
|
|
@@ -11710,6 +12037,7 @@ const {
|
|
|
11710
12037
|
isOwlSameAsPred,
|
|
11711
12038
|
isLogImplies,
|
|
11712
12039
|
isLogImpliedBy,
|
|
12040
|
+
LOG_NS,
|
|
11713
12041
|
} = require('./prelude');
|
|
11714
12042
|
|
|
11715
12043
|
function stripQuotes(lex) {
|
|
@@ -12039,7 +12367,111 @@ function prettyPrintQueryTriples(triples, prefixes) {
|
|
|
12039
12367
|
return blocks.join('\n');
|
|
12040
12368
|
}
|
|
12041
12369
|
|
|
12042
|
-
|
|
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
|
+
};
|
|
12043
12475
|
|
|
12044
12476
|
};
|
|
12045
12477
|
__modules["lib/rdfjs.js"] = function(require, module, exports){
|
package/index.js
CHANGED