eyeling 1.5.21 → 1.5.23

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
@@ -199,7 +199,6 @@ Supported:
199
199
  Non-goals / current limits:
200
200
 
201
201
  - not a full W3C N3 grammar (some edge cases for identifiers, quantifiers, advanced syntax)
202
- - quoted formulas are matched as whole formulas (no pattern matching inside formulas yet)
203
202
  - proof output is local per derived triple (not a global exported proof tree)
204
203
 
205
204
  ## Blank nodes and quantification (pragmatic N3/EYE-style)
@@ -243,7 +242,7 @@ As soon as the premise is provable, `eyeling` exits with status code `2`.
243
242
  `eyeling` implements a pragmatic subset of common N3 builtin families and evaluates them during backward goal proving:
244
243
 
245
244
  - **crypto**: `crypto:md5` `crypto:sha` `crypto:sha256` `crypto:sha512`
246
- - **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:reverse` `list:sort`
245
+ - **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`
247
246
  - **log**: `log:collectAllIn` `log:equalTo` `log:forAllIn` `log:impliedBy` `log:implies` `log:notEqualTo` `log:notIncludes` `log:skolem` `log:uri`
248
247
  - **math**: `math:absoluteValue` `math:acos` `math:asin` `math:atan` `math:cos` `math:cosh` `math:degrees` `math:difference` `math:equalTo` `math:exponentiation` `math:greaterThan` `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`
249
248
  - **string**: `string:concatenation` `string:contains` `string:containsIgnoringCase` `string:endsWith` `string:equalIgnoringCase` `string:format` `string:greaterThan` `string:lessThan` `string:matches` `string:notEqualIgnoringCase` `string:notGreaterThan` `string:notLessThan` `string:notMatches` `string:replace` `string:scrape` `string:startsWith`
@@ -13,7 +13,6 @@
13
13
  # -----------------------------
14
14
  # Data: (2 * 3) + (10 - 4) = 12
15
15
  # -----------------------------
16
-
17
16
  :n2 :n 2.
18
17
  :n3 :n 3.
19
18
  :n10 :n 10.
@@ -28,7 +27,6 @@
28
27
  # ----------------------
29
28
  # Backward rules: :value
30
29
  # ----------------------
31
-
32
30
  # Base case: numeric node
33
31
  { ?N :value ?V. } <= { ?N :n ?V. }.
34
32
 
@@ -65,6 +63,5 @@
65
63
  # ------------------------------
66
64
  # Forward rule: emit final value
67
65
  # ------------------------------
68
-
69
66
  { :Root :expr ?E. ?E :value ?V. } => { :Root :result ?V. }.
70
67
 
@@ -8,7 +8,6 @@
8
8
  # --------------------------
9
9
  # Data (a small family tree)
10
10
  # --------------------------
11
-
12
11
  :Adam :parentOf :Bob, :Carol .
13
12
  :Bob :parentOf :Dave, :Eve .
14
13
  :Carol :parentOf :Frank, :Grace .
@@ -29,7 +28,6 @@
29
28
  # -----------------------------------
30
29
  # Rules (generation, branch, cousins)
31
30
  # -----------------------------------
32
-
33
31
  # Root generation
34
32
  { } => { :Adam :generation 0 } .
35
33
 
package/examples/gps.n3 CHANGED
@@ -7,45 +7,42 @@
7
7
 
8
8
  @prefix math: <http://www.w3.org/2000/10/swap/math#>.
9
9
  @prefix list: <http://www.w3.org/2000/10/swap/list#>.
10
- @prefix gps: <https://eyereasoner.github.io/eye/reasoning/gps/gps-schema#>.
11
- @prefix : <https://eyereasoner.github.io/eye/reasoning#>.
12
-
13
- # ---------------------
14
- # Data (a small sample)
15
- # ---------------------
10
+ @prefix gps: <https://eyereasoner.github.io/eye/reasoning/gps/gps-schema#>.
11
+ @prefix : <https://eyereasoner.github.io/eye/reasoning#>.
16
12
 
17
13
  # current state
18
14
  :i1 :location :Gent.
19
15
 
