l3lab/ntp-mathlib huggingface dataset:
theorem inv_eq_of_inv_hom_id {f : X ⟶ Y} [IsIso f] {g : Y ⟶ X} (inv_hom_id : g ≫ f = 𝟙 Y) :
    inv f = g := by
  apply (cancel_mono f).mp
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : IsIso f
g : Y ⟶ X
inv_hom_id : g ≫ f = 𝟙 Y
⊢ inv f ≫ f = g ≫ f

Next tactic:
simp [inv_hom_id]
instance id (X : C) : IsIso (𝟙 X) := ⟨⟨𝟙 X, by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y Z X : C
⊢ 𝟙 X ≫ 𝟙 X = 𝟙 X ∧ 𝟙 X ≫ 𝟙 X = 𝟙 X

Next tactic:
simp
instance of_iso (f : X ≅ Y) : IsIso f.hom := ⟨⟨f.inv, by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : C
f : X ≅ Y
⊢ f.hom ≫ f.inv = 𝟙 X ∧ f.inv ≫ f.hom = 𝟙 Y

Next tactic:
simp
@[simp]
theorem inv_id : inv (𝟙 X) = 𝟙 X := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
h : Y ⟶ Z
⊢ inv (𝟙 X) = 𝟙 X

Next tactic:
apply inv_eq_of_hom_inv_id
@[simp]
theorem inv_id : inv (𝟙 X) = 𝟙 X := by
  apply inv_eq_of_hom_inv_id
  

Proof state:
case hom_inv_id
C : Type u
inst✝ : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
h : Y ⟶ Z
⊢ 𝟙 X ≫ 𝟙 X = 𝟙 X

Next tactic:
simp
@[simp]
theorem inv_comp [IsIso f] [IsIso h] : inv (f ≫ h) = inv h ≫ inv f := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
h : Y ⟶ Z
inst✝¹ : IsIso f
inst✝ : IsIso h
⊢ inv (f ≫ h) = inv h ≫ inv f

Next tactic:
apply inv_eq_of_hom_inv_id
@[simp]
theorem inv_comp [IsIso f] [IsIso h] : inv (f ≫ h) = inv h ≫ inv f := by
  apply inv_eq_of_hom_inv_id
  

Proof state:
case hom_inv_id
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
h : Y ⟶ Z
inst✝¹ : IsIso f
inst✝ : IsIso h
⊢ (f ≫ h) ≫ inv h ≫ inv f = 𝟙 X

Next tactic:
simp
@[simp]
theorem inv_inv [IsIso f] : inv (inv f) = f := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
h : Y ⟶ Z
inst✝ : IsIso f
⊢ inv (inv f) = f

Next tactic:
apply inv_eq_of_hom_inv_id
@[simp]
theorem inv_inv [IsIso f] : inv (inv f) = f := by
  apply inv_eq_of_hom_inv_id
  

Proof state:
case hom_inv_id
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
h : Y ⟶ Z
inst✝ : IsIso f
⊢ inv f ≫ f = 𝟙 Y

Next tactic:
simp
@[simp]
theorem Iso.inv_inv (f : X ≅ Y) : inv f.inv = f.hom := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : C
f✝ g : X ⟶ Y
h : Y ⟶ Z
f : X ≅ Y
⊢ inv f.inv = f.hom

Next tactic:
apply inv_eq_of_hom_inv_id
@[simp]
theorem Iso.inv_inv (f : X ≅ Y) : inv f.inv = f.hom := by
  apply inv_eq_of_hom_inv_id
  

Proof state:
case hom_inv_id
C : Type u
inst✝ : Category.{v, u} C
X Y Z : C
f✝ g : X ⟶ Y
h : Y ⟶ Z
f : X ≅ Y
⊢ f.inv ≫ f.hom = 𝟙 Y

Next tactic:
simp
@[simp]
theorem Iso.inv_hom (f : X ≅ Y) : inv f.hom = f.inv := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : C
f✝ g : X ⟶ Y
h : Y ⟶ Z
f : X ≅ Y
⊢ inv f.hom = f.inv

Next tactic:
apply inv_eq_of_hom_inv_id
@[simp]
theorem Iso.inv_hom (f : X ≅ Y) : inv f.hom = f.inv := by
  apply inv_eq_of_hom_inv_id
  

