l3lab/ntp-mathlib huggingface dataset:
theorem fst_of_isColimit {X Y : C} {t : BinaryBicone X Y} (ht : IsColimit t.toCocone) :
    t.fst = ht.desc (BinaryCofan.mk (𝟙 X) 0) := by
  apply ht.uniq (BinaryCofan.mk (𝟙 X) 0)
  rintro ⟨⟨⟩⟩ <;> dsimp <;> 

Proof state:
case x.mk.right
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
J : Type
inst✝ : Fintype J
X Y : C
t : BinaryBicone X Y
ht : IsColimit (BinaryBicone.toCocone t)
⊢ t.inr ≫ t.fst = 0

Next tactic:
simp
theorem snd_of_isColimit {X Y : C} {t : BinaryBicone X Y} (ht : IsColimit t.toCocone) :
    t.snd = ht.desc (BinaryCofan.mk 0 (𝟙 Y)) := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
J : Type
inst✝ : Fintype J
X Y : C
t : BinaryBicone X Y
ht : IsColimit (BinaryBicone.toCocone t)
⊢ t.snd = IsColimit.desc ht (BinaryCofan.mk 0 (𝟙 Y))

Next tactic:
apply ht.uniq (BinaryCofan.mk 0 (𝟙 Y))
theorem snd_of_isColimit {X Y : C} {t : BinaryBicone X Y} (ht : IsColimit t.toCocone) :
    t.snd = ht.desc (BinaryCofan.mk 0 (𝟙 Y)) := by
  apply ht.uniq (BinaryCofan.mk 0 (𝟙 Y))
  

Proof state:
case x
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
J : Type
inst✝ : Fintype J
X Y : C
t : BinaryBicone X Y
ht : IsColimit (BinaryBicone.toCocone t)
⊢ ∀ (j : Discrete WalkingPair), (BinaryBicone.toCocone t).ι.app j ≫ t.snd = (BinaryCofan.mk 0 (𝟙 Y)).ι.app j

Next tactic:
rintro ⟨⟨⟩⟩
theorem snd_of_isColimit {X Y : C} {t : BinaryBicone X Y} (ht : IsColimit t.toCocone) :
    t.snd = ht.desc (BinaryCofan.mk 0 (𝟙 Y)) := by
  apply ht.uniq (BinaryCofan.mk 0 (𝟙 Y))
  rintro ⟨⟨⟩⟩ <;> 

Proof state:
case x.mk.left
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
J : Type
inst✝ : Fintype J
X Y : C
t : BinaryBicone X Y
ht : IsColimit (BinaryBicone.toCocone t)
⊢ (BinaryBicone.toCocone t).ι.app { as := WalkingPair.left } ≫ t.snd =
    (BinaryCofan.mk 0 (𝟙 Y)).ι.app { as := WalkingPair.left }

Next tactic:
dsimp
theorem snd_of_isColimit {X Y : C} {t : BinaryBicone X Y} (ht : IsColimit t.toCocone) :
    t.snd = ht.desc (BinaryCofan.mk 0 (𝟙 Y)) := by
  apply ht.uniq (BinaryCofan.mk 0 (𝟙 Y))
  rintro ⟨⟨⟩⟩ <;> 

Proof state:
case x.mk.right
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
J : Type
inst✝ : Fintype J
X Y : C
t : BinaryBicone X Y
ht : IsColimit (BinaryBicone.toCocone t)
⊢ (BinaryBicone.toCocone t).ι.app { as := WalkingPair.right } ≫ t.snd =
    (BinaryCofan.mk 0 (𝟙 Y)).ι.app { as := WalkingPair.right }

Next tactic:
dsimp
theorem snd_of_isColimit {X Y : C} {t : BinaryBicone X Y} (ht : IsColimit t.toCocone) :
    t.snd = ht.desc (BinaryCofan.mk 0 (𝟙 Y)) := by
  apply ht.uniq (BinaryCofan.mk 0 (𝟙 Y))
  rintro ⟨⟨⟩⟩ <;> dsimp <;> 

Proof state:
case x.mk.left
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
J : Type
inst✝ : Fintype J
X Y : C
t : BinaryBicone X Y
ht : IsColimit (BinaryBicone.toCocone t)
⊢ t.inl ≫ t.snd = 0

