Skip to content

Commit 73709e4

Browse files
committed
sorry-free
1 parent d623d33 commit 73709e4

File tree

3 files changed

+501
-530
lines changed

3 files changed

+501
-530
lines changed

src/Init/Data/Range/Polymorphic/BitVec.lean

Lines changed: 12 additions & 349 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ public import Init.Data.Order.Lemmas
1111
public import Init.Data.UInt
1212
import Init.Omega
1313

14-
public section
15-
1614
open Std Std.PRange
1715

1816
namespace BitVec
1917

18+
public section
19+
2020
variable {n : Nat}
2121

2222
instance : UpwardEnumerable (BitVec n) where
@@ -81,12 +81,11 @@ instance : LawfulUpwardEnumerableLE (BitVec n) where
8181
simp [BitVec.ofNatLT]
8282

8383
instance : 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
457120
end BitVec

0 commit comments

Comments
 (0)