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 +1 -2
- package/examples/expression-eval.n3 +0 -3
- package/examples/family-cousins.n3 +0 -2
- package/examples/gps.n3 +23 -27
- package/examples/light-eaters.n3 +0 -2
- package/examples/list-builtins-tests.n3 +25 -9
- package/examples/odrl-trust.n3 +0 -4
- package/examples/output/gps.n3 +22 -8
- package/examples/output/list-builtins-tests.n3 +32 -0
- package/examples/spectral-week.n3 +0 -5
- package/eyeling.js +66 -3
- package/package.json +1 -1
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:
|
|
11
|
-
@prefix :
|
|
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
|
-
#
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
(:
|
|
24
|
-
(:
|
|
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
|
-
#
|
|
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)
|
|
33
|
+
:map-BE gps:description (?From true ?To ?Act ?Dur ?Cost ?Belief ?Comfort).
|
|
37
34
|
}.
|
|
38
35
|
|
|
39
|
-
# Recursive:
|
|
36
|
+
# Recursive: chain one step + rest path, and aggregate weights
|
|
40
37
|
{
|
|
41
|
-
(?From ?To ?
|
|
38
|
+
(?From ?To ?Actions ?Dur ?Cost ?Belief ?Comfort) :path true.
|
|
42
39
|
}
|
|
43
40
|
<=
|
|
44
41
|
{
|
|
45
|
-
(?From ?Mid ?Act ?Dur1 ?Cost1 ?Bel1 ?Comf1)
|
|
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 ?
|
|
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:
|
|
58
|
-
#
|
|
59
|
-
|
|
53
|
+
# ------------------------------------------------------
|
|
54
|
+
# "Query": derive gps:path facts for i1, goal = Oostende
|
|
55
|
+
# ------------------------------------------------------
|
|
60
56
|
{
|
|
61
|
-
:i1 :location
|
|
62
|
-
(
|
|
57
|
+
:i1 :location :Gent.
|
|
58
|
+
({:i1 :location :Gent} {:i1 :location :Oostende} ?Acts ?Dur ?Cost ?Bel ?Comf) :path true.
|
|
63
59
|
}
|
|
64
60
|
=>
|
|
65
61
|
{
|
package/examples/light-eaters.n3
CHANGED
|
@@ -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
|
-
#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
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
|
+
|
package/examples/odrl-trust.n3
CHANGED
|
@@ -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.
|
package/examples/output/gps.n3
CHANGED
|
@@ -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
|
-
# (
|
|
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
|
|
13
|
-
# (
|
|
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
|
-
# (
|
|
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
|
|
38
|
-
# (
|
|
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
|
|
1558
|
+
// Formulas: unify their internal triple sets (order-insensitive)
|
|
1525
1559
|
if (a instanceof FormulaTerm && b instanceof FormulaTerm) {
|
|
1526
|
-
|
|
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.
|