l3lab/ntp-mathlib huggingface dataset:
theorem is_coprod_iff_isPushout {X E Y YE : C} (c : BinaryCofan X E) (hc : IsColimit c) {f : X ⟶ Y}
    {iY : Y ⟶ YE} {fE : c.pt ⟶ YE} (H : CommSq f c.inl iY fE) :
    Nonempty (IsColimit (BinaryCofan.mk (c.inr ≫ fE) iY)) ↔ IsPushout f c.inl iY fE := by
  constructor
  · rintro ⟨h⟩
    refine' ⟨H, ⟨Limits.PushoutCocone.isColimitAux' _ _⟩⟩
    intro s
    dsimp only [PushoutCocone.inr, PushoutCocone.mk] -- Porting note: Originally `dsimp`
    refine' ⟨h.desc (BinaryCofan.mk (c.inr ≫ s.inr) s.inl), h.fac _ ⟨WalkingPair.right⟩, _, _⟩
    · apply BinaryCofan.IsColimit.hom_ext hc
      · rw [← H.w_assoc]; erw [h.fac _ ⟨WalkingPair.right⟩]; exact s.condition
      · rw [← Category.assoc]; 

Proof state:
case mp.intro.refine'_1.h₂
J : Type v'
inst✝¹ : Category.{u', v'} J
C : Type u
inst✝ : Category.{v, u} C
W X✝ Y✝ Z : C
f✝ : W ⟶ X✝
g : W ⟶ Y✝
h✝ : X✝ ⟶ Z
i : Y✝ ⟶ Z
X E Y YE : C
c : BinaryCofan X E
hc : IsColimit c
f : X ⟶ Y
iY : Y ⟶ YE
fE : c.pt ⟶ YE
H : CommSq f (BinaryCofan.inl c) iY fE
h : IsColimit (BinaryCofan.mk (BinaryCofan.inr c ≫ fE) iY)
s : PushoutCocone f (BinaryCofan.inl c)
⊢ (BinaryCofan.inr c ≫ fE) ≫
      IsColimit.desc h (BinaryCofan.mk (BinaryCofan.inr c ≫ PushoutCocone.inr s) (PushoutCocone.inl s)) =
    BinaryCofan.inr c ≫ s.ι.app WalkingSpan.right

Next tactic:
exact h.fac _ ⟨WalkingPair.left⟩
theorem is_coprod_iff_isPushout {X E Y YE : C} (c : BinaryCofan X E) (hc : IsColimit c) {f : X ⟶ Y}
    {iY : Y ⟶ YE} {fE : c.pt ⟶ YE} (H : CommSq f c.inl iY fE) :
    Nonempty (IsColimit (BinaryCofan.mk (c.inr ≫ fE) iY)) ↔ IsPushout f c.inl iY fE := by
  constructor
  · rintro ⟨h⟩
    refine' ⟨H, ⟨Limits.PushoutCocone.isColimitAux' _ _⟩⟩
    intro s
    dsimp only [PushoutCocone.inr, PushoutCocone.mk] -- Porting note: Originally `dsimp`
    refine' ⟨h.desc (BinaryCofan.mk (c.inr ≫ s.inr) s.inl), h.fac _ ⟨WalkingPair.right⟩, _, _⟩
    · apply BinaryCofan.IsColimit.hom_ext hc
      · rw [← H.w_assoc]; erw [h.fac _ ⟨WalkingPair.right⟩]; exact s.condition
      · rw [← Category.assoc]; exact h.fac _ ⟨WalkingPair.left⟩
    · 

Proof state:
case mp.intro.refine'_2
J : Type v'
inst✝¹ : Category.{u', v'} J
C : Type u
inst✝ : Category.{v, u} C
W X✝ Y✝ Z : C
f✝ : W ⟶ X✝
g : W ⟶ Y✝
h✝ : X✝ ⟶ Z
i : Y✝ ⟶ Z
X E Y YE : C
c : BinaryCofan X E
hc : IsColimit c
f : X ⟶ Y
iY : Y ⟶ YE
fE : c.pt ⟶ YE
H : CommSq f (BinaryCofan.inl c) iY fE
h : IsColimit (BinaryCofan.mk (BinaryCofan.inr c ≫ fE) iY)
s : PushoutCocone f (BinaryCofan.inl c)
⊢ ∀ {m : YE ⟶ s.pt},
    PushoutCocone.inl
            { pt := YE, ι := NatTrans.mk fun j => Option.rec (f ≫ iY) (fun val => WalkingPair.rec iY fE val) j } ≫
          m =
        PushoutCocone.inl s →
      fE ≫ m = s.ι.app WalkingSpan.right →
        m = IsColimit.desc h (BinaryCofan.mk (BinaryCofan.inr c ≫ PushoutCocone.inr s) (PushoutCocone.inl s))

