Skip to content

Commit fc6e045

Browse files
authored
feat: add more lemmas about Array and List slices, support subslices (#11178)
This PR provides more lemmas about `Subarray` and `ListSlice` and it also adds support for subslices of these two types of slices.
1 parent a106ea0 commit fc6e045

File tree

8 files changed

+1272
-90
lines changed

8 files changed

+1272
-90
lines changed

src/Init/Data/List/Lemmas.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,12 @@ theorem ext_getElem {l₁ l₂ : List α} (hl : length l₁ = length l₂)
298298
have h₁ := Nat.le_of_not_lt h₁
299299
rw [getElem?_eq_none h₁, getElem?_eq_none]; rwa [← hl]
300300

301+
theorem ext_getElem_iff {l₁ l₂ : List α} :
302+
l₁ = l₂ ↔ l₁.length = l₂.length ∧ ∀ (i : Nat) (h₁ : i < l₁.length) (h₂ : i < l₂.length), l₁[i]'h₁ = l₂[i]'h₂ := by
303+
constructor
304+
· simp +contextual
305+
· exact fun h => ext_getElem h.1 h.2
306+
301307
@[simp] theorem getElem_concat_length {l : List α} {a : α} {i : Nat} (h : i = l.length) (w) :
302308
(l ++ [a])[i]'w = a := by
303309
subst h; simp

src/Init/Data/List/Nat/TakeDrop.lean

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,22 @@ theorem drop_take : ∀ {i j : Nat} {l : List α}, drop i (take j l) = take (j -
374374
rw [drop_take]
375375
simp
376376

377+
@[simp]
378+
theorem drop_eq_drop_iff :
379+
∀ {l : List α} {i j : Nat}, l.drop i = l.drop j ↔ min i l.length = min j l.length
380+
| [], i, j => by simp
381+
| _ :: xs, 0, 0 => by simp
382+
| x :: xs, i + 1, 0 => by
383+
rw [List.ext_getElem_iff]
384+
simp [succ_min_succ, show ¬ xs.length - i = xs.length + 1 by omega]
385+
| x :: xs, 0, j + 1 => by
386+
rw [List.ext_getElem_iff]
387+
simp [succ_min_succ, show ¬ xs.length + 1 = xs.length - j by omega]
388+
| x :: xs, i + 1, j + 1 => by simp [succ_min_succ, drop_eq_drop_iff]
389+
390+
theorem drop_eq_drop_min {l : List α} {i : Nat} : l.drop i = l.drop (min i l.length) := by
391+
simp
392+
377393
theorem take_reverse {α} {xs : List α} {i : Nat} :
378394
xs.reverse.take i = (xs.drop (xs.length - i)).reverse := by
379395
by_cases h : i ≤ xs.length

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2846,6 +2846,7 @@ public theorem size_eq_if_rcc [LE α] [DecidableLE α] [UpwardEnumerable α]
28462846
· split <;> simp [*]
28472847
· rfl
28482848

2849+
@[simp]
28492850
public theorem length_toList [LE α] [DecidableLE α] [UpwardEnumerable α]
28502851
[Rxc.HasSize α] [LawfulUpwardEnumerable α] [LawfulUpwardEnumerableLE α]
28512852
[Rxc.IsAlwaysFinite α] [Rxc.LawfulHasSize α] :
@@ -2864,6 +2865,7 @@ public theorem length_toList [LE α] [DecidableLE α] [UpwardEnumerable α]
28642865
simp [h, ← ih _ h]
28652866
· simp
28662867

2868+
@[simp]
28672869
public theorem size_toArray [LE α] [DecidableLE α] [UpwardEnumerable α]
28682870
[Rxc.HasSize α] [LawfulUpwardEnumerable α] [LawfulUpwardEnumerableLE α]
28692871
[Rxc.IsAlwaysFinite α] [Rxc.LawfulHasSize α] :
@@ -2988,13 +2990,15 @@ public theorem size_eq_match_roc [LE α] [DecidableLE α] [UpwardEnumerable α]
29882990
rw [size_eq_match_rcc]
29892991
simp [Rcc.size_eq_if_roc]
29902992

2993+
@[simp]
29912994
public theorem length_toList [LE α] [DecidableLE α] [UpwardEnumerable α]
29922995
[Rxc.HasSize α] [LawfulUpwardEnumerable α] [LawfulUpwardEnumerableLE α]
29932996
[Rxc.IsAlwaysFinite α] [Rxc.LawfulHasSize α] :
29942997
r.toList.length = r.size := by
29952998
simp only [toList_eq_match_rcc, size_eq_match_rcc]
29962999
split <;> simp [Rcc.length_toList]
29973000

3001+
@[simp]
29983002
public theorem size_toArray [LE α] [DecidableLE α] [UpwardEnumerable α]
29993003
[Rxc.HasSize α] [LawfulUpwardEnumerable α] [LawfulUpwardEnumerableLE α]
30003004
[Rxc.IsAlwaysFinite α] [Rxc.LawfulHasSize α] :
@@ -3094,13 +3098,15 @@ public theorem size_eq_match_roc [Least? α] [LE α] [DecidableLE α] [UpwardEnu
30943098
rw [size_eq_match_rcc]
30953099
simp [Rcc.size_eq_if_roc]
30963100

3101+
@[simp]
30973102
public theorem length_toList [Least? α] [LE α] [DecidableLE α] [UpwardEnumerable α]
30983103
[Rxc.HasSize α] [LawfulUpwardEnumerable α] [LawfulUpwardEnumerableLE α]
30993104
[Rxc.IsAlwaysFinite α] [Rxc.LawfulHasSize α] :
31003105
r.toList.length = r.size := by
31013106
rw [toList_eq_match_rcc, size_eq_match_rcc]
31023107
split <;> simp [Rcc.length_toList]
31033108

3109+
@[simp]
31043110
public theorem size_toArray [Least? α] [LE α] [DecidableLE α] [UpwardEnumerable α]
31053111
[Rxc.HasSize α] [LawfulUpwardEnumerable α] [LawfulUpwardEnumerableLE α]
31063112
[Rxc.IsAlwaysFinite α] [Rxc.LawfulHasSize α] :
@@ -3223,6 +3229,7 @@ public theorem size_eq_if_rcc [LT α] [DecidableLT α] [UpwardEnumerable α]
32233229
· split <;> simp [*]
32243230
· rfl
32253231

3232+
@[simp]
32263233
public theorem length_toList [LT α] [DecidableLT α] [UpwardEnumerable α]
32273234
[Rxo.HasSize α] [LawfulUpwardEnumerable α] [LawfulUpwardEnumerableLT α]
32283235
[Rxo.IsAlwaysFinite α] [Rxo.LawfulHasSize α] :
@@ -3241,6 +3248,7 @@ public theorem length_toList [LT α] [DecidableLT α] [UpwardEnumerable α]
32413248
simp [h, ← ih _ h]
32423249
· simp
32433250

3251+
@[simp]
32443252
public theorem size_toArray [LT α] [DecidableLT α] [UpwardEnumerable α]
32453253
[Rxo.HasSize α] [LawfulUpwardEnumerable α] [LawfulUpwardEnumerableLT α]
32463254
[Rxo.IsAlwaysFinite α] [Rxo.LawfulHasSize α] :
@@ -3366,13 +3374,15 @@ public theorem size_eq_match_roc [LT α] [DecidableLT α] [UpwardEnumerable α]
33663374
rw [size_eq_match_rcc]
33673375
simp [Rco.size_eq_if_roo]
33683376

3377+
@[simp]
33693378
public theorem length_toList [LT α] [DecidableLT α] [UpwardEnumerable α]
33703379
[Rxo.HasSize α] [LawfulUpwardEnumerable α] [LawfulUpwardEnumerableLT α]
33713380
[Rxo.IsAlwaysFinite α] [Rxo.LawfulHasSize α] :
33723381
r.toList.length = r.size := by
33733382
simp only [toList_eq_match_rco, size_eq_match_rcc]
33743383
split <;> simp [Rco.length_toList]
33753384

3385+
@[simp]
33763386
public theorem size_toArray [LT α] [DecidableLT α] [UpwardEnumerable α]
33773387
[Rxo.HasSize α] [LawfulUpwardEnumerable α] [LawfulUpwardEnumerableLT α]
33783388
[Rxo.IsAlwaysFinite α] [Rxo.LawfulHasSize α] :
@@ -3472,13 +3482,15 @@ public theorem size_eq_match_roc [Least? α] [LT α] [DecidableLT α] [UpwardEnu
34723482
rw [size_eq_match_rcc]
34733483
simp [Rco.size_eq_if_roo]
34743484

3485+
@[simp]
34753486
public theorem length_toList [Least? α] [LT α] [DecidableLT α] [UpwardEnumerable α]
34763487
[Rxo.HasSize α] [LawfulUpwardEnumerable α] [LawfulUpwardEnumerableLT α]
34773488
[Rxo.IsAlwaysFinite α] [Rxo.LawfulHasSize α] :
34783489
r.toList.length = r.size := by
34793490
rw [toList_eq_match_rco, size_eq_match_rcc]
34803491
split <;> simp [Rco.length_toList]
34813492

3493+
@[simp]
34823494
public theorem size_toArray [Least? α] [LT α] [DecidableLT α] [UpwardEnumerable α]
34833495
[Rxo.HasSize α] [LawfulUpwardEnumerable α] [LawfulUpwardEnumerableLT α]
34843496
[Rxo.IsAlwaysFinite α] [Rxo.LawfulHasSize α] :
@@ -3590,6 +3602,7 @@ public theorem size_eq_match_rci [UpwardEnumerable α] [Rxi.HasSize α] [LawfulU
35903602
simp only [Rci.size]
35913603
split <;> simp [*]
35923604

3605+
@[simp]
35933606
public theorem length_toList [UpwardEnumerable α] [Rxi.HasSize α] [LawfulUpwardEnumerable α]
35943607
[Rxi.IsAlwaysFinite α] [Rxi.LawfulHasSize α] :
35953608
r.toList.length = r.size := by
@@ -3605,6 +3618,7 @@ public theorem length_toList [UpwardEnumerable α] [Rxi.HasSize α] [LawfulUpwar
36053618
· simp only [Nat.add_right_cancel_iff, *] at h
36063619
simp [ih _ h, h]
36073620

3621+
@[simp]
36083622
public theorem size_toArray [UpwardEnumerable α] [Rxi.HasSize α] [LawfulUpwardEnumerable α]
36093623
[Rxi.IsAlwaysFinite α] [Rxi.LawfulHasSize α] :
36103624
r.toArray.size = r.size := by
@@ -3711,12 +3725,14 @@ public theorem size_eq_match_roi [UpwardEnumerable α] [Rxi.HasSize α] [LawfulU
37113725
rw [size_eq_match_rci]
37123726
simp [Rci.size_eq_size_roi]
37133727

3728+
@[simp]
37143729
public theorem length_toList [UpwardEnumerable α] [Rxi.HasSize α] [LawfulUpwardEnumerable α]
37153730
[Rxi.IsAlwaysFinite α] [Rxi.LawfulHasSize α] :
37163731
r.toList.length = r.size := by
37173732
simp only [toList_eq_match_rci, size_eq_match_rci]
37183733
split <;> simp [Rci.length_toList]
37193734

3735+
@[simp]
37203736
public theorem size_toArray [UpwardEnumerable α] [Rxi.HasSize α] [LawfulUpwardEnumerable α]
37213737
[Rxi.IsAlwaysFinite α] [Rxi.LawfulHasSize α] :
37223738
r.toArray.size = r.size := by
@@ -3809,13 +3825,15 @@ public theorem size_eq_match_roi [Least? α] [UpwardEnumerable α] [Rxi.HasSize
38093825
rw [size_eq_match_rci]
38103826
simp [Rci.size_eq_size_roi]
38113827

3828+
@[simp]
38123829
public theorem length_toList [Least? α] [UpwardEnumerable α]
38133830
[Rxi.HasSize α] [LawfulUpwardEnumerable α]
38143831
[Rxi.IsAlwaysFinite α] [Rxi.LawfulHasSize α] :
38153832
r.toList.length = r.size := by
38163833
rw [toList_eq_match_rci, size_eq_match_rci]
38173834
split <;> simp [Rci.length_toList]
38183835

3836+
@[simp]
38193837
public theorem size_toArray [Least? α] [UpwardEnumerable α]
38203838
[Rxi.HasSize α] [LawfulUpwardEnumerable α]
38213839
[Rxi.IsAlwaysFinite α] [Rxi.LawfulHasSize α] :

src/Init/Data/Slice/Array/Basic.lean

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,45 +23,82 @@ variable {α : Type u}
2323

2424
instance : Rcc.Sliceable (Array α) Nat (Subarray α) where
2525
mkSlice xs range :=
26-
let halfOpenRange := Rcc.HasRcoIntersection.intersection range 0...<xs.size
27-
(xs.toSubarray halfOpenRange.lower halfOpenRange.upper)
26+
xs.toSubarray range.lower (range.upper + 1)
2827

2928
instance : Rco.Sliceable (Array α) Nat (Subarray α) where
3029
mkSlice xs range :=
31-
let halfOpenRange := Rco.HasRcoIntersection.intersection range 0...<xs.size
32-
(xs.toSubarray halfOpenRange.lower halfOpenRange.upper)
30+
xs.toSubarray range.lower range.upper
3331

3432
instance : Rci.Sliceable (Array α) Nat (Subarray α) where
3533
mkSlice xs range :=
3634
let halfOpenRange := Rci.HasRcoIntersection.intersection range 0...<xs.size
37-
(xs.toSubarray halfOpenRange.lower halfOpenRange.upper)
35+
xs.toSubarray halfOpenRange.lower halfOpenRange.upper
3836

3937
instance : Roc.Sliceable (Array α) Nat (Subarray α) where
4038
mkSlice xs range :=
41-
let halfOpenRange := Roc.HasRcoIntersection.intersection range 0...<xs.size
42-
(xs.toSubarray halfOpenRange.lower halfOpenRange.upper)
39+
xs.toSubarray (range.lower + 1) (range.upper + 1)
4340

4441
instance : Roo.Sliceable (Array α) Nat (Subarray α) where
4542
mkSlice xs range :=
46-
let halfOpenRange := Roo.HasRcoIntersection.intersection range 0...<xs.size
47-
(xs.toSubarray halfOpenRange.lower halfOpenRange.upper)
43+
xs.toSubarray (range.lower + 1) range.upper
4844

4945
instance : Roi.Sliceable (Array α) Nat (Subarray α) where
5046
mkSlice xs range :=
5147
let halfOpenRange := Roi.HasRcoIntersection.intersection range 0...<xs.size
52-
(xs.toSubarray halfOpenRange.lower halfOpenRange.upper)
48+
xs.toSubarray halfOpenRange.lower halfOpenRange.upper
5349

5450
instance : Ric.Sliceable (Array α) Nat (Subarray α) where
5551
mkSlice xs range :=
56-
let halfOpenRange := Ric.HasRcoIntersection.intersection range 0...<xs.size
57-
(xs.toSubarray halfOpenRange.lower halfOpenRange.upper)
52+
xs.toSubarray 0 (range.upper + 1)
5853

5954
instance : Rio.Sliceable (Array α) Nat (Subarray α) where
6055
mkSlice xs range :=
61-
let halfOpenRange := Rio.HasRcoIntersection.intersection range 0...<xs.size
62-
(xs.toSubarray halfOpenRange.lower halfOpenRange.upper)
56+
xs.toSubarray 0 range.upper
6357

6458
instance : Rii.Sliceable (Array α) Nat (Subarray α) where
6559
mkSlice xs _ :=
66-
let halfOpenRange := 0...<xs.size
67-
(xs.toSubarray halfOpenRange.lower halfOpenRange.upper)
60+
xs.toSubarray 0 xs.size
61+
62+
instance : Rcc.Sliceable (Subarray α) Nat (Subarray α) where
63+
mkSlice xs range :=
64+
let halfOpenRange := Rcc.HasRcoIntersection.intersection range 0...<xs.size
65+
xs.array[(halfOpenRange.lower + xs.start)...(halfOpenRange.upper + xs.start)]
66+
67+
instance : Rco.Sliceable (Subarray α) Nat (Subarray α) where
68+
mkSlice xs range :=
69+
let halfOpenRange := Rco.HasRcoIntersection.intersection range 0...<xs.size
70+
xs.array[(halfOpenRange.lower + xs.start)...(halfOpenRange.upper + xs.start)]
71+
72+
instance : Rci.Sliceable (Subarray α) Nat (Subarray α) where
73+
mkSlice xs range :=
74+
let halfOpenRange := Rci.HasRcoIntersection.intersection range 0...<xs.size
75+
xs.array[(halfOpenRange.lower + xs.start)...(halfOpenRange.upper + xs.start)]
76+
77+
instance : Roc.Sliceable (Subarray α) Nat (Subarray α) where
78+
mkSlice xs range :=
79+
let halfOpenRange := Roc.HasRcoIntersection.intersection range 0...<xs.size
80+
xs.array[(halfOpenRange.lower + xs.start)...(halfOpenRange.upper + xs.start)]
81+
82+
instance : Roo.Sliceable (Subarray α) Nat (Subarray α) where
83+
mkSlice xs range :=
84+
let halfOpenRange := Roo.HasRcoIntersection.intersection range 0...<xs.size
85+
xs.array[(halfOpenRange.lower + xs.start)...(halfOpenRange.upper + xs.start)]
86+
87+
instance : Roi.Sliceable (Subarray α) Nat (Subarray α) where
88+
mkSlice xs range :=
89+
let halfOpenRange := Roi.HasRcoIntersection.intersection range 0...<xs.size
90+
xs.array[(halfOpenRange.lower + xs.start)...(halfOpenRange.upper + xs.start)]
91+
92+
instance : Ric.Sliceable (Subarray α) Nat (Subarray α) where
93+
mkSlice xs range :=
94+
let halfOpenRange := Ric.HasRcoIntersection.intersection range 0...<xs.size
95+
xs.array[(halfOpenRange.lower + xs.start)...(halfOpenRange.upper + xs.start)]
96+
97+
instance : Rio.Sliceable (Subarray α) Nat (Subarray α) where
98+
mkSlice xs range :=
99+
let halfOpenRange := Rio.HasRcoIntersection.intersection range 0...<xs.size
100+
xs.array[(halfOpenRange.lower + xs.start)...(halfOpenRange.upper + xs.start)]
101+
102+
instance : Rii.Sliceable (Subarray α) Nat (Subarray α) where
103+
mkSlice xs _ :=
104+
xs

0 commit comments

Comments
 (0)