Skip to content

Commit 7e6a02d

Browse files
IxVM kernel: Ixon Claim-shaped entrypoint (#423)
Replaces `kernel_check_test(target_addr, check_deps)` with two Aiur entrypoints in `Ix/IxVM/Kernel/Claim.lean`: ```rust pub fn verify_claim(claim_digest: [G; 32]) pub fn dbg_check_const(target_addr: [G; 32]) ``` ## `verify_claim` Public input is the 32-G blake3 digest of `Claim.ser claim`. Flow mirrors `load_verified_constant`: read bytes from the IOBuffer at key=`claim_digest`, recompute blake3, assert equality, deserialize once into a typed Aiur `Claim` ADT, then dispatch. ```rust pub fn verify_claim(claim_digest: [G; 32]) { let claim = load_verified_claim(claim_digest); match claim { Claim.Eval(i, o, asm) => run_eval(i, o, asm), Claim.Check(c, asm) => run_check(c, asm), Claim.CheckEnv(root, asm) => run_check_env(root, asm), Claim.Reveal(comm, info) => run_reveal(comm, info), Claim.Contains(t, c) => run_contains(t, c), } } ``` `load_verified_claim` is the constant-load shape applied to claims: recompute blake3, assert against the IO key, deserialize, assert no trailing bytes. Per-variant handlers: * `run_check (c, asm)` — `asm=None`: full transitive `check_all` over the ingressed closure. `asm=Some root`: load the assumption tree at `root`, recompute its merkle root via `parse_atree_body` (mirrors `Ix.Merkle.leafHash`/`nodeHash`), assert match, then `check_all_skipping` — every position whose addr is in the leaf set is treated as an axiom (skipped), the rest are checked. * `run_check_env (root, asm)` — load the env-tree at `root`, optionally load the assumption tree, then per env-leaf NOT in the assumption set: re-ingress its closure and `check_const`. Per-leaf ingress is the simplest model; closure sharing is a future optimization. * `run_contains (tree_root, target)` — load assumption tree at `tree_root`, assert `target` appears as a leaf. * `run_reveal (comm, info)` — load the constant at `comm`, match variant against `info`'s variant (Defn/Recr/Axio/Quot/CPrj/ RPrj/IPrj/DPrj/Muts), then per-Some field assert equality. `Expr` fields bind via `expr_addr = blake3(put_expr e)` per docs/Ixon.md:970-971. Direct fields (kind, safety, lvls, idx, cidx, block, …) compare literally. Mismatched variant pairs fall off the non-exhaustive `match` — proof generation fails. * `run_eval` — placeholder until Rust kernel pins reduction semantics. ## `dbg_check_const` Non-claim debug entrypoint: subject-only `check_const`, transitive deps trusted. Used by the arena suite and `lake exe kernel --debug-fast`. Verifier policy must reject this funcidx as a production claim. ## Aiur ADT mirror `Ix/IxVM/Kernel/Claim.lean` defines mirrors of `Ix.Claim` sub-types: * `Claim` — 5 variants matching `Ix.Claim`. * `RevealConstantInfo` / `RevealMutConstInfo` / `RevealConstructorInfo` / `RevealRecursorRule` — `Option‹...›` per field for selective revelation; Expr fields swapped for `Addr` content hashes. `(idx, info)` lists ride as `List‹(U64, _)›` tuples — no wrapper enum. Parsers (`get_claim`, `get_reveal_info`, `get_reveal_mut_const_info`, `get_reveal_ctor_info`, `get_reveal_rule`, bitmask-gated `get_opt_*_masked`) cover every wire-format arm. Match arms use enumerated discriminants without default catch-alls; Aiur's non-exhaustive match suffices. ## Lean side `Ix/IxVM/ClaimHarness.lean` (Lean ↔ Aiur glue): * `ClaimWitness` record (`funcName`, `input`, `inputIOBuffer`). * `buildClaimWitness (env claim trees := {}) : ClaimWitness` — serializes the claim, seeds it at key=`claim_digest`, ingests the relevant Ixon closure per variant, and seeds any caller-supplied `AssumptionTree` at key=`tree.root`. * `buildDbgCheckConst (env target) : ClaimWitness`. * `envCanonicalTree (env) : Option AssumptionTree` — convenience for `CheckEnv` against the env's canonical merkle root. ## Caller migrations * `Tests/Ix/IxVM.lean::kernelCheck` → `verify_claim` driving `Claim.check addr none`. * `Tests/Ix/Kernel/Arena.lean::buildInput` → `dbg_check_const`. * `Benchmarks/CheckNatAddComm.lean` → `verify_claim` driving `Claim.check addr none`. * `Kernel.lean` (`lake exe kernel`) → `verify_claim` default; `--debug-fast` switches to `dbg_check_const`. ## Test coverage Seven new claim-variant smoke tests wired into the `ixvm` ignored suite via `claimSmokeTests` in `Tests/Ix/IxVM.lean`: * `Claim Check with-asm (Nat.zero)` — asm tree covering every dep; kernel ends up checking only the subject. * `Claim Contains (synthetic 3-leaf)` — membership against a synthetic 3-leaf canonical tree. * `Claim CheckEnv (Nat.zero closure)` — 4-const env-tree. * `Claim Reveal Defn (kind+safety)` — enum-tag compare. * `Claim Reveal CPrj (all fields)` — addr+u64 compare. * `Claim Reveal Defn (typ Expr addr)` — `expr_addr` vs Lean's `Address.blake3 (Ixon.runPut (putExpr d.typ))`. * `Claim Reveal Muts (first component)` — variant dispatch across the three `RevealMutConstInfo` sub-variants. `Tests/Main.lean::ixvm` runner includes them alongside the existing `kernelChecks` and `serdeNatAddComm` test cases. All 14 claim-check assertions (7 × Execute output + IOBuffer) pass under `lake test -- --ignored ixvm`. `lake exe kernel Nat.zero` is 1528173 FFT (vs 1527378 pre-PR — +795 FFT for the Claim deserialization shim; acceptable).
1 parent fa93e54 commit 7e6a02d

10 files changed

Lines changed: 1496 additions & 195 deletions

File tree

Benchmarks/CheckNatAddComm.lean

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,20 @@ def main : IO Unit := do
2424
| throw (IO.userError "Merging failed")
2525
let .ok compiled := toplevel.compile
2626
| throw (IO.userError "Compilation failed")
27-
let some funIdx := compiled.getFuncIdx `kernel_check_test
28-
| throw (IO.userError "Aiur function not found")
27+
let some funIdx := compiled.getFuncIdx `verify_claim
28+
| throw (IO.userError "verify_claim entrypoint missing")
2929
let aiurSystem := Aiur.AiurSystem.build compiled.bytecode commitmentParameters
3030

3131
let env ← get_env!
32-
let ixonEnv ← IxVM.CheckHarness.loadIxonEnv ``Nat.add_comm env
33-
let ioBuffer := IxVM.CheckHarness.buildKernelCheckIOBuffer ixonEnv
34-
let targetAddrBytes := IxVM.CheckHarness.kernelCheckTarget ``Nat.add_comm ixonEnv
35-
-- check_deps=1 here: bench full transitive checking.
36-
let input := targetAddrBytes.push 1
32+
let ixonEnv ← IxVM.ClaimHarness.loadIxonEnv ``Nat.add_comm env
33+
let target ← IxVM.ClaimHarness.lookupAddr ixonEnv ``Nat.add_comm
34+
-- `assumptions = none` = full transitive typecheck.
35+
let witness ← IO.ofExcept <| IxVM.ClaimHarness.buildClaimWitness ixonEnv
36+
(Ix.Claim.check target none)
3737

3838
let _ ← bgroup "Kernel typechecking" { oneShot := true } do
3939
throughput (.Elements ixonEnv.consts.size.toUInt64 "consts")
4040
bench "check Nat.add_comm"
41-
(aiurSystem.prove friParameters funIdx input)
42-
ioBuffer
41+
(aiurSystem.prove friParameters funIdx witness.input)
42+
witness.inputIOBuffer
4343
return

Benchmarks/IxVM.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ def main : IO Unit := do
2929
let aiurSystem := Aiur.AiurSystem.build compiled.bytecode commitmentParameters
3030

3131
let env ← get_env!
32-
let ixonEnv ← IxVM.CheckHarness.loadIxonEnv ``Nat.add_comm env
33-
let (ioBuffer, n) := IxVM.CheckHarness.buildSerdeIOBuffer ixonEnv
32+
let ixonEnv ← IxVM.ClaimHarness.loadIxonEnv ``Nat.add_comm env
33+
let (ioBuffer, n) := IxVM.ClaimHarness.buildSerdeIOBuffer ixonEnv
3434

3535
let _ ← bgroup "IxVM benchmarks" { oneShot := true } do
3636
throughput (.Elements n.toUInt64 "consts")

Ix/IxVM.lean

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ public import Ix.IxVM.Kernel.DefEq
1818
public import Ix.IxVM.Kernel.Inductive
1919
public import Ix.IxVM.Kernel.CanonicalCheck
2020
public import Ix.IxVM.Kernel.Check
21-
public import Ix.IxVM.CheckHarness
21+
public import Ix.IxVM.Kernel.Claim
22+
public import Ix.IxVM.ClaimHarness
2223

2324
public section
2425

@@ -42,25 +43,6 @@ def entrypoints := ⟦
4243
}
4344
}
4445