Next tactic:
simp
theorem snd_of_isColimit {X Y : C} {t : BinaryBicone X Y} (ht : IsColimit t.toCocone) :
    t.snd = ht.desc (BinaryCofan.mk 0 (𝟙 Y)) := by
  apply ht.uniq (BinaryCofan.mk 0 (𝟙 Y))
  rintro ⟨⟨⟩⟩ <;> dsimp <;> 

Proof state:
case x.mk.right
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
J : Type
inst✝ : Fintype J
X Y : C
t : BinaryBicone X Y
ht : IsColimit (BinaryBicone.toCocone t)
⊢ t.inr ≫ t.snd = 𝟙 Y

Next tactic:
simp
/-- In a preadditive category, any binary bicone which is a colimit cocone is in fact a
    bilimit bicone. -/
def isBinaryBilimitOfIsColimit {X Y : C} (t : BinaryBicone X Y) (ht : IsColimit t.toCocone) :
    t.IsBilimit :=
  isBinaryBilimitOfTotal _ <| by
    

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
J : Type
inst✝ : Fintype J
X Y : C
t : BinaryBicone X Y
ht : IsColimit (BinaryBicone.toCocone t)
⊢ t.fst ≫ t.inl + t.snd ≫ t.inr = 𝟙 t.pt

Next tactic:
refine' BinaryCofan.IsColimit.hom_ext ht _ _
/-- In a preadditive category, any binary bicone which is a colimit cocone is in fact a
    bilimit bicone. -/
def isBinaryBilimitOfIsColimit {X Y : C} (t : BinaryBicone X Y) (ht : IsColimit t.toCocone) :
    t.IsBilimit :=
  isBinaryBilimitOfTotal _ <| by
    refine' BinaryCofan.IsColimit.hom_ext ht _ _ <;> 

Proof state:
case refine'_1
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
J : Type
inst✝ : Fintype J
X Y : C
t : BinaryBicone X Y
ht : IsColimit (BinaryBicone.toCocone t)
⊢ BinaryCofan.inl (BinaryBicone.toCocone t) ≫ (t.fst ≫ t.inl + t.snd ≫ t.inr) =
    BinaryCofan.inl (BinaryBicone.toCocone t) ≫ 𝟙 t.pt

Next tactic:
simp
/-- In a preadditive category, any binary bicone which is a colimit cocone is in fact a
    bilimit bicone. -/
def isBinaryBilimitOfIsColimit {X Y : C} (t : BinaryBicone X Y) (ht : IsColimit t.toCocone) :
    t.IsBilimit :=
  isBinaryBilimitOfTotal _ <| by
    refine' BinaryCofan.IsColimit.hom_ext ht _ _ <;> 

Proof state:
case refine'_2
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
J : Type
inst✝ : Fintype J
X Y : C
t : BinaryBicone X Y
ht : IsColimit (BinaryBicone.toCocone t)
⊢ BinaryCofan.inr (BinaryBicone.toCocone t) ≫ (t.fst ≫ t.inl + t.snd ≫ t.inr) =
    BinaryCofan.inr (BinaryBicone.toCocone t) ≫ 𝟙 t.pt

Next tactic:
simp
/-- We can turn any colimit cocone over a pair into a bilimit bicone. -/
def binaryBiconeIsBilimitOfColimitCoconeOfIsColimit {X Y : C} {t : Cocone (pair X Y)}
    (ht : IsColimit t) : (BinaryBicone.ofColimitCocone ht).IsBilimit :=
  isBinaryBilimitOfIsColimit (BinaryBicone.ofColimitCocone ht) <|
    IsColimit.ofIsoColimit ht <|
      Cocones.ext (Iso.refl _) fun j => by
        

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
J : Type
inst✝ : Fintype J
X Y : C
t : Cocone (pair X Y)
ht : IsColimit t
j : Discrete WalkingPair
⊢ t.ι.app j ≫ (Iso.refl t.pt).hom = (BinaryBicone.toCocone (BinaryBicone.ofColimitCocone ht)).ι.app j

Next tactic:
rcases j with ⟨⟨⟩⟩
/-- We can turn any colimit cocone over a pair into a bilimit bicone. -/
def binaryBiconeIsBilimitOfColimitCoconeOfIsColimit {X Y : C} {t : Cocone (pair X Y)}
    (ht : IsColimit t) : (BinaryBicone.ofColimitCocone ht).IsBilimit :=
  isBinaryBilimitOfIsColimit (BinaryBicone.ofColimitCocone ht) <|
    IsColimit.ofIsoColimit ht <|
      Cocones.ext (Iso.refl _) fun j => by
        rcases j with ⟨⟨⟩⟩ <;> 

Proof state:
case mk.left
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
J : Type
inst✝ : Fintype J
X Y : C
t : Cocone (pair X Y)
ht : IsColimit t
⊢ t.ι.app { as := WalkingPair.left } ≫ (Iso.refl t.pt).hom =
    (BinaryBicone.toCocone (BinaryBicone.ofColimitCocone ht)).ι.app { as := WalkingPair.left }

Next tactic:
simp
/-- We can turn any colimit cocone over a pair into a bilimit bicone. -/
def binaryBiconeIsBilimitOfColimitCoconeOfIsColimit {X Y : C} {t : Cocone (pair X Y)}
    (ht : IsColimit t) : (BinaryBicone.ofColimitCocone ht).IsBilimit :=
  isBinaryBilimitOfIsColimit (BinaryBicone.ofColimitCocone ht) <|
    IsColimit.ofIsoColimit ht <|
      Cocones.ext (Iso.refl _) fun j => by
        rcases j with ⟨⟨⟩⟩ <;> 

Proof state:
case mk.right
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
J : Type
inst✝ : Fintype J
X Y : C
t : Cocone (pair X Y)
ht : IsColimit t
⊢ t.ι.app { as := WalkingPair.right } ≫ (Iso.refl t.pt).hom =
    (BinaryBicone.toCocone (BinaryBicone.ofColimitCocone ht)).ι.app { as := WalkingPair.right }

Next tactic:
simp
/-- In any preadditive category, any binary biproduct satsifies
`biprod.fst ≫ biprod.inl + biprod.snd ≫ biprod.inr = 𝟙 (X ⊞ Y)`.
-/
@[simp]
theorem biprod.total : biprod.fst ≫ biprod.inl + biprod.snd ≫ biprod.inr = 𝟙 (X ⊞ Y) := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
J : Type
inst✝¹ : Fintype J
X Y : C
inst✝ : HasBinaryBiproduct X Y
⊢ fst ≫ inl + snd ≫ inr = 𝟙 (X ⊞ Y)

Next tactic:
ext
/-- In any preadditive category, any binary biproduct satsifies
`biprod.fst ≫ biprod.inl + biprod.snd ≫ biprod.inr = 𝟙 (X ⊞ Y)`.
-/
@[simp]
theorem biprod.total : biprod.fst ≫ biprod.inl + biprod.snd ≫ biprod.inr = 𝟙 (X ⊞ Y) := by
  ext <;> 

Proof state:
case h₀.h₀
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
J : Type
inst✝¹ : Fintype J
X Y : C
inst✝ : HasBinaryBiproduct X Y
⊢ (inl ≫ (fst ≫ inl + snd ≫ inr)) ≫ fst = (inl ≫ 𝟙 (X ⊞ Y)) ≫ fst

Next tactic:
simp [add_comp]
/-- In any preadditive category, any binary biproduct satsifies
`biprod.fst ≫ biprod.inl + biprod.snd ≫ biprod.inr = 𝟙 (X ⊞ Y)`.
-/
@[simp]
theorem biprod.total : biprod.fst ≫ biprod.inl + biprod.snd ≫ biprod.inr = 𝟙 (X ⊞ Y) := by
  ext <;> 

Proof state:
case h₀.h₁
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
J : Type
inst✝¹ : Fintype J
X Y : C
inst✝ : HasBinaryBiproduct X Y
⊢ (inl ≫ (fst ≫ inl + snd ≫ inr)) ≫ snd = (inl ≫ 𝟙 (X ⊞ Y)) ≫ snd

