@@ -11,12 +11,12 @@ public import Init.Data.Order.Lemmas
1111public import Init.Data.UInt
1212import Init.Omega
1313
14- public section
15-
1614open Std Std.PRange
1715
1816namespace BitVec
1917
18+ public section
19+
2020variable {n : Nat}
2121
2222instance : UpwardEnumerable (BitVec n) where
@@ -81,12 +81,11 @@ instance : LawfulUpwardEnumerableLE (BitVec n) where
8181 simp [BitVec.ofNatLT]
8282
8383instance : LawfulUpwardEnumerableLT (BitVec n) := inferInstance
84- instance : LawfulUpwardEnumerableLT (BitVec n) := inferInstance
8584
86- instance : Rxc.HasSize (BitVec n) where
85+ instance instRxcHasSize : Rxc.HasSize (BitVec n) where
8786 size lo hi := hi.toNat + 1 - lo.toNat
8887
89- instance : Rxc.LawfulHasSize (BitVec n) where
88+ instance instRxcLawfulHasSize : Rxc.LawfulHasSize (BitVec n) where
9089 size_eq_zero_of_not_le bound x := by
9190 simp only [BitVec.not_le, Rxc.HasSize.size, BitVec.lt_def]
9291 omega
@@ -98,360 +97,24 @@ instance : Rxc.LawfulHasSize (BitVec n) where
9897 simp only [succ?_eq_some, Rxc.HasSize.size, BitVec.le_def]
9998 omega
10099
101- instance : Rxc.IsAlwaysFinite (BitVec n) := inferInstance
100+ instance instRxcIsAlwaysFinite : Rxc.IsAlwaysFinite (BitVec n) := inferInstance
102101
103- instance : Rxo.HasSize (BitVec n) := .ofClosed
104- instance : Rxo.LawfulHasSize (BitVec n) := inferInstance
105- instance : Rxo.IsAlwaysFinite (BitVec n) := inferInstance
102+ instance instRxoHasSize : Rxo.HasSize (BitVec n) := .ofClosed
103+ instance instRxoLawfulHasSize : Rxo.LawfulHasSize (BitVec n) := inferInstance
104+ instance instRxoIsAlwaysFinite : Rxo.IsAlwaysFinite (BitVec n) := inferInstance
106105
107- instance : Rxi.HasSize (BitVec n) where
106+ instance instRxiHasSize : Rxi.HasSize (BitVec n) where
108107 size lo := 2 ^ n - lo.toNat
109108
110- instance : Rxi.LawfulHasSize (BitVec n) where
109+ instance instRxiLawfulHasSize : Rxi.LawfulHasSize (BitVec n) where
111110 size_eq_one_of_succ?_eq_none x := by
112111 simp only [succ?_eq_none, Rxi.HasSize.size]
113112 omega
114113 size_eq_succ_of_succ?_eq_some lo lo' := by
115114 simp only [succ?_eq_some, Rxi.HasSize.size]
116115 omega
117116
118- instance : Rxi.IsAlwaysFinite (BitVec n) := inferInstance
119-
120- namespace Signed
121-
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-
130- @[expose]
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]
175-
176- theorem rotate_rotate {x : BitVec n} :
177- rotate (rotate x) = x := by
178- match n with
179- | 0 => simp [eq_nil x, rotate, irredMin_def]
180- | n + 1 =>
181- simp only [rotate, BitVec.add_assoc]
182- simp [← BitVec.toNat_inj, ← Nat.two_mul, irredMin_def, show 2 * 2 ^ n = 2 ^ (n + 1 ) by omega]
183-
184- theorem rotate_map_eq_iff {x y : Option (BitVec n)} :
185- rotate <$> x = y ↔ x = rotate <$> y := by
186- suffices h : ∀ x y : Option (BitVec n), rotate <$> x = y → x = rotate <$> y by
187- exact ⟨h x y, fun h' => (h y x h'.symm).symm⟩
188- intro x y h
189- replace h := congrArg (rotate <$> ·) h
190- simpa [Function.comp_def, rotate_rotate] using h
191-
192- scoped instance instUpwardEnumerable : UpwardEnumerable (BitVec n) where
193- succ? x := rotate <$> UpwardEnumerable.succ? (rotate x)
194- succMany? n x := rotate <$> UpwardEnumerable.succMany? n (rotate x)
195-
196- theorem succ?_rotate {x : BitVec n} :
197- succ? (rotate x) = (haveI := BitVec.instUpwardEnumerable (n := n); rotate <$> succ? x) := by
198- simp [succ?, rotate_rotate]
199-
200- theorem succMany?_rotate {x : BitVec n} :
201- succMany? m (rotate x) =
202- (haveI := BitVec.instUpwardEnumerable (n := n); rotate <$> succMany? m x) := by
203- simp [succMany?, rotate_rotate]
204-
205- theorem sle_iff_rotate_le_rotate {x y : BitVec n} :
206- x.sle y ↔ rotate x ≤ rotate y := by
207- match n with
208- | 0 => simp [eq_nil x, eq_nil y]
209- | n + 1 =>
210- simp [BitVec.sle_iff_toInt_le, BitVec.toInt, Nat.pow_add, Nat.mul_comm _ 2 , rotate, BitVec.le_def,
211- irredMin_def]
212- split <;> split
213- · simp only [Int.ofNat_le]
214- rw [Nat.mod_eq_of_lt (by omega), Nat.mod_eq_of_lt (by omega)]
215- omega
216- · have : (↑y.toNat : Int) - 2 * 2 ^ n < 0 := by
217- have := BitVec.toNat_lt_twoPow_of_le (x := y) (Nat.le_refl _)
218- simp [Nat.pow_add, Nat.mul_comm _ 2 ] at this
219- simp only [← Int.ofNat_lt, Int.natCast_mul, Int.cast_ofNat_Int, Int.natCast_pow] at this
220- omega
221- have : ¬ (↑x.toNat ≤ (↑y.toNat : Int) - 2 * 2 ^ n) := by
222- apply Int.not_le_of_gt
223- calc _ < 0 := this
224- _ ≤ _ := by omega
225- simp [this]
226- rw [Nat.mod_eq_mod_iff (x := y.toNat + 2 ^ n) (y := y.toNat - 2 ^ n) (z := 2 * 2 ^ n) |>.mpr]
227- rotate_left
228- · exact ⟨0 , 1 , by omega⟩
229- rw [Nat.mod_eq_of_lt (by omega), Nat.mod_eq_of_lt (by omega)]
230- omega
231- · have : (↑x.toNat : Int) - 2 * 2 ^ n ≤ ↑y.toNat := by
232- have : x.toNat < 2 * 2 ^ n := by omega
233- have : (↑x.toNat : Int) < 2 * 2 ^ n := by simpa [← Int.ofNat_lt] using this
234- omega
235- simp [this]
236- rw [Nat.mod_eq_mod_iff (x := x.toNat + 2 ^ n) (y := x.toNat - 2 ^ n) (z := 2 * 2 ^ n) |>.mpr]
237- rotate_left
238- · exact ⟨0 , 1 , by omega⟩
239- rw [Nat.mod_eq_of_lt (by omega), Nat.mod_eq_of_lt (by omega)]
240- omega
241- · simp
242- rw [Nat.mod_eq_mod_iff (x := x.toNat + 2 ^ n) (y := x.toNat - 2 ^ n) (z := 2 * 2 ^ n) |>.mpr ⟨0 , 1 , by omega⟩,
243- Nat.mod_eq_mod_iff (x := y.toNat + 2 ^ n) (y := y.toNat - 2 ^ n) (z := 2 * 2 ^ n) |>.mpr ⟨0 , 1 , by omega⟩,
244- Nat.mod_eq_of_lt (by omega), Nat.mod_eq_of_lt (by omega)]
245- omega
246-
247- theorem rotate_inj {x y : BitVec n} :
248- rotate x = rotate y ↔ x = y := by
249- apply Iff.intro
250- · intro h
251- simpa [rotate_rotate] using congrArg rotate h
252- · intro h
253- exact congrArg rotate h
254-
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-
288- theorem toInt_eq_ofNat_toNat_rotate_sub {x : BitVec n} (h : n > 0 ) :
289- x.toInt = (↑(rotate x).toNat : Int) - 2 ^ (n - 1 ) := by
290- match n with
291- | 0 => omega
292- | n + 1 =>
293- simp [BitVec.toInt, rotate, irredMin_def]
294- have : (2 : Int) ^ n > 0 := Int.pow_pos (by omega)
295- split <;> rename_i h
296- · rw [Nat.pow_add, Nat.pow_one, Nat.mul_comm _ 2 , Nat.mul_lt_mul_left (by omega),
297- ← Int.ofNat_lt, Int.natCast_pow, Int.cast_ofNat_Int] at h
298- rw [Int.emod_eq_of_lt (by omega) (by omega)]
299- omega
300- · rw [Nat.pow_add, Nat.pow_one, Nat.mul_comm _ 2 , Nat.mul_lt_mul_left (by omega),
301- ← Int.ofNat_lt, Int.natCast_pow, Int.cast_ofNat_Int] at h
302- simp [Int.pow_add, Int.mul_comm _ 2 , Int.two_mul, ← Int.sub_sub]
303- rw [eq_comm, Int.emod_eq_iff (by omega)]
304- refine ⟨by omega, ?_, ?_⟩
305- · have := BitVec.toNat_lt_twoPow_of_le (x := x) (Nat.le_refl _)
306- rw [Int.ofNat_natAbs_of_nonneg (by omega)]
307- simp only [Nat.pow_add, Nat.pow_one, ← Int.ofNat_lt, Int.natCast_mul, Int.natCast_pow,
308- Int.cast_ofNat_Int] at this
309- omega
310- · conv => rhs; rw [← Int.sub_sub, Int.sub_sub (b := 2 ^ n), Int.add_comm, ← Int.sub_sub]
311- exact ⟨-1 , by omega⟩
312-
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-
326- scoped instance instLE : LE (BitVec n) where
327- le x y := x.sle y
328-
329- scoped instance : DecidableLE (BitVec n) := fun x y => inferInstanceAs (Decidable <| x.sle y)
330-
331- scoped instance instLT : LT (BitVec n) where
332- lt x y := x.slt y
333-
334- scoped instance : DecidableLT (BitVec n) := fun x y => inferInstanceAs (Decidable <| x.slt y)
335-
336- scoped instance : LawfulOrderLT (BitVec n) where
337- lt_iff x y := by
338- simp only [LE.le, LT.lt]
339- simpa [BitVec.slt_iff_toInt_lt, BitVec.sle_iff_toInt_le] using Int.le_of_lt
340-
341- scoped instance : IsPartialOrder (BitVec n) where
342- le_refl x := by simp only [LE.le]; simp [BitVec.sle_iff_toInt_le]
343- le_trans := by
344- simp only [LE.le]
345- simpa [BitVec.sle_iff_toInt_le] using fun _ _ _ => Int.le_trans
346- le_antisymm := by
347- simp only [LE.le, ← BitVec.toInt_inj]
348- simpa [BitVec.sle_iff_toInt_le] using fun _ _ => Int.le_antisymm
349-
350- scoped instance : LawfulUpwardEnumerableLE (BitVec n) where
351- le_iff x y := by
352- rw [← rotate_rotate (x := x), ← rotate_rotate (x := y)]
353- generalize (rotate x) = x
354- generalize (rotate y) = y
355- simp only [LE.le]
356- rw [sle_iff_rotate_le_rotate]
357- letI := BitVec.instUpwardEnumerable (n := n)
358- letI := instLEBitVec (w := n)
359- simp [UpwardEnumerable.le_iff, rotate_rotate, UpwardEnumerable.le_iff_exists,
360- succMany?_rotate, rotate_inj]
361-
362- scoped instance :
363- LawfulUpwardEnumerable (BitVec n) where
364- ne_of_lt x y h := by
365- rw [← rotate_rotate (x := x), ← rotate_rotate (x := y)] at h ⊢
366- generalize rotate x = x at h ⊢
367- generalize rotate y = y at h ⊢
368- letI : UpwardEnumerable (BitVec n) := BitVec.instUpwardEnumerable
369- have : x ≠ y := by
370- apply UpwardEnumerable.ne_of_lt
371- obtain ⟨n, hn⟩ := h
372- refine ⟨n, ?_⟩
373- rwa [succMany?_rotate, rotate_map_eq_iff, Option.map_eq_map, Option.map_some, rotate_rotate] at hn
374- apply this.imp; intro heq
375- simpa [rotate_rotate] using congrArg rotate heq
376- succMany?_zero x := by
377- rw [← rotate_rotate (x := x)]
378- generalize rotate x = x
379- letI : UpwardEnumerable (BitVec n) := BitVec.instUpwardEnumerable
380- simp [succMany?_rotate, succMany?_zero]
381- succMany?_add_one m x := by
382- rw [← rotate_rotate (x := x)]
383- generalize rotate x = x
384- letI : UpwardEnumerable (BitVec n) := BitVec.instUpwardEnumerable
385- simp [succMany?_rotate, succMany?_add_one, Option.bind_map, Function.comp_def, succ?_rotate]
386-
387- scoped instance : LawfulUpwardEnumerableLT (BitVec n) := inferInstance
388- scoped instance : LawfulUpwardEnumerableLT (BitVec n) := inferInstance
389-
390- scoped instance : Rxc.HasSize (BitVec n) where
391- size lo hi :=
392- haveI := BitVec.instHasSize (n := n)
393- Rxc.HasSize.size (rotate lo) (rotate hi)
394-
395- scoped instance : Rxc.LawfulHasSize (BitVec n) where
396- size_eq_zero_of_not_le bound x := by
397- simp only [LE.le]
398- match n with
399- | 0 => simp [eq_nil x, eq_nil bound]
400- | n + 1 =>
401- simp [BitVec.sle_iff_toInt_le, Rxc.HasSize.size,
402- toInt_eq_ofNat_toNat_rotate_sub (show n + 1 > 0 by omega)]
403- omega
404- size_eq_one_of_succ?_eq_none lo hi := by
405- rw [← rotate_rotate (x := lo)]
406- generalize rotate lo = lo
407- simp only [LE.le]
408- match n with
409- | 0 => simp [eq_nil lo, eq_nil hi, succ?, rotate, Rxc.HasSize.size, irredMin_def]
410- | n + 1 =>
411- simp [BitVec.sle_iff_toInt_le, toInt_eq_ofNat_toNat_rotate_sub,
412- Rxc.HasSize.size, rotate_rotate, succ?_rotate, Option.map_eq_map, Option.map_eq_none_iff,
413- succ?_eq_none]
414- omega
415- size_eq_succ_of_succ?_eq_some lo hi x := by
416- rw [← rotate_rotate (x := lo)]
417- generalize rotate lo = lo
418- simp only [LE.le]
419- match n with
420- | 0 => simp [eq_nil lo, eq_nil hi, succ?, rotate, Rxc.HasSize.size, irredMin_def]
421- | n + 1 =>
422- simp [BitVec.sle_iff_toInt_le, toInt_eq_ofNat_toNat_rotate_sub,
423- Rxc.HasSize.size, rotate_rotate, succ?_rotate, succ?_eq_some]
424- rintro h y h' hy rfl
425- simp only [rotate_rotate]
426- omega
427-
428- scoped instance : Rxc.IsAlwaysFinite (BitVec n) := inferInstance
429-
430- scoped instance : Rxo.HasSize (BitVec n) := .ofClosed
431- scoped instance : Rxo.LawfulHasSize (BitVec n) := .of_closed
432- scoped instance : Rxo.IsAlwaysFinite (BitVec n) := inferInstance
433-
434- scoped instance : Rxi.HasSize (BitVec n) where
435- size lo := 2 ^ n - (rotate lo).toNat
436-
437- scoped instance : Rxi.LawfulHasSize (BitVec n) where
438- size_eq_one_of_succ?_eq_none x := by
439- rw [← rotate_rotate (x := x)]
440- generalize rotate x = x
441- simp only [succ?_rotate, Option.map_eq_map, Option.map_eq_none_iff, Rxi.HasSize.size,
442- rotate_rotate]
443- letI := BitVec.instHasSize_2 (n := n)
444- exact Rxi.size_eq_one_of_succ?_eq_none x
445- size_eq_succ_of_succ?_eq_some lo lo' := by
446- rw [← rotate_rotate (x := lo), ← rotate_rotate (x := lo')]
447- generalize rotate lo = lo
448- generalize rotate lo' = lo'
449- simp [succ?_rotate, rotate_inj, instHasSize_2, rotate_rotate]
450- letI := BitVec.instHasSize_2 (n := n)
451- exact Rxi.size_eq_succ_of_succ?_eq_some lo lo'
452-
453- scoped instance : Rxi.IsAlwaysFinite (BitVec n) := inferInstance
454-
455- end Signed
117+ instance instRxiIsAlwaysFinite : Rxi.IsAlwaysFinite (BitVec n) := inferInstance
456118
119+ end
457120end BitVec
0 commit comments