Skip to content

Commit b5a383c

Browse files
committed
chore: add bitblast file for marc to repro
1 parent 0f2ede4 commit b5a383c

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

src/Init/Data/BitVec/Bitblast.lean

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1681,6 +1681,81 @@ theorem toInt_sdiv (a b : BitVec w) : (a.sdiv b).toInt = (a.toInt.tdiv b.toInt).
16811681
· rw [← toInt_bmod_cancel]
16821682
rw [BitVec.toInt_sdiv_of_ne_or_ne _ _ (by simpa only [Decidable.not_and_iff_not_or_not] using h)]
16831683

1684+
/--
1685+
Rewrite `(x.sdiv y).toInt` as an exceptional case of `intMin / -1`,
1686+
and a uniform uniformly expression as `x.toInt.tdiv y.toInt` for all other cases.
1687+
1688+
Recall that `x.tdiv 0 = 0`, so there is an implicit case analysis on `y`.
1689+
-/
1690+
theorem toInt_sdiv_eq_ite {x y : BitVec w} :
1691+
(x.sdiv y).toInt =
1692+
if x = intMin w ∧ y = -1#w then (intMin w).toInt
1693+
else x.toInt.tdiv y.toInt := by
1694+
by_cases hx : x = intMin w
1695+
· simp only [hx, _root_.true_and]
1696+
by_cases hy : y = -1#w
1697+
· simp [hy, intMin_sdiv_neg_one]
1698+
· simp only [hy, ↓reduceIte]
1699+
apply toInt_sdiv_of_ne_or_ne
1700+
simp [hy]
1701+
· simp only [hx, _root_.false_and, ↓reduceIte]
1702+
apply toInt_sdiv_of_ne_or_ne
1703+
simp [hx]
1704+
1705+
#eval (0#0).msb
1706+
#check Int.tdiv_nonpos_of_nonneg_of_nonpos
1707+
#check Int.tdiv_nonpos_of_nonneg_of_nonpos
1708+
1709+
1710+
/--
1711+
The sign of a division is determined as follows:
1712+
- if the denominator is zero, then the output is zero and the msb is false as it is non-negative.
1713+
- If the deminator is positive, then the sign of the output is the same as the sign of the numerator.
1714+
- If the denominator is negative, then the sign of the output is the opposite of the sign of the numerator,
1715+
except for the case where the numerator is `intMin`, in which case the result is `true`.
1716+
-/
1717+
theorem msb_sdiv_eq_ite {x y : BitVec w} :
1718+
(x.sdiv y).msb = ((decide (0 < w)) &&
1719+
(!decide (y = 0#w) &&
1720+
(decide (x = intMin w) && decide (y = -1#w) || x.msb ^^ y.msb)))
1721+
:= by
1722+
by_cases hw : w = 0; subst hw; decide +revert
1723+
simp [show 0 < w by omega]
1724+
by_cases hy : y = 0#w
1725+
· simp [hy]
1726+
· simp [hy]
1727+
by_cases h : x = intMin w ∧ y = -1#w
1728+
· simp [h, intMin_sdiv_neg_one, msb_intMin]; omega
1729+
· suffices (decide (x = intMin w) && decide (y = -1#w)) = false by
1730+
simp [this]
1731+
rw [msb_eq_toInt, toInt_sdiv_of_ne_or_ne]
1732+
· rw [msb_eq_toInt, msb_eq_toInt]
1733+
by_cases hx : 0 ≤ x.toInt
1734+
· by_cases hy : 0 ≤ y.toInt
1735+
· have := Int.tdiv_nonneg hx hy
1736+
simp [show ¬ (x.toInt < 0) by omega
1737+
, show ¬ (y.toInt < 0) by omega,
1738+
show ¬ (x.toInt.tdiv y.toInt < 0) by omega]
1739+
· simp [show ¬ x.toInt < 0 by omega]
1740+
simp [show y.toInt < 0 by omega]
1741+
have := Int.tdiv_neg
1742+
sorry
1743+
· by_cases hy : 0 ≤ y.toInt
1744+
· simp [show ¬ y.toInt < 0 by omega]
1745+
simp [show x.toInt < 0 by omega]
1746+
sorry
1747+
· simp [show x.toInt < 0 by omega]
1748+
simp [show y.toInt < 0 by omega]
1749+
rw [Int.tdiv_nonneg_of_nonpos_of_nonpos]
1750+
-- apply Int.tdiv_nonneg_of_nonpos_of_nonpos
1751+
-- · omega
1752+
-- · omega
1753+
1754+
-- simp only [bool_to_prop] -- TODO: teach bool_to_prop about xor.
1755+
· rw [Classical.not_and_iff_not_or_not] at h
1756+
rcases h with h | h <;> simp [h]
1757+
simpa using h
1758+
16841759
theorem msb_umod_eq_false_of_left {x : BitVec w} (hx : x.msb = false) (y : BitVec w) : (x % y).msb = false := by
16851760
rw [msb_eq_false_iff_two_mul_lt] at hx ⊢
16861761
rw [toNat_umod]

0 commit comments

Comments
 (0)