Next tactic:
simp [add_comp]
/-- In any preadditive category, any binary biproduct satsifies
`biprod.fst ≫ biprod.inl + biprod.snd ≫ biprod.inr = 𝟙 (X ⊞ Y)`.
-/
@[simp]
theorem biprod.total : biprod.fst ≫ biprod.inl + biprod.snd ≫ biprod.inr = 𝟙 (X ⊞ Y) := by
  ext <;> 

Proof state:
case h₁.h₀
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
J : Type
inst✝¹ : Fintype J
X Y : C
inst✝ : HasBinaryBiproduct X Y
⊢ (inr ≫ (fst ≫ inl + snd ≫ inr)) ≫ fst = (inr ≫ 𝟙 (X ⊞ Y)) ≫ fst

Next tactic:
simp [add_comp]
/-- In any preadditive category, any binary biproduct satsifies
`biprod.fst ≫ biprod.inl + biprod.snd ≫ biprod.inr = 𝟙 (X ⊞ Y)`.
-/
@[simp]
theorem biprod.total : biprod.fst ≫ biprod.inl + biprod.snd ≫ biprod.inr = 𝟙 (X ⊞ Y) := by
  ext <;> 

Proof state:
case h₁.h₁
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
J : Type
inst✝¹ : Fintype J
X Y : C
inst✝ : HasBinaryBiproduct X Y
⊢ (inr ≫ (fst ≫ inl + snd ≫ inr)) ≫ snd = (inr ≫ 𝟙 (X ⊞ Y)) ≫ snd

Next tactic:
simp [add_comp]
theorem biprod.lift_eq {T : C} {f : T ⟶ X} {g : T ⟶ Y} :
    biprod.lift f g = f ≫ biprod.inl + g ≫ biprod.inr := by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
J : Type
inst✝¹ : Fintype J
X Y : C
inst✝ : HasBinaryBiproduct X Y
T : C
f : T ⟶ X
g : T ⟶ Y
⊢ lift f g = f ≫ inl + g ≫ inr

Next tactic:
ext
theorem biprod.lift_eq {T : C} {f : T ⟶ X} {g : T ⟶ Y} :
    biprod.lift f g = f ≫ biprod.inl + g ≫ biprod.inr := by ext <;> 

Proof state:
case h₀
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
J : Type
inst✝¹ : Fintype J
X Y : C
inst✝ : HasBinaryBiproduct X Y
T : C
f : T ⟶ X
g : T ⟶ Y
⊢ lift f g ≫ fst = (f ≫ inl + g ≫ inr) ≫ fst

Next tactic:
simp [add_comp]
theorem biprod.lift_eq {T : C} {f : T ⟶ X} {g : T ⟶ Y} :
    biprod.lift f g = f ≫ biprod.inl + g ≫ biprod.inr := by ext <;> 

Proof state:
case h₁
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
J : Type
inst✝¹ : Fintype J
X Y : C
inst✝ : HasBinaryBiproduct X Y
T : C
f : T ⟶ X
g : T ⟶ Y
⊢ lift f g ≫ snd = (f ≫ inl + g ≫ inr) ≫ snd

Next tactic:
simp [add_comp]
theorem biprod.desc_eq {T : C} {f : X ⟶ T} {g : Y ⟶ T} :
    biprod.desc f g = biprod.fst ≫ f + biprod.snd ≫ g := by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
J : Type
inst✝¹ : Fintype J
X Y : C
inst✝ : HasBinaryBiproduct X Y
T : C
f : X ⟶ T
g : Y ⟶ T
⊢ desc f g = fst ≫ f + snd ≫ g

Next tactic:
ext
theorem biprod.desc_eq {T : C} {f : X ⟶ T} {g : Y ⟶ T} :
    biprod.desc f g = biprod.fst ≫ f + biprod.snd ≫ g := by ext <;> 

Proof state:
case h₀
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
J : Type
inst✝¹ : Fintype J
X Y : C
inst✝ : HasBinaryBiproduct X Y
T : C
f : X ⟶ T
g : Y ⟶ T
⊢ inl ≫ desc f g = inl ≫ (fst ≫ f + snd ≫ g)

Next tactic:
simp [add_comp]
theorem biprod.desc_eq {T : C} {f : X ⟶ T} {g : Y ⟶ T} :
    biprod.desc f g = biprod.fst ≫ f + biprod.snd ≫ g := by ext <;> 

