eyeling 1.18.0 → 1.18.2
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/HANDBOOK.md +175 -12
- package/README.md +5 -207
- package/examples/sudoku.n3 +1 -1
- package/package.json +1 -1
package/HANDBOOK.md
CHANGED
|
@@ -1767,7 +1767,41 @@ For fully stream-oriented RDF/JS consumers there is also `reasonRdfJs(...)`, whi
|
|
|
1767
1767
|
|
|
1768
1768
|
Eyeling exposes itself in three layers.
|
|
1769
1769
|
|
|
1770
|
-
### 14.1
|
|
1770
|
+
### 14.1 Install and first run
|
|
1771
|
+
|
|
1772
|
+
Eyeling targets modern JavaScript runtimes. For the npm package and CLI workflow, use **Node.js 18 or newer**.
|
|
1773
|
+
|
|
1774
|
+
Install from npm:
|
|
1775
|
+
|
|
1776
|
+
```bash
|
|
1777
|
+
npm i eyeling
|
|
1778
|
+
```
|
|
1779
|
+
|
|
1780
|
+
Run a file:
|
|
1781
|
+
|
|
1782
|
+
```bash
|
|
1783
|
+
npx eyeling examples/socrates.n3
|
|
1784
|
+
```
|
|
1785
|
+
|
|
1786
|
+
Show the available options:
|
|
1787
|
+
|
|
1788
|
+
```bash
|
|
1789
|
+
npx eyeling --help
|
|
1790
|
+
```
|
|
1791
|
+
|
|
1792
|
+
A few practical defaults are worth remembering:
|
|
1793
|
+
|
|
1794
|
+
- In normal mode, Eyeling prints **newly derived forward facts**.
|
|
1795
|
+
- If the input contains top-level `log:query` directives, Eyeling prints the **query-selected conclusion triples** instead.
|
|
1796
|
+
- If the final closure contains any `log:outputString` triples, Eyeling renders those strings instead of emitting the default N3 result set.
|
|
1797
|
+
|
|
1798
|
+
Custom builtins can be loaded explicitly from the CLI:
|
|
1799
|
+
|
|
1800
|
+
```bash
|
|
1801
|
+
npx eyeling --builtin lib/builtin-sudoku.js examples/sudoku.n3
|
|
1802
|
+
```
|
|
1803
|
+
|
|
1804
|
+
### 14.2 The bundled CLI (`eyeling.js`)
|
|
1771
1805
|
|
|
1772
1806
|
The bundle contains the whole engine. The CLI path is the “canonical behavior”:
|
|
1773
1807
|
|
|
@@ -1777,7 +1811,7 @@ The bundle contains the whole engine. The CLI path is the “canonical behavior
|
|
|
1777
1811
|
- optional proof comments
|
|
1778
1812
|
- optional streaming
|
|
1779
1813
|
|
|
1780
|
-
#### 14.
|
|
1814
|
+
#### 14.2.1 CLI options at a glance
|
|
1781
1815
|
|
|
1782
1816
|
The current CLI supports a small set of flags (see `lib/cli.js`):
|
|
1783
1817
|
|
|
@@ -1790,7 +1824,7 @@ The current CLI supports a small set of flags (see `lib/cli.js`):
|
|
|
1790
1824
|
- `-v`, `--version` — print version and exit.
|
|
1791
1825
|
- `-h`, `--help` — show usage.
|
|
1792
1826
|
|
|
1793
|
-
### 14.
|
|
1827
|
+
### 14.3 `lib/entry.js`: bundler-friendly exports
|
|
1794
1828
|
|
|
1795
1829
|
`lib/entry.js` exports:
|
|
1796
1830
|
|
|
@@ -1799,7 +1833,14 @@ The current CLI supports a small set of flags (see `lib/cli.js`):
|
|
|
1799
1833
|
|
|
1800
1834
|
`rdfjs` is a small built-in RDF/JS `DataFactory`, so browser / worker code can construct quads without pulling in another package first.
|
|
1801
1835
|
|
|
1802
|
-
### 14.
|
|
1836
|
+
### 14.4 JavaScript API
|
|
1837
|
+
|
|
1838
|
+
Eyeling exposes two JavaScript entry styles:
|
|
1839
|
+
|
|
1840
|
+
- `reason(...)` from `index.js` when you want the same text output as the CLI
|
|
1841
|
+
- `reasonStream(...)` / `reasonRdfJs(...)` from the bundle entry when you want in-process reasoning and structured RDF/JS results
|
|
1842
|
+
|
|
1843
|
+
#### 14.4.1 npm helper: `reason(...)`
|
|
1803
1844
|
|
|
1804
1845
|
The npm `reason(...)` function does something intentionally simple and robust:
|
|
1805
1846
|
|
|
@@ -1810,19 +1851,141 @@ The npm `reason(...)` function does something intentionally simple and robust:
|
|
|
1810
1851
|
|
|
1811
1852
|
This keeps the observable output identical to the CLI while still allowing richer JS-side inputs.
|
|
1812
1853
|
|
|
1813
|
-
|
|
1854
|
+
CommonJS:
|
|
1855
|
+
|
|
1856
|
+
```js
|
|
1857
|
+
const { reason } = require('eyeling');
|
|
1858
|
+
|
|
1859
|
+
const input = `
|
|
1860
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
|
|
1861
|
+
@prefix : <http://example.org/socrates#>.
|
|
1862
|
+
|
|
1863
|
+
:Socrates a :Human.
|
|
1864
|
+
:Human rdfs:subClassOf :Mortal.
|
|
1865
|
+
|
|
1866
|
+
{ ?s a ?A. ?A rdfs:subClassOf ?B. } => { ?s a ?B. }.
|
|
1867
|
+
`;
|
|
1868
|
+
|
|
1869
|
+
console.log(reason({ proofComments: false }, input));
|
|
1870
|
+
```
|
|
1871
|
+
|
|
1872
|
+
ESM:
|
|
1873
|
+
|
|
1874
|
+
```js
|
|
1875
|
+
import eyeling from 'eyeling';
|
|
1876
|
+
|
|
1877
|
+
const input = `
|
|
1878
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
|
|
1879
|
+
@prefix : <http://example.org/socrates#>.
|
|
1880
|
+
|
|
1881
|
+
:Socrates a :Human.
|
|
1882
|
+
:Human rdfs:subClassOf :Mortal.
|
|
1883
|
+
|
|
1884
|
+
{ ?s a ?A. ?A rdfs:subClassOf ?B. } => { ?s a ?B. }.
|
|
1885
|
+
`;
|
|
1886
|
+
|
|
1887
|
+
console.log(eyeling.reason({ proofComments: false }, input));
|
|
1888
|
+
```
|
|
1889
|
+
|
|
1890
|
+
Notes:
|
|
1891
|
+
|
|
1892
|
+
- `reason()` returns the same textual output you would get from the CLI for the same input and options.
|
|
1893
|
+
- By default, the npm helper keeps output machine-friendly (`proofComments: false`).
|
|
1894
|
+
- Use this path when you want CLI-equivalent behavior inside JavaScript.
|
|
1895
|
+
|
|
1896
|
+
#### 14.4.2 RDF-JS and Eyeling rule-object interoperability
|
|
1897
|
+
|
|
1898
|
+
The JavaScript APIs accept three input styles:
|
|
1899
|
+
|
|
1900
|
+
1. plain N3 text
|
|
1901
|
+
2. RDF/JS fact input (`quads`, `facts`, or `dataset`)
|
|
1902
|
+
3. Eyeling rule objects or full AST bundles
|
|
1903
|
+
|
|
1904
|
+
If you want to use N3 source text, pass the whole input as a plain string.
|
|
1905
|
+
|
|
1906
|
+
For RDF/JS facts, the graph must be the default graph. Named-graph quads are rejected.
|
|
1907
|
+
|
|
1908
|
+
If you already have rules in structured form, Eyeling rule objects can be passed directly in the API:
|
|
1909
|
+
|
|
1910
|
+
```js
|
|
1911
|
+
const { reason, rdfjs } = require('eyeling');
|
|
1912
|
+
|
|
1913
|
+
const ex = 'http://example.org/';
|
|
1914
|
+
|
|
1915
|
+
const rule = {
|
|
1916
|
+
_type: 'Rule',
|
|
1917
|
+
premise: [
|
|
1918
|
+
{
|
|
1919
|
+
_type: 'Triple',
|
|
1920
|
+
s: { _type: 'Var', name: 'x' },
|
|
1921
|
+
p: { _type: 'Iri', value: ex + 'parent' },
|
|
1922
|
+
o: { _type: 'Var', name: 'y' },
|
|
1923
|
+
},
|
|
1924
|
+
],
|
|
1925
|
+
conclusion: [
|
|
1926
|
+
{
|
|
1927
|
+
_type: 'Triple',
|
|
1928
|
+
s: { _type: 'Var', name: 'x' },
|
|
1929
|
+
p: { _type: 'Iri', value: ex + 'ancestor' },
|
|
1930
|
+
o: { _type: 'Var', name: 'y' },
|
|
1931
|
+
},
|
|
1932
|
+
],
|
|
1933
|
+
isForward: true,
|
|
1934
|
+
isFuse: false,
|
|
1935
|
+
headBlankLabels: [],
|
|
1936
|
+
};
|
|
1937
|
+
|
|
1938
|
+
const out = reason(
|
|
1939
|
+
{ proofComments: false },
|
|
1940
|
+
{
|
|
1941
|
+
quads: [rdfjs.quad(rdfjs.namedNode(ex + 'alice'), rdfjs.namedNode(ex + 'parent'), rdfjs.namedNode(ex + 'bob'))],
|
|
1942
|
+
rules: [rule],
|
|
1943
|
+
},
|
|
1944
|
+
);
|
|
1945
|
+
|
|
1946
|
+
console.log(out);
|
|
1947
|
+
```
|
|
1948
|
+
|
|
1949
|
+
You can also pass a full AST bundle directly, for example `[prefixes, triples, forwardRules, backwardRules]`.
|
|
1950
|
+
|
|
1951
|
+
#### 14.4.3 In-process bundle API: `reasonStream(...)` and `reasonRdfJs(...)`
|
|
1952
|
+
|
|
1953
|
+
Use the bundle entry if you want structured results while the engine is running instead of final CLI text after the fact.
|
|
1954
|
+
|
|
1955
|
+
`reasonStream(...)` can emit RDF/JS quads while reasoning runs:
|
|
1956
|
+
|
|
1957
|
+
```js
|
|
1958
|
+
import eyeling from './eyeling.js';
|
|
1959
|
+
|
|
1960
|
+
const result = eyeling.reasonStream(input, {
|
|
1961
|
+
proof: false,
|
|
1962
|
+
onDerived: ({ quad }) => {
|
|
1963
|
+
if (quad) console.log(quad);
|
|
1964
|
+
},
|
|
1965
|
+
});
|
|
1966
|
+
```
|
|
1967
|
+
|
|
1968
|
+
That same path also lets derived results be consumed as an async stream of RDF/JS quads:
|
|
1969
|
+
|
|
1970
|
+
```js
|
|
1971
|
+
for await (const quad of eyeling.reasonRdfJs(input)) {
|
|
1972
|
+
console.log(quad);
|
|
1973
|
+
}
|
|
1974
|
+
```
|
|
1814
1975
|
|
|
1815
|
-
|
|
1816
|
-
- RDF/JS fact inputs (`quads`, `facts`, or `dataset`)
|
|
1817
|
-
- Eyeling rule objects or full AST bundles like `[prefixes, triples, frules, brules]`
|
|
1976
|
+
Use these entry points when you need one or more of the following:
|
|
1818
1977
|
|
|
1819
|
-
|
|
1978
|
+
- RDF/JS quads as fact input
|
|
1979
|
+
- Eyeling rule objects passed directly from JavaScript
|
|
1980
|
+
- derived results consumed as RDF/JS quads
|
|
1981
|
+
- streaming derived RDF/JS quads during reasoning
|
|
1820
1982
|
|
|
1821
|
-
|
|
1983
|
+
### 14.5 Choosing the right entry point
|
|
1822
1984
|
|
|
1823
|
-
|
|
1985
|
+
A practical rule of thumb:
|
|
1824
1986
|
|
|
1825
|
-
- if you want
|
|
1987
|
+
- if you want the same final text output as the CLI, use `reason(...)`
|
|
1988
|
+
- if you want in-process access to structured facts, quads, or streaming derivations, use `reasonStream(...)` / `reasonRdfJs(...)`
|
|
1826
1989
|
|
|
1827
1990
|
---
|
|
1828
1991
|
|
package/README.md
CHANGED
|
@@ -4,218 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
A compact [Notation3 (N3)](https://notation3.org/) reasoner in **JavaScript**.
|
|
6
6
|
|
|
7
|
-
- Single self-contained bundle (`eyeling.js`), no external runtime dependencies
|
|
8
|
-
- Forward (`=>`) and backward (`<=`) chaining over Horn-style rules
|
|
9
|
-
- **CLI / npm `reason()` output is mode-dependent by default**: it prints **newly derived forward facts** in normal mode, or (when top-level `{ ... } log:query { ... }.` directives are present) the **unique instantiated conclusion triples** of those queries, optionally with compact proof comments
|
|
10
|
-
- Works in Node.js and fully client-side (browser/worker)
|
|
11
|
-
|
|
12
|
-
## Links
|
|
13
|
-
|
|
14
|
-
- **Handbook:** [https://eyereasoner.github.io/eyeling/HANDBOOK](https://eyereasoner.github.io/eyeling/HANDBOOK)
|
|
15
|
-
- **Semantics:** [https://eyereasoner.github.io/eyeling/SEMANTICS](https://eyereasoner.github.io/eyeling/SEMANTICS)
|
|
16
|
-
- **Playground:** [https://eyereasoner.github.io/eyeling/demo](https://eyereasoner.github.io/eyeling/demo)
|
|
17
|
-
- **Conformance report:** [https://codeberg.org/phochste/notation3tests/src/branch/main/reports/report.md](https://codeberg.org/phochste/notation3tests/src/branch/main/reports/report.md)
|
|
18
|
-
|
|
19
|
-
Eyeling is regularly checked against the community Notation3 test suite. If you want implementation details (parser, unifier, proof search, skolemization, scoped closure, builtins), start with the handbook.
|
|
20
|
-
|
|
21
7
|
## Quick start
|
|
22
8
|
|
|
23
|
-
### Requirements
|
|
24
|
-
|
|
25
|
-
- Node.js >= 18
|
|
26
|
-
|
|
27
|
-
### Install
|
|
28
|
-
|
|
29
9
|
```bash
|
|
30
10
|
npm i eyeling
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## CLI usage
|
|
34
|
-
|
|
35
|
-
Run on a file:
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
11
|
npx eyeling examples/socrates.n3
|
|
39
12
|
```
|
|
40
13
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
npx eyeling --help
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Useful flags include `--proof-comments`, `--stream`, and `--enforce-https`. If the final closure contains any `log:outputString` triples, Eyeling now renders those strings automatically instead of printing N3 output.
|
|
48
|
-
|
|
49
|
-
## What gets printed?
|
|
50
|
-
|
|
51
|
-
### Normal mode (default)
|
|
52
|
-
|
|
53
|
-
Without top-level `log:query` directives, Eyeling prints **newly derived forward facts** by default.
|
|
54
|
-
|
|
55
|
-
### `log:query` mode (output selection)
|
|
56
|
-
|
|
57
|
-
If the input contains one or more **top-level** directives of the form:
|
|
58
|
-
|
|
59
|
-
```n3
|
|
60
|
-
{ ?x a :Human. } log:query { ?x a :Mortal. }.
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
Eyeling still computes the saturated forward closure, but it **prints only** the **unique instantiated conclusion triples** of those `log:query` directives (instead of all newly derived forward facts).
|
|
64
|
-
|
|
65
|
-
## JavaScript API
|
|
66
|
-
|
|
67
|
-
### npm helper: `reason()`
|
|
68
|
-
|
|
69
|
-
CommonJS:
|
|
70
|
-
|
|
71
|
-
```js
|
|
72
|
-
const { reason } = require('eyeling');
|
|
73
|
-
|
|
74
|
-
const input = `
|
|
75
|
-
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
|
|
76
|
-
@prefix : <http://example.org/socrates#>.
|
|
77
|
-
|
|
78
|
-
:Socrates a :Human.
|
|
79
|
-
:Human rdfs:subClassOf :Mortal.
|
|
80
|
-
|
|
81
|
-
{ ?s a ?A. ?A rdfs:subClassOf ?B. } => { ?s a ?B. }.
|
|
82
|
-
`;
|
|
83
|
-
|
|
84
|
-
console.log(reason({ proofComments: false }, input));
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
ESM:
|
|
88
|
-
|
|
89
|
-
```js
|
|
90
|
-
import eyeling from 'eyeling';
|
|
91
|
-
|
|
92
|
-
console.log(eyeling.reason({ proofComments: false }, input));
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
Notes:
|
|
96
|
-
|
|
97
|
-
- `reason()` returns the same textual output you would get from the CLI for the same input/options.
|
|
98
|
-
- By default, the npm helper keeps output machine-friendly (`proofComments: false`).
|
|
99
|
-
- The npm helper shells out to the bundled `eyeling.js` CLI for simplicity and robustness.
|
|
100
|
-
|
|
101
|
-
### RDF/JS and Eyeling rule-object interop
|
|
102
|
-
|
|
103
|
-
The JavaScript APIs now accept three input styles:
|
|
104
|
-
|
|
105
|
-
1. plain N3 text
|
|
106
|
-
2. RDF/JS facts (`quads`, `facts`, or `dataset`)
|
|
107
|
-
3. Eyeling rule objects / AST bundles (the same shapes you get from `eyeling --ast`)
|
|
108
|
-
|
|
109
|
-
If you want to use N3 source text, pass the whole input as a plain N3 string.
|
|
110
|
-
|
|
111
|
-
For RDF/JS facts, the graph must be the default graph. Named-graph quads are rejected.
|
|
112
|
-
|
|
113
|
-
For structured inputs, `rules` is supplied as current Eyeling rule objects:
|
|
114
|
-
|
|
115
|
-
```js
|
|
116
|
-
const { reason, rdfjs } = require('eyeling');
|
|
117
|
-
|
|
118
|
-
const ex = 'http://example.org/';
|
|
119
|
-
|
|
120
|
-
const rule = {
|
|
121
|
-
_type: 'Rule',
|
|
122
|
-
premise: [
|
|
123
|
-
{
|
|
124
|
-
_type: 'Triple',
|
|
125
|
-
s: { _type: 'Var', name: 'x' },
|
|
126
|
-
p: { _type: 'Iri', value: ex + 'parent' },
|
|
127
|
-
o: { _type: 'Var', name: 'y' },
|
|
128
|
-
},
|
|
129
|
-
],
|
|
130
|
-
conclusion: [
|
|
131
|
-
{
|
|
132
|
-
_type: 'Triple',
|
|
133
|
-
s: { _type: 'Var', name: 'x' },
|
|
134
|
-
p: { _type: 'Iri', value: ex + 'ancestor' },
|
|
135
|
-
o: { _type: 'Var', name: 'y' },
|
|
136
|
-
},
|
|
137
|
-
],
|
|
138
|
-
isForward: true,
|
|
139
|
-
isFuse: false,
|
|
140
|
-
headBlankLabels: [],
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
const out = reason(
|
|
144
|
-
{ proofComments: false },
|
|
145
|
-
{
|
|
146
|
-
quads: [rdfjs.quad(rdfjs.namedNode(ex + 'alice'), rdfjs.namedNode(ex + 'parent'), rdfjs.namedNode(ex + 'bob'))],
|
|
147
|
-
rules: [rule],
|
|
148
|
-
},
|
|
149
|
-
);
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
You can also pass a full AST bundle directly:
|
|
153
|
-
|
|
154
|
-
```js
|
|
155
|
-
const ast = [prefixes, triples, forwardRules, backwardRules];
|
|
156
|
-
const out2 = reason({ proofComments: false }, ast);
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
### Direct bundle / browser-worker API: `reasonStream()`
|
|
160
|
-
|
|
161
|
-
For in-process reasoning (browser, worker, or direct use of `eyeling.js`):
|
|
162
|
-
|
|
163
|
-
```js
|
|
164
|
-
const result = eyeling.reasonStream(input, {
|
|
165
|
-
proof: false,
|
|
166
|
-
onDerived: ({ triple }) => console.log(triple),
|
|
167
|
-
// includeInputFactsInClosure: false,
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
console.log(result.closureN3);
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
`eyeling.js` now also exposes `eyeling.rdfjs` and `eyeling.reasonRdfJs(...)` for RDF/JS workflows.
|
|
174
|
-
|
|
175
|
-
#### `reasonStream()` output behavior
|
|
176
|
-
|
|
177
|
-
`closureN3` is also mode-dependent:
|
|
178
|
-
|
|
179
|
-
- **Normal mode:** by default, `closureN3` is the closure (**input facts + derived facts**)
|
|
180
|
-
- **`log:query` mode:** `closureN3` is the **query-selected triples**
|
|
181
|
-
|
|
182
|
-
To exclude input facts from the normal-mode closure, pass:
|
|
183
|
-
|
|
184
|
-
```js
|
|
185
|
-
includeInputFactsInClosure: false;
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
When `rdfjs: true` is passed, `onDerived` also receives a `quad` field and the result may include `closureQuads` / `queryQuads`.
|
|
189
|
-
|
|
190
|
-
The returned object also includes `queryMode`, `queryTriples`, and `queryDerived` (and in normal mode, `onDerived` fires for newly derived facts; in `log:query` mode it fires for the query-selected derived triples).
|
|
191
|
-
|
|
192
|
-
### `reasonRdfJs()`
|
|
193
|
-
|
|
194
|
-
`reasonRdfJs(input, opts)` exposes derived results as an async iterable of RDF/JS quads as they are produced:
|
|
195
|
-
|
|
196
|
-
```js
|
|
197
|
-
const { reasonRdfJs, rdfjs } = require('eyeling');
|
|
198
|
-
|
|
199
|
-
for await (const quad of reasonRdfJs({
|
|
200
|
-
quads: [rdfjs.quad(rdfjs.namedNode(ex + 'alice'), rdfjs.namedNode(ex + 'parent'), rdfjs.namedNode(ex + 'bob'))],
|
|
201
|
-
rules: [rule],
|
|
202
|
-
})) {
|
|
203
|
-
console.log(quad.subject.value, quad.predicate.value, quad.object.value);
|
|
204
|
-
}
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
## Builtins
|
|
208
|
-
|
|
209
|
-
Builtins are defined in [eyeling-builtins.ttl](https://github.com/eyereasoner/eyeling/blob/main/eyeling-builtins.ttl) and described in the [Handbook (Chapter 11)](https://eyereasoner.github.io/eyeling/HANDBOOK#ch11).
|
|
210
|
-
|
|
211
|
-
## Development and testing (repo checkout)
|
|
212
|
-
|
|
213
|
-
```bash
|
|
214
|
-
npm test
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
You can also inspect the `examples/` directory for many small and large N3 programs.
|
|
218
|
-
|
|
219
|
-
## License
|
|
14
|
+
## Read more
|
|
220
15
|
|
|
221
|
-
|
|
16
|
+
- **Handbook:** [eyereasoner.github.io/eyeling/HANDBOOK](https://eyereasoner.github.io/eyeling/HANDBOOK)
|
|
17
|
+
- **Playground:** [eyereasoner.github.io/eyeling/demo](https://eyereasoner.github.io/eyeling/demo)
|
|
18
|
+
- **Semantics:** [eyereasoner.github.io/eyeling/SEMANTICS](https://eyereasoner.github.io/eyeling/SEMANTICS)
|
|
19
|
+
- **Conformance report:** [codeberg.org/phochste/notation3tests/.../report.md](https://codeberg.org/phochste/notation3tests/src/branch/main/reports/report.md)
|
package/examples/sudoku.n3
CHANGED
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
log:outputString "\n" ;
|
|
116
116
|
log:outputString "Completed grid\n" ;
|
|
117
117
|
log:outputString ?solutionText ;
|
|
118
|
-
log:outputString "\n" .
|
|
118
|
+
log:outputString "\n\n" .
|
|
119
119
|
:02-reason log:outputString "=== Reason Why ===\n" ;
|
|
120
120
|
log:outputString ?reasonText ;
|
|
121
121
|
log:outputString "\n\n" .
|