diff --git a/src/Init/Data/BitVec/Lemmas.lean b/src/Init/Data/BitVec/Lemmas.lean index 3d4a7d3445d3..148f578f235f 100644 --- a/src/Init/Data/BitVec/Lemmas.lean +++ b/src/Init/Data/BitVec/Lemmas.lean @@ -162,6 +162,16 @@ theorem toNat_zero (n : Nat) : (0#n).toNat = 0 := by trivial @[simp] theorem toNat_mod_cancel (x : BitVec n) : x.toNat % (2^n) = x.toNat := Nat.mod_eq_of_lt x.isLt +@[simp] theorem sub_toNat_mod_cancel {x : BitVec w} (h : ¬ x = 0#w) : + (2 ^ w - x.toNat) % 2 ^ w = 2 ^ w - x.toNat := by + simp only [toNat_eq, toNat_ofNat, Nat.zero_mod] at h + rw [Nat.mod_eq_of_lt (by omega)] + +@[simp] theorem sub_sub_toNat_cancel {x : BitVec w} : + 2 ^ w - (2 ^ w - x.toNat) = x.toNat := by + simp [Nat.sub_sub_eq_min, Nat.min_eq_right] + omega + private theorem lt_two_pow_of_le {x m n : Nat} (lt : x < 2 ^ m) (le : m ≤ n) : x < 2 ^ n := Nat.lt_of_lt_of_le lt (Nat.pow_le_pow_of_le_right (by trivial : 0 < 2) le) @@ -300,8 +310,7 @@ theorem truncate_eq_zeroExtend {v : Nat} {x : BitVec w} : @[simp, bv_toNat] theorem toNat_zeroExtend' {m n : Nat} (p : m ≤ n) (x : BitVec m) : (zeroExtend' p x).toNat = x.toNat := by - unfold zeroExtend' - simp [p, x.isLt, Nat.mod_eq_of_lt] + simp [zeroExtend'] @[bv_toNat] theorem toNat_zeroExtend (i : Nat) (x : BitVec n) : BitVec.toNat (zeroExtend i x) = x.toNat % 2^i := by @@ -1248,6 +1257,19 @@ theorem neg_eq_not_add (x : BitVec w) : -x = ~~~x + 1 := by have hx : x.toNat < 2^w := x.isLt rw [Nat.sub_sub, Nat.add_comm 1 x.toNat, ← Nat.sub_sub, Nat.sub_add_cancel (by omega)] +@[simp] +theorem neg_neg {x : BitVec w} : - - x = x := by + by_cases h : x = 0#w + · simp [h] + · simp [bv_toNat, h] + +theorem neg_ne_iff_ne_neg {x y : BitVec w} : -x ≠ y ↔ x ≠ -y := by + constructor + all_goals + intro h h' + subst h' + simp at h + /-! ### mul -/ theorem mul_def {n} {x y : BitVec n} : x * y = (ofFin <| x.toFin * y.toFin) := by rfl