Proof state:
case h₁
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
J : Type
inst✝¹ : Fintype J
X Y : C
inst✝ : HasBinaryBiproduct X Y
T : C
f : X ⟶ T
g : Y ⟶ T
⊢ inr ≫ desc f g = inr ≫ (fst ≫ f + snd ≫ g)

Next tactic:
simp [add_comp]
@[reassoc (attr := simp)]
theorem biprod.lift_desc {T U : C} {f : T ⟶ X} {g : T ⟶ Y} {h : X ⟶ U} {i : Y ⟶ U} :
    biprod.lift f g ≫ biprod.desc h i = f ≫ h + g ≫ i := by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
J : Type
inst✝¹ : Fintype J
X Y : C
inst✝ : HasBinaryBiproduct X Y
T U : C
f : T ⟶ X
g : T ⟶ Y
h : X ⟶ U
i : Y ⟶ U
⊢ lift f g ≫ desc h i = f ≫ h + g ≫ i

Next tactic:
simp [biprod.lift_eq, biprod.desc_eq]
theorem biprod.map_eq [HasBinaryBiproducts C] {W X Y Z : C} {f : W ⟶ Y} {g : X ⟶ Z} :
    biprod.map f g = biprod.fst ≫ f ≫ biprod.inl + biprod.snd ≫ g ≫ biprod.inr := by
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : Preadditive C
J : Type
inst✝² : Fintype J
X✝ Y✝ : C
inst✝¹ : HasBinaryBiproduct X✝ Y✝
inst✝ : HasBinaryBiproducts C
W X Y Z : C
f : W ⟶ Y
g : X ⟶ Z
⊢ map f g = fst ≫ f ≫ inl + snd ≫ g ≫ inr

Next tactic:
ext
theorem biprod.map_eq [HasBinaryBiproducts C] {W X Y Z : C} {f : W ⟶ Y} {g : X ⟶ Z} :
    biprod.map f g = biprod.fst ≫ f ≫ biprod.inl + biprod.snd ≫ g ≫ biprod.inr := by
  ext <;> 

Proof state:
case h₀.h₀
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : Preadditive C
J : Type
inst✝² : Fintype J
X✝ Y✝ : C
inst✝¹ : HasBinaryBiproduct X✝ Y✝
inst✝ : HasBinaryBiproducts C
W X Y Z : C
f : W ⟶ Y
g : X ⟶ Z
⊢ (inl ≫ map f g) ≫ fst = (inl ≫ (fst ≫ f ≫ inl + snd ≫ g ≫ inr)) ≫ fst

Next tactic:
simp
theorem biprod.map_eq [HasBinaryBiproducts C] {W X Y Z : C} {f : W ⟶ Y} {g : X ⟶ Z} :
    biprod.map f g = biprod.fst ≫ f ≫ biprod.inl + biprod.snd ≫ g ≫ biprod.inr := by
  ext <;> 

Proof state:
case h₀.h₁
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : Preadditive C
J : Type
inst✝² : Fintype J
X✝ Y✝ : C
inst✝¹ : HasBinaryBiproduct X✝ Y✝
inst✝ : HasBinaryBiproducts C
W X Y Z : C
f : W ⟶ Y
g : X ⟶ Z
⊢ (inl ≫ map f g) ≫ snd = (inl ≫ (fst ≫ f ≫ inl + snd ≫ g ≫ inr)) ≫ snd

Next tactic:
simp
theorem biprod.map_eq [HasBinaryBiproducts C] {W X Y Z : C} {f : W ⟶ Y} {g : X ⟶ Z} :
    biprod.map f g = biprod.fst ≫ f ≫ biprod.inl + biprod.snd ≫ g ≫ biprod.inr := by
  ext <;> 

Proof state:
case h₁.h₀
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : Preadditive C
J : Type
inst✝² : Fintype J
X✝ Y✝ : C
inst✝¹ : HasBinaryBiproduct X✝ Y✝
inst✝ : HasBinaryBiproducts C
W X Y Z : C
f : W ⟶ Y
g : X ⟶ Z
⊢ (inr ≫ map f g) ≫ fst = (inr ≫ (fst ≫ f ≫ inl + snd ≫ g ≫ inr)) ≫ fst

