eyeling 1.6.13 → 1.6.14

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.
Files changed (75) hide show
  1. package/examples/output/age.n3 +0 -17
  2. package/examples/output/alignment-demo.n3 +0 -572
  3. package/examples/output/backward.n3 +0 -15
  4. package/examples/output/basic-monadic.n3 +0 -105
  5. package/examples/output/brussels-brew-club.n3 +0 -476
  6. package/examples/output/cat-koko.n3 +0 -108
  7. package/examples/output/cobalt-kepler-kitchen.n3 +0 -7064
  8. package/examples/output/complex.n3 +0 -46
  9. package/examples/output/control-system.n3 +0 -75
  10. package/examples/output/cranberry-calculus.n3 +0 -1313
  11. package/examples/output/crypto-builtins-tests.n3 +0 -60
  12. package/examples/output/deep-taxonomy-10.n3 +0 -602
  13. package/examples/output/deep-taxonomy-100.n3 +1 -5733
  14. package/examples/output/deep-taxonomy-1000.n3 +1 -57033
  15. package/examples/output/deep-taxonomy-10000.n3 +1 -570033
  16. package/examples/output/derived-backward-rule-2.n3 +0 -58
  17. package/examples/output/derived-backward-rule.n3 +0 -44
  18. package/examples/output/derived-rule.n3 +0 -42
  19. package/examples/output/dijkstra.n3 +0 -297
  20. package/examples/output/dog.n3 +0 -30
  21. package/examples/output/drone-corridor-planner.n3 +0 -799
  22. package/examples/output/easter.n3 +0 -3570
  23. package/examples/output/equals.n3 +0 -15
  24. package/examples/output/ev-roundtrip-planner.n3 +0 -392
  25. package/examples/output/existential-rule.n3 +0 -34
  26. package/examples/output/expression-eval.n3 +0 -20
  27. package/examples/output/family-cousins.n3 +0 -636
  28. package/examples/output/fibonacci.n3 +0 -36
  29. package/examples/output/french-cities.n3 +0 -484
  30. package/examples/output/good-cobbler.n3 +0 -22
  31. package/examples/output/gps.n3 +0 -62
  32. package/examples/output/gray-code-counter.n3 +0 -17
  33. package/examples/output/hanoi.n3 +0 -17
  34. package/examples/output/jade-eigen-loom.n3 +0 -4690
  35. package/examples/output/json-pointer.n3 +0 -529
  36. package/examples/output/json-reconcile-vat.n3 +0 -12882
  37. package/examples/output/light-eaters.n3 +0 -311
  38. package/examples/output/list-builtins-tests.n3 +0 -167
  39. package/examples/output/list-iterate.n3 +0 -124
  40. package/examples/output/lldm.n3 +0 -960
  41. package/examples/output/log-collect-all-in.n3 +0 -117
  42. package/examples/output/log-for-all-in.n3 +0 -27
  43. package/examples/output/log-not-includes.n3 +0 -59
  44. package/examples/output/log-skolem.n3 +0 -17
  45. package/examples/output/log-uri.n3 +0 -42
  46. package/examples/output/math-builtins-tests.n3 +0 -4434
  47. package/examples/output/minimal-skos-alignment.n3 +0 -39
  48. package/examples/output/monkey.n3 +0 -36
  49. package/examples/output/odrl-trust.n3 +0 -46
  50. package/examples/output/oslo-steps-library-scholarly.n3 +0 -1260
  51. package/examples/output/oslo-steps-workflow-composition.n3 +0 -180
  52. package/examples/output/peano.n3 +0 -23
  53. package/examples/output/pi.n3 +0 -17
  54. package/examples/output/pillar.n3 +0 -32
  55. package/examples/output/polygon.n3 +0 -17
  56. package/examples/output/rdf-list.n3 +0 -28
  57. package/examples/output/reordering.n3 +0 -26
  58. package/examples/output/ruby-runge-workshop.n3 +0 -613
  59. package/examples/output/rule-matching.n3 +0 -26
  60. package/examples/output/saffron-slopeworks.n3 +0 -1447
  61. package/examples/output/self-referential.n3 +0 -81
  62. package/examples/output/similar.n3 +0 -15
  63. package/examples/output/snaf.n3 +0 -23
  64. package/examples/output/socrates.n3 +0 -21
  65. package/examples/output/spectral-week.n3 +0 -350
  66. package/examples/output/string-builtins-tests.n3 +0 -240
  67. package/examples/output/topaz-markov-mill.n3 +0 -4178
  68. package/examples/output/traffic-skos-aggregate.n3 +0 -3151
  69. package/examples/output/turing.n3 +0 -36
  70. package/examples/output/ultramarine-simpson-forge.n3 +0 -3873
  71. package/examples/output/witch.n3 +0 -107
  72. package/examples/output/zebra.n3 +0 -111
  73. package/eyeling.js +97 -18
  74. package/package.json +1 -1
  75. package/test/examples.test.js +1 -1
