@@ -87,6 +87,108 @@ theorem bitheapOfVar_go (i : Nat) (bv : BitVecEnv w) (k : Nat) (hk : k ≤ w) :
8787 rw [List.range_succ, List.foldl_append, List.foldl_cons, List.foldl_nil]
8888 sorry
8989
90+ theorem foldl_addBit_evalMod (idx : Nat) (h : BitHeap w) (cs : List Circuit) :
91+ (List.foldl (fun a c => addBit idx c a) h cs).evalMod env
92+ = (h.evalMod env + (cs.map (fun c => 2 ^idx * (c.eval env).toInt)).sum) % 2 ^w := by
93+ induction cs generalizing h with
94+ | nil =>
95+ simp [evalMod]
96+ | cons c tl ih =>
97+ simp only [List.foldl_cons, List.map_cons, List.sum_cons, ih, BitHeap.evalMod_heap_addBit, Int.emod_add_emod]
98+ grind
99+
100+ theorem foldl_columns_evalMod (acc : BitHeap w) (ps : List (Column × Nat)) :
101+ (ps.foldl (fun a p => List.foldl (fun a' c => addBit p.2 c a') a p.1 .elems.toList)
102+ acc).evalMod env
103+ = (acc.evalMod env
104+ + (ps.map (fun p =>
105+ (p.1 .elems.toList.map (fun c => 2 ^p.2 * (c.eval env).toInt)).sum)).sum) % 2 ^w := by
106+ induction ps generalizing acc with
107+ | nil =>
108+ simp [evalMod]
109+ | cons p tl ih =>
110+ simp only [List.foldl_cons, List.map_cons, List.sum_cons]
111+ rw [ih, foldl_addBit_evalMod, Int.emod_add_emod]
112+ grind
113+
114+ theorem hornersMethod_eq_sum_zipIdx (env : Circuit.BitEnv) (l : List Column) (s : Nat) :
115+ (2 ^s : Int) * (HornersMethod env l : Int)
116+ = ((l.zipIdx s).map (fun p =>
117+ (p.1 .elems.toList.map (fun c => 2 ^p.2 * (c.eval env).toInt)).sum)).sum := by
118+ induction l generalizing s with
119+ | nil =>
120+ simp [HornersMethod]
121+ | cons p ps ih =>
122+ simp [HornersMethod, List.zipIdx_cons, List.map_cons, List.sum_cons]
123+ rw [← ih]
124+ rw [Int.mul_add]
125+ have : 2 ^ s * (2 * ↑(HornersMethod env ps)) = 2 ^ (s + 1 ) * (HornersMethod env ps) := by
126+ grind
127+ norm_cast
128+ simp [this, Column.eval_eq_sum]
129+ induction p.elems.toList with
130+ | nil =>
131+ simp
132+ | cons c tl ih' =>
133+ simp only [List.map_cons, List.sum_cons]
134+ grind
135+
136+ theorem eval_eq_sum_columns (h : BitHeap w) (env : Circuit.BitEnv) :
137+ ((h.eval env : Int))
138+ = (h.columns.toList.zipIdx.map (fun p =>
139+ (p.1 .elems.toList.map (fun c => 2 ^p.2 * (c.eval env).toInt)).sum)).sum := by
140+ simp [eval]
141+ have h0 := hornersMethod_eq_sum_zipIdx env h.columns.toList 0
142+ simp only [pow_zero, one_mul] at h0
143+ exact h0
144+
145+ theorem mergeInto_evalMod (acc h : BitHeap w) :
146+ (mergeInto acc h).evalMod env = (acc.evalMod env + h.evalMod env) % 2 ^w := by
147+ simp [mergeInto]
148+ rw [Vector.foldl, ←Array.foldl_toList]
149+ rw [foldl_columns_evalMod]
150+ simp only [evalMod, Vector.toArray_zipIdx, Array.toList_zipIdx, Int.emod_add_emod,
151+ Int.add_emod_emod]
152+ rw [eval_eq_sum_columns, eval_eq_sum_columns]
153+ grind
154+
155+ theorem foldl_mergeInto_evalMod (hs : List (BitHeap w)) (acc : BitHeap w) :
156+ (hs.foldl mergeInto acc).evalMod env
157+ = (acc.evalMod env + (hs.map (·.evalMod env)).sum) % 2 ^w := by
158+ induction hs generalizing acc with
159+ | nil =>
160+ simp only [evalMod, List.foldl_nil, List.map_nil, List.sum_nil, add_zero, dvd_refl,
161+ Int.emod_emod_of_dvd]
162+ | cons h tl ih =>
163+ simp only [List.foldl_cons, List.map_cons, List.sum_cons]
164+ rw [ih]
165+ rw [mergeInto_evalMod]
166+ simp
167+ grind
168+
169+ theorem foldl_add_init {w : ℕ} (acc hd : BitVec w) (tl : List (BitVec w)) :
170+ List.foldl (· + ·) (acc + hd) tl = List.foldl (· + ·) acc tl + hd := by
171+ induction tl generalizing acc with
172+ | nil => rfl
173+ | cons x xs ih =>
174+ simp only [List.foldl_cons]
175+ rw [← ih]
176+ grind
177+
178+ theorem foldl_add_toNat_go (acc : BitVec w) (l : List (BitVec w)) :
179+ ((l.foldl (· + ·) acc).toNat : Int)
180+ = ((acc.toNat : Int) + (l.map (fun x => (x.toNat : Int))).sum) % 2 ^w := by
181+ induction l with
182+ | nil =>
183+ simp only [List.foldl_nil, List.map_nil, List.sum_nil, add_zero]
184+ norm_cast
185+ simp only [BitVec.toNat_mod_cancel]
186+ | cons hd tl ih =>
187+ simp only [List.foldl_cons, List.map_cons, List.sum_cons]
188+ rw [foldl_add_init]
189+ rw [BitVec.toNat_add]
190+ simp [ih]
191+ grind
90192
91193theorem toBitHeap_correct (c : ArithCircuit w) (bv : BitVecEnv w) :
92194 c.toBitHeap.evalMod bv.toBitEnv = ((c.denote bv).toNat : Int):= by
@@ -97,9 +199,17 @@ theorem toBitHeap_correct (c : ArithCircuit w) (bv : BitVecEnv w) :
97199 simp [denote]
98200 norm_cast
99201 rw [BitVec.toNat_mod_cancel]
100- | case2 =>
101- sorry
102- | case3 =>
202+ | case2 args ih =>
203+ simp only [denote, BitHeap.addBitHeap]
204+ rw [foldl_mergeInto_evalMod]
205+ rw [foldl_add_toNat_go]
206+ simp only [empty_evalMod, List.map_map, zero_add, BitVec.ofNat_eq_ofNat, BitVec.toNat_ofNat,
207+ Nat.zero_mod, Int.cast_ofNat_Int]
208+ congr 1
209+ congr 1
210+ simp only [List.map_inj_left, Function.comp_apply]
211+ assumption
212+ | case3 l r ih1 ih2=>
103213 sorry
104214
105215end ArithCircuit
0 commit comments