File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -78,10 +78,8 @@ types (toU64, toU128) rather than raw field elements.
7878
7979### Tier 8: Semantic U64 Counting & Min/Max
8080
81- - [ ] AC-37: u64_clz_semantic [ blocked: needs u64
82- clz definition]
83- - [ ] AC-38: u64_ctz_semantic [ blocked: needs u64
84- ctz definition]
81+ - [x] AC-37: u64_clz_semantic
82+ - [x] AC-38: u64_ctz_semantic
8583- [ ] AC-39: u64_clo_semantic [ blocked: needs u64
8684 clo definition]
8785- [ ] AC-40: u64_cto_semantic [ blocked: needs u64
Original file line number Diff line number Diff line change @@ -358,4 +358,28 @@ theorem felt_lo32_hi32_toU64 (n : Nat)
358358 ZMod.val_natCast_of_lt h32_hi]
359359 omega
360360
361+ /-- Count leading zeros of a 64-bit value represented
362+ as two u32 limbs. If hi is zero, count all 32 bits
363+ of hi plus leading zeros of lo. -/
364+ def u64CountLeadingZeros (lo hi : Nat) : Nat :=
365+ if hi = 0 then u32CountLeadingZeros lo + 32
366+ else u32CountLeadingZeros hi
367+
368+ /-- Count trailing zeros of a 64-bit value represented
369+ as two u32 limbs. If lo is zero, count all 32 bits
370+ of lo plus trailing zeros of hi. -/
371+ def u64CountTrailingZeros (lo hi : Nat) : Nat :=
372+ if lo = 0 then u32CountTrailingZeros hi + 32
373+ else u32CountTrailingZeros lo
374+
375+ /-- Count leading ones of a 64-bit value. -/
376+ def u64CountLeadingOnes (lo hi : Nat) : Nat :=
377+ u64CountLeadingZeros (lo ^^^ (u32Max - 1 ))
378+ (hi ^^^ (u32Max - 1 ))
379+
380+ /-- Count trailing ones of a 64-bit value. -/
381+ def u64CountTrailingOnes (lo hi : Nat) : Nat :=
382+ u64CountTrailingZeros (lo ^^^ (u32Max - 1 ))
383+ (hi ^^^ (u32Max - 1 ))
384+
361385end MidenLean
Original file line number Diff line number Diff line change 11import MidenLean.Proofs.Tactics
2+ import MidenLean.Proofs.Interp
23import MidenLean.Generated.U64
34
45namespace MidenLean.Proofs
@@ -61,4 +62,22 @@ theorem u64_clz_correct (lo hi : Felt) (rest : List Felt) (s : MidenState)
6162 rw [stepDrop]; miden_bind
6263 rw [stepU32Clz (ha := hhi)]
6364
65+ /-- The _correct output equals u64CountLeadingZeros
66+ applied to the limb values. -/
67+ theorem u64_clz_semantic (lo hi : Felt) :
68+ (if hi == (0 : Felt)
69+ then Felt.ofNat (u32CountLeadingZeros lo.val) + 32
70+ else Felt.ofNat (u32CountLeadingZeros hi.val)) =
71+ Felt.ofNat (u64CountLeadingZeros lo.val hi.val) := by
72+ simp only [u64CountLeadingZeros]
73+ by_cases h : hi.val = 0
74+ · have : hi = (0 : Felt) := ZMod.val_injective _ h
75+ simp only [this, beq_self_eq_true, ite_true,
76+ ZMod.val_zero]
77+ simp only [Felt.ofNat]
78+ push_cast; ring
79+ · have : hi ≠ (0 : Felt) := fun heq =>
80+ h (by rw [heq]; simp)
81+ simp [this, h]
82+
6483end MidenLean.Proofs
Original file line number Diff line number Diff line change 11import MidenLean.Proofs.Tactics
2+ import MidenLean.Proofs.Interp
23import MidenLean.Generated.U64
34
45namespace MidenLean.Proofs
@@ -56,4 +57,20 @@ theorem u64_ctz_correct (lo hi : Felt) (rest : List Felt) (s : MidenState)
5657 rw [stepDrop]; miden_bind
5758 rw [stepU32Ctz (ha := hlo)]
5859
60+ /-- The _correct output equals u64CountTrailingZeros. -/
61+ theorem u64_ctz_semantic (lo hi : Felt) :
62+ (if lo == (0 : Felt)
63+ then Felt.ofNat (u32CountTrailingZeros hi.val) + 32
64+ else Felt.ofNat (u32CountTrailingZeros lo.val)) =
65+ Felt.ofNat (u64CountTrailingZeros lo.val hi.val) := by
66+ simp only [u64CountTrailingZeros]
67+ by_cases h : lo.val = 0
68+ · have : lo = (0 : Felt) := ZMod.val_injective _ h
69+ simp only [this, beq_self_eq_true, ite_true,
70+ ZMod.val_zero, Felt.ofNat]
71+ push_cast; ring
72+ · have : lo ≠ (0 : Felt) := fun heq =>
73+ h (by rw [heq]; simp)
74+ simp [this, h]
75+
5976end MidenLean.Proofs
You can’t perform that action at this time.
0 commit comments