@@ -1,115 +1,8 @@
1
1
  @prefix : <https://eyereasoner.github.io/eye/reasoning/witch#> .
2
2
 
3
- # ----------------------------------------------------------------------
4
- # Proof for derived triple:
5
- # :DUCK a :ISMADEOFWOOD .
6
- # It holds because the following instance of the rule body is provable:
7
- # :DUCK a :FLOATS .
8
- # via the schematic forward rule:
9
- # {
10
- # ?x a :FLOATS .
11
- # } => {
12
- # ?x a :ISMADEOFWOOD .
13
- # } .
14
- # with substitution (on rule variables):
15
- # ?x = :DUCK
16
- # Therefore the derived triple above is entailed by the rules and facts.
17
- # ----------------------------------------------------------------------
18
-
19
3
  :DUCK a :ISMADEOFWOOD .
20
-
21
- # ----------------------------------------------------------------------
22
- # Proof for derived triple:
23
- # :GIRL a :FLOATS .
24
- # It holds because the following instance of the rule body is provable:
25
- # :DUCK a :FLOATS .
26
- # :DUCK :SAMEWEIGHT :GIRL .
27
- # via the schematic forward rule:
28
- # {
29
- # ?x a :FLOATS .
30
- # ?x :SAMEWEIGHT ?y .
31
- # } => {
32
- # ?y a :FLOATS .
33
- # } .
34
- # with substitution (on rule variables):
35
- # ?x = :DUCK
36
- # ?y = :GIRL
37
- # Therefore the derived triple above is entailed by the rules and facts.
38
- # ----------------------------------------------------------------------
39
-
40
4
  :GIRL a :FLOATS .
41
-
42
- # ----------------------------------------------------------------------
43
- # Proof for derived triple:
44
- # :DUCK a :BURNS .
45
- # It holds because the following instance of the rule body is provable:
46
- # :DUCK a :ISMADEOFWOOD .
47
- # via the schematic forward rule:
48
- # {
49
- # ?x a :ISMADEOFWOOD .
50
- # } => {
51
- # ?x a :BURNS .
52
- # } .
53
- # with substitution (on rule variables):
54
- # ?x = :DUCK
55
- # Therefore the derived triple above is entailed by the rules and facts.
56
- # ----------------------------------------------------------------------
57
-
58
5
  :DUCK a :BURNS .
59
-
60
- # ----------------------------------------------------------------------
61
- # Proof for derived triple:
62
- # :GIRL a :ISMADEOFWOOD .
63
- # It holds because the following instance of the rule body is provable:
64
- # :GIRL a :FLOATS .
65
- # via the schematic forward rule:
66
- # {
67
- # ?x a :FLOATS .
68
- # } => {
69
- # ?x a :ISMADEOFWOOD .
70
- # } .
71
- # with substitution (on rule variables):
72
- # ?x = :GIRL
73
- # Therefore the derived triple above is entailed by the rules and facts.
74
- # ----------------------------------------------------------------------
75
-
76
6
  :GIRL a :ISMADEOFWOOD .