20
- # map of Belgium
21
- (:Gent :Brugge :drive_gent_brugge 1500.0 0.006 0.96 0.99) :edge true .
22
- (:Gent :Kortrijk :drive_gent_kortrijk 1600.0 0.007 0.96 0.99) :edge true .
23
- (:Kortrijk :Brugge :drive_kortrijk_brugge 1600.0 0.007 0.96 0.99) :edge true .
24
- (:Brugge :Oostende :drive_brugge_oostende 900.0 0.004 0.98 1.0) :edge true .
25
-
26
- # ----------------
27
- # Path computation
28
- # ----------------
16
+ # -------------------------------------------------
17
+ # map of Belgium (as backward rules / descriptions)
18
+ # -------------------------------------------------
19
+ {:map-BE gps:description ({?S :location :Gent} true {?S :location :Brugge} :drive_gent_brugge 1500.0 0.006 0.96 0.99)} <= true.
20
+ {:map-BE gps:description ({?S :location :Gent} true {?S :location :Kortrijk} :drive_gent_kortrijk 1600.0 0.007 0.96 0.99)} <= true.
21
+ {:map-BE gps:description ({?S :location :Kortrijk} true {?S :location :Brugge} :drive_kortrijk_brugge 1600.0 0.007 0.96 0.99)} <= true.
22
+ {:map-BE gps:description ({?S :location :Brugge} true {?S :location :Oostende} :drive_brugge_oostende 900.0 0.004 0.98 1.0 )} <= true.
29
23
 
30
- # Base: one edge is a path
24
+ # -----------------------------
25
+ # Compute all paths by chaining
26
+ # -----------------------------
27
+ # Base: a single map description is a path
31
28
  {
32
29
  (?From ?To (?Act) ?Dur ?Cost ?Belief ?Comfort) :path true.
33
30
  }
34
31
  <=
35
32
  {
36
- (?From ?To ?Act ?Dur ?Cost ?Belief ?Comfort) :edge true.
33
+ :map-BE gps:description (?From true ?To ?Act ?Dur ?Cost ?Belief ?Comfort).
37
34
  }.
38
35
 
39
- # Recursive: edge + path => path, aggregate weights, concatenate action list
36
+ # Recursive: chain one step + rest path, and aggregate weights
40
37
  {
41
- (?From ?To ?Acts ?Dur ?Cost ?Belief ?Comfort) :path true.
38
+ (?From ?To ?Actions ?Dur ?Cost ?Belief ?Comfort) :path true.
42
39
  }
43
40
  <=
44
41
  {
45
- (?From ?Mid ?Act ?Dur1 ?Cost1 ?Bel1 ?Comf1) :edge true.
42
+ :map-BE gps:description (?From true ?Mid ?Act ?Dur1 ?Cost1 ?Bel1 ?Comf1).
46
43
  (?Mid ?To ?RestActs ?Dur2 ?Cost2 ?Bel2 ?Comf2) :path true.
47
44
 
48
- ((?Act) ?RestActs) list:append ?Acts.
45
+ ((?Act) ?RestActs) list:append ?Actions.
49
46
 
50
47
  (?Dur1 ?Dur2) math:sum ?Dur.
51
48
  (?Cost1 ?Cost2) math:sum ?Cost.
@@ -53,13 +50,12 @@
53
50
  (?Comf1 ?Comf2) math:product ?Comfort.
54
51
  }.
55
52
 
56
- # -------------------------
57
- # Query: only paths to goal
58
- # -------------------------
59
-
53
+ # ------------------------------------------------------
54
+ # "Query": derive gps:path facts for i1, goal = Oostende
55
+ # ------------------------------------------------------
60
56
  {
61
- :i1 :location ?Start.
62
- (?Start :Oostende ?Acts ?Dur ?Cost ?Bel ?Comf) :path true.
57
+ :i1 :location :Gent.
58
+ ({:i1 :location :Gent} {:i1 :location :Oostende} ?Acts ?Dur ?Cost ?Bel ?Comf) :path true.
63
59
  }
64
60
  =>
