-
Notifications
You must be signed in to change notification settings - Fork 0
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: shiftRight bitblasting theorems #11
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -403,12 +403,8 @@ theorem shiftLeftRec_eq {x : BitVec w₁} {y : BitVec w₂} {n : Nat} : | |||||||||
induction n generalizing x y | ||||||||||
case zero => | ||||||||||
ext i | ||||||||||
simp only [shiftLeftRec_zero, twoPow_zero, Nat.reduceAdd, truncate_one] | ||||||||||
suffices (y &&& 1#w₂) = zeroExtend w₂ (ofBool (y.getLsb 0)) by simp [this] | ||||||||||
ext i | ||||||||||
by_cases h : (↑i : Nat) = 0 | ||||||||||
· simp [h, Bool.and_comm] | ||||||||||
· simp [h]; omega | ||||||||||
simp only [shiftLeftRec_zero, twoPow_zero, Nat.reduceAdd, truncate_one, | ||||||||||
and_one_eq_zeroExtend_ofBool_getLsb] | ||||||||||
case succ n ih => | ||||||||||
simp only [shiftLeftRec_succ, and_twoPow] | ||||||||||
rw [ih] | ||||||||||
|
@@ -431,4 +427,102 @@ theorem shiftLeft_eq_shiftLeftRec (x : BitVec w₁) (y : BitVec w₂) : | |||||||||
· simp [of_length_zero] | ||||||||||
· simp [shiftLeftRec_eq] | ||||||||||
|
||||||||||
/- ### Logical shift right (ushiftRight) recurrence for bitblasting -/ | ||||||||||
|
||||||||||
def ushiftRight_rec (x : BitVec w₁) (y : BitVec w₂) (n : Nat) : BitVec w₁ := | ||||||||||
let shiftAmt := (y &&& (twoPow w₂ n)) | ||||||||||
match n with | ||||||||||
| 0 => x >>> shiftAmt | ||||||||||
| n + 1 => (ushiftRight_rec x y n) >>> shiftAmt | ||||||||||
|
||||||||||
@[simp] | ||||||||||
theorem ushiftRight_rec_zero (x : BitVec w₁) (y : BitVec w₂) : | ||||||||||
ushiftRight_rec x y 0 = x >>> (y &&& twoPow w₂ 0) := by | ||||||||||
simp [ushiftRight_rec] | ||||||||||
|
||||||||||
@[simp] | ||||||||||
theorem ushiftRight_rec_succ (x : BitVec w₁) (y : BitVec w₂) : | ||||||||||
ushiftRight_rec x y (n + 1) = | ||||||||||
(ushiftRight_rec x y n) >>> (y &&& twoPow w₂ (n + 1)) := by | ||||||||||
simp [ushiftRight_rec] | ||||||||||
|
||||||||||
theorem ushiftRight'_ushiftRight' {x y z : BitVec w} : | ||||||||||
x >>> y >>> z = x >>> (y.toNat + z.toNat) := by | ||||||||||
simp [shiftRight_add] | ||||||||||
|
||||||||||
theorem ushiftRight_or_eq_ushiftRight_ushiftRight_of_and_eq_zero {x : BitVec w₁} {y z : BitVec w₂} | ||||||||||
(h : y &&& z = 0#w₂) : | ||||||||||
x >>> (y ||| z) = x >>> y >>> z := by | ||||||||||
simp [← add_eq_or_of_and_eq_zero _ _ h, toNat_add_of_and_eq_zero h, shiftRight_add] | ||||||||||
|
||||||||||
theorem getLsb_ushiftRight' (x : BitVec w₁) (y : BitVec w₂) (i : Nat) : | ||||||||||
(x >>> y).getLsb i = x.getLsb (y.toNat + i) := by | ||||||||||
simp [getLsb_ushiftRight] | ||||||||||
|
||||||||||
theorem ushiftRight_rec_eq (x : BitVec w₁) (y : BitVec w₂) (n : Nat) : | ||||||||||
ushiftRight_rec x y n = x >>> (y.truncate (n + 1)).zeroExtend w₂ := by | ||||||||||
induction n generalizing x y | ||||||||||
case zero => | ||||||||||
ext i | ||||||||||
simp only [ushiftRight_rec_zero, twoPow_zero, Nat.reduceAdd, | ||||||||||
and_one_eq_zeroExtend_ofBool_getLsb, truncate_one] | ||||||||||
case succ n ih => | ||||||||||
simp only [ushiftRight_rec_succ, and_twoPow] | ||||||||||
rw [ih] | ||||||||||
by_cases h : y.getLsb (n + 1) <;> simp only [h, ↓reduceIte] | ||||||||||
· rw [zeroExtend_truncate_succ_eq_zeroExtend_truncate_or_twoPow_of_getLsb_true h] | ||||||||||
rw [ushiftRight_or_eq_ushiftRight_ushiftRight_of_and_eq_zero] | ||||||||||
simp | ||||||||||
· simp [zeroExtend_truncate_succ_eq_zeroExtend_truncate_of_getLsb_false (i := n + 1), h] | ||||||||||
|
||||||||||
theorem shiftRight_eq_shiftRight_rec (x : BitVec w₁) (y : BitVec w₂) : | ||||||||||
x >>> y = ushiftRight_rec x y (w₂ - 1) := by | ||||||||||
rcases w₂ with rfl | w₂ | ||||||||||
· simp [of_length_zero] | ||||||||||
· simp [ushiftRight_rec_eq] | ||||||||||
|
||||||||||
/- ### Arithmetic shift right (sshiftRight) recurrence -/ | ||||||||||
|
||||||||||
def sshiftRightRec (x : BitVec w) (y : BitVec w₂) (n : Nat) : BitVec w := | ||||||||||
let shiftAmt := (y &&& (twoPow w₂ n)) | ||||||||||
Comment on lines
+486
to
+487
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
match n with | ||||||||||
| 0 => x.sshiftRight' shiftAmt | ||||||||||
| n + 1 => (sshiftRightRec x y n).sshiftRight' shiftAmt | ||||||||||
|
||||||||||
@[simp] | ||||||||||
theorem sshiftRightRec_zero_eq (x : BitVec w) (y : BitVec w₂) : | ||||||||||
sshiftRightRec x y 0 = x.sshiftRight' (y &&& 1#w₂) := by | ||||||||||
Comment on lines
+493
to
+494
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
simp only [sshiftRightRec, twoPow_zero] | ||||||||||
|
||||||||||
@[simp] | ||||||||||
theorem sshiftRightRec_succ_eq (x : BitVec w) (y : BitVec w₂) (n : Nat) : | ||||||||||
sshiftRightRec x y (n + 1) = (sshiftRightRec x y n).sshiftRight' (y &&& twoPow w₂ (n + 1)) := by | ||||||||||
Comment on lines
+498
to
+499
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
simp [sshiftRightRec] | ||||||||||
|
||||||||||
theorem sshiftRight_or_eq_sshiftRight_sshiftRight_of_and_eq_zero {x : BitVec w} {y z : BitVec w₂} | ||||||||||
(h : y &&& z = 0#w₂) : | ||||||||||
Comment on lines
+502
to
+503
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
x.sshiftRight' (y ||| z) = (x.sshiftRight' y).sshiftRight' z := by | ||||||||||
simp [sshiftRight', ← add_eq_or_of_and_eq_zero _ _ h, | ||||||||||
toNat_add_of_and_eq_zero h, sshiftRight'_add] | ||||||||||
Comment on lines
+505
to
+506
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
|
||||||||||
theorem sshiftRightRec_eq (x : BitVec w₁) (y : BitVec w₂) (n : Nat) : | ||||||||||
sshiftRightRec x y n = x.sshiftRight' ((y.truncate (n + 1)).zeroExtend w₂) := by | ||||||||||
induction n generalizing x y | ||||||||||
Comment on lines
+509
to
+510
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
case zero => | ||||||||||
ext i | ||||||||||
simp [ushiftRight_rec_zero, twoPow_zero, Nat.reduceAdd, and_one_eq_zeroExtend_ofBool_getLsb, | ||||||||||
truncate_one] | ||||||||||
case succ n ih => | ||||||||||
simp only [sshiftRightRec_succ_eq, and_twoPow, ih] | ||||||||||
by_cases h : y.getLsb (n + 1) <;> simp [h] | ||||||||||
· simp [zeroExtend_truncate_succ_eq_zeroExtend_truncate_or_twoPow_of_getLsb_true h, | ||||||||||
sshiftRight_or_eq_sshiftRight_sshiftRight_of_and_eq_zero] | ||||||||||
· simp [zeroExtend_truncate_succ_eq_zeroExtend_truncate_of_getLsb_false (i := n + 1), h] | ||||||||||
|
||||||||||
theorem sshiftRight_eq_sshiftRightRec (x : BitVec w₁) (y : BitVec w₂) : | ||||||||||
(x.sshiftRight' y).getLsb i = (sshiftRightRec x y (w₂ - 1)).getLsb i := by | ||||||||||
rcases w₂ with rfl | w₂ | ||||||||||
· simp [of_length_zero] | ||||||||||
· simp [sshiftRightRec_eq] | ||||||||||
|
||||||||||
end BitVec |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.