77
-
78
- # ----------------------------------------------------------------------
79
- # Proof for derived triple:
80
- # :GIRL a :BURNS .
81
- # It holds because the following instance of the rule body is provable:
82
- # :GIRL a :ISMADEOFWOOD .
83
- # via the schematic forward rule:
84
- # {
85
- # ?x a :ISMADEOFWOOD .
86
- # } => {
87
- # ?x a :BURNS .
88
- # } .
89
- # with substitution (on rule variables):
90
- # ?x = :GIRL
91
- # Therefore the derived triple above is entailed by the rules and facts.
92
- # ----------------------------------------------------------------------
93
-
94
7
  :GIRL a :BURNS .
95
-
96
- # ----------------------------------------------------------------------
97
- # Proof for derived triple:
98
- # :GIRL a :WITCH .
99
- # It holds because the following instance of the rule body is provable:
100
- # :GIRL a :BURNS .
101
- # :GIRL a :WOMAN .
102
- # via the schematic forward rule:
103
- # {
104
- # ?x a :BURNS .
105
- # ?x a :WOMAN .
106
- # } => {
107
- # ?x a :WITCH .
108
- # } .
109
- # with substitution (on rule variables):
110
- # ?x = :GIRL
111
- # Therefore the derived triple above is entailed by the rules and facts.
112
- # ----------------------------------------------------------------------
113
-
114
8
  :GIRL a :WITCH .
115
-
@@ -1,114 +1,3 @@
1
1
  @prefix : <http://eulersharp.sourceforge.net/2005/11swap/zebra#> .
2
2
 
