eyeling 1.21.10 → 1.22.0
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 +45 -0
- package/examples/arcling/README.md +17 -21
- package/examples/arcling/delfour/delfour.model.go +546 -0
- package/examples/arcling/delfour/delfour.spec.md +1 -2
- package/examples/arcling/flandor/flandor.model.go +630 -0
- package/examples/arcling/flandor/flandor.spec.md +1 -2
- package/examples/arcling/medior/medior.model.go +626 -0
- package/examples/arcling/medior/medior.spec.md +1 -2
- package/package.json +1 -1
- package/test/arcling.test.js +34 -16
- package/examples/arcling/delfour/delfour.instance.schema.json +0 -201
- package/examples/arcling/delfour/delfour.model.mjs +0 -273
- package/examples/arcling/flandor/flandor.instance.schema.json +0 -285
- package/examples/arcling/flandor/flandor.model.mjs +0 -303
- package/examples/arcling/medior/medior.instance.schema.json +0 -275
- package/examples/arcling/medior/medior.model.mjs +0 -344
package/HANDBOOK.md
CHANGED
|
@@ -307,6 +307,31 @@ This avoids the “existential in the body” trap and matches how most rule aut
|
|
|
307
307
|
|
|
308
308
|
Blanks in the **conclusion** are _not_ lifted — they remain blanks and later become existentials (Chapter 9).
|
|
309
309
|
|
|
310
|
+
### 5.1.1 Quoted formulas keep their own blank-node scope
|
|
311
|
+
|
|
312
|
+
There is one important exception to the “lift blanks in rule bodies” rule: **do not descend into a quoted formula** (`GraphTerm`) and lift the blanks that appear _inside_ it.
|
|
313
|
+
|
|
314
|
+
So this rule body:
|
|
315
|
+
|
|
316
|
+
```n3
|
|
317
|
+
{
|
|
318
|
+
( { ?S a :Subject } { [] a :Thing } ) log:conjunction ?Z.
|
|
319
|
+
} => { ... }.
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
must keep the inner `[]` as a **formula-local blank node**. Eyeling should treat it as belonging to the quoted graph, not as a rule-body variable that escapes into the surrounding rule.
|
|
323
|
+
|
|
324
|
+
That distinction matters because quoted formulas play **two different roles** in Eyeling:
|
|
325
|
+
|
|
326
|
+
1. **Formula as data** — for example when constructing a formula with `log:conjunction` or storing `{ ... }` in a triple. In this role, local blanks stay blanks. They print as blank nodes and participate in alpha-equivalence only within that quoted formula.
|
|
327
|
+
2. **Formula as a query pattern** — for example when `log:includes`, `log:notIncludes`, `log:collectAllIn`, or `log:forAllIn` prove a quoted formula. In that role, the builtin may treat the formula’s **local blanks existentially** while matching.
|
|
328
|
+
|
|
329
|
+
The practical rule is:
|
|
330
|
+
|
|
331
|
+
> **Rule normalization preserves blank-node scope inside quoted formulas; builtins may later interpret those preserved blanks as existential query placeholders when the formula is used as a pattern.**
|
|
332
|
+
|
|
333
|
+
This separation is deliberate. It keeps `log:conjunction` and formula printing honest, while still allowing query-like builtins to match formulas containing local `[]` placeholders.
|
|
334
|
+
|
|
310
335
|
### 5.2 Builtin deferral in forward-rule bodies
|
|
311
336
|
|
|
312
337
|
In a depth-first proof, the order of goals matters. Many built-ins only become informative once parts of the triple are **already instantiated** (for example comparisons, pattern tests, and other built-ins that don’t normally create bindings).
|
|
@@ -1481,6 +1506,24 @@ Also supported:
|
|
|
1481
1506
|
|
|
1482
1507
|
- The object may be the literal `true`, meaning the empty formula, which is always included (subject to the priority gating above).
|
|
1483
1508
|
|
|
1509
|
+
**Important blank-node note:** when the goal formula is used as a **pattern**, Eyeling treats blank nodes that are **local to that quoted formula** as existential placeholders during the proof.
|
|
1510
|
+
|
|
1511
|
+
So a pattern such as:
|
|
1512
|
+
|
|
1513
|
+
```n3
|
|
1514
|
+
{ ?x :p [] }
|
|
1515
|
+
```
|
|
1516
|
+
|
|
1517
|
+
means “find an `?x` that has some `:p` value”, not “find the specific blank node label printed here”.
|
|
1518
|
+
|
|
1519
|
+
But that existential behavior is intentionally limited:
|
|
1520
|
+
|
|
1521
|
+
- it applies only to blanks that are **owned by the quoted formula being proved**
|
|
1522
|
+
- it does **not** rename or relax terms that were already supplied by an outer substitution
|
|
1523
|
+
- it does **not** turn concrete members of already-bound lists or other already-ground structures into fresh variables
|
|
1524
|
+
|
|
1525
|
+
That last point is easy to miss. A builtin may receive a formula after part of it has already been instantiated from outer bindings. Those substituted-in terms are fixed data, not fresh existential placeholders. Keeping that boundary sharp prevents accidental overmatching and keeps numeric/list-oriented examples stable.
|
|
1526
|
+
|
|
1484
1527
|
#### `log:notIncludes` (test)
|
|
1485
1528
|
|
|
1486
1529
|
Negation-as-failure version: it succeeds iff `log:includes` would yield no solutions (under the same scoping rules).
|
|
@@ -1494,6 +1537,8 @@ Negation-as-failure version: it succeeds iff `log:includes` would yield no solut
|
|
|
1494
1537
|
- Unifies `OutList` with that list.
|
|
1495
1538
|
- If `OutList` is a blank node, Eyeling just checks satisfiable without binding/collecting.
|
|
1496
1539
|
|
|
1540
|
+
As with `log:includes`, blank nodes that are local to `WhereFormula` behave as existential query placeholders while that formula is being proved. But blanks that came from already-bound outer data remain fixed.
|
|
1541
|
+
|
|
1497
1542
|
This is essentially a list-producing “findall”.
|
|
1498
1543
|
|
|
1499
1544
|
#### `log:forAllIn` (test)
|
|
@@ -6,7 +6,7 @@ An Arcling case sits alongside the declarative N3 cases in `examples/`. Its purp
|
|
|
6
6
|
|
|
7
7
|
In one line:
|
|
8
8
|
|
|
9
|
-
> `examples/arcling/` presents ARC cases in mathematical English with reference
|
|
9
|
+
> `examples/arcling/` presents ARC cases in mathematical English with reference Go realizations and JSON test vectors.
|
|
10
10
|
|
|
11
11
|
## Insight Economy context
|
|
12
12
|
|
|
@@ -27,7 +27,7 @@ Eyeling already has a strong way to present a case in declarative N3. Arcling ad
|
|
|
27
27
|
Each Arcling case gives you:
|
|
28
28
|
|
|
29
29
|
- a **normative statement** in mathematical English,
|
|
30
|
-
- a **reference realization** in
|
|
30
|
+
- a **reference realization** in Go,
|
|
31
31
|
- a **concrete instance** in JSON,
|
|
32
32
|
- and an **expected result** for comparison and regression testing.
|
|
33
33
|
|
|
@@ -65,7 +65,7 @@ Typical uses:
|
|
|
65
65
|
- cases with a stable logical core and a small executable shell,
|
|
66
66
|
- cases that benefit from conformance-style testing.
|
|
67
67
|
|
|
68
|
-
## The
|
|
68
|
+
## The four files
|
|
69
69
|
|
|
70
70
|
Each Arcling case should contain these files.
|
|
71
71
|
|
|
@@ -75,7 +75,7 @@ The normative case description.
|
|
|
75
75
|
|
|
76
76
|
This file should use **mathematical English**. It should define the vocabulary, the inputs, the derived predicates, the decision rule, the governance rule, the checks, and the output contract.
|
|
77
77
|
|
|
78
|
-
The spec should be written so that a careful reader can understand the case without reading the
|
|
78
|
+
The spec should be written so that a careful reader can understand the case without reading the Go source first.
|
|
79
79
|
|
|
80
80
|
### 2. `name.data.json`
|
|
81
81
|
|
|
@@ -83,40 +83,36 @@ The concrete instance data.
|
|
|
83
83
|
|
|
84
84
|
This file contains the facts for the case: entities, thresholds, observed values, policies, timestamps, candidate actions, and any other case inputs.
|
|
85
85
|
|
|
86
|
-
### 3. `name.model.
|
|
86
|
+
### 3. `name.model.go`
|
|
87
87
|
|
|
88
|
-
The reference
|
|
88
|
+
The reference Go realization.
|
|
89
89
|
|
|
90
90
|
This file should implement the case directly and clearly. A good pattern is to map named clauses in the spec to named functions in the model.
|
|
91
91
|
|
|
92
92
|
For example:
|
|
93
93
|
|
|
94
|
-
- `
|
|
95
|
-
- `
|
|
96
|
-
- `
|
|
97
|
-
- `
|
|
94
|
+
- `clauseR1ExportWeakness`
|
|
95
|
+
- `clauseS2RecommendedPackage`
|
|
96
|
+
- `clauseG1AuthorizedUse`
|
|
97
|
+
- `clauseM2PayloadHash`
|
|
98
98
|
|
|
99
99
|
The model is not the normative source. It is the **reference realization** of the normative source.
|
|
100
100
|
|
|
101
|
+
Input validation is part of the reference model. A malformed instance should fail before evaluation rather than requiring a separate schema artifact.
|
|
102
|
+
|
|
101
103
|
### 4. `name.expected.json`
|
|
102
104
|
|
|
103
105
|
The expected derived result.
|
|
104
106
|
|
|
105
107
|
This file is the conformance vector for the case. It should capture the main derived predicates, the selected answer, the visible checks, and any stable integrity values needed for regression testing.
|
|
106
108
|
|
|
107
|
-
### 5. `name.instance.schema.json`
|
|
108
|
-
|
|
109
|
-
The instance schema.
|
|
110
|
-
|
|
111
|
-
This file defines the required structure of the input JSON. It should be strict enough to catch malformed case instances before evaluation.
|
|
112
|
-
|
|
113
109
|
## How to read an Arcling case
|
|
114
110
|
|
|
115
111
|
A good reading order is:
|
|
116
112
|
|
|
117
113
|
1. start with `name.spec.md`,
|
|
118
114
|
2. inspect `name.data.json`,
|
|
119
|
-
3. run `name.model.
|
|
115
|
+
3. run `go run name.model.go --json`,
|
|
120
116
|
4. compare the result with `name.expected.json`,
|
|
121
117
|
5. then relate the case back to its N3 counterpart.
|
|
122
118
|
|
|
@@ -127,7 +123,7 @@ That order keeps the meaning visible before the operational details.
|
|
|
127
123
|
A useful mental model is:
|
|
128
124
|
|
|
129
125
|
- `examples/` shows ARC cases in **declarative Eyeling form**,
|
|
130
|
-
- `examples/arcling/` shows the same kind of cases in **mathematical-English specification plus reference
|
|
126
|
+
- `examples/arcling/` shows the same kind of cases in **mathematical-English specification plus reference Go form**.
|
|
131
127
|
|
|
132
128
|
So the two collections are complementary:
|
|
133
129
|
|
|
@@ -144,7 +140,7 @@ The spec should say what the case means. It should not merely paraphrase the cod
|
|
|
144
140
|
|
|
145
141
|
### 2. Keep the code direct
|
|
146
142
|
|
|
147
|
-
The
|
|
143
|
+
The Go model should say what it does and do what it says. Avoid unnecessary framework machinery.
|
|
148
144
|
|
|
149
145
|
### 3. Keep the data separate
|
|
150
146
|
|
|
@@ -163,7 +159,7 @@ If a case is called `delfour`, `medior`, or `flandor` in `examples/`, the Arclin
|
|
|
163
159
|
1. Start from a strong ARC-style N3 example.
|
|
164
160
|
2. Write a mathematical-English specification of the case.
|
|
165
161
|
3. Move the concrete instance into JSON.
|
|
166
|
-
4. Implement a small
|
|
162
|
+
4. Implement a small Go reference model.
|
|
167
163
|
5. Capture the expected result in JSON.
|
|
168
164
|
6. Keep the visible output in Answer / Reason Why / Check shape.
|
|
169
165
|
7. Link the Arcling case to its N3 counterpart.
|
|
@@ -186,4 +182,4 @@ It exists to make a case simultaneously:
|
|
|
186
182
|
|
|
187
183
|
## In one line
|
|
188
184
|
|
|
189
|
-
`examples/arcling/` presents ARC cases in mathematical English with reference
|
|
185
|
+
`examples/arcling/` presents ARC cases in mathematical English with reference Go realizations, JSON instances, and expected results, alongside declarative Eyeling examples.
|