Next tactic:
intro m e₁ e₂
theorem is_coprod_iff_isPushout {X E Y YE : C} (c : BinaryCofan X E) (hc : IsColimit c) {f : X ⟶ Y}
    {iY : Y ⟶ YE} {fE : c.pt ⟶ YE} (H : CommSq f c.inl iY fE) :
    Nonempty (IsColimit (BinaryCofan.mk (c.inr ≫ fE) iY)) ↔ IsPushout f c.inl iY fE := by
  constructor
  · rintro ⟨h⟩
    refine' ⟨H, ⟨Limits.PushoutCocone.isColimitAux' _ _⟩⟩
    intro s
    dsimp only [PushoutCocone.inr, PushoutCocone.mk] -- Porting note: Originally `dsimp`
    refine' ⟨h.desc (BinaryCofan.mk (c.inr ≫ s.inr) s.inl), h.fac _ ⟨WalkingPair.right⟩, _, _⟩
    · apply BinaryCofan.IsColimit.hom_ext hc
      · rw [← H.w_assoc]; erw [h.fac _ ⟨WalkingPair.right⟩]; exact s.condition
      · rw [← Category.assoc]; exact h.fac _ ⟨WalkingPair.left⟩
    · intro m e₁ e₂
      

Proof state:
case mp.intro.refine'_2
J : Type v'
inst✝¹ : Category.{u', v'} J
C : Type u
inst✝ : Category.{v, u} C
W X✝ Y✝ Z : C
f✝ : W ⟶ X✝
g : W ⟶ Y✝
h✝ : X✝ ⟶ Z
i : Y✝ ⟶ Z
X E Y YE : C
c : BinaryCofan X E
hc : IsColimit c
f : X ⟶ Y
iY : Y ⟶ YE
fE : c.pt ⟶ YE
H : CommSq f (BinaryCofan.inl c) iY fE
h : IsColimit (BinaryCofan.mk (BinaryCofan.inr c ≫ fE) iY)
s : PushoutCocone f (BinaryCofan.inl c)
m : YE ⟶ s.pt
e₁ :
  PushoutCocone.inl
        { pt := YE, ι := NatTrans.mk fun j => Option.rec (f ≫ iY) (fun val => WalkingPair.rec iY fE val) j } ≫
      m =
    PushoutCocone.inl s
e₂ : fE ≫ m = s.ι.app WalkingSpan.right
⊢ m = IsColimit.desc h (BinaryCofan.mk (BinaryCofan.inr c ≫ PushoutCocone.inr s) (PushoutCocone.inl s))

Next tactic:
apply BinaryCofan.IsColimit.hom_ext h
theorem is_coprod_iff_isPushout {X E Y YE : C} (c : BinaryCofan X E) (hc : IsColimit c) {f : X ⟶ Y}
    {iY : Y ⟶ YE} {fE : c.pt ⟶ YE} (H : CommSq f c.inl iY fE) :
    Nonempty (IsColimit (BinaryCofan.mk (c.inr ≫ fE) iY)) ↔ IsPushout f c.inl iY fE := by
  constructor
  · rintro ⟨h⟩
    refine' ⟨H, ⟨Limits.PushoutCocone.isColimitAux' _ _⟩⟩
    intro s
    dsimp only [PushoutCocone.inr, PushoutCocone.mk] -- Porting note: Originally `dsimp`
    refine' ⟨h.desc (BinaryCofan.mk (c.inr ≫ s.inr) s.inl), h.fac _ ⟨WalkingPair.right⟩, _, _⟩
    · apply BinaryCofan.IsColimit.hom_ext hc
      · rw [← H.w_assoc]; erw [h.fac _ ⟨WalkingPair.right⟩]; exact s.condition
      · rw [← Category.assoc]; exact h.fac _ ⟨WalkingPair.left⟩
    · intro m e₁ e₂
      apply BinaryCofan.IsColimit.hom_ext h
      · 

