l3lab/ntp-mathlib huggingface dataset:
/-- A category with finite products in which coimage-image comparisons are all isomorphisms
is a normal epi category.
-/
def normalEpiCategory : NormalEpiCategory C where
  normalEpiOfEpi f m :=
    { W := kernel f
      g := kernel.ι _
      w := kernel.condition _
      isColimit := by
        haveI : Limits.HasImages C := hasImages
        haveI : HasEqualizers C := Preadditive.hasEqualizers_of_hasKernels
        haveI : HasZeroObject C := Limits.hasZeroObject_of_hasFiniteBiproducts _
        have aux : ∀ (s : CokernelCofork (kernel.ι f)), Cofork.π (CokernelCofork.ofπ f (by simp)) ≫
          inv (imageMonoFactorisation f).m ≫ inv (Abelian.coimageImageComparison f) ≫
          colimit.desc (parallelPair (kernel.ι f) 0) s = Cofork.π s := ?_
        refine' isColimitAux _ (fun A => inv (imageMonoFactorisation f).m ≫
                inv (Abelian.coimageImageComparison f) ≫ colimit.desc _ _) aux _
        · 

Proof state:
case refine_2
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : Preadditive C
inst✝³ : HasKernels C
inst✝² : HasCokernels C
inst✝¹ : ∀ {X Y : C} (f : X ⟶ Y), IsIso (coimageImageComparison f)
inst✝ : HasFiniteProducts C
X✝ Y✝ : C
f : X✝ ⟶ Y✝
m : Epi f
this✝¹ : HasImages C
this✝ : HasEqualizers C
this : HasZeroObject C
aux :
  ∀ (s : CokernelCofork (kernel.ι f)),
    Cofork.π (CokernelCofork.ofπ f (_ : kernel.ι f ≫ f = 0)) ≫
        inv (imageMonoFactorisation f).m ≫
          inv (coimageImageComparison f) ≫ colimit.desc (parallelPair (kernel.ι f) 0) s =
      Cofork.π s
⊢ ∀ (s : CokernelCofork (kernel.ι f)) (m_1 : (CokernelCofork.ofπ f (_ : kernel.ι f ≫ f = 0)).pt ⟶ s.pt),
    Cofork.π (CokernelCofork.ofπ f (_ : kernel.ι f ≫ f = 0)) ≫ m_1 = Cofork.π s →
      m_1 =
        (fun A =>
            inv (imageMonoFactorisation f).m ≫
              inv (coimageImageComparison f) ≫ colimit.desc (parallelPair (kernel.ι f) 0) A)
          s

Next tactic:
intro A g hg
/-- A category with finite products in which coimage-image comparisons are all isomorphisms
is a normal epi category.
-/
def normalEpiCategory : NormalEpiCategory C where
  normalEpiOfEpi f m :=
    { W := kernel f
      g := kernel.ι _
      w := kernel.condition _
      isColimit := by
        haveI : Limits.HasImages C := hasImages
        haveI : HasEqualizers C := Preadditive.hasEqualizers_of_hasKernels
        haveI : HasZeroObject C := Limits.hasZeroObject_of_hasFiniteBiproducts _
        have aux : ∀ (s : CokernelCofork (kernel.ι f)), Cofork.π (CokernelCofork.ofπ f (by simp)) ≫
          inv (imageMonoFactorisation f).m ≫ inv (Abelian.coimageImageComparison f) ≫
          colimit.desc (parallelPair (kernel.ι f) 0) s = Cofork.π s := ?_
        refine' isColimitAux _ (fun A => inv (imageMonoFactorisation f).m ≫
                inv (Abelian.coimageImageComparison f) ≫ colimit.desc _ _) aux _
        · intro A g hg
          

Proof state:
case refine_2
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : Preadditive C
inst✝³ : HasKernels C
inst✝² : HasCokernels C
inst✝¹ : ∀ {X Y : C} (f : X ⟶ Y), IsIso (coimageImageComparison f)
inst✝ : HasFiniteProducts C
X✝ Y✝ : C
f : X✝ ⟶ Y✝
m : Epi f
this✝¹ : HasImages C
this✝ : HasEqualizers C
this : HasZeroObject C
aux :
  ∀ (s : CokernelCofork (kernel.ι f)),
    Cofork.π (CokernelCofork.ofπ f (_ : kernel.ι f ≫ f = 0)) ≫
        inv (imageMonoFactorisation f).m ≫
          inv (coimageImageComparison f) ≫ colimit.desc (parallelPair (kernel.ι f) 0) s =
      Cofork.π s
