@@ -3,6 +3,7 @@ import DatapathVerification.BitHeap.Circuit
33import DatapathVerification.BitHeap.Column
44import Mathlib.Tactic.SplitIfs
55import Mathlib.Algebra.Divisibility.Basic
6+ import Mathlib.Data.Int.ModEq
67import Mathlib.Algebra.Order.BigOperators.Group.List
78import Mathlib.Algebra.Order.Group.Nat
89
@@ -125,10 +126,39 @@ def addBit (column : Nat) (c : Circuit) (h : BitHeap w) : BitHeap w :=
125126def truncate (h : BitHeap w) (n : Nat) (hn : n ≤ w) : BitHeap n :=
126127 ⟨Vector.ofFn (fun i => h.columns[i]'(by omega))⟩
127128
129+ theorem hornersMethod_take (env : BitEnv) (n : Nat) (l : List Column) :
130+ ((HornersMethod env (l.take n) : Int)) % 2 ^n
131+ = ((HornersMethod env l : Int)) % 2 ^n := by
132+ induction n generalizing l with
133+ | zero => simp
134+ | succ m ih =>
135+ cases l with
136+ | nil => simp
137+ | cons c cs =>
138+ simp only [List.take_succ_cons, HornersMethod, Nat.cast_add, Nat.cast_mul,
139+ Nat.cast_ofNat]
140+ have h2 : (2 : Int) * (HornersMethod env (cs.take m))
141+ ≡ 2 * (HornersMethod env cs) [ZMOD 2 ^(m+1 )] := by
142+ have hme : ((HornersMethod env (cs.take m) : Int))
143+ ≡ (HornersMethod env cs : Int) [ZMOD 2 ^m] := ih cs
144+ have hm2 := hme.mul_left' (c := 2 )
145+ rw [pow_succ, mul_comm ((2 :Int)^m) 2 ]
146+ exact hm2
147+ exact (Int.ModEq.refl _).add h2
148+
149+ theorem truncate_columns_toList (h : BitHeap w) (n : Nat) (hn : n ≤ w) :
150+ (h.truncate n hn).columns.toList = h.columns.toList.take n := by
151+ apply List.ext_getElem
152+ · simp [truncate]
153+ omega
154+ · intro i h1 h2
155+ simp only [truncate, Fin.getElem_fin, Vector.getElem_toList, Vector.getElem_ofFn,
156+ List.getElem_take]
157+
128158theorem evalMod_truncate (h : BitHeap w) (n : Nat) (hn : n ≤ w) (env : BitEnv) :
129159 (h.truncate n hn).evalMod env = (h.eval env) % 2 ^n := by
130- simp [evalMod, eval, truncate ]
131- sorry
160+ simp only [evalMod, eval]
161+ simp [hornersMethod_take, truncate_columns_toList]
132162
133163def mergeInto (acc h : BitHeap w) : BitHeap w :=
134164 h.columns.zipIdx.foldl (fun acc' (col, idx) =>
@@ -137,14 +167,16 @@ def mergeInto (acc h : BitHeap w) : BitHeap w :=
137167def addBitHeap (bhs : List (BitHeap w)) : BitHeap w :=
138168 bhs.foldl mergeInto (BitHeap.empty w)
139169
170+ def mulColumns (acc : BitHeap v) (col0 col1 : Column) (idx : Nat) : BitHeap v :=
171+ col0.elems.toList.foldl (fun a c1 =>
172+ col1.elems.toList.foldl (fun a' c2 =>
173+ a'.addBit idx (.binop .and c1 c2)) a) acc
174+
140175def mulBitHeap (h0 h1 : BitHeap w) : BitHeap (2 * w - 1 ) :=
141- let h := BitHeap.empty (2 * w - 1 )
142- let h := h0.columns.zipIdx.foldl (fun acc (column0, i0) =>
143- h1.columns.zipIdx.foldl (fun acc' (column1, i2) =>
144- column0.elems.toList.foldl (fun acc'' c1 =>
145- column1.elems.toList.foldl (fun acc''' c2 =>
146- acc'''.addBit (i0 + i2) (Circuit.binop .and c1 c2)) acc'') acc') acc) h
147- h
176+ h0.columns.zipIdx.foldl (fun acc (col0, i0) =>
177+ h1.columns.zipIdx.foldl (fun acc' (col1, i1) =>
178+ mulColumns acc' col0 col1 (i0 + i1)) acc)
179+ (BitHeap.empty (2 * w - 1 ))
148180
149181structure AdderResult (w : Nat) where
150182 heap : BitHeap w
0 commit comments