eyeling 1.29.2 → 1.30.0
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/README.md +153 -0
- package/dist/browser/eyeling.browser.js +711 -21
- package/examples/input/rdf-surfaces-all-values-from-reverse.ttl +17 -0
- package/examples/input/rdf-surfaces-all-values-from.ttl +13 -0
- package/examples/input/rdf-surfaces-ancestor.ttl +20 -0
- package/examples/input/rdf-surfaces-city.ttl +11 -0
- package/examples/input/rdf-surfaces-domain.ttl +11 -0
- package/examples/input/rdf-surfaces-multi-premise.ttl +13 -0
- package/examples/input/rdf-surfaces-owl-all-values-from-codex.ttl +35 -0
- package/examples/input/rdf-surfaces-property-chain.ttl +13 -0
- package/examples/input/rdf-surfaces-range.ttl +11 -0
- package/examples/input/rdf-surfaces-rdfs-range-codex.ttl +18 -0
- package/examples/input/rdf-surfaces-rdfs-subclass-codex.ttl +18 -0
- package/examples/output/rdf-surfaces-all-values-from-reverse.n3 +3 -0
- package/examples/output/rdf-surfaces-all-values-from.n3 +3 -0
- package/examples/output/rdf-surfaces-ancestor.n3 +5 -0
- package/examples/output/rdf-surfaces-city.n3 +3 -0
- package/examples/output/rdf-surfaces-domain.n3 +3 -0
- package/examples/output/rdf-surfaces-multi-premise.n3 +3 -0
- package/examples/output/rdf-surfaces-owl-all-values-from-codex.n3 +6 -0
- package/examples/output/rdf-surfaces-property-chain.n3 +3 -0
- package/examples/output/rdf-surfaces-range.n3 +3 -0
- package/examples/output/rdf-surfaces-rdfs-range-codex.n3 +3 -0
- package/examples/output/rdf-surfaces-rdfs-subclass-codex.n3 +3 -0
- package/examples/rdf-surfaces-all-values-from-reverse.n3 +6 -0
- package/examples/rdf-surfaces-all-values-from.n3 +6 -0
- package/examples/rdf-surfaces-ancestor.n3 +6 -0
- package/examples/rdf-surfaces-city.n3 +6 -0
- package/examples/rdf-surfaces-domain.n3 +6 -0
- package/examples/rdf-surfaces-multi-premise.n3 +6 -0
- package/examples/rdf-surfaces-owl-all-values-from-codex.n3 +10 -0
- package/examples/rdf-surfaces-property-chain.n3 +6 -0
- package/examples/rdf-surfaces-range.n3 +6 -0
- package/examples/rdf-surfaces-rdfs-range-codex.n3 +6 -0
- package/examples/rdf-surfaces-rdfs-subclass-codex.n3 +6 -0
- package/eyeling.js +711 -21
- package/index.d.ts +4 -0
- package/index.js +2 -1
- package/lib/builtins.js +128 -3
- package/lib/cli.js +11 -4
- package/lib/engine.js +15 -7
- package/lib/lexer.js +4 -0
- package/lib/multisource.js +5 -3
- package/lib/prelude.js +18 -0
- package/lib/rdf_surfaces.js +524 -0
- package/lib/rules.js +3 -4
- package/package.json +8 -5
- package/test/builtins.test.js +36 -0
- package/test/examples.test.js +37 -5
- package/test/rdf_surfaces.test.js +204 -0
package/index.d.ts
CHANGED
|
@@ -169,6 +169,8 @@ declare module 'eyeling' {
|
|
|
169
169
|
store?: string | StoreOptions;
|
|
170
170
|
storePath?: string;
|
|
171
171
|
storeClear?: boolean;
|
|
172
|
+
rdf?: boolean;
|
|
173
|
+
rdfSurfaces?: boolean;
|
|
172
174
|
}
|
|
173
175
|
|
|
174
176
|
export interface BuiltinRegistrationContext {
|
|
@@ -191,6 +193,8 @@ declare module 'eyeling' {
|
|
|
191
193
|
includeInputFactsInClosure?: boolean;
|
|
192
194
|
enforceHttps?: boolean;
|
|
193
195
|
rdfjs?: boolean;
|
|
196
|
+
rdf?: boolean;
|
|
197
|
+
rdfSurfaces?: boolean;
|
|
194
198
|
dataFactory?: RdfJsDataFactory | null;
|
|
195
199
|
skipUnsupportedRdfJs?: boolean;
|
|
196
200
|
builtinModules?: string | string[];
|
package/index.js
CHANGED
|
@@ -40,7 +40,8 @@ function reason(opt = {}, input = '') {
|
|
|
40
40
|
else args.push('--no-proof-comments');
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
if (opt.rdf) args.push('--rdf');
|
|
43
|
+
if (opt.rdf || opt.rdfSurfaces) args.push('--rdf');
|
|
44
|
+
if (opt.rdfSurfaces) args.push('--rdf-surfaces');
|
|
44
45
|
|
|
45
46
|
if (typeof opt.store === 'string' && opt.store) args.push('--store', opt.store);
|
|
46
47
|
else if (opt.store && typeof opt.store === 'object') {
|
package/lib/builtins.js
CHANGED
|
@@ -30,6 +30,8 @@ const {
|
|
|
30
30
|
PrefixEnv,
|
|
31
31
|
literalParts,
|
|
32
32
|
copyQuotedGraphMetadata,
|
|
33
|
+
isInternalBlankVarName,
|
|
34
|
+
internalBlankVarSuffix,
|
|
33
35
|
} = require('./prelude');
|
|
34
36
|
|
|
35
37
|
const { decodeN3StringEscapes } = require('./lexer');
|
|
@@ -132,6 +134,127 @@ function __assertBuiltinHandlerResult(iri, out) {
|
|
|
132
134
|
}
|
|
133
135
|
}
|
|
134
136
|
|
|
137
|
+
function collectVarNamesInTerm(t, acc) {
|
|
138
|
+
if (t instanceof Var) {
|
|
139
|
+
acc.add(t.name);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (t instanceof ListTerm) {
|
|
143
|
+
for (const e of t.elems) collectVarNamesInTerm(e, acc);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (t instanceof OpenListTerm) {
|
|
147
|
+
for (const e of t.prefix) collectVarNamesInTerm(e, acc);
|
|
148
|
+
acc.add(t.tailVar);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (t instanceof GraphTerm) {
|
|
152
|
+
for (const tr of t.triples) collectVarNamesInTriple(tr, acc);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function collectVarNamesInTriple(tr, acc) {
|
|
157
|
+
collectVarNamesInTerm(tr.s, acc);
|
|
158
|
+
collectVarNamesInTerm(tr.p, acc);
|
|
159
|
+
collectVarNamesInTerm(tr.o, acc);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function cloneSubstWithMappedKeys(subst, keyMap, externalizeTerm) {
|
|
163
|
+
const out = Object.create(null);
|
|
164
|
+
for (const [key, val] of Object.entries(subst || {})) {
|
|
165
|
+
out[keyMap.get(key) || key] = externalizeTerm ? externalizeTerm(val) : val;
|
|
166
|
+
}
|
|
167
|
+
return out;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function hasInternalBlankVarInSubst(subst) {
|
|
171
|
+
for (const key of Object.keys(subst || {})) {
|
|
172
|
+
if (isInternalBlankVarName(key)) return true;
|
|
173
|
+
}
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function makeCustomBuiltinPublicBridge(goal, subst) {
|
|
178
|
+
const used = new Set(Object.keys(subst || {}).filter((name) => !isInternalBlankVarName(name)));
|
|
179
|
+
collectVarNamesInTriple(goal, used);
|
|
180
|
+
for (const name of Array.from(used)) {
|
|
181
|
+
if (isInternalBlankVarName(name)) used.delete(name);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const internalNames = new Set();
|
|
185
|
+
collectVarNamesInTriple(goal, internalNames);
|
|
186
|
+
for (const key of Object.keys(subst || {})) internalNames.add(key);
|
|
187
|
+
for (const name of Array.from(internalNames)) {
|
|
188
|
+
if (!isInternalBlankVarName(name)) internalNames.delete(name);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (internalNames.size === 0 && !hasInternalBlankVarInSubst(subst)) return null;
|
|
192
|
+
|
|
193
|
+
const internalToPublic = new Map();
|
|
194
|
+
const publicToInternal = new Map();
|
|
195
|
+
|
|
196
|
+
function allocatePublicName(internalName) {
|
|
197
|
+
const suffix = internalBlankVarSuffix(internalName) || String(internalToPublic.size + 1);
|
|
198
|
+
const base = /^[$A-Za-z_][0-9A-Za-z_]*$/u.test(`_b${suffix}`) ? `_b${suffix}` : `_b${internalToPublic.size + 1}`;
|
|
199
|
+
let name = base;
|
|
200
|
+
let n = 1;
|
|
201
|
+
while (used.has(name) || publicToInternal.has(name)) {
|
|
202
|
+
n += 1;
|
|
203
|
+
name = `${base}_${n}`;
|
|
204
|
+
}
|
|
205
|
+
used.add(name);
|
|
206
|
+
internalToPublic.set(internalName, name);
|
|
207
|
+
publicToInternal.set(name, internalName);
|
|
208
|
+
return name;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
for (const name of internalNames) allocatePublicName(name);
|
|
212
|
+
|
|
213
|
+
function externalName(name) {
|
|
214
|
+
if (!isInternalBlankVarName(name)) return name;
|
|
215
|
+
return internalToPublic.get(name) || allocatePublicName(name);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function externalizeTerm(t) {
|
|
219
|
+
if (t instanceof Var) return new Var(externalName(t.name));
|
|
220
|
+
if (t instanceof ListTerm) return new ListTerm(t.elems.map(externalizeTerm));
|
|
221
|
+
if (t instanceof OpenListTerm) return new OpenListTerm(t.prefix.map(externalizeTerm), externalName(t.tailVar));
|
|
222
|
+
if (t instanceof GraphTerm) {
|
|
223
|
+
const triples = t.triples.map((tr) => new Triple(externalizeTerm(tr.s), externalizeTerm(tr.p), externalizeTerm(tr.o)));
|
|
224
|
+
return copyQuotedGraphMetadata(t, new GraphTerm(triples));
|
|
225
|
+
}
|
|
226
|
+
return t;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function internalizeTerm(t) {
|
|
230
|
+
if (t instanceof Var) return new Var(publicToInternal.get(t.name) || t.name);
|
|
231
|
+
if (t instanceof ListTerm) return new ListTerm(t.elems.map(internalizeTerm));
|
|
232
|
+
if (t instanceof OpenListTerm) return new OpenListTerm(t.prefix.map(internalizeTerm), publicToInternal.get(t.tailVar) || t.tailVar);
|
|
233
|
+
if (t instanceof GraphTerm) {
|
|
234
|
+
const triples = t.triples.map((tr) => new Triple(internalizeTerm(tr.s), internalizeTerm(tr.p), internalizeTerm(tr.o)));
|
|
235
|
+
return copyQuotedGraphMetadata(t, new GraphTerm(triples));
|
|
236
|
+
}
|
|
237
|
+
return t;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function internalizeDelta(delta) {
|
|
241
|
+
const out = Object.create(null);
|
|
242
|
+
for (const [key, val] of Object.entries(delta || {})) {
|
|
243
|
+
out[publicToInternal.get(key) || key] = internalizeTerm(val);
|
|
244
|
+
}
|
|
245
|
+
return out;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return {
|
|
249
|
+
goal: new Triple(externalizeTerm(goal.s), externalizeTerm(goal.p), externalizeTerm(goal.o)),
|
|
250
|
+
subst: cloneSubstWithMappedKeys(subst, internalToPublic, externalizeTerm),
|
|
251
|
+
internalizeResults(out) {
|
|
252
|
+
if (out == null) return out;
|
|
253
|
+
return out.map(internalizeDelta);
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
|
|
135
258
|
function apiTermToN3(term, prefixes = PrefixEnv.newDefault()) {
|
|
136
259
|
return termToN3(term, prefixes || PrefixEnv.newDefault());
|
|
137
260
|
}
|
|
@@ -231,10 +354,11 @@ function __evalRegisteredBuiltin(pv, goal, subst, facts, backRules, depth, varGe
|
|
|
231
354
|
const handler = __customBuiltinHandlers.get(pv);
|
|
232
355
|
if (typeof handler !== 'function') return null;
|
|
233
356
|
|
|
357
|
+
const bridge = makeCustomBuiltinPublicBridge(goal, subst);
|
|
234
358
|
const ctx = {
|
|
235
359
|
iri: pv,
|
|
236
|
-
goal,
|
|
237
|
-
subst,
|
|
360
|
+
goal: bridge ? bridge.goal : goal,
|
|
361
|
+
subst: bridge ? bridge.subst : subst,
|
|
238
362
|
facts,
|
|
239
363
|
backRules,
|
|
240
364
|
depth,
|
|
@@ -244,7 +368,8 @@ function __evalRegisteredBuiltin(pv, goal, subst, facts, backRules, depth, varGe
|
|
|
244
368
|
};
|
|
245
369
|
|
|
246
370
|
try {
|
|
247
|
-
const
|
|
371
|
+
const raw = handler(ctx);
|
|
372
|
+
const out = bridge ? bridge.internalizeResults(raw) : raw;
|
|
248
373
|
if (out == null) return [];
|
|
249
374
|
__assertBuiltinHandlerResult(pv, out);
|
|
250
375
|
return out;
|
package/lib/cli.js
CHANGED
|
@@ -685,7 +685,7 @@ async function ingestLineBasedRdfSourceToStore(sourceLabel, store, { rdfMode = t
|
|
|
685
685
|
}
|
|
686
686
|
|
|
687
687
|
|
|
688
|
-
async function runStreamMessagesMode(sourceLabels, { rdfMode, storeName = null, storePath = null, storeClear = false } = {}) {
|
|
688
|
+
async function runStreamMessagesMode(sourceLabels, { rdfMode, rdfSurfacesMode = false, storeName = null, storePath = null, storeClear = false } = {}) {
|
|
689
689
|
const ordinarySourceLabels = [];
|
|
690
690
|
const messageSourceLabels = [];
|
|
691
691
|
|
|
@@ -723,6 +723,7 @@ async function runStreamMessagesMode(sourceLabels, { rdfMode, storeName = null,
|
|
|
723
723
|
keepSourceArtifacts: false,
|
|
724
724
|
sourceLocations: false,
|
|
725
725
|
rdf: rdfMode,
|
|
726
|
+
rdfSurfaces: rdfSurfacesMode,
|
|
726
727
|
}),
|
|
727
728
|
);
|
|
728
729
|
} catch (e) {
|
|
@@ -756,6 +757,7 @@ async function runStreamMessagesMode(sourceLabels, { rdfMode, storeName = null,
|
|
|
756
757
|
keepSourceArtifacts: false,
|
|
757
758
|
sourceLocations: false,
|
|
758
759
|
rdf: false,
|
|
760
|
+
rdfSurfaces: false,
|
|
759
761
|
});
|
|
760
762
|
} catch (e) {
|
|
761
763
|
if (e && e.name === 'N3SyntaxError') {
|
|
@@ -810,6 +812,7 @@ async function main() {
|
|
|
810
812
|
` -h, --help Show this help and exit.\n` +
|
|
811
813
|
` -p, --proof Enable proof explanations.\n` +
|
|
812
814
|
` -r, --rdf Enable RDF/TriG input/output compatibility.\n` +
|
|
815
|
+
` --rdf-surfaces Enable RDF Surfaces %not[...%] syntax (implies --rdf).\n` +
|
|
813
816
|
` --stream-messages Process RDF Message Logs one message at a time under -r.\n` +
|
|
814
817
|
` --store <name> Use an optional persistent fact store.\n` +
|
|
815
818
|
` --store-clear Clear the named store before this run.\n` +
|
|
@@ -885,7 +888,8 @@ async function main() {
|
|
|
885
888
|
const showAst = argv.includes('--ast') || argv.includes('-a');
|
|
886
889
|
const streamMode = argv.includes('--stream') || argv.includes('-t');
|
|
887
890
|
const streamMessagesMode = argv.includes('--stream-messages');
|
|
888
|
-
const
|
|
891
|
+
const rdfSurfacesMode = argv.includes('--rdf-surfaces');
|
|
892
|
+
const rdfMode = argv.includes('--rdf') || argv.includes('-r') || rdfSurfacesMode;
|
|
889
893
|
const storeName = argv.__storeName || null;
|
|
890
894
|
const storePath = argv.__storePath || null;
|
|
891
895
|
const storeClear = argv.includes('--store-clear');
|
|
@@ -954,7 +958,7 @@ async function main() {
|
|
|
954
958
|
}
|
|
955
959
|
|
|
956
960
|
if (streamMessagesMode) {
|
|
957
|
-
await runStreamMessagesMode(sourceLabels, { rdfMode, storeName, storePath, storeClear });
|
|
961
|
+
await runStreamMessagesMode(sourceLabels, { rdfMode, rdfSurfacesMode, storeName, storePath, storeClear });
|
|
958
962
|
return;
|
|
959
963
|
}
|
|
960
964
|
|
|
@@ -1008,6 +1012,7 @@ async function main() {
|
|
|
1008
1012
|
keepSourceArtifacts: false,
|
|
1009
1013
|
sourceLocations: false,
|
|
1010
1014
|
rdf: rdfMode,
|
|
1015
|
+
rdfSurfaces: rdfSurfacesMode,
|
|
1011
1016
|
}),
|
|
1012
1017
|
);
|
|
1013
1018
|
} catch (e) {
|
|
@@ -1020,7 +1025,7 @@ async function main() {
|
|
|
1020
1025
|
}
|
|
1021
1026
|
|
|
1022
1027
|
const mergedRuleDocument = mergeParsedDocuments(parsedRuleSources);
|
|
1023
|
-
const result = await engine.runStoreBacked(mergedRuleDocument, store, { rdf: rdfMode });
|
|
1028
|
+
const result = await engine.runStoreBacked(mergedRuleDocument, store, { rdf: rdfMode, rdfSurfaces: rdfSurfacesMode });
|
|
1024
1029
|
const outTriples = result.queryMode ? result.queryTriples || [] : (result.derived || []).map((df) => df.fact);
|
|
1025
1030
|
if (result.queryMode) {
|
|
1026
1031
|
const bodyText = engine.prettyPrintQueryTriples(outTriples, result.prefixes);
|
|
@@ -1055,6 +1060,7 @@ async function main() {
|
|
|
1055
1060
|
keepSourceArtifacts: false,
|
|
1056
1061
|
sourceLocations: engine.getProofCommentsEnabled(),
|
|
1057
1062
|
rdf: rdfMode,
|
|
1063
|
+
rdfSurfaces: rdfSurfacesMode,
|
|
1058
1064
|
}),
|
|
1059
1065
|
);
|
|
1060
1066
|
} catch (e) {
|
|
@@ -1155,6 +1161,7 @@ function factsContainOutputStrings(triplesForOutput) {
|
|
|
1155
1161
|
{
|
|
1156
1162
|
proof: engine.getProofCommentsEnabled(),
|
|
1157
1163
|
rdf: rdfMode,
|
|
1164
|
+
rdfSurfaces: rdfSurfacesMode,
|
|
1158
1165
|
store: { name: storeName, clear: storeClear, path: storePath || undefined },
|
|
1159
1166
|
},
|
|
1160
1167
|
);
|
package/lib/engine.js
CHANGED
|
@@ -3623,12 +3623,14 @@ function reasonStream(input, opts = {}) {
|
|
|
3623
3623
|
skipUnsupportedRdfJs = false,
|
|
3624
3624
|
builtinModules = null,
|
|
3625
3625
|
rdf = false,
|
|
3626
|
+
rdfSurfaces = false,
|
|
3626
3627
|
sourceLabel = '<input>',
|
|
3627
3628
|
} = opts;
|
|
3628
3629
|
|
|
3629
|
-
const useRdfCompatibility = !!rdf;
|
|
3630
|
+
const useRdfCompatibility = !!rdf || !!rdfSurfaces;
|
|
3631
|
+
const useRdfSurfaces = !!rdfSurfaces;
|
|
3630
3632
|
|
|
3631
|
-
const parsedSourceList = parseN3SourceList(input, { baseIri, rdf: useRdfCompatibility, sourceLocations: proof });
|
|
3633
|
+
const parsedSourceList = parseN3SourceList(input, { baseIri, rdf: useRdfCompatibility, rdfSurfaces: useRdfSurfaces, sourceLocations: proof });
|
|
3632
3634
|
const parsedTextInput = (!parsedSourceList && proof && typeof input === 'string')
|
|
3633
3635
|
? parseN3Text(input, {
|
|
3634
3636
|
baseIri: baseIri || '',
|
|
@@ -3636,6 +3638,7 @@ function reasonStream(input, opts = {}) {
|
|
|
3636
3638
|
keepSourceArtifacts: false,
|
|
3637
3639
|
sourceLocations: true,
|
|
3638
3640
|
rdf: useRdfCompatibility,
|
|
3641
|
+
rdfSurfaces: useRdfSurfaces,
|
|
3639
3642
|
})
|
|
3640
3643
|
: null;
|
|
3641
3644
|
const hasInlineN3 = input && typeof input === 'object' && !Array.isArray(input) && typeof input.n3 === 'string';
|
|
@@ -3680,6 +3683,7 @@ function reasonStream(input, opts = {}) {
|
|
|
3680
3683
|
keepSourceArtifacts: false,
|
|
3681
3684
|
sourceLocations: proof,
|
|
3682
3685
|
rdf: useRdfCompatibility,
|
|
3686
|
+
rdfSurfaces: useRdfSurfaces,
|
|
3683
3687
|
});
|
|
3684
3688
|
prefixes = directDoc.prefixes;
|
|
3685
3689
|
triples = directDoc.triples;
|
|
@@ -3791,10 +3795,11 @@ async function __parseRunAsyncInput(input, opts) {
|
|
|
3791
3795
|
baseIri = null,
|
|
3792
3796
|
proof = false,
|
|
3793
3797
|
rdf = false,
|
|
3798
|
+
rdfSurfaces = false,
|
|
3794
3799
|
sourceLabel = '<input>',
|
|
3795
3800
|
} = opts || {};
|
|
3796
3801
|
|
|
3797
|
-
const parsedSourceList = parseN3SourceList(input, { baseIri, rdf: !!rdf, sourceLocations: !!proof });
|
|
3802
|
+
const parsedSourceList = parseN3SourceList(input, { baseIri, rdf: !!rdf || !!rdfSurfaces, rdfSurfaces: !!rdfSurfaces, sourceLocations: !!proof });
|
|
3798
3803
|
if (parsedSourceList) return parsedSourceList;
|
|
3799
3804
|
|
|
3800
3805
|
const parsedObject = await normalizeParsedReasonerInputAsync(input);
|
|
@@ -3809,7 +3814,8 @@ async function __parseRunAsyncInput(input, opts) {
|
|
|
3809
3814
|
label: sourceLabel || '<input>',
|
|
3810
3815
|
keepSourceArtifacts: false,
|
|
3811
3816
|
sourceLocations: !!proof,
|
|
3812
|
-
rdf: !!rdf,
|
|
3817
|
+
rdf: !!rdf || !!rdfSurfaces,
|
|
3818
|
+
rdfSurfaces: !!rdfSurfaces,
|
|
3813
3819
|
});
|
|
3814
3820
|
}
|
|
3815
3821
|
|
|
@@ -3885,7 +3891,8 @@ async function __proveGoalsAgainstStore(goals, subst, store, backRules, localFac
|
|
|
3885
3891
|
async function runStoreBacked(input, store, opts = {}) {
|
|
3886
3892
|
const parsed = parseN3SourceList(input, {
|
|
3887
3893
|
baseIri: opts.baseIri || null,
|
|
3888
|
-
rdf: !!opts.rdf,
|
|
3894
|
+
rdf: !!opts.rdf || !!opts.rdfSurfaces,
|
|
3895
|
+
rdfSurfaces: !!opts.rdfSurfaces,
|
|
3889
3896
|
sourceLocations: !!opts.proof,
|
|
3890
3897
|
}) || input;
|
|
3891
3898
|
|
|
@@ -3930,7 +3937,7 @@ async function runStoreBacked(input, store, opts = {}) {
|
|
|
3930
3937
|
}
|
|
3931
3938
|
|
|
3932
3939
|
let queryTriples = [];
|
|
3933
|
-
|
|
3940
|
+
let queryDerived = [];
|
|
3934
3941
|
if (qrules.length) {
|
|
3935
3942
|
for (const r of qrules) {
|
|
3936
3943
|
const solutions = await __proveGoalsAgainstStore(r.premise || [], __emptySubst(), store, brules, triples, 0, varGen, {});
|
|
@@ -4002,7 +4009,8 @@ async function runAsync(input, opts = {}) {
|
|
|
4002
4009
|
if (!storeConfig) {
|
|
4003
4010
|
const normalizedInput = parseN3SourceList(input, {
|
|
4004
4011
|
baseIri: runOpts.baseIri || null,
|
|
4005
|
-
rdf: !!runOpts.rdf,
|
|
4012
|
+
rdf: !!runOpts.rdf || !!runOpts.rdfSurfaces,
|
|
4013
|
+
rdfSurfaces: !!runOpts.rdfSurfaces,
|
|
4006
4014
|
sourceLocations: !!runOpts.proof,
|
|
4007
4015
|
}) || (await normalizeReasonerInputAsync(input));
|
|
4008
4016
|
return reasonStream(normalizedInput, runOpts);
|
package/lib/lexer.js
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
'use strict';
|
|
9
9
|
|
|
10
|
+
const { normalizeRdfSurfaces } = require('./rdf_surfaces');
|
|
11
|
+
|
|
10
12
|
class Token {
|
|
11
13
|
constructor(typ, value = null, offset = null) {
|
|
12
14
|
this.typ = typ;
|
|
@@ -1347,7 +1349,9 @@ function isNumericLikeIdentifier(word) {
|
|
|
1347
1349
|
|
|
1348
1350
|
function lex(inputText, opts = {}) {
|
|
1349
1351
|
const rdf = !!(opts && opts.rdf);
|
|
1352
|
+
const rdfSurfaces = !!(opts && opts.rdfSurfaces);
|
|
1350
1353
|
if (rdf) inputText = normalizeRdfCompatibility(inputText);
|
|
1354
|
+
if (rdfSurfaces) inputText = normalizeRdfSurfaces(inputText);
|
|
1351
1355
|
// Avoid copying large ASCII/BMP inputs into an Array. Array.from() is
|
|
1352
1356
|
// only needed when the text contains surrogate pairs and we want the old
|
|
1353
1357
|
// code-point iteration behavior for non-BMP characters.
|
package/lib/multisource.js
CHANGED
|
@@ -172,9 +172,10 @@ function parseN3Text(text, opts = {}) {
|
|
|
172
172
|
collectUsedPrefixes = false,
|
|
173
173
|
sourceLocations = false,
|
|
174
174
|
rdf = false,
|
|
175
|
+
rdfSurfaces = false,
|
|
175
176
|
} = opts || {};
|
|
176
177
|
|
|
177
|
-
if (rdf) {
|
|
178
|
+
if (rdf && !rdfSurfaces) {
|
|
178
179
|
const fastDoc = tryParseFastRdfText(text, { baseIri, label });
|
|
179
180
|
if (fastDoc) {
|
|
180
181
|
if (sourceLocations) annotateParsedSourceLocations(fastDoc, text, label);
|
|
@@ -183,7 +184,7 @@ function parseN3Text(text, opts = {}) {
|
|
|
183
184
|
}
|
|
184
185
|
}
|
|
185
186
|
|
|
186
|
-
const tokens = lex(text, { rdf });
|
|
187
|
+
const tokens = lex(text, { rdf, rdfSurfaces });
|
|
187
188
|
const parser = new Parser(tokens);
|
|
188
189
|
if (baseIri) parser.prefixes.setBase(baseIri);
|
|
189
190
|
const [prefixes, triples, frules, brules, logQueryRules] = parser.parseDocument();
|
|
@@ -382,7 +383,8 @@ function parseN3SourceList(input, opts = {}) {
|
|
|
382
383
|
collectUsedPrefixes: true,
|
|
383
384
|
keepSourceArtifacts: !!opts.keepSourceArtifacts,
|
|
384
385
|
sourceLocations: !!opts.sourceLocations,
|
|
385
|
-
rdf: !!opts.rdf,
|
|
386
|
+
rdf: !!opts.rdf || !!opts.rdfSurfaces,
|
|
387
|
+
rdfSurfaces: !!opts.rdfSurfaces,
|
|
386
388
|
}),
|
|
387
389
|
);
|
|
388
390
|
return mergeParsedDocuments(parsed, {
|
package/lib/prelude.js
CHANGED
|
@@ -25,6 +25,21 @@ const DT_NS = 'https://eyereasoner.github.io/eyeling/datatype#';
|
|
|
25
25
|
const SKOLEM_NS = 'https://eyereasoner.github.io/.well-known/genid/';
|
|
26
26
|
const RDF_JSON_DT = RDF_NS + 'JSON';
|
|
27
27
|
|
|
28
|
+
// Private rule-lifting variable prefix used for blank nodes that appear in
|
|
29
|
+
// rule-body patterns. The prefix is intentionally not spellable in N3 input,
|
|
30
|
+
// but public extension APIs should present these variables with stable,
|
|
31
|
+
// ordinary names and translate them back internally.
|
|
32
|
+
const INTERNAL_BLANK_VAR_PREFIX = '\uE000eyeling_b';
|
|
33
|
+
|
|
34
|
+
function isInternalBlankVarName(name) {
|
|
35
|
+
return typeof name === 'string' && name.startsWith(INTERNAL_BLANK_VAR_PREFIX);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function internalBlankVarSuffix(name) {
|
|
39
|
+
if (!isInternalBlankVarName(name)) return '';
|
|
40
|
+
return name.slice(INTERNAL_BLANK_VAR_PREFIX.length);
|
|
41
|
+
}
|
|
42
|
+
|
|
28
43
|
function parseUriReferenceForResolution(uri) {
|
|
29
44
|
// RFC 3986 Appendix B-style component parser, with the scheme tightened to
|
|
30
45
|
// the RFC scheme grammar. Capturing delimiter presence matters: `?` with an
|
|
@@ -728,6 +743,9 @@ module.exports = {
|
|
|
728
743
|
DT_NS,
|
|
729
744
|
SKOLEM_NS,
|
|
730
745
|
RDF_JSON_DT,
|
|
746
|
+
INTERNAL_BLANK_VAR_PREFIX,
|
|
747
|
+
isInternalBlankVarName,
|
|
748
|
+
internalBlankVarSuffix,
|
|
731
749
|
resolveIriRef,
|
|
732
750
|
literalParts,
|
|
733
751
|
normalizeLiteralForTid,
|