eyeling 1.8.1 → 1.8.3

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
@@ -117,7 +117,6 @@ Options:
117
117
  -a, --ast Print parsed AST as JSON and exit.
118
118
  -e, --enforce-https Rewrite http:// IRIs to https:// for log dereferencing builtins.
119
119
  -h, --help Show this help and exit.
120
- -n, --no-proof-comments Disable proof explanations (default).
121
120
  -p, --proof-comments Enable proof explanations.
122
121
  -r, --strings Print log:outputString strings (ordered by key) instead of N3 output.
123
122
  -s, --super-restricted Disable all builtins except => and <=.
@@ -136,7 +135,7 @@ By default, `eyeling`:
136
135
 
137
136
  For each newly derived triple, `eyeling` prints:
138
137
 
139
- 1. a proof-style comment block explaining why the triple holds (unless `-n`), and then
138
+ 1. a proof-style comment block explaining why the triple holds, and then
140
139
  2. the triple itself in N3/Turtle syntax.
141
140
 
142
141
  The proof comments are compact “local justifications” per derived triple (not a single exported global proof tree).
@@ -0,0 +1,242 @@
1
+ # =============================================================================
2
+ # ODRL Policies with scoped NAF via log:conclusion + log:(not)Includes
3
+ #
4
+ # Pattern:
5
+ # - Put "data + rules" in a quoted KB formula
6
+ # - Compute its deductive closure with log:conclusion
7
+ # - Ask questions about what the closure entails using log:includes / log:notIncludes
8
+ #
9
+ # What you get as output:
10
+ # - :decisionStatus in { :PermitOnly, :DenyOnly, :Both, :Neither }
11
+ # - :effectiveDecision applying ODRL conflict strategy
12
+ #
13
+ # ODRL conflict strategies:
14
+ # odrl:perm => Permission overrides Prohibition
15
+ # odrl:prohibit => Prohibition overrides Permission
16
+ # odrl:invalid => Conflicts void the whole policy
17
+ # =============================================================================
18
+
19
+ @prefix : <http://example.org/odrl-paraconsistent#>.
20
+ @prefix odrl: <http://www.w3.org/ns/odrl/2/>.
21
+ @prefix log: <http://www.w3.org/2000/10/swap/log#>.
22
+ @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
23
+
24
+ # ---------------------------------------------------------------
25
+ # 1) KB formula: ODRL policies + requests + matching rules
26
+ # (kept inside a formula so raw derivations don’t clutter output)
27
+ # ---------------------------------------------------------------
28
+
29
+ :kb :hasFormula {
30
+
31
+ # ----------------------
32
+ # Assets / Parties
33
+ # ----------------------
34
+ :Report a odrl:Asset.
35
+ :Alice a odrl:Party.
36
+ :Bob a odrl:Party.
37
+
38
+ # ----------------------
39
+ # Policy Sets
40
+ # ----------------------
41
+
42
+ # Same rules, different conflict strategy:
43
+ :PS_Prohibit a odrl:Set; odrl:conflict odrl:prohibit.
44
+ :PS_Perm a odrl:Set; odrl:conflict odrl:perm.
45
+ :PS_Invalid a odrl:Set; odrl:conflict odrl:invalid.
46
+
47
+ # Rule templates (blank nodes are fine here)
48
+ # Permission: Alice may print Report for purpose Research
49
+ :PS_Prohibit odrl:permission [
50
+ odrl:target :Report;
51
+ odrl:action odrl:print;
52
+ odrl:assignee :Alice;
53
+ odrl:constraint [
54
+ odrl:leftOperand odrl:purpose;
55
+ odrl:operator odrl:eq;
56
+ odrl:rightOperand :Research
57
+ ]
58
+ ].
59
+
60
+ :PS_Perm odrl:permission [
61
+ odrl:target :Report;
62
+ odrl:action odrl:print;
63
+ odrl:assignee :Alice;
64
+ odrl:constraint [
65
+ odrl:leftOperand odrl:purpose;
66
+ odrl:operator odrl:eq;
67
+ odrl:rightOperand :Research
68
+ ]
69
+ ].
70
+
71
+ :PS_Invalid odrl:permission [
72
+ odrl:target :Report;
73
+ odrl:action odrl:print;
74
+ odrl:assignee :Alice;
75
+ odrl:constraint [
76
+ odrl:leftOperand odrl:purpose;
77
+ odrl:operator odrl:eq;
78
+ odrl:rightOperand :Research
79
+ ]
80
+ ].
81
+
82
+ # Prohibition: Alice is prohibited to print Report (no constraint => always)
83
+ :PS_Prohibit odrl:prohibition [
84
+ odrl:target :Report;
85
+ odrl:action odrl:print;
86
+ odrl:assignee :Alice
87
+ ].
88
+
89
+ :PS_Perm odrl:prohibition [
90
+ odrl:target :Report;
91
+ odrl:action odrl:print;
92
+ odrl:assignee :Alice
93
+ ].
94
+
95
+ :PS_Invalid odrl:prohibition [
96
+ odrl:target :Report;
97
+ odrl:action odrl:print;
98
+ odrl:assignee :Alice
99
+ ].
100
+
101
+ # Extra: Bob may read (permit-only example)
102
+ :PS_Prohibit odrl:permission [
103
+ odrl:target :Report;
104
+ odrl:action odrl:read;
105
+ odrl:assignee :Bob
106
+ ].
107
+
108
+ # Extra: Bob is prohibited to distribute (deny-only example)
109
+ :PS_Prohibit odrl:prohibition [
110
+ odrl:target :Report;
111
+ odrl:action odrl:distribute;
112
+ odrl:assignee :Bob
113
+ ].
114
+
115
+ # ----------------------
116
+ # Requests we want to evaluate
117
+ # ----------------------
118
+
119
+ :Req_Alice_Print_Research_Prohibit
120
+ a :Request;
121
+ :policy :PS_Prohibit;
122
+ :assignee :Alice;
123
+ :action odrl:print;
124
+ :target :Report;
125
+ :purpose :Research.
126
+
127
+ :Req_Alice_Print_Research_Perm
128
+ a :Request;
129
+ :policy :PS_Perm;
130
+ :assignee :Alice;
131
+ :action odrl:print;
132
+ :target :Report;
133
+ :purpose :Research.
134
+
135
+ :Req_Alice_Print_Research_Invalid
136
+ a :Request;
137
+ :policy :PS_Invalid;
138
+ :assignee :Alice;
139
+ :action odrl:print;
140
+ :target :Report;
141
+ :purpose :Research.
142
+
143
+ :Req_Bob_Read
144
+ a :Request;
145
+ :policy :PS_Prohibit;
146
+ :assignee :Bob;
147
+ :action odrl:read;
148
+ :target :Report.
149
+
150
+ :Req_Bob_Distribute
151
+ a :Request;
152
+ :policy :PS_Prohibit;
153
+ :assignee :Bob;
154
+ :action odrl:distribute;
155
+ :target :Report.
156
+
157
+ :Req_Bob_Archive
158
+ a :Request;
159
+ :policy :PS_Prohibit;
160
+ :assignee :Bob;
161
+ :action odrl:archive; # no rules mention this action => Neither
162
+ :target :Report.
163
+
164
+ # ----------------------
165
+ # Decision derivation rules (inside KB)
166
+ # ----------------------
167
+
168
+ # Permission without constraint
169
+ { ?req a :Request; :policy ?ps; :assignee ?who; :action ?act; :target ?asset.
170
+ ?ps odrl:permission ?perm.
171
+ ?perm odrl:assignee ?who; odrl:action ?act; odrl:target ?asset.
172
+ } => { ?req :decision :Permit. }.
173
+
174
+ # Permission with purpose constraint (eq)
175
+ { ?req a :Request; :policy ?ps; :assignee ?who; :action ?act; :target ?asset; :purpose ?purpose.
176
+ ?ps odrl:permission ?perm.
177
+ ?perm odrl:assignee ?who; odrl:action ?act; odrl:target ?asset; odrl:constraint ?c.
178
+ ?c odrl:leftOperand odrl:purpose; odrl:operator odrl:eq; odrl:rightOperand ?purpose.
179
+ } => { ?req :decision :Permit. }.
180
+
181
+ # Prohibition without constraint
182
+ { ?req a :Request; :policy ?ps; :assignee ?who; :action ?act; :target ?asset.
183
+ ?ps odrl:prohibition ?proh.
184
+ ?proh odrl:assignee ?who; odrl:action ?act; odrl:target ?asset.
185
+ } => { ?req :decision :Deny. }.
186
+ }.
187
+
188
+ # ---------------------------------------------------------------
189
+ # 2) Pull a few “queryable” facts out of the closure
190
+ # ---------------------------------------------------------------
191
+
192
+ { :kb :hasFormula ?F. ?F log:conclusion ?C.
193
+ ?C log:includes { ?req :policy ?ps. ?ps odrl:conflict ?strategy. }.
194
+ } => { ?req :conflictStrategy ?strategy. }.
195
+
196
+ # ---------------------------------------------------------------
197
+ # 3) DecisionStatus via scoped NAF on the closure
198
+ # ---------------------------------------------------------------
199
+
200
+ # Both (conflict)
201
+ { :kb :hasFormula ?F. ?F log:conclusion ?C.
202
+ ?C log:includes { ?req :decision :Permit. }.
203
+ ?C log:includes { ?req :decision :Deny. }.
204
+ } => { ?req :decisionStatus :Both. }.
205
+
206
+ # PermitOnly
207
+ { :kb :hasFormula ?F. ?F log:conclusion ?C.
208
+ ?C log:includes { ?req :decision :Permit. }.
209
+ ?C log:notIncludes { ?req :decision :Deny. }.
210
+ } => { ?req :decisionStatus :PermitOnly. }.
211
+
212
+ # DenyOnly
213
+ { :kb :hasFormula ?F. ?F log:conclusion ?C.
214
+ ?C log:includes { ?req :decision :Deny. }.
215
+ ?C log:notIncludes { ?req :decision :Permit. }.
216
+ } => { ?req :decisionStatus :DenyOnly. }.
217
+
218
+ # Neither (no applicable rules)
219
+ { :kb :hasFormula ?F. ?F log:conclusion ?C.
220
+ ?C log:notIncludes { ?req :decision :Permit. }.
221
+ ?C log:notIncludes { ?req :decision :Deny. }.
222
+ } => { ?req :decisionStatus :Neither. }.
223
+
224
+ # ---------------------------------------------------------------
225
+ # 4) Effective decision applying ODRL conflict strategy
226
+ # ---------------------------------------------------------------
227
+
228
+ # Non-conflicts
229
+ { ?req :decisionStatus :PermitOnly. } => { ?req :effectiveDecision :Permit. }.
230
+ { ?req :decisionStatus :DenyOnly. } => { ?req :effectiveDecision :Deny. }.
231
+ { ?req :decisionStatus :Neither. } => { ?req :effectiveDecision :NotSpecified. }.
232
+
233
+ # Conflicts resolved by strategy + flag in the SAME derivation
234
+ { ?req :decisionStatus :Both. ?req :conflictStrategy odrl:prohibit. }
235
+ => { ?req :effectiveDecision :Deny; :needsReview true. }.
236
+
237
+ { ?req :decisionStatus :Both. ?req :conflictStrategy odrl:perm. }
238
+ => { ?req :effectiveDecision :Permit; :needsReview true. }.
239
+
240
+ { ?req :decisionStatus :Both. ?req :conflictStrategy odrl:invalid. }
241
+ => { ?req :effectiveDecision :VoidPolicy; :needsReview true. }.
242
+
@@ -0,0 +1,22 @@
1
+ @prefix : <http://example.org/odrl-paraconsistent#> .
2
+ @prefix odrl: <http://www.w3.org/ns/odrl/2/> .
3
+
4
+ :Req_Alice_Print_Research_Prohibit :conflictStrategy odrl:prohibit .
5
+ :Req_Alice_Print_Research_Perm :conflictStrategy odrl:perm .
6
+ :Req_Alice_Print_Research_Invalid :conflictStrategy odrl:invalid .
7
+ :Req_Bob_Read :conflictStrategy odrl:prohibit .
8
+ :Req_Bob_Distribute :conflictStrategy odrl:prohibit .
9
+ :Req_Bob_Archive :conflictStrategy odrl:prohibit .
10
+ :Req_Alice_Print_Research_Prohibit :decisionStatus :Both .
11
+ :Req_Alice_Print_Research_Perm :decisionStatus :Both .
12
+ :Req_Alice_Print_Research_Invalid :decisionStatus :Both .
13
+ :Req_Bob_Read :decisionStatus :PermitOnly .
14
+ :Req_Bob_Distribute :decisionStatus :DenyOnly .
15
+ :Req_Bob_Read :effectiveDecision :Permit .
16
+ :Req_Bob_Distribute :effectiveDecision :Deny .
17
+ :Req_Alice_Print_Research_Prohibit :effectiveDecision :Deny .
18
+ :Req_Alice_Print_Research_Prohibit :needsReview true .
19
+ :Req_Alice_Print_Research_Perm :effectiveDecision :Permit .
20
+ :Req_Alice_Print_Research_Perm :needsReview true .
21
+ :Req_Alice_Print_Research_Invalid :effectiveDecision :VoidPolicy .
22
+ :Req_Alice_Print_Research_Invalid :needsReview true .
@@ -0,0 +1,38 @@
1
+ @prefix : <http://example.org/paraconsistent#> .
2
+
3
+ :tweety :canFlyStatus :Both .
4
+ :mythic :canFlyStatus :Both .
5
+ :falco :canFlyStatus :TrueOnly .
6
+ :batsy :canFlyStatus :TrueOnly .
7
+ :opus :canFlyStatus :FalseOnly .
8
+ :batsy :hasWingsStatus :Both .
9
+ :tweety :hasWingsStatus :TrueOnly .
10
+ :falco :hasWingsStatus :TrueOnly .
11
+ :mythic :hasWingsStatus :TrueOnly .
12
+ :nemo :hasWingsStatus :FalseOnly .
13
+ :tweety :inconsistent :canFly .
14
+ :tweety :needsReview :canFly .
15
+ :mythic :inconsistent :canFly .
16
+ :mythic :needsReview :canFly .
17
+ :batsy :inconsistent :hasWings .
18
+ :batsy :needsReview :hasWings .
19
+ :falco :canFlySafely true .
20
+ :batsy :canFlySafely true .
21
+ :opus :canFlySafely false .
22
+ :tweety :canFlySafely :Undecided .
23
+ :mythic :canFlySafely :Undecided .
24
+ :tweety :hasWingsSafely true .
25
+ :falco :hasWingsSafely true .
26
+ :mythic :hasWingsSafely true .
27
+ :nemo :hasWingsSafely false .
28
+ :batsy :hasWingsSafely :Undecided .
29
+ :falco :movesBySafely :Flying .
30
+ :falco :migratesSafely true .
31
+ :batsy :movesBySafely :Flying .
32
+ :batsy :migratesSafely true .
33
+ :opus :movesBySafely :Walking .
34
+ :opus :migratesSafely false .
35
+ :tweety :movesBySafely :Unknown .
36
+ :tweety :migratesSafely :Undecided .
37
+ :mythic :movesBySafely :Unknown .
38
+ :mythic :migratesSafely :Undecided .
@@ -0,0 +1,109 @@
1
+ # =============================================================================
2
+ # Paraconsistent N3 example
3
+ #
4
+ # What it demonstrates:
5
+ # 1) Contradictions tolerated: we can have both :p true and :p false.
6
+ # 2) Scoped NAF via deductive closure:
7
+ # - compute closure with log:conclusion
8
+ # - check "absence" using log:notIncludes (scoped NAF)
9
+ # - check "presence" using log:includes
10
+ # 3) Only meaningful derivations are materialized:
11
+ # - raw/possibly-contradictory facts are kept inside a quoted KB graph
12
+ # - we only output statuses + "safe" summaries
13
+ # =============================================================================
14
+
15
+ @prefix : <http://example.org/paraconsistent#>.
16
+ @prefix log: <http://www.w3.org/2000/10/swap/log#>.
17
+
18
+ # ---------------------------------------------------------------
19
+ # 1) Knowledge base (data + domain rules) stored as a graph term
20
+ # (so its internal derivations are not printed as top-level output)
21
+ # ---------------------------------------------------------------
22
+
23
+ :kb :hasFormula {
24
+
25
+ # --- Data (intentionally inconsistent in places) ---
26
+ :tweety a :Bird, :Penguin.
27
+ :falco a :Bird.
28
+ :opus a :Penguin.
29
+ :batsy a :Mammal, :Bat.
30
+ :nemo a :Fish.
31
+
32
+ # explicit observation that conflicts with "Birds fly"
33
+ :mythic a :Bird.
34
+ :mythic :canFly false.
35
+
36
+ # --- Domain rules that may conflict ---
37
+ { ?x a :Bird. } => { ?x :canFly true. ?x :hasWings true. }.
38
+ { ?x a :Penguin. } => { ?x :canFly false. }.
39
+
40
+ { ?x a :Mammal. } => { ?x :hasWings false. }.
41
+ { ?x a :Bat. } => { ?x :hasWings true. ?x :canFly true. }.
42
+
43
+ { ?x a :Fish. } => { ?x :canSwim true. ?x :hasWings false. }.
44
+ }.
45
+
46
+ # ---------------------------------------------------------------
47
+ # 2) Status computation using:
48
+ # ?KB log:conclusion ?C .
49
+ # ?C log:includes / log:notIncludes { ... } .
50
+ #
51
+ # Status values: :TrueOnly / :FalseOnly / :Both
52
+ # ---------------------------------------------------------------
53
+
54
+ # Helper: get the closure once per match (no need to print it)
55
+ { :kb :hasFormula ?F. ?F log:conclusion ?C.
56
+ ?C log:includes { ?x :canFly true. }.
57
+ ?C log:includes { ?x :canFly false. }.
58
+ } => { ?x :canFlyStatus :Both. }.
59
+
60
+ { :kb :hasFormula ?F. ?F log:conclusion ?C.
61
+ ?C log:includes { ?x :canFly true. }.
62
+ ?C log:notIncludes { ?x :canFly false. }.
63
+ } => { ?x :canFlyStatus :TrueOnly. }.
64
+
65
+ { :kb :hasFormula ?F. ?F log:conclusion ?C.
66
+ ?C log:includes { ?x :canFly false. }.
67
+ ?C log:notIncludes { ?x :canFly true. }.
68
+ } => { ?x :canFlyStatus :FalseOnly. }.
69
+
70
+
71
+ { :kb :hasFormula ?F. ?F log:conclusion ?C.
72
+ ?C log:includes { ?x :hasWings true. }.
73
+ ?C log:includes { ?x :hasWings false. }.
74
+ } => { ?x :hasWingsStatus :Both. }.
75
+
76
+ { :kb :hasFormula ?F. ?F log:conclusion ?C.
77
+ ?C log:includes { ?x :hasWings true. }.
78
+ ?C log:notIncludes { ?x :hasWings false. }.
79
+ } => { ?x :hasWingsStatus :TrueOnly. }.
80
+
81
+ { :kb :hasFormula ?F. ?F log:conclusion ?C.
82
+ ?C log:includes { ?x :hasWings false. }.
83
+ ?C log:notIncludes { ?x :hasWings true. }.
84
+ } => { ?x :hasWingsStatus :FalseOnly. }.
85
+
86
+ # ---------------------------------------------------------------
87
+ # 3) Localize inconsistencies (paraconsistent: flag, don't explode)
88
+ # ---------------------------------------------------------------
89
+
90
+ { ?x :canFlyStatus :Both. } => { ?x :inconsistent :canFly. ?x :needsReview :canFly. }.
91
+ { ?x :hasWingsStatus :Both. } => { ?x :inconsistent :hasWings. ?x :needsReview :hasWings. }.
92
+
93
+ # ---------------------------------------------------------------
94
+ # 4) Meaningful materialized summaries ("safe" single-valued views)
95
+ # ---------------------------------------------------------------
96
+
97
+ { ?x :canFlyStatus :TrueOnly. } => { ?x :canFlySafely true. }.
98
+ { ?x :canFlyStatus :FalseOnly. } => { ?x :canFlySafely false. }.
99
+ { ?x :canFlyStatus :Both. } => { ?x :canFlySafely :Undecided. }.
100
+
101
+ { ?x :hasWingsStatus :TrueOnly. } => { ?x :hasWingsSafely true. }.
102
+ { ?x :hasWingsStatus :FalseOnly. } => { ?x :hasWingsSafely false. }.
103
+ { ?x :hasWingsStatus :Both. } => { ?x :hasWingsSafely :Undecided. }.
104
+
105
+ # Safe behavior derived only from the safe canFlyStatus
106
+ { ?x :canFlyStatus :TrueOnly. } => { ?x :movesBySafely :Flying. ?x :migratesSafely true. }.
107
+ { ?x :canFlyStatus :FalseOnly. } => { ?x :movesBySafely :Walking. ?x :migratesSafely false. }.
108
+ { ?x :canFlyStatus :Both. } => { ?x :movesBySafely :Unknown. ?x :migratesSafely :Undecided. }.
109
+
package/eyeling.js CHANGED
@@ -7449,7 +7449,6 @@ function main() {
7449
7449
  ` -a, --ast Print parsed AST as JSON and exit.\n` +
7450
7450
  ` -e, --enforce-https Rewrite http:// IRIs to https:// for log dereferencing builtins.\n` +
7451
7451
  ` -h, --help Show this help and exit.\n` +
7452
- ` -n, --no-proof-comments Disable proof explanations (default).\n` +
7453
7452
  ` -p, --proof-comments Enable proof explanations.\n` +
7454
7453
  ` -r, --strings Print log:outputString strings (ordered by key) instead of N3 output.\n` +
7455
7454
  ` -s, --super-restricted Disable all builtins except => and <=.\n` +
@@ -7488,12 +7487,6 @@ function main() {
7488
7487
  proofCommentsEnabled = true;
7489
7488
  }
7490
7489
 
7491
- // --no-proof-comments / -n: disable proof explanations (default)
7492
- // Keep this after --proof-comments so -n wins if both are present.
7493
- if (argv.includes('--no-proof-comments') || argv.includes('-n')) {
7494
- proofCommentsEnabled = false;
7495
- }
7496
-
7497
7490
  // --super-restricted / -s: disable all builtins except => / <=
7498
7491
  if (argv.includes('--super-restricted') || argv.includes('-s')) {
7499
7492
  superRestrictedMode = true;
package/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ declare module 'eyeling' {
2
+ export function reason(opts:any,input: string): string;
3
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.8.1",
3
+ "version": "1.8.3",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [
@@ -17,8 +17,10 @@
17
17
  "bin": {
18
18
  "eyeling": "./eyeling.js"
19
19
  },
20
+ "types": "./index.d.ts",
20
21
  "files": [
21
22
  "index.js",
23
+ "index.d.ts",
22
24
  "eyeling.js",
23
25
  "eyeling-builtins.ttl",
24
26
  "test",