Next tactic:
simp
theorem biprod.map_eq [HasBinaryBiproducts C] {W X Y Z : C} {f : W ⟶ Y} {g : X ⟶ Z} :
    biprod.map f g = biprod.fst ≫ f ≫ biprod.inl + biprod.snd ≫ g ≫ biprod.inr := by
  ext <;> 

Proof state:
case h₁.h₁
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : Preadditive C
J : Type
inst✝² : Fintype J
X✝ Y✝ : C
inst✝¹ : HasBinaryBiproduct X✝ Y✝
inst✝ : HasBinaryBiproducts C
W X Y Z : C
f : W ⟶ Y
g : X ⟶ Z
⊢ (inr ≫ map f g) ≫ snd = (inr ≫ (fst ≫ f ≫ inl + snd ≫ g ≫ inr)) ≫ snd

Next tactic:
simp
/-- Every split mono `f` with a cokernel induces a binary bicone with `f` as its `inl` and
the cokernel map as its `snd`.
We will show in `is_bilimit_binary_bicone_of_split_mono_of_cokernel` that this binary bicone is in
fact already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitMonoOfCokernel {X Y : C} {f : X ⟶ Y} [IsSplitMono f] {c : CokernelCofork f}
    (i : IsColimit c) : BinaryBicone X c.pt where
  pt := Y
  fst := retraction f
  snd := c.π
  inl := f
  inr :=
    let c' : CokernelCofork (𝟙 Y - (𝟙 Y - retraction f ≫ f)) :=
      CokernelCofork.ofπ (Cofork.π c) (by 

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : Preadditive C
J : Type
inst✝² : Fintype J
X✝ Y✝ : C
inst✝¹ : HasBinaryBiproduct X✝ Y✝
X Y : C
f : X ⟶ Y
inst✝ : IsSplitMono f
c : CokernelCofork f
i : IsColimit c
⊢ (𝟙 Y - (𝟙 Y - retraction f ≫ f)) ≫ Cofork.π c = 0

Next tactic:
simp
/-- Every split mono `f` with a cokernel induces a binary bicone with `f` as its `inl` and
the cokernel map as its `snd`.
We will show in `is_bilimit_binary_bicone_of_split_mono_of_cokernel` that this binary bicone is in
fact already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitMonoOfCokernel {X Y : C} {f : X ⟶ Y} [IsSplitMono f] {c : CokernelCofork f}
    (i : IsColimit c) : BinaryBicone X c.pt where
  pt := Y
  fst := retraction f
  snd := c.π
  inl := f
  inr :=
    let c' : CokernelCofork (𝟙 Y - (𝟙 Y - retraction f ≫ f)) :=
      CokernelCofork.ofπ (Cofork.π c) (by simp)
    let i' : IsColimit c' := isCokernelEpiComp i (retraction f) (by 

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : Preadditive C
J : Type
inst✝² : Fintype J
X✝ Y✝ : C
inst✝¹ : HasBinaryBiproduct X✝ Y✝
X Y : C
f : X ⟶ Y
inst✝ : IsSplitMono f
c : CokernelCofork f
i : IsColimit c
c' : CokernelCofork (𝟙 Y - (𝟙 Y - retraction f ≫ f)) :=
  CokernelCofork.ofπ (Cofork.π c) (_ : (𝟙 Y - (𝟙 Y - retraction f ≫ f)) ≫ Cofork.π c = 0)
⊢ 𝟙 Y - (𝟙 Y - retraction f ≫ f) = retraction f ≫ f

Next tactic:
simp
/-- Every split mono `f` with a cokernel induces a binary bicone with `f` as its `inl` and
the cokernel map as its `snd`.
We will show in `is_bilimit_binary_bicone_of_split_mono_of_cokernel` that this binary bicone is in
fact already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitMonoOfCokernel {X Y : C} {f : X ⟶ Y} [IsSplitMono f] {c : CokernelCofork f}
    (i : IsColimit c) : BinaryBicone X c.pt where
  pt := Y
  fst := retraction f
  snd := c.π
  inl := f
  inr :=
    let c' : CokernelCofork (𝟙 Y - (𝟙 Y - retraction f ≫ f)) :=
      CokernelCofork.ofπ (Cofork.π c) (by simp)
    let i' : IsColimit c' := isCokernelEpiComp i (retraction f) (by simp)
    let i'' := isColimitCoforkOfCokernelCofork i'
    (splitEpiOfIdempotentOfIsColimitCofork C (by 

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : Preadditive C
J : Type
inst✝² : Fintype J
X✝ Y✝ : C
inst✝¹ : HasBinaryBiproduct X✝ Y✝
X Y : C
f : X ⟶ Y
inst✝ : IsSplitMono f
c : CokernelCofork f
i : IsColimit c
c' : CokernelCofork (𝟙 Y - (𝟙 Y - retraction f ≫ f)) :=
  CokernelCofork.ofπ (Cofork.π c) (_ : (𝟙 Y - (𝟙 Y - retraction f ≫ f)) ≫ Cofork.π c = 0)
i' : IsColimit c' := isCokernelEpiComp i (retraction f) (_ : 𝟙 Y - (𝟙 Y - retraction f ≫ f) = retraction f ≫ f)
i'' : IsColimit (coforkOfCokernelCofork c') := isColimitCoforkOfCokernelCofork i'
⊢ (𝟙 Y - retraction f ≫ f) ≫ (𝟙 Y - retraction f ≫ f) = 𝟙 Y - retraction f ≫ f

Next tactic:
simp
/-- Every split mono `f` with a cokernel induces a binary bicone with `f` as its `inl` and
the cokernel map as its `snd`.
We will show in `is_bilimit_binary_bicone_of_split_mono_of_cokernel` that this binary bicone is in
fact already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitMonoOfCokernel {X Y : C} {f : X ⟶ Y} [IsSplitMono f] {c : CokernelCofork f}
    (i : IsColimit c) : BinaryBicone X c.pt where
  pt := Y
  fst := retraction f
  snd := c.π
  inl := f
  inr :=
    let c' : CokernelCofork (𝟙 Y - (𝟙 Y - retraction f ≫ f)) :=
      CokernelCofork.ofπ (Cofork.π c) (by simp)
    let i' : IsColimit c' := isCokernelEpiComp i (retraction f) (by simp)
    let i'' := isColimitCoforkOfCokernelCofork i'
    (splitEpiOfIdempotentOfIsColimitCofork C (by simp) i'').section_
  inl_fst := by 

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : Preadditive C
J : Type
inst✝² : Fintype J
X✝ Y✝ : C
inst✝¹ : HasBinaryBiproduct X✝ Y✝
X Y : C
f : X ⟶ Y
inst✝ : IsSplitMono f
c : CokernelCofork f
i : IsColimit c
⊢ f ≫ retraction f = 𝟙 X

Next tactic:
simp
/-- Every split mono `f` with a cokernel induces a binary bicone with `f` as its `inl` and
the cokernel map as its `snd`.
We will show in `is_bilimit_binary_bicone_of_split_mono_of_cokernel` that this binary bicone is in
fact already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitMonoOfCokernel {X Y : C} {f : X ⟶ Y} [IsSplitMono f] {c : CokernelCofork f}
    (i : IsColimit c) : BinaryBicone X c.pt where
  pt := Y
  fst := retraction f
  snd := c.π
  inl := f
  inr :=
    let c' : CokernelCofork (𝟙 Y - (𝟙 Y - retraction f ≫ f)) :=
      CokernelCofork.ofπ (Cofork.π c) (by simp)
    let i' : IsColimit c' := isCokernelEpiComp i (retraction f) (by simp)
    let i'' := isColimitCoforkOfCokernelCofork i'
    (splitEpiOfIdempotentOfIsColimitCofork C (by simp) i'').section_
  inl_fst := by simp
  inl_snd := by 

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : Preadditive C
J : Type
inst✝² : Fintype J
X✝ Y✝ : C
inst✝¹ : HasBinaryBiproduct X✝ Y✝
X Y : C
f : X ⟶ Y
inst✝ : IsSplitMono f
c : CokernelCofork f
i : IsColimit c
⊢ f ≫ Cofork.π c = 0

Next tactic:
simp
/-- Every split mono `f` with a cokernel induces a binary bicone with `f` as its `inl` and
the cokernel map as its `snd`.
We will show in `is_bilimit_binary_bicone_of_split_mono_of_cokernel` that this binary bicone is in
fact already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitMonoOfCokernel {X Y : C} {f : X ⟶ Y} [IsSplitMono f] {c : CokernelCofork f}
    (i : IsColimit c) : BinaryBicone X c.pt where
  pt := Y
  fst := retraction f
  snd := c.π
  inl := f
  inr :=
    let c' : CokernelCofork (𝟙 Y - (𝟙 Y - retraction f ≫ f)) :=
      CokernelCofork.ofπ (Cofork.π c) (by simp)
    let i' : IsColimit c' := isCokernelEpiComp i (retraction f) (by simp)
    let i'' := isColimitCoforkOfCokernelCofork i'
    (splitEpiOfIdempotentOfIsColimitCofork C (by simp) i'').section_
  inl_fst := by simp
  inl_snd := by simp
  inr_fst := by
    

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : Preadditive C
J : Type
inst✝² : Fintype J
X✝ Y✝ : C
inst✝¹ : HasBinaryBiproduct X✝ Y✝
X Y : C
f : X ⟶ Y
inst✝ : IsSplitMono f
c : CokernelCofork f
i : IsColimit c
⊢ (let c' := CokernelCofork.ofπ (Cofork.π c) (_ : (𝟙 Y - (𝟙 Y - retraction f ≫ f)) ≫ Cofork.π c = 0);
      let i' := isCokernelEpiComp i (retraction f) (_ : 𝟙 Y - (𝟙 Y - retraction f ≫ f) = retraction f ≫ f);
      let i'' := isColimitCoforkOfCokernelCofork i';
      (splitEpiOfIdempotentOfIsColimitCofork C
          (_ : (𝟙 Y - retraction f ≫ f) ≫ (𝟙 Y - retraction f ≫ f) = 𝟙 Y - retraction f ≫ f) i'').section_) ≫
      retraction f =
    0

Next tactic:
dsimp only
/-- Every split mono `f` with a cokernel induces a binary bicone with `f` as its `inl` and
the cokernel map as its `snd`.
We will show in `is_bilimit_binary_bicone_of_split_mono_of_cokernel` that this binary bicone is in
fact already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitMonoOfCokernel {X Y : C} {f : X ⟶ Y} [IsSplitMono f] {c : CokernelCofork f}
    (i : IsColimit c) : BinaryBicone X c.pt where
  pt := Y
  fst := retraction f
  snd := c.π
  inl := f
  inr :=
    let c' : CokernelCofork (𝟙 Y - (𝟙 Y - retraction f ≫ f)) :=
      CokernelCofork.ofπ (Cofork.π c) (by simp)
    let i' : IsColimit c' := isCokernelEpiComp i (retraction f) (by simp)
    let i'' := isColimitCoforkOfCokernelCofork i'
    (splitEpiOfIdempotentOfIsColimitCofork C (by simp) i'').section_
  inl_fst := by simp
  inl_snd := by simp
  inr_fst := by
    dsimp only
    

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : Preadditive C
J : Type
inst✝² : Fintype J
X✝ Y✝ : C
inst✝¹ : HasBinaryBiproduct X✝ Y✝
X Y : C
f : X ⟶ Y
inst✝ : IsSplitMono f
c : CokernelCofork f
i : IsColimit c
⊢ (splitEpiOfIdempotentOfIsColimitCofork C
          (_ : (𝟙 Y - retraction f ≫ f) ≫ (𝟙 Y - retraction f ≫ f) = 𝟙 Y - retraction f ≫ f)
          (isColimitCoforkOfCokernelCofork
            (isCokernelEpiComp i (retraction f) (_ : 𝟙 Y - (𝟙 Y - retraction f ≫ f) = retraction f ≫ f)))).section_ ≫
      retraction f =
    0

Next tactic:
rw [splitEpiOfIdempotentOfIsColimitCofork_section_,
      isColimitCoforkOfCokernelCofork_desc, isCokernelEpiComp_desc]