@@ -33,7 +33,10 @@ variable (T) in
3333squares in `T`. -/
3434def 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)]
3740protected def Arrow.Hom (f g : Arrow T) := CommaMorphism f g
3841
3942instance : Quiver (Arrow T) where
@@ -45,43 +48,31 @@ instance : Category (Arrow T) :=
4548namespace Arrow
4649
4750/-- The left object of an arrow. -/
51+ @ [to_dual /-- The right object of an arrow. -/ ]
4852abbrev 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`. -/
5455abbrev 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. -/ ]
5759abbrev 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₂)]
6362lemma 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) ]
6867theorem 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)]
7671theorem 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 ]
8576def 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]
9587lemma 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]
9992theorem 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]
10498theorem 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]
107102instance {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)]
111106theorem 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]
118113theorem 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]
124117theorem 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]
127121theorem 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]
176178def 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+
183193set_option backward.defeqAttrib.useBackward true in
184- @[reassoc]
194+ @ [to_dual none, reassoc]
185195theorem 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
189199set_option backward.defeqAttrib.useBackward true in
190- @ [reassoc (attr := simp)]
200+ @ [to_dual none, reassoc (attr := simp)]
191201theorem 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
195205set_option backward.defeqAttrib.useBackward true in
196- @[reassoc]
206+ @ [to_dual none, reassoc]
197207theorem 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 )]
201212theorem 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
214233signature. -/
215234abbrev 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+
219245section
220246
221247variable {f g : Arrow T} (sq : f ⟶ g)
222248
249+ @[to_dual]
223250instance 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]
239260lemma 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]
243265lemma 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]
247270lemma 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 ←) ]
252275theorem 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]
259279theorem 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]
262283theorem 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
265286set_option backward.defeqAttrib.useBackward true in
287+ @ [to_dual epi_right]
266288instance 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))]
292302lemma 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) )]
296306lemma 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-
307309end
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. -/ ]
342344def 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-
350347set_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]
366363def 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
370369variable (C D)
371370
@@ -375,7 +374,9 @@ a functor `F : C ⥤ D` to `F.mapArrow`. -/
375374@[simps]
376375def 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
380381variable {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
433434that the induced maps `Arrow C → Arrow D` coincide. -/
435+ @ [to_dual self]
434436lemma 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