A : CokernelCofork (kernel.ι f)
g : (CokernelCofork.ofπ f (_ : kernel.ι f ≫ f = 0)).pt ⟶ A.pt
hg : Cofork.π (CokernelCofork.ofπ f (_ : kernel.ι f ≫ f = 0)) ≫ g = Cofork.π A
⊢ g =
    (fun A =>
        inv (imageMonoFactorisation f).m ≫
          inv (coimageImageComparison f) ≫ colimit.desc (parallelPair (kernel.ι f) 0) A)
      A

Next tactic:
rw [CokernelCofork.π_ofπ] at hg
/-- A category with finite products in which coimage-image comparisons are all isomorphisms
is a normal epi category.
-/
def normalEpiCategory : NormalEpiCategory C where
  normalEpiOfEpi f m :=
    { W := kernel f
      g := kernel.ι _
      w := kernel.condition _
      isColimit := by
        haveI : Limits.HasImages C := hasImages
        haveI : HasEqualizers C := Preadditive.hasEqualizers_of_hasKernels
        haveI : HasZeroObject C := Limits.hasZeroObject_of_hasFiniteBiproducts _
        have aux : ∀ (s : CokernelCofork (kernel.ι f)), Cofork.π (CokernelCofork.ofπ f (by simp)) ≫
          inv (imageMonoFactorisation f).m ≫ inv (Abelian.coimageImageComparison f) ≫
          colimit.desc (parallelPair (kernel.ι f) 0) s = Cofork.π s := ?_
        refine' isColimitAux _ (fun A => inv (imageMonoFactorisation f).m ≫
                inv (Abelian.coimageImageComparison f) ≫ colimit.desc _ _) aux _
        · intro A g hg
          rw [CokernelCofork.π_ofπ] at hg
          

Proof state:
case refine_2
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : Preadditive C
inst✝³ : HasKernels C
inst✝² : HasCokernels C
inst✝¹ : ∀ {X Y : C} (f : X ⟶ Y), IsIso (coimageImageComparison f)
inst✝ : HasFiniteProducts C
X✝ Y✝ : C
f : X✝ ⟶ Y✝
m : Epi f
this✝¹ : HasImages C
this✝ : HasEqualizers C
this : HasZeroObject C
aux :
  ∀ (s : CokernelCofork (kernel.ι f)),
    Cofork.π (CokernelCofork.ofπ f (_ : kernel.ι f ≫ f = 0)) ≫
        inv (imageMonoFactorisation f).m ≫
          inv (coimageImageComparison f) ≫ colimit.desc (parallelPair (kernel.ι f) 0) s =
      Cofork.π s
A : CokernelCofork (kernel.ι f)
g : (CokernelCofork.ofπ f (_ : kernel.ι f ≫ f = 0)).pt ⟶ A.pt
hg : f ≫ g = Cofork.π A
⊢ g =
    (fun A =>
        inv (imageMonoFactorisation f).m ≫
          inv (coimageImageComparison f) ≫ colimit.desc (parallelPair (kernel.ι f) 0) A)
      A

Next tactic:
rw [← cancel_epi f, hg, ← aux, CokernelCofork.π_ofπ]
/-- A category with finite products in which coimage-image comparisons are all isomorphisms
is a normal epi category.
-/
def normalEpiCategory : NormalEpiCategory C where
  normalEpiOfEpi f m :=
    { W := kernel f
      g := kernel.ι _
      w := kernel.condition _
      isColimit := by
        haveI : Limits.HasImages C := hasImages
        haveI : HasEqualizers C := Preadditive.hasEqualizers_of_hasKernels
        haveI : HasZeroObject C := Limits.hasZeroObject_of_hasFiniteBiproducts _
        have aux : ∀ (s : CokernelCofork (kernel.ι f)), Cofork.π (CokernelCofork.ofπ f (by simp)) ≫
          inv (imageMonoFactorisation f).m ≫ inv (Abelian.coimageImageComparison f) ≫
          colimit.desc (parallelPair (kernel.ι f) 0) s = Cofork.π s := ?_
        refine' isColimitAux _ (fun A => inv (imageMonoFactorisation f).m ≫
                inv (Abelian.coimageImageComparison f) ≫ colimit.desc _ _) aux _
        · intro A g hg
          rw [CokernelCofork.π_ofπ] at hg
          rw [← cancel_epi f, hg, ← aux, CokernelCofork.π_ofπ]
        · 

