Skip to content

Equational proof kernel, loon prove, Div effect, and the self-verification ladder (rungs 0-3) - #97

Merged
ecto merged 4 commits into
mainfrom
claude/formal-verification-loon-123311
Oct 28, 2026
Merged

ecto merged 4 commits into
mainfrom
claude/formal-verification-loon-123311

Conversation

@ecto

@ecto ecto commented Oct 28, 2026 •

Copy link
Copy Markdown
Owner

What

Loon can now state laws, check proofs of them, and has begun proving its own kernel sound.

The kernel and loon prove (crates/loon-lang/src/verify/)

  • [law name [params] [= lhs rhs]], optionally :given [[= a b] ...] for conditional laws. [proof name steps...] with unfold, rewrite (:rev, :at N, :in h), induction (one hypothesis per recursive field), cases on variables or on any total-fn term (:as h), sym, refl, admit (taints). Mutual induction via :mutual. Constructor injectivity on hypotheses; ex falso on distinct constructors. Obligations from conditional laws are discharged by normalization, an in-scope hypothesis, or a settled law.
  • Goals close by evaluating total definitions and canonicalizing + and any operator declared [ac op assoc comm :unit u law], active only once those laws are kernel-proven and shape-checked.
  • loon prove DIR: bounded falsification first (generic ADT enumeration on the EIR VM, smallest counterexample, vacuous inputs never prove), then the kernel in dependency order, a canary check, and a text or --json report with the blake3 hash of the frozen defs. An unsound run scores 0 and exits 2.

Div effect (check/termination.rs): structural recursion is inferred total, including mutually recursive groups with a shared measure; everything else carries Div. E0405 when a fn annotated #{} may diverge. Not a capability, never grantable.

Corpora

  • verify/: list laws, Hutton compiler correctness, Peano arithmetic through mul-assoc, Gauss and sum-of-odds, conditional laws such as left-cancellation of append. 27 proven.
  • verify/meta/: the kernel's own term language, substitution, non-linear first-order matching, and a fuel-indexed leftmost-outermost evaluator. Proven: substitution composition, match soundness (apply-match p t = t), fuel composition and monotonicity. 32 proven.
  • Both corpora sound, nothing admitted, 4 deliberately false laws each falsified.

Why

docs/plans/2026-10-28-verify-autoresearch.md (design, grammar, the overnight loop) and docs/plans/2026-10-28-self-verifying-kernel.md (the 7-rung ladder; rungs 0-3 are in this PR). The goal is a verification story that fits invisible types: no dependent types, no tactic language, a kernel an auditor can read, proofs as data an agent loop can search for. The ladder's end is the kernel's soundness proof run through the kernel itself.

Reviewer notes

  • Trust surface: substitution, one-step unfolding, first-order matching (modulo commutativity for declared AC ops), constructor-match normalization, AC canonicalization, the induction scheme (structural, mutual, strong-on-size for mutual groups), obligation discharge, and verify/infer.rs, a small HM used for law param and scrutinee types because the language checker does not generalize top-level fns. A wrong type there would make a cases split unsound; it fails closed. Each of these is either modeled in verify/meta/ or listed as an assumption in the plan.
  • Builtins like reverse/map have no Loon body, so they are bridged by bounded-only laws in verify/builtins.oo, reported as bounded, never proven.
  • Two existing effect-row tests changed fixtures from #{} to #{Div} because their recursion is genuinely non-structural.
  • Found and left alone, outside scope: the VM does not bind variables in nested constructor patterns; the checker shares one Cons instantiation per function; the ownership checker flags a variable used in two match arms.
  • cargo test --workspace: 920 pass. Release-build loon prove takes 3 s on verify/ and 8 s on verify/meta/.

🤖 Generated with Claude Code

ecto and others added 4 commits October 28, 2026 13:56
Loon can now state laws and check proofs of them.

- `Div` is an inferred effect: structural recursion is total, anything
  else (non-structural recursion, loop, mutual recursion) carries Div.
  E0405 when a fn annotated `#{}` may diverge. Div is not a capability.
- `[law name [params] [= lhs rhs]]` and `[proof name steps...]`, checked
  by a small rewrite kernel in crates/loon-lang/src/verify: unfold,
  rewrite (:rev, :at), induction with one hypothesis per recursive field,
  cases on fields with inferred ADT types, refl, admit (tainting).
  Goals close by evaluating total definitions and canonicalizing `+`
  and any user operator declared `[ac op assoc comm :unit u law]` once
  those laws are themselves proven.
- `loon prove DIR`: bounded falsification first (generic ADT enumeration
  on the EIR VM), kernel in dependency order, canary check, text or JSON
  report with the hash of the frozen defs. Unsound runs score 0.
- Corpus under verify/: list laws, Hutton compiler correctness, and Peano
  arithmetic through mul-assoc, Gauss and sum-of-odds. 22 proven, 4
  deliberately false laws falsified, sound.
- Plan: docs/plans/2026-10-28-verify-autoresearch.md

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…corpus

Rungs 1 and 2 of docs/plans/2026-10-28-self-verifying-kernel.md.

- `[law name [params] :given [[= a b] ...] [= l r]]`: hypotheses are
  ground rules h1, h2, ... inside their own proof, with constructor
  injectivity giving h1.1, h1.2, ... Citing a conditional law or ih
  raises obligations discharged by normalization, an in-scope
  hypothesis, or a settled unconditional law. Bounded evaluation skips
  vacuous inputs and never proves by vacuity.
- Totality for mutually recursive groups: SCCs with one measure
  parameter per member, every in-group call passing a strict subterm.
- Mutual induction: `[proof p :mutual q [induction ...]]` pairs supply
  each other's law at constructor fields of the split value; the group
  settles together or not at all, and members are not citable by name.
- verify/meta: Term/Subst model with subst-empty, subst-compose (term
  and list versions) and apply-match-var proven; general apply-match
  stuck pending case splits on non-variable scrutinees and :given
  inside mutual groups.
- verify/laws/cond.oo: append-cancel-left, rev-inj, add-cancel-left.

27 proven in verify/, 9 in verify/meta/, both sound.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Kernel: `[cases EXPR :as h ...]` splits on any total-fn term of ADT
  type, naming the equation; `[sym]` swaps goal sides; `[rewrite R :in h]`
  rewrites inside a hypothesis; a case closes ex falso when a hypothesis
  equates distinct constructors; `:given` is allowed in mutual groups,
  partner hypotheses becoming obligations.
- Meta corpus: the matcher now threads one binding list (as the Rust
  matcher does), still with non-linear patterns. Match soundness
  `apply-match p t = t` is proven through term-eq/sym-eq soundness,
  agree lemmas, and mutual match-in-sound/match-list-in-sound.
- Evaluator model: Clause/Fn/Prog, leftmost-outermost `step`, fuel-
  indexed `evaln`. Proven: evaln-zero, evaln-normal, evaln-succ-normal,
  evaln-add (fuel composes), fuel-monotone, step-list-normal-head.

verify/: 27 proven; verify/meta: 32 proven; both sound, nothing admitted.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@ecto ecto changed the title Equational proof kernel, loon prove, and the Div effect Equational proof kernel, loon prove, Div effect, and the self-verification ladder (rungs 0-3) Oct 28, 2026
@ecto
ecto merged commit 1d3169d into main Oct 28, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant