eyeling 1.5.7

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 (4) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +188 -0
  3. package/eyeling.js +3945 -0
  4. package/package.json +27 -0
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ ### Copyright 2021-2025 Jos De Roo, KNoWS office of IDLab, Ghent University - imec
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,188 @@
1
+ # eyeling
2
+
3
+ A minimal [Notation3 (N3)](https://notation3.org/) reasoner in **JavaScript**.
4
+
5
+ `eyeling` is:
6
+
7
+ - a single self-contained file (`eyeling.js`, no external deps),
8
+ - intentionally tiny and close in spirit to EYE,
9
+ - a practical N3/Turtle superset (enough for lots of real rulesets),
10
+ - supports forward (`=>`) + backward (`<=`) chaining over Horn-style rules,
11
+ - prints only newly derived forward facts, optionally preceded by compact proof comments,
12
+ - we never want to leak raw data, hence pass-only-new and backward rules for functions that work with raw data, and of course we also keep all reasoning in the browser.
13
+
14
+ ## Playground (in your browser)
15
+
16
+ Try it here:
17
+
18
+ - [Eyeling playground](https://eyereasoner.github.io/eyeling/demo)
19
+
20
+ The playground runs `eyeling` client-side. You can:
21
+ - edit an N3 program directly,
22
+ - load an N3 program from a URL,
23
+ - share a link with the program encoded in the URL fragment (`#...`).
24
+
25
+ ### Example (Socrates)
26
+
27
+ This link preloads a small “Socrates is Mortal” ruleset:
28
+
29
+ [Socrates example](https://eyereasoner.github.io/eyeling/demo#%23%20------------------%0A%23%20Socrates%20inference%0A%23%20------------------%0A%0A%40prefix%20rdfs%3A%20%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E.%0A%40prefix%20%3A%20%3Chttp%3A%2F%2Fexample.org%2Fsocrates%23%3E.%0A%0A%23%20facts%0A%3ASocrates%20a%20%3AHuman.%0A%3AHuman%20rdfs%3AsubClassOf%20%3AMortal.%0A%0A%23%20subclass%20rule%0A%7B%0A%20%20%20%20%3FS%20a%20%3FA.%0A%20%20%20%20%3FA%20rdfs%3AsubClassOf%20%3FB.%0A%7D%20%3D%3E%20%7B%0A%20%20%20%20%3FS%20a%20%3FB.%0A%7D%2E%0A)
30
+
31
+ ## Quick start (Node.js)
32
+
33
+ ### Requirements
34
+
35
+ - A reasonably recent Node.js (anything modern with `BigInt` support is fine).
36
+
37
+ ### Run a single file
38
+
39
+ From the repo root:
40
+
41
+ ```bash
42
+ # Option 1: use the shebang (Unix-like)
43
+ ./eyeling.js examples/socrates.n3
44
+
45
+ # Option 2: explicit node
46
+ node eyeling.js examples/socrates.n3
47
+ ```
48
+
49
+ By default, `eyeling`:
50
+
51
+ 1. parses the input (facts + rules),
52
+ 2. runs **forward chaining to a fixpoint**,
53
+ 3. prints only **newly derived forward facts** (not the original input facts),
54
+ 4. prints a compact per-triple explanation as `#` comments (can be disabled).
55
+
56
+ ### Options
57
+
58
+ ```bash
59
+ node eyeling.js --version
60
+ node eyeling.js -v
61
+
62
+ # Disable proof comments (print only derived triples)
63
+ node eyeling.js --no-proof-comments examples/socrates.n3
64
+ node eyeling.js -n examples/socrates.n3
65
+ ```
66
+
67
+ ### Run all examples
68
+
69
+ ```bash
70
+ cd examples
71
+ ./test
72
+ ```
73
+
74
+ This runs `eyeling.js` over each example and compares against the golden outputs in `examples/output`.
75
+
76
+ ## What output do I get?
77
+
78
+ For each newly derived triple, `eyeling` prints:
79
+
80
+ 1. a proof-style comment block explaining why the triple holds (unless `-n`), and then
81
+ 2. the triple itself in N3/Turtle syntax.
82
+
83
+ The proof comments are compact “local justifications” per derived triple (not a single exported global proof tree).
84
+
85
+ ## Reasoning model
86
+
87
+ ### Forward + backward chaining
88
+
89
+ * **Forward chaining to fixpoint** for forward rules written as `{ P } => { C } .`
90
+ * **Backward chaining (SLD-style)** for backward rules written as `{ H } <= { B } .` and for built-ins.
91
+
92
+ Forward rule premises are proved using:
93
+
94
+ * ground facts (input + derived),
95
+ * backward rules,
96
+ * built-ins.
97
+
98
+ The CLI prints only newly derived forward facts.
99
+
100
+ ### Performance notes (current engine)
101
+
102
+ `eyeling` stays tiny, but includes a few key performance mechanisms:
103
+
104
+ * facts are indexed for matching:
105
+
106
+ * by predicate, and (when possible) by **(predicate, object)** (important for type-heavy workloads),
107
+ * duplicate detection uses a fast key path when a triple is fully IRI/Literal-shaped,
108
+ * backward rules are indexed by head predicate,
109
+ * the backward prover is **iterative** (explicit stack), so deep chains won’t blow the JS call stack,
110
+ * for very deep backward chains, substitutions may be compactified (semantics-preserving) to avoid quadratic “copy a growing substitution object” behavior.
111
+
112
+ ## Parsing: practical N3 subset
113
+
114
+ Supported:
115
+
116
+ * `@prefix` / `@base`
117
+ * triples with `;` and `,`
118
+ * variables `?x`
119
+ * blank nodes:
120
+
121
+ * anonymous `[]`
122
+ * property lists `[ :p :o; :q :r ]`
123
+ * collections `( ... )`
124
+ * quoted formulas `{ ... }`
125
+ * implications:
126
+
127
+ * forward rules `{ P } => { C } .`
128
+ * backward rules `{ H } <= { B } .`
129
+ * datatyped literals with `^^`
130
+ * `#` line comments
131
+
132
+ Non-goals / current limits:
133
+
134
+ * not a full W3C N3 grammar (some edge cases for identifiers, quantifiers, advanced syntax),
135
+ * quoted formulas are matched as whole formulas (no pattern matching inside formulas yet),
136
+ * proof output is local per derived triple (not a global exported proof tree).
137
+
138
+ ## Blank nodes and quantification (pragmatic N3/EYE-style)
139
+
140
+ `eyeling` follows the usual N3 intuition:
141
+
142
+ 1. blank nodes in facts are normal RDF blanks (`_:b1`, `_:b2`, … within a run),
143
+ 2. blank nodes in rule premises behave like rule-scoped universals (similar to variables),
144
+ 3. blank nodes only in rule conclusions behave like existentials:
145
+ each rule firing generates fresh Skolem blanks (`_:sk_0`, `_:sk_1`, …).
146
+
147
+ Equal facts up to renaming of Skolem IDs are treated as duplicates and are not re-added.
148
+
149
+ ## Rule-producing rules (meta-rules)
150
+
151
+ `eyeling` understands the `log:implies` / `log:impliedBy` idiom:
152
+
153
+ Top level:
154
+
155
+ * `{ P } log:implies { C } .` becomes a forward rule `{ P } => { C } .`
156
+ * `{ H } log:impliedBy { B } .` becomes a backward rule `{ H } <= { B } .`
157
+
158
+ During reasoning:
159
+
160
+ * any **derived** `log:implies` / `log:impliedBy` triple with formula subject/object is turned into a new live forward/backward rule.
161
+
162
+ ## Inference fuse — `{ ... } => false.`
163
+
164
+ Rules whose conclusion is `false` are treated as hard failures:
165
+
166
+ ```n3
167
+ :stone :color :black .
168
+ :stone :color :white .
169
+ { ?X :color :black . ?X :color :white . } => false.
170
+ ```
171
+
172
+ As soon as the premise is provable, `eyeling` exits with status code `2`.
173
+
174
+ ## Built-ins (overview)
175
+
176
+ `eyeling` implements a pragmatic subset of common N3 builtin families and evaluates them during backward goal proving:
177
+
178
+ * **crypto**: `crypto:md5` `crypto:sha` `crypto:sha256` `crypto:sha512`
179
+ * **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`
180
+ * **log**: `log:collectAllIn` `log:equalTo` `log:forAllIn` `log:impliedBy` `log:implies` `log:notEqualTo` `log:notIncludes` `log:skolem` `log:uri`
181
+ * **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`
182
+ * **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`
183
+ * **time**: `time:localTime`
184
+
185
+
186
+ ## License
187
+
188
+ MIT (see [LICENSE](https://github.com/eyereasoner/eyeling/blob/main/LICENSE.md)).