eyeling 1.7.8 → 1.7.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/examples/log-pan-rt-soe.n3 +29 -0
- package/examples/output/log-pan-rt-soe.n3 +9 -0
- package/examples/output/time.n3 +8 -0
- package/examples/time.n3 +29 -0
- package/eyeling.js +328 -38
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -216,10 +216,10 @@ Commonly used N3/Turtle features:
|
|
|
216
216
|
|
|
217
217
|
- **crypto**: `crypto:md5` `crypto:sha` `crypto:sha256` `crypto:sha512`
|
|
218
218
|
- **list**: `list:append` `list:first` `list:firstRest` `list:in` `list:iterate` `list:last` `list:length` `list:map` `list:member` `list:memberAt` `list:notMember` `list:remove` `list:rest` `list:reverse` `list:sort`
|
|
219
|
-
- **log**: `log:collectAllIn` `log:content` `log:equalTo` `log:forAllIn` `log:impliedBy` `log:implies` `log:notEqualTo` `log:notIncludes` `log:semantics` `log:skolem` `log:uri`
|
|
219
|
+
- **log**: `log:collectAllIn` `log:content` `log:dtlit` `log:equalTo` `log:forAllIn` `log:impliedBy` `log:implies` `log:includes` `log:langlit` `log:notEqualTo` `log:notIncludes` `log:outputString` `log:parsedAsN3` `log:rawType` `log:semantics` `log:semanticsOrError` `log:skolem` `log:uri`
|
|
220
220
|
- **math**: `math:absoluteValue` `math:acos` `math:asin` `math:atan` `math:cos` `math:cosh` `math:degrees` `math:difference` `math:equalTo` `math:exponentiation` `math:greaterThan` `math:integerQuotient` `math:lessThan` `math:negation` `math:notEqualTo` `math:notGreaterThan` `math:notLessThan` `math:product` `math:quotient` `math:remainder` `math:rounded` `math:sin` `math:sinh` `math:sum` `math:tan` `math:tanh`
|
|
221
221
|
- **string**: `string:concatenation` `string:contains` `string:containsIgnoringCase` `string:endsWith` `string:equalIgnoringCase` `string:format` `string:greaterThan` `string:jsonPointer` `string:lessThan` `string:matches` `string:notEqualIgnoringCase` `string:notGreaterThan` `string:notLessThan` `string:notMatches` `string:replace` `string:scrape` `string:startsWith`
|
|
222
|
-
- **time**: `time:localTime`
|
|
222
|
+
- **time**: `time:day` `time:localTime` `time:minute` `time:month` `time:second` `time:timeZone` `time:year`
|
|
223
223
|
|
|
224
224
|
## License
|
|
225
225
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# =======================================================
|
|
2
|
+
# log:parsedAsN3 log:rawType log:semanticsOrError example
|
|
3
|
+
# =======================================================
|
|
4
|
+
|
|
5
|
+
@prefix : <http://example.org/> .
|
|
6
|
+
@prefix log: <http://www.w3.org/2000/10/swap/log#> .
|
|
7
|
+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
|
8
|
+
|
|
9
|
+
:Let :param """
|
|
10
|
+
@prefix : <http://example.org/> .
|
|
11
|
+
:s :p :o .
|
|
12
|
+
""" .
|
|
13
|
+
|
|
14
|
+
{
|
|
15
|
+
:Let :param ?txt .
|
|
16
|
+
?txt log:parsedAsN3 ?f .
|
|
17
|
+
?f log:rawType ?tParsed .
|
|
18
|
+
|
|
19
|
+
<https://www.w3.org/2000/10/swap/test/s2.n3> log:semanticsOrError ?x .
|
|
20
|
+
?x log:rawType ?tRemote .
|
|
21
|
+
}
|
|
22
|
+
=>
|
|
23
|
+
{
|
|
24
|
+
:parsedFormula :is ?f .
|
|
25
|
+
:parsedType :is ?tParsed .
|
|
26
|
+
:remoteValue :is ?x .
|
|
27
|
+
:remoteType :is ?tRemote .
|
|
28
|
+
} .
|
|
29
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
@prefix : <http://example.org/> .
|
|
2
|
+
@prefix log: <http://www.w3.org/2000/10/swap/log#> .
|
|
3
|
+
|
|
4
|
+
:parsedFormula :is {
|
|
5
|
+
:s :p :o .
|
|
6
|
+
} .
|
|
7
|
+
:parsedType :is log:Formula .
|
|
8
|
+
:remoteValue :is "error(dereference_failed,https://www.w3.org/2000/10/swap/test/s2.n3)" .
|
|
9
|
+
:remoteType :is log:Literal .
|
package/examples/time.n3
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# =======================
|
|
2
|
+
# time: builtins examples
|
|
3
|
+
# =======================
|
|
4
|
+
|
|
5
|
+
@prefix : <http://example.org/> .
|
|
6
|
+
@prefix time: <http://www.w3.org/2000/10/swap/time#> .
|
|
7
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
8
|
+
|
|
9
|
+
:Let :dt "2023-04-01T18:06:04Z"^^xsd:dateTime .
|
|
10
|
+
|
|
11
|
+
{
|
|
12
|
+
:Let :dt ?d .
|
|
13
|
+
?d time:year ?y ;
|
|
14
|
+
time:month ?m ;
|
|
15
|
+
time:day ?day ;
|
|
16
|
+
time:minute ?min ;
|
|
17
|
+
time:second ?sec ;
|
|
18
|
+
time:timeZone ?tz .
|
|
19
|
+
}
|
|
20
|
+
=>
|
|
21
|
+
{
|
|
22
|
+
:out :year ?y ;
|
|
23
|
+
:month ?m ;
|
|
24
|
+
:day ?day ;
|
|
25
|
+
:minute ?min ;
|
|
26
|
+
:second ?sec ;
|
|
27
|
+
:tz ?tz .
|
|
28
|
+
} .
|
|
29
|
+
|
package/eyeling.js
CHANGED
|
@@ -89,14 +89,13 @@ const jsonPointerCache = new Map();
|
|
|
89
89
|
// Key is the dereferenced document IRI *without* fragment.
|
|
90
90
|
const __logContentCache = new Map(); // iri -> string | null (null means fetch/read failed)
|
|
91
91
|
const __logSemanticsCache = new Map(); // iri -> GraphTerm | null (null means parse failed)
|
|
92
|
+
const __logSemanticsOrErrorCache = new Map(); // iri -> Term (GraphTerm | Literal) for log:semanticsOrError
|
|
92
93
|
const __logConclusionCache = new WeakMap(); // GraphTerm -> GraphTerm (deductive closure)
|
|
93
94
|
|
|
94
95
|
// Environment detection (Node vs Browser/Worker).
|
|
95
96
|
// Eyeling is primarily synchronous, so we use sync XHR in browsers for log:content/log:semantics.
|
|
96
97
|
// Note: Browser fetches are subject to CORS; use CORS-enabled resources or a proxy.
|
|
97
|
-
const __IS_NODE =
|
|
98
|
-
typeof process !== 'undefined' &&
|
|
99
|
-
!!(process.versions && process.versions.node);
|
|
98
|
+
const __IS_NODE = typeof process !== 'undefined' && !!(process.versions && process.versions.node);
|
|
100
99
|
|
|
101
100
|
function __hasXmlHttpRequest() {
|
|
102
101
|
return typeof XMLHttpRequest !== 'undefined';
|
|
@@ -106,10 +105,7 @@ function __resolveBrowserUrl(ref) {
|
|
|
106
105
|
if (!ref) return ref;
|
|
107
106
|
// If already absolute, keep as-is.
|
|
108
107
|
if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(ref)) return ref;
|
|
109
|
-
const base =
|
|
110
|
-
(typeof document !== 'undefined' && document.baseURI) ||
|
|
111
|
-
(typeof location !== 'undefined' && location.href) ||
|
|
112
|
-
'';
|
|
108
|
+
const base = (typeof document !== 'undefined' && document.baseURI) || (typeof location !== 'undefined' && location.href) || '';
|
|
113
109
|
try {
|
|
114
110
|
return new URL(ref, base).toString();
|
|
115
111
|
} catch {
|
|
@@ -123,10 +119,7 @@ function __fetchHttpTextSyncBrowser(url) {
|
|
|
123
119
|
const xhr = new XMLHttpRequest();
|
|
124
120
|
xhr.open('GET', url, false); // synchronous
|
|
125
121
|
try {
|
|
126
|
-
xhr.setRequestHeader(
|
|
127
|
-
'Accept',
|
|
128
|
-
'text/n3, text/turtle, application/n-triples, application/n-quads, text/plain;q=0.1, */*;q=0.01'
|
|
129
|
-
);
|
|
122
|
+
xhr.setRequestHeader('Accept', 'text/n3, text/turtle, application/n-triples, application/n-quads, text/plain;q=0.1, */*;q=0.01');
|
|
130
123
|
} catch {
|
|
131
124
|
// Some environments restrict setting headers (ignore).
|
|
132
125
|
}
|
|
@@ -231,7 +224,7 @@ function __fetchHttpTextViaSubprocess(url) {
|
|
|
231
224
|
`;
|
|
232
225
|
const r = cp.spawnSync(process.execPath, ['-e', script, url], {
|
|
233
226
|
encoding: 'utf8',
|
|
234
|
-
maxBuffer: 32 * 1024 * 1024
|
|
227
|
+
maxBuffer: 32 * 1024 * 1024,
|
|
235
228
|
});
|
|
236
229
|
if (r.status !== 0) return null;
|
|
237
230
|
return r.stdout;
|
|
@@ -296,8 +289,8 @@ function __derefSemanticsSync(iriNoFrag) {
|
|
|
296
289
|
return null;
|
|
297
290
|
}
|
|
298
291
|
try {
|
|
299
|
-
const baseIri =
|
|
300
|
-
|
|
292
|
+
const baseIri = typeof key === 'string' && key ? key : iriNoFrag;
|
|
293
|
+
const formula = __parseSemanticsToFormula(text, baseIri);
|
|
301
294
|
__logSemanticsCache.set(key, formula);
|
|
302
295
|
return formula;
|
|
303
296
|
} catch {
|
|
@@ -386,8 +379,6 @@ function __computeConclusionFromFormula(formula) {
|
|
|
386
379
|
return out;
|
|
387
380
|
}
|
|
388
381
|
|
|
389
|
-
|
|
390
|
-
|
|
391
382
|
// Controls whether human-readable proof comments are printed.
|
|
392
383
|
let proofCommentsEnabled = false;
|
|
393
384
|
// Super restricted mode: disable *all* builtins except => / <= (log:implies / log:impliedBy)
|
|
@@ -2971,6 +2962,23 @@ function stripQuotes(lex) {
|
|
|
2971
2962
|
return lex;
|
|
2972
2963
|
}
|
|
2973
2964
|
|
|
2965
|
+
function termToJsXsdStringNoLang(t) {
|
|
2966
|
+
// Strict xsd:string extraction *without* language tags.
|
|
2967
|
+
// Accept:
|
|
2968
|
+
// - plain string literals ("...")
|
|
2969
|
+
// - "..."^^xsd:string
|
|
2970
|
+
// Reject:
|
|
2971
|
+
// - language-tagged strings ("..."@en)
|
|
2972
|
+
// - any other datatype
|
|
2973
|
+
if (!(t instanceof Literal)) return null;
|
|
2974
|
+
if (literalHasLangTag(t.value)) return null;
|
|
2975
|
+
|
|
2976
|
+
const [lex, dt] = literalParts(t.value);
|
|
2977
|
+
if (!isQuotedLexical(lex)) return null;
|
|
2978
|
+
if (dt !== null && dt !== XSD_NS + 'string' && dt !== 'xsd:string') return null;
|
|
2979
|
+
return decodeN3StringEscapes(stripQuotes(lex));
|
|
2980
|
+
}
|
|
2981
|
+
|
|
2974
2982
|
function termToJsString(t) {
|
|
2975
2983
|
// Strict string extraction for SWAP/N3 string builtins:
|
|
2976
2984
|
// - accept plain string literals ("...") and language-tagged ones ("..."@en)
|
|
@@ -3471,6 +3479,33 @@ function parseXsdDatetimeTerm(t) {
|
|
|
3471
3479
|
return d; // Date in local/UTC, we only use timestamp
|
|
3472
3480
|
}
|
|
3473
3481
|
|
|
3482
|
+
function parseXsdDateTimeLexParts(t) {
|
|
3483
|
+
// Parse *lexical* components of an xsd:dateTime literal without timezone normalization.
|
|
3484
|
+
// Returns { yearStr, month, day, minute, second, tz } or null.
|
|
3485
|
+
if (!(t instanceof Literal)) return null;
|
|
3486
|
+
const [lex, dt] = literalParts(t.value);
|
|
3487
|
+
if (dt !== XSD_NS + 'dateTime') return null;
|
|
3488
|
+
const val = stripQuotes(lex);
|
|
3489
|
+
|
|
3490
|
+
// xsd:dateTime lexical: YYYY-MM-DDThh:mm:ss(.s+)?(Z|(+|-)hh:mm)?
|
|
3491
|
+
const m = /^(-?\d{4,})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(Z|[+-]\d{2}:\d{2})?$/.exec(val);
|
|
3492
|
+
if (!m) return null;
|
|
3493
|
+
|
|
3494
|
+
const yearStr = m[1];
|
|
3495
|
+
const month = parseInt(m[2], 10);
|
|
3496
|
+
const day = parseInt(m[3], 10);
|
|
3497
|
+
const minute = parseInt(m[5], 10);
|
|
3498
|
+
const second = parseInt(m[6], 10);
|
|
3499
|
+
const tz = m[7] || null;
|
|
3500
|
+
|
|
3501
|
+
if (!(month >= 1 && month <= 12)) return null;
|
|
3502
|
+
if (!(day >= 1 && day <= 31)) return null;
|
|
3503
|
+
if (!(minute >= 0 && minute <= 59)) return null;
|
|
3504
|
+
if (!(second >= 0 && second <= 59)) return null;
|
|
3505
|
+
|
|
3506
|
+
return { yearStr, month, day, minute, second, tz };
|
|
3507
|
+
}
|
|
3508
|
+
|
|
3474
3509
|
function parseDatetimeLike(t) {
|
|
3475
3510
|
const d = parseXsdDateTerm(t);
|
|
3476
3511
|
if (d !== null) return d;
|
|
@@ -4561,6 +4596,162 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
4561
4596
|
// 4.3 time: builtins
|
|
4562
4597
|
// -----------------------------------------------------------------
|
|
4563
4598
|
|
|
4599
|
+
// time:day
|
|
4600
|
+
// Gets as object the integer day component of the subject xsd:dateTime.
|
|
4601
|
+
// Schema: $s+ time:day $o-
|
|
4602
|
+
if (pv === TIME_NS + 'day') {
|
|
4603
|
+
const parts = parseXsdDateTimeLexParts(g.s);
|
|
4604
|
+
if (!parts) return [];
|
|
4605
|
+
const out = internLiteral(String(parts.day));
|
|
4606
|
+
|
|
4607
|
+
if (g.o instanceof Var) {
|
|
4608
|
+
const s2 = { ...subst };
|
|
4609
|
+
s2[g.o.name] = out;
|
|
4610
|
+
return [s2];
|
|
4611
|
+
}
|
|
4612
|
+
if (g.o instanceof Blank) return [{ ...subst }];
|
|
4613
|
+
|
|
4614
|
+
const oi = parseIntLiteral(g.o);
|
|
4615
|
+
if (oi !== null) {
|
|
4616
|
+
try {
|
|
4617
|
+
if (oi === BigInt(parts.day)) return [{ ...subst }];
|
|
4618
|
+
} catch {}
|
|
4619
|
+
}
|
|
4620
|
+
|
|
4621
|
+
const s2 = unifyTerm(g.o, out, subst);
|
|
4622
|
+
return s2 !== null ? [s2] : [];
|
|
4623
|
+
}
|
|
4624
|
+
|
|
4625
|
+
// time:minute
|
|
4626
|
+
// Gets as object the integer minutes component of the subject xsd:dateTime.
|
|
4627
|
+
// Schema: $s+ time:minute $o-
|
|
4628
|
+
if (pv === TIME_NS + 'minute') {
|
|
4629
|
+
const parts = parseXsdDateTimeLexParts(g.s);
|
|
4630
|
+
if (!parts) return [];
|
|
4631
|
+
const out = internLiteral(String(parts.minute));
|
|
4632
|
+
|
|
4633
|
+
if (g.o instanceof Var) {
|
|
4634
|
+
const s2 = { ...subst };
|
|
4635
|
+
s2[g.o.name] = out;
|
|
4636
|
+
return [s2];
|
|
4637
|
+
}
|
|
4638
|
+
if (g.o instanceof Blank) return [{ ...subst }];
|
|
4639
|
+
|
|
4640
|
+
const oi = parseIntLiteral(g.o);
|
|
4641
|
+
if (oi !== null) {
|
|
4642
|
+
try {
|
|
4643
|
+
if (oi === BigInt(parts.minute)) return [{ ...subst }];
|
|
4644
|
+
} catch {}
|
|
4645
|
+
}
|
|
4646
|
+
|
|
4647
|
+
const s2 = unifyTerm(g.o, out, subst);
|
|
4648
|
+
return s2 !== null ? [s2] : [];
|
|
4649
|
+
}
|
|
4650
|
+
|
|
4651
|
+
// time:month
|
|
4652
|
+
// Gets as object the integer month component of the subject xsd:dateTime.
|
|
4653
|
+
// Schema: $s+ time:month $o-
|
|
4654
|
+
if (pv === TIME_NS + 'month') {
|
|
4655
|
+
const parts = parseXsdDateTimeLexParts(g.s);
|
|
4656
|
+
if (!parts) return [];
|
|
4657
|
+
const out = internLiteral(String(parts.month));
|
|
4658
|
+
|
|
4659
|
+
if (g.o instanceof Var) {
|
|
4660
|
+
const s2 = { ...subst };
|
|
4661
|
+
s2[g.o.name] = out;
|
|
4662
|
+
return [s2];
|
|
4663
|
+
}
|
|
4664
|
+
if (g.o instanceof Blank) return [{ ...subst }];
|
|
4665
|
+
|
|
4666
|
+
const oi = parseIntLiteral(g.o);
|
|
4667
|
+
if (oi !== null) {
|
|
4668
|
+
try {
|
|
4669
|
+
if (oi === BigInt(parts.month)) return [{ ...subst }];
|
|
4670
|
+
} catch {}
|
|
4671
|
+
}
|
|
4672
|
+
|
|
4673
|
+
const s2 = unifyTerm(g.o, out, subst);
|
|
4674
|
+
return s2 !== null ? [s2] : [];
|
|
4675
|
+
}
|
|
4676
|
+
|
|
4677
|
+
// time:second
|
|
4678
|
+
// Gets as object the integer seconds component of the subject xsd:dateTime.
|
|
4679
|
+
// Schema: $s+ time:second $o-
|
|
4680
|
+
if (pv === TIME_NS + 'second') {
|
|
4681
|
+
const parts = parseXsdDateTimeLexParts(g.s);
|
|
4682
|
+
if (!parts) return [];
|
|
4683
|
+
const out = internLiteral(String(parts.second));
|
|
4684
|
+
|
|
4685
|
+
if (g.o instanceof Var) {
|
|
4686
|
+
const s2 = { ...subst };
|
|
4687
|
+
s2[g.o.name] = out;
|
|
4688
|
+
return [s2];
|
|
4689
|
+
}
|
|
4690
|
+
if (g.o instanceof Blank) return [{ ...subst }];
|
|
4691
|
+
|
|
4692
|
+
const oi = parseIntLiteral(g.o);
|
|
4693
|
+
if (oi !== null) {
|
|
4694
|
+
try {
|
|
4695
|
+
if (oi === BigInt(parts.second)) return [{ ...subst }];
|
|
4696
|
+
} catch {}
|
|
4697
|
+
}
|
|
4698
|
+
|
|
4699
|
+
const s2 = unifyTerm(g.o, out, subst);
|
|
4700
|
+
return s2 !== null ? [s2] : [];
|
|
4701
|
+
}
|
|
4702
|
+
|
|
4703
|
+
// time:timeZone
|
|
4704
|
+
// Gets as object the trailing timezone offset of the subject xsd:dateTime (e.g., "-05:00" or "Z").
|
|
4705
|
+
// Schema: $s+ time:timeZone $o-
|
|
4706
|
+
if (pv === TIME_NS + 'timeZone') {
|
|
4707
|
+
const parts = parseXsdDateTimeLexParts(g.s);
|
|
4708
|
+
if (!parts) return [];
|
|
4709
|
+
if (parts.tz === null) return [];
|
|
4710
|
+
const out = internLiteral(`"${parts.tz}"`);
|
|
4711
|
+
|
|
4712
|
+
if (g.o instanceof Var) {
|
|
4713
|
+
const s2 = { ...subst };
|
|
4714
|
+
s2[g.o.name] = out;
|
|
4715
|
+
return [s2];
|
|
4716
|
+
}
|
|
4717
|
+
if (g.o instanceof Blank) return [{ ...subst }];
|
|
4718
|
+
|
|
4719
|
+
if (termsEqual(g.o, out)) return [{ ...subst }];
|
|
4720
|
+
|
|
4721
|
+
// Also accept explicitly typed xsd:string literals.
|
|
4722
|
+
if (g.o instanceof Literal) {
|
|
4723
|
+
const [lexO, dtO] = literalParts(g.o.value);
|
|
4724
|
+
if (dtO === XSD_NS + 'string' && stripQuotes(lexO) === parts.tz) return [{ ...subst }];
|
|
4725
|
+
}
|
|
4726
|
+
return [];
|
|
4727
|
+
}
|
|
4728
|
+
|
|
4729
|
+
// time:year
|
|
4730
|
+
// Gets as object the integer year component of the subject xsd:dateTime.
|
|
4731
|
+
// Schema: $s+ time:year $o-
|
|
4732
|
+
if (pv === TIME_NS + 'year') {
|
|
4733
|
+
const parts = parseXsdDateTimeLexParts(g.s);
|
|
4734
|
+
if (!parts) return [];
|
|
4735
|
+
const out = internLiteral(String(parts.yearStr));
|
|
4736
|
+
|
|
4737
|
+
if (g.o instanceof Var) {
|
|
4738
|
+
const s2 = { ...subst };
|
|
4739
|
+
s2[g.o.name] = out;
|
|
4740
|
+
return [s2];
|
|
4741
|
+
}
|
|
4742
|
+
if (g.o instanceof Blank) return [{ ...subst }];
|
|
4743
|
+
|
|
4744
|
+
const oi = parseIntLiteral(g.o);
|
|
4745
|
+
if (oi !== null) {
|
|
4746
|
+
try {
|
|
4747
|
+
if (oi === BigInt(parts.yearStr)) return [{ ...subst }];
|
|
4748
|
+
} catch {}
|
|
4749
|
+
}
|
|
4750
|
+
|
|
4751
|
+
const s2 = unifyTerm(g.o, out, subst);
|
|
4752
|
+
return s2 !== null ? [s2] : [];
|
|
4753
|
+
}
|
|
4754
|
+
|
|
4564
4755
|
// time:localTime
|
|
4565
4756
|
// "" time:localTime ?D. binds ?D to “now” as xsd:dateTime.
|
|
4566
4757
|
if (pv === TIME_NS + 'localTime') {
|
|
@@ -5003,30 +5194,29 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
|
|
|
5003
5194
|
return s2 !== null ? [s2] : [];
|
|
5004
5195
|
}
|
|
5005
5196
|
|
|
5197
|
+
// log:conclusion
|
|
5198
|
+
// Schema: $s+ log:conclusion $o?
|
|
5199
|
+
// $o is the deductive closure of the subject formula $s (including rule inferences).
|
|
5200
|
+
if (pv === LOG_NS + 'conclusion') {
|
|
5201
|
+
// Accept 'true' as the empty formula.
|
|
5202
|
+
let inFormula = null;
|
|
5203
|
+
if (g.s instanceof GraphTerm) inFormula = g.s;
|
|
5204
|
+
else if (g.s instanceof Literal && g.s.value === 'true') inFormula = new GraphTerm([]);
|
|
5205
|
+
else return [];
|
|
5006
5206
|
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
// $o is the deductive closure of the subject formula $s (including rule inferences).
|
|
5010
|
-
if (pv === LOG_NS + 'conclusion') {
|
|
5011
|
-
// Accept 'true' as the empty formula.
|
|
5012
|
-
let inFormula = null;
|
|
5013
|
-
if (g.s instanceof GraphTerm) inFormula = g.s;
|
|
5014
|
-
else if (g.s instanceof Literal && g.s.value === 'true') inFormula = new GraphTerm([]);
|
|
5015
|
-
else return [];
|
|
5207
|
+
const conclusion = __computeConclusionFromFormula(inFormula);
|
|
5208
|
+
if (!(conclusion instanceof GraphTerm)) return [];
|
|
5016
5209
|
|
|
5017
|
-
|
|
5018
|
-
|
|
5210
|
+
if (g.o instanceof Var) {
|
|
5211
|
+
const s2 = { ...subst };
|
|
5212
|
+
s2[g.o.name] = conclusion;
|
|
5213
|
+
return [s2];
|
|
5214
|
+
}
|
|
5215
|
+
if (g.o instanceof Blank) return [{ ...subst }];
|
|
5019
5216
|
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
s2[g.o.name] = conclusion;
|
|
5023
|
-
return [s2];
|
|
5217
|
+
const s2 = unifyTerm(g.o, conclusion, subst);
|
|
5218
|
+
return s2 !== null ? [s2] : [];
|
|
5024
5219
|
}
|
|
5025
|
-
if (g.o instanceof Blank) return [{ ...subst }];
|
|
5026
|
-
|
|
5027
|
-
const s2 = unifyTerm(g.o, conclusion, subst);
|
|
5028
|
-
return s2 !== null ? [s2] : [];
|
|
5029
|
-
}
|
|
5030
5220
|
|
|
5031
5221
|
// log:content
|
|
5032
5222
|
// Schema: $s+ log:content $o?
|
|
@@ -5074,6 +5264,108 @@ if (pv === LOG_NS + 'conclusion') {
|
|
|
5074
5264
|
return s2 !== null ? [s2] : [];
|
|
5075
5265
|
}
|
|
5076
5266
|
|
|
5267
|
+
// log:semanticsOrError
|
|
5268
|
+
// Schema: $s+ log:semanticsOrError $o?
|
|
5269
|
+
// Like log:semantics, but yields an xsd:string error message on failure.
|
|
5270
|
+
if (pv === LOG_NS + 'semanticsOrError') {
|
|
5271
|
+
const iri = iriValue(g.s);
|
|
5272
|
+
if (iri === null) return [];
|
|
5273
|
+
|
|
5274
|
+
const docIri = __stripFragment(iri);
|
|
5275
|
+
const norm = __normalizeDerefIri(docIri);
|
|
5276
|
+
const key = typeof norm === 'string' && norm ? norm : docIri;
|
|
5277
|
+
|
|
5278
|
+
let term = null;
|
|
5279
|
+
|
|
5280
|
+
if (__logSemanticsOrErrorCache.has(key)) {
|
|
5281
|
+
term = __logSemanticsOrErrorCache.get(key);
|
|
5282
|
+
} else {
|
|
5283
|
+
// If we already successfully computed log:semantics, reuse it.
|
|
5284
|
+
const formula = __derefSemanticsSync(docIri);
|
|
5285
|
+
|
|
5286
|
+
if (formula instanceof GraphTerm) {
|
|
5287
|
+
term = formula;
|
|
5288
|
+
} else {
|
|
5289
|
+
// Try to get an informative error.
|
|
5290
|
+
const txt = __derefTextSync(docIri);
|
|
5291
|
+
if (typeof txt !== 'string') {
|
|
5292
|
+
term = makeStringLiteral(`error(dereference_failed,${docIri})`);
|
|
5293
|
+
} else {
|
|
5294
|
+
try {
|
|
5295
|
+
const baseIri = typeof key === 'string' && key ? key : docIri;
|
|
5296
|
+
term = __parseSemanticsToFormula(txt, baseIri);
|
|
5297
|
+
// Keep the semantics cache consistent.
|
|
5298
|
+
__logSemanticsCache.set(key, term);
|
|
5299
|
+
} catch (e) {
|
|
5300
|
+
const msg = e && e.message ? e.message : String(e);
|
|
5301
|
+
term = makeStringLiteral(`error(parse_error,${msg})`);
|
|
5302
|
+
}
|
|
5303
|
+
}
|
|
5304
|
+
}
|
|
5305
|
+
|
|
5306
|
+
__logSemanticsOrErrorCache.set(key, term);
|
|
5307
|
+
}
|
|
5308
|
+
|
|
5309
|
+
if (g.o instanceof Var) {
|
|
5310
|
+
const s2 = { ...subst };
|
|
5311
|
+
s2[g.o.name] = term;
|
|
5312
|
+
return [s2];
|
|
5313
|
+
}
|
|
5314
|
+
if (g.o instanceof Blank) return [{ ...subst }];
|
|
5315
|
+
|
|
5316
|
+
const s2 = unifyTerm(g.o, term, subst);
|
|
5317
|
+
return s2 !== null ? [s2] : [];
|
|
5318
|
+
}
|
|
5319
|
+
|
|
5320
|
+
// log:parsedAsN3
|
|
5321
|
+
// Schema: $s+ log:parsedAsN3 $o-
|
|
5322
|
+
// Parses the subject xsd:string as N3 and returns it as a formula.
|
|
5323
|
+
if (pv === LOG_NS + 'parsedAsN3') {
|
|
5324
|
+
const txt = termToJsXsdStringNoLang(g.s);
|
|
5325
|
+
if (txt === null) return [];
|
|
5326
|
+
|
|
5327
|
+
let formula;
|
|
5328
|
+
try {
|
|
5329
|
+
// No external base is specified in the builtin definition; the parsed
|
|
5330
|
+
// string may contain its own @base / @prefix directives.
|
|
5331
|
+
formula = __parseSemanticsToFormula(txt, '');
|
|
5332
|
+
} catch {
|
|
5333
|
+
return [];
|
|
5334
|
+
}
|
|
5335
|
+
|
|
5336
|
+
if (g.o instanceof Var) {
|
|
5337
|
+
const s2 = { ...subst };
|
|
5338
|
+
s2[g.o.name] = formula;
|
|
5339
|
+
return [s2];
|
|
5340
|
+
}
|
|
5341
|
+
if (g.o instanceof Blank) return [{ ...subst }];
|
|
5342
|
+
|
|
5343
|
+
const s2 = unifyTerm(g.o, formula, subst);
|
|
5344
|
+
return s2 !== null ? [s2] : [];
|
|
5345
|
+
}
|
|
5346
|
+
|
|
5347
|
+
// log:rawType
|
|
5348
|
+
// Schema: $s+ log:rawType $o-
|
|
5349
|
+
// Returns one of log:Formula, log:Literal, rdf:List, or log:Other.
|
|
5350
|
+
if (pv === LOG_NS + 'rawType') {
|
|
5351
|
+
if (g.s instanceof Var) return [];
|
|
5352
|
+
|
|
5353
|
+
let ty;
|
|
5354
|
+
if (g.s instanceof GraphTerm) ty = internIri(LOG_NS + 'Formula');
|
|
5355
|
+
else if (g.s instanceof Literal) ty = internIri(LOG_NS + 'Literal');
|
|
5356
|
+
else if (g.s instanceof ListTerm || g.s instanceof OpenListTerm) ty = internIri(RDF_NS + 'List');
|
|
5357
|
+
else ty = internIri(LOG_NS + 'Other');
|
|
5358
|
+
|
|
5359
|
+
if (g.o instanceof Var) {
|
|
5360
|
+
const s2 = { ...subst };
|
|
5361
|
+
s2[g.o.name] = ty;
|
|
5362
|
+
return [s2];
|
|
5363
|
+
}
|
|
5364
|
+
if (g.o instanceof Blank) return [{ ...subst }];
|
|
5365
|
+
|
|
5366
|
+
const s2 = unifyTerm(g.o, ty, subst);
|
|
5367
|
+
return s2 !== null ? [s2] : [];
|
|
5368
|
+
}
|
|
5077
5369
|
|
|
5078
5370
|
// log:dtlit
|
|
5079
5371
|
// Schema: ( $s.1? $s.2? )? log:dtlit $o?
|
|
@@ -5314,7 +5606,6 @@ if (pv === LOG_NS + 'conclusion') {
|
|
|
5314
5606
|
return [{ ...subst }];
|
|
5315
5607
|
}
|
|
5316
5608
|
|
|
5317
|
-
|
|
5318
5609
|
// log:collectAllIn (scoped)
|
|
5319
5610
|
if (pv === LOG_NS + 'collectAllIn') {
|
|
5320
5611
|
if (!(g.s instanceof ListTerm) || g.s.elems.length !== 3) return [];
|
|
@@ -6453,7 +6744,6 @@ function __collectOutputStringsFromFacts(facts, prefixes) {
|
|
|
6453
6744
|
return pairs.map((p) => p.text).join('');
|
|
6454
6745
|
}
|
|
6455
6746
|
|
|
6456
|
-
|
|
6457
6747
|
function main() {
|
|
6458
6748
|
// Drop "node" and script name; keep only user-provided args
|
|
6459
6749
|
const argv = process.argv.slice(2);
|