Proof state:
case mp.intro.refine'_2.h₁
J : Type v'
inst✝¹ : Category.{u', v'} J
C : Type u
inst✝ : Category.{v, u} C
W X✝ Y✝ Z : C
f✝ : W ⟶ X✝
g : W ⟶ Y✝
h✝ : X✝ ⟶ Z
i : Y✝ ⟶ Z
X E Y YE : C
c : BinaryCofan X E
hc : IsColimit c
f : X ⟶ Y
iY : Y ⟶ YE
fE : c.pt ⟶ YE
H : CommSq f (BinaryCofan.inl c) iY fE
h : IsColimit (BinaryCofan.mk (BinaryCofan.inr c ≫ fE) iY)
s : PushoutCocone f (BinaryCofan.inl c)
m : YE ⟶ s.pt
e₁ :
  PushoutCocone.inl
        { pt := YE, ι := NatTrans.mk fun j => Option.rec (f ≫ iY) (fun val => WalkingPair.rec iY fE val) j } ≫
      m =
    PushoutCocone.inl s
e₂ : fE ≫ m = s.ι.app WalkingSpan.right
⊢ BinaryCofan.inl (BinaryCofan.mk (BinaryCofan.inr c ≫ fE) iY) ≫ m =
    BinaryCofan.inl (BinaryCofan.mk (BinaryCofan.inr c ≫ fE) iY) ≫
      IsColimit.desc h (BinaryCofan.mk (BinaryCofan.inr c ≫ PushoutCocone.inr s) (PushoutCocone.inl s))

Next tactic:
dsimp only [BinaryCofan.mk, id]
theorem is_coprod_iff_isPushout {X E Y YE : C} (c : BinaryCofan X E) (hc : IsColimit c) {f : X ⟶ Y}
    {iY : Y ⟶ YE} {fE : c.pt ⟶ YE} (H : CommSq f c.inl iY fE) :
    Nonempty (IsColimit (BinaryCofan.mk (c.inr ≫ fE) iY)) ↔ IsPushout f c.inl iY fE := by
  constructor
  · rintro ⟨h⟩
    refine' ⟨H, ⟨Limits.PushoutCocone.isColimitAux' _ _⟩⟩
    intro s
    dsimp only [PushoutCocone.inr, PushoutCocone.mk] -- Porting note: Originally `dsimp`
    refine' ⟨h.desc (BinaryCofan.mk (c.inr ≫ s.inr) s.inl), h.fac _ ⟨WalkingPair.right⟩, _, _⟩
    · apply BinaryCofan.IsColimit.hom_ext hc
      · rw [← H.w_assoc]; erw [h.fac _ ⟨WalkingPair.right⟩]; exact s.condition
      · rw [← Category.assoc]; exact h.fac _ ⟨WalkingPair.left⟩
    · intro m e₁ e₂
      apply BinaryCofan.IsColimit.hom_ext h
      · dsimp only [BinaryCofan.mk, id] -- Porting note: Originally `dsimp`
        

Proof state:
case mp.intro.refine'_2.h₁
J : Type v'
inst✝¹ : Category.{u', v'} J
C : Type u
inst✝ : Category.{v, u} C
W X✝ Y✝ Z : C
f✝ : W ⟶ X✝
g : W ⟶ Y✝
h✝ : X✝ ⟶ Z
i : Y✝ ⟶ Z
X E Y YE : C
c : BinaryCofan X E
hc : IsColimit c
f : X ⟶ Y
iY : Y ⟶ YE
fE : c.pt ⟶ YE
H : CommSq f (BinaryCofan.inl c) iY fE
h : IsColimit (BinaryCofan.mk (BinaryCofan.inr c ≫ fE) iY)
s : PushoutCocone f (BinaryCofan.inl c)
m : YE ⟶ s.pt
e₁ :
  PushoutCocone.inl
        { pt := YE, ι := NatTrans.mk fun j => Option.rec (f ≫ iY) (fun val => WalkingPair.rec iY fE val) j } ≫
      m =
    PushoutCocone.inl s
e₂ : fE ≫ m = s.ι.app WalkingSpan.right
⊢ BinaryCofan.inl
        { pt := YE,
          ι :=
            NatTrans.mk fun x =>
              WalkingPair.rec (motive := fun t =>
                x.as = t →
                  ((pair ((pair X E).obj { as := WalkingPair.right }) Y).obj { as := x.as } ⟶
                    ((Functor.const (Discrete WalkingPair)).obj YE).obj { as := x.as }))
                (fun h => (_ : WalkingPair.left = x.as) ▸ BinaryCofan.inr c ≫ fE)
                (fun h => (_ : WalkingPair.right = x.as) ▸ iY) x.as (_ : x.as = x.as) } ≫
      m =
    BinaryCofan.inl
        { pt := YE,
          ι :=
            NatTrans.mk fun x =>
              WalkingPair.rec (motive := fun t =>
                x.as = t →
                  ((pair ((pair X E).obj { as := WalkingPair.right }) Y).obj { as := x.as } ⟶
                    ((Functor.const (Discrete WalkingPair)).obj YE).obj { as := x.as }))
                (fun h => (_ : WalkingPair.left = x.as) ▸ BinaryCofan.inr c ≫ fE)
                (fun h => (_ : WalkingPair.right = x.as) ▸ iY) x.as (_ : x.as = x.as) } ≫
      IsColimit.desc h
        { pt := s.pt,
          ι :=
            NatTrans.mk fun x =>
              WalkingPair.rec (motive := fun t =>
                x.as = t →
                  ((pair ((pair X E).obj { as := WalkingPair.right }) Y).obj { as := x.as } ⟶
                    ((Functor.const (Discrete WalkingPair)).obj s.pt).obj { as := x.as }))
                (fun h => (_ : WalkingPair.left = x.as) ▸ BinaryCofan.inr c ≫ PushoutCocone.inr s)
                (fun h => (_ : WalkingPair.right = x.as) ▸ PushoutCocone.inl s) x.as (_ : x.as = x.as) }

Next tactic:
rw [Category.assoc, e₂, eq_comm]
theorem is_coprod_iff_isPushout {X E Y YE : C} (c : BinaryCofan X E) (hc : IsColimit c) {f : X ⟶ Y}
    {iY : Y ⟶ YE} {fE : c.pt ⟶ YE} (H : CommSq f c.inl iY fE) :
    Nonempty (IsColimit (BinaryCofan.mk (c.inr ≫ fE) iY)) ↔ IsPushout f c.inl iY fE := by
  constructor
  · rintro ⟨h⟩
    refine' ⟨H, ⟨Limits.PushoutCocone.isColimitAux' _ _⟩⟩
    intro s
    dsimp only [PushoutCocone.inr, PushoutCocone.mk] -- Porting note: Originally `dsimp`
    refine' ⟨h.desc (BinaryCofan.mk (c.inr ≫ s.inr) s.inl), h.fac _ ⟨WalkingPair.right⟩, _, _⟩
    · apply BinaryCofan.IsColimit.hom_ext hc
      · rw [← H.w_assoc]; erw [h.fac _ ⟨WalkingPair.right⟩]; exact s.condition
      · rw [← Category.assoc]; exact h.fac _ ⟨WalkingPair.left⟩
    · intro m e₁ e₂
      apply BinaryCofan.IsColimit.hom_ext h
      · dsimp only [BinaryCofan.mk, id] -- Porting note: Originally `dsimp`
        rw [Category.assoc, e₂, eq_comm]; 

Proof state:
case mp.intro.refine'_2.h₁
J : Type v'
inst✝¹ : Category.{u', v'} J
C : Type u
inst✝ : Category.{v, u} C
W X✝ Y✝ Z : C
f✝ : W ⟶ X✝
g : W ⟶ Y✝
h✝ : X✝ ⟶ Z
i : Y✝ ⟶ Z
X E Y YE : C
c : BinaryCofan X E
hc : IsColimit c
f : X ⟶ Y
iY : Y ⟶ YE
fE : c.pt ⟶ YE
H : CommSq f (BinaryCofan.inl c) iY fE
h : IsColimit (BinaryCofan.mk (BinaryCofan.inr c ≫ fE) iY)
s : PushoutCocone f (BinaryCofan.inl c)
m : YE ⟶ s.pt
e₁ :
  PushoutCocone.inl
        { pt := YE, ι := NatTrans.mk fun j => Option.rec (f ≫ iY) (fun val => WalkingPair.rec iY fE val) j } ≫
      m =
    PushoutCocone.inl s
e₂ : fE ≫ m = s.ι.app WalkingSpan.right
⊢ BinaryCofan.inl
        { pt := YE,
          ι :=
            NatTrans.mk fun x =>
              WalkingPair.rec (motive := fun t =>
                x.as = t →
                  ((pair ((pair X E).obj { as := WalkingPair.right }) Y).obj { as := x.as } ⟶
                    ((Functor.const (Discrete WalkingPair)).obj YE).obj { as := x.as }))
                (fun h => (_ : WalkingPair.left = x.as) ▸ BinaryCofan.inr c ≫ fE)
                (fun h => (_ : WalkingPair.right = x.as) ▸ iY) x.as (_ : x.as = x.as) } ≫
      IsColimit.desc h
        { pt := s.pt,
          ι :=
            NatTrans.mk fun x =>
              WalkingPair.rec (motive := fun t =>
                x.as = t →
                  ((pair ((pair X E).obj { as := WalkingPair.right }) Y).obj { as := x.as } ⟶
                    ((Functor.const (Discrete WalkingPair)).obj s.pt).obj { as := x.as }))
                (fun h => (_ : WalkingPair.left = x.as) ▸ BinaryCofan.inr c ≫ PushoutCocone.inr s)
                (fun h => (_ : WalkingPair.right = x.as) ▸ PushoutCocone.inl s) x.as (_ : x.as = x.as) } =
    BinaryCofan.inr c ≫ s.ι.app WalkingSpan.right

Next tactic:
exact h.fac _ ⟨WalkingPair.left⟩
theorem is_coprod_iff_isPushout {X E Y YE : C} (c : BinaryCofan X E) (hc : IsColimit c) {f : X ⟶ Y}
    {iY : Y ⟶ YE} {fE : c.pt ⟶ YE} (H : CommSq f c.inl iY fE) :
    Nonempty (IsColimit (BinaryCofan.mk (c.inr ≫ fE) iY)) ↔ IsPushout f c.inl iY fE := by
  constructor
  · rintro ⟨h⟩
    refine' ⟨H, ⟨Limits.PushoutCocone.isColimitAux' _ _⟩⟩
    intro s
    dsimp only [PushoutCocone.inr, PushoutCocone.mk] -- Porting note: Originally `dsimp`
    refine' ⟨h.desc (BinaryCofan.mk (c.inr ≫ s.inr) s.inl), h.fac _ ⟨WalkingPair.right⟩, _, _⟩
    · apply BinaryCofan.IsColimit.hom_ext hc
      · rw [← H.w_assoc]; erw [h.fac _ ⟨WalkingPair.right⟩]; exact s.condition
      · rw [← Category.assoc]; exact h.fac _ ⟨WalkingPair.left⟩
    · intro m e₁ e₂
      apply BinaryCofan.IsColimit.hom_ext h
      · dsimp only [BinaryCofan.mk, id] -- Porting note: Originally `dsimp`
        rw [Category.assoc, e₂, eq_comm]; exact h.fac _ ⟨WalkingPair.left⟩
      · 

Proof state:
case mp.intro.refine'_2.h₂
J : Type v'
inst✝¹ : Category.{u', v'} J
C : Type u
inst✝ : Category.{v, u} C
W X✝ Y✝ Z : C
f✝ : W ⟶ X✝
g : W ⟶ Y✝
h✝ : X✝ ⟶ Z
i : Y✝ ⟶ Z
X E Y YE : C
c : BinaryCofan X E
hc : IsColimit c
f : X ⟶ Y
iY : Y ⟶ YE
fE : c.pt ⟶ YE
H : CommSq f (BinaryCofan.inl c) iY fE
h : IsColimit (BinaryCofan.mk (BinaryCofan.inr c ≫ fE) iY)
s : PushoutCocone f (BinaryCofan.inl c)
m : YE ⟶ s.pt
e₁ :
  PushoutCocone.inl
        { pt := YE, ι := NatTrans.mk fun j => Option.rec (f ≫ iY) (fun val => WalkingPair.rec iY fE val) j } ≫
      m =
    PushoutCocone.inl s
e₂ : fE ≫ m = s.ι.app WalkingSpan.right
⊢ BinaryCofan.inr (BinaryCofan.mk (BinaryCofan.inr c ≫ fE) iY) ≫ m =
    BinaryCofan.inr (BinaryCofan.mk (BinaryCofan.inr c ≫ fE) iY) ≫
      IsColimit.desc h (BinaryCofan.mk (BinaryCofan.inr c ≫ PushoutCocone.inr s) (PushoutCocone.inl s))

Next tactic:
refine' e₁.trans (Eq.symm _)
theorem is_coprod_iff_isPushout {X E Y YE : C} (c : BinaryCofan X E) (hc : IsColimit c) {f : X ⟶ Y}
    {iY : Y ⟶ YE} {fE : c.pt ⟶ YE} (H : CommSq f c.inl iY fE) :
    Nonempty (IsColimit (BinaryCofan.mk (c.inr ≫ fE) iY)) ↔ IsPushout f c.inl iY fE := by
  constructor
  · rintro ⟨h⟩
    refine' ⟨H, ⟨Limits.PushoutCocone.isColimitAux' _ _⟩⟩
    intro s
    dsimp only [PushoutCocone.inr, PushoutCocone.mk] -- Porting note: Originally `dsimp`
    refine' ⟨h.desc (BinaryCofan.mk (c.inr ≫ s.inr) s.inl), h.fac _ ⟨WalkingPair.right⟩, _, _⟩
    · apply BinaryCofan.IsColimit.hom_ext hc
      · rw [← H.w_assoc]; erw [h.fac _ ⟨WalkingPair.right⟩]; exact s.condition
      · rw [← Category.assoc]; exact h.fac _ ⟨WalkingPair.left⟩
    · intro m e₁ e₂
      apply BinaryCofan.IsColimit.hom_ext h
      · dsimp only [BinaryCofan.mk, id] -- Porting note: Originally `dsimp`
        rw [Category.assoc, e₂, eq_comm]; exact h.fac _ ⟨WalkingPair.left⟩
      · refine' e₁.trans (Eq.symm _); 

Proof state:
case mp.intro.refine'_2.h₂
J : Type v'
inst✝¹ : Category.{u', v'} J
C : Type u
inst✝ : Category.{v, u} C
W X✝ Y✝ Z : C
f✝ : W ⟶ X✝
g : W ⟶ Y✝
h✝ : X✝ ⟶ Z
i : Y✝ ⟶ Z
X E Y YE : C
c : BinaryCofan X E
hc : IsColimit c
f : X ⟶ Y
iY : Y ⟶ YE
fE : c.pt ⟶ YE
H : CommSq f (BinaryCofan.inl c) iY fE
h : IsColimit (BinaryCofan.mk (BinaryCofan.inr c ≫ fE) iY)
s : PushoutCocone f (BinaryCofan.inl c)
m : YE ⟶ s.pt
e₁ :
  PushoutCocone.inl
        { pt := YE, ι := NatTrans.mk fun j => Option.rec (f ≫ iY) (fun val => WalkingPair.rec iY fE val) j } ≫
      m =
    PushoutCocone.inl s
e₂ : fE ≫ m = s.ι.app WalkingSpan.right
⊢ BinaryCofan.inr (BinaryCofan.mk (BinaryCofan.inr c ≫ fE) iY) ≫
      IsColimit.desc h (BinaryCofan.mk (BinaryCofan.inr c ≫ PushoutCocone.inr s) (PushoutCocone.inl s)) =
    PushoutCocone.inl s

Next tactic:
exact h.fac _ _
theorem is_coprod_iff_isPushout {X E Y YE : C} (c : BinaryCofan X E) (hc : IsColimit c) {f : X ⟶ Y}
    {iY : Y ⟶ YE} {fE : c.pt ⟶ YE} (H : CommSq f c.inl iY fE) :
    Nonempty (IsColimit (BinaryCofan.mk (c.inr ≫ fE) iY)) ↔ IsPushout f c.inl iY fE := by
  constructor
  · rintro ⟨h⟩
    refine' ⟨H, ⟨Limits.PushoutCocone.isColimitAux' _ _⟩⟩
    intro s
    dsimp only [PushoutCocone.inr, PushoutCocone.mk] -- Porting note: Originally `dsimp`
    refine' ⟨h.desc (BinaryCofan.mk (c.inr ≫ s.inr) s.inl), h.fac _ ⟨WalkingPair.right⟩, _, _⟩
    · apply BinaryCofan.IsColimit.hom_ext hc
      · rw [← H.w_assoc]; erw [h.fac _ ⟨WalkingPair.right⟩]; exact s.condition
      · rw [← Category.assoc]; exact h.fac _ ⟨WalkingPair.left⟩
    · intro m e₁ e₂
      apply BinaryCofan.IsColimit.hom_ext h
      · dsimp only [BinaryCofan.mk, id] -- Porting note: Originally `dsimp`
        rw [Category.assoc, e₂, eq_comm]; exact h.fac _ ⟨WalkingPair.left⟩
      · refine' e₁.trans (Eq.symm _); exact h.fac _ _
  · 

Proof state:
case mpr
J : Type v'
inst✝¹ : Category.{u', v'} J
C : Type u
inst✝ : Category.{v, u} C
W X✝ Y✝ Z : C
f✝ : W ⟶ X✝
g : W ⟶ Y✝
h : X✝ ⟶ Z
i : Y✝ ⟶ Z
X E Y YE : C
c : BinaryCofan X E
hc : IsColimit c
f : X ⟶ Y
iY : Y ⟶ YE
fE : c.pt ⟶ YE
H : CommSq f (BinaryCofan.inl c) iY fE
⊢ IsPushout f (BinaryCofan.inl c) iY fE → Nonempty (IsColimit (BinaryCofan.mk (BinaryCofan.inr c ≫ fE) iY))

