Repository navigation
processor: Kami words on stdlib bits; thin KamiWord bridge (stacked on #561) - #562
Open
JasonGross wants to merge 10 commits into
Open
JasonGross wants to merge 10 commits into
JasonGross wants to merge 10 commits into
Conversation
This was referenced Sep 12, 2026
JasonGross
force-pushed
the
fable/kami-bits
branch
from
September 12, 2026 19:05
6dff79e to
efe4ea4
Compare
This was referenced Sep 12, 2026
Merged
Contributor
Author
|
Stacked follow-up: #563 makes the Kami word instance be coqutil's Naive.word (all fields shown equal) and drops KamiRiscvWordProperties.v. Written by Claude Fable 5.1 via Claude Code (session https://claude.ai/code/session_01YJbiRBkJtM7x6PvYV6hmEm). |
JasonGross
force-pushed
the
fable/kami-bits
branch
7 times, most recently
from
September 14, 2026 21:31
3e65466 to
61831cc
Compare
andres-erbsen
marked this pull request as ready for review
September 15, 2026 04:26
JasonGross
force-pushed
the
fable/kami-bits
branch
4 times, most recently
from
September 15, 2026 07:21
e52c4ce to
e32f886
Compare
deps/kami moves to the fable/word-on-bits branch (aff07cc), where Kami.Lib.Word.word n is the standard library's bits (Z.of_nat n) and every word operation is a simpl never wrapper specified through Zmod.unsigned. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJbiRBkJtM7x6PvYV6hmEm
Kami's word is no longer inductive, so the bridge no longer needs its own induction and bit-blasting proofs: one lemma, Z.of_N (wordToN w) = Zmod.unsigned w, carries every Kami unsigned_* fact onto the goals the word.ok instance produces, and the file shrinks from 598 to 332 lines. The instance itself is unchanged: rep, unsigned, signed, of_Z and all the operations are the same Kami functions as before, so kunsigned, kofZ and kword keep their spellings for the rest of processor/ and end2end/. One thing to know when reading the ok proof: Zmod.unsigned's modulus is an implicit argument that mentions 2 ^ Z.of_nat (Z.to_nat width), so rewriting 2 ^ Z.of_nat sz into 2 ^ width would be ill-typed; the proof only ever rewrites the other way. Ten helper lemmas that nothing outside this file referenced were dropped rather than re-proved. No kept statement changed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJbiRBkJtM7x6PvYV6hmEm
uwordToZ is Zmod.unsigned now rather than Z.of_N (wordToN _), so the six places that relied on it being kunsigned by conversion go through the new KamiWord.uwordToZ_kunsigned instead. word is not an inductive type, so injection on an equality of words takes the Zmod record apart; riscvMemInit's NoDup proof projects out of the option with f_equal instead. kami_evalSignExtendTrunc's zero-width case and the three shift lemmas are re-proved at the unsigned interface. End2EndPipeline.v needed two changes, both because reduction and lia now behave differently under the Zmod-based word. Its base case used a bare cbv, which reduces through Zmod.of_Z and duplicates subterms at every nesting level; it is now a restricted cbn. And one arithmetic goal deep inside the end2end proof took 140 s and built a certificate deep enough to overflow the kernel stack at Qed, because Kami's Word.v registers ZifyNat and ZifyN globally and lia then translates every nat and N hypothesis in a very large context; it is now discharged by imem_heap_stack_lengths, the same goal stated on its own, where lia takes two seconds. The file went from a stack overflow to 28 s. All theorem statements are unchanged; imem_heap_stack_lengths is new. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJbiRBkJtM7x6PvYV6hmEm
… 34 s)
`prove_states_related`'s pc branch is
try (eapply pc_related_plus4; try eassumption; red; eauto; fail)
Over the 39 goals at one call site, the 37 eapply's that SUCCEED cost
0.000 s each; the 2 that fail cost 145.7 s and 13.0 s. Plain eapply
unifies the goal against `pc_related_and_valid (?kpc ^+ $4) (word.add
?rpc (word.of_Z 4))`, so on a goal without that shape it descends into
the Zmod-based word operations and their proof field before concluding
"no". `simple eapply` restricts unification, keeps the identical 37
success / 2 failure split, and fails instantly.
Measured on KamiRiscvStep.v with `rocq c -time`, cold:
baseline after port now
prove_states_related, all sites 8.4 s 1307 s 13 s
sum of all command times 455 s 1842 s 513 s
wall clock 8m18s 27m27s 8m34s
It is NOT the `cbv [RegsToT pRegsToT]; kregmap_red; exact eq_refl`
branch: that costs 6 s across all 39 goals. Kernel conversion over Zmod
records is cheap because it evaluates with sharing; the `of_Z`
duplication hazard only bites simpl/cbn/cbv, which rebuild terms.
KamiRiscvStep.v keeps its `From Stdlib Require Import Zmod.`: Kami.Lib.Word
does not re-export the Zmod prefix and this file uses
Zmod.unsigned/Zmod.signed in 9 places.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YJbiRBkJtM7x6PvYV6hmEm
Kami's Lt/Slt now evaluate to Z.ltb on uwordToZ/wordToZ, so the word instance's ltu/lts are spelled the same way, is_mmio_spec and the eight branch cases decide the test from the riscv-side comparison fact, and the deleted Kami lemma unsigned_inj is Zmod.unsigned_inj. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJbiRBkJtM7x6PvYV6hmEm
The word instance's fields are Zmod.add, Zmod.sub, ... directly (Kami's names are notations for them now), kofZ and ksigned are eta-expanded since ZToWord sz z is a notation, and the Kami lemmas that were stdlib lemmas (wplus_comm, wplus_assoc, ZToWord_wordToZ, unsigned_ZToWord, unsigned_wplus, weqb_true_iff, ...) are named by their Zmod.* / bits.* names; KamiWord.v's own wnot_idempotent and ZToWord_zero were bits.not_not and Zmod.of_Z_0. KamiRiscvStep.v declares #[local] Arguments Z.pow / Z.of_nat : simpl never so that its simpl/cbn calls keep the modulus 2 ^ Z.of_nat sz that every Kami lemma is keyed on (they unfold the riscv and Kami evaluation functions, not these two constants); with that, one hypothesis that simpl used to close now survives and shifts the auto-generated names, so the ten AddrAligned sites rewrite by the shape of the remu equation instead of by name. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJbiRBkJtM7x6PvYV6hmEm
wrshifta is Zmod.srs, so wrshifta_ZToWord goes through Z.shiftr_div_pow2 instead of reflexivity; wordToZ_inj is Zmod.signed_inj; the shifts are Zmod.slu/sru/srs at Z.of_nat n, one application deeper for f_equal in kami_word_riscv_ok. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJbiRBkJtM7x6PvYV6hmEm
…are gone wordToZ, uwordToZ, weqb, wzero, wnot, ZToWord, wlshift, wrshift and wrshifta are Zmod.signed, Zmod.unsigned, Zmod.eqb, Zmod.zero, Zmod.not, bits.of_Z (Z.of_nat sz), Zmod.slu, Zmod.sru and Zmod.srs (the shifts at Z.of_nat n); End2EndPipeline.v imports Zmod for the name. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJbiRBkJtM7x6PvYV6hmEm
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJbiRBkJtM7x6PvYV6hmEm
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJbiRBkJtM7x6PvYV6hmEm
JasonGross
force-pushed
the
fable/kami-bits
branch
from
September 15, 2026 08:03
e32f886 to
62cb13b
Compare
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.
Stacked on #561: this branch contains #561's commits (the base branch lives on a fork, so GitHub cannot show the stacked diff alone). The Kami part is the last four commits, 728df75..efe4ea4; review those.
Pins
deps/kamito mit-plv/kami#51, where Kami'sword nis stdlibbits (Z.of_nat n)with thenatindex kept, and simplifies the processor bridge accordingly:processor/src/processor/KamiWord.vshrinks from 598 to 332 lines because a Kamiword 32is now the same representation as coqutil'sNaive.word 32, so theword.oklaws come from stdlib'sZmodlemmas instead of a hand-rolled bijection. The remaining edits are proof repairs inKamiRiscvStep.v(andKamiRiscv.v,End2EndPipeline.v) with unchanged statements; the last three commits follow Kami's Word.v cleanup (split1,wmsb, shifts and remainders as the stdlib operations, unused lemmas gone) and Kami's operations becoming theZmodones (the instance's fields areZmod.addetc. and proofs name the stdlib lemmas;KamiRiscvStep.vkeeps itssimplcalls with file-localArguments Z.pow/Z.of_nat : simpl neverso the modulus stays folded) and Kami'sLt/Sltevaluating toZ.ltb(the instance'sltu/ltsareZ.ltbonuwordToZ/wordToZ, andis_mmio_specplus the eight branch cases decide that test from the riscv-side fact with one small tactic instead ofchangeblocks);end2end/src/end2end/KamiRiscvWordProperties.vstays because it suppliesword.riscv_okfor the Kami word (the division-by-zero and shift-masking conventions are unchanged).make all(compiler, processor, end2end, LiveVerif) passes;Print Assumptions end2end_lightbulbis unchanged. One caveat found on the way: with words asZmodrecords, a bareliawhose Zify-translated context mentions many words can build a certificate deep enough to overflow the kernel stack atQed(it did inEnd2EndPipeline.v); the offending step is now a small standalone lemma. Compile time of the processor + end2end cone is 10m09s versus 9m23s before the port (1.08x): the only real regression was a speculativeeapplyinprove_states_relatedthat now failed slowly by unfolding throughZmod, fixed withsimple eapply. After this port a failingeapplyis much more expensive than a succeeding one, sosimple eapplyis the right tool wherever a hot tactic applies a lemma undertry/repeat.Depends on mit-plv/kami#51 and on #561; CI cannot fetch the pinned Kami commit until #51 merges, so this stays a draft until then.
Written by Claude Fable 5.1 and Claude Opus 5.
🤖 Generated with Claude Code
https://claude.ai/code/session_01YJbiRBkJtM7x6PvYV6hmEm