Skip to content

Commit f07d120

Browse files
committed
chore(CategoryTheory/Comma/Arrow): use to_dual (leanprover-community#40862)
This PR uses `to_dual` to dualize the `Arrow` category. Theorems `isIso_of_isIso` and `isIso_of_isIso'` did not have a dual, and had stronger iff forms, and weren't used, so I decided to remove them (or mark private). I skipped the parts involving `eqToHom`, since `eqToHom` hasn't been tagged with `to_dual` yet.
1 parent b1e3b32 commit f07d120

1 file changed

Lines changed: 74 additions & 72 deletions

File tree

Mathlib/CategoryTheory/Comma/Arrow.lean

Lines changed: 74 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ variable (T) in
3333
squares in `T`. -/
3434
def Arrow := Comma (𝟭 T) (𝟭 T)
3535

36+
to_dual_name_hint Left Right
37+
3638
/-- The type of morphisms in the category `Arrow T`. -/
39+
@[to_dual self (reorder := f g)]
3740
protected def Arrow.Hom (f g : Arrow T) := CommaMorphism f g
3841

3942
instance : Quiver (Arrow T) where
@@ -45,43 +48,31 @@ instance : Category (Arrow T) :=
4548
namespace Arrow
4649

4750
/-- The left object of an arrow. -/
51+
@[to_dual /-- The right object of an arrow. -/]
4852
abbrev left (X : Arrow T) : T := Comma.left X
4953

50-
/-- The right object of an arrow. -/
51-
abbrev right (X : Arrow T) : T := Comma.right X
52-
5354
/-- Given `X : Arrow T`, this is the morphism `X.left ⟶ X.right`. -/
5455
abbrev hom (X : Arrow T) : X.left ⟶ X.right := Comma.hom X
5556

5657
/-- The left part of a morphism in the category of arrows. -/
58+
@[to_dual /-- The right part of a morphism in the category of arrows. -/]
5759
abbrev Hom.left {X Y : Arrow T} (f : X ⟶ Y) : X.left ⟶ Y.left := CommaMorphism.left f
5860

59-
/-- The right part of a morphism in the category of arrows. -/
60-
abbrev Hom.right {X Y : Arrow T} (f : X ⟶ Y) : X.right ⟶ Y.right := CommaMorphism.right f
61-
62-
@[ext]
61+
@[ext, to_dual self (reorder := X Y, h₁ h₂)]
6362
lemma hom_ext {X Y : Arrow T} (f g : X ⟶ Y) (h₁ : f.left = g.left) (h₂ : f.right = g.right) :
6463
f = g :=
6564
CommaMorphism.ext h₁ h₂
6665

67-
@[simp]
66+
@[to_dual (attr := simp)]
6867
theorem id_left (f : Arrow T) : Arrow.Hom.left (𝟙 f) = 𝟙 f.left :=
6968
rfl
7069

71-
@[simp]
72-
theorem id_right (f : Arrow T) : Arrow.Hom.right (𝟙 f) = 𝟙 f.right :=
73-
rfl
74-
75-
@[simp, reassoc]
70+
@[to_dual (reorder := f g) (attr := simp, reassoc)]
7671
theorem comp_left {X Y Z : Arrow T} (f : X ⟶ Y) (g : Y ⟶ Z) :
7772
(f ≫ g).left = f.left ≫ g.left := rfl
7873

79-
@[simp, reassoc]
80-
theorem comp_right {X Y Z : Arrow T} (f : X ⟶ Y) (g : Y ⟶ Z) :
81-
(f ≫ g).right = f.right ≫ g.right := rfl
82-
8374
/-- An object in the arrow category is simply a morphism in `T`. -/
84-
@[simps]
75+
@[simps, to_dual self]
8576
def mk {X Y : T} (f : X ⟶ Y) : Arrow T where
8677
left := X
8778
right := Y
@@ -92,38 +83,41 @@ theorem mk_eq (f : Arrow T) : Arrow.mk f.hom = f := by
9283
cases f
9384
rfl
9485

86+
@[to_dual none]
9587
lemma mk_surjective (f : Arrow T) :
9688
∃ (X Y : T) (g : X ⟶ Y), f = Arrow.mk g :=
9789
⟨_, _, f.hom, rfl⟩
9890

91+
@[to_dual self]
9992
theorem mk_injective (A B : T) :
10093
Function.Injective (Arrow.mk : (A ⟶ B) → Arrow T) := fun f g h => by
10194
cases h
10295
rfl
10396

97+
@[to_dual self]
10498
theorem mk_inj (A B : T) {f g : A ⟶ B} : Arrow.mk f = Arrow.mk g ↔ f = g :=
10599
(mk_injective A B).eq_iff
106100

101+
@[to_dual self]
107102
instance {X Y : T} : CoeOut (X ⟶ Y) (Arrow T) where
108103
coe := mk
109104

110-
@[reassoc (attr := simp high)]
105+
@[to_dual none, reassoc (attr := simp high)]
111106
theorem w {f g : Arrow T} (sq : f ⟶ g) : sq.left ≫ g.hom = f.hom ≫ sq.right :=
112107
CommaMorphism.w sq
113108

114-
@[reassoc]
115-
lemma Hom.w {f g : Arrow T} (sq : f ⟶ g) : sq.left ≫ g.hom = f.hom ≫ sq.right := by
116-
simp
109+
@[to_dual none, reassoc]
110+
alias Hom.w := w
117111

112+
@[to_dual]
118113
theorem hom.congr_left {f g : Arrow T} {φ₁ φ₂ : f ⟶ g} (h : φ₁ = φ₂) : φ₁.left = φ₂.left := by
119114
rw [h]
120115

121-
theorem hom.congr_right {f g : Arrow T} {φ₁ φ₂ : f ⟶ g} (h : φ₁ = φ₂) : φ₁.right = φ₂.right := by
122-
simp [h]
123-
116+
@[to_dual none]
124117
theorem iso_w {f g : Arrow T} (e : f ≅ g) : g.hom = e.inv.left ≫ f.hom ≫ e.hom.right := by
125118
simp [← Arrow.comp_right]
126119

120+
@[to_dual none]
127121
theorem iso_w' {W X Y Z : T} {f : W ⟶ X} {g : Y ⟶ Z} (e : Arrow.mk f ≅ Arrow.mk g) :
128122
g = e.inv.left ≫ f ≫ e.hom.right :=
129123
iso_w e
@@ -171,6 +165,14 @@ def homMk {f g : Arrow T} (u : f.left ⟶ g.left) (v : f.right ⟶ g.right)
171165
right := v
172166
w := w
173167

168+
/-- `homMk''` is the dual of `homMk`, which we need for `to_dual`.
169+
Please avoid using this directly. -/
170+
@[to_dual existing homMk]
171+
abbrev homMk'' {f g : Arrow T} (u : g.right ⟶ f.right) (v : g.left ⟶ f.left)
172+
(w : g.hom ≫ u = v ≫ f.hom := by cat_disch) : g ⟶ f :=
173+
homMk v u
174+
attribute [to_dual none] homMk_left homMk_right
175+
174176
/-- We can also build a morphism in the arrow category out of any commutative square in `T`. -/
175177
@[simps]
176178
def homMk' {X Y : T} {f : X ⟶ Y} {P Q : T} {g : P ⟶ Q} (u : X ⟶ P) (v : Y ⟶ Q)
@@ -180,24 +182,33 @@ def homMk' {X Y : T} {f : X ⟶ Y} {P Q : T} {g : P ⟶ Q} (u : X ⟶ P) (v : Y
180182
right := v
181183
w := w
182184

185+
/-- `homMk'''` is the dual of `homMk'`, which we need for `to_dual`.
186+
Please avoid using this directly. -/
187+
@[to_dual existing homMk']
188+
abbrev homMk''' {X Y : T} {f : Y ⟶ X} {P Q : T} {g : Q ⟶ P} (u : P ⟶ X) (v : Q ⟶ Y)
189+
(w : g ≫ u = v ≫ f := by cat_disch) : mk g ⟶ mk f :=
190+
homMk' v u
191+
attribute [to_dual none] homMk'_left
192+
183193
set_option backward.defeqAttrib.useBackward true in
184-
@[reassoc]
194+
@[to_dual none, reassoc]
185195
theorem w_mk_left {X Y : T} {f : X ⟶ Y} {g : Arrow T} (sq : mk f ⟶ g) :
186196
dsimp% sq.left ≫ g.hom = f ≫ sq.right :=
187197
sq.w
188198

189199
set_option backward.defeqAttrib.useBackward true in
190-
@[reassoc (attr := simp)]
200+
@[to_dual none, reassoc (attr := simp)]
191201
theorem w_mk_right {f : Arrow T} {X Y : T} {g : X ⟶ Y} (sq : f ⟶ mk g) :
192202
dsimp% sq.left ≫ g = f.hom ≫ sq.right :=
193203
sq.w
194204

195205
set_option backward.defeqAttrib.useBackward true in
196-
@[reassoc]
206+
@[to_dual none, reassoc]
197207
theorem w_mk {X Y X' Y' : T} {f : X ⟶ Y} {g : X' ⟶ Y'} (sq : mk f ⟶ mk g) :
198208
dsimp% sq.left ≫ g = f ≫ sq.right :=
199209
sq.w
200210

211+
@[to_dual self (reorder := f g, 6 7)]
201212
theorem isIso_of_isIso_left_of_isIso_right {f g : Arrow T} (ff : f ⟶ g) [IsIso ff.left]
202213
[IsIso ff.right] : IsIso ff where
203214
out := ⟨homMk (inv ff.left) (inv ff.right), by cat_disch⟩
@@ -210,59 +221,70 @@ def isoMk {f g : Arrow T} (l : f.left ≅ g.left) (r : f.right ≅ g.right)
210221
(h : l.hom ≫ g.hom = f.hom ≫ r.hom := by cat_disch) : f ≅ g :=
211222
Comma.isoMk l r h
212223

224+
/-- `isoMk''` is the dual of `isoMk`, which we need for `to_dual`.
225+
Please avoid using this directly. -/
226+
@[to_dual existing isoMk]
227+
abbrev isoMk'' {f g : Arrow T} (l : f.right ≅ g.right) (r : f.left ≅ g.left)
228+
(h : g.hom ≫ l.inv = r.inv ≫ f.hom := by cat_disch) : f ≅ g :=
229+
isoMk r l (by rwa [Iso.comp_inv_eq, Category.assoc, Iso.eq_inv_comp] at h)
230+
attribute [to_dual none] isoMk_hom_left isoMk_hom_right isoMk_inv_left isoMk_inv_right
231+
213232
/-- A variant of `Arrow.isoMk` that creates an iso between two `Arrow.mk`s with a better type
214233
signature. -/
215234
abbrev isoMk' {W X Y Z : T} (f : W ⟶ X) (g : Y ⟶ Z) (e₁ : W ≅ Y) (e₂ : X ≅ Z)
216235
(h : e₁.hom ≫ g = f ≫ e₂.hom := by cat_disch) : Arrow.mk f ≅ Arrow.mk g :=
217236
Arrow.isoMk e₁ e₂ h
218237

238+
/-- `isoMk'''` is the dual of `isoMk'`, which we need for `to_dual`.
239+
Please avoid using this directly. -/
240+
@[to_dual existing isoMk']
241+
abbrev isoMk''' {W X Y Z : T} (f : X ⟶ W) (g : Z ⟶ Y) (e₁ : W ≅ Y)
242+
(e₂ : X ≅ Z) (h : g ≫ e₁.inv = e₂.inv ≫ f := by cat_disch) : mk f ≅ mk g :=
243+
isoMk' f g e₂ e₁ (by rwa [Iso.comp_inv_eq, Category.assoc, Iso.eq_inv_comp] at h)
244+
219245
section
220246

221247
variable {f g : Arrow T} (sq : f ⟶ g)
222248

249+
@[to_dual]
223250
instance isIso_left [IsIso sq] : IsIso sq.left :=
224251
⟨(inv sq).left, by simp [← comp_left]⟩
225252

226-
instance isIso_right [IsIso sq] : IsIso sq.right :=
227-
⟨(inv sq).right, by simp [← comp_right]⟩
228-
229-
lemma isIso_of_isIso' {f g : Arrow T} (sq : f ⟶ g) [IsIso sq] [IsIso f.hom] :
253+
@[to_dual none]
254+
private lemma isIso_of_isIso' {f g : Arrow T} (sq : f ⟶ g) [IsIso sq] [IsIso f.hom] :
230255
IsIso g.hom := by
231256
rw [iso_w (asIso sq)]
232257
infer_instance
233258

234-
lemma isIso_of_isIso {X Y : T} {f : X ⟶ Y} {g : Arrow T} (sq : mk f ⟶ g) [IsIso sq] [IsIso f] :
235-
IsIso g.hom := by
236-
have : IsIso (mk f).hom := by assumption
237-
apply isIso_of_isIso' sq
238-
259+
@[to_dual none]
239260
lemma isIso_hom_iff_isIso_hom_of_isIso {f g : Arrow T} (sq : f ⟶ g) [IsIso sq] :
240261
IsIso f.hom ↔ IsIso g.hom :=
241262
fun _ => isIso_of_isIso' sq, fun _ => isIso_of_isIso' (inv sq)⟩
242263

264+
@[to_dual none]
243265
lemma isIso_iff_isIso_of_isIso {W X Y Z : T} {f : W ⟶ X} {g : Y ⟶ Z} (sq : mk f ⟶ mk g) [IsIso sq] :
244266
IsIso f ↔ IsIso g :=
245267
isIso_hom_iff_isIso_hom_of_isIso sq
246268

269+
@[to_dual none]
247270
lemma isIso_hom_iff_isIso_of_isIso {Y Z : T} {f : Arrow T} {g : Y ⟶ Z} (sq : f ⟶ mk g) [IsIso sq] :
248271
IsIso f.hom ↔ IsIso g :=
249272
isIso_hom_iff_isIso_hom_of_isIso sq
250273

251-
@[simp]
274+
@[to_dual (attr := simp, push ←)]
252275
theorem inv_left [IsIso sq] : (inv sq).left = inv sq.left :=
253276
IsIso.eq_inv_of_hom_inv_id (by simp [← comp_left])
254277

255-
@[simp]
256-
theorem inv_right [IsIso sq] : (inv sq).right = inv sq.right :=
257-
IsIso.eq_inv_of_hom_inv_id (by simp [← comp_right])
258-
278+
@[to_dual none]
259279
theorem left_hom_inv_right [IsIso sq] : sq.left ≫ g.hom ≫ inv sq.right = f.hom := by
260280
simp only [← Category.assoc, IsIso.comp_inv_eq, w]
261281

282+
@[to_dual none]
262283
theorem inv_left_hom_right [IsIso sq] : inv sq.left ≫ f.hom ≫ sq.right = g.hom := by
263284
simp only [w, IsIso.inv_comp_eq]
264285

265286
set_option backward.defeqAttrib.useBackward true in
287+
@[to_dual epi_right]
266288
instance mono_left [Mono sq] : Mono sq.left where
267289
right_cancellation {Z} φ ψ h := by
268290
let aux : (Z ⟶ f.left) → (Arrow.mk (𝟙 Z) ⟶ f) := fun φ =>
@@ -276,34 +298,14 @@ instance mono_left [Mono sq] : Mono sq.left where
276298
· exact h
277299
· simp [this, ← Arrow.w_mk_right, reassoc_of% h]
278300

279-
set_option backward.defeqAttrib.useBackward true in
280-
instance epi_right [Epi sq] : Epi sq.right where
281-
left_cancellation {Z} φ ψ h := by
282-
let aux : (g.right ⟶ Z) → (g ⟶ Arrow.mk (𝟙 Z)) := fun φ =>
283-
Arrow.homMk (g.hom ≫ φ) φ
284-
change (aux φ).right = (aux ψ).right
285-
congr 1
286-
rw [← cancel_epi sq]
287-
ext
288-
· simp only [comp_left, comp_left, aux, mk_left, homMk_left, w_assoc, h]
289-
· exact h
290-
291-
@[reassoc (attr := simp)]
301+
@[to_dual (attr := reassoc (attr := simp))]
292302
lemma hom_inv_id_left (e : f ≅ g) : e.hom.left ≫ e.inv.left = 𝟙 _ := by
293303
rw [← comp_left, e.hom_inv_id, id_left]
294304

295-
@[reassoc (attr := simp)]
305+
@[to_dual (attr := reassoc (attr := simp))]
296306
lemma inv_hom_id_left (e : f ≅ g) : e.inv.left ≫ e.hom.left = 𝟙 _ := by
297307
rw [← comp_left, e.inv_hom_id, id_left]
298308

299-
@[reassoc (attr := simp)]
300-
lemma hom_inv_id_right (e : f ≅ g) : e.hom.right ≫ e.inv.right = 𝟙 _ := by
301-
rw [← comp_right, e.hom_inv_id, id_right]
302-
303-
@[reassoc (attr := simp)]
304-
lemma inv_hom_id_right (e : f ≅ g) : e.inv.right ≫ e.hom.right = 𝟙 _ := by
305-
rw [← comp_right, e.inv_hom_id, id_right]
306-
307309
end
308310

309311
/-- Given a square from an arrow `i` to an isomorphism `p`, express the source part of `sq`
@@ -338,15 +340,10 @@ def squareToSnd {X Y Z : C} {i : Arrow C} {f : X ⟶ Y} {g : Y ⟶ Z} (sq : i
338340
Arrow.homMk (sq.left ≫ f) (sq.right) (by simp [w_mk sq])
339341

340342
/-- The functor sending an arrow to its source. -/
341-
@[simps!]
343+
@[to_dual (attr := simps!) /-- The functor sending an arrow to its target. -/]
342344
def leftFunc : Arrow C ⥤ C :=
343345
Comma.fst _ _
344346

345-
/-- The functor sending an arrow to its target. -/
346-
@[simps!]
347-
def rightFunc : Arrow C ⥤ C :=
348-
Comma.snd _ _
349-
350347
set_option backward.defeqAttrib.useBackward true in
351348
/-- The natural transformation from `leftFunc` to `rightFunc`, given by the arrow itself. -/
352349
@[simps]
@@ -365,7 +362,9 @@ set_option backward.defeqAttrib.useBackward true in
365362
@[simps]
366363
def mapArrow (F : C ⥤ D) : Arrow C ⥤ Arrow D where
367364
obj a := Arrow.mk (F.map a.hom)
368-
map f := Arrow.homMk (F.map f.left) (F.map f.right) (by simp [← Functor.map_comp])
365+
map {X Y} f := Arrow.homMk (F.map f.left) (F.map f.right) (by simp [← Functor.map_comp])
366+
367+
attribute [to_dual self (reorder := X Y)] mapArrow_map
369368

370369
variable (C D)
371370

@@ -375,7 +374,9 @@ a functor `F : C ⥤ D` to `F.mapArrow`. -/
375374
@[simps]
376375
def mapArrowFunctor : (C ⥤ D) ⥤ (Arrow C ⥤ Arrow D) where
377376
obj F := F.mapArrow
378-
map τ := { app f := Arrow.homMk (τ.app _) (τ.app _) }
377+
map {X Y} τ := { app f := Arrow.homMk (τ.app _) (τ.app _) }
378+
379+
attribute [to_dual self (reorder := X Y)] mapArrowFunctor_map_app
379380

380381
variable {C D}
381382

@@ -431,6 +432,7 @@ def Arrow.discreteEquiv (S : Type u) : Arrow (Discrete S) ≃ S where
431432

432433
/-- Extensionality lemma for functors `C ⥤ D` which uses as an assumption
433434
that the induced maps `Arrow C → Arrow D` coincide. -/
435+
@[to_dual self]
434436
lemma Arrow.functor_ext {F G : C ⥤ D} (h : ∀ ⦃X Y : C⦄ (f : X ⟶ Y),
435437
F.mapArrow.obj (Arrow.mk f) = G.mapArrow.obj (Arrow.mk f)) :
436438
F = G :=

0 commit comments

Comments
 (0)