Skip to content

Commit d6513c7

Browse files
committed
Tighten foundation strictness and proof dependencies
1 parent d0eb476 commit d6513c7

21 files changed

Lines changed: 3384 additions & 368 deletions

docs/DIAGNOSTICS.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,12 @@ The exit code is `1` whenever any diagnostic is emitted, `0` otherwise.
103103
| `E041` | Domain plugin error. Triggered by a malformed `(domain <name> ...)` block, an unknown domain plugin, or an unsupported request inside a registered domain plugin such as `automatic-sequences`. |
104104
| `E050` | Lean export error. Triggered when `rml export lean` sees forms outside the typed non-probabilistic subset, such as `has probability`, range/valence configuration, operator redefinitions, imports, namespaces, or templates. |
105105
| `E060` | Malformed `(root-construct …)` declaration. Triggered by a missing or non-symbolic name, an unrecognised child clause shape, or a non-symbolic value where a status / kind / dependency name is expected. See [`FOUNDATIONS.md`](./FOUNDATIONS.md). |
106-
| `E061` | Malformed `(foundation …)` declaration. Triggered by a missing name, an unrecognised child clause shape, or a malformed `(defines <op> <aggregator>)` / `(extends …)` / `(numeric-domain …)` / `(truth-domain …)` clause. See [`FOUNDATIONS.md`](./FOUNDATIONS.md). |
106+
| `E061` | Malformed `(foundation …)` declaration. Triggered by a missing name, an unrecognised child clause shape, or a malformed `(defines <op> <aggregator>)` / `(extends …)` / `(numeric-domain …)` / `(truth-domain …)` / `(carrier …)` / `(truth-table …)` clause. See [`FOUNDATIONS.md`](./FOUNDATIONS.md). |
107107
| `E062` | `(with-foundation <name> …)` references a foundation that has not been registered. Evaluation skips the body but continues with the surrounding forms; the active foundation remains the previously-active one. See [`FOUNDATIONS.md`](./FOUNDATIONS.md). |
108+
| `E063` | Carrier violation under `(strict-carrier)`. A probability assignment or query result fell outside the active foundation's declared carrier. See [`FOUNDATIONS.md`](./FOUNDATIONS.md). |
109+
| `E064` | Proof-substrate error. Triggered by malformed proof rules, assumptions, proof objects, `(check-proof …)` forms, premise/rule/conclusion mismatches, unjustified raw premises, or cyclic proof dependencies. See [`FOUNDATIONS.md`](./FOUNDATIONS.md). |
110+
| `E065` | Pure-links strict-mode error. Triggered by malformed `(strict-foundation …)` / `(allow-host-primitive …)` forms or by a query whose transitive dependency path reaches an unallowed `host-primitive` / `host-derived` construct. See [`FOUNDATIONS.md`](./FOUNDATIONS.md). |
111+
| `E066` | MTC/anum encode/decode error. Triggered by non-`Node` encode inputs, characters outside the four-abit alphabet, unbalanced frames, malformed frame tags, or byte-unaligned leaf payloads. See [`FOUNDATIONS.md`](./FOUNDATIONS.md). |
108112

109113
Codes are stable identifiers — they do not change between releases unless we
110114
explicitly note a breaking change in the changelog. The accompanying

docs/FOUNDATIONS.md

Lines changed: 77 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ so partial descriptors can be accumulated.
102102
| `E061` | Malformed `(foundation ...)` declaration (missing name, unknown child clause shape, malformed `(defines ...)` clause, malformed `(root ...)` / `(abit ...)` clause). |
103103
| `E062` | `(with-foundation <name> ...)` references a foundation that has not been registered. The diagnostic does not abort evaluation — forms after the bad scope still run. |
104104
| `E063` | Carrier violation under `(strict-carrier)` — a query result or probability assignment falls outside the active foundation's declared carrier. |
105-
| `E064` | Malformed `(check-proof ...)` form or proof-object replay failure (premise/conclusion mismatch). |
106-
| `E065` | Pure-links strict mode rejected a query that referenced a `host-primitive` / `host-derived` construct not on the `(allow-host-primitive ...)` list; also raised for malformed `(strict-foundation ...)` / `(allow-host-primitive ...)` forms. |
105+
| `E064` | Malformed proof rule / assumption / proof object / `(check-proof ...)` form, premise/conclusion mismatch, unjustified raw premise, or cyclic proof dependency. |
106+
| `E065` | Pure-links strict mode rejected a query whose transitive dependency path reaches an unallowed `host-primitive` / `host-derived` construct; also raised for malformed `(strict-foundation ...)` / `(allow-host-primitive ...)` forms. |
107107
| `E066` | MTC/anum encode/decode error (input outside the four-abit alphabet, unbalanced frame, leaf payload not byte-aligned, or non-Node value passed to `encodeAnum`). |
108108