Proof state:
case hom_inv_id
C : Type u
inst✝ : Category.{v, u} C
X Y Z : C
f✝ g : X ⟶ Y
h : Y ⟶ Z
f : X ≅ Y
⊢ f.hom ≫ f.inv = 𝟙 X

Next tactic:
simp
theorem of_isIso_comp_left {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) [IsIso f] [IsIso (f ≫ g)] :
    IsIso g := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ g✝ : X✝ ⟶ Y✝
h : Y✝ ⟶ Z✝
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
inst✝¹ : IsIso f
inst✝ : IsIso (f ≫ g)
⊢ IsIso g

Next tactic:
rw [← id_comp g, ← inv_hom_id f, assoc]
theorem of_isIso_comp_left {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) [IsIso f] [IsIso (f ≫ g)] :
    IsIso g := by
  rw [← id_comp g, ← inv_hom_id f, assoc]
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ g✝ : X✝ ⟶ Y✝
h : Y✝ ⟶ Z✝
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
inst✝¹ : IsIso f
inst✝ : IsIso (f ≫ g)
⊢ IsIso (inv f ≫ f ≫ g)

Next tactic:
infer_instance
theorem of_isIso_comp_right {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) [IsIso g] [IsIso (f ≫ g)] :
    IsIso f := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ g✝ : X✝ ⟶ Y✝
h : Y✝ ⟶ Z✝
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
inst✝¹ : IsIso g
inst✝ : IsIso (f ≫ g)
⊢ IsIso f

Next tactic:
rw [← comp_id f, ← hom_inv_id g, ← assoc]
theorem of_isIso_comp_right {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) [IsIso g] [IsIso (f ≫ g)] :
    IsIso f := by
  rw [← comp_id f, ← hom_inv_id g, ← assoc]
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ g✝ : X✝ ⟶ Y✝
h : Y✝ ⟶ Z✝
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
inst✝¹ : IsIso g
inst✝ : IsIso (f ≫ g)
⊢ IsIso ((f ≫ g) ≫ inv g)

Next tactic:
infer_instance
theorem of_isIso_fac_left {X Y Z : C} {f : X ⟶ Y} {g : Y ⟶ Z} {h : X ⟶ Z} [IsIso f]
    [hh : IsIso h] (w : f ≫ g = h) : IsIso g := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ g✝ : X✝ ⟶ Y✝
h✝ : Y✝ ⟶ Z✝
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
h : X ⟶ Z
inst✝ : IsIso f
hh : IsIso h
w : f ≫ g = h
⊢ IsIso g

Next tactic:
rw [← w] at hh
theorem of_isIso_fac_left {X Y Z : C} {f : X ⟶ Y} {g : Y ⟶ Z} {h : X ⟶ Z} [IsIso f]
    [hh : IsIso h] (w : f ≫ g = h) : IsIso g := by
  rw [← w] at hh
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ g✝ : X✝ ⟶ Y✝
h✝ : Y✝ ⟶ Z✝
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
h : X ⟶ Z
inst✝ : IsIso f
hh : IsIso (f ≫ g)
w : f ≫ g = h
⊢ IsIso g

Next tactic:
haveI := hh
theorem of_isIso_fac_left {X Y Z : C} {f : X ⟶ Y} {g : Y ⟶ Z} {h : X ⟶ Z} [IsIso f]
    [hh : IsIso h] (w : f ≫ g = h) : IsIso g := by
  rw [← w] at hh
  haveI := hh
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ g✝ : X✝ ⟶ Y✝
h✝ : Y✝ ⟶ Z✝
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
h : X ⟶ Z
inst✝ : IsIso f
hh : IsIso (f ≫ g)
w : f ≫ g = h
this : IsIso (f ≫ g)
⊢ IsIso g

Next tactic:
exact of_isIso_comp_left f g
theorem of_isIso_fac_right {X Y Z : C} {f : X ⟶ Y} {g : Y ⟶ Z} {h : X ⟶ Z} [IsIso g]
    [hh : IsIso h] (w : f ≫ g = h) : IsIso f := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ g✝ : X✝ ⟶ Y✝
