Skip to content

Commit 2cddf23

Browse files
authored
feat: grind annotations for List/Array/Vector.mapIdx theorems (#8748)
This PR adds grind annotations for `Array/Vector.mapIdx` and `mapFinIdx` theorems. The annotations are added to theorems that correspond to those already annotated in the List implementation, ensuring consistency across all three container types (List, Array, Vector) for indexed mapping operations. Key theorems annotated include: - Size and element access theorems (`size_mapIdx`, `getElem_mapIdx`, `getElem?_mapIdx`) - Construction theorems (`mapIdx_empty`, `mapIdx_push`, `mapIdx_append`) - Membership and equality theorems (`mem_mapIdx`, `mapIdx_mapIdx`) - Conversion theorems (`toList_mapIdx`, `mapIdx_toArray`, etc.) - Reverse and composition operations - Similar annotations for `mapFinIdx` variants
1 parent 75fe50a commit 2cddf23

File tree

3 files changed

+76
-70
lines changed

3 files changed

+76
-70
lines changed

src/Init/Data/Array/MapIdx.lean

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -51,27 +51,27 @@ theorem mapFinIdx_spec {xs : Array α} {f : (i : Nat) → α → (h : i < xs.siz
5151
∀ i h, p i ((Array.mapFinIdx xs f)[i]) h :=
5252
(mapFinIdx_induction _ _ (fun _ => True) trivial p fun _ _ _ => ⟨hs .., trivial⟩).2
5353

54-
@[simp] theorem size_mapFinIdx {xs : Array α} {f : (i : Nat) → α → (h : i < xs.size) → β} :
54+
@[simp, grind =] theorem size_mapFinIdx {xs : Array α} {f : (i : Nat) → α → (h : i < xs.size) → β} :
5555
(xs.mapFinIdx f).size = xs.size :=
5656
(mapFinIdx_spec (p := fun _ _ _ => True) (hs := fun _ _ => trivial)).1
5757

58-
@[simp] theorem size_zipIdx {xs : Array α} {k : Nat} : (xs.zipIdx k).size = xs.size :=
58+
@[simp, grind =] theorem size_zipIdx {xs : Array α} {k : Nat} : (xs.zipIdx k).size = xs.size :=
5959
Array.size_mapFinIdx
6060

6161
@[deprecated size_zipIdx (since := "2025-01-21")] abbrev size_zipWithIndex := @size_zipIdx
6262

63-
@[simp] theorem getElem_mapFinIdx {xs : Array α} {f : (i : Nat) → α → (h : i < xs.size) → β} {i : Nat}
63+
@[simp, grind =] theorem getElem_mapFinIdx {xs : Array α} {f : (i : Nat) → α → (h : i < xs.size) → β} {i : Nat}
6464
(h : i < (xs.mapFinIdx f).size) :
6565
(xs.mapFinIdx f)[i] = f i (xs[i]'(by simp_all)) (by simp_all) :=
6666
(mapFinIdx_spec (p := fun i b h => b = f i xs[i] h) fun _ _ => rfl).2 i _
6767

68-
@[simp] theorem getElem?_mapFinIdx {xs : Array α} {f : (i : Nat) → α → (h : i < xs.size) → β} {i : Nat} :
68+
@[simp, grind =] theorem getElem?_mapFinIdx {xs : Array α} {f : (i : Nat) → α → (h : i < xs.size) → β} {i : Nat} :
6969
(xs.mapFinIdx f)[i]? =
7070
xs[i]?.pbind fun b h => some <| f i b (getElem?_eq_some_iff.1 h).1 := by
7171
simp only [getElem?_def, size_mapFinIdx, getElem_mapFinIdx]
7272
split <;> simp_all
7373

74-
@[simp] theorem toList_mapFinIdx {xs : Array α} {f : (i : Nat) → α → (h : i < xs.size) → β} :
74+
@[simp, grind =] theorem toList_mapFinIdx {xs : Array α} {f : (i : Nat) → α → (h : i < xs.size) → β} :
7575
(xs.mapFinIdx f).toList = xs.toList.mapFinIdx (fun i a h => f i a (by simpa)) := by
7676
apply List.ext_getElem <;> simp
7777

@@ -91,20 +91,20 @@ theorem mapIdx_spec {f : Nat → α → β} {xs : Array α}
9191
∀ i h, p i ((xs.mapIdx f)[i]) h :=
9292
(mapIdx_induction (motive := fun _ => True) trivial fun _ _ _ => ⟨hs .., trivial⟩).2
9393

94-
@[simp] theorem size_mapIdx {f : Nat → α → β} {xs : Array α} : (xs.mapIdx f).size = xs.size :=
94+
@[simp, grind =] theorem size_mapIdx {f : Nat → α → β} {xs : Array α} : (xs.mapIdx f).size = xs.size :=
9595
(mapIdx_spec (p := fun _ _ _ => True) (hs := fun _ _ => trivial)).1
9696

97-
@[simp] theorem getElem_mapIdx {f : Nat → α → β} {xs : Array α} {i : Nat}
97+
@[simp, grind =] theorem getElem_mapIdx {f : Nat → α → β} {xs : Array α} {i : Nat}
9898
(h : i < (xs.mapIdx f).size) :
9999
(xs.mapIdx f)[i] = f i (xs[i]'(by simp_all)) :=
100100
(mapIdx_spec (p := fun i b h => b = f i xs[i]) fun _ _ => rfl).2 i (by simp_all)
101101

102-
@[simp] theorem getElem?_mapIdx {f : Nat → α → β} {xs : Array α} {i : Nat} :
102+
@[simp, grind =] theorem getElem?_mapIdx {f : Nat → α → β} {xs : Array α} {i : Nat} :
103103
(xs.mapIdx f)[i]? =
104104
xs[i]?.map (f i) := by
105105
simp [getElem?_def, size_mapIdx, getElem_mapIdx]
106106

107-
@[simp] theorem toList_mapIdx {f : Nat → α → β} {xs : Array α} :
107+
@[simp, grind =] theorem toList_mapIdx {f : Nat → α → β} {xs : Array α} :
108108
(xs.mapIdx f).toList = xs.toList.mapIdx (fun i a => f i a) := by
109109
apply List.ext_getElem <;> simp
110110

@@ -126,7 +126,7 @@ namespace Array
126126

127127
/-! ### zipIdx -/
128128

129-
@[simp] theorem getElem_zipIdx {xs : Array α} {k : Nat} {i : Nat} (h : i < (xs.zipIdx k).size) :
129+
@[simp, grind =] theorem getElem_zipIdx {xs : Array α} {k : Nat} {i : Nat} (h : i < (xs.zipIdx k).size) :
130130
(xs.zipIdx k)[i] = (xs[i]'(by simp_all), k + i) := by
131131
simp [zipIdx]
132132

@@ -140,7 +140,7 @@ abbrev getElem_zipWithIndex := @getElem_zipIdx
140140
@[deprecated zipIdx_toArray (since := "2025-01-21")]
141141
abbrev zipWithIndex_toArray := @zipIdx_toArray
142142

143-
@[simp] theorem toList_zipIdx {xs : Array α} {k : Nat} :
143+
@[simp, grind =] theorem toList_zipIdx {xs : Array α} {k : Nat} :
144144
(xs.zipIdx k).toList = xs.toList.zipIdx k := by
145145
rcases xs with ⟨xs⟩
146146
simp
@@ -185,7 +185,7 @@ abbrev mem_zipWithIndex_iff_getElem? := @mem_zipIdx_iff_getElem?
185185
subst w
186186
rfl
187187

188-
@[simp]
188+
@[simp, grind =]
189189
theorem mapFinIdx_empty {f : (i : Nat) → α → (h : i < 0) → β} : mapFinIdx #[] f = #[] :=
190190
rfl
191191

@@ -195,6 +195,7 @@ theorem mapFinIdx_eq_ofFn {xs : Array α} {f : (i : Nat) → α → (h : i < xs.
195195
simp only [List.mapFinIdx_toArray, List.mapFinIdx_eq_ofFn, Fin.getElem_fin, List.getElem_toArray]
196196
simp [Array.size]
197197

198+
@[grind =]
198199
theorem mapFinIdx_append {xs ys : Array α} {f : (i : Nat) → α → (h : i < (xs ++ ys).size) → β} :
199200
(xs ++ ys).mapFinIdx f =
200201
xs.mapFinIdx (fun i a h => f i a (by simp; omega)) ++
@@ -203,7 +204,7 @@ theorem mapFinIdx_append {xs ys : Array α} {f : (i : Nat) → α → (h : i < (
203204
cases ys
204205
simp [List.mapFinIdx_append, Array.size]
205206

206-
@[simp]
207+
@[simp, grind =]
207208
theorem mapFinIdx_push {xs : Array α} {a : α} {f : (i : Nat) → α → (h : i < (xs.push a).size) → β} :
208209
mapFinIdx (xs.push a) f =
209210
(mapFinIdx xs (fun i a h => f i a (by simp; omega))).push (f xs.size a (by simp)) := by
@@ -237,7 +238,7 @@ theorem exists_of_mem_mapFinIdx {b : β} {xs : Array α} {f : (i : Nat) → α
237238
rcases xs with ⟨xs⟩
238239
exact List.exists_of_mem_mapFinIdx (by simpa using h)
239240

240-
@[simp] theorem mem_mapFinIdx {b : β} {xs : Array α} {f : (i : Nat) → α → (h : i < xs.size) → β} :
241+
@[simp, grind =] theorem mem_mapFinIdx {b : β} {xs : Array α} {f : (i : Nat) → α → (h : i < xs.size) → β} :
241242
b ∈ xs.mapFinIdx f ↔ ∃ (i : Nat) (h : i < xs.size), f i xs[i] h = b := by
242243
rcases xs with ⟨xs⟩
243244
simp
@@ -290,7 +291,7 @@ theorem mapFinIdx_eq_mapFinIdx_iff {xs : Array α} {f g : (i : Nat) → α → (
290291
rw [eq_comm, mapFinIdx_eq_iff]
291292
simp
292293

293-
@[simp] theorem mapFinIdx_mapFinIdx {xs : Array α}
294+
@[simp, grind =] theorem mapFinIdx_mapFinIdx {xs : Array α}
294295
{f : (i : Nat) → α → (h : i < xs.size) → β}
295296
{g : (i : Nat) → β → (h : i < (xs.mapFinIdx f).size) → γ} :
296297
(xs.mapFinIdx f).mapFinIdx g = xs.mapFinIdx (fun i a h => g i (f i a h) (by simpa using h)) := by
@@ -305,14 +306,14 @@ theorem mapFinIdx_eq_replicate_iff {xs : Array α} {f : (i : Nat) → α → (h
305306
@[deprecated mapFinIdx_eq_replicate_iff (since := "2025-03-18")]
306307
abbrev mapFinIdx_eq_mkArray_iff := @mapFinIdx_eq_replicate_iff
307308

308-
@[simp] theorem mapFinIdx_reverse {xs : Array α} {f : (i : Nat) → α → (h : i < xs.reverse.size) → β} :
309+
@[simp, grind =] theorem mapFinIdx_reverse {xs : Array α} {f : (i : Nat) → α → (h : i < xs.reverse.size) → β} :
309310
xs.reverse.mapFinIdx f = (xs.mapFinIdx (fun i a h => f (xs.size - 1 - i) a (by simp; omega))).reverse := by
310311
rcases xs with ⟨l⟩
311312
simp [List.mapFinIdx_reverse, Array.size]
312313

313314
/-! ### mapIdx -/
314315

315-
@[simp]
316+
@[simp, grind =]
316317
theorem mapIdx_empty {f : Nat → α → β} : mapIdx f #[] = #[] :=
317318
rfl
318319

@@ -332,13 +333,14 @@ theorem mapIdx_eq_zipIdx_map {xs : Array α} {f : Nat → α → β} :
332333
@[deprecated mapIdx_eq_zipIdx_map (since := "2025-01-21")]
333334
abbrev mapIdx_eq_zipWithIndex_map := @mapIdx_eq_zipIdx_map
334335

336+
@[grind =]
335337
theorem mapIdx_append {xs ys : Array α} :
336338
(xs ++ ys).mapIdx f = xs.mapIdx f ++ ys.mapIdx (fun i => f (i + xs.size)) := by
337339
rcases xs with ⟨xs⟩
338340
rcases ys with ⟨ys⟩
339341
simp [List.mapIdx_append]
340342

341-
@[simp]
343+
@[simp, grind =]
342344
theorem mapIdx_push {xs : Array α} {a : α} :
343345
mapIdx f (xs.push a) = (mapIdx f xs).push (f xs.size a) := by
344346
simp [← append_singleton, mapIdx_append]
@@ -360,7 +362,7 @@ theorem exists_of_mem_mapIdx {b : β} {xs : Array α}
360362
rw [mapIdx_eq_mapFinIdx] at h
361363
simpa [Fin.exists_iff] using exists_of_mem_mapFinIdx h
362364

363-
@[simp] theorem mem_mapIdx {b : β} {xs : Array α} :
365+
@[simp, grind =] theorem mem_mapIdx {b : β} {xs : Array α} :
364366
b ∈ mapIdx f xs ↔ ∃ (i : Nat) (h : i < xs.size), f i xs[i] = b := by
365367
constructor
366368
· intro h
@@ -414,7 +416,7 @@ theorem mapIdx_eq_mapIdx_iff {xs : Array α} :
414416
rcases xs with ⟨xs⟩
415417
simp [List.mapIdx_eq_mapIdx_iff]
416418

417-
@[simp] theorem mapIdx_set {f : Nat → α → β} {xs : Array α} {i : Nat} {h : i < xs.size} {a : α} :
419+
@[simp, grind =] theorem mapIdx_set {f : Nat → α → β} {xs : Array α} {i : Nat} {h : i < xs.size} {a : α} :
418420
(xs.set i a).mapIdx f = (xs.mapIdx f).set i (f i a) (by simpa) := by
419421
rcases xs with ⟨xs⟩
420422
simp [List.mapIdx_set]
@@ -424,17 +426,17 @@ theorem mapIdx_eq_mapIdx_iff {xs : Array α} :
424426
rcases xs with ⟨xs⟩
425427
simp [List.mapIdx_set]
426428

427-
@[simp] theorem back?_mapIdx {xs : Array α} {f : Nat → α → β} :
429+
@[simp, grind =] theorem back?_mapIdx {xs : Array α} {f : Nat → α → β} :
428430
(mapIdx f xs).back? = (xs.back?).map (f (xs.size - 1)) := by
429431
rcases xs with ⟨xs⟩
430432
simp [List.getLast?_mapIdx]
431433

432-
@[simp] theorem back_mapIdx {xs : Array α} {f : Nat → α → β} (h) :
434+
@[simp, grind =] theorem back_mapIdx {xs : Array α} {f : Nat → α → β} (h) :
433435
(xs.mapIdx f).back h = f (xs.size - 1) (xs.back (by simpa using h)) := by
434436
rcases xs with ⟨xs⟩
435437
simp [List.getLast_mapIdx]
436438

437-
@[simp] theorem mapIdx_mapIdx {xs : Array α} {f : Nat → α → β} {g : Nat → β → γ} :
439+
@[simp, grind =] theorem mapIdx_mapIdx {xs : Array α} {f : Nat → α → β} {g : Nat → β → γ} :
438440
(xs.mapIdx f).mapIdx g = xs.mapIdx (fun i => g i ∘ f i) := by
439441
simp [mapIdx_eq_iff]
440442

@@ -447,7 +449,7 @@ theorem mapIdx_eq_replicate_iff {xs : Array α} {f : Nat → α → β} {b : β}
447449
@[deprecated mapIdx_eq_replicate_iff (since := "2025-03-18")]
448450
abbrev mapIdx_eq_mkArray_iff := @mapIdx_eq_replicate_iff
449451

450-
@[simp] theorem mapIdx_reverse {xs : Array α} {f : Nat → α → β} :
452+
@[simp, grind =] theorem mapIdx_reverse {xs : Array α} {f : Nat → α → β} :
451453
xs.reverse.mapIdx f = (mapIdx (fun i => f (xs.size - 1 - i)) xs).reverse := by
452454
rcases xs with ⟨xs⟩
453455
simp [List.mapIdx_reverse]
@@ -456,7 +458,7 @@ end Array
456458

457459
namespace List
458460

459-
@[grind] theorem mapFinIdxM_toArray [Monad m] [LawfulMonad m] {l : List α}
461+
@[grind =] theorem mapFinIdxM_toArray [Monad m] [LawfulMonad m] {l : List α}
460462
{f : (i : Nat) → α → (h : i < l.length) → m β} :
461463
l.toArray.mapFinIdxM f = toArray <$> l.mapFinIdxM f := by
462464
let rec go (i : Nat) (acc : Array β) (inv : i + acc.size = l.length) :
@@ -477,7 +479,7 @@ namespace List
477479
simp only [Array.mapFinIdxM, mapFinIdxM]
478480
exact go _ #[] _
479481

480-
@[grind] theorem mapIdxM_toArray [Monad m] [LawfulMonad m] {l : List α}
482+
@[grind =] theorem mapIdxM_toArray [Monad m] [LawfulMonad m] {l : List α}
481483
{f : Nat → α → m β} :
482484
l.toArray.mapIdxM f = toArray <$> l.mapIdxM f := by
483485
let rec go (bs : List α) (acc : Array β) (inv : bs.length + acc.size = l.length) :

0 commit comments

Comments
 (0)