eyeling 1.5.35 → 1.5.37
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/examples/brussels-brew-club.n3 +119 -0
- package/examples/drone-corridor-planner.n3 +146 -40
- package/examples/ev-roundtrip-planner.n3 +189 -0
- package/examples/json-pointer.n3 +5 -0
- package/examples/json-reconcile-vat.n3 +5 -0
- package/examples/oslo-steps-workflow-composition.n3 +305 -0
- package/examples/output/brussels-brew-club.n3 +498 -0
- package/examples/output/drone-corridor-planner.n3 +717 -51
- package/examples/output/ev-roundtrip-planner.n3 +403 -0
- package/examples/output/json-reconcile-vat.n3 +49 -48
- package/examples/output/oslo-steps-workflow-composition.n3 +148 -0
- package/examples/output/skolem.n3 +5 -4
- package/examples/rdf-list.n3 +7 -3
- package/eyeling.js +183 -7
- package/package.json +1 -1
- package/test/api.test.js +30 -0
- package/examples/drone-corridor-planner-v2.n3 +0 -237
- package/examples/output/drone-corridor-planner-v2.n3 +0 -819
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# ==================
|
|
2
|
+
# Brussels Brew Club
|
|
3
|
+
# ==================
|
|
4
|
+
#
|
|
5
|
+
# A tiny loyalty + compliance reasoner with:
|
|
6
|
+
# - JSON profile parsing (rdf:JSON + string:jsonPointer)
|
|
7
|
+
# - backward rules (<=) used during forward chaining
|
|
8
|
+
# - stable IDs with log:skolem
|
|
9
|
+
# - timestamps with time:localTime
|
|
10
|
+
|
|
11
|
+
@prefix : <http://example.org/brewclub#> .
|
|
12
|
+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
|
13
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
14
|
+
@prefix log: <http://www.w3.org/2000/10/swap/log#> .
|
|
15
|
+
@prefix math: <http://www.w3.org/2000/10/swap/math#> .
|
|
16
|
+
@prefix string:<http://www.w3.org/2000/10/swap/string#> .
|
|
17
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
|
18
|
+
|
|
19
|
+
# ---------------------------
|
|
20
|
+
# Deterministic "run context"
|
|
21
|
+
# ---------------------------
|
|
22
|
+
|
|
23
|
+
:run :now "2000-01-01T00:00:00+00:00"^^xsd:dateTime .
|
|
24
|
+
|
|
25
|
+
# -----
|
|
26
|
+
# Facts
|
|
27
|
+
# -----
|
|
28
|
+
|
|
29
|
+
:alice :profileJson """{ "name": "Alice", "age": 23, "city": "Brussels" }"""^^rdf:JSON .
|
|
30
|
+
:bob :profileJson """{ "name": "Bob", "age": 16, "city": "Brussels" }"""^^rdf:JSON .
|
|
31
|
+
|
|
32
|
+
:order1 a :Order ;
|
|
33
|
+
:id "ORD-2025-001" ;
|
|
34
|
+
:by :alice ;
|
|
35
|
+
:total "31.50"^^xsd:decimal ;
|
|
36
|
+
:contains :Espresso, :Croissant .
|
|
37
|
+
|
|
38
|
+
:order2 a :Order ;
|
|
39
|
+
:id "ORD-2025-002" ;
|
|
40
|
+
:by :bob ;
|
|
41
|
+
:total "12.00"^^xsd:decimal ;
|
|
42
|
+
:contains :HotChocolate .
|
|
43
|
+
|
|
44
|
+
:Beer a :AlcoholicDrink .
|
|
45
|
+
:Espresso a :Drink .
|
|
46
|
+
:HotChocolate a :Drink .
|
|
47
|
+
:Croissant a :Food .
|
|
48
|
+
|
|
49
|
+
# -----
|
|
50
|
+
# Rules
|
|
51
|
+
# -----
|
|
52
|
+
|
|
53
|
+
# 1) Extract fields from JSON profile into normal triples
|
|
54
|
+
{
|
|
55
|
+
?p :profileJson ?j .
|
|
56
|
+
(?j "/age") string:jsonPointer ?age .
|
|
57
|
+
(?j "/name") string:jsonPointer ?name .
|
|
58
|
+
(?j "/city") string:jsonPointer ?city .
|
|
59
|
+
}
|
|
60
|
+
=>
|
|
61
|
+
{
|
|
62
|
+
?p :age ?age ;
|
|
63
|
+
:name ?name ;
|
|
64
|
+
:city ?city .
|
|
65
|
+
}.
|
|
66
|
+
|
|
67
|
+
# 2) Backward rule: Adult is defined by age > 17
|
|
68
|
+
{ ?p a :Adult }
|
|
69
|
+
<=
|
|
70
|
+
{ ?p :age ?a . ?a math:greaterThan 17 }.
|
|
71
|
+
|
|
72
|
+
# 3) Backward rule: BigOrder is defined by total > 25.00
|
|
73
|
+
{ ?o a :BigOrder }
|
|
74
|
+
<=
|
|
75
|
+
{ ?o :total ?t . ?t math:greaterThan "25.00"^^xsd:decimal }.
|
|
76
|
+
|
|
77
|
+
# 4) Deterministic membership card rule:
|
|
78
|
+
# Uses :run :now ?now instead of time:localTime ?now
|
|
79
|
+
{
|
|
80
|
+
?p a :Adult .
|
|
81
|
+
?p :name ?name .
|
|
82
|
+
:run :now ?now .
|
|
83
|
+
|
|
84
|
+
(?p) log:skolem ?card .
|
|
85
|
+
("Brew Club card for " ?name) string:concatenation ?label .
|
|
86
|
+
}
|
|
87
|
+
=>
|
|
88
|
+
{
|
|
89
|
+
?card a :MembershipCard ;
|
|
90
|
+
:holder ?p ;
|
|
91
|
+
:issuedAt ?now ;
|
|
92
|
+
rdfs:label ?label .
|
|
93
|
+
}.
|
|
94
|
+
|
|
95
|
+
# 5) Discounts: BigOrder + Adult -> discount eligibility
|
|
96
|
+
{
|
|
97
|
+
?o a :Order .
|
|
98
|
+
?o a :BigOrder .
|
|
99
|
+
?o :by ?p .
|
|
100
|
+
?p a :Adult .
|
|
101
|
+
}
|
|
102
|
+
=>
|
|
103
|
+
{
|
|
104
|
+
?o :eligibleDiscount "true"^^xsd:boolean .
|
|
105
|
+
}.
|
|
106
|
+
|
|
107
|
+
# 6) Stable receipt IRI from the order id
|
|
108
|
+
{
|
|
109
|
+
?o a :Order .
|
|
110
|
+
?o :id ?id .
|
|
111
|
+
(?id) log:skolem ?receipt .
|
|
112
|
+
}
|
|
113
|
+
=>
|
|
114
|
+
{
|
|
115
|
+
?receipt a :Receipt ;
|
|
116
|
+
:forOrder ?o ;
|
|
117
|
+
:receiptId ?id .
|
|
118
|
+
}.
|
|
119
|
+
|
|
@@ -1,85 +1,193 @@
|
|
|
1
|
-
#
|
|
2
|
-
# Drone Corridor Planner
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
1
|
+
# ========================================================================================
|
|
2
|
+
# Drone Corridor Planner (example N3 program)
|
|
3
|
+
#
|
|
4
|
+
# What this file is
|
|
5
|
+
# - A tiny “planner” written in Notation3 (N3): it searches for a sequence of
|
|
6
|
+
# actions that moves a drone from a start state to a goal state.
|
|
7
|
+
# - Intended to run in an N3 reasoner that supports forward rules (`=>`),
|
|
8
|
+
# backward rules (`<=`), and a few built-ins (e.g., `math:*`, `list:*`).
|
|
9
|
+
#
|
|
10
|
+
# How to run (one simple option)
|
|
11
|
+
# - With the JavaScript `eyeling` CLI:
|
|
12
|
+
# npx eyeling examples/drone-corridor-planner.n3
|
|
13
|
+
# The output will be newly derived facts, including one or more `gps:plan`
|
|
14
|
+
# results (see “Output” below).
|
|
15
|
+
#
|
|
16
|
+
# Big idea (in plain terms)
|
|
17
|
+
# - We describe a “world” as a small set of facts: location, battery level,
|
|
18
|
+
# and whether the drone has a permit.
|
|
19
|
+
# - We describe each possible action (fly, train, charge, buy/get permit) as a
|
|
20
|
+
# state transition: FROM-state -> TO-state plus some numeric “weights”.
|
|
21
|
+
# - The rules then *compose* these transitions into multi-step plans while
|
|
22
|
+
# aggregating the weights (e.g., add durations, multiply beliefs).
|
|
23
|
+
#
|
|
24
|
+
# Reading the action descriptions
|
|
25
|
+
# - Each action is encoded as a `gps:description` with this shape:
|
|
26
|
+
# ( FROM true TO :actionName duration cost belief comfort )
|
|
27
|
+
# where:
|
|
28
|
+
# - FROM / TO are little graphs in `{ ... }` describing the state.
|
|
29
|
+
# - `true` is a placeholder “precondition” (kept for symmetry with richer
|
|
30
|
+
# variants where extra conditions may appear).
|
|
31
|
+
# - duration/cost/belief/comfort are example numbers used for scoring/pruning.
|
|
32
|
+
#
|
|
33
|
+
# Bounded search (why it doesn’t loop forever)
|
|
34
|
+
# - The planner is *fuel-bounded*: it carries a list of “fuel tokens” and
|
|
35
|
+
# consumes one token per step. When fuel runs out, expansion stops.
|
|
36
|
+
# - This is important because the map can contain cycles (e.g., going back to a
|
|
37
|
+
# previous city). Fuel-bounding keeps the search safe and finite.
|
|
38
|
+
#
|
|
39
|
+
# How scores are combined across a multi-step plan
|
|
40
|
+
# - Duration and cost are summed.
|
|
41
|
+
# - Belief and comfort are multiplied (so long plans tend to reduce them).
|
|
42
|
+
# - The list of actions is built by appending each step’s action name.
|
|
43
|
+
#
|
|
44
|
+
# Output (what you should expect to see)
|
|
45
|
+
# - The “Query” section asks for plans that take the drone from the initial
|
|
46
|
+
# state to the goal (Oostende), then prunes bad plans using thresholds like:
|
|
47
|
+
# belief > ... and cost < ...
|
|
48
|
+
# - Each surviving plan is reported as a derived fact like:
|
|
49
|
+
# :d1 gps:plan ( ...actions... duration cost belief comfort battery permit fuelLeft ).
|
|
50
|
+
#
|
|
51
|
+
# Customizing this example
|
|
52
|
+
# - Add/edit `gps:description` lines to introduce new routes/actions.
|
|
53
|
+
# - Change the initial state (`:d1 :location ...`, `:battery ...`, `:permit ...`).
|
|
54
|
+
# - Adjust `:fuel7` (more/less steps) and the pruning thresholds in the Query.
|
|
55
|
+
#
|
|
56
|
+
# Notes
|
|
57
|
+
# - This is a *toy* corridor-planning model meant to illustrate rule-based
|
|
58
|
+
# planning patterns. The numeric values and “units” are illustrative.
|
|
59
|
+
# ========================================================================================
|
|
6
60
|
|
|
7
61
|
@prefix math: <http://www.w3.org/2000/10/swap/math#>.
|
|
8
62
|
@prefix list: <http://www.w3.org/2000/10/swap/list#>.
|
|
9
63
|
@prefix gps: <https://eyereasoner.github.io/eye/reasoning/gps/gps-schema#>.
|
|
10
64
|
@prefix : <https://eyereasoner.github.io/eye/reasoning#>.
|
|
11
65
|
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
# ----------------
|
|
66
|
+
# -------------
|
|
15
67
|
# current state
|
|
16
|
-
#
|
|
68
|
+
# -------------
|
|
17
69
|
:d1 :location :Gent.
|
|
18
70
|
:d1 :battery :full.
|
|
19
71
|
:d1 :permit :none.
|
|
20
72
|
|
|
21
|
-
# bounded search horizon (
|
|
22
|
-
:
|
|
73
|
+
# bounded search horizon (7 steps max)
|
|
74
|
+
:fuel7 :value (:t :t :t :t :t :t :t).
|
|
23
75
|
|
|
24
|
-
#
|
|
76
|
+
# -----------------------------------------------------------------
|
|
25
77
|
# "map" / action descriptions (as backward rules)
|
|
26
|
-
#
|
|
78
|
+
# State = { ?S :location ... . ?S :battery ... . ?S :permit ... . }
|
|
79
|
+
# -----------------------------------------------------------------
|
|
80
|
+
# two ways to reach Brugge (tradeoff: cost/comfort)
|
|
27
81
|
{:map-DRONE gps:description (
|
|
28
|
-
{?S :location :Gent.
|
|
29
|
-
{?S :location :Brugge.
|
|
82
|
+
{?S :location :Gent. ?S :battery :full. ?S :permit ?P.} true
|
|
83
|
+
{?S :location :Brugge. ?S :battery :mid. ?S :permit ?P.}
|
|
30
84
|
:fly_gent_brugge
|
|
31
85
|
1500.0 0.006 0.99 0.99
|
|
32
86
|
)} <= true.
|
|
33
87
|
|
|
34
88
|
{:map-DRONE gps:description (
|
|
35
|
-
{?S :location :Gent.
|
|
89
|
+
{?S :location :Gent. ?S :battery ?B. ?S :permit ?P.} true
|
|
90
|
+
{?S :location :Brugge. ?S :battery ?B. ?S :permit ?P.}
|
|
91
|
+
:train_gent_brugge
|
|
92
|
+
1700.0 0.012 0.999 0.995
|
|
93
|
+
)} <= true.
|
|
94
|
+
|
|
95
|
+
# via Kortrijk (permit + charging opportunities)
|
|
96
|
+
{:map-DRONE gps:description (
|
|
97
|
+
{?S :location :Gent. ?S :battery :full. ?S :permit ?P.} true
|
|
36
98
|
{?S :location :Kortrijk. ?S :battery :mid. ?S :permit ?P.}
|
|
37
99
|
:fly_gent_kortrijk
|
|
38
100
|
1600.0 0.007 0.99 0.99
|
|
39
101
|
)} <= true.
|
|
40
102
|
|
|
41
103
|
{:map-DRONE gps:description (
|
|
42
|
-
{?S :location :Kortrijk. ?S :battery :mid. ?S :permit ?P.}
|
|
104
|
+
{?S :location :Kortrijk. ?S :battery :mid. ?S :permit ?P.} true
|
|
43
105
|
{?S :location :Brugge. ?S :battery :low. ?S :permit ?P.}
|
|
44
106
|
:fly_kortrijk_brugge
|
|
45
107
|
1600.0 0.007 0.99 0.99
|
|
46
108
|
)} <= true.
|
|
47
109
|
|
|
48
|
-
# cycle edge (safe due to fuel bound)
|
|
110
|
+
# cycle edge (safe due to fuel bound; typically pruned by belief threshold)
|
|
49
111
|
{:map-DRONE gps:description (
|
|
50
|
-
{?S :location :Brugge. ?S :battery :mid. ?S :permit ?P.}
|
|
112
|
+
{?S :location :Brugge. ?S :battery :mid. ?S :permit ?P.} true
|
|
51
113
|
{?S :location :Kortrijk. ?S :battery :low. ?S :permit ?P.}
|
|
52
114
|
:fly_brugge_kortrijk
|
|
53
115
|
1600.0 0.007 0.985 0.98
|
|
54
116
|
)} <= true.
|
|
55
117
|
|
|
56
|
-
# permit
|
|
118
|
+
# get permit in Kortrijk (best belief)
|
|
57
119
|
{:map-DRONE gps:description (
|
|
58
|
-
{?S :location :Kortrijk. ?S :battery ?B.
|
|
59
|
-
{?S :location :Kortrijk. ?S :battery ?B.
|
|
60
|
-
:
|
|
120
|
+
{?S :location :Kortrijk. ?S :battery ?B. ?S :permit :none.} true
|
|
121
|
+
{?S :location :Kortrijk. ?S :battery ?B. ?S :permit :yes.}
|
|
122
|
+
:get_zone_permit_kortrijk
|
|
61
123
|
300.0 0.001 0.999 1.0
|
|
62
124
|
)} <= true.
|
|
63
125
|
|
|
64
|
-
#
|
|
126
|
+
# get permit in Brugge (faster, but lower belief)
|
|
65
127
|
{:map-DRONE gps:description (
|
|
66
|
-
{?S :location :Brugge.
|
|
67
|
-
{?S :location :Brugge.
|
|
128
|
+
{?S :location :Brugge. ?S :battery ?B. ?S :permit :none.} true
|
|
129
|
+
{?S :location :Brugge. ?S :battery ?B. ?S :permit :yes.}
|
|
130
|
+
:buy_permit_brugge
|
|
131
|
+
450.0 0.002 0.98 1.0
|
|
132
|
+
)} <= true.
|
|
133
|
+
|
|
134
|
+
# charging options
|
|
135
|
+
{:map-DRONE gps:description (
|
|
136
|
+
{?S :location :Brugge. ?S :battery :low. ?S :permit ?P.} true
|
|
137
|
+
{?S :location :Brugge. ?S :battery :full. ?S :permit ?P.}
|
|
68
138
|
:quick_charge_brugge
|
|
69
139
|
600.0 0.004 0.999 0.97
|
|
70
140
|
)} <= true.
|
|
71
141
|
|
|
72
|
-
# restricted corridor to Oostende requires permit=yes
|
|
73
142
|
{:map-DRONE gps:description (
|
|
74
|
-
{?S :location :Brugge.
|
|
75
|
-
{?S :location :
|
|
143
|
+
{?S :location :Brugge. ?S :battery :mid. ?S :permit ?P.} true
|
|
144
|
+
{?S :location :Brugge. ?S :battery :full. ?S :permit ?P.}
|
|
145
|
+
:topup_brugge
|
|
146
|
+
400.0 0.003 0.999 0.98
|
|
147
|
+
)} <= true.
|
|
148
|
+
|
|
149
|
+
{:map-DRONE gps:description (
|
|
150
|
+
{?S :location :Kortrijk. ?S :battery :mid. ?S :permit ?P.} true
|
|
151
|
+
{?S :location :Kortrijk. ?S :battery :full. ?S :permit ?P.}
|
|
152
|
+
:emergency_charge_kortrijk
|
|
153
|
+
500.0 0.003 0.999 0.95
|
|
154
|
+
)} <= true.
|
|
155
|
+
|
|
156
|
+
# to Oostende: three alternatives
|
|
157
|
+
# A) restricted corridor: fastest+comfortable, but requires permit=yes and full battery
|
|
158
|
+
{:map-DRONE gps:description (
|
|
159
|
+
{?S :location :Brugge. ?S :battery :full. ?S :permit :yes.} true
|
|
160
|
+
{?S :location :Oostende. ?S :battery :mid. ?S :permit :yes.}
|
|
76
161
|
:cross_corridor_brugge_oostende
|
|
77
162
|
900.0 0.004 0.98 1.0
|
|
78
163
|
)} <= true.
|
|
79
164
|
|
|
80
|
-
#
|
|
165
|
+
# B) public coastline: no permit required, slower
|
|
166
|
+
{:map-DRONE gps:description (
|
|
167
|
+
{?S :location :Brugge. ?S :battery :mid. ?S :permit ?P.} true
|
|
168
|
+
{?S :location :Oostende. ?S :battery :low. ?S :permit ?P.}
|
|
169
|
+
:public_coastline_brugge_oostende
|
|
170
|
+
1300.0 0.006 0.97 0.96
|
|
171
|
+
)} <= true.
|
|
172
|
+
|
|
173
|
+
{:map-DRONE gps:description (
|
|
174
|
+
{?S :location :Brugge. ?S :battery :full. ?S :permit ?P.} true
|
|
175
|
+
{?S :location :Oostende. ?S :battery :mid. ?S :permit ?P.}
|
|
176
|
+
:public_coastline_brugge_oostende
|
|
177
|
+
1200.0 0.006 0.975 0.96
|
|
178
|
+
)} <= true.
|
|
179
|
+
|
|
180
|
+
# C) Kortrijk shortcut: requires permit and full battery; quicker but lower comfort
|
|
181
|
+
{:map-DRONE gps:description (
|
|
182
|
+
{?S :location :Kortrijk. ?S :battery :full. ?S :permit :yes.} true
|
|
183
|
+
{?S :location :Oostende. ?S :battery :mid. ?S :permit :yes.}
|
|
184
|
+
:direct_corridor_kortrijk_oostende
|
|
185
|
+
1100.0 0.009 0.955 0.92
|
|
186
|
+
)} <= true.
|
|
187
|
+
|
|
188
|
+
# ----------------------------------
|
|
81
189
|
# planner: compute all bounded paths
|
|
82
|
-
#
|
|
190
|
+
# ----------------------------------
|
|
83
191
|
# Base: one description is a path (consume 1 fuel token)
|
|
84
192
|
{
|
|
85
193
|
(?From ?To (?Act) ?Dur ?Cost ?Bel ?Comf ?FuelIn ?FuelOut) :path true.
|
|
@@ -109,23 +217,21 @@
|
|
|
109
217
|
(?Comf1 ?Comf2) math:product ?Comf.
|
|
110
218
|
}.
|
|
111
219
|
|
|
112
|
-
#
|
|
113
|
-
# Query: plans for d1 to Oostende with thresholds
|
|
114
|
-
#
|
|
220
|
+
# -------------------------------------------------------
|
|
221
|
+
# Query: plans for d1 to Oostende with pruning thresholds
|
|
222
|
+
# -------------------------------------------------------
|
|
115
223
|
{
|
|
116
|
-
:
|
|
224
|
+
:fuel7 :value ?Fuel.
|
|
117
225
|
|
|
118
226
|
({:d1 :location :Gent. :d1 :battery :full. :d1 :permit :none.}
|
|
119
227
|
{:d1 :location :Oostende. :d1 :battery ?B. :d1 :permit ?P.}
|
|
120
228
|
?Acts ?Dur ?Cost ?Bel ?Comf ?Fuel ?FuelLeft) :path true.
|
|
121
229
|
|
|
122
|
-
?Bel math:greaterThan 0.
|
|
123
|
-
?Cost math:lessThan 0.
|
|
230
|
+
?Bel math:greaterThan 0.94.
|
|
231
|
+
?Cost math:lessThan 0.03.
|
|
124
232
|
}
|
|
125
233
|
=>
|
|
126
234
|
{
|
|
127
|
-
:d1 gps:plan (?Acts ?Dur ?Cost ?Bel ?Comf ?FuelLeft).
|
|
128
|
-
:d1 :finalBattery ?B.
|
|
129
|
-
:d1 :finalPermit ?P.
|
|
235
|
+
:d1 gps:plan (?Acts ?Dur ?Cost ?Bel ?Comf ?B ?P ?FuelLeft).
|
|
130
236
|
}.
|
|
131
237
|
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# ======================================================================================
|
|
2
|
+
# EV Roadtrip Planner
|
|
3
|
+
#
|
|
4
|
+
# World state (toy):
|
|
5
|
+
# :car1 :at <city>.
|
|
6
|
+
# :car1 :battery :high|:mid|:low.
|
|
7
|
+
# :car1 :pass :none|:yes.
|
|
8
|
+
#
|
|
9
|
+
# Actions are gps:description:
|
|
10
|
+
# ( FROM true TO :actionName duration cost belief comfort )
|
|
11
|
+
#
|
|
12
|
+
# Planner:
|
|
13
|
+
# (:FromState :ToState :Actions :Dur :Cost :Bel :Comf :FuelIn :FuelOut) :path true.
|
|
14
|
+
#
|
|
15
|
+
# Query emits:
|
|
16
|
+
# :car1 gps:plan ( ...actions... duration cost belief comfort battery pass fuelLeft ).
|
|
17
|
+
# ======================================================================================
|
|
18
|
+
|
|
19
|
+
@prefix math: <http://www.w3.org/2000/10/swap/math#>.
|
|
20
|
+
@prefix list: <http://www.w3.org/2000/10/swap/list#>.
|
|
21
|
+
@prefix gps: <https://eyereasoner.github.io/eye/reasoning/gps/gps-schema#>.
|
|
22
|
+
@prefix : <https://eyereasoner.github.io/eye/reasoning#>.
|
|
23
|
+
|
|
24
|
+
# -------------------------------------------------------------------------
|
|
25
|
+
# current state (for readability; query also cites an explicit start state)
|
|
26
|
+
# -------------------------------------------------------------------------
|
|
27
|
+
:car1 :at :Brussels.
|
|
28
|
+
:car1 :battery :high.
|
|
29
|
+
:car1 :pass :none.
|
|
30
|
+
|
|
31
|
+
# bounded search horizon (8 steps max)
|
|
32
|
+
:fuel8 :value (:t :t :t :t :t :t :t :t).
|
|
33
|
+
|
|
34
|
+
# ------------------------------------------------------------------
|
|
35
|
+
# "map" / action descriptions (as backward rules)
|
|
36
|
+
# State = { :car1 :at ... . :car1 :battery ... . :car1 :pass ... . }
|
|
37
|
+
# ------------------------------------------------------------------
|
|
38
|
+
# Brussels -> Liège (two alternatives: drive vs train)
|
|
39
|
+
{:map-EV gps:description (
|
|
40
|
+
{:car1 :at :Brussels. :car1 :battery :high. :car1 :pass ?P.}
|
|
41
|
+
true
|
|
42
|
+
{:car1 :at :Liege. :car1 :battery :mid. :car1 :pass ?P.}
|
|
43
|
+
:drive_bru_liege
|
|
44
|
+
85.0 0.018 0.985 0.960
|
|
45
|
+
)} <= true.
|
|
46
|
+
|
|
47
|
+
{:map-EV gps:description (
|
|
48
|
+
{:car1 :at :Brussels. :car1 :battery ?B. :car1 :pass ?P.}
|
|
49
|
+
true
|
|
50
|
+
{:car1 :at :Liege. :car1 :battery ?B. :car1 :pass ?P.}
|
|
51
|
+
:train_bru_liege
|
|
52
|
+
95.0 0.020 0.999 0.990
|
|
53
|
+
)} <= true.
|
|
54
|
+
|
|
55
|
+
# Liège -> Aachen (consumes battery)
|
|
56
|
+
{:map-EV gps:description (
|
|
57
|
+
{:car1 :at :Liege. :car1 :battery :mid. :car1 :pass ?P.}
|
|
58
|
+
true
|
|
59
|
+
{:car1 :at :Aachen. :car1 :battery :low. :car1 :pass ?P.}
|
|
60
|
+
:drive_liege_aachen
|
|
61
|
+
55.0 0.012 0.990 0.950
|
|
62
|
+
)} <= true.
|
|
63
|
+
|
|
64
|
+
# A tiny “cycle edge” back (to test fuel-bounding + pruning)
|
|
65
|
+
{:map-EV gps:description (
|
|
66
|
+
{:car1 :at :Aachen. :car1 :battery :mid. :car1 :pass ?P.}
|
|
67
|
+
true
|
|
68
|
+
{:car1 :at :Liege. :car1 :battery :low. :car1 :pass ?P.}
|
|
69
|
+
:drive_aachen_liege
|
|
70
|
+
60.0 0.013 0.970 0.930
|
|
71
|
+
)} <= true.
|
|
72
|
+
|
|
73
|
+
# Buy charging pass (Brussels or Liège)
|
|
74
|
+
{:map-EV gps:description (
|
|
75
|
+
{:car1 :at :Brussels. :car1 :battery ?B. :car1 :pass :none.}
|
|
76
|
+
true
|
|
77
|
+
{:car1 :at :Brussels. :car1 :battery ?B. :car1 :pass :yes.}
|
|
78
|
+
:buy_pass_brussels
|
|
79
|
+
10.0 0.004 0.999 0.990
|
|
80
|
+
)} <= true.
|
|
81
|
+
|
|
82
|
+
{:map-EV gps:description (
|
|
83
|
+
{:car1 :at :Liege. :car1 :battery ?B. :car1 :pass :none.}
|
|
84
|
+
true
|
|
85
|
+
{:car1 :at :Liege. :car1 :battery ?B. :car1 :pass :yes.}
|
|
86
|
+
:buy_pass_liege
|
|
87
|
+
15.0 0.003 0.995 0.980
|
|
88
|
+
)} <= true.
|
|
89
|
+
|
|
90
|
+
# Charging options (better if you have a pass)
|
|
91
|
+
{:map-EV gps:description (
|
|
92
|
+
{:car1 :at :Liege. :car1 :battery :low. :car1 :pass ?P.}
|
|
93
|
+
true
|
|
94
|
+
{:car1 :at :Liege. :car1 :battery :mid. :car1 :pass ?P.}
|
|
95
|
+
:quick_charge_liege
|
|
96
|
+
35.0 0.010 0.999 0.970
|
|
97
|
+
)} <= true.
|
|
98
|
+
|
|
99
|
+
{:map-EV gps:description (
|
|
100
|
+
{:car1 :at :Aachen. :car1 :battery :low. :car1 :pass :yes.}
|
|
101
|
+
true
|
|
102
|
+
{:car1 :at :Aachen. :car1 :battery :mid. :car1 :pass :yes.}
|
|
103
|
+
:fast_charge_aachen_pass
|
|
104
|
+
25.0 0.009 0.999 0.980
|
|
105
|
+
)} <= true.
|
|
106
|
+
|
|
107
|
+
{:map-EV gps:description (
|
|
108
|
+
{:car1 :at :Aachen. :car1 :battery :low. :car1 :pass :none.}
|
|
109
|
+
true
|
|
110
|
+
{:car1 :at :Aachen. :car1 :battery :mid. :car1 :pass :none.}
|
|
111
|
+
:fast_charge_aachen_payg
|
|
112
|
+
30.0 0.016 0.990 0.950
|
|
113
|
+
)} <= true.
|
|
114
|
+
|
|
115
|
+
# Aachen -> Cologne (three alternatives: premium corridor vs public road)
|
|
116
|
+
# A) Premium corridor: requires pass=yes and mid battery (best comfort)
|
|
117
|
+
{:map-EV gps:description (
|
|
118
|
+
{:car1 :at :Aachen. :car1 :battery :mid. :car1 :pass :yes.}
|
|
119
|
+
true
|
|
120
|
+
{:car1 :at :Cologne. :car1 :battery :low. :car1 :pass :yes.}
|
|
121
|
+
:premium_corridor_aachen_cologne
|
|
122
|
+
45.0 0.020 0.980 0.995
|
|
123
|
+
)} <= true.
|
|
124
|
+
|
|
125
|
+
# B) Public road: no pass required (slower)
|
|
126
|
+
{:map-EV gps:description (
|
|
127
|
+
{:car1 :at :Aachen. :car1 :battery :mid. :car1 :pass ?P.}
|
|
128
|
+
true
|
|
129
|
+
{:car1 :at :Cologne. :car1 :battery :low. :car1 :pass ?P.}
|
|
130
|
+
:public_road_aachen_cologne
|
|
131
|
+
60.0 0.011 0.975 0.960
|
|
132
|
+
)} <= true.
|
|
133
|
+
|
|
134
|
+
# C) “Last-mile” taxi shuttle: keeps battery, higher cost, high belief
|
|
135
|
+
{:map-EV gps:description (
|
|
136
|
+
{:car1 :at :Aachen. :car1 :battery :low. :car1 :pass ?P.}
|
|
137
|
+
true
|
|
138
|
+
{:car1 :at :Cologne. :car1 :battery :low. :car1 :pass ?P.}
|
|
139
|
+
:shuttle_aachen_cologne
|
|
140
|
+
70.0 0.024 0.999 0.985
|
|
141
|
+
)} <= true.
|
|
142
|
+
|
|
143
|
+
# ----------------------------------
|
|
144
|
+
# planner: compute all bounded paths
|
|
145
|
+
# ----------------------------------
|
|
146
|
+
# Base: one description is a path (consume 1 fuel token)
|
|
147
|
+
{ (?From ?To (?Act) ?Dur ?Cost ?Bel ?Comf ?FuelIn ?FuelOut) :path true. }
|
|
148
|
+
<=
|
|
149
|
+
{
|
|
150
|
+
:map-EV gps:description (?From true ?To ?Act ?Dur ?Cost ?Bel ?Comf).
|
|
151
|
+
?FuelIn list:rest ?FuelOut.
|
|
152
|
+
}.
|
|
153
|
+
|
|
154
|
+
# Recursive: chain one step + rest path, aggregate weights, consume 1 fuel token
|
|
155
|
+
{ (?From ?To ?Actions ?Dur ?Cost ?Bel ?Comf ?FuelIn ?FuelOut) :path true. }
|
|
156
|
+
<=
|
|
157
|
+
{
|
|
158
|
+
:map-EV gps:description (?From true ?Mid ?Act ?Dur1 ?Cost1 ?Bel1 ?Comf1).
|
|
159
|
+
?FuelIn list:rest ?FuelMid.
|
|
160
|
+
(?Mid ?To ?RestActs ?Dur2 ?Cost2 ?Bel2 ?Comf2 ?FuelMid ?FuelOut) :path true.
|
|
161
|
+
|
|
162
|
+
((?Act) ?RestActs) list:append ?Actions.
|
|
163
|
+
(?Dur1 ?Dur2) math:sum ?Dur.
|
|
164
|
+
(?Cost1 ?Cost2) math:sum ?Cost.
|
|
165
|
+
(?Bel1 ?Bel2) math:product ?Bel.
|
|
166
|
+
(?Comf1 ?Comf2) math:product ?Comf.
|
|
167
|
+
}.
|
|
168
|
+
|
|
169
|
+
# --------------------------------------------------------
|
|
170
|
+
# Query: plans for car1 to Cologne with pruning thresholds
|
|
171
|
+
# --------------------------------------------------------
|
|
172
|
+
{
|
|
173
|
+
:fuel8 :value ?Fuel.
|
|
174
|
+
|
|
175
|
+
(
|
|
176
|
+
{:car1 :at :Brussels. :car1 :battery :high. :car1 :pass :none.}
|
|
177
|
+
{:car1 :at :Cologne. :car1 :battery ?B. :car1 :pass ?P.}
|
|
178
|
+
?Acts ?Dur ?Cost ?Bel ?Comf ?Fuel ?FuelLeft
|
|
179
|
+
) :path true.
|
|
180
|
+
|
|
181
|
+
?Bel math:greaterThan 0.93.
|
|
182
|
+
?Cost math:lessThan 0.090.
|
|
183
|
+
?Dur math:lessThan 260.0.
|
|
184
|
+
}
|
|
185
|
+
=>
|
|
186
|
+
{
|
|
187
|
+
:car1 gps:plan (?Acts ?Dur ?Cost ?Bel ?Comf ?B ?P ?FuelLeft).
|
|
188
|
+
}.
|
|
189
|
+
|
package/examples/json-pointer.n3
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
# =================================================
|
|
2
|
+
# JSON Pointer example
|
|
3
|
+
# See https://datatracker.ietf.org/doc/html/rfc6901
|
|
4
|
+
# =================================================
|
|
5
|
+
|
|
1
6
|
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
|
2
7
|
@prefix string: <http://www.w3.org/2000/10/swap/string#> .
|
|
3
8
|
@prefix list: <http://www.w3.org/2000/10/swap/list#> .
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
# =================================================
|
|
2
|
+
# Rconcile VAT JSON Pointer example
|
|
3
|
+
# See https://datatracker.ietf.org/doc/html/rfc6901
|
|
4
|
+
# =================================================
|
|
5
|
+
|
|
1
6
|
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
|
2
7
|
@prefix string: <http://www.w3.org/2000/10/swap/string#> .
|
|
3
8
|
@prefix list: <http://www.w3.org/2000/10/swap/list#> .
|