3
- # ----------------------------------------------------------------------
4
- # Proof for derived triple:
5
- # :german :eats :fish .
6
- # It holds because the following instance of the rule body is provable:
7
- # ((:yellow :norwegian :cats :water :dunhill) (:blue :dane :horse :tea :blends) (:red :brit :birds :milk :pallmall) (:green :german :fish :coffee :prince) (:white :swede :dogs :beer :bluemasters)) log:equalTo ((:yellow :norwegian :cats :water :dunhill) (:blue :dane :horse :tea :blends) (:red :brit :birds :milk :pallmall) (:green :german :fish :coffee :prince) (:white :swede :dogs :beer :bluemasters)) .
8
- # ((:yellow :norwegian :cats :water :dunhill) (:blue :dane :horse :tea :blends) (:red :brit :birds :milk :pallmall) (:green :german :fish :coffee :prince) (:white :swede :dogs :beer :bluemasters)) :pair ((:blue :dane :horse :tea :blends) (:yellow :norwegian :cats :water :dunhill)) .
9
- # ((:yellow :norwegian :cats :water :dunhill) (:blue :dane :horse :tea :blends) (:red :brit :birds :milk :pallmall) (:green :german :fish :coffee :prince) (:white :swede :dogs :beer :bluemasters)) :pair ((:blue :dane :horse :tea :blends) (:yellow :norwegian :cats :water :dunhill)) .
10
- # ((:yellow :norwegian :cats :water :dunhill) (:blue :dane :horse :tea :blends) (:red :brit :birds :milk :pallmall) (:green :german :fish :coffee :prince) (:white :swede :dogs :beer :bluemasters)) :sublist ((:green :german :fish :coffee :prince) (:white :swede :dogs :beer :bluemasters)) .
11
- # ((:yellow :norwegian :cats :water :dunhill) (:blue :dane :horse :tea :blends) (:red :brit :birds :milk :pallmall) (:green :german :fish :coffee :prince) (:white :swede :dogs :beer :bluemasters)) :pair ((:blue :dane :horse :tea :blends) (:yellow :norwegian :cats :water :dunhill)) .
12
- # ((:yellow :norwegian :cats :water :dunhill) (:blue :dane :horse :tea :blends) (:red :brit :birds :milk :pallmall) (:green :german :fish :coffee :prince) (:white :swede :dogs :beer :bluemasters)) list:member (:red :brit :birds :milk :pallmall) .
13
- # ((:yellow :norwegian :cats :water :dunhill) (:blue :dane :horse :tea :blends) (:red :brit :birds :milk :pallmall) (:green :german :fish :coffee :prince) (:white :swede :dogs :beer :bluemasters)) list:member (:white :swede :dogs :beer :bluemasters) .
14
- # ((:yellow :norwegian :cats :water :dunhill) (:blue :dane :horse :tea :blends) (:red :brit :birds :milk :pallmall) (:green :german :fish :coffee :prince) (:white :swede :dogs :beer :bluemasters)) list:member (:blue :dane :horse :tea :blends) .
15
- # ((:yellow :norwegian :cats :water :dunhill) (:blue :dane :horse :tea :blends) (:red :brit :birds :milk :pallmall) (:green :german :fish :coffee :prince) (:white :swede :dogs :beer :bluemasters)) list:member (:red :brit :birds :milk :pallmall) .
16
- # ((:yellow :norwegian :cats :water :dunhill) (:blue :dane :horse :tea :blends) (:red :brit :birds :milk :pallmall) (:green :german :fish :coffee :prince) (:white :swede :dogs :beer :bluemasters)) list:member (:yellow :norwegian :cats :water :dunhill) .
17
- # ((:yellow :norwegian :cats :water :dunhill) (:blue :dane :horse :tea :blends) (:red :brit :birds :milk :pallmall) (:green :german :fish :coffee :prince) (:white :swede :dogs :beer :bluemasters)) list:member (:white :swede :dogs :beer :bluemasters) .
18
- # ((:yellow :norwegian :cats :water :dunhill) (:blue :dane :horse :tea :blends) (:red :brit :birds :milk :pallmall) (:green :german :fish :coffee :prince) (:white :swede :dogs :beer :bluemasters)) list:member (:green :german :fish :coffee :prince) .
19
- # ((:yellow :norwegian :cats :water :dunhill) (:blue :dane :horse :tea :blends) (:red :brit :birds :milk :pallmall) (:green :german :fish :coffee :prince) (:white :swede :dogs :beer :bluemasters)) list:member (:green :german :fish :coffee :prince) .
20
- # via the schematic forward rule:
21
- # {
22
- # ?L log:equalTo ((?A1 :norwegian ?A2 ?A3 ?A4) (:blue ?A5 ?A6 ?A7 ?A8) (?A9 ?A10 ?A11 :milk ?A12) ?A13 ?A14) .
23
- # ?L :pair ((?A15 ?A16 ?A17 ?A18 :blends) (?A19 ?A20 :cats ?A21 ?A22)) .
24
- # ?L :pair ((?A23 ?A24 :horse ?A25 ?A26) (?A27 ?A28 ?A29 ?A30 :dunhill)) .
25
- # ?L :sublist ((:green ?A31 ?A32 :coffee ?A33) (:white ?A34 ?A35 ?A36 ?A37)) .
26
- # ?L :pair ((?A38 ?A39 ?A40 ?A41 :blends) (?A42 ?A43 ?A44 :water ?A45)) .
27
- # ?L list:member (:red :brit ?A46 ?A47 ?A48) .
28
- # ?L list:member (?A49 :swede :dogs ?A50 ?A51) .
29
- # ?L list:member (?A52 :dane ?A53 :tea ?A54) .
30
- # ?L list:member (?A55 ?A56 :birds ?A57 :pallmall) .
31
- # ?L list:member (:yellow ?A58 ?A59 ?A60 :dunhill) .
32
- # ?L list:member (?A61 ?A62 ?A63 :beer :bluemasters) .
33
- # ?L list:member (?A64 :german ?A65 ?A66 :prince) .
34
- # ?L list:member (?A67 ?B :fish ?A69 ?A70) .
35
- # } => {
36
- # ?B :eats :fish .
37
- # } .
38
- # with substitution (on rule variables):
39
- # ?A1 = :yellow
40
- # ?A10 = :brit
41
- # ?A11 = :birds
42
- # ?A12 = :pallmall
43
- # ?A13 = (:green :german :fish :coffee :prince)
44
- # ?A14 = (:white :swede :dogs :beer :bluemasters)
45
- # ?A15 = :blue
46
- # ?A16 = :dane
47
- # ?A17 = :horse
48
- # ?A18 = :tea
49
- # ?A19 = :yellow
50
- # ?A2 = :cats
51
- # ?A20 = :norwegian
52
- # ?A21 = :water
53
- # ?A22 = :dunhill
54
- # ?A23 = :blue
55
- # ?A24 = :dane
56
- # ?A25 = :tea
57
- # ?A26 = :blends
58
- # ?A27 = :yellow
59
- # ?A28 = :norwegian
60
- # ?A29 = :cats
61
- # ?A3 = :water
62
- # ?A30 = :water
63
- # ?A31 = :german
64
- # ?A32 = :fish
65
- # ?A33 = :prince
66
- # ?A34 = :swede
67
- # ?A35 = :dogs
68
- # ?A36 = :beer
69
- # ?A37 = :bluemasters
70
- # ?A38 = :blue
71
- # ?A39 = :dane
72
- # ?A4 = :dunhill
73
- # ?A40 = :horse
74
- # ?A41 = :tea
75
- # ?A42 = :yellow
76
- # ?A43 = :norwegian
77
- # ?A44 = :cats
78
- # ?A45 = :dunhill
79
- # ?A46 = :birds
80
- # ?A47 = :milk
81
- # ?A48 = :pallmall
82
- # ?A49 = :white
83
- # ?A5 = :dane
84
- # ?A50 = :beer
85
- # ?A51 = :bluemasters
86
- # ?A52 = :blue
87
- # ?A53 = :horse
88
- # ?A54 = :blends
89
- # ?A55 = :red
90
- # ?A56 = :brit
91
- # ?A57 = :milk
92
- # ?A58 = :norwegian
93
- # ?A59 = :cats
94
- # ?A6 = :horse
95
- # ?A60 = :water
96
- # ?A61 = :white
97
- # ?A62 = :swede
98
- # ?A63 = :dogs
99
- # ?A64 = :green
100
- # ?A65 = :fish
101
- # ?A66 = :coffee
102
- # ?A67 = :green
103
- # ?A69 = :coffee
104
- # ?A7 = :tea
105
- # ?A70 = :prince
106
- # ?A8 = :blends
107
- # ?A9 = :red
108
- # ?B = :german
109
- # ?L = ((:yellow :norwegian :cats :water :dunhill) (:blue :dane :horse :tea :blends) (:red :brit :birds :milk :pallmall) (:green :german :fish :coffee :prince) (:white :swede :dogs :beer :bluemasters))
110
- # Therefore the derived triple above is entailed by the rules and facts.
111
- # ----------------------------------------------------------------------
112
-
113
3
  :german :eats :fish .