Proof state:
case refine_1
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : Preadditive C
inst✝³ : HasKernels C
inst✝² : HasCokernels C
inst✝¹ : ∀ {X Y : C} (f : X ⟶ Y), IsIso (coimageImageComparison f)
inst✝ : HasFiniteProducts C
X✝ Y✝ : C
f : X✝ ⟶ Y✝
m : Epi f
this✝¹ : HasImages C
this✝ : HasEqualizers C
this : HasZeroObject C
⊢ ∀ (s : CokernelCofork (kernel.ι f)),
    Cofork.π (CokernelCofork.ofπ f (_ : kernel.ι f ≫ f = 0)) ≫
        inv (imageMonoFactorisation f).m ≫
          inv (coimageImageComparison f) ≫ colimit.desc (parallelPair (kernel.ι f) 0) s =
      Cofork.π s

Next tactic:
intro A
/-- A category with finite products in which coimage-image comparisons are all isomorphisms
is a normal epi category.
-/
def normalEpiCategory : NormalEpiCategory C where
  normalEpiOfEpi f m :=
    { W := kernel f
      g := kernel.ι _
      w := kernel.condition _
      isColimit := by
        haveI : Limits.HasImages C := hasImages
        haveI : HasEqualizers C := Preadditive.hasEqualizers_of_hasKernels
        haveI : HasZeroObject C := Limits.hasZeroObject_of_hasFiniteBiproducts _
        have aux : ∀ (s : CokernelCofork (kernel.ι f)), Cofork.π (CokernelCofork.ofπ f (by simp)) ≫
          inv (imageMonoFactorisation f).m ≫ inv (Abelian.coimageImageComparison f) ≫
          colimit.desc (parallelPair (kernel.ι f) 0) s = Cofork.π s := ?_
        refine' isColimitAux _ (fun A => inv (imageMonoFactorisation f).m ≫
                inv (Abelian.coimageImageComparison f) ≫ colimit.desc _ _) aux _
        · intro A g hg
          rw [CokernelCofork.π_ofπ] at hg
          rw [← cancel_epi f, hg, ← aux, CokernelCofork.π_ofπ]
        · intro A
          

Proof state:
case refine_1
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : Preadditive C
inst✝³ : HasKernels C
inst✝² : HasCokernels C
inst✝¹ : ∀ {X Y : C} (f : X ⟶ Y), IsIso (coimageImageComparison f)
inst✝ : HasFiniteProducts C
X✝ Y✝ : C
f : X✝ ⟶ Y✝
m : Epi f
this✝¹ : HasImages C
this✝ : HasEqualizers C
this : HasZeroObject C
A : CokernelCofork (kernel.ι f)
⊢ Cofork.π (CokernelCofork.ofπ f (_ : kernel.ι f ≫ f = 0)) ≫
      inv (imageMonoFactorisation f).m ≫ inv (coimageImageComparison f) ≫ colimit.desc (parallelPair (kernel.ι f) 0) A =
    Cofork.π A

Next tactic:
simp only [CokernelCofork.π_ofπ, ← Category.assoc]
/-- A category with finite products in which coimage-image comparisons are all isomorphisms
is a normal epi category.
-/
def normalEpiCategory : NormalEpiCategory C where
  normalEpiOfEpi f m :=
    { W := kernel f
      g := kernel.ι _
      w := kernel.condition _
      isColimit := by
        haveI : Limits.HasImages C := hasImages
        haveI : HasEqualizers C := Preadditive.hasEqualizers_of_hasKernels
        haveI : HasZeroObject C := Limits.hasZeroObject_of_hasFiniteBiproducts _
        have aux : ∀ (s : CokernelCofork (kernel.ι f)), Cofork.π (CokernelCofork.ofπ f (by simp)) ≫
          inv (imageMonoFactorisation f).m ≫ inv (Abelian.coimageImageComparison f) ≫
          colimit.desc (parallelPair (kernel.ι f) 0) s = Cofork.π s := ?_
        refine' isColimitAux _ (fun A => inv (imageMonoFactorisation f).m ≫
                inv (Abelian.coimageImageComparison f) ≫ colimit.desc _ _) aux _
        · intro A g hg
          rw [CokernelCofork.π_ofπ] at hg
          rw [← cancel_epi f, hg, ← aux, CokernelCofork.π_ofπ]
        · intro A
          simp only [CokernelCofork.π_ofπ, ← Category.assoc]
          

