Skip to content

Commit e6b5207

Browse files
committed
feat: use grind in CategoryTheory.NatIso
1 parent 6542bc8 commit e6b5207

3 files changed

Lines changed: 57 additions & 81 deletions

File tree

Mathlib/CategoryTheory/Functor/Category.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ instance Functor.category : Category.{max u₁ v₂} (C ⥤ D) where
5757

5858
namespace NatTrans
5959

60-
@[ext]
60+
@[ext, grind ext]
6161
theorem ext' {α β : F ⟶ G} (w : α.app = β.app) : α = β := NatTrans.ext w
6262

6363
@[simp]

Mathlib/CategoryTheory/Iso.lean

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -66,40 +66,34 @@ variable {C : Type u} [Category.{v} C] {X Y Z : C}
6666

6767
namespace Iso
6868

69-
@[ext]
69+
@[ext, grind ext]
7070
theorem ext ⦃α β : X ≅ Y⦄ (w : α.hom = β.hom) : α = β :=
71-
suffices α.inv = β.inv by
72-
cases α
73-
cases β
74-
cases w
75-
cases this
76-
rfl
71+
suffices α.inv = β.inv by grind [Iso]
7772
calc
78-
α.inv = α.inv ≫ β.hom ≫ β.inv := by grind
79-
_ = (α.inv ≫ α.hom) ≫ β.inv := by grind
80-
_ = β.inv := by grind
73+
α.inv = α.inv ≫ β.hom ≫ β.inv := by grind
74+
_ = β.inv := by grind
8175

8276
/-- Inverse isomorphism. -/
8377
@[symm]
8478
def symm (I : X ≅ Y) : Y ≅ X where
8579
hom := I.inv
8680
inv := I.hom
8781

88-
@[simp]
82+
@[simp, grind =]
8983
theorem symm_hom (α : X ≅ Y) : α.symm.hom = α.inv :=
9084
rfl
9185

92-
@[simp]
86+
@[simp, grind =]
9387
theorem symm_inv (α : X ≅ Y) : α.symm.inv = α.hom :=
9488
rfl
9589

96-
@[simp]
90+
@[simp, grind =]
9791
theorem symm_mk {X Y : C} (hom : X ⟶ Y) (inv : Y ⟶ X) (hom_inv_id) (inv_hom_id) :
9892
Iso.symm { hom, inv, hom_inv_id := hom_inv_id, inv_hom_id := inv_hom_id } =
9993
{ hom := inv, inv := hom, hom_inv_id := inv_hom_id, inv_hom_id := hom_inv_id } :=
10094
rfl
10195

102-
@[simp]
96+
@[simp, grind =]
10397
theorem symm_symm_eq {X Y : C} (α : X ≅ Y) : α.symm.symm = α := rfl
10498

10599
theorem symm_bijective {X Y : C} : Function.Bijective (symm : (X ≅ Y) → _) :=
@@ -118,11 +112,13 @@ def refl (X : C) : X ≅ X where
118112
hom := 𝟙 X
119113
inv := 𝟙 X
120114

115+
attribute [grind =] refl_hom refl_inv
116+
121117
instance : Inhabited (X ≅ X) := ⟨Iso.refl X⟩
122118

123119
theorem nonempty_iso_refl (X : C) : Nonempty (X ≅ X) := ⟨default⟩
124120

125-
@[simp]
121+
@[simp, grind =]
126122
theorem refl_symm (X : C) : (Iso.refl X).symm = Iso.refl X := rfl
127123

128124
/-- Composition of two isomorphisms -/
@@ -131,25 +127,27 @@ def trans (α : X ≅ Y) (β : Y ≅ Z) : X ≅ Z where
131127
hom := α.hom ≫ β.hom
132128
inv := β.inv ≫ α.inv
133129

130+
attribute [grind =] trans_hom trans_inv
131+
134132
@[simps]
135133
instance instTransIso : Trans (α := C) (· ≅ ·) (· ≅ ·) (· ≅ ·) where
136134
trans := trans
137135

138136
/-- Notation for composition of isomorphisms. -/
139137
infixr:80 " ≪≫ " => Iso.trans -- type as `\ll \gg`.
140138

