@@ -3354,6 +3354,17 @@ theorem toNat_add_of_not_uaddOverflow {x y : BitVec w} (h : ¬ uaddOverflow x y)
33543354 · simp only [uaddOverflow, ge_iff_le, decide_eq_true_eq, Nat.not_le] at h
33553355 rw [toNat_add, Nat.mod_eq_of_lt h]
33563356
3357+ /--
3358+ Unsigned addition overflow reassociation.
3359+ If `(x + y)` and `(y + z)` do not overflow, then `(x + y) + z` overflows iff `x + (y + z)` overflows.
3360+ -/
3361+ theorem uaddOverflow_assoc {x y z : BitVec w} (h : ¬ x.uaddOverflow y) (h' : ¬ y.uaddOverflow z) :
3362+ (x + y).uaddOverflow z = x.uaddOverflow (y + z) := by
3363+ simp only [uaddOverflow, ge_iff_le, decide_eq_true_eq, Nat.not_le] at h h'
3364+ simp only [uaddOverflow, toNat_add, ge_iff_le, decide_eq_decide]
3365+ repeat rw [Nat.mod_eq_of_lt (by omega)]
3366+ omega
3367+
33573368protected theorem add_assoc (x y z : BitVec n) : x + y + z = x + (y + z) := by
33583369 apply eq_of_toNat_eq ; simp [Nat.add_assoc]
33593370instance : Std.Associative (α := BitVec n) (· + ·) := ⟨BitVec.add_assoc⟩
@@ -3392,6 +3403,20 @@ theorem toInt_add_of_not_saddOverflow {x y : BitVec w} (h : ¬ saddOverflow x y)
33923403 _root_.not_or, Int.not_le, Int.not_lt] at h
33933404 rw [toInt_add, Int.bmod_eq_of_le (by push_cast; omega) (by push_cast; omega)]
33943405
3406+ /--
3407+ Signed addition overflow reassociation.
3408+ If `(x + y)` and `(y + z)` do not overflow, then `(x + y) + z` overflows iff `x + (y + z)` overflows.
3409+ -/
3410+ theorem saddOverflow_assoc {x y z : BitVec w} (h : ¬ x.saddOverflow y) (h' : ¬ y.saddOverflow z) :
3411+ (x + y).saddOverflow z = x.saddOverflow (y + z) := by
3412+ rcases w with _|w
3413+ · simp [of_length_zero]
3414+ · simp only [saddOverflow, Nat.add_one_sub_one, ge_iff_le, Bool.or_eq_true, decide_eq_true_eq,
3415+ _root_.not_or, Int.not_le, Int.not_lt] at h h'
3416+ simp only [bool_to_prop, saddOverflow, toInt_add, ge_iff_le, Nat.add_one_sub_one]
3417+ repeat rw [Int.bmod_eq_of_le (by push_cast; omega) (by push_cast; omega)]
3418+ omega
3419+
33953420@[simp]
33963421theorem shiftLeft_add_distrib {x y : BitVec w} {n : Nat} :
33973422 (x + y) <<< n = x <<< n + y <<< n := by
@@ -3820,6 +3845,18 @@ theorem toNat_mul_of_not_umulOverflow {x y : BitVec w} (h : ¬ umulOverflow x y)
38203845 · simp only [umulOverflow, ge_iff_le, decide_eq_true_eq, Nat.not_le] at h
38213846 rw [toNat_mul, Nat.mod_eq_of_lt h]
38223847
3848+ /--
3849+ Unsigned multiplication overflow reassociation.
3850+ If `(x * y)` and `(y * z)` do not overflow, then `(x * y) * z` overflows iff `x * (y * z)` overflows.
3851+ -/
3852+ theorem umulOverflow_assoc {x y z : BitVec w} (h : ¬ x.umulOverflow y) (h' : ¬ y.umulOverflow z) :
3853+
3854+ (x * y).umulOverflow z = x.umulOverflow (y * z) := by
3855+ simp only [umulOverflow, ge_iff_le, decide_eq_true_eq, Nat.not_le] at h h'
3856+ simp only [umulOverflow, toNat_mul, ge_iff_le, decide_eq_decide]
3857+ repeat rw [Nat.mod_eq_of_lt (by omega)]
3858+ rw [Nat.mul_assoc]
3859+
38233860@[simp]
38243861theorem toInt_mul_of_not_smulOverflow {x y : BitVec w} (h : ¬ smulOverflow x y) :
38253862 (x * y).toInt = x.toInt * y.toInt := by
@@ -3829,6 +3866,20 @@ theorem toInt_mul_of_not_smulOverflow {x y : BitVec w} (h : ¬ smulOverflow x y)
38293866 _root_.not_or, Int.not_le, Int.not_lt] at h
38303867 rw [toInt_mul, Int.bmod_eq_of_le (by push_cast; omega) (by push_cast; omega)]
38313868
3869+ /--
3870+ Signed multiplication overflow reassociation.
3871+ If `(x * y)` and `(y * z)` do not overflow, then `(x * y) * z` overflows iff `x * (y * z)` overflows.
3872+ -/
3873+ theorem smulOverflow_assoc {x y z : BitVec w} (h : ¬ x.smulOverflow y) (h' : ¬ y.smulOverflow z) :
3874+ (x * y).smulOverflow z = x.smulOverflow (y * z) := by
3875+ rcases w with _|w
3876+ · simp [of_length_zero]
3877+ · simp only [smulOverflow, Nat.add_one_sub_one, ge_iff_le, Bool.or_eq_true, decide_eq_true_eq,
3878+ _root_.not_or, Int.not_le, Int.not_lt] at h h'
3879+ simp only [smulOverflow, toInt_mul, Nat.add_one_sub_one, ge_iff_le, bool_to_prop]
3880+ repeat rw [Int.bmod_eq_of_le (by push_cast; omega) (by push_cast; omega)]
3881+ rw [Int.mul_assoc]
3882+
38323883theorem ofInt_mul {n} (x y : Int) : BitVec.ofInt n (x * y) =
38333884 BitVec.ofInt n x * BitVec.ofInt n y := by
38343885 apply eq_of_toInt_eq
0 commit comments