h✝ : Y✝ ⟶ Z✝
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
h : X ⟶ Z
inst✝ : IsIso g
hh : IsIso h
w : f ≫ g = h
⊢ IsIso f

Next tactic:
rw [← w] at hh
theorem of_isIso_fac_right {X Y Z : C} {f : X ⟶ Y} {g : Y ⟶ Z} {h : X ⟶ Z} [IsIso g]
    [hh : IsIso h] (w : f ≫ g = h) : IsIso f := by
  rw [← w] at hh
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ g✝ : X✝ ⟶ Y✝
h✝ : Y✝ ⟶ Z✝
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
h : X ⟶ Z
inst✝ : IsIso g
hh : IsIso (f ≫ g)
w : f ≫ g = h
⊢ IsIso f

Next tactic:
haveI := hh
theorem of_isIso_fac_right {X Y Z : C} {f : X ⟶ Y} {g : Y ⟶ Z} {h : X ⟶ Z} [IsIso g]
    [hh : IsIso h] (w : f ≫ g = h) : IsIso f := by
  rw [← w] at hh
  haveI := hh
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ g✝ : X✝ ⟶ Y✝
h✝ : Y✝ ⟶ Z✝
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
h : X ⟶ Z
inst✝ : IsIso g
hh : IsIso (f ≫ g)
w : f ≫ g = h
this : IsIso (f ≫ g)
⊢ IsIso f

Next tactic:
exact of_isIso_comp_right f g
theorem eq_of_inv_eq_inv {f g : X ⟶ Y} [IsIso f] [IsIso g] (p : inv f = inv g) : f = g := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
inst✝¹ : IsIso f
inst✝ : IsIso g
p : inv f = inv g
⊢ f = g

Next tactic:
apply (cancel_epi (inv f)).1
theorem eq_of_inv_eq_inv {f g : X ⟶ Y} [IsIso f] [IsIso g] (p : inv f = inv g) : f = g := by
  apply (cancel_epi (inv f)).1
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
inst✝¹ : IsIso f
inst✝ : IsIso g
p : inv f = inv g
⊢ inv f ≫ f = inv f ≫ g

Next tactic:
erw [inv_hom_id, p, inv_hom_id]
theorem isIso_of_hom_comp_eq_id (g : X ⟶ Y) [IsIso g] {f : Y ⟶ X} (h : g ≫ f = 𝟙 X) : IsIso f := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
g : X ⟶ Y
inst✝ : IsIso g
f : Y ⟶ X
h : g ≫ f = 𝟙 X
⊢ IsIso f

Next tactic:
rw [(hom_comp_eq_id _).mp h]
theorem isIso_of_hom_comp_eq_id (g : X ⟶ Y) [IsIso g] {f : Y ⟶ X} (h : g ≫ f = 𝟙 X) : IsIso f := by
  rw [(hom_comp_eq_id _).mp h]
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
g : X ⟶ Y
inst✝ : IsIso g
f : Y ⟶ X
h : g ≫ f = 𝟙 X
⊢ IsIso (inv g)

Next tactic:
infer_instance
theorem isIso_of_comp_hom_eq_id (g : X ⟶ Y) [IsIso g] {f : Y ⟶ X} (h : f ≫ g = 𝟙 Y) : IsIso f := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
g : X ⟶ Y
inst✝ : IsIso g
f : Y ⟶ X
h : f ≫ g = 𝟙 Y
⊢ IsIso f

Next tactic:
rw [(comp_hom_eq_id _).mp h]
theorem isIso_of_comp_hom_eq_id (g : X ⟶ Y) [IsIso g] {f : Y ⟶ X} (h : f ≫ g = 𝟙 Y) : IsIso f := by
  rw [(comp_hom_eq_id _).mp h]
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
g : X ⟶ Y
inst✝ : IsIso g
f : Y ⟶ X
h : f ≫ g = 𝟙 Y
⊢ IsIso (inv g)