141-
@[simp]
139+
@[simp, grind =]
142140
theorem trans_mk {X Y Z : C} (hom : X ⟶ Y) (inv : Y ⟶ X) (hom_inv_id) (inv_hom_id)
143141
(hom' : Y ⟶ Z) (inv' : Z ⟶ Y) (hom_inv_id') (inv_hom_id') (hom_inv_id'') (inv_hom_id'') :
144142
Iso.trans ⟨hom, inv, hom_inv_id, inv_hom_id⟩ ⟨hom', inv', hom_inv_id', inv_hom_id'⟩ =
145143
⟨hom ≫ hom', inv' ≫ inv, hom_inv_id'', inv_hom_id''⟩ :=
146144
rfl
147145

148-
@[simp]
146+
@[simp, grind _=_]
149147
theorem trans_symm (α : X ≅ Y) (β : Y ≅ Z) : (α ≪≫ β).symm = β.symm ≪≫ α.symm :=
150148
rfl
151149

152-
@[simp]
150+
@[simp, grind _=_]
153151
theorem trans_assoc {Z' : C} (α : X ≅ Y) (β : Y ≅ Z) (γ : Z ≅ Z') :
154152
(α ≪≫ β) ≪≫ γ = α ≪≫ β ≪≫ γ := by
155153
ext; simp only [trans_hom, Category.assoc]
@@ -240,11 +238,11 @@ noncomputable def inv (f : X ⟶ Y) [I : IsIso f] : Y ⟶ X :=
240238

241239
namespace IsIso
242240

243-
@[simp]
241+
@[simp, grind =]
244242
theorem hom_inv_id (f : X ⟶ Y) [I : IsIso f] : f ≫ inv f = 𝟙 X :=
245243
(Classical.choose_spec I.1).left
246244

247-
@[simp]
245+
@[simp, grind =]
248246
theorem inv_hom_id (f : X ⟶ Y) [I : IsIso f] : inv f ≫ f = 𝟙 Y :=
249247
(Classical.choose_spec I.1).right
250248

@@ -269,7 +267,7 @@ theorem inv_hom_id_assoc (f : X ⟶ Y) [I : IsIso f] {Z} (g : Y ⟶ Z) : inv f
269267
end IsIso
270268

271269
lemma Iso.isIso_hom (e : X ≅ Y) : IsIso e.hom :=
272-
⟨e.inv, by simp, by simp⟩
270+
⟨e.inv, by simp only [hom_inv_id], by simp⟩
273271

274272
lemma Iso.isIso_inv (e : X ≅ Y) : IsIso e.inv := e.symm.isIso_hom
275273

@@ -308,16 +306,16 @@ instance (priority := 100) mono_of_iso (f : X ⟶ Y) [IsIso f] : Mono f where
308306
rw [← Category.comp_id g, ← Category.comp_id h, ← IsIso.hom_inv_id f,
309307
← Category.assoc, w, ← Category.assoc]
310308

311-
@[aesop apply safe (rule_sets := [CategoryTheory])]
309+
@[aesop apply safe (rule_sets := [CategoryTheory]), grind ←=]
312310
theorem inv_eq_of_hom_inv_id {f : X ⟶ Y} [IsIso f] {g : Y ⟶ X} (hom_inv_id : f ≫ g = 𝟙 X) :
313311
inv f = g := by
314-
apply (cancel_epi f).mp
315-
simp [hom_inv_id]
312+
have := congrArg (inv f ≫ ·) hom_inv_id
313+
grind
316314

317315
theorem inv_eq_of_inv_hom_id {f : X ⟶ Y} [IsIso f] {g : Y ⟶ X} (inv_hom_id : g ≫ f = 𝟙 Y) :
318316
inv f = g := by
319-
apply (cancel_mono f).mp
320-
simp [inv_hom_id]
317+
have := congrArg (· ≫ inv f) inv_hom_id
318+
grind
321319

322320
@[aesop apply safe (rule_sets := [CategoryTheory])]
323321
theorem eq_inv_of_hom_inv_id {f : X ⟶ Y} [IsIso f] {g : Y ⟶ X} (hom_inv_id : f ≫ g = 𝟙 X) :
@@ -503,15 +501,13 @@ section
503501

504502
variable {D : Type*} [Category D] {X Y : C} (e : X ≅ Y)
505503

506-
@[reassoc (attr := simp), grind =]
504+
@[reassoc (attr := simp)]
507505
lemma map_hom_inv_id (F : C ⥤ D) :
508-
F.map e.hom ≫ F.map e.inv = 𝟙 _ := by
509-
rw [← F.map_comp, e.hom_inv_id, F.map_id]
506+
F.map e.hom ≫ F.map e.inv = 𝟙 _ := by grind
510507