65
61
  {
@@ -10,7 +10,6 @@
10
10
  # convert daily light exposure into stored energy (photosynthesis),
11
11
  # then decide whether they thrive or go hungry under their conditions.
12
12
  # ------------------------------------------------------------
13
-
14
13
  # One day with a fixed amount of usable light (hours)
15
14
  :Today :lightHours 10.0.
16
15
 
@@ -26,7 +25,6 @@
26
25
  # ------------------------------------------------------------
27
26
  # Rules
28
27
  # ------------------------------------------------------------
29
-
30
28
  # (1) Daily light energy available at each place:
31
29
  # E_place = lightIntensity * lightHours
32
30
  {
@@ -10,7 +10,7 @@
10
10
  # 4.4 list: builtins
11
11
  # ============================================================
12
12
 
13
- # 4.4.1 list:append
13
+ # list:append
14
14
  # ( (1 2) (3 4) ) list:append (1 2 3 4) .
15
15
  {
16
16
  ( (1 2) (3 4) ) list:append (1 2 3 4) .
@@ -18,7 +18,7 @@
18
18
  :ok_list_append_1 a :Pass .
19
19
  } .
20
20
 
21
- # 4.4.2 list:first
21
+ # list:first
22
22
  # (1 2 3 4) list:first 1 .
23
23
  {
24
24
  (1 2 3 4) list:first 1 .
@@ -26,7 +26,7 @@
26
26
  :ok_list_first_1 a :Pass .
27
27
  } .
28
28
 
29
- # 4.4.3 list:in
29
+ # list:in
30
30
  # "cat" list:in ( "dog" "penguin" "cat" ) .
31
31
  {
32
32
  "cat" list:in ( "dog" "penguin" "cat" ) .
@@ -34,7 +34,7 @@
34
34
  :ok_list_in_1 a :Pass .
35
35
  } .
36
36
 
37
- # 4.4.4 list:iterate
37
+ # list:iterate
38
38
  # ("dog" "penguin" "cat") list:iterate (?index "cat") .
39
39
  {
40
40
  ("dog" "penguin" "cat") list:iterate (?index "cat") .
@@ -42,7 +42,7 @@
42
42
  :ok_list_iterate_1 a :Pass .
43
43
  } .
44
44
 
45
- # 4.4.5 list:last
45
+ # list:last
46
46
  # (1 2 3 4) list:last 4 .
47
47
  {
48
48
  (1 2 3 4) list:last 4 .
@@ -50,7 +50,7 @@
50
50
  :ok_list_last_1 a :Pass .
51
51
  } .
52
52
 
53
- # 4.4.6 list:length
53
+ # list:length
54
54
  # (1 2 3 4) list:length 4 .
55
55
  {
56
56
  (1 2 3 4) list:length 4 .
@@ -58,7 +58,7 @@
58
58
  :ok_list_length_1 a :Pass .
59
59
  } .
60
60
 
61
- # 4.4.7 list:member
61
+ # list:member
62
62
  # ("dog" "penguin" "cat") list:member "cat" .
63
63
  {
64
64
  ("dog" "penguin" "cat") list:member "cat" .
@@ -66,7 +66,7 @@
66
66
  :ok_list_member_1 a :Pass .
67
67
  } .
68
68
 
69
- # 4.4.8 list:memberAt
69
+ # list:memberAt
70
70
  # (("dog" "penguin" "cat") 2) list:memberAt "cat" .
71
71
  {
72
72
  (("dog" "penguin" "cat") 2) list:memberAt "cat" .
@@ -74,7 +74,7 @@
74
74
  :ok_list_memberAt_1 a :Pass .
75
75
  } .
76
76
 
77
- # 4.4.9 list:remove
77
+ # list:remove
78
78
  # (("dog" "penguin" "cat" "penguin") "penguin") list:remove ("dog" "cat") .
79
79
  {
80
80
  (("dog" "penguin" "cat" "penguin") "penguin") list:remove ("dog" "cat") .
@@ -82,3 +82,19 @@
82
82
  :ok_list_remove_1 a :Pass .
83
83
  } .
84
84
 
85
+ # list:rest
86
+ # (1 2 3 4) list:rest (2 3 4) .
87
+ {
88
+ (1 2 3 4) list:rest (2 3 4) .
89
+ } => {
90
+ :ok_list_rest_1 a :Pass .
91
+ } .
92
+
93
+ # list:firstRest
94
+ # (1 2 3 4) list:firstRest (1 (2 3 4)) .
95
+ {
96
+ (1 2 3 4) list:firstRest (1 (2 3 4)) .
97
+ } => {
98
+ :ok_list_firstRest_1 a :Pass .
99
+ } .
100
+
@@ -10,7 +10,6 @@
10
10
  # ------------------
11
11
  # Trust model (0..1)
12
12
  # ------------------
13
-
14
13
  :Gov :trust 0.95.
15
14
  :Partner :trust 0.70.
16
15
  :RandomBlog :trust 0.30.
@@ -18,7 +17,6 @@
18
17
  # ---------------------------
19
18
  # A request we want to decide
20
19
  # ---------------------------
21
-
22
20
  :req1 a :Request;
23
21
  odrl:assignee :Alice;
24
22
  odrl:target :Doc1;
@@ -27,7 +25,6 @@
27
25
  # -------------
28
26
  # ODRL Policies
29
27
  # -------------
30
-
31
28
  # High-trust permission from Gov (trusted enough)
32
29
  :PolGov a odrl:Policy;
33
30
  dct:creator :Gov;
@@ -79,7 +76,6 @@
79
76
  # --------------------------------
80
77
  # Minimal "ODRL + trust" evaluator
81
78
  # --------------------------------
82
-
83
79
  # Candidate PERMIT for a request, scored by issuer trust, only if trust >= minTrust
84
80
  {
85
81
  (?Req odrl:permit ?Score) :cand true.
@@ -6,11 +6,19 @@
6
6
  # :i1 gps:path ((:drive_gent_kortrijk :drive_kortrijk_brugge :drive_brugge_oostende) 4100 0.018 0.903168 0.9801) .
7
7
  # It holds because the following instance of the rule body is provable:
8
8
  # :i1 :location :Gent .
9
- # (:Gent :Oostende (:drive_gent_kortrijk :drive_kortrijk_brugge :drive_brugge_oostende) 4100 0.018 0.903168 0.9801) :path true .
9
+ # ({
10
+ # :i1 :location :Gent .
11
+ # } {
12
+ # :i1 :location :Oostende .
13
+ # } (:drive_gent_kortrijk :drive_kortrijk_brugge :drive_brugge_oostende) 4100 0.018 0.903168 0.9801) :path true .
10
14
  # via the schematic forward rule:
11
15
  # {
12
- # :i1 :location ?Start .
13
- # (?Start :Oostende ?Acts ?Dur ?Cost ?Bel ?Comf) :path true .
16
+ # :i1 :location :Gent .
17
+ # ({
18
+ # :i1 :location :Gent .
19
+ # } {
20
+ # :i1 :location :Oostende .
21
+ # } ?Acts ?Dur ?Cost ?Bel ?Comf) :path true .
14
22
  # } => {
15
23
  # :i1 gps:path (?Acts ?Dur ?Cost ?Bel ?Comf) .
16
24
  # } .
@@ -20,7 +28,6 @@
20
28
  # ?Comf = 0.9801
21
29
  # ?Cost = 0.018
22
30
  # ?Dur = 4100
23
- # ?Start = :Gent
24
31
  # Therefore the derived triple above is entailed by the rules and facts.
25
32
  # ----------------------------------------------------------------------
26
33
 
@@ -31,11 +38,19 @@
31
38
  # :i1 gps:path ((:drive_gent_brugge :drive_brugge_oostende) 2400 0.01 0.9408 0.99) .
32
39
  # It holds because the following instance of the rule body is provable:
33
40
  # :i1 :location :Gent .
34
- # (:Gent :Oostende (:drive_gent_brugge :drive_brugge_oostende) 2400 0.01 0.9408 0.99) :path true .
41
+ # ({
42
+ # :i1 :location :Gent .
43
+ # } {
44
+ # :i1 :location :Oostende .
45
+ # } (:drive_gent_brugge :drive_brugge_oostende) 2400 0.01 0.9408 0.99) :path true .
35
46
  # via the schematic forward rule:
36
47
  # {
37
- # :i1 :location ?Start .
38
- # (?Start :Oostende ?Acts ?Dur ?Cost ?Bel ?Comf) :path true .
48
+ # :i1 :location :Gent .
49
+ # ({
50
+ # :i1 :location :Gent .
51
+ # } {
52
+ # :i1 :location :Oostende .
53
+ # } ?Acts ?Dur ?Cost ?Bel ?Comf) :path true .
39
54
  # } => {
40
55
  # :i1 gps:path (?Acts ?Dur ?Cost ?Bel ?Comf) .
41
56
  # } .
@@ -45,7 +60,6 @@
45
60
  # ?Comf = 0.99
46
61
  # ?Cost = 0.01
47
62
  # ?Dur = 2400
48
- # ?Start = :Gent
49
63
  # Therefore the derived triple above is entailed by the rules and facts.
50
64
  # ----------------------------------------------------------------------
51
65
 
@@ -146,3 +146,35 @@
146
146
 
147
147
  :ok_list_remove_1 a :Pass .
148
148
 
149
+ # ----------------------------------------------------------------------
150
+ # Proof for derived triple:
151
+ # :ok_list_rest_1 a :Pass .
152
+ # It holds because the following instance of the rule body is provable:
153
+ # (1 2 3 4) list:rest (2 3 4) .
154
+ # via the schematic forward rule:
155
+ # {
156
+ # (1 2 3 4) list:rest (2 3 4) .
157
+ # } => {
158
+ # :ok_list_rest_1 a :Pass .
159
+ # } .
160
+ # Therefore the derived triple above is entailed by the rules and facts.
161
+ # ----------------------------------------------------------------------
162
+
163
+ :ok_list_rest_1 a :Pass .
164
+
165
+ # ----------------------------------------------------------------------
166
+ # Proof for derived triple:
167
+ # :ok_list_firstRest_1 a :Pass .
168
+ # It holds because the following instance of the rule body is provable:
169
+ # (1 2 3 4) list:firstRest (1 (2 3 4)) .
170
+ # via the schematic forward rule:
171
+ # {
172
+ # (1 2 3 4) list:firstRest (1 (2 3 4)) .
173
+ # } => {
174
+ # :ok_list_firstRest_1 a :Pass .
175
+ # } .
176
+ # Therefore the derived triple above is entailed by the rules and facts.
177
+ # ----------------------------------------------------------------------
178
+
179
+ :ok_list_firstRest_1 a :Pass .
180
+
@@ -9,7 +9,6 @@
9
9
  # ------------------------------------------------------------
10
10
  # Spectral light intake (red + blue) and weekly energy storage
11
11
  # ------------------------------------------------------------
12
-
13
12
  # Locations: daily hours of red/blue light, and intensity per hour.
14
13
  :Greenhouse :redHours 8.0; :blueHours 2.0;
15
14
  :redIntensity 120.0;
@@ -32,7 +31,6 @@
32
31
  # Ered = redIntensity * redHours
33
32
  # Eblue = blueIntensity * blueHours
34
33
  # ------------------------------------
35
-
36
34
  {
37
35
  ?Loc :redIntensity ?RI; :redHours ?RH.
38
36
  (?RI ?RH) math:product ?Ered.
@@ -53,7 +51,6 @@
53
51
  # Ablue = Loc.blueEnergy * Plant.absorbBlue
54
52
  # absorbed = Ared + Ablue
55
53
  # -------------------------------------------
56
-
57
54
  {
58
55
  ?P a :Plant; :location ?Loc; :absorbRed ?AR.
59
56
  ?Loc :redEnergy ?Ered.
@@ -81,7 +78,6 @@
81
78
  # -------------------------------------------------
82
79
  # Daily stored energy = absorbedEnergy * conversion
83
80
  # -------------------------------------------------
84
-
85
81
  {
86
82
  ?P :absorbedEnergy ?Abs; :conversion ?C.
87
83
  (?Abs ?C) math:product ?Stored.
@@ -92,7 +88,6 @@
92
88
  # ------------------------------------
93
89
  # Weekly stored energy = dailyStored*7
94
90
  # ------------------------------------
95
-
96
91
  {
97
92
  ?P :dailyStored ?D.
98
93
  (?D 7) math:product ?W.
package/eyeling.js CHANGED
@@ -1463,6 +1463,40 @@ function unifyOpenWithList(prefix, tailv, ys, subst) {
1463
1463
  return s2;
1464
1464
  }
1465
1465
 
1466
+ function unifyFormulaTriples(xs, ys, subst) {
1467
+ if (xs.length !== ys.length) return null;
1468
+
1469
+ // Fast path: exact same sequence.
1470
+ if (triplesListEqual(xs, ys)) return { ...subst };
1471
+
1472
+ // Backtracking match (order-insensitive), *threading* the substitution through.
1473
+ const used = new Array(ys.length).fill(false);
1474
+
1475
+ function step(i, s) {
1476
+ if (i >= xs.length) return s;
1477
+ const x = xs[i];
1478
+
1479
+ for (let j = 0; j < ys.length; j++) {
1480
+ if (used[j]) continue;
1481
+ const y = ys[j];
1482
+
1483
+ // Cheap pruning when both predicates are IRIs.
1484
+ if (x.p instanceof Iri && y.p instanceof Iri && x.p.value !== y.p.value) continue;
1485
+
1486
+ const s2 = unifyTriple(x, y, s); // IMPORTANT: use `s`, not {}
1487
+ if (s2 === null) continue;
1488
+
1489
+ used[j] = true;
1490
+ const s3 = step(i + 1, s2);
1491
+ if (s3 !== null) return s3;
1492
+ used[j] = false;
1493
+ }
1494
+ return null;
1495
+ }
1496
+
1497
+ return step(0, { ...subst }); // IMPORTANT: start from the incoming subst
1498
+ }
1499
+
1466
1500
  function unifyTerm(a, b, subst) {
1467
1501
  a = applySubstTerm(a, subst);
1468
1502
  b = applySubstTerm(b, subst);
@@ -1521,11 +1555,10 @@ function unifyTerm(a, b, subst) {
1521
1555
  return s2;
1522
1556
  }
1523
1557
 
1524
- // Formulas are treated as opaque unless exactly equal
1558
+ // Formulas: unify their internal triple sets (order-insensitive)
1525
1559
  if (a instanceof FormulaTerm && b instanceof FormulaTerm) {
1526
- if (triplesListEqual(a.triples, b.triples)) return { ...subst };
1560
+ return unifyFormulaTriples(a.triples, b.triples, subst);
1527
1561
  }
1528
-
1529
1562
  return null;
1530
1563
  }
1531
1564
 
@@ -2525,6 +2558,36 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
2525
2558
  return s2 !== null ? [s2] : [];
2526
2559
  }
2527
2560
 
2561
+ // list:rest
2562
+ // true iff $s is a (non-empty) list and $o is the rest (tail) of that list.
2563
+ // Schema: $s+ list:rest $o-
2564
+ if (g.p instanceof Iri && g.p.value === LIST_NS + "rest") {
2565
+ // Closed list: (a b c) -> (b c)
2566
+ if (g.s instanceof ListTerm) {
2567
+ if (!g.s.elems.length) return [];
2568
+ const rest = new ListTerm(g.s.elems.slice(1));
2569
+ const s2 = unifyTerm(g.o, rest, subst);
2570
+ return s2 !== null ? [s2] : [];
2571
+ }
2572
+
2573
+ // Open list: (a b ... ?T) -> (b ... ?T)
2574
+ if (g.s instanceof OpenListTerm) {
2575
+ if (!g.s.prefix.length) return []; // can't compute rest without a known head
2576
+
2577
+ if (g.s.prefix.length === 1) {
2578
+ // (a ... ?T) rest is exactly ?T
2579
+ const s2 = unifyTerm(g.o, new Var(g.s.tailVar), subst);
2580
+ return s2 !== null ? [s2] : [];
2581
+ }
2582
+
2583
+ const rest = new OpenListTerm(g.s.prefix.slice(1), g.s.tailVar);
2584
+ const s2 = unifyTerm(g.o, rest, subst);
2585
+ return s2 !== null ? [s2] : [];
2586
+ }
2587
+
2588
+ return [];
2589
+ }
2590
+
2528
2591
  // list:iterate
2529
2592
  // true iff $s is a list and $o is a list (index value),
2530
2593
  // where index is a valid 0-based index into $s and value is the element at that index.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.5.21",
3
+ "version": "1.5.23",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [