l3lab/ntp-mathlib huggingface dataset:
/-- A functor between preadditive categories preserves the coequalizer of two
morphisms if it preserves all cokernels. -/
def preservesCoequalizerOfPreservesCokernels
    [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] {X Y : C} (f g : X ⟶ Y) :
    PreservesColimit (parallelPair f g) F := by
  letI := preservesBinaryBiproductsOfPreservesBinaryCoproducts F
  haveI := additive_of_preservesBinaryBiproducts F
  constructor
  intro c i
  let c' := isColimitCokernelCoforkOfCofork (i.ofIsoColimit (Cofork.isoCoforkOfπ c))
  dsimp only [cokernelCoforkOfCofork_ofπ] at c'
  

Proof state:
case preserves
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₂
inst✝⁴ : Category.{v₂, u₂} D
inst✝³ : Preadditive D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
inst✝¹ : HasBinaryBiproducts C
inst✝ : {X Y : C} → (f : X ⟶ Y) → PreservesColimit (parallelPair f 0) F
X Y : C
f g : X ⟶ Y
this✝ : PreservesBinaryBiproducts F := preservesBinaryBiproductsOfPreservesBinaryCoproducts F
this : Additive F
c : Cocone (parallelPair f g)
i : IsColimit c
c' : IsColimit (CokernelCofork.ofπ (Cofork.π c) (_ : (f - g) ≫ Cofork.π c = 0)) :=
  isColimitCokernelCoforkOfCofork (IsColimit.ofIsoColimit i (Cofork.isoCoforkOfπ c))
⊢ IsColimit (F.mapCocone c)

Next tactic:
let iFc := isColimitCoforkMapOfIsColimit' F _ c'
/-- A functor between preadditive categories preserves the coequalizer of two
morphisms if it preserves all cokernels. -/
def preservesCoequalizerOfPreservesCokernels
    [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] {X Y : C} (f g : X ⟶ Y) :
    PreservesColimit (parallelPair f g) F := by
  letI := preservesBinaryBiproductsOfPreservesBinaryCoproducts F
  haveI := additive_of_preservesBinaryBiproducts F
  constructor
  intro c i
  let c' := isColimitCokernelCoforkOfCofork (i.ofIsoColimit (Cofork.isoCoforkOfπ c))
  dsimp only [cokernelCoforkOfCofork_ofπ] at c'
  let iFc := isColimitCoforkMapOfIsColimit' F _ c'
  

Proof state:
case preserves
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₂
inst✝⁴ : Category.{v₂, u₂} D
inst✝³ : Preadditive D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
inst✝¹ : HasBinaryBiproducts C
inst✝ : {X Y : C} → (f : X ⟶ Y) → PreservesColimit (parallelPair f 0) F
X Y : C
f g : X ⟶ Y
this✝ : PreservesBinaryBiproducts F := preservesBinaryBiproductsOfPreservesBinaryCoproducts F
this : Additive F
c : Cocone (parallelPair f g)
i : IsColimit c
c' : IsColimit (CokernelCofork.ofπ (Cofork.π c) (_ : (f - g) ≫ Cofork.π c = 0)) :=
  isColimitCokernelCoforkOfCofork (IsColimit.ofIsoColimit i (Cofork.isoCoforkOfπ c))
iFc : IsColimit (CokernelCofork.ofπ (F.map (Cofork.π c)) (_ : F.map (f - g) ≫ F.map (Cofork.π c) = 0)) :=
  isColimitCoforkMapOfIsColimit' F (_ : (f - g) ≫ Cofork.π c = 0) c'
⊢ IsColimit (F.mapCocone c)

Next tactic:
apply
    IsColimit.ofIsoColimit _ ((Cocones.functoriality _ F).mapIso (Cofork.isoCoforkOfπ c).symm)
/-- A functor between preadditive categories preserves the coequalizer of two
morphisms if it preserves all cokernels. -/
def preservesCoequalizerOfPreservesCokernels
    [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] {X Y : C} (f g : X ⟶ Y) :
    PreservesColimit (parallelPair f g) F := by
  letI := preservesBinaryBiproductsOfPreservesBinaryCoproducts F
  haveI := additive_of_preservesBinaryBiproducts F
  constructor
  intro c i
  let c' := isColimitCokernelCoforkOfCofork (i.ofIsoColimit (Cofork.isoCoforkOfπ c))
  dsimp only [cokernelCoforkOfCofork_ofπ] at c'
  let iFc := isColimitCoforkMapOfIsColimit' F _ c'
  apply
    IsColimit.ofIsoColimit _ ((Cocones.functoriality _ F).mapIso (Cofork.isoCoforkOfπ c).symm)
  

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₂
inst✝⁴ : Category.{v₂, u₂} D
inst✝³ : Preadditive D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
inst✝¹ : HasBinaryBiproducts C
inst✝ : {X Y : C} → (f : X ⟶ Y) → PreservesColimit (parallelPair f 0) F
X Y : C
f g : X ⟶ Y
this✝ : PreservesBinaryBiproducts F := preservesBinaryBiproductsOfPreservesBinaryCoproducts F
this : Additive F
c : Cocone (parallelPair f g)
i : IsColimit c
c' : IsColimit (CokernelCofork.ofπ (Cofork.π c) (_ : (f - g) ≫ Cofork.π c = 0)) :=
  isColimitCokernelCoforkOfCofork (IsColimit.ofIsoColimit i (Cofork.isoCoforkOfπ c))
iFc : IsColimit (CokernelCofork.ofπ (F.map (Cofork.π c)) (_ : F.map (f - g) ≫ F.map (Cofork.π c) = 0)) :=
  isColimitCoforkMapOfIsColimit' F (_ : (f - g) ≫ Cofork.π c = 0) c'
⊢ IsColimit
    ((Cocones.functoriality (parallelPair f g) F).obj (Cofork.ofπ (Cofork.π c) (_ : f ≫ Cofork.π c = g ≫ Cofork.π c)))

Next tactic:
apply (isColimitMapCoconeCoforkEquiv F (Cofork.condition c)).invFun
/-- A functor between preadditive categories preserves the coequalizer of two
morphisms if it preserves all cokernels. -/
def preservesCoequalizerOfPreservesCokernels
    [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] {X Y : C} (f g : X ⟶ Y) :
    PreservesColimit (parallelPair f g) F := by
  letI := preservesBinaryBiproductsOfPreservesBinaryCoproducts F
  haveI := additive_of_preservesBinaryBiproducts F
  constructor
  intro c i
  let c' := isColimitCokernelCoforkOfCofork (i.ofIsoColimit (Cofork.isoCoforkOfπ c))
  dsimp only [cokernelCoforkOfCofork_ofπ] at c'
  let iFc := isColimitCoforkMapOfIsColimit' F _ c'
  apply
    IsColimit.ofIsoColimit _ ((Cocones.functoriality _ F).mapIso (Cofork.isoCoforkOfπ c).symm)
  apply (isColimitMapCoconeCoforkEquiv F (Cofork.condition c)).invFun
  

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₂
inst✝⁴ : Category.{v₂, u₂} D
inst✝³ : Preadditive D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
inst✝¹ : HasBinaryBiproducts C
inst✝ : {X Y : C} → (f : X ⟶ Y) → PreservesColimit (parallelPair f 0) F
X Y : C
f g : X ⟶ Y
this✝ : PreservesBinaryBiproducts F := preservesBinaryBiproductsOfPreservesBinaryCoproducts F
this : Additive F
c : Cocone (parallelPair f g)
i : IsColimit c
c' : IsColimit (CokernelCofork.ofπ (Cofork.π c) (_ : (f - g) ≫ Cofork.π c = 0)) :=
  isColimitCokernelCoforkOfCofork (IsColimit.ofIsoColimit i (Cofork.isoCoforkOfπ c))