109109
## 3. Foundations
@@ -129,7 +129,7 @@ Field reference:
129129
| `(defines <op> <aggregator>)` | Re-binds operator `<op>` to aggregator `<aggregator>` while the foundation is active. Repeats are allowed; each new `(defines ...)` replaces the binding for that operator. |
130130
| `(carrier <v1> <v2> ...)` | Declares the set of values the foundation considers legal. Symbolic constants (`true`, `false`, `unknown`) resolve through `env.symbol_prob` on activation; numeric literals stay literal. Informational unless `(strict-carrier)` is also present (see §6). |
131131
| `(strict-carrier)` | Opts the foundation into runtime carrier enforcement. Out-of-carrier query results and probability assignments raise `E063` instead of being silently clamped. |
132-
| `(truth-table <op> (in1 in2 -> out) ...)` | Rebinds `<op>` to a links-defined finite truth table for the duration of `(with-foundation ...)`. Partial tables are allowed — rows that don't match fall through to the previously installed op. Symbolic truth constants resolve through `env.symbol_prob` on activation. |
132+
| `(truth-table <op> (in1 in2 -> out) ...)` | Rebinds `<op>` to a finite truth table for the duration of `(with-foundation ...)` and records that active implementation as `links-defined`. The host still executes the table lookup; the selected behaviour comes from the rows. Partial tables are allowed — rows that don't match fall through to the previously installed op. Symbolic truth constants resolve through `env.symbol_prob` on activation. |
133133
| `(experimental)` | Flags the foundation as experimental so the trust audit prints an `[experimental]` tag next to its name. Carries no behavioural guarantees. |
134134
| `(root <symbol>)` | Records the foundation's root concept (e.g. `` for `mtc-anum`). Informational; surfaced on the report. |
135135
| `(abit <symbol> <meaning>)` | Records one atomic bit of the foundation's alphabet. Used by experimental profiles like `mtc-anum` to publish their four-abit (`[`, `]`, `0`, `1`) serialization alphabet. Informational; surfaced on the report. |
@@ -216,6 +216,12 @@ snapshot of the active foundation. The snapshot has the shape:
216216
rootConstructs: [ { name, kind, status, dependsOn, encodedAs, ... } ],
217217
byStatus: { "<status>": ["<name>", ...] },
218218
foundations: [ { name, description, defines, ... } ],
219+
activeImplementations: [
220+
{ construct, foundation, implementation, status, dependsOn }
221+
],
222+
proofRules: [ { name, premises, conclusion } ],
223+
proofAssumptions: [ { name, kind, judgement } ],
224+
proofObjects: [ { name, rule, premises, premiseRefs, conclusion } ],
219225
}
220226
```
221227

@@ -272,6 +278,10 @@ external-trusted:
272278
- smt-trusted
273279
274280
foundations:
281+
- boolean-links — links-defined two-valued Boolean logic via finite truth tables
282+
numeric domain: boolean-zero-one
283+
truth domain: boolean-two-valued
284+
truth tables: and(4 rows), not(2 rows), or(4 rows)
275285
- boolean-classical — two-valued-classical-boolean-logic
276286
numeric domain: boolean-zero-one
277287
truth domain: two-valued
@@ -313,17 +323,23 @@ env.exit_foundation();
313323

314324
## 5. Bundled foundations
315325

316-
Two alternative foundations ship in [`lib/self/foundations.lino`](../lib/self/foundations.lino):
326+
Three alternative foundations ship in [`lib/self/foundations.lino`](../lib/self/foundations.lino)
327+
and are pre-seeded by the JS and Rust hosts:
317328

329+
- **`boolean-links`** — two-valued Boolean logic over the strict carrier
330+
`{0,1}`. `and`, `or`, and `not` are selected from finite truth-table
331+
rows, so the active implementation descriptors for those operators
332+
are `links-defined` while the foundation is active.
318333
- **`boolean-classical`** — two-valued classical Boolean logic. `and`
319334
becomes `min`, `or` becomes `max`, `both` collapses to `min`, and
320335
`neither` to `product`. The numeric domain field is set to
321-
`boolean-zero-one` so the trust report records the intended carrier;
322-
numeric-domain enforcement is planned (§6).
336+
`boolean-zero-one` so the trust report records the intended carrier.
337+
These bindings still use host aggregator implementations.
323338
- **`kleene-three-valued`** — Strong Kleene three-valued logic.
324339
Same `min`/`max` operator shape as classical, but the truth domain is
325340
`three-valued` and the numeric domain is the real unit interval; the
326-
midpoint `0.5` represents `unknown`.
341+
midpoint `0.5` represents `unknown`. These bindings also use host
342+
aggregators.
327343

328344
The example [`examples/foundation-boolean-kleene.lino`](../examples/foundation-boolean-kleene.lino)
329345
exercises both in one file and shows the default semantics being
@@ -363,10 +379,11 @@ whether `true`/`false` are bound to `{0,1}` or `{0.0, 1.0}` or `{0, 0.5,
363379

364380
## 7. Truth tables: `(truth-table ...)`
365381

366-
Operators can also be rebound to a finite truth table written in pure
367-
`.lino`. This is the simplest path to a "links-defined" operator — the
368-
rows are data, no host aggregator is consulted while the foundation is
369-
active.
382+
Operators can also be rebound to a finite truth table written in
383+
`.lino`. This is the smallest implemented path to a `links-defined`
384+
operator: the rows are links data, and matching rows do not consult a
385+
host aggregator while the foundation is active. The evaluator still
386+
performs the table lookup, so this is not a self-hosted proof kernel.
370387

371388
```lino
372389
(foundation xor3
@@ -385,8 +402,9 @@ active.
385402
```
386403

387404
Partial tables are allowed: rows that don't match fall through to the
388-
previously installed operator. The symbolic constants are resolved
389-
through `env.symbol_prob` on activation, just like `(carrier ...)`.
405+
previously installed operator, which may be host-backed. The symbolic
406+
constants are resolved through `env.symbol_prob` on activation, just
407+
like `(carrier ...)`.
390408

391409
## 8. Pure-links strict mode
392410

@@ -395,20 +413,33 @@ The `(strict-foundation pure-links)` form (paired with optional
395413
described in the original roadmap. While active, any query that
396414
transitively depends on a `host-primitive` or `host-derived` construct
397415
not on the whitelist raises `E065`. The dependency graph in the trust
398-
audit drives the check — it is the transitive closure of `depends-on`
399-
links in the registry.
416+
audit drives the check. The scanner reports concrete paths through the
417+
active implementation map and the root-construct `depends-on` graph,
418+
for example `and -> avg -> host-primitive`.
400419

401420
```lino
402421
(strict-foundation pure-links)
403-
(allow-host-primitive + - lambda apply)
404422
405-
; OK: uses only whitelisted primitives.
406-
(? (1 + 2))
423+
(a: a is a)
424+
(b: b is b)
425+
((a = true) has probability 1)
426+
((b = true) has probability 0)
427+
428+
; E065: default `and` depends on the host `avg` aggregator:
429+
; and -> avg -> host-primitive
430+
(? ((a = true) and (b = true)))
407431
408-
; E065: `min` is host-primitive and not whitelisted.
409-
(? (min 1 2))
432+
; OK: the active implementation of `and` is a truth-table row set
433+
; recorded as links-defined.
434+
(with-foundation boolean-links
435+
(? ((a = true) and (b = true))))
410436
```
411437

438+
`(allow-host-primitive <name>...)` whitelists exact construct or
439+
dependency names. For example, allowing `avg` permits the default
440+
`and -> avg -> host-primitive` path, while allowing an unrelated
441+
ancestor does not.
442+
412443
The strict mode is *opt-in*; nothing about its presence in the host
413444
changes the behaviour of a file that does not use it. The dependency
414445
graph is also rendered in `formatFoundationReport` so the user can see,
@@ -422,7 +453,9 @@ It is **never** activated implicitly — `default-rml` stays the active
422453
foundation on every fresh `Env`. The profile carries an `[experimental]`
423454
tag, a root symbol ``, and four "abits" (atomic bits): `[`, `]`, `0`,
424455
`1`. Together those four characters form a self-contained serialization
425-
alphabet for arbitrary `Node` values.
456+
alphabet for arbitrary `Node` values. It is descriptive metadata plus
457+
encode/decode helpers, not a replacement evaluator, proof checker, or
458+
minimal trusted kernel.
426459

427460
```text
428461
mtc-anum [experimental] — minimal-trust-core experimental anum profile
@@ -454,8 +487,10 @@ frames, and leaf payloads that are not byte-aligned, all with `E066`.
454487

455488
## 10. Status of the broader programme
456489

457-
The full multi-phase roadmap from issue #97 is now implemented on the
458-
backward-compatible side of the line:
490+
The issue #97 roadmap is implemented where the work could stay
491+
backward-compatible and inspectable. The remaining self-hosting target
492+
is still deliberately explicit: Phase 5 has descriptor and dependency
493+
coverage, but not a links-defined type/proof kernel.
459494

460495
- **Phase 1 — inventory + reporting + scoped overrides.** Implemented.
461496
See §2 (registry), §4 (`foundation-report`), §3 (`(with-foundation ...)`).
@@ -464,26 +499,30 @@ backward-compatible side of the line:
464499
`assigned-equality`, `definitional-equality` are distinct entries
465500
with their own `depends-on`. Proof-trace layering remains an open
466501
follow-up.
467-
- **Phase 3 — proof-object substrate.** Implemented via `(check-proof
468-
...)` and the proof-object replay path. Diagnostic `E064` covers
469-
malformed forms and premise/conclusion mismatches.
502+
- **Phase 3 — proof-object substrate.** Implemented via proof rules,
503+
`(assumption ...)` / `(axiom ...)`, `(proof-object ...)`, and
504+
`(check-proof ...)`. Premises must cite an assumption, axiom, or
505+
earlier proof object using `(premise-by ...)` / `(uses ...)`;
506+
unjustified raw premises raise `E064`.
470507
- **Phase 4 — links-defined finite logics.** Implemented. See the
471-
bundled `boolean-classical` / `kleene-three-valued` foundations
472-
(§5), the `(truth-table ...)` clause (§7), and `(carrier ...)` +
473-
`(strict-carrier)` (§6).
474-
- **Phase 5 — links-defined type/proof kernel fragment.** The
475-
registry's `Prop`, `Pi`, `lambda`, `apply`, `beta-reduction`, and
508+
bundled `boolean-links` truth-table foundation (§5), the
509+
`(truth-table ...)` clause (§7), and `(carrier ...)` +
510+
`(strict-carrier)` (§6). The older `boolean-classical` /
511+
`kleene-three-valued` foundations remain host-aggregator examples.
512+
- **Phase 5 — links-defined type/proof kernel fragment.** Partial:
513+
the registry's `Prop`, `Pi`, `lambda`, `apply`, `beta-reduction`, and
476514
equality layers are catalogued with `depends-on` links, and the
477-
trust audit can walk them via the dependency graph.
515+
trust audit can walk them via the dependency graph. The actual
516+
type/proof kernel remains host-implemented.
478517
- **Phase 6 — pure-links checking mode.** Implemented. See §8.
479-
- **Phase 7 — dependency-graph traversal.** The trust audit now renders
480-
the transitive closure of `depends-on` and is what powers strict-mode
481-
enforcement.
518+
- **Phase 7 — dependency-graph traversal.** Implemented for trust
519+
reporting and strict-mode enforcement paths.
482520
- **Phase 8 — bundled `(carrier ...)` / `(strict-carrier)` /
483521
`(truth-table ...)`.** Implemented (§6, §7).
484-
- **Phase 9 — experimental profiles (`mtc-anum`).** Implemented (§9),
485-
pre-seeded but opt-in, with `encodeAnum` / `decodeAnum` helpers and
486-
the `(experimental)` / `(root ...)` / `(abit ...)` clauses.
522+
- **Phase 9 — experimental profiles (`mtc-anum`).** Implemented as an
523+
opt-in serialization profile (§9), with `encodeAnum` / `decodeAnum`
524+
helpers and the `(experimental)` / `(root ...)` / `(abit ...)`
525+
clauses. It does not implement a minimal trusted core evaluator.
487526

488527
Everything in this document is the *backward-compatible* surface. The
489528
strict modes (`(strict-carrier)`, `(strict-foundation pure-links)`) are

0 commit comments

Comments
 (0)