Proof state:
case refine_1
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : Preadditive C
inst✝³ : HasKernels C
inst✝² : HasCokernels C
inst✝¹ : ∀ {X Y : C} (f : X ⟶ Y), IsIso (coimageImageComparison f)
inst✝ : HasFiniteProducts C
X✝ Y✝ : C
f : X✝ ⟶ Y✝
m : Epi f
this✝¹ : HasImages C
this✝ : HasEqualizers C
this : HasZeroObject C
A : CokernelCofork (kernel.ι f)
⊢ ((f ≫ inv (imageMonoFactorisation f).m) ≫ inv (coimageImageComparison f)) ≫
      colimit.desc (parallelPair (kernel.ι f) 0) A =
    Cofork.π A

Next tactic:
convert colimit.ι_desc A WalkingParallelPair.one using 2
/-- A category with finite products in which coimage-image comparisons are all isomorphisms
is a normal epi category.
-/
def normalEpiCategory : NormalEpiCategory C where
  normalEpiOfEpi f m :=
    { W := kernel f
      g := kernel.ι _
      w := kernel.condition _
      isColimit := by
        haveI : Limits.HasImages C := hasImages
        haveI : HasEqualizers C := Preadditive.hasEqualizers_of_hasKernels
        haveI : HasZeroObject C := Limits.hasZeroObject_of_hasFiniteBiproducts _
        have aux : ∀ (s : CokernelCofork (kernel.ι f)), Cofork.π (CokernelCofork.ofπ f (by simp)) ≫
          inv (imageMonoFactorisation f).m ≫ inv (Abelian.coimageImageComparison f) ≫
          colimit.desc (parallelPair (kernel.ι f) 0) s = Cofork.π s := ?_
        refine' isColimitAux _ (fun A => inv (imageMonoFactorisation f).m ≫
                inv (Abelian.coimageImageComparison f) ≫ colimit.desc _ _) aux _
        · intro A g hg
          rw [CokernelCofork.π_ofπ] at hg
          rw [← cancel_epi f, hg, ← aux, CokernelCofork.π_ofπ]
        · intro A
          simp only [CokernelCofork.π_ofπ, ← Category.assoc]
          convert colimit.ι_desc A WalkingParallelPair.one using 2
          

Proof state:
case h.e'_2.h.e'_6
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : Preadditive C
inst✝³ : HasKernels C
inst✝² : HasCokernels C
inst✝¹ : ∀ {X Y : C} (f : X ⟶ Y), IsIso (coimageImageComparison f)
inst✝ : HasFiniteProducts C
X✝ Y✝ : C
f : X✝ ⟶ Y✝
m : Epi f
this✝¹ : HasImages C
this✝ : HasEqualizers C
this : HasZeroObject C
A : CokernelCofork (kernel.ι f)
⊢ (f ≫ inv (imageMonoFactorisation f).m) ≫ inv (coimageImageComparison f) =
    colimit.ι (parallelPair (kernel.ι f) 0) WalkingParallelPair.one

