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 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 .
@@ -0,0 +1,8 @@
1
+ @prefix : <http://example.org/> .
2
+
3
+ :out :year 2023 .
4
+ :out :month 4 .
5
+ :out :day 1 .
6
+ :out :minute 6 .
7
+ :out :second 4 .
8
+ :out :tz "Z" .
@@ -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 = (typeof key === 'string' && key) ? key : iriNoFrag;
300
- const formula = __parseSemanticsToFormula(text, baseIri);
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
- // log:conclusion
5008
- // Schema: $s+ log:conclusion $o?
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
- const conclusion = __computeConclusionFromFormula(inFormula);
5018
- if (!(conclusion instanceof GraphTerm)) return [];
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
- if (g.o instanceof Var) {
5021
- const s2 = { ...subst };
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.7.8",
3
+ "version": "1.7.10",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [