@@ -4122,6 +4122,22 @@ theorem toNat_twoPow (w : Nat) (i : Nat) : (twoPow w i).toNat = 2^i % 2^w := by
4122
4122
have h1 : 1 < 2 ^ (w + 1 ) := Nat.one_lt_two_pow (by omega)
4123
4123
rw [Nat.mod_eq_of_lt h1, Nat.shiftLeft_eq, Nat.one_mul]
4124
4124
4125
+ theorem toNat_twoPow_of_le {i w : Nat} (h : w ≤ i) : (twoPow w i).toNat = 0 := by
4126
+ rw [toNat_twoPow]
4127
+ apply Nat.mod_eq_zero_of_dvd
4128
+ exact Nat.pow_dvd_pow_iff_le_right'.mpr h
4129
+
4130
+ theorem toNat_twoPow_of_lt {i w : Nat} (h : i < w) : (twoPow w i).toNat = 2 ^i := by
4131
+ rw [toNat_twoPow]
4132
+ apply Nat.mod_eq_of_lt
4133
+ apply Nat.pow_lt_pow_of_lt (by omega) (by omega)
4134
+
4135
+ theorem toNat_twoPow_eq_ite {i w : Nat} : (twoPow w i).toNat = if i < w then 2 ^i else 0 := by
4136
+ by_cases h : i < w
4137
+ · simp only [h, toNat_twoPow_of_lt, if_true]
4138
+ · simp only [h, if_false]
4139
+ rw [toNat_twoPow_of_le (by omega)]
4140
+
4125
4141
@[simp]
4126
4142
theorem getLsbD_twoPow (i j : Nat) : (twoPow w i).getLsbD j = ((i < w) && (i = j)) := by
4127
4143
rcases w with rfl | w
@@ -4140,6 +4156,33 @@ theorem getLsbD_twoPow (i j : Nat) : (twoPow w i).getLsbD j = ((i < w) && (i = j
4140
4156
simp at hi
4141
4157
simp_all
4142
4158
4159
+ @[simp]
4160
+ theorem msb_twoPow {i w: Nat} :
4161
+ (twoPow w i).msb = (decide (i < w) && decide (i = w - 1 )) := by
4162
+ simp only [BitVec.msb, getMsbD_eq_getLsbD, Nat.sub_zero, getLsbD_twoPow,
4163
+ Bool.and_iff_right_iff_imp, Bool.and_eq_true, decide_eq_true_eq, and_imp]
4164
+ intros
4165
+ omega
4166
+
4167
+ theorem toInt_twoPow {w i : Nat} :
4168
+ (BitVec.twoPow w i).toInt = if w ≤ i then 0
4169
+ else if i + 1 = w then (-(2 ^i : Nat) : Int) else 2 ^i := by
4170
+ simp only [BitVec.toInt_eq_msb_cond, toNat_twoPow_eq_ite]
4171
+ rcases w with _ | w
4172
+ · simp
4173
+ · by_cases h : i = w
4174
+ · simp [h, show ¬ (w + 1 ≤ w) by omega]
4175
+ omega
4176
+ · by_cases h' : w + 1 ≤ i
4177
+ · simp [h', show ¬ i < w + 1 by omega]
4178
+ · simp [h, h', show i < w + 1 by omega, Int.natCast_pow]
4179
+
4180
+ theorem toFin_twoPow {w i : Nat} :
4181
+ (BitVec.twoPow w i).toFin = Fin.ofNat' (2 ^w) (2 ^i) := by
4182
+ rcases w with rfl | w
4183
+ · simp [BitVec.twoPow, BitVec.toFin, toFin_shiftLeft, Fin.fin_one_eq_zero]
4184
+ · simp [BitVec.twoPow, BitVec.toFin, toFin_shiftLeft, Nat.shiftLeft_eq]
4185
+
4143
4186
@[simp]
4144
4187
theorem getElem_twoPow {i j : Nat} (h : j < w) : (twoPow w i)[j] = decide (j = i) := by
4145
4188
rw [←getLsbD_eq_getElem, getLsbD_twoPow]
@@ -4153,14 +4196,6 @@ theorem getMsbD_twoPow {i j w: Nat} :
4153
4196
by_cases h₀ : i < w <;> by_cases h₁ : j < w <;>
4154
4197
simp [h₀, h₁] <;> omega
4155
4198
4156
- @[simp]
4157
- theorem msb_twoPow {i w: Nat} :
4158
- (twoPow w i).msb = (decide (i < w) && decide (i = w - 1 )) := by
4159
- simp only [BitVec.msb, getMsbD_eq_getLsbD, Nat.sub_zero, getLsbD_twoPow,
4160
- Bool.and_iff_right_iff_imp, Bool.and_eq_true, decide_eq_true_eq, and_imp]
4161
- intros
4162
- omega
4163
-
4164
4199
theorem and_twoPow (x : BitVec w) (i : Nat) :
4165
4200
x &&& (twoPow w i) = if x.getLsbD i then twoPow w i else 0 #w := by
4166
4201
ext j h
0 commit comments