Morphisms from equations between objects. #

When working categorically, sometimes one encounters an equation h : X = Y between objects.

Your initial aversion to this is natural and appropriate: you're in for some trouble, and if there is another way to approach the problem that won't rely on this equality, it may be worth pursuing.

You have two options:

1. Use the equality h as one normally would in Lean (e.g. using rw and subst). This may immediately cause difficulties, because in category theory everything is dependently typed, and equations between objects quickly lead to nasty goals with eq.rec.
2. Promote h to a morphism using eqToHom h : X ⟶ Y, or eqToIso h : X ≅ Y.

This file introduces various simp lemmas which in favourable circumstances result in the various eqToHom morphisms to drop out at the appropriate moment!

def CategoryTheory.eqToHom {C : Type u₁} [] {X : C} {Y : C} (p : X = Y) :
X Y

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.

Equations
Instances For
@[simp]
theorem CategoryTheory.eqToHom_refl {C : Type u₁} [] (X : C) (p : X = X) :
@[simp]
theorem CategoryTheory.eqToHom_trans_assoc {C : Type u₁} [] {X : C} {Y : C} {Z : C} (p : X = Y) (q : Y = Z✝) {Z : C} (h : Z✝ Z) :
@[simp]
theorem CategoryTheory.eqToHom_trans {C : Type u₁} [] {X : C} {Y : C} {Z : C} (p : X = Y) (q : Y = Z) :
theorem CategoryTheory.comp_eqToHom_iff {C : Type u₁} [] {X : C} {Y : C} {Y' : C} (p : Y = Y') (f : X Y) (g : X Y') :
theorem CategoryTheory.eqToHom_comp_iff {C : Type u₁} [] {X : C} {X' : C} {Y : C} (p : X = X') (f : X Y) (g : X' Y) :
@[simp]
theorem CategoryTheory.eqToHom_naturality_assoc {C : Type u₁} [] {β : Sort u_1} {f : βC} {g : βC} (z : (b : β) → f b g b) {j : β} {j' : β} (w : j = j') {Z : C} (h : g j' Z) :
@[simp]
theorem CategoryTheory.eqToHom_naturality {C : Type u₁} [] {β : Sort u_1} {f : βC} {g : βC} (z : (b : β) → f b g b) {j : β} {j' : β} (w : j = j') :

We can push eqToHom to the left through families of morphisms.

@[simp]
theorem CategoryTheory.eqToHom_iso_hom_naturality_assoc {C : Type u₁} [] {β : Sort u_1} {f : βC} {g : βC} (z : (b : β) → f b g b) {j : β} {j' : β} (w : j = j') {Z : C} (h : g j' Z) :
@[simp]
theorem CategoryTheory.eqToHom_iso_hom_naturality {C : Type u₁} [] {β : Sort u_1} {f : βC} {g : βC} (z : (b : β) → f b g b) {j : β} {j' : β} (w : j = j') :

A variant on eqToHom_naturality that helps Lean identify the families f and g.

@[simp]
theorem CategoryTheory.eqToHom_iso_inv_naturality_assoc {C : Type u₁} [] {β : Sort u_1} {f : βC} {g : βC} (z : (b : β) → f b g b) {j : β} {j' : β} (w : j = j') {Z : C} (h : f j' Z) :
@[simp]
theorem CategoryTheory.eqToHom_iso_inv_naturality {C : Type u₁} [] {β : Sort u_1} {f : βC} {g : βC} (z : (b : β) → f b g b) {j : β} {j' : β} (w : j = j') :

A variant on eqToHom_naturality that helps Lean identify the families f and g.

@[simp]
theorem CategoryTheory.congrArg_cast_hom_left {C : Type u₁} [] {X : C} {Y : C} {Z : C} (p : X = Y) (q : Y Z) :

Reducible form of congrArg_mpr_hom_left

theorem CategoryTheory.congrArg_mpr_hom_left {C : Type u₁} [] {X : C} {Y : C} {Z : C} (p : X = Y) (q : Y Z) :

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.

@[simp]
theorem CategoryTheory.congrArg_cast_hom_right {C : Type u₁} [] {X : C} {Y : C} {Z : C} (p : X Y) (q : Z = Y) :

Reducible form of congrArg_mpr_hom_right

theorem CategoryTheory.congrArg_mpr_hom_right {C : Type u₁} [] {X : C} {Y : C} {Z : C} (p : X Y) (q : Z = Y) :

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.

def CategoryTheory.eqToIso {C : Type u₁} [] {X : C} {Y : C} (p : X = Y) :
X Y

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.

Equations
• = { hom := , inv := , hom_inv_id := , inv_hom_id := }
Instances For
@[simp]
theorem CategoryTheory.eqToIso.hom {C : Type u₁} [] {X : C} {Y : C} (p : X = Y) :
@[simp]
theorem CategoryTheory.eqToIso.inv {C : Type u₁} [] {X : C} {Y : C} (p : X = Y) :
@[simp]
theorem CategoryTheory.eqToIso_refl {C : Type u₁} [] {X : C} (p : X = X) :
@[simp]
theorem CategoryTheory.eqToIso_trans {C : Type u₁} [] {X : C} {Y : C} {Z : C} (p : X = Y) (q : Y = Z) :
@[simp]
theorem CategoryTheory.eqToHom_op {C : Type u₁} [] {X : C} {Y : C} (h : X = Y) :
@[simp]
theorem CategoryTheory.eqToHom_unop {C : Type u₁} [] {X : Cᵒᵖ} {Y : Cᵒᵖ} (h : X = Y) :
instance CategoryTheory.instIsIsoEqToHom {C : Type u₁} [] {X : C} {Y : C} (h : X = Y) :
Equations
• =
@[simp]
theorem CategoryTheory.inv_eqToHom {C : Type u₁} [] {X : C} {Y : C} (h : X = Y) :
theorem CategoryTheory.Functor.ext {C : Type u₁} [] {D : Type u₂} [] {F : } {G : } (h_obj : ∀ (X : C), F.obj X = G.obj X) (h_map : autoParam (∀ (X Y : C) (f : X Y), F.map f = ) _auto✝) :
F = G

Proving equality between functors. This isn't an extensionality lemma, because usually you don't really want to do this.

theorem CategoryTheory.Functor.ext_of_iso {C : Type u₁} [] {D : Type u₂} [] {F : } {G : } (e : F G) (hobj : ∀ (X : C), F.obj X = G.obj X) (happ : ∀ (X : C), e.hom.app X = ) :
F = G
theorem CategoryTheory.Functor.conj_eqToHom_iff_heq {C : Type u₁} [] {W : C} {X : C} {Y : C} {Z : C} (f : W X) (g : Y Z) (h : W = Y) (h' : X = Z) :
HEq f g

Two morphisms are conjugate via eqToHom if and only if they are heterogeneously equal.

theorem CategoryTheory.Functor.hext {C : Type u₁} [] {D : Type u₂} [] {F : } {G : } (h_obj : ∀ (X : C), F.obj X = G.obj X) (h_map : ∀ (X Y : C) (f : X Y), HEq (F.map f) (G.map f)) :
F = G

Proving equality between functors using heterogeneous equality.

theorem CategoryTheory.Functor.congr_obj {C : Type u₁} [] {D : Type u₂} [] {F : } {G : } (h : F = G) (X : C) :
F.obj X = G.obj X
theorem CategoryTheory.Functor.congr_hom {C : Type u₁} [] {D : Type u₂} [] {F : } {G : } (h : F = G) {X : C} {Y : C} (f : X Y) :
F.map f =
theorem CategoryTheory.Functor.congr_inv_of_congr_hom {C : Type u₁} [] {D : Type u₂} [] (F : ) (G : ) {X : C} {Y : C} (e : X Y) (hX : F.obj X = G.obj X) (hY : F.obj Y = G.obj Y) (h₂ : F.map e.hom = ) :
F.map e.inv =
theorem CategoryTheory.Functor.congr_map {C : Type u₁} [] {D : Type u₂} [] (F : ) {X : C} {Y : C} {f : X Y} {g : X Y} (h : f = g) :
F.map f = F.map g
theorem CategoryTheory.Functor.map_comp_heq {C : Type u₁} [] {D : Type u₂} [] {F : } {G : } {X : C} {Y : C} {Z : C} {f : X Y} {g : Y Z} (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 ) (G.map )
theorem CategoryTheory.Functor.map_comp_heq' {C : Type u₁} [] {D : Type u₂} [] {F : } {G : } {X : C} {Y : C} {Z : C} {f : X Y} {g : Y Z} (hobj : ∀ (X : C), F.obj X = G.obj X) (hmap : ∀ {X Y : C} (f : X Y), HEq (F.map f) (G.map f)) :
HEq (F.map ) (G.map )
theorem CategoryTheory.Functor.precomp_map_heq {C : Type u₁} [] {D : Type u₂} [] {E : Type u₃} [] {F : } {G : } (H : ) (hmap : ∀ {X Y : C} (f : X Y), HEq (F.map f) (G.map f)) {X : E} {Y : E} (f : X Y) :
HEq (.map f) (.map f)
theorem CategoryTheory.Functor.postcomp_map_heq {C : Type u₁} [] {D : Type u₂} [] {E : Type u₃} [] {F : } {G : } {X : C} {Y : C} {f : X Y} (H : ) (hx : F.obj X = G.obj X) (hy : F.obj Y = G.obj Y) (hmap : HEq (F.map f) (G.map f)) :
HEq (.map f) (.map f)
theorem CategoryTheory.Functor.postcomp_map_heq' {C : Type u₁} [] {D : Type u₂} [] {E : Type u₃} [] {F : } {G : } {X : C} {Y : C} {f : X Y} (H : ) (hobj : ∀ (X : C), F.obj X = G.obj X) (hmap : ∀ {X Y : C} (f : X Y), HEq (F.map f) (G.map f)) :
HEq (.map f) (.map f)
theorem CategoryTheory.Functor.hcongr_hom {C : Type u₁} [] {D : Type u₂} [] {F : } {G : } (h : F = G) {X : C} {Y : C} (f : X Y) :
HEq (F.map f) (G.map f)
theorem CategoryTheory.eqToHom_map {C : Type u₁} [] {D : Type u₂} [] (F : ) {X : C} {Y : C} (p : X = Y) :
F.map =

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.

@[simp]
theorem CategoryTheory.eqToHom_map_comp_assoc {C : Type u₁} [] {D : Type u₂} [] (F : ) {X : C} {Y : C} {Z : C} (p : X = Y) (q : Y = Z✝) {Z : D} (h : F.obj Z✝ Z) :
@[simp]
theorem CategoryTheory.eqToHom_map_comp {C : Type u₁} [] {D : Type u₂} [] (F : ) {X : C} {Y : C} {Z : C} (p : X = Y) (q : Y = Z) :
CategoryTheory.CategoryStruct.comp (F.map ) (F.map ) = F.map
theorem CategoryTheory.eqToIso_map {C : Type u₁} [] {D : Type u₂} [] (F : ) {X : C} {Y : C} (p : X = Y) :
F.mapIso =

See the note on eqToHom_map regarding using this as a simp lemma.

@[simp]
theorem CategoryTheory.eqToIso_map_trans {C : Type u₁} [] {D : Type u₂} [] (F : ) {X : C} {Y : C} {Z : C} (p : X = Y) (q : Y = Z) :
F.mapIso ≪≫ F.mapIso = F.mapIso
@[simp]
theorem CategoryTheory.eqToHom_app {C : Type u₁} [] {D : Type u₂} [] {F : } {G : } (h : F = G) (X : C) :
.app X =
theorem CategoryTheory.NatTrans.congr {C : Type u₁} [] {D : Type u₂} [] {F : } {G : } (α : F G) {X : C} {Y : C} (h : X = Y) :
theorem CategoryTheory.eq_conj_eqToHom {C : Type u₁} [] {X : C} {Y : C} (f : X Y) :
theorem CategoryTheory.dcongr_arg {C : Type u₁} [] {ι : Type u_2} {F : ιC} {G : ιC} (α : (i : ι) → F i G i) {i : ι} {j : ι} (h : i = j) :