@@ -119,16 +119,67 @@ instance : Rxi.IsAlwaysFinite (BitVec n) := inferInstance
119119
120120namespace Signed
121121
122+ def irredMin n : BitVec n := ↑(2 ^ (n - 1 ) : Nat)
123+ theorem irredMin_def : irredMin n = ↑(2 ^ (n - 1 ) : Nat) := (rfl)
124+ seal irredMin
125+
126+ def irredMax n : BitVec n := ↑(2 ^ (n - 1 ) - 1 : Nat)
127+ theorem irredMax_def : irredMax n = ↑(2 ^ (n - 1 ) - 1 : Nat) := (rfl)
128+ seal irredMax
129+
122130@[expose]
123- def rotate (x : BitVec n) : BitVec n := x + ↑(2 ^ (n - 1 ) : Nat)
131+ def rotate (x : BitVec n) : BitVec n := x + irredMin n
132+
133+ theorem irredMax_eq_irredMin_add :
134+ irredMax n = irredMin n + ↑(2 ^ n - 1 : Nat) := by
135+ match n with
136+ | 0 => simp [eq_nil (irredMax 0 ), eq_nil (irredMin 0 )]
137+ | n + 1 =>
138+ simp only [irredMax_def, Nat.add_one_sub_one, natCast_eq_ofNat, irredMin_def, ← ofNat_add,
139+ ← toNat_inj, toNat_ofNat, Nat.mod_eq_mod_iff]
140+ exact ⟨1 , 0 , by omega⟩
141+
142+ theorem irredMin_add_irredMin :
143+ irredMin n + irredMin n = 0 := by
144+ match n with
145+ | 0 => simp [eq_nil (irredMin 0 )]
146+ | n + 1 =>
147+ simp [irredMin_def, ← BitVec.ofNat_add, show 2 ^ n + 2 ^ n = 2 ^ (n + 1 ) by omega,
148+ ← BitVec.toNat_inj]
149+
150+ theorem rotate_neg_eq_irredMin_sub {x : BitVec n} :
151+ rotate (-x) = irredMin n - x := by
152+ simp only [rotate, irredMin_def, natCast_eq_ofNat]
153+ rw [eq_sub_iff_add_eq, BitVec.add_comm, ← BitVec.add_assoc, BitVec.add_neg_eq_sub,
154+ BitVec.sub_self, BitVec.zero_add]
155+
156+ theorem rotate_eq_sub_irredMin {x : BitVec n} :
157+ rotate x = x - irredMin n := by
158+ simp [rotate, eq_sub_iff_add_eq, BitVec.add_assoc, irredMin_add_irredMin]
159+
160+ theorem rotate_add {x y : BitVec n} :
161+ rotate (x + y) = rotate x + y := by
162+ simp [rotate, BitVec.add_assoc, BitVec.add_comm y]
163+
164+ theorem rotate_sub {x y : BitVec n} :
165+ rotate (x - y) = rotate x - y := by
166+ simp [BitVec.sub_eq_add_neg, rotate_add]
167+
168+ theorem rotate_irredMin :
169+ rotate (irredMin n) = ↑(0 : Nat) := by
170+ simp [rotate, irredMin_add_irredMin]
171+
172+ theorem rotate_irredMax :
173+ rotate (irredMax n) = ↑(2 ^ n - 1 : Nat) := by
174+ simp [irredMax_eq_irredMin_add, rotate_add, rotate_irredMin]
124175
125176theorem rotate_rotate {x : BitVec n} :
126177 rotate (rotate x) = x := by
127178 match n with
128- | 0 => simp [eq_nil x, rotate]
179+ | 0 => simp [eq_nil x, rotate, irredMin_def ]
129180 | n + 1 =>
130181 simp only [rotate, BitVec.add_assoc]
131- simp [← BitVec.toNat_inj, ← Nat.two_mul, show 2 * 2 ^ n = 2 ^ (n + 1 ) by omega]
182+ simp [← BitVec.toNat_inj, ← Nat.two_mul, irredMin_def, show 2 * 2 ^ n = 2 ^ (n + 1 ) by omega]
132183
133184theorem rotate_map_eq_iff {x y : Option (BitVec n)} :
134185 rotate <$> x = y ↔ x = rotate <$> y := by
@@ -156,7 +207,8 @@ theorem sle_iff_rotate_le_rotate {x y : BitVec n} :
156207 match n with
157208 | 0 => simp [eq_nil x, eq_nil y]
158209 | n + 1 =>
159- simp [BitVec.sle_iff_toInt_le, BitVec.toInt, Nat.pow_add, Nat.mul_comm _ 2 , rotate, BitVec.le_def]
210+ simp [BitVec.sle_iff_toInt_le, BitVec.toInt, Nat.pow_add, Nat.mul_comm _ 2 , rotate, BitVec.le_def,
211+ irredMin_def]
160212 split <;> split
161213 · simp only [Int.ofNat_le]
162214 rw [Nat.mod_eq_of_lt (by omega), Nat.mod_eq_of_lt (by omega)]
@@ -200,12 +252,45 @@ theorem rotate_inj {x y : BitVec n} :
200252 · intro h
201253 exact congrArg rotate h
202254
255+ theorem rotate_eq_iff {x y : BitVec n} :
256+ rotate x = y ↔ x = rotate y := by
257+ rw [← rotate_rotate (x := y), rotate_inj, rotate_rotate]
258+
259+ theorem toInt_eq_ofNat_toNat_rotate_sub' {x : BitVec n} (h : n > 0 ) :
260+ x.toInt = (↑(rotate x).toNat : Int) - ↑(irredMin n).toNat := by
261+ match n with
262+ | 0 => omega
263+ | n + 1 =>
264+ simp [BitVec.toInt, rotate, irredMin_def]
265+ rw [Int.emod_eq_of_lt (a := 2 ^ n)]; rotate_left
266+ · exact Int.le_of_lt (Int.pow_pos (by omega))
267+ · rw [Int.pow_add, Int.pow_succ, Int.pow_zero, Int.one_mul, Int.mul_comm, Int.two_mul]
268+ exact Int.lt_add_of_pos_right _ (Int.pow_pos (by omega))
269+ have : (2 : Int) ^ n > 0 := Int.pow_pos (by omega)
270+ split <;> rename_i h
271+ · rw [Nat.pow_add, Nat.pow_one, Nat.mul_comm _ 2 , Nat.mul_lt_mul_left (by omega),
272+ ← Int.ofNat_lt, Int.natCast_pow, Int.cast_ofNat_Int] at h
273+ rw [Int.emod_eq_of_lt (by omega) (by omega)]
274+ omega
275+ · rw [Nat.pow_add, Nat.pow_one, Nat.mul_comm _ 2 , Nat.mul_lt_mul_left (by omega),
276+ ← Int.ofNat_lt, Int.natCast_pow, Int.cast_ofNat_Int] at h
277+ simp [Int.pow_add, Int.mul_comm _ 2 , Int.two_mul, ← Int.sub_sub]
278+ rw [eq_comm, Int.emod_eq_iff (by omega)]
279+ refine ⟨by omega, ?_, ?_⟩
280+ · have := BitVec.toNat_lt_twoPow_of_le (x := x) (Nat.le_refl _)
281+ rw [Int.ofNat_natAbs_of_nonneg (by omega)]
282+ simp only [Nat.pow_add, Nat.pow_one, ← Int.ofNat_lt, Int.natCast_mul, Int.natCast_pow,
283+ Int.cast_ofNat_Int] at this
284+ omega
285+ · conv => rhs; rw [← Int.sub_sub, Int.sub_sub (b := 2 ^ n), Int.add_comm, ← Int.sub_sub]
286+ exact ⟨-1 , by omega⟩
287+
203288theorem toInt_eq_ofNat_toNat_rotate_sub {x : BitVec n} (h : n > 0 ) :
204289 x.toInt = (↑(rotate x).toNat : Int) - 2 ^ (n - 1 ) := by
205290 match n with
206291 | 0 => omega
207292 | n + 1 =>
208- simp [BitVec.toInt, rotate]
293+ simp [BitVec.toInt, rotate, irredMin_def ]
209294 have : (2 : Int) ^ n > 0 := Int.pow_pos (by omega)
210295 split <;> rename_i h
211296 · rw [Nat.pow_add, Nat.pow_one, Nat.mul_comm _ 2 , Nat.mul_lt_mul_left (by omega),
@@ -225,6 +310,19 @@ theorem toInt_eq_ofNat_toNat_rotate_sub {x : BitVec n} (h : n > 0) :
225310 · conv => rhs; rw [← Int.sub_sub, Int.sub_sub (b := 2 ^ n), Int.add_comm, ← Int.sub_sub]
226311 exact ⟨-1 , by omega⟩
227312
313+ theorem ofNat_eq_rotate_ofInt_sub {n k : Nat} :
314+ BitVec.ofNat n k = rotate (BitVec.ofInt n (↑k - ↑(irredMin n).toNat)) := by
315+ match n with
316+ | 0 => simp only [eq_nil (BitVec.ofNat _ _), eq_nil (rotate _)]
317+ | n + 1 =>
318+ simp [irredMin]
319+ rw [Int.emod_eq_of_lt]; rotate_left
320+ · exact Int.le_of_lt (Int.pow_pos (by omega))
321+ · exact Int.pow_lt_pow_of_lt (by omega) (by omega)
322+ simp [← BitVec.toInt_inj, toInt_ofNat', rotate, Int.bmod_eq_bmod_iff_bmod_sub_eq_zero]
323+ simp [Int.sub_eq_add_neg, Int.neg_add, ← Int.add_assoc]
324+ simp [Int.add_neg_eq_sub, irredMin, toInt_ofNat']
325+
228326scoped instance instLE : LE (BitVec n) where
229327 le x y := x.sle y
230328
@@ -308,7 +406,7 @@ scoped instance : Rxc.LawfulHasSize (BitVec n) where
308406 generalize rotate lo = lo
309407 simp only [LE.le]
310408 match n with
311- | 0 => simp [eq_nil lo, eq_nil hi, succ?, rotate, Rxc.HasSize.size]
409+ | 0 => simp [eq_nil lo, eq_nil hi, succ?, rotate, Rxc.HasSize.size, irredMin_def ]
312410 | n + 1 =>
313411 simp [BitVec.sle_iff_toInt_le, toInt_eq_ofNat_toNat_rotate_sub,
314412 Rxc.HasSize.size, rotate_rotate, succ?_rotate, Option.map_eq_map, Option.map_eq_none_iff,
@@ -319,7 +417,7 @@ scoped instance : Rxc.LawfulHasSize (BitVec n) where
319417 generalize rotate lo = lo
320418 simp only [LE.le]
321419 match n with
322- | 0 => simp [eq_nil lo, eq_nil hi, succ?, rotate, Rxc.HasSize.size]
420+ | 0 => simp [eq_nil lo, eq_nil hi, succ?, rotate, Rxc.HasSize.size, irredMin_def ]
323421 | n + 1 =>
324422 simp [BitVec.sle_iff_toInt_le, toInt_eq_ofNat_toNat_rotate_sub,
325423 Rxc.HasSize.size, rotate_rotate, succ?_rotate, succ?_eq_some]
0 commit comments