Skip to content

Commit 3dd12f8

Browse files
authored
feat: further @[grind] annotations for Option (#8460)
This PR adds further `@[grind]` annotations for `Option`, as follow-up to the recent additions to the `Option` API in #8379 and #8298. **However**, I am concurrently investigating adding `attribute [grind cases] Option`, which will result in many (most?) of the annotations for `Option` being removed again. In any case, I'm going to merge this first, as if that is viable I would like to test that most/all the lemmas now marked with `@[grind]` are still provable by `grind`.
1 parent 0f8618f commit 3dd12f8

File tree

7 files changed

+187
-100
lines changed

7 files changed

+187
-100
lines changed

src/Init/Data/Option/Array.lean

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ namespace Option
3939
o.toArray.foldr f a = o.elim a (fun b => f b a) := by
4040
cases o <;> simp
4141

42-
@[simp]
42+
@[simp, grind =]
4343
theorem toList_toArray {o : Option α} : o.toArray.toList = o.toList := by
4444
cases o <;> simp
4545

46-
@[simp]
46+
@[simp, grind =]
4747
theorem toArray_toList {o : Option α} : o.toList.toArray = o.toArray := by
4848
cases o <;> simp
4949

@@ -69,7 +69,8 @@ theorem toArray_min [Min α] {o o' : Option α} :
6969
theorem size_toArray_le {o : Option α} : o.toArray.size ≤ 1 := by
7070
cases o <;> simp
7171

72-
theorem size_toArray_eq_ite {o : Option α} :
72+
@[grind =]
73+
theorem size_toArray {o : Option α} :
7374
o.toArray.size = if o.isSome then 1 else 0 := by
7475
cases o <;> simp
7576

src/Init/Data/Option/Attach.lean

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@ terminates.
5151
-/
5252
@[inline] def attach (xs : Option α) : Option {x // xs = some x} := xs.attachWith _ fun _ => id
5353

54-
@[simp] theorem attach_none : (none : Option α).attach = none := rfl
55-
@[simp] theorem attachWith_none : (none : Option α).attachWith P H = none := rfl
54+
@[simp, grind =] theorem attach_none : (none : Option α).attach = none := rfl
55+
@[simp, grind =] theorem attachWith_none : (none : Option α).attachWith P H = none := rfl
5656

57-
@[simp] theorem attach_some {x : α} :
57+
@[simp, grind =] theorem attach_some {x : α} :
5858
(some x).attach = some ⟨x, rfl⟩ := rfl
59-
@[simp] theorem attachWith_some {x : α} {P : α → Prop} (h : ∀ (b : α), some x = some b → P b) :
59+
@[simp, grind =] theorem attachWith_some {x : α} {P : α → Prop} (h : ∀ (b : α), some x = some b → P b) :
6060
(some x).attachWith P h = some ⟨x, by simpa using h⟩ := rfl
6161

6262
theorem attach_congr {o₁ o₂ : Option α} (h : o₁ = o₂) :
@@ -76,7 +76,7 @@ theorem attach_map_val (o : Option α) (f : α → β) :
7676
@[deprecated attach_map_val (since := "2025-02-17")]
7777
abbrev attach_map_coe := @attach_map_val
7878

79-
theorem attach_map_subtype_val (o : Option α) :
79+
@[simp, grind =]theorem attach_map_subtype_val (o : Option α) :
8080
o.attach.map Subtype.val = o :=
8181
(attach_map_val _ _).trans (congrFun Option.map_id _)
8282

@@ -87,7 +87,7 @@ theorem attachWith_map_val {p : α → Prop} (f : α → β) (o : Option α) (H
8787
@[deprecated attachWith_map_val (since := "2025-02-17")]
8888
abbrev attachWith_map_coe := @attachWith_map_val
8989

90-
theorem attachWith_map_subtype_val {p : α → Prop} (o : Option α) (H : ∀ a, o = some a → p a) :
90+
@[simp, grind =] theorem attachWith_map_subtype_val {p : α → Prop} (o : Option α) (H : ∀ a, o = some a → p a) :
9191
(o.attachWith p H).map Subtype.val = o :=
9292
(attachWith_map_val _ _ _).trans (congrFun Option.map_id _)
9393

@@ -98,17 +98,17 @@ theorem attach_eq_some : ∀ (o : Option α) (x : {x // o = some x}), o.attach =
9898
theorem mem_attach : ∀ (o : Option α) (x : {x // o = some x}), x ∈ o.attach :=
9999
attach_eq_some
100100

101-
@[simp] theorem isNone_attach (o : Option α) : o.attach.isNone = o.isNone := by
101+
@[simp, grind =] theorem isNone_attach (o : Option α) : o.attach.isNone = o.isNone := by
102102
cases o <;> simp
103103

104-
@[simp] theorem isNone_attachWith {p : α → Prop} (o : Option α) (H : ∀ a, o = some a → p a) :
104+
@[simp, grind =] theorem isNone_attachWith {p : α → Prop} (o : Option α) (H : ∀ a, o = some a → p a) :
105105
(o.attachWith p H).isNone = o.isNone := by
106106
cases o <;> simp
107107

108-
@[simp] theorem isSome_attach (o : Option α) : o.attach.isSome = o.isSome := by
108+
@[simp, grind =] theorem isSome_attach (o : Option α) : o.attach.isSome = o.isSome := by
109109
cases o <;> simp
110110

111-
@[simp] theorem isSome_attachWith {p : α → Prop} (o : Option α) (H : ∀ a, o = some a → p a) :
111+
@[simp, grind =] theorem isSome_attachWith {p : α → Prop} (o : Option α) (H : ∀ a, o = some a → p a) :
112112
(o.attachWith p H).isSome = o.isSome := by
113113
cases o <;> simp
114114

@@ -127,25 +127,28 @@ theorem mem_attach : ∀ (o : Option α) (x : {x // o = some x}), x ∈ o.attach
127127
o.attachWith p H = some x ↔ o = some x.val := by
128128
cases o <;> cases x <;> simp
129129

130-
@[simp] theorem get_attach {o : Option α} (h : o.attach.isSome = true) :
130+
@[simp, grind =] theorem get_attach {o : Option α} (h : o.attach.isSome = true) :
131131
o.attach.get h = ⟨o.get (by simpa using h), by simp⟩ :=
132132
Subsingleton.elim _ _
133133

134-
@[simp] theorem getD_attach {o : Option α} {fallback} :
134+
@[simp, grind =] theorem getD_attach {o : Option α} {fallback} :
135135
o.attach.getD fallback = fallback :=
136136
Subsingleton.elim _ _
137137

138-
@[simp] theorem get!_attach {o : Option α} [Inhabited { x // o = some x }] :
138+
@[simp, grind =] theorem get!_attach {o : Option α} [Inhabited { x // o = some x }] :
139139
o.attach.get! = default :=
140140
Subsingleton.elim _ _
141141

142-
@[simp] theorem get_attachWith {p : α → Prop} {o : Option α} (H : ∀ a, o = some a → p a) (h : (o.attachWith p H).isSome) :
142+
@[simp, grind =] theorem get_attachWith {p : α → Prop} {o : Option α} (H : ∀ a, o = some a → p a) (h : (o.attachWith p H).isSome) :
143143
(o.attachWith p H).get h = ⟨o.get (by simpa using h), H _ (by simp)⟩ := by
144144
cases o <;> simp
145145

146-
@[simp] theorem getD_attachWith {p : α → Prop} {o : Option α} {h} {fallback} :
146+
@[simp, grind =] theorem getD_attachWith {p : α → Prop} {o : Option α} {h} {fallback} :
147147
(o.attachWith p h).getD fallback =
148-
⟨o.getD fallback.1, by cases o <;> (try exact fallback.2) <;> exact h _ (by simp)⟩ := by
148+
⟨o.getD fallback.val, by
149+
cases o
150+
· exact fallback.property
151+
· exact h _ (by simp)⟩ := by
149152
cases o <;> simp
150153

151154
theorem toList_attach (o : Option α) :
@@ -168,23 +171,23 @@ theorem toArray_attachWith {p : α → Prop} {o : Option α} {h} :
168171
o.toList.attach = (o.attach.map fun ⟨a, h⟩ => ⟨a, by simpa using h⟩).toList := by
169172
cases o <;> simp [toList]
170173

171-
theorem attach_map {o : Option α} (f : α → β) :
174+
@[grind =] theorem attach_map {o : Option α} (f : α → β) :
172175
(o.map f).attach = o.attach.map (fun ⟨x, h⟩ => ⟨f x, map_eq_some_iff.2 ⟨_, h, rfl⟩⟩) := by
173176
cases o <;> simp
174177

175-
theorem attachWith_map {o : Option α} (f : α → β) {P : β → Prop} {H : ∀ (b : β), o.map f = some b → P b} :
178+
@[grind =] theorem attachWith_map {o : Option α} (f : α → β) {P : β → Prop} {H : ∀ (b : β), o.map f = some b → P b} :
176179
(o.map f).attachWith P H = (o.attachWith (P ∘ f) (fun _ h => H _ (map_eq_some_iff.2 ⟨_, h, rfl⟩))).map
177180
fun ⟨x, h⟩ => ⟨f x, h⟩ := by
178181
cases o <;> simp
179182

180-
theorem map_attach_eq_pmap {o : Option α} (f : { x // o = some x } → β) :
183+
@[grind =] theorem map_attach_eq_pmap {o : Option α} (f : { x // o = some x } → β) :
181184
o.attach.map f = o.pmap (fun a (h : o = some a) => f ⟨a, h⟩) (fun _ h => h) := by
182185
cases o <;> simp
183186

184187
@[deprecated map_attach_eq_pmap (since := "2025-02-09")]
185188
abbrev map_attach := @map_attach_eq_pmap
186189

187-
@[simp] theorem map_attachWith {l : Option α} {P : α → Prop} {H : ∀ (a : α), l = some a → P a}
190+
@[simp, grind =] theorem map_attachWith {l : Option α} {P : α → Prop} {H : ∀ (a : α), l = some a → P a}
188191
(f : { x // P x } → β) :
189192
(l.attachWith P H).map f = l.attach.map fun ⟨x, h⟩ => f ⟨x, H _ h⟩ := by
190193
cases l <;> simp_all
@@ -200,20 +203,20 @@ theorem map_attach_eq_attachWith {o : Option α} {p : α → Prop} (f : ∀ a, o
200203
o.attach.map (fun x => ⟨x.1, f x.1 x.2⟩) = o.attachWith p f := by
201204
cases o <;> simp_all [Function.comp_def]
202205

203-
theorem attach_bind {o : Option α} {f : α → Option β} :
206+
@[grind =] theorem attach_bind {o : Option α} {f : α → Option β} :
204207
(o.bind f).attach =
205208
o.attach.bind fun ⟨x, h⟩ => (f x).attach.map fun ⟨y, h'⟩ => ⟨y, bind_eq_some_iff.2 ⟨_, h, h'⟩⟩ := by
206209
cases o <;> simp
207210

208-
theorem bind_attach {o : Option α} {f : {x // o = some x} → Option β} :
211+
@[grind =] theorem bind_attach {o : Option α} {f : {x // o = some x} → Option β} :
209212
o.attach.bind f = o.pbind fun a h => f ⟨a, h⟩ := by
210213
cases o <;> simp
211214

212215
theorem pbind_eq_bind_attach {o : Option α} {f : (a : α) → o = some a → Option β} :
213216
o.pbind f = o.attach.bind fun ⟨x, h⟩ => f x h := by
214217
cases o <;> simp
215218

216-
theorem attach_filter {o : Option α} {p : α → Bool} :
219+
@[grind =] theorem attach_filter {o : Option α} {p : α → Bool} :
217220
(o.filter p).attach =
218221
o.attach.bind fun ⟨x, h⟩ => if h' : p x then some ⟨x, by simp_all⟩ else none := by
219222
cases o with
@@ -229,12 +232,12 @@ theorem attach_filter {o : Option α} {p : α → Bool} :
229232
· rintro ⟨h, rfl⟩
230233
simp [h]
231234

232-
theorem filter_attachWith {P : α → Prop} {o : Option α} {h : ∀ x, o = some x → P x} {q : α → Bool} :
235+
@[grind =] theorem filter_attachWith {P : α → Prop} {o : Option α} {h : ∀ x, o = some x → P x} {q : α → Bool} :
233236
(o.attachWith P h).filter q =
234237
(o.filter q).attachWith P (fun _ h' => h _ (eq_some_of_filter_eq_some h')) := by
235238
cases o <;> simp [filter_some] <;> split <;> simp
236239

237-
theorem filter_attach {o : Option α} {p : {x // o = some x} → Bool} :
240+
@[grind =] theorem filter_attach {o : Option α} {p : {x // o = some x} → Bool} :
238241
o.attach.filter p = o.pbind fun a h => if p ⟨a, h⟩ then some ⟨a, h⟩ else none := by
239242
cases o <;> simp [filter_some]
240243

@@ -278,7 +281,7 @@ theorem toArray_pmap {p : α → Prop} {o : Option α} {f : (a : α) → p a →
278281
(o.pmap f h).toArray = o.attach.toArray.map (fun x => f x.1 (h _ x.2)) := by
279282
cases o <;> simp
280283

281-
theorem attach_pfilter {o : Option α} {p : (a : α) → o = some a → Bool} :
284+
@[grind =] theorem attach_pfilter {o : Option α} {p : (a : α) → o = some a → Bool} :
282285
(o.pfilter p).attach =
283286
o.attach.pbind fun x h => if h' : p x (by simp_all) then
284287
some ⟨x.1, by simpa [pfilter_eq_some_iff] using ⟨_, h'⟩⟩ else none := by

0 commit comments

Comments
 (0)