Skip to content

Commit 5b7c654

Browse files
mhk119bollu
authored andcommitted
feat: toInt_ushiftRight, ushiftRight_eq_zero
1 parent 5982a6d commit 5b7c654

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

src/Init/Data/BitVec/Lemmas.lean

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,51 @@ theorem toNat_ushiftRight_lt (x : BitVec w) (n : Nat) (hn : n ≤ w) :
13161316
· apply hn
13171317
· apply Nat.pow_pos (by decide)
13181318

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+
13191364
@[simp]
13201365
theorem getMsbD_ushiftRight {x : BitVec w} {i n : Nat} :
13211366
(x >>> n).getMsbD i = (decide (i < w) && (!decide (i < n) && x.getMsbD (i - n))) := by

src/Init/Data/Int/Bitwise/Lemmas.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,8 @@ theorem shiftRight_eq_div_pow (m : Int) (n : Nat) :
3434
theorem zero_shiftRight (n : Nat) : (0 : Int) >>> n = 0 := by
3535
simp [Int.shiftRight_eq_div_pow]
3636

37+
@[simp]
38+
theorem shiftRight_zero (n : Int) : n >>> 0 = n := by
39+
simp [Int.shiftRight_eq_div_pow]
40+
3741
end Int

src/Init/Data/Nat/Bitwise/Basic.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ theorem shiftRight_eq_div_pow (m : Nat) : ∀ n, m >>> n = m / 2 ^ n
7171
rw [shiftRight_add, shiftRight_eq_div_pow m k]
7272
simp [Nat.div_div_eq_div_mul, ← Nat.pow_succ, shiftRight_succ]
7373

74+
theorem shiftRight_eq_zero (m n : Nat) (hn : m < 2^n) : m >>> n = 0 := by
75+
simp [Nat.shiftRight_eq_div_pow, Nat.div_eq_of_lt hn]
76+
7477
/-!
7578
### testBit
7679
We define an operation for testing individual bits in the binary representation

0 commit comments

Comments
 (0)