511-
@[reassoc (attr := simp), grind =]
508+
@[reassoc (attr := simp)]
512509
lemma map_inv_hom_id (F : C ⥤ D) :
513-
F.map e.inv ≫ F.map e.hom = 𝟙 _ := by
514-
rw [← F.map_comp, e.inv_hom_id, F.map_id]
510+
F.map e.inv ≫ F.map e.hom = 𝟙 _ := by grind
515511

516512
end
517513

Mathlib/CategoryTheory/NatIso.lean

Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ we put some declarations that are specifically about natural isomorphisms in the
3030
namespace so that they are available using dot notation.
3131
-/
3232

33+
set_option mathlib.tactic.category.grind true
34+
3335
-- declare the `v`'s first; see `CategoryTheory.Category` for an explanation
3436
universe v₁ v₂ v₃ v₄ u₁ u₂ u₃ u₄
3537

@@ -49,44 +51,34 @@ def app {F G : C ⥤ D} (α : F ≅ G) (X : C) :
4951
F.obj X ≅ G.obj X where
5052
hom := α.hom.app X
5153
inv := α.inv.app X
52-
hom_inv_id := by rw [← comp_app, Iso.hom_inv_id]; rfl
53-
inv_hom_id := by rw [← comp_app, Iso.inv_hom_id]; rfl
5454

5555
attribute [grind =] app_hom app_inv
5656

5757
@[reassoc (attr := simp), grind =]
5858
theorem hom_inv_id_app {F G : C ⥤ D} (α : F ≅ G) (X : C) :
59-
α.hom.app X ≫ α.inv.app X = 𝟙 (F.obj X) :=
60-
congr_fun (congr_arg NatTrans.app α.hom_inv_id) X
59+
α.hom.app X ≫ α.inv.app X = 𝟙 (F.obj X) := by cat_disch
6160

6261
@[reassoc (attr := simp), grind =]
6362
theorem inv_hom_id_app {F G : C ⥤ D} (α : F ≅ G) (X : C) :
64-
α.inv.app X ≫ α.hom.app X = 𝟙 (G.obj X) :=
65-
congr_fun (congr_arg NatTrans.app α.inv_hom_id) X
63+
α.inv.app X ≫ α.hom.app X = 𝟙 (G.obj X) := by cat_disch
6664

6765
@[reassoc (attr := simp)]
6866
lemma hom_inv_id_app_app {F G : C ⥤ D ⥤ E} (e : F ≅ G) (X₁ : C) (X₂ : D) :
69-
(e.hom.app X₁).app X₂ ≫ (e.inv.app X₁).app X₂ = 𝟙 _ := by
70-
rw [← NatTrans.comp_app, Iso.hom_inv_id_app, NatTrans.id_app]
67+
(e.hom.app X₁).app X₂ ≫ (e.inv.app X₁).app X₂ = 𝟙 _ := by cat_disch
7168

7269
@[reassoc (attr := simp)]
7370
lemma inv_hom_id_app_app {F G : C ⥤ D ⥤ E} (e : F ≅ G) (X₁ : C) (X₂ : D) :
74-
(e.inv.app X₁).app X₂ ≫ (e.hom.app X₁).app X₂ = 𝟙 _ := by
75-
rw [← NatTrans.comp_app, Iso.inv_hom_id_app, NatTrans.id_app]
71+
(e.inv.app X₁).app X₂ ≫ (e.hom.app X₁).app X₂ = 𝟙 _ := by cat_disch
7672