Next tactic:
rw [IsIso.comp_inv_eq, IsIso.comp_inv_eq, eq_comm, ← imageMonoFactorisation_e']
/-- A category with finite products in which coimage-image comparisons are all isomorphisms
is a normal epi category.
-/
def normalEpiCategory : NormalEpiCategory C where
  normalEpiOfEpi f m :=
    { W := kernel f
      g := kernel.ι _
      w := kernel.condition _
      isColimit := by
        haveI : Limits.HasImages C := hasImages
        haveI : HasEqualizers C := Preadditive.hasEqualizers_of_hasKernels
        haveI : HasZeroObject C := Limits.hasZeroObject_of_hasFiniteBiproducts _
        have aux : ∀ (s : CokernelCofork (kernel.ι f)), Cofork.π (CokernelCofork.ofπ f (by simp)) ≫
          inv (imageMonoFactorisation f).m ≫ inv (Abelian.coimageImageComparison f) ≫
          colimit.desc (parallelPair (kernel.ι f) 0) s = Cofork.π s := ?_
        refine' isColimitAux _ (fun A => inv (imageMonoFactorisation f).m ≫
                inv (Abelian.coimageImageComparison f) ≫ colimit.desc _ _) aux _
        · intro A g hg
          rw [CokernelCofork.π_ofπ] at hg
          rw [← cancel_epi f, hg, ← aux, CokernelCofork.π_ofπ]
        · intro A
          simp only [CokernelCofork.π_ofπ, ← Category.assoc]
          convert colimit.ι_desc A WalkingParallelPair.one using 2
          rw [IsIso.comp_inv_eq, IsIso.comp_inv_eq, eq_comm, ← imageMonoFactorisation_e']
          

Proof state:
case h.e'_2.h.e'_6
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : Preadditive C
inst✝³ : HasKernels C
inst✝² : HasCokernels C
inst✝¹ : ∀ {X Y : C} (f : X ⟶ Y), IsIso (coimageImageComparison f)
inst✝ : HasFiniteProducts C
X✝ Y✝ : C
f : X✝ ⟶ Y✝
m : Epi f
this✝¹ : HasImages C
this✝ : HasEqualizers C
this : HasZeroObject C
A : CokernelCofork (kernel.ι f)
⊢ (imageMonoFactorisation f).e ≫ (imageMonoFactorisation f).m = f

Next tactic:
exact (imageMonoFactorisation f).fac
/-- The map `p : P ⟶ image f` is an epimorphism -/
instance : Epi (Abelian.factorThruImage f) := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q : C
f : P ⟶ Q
⊢ Epi (Abelian.factorThruImage f)

Next tactic:
infer_instance
instance isIso_factorThruImage [Mono f] : IsIso (Abelian.factorThruImage f) := by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Abelian C
P Q : C
f : P ⟶ Q
inst✝ : Mono f
⊢ IsIso (Abelian.factorThruImage f)

Next tactic:
infer_instance
/-- The canonical morphism `i : coimage f ⟶ Q` is a monomorphism -/
instance : Mono (Abelian.factorThruCoimage f) := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q : C
f : P ⟶ Q
⊢ Mono (Abelian.factorThruCoimage f)

Next tactic:
infer_instance
instance isIso_factorThruCoimage [Epi f] : IsIso (Abelian.factorThruCoimage f) := by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Abelian C
P Q : C
f : P ⟶ Q
inst✝ : Epi f
⊢ IsIso (Abelian.factorThruCoimage f)

Next tactic:
infer_instance
theorem epi_of_cokernel_π_eq_zero (h : cokernel.π f = 0) : Epi f := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q : C
f : P ⟶ Q
h : cokernel.π f = 0
⊢ Epi f

Next tactic:
apply NormalMonoCategory.epi_of_zero_cokernel _ (cokernel f)
theorem epi_of_cokernel_π_eq_zero (h : cokernel.π f = 0) : Epi f := by
  apply NormalMonoCategory.epi_of_zero_cokernel _ (cokernel f)
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q : C
f : P ⟶ Q
h : cokernel.π f = 0
⊢ IsColimit (CokernelCofork.ofπ 0 (_ : f ≫ 0 = 0))

Next tactic:
simp_rw [← h]
theorem epi_of_cokernel_π_eq_zero (h : cokernel.π f = 0) : Epi f := by
  apply NormalMonoCategory.epi_of_zero_cokernel _ (cokernel f)
  simp_rw [← h]
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q : C
f : P ⟶ Q
h : cokernel.π f = 0
⊢ IsColimit (CokernelCofork.ofπ (cokernel.π f) (_ : f ≫ cokernel.π f = 0))

Next tactic:
exact IsColimit.ofIsoColimit (colimit.isColimit (parallelPair f 0)) (isoOfπ _)
theorem image_ι_comp_eq_zero {R : C} {g : Q ⟶ R} (h : f ≫ g = 0) : Abelian.image.ι f ≫ g = 0 :=
  zero_of_epi_comp (Abelian.factorThruImage f) <| by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q : C
f : P ⟶ Q
R : C
g : Q ⟶ R
h : f ≫ g = 0
⊢ Abelian.factorThruImage f ≫ image.ι f ≫ g = 0

Next tactic:
simp [h]
theorem comp_coimage_π_eq_zero {R : C} {g : Q ⟶ R} (h : f ≫ g = 0) : f ≫ Abelian.coimage.π g = 0 :=
  zero_of_comp_mono (Abelian.factorThruCoimage g) <| by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q : C
f : P ⟶ Q
R : C
g : Q ⟶ R
h : f ≫ g = 0
⊢ (f ≫ coimage.π g) ≫ Abelian.factorThruCoimage g = 0

Next tactic:
simp [h]
/-- Factoring through the image is a strong epi-mono factorisation. -/
@[simps]
def imageStrongEpiMonoFactorisation : StrongEpiMonoFactorisation f where
  I := Abelian.image f
  m := image.ι f
  m_mono := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q : C
f : P ⟶ Q
⊢ Mono (image.ι f)

Next tactic:
infer_instance
/-- Factoring through the coimage is a strong epi-mono factorisation. -/
@[simps]
def coimageStrongEpiMonoFactorisation : StrongEpiMonoFactorisation f where
  I := Abelian.coimage f
  m := Abelian.factorThruCoimage f
  m_mono := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q : C
f : P ⟶ Q
⊢ Mono (Abelian.factorThruCoimage f)

Next tactic:
infer_instance
example : HasImages C := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
⊢ HasImages C

Next tactic:
infer_instance
example : HasImageMaps C := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
⊢ HasImageMaps C

Next tactic:
infer_instance
/-- The coimage-image comparison morphism is always an isomorphism in an abelian category.
See `CategoryTheory.Abelian.ofCoimageImageComparisonIsIso` for the converse.
-/
instance : IsIso (coimageImageComparison f) := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
X Y : C
f : X ⟶ Y
⊢ IsIso (coimageImageComparison f)

Next tactic:
convert
    IsIso.of_iso
      (IsImage.isoExt (coimageStrongEpiMonoFactorisation f).toMonoIsImage
        (imageStrongEpiMonoFactorisation f).toMonoIsImage)
/-- The coimage-image comparison morphism is always an isomorphism in an abelian category.
See `CategoryTheory.Abelian.ofCoimageImageComparisonIsIso` for the converse.
-/
instance : IsIso (coimageImageComparison f) := by
  convert
    IsIso.of_iso
      (IsImage.isoExt (coimageStrongEpiMonoFactorisation f).toMonoIsImage
        (imageStrongEpiMonoFactorisation f).toMonoIsImage)
  

Proof state:
case h.e'_5.h
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
X Y : C
f : X ⟶ Y
e_3✝ : Abelian.coimage f = (coimageStrongEpiMonoFactorisation f).toMonoFactorisation.I
e_4✝ : Abelian.image f = (imageStrongEpiMonoFactorisation f).toMonoFactorisation.I
⊢ coimageImageComparison f =
    (IsImage.isoExt (StrongEpiMonoFactorisation.toMonoIsImage (coimageStrongEpiMonoFactorisation f))
        (StrongEpiMonoFactorisation.toMonoIsImage (imageStrongEpiMonoFactorisation f))).hom

Next tactic:
ext
/-- The coimage-image comparison morphism is always an isomorphism in an abelian category.
See `CategoryTheory.Abelian.ofCoimageImageComparisonIsIso` for the converse.
-/
instance : IsIso (coimageImageComparison f) := by
  convert
    IsIso.of_iso
      (IsImage.isoExt (coimageStrongEpiMonoFactorisation f).toMonoIsImage
        (imageStrongEpiMonoFactorisation f).toMonoIsImage)
  ext
  

Proof state:
case h.e'_5.h.h.h
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
X Y : C
f : X ⟶ Y
e_3✝ : Abelian.coimage f = (coimageStrongEpiMonoFactorisation f).toMonoFactorisation.I
e_4✝ : Abelian.image f = (imageStrongEpiMonoFactorisation f).toMonoFactorisation.I
⊢ (coequalizer.π (kernel.ι f) 0 ≫ coimageImageComparison f) ≫ equalizer.ι (cokernel.π f) 0 =
    (coequalizer.π (kernel.ι f) 0 ≫
        (IsImage.isoExt (StrongEpiMonoFactorisation.toMonoIsImage (coimageStrongEpiMonoFactorisation f))
            (StrongEpiMonoFactorisation.toMonoIsImage (imageStrongEpiMonoFactorisation f))).hom) ≫
      equalizer.ι (cokernel.π f) 0

Next tactic:
change _ = _ ≫ (imageStrongEpiMonoFactorisation f).m
/-- The coimage-image comparison morphism is always an isomorphism in an abelian category.
See `CategoryTheory.Abelian.ofCoimageImageComparisonIsIso` for the converse.
-/
instance : IsIso (coimageImageComparison f) := by
  convert
    IsIso.of_iso
      (IsImage.isoExt (coimageStrongEpiMonoFactorisation f).toMonoIsImage
        (imageStrongEpiMonoFactorisation f).toMonoIsImage)
  ext
  change _ = _ ≫ (imageStrongEpiMonoFactorisation f).m
  

Proof state:
case h.e'_5.h.h.h
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
X Y : C
f : X ⟶ Y
e_3✝ : Abelian.coimage f = (coimageStrongEpiMonoFactorisation f).toMonoFactorisation.I
e_4✝ : Abelian.image f = (imageStrongEpiMonoFactorisation f).toMonoFactorisation.I
⊢ (coequalizer.π (kernel.ι f) 0 ≫ coimageImageComparison f) ≫ equalizer.ι (cokernel.π f) 0 =
    (coequalizer.π (kernel.ι f) 0 ≫
        (IsImage.isoExt (StrongEpiMonoFactorisation.toMonoIsImage (coimageStrongEpiMonoFactorisation f))
            (StrongEpiMonoFactorisation.toMonoIsImage (imageStrongEpiMonoFactorisation f))).hom) ≫
      (imageStrongEpiMonoFactorisation f).toMonoFactorisation.m

Next tactic:
simp [-imageStrongEpiMonoFactorisation_m]
theorem coimageIsoImage'_hom :
    (coimageIsoImage' f).hom =
      cokernel.desc _ (factorThruImage f) (by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
X Y : C
f : X ⟶ Y
⊢ kernel.ι f ≫ factorThruImage f = 0

Next tactic:
simp [← cancel_mono (Limits.image.ι f)]
theorem coimageIsoImage'_hom :
    (coimageIsoImage' f).hom =
      cokernel.desc _ (factorThruImage f) (by simp [← cancel_mono (Limits.image.ι f)]) := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
X Y : C
f : X ⟶ Y
⊢ (coimageIsoImage' f).hom = cokernel.desc (kernel.ι f) (factorThruImage f) (_ : kernel.ι f ≫ factorThruImage f = 0)

Next tactic:
ext
theorem coimageIsoImage'_hom :
    (coimageIsoImage' f).hom =
      cokernel.desc _ (factorThruImage f) (by simp [← cancel_mono (Limits.image.ι f)]) := by
  ext
  

Proof state:
case h
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
X Y : C
f : X ⟶ Y
⊢ coequalizer.π (kernel.ι f) 0 ≫ (coimageIsoImage' f).hom =
    coequalizer.π (kernel.ι f) 0 ≫
      cokernel.desc (kernel.ι f) (factorThruImage f) (_ : kernel.ι f ≫ factorThruImage f = 0)

Next tactic:
simp only [← cancel_mono (Limits.image.ι f), IsImage.isoExt_hom, cokernel.π_desc,
    Category.assoc, IsImage.lift_ι, coimageStrongEpiMonoFactorisation_m,
    Limits.image.fac]
theorem factorThruImage_comp_coimageIsoImage'_inv :
    factorThruImage f ≫ (coimageIsoImage' f).inv = cokernel.π _ := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
X Y : C
f : X ⟶ Y
⊢ factorThruImage f ≫ (coimageIsoImage' f).inv = cokernel.π (kernel.ι f)

Next tactic:
simp only [IsImage.isoExt_inv, image.isImage_lift, image.fac_lift,
    coimageStrongEpiMonoFactorisation_e]
theorem imageIsoImage_hom_comp_image_ι : (imageIsoImage f).hom ≫ Limits.image.ι _ = kernel.ι _ := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
X Y : C
f : X ⟶ Y
⊢ (imageIsoImage f).hom ≫ Limits.image.ι f = kernel.ι (cokernel.π f)

Next tactic:
simp only [IsImage.isoExt_hom, IsImage.lift_ι, imageStrongEpiMonoFactorisation_m]
theorem imageIsoImage_inv :
    (imageIsoImage f).inv =
      kernel.lift _ (Limits.image.ι f) (by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
X Y : C
f : X ⟶ Y
⊢ Limits.image.ι f ≫ cokernel.π f = 0

Next tactic:
simp [← cancel_epi (factorThruImage f)]