Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add Bitvec.(toInt, toFin)_twoPow #7225

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/Init/Data/BitVec/Lemmas.lean
Original file line number Diff line number Diff line change
Expand Up @@ -3731,6 +3731,30 @@ theorem getLsbD_twoPow (i j : Nat) : (twoPow w i).getLsbD j = ((i < w) && (i = j
simp at hi
simp_all

theorem toInt_twoPow {w i : Nat} :
(BitVec.twoPow w i).toInt = (if w ≤ i then 0 else if i + 1 = w then -1 <<< i else 1 <<< i : Int) := by
simp only [BitVec.twoPow, BitVec.toInt]
rcases w with _|w
· simp
· by_cases h : w + 1 ≤ i
· simp [h]; norm_cast; omega
· simp only [toNat_shiftLeft, toNat_ofNat, Nat.zero_lt_succ, Nat.one_mod_two_pow,
Int.ofNat_emod, h, ↓reduceIte, Nat.add_right_cancel_iff]
have hy : (2 ^ i % 2 ^ (w + 1)) = 2 ^ i := by rw [Nat.mod_eq_of_lt (by rw [Nat.pow_lt_pow_iff_right (by omega)]; omega)]
have hj : 2 * 2 ^ i = 2 ^ (i + 1) := by rw [Nat.pow_add, Nat.mul_comm]
Comment on lines +3743 to +3744
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
have hy : (2 ^ i % 2 ^ (w + 1)) = 2 ^ i := by rw [Nat.mod_eq_of_lt (by rw [Nat.pow_lt_pow_iff_right (by omega)]; omega)]
have hj : 2 * 2 ^ i = 2 ^ (i + 1) := by rw [Nat.pow_add, Nat.mul_comm]
have hy : 2 ^ i % 2 ^ (w + 1) = 2 ^ i := by rw [Nat.mod_eq_of_lt (by rw [Nat.pow_lt_pow_iff_right (by omega)]; omega)]
have hj : 2 * 2 ^ i = 2 ^ (i + 1) := by rw [Nat.pow_add, Nat.mul_comm]

I wonder if these two lemma above should not be named simp lemmas.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, the entire second half of the proof would be a lot nicer, if we can make avoid the casts in the middle and just make this all simp away. I am wondering if there is a set of simp lemmas which could help here?

norm_cast
simp only [Nat.shiftLeft_eq, Nat.one_mul, hy, hj]
by_cases i + 1 = (w + 1)
· simp [show i = w by omega]; omega
Comment on lines +3747 to +3748
Copy link
Contributor

@tobiasgrosser tobiasgrosser Feb 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
by_cases i + 1 = (w + 1)
· simp [show i = w by omega]; omega
by_cases i + 1 = w + 1
· simp [show i = w by omega]; omega

· simp [show 2 ^ (i + 1) < 2 ^ (w + 1) by rw [Nat.pow_lt_pow_iff_right (by omega)]; omega]
omega

theorem toFin_twoPow {w i : Nat} :
(BitVec.twoPow w i).toFin = Fin.ofNat' (2 ^ w) (2 ^ i) := by
rcases w with rfl | w
· simp [BitVec.twoPow, BitVec.toFin, toFin_shiftLeft, Fin.fin_one_eq_zero]
· simp [BitVec.twoPow, BitVec.toFin, toFin_shiftLeft, Nat.shiftLeft_eq]

@[simp]
theorem getElem_twoPow {i j : Nat} (h : j < w) : (twoPow w i)[j] = decide (j = i) := by
rw [←getLsbD_eq_getElem, getLsbD_twoPow]
Expand Down
Loading