Honeycomb

13. Kernel Execution🔗

Honeycomb has ordinary control flow, but the core throughput path is intentionally branch-free: a straight sequence of resident-weight MACs over a streamed operand block. This chapter gives that path its own compact executor and proves that it computes the source dot product for all inputs.

namespace Honeycomb structure KernelState where acc : Int weights : Nat -> Int stream : Nat -> Int wptr : Nat sptr : Nat def fsumFrom (w a : Nat -> Int) (wp sp : Nat) : Nat -> Int | 0 => 0 | n + 1 => w wp * a sp + fsumFrom w a (wp + 1) (sp + 1) n def kstep (s : KernelState) : KernelState := let x := s.weights s.wptr let y := s.stream s.sptr { s with acc := s.acc + x * y, wptr := s.wptr + 1, sptr := s.sptr + 1 } def krun : Nat -> KernelState -> KernelState | 0, s => s | n + 1, s => krun n (kstep s) def srun : Nat -> KernelState -> KernelState := krun theorem run_eq_srun_branchFree (n : Nat) (s : KernelState) : krun n s = srun n s := rfl

The accumulator invariant says exactly what has happened after n kernel cycles: the initial accumulator plus the dot product of the n resident and streamed operands starting at the two pointers.

theorem krun_acc : forall (n : Nat) (s : KernelState), (krun n s).acc = s.acc + fsumFrom s.weights s.stream s.wptr s.sptr n s:KernelState(krun 0 s).acc = s.acc + fsumFrom s.weights s.stream s.wptr s.sptr 0 s:KernelState(krun 0 s).acc = s.acc + fsumFrom s.weights s.stream s.wptr s.sptr 0 All goals completed! 🐙 n:Nats:KernelState(krun (n + 1) s).acc = s.acc + fsumFrom s.weights s.stream s.wptr s.sptr (n + 1) n:Nats:KernelState(krun (n + 1) s).acc = s.acc + fsumFrom s.weights s.stream s.wptr s.sptr (n + 1) n:Nats:KernelState(kstep s).acc + fsumFrom (kstep s).weights (kstep s).stream (kstep s).wptr (kstep s).sptr n = s.acc + fsumFrom s.weights s.stream s.wptr s.sptr (n + 1) n:Nats:KernelStates.acc + s.weights s.wptr * s.stream s.sptr + fsumFrom s.weights s.stream (s.wptr + 1) (s.sptr + 1) n = s.acc + (s.weights s.wptr * s.stream s.sptr + fsumFrom s.weights s.stream (s.wptr + 1) (s.sptr + 1) n) All goals completed! 🐙 def dotSpec (w a : Nat -> Int) (n : Nat) : Int := fsumFrom w a 0 0 n theorem kernelDot_correct (w a : Nat -> Int) (n : Nat) : (krun n (KernelState.mk 0 w a 0 0)).acc = dotSpec w a n := w:Nat Inta:Nat Intn:Nat(krun n { acc := 0, weights := w, stream := a, wptr := 0, sptr := 0 }).acc = dotSpec w a n w:Nat Inta:Nat Intn:Nat{ acc := 0, weights := w, stream := a, wptr := 0, sptr := 0 }.acc + fsumFrom { acc := 0, weights := w, stream := a, wptr := 0, sptr := 0 }.weights { acc := 0, weights := w, stream := a, wptr := 0, sptr := 0 }.stream { acc := 0, weights := w, stream := a, wptr := 0, sptr := 0 }.wptr { acc := 0, weights := w, stream := a, wptr := 0, sptr := 0 }.sptr n = dotSpec w a n All goals completed! 🐙

The integer proof above is the source-level claim. The fixed-width hardware claim needs an overflow obligation: every prefix sum that may enter the accumulator must fit the configured signed accumulator width. This is stronger than a final-result-only check, because wrapping at an intermediate cycle would already have changed the later computation.

def kernelPrefixFits (cfg : Config) (s : KernelState) (n : Nat) : Prop := forall k, k <= n -> signedFits cfg.accBits (s.acc + fsumFrom s.weights s.stream s.wptr s.sptr k) theorem kernel_final_fits_of_prefixFits (cfg : Config) (s : KernelState) (n : Nat) (hfit : kernelPrefixFits cfg s n) : signedFits cfg.accBits (krun n s).acc := cfg:Configs:KernelStaten:Nathfit:kernelPrefixFits cfg s nsignedFits cfg.accBits (krun n s).acc cfg:Configs:KernelStaten:Nathfit:kernelPrefixFits cfg s nsignedFits cfg.accBits (s.acc + fsumFrom s.weights s.stream s.wptr s.sptr n) All goals completed! 🐙 theorem kernel_accumulator_exact_when_prefixFits (cfg : Config) (hbits : 0 < cfg.accBits) (s : KernelState) (n : Nat) (hfit : kernelPrefixFits cfg s n) : (accOfInt cfg (krun n s).acc).toInt = (krun n s).acc := cfg:Confighbits:0 < cfg.accBitss:KernelStaten:Nathfit:kernelPrefixFits cfg s nBitVec.toInt (accOfInt cfg (krun n s).acc) = (krun n s).acc All goals completed! 🐙

A small executable smoke test stays in the book. If the semantics change, this example changes with it.

def wDemo : Nat -> Int := fun i => match i with | 0 => 1 | 1 => 2 | 2 => 3 | _ => 0 def aDemo : Nat -> Int := fun i => match i with | 0 => 4 | 1 => 5 | 2 => 6 | _ => 0 theorem kernelDot_demo : dotSpec wDemo aDemo 3 = 32 := dotSpec wDemo aDemo 3 = 32 All goals completed! 🐙 end Honeycomb

13.1. The machine computes this dot product🔗

Everything above lives in the unbounded-Int kernel model. The gap the review flagged (R5): no theorem stitched n iterations of the fixed-width machine's kmac to krun n. This section closes it. The abstraction function kernelOf reads a machine state as a kernel state — the accumulator's integer value, and the weight/stream sequences as the machine will actually read them, with both hardware wraps (the 16-bit pointer and the 8-bit physical index) folded into the indexing. Under the same kernelPrefixFits obligation that guards every intermediate sum, n ISA steps of a resident kmac loop compute exactly krun n: the fixed-width machine performs the exact integer dot product, end to end.

