@@ -1803,39 +1803,54 @@ theorem neg_toInt_neg_umod_eq_of_msb_true_msb_true {x y : BitVec w} (hx : x.msb
18031803 · simp [h]
18041804 · rw [msb_neg_umod_neg_of_msb_true_of_msb_true hx hy]
18051805
1806+ theorem toNat_pos_of_ne_zero {x : BitVec w} (hx : x ≠ 0 #w) :
1807+ 0 < x.toNat := by
1808+ by_cases hw : w = 0 ; subst hw; decide +revert
1809+ have wpos : 0 < w := by omega
1810+ simp [toNat_eq] at hx
1811+ omega
1812+
1813+ theorem toInt_umod_neg_add {x y : BitVec w} (humod : ¬y.toInt ∣ x.toInt) (hymsb : y.msb = true) (hxmsb : x.msb = false) :
1814+ (x % -y + y).toInt = x.toInt % y.toInt + y.toInt := by
1815+ rcases w with _|w ; simp [of_length_zero]
1816+ have hypos : 0 < y.toNat := toNat_pos_of_ne_zero (by simp [hymsb])
1817+ have hxnonneg := toInt_nonneg_of_msb_false hxmsb
1818+ have hynonpos := toInt_neg_of_msb_true hymsb
1819+ have hylt : (-y).toNat ≤ 2 ^ (w) := toNat_neg_lt y hymsb
1820+ have hmodlt := Nat.mod_lt x.toNat (y := (-y).toNat)
1821+ (by rw [toNat_neg, Nat.mod_eq_of_lt (by omega)]; omega)
1822+ simp only [humod, reduceIte, toInt_add, hxnonneg, show ¬0 ≤ y.toInt by omega]
1823+ rw [toInt_umod, toInt_eq_neg_toNat_neg_of_msb_true hymsb, Int.bmod_add_bmod,
1824+ Int.bmod_eq_of_le (n := (x.toNat : Int) % ((-y).toNat : Int) + -((-y).toNat : Int))
1825+ (m := 2 ^ (w+1 )) (by omega) (by omega),
1826+ toInt_eq_toNat_of_msb hxmsb, Int.emod_neg]
1827+
18061828theorem toInt_smod {x y : BitVec w} :
18071829 (x.smod y).toInt = x.toInt.fmod y.toInt := by
18081830 rcases w with _|w ; simp [of_length_zero]
18091831 by_cases hyzero : y = 0 #(w + 1 ); simp [hyzero]
18101832 have hypos : 0 < y.toNat := by simp [toNat_eq] at hyzero; omega
1833+ have hytoNat := msb_eq_toNat (x := y)
18111834 rw [smod_eq]
18121835 cases hxmsb : x.msb <;> cases hymsb : y.msb
18131836 <;> simp only [umod_eq]
1814- · have hylt := toNat_lt_of_msb_false ( by omega)
1815- have hmodlt := Nat.mod_lt x.toNat (by omega)
1837+ <;> simp [hymsb] at hytoNat
1838+ · have hmodlt := Nat.mod_lt x.toNat (by omega)
18161839 rw [toInt_umod, Int.fmod_eq_emod_of_nonneg x.toInt (toInt_nonneg_of_msb_false hymsb),
18171840 toInt_eq_toNat_of_msb hxmsb, toInt_eq_toNat_of_msb hymsb,
1818- Int.bmod_eq_of_le_mul_two (by omega) (by simp at hylt; omega)]
1819- · have hxnonneg := toInt_nonneg_of_msb_false hxmsb
1820- have hynonpos := toInt_neg_of_msb_true hymsb
1821- have hylt : (-y).toNat ≤ 2 ^ w := toNat_neg_lt y hymsb
1822- simp only [Int.fmod_eq_tmod, Int.tmod_eq_emod_of_nonneg hxnonneg, Int.ofNat_toNat]
1823- have hmodlt := Nat.mod_lt x.toNat (y := (-y).toNat)
1824- (by rw [toNat_neg, Nat.mod_eq_of_lt (by omega)]; omega)
1825- by_cases humod : x % -y = 0 #(w+1 )
1826- · simp only [humod, reduceIte, toInt_zero]
1827- simp only [hxmsb, hymsb, ←toInt_dvd_toInt_iff_of_msb_false_msb_true] at humod
1828- omega
1829- · simp only [humod]
1830- simp only [hxmsb, hymsb, ←toInt_dvd_toInt_iff_of_msb_false_msb_true] at humod
1831- simp only [humod, reduceIte, toInt_add, hxnonneg, show ¬0 ≤ y.toInt by omega]
1832- rw [toInt_umod, toInt_eq_neg_toNat_neg_of_msb_true hymsb, Int.bmod_add_bmod,
1833- Int.bmod_eq_of_le (n := (x.toNat : Int) % ((-y).toNat : Int) + -((-y).toNat : Int))
1834- (m := 2 ^ (w + 1 )) (by omega) (by omega),
1835- toInt_eq_toNat_of_msb hxmsb, Int.emod_neg]
1841+ Int.bmod_eq_of_le_mul_two (by omega) (by omega)]
1842+ · by_cases hx_dvd_y : y.toInt ∣ x.toInt
1843+ · have := (@toInt_dvd_toInt_iff_of_msb_false_msb_true (w + 1 ) x y hxmsb hymsb).mp hx_dvd_y
1844+ simp [hx_dvd_y, Int.fmod_eq_zero_of_dvd, this ]
1845+ · have hxnonneg := toInt_nonneg_of_msb_false hxmsb
1846+ have hynonpos := toInt_neg_of_msb_true hymsb
1847+ have := (@toInt_dvd_toInt_iff_of_msb_false_msb_true (w + 1 ) x y hxmsb hymsb)
1848+ simp only [hx_dvd_y, false_iff] at this
1849+ simp only [this , Int.fmod_eq_tmod, Int.tmod_eq_emod_of_nonneg hxnonneg]
1850+ simp [hx_dvd_y, hxnonneg, hymsb, hxmsb, show ¬0 ≤ y.toInt by omega,
1851+ toInt_umod_neg_add hx_dvd_y]
18361852 · have hynonneg := toInt_nonneg_of_msb_false hymsb
18371853 rw [Int.fmod_eq_emod_of_nonneg x.toInt (b := y.toInt) (by omega)]
1838- have hylt := toNat_lt_of_msb_false hymsb
18391854 have hdvd := toInt_dvd_toInt_iff_of_msb_true_msb_false hxmsb hymsb
18401855 by_cases humod : -x % y = 0 #(w+1 )
18411856 · simp only [humod, iff_true] at hdvd
@@ -1844,7 +1859,7 @@ theorem toInt_smod {x y : BitVec w} :
18441859 · simp only [humod, reduceIte, toInt_sub, toInt_eq_toNat_of_msb hymsb, toInt_umod,
18451860 Int.sub_bmod_bmod, toInt_eq_neg_toNat_neg_of_msb_true hxmsb, Int.neg_emod]
18461861 have hmodlt := Nat.mod_lt (x := (-x).toNat) (y := y.toNat) hypos
1847- rw [Int.bmod_eq_of_le (by omega) (by simp at hylt; omega)]
1862+ rw [Int.bmod_eq_of_le (by omega) (by omega)]
18481863 simp only [toInt_eq_toNat_of_msb hymsb, BitVec.toInt_eq_neg_toNat_neg_of_msb_true hxmsb,
18491864 Int.dvd_neg, humod, iff_false] at hdvd
18501865 omega
0 commit comments