Aiur kernel: complete port from Rust reference + kernel-arena coverage#398
Merged
Conversation
3e5024e to
d2adc46
Compare
Brings the Aiur-source kernel typechecker to parity with the Rust
kernel for the full stdlib, the lean-kernel-arena tutorial fixtures,
and the curated ixvm test list. Validated via a new arena test suite
plus the existing per-name kernel checks: 281/0 in
`lake test -- --ignored ixvm`.
Aiur source (`Ix/IxVM/...`):
* `Kernel/{Whnf,DefEq,Levels,Infer,Subst,Inductive,Check,
CanonicalCheck,Primitive}.lean`: complete kernel split out from the
monolithic `Kernel.lean` (deleted along with `KERNEL.md`). Mirrors
`src/ix/kernel/*.rs` module-by-module.
* `Ingress.lean`: load `Constant`s + blobs from the IOBuffer with
blake3 verification; build per-position `addrs`/`top`. Compute
constructor content-hash addresses entirely in-Aiur via
`cprj_content_addr` (no IOBuffer side channel) so
`check_eq_type`'s `address_eq` against `eq_refl_addr` succeeds
when an inductive's ctors weren't transitively loaded as
independent CPrjs. Append synthetic `Axiom Sort 0` entries for
every hardcoded `*_addr()` primitive so internal expansions
(`str_lit_to_ctor`, decidability dispatch, etc.) can construct
`Const(idx, _)` references that resolve via `find_addr_idx_safe`
even when the primitive isn't in the user's syntactic closure.
* `IxVM.lean`: `kernel_check_test(target_addr, check_deps)`
entrypoint. `check_deps = 1` runs `check_all` over every loaded
const; `check_deps = 0` runs `check_const` only on the target
(saves the per-dep validation work — significant for proving
since recursor canonical-build dominates).
* `KernelTypes.lean`, `Convert.lean`, `Core.lean`: supporting
types/conversions for the kernel proper.
Rust side (`src/aiur/execute.rs`, `src/ffi/aiur/protocol.rs`,
`src/aiur/{trace,synthesis}.rs`):
* Refactor bytecode `execute` to return `Result<_, ExecError>`
instead of panicking on assertion failures, missing match cases,
or out-of-bounds. Plumbed through the FFI as `Except String α` so
Lean callers can classify Aiur kernel rejections as expected
outcomes rather than process crashes.
* `synthesis::AiurSystem::prove` keeps panic semantics by
`.expect`-ing the inner Result (prover assumes valid input).
* `trace.rs` updated for the new `IOBuffer` return types.
Lean-side IO buffer / harness (`Ix/IxVM/CheckHarness.lean`):
* IOBuffer convention reorganized fundamental-first with suffix tags
(`addr.push(tag)` is O(1) amortized; prefix `[tag] ++ addr`
allocates):
| `addr` | const bytes (or empty = blob marker) |
| `addr ++ [0]` | raw blob bytes |
| `addr ++ [1]` | single G (Defn ReducibilityHints) |
* `loadIxonEnv` (single-target) + `loadSharedIxonEnv` (union of N
targets, one compile shared across many drivers).
* `closureFrom` walks `Constant.refs` + projection `block_addr` from
a target. `buildKernelCheckIOBufferFor` restricts every per-address
entry to that closure for a minimal per-target IOBuffer.
* `addEntries` helper dedupes the per-tag insertion logic between
the full-env and per-target builders.
Tests (`Tests/Ix/IxVM.lean`, `Tests/Ix/Kernel/Arena.lean`,
`Tests/Main.lean`):
* `Tests.Ix.IxVM` reorganized into clear sections: `IxVMPrim`
(primitive-reduction theorems), `IxVMInd` (mutual + nested
inductives), `serdeNatAddComm` / `kernelCheck` / `kernelChecks`
runners.
* `Tests.Ix.Kernel.Arena` drives the Aiur kernel against every
lean-kernel-arena tutorial fixture (good must typecheck, bad must
be rejected). Two `knownIncompatible` skips: `tut06_bad01`
(Anon-mode dup levelParams hygiene check) and
`Tests.Ix.Kernel.TutorialDefs.AdvNat.rec` (malformed rec rule
sanitized by aux-gen). Both hold against the Rust kernel via
Meta-mode-only / bespoke-FFI paths the Aiur kernel can't see.
* `Tests.Main`'s `ixvm` runner builds an `AiurTestEnv` once and
weaves both `mkAiurTests`'s output and `arenaTests`'s output into
the same `LSpec` suite.
Misc:
* `Tests/Aiur/Common.lean`: surface execute's `Except` properly.
* `Benchmarks/{CheckNatAddComm,IxVM}.lean`: pass `check_deps = 1`
explicitly to preserve existing semantics.
* `Kernel.lean` exe: handle the `Except` return.
# Outstanding TODOs
Carried forward unchanged from the original Aiur kernel port:
* `Ix/IxVM/Kernel/Primitive.lean::u64_add_with_carry`
Duplicates `ByteStream.lean::u64_add` to expose the final carry as
`(U64, G)`. Should be deleted once `ByteStream.u64_add` itself is
patched to return the carry — the patch ripples beyond the kernel
(Blake3, IxonSerialize, ByteStream itself), so a follow-up.
* `Ix/IxVM/Kernel/Primitive.lean::divmod_256` (and `u64_mul`'s
schoolbook). Currently use `divmod_256` byte-by-byte arithmetic.
Should be replaced with a proper `u8_mul` Aiur gadget once it
lands. Tracked on a separate branch.
# WHNF fuel cap
Aiur deliberately omits Rust's `MAX_WHNF_FUEL = 10_000`. In a zk
prover context, divergent input fails to produce a proof — the caller
guarantees termination, so a soundness-preserving early abort isn't
needed. Documented inline at `Whnf.lean::whnf`.
# Provenance
Each Aiur file/function carries `Mirror: src/ix/kernel/...` citations
so the Rust authority for any branch is one-grep away.
gabriel-barrett
approved these changes
May 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brings the Aiur-source kernel typechecker to parity with the Rust
kernel for the full stdlib, the lean-kernel-arena tutorial fixtures,
and the curated ixvm test list. Validated via a new arena test suite
plus the existing per-name kernel checks: 281/0 in
lake test -- --ignored ixvm.Aiur source (
Ix/IxVM/...):Kernel/{Whnf,DefEq,Levels,Infer,Subst,Inductive,Check, CanonicalCheck,Primitive}.lean: complete kernel split out from themonolithic
Kernel.lean(deleted along withKERNEL.md). Mirrorssrc/ix/kernel/*.rsmodule-by-module.Ingress.lean: loadConstants + blobs from the IOBuffer withblake3 verification; build per-position
addrs/top. Computeconstructor content-hash addresses entirely in-Aiur via
cprj_content_addr(no IOBuffer side channel) socheck_eq_type'saddress_eqagainsteq_refl_addrsucceedswhen an inductive's ctors weren't transitively loaded as
independent CPrjs. Append synthetic
Axiom Sort 0entries forevery hardcoded
*_addr()primitive so internal expansions(
str_lit_to_ctor, decidability dispatch, etc.) can constructConst(idx, _)references that resolve viafind_addr_idx_safeeven when the primitive isn't in the user's syntactic closure.
IxVM.lean:kernel_check_test(target_addr, check_deps)entrypoint.
check_deps = 1runscheck_allover every loadedconst;
check_deps = 0runscheck_constonly on the target(saves the per-dep validation work — significant for proving
since recursor canonical-build dominates).
KernelTypes.lean,Convert.lean,Core.lean: supportingtypes/conversions for the kernel proper.
Rust side (
src/aiur/execute.rs,src/ffi/aiur/protocol.rs,src/aiur/{trace,synthesis}.rs):executeto returnResult<_, ExecError>instead of panicking on assertion failures, missing match cases,
or out-of-bounds. Plumbed through the FFI as
Except String αsoLean callers can classify Aiur kernel rejections as expected
outcomes rather than process crashes.
synthesis::AiurSystem::provekeeps panic semantics by.expect-ing the inner Result (prover assumes valid input).trace.rsupdated for the newIOBufferreturn types.Lean-side IO buffer / harness (
Ix/IxVM/CheckHarness.lean):(
addr.push(tag)is O(1) amortized; prefix[tag] ++ addrallocates):
|
addr| const bytes (or empty = blob marker) ||
addr ++ [0]| raw blob bytes ||
addr ++ [1]| single G (Defn ReducibilityHints) |loadIxonEnv(single-target) +loadSharedIxonEnv(union of Ntargets, one compile shared across many drivers).
closureFromwalksConstant.refs+ projectionblock_addrfroma target.
buildKernelCheckIOBufferForrestricts every per-addressentry to that closure for a minimal per-target IOBuffer.
addEntrieshelper dedupes the per-tag insertion logic betweenthe full-env and per-target builders.
Tests (
Tests/Ix/IxVM.lean,Tests/Ix/Kernel/Arena.lean,Tests/Main.lean):Tests.Ix.IxVMreorganized into clear sections:IxVMPrim(primitive-reduction theorems),
IxVMInd(mutual + nestedinductives),
serdeNatAddComm/kernelCheck/kernelChecksrunners.
Tests.Ix.Kernel.Arenadrives the Aiur kernel against everylean-kernel-arena tutorial fixture (good must typecheck, bad must
be rejected). Two
knownIncompatibleskips:tut06_bad01(Anon-mode dup levelParams hygiene check) and
Tests.Ix.Kernel.TutorialDefs.AdvNat.rec(malformed rec rulesanitized by aux-gen). Both hold against the Rust kernel via
Meta-mode-only / bespoke-FFI paths the Aiur kernel can't see.
Tests.Main'sixvmrunner builds anAiurTestEnvonce andweaves both
mkAiurTests's output andarenaTests's output intothe same
LSpecsuite.Misc:
Tests/Aiur/Common.lean: surface execute'sExceptproperly.Benchmarks/{CheckNatAddComm,IxVM}.lean: passcheck_deps = 1explicitly to preserve existing semantics.
Kernel.leanexe: handle theExceptreturn.Outstanding TODOs
Carried forward unchanged from the original Aiur kernel port:
Ix/IxVM/Kernel/Primitive.lean::u64_add_with_carryDuplicates
ByteStream.lean::u64_addto expose the final carry as(U64, G). Should be deleted onceByteStream.u64_additself ispatched to return the carry — the patch ripples beyond the kernel
(Blake3, IxonSerialize, ByteStream itself), so a follow-up.
Ix/IxVM/Kernel/Primitive.lean::divmod_256(andu64_mul'sschoolbook). Currently use
divmod_256byte-by-byte arithmetic.Should be replaced with a proper
u8_mulAiur gadget once itlands. Tracked on a separate branch.
WHNF fuel cap
Aiur deliberately omits Rust's
MAX_WHNF_FUEL = 10_000. In a zkprover context, divergent input fails to produce a proof — the caller
guarantees termination, so a soundness-preserving early abort isn't
needed. Documented inline at
Whnf.lean::whnf.Provenance
Each Aiur file/function carries
Mirror: src/ix/kernel/...citationsso the Rust authority for any branch is one-grep away.