From 9705185acee99aa52fcb65b5794ce044ca4ca4d1 Mon Sep 17 00:00:00 2001 From: Siddharth Bhat Date: Thu, 3 Oct 2024 22:32:00 -0500 Subject: [PATCH] feat: BitVec lemmas for smtUDiv, smtSDiv with zero denominator --- src/Init/Data/BitVec/Lemmas.lean | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/Init/Data/BitVec/Lemmas.lean b/src/Init/Data/BitVec/Lemmas.lean index 61ce0dbe2b76..139d07705068 100644 --- a/src/Init/Data/BitVec/Lemmas.lean +++ b/src/Init/Data/BitVec/Lemmas.lean @@ -512,6 +512,31 @@ theorem eq_zero_or_eq_one (a : BitVec 1) : a = 0#1 ∨ a = 1#1 := by subst h simp +@[simp] +theorem toInt_zero {w : Nat} : (0#w).toInt = 0 := by + simp [BitVec.toInt, show 0 < 2^w by exact Nat.two_pow_pos w] + +/-! ### slt -/ + +/-- +A bitvector, when interpreted as an integer, is less than zero iff +its most significant bit is true. +-/ +theorem slt_zero_iff_msb_cond (x : BitVec w) : x.slt 0#w ↔ x.msb = true := by + have := toInt_eq_msb_cond x + constructor + · intros h + apply Classical.byContradiction + intros hmsb + simp only [Bool.not_eq_true] at hmsb + simp only [hmsb, Bool.false_eq_true, ↓reduceIte] at this + simp only [BitVec.slt, toInt_zero, decide_eq_true_eq] at h + omega /- Can't have `x.toInt` which is equal to `x.toNat` be strictly less than zero -/ + · intros h + simp only [h, ↓reduceIte] at this + simp [BitVec.slt, this] + omega + /-! ### setWidth, zeroExtend and truncate -/ @[simp] @@ -2376,6 +2401,9 @@ theorem umod_eq_and {x y : BitVec 1} : x % y = x &&& (~~~y) := by theorem smtUDiv_eq (x y : BitVec w) : smtUDiv x y = if y = 0#w then allOnes w else x / y := by simp [smtUDiv] +@[simp] +theorem smtUDiv_zero {x : BitVec n} : x.smtUDiv 0#n = allOnes n := rfl + /-! ### sdiv -/ /-- Equation theorem for `sdiv` in terms of `udiv`. -/ @@ -2443,6 +2471,10 @@ theorem smtSDiv_eq (x y : BitVec w) : smtSDiv x y = rw [BitVec.smtSDiv] rcases x.msb <;> rcases y.msb <;> simp +@[simp] +theorem smtSDiv_zero {x : BitVec n} : x.smtSDiv 0#n = if x.slt 0#n then 1#n else (allOnes n) := by + rcases hx : x.msb <;> simp [smtSDiv, slt_zero_iff_msb_cond x, hx, ← negOne_eq_allOnes] + /-! ### srem -/ theorem srem_eq (x y : BitVec w) : srem x y =