Next tactic:
infer_instance
@[simp]
theorem cancel_iso_hom_left {X Y Z : C} (f : X ≅ Y) (g g' : Y ⟶ Z) :
    f.hom ≫ g = f.hom ≫ g' ↔ g = g' := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ Z✝ X Y Z : C
f : X ≅ Y
g g' : Y ⟶ Z
⊢ f.hom ≫ g = f.hom ≫ g' ↔ g = g'

Next tactic:
simp only [cancel_epi]
@[simp]
theorem cancel_iso_inv_left {X Y Z : C} (f : Y ≅ X) (g g' : Y ⟶ Z) :
    f.inv ≫ g = f.inv ≫ g' ↔ g = g' := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ Z✝ X Y Z : C
f : Y ≅ X
g g' : Y ⟶ Z
⊢ f.inv ≫ g = f.inv ≫ g' ↔ g = g'

Next tactic:
simp only [cancel_epi]
@[simp]
theorem cancel_iso_hom_right {X Y Z : C} (f f' : X ⟶ Y) (g : Y ≅ Z) :
    f ≫ g.hom = f' ≫ g.hom ↔ f = f' := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ Z✝ X Y Z : C
f f' : X ⟶ Y
g : Y ≅ Z
⊢ f ≫ g.hom = f' ≫ g.hom ↔ f = f'

Next tactic:
simp only [cancel_mono]
@[simp]
theorem cancel_iso_inv_right {X Y Z : C} (f f' : X ⟶ Y) (g : Z ≅ Y) :
    f ≫ g.inv = f' ≫ g.inv ↔ f = f' := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ Z✝ X Y Z : C
f f' : X ⟶ Y
g : Z ≅ Y
⊢ f ≫ g.inv = f' ≫ g.inv ↔ f = f'

Next tactic:
simp only [cancel_mono]
@[simp]
theorem cancel_iso_hom_right_assoc {W X X' Y Z : C} (f : W ⟶ X) (g : X ⟶ Y) (f' : W ⟶ X')
    (g' : X' ⟶ Y) (h : Y ≅ Z) : f ≫ g ≫ h.hom = f' ≫ g' ≫ h.hom ↔ f ≫ g = f' ≫ g' := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ Z✝ W X X' Y Z : C
f : W ⟶ X
g : X ⟶ Y
f' : W ⟶ X'
g' : X' ⟶ Y
h : Y ≅ Z
⊢ f ≫ g ≫ h.hom = f' ≫ g' ≫ h.hom ↔ f ≫ g = f' ≫ g'

Next tactic:
simp only [← Category.assoc, cancel_mono]
@[simp]
theorem cancel_iso_inv_right_assoc {W X X' Y Z : C} (f : W ⟶ X) (g : X ⟶ Y) (f' : W ⟶ X')
    (g' : X' ⟶ Y) (h : Z ≅ Y) : f ≫ g ≫ h.inv = f' ≫ g' ≫ h.inv ↔ f ≫ g = f' ≫ g' := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ Z✝ W X X' Y Z : C
f : W ⟶ X
g : X ⟶ Y
f' : W ⟶ X'
g' : X' ⟶ Y
h : Z ≅ Y
⊢ f ≫ g ≫ h.inv = f' ≫ g' ≫ h.inv ↔ f ≫ g = f' ≫ g'

Next tactic:
simp only [← Category.assoc, cancel_mono]
/-- A functor `F : C ⥤ D` sends isomorphisms `i : X ≅ Y` to isomorphisms `F.obj X ≅ F.obj Y` -/
@[simps, pp_dot]
def mapIso (F : C ⥤ D) {X Y : C} (i : X ≅ Y) : F.obj X ≅ F.obj Y where
  hom := F.map i.hom
  inv := F.map i.inv
  hom_inv_id := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X✝ Y✝ Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
X Y : C
i : X ≅ Y
⊢ F.map i.hom ≫ F.map i.inv = 𝟙 (F.obj X)

Next tactic:
rw [← map_comp, Iso.hom_inv_id, ← map_id]
/-- A functor `F : C ⥤ D` sends isomorphisms `i : X ≅ Y` to isomorphisms `F.obj X ≅ F.obj Y` -/
@[simps, pp_dot]
def mapIso (F : C ⥤ D) {X Y : C} (i : X ≅ Y) : F.obj X ≅ F.obj Y where
  hom := F.map i.hom
  inv := F.map i.inv
  hom_inv_id := by rw [← map_comp, Iso.hom_inv_id, ← map_id]
  inv_hom_id := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X✝ Y✝ Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
X Y : C
i : X ≅ Y
⊢ F.map i.inv ≫ F.map i.hom = 𝟙 (F.obj Y)

Next tactic:
rw [← map_comp, Iso.inv_hom_id, ← map_id]
@[simp]
theorem mapIso_trans (F : C ⥤ D) {X Y Z : C} (i : X ≅ Y) (j : Y ≅ Z) :
    F.mapIso (i ≪≫ j) = F.mapIso i ≪≫ F.mapIso j :=
  by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X✝ Y✝ Z✝ : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
X Y Z : C
i : X ≅ Y
j : Y ≅ Z
⊢ F.mapIso (i ≪≫ j) = F.mapIso i ≪≫ F.mapIso j

Next tactic:
ext
@[simp]
theorem mapIso_trans (F : C ⥤ D) {X Y Z : C} (i : X ≅ Y) (j : Y ≅ Z) :
    F.mapIso (i ≪≫ j) = F.mapIso i ≪≫ F.mapIso j :=
  by ext; 

Proof state:
case w
C : Type u
inst✝¹ : Category.{v, u} C
X✝ Y✝ Z✝ : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
X Y Z : C
i : X ≅ Y
j : Y ≅ Z
⊢ (F.mapIso (i ≪≫ j)).hom = (F.mapIso i ≪≫ F.mapIso j).hom

Next tactic:
apply Functor.map_comp
@[simp]
theorem map_inv (F : C ⥤ D) {X Y : C} (f : X ⟶ Y) [IsIso f] : F.map (inv f) = inv (F.map f) := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X✝ Y✝ Z : C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
F : C ⥤ D
X Y : C
f : X ⟶ Y
inst✝ : IsIso f
⊢ F.map (inv f) = inv (F.map f)

Next tactic:
apply eq_inv_of_hom_inv_id
@[simp]
theorem map_inv (F : C ⥤ D) {X Y : C} (f : X ⟶ Y) [IsIso f] : F.map (inv f) = inv (F.map f) := by
  apply eq_inv_of_hom_inv_id
  

Proof state:
case hom_inv_id
C : Type u
inst✝² : Category.{v, u} C
X✝ Y✝ Z : C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
F : C ⥤ D
X Y : C
f : X ⟶ Y
inst✝ : IsIso f
⊢ F.map f ≫ F.map (inv f) = 𝟙 (F.obj X)

Next tactic:
simp [← F.map_comp]
theorem map_hom_inv (F : C ⥤ D) {X Y : C} (f : X ⟶ Y) [IsIso f] :
    F.map f ≫ F.map (inv f) = 𝟙 (F.obj X) := by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X✝ Y✝ Z : C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
F : C ⥤ D
X Y : C
f : X ⟶ Y
inst✝ : IsIso f
⊢ F.map f ≫ F.map (inv f) = 𝟙 (F.obj X)

Next tactic:
simp
theorem map_inv_hom (F : C ⥤ D) {X Y : C} (f : X ⟶ Y) [IsIso f] :
    F.map (inv f) ≫ F.map f = 𝟙 (F.obj Y) := by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X✝ Y✝ Z : C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
F : C ⥤ D
X Y : C
f : X ⟶ Y
inst✝ : IsIso f
⊢ F.map (inv f) ≫ F.map f = 𝟙 (F.obj Y)

Next tactic:
simp
@[reassoc]
lemma liftK_π_eq_zero_of_boundary (k : A ⟶ S.X₂) (x : A ⟶ S.X₁) (hx : k = x ≫ S.f) :
    h.liftK k (by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.11868, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
k : A ⟶ S.X₂
x : A ⟶ S.X₁
hx : k = x ≫ S.f
⊢ k ≫ S.g = 0

Next tactic:
rw [hx, assoc, S.zero, comp_zero]
@[reassoc]
lemma liftK_π_eq_zero_of_boundary (k : A ⟶ S.X₂) (x : A ⟶ S.X₁) (hx : k = x ≫ S.f) :
    h.liftK k (by rw [hx, assoc, S.zero, comp_zero]) ≫ h.π = 0 := by
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
k : A ⟶ S.X₂
x : A ⟶ S.X₁
hx : k = x ≫ S.f
⊢ liftK h k (_ : k ≫ S.g = 0) ≫ h.π = 0

Next tactic:
rw [show 0 = (x ≫ h.f') ≫ h.π by simp]
@[reassoc]
lemma liftK_π_eq_zero_of_boundary (k : A ⟶ S.X₂) (x : A ⟶ S.X₁) (hx : k = x ≫ S.f) :
    h.liftK k (by rw [hx, assoc, S.zero, comp_zero]) ≫ h.π = 0 := by
  rw [show 0 = (x ≫ h.f') ≫ h.π by 

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
k : A ⟶ S.X₂
x : A ⟶ S.X₁
hx : k = x ≫ S.f
⊢ 0 = (x ≫ f' h) ≫ h.π

Next tactic:
simp
@[reassoc]
lemma liftK_π_eq_zero_of_boundary (k : A ⟶ S.X₂) (x : A ⟶ S.X₁) (hx : k = x ≫ S.f) :
    h.liftK k (by rw [hx, assoc, S.zero, comp_zero]) ≫ h.π = 0 := by
  rw [show 0 = (x ≫ h.f') ≫ h.π by simp]
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
k : A ⟶ S.X₂
x : A ⟶ S.X₁
hx : k = x ≫ S.f
⊢ liftK h k (_ : k ≫ S.g = 0) ≫ h.π = (x ≫ f' h) ≫ h.π

Next tactic:
congr 1
@[reassoc]
lemma liftK_π_eq_zero_of_boundary (k : A ⟶ S.X₂) (x : A ⟶ S.X₁) (hx : k = x ≫ S.f) :
    h.liftK k (by rw [hx, assoc, S.zero, comp_zero]) ≫ h.π = 0 := by
  rw [show 0 = (x ≫ h.f') ≫ h.π by simp]
  congr 1
  

Proof state:
case e_a
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
k : A ⟶ S.X₂
x : A ⟶ S.X₁
hx : k = x ≫ S.f
⊢ liftK h k (_ : k ≫ S.g = 0) = x ≫ f' h

Next tactic:
simp only [← cancel_mono h.i, hx, liftK_i, assoc, f'_i]
lemma isIso_i (hg : S.g = 0) : IsIso h.i :=
  ⟨h.liftK (𝟙 S.X₂) (by 

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hg : S.g = 0
⊢ 𝟙 S.X₂ ≫ S.g = 0

Next tactic:
rw [hg, id_comp]
lemma isIso_i (hg : S.g = 0) : IsIso h.i :=
  ⟨h.liftK (𝟙 S.X₂) (by rw [hg, id_comp]),
    by 

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hg : S.g = 0
⊢ h.i ≫ liftK h (𝟙 S.X₂) (_ : 𝟙 S.X₂ ≫ S.g = 0) = 𝟙 h.K

Next tactic:
simp only [← cancel_mono h.i, id_comp, assoc, liftK_i, comp_id]
lemma isIso_π (hf : S.f = 0) : IsIso h.π := by
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hf : S.f = 0
⊢ IsIso h.π

Next tactic:
have ⟨φ, hφ⟩ := CokernelCofork.IsColimit.desc' h.hπ' (𝟙 _)
    (by rw [← cancel_mono h.i, comp_id, f'_i, zero_comp, hf])
lemma isIso_π (hf : S.f = 0) : IsIso h.π := by
  have ⟨φ, hφ⟩ := CokernelCofork.IsColimit.desc' h.hπ' (𝟙 _)
    (by 

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hf : S.f = 0
⊢ f' h ≫ 𝟙 h.K = 0

Next tactic:
rw [← cancel_mono h.i, comp_id, f'_i, zero_comp, hf]
lemma isIso_π (hf : S.f = 0) : IsIso h.π := by
  have ⟨φ, hφ⟩ := CokernelCofork.IsColimit.desc' h.hπ' (𝟙 _)
    (by rw [← cancel_mono h.i, comp_id, f'_i, zero_comp, hf])
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hf : S.f = 0
φ : (CokernelCofork.ofπ h.π (_ : f' h ≫ h.π = 0)).pt ⟶ h.K
hφ : Cofork.π (CokernelCofork.ofπ h.π (_ : f' h ≫ h.π = 0)) ≫ φ = 𝟙 h.K
⊢ IsIso h.π

Next tactic:
dsimp at hφ
lemma isIso_π (hf : S.f = 0) : IsIso h.π := by
  have ⟨φ, hφ⟩ := CokernelCofork.IsColimit.desc' h.hπ' (𝟙 _)
    (by rw [← cancel_mono h.i, comp_id, f'_i, zero_comp, hf])
  dsimp at hφ
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hf : S.f = 0
φ : (CokernelCofork.ofπ h.π (_ : f' h ≫ h.π = 0)).pt ⟶ h.K
hφ : h.π ≫ φ = 𝟙 h.K
⊢ IsIso h.π

Next tactic:
exact ⟨φ, hφ, by rw [← cancel_epi h.π, reassoc_of% hφ, comp_id]⟩
lemma isIso_π (hf : S.f = 0) : IsIso h.π := by
  have ⟨φ, hφ⟩ := CokernelCofork.IsColimit.desc' h.hπ' (𝟙 _)
    (by rw [← cancel_mono h.i, comp_id, f'_i, zero_comp, hf])
  dsimp at hφ
  exact ⟨φ, hφ, by 

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hf : S.f = 0
φ : (CokernelCofork.ofπ h.π (_ : f' h ≫ h.π = 0)).pt ⟶ h.K
hφ : h.π ≫ φ = 𝟙 h.K
⊢ φ ≫ h.π = 𝟙 h.H

Next tactic:
rw [← cancel_epi h.π, reassoc_of% hφ, comp_id]
/-- When the second map `S.g` is zero, this is the left homology data on `S` given
by any colimit cokernel cofork of `S.f` -/
@[simps]
def ofIsColimitCokernelCofork (hg : S.g = 0) (c : CokernelCofork S.f) (hc : IsColimit c) :
    S.LeftHomologyData where
  K := S.X₂
  H := c.pt
  i := 𝟙 _
  π := c.π
  wi := by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.20544, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hg : S.g = 0
c : CokernelCofork S.f
hc : IsColimit c
⊢ 𝟙 S.X₂ ≫ S.g = 0

Next tactic:
rw [id_comp, hg]
@[simp] lemma ofIsColimitCokernelCofork_f' (hg : S.g = 0) (c : CokernelCofork S.f)
    (hc : IsColimit c) : (ofIsColimitCokernelCofork S hg c hc).f' = S.f := by
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hg : S.g = 0
c : CokernelCofork S.f
hc : IsColimit c
⊢ f' (ofIsColimitCokernelCofork S hg c hc) = S.f

Next tactic:
rw [← cancel_mono (ofIsColimitCokernelCofork S hg c hc).i, f'_i,
    ofIsColimitCokernelCofork_i]
@[simp] lemma ofIsColimitCokernelCofork_f' (hg : S.g = 0) (c : CokernelCofork S.f)
    (hc : IsColimit c) : (ofIsColimitCokernelCofork S hg c hc).f' = S.f := by
  rw [← cancel_mono (ofIsColimitCokernelCofork S hg c hc).i, f'_i,
    ofIsColimitCokernelCofork_i]
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hg : S.g = 0
c : CokernelCofork S.f
hc : IsColimit c
⊢ S.f = S.f ≫ 𝟙 S.X₂

Next tactic:
dsimp
@[simp] lemma ofIsColimitCokernelCofork_f' (hg : S.g = 0) (c : CokernelCofork S.f)
    (hc : IsColimit c) : (ofIsColimitCokernelCofork S hg c hc).f' = S.f := by
  rw [← cancel_mono (ofIsColimitCokernelCofork S hg c hc).i, f'_i,
    ofIsColimitCokernelCofork_i]
  dsimp
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hg : S.g = 0
c : CokernelCofork S.f
hc : IsColimit c
⊢ S.f = S.f ≫ 𝟙 S.X₂

Next tactic:
rw [comp_id]
/-- When the first map `S.f` is zero, this is the left homology data on `S` given
by any limit kernel fork of `S.g` -/
@[simps]
def ofIsLimitKernelFork (hf : S.f = 0) (c : KernelFork S.g) (hc : IsLimit c) :
    S.LeftHomologyData where
  K := c.pt
  H := c.pt
  i := c.ι
  π := 𝟙 _
  wi := KernelFork.condition _
  hi := IsLimit.ofIsoLimit hc (Fork.ext (Iso.refl _))
  wπ := Fork.IsLimit.hom_ext hc (by
    

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.26101, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hf : S.f = 0
c : KernelFork S.g
hc : IsLimit c
⊢ (IsLimit.lift (IsLimit.ofIsoLimit hc (Fork.ext (Iso.refl c.pt))) (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0)) ≫ 𝟙 c.pt) ≫
      Fork.ι c =
    0 ≫ Fork.ι c

Next tactic:
dsimp
/-- When the first map `S.f` is zero, this is the left homology data on `S` given
by any limit kernel fork of `S.g` -/
@[simps]
def ofIsLimitKernelFork (hf : S.f = 0) (c : KernelFork S.g) (hc : IsLimit c) :
    S.LeftHomologyData where
  K := c.pt
  H := c.pt
  i := c.ι
  π := 𝟙 _
  wi := KernelFork.condition _
  hi := IsLimit.ofIsoLimit hc (Fork.ext (Iso.refl _))
  wπ := Fork.IsLimit.hom_ext hc (by
    dsimp
    

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.26101, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hf : S.f = 0
c : KernelFork S.g
hc : IsLimit c
⊢ ((IsLimit.lift hc (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0)) ≫ 𝟙 c.pt) ≫ 𝟙 c.pt) ≫ Fork.ι c = 0 ≫ Fork.ι c

Next tactic:
simp only [comp_id, zero_comp, Fork.IsLimit.lift_ι, Fork.ι_ofι, hf]
/-- When the first map `S.f` is zero, this is the left homology data on `S` given
by any limit kernel fork of `S.g` -/
@[simps]
def ofIsLimitKernelFork (hf : S.f = 0) (c : KernelFork S.g) (hc : IsLimit c) :
    S.LeftHomologyData where
  K := c.pt
  H := c.pt
  i := c.ι
  π := 𝟙 _
  wi := KernelFork.condition _
  hi := IsLimit.ofIsoLimit hc (Fork.ext (Iso.refl _))
  wπ := Fork.IsLimit.hom_ext hc (by
    dsimp
    simp only [comp_id, zero_comp, Fork.IsLimit.lift_ι, Fork.ι_ofι, hf])
  hπ := CokernelCofork.IsColimit.ofId _ (Fork.IsLimit.hom_ext hc (by
    

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.26101, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hf : S.f = 0
c : KernelFork S.g
hc : IsLimit c
⊢ IsLimit.lift (IsLimit.ofIsoLimit hc (Fork.ext (Iso.refl c.pt))) (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0)) ≫ Fork.ι c =
    0 ≫ Fork.ι c

Next tactic:
dsimp
/-- When the first map `S.f` is zero, this is the left homology data on `S` given
by any limit kernel fork of `S.g` -/
@[simps]
def ofIsLimitKernelFork (hf : S.f = 0) (c : KernelFork S.g) (hc : IsLimit c) :
    S.LeftHomologyData where
  K := c.pt
  H := c.pt
  i := c.ι
  π := 𝟙 _
  wi := KernelFork.condition _
  hi := IsLimit.ofIsoLimit hc (Fork.ext (Iso.refl _))
  wπ := Fork.IsLimit.hom_ext hc (by
    dsimp
    simp only [comp_id, zero_comp, Fork.IsLimit.lift_ι, Fork.ι_ofι, hf])
  hπ := CokernelCofork.IsColimit.ofId _ (Fork.IsLimit.hom_ext hc (by
    dsimp
    

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.26101, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hf : S.f = 0
c : KernelFork S.g
hc : IsLimit c
⊢ (IsLimit.lift hc (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0)) ≫ 𝟙 c.pt) ≫ Fork.ι c = 0 ≫ Fork.ι c

Next tactic:
simp only [comp_id, zero_comp, Fork.IsLimit.lift_ι, Fork.ι_ofι, hf]