Next tactic:
refine' fun H => ⟨_⟩
theorem is_coprod_iff_isPushout {X E Y YE : C} (c : BinaryCofan X E) (hc : IsColimit c) {f : X ⟶ Y}
    {iY : Y ⟶ YE} {fE : c.pt ⟶ YE} (H : CommSq f c.inl iY fE) :
    Nonempty (IsColimit (BinaryCofan.mk (c.inr ≫ fE) iY)) ↔ IsPushout f c.inl iY fE := by
  constructor
  · rintro ⟨h⟩
    refine' ⟨H, ⟨Limits.PushoutCocone.isColimitAux' _ _⟩⟩
    intro s
    dsimp only [PushoutCocone.inr, PushoutCocone.mk] -- Porting note: Originally `dsimp`
    refine' ⟨h.desc (BinaryCofan.mk (c.inr ≫ s.inr) s.inl), h.fac _ ⟨WalkingPair.right⟩, _, _⟩
    · apply BinaryCofan.IsColimit.hom_ext hc
      · rw [← H.w_assoc]; erw [h.fac _ ⟨WalkingPair.right⟩]; exact s.condition
      · rw [← Category.assoc]; exact h.fac _ ⟨WalkingPair.left⟩
    · intro m e₁ e₂
      apply BinaryCofan.IsColimit.hom_ext h
      · dsimp only [BinaryCofan.mk, id] -- Porting note: Originally `dsimp`
        rw [Category.assoc, e₂, eq_comm]; exact h.fac _ ⟨WalkingPair.left⟩
      · refine' e₁.trans (Eq.symm _); exact h.fac _ _
  · refine' fun H => ⟨_⟩
    

Proof state:
case mpr
J : Type v'
inst✝¹ : Category.{u', v'} J
C : Type u
inst✝ : Category.{v, u} C
W X✝ Y✝ Z : C
f✝ : W ⟶ X✝
g : W ⟶ Y✝
h : X✝ ⟶ Z
i : Y✝ ⟶ Z
X E Y YE : C
c : BinaryCofan X E
hc : IsColimit c
f : X ⟶ Y
iY : Y ⟶ YE
fE : c.pt ⟶ YE
H✝ : CommSq f (BinaryCofan.inl c) iY fE
H : IsPushout f (BinaryCofan.inl c) iY fE
⊢ IsColimit (BinaryCofan.mk (BinaryCofan.inr c ≫ fE) iY)

Next tactic:
fapply Limits.BinaryCofan.isColimitMk
theorem is_coprod_iff_isPushout {X E Y YE : C} (c : BinaryCofan X E) (hc : IsColimit c) {f : X ⟶ Y}
    {iY : Y ⟶ YE} {fE : c.pt ⟶ YE} (H : CommSq f c.inl iY fE) :
    Nonempty (IsColimit (BinaryCofan.mk (c.inr ≫ fE) iY)) ↔ IsPushout f c.inl iY fE := by
  constructor
  · rintro ⟨h⟩
    refine' ⟨H, ⟨Limits.PushoutCocone.isColimitAux' _ _⟩⟩
    intro s
    dsimp only [PushoutCocone.inr, PushoutCocone.mk] -- Porting note: Originally `dsimp`
    refine' ⟨h.desc (BinaryCofan.mk (c.inr ≫ s.inr) s.inl), h.fac _ ⟨WalkingPair.right⟩, _, _⟩
    · apply BinaryCofan.IsColimit.hom_ext hc
      · rw [← H.w_assoc]; erw [h.fac _ ⟨WalkingPair.right⟩]; exact s.condition
      · rw [← Category.assoc]; exact h.fac _ ⟨WalkingPair.left⟩
    · intro m e₁ e₂
      apply BinaryCofan.IsColimit.hom_ext h
      · dsimp only [BinaryCofan.mk, id] -- Porting note: Originally `dsimp`
        rw [Category.assoc, e₂, eq_comm]; exact h.fac _ ⟨WalkingPair.left⟩
      · refine' e₁.trans (Eq.symm _); exact h.fac _ _
  · refine' fun H => ⟨_⟩
    fapply Limits.BinaryCofan.isColimitMk
    · 