namespace Honeycomb /-- Append one term at the far end of the running sum. -/ theorem fsumFrom_snoc (w a : Nat -> Int) (wp sp : Nat) : forall k, fsumFrom w a wp sp (k + 1) = fsumFrom w a wp sp k + w (wp + k) * a (sp + k) w:Nat Inta:Nat Intwp:Natsp:NatfsumFrom w a wp sp (0 + 1) = fsumFrom w a wp sp 0 + w (wp + 0) * a (sp + 0) w:Nat Inta:Nat Intwp:Natsp:NatfsumFrom w a wp sp (0 + 1) = fsumFrom w a wp sp 0 + w (wp + 0) * a (sp + 0) All goals completed! 🐙 w:Nat Inta:Nat Intwp:Natsp:Natk:NatfsumFrom w a wp sp (k + 1 + 1) = fsumFrom w a wp sp (k + 1) + w (wp + (k + 1)) * a (sp + (k + 1)) w:Nat Inta:Nat Intwp:Natsp:Natk:NatfsumFrom w a wp sp (k + 1 + 1) = fsumFrom w a wp sp (k + 1) + w (wp + (k + 1)) * a (sp + (k + 1)) w:Nat Inta:Nat Intwp:Natsp:Natk:Natw wp * a sp + fsumFrom w a (wp + 1) (sp + 1) (k + 1) = fsumFrom w a wp sp (k + 1) + w (wp + (k + 1)) * a (sp + (k + 1)) w:Nat Inta:Nat Intwp:Natsp:Natk:Natw wp * a sp + (fsumFrom w a (wp + 1) (sp + 1) k + w (wp + 1 + k) * a (sp + 1 + k)) = fsumFrom w a wp sp (k + 1) + w (wp + (k + 1)) * a (sp + (k + 1)) w:Nat Inta:Nat Intwp:Natsp:Natk:Natw wp * a sp + (fsumFrom w a (wp + 1) (sp + 1) k + w (wp + 1 + k) * a (sp + 1 + k)) = w wp * a sp + fsumFrom w a (wp + 1) (sp + 1) k + w (wp + (k + 1)) * a (sp + (k + 1)) w:Nat Inta:Nat Intwp:Natsp:Natk:Nath1:wp + 1 + k = wp + (k + 1)w wp * a sp + (fsumFrom w a (wp + 1) (sp + 1) k + w (wp + 1 + k) * a (sp + 1 + k)) = w wp * a sp + fsumFrom w a (wp + 1) (sp + 1) k + w (wp + (k + 1)) * a (sp + (k + 1)) w:Nat Inta:Nat Intwp:Natsp:Natk:Nath1:wp + 1 + k = wp + (k + 1)h2:sp + 1 + k = sp + (k + 1)w wp * a sp + (fsumFrom w a (wp + 1) (sp + 1) k + w (wp + 1 + k) * a (sp + 1 + k)) = w wp * a sp + fsumFrom w a (wp + 1) (sp + 1) k + w (wp + (k + 1)) * a (sp + (k + 1)) w:Nat Inta:Nat Intwp:Natsp:Natk:Nath1:wp + 1 + k = wp + (k + 1)h2:sp + 1 + k = sp + (k + 1)w wp * a sp + (fsumFrom w a (wp + 1) (sp + 1) k + w (wp + (k + 1)) * a (sp + (k + 1))) = w wp * a sp + fsumFrom w a (wp + 1) (sp + 1) k + w (wp + (k + 1)) * a (sp + (k + 1)) All goals completed! 🐙 /-- The 8-bit physical index ignores the 16-bit pointer wrap: reducing mod `2^16` first changes nothing mod `2^8`. -/ theorem memIndexOfNat_mod65536 (x : Nat) : memIndexOfNat defaultConfig (x % 65536) = memIndexOfNat defaultConfig x := x:NatmemIndexOfNat defaultConfig (x % 65536) = memIndexOfNat defaultConfig x All goals completed! 🐙 /-- Likewise for the 64-bit program counter. -/ theorem memIndexOfNat_mod2_64 (x : Nat) : memIndexOfNat defaultConfig (x % 18446744073709551616) = memIndexOfNat defaultConfig x := x:NatmemIndexOfNat defaultConfig (x % 18446744073709551616) = memIndexOfNat defaultConfig x All goals completed! 🐙 /-- The kernel state a machine state denotes: the accumulator's integer value, and the operand sequences as the machine will read them — index `i` is the fixed-width read the hardware performs `i` kmacs from now, both wraps folded in. -/ def kernelOf (s : State defaultConfig) : KernelState := { acc := s.acc.toInt, weights := fun i => (s.weights (memIndexOfNat defaultConfig (s.wptr.toNat + i))).toInt, stream := fun i => (s.stream (memIndexOfNat defaultConfig (s.sptr.toNat + i))).toInt, wptr := 0, sptr := 0 } /-- **The kmac-loop invariant.** Stepping a resident `kmac` loop `k` instructions deep: the machine is still running, its memories are untouched, its pointers and program counter have advanced with their wraps, and its accumulator holds — exactly, as an integer — the kernel model's running sum. -/ theorem kmac_loop_invariant (s0 : State defaultConfig) (imem : Nat -> DecodedInstr) (n : Nat) (hhalt : s0.halted = false) (hprog : forall k, k < n -> (imem (memIndexOfNat defaultConfig (s0.pc.toNat + k))).op = .kmac) (hfit : kernelPrefixFits defaultConfig (kernelOf s0) n) : forall k, k <= n -> exists sk, stepN (programOf imem) k s0 = some sk /\ sk.halted = false /\ sk.weights = s0.weights /\ sk.stream = s0.stream /\ sk.wptr.toNat = (s0.wptr.toNat + k) % 65536 /\ sk.sptr.toNat = (s0.sptr.toNat + k) % 65536 /\ sk.pc.toNat = (s0.pc.toNat + k) % 18446744073709551616 /\ sk.acc.toInt = (krun k (kernelOf s0)).acc := s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) n (k : Nat), k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acc s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natk n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acc induction k with s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) n0 n sk, stepN (programOf imem) 0 s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + 0) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + 0) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + 0) % 18446744073709551616 BitVec.toInt sk.acc = (krun 0 (kernelOf s0)).acc s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) na✝:0 n sk, stepN (programOf imem) 0 s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + 0) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + 0) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + 0) % 18446744073709551616 BitVec.toInt sk.acc = (krun 0 (kernelOf s0)).acc s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) na✝:0 nBitVec.toNat s0.wptr = (BitVec.toNat s0.wptr + 0) % 65536s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) na✝:0 nBitVec.toNat s0.sptr = (BitVec.toNat s0.sptr + 0) % 65536s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) na✝:0 nBitVec.toNat s0.pc = (BitVec.toNat s0.pc + 0) % 18446744073709551616s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) na✝:0 nBitVec.toInt s0.acc = (krun 0 (kernelOf s0)).acc s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) na✝:0 nBitVec.toNat s0.wptr = (BitVec.toNat s0.wptr + 0) % 65536 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) na✝:0 nhlt:BitVec.toNat s0.wptr < 65536BitVec.toNat s0.wptr = (BitVec.toNat s0.wptr + 0) % 65536 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) na✝:0 nhlt:BitVec.toNat s0.wptr < 65536BitVec.toNat s0.wptr = BitVec.toNat s0.wptr % 65536; All goals completed! 🐙 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) na✝:0 nBitVec.toNat s0.sptr = (BitVec.toNat s0.sptr + 0) % 65536 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) na✝:0 nhlt:BitVec.toNat s0.sptr < 65536BitVec.toNat s0.sptr = (BitVec.toNat s0.sptr + 0) % 65536 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) na✝:0 nhlt:BitVec.toNat s0.sptr < 65536BitVec.toNat s0.sptr = BitVec.toNat s0.sptr % 65536; All goals completed! 🐙 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) na✝:0 nBitVec.toNat s0.pc = (BitVec.toNat s0.pc + 0) % 18446744073709551616 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) na✝:0 nhlt:BitVec.toNat s0.pc < 18446744073709551616BitVec.toNat s0.pc = (BitVec.toNat s0.pc + 0) % 18446744073709551616 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) na✝:0 nhlt:BitVec.toNat s0.pc < 18446744073709551616BitVec.toNat s0.pc = BitVec.toNat s0.pc % 18446744073709551616; All goals completed! 🐙 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) na✝:0 nBitVec.toInt s0.acc = (krun 0 (kernelOf s0)).acc All goals completed! 🐙 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acck + 1 n sk, stepN (programOf imem) (k + 1) s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + (k + 1)) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + (k + 1)) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + (k + 1)) % 18446744073709551616 BitVec.toInt sk.acc = (krun (k + 1) (kernelOf s0)).acc s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 n sk, stepN (programOf imem) (k + 1) s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + (k + 1)) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + (k + 1)) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + (k + 1)) % 18446744073709551616 BitVec.toInt sk.acc = (krun (k + 1) (kernelOf s0)).acc s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acc sk, stepN (programOf imem) (k + 1) s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + (k + 1)) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + (k + 1)) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + (k + 1)) % 18446744073709551616 BitVec.toInt sk.acc = (krun (k + 1) (kernelOf s0)).acc -- the next instruction is the loop's kmac s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchd:(imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))).op = CellOp.kmac sk, stepN (programOf imem) (k + 1) s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + (k + 1)) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + (k + 1)) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + (k + 1)) % 18446744073709551616 BitVec.toInt sk.acc = (krun (k + 1) (kernelOf s0)).acc -- one more ISA step s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchd:(imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))).op = CellOp.kmachone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk) sk, stepN (programOf imem) (k + 1) s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + (k + 1)) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + (k + 1)) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + (k + 1)) % 18446744073709551616 BitVec.toInt sk.acc = (krun (k + 1) (kernelOf s0)).acc s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchd:(imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))).op = CellOp.kmachone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)stepN (programOf imem) (k + 1) s0 = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchd:(imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))).op = CellOp.kmachone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)(execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk).halted = falses0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchd:(imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))).op = CellOp.kmachone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)(execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk).weights = s0.weightss0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchd:(imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))).op = CellOp.kmachone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)(execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk).stream = s0.streams0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchd:(imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))).op = CellOp.kmachone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)BitVec.toNat (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk).wptr = (BitVec.toNat s0.wptr + (k + 1)) % 65536s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchd:(imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))).op = CellOp.kmachone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)BitVec.toNat (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk).sptr = (BitVec.toNat s0.sptr + (k + 1)) % 65536s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchd:(imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))).op = CellOp.kmachone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)BitVec.toNat (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk).pc = (BitVec.toNat s0.pc + (k + 1)) % 18446744073709551616s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchd:(imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))).op = CellOp.kmachone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)BitVec.toInt (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk).acc = (krun (k + 1) (kernelOf s0)).acc s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchd:(imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))).op = CellOp.kmachone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)stepN (programOf imem) (k + 1) s0 = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk) s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchd:(imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))).op = CellOp.kmachone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)((some sk).bind fun s' => step defaultConfig (programOf imem) s') = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk) All goals completed! 🐙 all_goals ( s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmacBitVec.toInt (execDecoded d sk).acc = (krun (k + 1) (kernelOf s0)).acc s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmacBitVec.toInt (match d.op with | CellOp.mac => retire (setAcc sk (accAddProduct defaultConfig sk.acc (elemOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.kmac => retire (setPtrs (setAcc sk (accAddProduct defaultConfig sk.acc (readWeight sk (memIndexOfLocal defaultConfig sk.wptr)) (readStream sk (memIndexOfLocal defaultConfig sk.sptr)))) (nextLocal defaultConfig sk.wptr) (nextLocal defaultConfig sk.sptr)) (nextPC defaultConfig sk.pc) | CellOp.clracc => retire (setAcc sk 0) (nextPC defaultConfig sk.pc) | CellOp.movacc => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig (BitVec.toInt sk.acc)))) (nextPC defaultConfig sk.pc) | CellOp.li => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig d.imm))) (nextPC defaultConfig sk.pc) | CellOp.ld => retire (setRegs sk (updReg sk.regs d.rd (readData sk (memIndexOfWord defaultConfig (readReg sk d.ra))))) (nextPC defaultConfig sk.pc) | CellOp.st => retire (setData sk (updMem sk.data (memIndexOfWord defaultConfig (readReg sk d.ra)) (readReg sk d.rb))) (nextPC defaultConfig sk.pc) | CellOp.setwptr => retire (setPtrs sk (localAddrOfNat defaultConfig d.addr) sk.sptr) (nextPC defaultConfig sk.pc) | CellOp.setsptr => retire (setPtrs sk sk.wptr (localAddrOfNat defaultConfig d.addr)) (nextPC defaultConfig sk.pc) | CellOp.blz => retire sk (if BitVec.toInt (readReg sk d.ra) 0 then branchPC defaultConfig sk.pc d.imm else nextPC defaultConfig sk.pc) | CellOp.alu => execAlu (functOf d.addr) d.rd d.ra d.rb sk | CellOp.jr => retire sk (jumpPC defaultConfig (readReg sk d.ra)) | CellOp.stw => retire (setWeights sk (updWeight sk.weights (memIndexOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.halt => retireHalt sk).acc = (krun (k + 1) (kernelOf s0)).acc s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmacBitVec.toInt (match CellOp.kmac with | CellOp.mac => retire (setAcc sk (accAddProduct defaultConfig sk.acc (elemOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.kmac => retire (setPtrs (setAcc sk (accAddProduct defaultConfig sk.acc (readWeight sk (memIndexOfLocal defaultConfig sk.wptr)) (readStream sk (memIndexOfLocal defaultConfig sk.sptr)))) (nextLocal defaultConfig sk.wptr) (nextLocal defaultConfig sk.sptr)) (nextPC defaultConfig sk.pc) | CellOp.clracc => retire (setAcc sk 0) (nextPC defaultConfig sk.pc) | CellOp.movacc => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig (BitVec.toInt sk.acc)))) (nextPC defaultConfig sk.pc) | CellOp.li => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig d.imm))) (nextPC defaultConfig sk.pc) | CellOp.ld => retire (setRegs sk (updReg sk.regs d.rd (readData sk (memIndexOfWord defaultConfig (readReg sk d.ra))))) (nextPC defaultConfig sk.pc) | CellOp.st => retire (setData sk (updMem sk.data (memIndexOfWord defaultConfig (readReg sk d.ra)) (readReg sk d.rb))) (nextPC defaultConfig sk.pc) | CellOp.setwptr => retire (setPtrs sk (localAddrOfNat defaultConfig d.addr) sk.sptr) (nextPC defaultConfig sk.pc) | CellOp.setsptr => retire (setPtrs sk sk.wptr (localAddrOfNat defaultConfig d.addr)) (nextPC defaultConfig sk.pc) | CellOp.blz => retire sk (if BitVec.toInt (readReg sk d.ra) 0 then branchPC defaultConfig sk.pc d.imm else nextPC defaultConfig sk.pc) | CellOp.alu => execAlu (functOf d.addr) d.rd d.ra d.rb sk | CellOp.jr => retire sk (jumpPC defaultConfig (readReg sk d.ra)) | CellOp.stw => retire (setWeights sk (updWeight sk.weights (memIndexOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.halt => retireHalt sk).acc = (krun (k + 1) (kernelOf s0)).acc) s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmac(match CellOp.kmac with | CellOp.mac => retire (setAcc sk (accAddProduct defaultConfig sk.acc (elemOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.kmac => retire (setPtrs (setAcc sk (accAddProduct defaultConfig sk.acc (readWeight sk (memIndexOfLocal defaultConfig sk.wptr)) (readStream sk (memIndexOfLocal defaultConfig sk.sptr)))) (nextLocal defaultConfig sk.wptr) (nextLocal defaultConfig sk.sptr)) (nextPC defaultConfig sk.pc) | CellOp.clracc => retire (setAcc sk 0) (nextPC defaultConfig sk.pc) | CellOp.movacc => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig (BitVec.toInt sk.acc)))) (nextPC defaultConfig sk.pc) | CellOp.li => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig d.imm))) (nextPC defaultConfig sk.pc) | CellOp.ld => retire (setRegs sk (updReg sk.regs d.rd (readData sk (memIndexOfWord defaultConfig (readReg sk d.ra))))) (nextPC defaultConfig sk.pc) | CellOp.st => retire (setData sk (updMem sk.data (memIndexOfWord defaultConfig (readReg sk d.ra)) (readReg sk d.rb))) (nextPC defaultConfig sk.pc) | CellOp.setwptr => retire (setPtrs sk (localAddrOfNat defaultConfig d.addr) sk.sptr) (nextPC defaultConfig sk.pc) | CellOp.setsptr => retire (setPtrs sk sk.wptr (localAddrOfNat defaultConfig d.addr)) (nextPC defaultConfig sk.pc) | CellOp.blz => retire sk (if BitVec.toInt (readReg sk d.ra) 0 then branchPC defaultConfig sk.pc d.imm else nextPC defaultConfig sk.pc) | CellOp.alu => execAlu (functOf d.addr) d.rd d.ra d.rb sk | CellOp.jr => retire sk (jumpPC defaultConfig (readReg sk d.ra)) | CellOp.stw => retire (setWeights sk (updWeight sk.weights (memIndexOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.halt => retireHalt sk).halted = false -- halted: retire preserves it All goals completed! 🐙 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmac(match CellOp.kmac with | CellOp.mac => retire (setAcc sk (accAddProduct defaultConfig sk.acc (elemOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.kmac => retire (setPtrs (setAcc sk (accAddProduct defaultConfig sk.acc (readWeight sk (memIndexOfLocal defaultConfig sk.wptr)) (readStream sk (memIndexOfLocal defaultConfig sk.sptr)))) (nextLocal defaultConfig sk.wptr) (nextLocal defaultConfig sk.sptr)) (nextPC defaultConfig sk.pc) | CellOp.clracc => retire (setAcc sk 0) (nextPC defaultConfig sk.pc) | CellOp.movacc => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig (BitVec.toInt sk.acc)))) (nextPC defaultConfig sk.pc) | CellOp.li => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig d.imm))) (nextPC defaultConfig sk.pc) | CellOp.ld => retire (setRegs sk (updReg sk.regs d.rd (readData sk (memIndexOfWord defaultConfig (readReg sk d.ra))))) (nextPC defaultConfig sk.pc) | CellOp.st => retire (setData sk (updMem sk.data (memIndexOfWord defaultConfig (readReg sk d.ra)) (readReg sk d.rb))) (nextPC defaultConfig sk.pc) | CellOp.setwptr => retire (setPtrs sk (localAddrOfNat defaultConfig d.addr) sk.sptr) (nextPC defaultConfig sk.pc) | CellOp.setsptr => retire (setPtrs sk sk.wptr (localAddrOfNat defaultConfig d.addr)) (nextPC defaultConfig sk.pc) | CellOp.blz => retire sk (if BitVec.toInt (readReg sk d.ra) 0 then branchPC defaultConfig sk.pc d.imm else nextPC defaultConfig sk.pc) | CellOp.alu => execAlu (functOf d.addr) d.rd d.ra d.rb sk | CellOp.jr => retire sk (jumpPC defaultConfig (readReg sk d.ra)) | CellOp.stw => retire (setWeights sk (updWeight sk.weights (memIndexOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.halt => retireHalt sk).weights = s0.weights All goals completed! 🐙 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmac(match CellOp.kmac with | CellOp.mac => retire (setAcc sk (accAddProduct defaultConfig sk.acc (elemOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.kmac => retire (setPtrs (setAcc sk (accAddProduct defaultConfig sk.acc (readWeight sk (memIndexOfLocal defaultConfig sk.wptr)) (readStream sk (memIndexOfLocal defaultConfig sk.sptr)))) (nextLocal defaultConfig sk.wptr) (nextLocal defaultConfig sk.sptr)) (nextPC defaultConfig sk.pc) | CellOp.clracc => retire (setAcc sk 0) (nextPC defaultConfig sk.pc) | CellOp.movacc => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig (BitVec.toInt sk.acc)))) (nextPC defaultConfig sk.pc) | CellOp.li => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig d.imm))) (nextPC defaultConfig sk.pc) | CellOp.ld => retire (setRegs sk (updReg sk.regs d.rd (readData sk (memIndexOfWord defaultConfig (readReg sk d.ra))))) (nextPC defaultConfig sk.pc) | CellOp.st => retire (setData sk (updMem sk.data (memIndexOfWord defaultConfig (readReg sk d.ra)) (readReg sk d.rb))) (nextPC defaultConfig sk.pc) | CellOp.setwptr => retire (setPtrs sk (localAddrOfNat defaultConfig d.addr) sk.sptr) (nextPC defaultConfig sk.pc) | CellOp.setsptr => retire (setPtrs sk sk.wptr (localAddrOfNat defaultConfig d.addr)) (nextPC defaultConfig sk.pc) | CellOp.blz => retire sk (if BitVec.toInt (readReg sk d.ra) 0 then branchPC defaultConfig sk.pc d.imm else nextPC defaultConfig sk.pc) | CellOp.alu => execAlu (functOf d.addr) d.rd d.ra d.rb sk | CellOp.jr => retire sk (jumpPC defaultConfig (readReg sk d.ra)) | CellOp.stw => retire (setWeights sk (updWeight sk.weights (memIndexOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.halt => retireHalt sk).stream = s0.stream All goals completed! 🐙 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmacBitVec.toNat (match CellOp.kmac with | CellOp.mac => retire (setAcc sk (accAddProduct defaultConfig sk.acc (elemOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.kmac => retire (setPtrs (setAcc sk (accAddProduct defaultConfig sk.acc (readWeight sk (memIndexOfLocal defaultConfig sk.wptr)) (readStream sk (memIndexOfLocal defaultConfig sk.sptr)))) (nextLocal defaultConfig sk.wptr) (nextLocal defaultConfig sk.sptr)) (nextPC defaultConfig sk.pc) | CellOp.clracc => retire (setAcc sk 0) (nextPC defaultConfig sk.pc) | CellOp.movacc => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig (BitVec.toInt sk.acc)))) (nextPC defaultConfig sk.pc) | CellOp.li => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig d.imm))) (nextPC defaultConfig sk.pc) | CellOp.ld => retire (setRegs sk (updReg sk.regs d.rd (readData sk (memIndexOfWord defaultConfig (readReg sk d.ra))))) (nextPC defaultConfig sk.pc) | CellOp.st => retire (setData sk (updMem sk.data (memIndexOfWord defaultConfig (readReg sk d.ra)) (readReg sk d.rb))) (nextPC defaultConfig sk.pc) | CellOp.setwptr => retire (setPtrs sk (localAddrOfNat defaultConfig d.addr) sk.sptr) (nextPC defaultConfig sk.pc) | CellOp.setsptr => retire (setPtrs sk sk.wptr (localAddrOfNat defaultConfig d.addr)) (nextPC defaultConfig sk.pc) | CellOp.blz => retire sk (if BitVec.toInt (readReg sk d.ra) 0 then branchPC defaultConfig sk.pc d.imm else nextPC defaultConfig sk.pc) | CellOp.alu => execAlu (functOf d.addr) d.rd d.ra d.rb sk | CellOp.jr => retire sk (jumpPC defaultConfig (readReg sk d.ra)) | CellOp.stw => retire (setWeights sk (updWeight sk.weights (memIndexOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.halt => retireHalt sk).wptr = (BitVec.toNat s0.wptr + (k + 1)) % 65536 -- wptr advances with its wrap s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmac(BitVec.toNat sk.wptr + 1) % 65536 = (BitVec.toNat s0.wptr + (k + 1)) % 65536 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmac((BitVec.toNat s0.wptr + k) % 65536 + 1) % 65536 = (BitVec.toNat s0.wptr + (k + 1)) % 65536 All goals completed! 🐙 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmacBitVec.toNat (match CellOp.kmac with | CellOp.mac => retire (setAcc sk (accAddProduct defaultConfig sk.acc (elemOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.kmac => retire (setPtrs (setAcc sk (accAddProduct defaultConfig sk.acc (readWeight sk (memIndexOfLocal defaultConfig sk.wptr)) (readStream sk (memIndexOfLocal defaultConfig sk.sptr)))) (nextLocal defaultConfig sk.wptr) (nextLocal defaultConfig sk.sptr)) (nextPC defaultConfig sk.pc) | CellOp.clracc => retire (setAcc sk 0) (nextPC defaultConfig sk.pc) | CellOp.movacc => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig (BitVec.toInt sk.acc)))) (nextPC defaultConfig sk.pc) | CellOp.li => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig d.imm))) (nextPC defaultConfig sk.pc) | CellOp.ld => retire (setRegs sk (updReg sk.regs d.rd (readData sk (memIndexOfWord defaultConfig (readReg sk d.ra))))) (nextPC defaultConfig sk.pc) | CellOp.st => retire (setData sk (updMem sk.data (memIndexOfWord defaultConfig (readReg sk d.ra)) (readReg sk d.rb))) (nextPC defaultConfig sk.pc) | CellOp.setwptr => retire (setPtrs sk (localAddrOfNat defaultConfig d.addr) sk.sptr) (nextPC defaultConfig sk.pc) | CellOp.setsptr => retire (setPtrs sk sk.wptr (localAddrOfNat defaultConfig d.addr)) (nextPC defaultConfig sk.pc) | CellOp.blz => retire sk (if BitVec.toInt (readReg sk d.ra) 0 then branchPC defaultConfig sk.pc d.imm else nextPC defaultConfig sk.pc) | CellOp.alu => execAlu (functOf d.addr) d.rd d.ra d.rb sk | CellOp.jr => retire sk (jumpPC defaultConfig (readReg sk d.ra)) | CellOp.stw => retire (setWeights sk (updWeight sk.weights (memIndexOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.halt => retireHalt sk).sptr = (BitVec.toNat s0.sptr + (k + 1)) % 65536 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmac(BitVec.toNat sk.sptr + 1) % 65536 = (BitVec.toNat s0.sptr + (k + 1)) % 65536 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmac((BitVec.toNat s0.sptr + k) % 65536 + 1) % 65536 = (BitVec.toNat s0.sptr + (k + 1)) % 65536 All goals completed! 🐙 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmacBitVec.toNat (match CellOp.kmac with | CellOp.mac => retire (setAcc sk (accAddProduct defaultConfig sk.acc (elemOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.kmac => retire (setPtrs (setAcc sk (accAddProduct defaultConfig sk.acc (readWeight sk (memIndexOfLocal defaultConfig sk.wptr)) (readStream sk (memIndexOfLocal defaultConfig sk.sptr)))) (nextLocal defaultConfig sk.wptr) (nextLocal defaultConfig sk.sptr)) (nextPC defaultConfig sk.pc) | CellOp.clracc => retire (setAcc sk 0) (nextPC defaultConfig sk.pc) | CellOp.movacc => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig (BitVec.toInt sk.acc)))) (nextPC defaultConfig sk.pc) | CellOp.li => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig d.imm))) (nextPC defaultConfig sk.pc) | CellOp.ld => retire (setRegs sk (updReg sk.regs d.rd (readData sk (memIndexOfWord defaultConfig (readReg sk d.ra))))) (nextPC defaultConfig sk.pc) | CellOp.st => retire (setData sk (updMem sk.data (memIndexOfWord defaultConfig (readReg sk d.ra)) (readReg sk d.rb))) (nextPC defaultConfig sk.pc) | CellOp.setwptr => retire (setPtrs sk (localAddrOfNat defaultConfig d.addr) sk.sptr) (nextPC defaultConfig sk.pc) | CellOp.setsptr => retire (setPtrs sk sk.wptr (localAddrOfNat defaultConfig d.addr)) (nextPC defaultConfig sk.pc) | CellOp.blz => retire sk (if BitVec.toInt (readReg sk d.ra) 0 then branchPC defaultConfig sk.pc d.imm else nextPC defaultConfig sk.pc) | CellOp.alu => execAlu (functOf d.addr) d.rd d.ra d.rb sk | CellOp.jr => retire sk (jumpPC defaultConfig (readReg sk d.ra)) | CellOp.stw => retire (setWeights sk (updWeight sk.weights (memIndexOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.halt => retireHalt sk).pc = (BitVec.toNat s0.pc + (k + 1)) % 18446744073709551616 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmac(BitVec.toNat sk.pc + 1) % 18446744073709551616 = (BitVec.toNat s0.pc + (k + 1)) % 18446744073709551616 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmac((BitVec.toNat s0.pc + k) % 18446744073709551616 + 1) % 18446744073709551616 = (BitVec.toNat s0.pc + (k + 1)) % 18446744073709551616 All goals completed! 🐙 s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmacBitVec.toInt (match CellOp.kmac with | CellOp.mac => retire (setAcc sk (accAddProduct defaultConfig sk.acc (elemOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.kmac => retire (setPtrs (setAcc sk (accAddProduct defaultConfig sk.acc (readWeight sk (memIndexOfLocal defaultConfig sk.wptr)) (readStream sk (memIndexOfLocal defaultConfig sk.sptr)))) (nextLocal defaultConfig sk.wptr) (nextLocal defaultConfig sk.sptr)) (nextPC defaultConfig sk.pc) | CellOp.clracc => retire (setAcc sk 0) (nextPC defaultConfig sk.pc) | CellOp.movacc => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig (BitVec.toInt sk.acc)))) (nextPC defaultConfig sk.pc) | CellOp.li => retire (setRegs sk (updReg sk.regs d.rd (wordOfInt defaultConfig d.imm))) (nextPC defaultConfig sk.pc) | CellOp.ld => retire (setRegs sk (updReg sk.regs d.rd (readData sk (memIndexOfWord defaultConfig (readReg sk d.ra))))) (nextPC defaultConfig sk.pc) | CellOp.st => retire (setData sk (updMem sk.data (memIndexOfWord defaultConfig (readReg sk d.ra)) (readReg sk d.rb))) (nextPC defaultConfig sk.pc) | CellOp.setwptr => retire (setPtrs sk (localAddrOfNat defaultConfig d.addr) sk.sptr) (nextPC defaultConfig sk.pc) | CellOp.setsptr => retire (setPtrs sk sk.wptr (localAddrOfNat defaultConfig d.addr)) (nextPC defaultConfig sk.pc) | CellOp.blz => retire sk (if BitVec.toInt (readReg sk d.ra) 0 then branchPC defaultConfig sk.pc d.imm else nextPC defaultConfig sk.pc) | CellOp.alu => execAlu (functOf d.addr) d.rd d.ra d.rb sk | CellOp.jr => retire sk (jumpPC defaultConfig (readReg sk d.ra)) | CellOp.stw => retire (setWeights sk (updWeight sk.weights (memIndexOfWord defaultConfig (readReg sk d.ra)) (elemOfWord defaultConfig (readReg sk d.rb)))) (nextPC defaultConfig sk.pc) | CellOp.halt => retireHalt sk).acc = (krun (k + 1) (kernelOf s0)).acc -- the accumulator stays exact: the (k+1)-prefix fits s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmacBitVec.toInt (accOfInt defaultConfig (BitVec.toInt sk.acc + product (sk.weights (memIndexOfNat defaultConfig (BitVec.toNat sk.wptr))) (sk.stream (memIndexOfNat defaultConfig (BitVec.toNat sk.sptr))))) = (krun (k + 1) (kernelOf s0)).acc s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmachidxw:memIndexOfNat defaultConfig (BitVec.toNat sk.wptr) = memIndexOfNat defaultConfig (BitVec.toNat s0.wptr + k)BitVec.toInt (accOfInt defaultConfig (BitVec.toInt sk.acc + product (sk.weights (memIndexOfNat defaultConfig (BitVec.toNat sk.wptr))) (sk.stream (memIndexOfNat defaultConfig (BitVec.toNat sk.sptr))))) = (krun (k + 1) (kernelOf s0)).acc s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmachidxw:memIndexOfNat defaultConfig (BitVec.toNat sk.wptr) = memIndexOfNat defaultConfig (BitVec.toNat s0.wptr + k)hidxs:memIndexOfNat defaultConfig (BitVec.toNat sk.sptr) = memIndexOfNat defaultConfig (BitVec.toNat s0.sptr + k)BitVec.toInt (accOfInt defaultConfig (BitVec.toInt sk.acc + product (sk.weights (memIndexOfNat defaultConfig (BitVec.toNat sk.wptr))) (sk.stream (memIndexOfNat defaultConfig (BitVec.toNat sk.sptr))))) = (krun (k + 1) (kernelOf s0)).acc s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmachidxw:memIndexOfNat defaultConfig (BitVec.toNat sk.wptr) = memIndexOfNat defaultConfig (BitVec.toNat s0.wptr + k)hidxs:memIndexOfNat defaultConfig (BitVec.toNat sk.sptr) = memIndexOfNat defaultConfig (BitVec.toNat s0.sptr + k)BitVec.toInt (accOfInt defaultConfig (BitVec.toInt sk.acc + product (s0.weights (memIndexOfNat defaultConfig (BitVec.toNat s0.wptr + k))) (s0.stream (memIndexOfNat defaultConfig (BitVec.toNat s0.sptr + k))))) = (krun (k + 1) (kernelOf s0)).acc s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmachidxw:memIndexOfNat defaultConfig (BitVec.toNat sk.wptr) = memIndexOfNat defaultConfig (BitVec.toNat s0.wptr + k)hidxs:memIndexOfNat defaultConfig (BitVec.toNat sk.sptr) = memIndexOfNat defaultConfig (BitVec.toNat s0.sptr + k)hsum:BitVec.toInt sk.acc + (kernelOf s0).weights k * (kernelOf s0).stream k = (krun (k + 1) (kernelOf s0)).accBitVec.toInt (accOfInt defaultConfig (BitVec.toInt sk.acc + product (s0.weights (memIndexOfNat defaultConfig (BitVec.toNat s0.wptr + k))) (s0.stream (memIndexOfNat defaultConfig (BitVec.toNat s0.sptr + k))))) = (krun (k + 1) (kernelOf s0)).acc s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmachidxw:memIndexOfNat defaultConfig (BitVec.toNat sk.wptr) = memIndexOfNat defaultConfig (BitVec.toNat s0.wptr + k)hidxs:memIndexOfNat defaultConfig (BitVec.toNat sk.sptr) = memIndexOfNat defaultConfig (BitVec.toNat s0.sptr + k)hsum:BitVec.toInt sk.acc + (kernelOf s0).weights k * (kernelOf s0).stream k = (krun (k + 1) (kernelOf s0)).acchfits:signedFits defaultConfig.accBits (BitVec.toInt sk.acc + (kernelOf s0).weights k * (kernelOf s0).stream k)BitVec.toInt (accOfInt defaultConfig (BitVec.toInt sk.acc + product (s0.weights (memIndexOfNat defaultConfig (BitVec.toNat s0.wptr + k))) (s0.stream (memIndexOfNat defaultConfig (BitVec.toNat s0.sptr + k))))) = (krun (k + 1) (kernelOf s0)).acc calc (accOfInt defaultConfig (sk.acc.toInt + (s0.weights (memIndexOfNat defaultConfig (s0.wptr.toNat + k))).toInt * (s0.stream (memIndexOfNat defaultConfig (s0.sptr.toNat + k))).toInt)).toInt = sk.acc.toInt + ((kernelOf s0).weights k) * ((kernelOf s0).stream k) := s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmachidxw:memIndexOfNat defaultConfig (BitVec.toNat sk.wptr) = memIndexOfNat defaultConfig (BitVec.toNat s0.wptr + k)hidxs:memIndexOfNat defaultConfig (BitVec.toNat sk.sptr) = memIndexOfNat defaultConfig (BitVec.toNat s0.sptr + k)hsum:BitVec.toInt sk.acc + (kernelOf s0).weights k * (kernelOf s0).stream k = (krun (k + 1) (kernelOf s0)).acchfits:signedFits defaultConfig.accBits (BitVec.toInt sk.acc + (kernelOf s0).weights k * (kernelOf s0).stream k)BitVec.toInt (accOfInt defaultConfig (BitVec.toInt sk.acc + BitVec.toInt (s0.weights (memIndexOfNat defaultConfig (BitVec.toNat s0.wptr + k))) * BitVec.toInt (s0.stream (memIndexOfNat defaultConfig (BitVec.toNat s0.sptr + k))))) = BitVec.toInt sk.acc + (kernelOf s0).weights k * (kernelOf s0).stream k exact accOfInt_exact defaultConfig (s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nk:Natih:k n sk, stepN (programOf imem) k s0 = some sk sk.halted = false sk.weights = s0.weights sk.stream = s0.stream BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536 BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536 BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616 BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchk:k + 1 nsk:State defaultConfighstep:stepN (programOf imem) k s0 = some skhh:sk.halted = falsehw:sk.weights = s0.weightshs:sk.stream = s0.streamhwp:BitVec.toNat sk.wptr = (BitVec.toNat s0.wptr + k) % 65536hsp:BitVec.toNat sk.sptr = (BitVec.toNat s0.sptr + k) % 65536hpc:BitVec.toNat sk.pc = (BitVec.toNat s0.pc + k) % 18446744073709551616hacc:BitVec.toInt sk.acc = (krun k (kernelOf s0)).acchone:step defaultConfig (programOf imem) sk = some (execDecoded (imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc))) sk)d:DecodedInstrhgen:imem (memIndexOfNat defaultConfig (BitVec.toNat sk.pc)) = dhd:d.op = CellOp.kmachidxw:memIndexOfNat defaultConfig (BitVec.toNat sk.wptr) = memIndexOfNat defaultConfig (BitVec.toNat s0.wptr + k)hidxs:memIndexOfNat defaultConfig (BitVec.toNat sk.sptr) = memIndexOfNat defaultConfig (BitVec.toNat s0.sptr + k)hsum:BitVec.toInt sk.acc + (kernelOf s0).weights k * (kernelOf s0).stream k = (krun (k + 1) (kernelOf s0)).acchfits:signedFits defaultConfig.accBits (BitVec.toInt sk.acc + (kernelOf s0).weights k * (kernelOf s0).stream k)0 < defaultConfig.accBits All goals completed! 🐙) hfits _ = (krun (k + 1) (kernelOf s0)).acc := hsum /-- **The machine computes the exact dot product.** A resident `kmac` loop, run `n` ISA steps under the prefix-fit obligation, leaves in the fixed-width accumulator exactly the kernel model's integer result — the hardware's wraps never touch the value. Composed with `kernelDot_correct`, the machine's accumulator *is* the mathematical dot product. -/ theorem kmac_loop_exact (s0 : State defaultConfig) (imem : Nat -> DecodedInstr) (n : Nat) (hhalt : s0.halted = false) (hprog : forall k, k < n -> (imem (memIndexOfNat defaultConfig (s0.pc.toNat + k))).op = .kmac) (hfit : kernelPrefixFits defaultConfig (kernelOf s0) n) : exists sn, stepN (programOf imem) n s0 = some sn /\ sn.acc.toInt = (krun n (kernelOf s0)).acc := s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) n sn, stepN (programOf imem) n s0 = some sn BitVec.toInt sn.acc = (krun n (kernelOf s0)).acc s0:State defaultConfigimem:Nat DecodedInstrn:Nathhalt:s0.halted = falsehprog: (k : Nat), k < n (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) nsn:State defaultConfighstep:stepN (programOf imem) n s0 = some snleft✝⁵:sn.halted = falseleft✝⁴:sn.weights = s0.weightsleft✝³:sn.stream = s0.streamleft✝²:BitVec.toNat sn.wptr = (BitVec.toNat s0.wptr + n) % 65536left✝¹:BitVec.toNat sn.sptr = (BitVec.toNat s0.sptr + n) % 65536left✝:BitVec.toNat sn.pc = (BitVec.toNat s0.pc + n) % 18446744073709551616hacc:BitVec.toInt sn.acc = (krun n (kernelOf s0)).acc sn, stepN (programOf imem) n s0 = some sn BitVec.toInt sn.acc = (krun n (kernelOf s0)).acc All goals completed! 🐙 /-! ## The wide kernel fold (milestone 5): `W` MACs per cycle The throughput path folds one block-FP region per cycle — `W` resident weights against `W` streamed operands, summed and added to the accumulator in a single step, both pointers advanced by `W`. This is the hardware image of the shared-exponent block: `W = 8` against an 8-byte weight-port read. Widening the datapath reopens the block-float MAC obligation, and the obligation is a conservation law — one `W`-wide step computes exactly what `W` one-wide `kstep`s compute. Once that holds, `wrun` is *definitionally* `krun` at a stride, so `kernelDot_correct` and the `kernelPrefixFits` overflow bound transfer to the 8-wide tile with no new arithmetic reasoning. -/ /-- Fold `W` products in one step; advance both pointers by `W`. -/ def wstep (W : Nat) (s : KernelState) : KernelState := { s with acc := s.acc + fsumFrom s.weights s.stream s.wptr s.sptr W, wptr := s.wptr + W, sptr := s.sptr + W } def wrun (W : Nat) : Nat -> KernelState -> KernelState | 0, s => s | m + 1, s => wrun W m (wstep W s) /-- `krun` advances the pointers by the step count and never touches the operand memories. -/ theorem krun_ptrs : forall (n : Nat) (s : KernelState), (krun n s).weights = s.weights (krun n s).stream = s.stream (krun n s).wptr = s.wptr + n (krun n s).sptr = s.sptr + n s:KernelState(krun 0 s).weights = s.weights (krun 0 s).stream = s.stream (krun 0 s).wptr = s.wptr + 0 (krun 0 s).sptr = s.sptr + 0 s:KernelState(krun 0 s).weights = s.weights (krun 0 s).stream = s.stream (krun 0 s).wptr = s.wptr + 0 (krun 0 s).sptr = s.sptr + 0 All goals completed! 🐙 n:Nats:KernelState(krun (n + 1) s).weights = s.weights (krun (n + 1) s).stream = s.stream (krun (n + 1) s).wptr = s.wptr + (n + 1) (krun (n + 1) s).sptr = s.sptr + (n + 1) n:Nats:KernelState(krun (n + 1) s).weights = s.weights (krun (n + 1) s).stream = s.stream (krun (n + 1) s).wptr = s.wptr + (n + 1) (krun (n + 1) s).sptr = s.sptr + (n + 1) n:Nats:KernelStatehw:(krun n (kstep s)).weights = (kstep s).weightshs:(krun n (kstep s)).stream = (kstep s).streamhwp:(krun n (kstep s)).wptr = (kstep s).wptr + nhsp:(krun n (kstep s)).sptr = (kstep s).sptr + n(krun (n + 1) s).weights = s.weights (krun (n + 1) s).stream = s.stream (krun (n + 1) s).wptr = s.wptr + (n + 1) (krun (n + 1) s).sptr = s.sptr + (n + 1) n:Nats:KernelStatehw:(krun n (kstep s)).weights = (kstep s).weightshs:(krun n (kstep s)).stream = (kstep s).streamhwp:(krun n (kstep s)).wptr = (kstep s).wptr + nhsp:(krun n (kstep s)).sptr = (kstep s).sptr + n(krun n (kstep s)).weights = s.weights (krun n (kstep s)).stream = s.stream (krun n (kstep s)).wptr = s.wptr + (n + 1) (krun n (kstep s)).sptr = s.sptr + (n + 1) n:Nats:KernelStatehw:(krun n (kstep s)).weights = (kstep s).weightshs:(krun n (kstep s)).stream = (kstep s).streamhwp:(krun n (kstep s)).wptr = (kstep s).wptr + nhsp:(krun n (kstep s)).sptr = (kstep s).sptr + n(krun n (kstep s)).wptr = s.wptr + (n + 1)n:Nats:KernelStatehw:(krun n (kstep s)).weights = (kstep s).weightshs:(krun n (kstep s)).stream = (kstep s).streamhwp:(krun n (kstep s)).wptr = (kstep s).wptr + nhsp:(krun n (kstep s)).sptr = (kstep s).sptr + n(krun n (kstep s)).sptr = s.sptr + (n + 1) n:Nats:KernelStatehw:(krun n (kstep s)).weights = (kstep s).weightshs:(krun n (kstep s)).stream = (kstep s).streamhwp:(krun n (kstep s)).wptr = (kstep s).wptr + nhsp:(krun n (kstep s)).sptr = (kstep s).sptr + n(krun n (kstep s)).wptr = s.wptr + (n + 1) n:Nats:KernelStatehw:(krun n (kstep s)).weights = (kstep s).weightshs:(krun n (kstep s)).stream = (kstep s).streamhwp:(krun n (kstep s)).wptr = (kstep s).wptr + nhsp:(krun n (kstep s)).sptr = (kstep s).sptr + n(kstep s).wptr + n = s.wptr + (n + 1); n:Nats:KernelStatehw:(krun n (kstep s)).weights = (kstep s).weightshs:(krun n (kstep s)).stream = (kstep s).streamhwp:(krun n (kstep s)).wptr = (kstep s).wptr + nhsp:(krun n (kstep s)).sptr = (kstep s).sptr + ns.wptr + 1 + n = s.wptr + (n + 1); All goals completed! 🐙 n:Nats:KernelStatehw:(krun n (kstep s)).weights = (kstep s).weightshs:(krun n (kstep s)).stream = (kstep s).streamhwp:(krun n (kstep s)).wptr = (kstep s).wptr + nhsp:(krun n (kstep s)).sptr = (kstep s).sptr + n(krun n (kstep s)).sptr = s.sptr + (n + 1) n:Nats:KernelStatehw:(krun n (kstep s)).weights = (kstep s).weightshs:(krun n (kstep s)).stream = (kstep s).streamhwp:(krun n (kstep s)).wptr = (kstep s).wptr + nhsp:(krun n (kstep s)).sptr = (kstep s).sptr + n(kstep s).sptr + n = s.sptr + (n + 1); n:Nats:KernelStatehw:(krun n (kstep s)).weights = (kstep s).weightshs:(krun n (kstep s)).stream = (kstep s).streamhwp:(krun n (kstep s)).wptr = (kstep s).wptr + nhsp:(krun n (kstep s)).sptr = (kstep s).sptr + ns.sptr + 1 + n = s.sptr + (n + 1); All goals completed! 🐙 /-- Iterating `kstep` is additive in the step count. -/ theorem krun_add : forall (a b : Nat) (s : KernelState), krun (a + b) s = krun b (krun a s) b:Nats:KernelStatekrun (0 + b) s = krun b (krun 0 s) b:Nats:KernelStatekrun (0 + b) s = krun b (krun 0 s) All goals completed! 🐙 a:Natb:Nats:KernelStatekrun (a + 1 + b) s = krun b (krun (a + 1) s) a:Natb:Nats:KernelStatekrun (a + 1 + b) s = krun b (krun (a + 1) s) a:Natb:Nats:KernelStateh:a + 1 + b = a + b + 1krun (a + 1 + b) s = krun b (krun (a + 1) s) a:Natb:Nats:KernelStateh:a + 1 + b = a + b + 1krun (a + b + 1) s = krun b (krun (a + 1) s) a:Natb:Nats:KernelStateh:a + 1 + b = a + b + 1krun (a + b) (kstep s) = krun b (krun a (kstep s)) All goals completed! 🐙 /-- **The conservation law.** One `W`-wide step equals `W` one-wide steps. -/ theorem wstep_eq_krun (W : Nat) (s : KernelState) : wstep W s = krun W s := W:Nats:KernelStatewstep W s = krun W s W:Nats:KernelStatehw:(krun W s).weights = s.weightshs:(krun W s).stream = s.streamhwp:(krun W s).wptr = s.wptr + Whsp:(krun W s).sptr = s.sptr + Wwstep W s = krun W s W:Nats:KernelStatehw:(krun W s).weights = s.weightshs:(krun W s).stream = s.streamhwp:(krun W s).wptr = s.wptr + Whsp:(krun W s).sptr = s.sptr + Whacc:(krun W s).acc = s.acc + fsumFrom s.weights s.stream s.wptr s.sptr Wwstep W s = krun W s W:Nats:KernelStatehw:(krun W s).weights = s.weightshs:(krun W s).stream = s.streamhwp:(krun W s).wptr = s.wptr + Whsp:(krun W s).sptr = s.sptr + Whacc:(krun W s).acc = s.acc + fsumFrom s.weights s.stream s.wptr s.sptr W{ acc := s.acc + fsumFrom s.weights s.stream s.wptr s.sptr W, weights := s.weights, stream := s.stream, wptr := s.wptr + W, sptr := s.sptr + W } = krun W s All goals completed! 🐙 /-- The `W`-wide fold over `m` steps is the one-wide fold over `W * m` steps — so it inherits every `krun` theorem. -/ theorem wrun_eq_krun (W : Nat) : forall (m : Nat) (s : KernelState), wrun W m s = krun (W * m) s W:Nats:KernelStatewrun W 0 s = krun (W * 0) s W:Nats:KernelStatewrun W 0 s = krun (W * 0) s All goals completed! 🐙 W:Natm:Nats:KernelStatewrun W (m + 1) s = krun (W * (m + 1)) s W:Natm:Nats:KernelStatewrun W (m + 1) s = krun (W * (m + 1)) s W:Natm:Nats:KernelStateh:W + W * m = W * (m + 1)wrun W (m + 1) s = krun (W * (m + 1)) s All goals completed! 🐙 /-- The 8-wide tile computes the exact dot product: `m` wide steps from a cleared accumulator leave `dotSpec w a (8 * m)`, the same result the one-wide loop computes, by conservation. -/ theorem wideKernel_dot_correct (w a : Nat -> Int) (m : Nat) : (wrun 8 m (KernelState.mk 0 w a 0 0)).acc = dotSpec w a (8 * m) := w:Nat Inta:Nat Intm:Nat(wrun 8 m { acc := 0, weights := w, stream := a, wptr := 0, sptr := 0 }).acc = dotSpec w a (8 * m) w:Nat Inta:Nat Intm:Nat{ acc := 0, weights := w, stream := a, wptr := 0, sptr := 0 }.acc + fsumFrom { acc := 0, weights := w, stream := a, wptr := 0, sptr := 0 }.weights { acc := 0, weights := w, stream := a, wptr := 0, sptr := 0 }.stream { acc := 0, weights := w, stream := a, wptr := 0, sptr := 0 }.wptr { acc := 0, weights := w, stream := a, wptr := 0, sptr := 0 }.sptr (8 * m) = dotSpec w a (8 * m) All goals completed! 🐙 /-- The 8-wide fold never overflows when the one-wide prefix-fit holds: every wide-step boundary accumulator is a one-wide prefix (at a multiple of 8), so `kernelPrefixFits` up to `8 * m` already guards them. The widening reuses the overflow proof verbatim — no new fit obligation is introduced by folding 8 at a time. -/ theorem wideKernel_stepsFit (cfg : Config) (s : KernelState) (m : Nat) (hfit : kernelPrefixFits cfg s (8 * m)) : forall j, j m signedFits cfg.accBits (wrun 8 j s).acc := cfg:Configs:KernelStatem:Nathfit:kernelPrefixFits cfg s (8 * m) (j : Nat), j m signedFits cfg.accBits (wrun 8 j s).acc cfg:Configs:KernelStatem:Nathfit:kernelPrefixFits cfg s (8 * m)j:Nathj:j msignedFits cfg.accBits (wrun 8 j s).acc cfg:Configs:KernelStatem:Nathfit:kernelPrefixFits cfg s (8 * m)j:Nathj:j mhacc:(wrun 8 j s).acc = s.acc + fsumFrom s.weights s.stream s.wptr s.sptr (8 * j)signedFits cfg.accBits (wrun 8 j s).acc cfg:Configs:KernelStatem:Nathfit:kernelPrefixFits cfg s (8 * m)j:Nathj:j mhacc:(wrun 8 j s).acc = s.acc + fsumFrom s.weights s.stream s.wptr s.sptr (8 * j)signedFits cfg.accBits (s.acc + fsumFrom s.weights s.stream s.wptr s.sptr (8 * j)) exact hfit (8 * j) (cfg:Configs:KernelStatem:Nathfit:kernelPrefixFits cfg s (8 * m)j:Nathj:j mhacc:(wrun 8 j s).acc = s.acc + fsumFrom s.weights s.stream s.wptr s.sptr (8 * j)8 * j 8 * m All goals completed! 🐙) /-- **The fixed-width machine realizes the wide fold.** A resident `kmac` loop of `8 * m` steps leaves in the accumulator exactly `wrun 8 m (kernelOf s0)` — so the 8-wide datapath computes the same architectural result as the equivalent single-MAC sequence, by conservation (`wrun_eq_krun`) composed with `kmac_loop_exact`. The wide *opcode/datapath* is a microarchitectural refinement that folds 8 per issue; this theorem pins the exact value it must produce, before any RTL exists. -/ theorem wide_loop_exact (s0 : State defaultConfig) (imem : Nat -> DecodedInstr) (m : Nat) (hhalt : s0.halted = false) (hprog : forall k, k < 8 * m -> (imem (memIndexOfNat defaultConfig (s0.pc.toNat + k))).op = .kmac) (hfit : kernelPrefixFits defaultConfig (kernelOf s0) (8 * m)) : exists sn, stepN (programOf imem) (8 * m) s0 = some sn /\ sn.acc.toInt = (wrun 8 m (kernelOf s0)).acc := s0:State defaultConfigimem:Nat DecodedInstrm:Nathhalt:s0.halted = falsehprog: (k : Nat), k < 8 * m (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) (8 * m) sn, stepN (programOf imem) (8 * m) s0 = some sn BitVec.toInt sn.acc = (wrun 8 m (kernelOf s0)).acc s0:State defaultConfigimem:Nat DecodedInstrm:Nathhalt:s0.halted = falsehprog: (k : Nat), k < 8 * m (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) (8 * m)sn:State defaultConfighstep:stepN (programOf imem) (8 * m) s0 = some snhacc:BitVec.toInt sn.acc = (krun (8 * m) (kernelOf s0)).acc sn, stepN (programOf imem) (8 * m) s0 = some sn BitVec.toInt sn.acc = (wrun 8 m (kernelOf s0)).acc exact sn, hstep, s0:State defaultConfigimem:Nat DecodedInstrm:Nathhalt:s0.halted = falsehprog: (k : Nat), k < 8 * m (imem (memIndexOfNat defaultConfig (BitVec.toNat s0.pc + k))).op = CellOp.kmachfit:kernelPrefixFits defaultConfig (kernelOf s0) (8 * m)sn:State defaultConfighstep:stepN (programOf imem) (8 * m) s0 = some snhacc:BitVec.toInt sn.acc = (krun (8 * m) (kernelOf s0)).accBitVec.toInt sn.acc = (wrun 8 m (kernelOf s0)).acc All goals completed! 🐙 end Honeycomb