iFc : IsColimit (CokernelCofork.ofπ (F.map (Cofork.π c)) (_ : F.map (f - g) ≫ F.map (Cofork.π c) = 0)) :=
  isColimitCoforkMapOfIsColimit' F (_ : (f - g) ≫ Cofork.π c = 0) c'
⊢ IsColimit (Cofork.ofπ (F.map (Cofork.π c)) (_ : F.map f ≫ F.map (Cofork.π c) = F.map g ≫ F.map (Cofork.π c)))

Next tactic:
let p : parallelPair (F.map (f - g)) 0 ≅ parallelPair (F.map f - F.map g) 0 :=
    parallelPair.ext (Iso.refl _) (Iso.refl _) (by simp) (by simp)
/-- A functor between preadditive categories preserves the coequalizer of two
morphisms if it preserves all cokernels. -/
def preservesCoequalizerOfPreservesCokernels
    [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] {X Y : C} (f g : X ⟶ Y) :
    PreservesColimit (parallelPair f g) F := by
  letI := preservesBinaryBiproductsOfPreservesBinaryCoproducts F
  haveI := additive_of_preservesBinaryBiproducts F
  constructor
  intro c i
  let c' := isColimitCokernelCoforkOfCofork (i.ofIsoColimit (Cofork.isoCoforkOfπ c))
  dsimp only [cokernelCoforkOfCofork_ofπ] at c'
  let iFc := isColimitCoforkMapOfIsColimit' F _ c'
  apply
    IsColimit.ofIsoColimit _ ((Cocones.functoriality _ F).mapIso (Cofork.isoCoforkOfπ c).symm)
  apply (isColimitMapCoconeCoforkEquiv F (Cofork.condition c)).invFun
  let p : parallelPair (F.map (f - g)) 0 ≅ parallelPair (F.map f - F.map g) 0 :=
    parallelPair.ext (Iso.refl _) (Iso.refl _) (by 

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₂
inst✝⁴ : Category.{v₂, u₂} D
inst✝³ : Preadditive D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
inst✝¹ : HasBinaryBiproducts C
inst✝ : {X Y : C} → (f : X ⟶ Y) → PreservesColimit (parallelPair f 0) F
X Y : C
f g : X ⟶ Y
this✝ : PreservesBinaryBiproducts F := preservesBinaryBiproductsOfPreservesBinaryCoproducts F
this : Additive F
c : Cocone (parallelPair f g)
i : IsColimit c
c' : IsColimit (CokernelCofork.ofπ (Cofork.π c) (_ : (f - g) ≫ Cofork.π c = 0)) :=
  isColimitCokernelCoforkOfCofork (IsColimit.ofIsoColimit i (Cofork.isoCoforkOfπ c))
iFc : IsColimit (CokernelCofork.ofπ (F.map (Cofork.π c)) (_ : F.map (f - g) ≫ F.map (Cofork.π c) = 0)) :=
  isColimitCoforkMapOfIsColimit' F (_ : (f - g) ≫ Cofork.π c = 0) c'
⊢ (parallelPair (F.map (f - g)) 0).map WalkingParallelPairHom.left ≫
      (Iso.refl ((parallelPair (F.map (f - g)) 0).obj WalkingParallelPair.one)).hom =
    (Iso.refl ((parallelPair (F.map (f - g)) 0).obj WalkingParallelPair.zero)).hom ≫
      (parallelPair (F.map f - F.map g) 0).map WalkingParallelPairHom.left

Next tactic:
simp
/-- A functor between preadditive categories preserves the coequalizer of two
morphisms if it preserves all cokernels. -/
def preservesCoequalizerOfPreservesCokernels
    [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] {X Y : C} (f g : X ⟶ Y) :
    PreservesColimit (parallelPair f g) F := by
  letI := preservesBinaryBiproductsOfPreservesBinaryCoproducts F
  haveI := additive_of_preservesBinaryBiproducts F
  constructor
  intro c i
  let c' := isColimitCokernelCoforkOfCofork (i.ofIsoColimit (Cofork.isoCoforkOfπ c))
  dsimp only [cokernelCoforkOfCofork_ofπ] at c'
  let iFc := isColimitCoforkMapOfIsColimit' F _ c'
  apply
    IsColimit.ofIsoColimit _ ((Cocones.functoriality _ F).mapIso (Cofork.isoCoforkOfπ c).symm)
  apply (isColimitMapCoconeCoforkEquiv F (Cofork.condition c)).invFun
  let p : parallelPair (F.map (f - g)) 0 ≅ parallelPair (F.map f - F.map g) 0 :=
    parallelPair.ext (Iso.refl _) (Iso.refl _) (by simp) (by 

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₂
inst✝⁴ : Category.{v₂, u₂} D
inst✝³ : Preadditive D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
inst✝¹ : HasBinaryBiproducts C
inst✝ : {X Y : C} → (f : X ⟶ Y) → PreservesColimit (parallelPair f 0) F
X Y : C
f g : X ⟶ Y
this✝ : PreservesBinaryBiproducts F := preservesBinaryBiproductsOfPreservesBinaryCoproducts F
this : Additive F
c : Cocone (parallelPair f g)
i : IsColimit c
c' : IsColimit (CokernelCofork.ofπ (Cofork.π c) (_ : (f - g) ≫ Cofork.π c = 0)) :=
  isColimitCokernelCoforkOfCofork (IsColimit.ofIsoColimit i (Cofork.isoCoforkOfπ c))
iFc : IsColimit (CokernelCofork.ofπ (F.map (Cofork.π c)) (_ : F.map (f - g) ≫ F.map (Cofork.π c) = 0)) :=
  isColimitCoforkMapOfIsColimit' F (_ : (f - g) ≫ Cofork.π c = 0) c'
⊢ (parallelPair (F.map (f - g)) 0).map WalkingParallelPairHom.right ≫
      (Iso.refl ((parallelPair (F.map (f - g)) 0).obj WalkingParallelPair.one)).hom =
    (Iso.refl ((parallelPair (F.map (f - g)) 0).obj WalkingParallelPair.zero)).hom ≫
      (parallelPair (F.map f - F.map g) 0).map WalkingParallelPairHom.right

Next tactic:
simp
/-- A functor between preadditive categories preserves the coequalizer of two
morphisms if it preserves all cokernels. -/
def preservesCoequalizerOfPreservesCokernels
    [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] {X Y : C} (f g : X ⟶ Y) :
    PreservesColimit (parallelPair f g) F := by
  letI := preservesBinaryBiproductsOfPreservesBinaryCoproducts F
  haveI := additive_of_preservesBinaryBiproducts F
  constructor
  intro c i
  let c' := isColimitCokernelCoforkOfCofork (i.ofIsoColimit (Cofork.isoCoforkOfπ c))
  dsimp only [cokernelCoforkOfCofork_ofπ] at c'
  let iFc := isColimitCoforkMapOfIsColimit' F _ c'
  apply
    IsColimit.ofIsoColimit _ ((Cocones.functoriality _ F).mapIso (Cofork.isoCoforkOfπ c).symm)
  apply (isColimitMapCoconeCoforkEquiv F (Cofork.condition c)).invFun
  let p : parallelPair (F.map (f - g)) 0 ≅ parallelPair (F.map f - F.map g) 0 :=
    parallelPair.ext (Iso.refl _) (Iso.refl _) (by simp) (by simp)
  

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₂
inst✝⁴ : Category.{v₂, u₂} D
inst✝³ : Preadditive D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
inst✝¹ : HasBinaryBiproducts C
inst✝ : {X Y : C} → (f : X ⟶ Y) → PreservesColimit (parallelPair f 0) F
X Y : C
f g : X ⟶ Y
this✝ : PreservesBinaryBiproducts F := preservesBinaryBiproductsOfPreservesBinaryCoproducts F
this : Additive F
c : Cocone (parallelPair f g)
i : IsColimit c
c' : IsColimit (CokernelCofork.ofπ (Cofork.π c) (_ : (f - g) ≫ Cofork.π c = 0)) :=
  isColimitCokernelCoforkOfCofork (IsColimit.ofIsoColimit i (Cofork.isoCoforkOfπ c))
iFc : IsColimit (CokernelCofork.ofπ (F.map (Cofork.π c)) (_ : F.map (f - g) ≫ F.map (Cofork.π c) = 0)) :=
  isColimitCoforkMapOfIsColimit' F (_ : (f - g) ≫ Cofork.π c = 0) c'
p : parallelPair (F.map (f - g)) 0 ≅ parallelPair (F.map f - F.map g) 0 :=
  parallelPair.ext (Iso.refl ((parallelPair (F.map (f - g)) 0).obj WalkingParallelPair.zero))
    (Iso.refl ((parallelPair (F.map (f - g)) 0).obj WalkingParallelPair.one))
    (_ : F.map (f - g) ≫ 𝟙 (F.obj Y) = 𝟙 (F.obj X) ≫ (F.map f - F.map g)) (_ : 0 ≫ 𝟙 (F.obj Y) = 𝟙 (F.obj X) ≫ 0)
⊢ IsColimit (Cofork.ofπ (F.map (Cofork.π c)) (_ : F.map f ≫ F.map (Cofork.π c) = F.map g ≫ F.map (Cofork.π c)))

Next tactic:
exact
    IsColimit.ofIsoColimit
      (isColimitCoforkOfCokernelCofork ((IsColimit.precomposeHomEquiv p.symm _).symm iFc))
      (Cofork.ext (Iso.refl _) (by simp))
/-- A functor between preadditive categories preserves the coequalizer of two
morphisms if it preserves all cokernels. -/
def preservesCoequalizerOfPreservesCokernels
    [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] {X Y : C} (f g : X ⟶ Y) :
    PreservesColimit (parallelPair f g) F := by
  letI := preservesBinaryBiproductsOfPreservesBinaryCoproducts F
  haveI := additive_of_preservesBinaryBiproducts F
  constructor
  intro c i
  let c' := isColimitCokernelCoforkOfCofork (i.ofIsoColimit (Cofork.isoCoforkOfπ c))
  dsimp only [cokernelCoforkOfCofork_ofπ] at c'
  let iFc := isColimitCoforkMapOfIsColimit' F _ c'
  apply
    IsColimit.ofIsoColimit _ ((Cocones.functoriality _ F).mapIso (Cofork.isoCoforkOfπ c).symm)
  apply (isColimitMapCoconeCoforkEquiv F (Cofork.condition c)).invFun
  let p : parallelPair (F.map (f - g)) 0 ≅ parallelPair (F.map f - F.map g) 0 :=
    parallelPair.ext (Iso.refl _) (Iso.refl _) (by simp) (by simp)
  exact
    IsColimit.ofIsoColimit
      (isColimitCoforkOfCokernelCofork ((IsColimit.precomposeHomEquiv p.symm _).symm iFc))
      (Cofork.ext (Iso.refl _) (by 

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₂
inst✝⁴ : Category.{v₂, u₂} D
inst✝³ : Preadditive D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
inst✝¹ : HasBinaryBiproducts C
inst✝ : {X Y : C} → (f : X ⟶ Y) → PreservesColimit (parallelPair f 0) F
X Y : C
f g : X ⟶ Y
this✝ : PreservesBinaryBiproducts F := preservesBinaryBiproductsOfPreservesBinaryCoproducts F
this : Additive F
c : Cocone (parallelPair f g)
i : IsColimit c
c' : IsColimit (CokernelCofork.ofπ (Cofork.π c) (_ : (f - g) ≫ Cofork.π c = 0)) :=
  isColimitCokernelCoforkOfCofork (IsColimit.ofIsoColimit i (Cofork.isoCoforkOfπ c))
iFc : IsColimit (CokernelCofork.ofπ (F.map (Cofork.π c)) (_ : F.map (f - g) ≫ F.map (Cofork.π c) = 0)) :=
  isColimitCoforkMapOfIsColimit' F (_ : (f - g) ≫ Cofork.π c = 0) c'
p : parallelPair (F.map (f - g)) 0 ≅ parallelPair (F.map f - F.map g) 0 :=
  parallelPair.ext (Iso.refl ((parallelPair (F.map (f - g)) 0).obj WalkingParallelPair.zero))
    (Iso.refl ((parallelPair (F.map (f - g)) 0).obj WalkingParallelPair.one))
    (_ : F.map (f - g) ≫ 𝟙 (F.obj Y) = 𝟙 (F.obj X) ≫ (F.map f - F.map g)) (_ : 0 ≫ 𝟙 (F.obj Y) = 𝟙 (F.obj X) ≫ 0)
⊢ Cofork.π
        (coforkOfCokernelCofork
          ((Cocones.precompose p.symm.hom).obj
            (CokernelCofork.ofπ (F.map (Cofork.π c)) (_ : F.map (f - g) ≫ F.map (Cofork.π c) = 0)))) ≫
      (Iso.refl
          (coforkOfCokernelCofork
              ((Cocones.precompose p.symm.hom).obj
                (CokernelCofork.ofπ (F.map (Cofork.π c)) (_ : F.map (f - g) ≫ F.map (Cofork.π c) = 0)))).pt).hom =
    Cofork.π (Cofork.ofπ (F.map (Cofork.π c)) (_ : F.map f ≫ F.map (Cofork.π c) = F.map g ≫ F.map (Cofork.π c)))

Next tactic:
simp
/-- A functor between preadditive categories preserves all coequalizers if it preserves all kernels.
-/
def preservesCoequalizersOfPreservesCokernels
    [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] :
    PreservesColimitsOfShape WalkingParallelPair F where
  preservesColimit {K} := by
    

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₂
inst✝⁴ : Category.{v₂, u₂} D
inst✝³ : Preadditive D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
inst✝¹ : HasBinaryBiproducts C
inst✝ : {X Y : C} → (f : X ⟶ Y) → PreservesColimit (parallelPair f 0) F
K : WalkingParallelPair ⥤ C
⊢ PreservesColimit K F

Next tactic:
letI := preservesCoequalizerOfPreservesCokernels F (K.map Limits.WalkingParallelPairHom.left)
        (K.map Limits.WalkingParallelPairHom.right)
/-- A functor between preadditive categories preserves all coequalizers if it preserves all kernels.
-/
def preservesCoequalizersOfPreservesCokernels
    [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] :
    PreservesColimitsOfShape WalkingParallelPair F where
  preservesColimit {K} := by
    letI := preservesCoequalizerOfPreservesCokernels F (K.map Limits.WalkingParallelPairHom.left)
        (K.map Limits.WalkingParallelPairHom.right)
    

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₂
inst✝⁴ : Category.{v₂, u₂} D
inst✝³ : Preadditive D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
inst✝¹ : HasBinaryBiproducts C
inst✝ : {X Y : C} → (f : X ⟶ Y) → PreservesColimit (parallelPair f 0) F
K : WalkingParallelPair ⥤ C
this : PreservesColimit (parallelPair (K.map WalkingParallelPairHom.left) (K.map WalkingParallelPairHom.right)) F :=
  preservesCoequalizerOfPreservesCokernels F (K.map WalkingParallelPairHom.left) (K.map WalkingParallelPairHom.right)
⊢ PreservesColimit K F

Next tactic:
apply preservesColimitOfIsoDiagram F (diagramIsoParallelPair K).symm
/-- A functor between preadditive categories which preserves kernels preserves all finite limits.
-/
def preservesFiniteColimitsOfPreservesCokernels [HasFiniteCoproducts C] [HasCoequalizers C]
    [HasZeroObject C] [HasZeroObject D]
    [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] : PreservesFiniteColimits F := by
  

Proof state:
C : Type u₁
inst✝¹⁰ : Category.{v₁, u₁} C
inst✝⁹ : Preadditive C
D : Type u₂
inst✝⁸ : Category.{v₂, u₂} D
inst✝⁷ : Preadditive D
F : C ⥤ D
inst✝⁶ : PreservesZeroMorphisms F
inst✝⁵ : HasBinaryBiproducts C
inst✝⁴ : HasFiniteCoproducts C
inst✝³ : HasCoequalizers C
inst✝² : HasZeroObject C
inst✝¹ : HasZeroObject D
inst✝ : {X Y : C} → (f : X ⟶ Y) → PreservesColimit (parallelPair f 0) F
⊢ PreservesFiniteColimits F

Next tactic:
letI := preservesCoequalizersOfPreservesCokernels F
/-- A functor between preadditive categories which preserves kernels preserves all finite limits.
-/
def preservesFiniteColimitsOfPreservesCokernels [HasFiniteCoproducts C] [HasCoequalizers C]
    [HasZeroObject C] [HasZeroObject D]
    [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] : PreservesFiniteColimits F := by
  letI := preservesCoequalizersOfPreservesCokernels F
  

Proof state:
C : Type u₁
inst✝¹⁰ : Category.{v₁, u₁} C
inst✝⁹ : Preadditive C
D : Type u₂
inst✝⁸ : Category.{v₂, u₂} D
inst✝⁷ : Preadditive D
F : C ⥤ D
inst✝⁶ : PreservesZeroMorphisms F
inst✝⁵ : HasBinaryBiproducts C
inst✝⁴ : HasFiniteCoproducts C
inst✝³ : HasCoequalizers C
inst✝² : HasZeroObject C
inst✝¹ : HasZeroObject D
inst✝ : {X Y : C} → (f : X ⟶ Y) → PreservesColimit (parallelPair f 0) F
this : PreservesColimitsOfShape WalkingParallelPair F := preservesCoequalizersOfPreservesCokernels F
⊢ PreservesFiniteColimits F

Next tactic:
letI := preservesInitialObjectOfPreservesZeroMorphisms F
/-- A functor between preadditive categories which preserves kernels preserves all finite limits.
-/
def preservesFiniteColimitsOfPreservesCokernels [HasFiniteCoproducts C] [HasCoequalizers C]
    [HasZeroObject C] [HasZeroObject D]
    [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] : PreservesFiniteColimits F := by
  letI := preservesCoequalizersOfPreservesCokernels F
  letI := preservesInitialObjectOfPreservesZeroMorphisms F
  

Proof state:
C : Type u₁
inst✝¹⁰ : Category.{v₁, u₁} C
inst✝⁹ : Preadditive C
D : Type u₂
inst✝⁸ : Category.{v₂, u₂} D
inst✝⁷ : Preadditive D
F : C ⥤ D
inst✝⁶ : PreservesZeroMorphisms F
inst✝⁵ : HasBinaryBiproducts C
inst✝⁴ : HasFiniteCoproducts C
inst✝³ : HasCoequalizers C
inst✝² : HasZeroObject C
inst✝¹ : HasZeroObject D
inst✝ : {X Y : C} → (f : X ⟶ Y) → PreservesColimit (parallelPair f 0) F
this✝ : PreservesColimitsOfShape WalkingParallelPair F := preservesCoequalizersOfPreservesCokernels F
this : PreservesColimit (empty C) F := preservesInitialObjectOfPreservesZeroMorphisms F
⊢ PreservesFiniteColimits F

Next tactic:
letI := preservesColimitsOfShapePemptyOfPreservesInitial F
/-- A functor between preadditive categories which preserves kernels preserves all finite limits.
-/
def preservesFiniteColimitsOfPreservesCokernels [HasFiniteCoproducts C] [HasCoequalizers C]
    [HasZeroObject C] [HasZeroObject D]
    [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] : PreservesFiniteColimits F := by
  letI := preservesCoequalizersOfPreservesCokernels F
  letI := preservesInitialObjectOfPreservesZeroMorphisms F
  letI := preservesColimitsOfShapePemptyOfPreservesInitial F
  

Proof state:
C : Type u₁
inst✝¹⁰ : Category.{v₁, u₁} C
inst✝⁹ : Preadditive C
D : Type u₂
inst✝⁸ : Category.{v₂, u₂} D
inst✝⁷ : Preadditive D
F : C ⥤ D
inst✝⁶ : PreservesZeroMorphisms F
inst✝⁵ : HasBinaryBiproducts C
inst✝⁴ : HasFiniteCoproducts C
inst✝³ : HasCoequalizers C
inst✝² : HasZeroObject C
inst✝¹ : HasZeroObject D
inst✝ : {X Y : C} → (f : X ⟶ Y) → PreservesColimit (parallelPair f 0) F
this✝¹ : PreservesColimitsOfShape WalkingParallelPair F := preservesCoequalizersOfPreservesCokernels F
this✝ : PreservesColimit (empty C) F := preservesInitialObjectOfPreservesZeroMorphisms F
this : PreservesColimitsOfShape (Discrete PEmpty.{1}) F := preservesColimitsOfShapePemptyOfPreservesInitial F
⊢ PreservesFiniteColimits F

Next tactic:
letI : PreservesFiniteCoproducts F := ⟨preservesFiniteCoproductsOfPreservesBinaryAndInitial F⟩
/-- A functor between preadditive categories which preserves kernels preserves all finite limits.
-/
def preservesFiniteColimitsOfPreservesCokernels [HasFiniteCoproducts C] [HasCoequalizers C]
    [HasZeroObject C] [HasZeroObject D]
    [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] : PreservesFiniteColimits F := by
  letI := preservesCoequalizersOfPreservesCokernels F
  letI := preservesInitialObjectOfPreservesZeroMorphisms F
  letI := preservesColimitsOfShapePemptyOfPreservesInitial F
  letI : PreservesFiniteCoproducts F := ⟨preservesFiniteCoproductsOfPreservesBinaryAndInitial F⟩
  

Proof state:
C : Type u₁
inst✝¹⁰ : Category.{v₁, u₁} C
inst✝⁹ : Preadditive C
D : Type u₂
inst✝⁸ : Category.{v₂, u₂} D
inst✝⁷ : Preadditive D
F : C ⥤ D
inst✝⁶ : PreservesZeroMorphisms F
inst✝⁵ : HasBinaryBiproducts C
inst✝⁴ : HasFiniteCoproducts C
inst✝³ : HasCoequalizers C
inst✝² : HasZeroObject C
inst✝¹ : HasZeroObject D
inst✝ : {X Y : C} → (f : X ⟶ Y) → PreservesColimit (parallelPair f 0) F
this✝² : PreservesColimitsOfShape WalkingParallelPair F := preservesCoequalizersOfPreservesCokernels F
this✝¹ : PreservesColimit (empty C) F := preservesInitialObjectOfPreservesZeroMorphisms F
this✝ : PreservesColimitsOfShape (Discrete PEmpty.{1}) F := preservesColimitsOfShapePemptyOfPreservesInitial F
this : PreservesFiniteCoproducts F := { preserves := preservesFiniteCoproductsOfPreservesBinaryAndInitial F }
⊢ PreservesFiniteColimits F

Next tactic:
exact preservesFiniteColimitsOfPreservesCoequalizersAndFiniteCoproducts F