Proof state:
case mpr.desc
J : Type v'
inst✝¹ : Category.{u', v'} J
C : Type u
inst✝ : Category.{v, u} C
W X✝ Y✝ Z : C
f✝ : W ⟶ X✝
g : W ⟶ Y✝
h : X✝ ⟶ Z
i : Y✝ ⟶ Z
X E Y YE : C
c : BinaryCofan X E
hc : IsColimit c
f : X ⟶ Y
iY : Y ⟶ YE
fE : c.pt ⟶ YE
H✝ : CommSq f (BinaryCofan.inl c) iY fE
H : IsPushout f (BinaryCofan.inl c) iY fE
⊢ (s : BinaryCofan ((pair X E).obj { as := WalkingPair.right }) Y) → YE ⟶ s.pt

Next tactic:
exact fun s => H.isColimit.desc (PushoutCocone.mk s.inr _ <|
        (hc.fac (BinaryCofan.mk (f ≫ s.inr) s.inl) ⟨WalkingPair.left⟩).symm)
theorem is_coprod_iff_isPushout {X E Y YE : C} (c : BinaryCofan X E) (hc : IsColimit c) {f : X ⟶ Y}
    {iY : Y ⟶ YE} {fE : c.pt ⟶ YE} (H : CommSq f c.inl iY fE) :
    Nonempty (IsColimit (BinaryCofan.mk (c.inr ≫ fE) iY)) ↔ IsPushout f c.inl iY fE := by
  constructor
  · rintro ⟨h⟩
    refine' ⟨H, ⟨Limits.PushoutCocone.isColimitAux' _ _⟩⟩
    intro s
    dsimp only [PushoutCocone.inr, PushoutCocone.mk] -- Porting note: Originally `dsimp`
    refine' ⟨h.desc (BinaryCofan.mk (c.inr ≫ s.inr) s.inl), h.fac _ ⟨WalkingPair.right⟩, _, _⟩
    · apply BinaryCofan.IsColimit.hom_ext hc
      · rw [← H.w_assoc]; erw [h.fac _ ⟨WalkingPair.right⟩]; exact s.condition
      · rw [← Category.assoc]; exact h.fac _ ⟨WalkingPair.left⟩
    · intro m e₁ e₂
      apply BinaryCofan.IsColimit.hom_ext h
      · dsimp only [BinaryCofan.mk, id] -- Porting note: Originally `dsimp`
        rw [Category.assoc, e₂, eq_comm]; exact h.fac _ ⟨WalkingPair.left⟩
      · refine' e₁.trans (Eq.symm _); exact h.fac _ _
  · refine' fun H => ⟨_⟩
    fapply Limits.BinaryCofan.isColimitMk
    · exact fun s => H.isColimit.desc (PushoutCocone.mk s.inr _ <|
        (hc.fac (BinaryCofan.mk (f ≫ s.inr) s.inl) ⟨WalkingPair.left⟩).symm)
    · 

Proof state:
case mpr.fac_left
J : Type v'
inst✝¹ : Category.{u', v'} J
C : Type u
inst✝ : Category.{v, u} C
W X✝ Y✝ Z : C
f✝ : W ⟶ X✝
g : W ⟶ Y✝
h : X✝ ⟶ Z
i : Y✝ ⟶ Z
X E Y YE : C
c : BinaryCofan X E
hc : IsColimit c
f : X ⟶ Y
iY : Y ⟶ YE
fE : c.pt ⟶ YE
H✝ : CommSq f (BinaryCofan.inl c) iY fE
H : IsPushout f (BinaryCofan.inl c) iY fE
⊢ ∀ (s : BinaryCofan ((pair X E).obj { as := WalkingPair.right }) Y),
    (BinaryCofan.inr c ≫ fE) ≫
        IsColimit.desc (IsPushout.isColimit H)
          (PushoutCocone.mk (BinaryCofan.inr s)
            (IsColimit.desc hc (BinaryCofan.mk (f ≫ BinaryCofan.inr s) (BinaryCofan.inl s)))
            (_ :
              (BinaryCofan.mk (f ≫ BinaryCofan.inr s) (BinaryCofan.inl s)).ι.app { as := WalkingPair.left } =
                c.ι.app { as := WalkingPair.left } ≫
                  IsColimit.desc hc (BinaryCofan.mk (f ≫ BinaryCofan.inr s) (BinaryCofan.inl s)))) =
      BinaryCofan.inl s

Next tactic:
intro s