File: Mathlib/CategoryTheory/EqToHom.lean

full_name: CategoryTheory.eqToHom
code: /-- An equality `X = Y` gives us a morphism `X ⟶ Y`.

It is typically better to use this, rather than rewriting by the equality then using `𝟙 _`
which usually leads to dependent type theory hell.
-/
def eqToHom {X Y : C} (p : X = Y) : X ⟶ Y 
goal: X ⟶ Y

full_name: CategoryTheory.eqToHom_refl
code: @[simp]
theorem eqToHom_refl (X : C) (p : X = X) : eqToHom p = 𝟙 X 
goal: CategoryTheory.eqToHom p = CategoryTheory.CategoryStruct.id X

full_name: CategoryTheory.eqToHom_trans
code: @[reassoc (attr := simp)]
theorem eqToHom_trans {X Y Z : C} (p : X = Y) (q : Y = Z) :
    eqToHom p ≫ eqToHom q = eqToHom (p.trans q) 
goal: CategoryTheory.CategoryStruct.comp (CategoryTheory.eqToHom p) (CategoryTheory.eqToHom q) = CategoryTheory.eqToHom ⋯

full_name: CategoryTheory.comp_eqToHom_iff
code: theorem comp_eqToHom_iff {X Y Y' : C} (p : Y = Y') (f : X ⟶ Y) (g : X ⟶ Y') :
    f ≫ eqToHom p = g ↔ f = g ≫ eqToHom p.symm 
goal: CategoryTheory.CategoryStruct.comp f (CategoryTheory.eqToHom p) = g ↔
  f = CategoryTheory.CategoryStruct.comp g (CategoryTheory.eqToHom ⋯)

full_name: CategoryTheory.eqToHom_comp_iff
code: theorem eqToHom_comp_iff {X X' Y : C} (p : X = X') (f : X ⟶ Y) (g : X' ⟶ Y) :
    eqToHom p ≫ g = f ↔ g = eqToHom p.symm ≫ f 
goal: CategoryTheory.CategoryStruct.comp (CategoryTheory.eqToHom p) g = f ↔
  g = CategoryTheory.CategoryStruct.comp (CategoryTheory.eqToHom ⋯) f

full_name: CategoryTheory.eqToHom_naturality
code: /-- We can push `eqToHom` to the left through families of morphisms. -/
-- The simpNF linter incorrectly claims that this will never apply.
-- https://github.com/leanprover-community/mathlib4/issues/5049
@[reassoc (attr := simp, nolint simpNF)]
theorem eqToHom_naturality {f g : β → C} (z : ∀ b, f b ⟶ g b) {j j' : β} (w : j = j') :
    z j ≫ eqToHom (by simp [w]) = eqToHom (by simp [w]) ≫ z j' 
goal: CategoryTheory.CategoryStruct.comp (z j) (CategoryTheory.eqToHom ⋯) =
  CategoryTheory.CategoryStruct.comp (CategoryTheory.eqToHom ⋯) (z j')

full_name: CategoryTheory.eqToHom_iso_hom_naturality
code: /-- A variant on `eqToHom_naturality` that helps Lean identify the families `f` and `g`. -/
-- The simpNF linter incorrectly claims that this will never apply.
-- https://github.com/leanprover-community/mathlib4/issues/5049
@[reassoc (attr := simp, nolint simpNF)]
theorem eqToHom_iso_hom_naturality {f g : β → C} (z : ∀ b, f b ≅ g b) {j j' : β} (w : j = j') :
    (z j).hom ≫ eqToHom (by simp [w]) = eqToHom (by simp [w]) ≫ (z j').hom 
goal: CategoryTheory.CategoryStruct.comp (z j).hom (CategoryTheory.eqToHom ⋯) =
  CategoryTheory.CategoryStruct.comp (CategoryTheory.eqToHom ⋯) (z j').hom

full_name: CategoryTheory.eqToHom_iso_inv_naturality
code: /-- A variant on `eqToHom_naturality` that helps Lean identify the families `f` and `g`. -/
-- The simpNF linter incorrectly claims that this will never apply.
-- https://github.com/leanprover-community/mathlib4/issues/5049
@[reassoc (attr := simp, nolint simpNF)]
theorem eqToHom_iso_inv_naturality {f g : β → C} (z : ∀ b, f b ≅ g b) {j j' : β} (w : j = j') :
    (z j).inv ≫ eqToHom (by simp [w]) = eqToHom (by simp [w]) ≫ (z j').inv 
goal: CategoryTheory.CategoryStruct.comp (z j).inv (CategoryTheory.eqToHom ⋯) =
  CategoryTheory.CategoryStruct.comp (CategoryTheory.eqToHom ⋯) (z j').inv

full_name: CategoryTheory.congrArg_cast_hom_left
code: /-- Reducible form of congrArg_mpr_hom_left -/
@[simp]
theorem congrArg_cast_hom_left {X Y Z : C} (p : X = Y) (q : Y ⟶ Z) :
    cast (congrArg (fun W : C => W ⟶ Z) p.symm) q = eqToHom p ≫ q 
goal: cast ⋯ q = CategoryTheory.CategoryStruct.comp (CategoryTheory.eqToHom p) q

full_name: CategoryTheory.congrArg_mpr_hom_left
code: /-- If we (perhaps unintentionally) perform equational rewriting on
the source object of a morphism,
we can replace the resulting `_.mpr f` term by a composition with an `eqToHom`.

It may be advisable to introduce any necessary `eqToHom` morphisms manually,
rather than relying on this lemma firing.
-/
theorem congrArg_mpr_hom_left {X Y Z : C} (p : X = Y) (q : Y ⟶ Z) :
    (congrArg (fun W : C => W ⟶ Z) p).mpr q = eqToHom p ≫ q 
goal: ⋯.mpr q = CategoryTheory.CategoryStruct.comp (CategoryTheory.eqToHom p) q

full_name: CategoryTheory.congrArg_cast_hom_right
code: /-- Reducible form of `congrArg_mpr_hom_right` -/
@[simp]
theorem congrArg_cast_hom_right {X Y Z : C} (p : X ⟶ Y) (q : Z = Y) :
    cast (congrArg (fun W : C => X ⟶ W) q.symm) p = p ≫ eqToHom q.symm 
goal: cast ⋯ p = CategoryTheory.CategoryStruct.comp p (CategoryTheory.eqToHom ⋯)

full_name: CategoryTheory.congrArg_mpr_hom_right
code: /-- If we (perhaps unintentionally) perform equational rewriting on
the target object of a morphism,
we can replace the resulting `_.mpr f` term by a composition with an `eqToHom`.

It may be advisable to introduce any necessary `eqToHom` morphisms manually,
rather than relying on this lemma firing.
-/
theorem congrArg_mpr_hom_right {X Y Z : C} (p : X ⟶ Y) (q : Z = Y) :
    (congrArg (fun W : C => X ⟶ W) q).mpr p = p ≫ eqToHom q.symm 
goal: ⋯.mpr p = CategoryTheory.CategoryStruct.comp p (CategoryTheory.eqToHom ⋯)

full_name: CategoryTheory.eqToIso
code: /-- An equality `X = Y` gives us an isomorphism `X ≅ Y`.

It is typically better to use this, rather than rewriting by the equality then using `Iso.refl _`
which usually leads to dependent type theory hell.
-/
def eqToIso {X Y : C} (p : X = Y) : X ≅ Y 
goal: X ≅ Y

full_name: CategoryTheory.eqToIso.hom
code: @[simp]
theorem eqToIso.hom {X Y : C} (p : X = Y) : (eqToIso p).hom = eqToHom p 
goal: (CategoryTheory.eqToIso p).hom = CategoryTheory.eqToHom p

full_name: CategoryTheory.eqToIso.inv
code: @[simp]
theorem eqToIso.inv {X Y : C} (p : X = Y) : (eqToIso p).inv = eqToHom p.symm 
goal: (CategoryTheory.eqToIso p).inv = CategoryTheory.eqToHom ⋯

full_name: CategoryTheory.eqToIso_refl
code: @[simp]
theorem eqToIso_refl {X : C} (p : X = X) : eqToIso p = Iso.refl X 
goal: CategoryTheory.eqToIso p = CategoryTheory.Iso.refl X

full_name: CategoryTheory.eqToIso_trans
code: @[simp]
theorem eqToIso_trans {X Y Z : C} (p : X = Y) (q : Y = Z) :
    eqToIso p ≪≫ eqToIso q = eqToIso (p.trans q) 
goal: CategoryTheory.eqToIso p ≪≫ CategoryTheory.eqToIso q = CategoryTheory.eqToIso ⋯

full_name: CategoryTheory.eqToHom_op
code: @[simp]
theorem eqToHom_op {X Y : C} (h : X = Y) : (eqToHom h).op = eqToHom (congr_arg op h.symm) 
goal: (CategoryTheory.eqToHom h).op = CategoryTheory.eqToHom ⋯

full_name: CategoryTheory.eqToHom_unop
code: @[simp]
theorem eqToHom_unop {X Y : Cᵒᵖ} (h : X = Y) :
    (eqToHom h).unop = eqToHom (congr_arg unop h.symm) 
goal: (CategoryTheory.eqToHom h).unop = CategoryTheory.eqToHom ⋯

full_name: CategoryTheory.instIsIsoEqToHom
code: instance {X Y : C} (h : X = Y) : IsIso (eqToHom h) 
goal: CategoryTheory.IsIso (CategoryTheory.eqToHom h)

full_name: CategoryTheory.inv_eqToHom
code: @[simp]
theorem inv_eqToHom {X Y : C} (h : X = Y) : inv (eqToHom h) = eqToHom h.symm 
goal: CategoryTheory.inv (CategoryTheory.eqToHom h) = CategoryTheory.eqToHom ⋯

full_name: CategoryTheory.Functor.ext
code: /-- Proving equality between functors. This isn't an extensionality lemma,
  because usually you don't really want to do this. -/
theorem ext {F G : C ⥤ D} (h_obj : ∀ X, F.obj X = G.obj X)
    (h_map : ∀ X Y f,
      F.map f = eqToHom (h_obj X) ≫ G.map f ≫ eqToHom (h_obj Y).symm := by aesop_cat) :
    F = G 
goal: F = G

full_name: CategoryTheory.Functor.ext_of_iso
code: lemma ext_of_iso {F G : C ⥤ D} (e : F ≅ G) (hobj : ∀ X, F.obj X = G.obj X)
    (happ : ∀ X, e.hom.app X = eqToHom (hobj X)) : F = G 
goal: F = G

full_name: CategoryTheory.Functor.conj_eqToHom_iff_heq
code: /-- Two morphisms are conjugate via eqToHom if and only if they are heterogeneously equal. -/
theorem conj_eqToHom_iff_heq {W X Y Z : C} (f : W ⟶ X) (g : Y ⟶ Z) (h : W = Y) (h' : X = Z) :
    f = eqToHom h ≫ g ≫ eqToHom h'.symm ↔ HEq f g 
goal: f =
    CategoryTheory.CategoryStruct.comp (CategoryTheory.eqToHom h)
      (CategoryTheory.CategoryStruct.comp g (CategoryTheory.eqToHom ⋯)) ↔
  HEq f g

full_name: CategoryTheory.Functor.hext
code: /-- Proving equality between functors using heterogeneous equality. -/
theorem hext {F G : C ⥤ D} (h_obj : ∀ X, F.obj X = G.obj X)
    (h_map : ∀ (X Y) (f : X ⟶ Y), HEq (F.map f) (G.map f)) : F = G 
goal: F = G

full_name: CategoryTheory.Functor.congr_obj
code: theorem congr_obj {F G : C ⥤ D} (h : F = G) (X) : F.obj X = G.obj X 
goal: F.obj X = G.obj X

full_name: CategoryTheory.Functor.congr_hom
code: theorem congr_hom {F G : C ⥤ D} (h : F = G) {X Y} (f : X ⟶ Y) :
    F.map f = eqToHom (congr_obj h X) ≫ G.map f ≫ eqToHom (congr_obj h Y).symm 
goal: F.map f =
  CategoryTheory.CategoryStruct.comp (CategoryTheory.eqToHom ⋯)
    (CategoryTheory.CategoryStruct.comp (G.map f) (CategoryTheory.eqToHom ⋯))

full_name: CategoryTheory.Functor.congr_inv_of_congr_hom
code: theorem congr_inv_of_congr_hom (F G : C ⥤ D) {X Y : C} (e : X ≅ Y) (hX : F.obj X = G.obj X)
    (hY : F.obj Y = G.obj Y)
    (h₂ : F.map e.hom = eqToHom (by rw [hX]) ≫ G.map e.hom ≫ eqToHom (by rw [hY])) :
    F.map e.inv = eqToHom (by rw [hY]) ≫ G.map e.inv ≫ eqToHom (by rw [hX]) 
goal: F.map e.inv =
  CategoryTheory.CategoryStruct.comp (CategoryTheory.eqToHom ⋯)
    (CategoryTheory.CategoryStruct.comp (G.map e.inv) (CategoryTheory.eqToHom ⋯))

full_name: CategoryTheory.Functor.map_comp_heq
code: theorem map_comp_heq (hx : F.obj X = G.obj X) (hy : F.obj Y = G.obj Y) (hz : F.obj Z = G.obj Z)
    (hf : HEq (F.map f) (G.map f)) (hg : HEq (F.map g) (G.map g)) :
    HEq (F.map (f ≫ g)) (G.map (f ≫ g)) 
goal: HEq (F.map (CategoryTheory.CategoryStruct.comp f g)) (G.map (CategoryTheory.CategoryStruct.comp f g))

full_name: CategoryTheory.Functor.map_comp_heq'
code: theorem map_comp_heq' (hobj : ∀ X : C, F.obj X = G.obj X)
    (hmap : ∀ {X Y} (f : X ⟶ Y), HEq (F.map f) (G.map f)) :
    HEq (F.map (f ≫ g)) (G.map (f ≫ g)) 
goal: HEq (F.map (CategoryTheory.CategoryStruct.comp f g)) (G.map (CategoryTheory.CategoryStruct.comp f g))

full_name: CategoryTheory.Functor.precomp_map_heq
code: theorem precomp_map_heq (H : E ⥤ C) (hmap : ∀ {X Y} (f : X ⟶ Y), HEq (F.map f) (G.map f)) {X Y : E}
    (f : X ⟶ Y) : HEq ((H ⋙ F).map f) ((H ⋙ G).map f) 
goal: HEq ((H.comp F).map f) ((H.comp G).map f)

full_name: CategoryTheory.Functor.postcomp_map_heq
code: theorem postcomp_map_heq (H : D ⥤ E) (hx : F.obj X = G.obj X) (hy : F.obj Y = G.obj Y)
    (hmap : HEq (F.map f) (G.map f)) : HEq ((F ⋙ H).map f) ((G ⋙ H).map f) 
goal: HEq ((F.comp H).map f) ((G.comp H).map f)

full_name: CategoryTheory.Functor.postcomp_map_heq'
code: theorem postcomp_map_heq' (H : D ⥤ E) (hobj : ∀ X : C, F.obj X = G.obj X)
    (hmap : ∀ {X Y} (f : X ⟶ Y), HEq (F.map f) (G.map f)) :
    HEq ((F ⋙ H).map f) ((G ⋙ H).map f) 
goal: HEq ((F.comp H).map f) ((G.comp H).map f)

full_name: CategoryTheory.Functor.hcongr_hom
code: theorem hcongr_hom {F G : C ⥤ D} (h : F = G) {X Y} (f : X ⟶ Y) : HEq (F.map f) (G.map f) 
goal: HEq (F.map f) (G.map f)

full_name: CategoryTheory.eqToHom_map
code: /-- This is not always a good idea as a `@[simp]` lemma,
as we lose the ability to use results that interact with `F`,
e.g. the naturality of a natural transformation.

In some files it may be appropriate to use `attribute [local simp] eqToHom_map`, however.
-/
theorem eqToHom_map (F : C ⥤ D) {X Y : C} (p : X = Y) :
    F.map (eqToHom p) = eqToHom (congr_arg F.obj p) 
goal: F.map (CategoryTheory.eqToHom p) = CategoryTheory.eqToHom ⋯

full_name: CategoryTheory.eqToHom_map_comp
code: @[reassoc (attr := simp)]
theorem eqToHom_map_comp (F : C ⥤ D) {X Y Z : C} (p : X = Y) (q : Y = Z) :
    F.map (eqToHom p) ≫ F.map (eqToHom q) = F.map (eqToHom <| p.trans q) 
goal: CategoryTheory.CategoryStruct.comp (F.map (CategoryTheory.eqToHom p)) (F.map (CategoryTheory.eqToHom q)) =
  F.map (CategoryTheory.eqToHom ⋯)

full_name: CategoryTheory.eqToIso_map
code: /-- See the note on `eqToHom_map` regarding using this as a `simp` lemma.
-/
theorem eqToIso_map (F : C ⥤ D) {X Y : C} (p : X = Y) :
    F.mapIso (eqToIso p) = eqToIso (congr_arg F.obj p) 
goal: F.mapIso (CategoryTheory.eqToIso p) = CategoryTheory.eqToIso ⋯

full_name: CategoryTheory.eqToIso_map_trans
code: @[simp]
theorem eqToIso_map_trans (F : C ⥤ D) {X Y Z : C} (p : X = Y) (q : Y = Z) :
    F.mapIso (eqToIso p) ≪≫ F.mapIso (eqToIso q) = F.mapIso (eqToIso <| p.trans q) 
goal: F.mapIso (CategoryTheory.eqToIso p) ≪≫ F.mapIso (CategoryTheory.eqToIso q) = F.mapIso (CategoryTheory.eqToIso ⋯)

full_name: CategoryTheory.eqToHom_app
code: @[simp]
theorem eqToHom_app {F G : C ⥤ D} (h : F = G) (X : C) :
    (eqToHom h : F ⟶ G).app X = eqToHom (Functor.congr_obj h X) 
goal: (CategoryTheory.eqToHom h).app X = CategoryTheory.eqToHom ⋯

full_name: CategoryTheory.NatTrans.congr
code: theorem NatTrans.congr {F G : C ⥤ D} (α : F ⟶ G) {X Y : C} (h : X = Y) :
    α.app X = F.map (eqToHom h) ≫ α.app Y ≫ G.map (eqToHom h.symm) 
goal: α.app X =
  CategoryTheory.CategoryStruct.comp (F.map (CategoryTheory.eqToHom h))
    (CategoryTheory.CategoryStruct.comp (α.app Y) (G.map (CategoryTheory.eqToHom ⋯)))

full_name: CategoryTheory.eq_conj_eqToHom
code: theorem eq_conj_eqToHom {X Y : C} (f : X ⟶ Y) : f = eqToHom rfl ≫ f ≫ eqToHom rfl 
goal: f =
  CategoryTheory.CategoryStruct.comp (CategoryTheory.eqToHom ⋯)
    (CategoryTheory.CategoryStruct.comp f (CategoryTheory.eqToHom ⋯))

full_name: CategoryTheory.dcongr_arg
code: theorem dcongr_arg {ι : Type*} {F G : ι → C} (α : ∀ i, F i ⟶ G i) {i j : ι} (h : i = j) :
    α i = eqToHom (congr_arg F h) ≫ α j ≫ eqToHom (congr_arg G h.symm) 
goal: α i =
  CategoryTheory.CategoryStruct.comp (CategoryTheory.eqToHom ⋯)
    (CategoryTheory.CategoryStruct.comp (α j) (CategoryTheory.eqToHom ⋯))