@@ -1316,6 +1316,51 @@ theorem toNat_ushiftRight_lt (x : BitVec w) (n : Nat) (hn : n ≤ w) :
1316
1316
· apply hn
1317
1317
· apply Nat.pow_pos (by decide)
1318
1318
1319
+
1320
+ /-- Shifting right by `n`, which is larger than the bitwidth `w` produces `0. -/
1321
+ theorem ushiftRight_eq_zero {x : BitVec w} {n : Nat} (hn : w ≤ n) :
1322
+ x >>> n = 0 #w := by
1323
+ simp [bv_toNat]
1324
+ have : 2 ^w ≤ 2 ^n := Nat.pow_le_pow_of_le Nat.one_lt_two hn
1325
+ rw [Nat.shiftRight_eq_div_pow, Nat.div_eq_of_lt (by omega)]
1326
+
1327
+
1328
+ /--
1329
+ Unsigned shift right by at least one bit makes the value of the bitvector less than or equal to `2^(w-1)`,
1330
+ makes the interpretation of the bitvector `Int` and `Nat` agree.
1331
+ -/
1332
+ theorem toInt_ushiftRight_of_lt {x : BitVec w} {n : Nat} (hn : 0 < n) :
1333
+ (x >>> n).toInt = x.toNat >>> n := by
1334
+ rw [toInt_eq_toNat_cond]
1335
+ simp only [toNat_ushiftRight, ite_eq_left_iff, Nat.not_lt]
1336
+ intros h
1337
+ by_cases hn: n ≤ w
1338
+ · have h1 := Nat.mul_lt_mul_of_pos_left (toNat_ushiftRight_lt x n hn) Nat.two_pos
1339
+ simp only [toNat_ushiftRight, Nat.zero_lt_succ, Nat.mul_lt_mul_left] at h1
1340
+ have : 2 ^ (w - n).succ ≤ 2 ^ w := Nat.pow_le_pow_of_le (by decide) (by omega)
1341
+ have := show 2 * x.toNat >>> n < 2 ^ w by
1342
+ omega
1343
+ omega
1344
+ · have : x.toNat >>> n = 0 := by
1345
+ apply Nat.shiftRight_eq_zero
1346
+ have : 2 ^w ≤ 2 ^n := Nat.pow_le_pow_of_le (by decide) (by omega)
1347
+ omega
1348
+ simp [this] at h
1349
+ omega
1350
+
1351
+ /--
1352
+ Unsigned shift right by at least one bit makes the value of the bitvector less than or equal to `2^(w-1)`,
1353
+ makes the interpretation of the bitvector `Int` and `Nat` agree.
1354
+ In the case when `n = 0`, then the shift right value equals the integer interpretation.
1355
+ -/
1356
+ @[simp]
1357
+ theorem toInt_ushiftRight_eq_ite {x : BitVec w} {n : Nat} :
1358
+ (x >>> n).toInt = if n = 0 then x.toInt else x.toNat >>> n := by
1359
+ by_cases hn : n = 0
1360
+ · simp [hn]
1361
+ · rw [toInt_ushiftRight_of_lt (by omega), toInt_eq_toNat_cond]
1362
+ simp [hn]
1363
+
1319
1364
@[simp]
1320
1365
theorem getMsbD_ushiftRight {x : BitVec w} {i n : Nat} :
1321
1366
(x >>> n).getMsbD i = (decide (i < w) && (!decide (i < n) && x.getMsbD (i - n))) := by
0 commit comments