@@ -46,27 +46,13 @@ namespace BVLems
4646 theorem sub_def (a b : BitVec n) : a - b = a.sub b := rfl
4747
4848 theorem toNat_shiftLeft {a : BitVec n} (i : Nat) : (a <<< i).toNat = (a.toNat * (2 ^ i)) % (2 ^ n) := by
49- rw [shiftLeft_def]; rcases a with ⟨⟨a, isLt⟩⟩
50- unfold BitVec.shiftLeft BitVec.toNat BitVec.ofNat
51- dsimp; rw [Nat.shiftLeft_eq]
49+ rw [BitVec.toNat_shiftLeft, Nat.shiftLeft_eq]
5250
5351 theorem toNat_ushiftRight {a : BitVec n} (i : Nat) : (a >>> i).toNat = (a.toNat) / (2 ^ i) := by
54- rw [ushiftRight_def]; rcases a with ⟨⟨a, isLt⟩⟩
55- unfold BitVec.ushiftRight BitVec.toNat
56- dsimp; rw [Nat.shiftRight_eq_div_pow]
52+ rw [BitVec.toNat_ushiftRight, Nat.shiftRight_eq_div_pow]
5753
58- theorem toNat_zeroExtend' {a : BitVec n} (le : n ≤ m) : (a.setWidth' le).toNat = a.toNat := rfl
59-
60- theorem toNat_zeroExtend {a : BitVec n} (i : Nat) : (a.zeroExtend i).toNat = a.toNat % (2 ^ i) := by
61- unfold BitVec.zeroExtend BitVec.setWidth; cases hdec : decide (n ≤ i)
62- case false =>
63- have hnle := of_decide_eq_false hdec
64- rw [Bool.dite_eq_false (proof:=hnle)]; rfl
65- case true =>
66- have hle := of_decide_eq_true hdec
67- rw [Bool.dite_eq_true (proof:=hle), toNat_zeroExtend']
68- rw [Nat.mod_eq_of_lt]; rcases a with ⟨⟨a, isLt⟩⟩;
69- apply Nat.le_trans isLt; apply Nat.pow_le_pow_right (Nat.le_succ_of_le .refl) hle
54+ theorem toNat_zeroExtend {n} {a : BitVec n} (i : Nat) : (a.zeroExtend i).toNat = a.toNat % (2 ^ i) :=
55+ BitVec.toNat_setWidth i a
7056
7157 theorem toNat_sub (a b : BitVec n) : (a - b).toNat = (2 ^ n - b.toNat + a.toNat) % (2 ^ n) := rfl
7258
@@ -95,58 +81,30 @@ namespace BVLems
9581 apply (Nat.le_iff_div_eq_zero (Nat.two_pow_pos _)).mpr
9682 apply Nat.le_trans (toNat_le _) (Nat.pow_le_pow_right (Nat.lt_succ_of_lt .refl) h)
9783
98- theorem ushiftRight_ge_length_eq_zero' (a : BitVec n) (i : Nat) : i ≥ n → BitVec.ofNat n (a.toNat >>> i) = 0 #n := by
99- intro h; apply congrArg (@BitVec.ofNat n)
100- rw [Nat.shiftRight_eq_div_pow, Nat.le_iff_div_eq_zero (Nat.two_pow_pos _)]
101- apply Nat.le_trans (toNat_le _) (Nat.pow_le_pow_right (Nat.lt_succ_of_lt .refl) h)
102-
103- theorem msb_equiv_lt (a : BitVec n) : !a.msb ↔ a.toNat < 2 ^ (n - 1 ) := by
104- dsimp [BitVec.msb, BitVec.getMsbD, BitVec.getLsbD]
105- cases n
106- case zero => cases a <;> simp
107- case succ n =>
108- have dtrue : decide (0 < n + 1 ) = true := by simp
109- rw [dtrue, Bool.not_eq_true', Bool.true_and, Nat.succ_sub_one, Nat.testBit_false_iff]
110- rw [Nat.mod_eq_of_lt (toNat_le _)]
111-
112- theorem msb_equiv_lt' (a : BitVec n) : !a.msb ↔ 2 * a.toNat < 2 ^ n := by
113- rw [msb_equiv_lt]
114- cases n
115- case zero => cases a <;> simp
116- case succ n =>
117- rw [Nat.succ_sub_one, Nat.pow_succ, Nat.mul_comm (m:=2 )]
118- apply Iff.symm; apply Nat.mul_lt_mul_left
119- exact Nat.lt_succ_of_lt .refl
120-
12184 theorem sshiftRight_ge_length_eq_msb (a : BitVec n) (i : Nat) : i ≥ n → a.sshiftRight i =
12285 if a.msb then (1 #n).neg else 0 #n := by
123- intro h; simp only [sshiftRight, BitVec.toInt, ← msb_equiv_lt']
124- cases hmsb : a.msb <;> simp only [Int.shiftRight_def ]
86+ intro h
87+ cases hmsb : a.msb <;> dsimp <;> rw [eq_iff_val_eq ]
12588 case false =>
126- dsimp only [Bool.not_false, ↓dreduceIte, Int.ofNat_eq_natCast, Int.natCast_shiftRight, Bool.false_eq_true]
127- rw [BitVec.ofNat]
128- apply ushiftRight_ge_length_eq_zero'; exact h
89+ rw [BitVec.sshiftRight_eq_of_msb_false hmsb]
90+ have ha : a.toNat < 2 ^ i := Nat.le_trans (toNat_le _) (
91+ Nat.pow_le_pow_right Nat.zero_lt_two h)
92+ simp [Nat.shiftRight_eq_div_pow, ha]
12993 case true =>
130- rw [← Int.subNatNat_eq_coe, Int.subNatNat_of_lt (toNat_le _)]
131- simp only [BitVec.ofInt]
132- dsimp only [Bool.not_true, Bool.false_eq_true, ↓dreduceIte,
133- Nat.pred_eq_sub_one, Int.ofNat_eq_natCast, Int.natCast_shiftRight, Int.natCast_pow,
134- Int.cast_ofNat_Int, neg_eq]
135- have hzero : (2 ^ n - BitVec.toNat a - 1 ) >>> i = 0 := by
136- rw [Nat.shiftRight_eq_div_pow]; apply (Nat.le_iff_div_eq_zero (Nat.two_pow_pos _)).mpr
137- rw [Nat.sub_one, Nat.pred_lt_iff_le (Nat.two_pow_pos _)]
138- apply Nat.le_trans (Nat.sub_le _ _) (Nat.pow_le_pow_right (Nat.lt_succ_of_lt .refl) h)
139- apply eq_of_val_eq; rw [toNat_ofNatLt, hzero]
140- rw [toNat_neg, Int.mod_def', Int.emod]
141- rw [Nat.zero_mod, Nat.succ_eq_add_one, Nat.zero_add]
142- rw [Int.subNatNat_of_sub_eq_zero (by grind)]
143- rw [Int.toNat_natCast, BitVec.toNat_ofNat]
144- cases n <;> try rfl
145- case succ n =>
146- have hlt : 2 ≤ 2 ^ Nat.succ n := @Nat.pow_le_pow_right 2 (Nat.lt_succ_of_lt .refl) 1 (.succ n) (Nat.succ_le_succ (Nat.zero_le _))
147- rw [Nat.mod_eq_of_lt (a:=1 ) hlt]
148- rw [Nat.mod_eq_of_lt (by grind)]
149- grind
94+ have hn : n > 0 := by
95+ apply Nat.ne_zero_iff_zero_lt.mp; intro hn; cases hn
96+ rw [BitVec.msb_eq_toNat] at hmsb
97+ have := toNat_le a; simp_all
98+ have hpn : 2 ^ n > 1 := Nat.pow_le_pow_right Nat.zero_lt_two hn
99+ have hin : 2 ^ n ≤ 2 ^ i := Nat.pow_le_pow_right Nat.zero_lt_two h
100+ rw [BitVec.sshiftRight_eq_of_msb_true hmsb]
101+ rw [BitVec.toNat_not, BitVec.toNat_neg, BitVec.toNat_ofNat]
102+ rw [Nat.one_mod_eq_one.mpr (Nat.ne_of_gt hpn)]
103+ have hsa : 2 ^ n - 1 - a.toNat < 2 ^ i := by
104+ apply Nat.sub_lt_of_lt; apply Nat.lt_iff_add_one_le.mpr
105+ rw [Nat.sub_add_cancel (Nat.le_of_lt hpn)]; exact hin
106+ have han : (~~~a >>> i).toNat = 0 := by simp [Nat.shiftRight_eq_div_pow, hsa]
107+ simp [han]
150108
151109 theorem shiftRight_eq_zero_iff (a : BitVec n) (b : Nat) : a >>> b = 0 #n ↔ a.toNat < 2 ^ b := by
152110 rw [ushiftRight_def]; rcases a with ⟨⟨a, isLt⟩⟩;
@@ -200,7 +158,7 @@ namespace BVLems
200158 rw [Bool.ite_eq_true _ _ _ hle, smtshiftLeft_def, toNat_ofNat, Nat.mod_eq_of_lt]
201159 apply Nat.le_trans hle (Nat.le_of_lt (Nat.le_pow .refl))
202160
203- theorem shl_equiv' . {u} (a : BitVec n) (b : Nat) : a <<< b =
161+ theorem shl_equiv_GLift . {u} (a : BitVec n) (b : Nat) : a <<< b =
204162 (Bool.ite' (b < n) (GLift.up.{1 , u} (a <<< BitVec.ofNat n b)) (GLift.up.{1 , u} 0 )).down := by
205163 have h := shl_equiv a b; rw [Bool.ite_simp] at h; rw [Bool.ite'_comm (f := GLift.down)]; exact h
206164
@@ -243,7 +201,7 @@ namespace BVLems
243201 rw [Bool.ite_eq_true _ _ _ hle, smtushiftRight_def, toNat_ofNat, Nat.mod_eq_of_lt]
244202 apply Nat.le_trans hle (Nat.le_of_lt (Nat.le_pow .refl))
245203
246- theorem lshr_equiv' . {u} (a : BitVec n) (b : Nat) : a >>> b =
204+ theorem lshr_equiv_GLift . {u} (a : BitVec n) (b : Nat) : a >>> b =
247205 (Bool.ite' (b < n) (GLift.up.{1 , u} (a >>> BitVec.ofNat n b)) (GLift.up.{1 , u} 0 )).down := by
248206 have h := lshr_equiv a b; rw [Bool.ite_simp] at h; rw [Bool.ite'_comm (f := GLift.down)]; exact h
249207
@@ -270,7 +228,7 @@ namespace BVLems
270228 rw [smtushiftRight_def, eqof, shiftRight_eq_zero_iff] at heq
271229 rw [toNat_zeroExtend, Nat.mod_eq_of_lt heq]
272230
273- theorem lshr_toNat_equiv_long' . {u} (a : BitVec n) (b : BitVec m) (h : m > n) : a >>> b.toNat =
231+ theorem lshr_toNat_equiv_long_GLift . {u} (a : BitVec n) (b : BitVec m) (h : m > n) : a >>> b.toNat =
274232 (Bool.ite' (GLift.up.{1 , u} (b >>> (BitVec.ofNat m n)) = GLift.up.{1 , u} 0 #m)
275233 (GLift.up.{1 , u} (a >>> (zeroExtend n b))) (GLift.up.{1 , u} 0 )).down := by
276234 have h := lshr_toNat_equiv_long a b h; rw [Bool.ite_simp] at h
@@ -286,7 +244,7 @@ namespace BVLems
286244 rw [Bool.ite_eq_true _ _ _ hle, toNat_ofNat, Nat.mod_eq_of_lt]
287245 apply Nat.le_trans hle (Nat.le_of_lt (Nat.le_pow .refl))
288246
289- theorem ashr_equiv' . {u} (a : BitVec n) (b : Nat) : a.sshiftRight b =
247+ theorem ashr_equiv_GLift . {u} (a : BitVec n) (b : Nat) : a.sshiftRight b =
290248 (Bool.ite' (b < n) (GLift.up.{1 , u} (a.sshiftRight (BitVec.ofNat n b).toNat))
291249 (Bool.ite' (GLift.up.{1 , u} a.msb = GLift.up.{1 , u} true ) (GLift.up.{1 , u} (1 #n).neg) (GLift.up.{1 , u} 0 #n))).down := by
292250 have h := ashr_equiv a b; rw [Bool.ite_simp] at h; rw [eqGLift_equiv]
@@ -315,7 +273,7 @@ namespace BVLems
315273 rw [smtushiftRight_def, eqof, shiftRight_eq_zero_iff] at heq
316274 rw [toNat_zeroExtend, Nat.mod_eq_of_lt heq]
317275
318- theorem ashr_toNat_equiv_long' . {u} (a : BitVec n) (b : BitVec m) (h : m > n) : a.sshiftRight b.toNat =
276+ theorem ashr_toNat_equiv_long_GLift . {u} (a : BitVec n) (b : BitVec m) (h : m > n) : a.sshiftRight b.toNat =
319277 (Bool.ite' (GLift.up.{1 , u} (b >>> (BitVec.ofNat m n)) = GLift.up.{1 , u} 0 #m)
320278 (GLift.up.{1 , u} (a.sshiftRight (zeroExtend n b).toNat))
321279 (Bool.ite'
@@ -405,7 +363,7 @@ theorem LamEquiv.shl_equiv
405363 ⟨.mkBvNatBinOp (.ofBvshl _) wfa wfb,
406364 .mkIte (.mkNatBinOp (.ofNlt) wfb (.ofBase (.ofNatVal n)))
407365 (.mkBvBinOp (.ofBvsmtshl _) wfa (.mkBvofNat wfb)) (.ofBase (.ofBvVal _ _)), fun lctxTerm => by
408- apply GLift.down.inj; apply BVLems.shl_equiv' ⟩
366+ apply GLift.down.inj; apply BVLems.shl_equiv_GLift ⟩
409367
410368abbrev LamTerm.shl_toNat_equiv_short (n : Nat) (a : LamTerm) (m : Nat) (b : LamTerm) :=
411369 LamTerm.mkBvBinOp n (.bvsmtshl n) a (.mkBvUOp m (.bvzeroExtend m n) b)
@@ -497,7 +455,7 @@ theorem LamEquiv.lshr_equiv
497455 ⟨.mkBvNatBinOp (.ofBvlshr _) wfa wfb,
498456 .mkIte (.mkNatBinOp (.ofNlt) wfb (.ofBase (.ofNatVal n)))
499457 (.mkBvBinOp (.ofBvsmtlshr _) wfa (.mkBvofNat wfb)) (.ofBase (.ofBvVal _ _)), fun lctxTerm => by
500- apply GLift.down.inj; apply BVLems.lshr_equiv' ⟩
458+ apply GLift.down.inj; apply BVLems.lshr_equiv_GLift ⟩
501459
502460abbrev LamTerm.lshr_toNat_equiv_short (n : Nat) (a : LamTerm) (m : Nat) (b : LamTerm) :=
503461 LamTerm.mkBvBinOp n (.bvsmtlshr n) a (.mkBvUOp m (.bvzeroExtend m n) b)
@@ -558,7 +516,7 @@ theorem LamEquiv.lshr_toNat_equiv_long
558516 .mkIte
559517 (.mkEq (.mkBvBinOp (.ofBvsmtlshr _) wfb (.ofBase (.ofBvVal _ _))) (.ofBase (.ofBvVal _ _)))
560518 (.mkBvBinOp (.ofBvsmtlshr _) wfa (.mkBvUOp (.ofBvzeroExtend _ _) wfb)) (.ofBase (.ofBvVal _ _)), fun lctxTerm => by
561- apply GLift.down.inj; apply BVLems.lshr_toNat_equiv_long' _ _ h⟩
519+ apply GLift.down.inj; apply BVLems.lshr_toNat_equiv_long_GLift _ _ h⟩
562520
563521def LamTerm.ashr_equiv (n : Nat) (a b bbv : LamTerm) :=
564522 LamTerm.mkIte (.base (.bv n)) (.mkNatBinOp .nlt b (.base (.natVal n)))
@@ -597,7 +555,7 @@ theorem LamEquiv.ashr_equiv
597555 (.mkIte (.mkEq (.mkBvUOp (.ofBvmsb _) wfa) (.ofBase .ofTrueB))
598556 (.mkBvUOp (.ofBvneg _) ((.ofBase (.ofBvVal _ _))))
599557 (.ofBase (.ofBvVal _ _))), fun lctxTerm => by
600- apply GLift.down.inj; apply BVLems.ashr_equiv' ⟩
558+ apply GLift.down.inj; apply BVLems.ashr_equiv_GLift ⟩
601559
602560abbrev LamTerm.ashr_toNat_equiv_short (n : Nat) (a : LamTerm) (m : Nat) (b : LamTerm) :=
603561 LamTerm.mkBvBinOp n (.bvsmtashr n) a (.mkBvUOp m (.bvzeroExtend m n) b)
@@ -664,7 +622,7 @@ theorem LamEquiv.ashr_toNat_equiv_long
664622 (.mkIte (.mkEq (.mkBvUOp (.ofBvmsb _) wfa) (.ofBase .ofTrueB))
665623 (.mkBvUOp (.ofBvneg _) (.ofBase (.ofBvVal _ _)))
666624 (.ofBase (.ofBvVal _ _))), fun lctxTerm => by
667- apply GLift.down.inj; apply BVLems.ashr_toNat_equiv_long' _ _ h⟩
625+ apply GLift.down.inj; apply BVLems.ashr_toNat_equiv_long_GLift _ _ h⟩
668626
669627inductive BVCastType where
670628 | ofNat : Nat → BVCastType
0 commit comments