114
-
package/eyeling.js CHANGED
@@ -39,7 +39,11 @@ const RDF_JSON_DT = RDF_NS + 'JSON';
39
39
  function resolveIriRef(ref, base) {
40
40
  if (!base) return ref;
41
41
  if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(ref)) return ref; // already absolute
42
- try { return new URL(ref, base).toString(); } catch { return ref; }
42
+ try {
43
+ return new URL(ref, base).toString();
44
+ } catch {
45
+ return ref;
46
+ }
43
47
  }
44
48
 
45
49
  function isRdfJsonDatatype(dt) {
@@ -271,14 +275,30 @@ function decodeN3StringEscapes(s) {
271
275
  }
272
276
  const e = s[++i];
273
277
  switch (e) {
274
- case 't': out += '\t'; break;
275
- case 'n': out += '\n'; break;
276
- case 'r': out += '\r'; break;
277
- case 'b': out += '\b'; break;
278
- case 'f': out += '\f'; break;
279
- case '"': out += '"'; break;
280
- case "'": out += "'"; break;
281
- case '\\': out += '\\'; break;
278
+ case 't':
279
+ out += '\t';
280
+ break;
281
+ case 'n':
282
+ out += '\n';
283
+ break;
284
+ case 'r':
285
+ out += '\r';
286
+ break;
287
+ case 'b':
288
+ out += '\b';
289
+ break;
290
+ case 'f':
291
+ out += '\f';
292
+ break;
293
+ case '"':
294
+ out += '"';
295
+ break;
296
+ case "'":
297
+ out += "'";
298
+ break;
299
+ case '\\':
300
+ out += '\\';
301
+ break;
282
302
 
283
303
  case 'u': {
284
304
  const hex = s.slice(i + 1, i + 5);
@@ -295,7 +315,7 @@ function decodeN3StringEscapes(s) {
295
315
  const hex = s.slice(i + 1, i + 9);
296
316
  if (/^[0-9A-Fa-f]{8}$/.test(hex)) {
297
317
  const cp = parseInt(hex, 16);
298
- if (cp >= 0 && cp <= 0x10FFFF) out += String.fromCodePoint(cp);
318
+ if (cp >= 0 && cp <= 0x10ffff) out += String.fromCodePoint(cp);
299
319
  else out += '\\U' + hex;
300
320
  i += 8;
301
321
  } else {
@@ -2343,9 +2363,14 @@ function stripQuotes(lex) {
2343
2363
  }
2344
2364
 
2345
2365
  function termToJsString(t) {
2346
- // Accept any Literal and interpret its lexical form as a JS string.
2366
+ // Strict string extraction for SWAP/N3 string builtins:
2367
+ // - accept plain string literals ("...") and language-tagged ones ("..."@en)
2368
+ // - accept "..."^^xsd:string
2369
+ // - reject any other datatype (e.g., "x"^^xsd:integer, "x"^^xsd:foobar)
2347
2370
  if (!(t instanceof Literal)) return null;
2348
- const [lex, _dt] = literalParts(t.value);
2371
+ const [lex, dt] = literalParts(t.value);
2372
+ if (!isQuotedLexical(lex)) return null;
2373
+ if (dt !== null && dt !== XSD_NS + 'string' && dt !== 'xsd:string') return null;
2349
2374
  return stripQuotes(lex);
2350
2375
  }
2351
2376
 
@@ -4198,13 +4223,11 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
4198
4223
  const [sLex, sDt0] = literalParts(a.value);
4199
4224
 
4200
4225
  // $s.1 must be xsd:string (plain or ^^xsd:string), not language-tagged.
4201
- const okString =
4202
- (sDt0 === null && isPlainStringLiteralValue(a.value)) || sDt0 === XSD_NS + 'string';
4226
+ const okString = (sDt0 === null && isPlainStringLiteralValue(a.value)) || sDt0 === XSD_NS + 'string';
4203
4227
  if (okString) {
4204
4228
  const dtIri = b.value;
4205
4229
  // For xsd:string, prefer the plain string literal form.
4206
- const outLit =
4207
- dtIri === XSD_NS + 'string' ? new Literal(sLex) : new Literal(`${sLex}^^<${dtIri}>`);
4230
+ const outLit = dtIri === XSD_NS + 'string' ? new Literal(sLex) : new Literal(`${sLex}^^<${dtIri}>`);
4208
4231
  const s2 = unifyTerm(goal.o, outLit, subst);
4209
4232
  if (s2 !== null) results.push(s2);
4210
4233
  }
@@ -4214,6 +4237,62 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
4214
4237
  return results;
4215
4238
  }
4216
4239
 
4240
+ // log:langlit
4241
+ // Schema: ( $s.1? $s.2? )? log:langlit $o?
4242
+ // true iff $o is a language-tagged literal with string value $s.1 and language tag $s.2
4243
+ if (g.p instanceof Iri && g.p.value === LOG_NS + 'langlit') {
4244
+ // Fully unbound (both arguments '?'-mode): treat as satisfiable, succeed once.
4245
+ if (g.s instanceof Var && g.o instanceof Var) return [{ ...subst }];
4246
+ const results = [];
4247
+ const LANG_RE = /^[A-Za-z]+(?:-[A-Za-z0-9]+)*$/; // (same notion as literalParts/literalHasLangTag)
4248
+
4249
+ function extractLangTag(litVal) {
4250
+ if (typeof litVal !== 'string') return null;
4251
+ if (!literalHasLangTag(litVal)) return null;
4252
+ const lastQuote = litVal.lastIndexOf('"');
4253
+ if (lastQuote < 0) return null;
4254
+ const after = lastQuote + 1;
4255
+ if (after >= litVal.length || litVal[after] !== '@') return null;
4256
+ const tag = litVal.slice(after + 1);
4257
+ if (!LANG_RE.test(tag)) return null;
4258
+ return tag;
4259
+ }
4260
+
4261
+ // Direction 1: object language-tagged literal -> subject list (string, langtag)
4262
+ if (g.o instanceof Literal) {
4263
+ const tag = extractLangTag(g.o.value);
4264
+ if (tag !== null) {
4265
+ const [oLex] = literalParts(g.o.value); // strips @lang into lexical part
4266
+ const strLit = isQuotedLexical(oLex) ? new Literal(oLex) : makeStringLiteral(String(oLex));
4267
+ const langLit = makeStringLiteral(tag);
4268
+ const subjList = new ListTerm([strLit, langLit]);
4269
+ const s2 = unifyTerm(goal.s, subjList, subst);
4270
+ if (s2 !== null) results.push(s2);
4271
+ }
4272
+ }
4273
+
4274
+ // Direction 2: subject list -> object language-tagged literal
4275
+ if (g.s instanceof ListTerm && g.s.elems.length === 2) {
4276
+ const a = g.s.elems[0]; // string
4277
+ const b = g.s.elems[1]; // lang tag string
4278
+ if (a instanceof Literal && b instanceof Literal) {
4279
+ const [sLex, sDt0] = literalParts(a.value);
4280
+ const okString = (sDt0 === null && isPlainStringLiteralValue(a.value)) || sDt0 === XSD_NS + 'string';
4281
+ const [langLex, langDt0] = literalParts(b.value);
4282
+ const okLang = (langDt0 === null && isPlainStringLiteralValue(b.value)) || langDt0 === XSD_NS + 'string';
4283
+ if (okString && okLang) {
4284
+ const tag = stripQuotes(langLex);
4285
+ if (LANG_RE.test(tag)) {
4286
+ const outLit = new Literal(`${sLex}@${tag}`);
4287
+ const s2 = unifyTerm(goal.o, outLit, subst);
4288
+ if (s2 !== null) results.push(s2);
4289
+ }
4290
+ }
4291
+ }
4292
+ }
4293
+ return results;
4294
+ }
4295
+
4217
4296
  // log:implies — expose internal forward rules as data
4218
4297
  if (g.p instanceof Iri && g.p.value === LOG_NS + 'implies') {
4219
4298
  const allFw = backRules.__allForwardRules || [];
@@ -4390,8 +4469,8 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
4390
4469
  return s2 !== null ? [s2] : [];
4391
4470
  }
4392
4471
 
4393
- const sOk = (g.s instanceof Var) || (g.s instanceof Blank) || (g.s instanceof Iri);
4394
- const oOk = (g.o instanceof Var) || (g.o instanceof Blank) || (g.o instanceof Literal);
4472
+ const sOk = g.s instanceof Var || g.s instanceof Blank || g.s instanceof Iri;
4473
+ const oOk = g.o instanceof Var || g.o instanceof Blank || g.o instanceof Literal;
4395
4474
  if (!sOk || !oOk) return [];
4396
4475
  return [{ ...subst }];
4397
4476
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.6.13",
3
+ "version": "1.6.14",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [
@@ -172,7 +172,7 @@ function main() {
172
172
  // Run eyeling on this file (cwd examplesDir so relative behavior matches old script)
173
173
  const outFd = fs.openSync(generatedPath, 'w');
174
174
 
175
- const r = cp.spawnSync(nodePath, [eyelingJsPath, file], {
175
+ const r = cp.spawnSync(nodePath, [eyelingJsPath, '-n', file], {
176
176
  cwd: examplesDir,
177
177
  stdio: ['ignore', outFd, 'pipe'], // stdout -> file, stderr captured
178
178
  maxBuffer: 200 * 1024 * 1024,