7773
@[reassoc (attr := simp)]
7874
lemma hom_inv_id_app_app_app {F G : C ⥤ D ⥤ E ⥤ E'} (e : F ≅ G)
7975
(X₁ : C) (X₂ : D) (X₃ : E) :
80-
((e.hom.app X₁).app X₂).app X₃ ≫ ((e.inv.app X₁).app X₂).app X₃ = 𝟙 _ := by
81-
rw [← NatTrans.comp_app, ← NatTrans.comp_app, Iso.hom_inv_id_app,
82-
NatTrans.id_app, NatTrans.id_app]
76+
((e.hom.app X₁).app X₂).app X₃ ≫ ((e.inv.app X₁).app X₂).app X₃ = 𝟙 _ := by cat_disch
8377

8478
@[reassoc (attr := simp)]
8579
lemma inv_hom_id_app_app_app {F G : C ⥤ D ⥤ E ⥤ E'} (e : F ≅ G)
8680
(X₁ : C) (X₂ : D) (X₃ : E) :
87-
((e.inv.app X₁).app X₂).app X₃ ≫ ((e.hom.app X₁).app X₂).app X₃ = 𝟙 _ := by
88-
rw [← NatTrans.comp_app, ← NatTrans.comp_app, Iso.inv_hom_id_app,
89-
NatTrans.id_app, NatTrans.id_app]
81+
((e.inv.app X₁).app X₂).app X₃ ≫ ((e.hom.app X₁).app X₂).app X₃ = 𝟙 _ := by cat_disch
9082

9183
end Iso
9284

@@ -110,12 +102,10 @@ theorem app_inv {F G : C ⥤ D} (α : F ≅ G) (X : C) : (α.app X).inv = α.inv
110102
variable {F G : C ⥤ D}
111103

112104
instance hom_app_isIso (α : F ≅ G) (X : C) : IsIso (α.hom.app X) :=
113-
⟨⟨α.inv.app X,
114-
by rw [← comp_app, Iso.hom_inv_id, ← id_app], by rw [← comp_app, Iso.inv_hom_id, ← id_app]⟩⟩⟩
105+
⟨⟨α.inv.app X, ⟨by grind, by grind⟩⟩⟩
115106

116107
instance inv_app_isIso (α : F ≅ G) (X : C) : IsIso (α.inv.app X) :=
117-
⟨⟨α.hom.app X,
118-
by rw [← comp_app, Iso.inv_hom_id, ← id_app], by rw [← comp_app, Iso.hom_inv_id, ← id_app]⟩⟩⟩
108+
⟨⟨α.hom.app X, ⟨by grind, by grind⟩⟩⟩
119109

120110
section
121111

@@ -161,8 +151,6 @@ theorem cancel_natIso_inv_right_assoc {W X X' : D} {Y : C} (f : W ⟶ X) (g : X
161151
f ≫ g ≫ α.inv.app Y = f' ≫ g' ≫ α.inv.app Y ↔ f ≫ g = f' ≫ g' := by
162152
simp only [← Category.assoc, cancel_mono, refl]
163153

164-
attribute [grind ←=] CategoryTheory.IsIso.inv_eq_of_hom_inv_id
165-
166154
@[simp]
167155
theorem inv_inv_app {F G : C ⥤ D} (e : F ≅ G) (X : C) : inv (e.inv.app X) = e.hom.app X := by
168156
cat_disch
@@ -182,30 +170,24 @@ theorem naturality_1' (α : F ⟶ G) (f : X ⟶ Y) {_ : IsIso (α.app X)} :
182170

183171
@[reassoc (attr := simp)]
184172
theorem naturality_2' (α : F ⟶ G) (f : X ⟶ Y) {_ : IsIso (α.app Y)} :
185-
α.app X ≫ G.map f ≫ inv (α.app Y) = F.map f := by
186-
rw [← Category.assoc, ← naturality, Category.assoc, IsIso.hom_inv_id, Category.comp_id]
173+
α.app X ≫ G.map f ≫ inv (α.app Y) = F.map f := by cat_disch
187174

188175
/-- The components of a natural isomorphism are isomorphisms.
189176
-/
190177
instance isIso_app_of_isIso (α : F ⟶ G) [IsIso α] (X) : IsIso (α.app X) :=
191-
⟨⟨(inv α).app X,
192-
⟨congr_fun (congr_arg NatTrans.app (IsIso.hom_inv_id α)) X,
193-
congr_fun (congr_arg NatTrans.app (IsIso.inv_hom_id α)) X⟩⟩⟩
178+
⟨⟨(inv α).app X, ⟨by grind, by grind⟩⟩⟩
194179

195180
@[simp]
196-
theorem isIso_inv_app (α : F ⟶ G) {_ : IsIso α} (X) : (inv α).app X = inv (α.app X) := by
197-
-- Porting note: the next lemma used to be in `ext`, but that is no longer allowed.
198-
-- We've added an aesop apply rule;
199-
-- it would be nice to have a hook to run those without aesop warning it didn't close the goal.
200-
apply IsIso.eq_inv_of_hom_inv_id
201-
rw [← NatTrans.comp_app]
202-
simp
181+
theorem isIso_inv_app (α : F ⟶ G) {_ : IsIso α} (X) : (inv α).app X = inv (α.app X) := by cat_disch
203182

204183
@[simp]
205184
theorem inv_map_inv_app (F : C ⥤ D ⥤ E) {X Y : C} (e : X ≅ Y) (Z : D) :
206-
inv ((F.map e.inv).app Z) = (F.map e.hom).app Z := by
207-
cat_disch
185+
inv ((F.map e.inv).app Z) = (F.map e.hom).app Z := by cat_disch
208186

187+
-- TODO: `hom_inv_id` and `inv_hom_id` are not yet working via `grind`,
188+
-- but they work fine in my minimization in the `grind` test suite.
189+
-- Investigate on nightly-testing / the next release?
190+
set_option mathlib.tactic.category.grind false in
209191
/-- Construct a natural isomorphism between functors by giving object level isomorphisms,
210192
and checking naturality only in the forward direction.
211193
-/
@@ -222,9 +204,11 @@ def ofComponents (app : ∀ X : C, F.obj X ≅ G.obj X)
222204
simp only [Iso.inv_hom_id_assoc, Iso.hom_inv_id, assoc, comp_id] at h
223205
exact h }
224206

207+
attribute [grind =] ofComponents_hom_app ofComponents_inv_app
208+
225209
@[simp]
226210
theorem ofComponents.app (app' : ∀ X : C, F.obj X ≅ G.obj X) (naturality) (X) :
227-
(ofComponents app' naturality).app X = app' X := by aesop
211+
(ofComponents app' naturality).app X = app' X := by cat_disch
228212

229213
-- Making this an instance would cause a typeclass inference loop with `isIso_app_of_isIso`.
230214
/-- A natural transformation is an isomorphism if all its components are isomorphisms.
@@ -234,22 +218,17 @@ theorem isIso_of_isIso_app (α : F ⟶ G) [∀ X : C, IsIso (α.app X)] : IsIso
234218

235219
/-- Horizontal composition of natural isomorphisms. -/
236220
@[simps]
237-
def hcomp {F G : C ⥤ D} {H I : D ⥤ E} (α : F ≅ G) (β : H ≅ I) : F ⋙ H ≅ G ⋙ I := by
238-
refine ⟨α.hom ◫ β.hom, α.inv ◫ β.inv, ?_, ?_⟩
239-
· ext
240-
rw [← NatTrans.exchange]
241-
simp
242-
ext; rw [← NatTrans.exchange]; simp
221+
def hcomp {F G : C ⥤ D} {H I : D ⥤ E} (α : F ≅ G) (β : H ≅ I) : F ⋙ H ≅ G ⋙ I where
222+
hom := α.hom ◫ β.hom
223+
inv := α.inv ◫ β.inv
243224

244225
theorem isIso_map_iff {F₁ F₂ : C ⥤ D} (e : F₁ ≅ F₂) {X Y : C} (f : X ⟶ Y) :
245226
IsIso (F₁.map f) ↔ IsIso (F₂.map f) := by
246227
revert F₁ F₂
247-
suffices ∀ {F₁ F₂ : C ⥤ D} (_ : F₁ ≅ F₂) (_ : IsIso (F₁.map f)), IsIso (F₂.map f) by
248-
exact fun F₁ F₂ e => ⟨this e, this e.symm⟩
228+
suffices ∀ {F₁ F₂ : C ⥤ D} (_ : F₁ ≅ F₂) (_ : IsIso (F₁.map f)), IsIso (F₂.map f) from
229+
fun F₁ F₂ e => ⟨this e, this e.symm⟩
249230
intro F₁ F₂ e hf
250-
refine IsIso.mk ⟨e.inv.app Y ≫ inv (F₁.map f) ≫ e.hom.app X, ?_, ?_⟩
251-
· simp only [NatTrans.naturality_assoc, IsIso.hom_inv_id_assoc, Iso.inv_hom_id_app]
252-
· simp only [assoc, ← e.hom.naturality, IsIso.inv_hom_id_assoc, Iso.inv_hom_id_app]
231+
exact IsIso.mk ⟨e.inv.app Y ≫ inv (F₁.map f) ≫ e.hom.app X, by cat_disch⟩
253232

254233
end NatIso
255234

@@ -261,6 +240,7 @@ namespace Functor
261240

262241
variable (F : C ⥤ D) (obj : C → D) (e : ∀ X, F.obj X ≅ obj X)
263242

243+
set_option mathlib.tactic.category.grind false in
264244
/-- Constructor for a functor that is isomorphic to a given functor `F : C ⥤ D`,
265245
while being definitionally equal on objects to a given map `obj : C → D`
266246
such that for all `X : C`, we have an isomorphism `F.obj X ≅ obj X`. -/

0 commit comments

Comments
 (0)