45-
-- `check_deps` controls whether transitive dependencies are
46-
-- typechecked along with the target. When 1, runs `check_all`
47-
-- (current behavior). When 0, runs `check_const` only on the target
48-
-- — saving the per-dep `validate_const_well_scoped`, `k_check`,
49-
-- recursor canonical-build, positivity, etc. Deps still need to be
50-
-- in `k_consts`/`addrs` so the target's own `whnf`/`infer` can
51-
-- resolve `Const` refs; the IOBuffer payload doesn't shrink.
52-
pub fn kernel_check_test(target_addr: [G; 32], check_deps: G) {
53-
let target = store(target_addr);
54-
let (k_consts, addrs) = ingress_with_primitives(target);
55-
match check_deps {
56-
0 =>
57-
let target_pos = find_addr_idx(target, addrs, 0);
58-
let ci = load(list_lookup(k_consts, target_pos));
59-
check_const(ci, target_pos, k_consts, addrs),
60-
_ => check_all(k_consts, k_consts, addrs),
61-
}
62-
}
63-
6446
fn level_cmp_tests() {
6547
-- Zero ≤ anything
6648
assert_eq!(level_leq(KLevel.Zero, KLevel.Param(0)), 1);
@@ -187,6 +169,7 @@ def ixVM : Except Aiur.Global Aiur.Source.Toplevel := do
187169
let vm ← vm.merge inductive_check
188170
let vm ← vm.merge canonicalCheck
189171
let vm ← vm.merge check
172+
let vm ← vm.merge claim
190173
vm.merge entrypoints
191174

192175
end IxVM

Ix/IxVM/CheckHarness.lean

Lines changed: 0 additions & 134 deletions
This file was deleted.

0 commit comments

Comments
 (0)