@@ -26,6 +26,9 @@ inductive ArithCircuit : Nat → Type
2626
2727def BitVecEnv (w : Nat) := Nat → BitVec w
2828
29+ def BitVecEnv.toBitEnv (bv : BitVecEnv w) : Circuit.BitEnv :=
30+ fun n => (bv (n / w)).getLsbD (n % w)
31+
2932/--
3033Convert a bitheap into a new bitheap that has a single row,
3134by using the naive compression algorithm.
@@ -35,15 +38,15 @@ def BitHeap.toSingleRow (bh : BitHeap w) : CircuitVector :=
3538 pp1.columns.toArray.map fun col => col.elems.toList.headD (.const false )
3639
3740namespace ArithCircuit
41+
3842/--
39- Given a bitvector (x : BV 3), but a bitheap
43+ Given a bitvector (x : BV 3), build a bitheap
4044```
4145* * *
4246x2 x1 x0
4347```
4448-/
4549def bitheapOfVar (varIndex : Nat) : BitHeap w :=
46- -- I want to create a bitheap that has one bit-variable per bit in the bitvector variable.
4750 -- | We need to know that this index is unique which is a gigantic pain.
4851 List.range w |>.foldl (fun bh i => bh.addBit i (BitHeap.Circuit.bit (varIndex * w + i))) (BitHeap.empty w)
4952
@@ -61,6 +64,44 @@ def toCircuitVector (c : ArithCircuit w) : CircuitVector :=
6164 let bh := c.toBitHeap
6265 BitHeap.toSingleRow bh
6366
67+ theorem BitVecEnv.toBitEnv_apply (bv : BitVecEnv w) (i k : Nat) (hk : k < w) :
68+ bv.toBitEnv (i * w + k) = (bv i).getLsbD k := by
69+ simp [BitVecEnv.toBitEnv]
70+ have h1 : (i * w + k) / w = i := by
71+ have hw : 0 < w := by grind
72+ rw [Nat.mul_comm, Nat.mul_add_div hw, Nat.add_eq_left, Nat.div_eq_of_lt hk]
73+ have h2 : k % w = k := by
74+ exact Nat.mod_eq_of_lt hk
75+ simp [h1, h2]
76+
77+ theorem bitheapOfVar_go (i : Nat) (bv : BitVecEnv w) (k : Nat) (hk : k ≤ w) :
78+ ((List.range k).foldl
79+ (fun bh j => bh.addBit j (.bit (i * w + j)))
80+ (BitHeap.empty w)).eval bv.toBitEnv
81+ = (bv i).toNat % 2 ^ k := by
82+ induction k with
83+ | zero =>
84+ simp only [List.range_zero, List.foldl_nil, empty_eval, pow_zero]
85+ grind
86+ | succ m ih =>
87+ rw [List.range_succ, List.foldl_append, List.foldl_cons, List.foldl_nil]
88+ sorry
89+
90+
91+ theorem toBitHeap_correct (c : ArithCircuit w) (bv : BitVecEnv w) :
92+ c.toBitHeap.evalMod bv.toBitEnv = ((c.denote bv).toNat : Int):= by
93+ fun_induction toBitHeap with
94+ | case1 varIndex =>
95+ simp only [BitHeap.evalMod, bitheapOfVar]
96+ rw [bitheapOfVar_go varIndex bv w (le_refl w)]
97+ simp [denote]
98+ norm_cast
99+ rw [BitVec.toNat_mod_cancel]
100+ | case2 =>
101+ sorry
102+ | case3 =>
103+ sorry
104+
64105end ArithCircuit
65106
66107end Comb
0 commit comments