l3lab/ntp-mathlib huggingface dataset:
theorem IsPushout.isVanKampen_iff (H : IsPushout f g h i) :
    H.IsVanKampen ↔ IsVanKampenColimit (PushoutCocone.mk h i H.w) := by
  constructor
  · intro H F' c' α fα eα hα
    refine' Iff.trans _
        ((H (F'.map WalkingSpan.Hom.fst) (F'.map WalkingSpan.Hom.snd) (c'.ι.app _) (c'.ι.app _)
          (α.app _) (α.app _) (α.app _) fα (by convert hα WalkingSpan.Hom.fst)
          (by convert hα WalkingSpan.Hom.snd) _ _ _).trans _)
    · have : F'.map WalkingSpan.Hom.fst ≫ c'.ι.app WalkingSpan.left =
          F'.map WalkingSpan.Hom.snd ≫ c'.ι.app WalkingSpan.right := by
        simp only [Cocone.w]
      rw [(IsColimit.equivOfNatIsoOfIso (diagramIsoSpan F') c' (PushoutCocone.mk _ _ this)
            _).nonempty_congr]
      · exact ⟨fun h => ⟨⟨this⟩, h⟩, fun h => h.2⟩
      · refine' Cocones.ext (Iso.refl c'.pt) _
        rintro (_ | _ | _) <;> dsimp <;>
          simp only [c'.w, Category.assoc, Category.id_comp, Category.comp_id]
    · exact ⟨NatTrans.congr_app eα.symm _⟩
    · exact ⟨NatTrans.congr_app eα.symm _⟩
    · exact ⟨by simp⟩
    constructor
    · rintro ⟨h₁, h₂⟩ (_ | _ | _)
      · rw [← c'.w WalkingSpan.Hom.fst]; exact (hα WalkingSpan.Hom.fst).paste_horiz h₁
      exacts [h₁, h₂]
    · intro h; exact ⟨h _, h _⟩
  · introv H W' hf hg hh hi w
    refine'
      Iff.trans _ ((H w.cocone ⟨by rintro (_ | _ | _); exacts [αW, αX, αY], _⟩ αZ _ _).trans _)
    rotate_left
    · rintro i _ (_ | _ | _)
      · dsimp; simp only [Functor.map_id, Category.comp_id, Category.id_comp]
      exacts [hf.w, hg.w]
    · ext (_ | _ | _)
      · dsimp; rw [PushoutCocone.condition_zero]; erw [Category.assoc, hh.w, hf.w_assoc]
      exacts [hh.w.symm, hi.w.symm]
    · rintro i _ (_ | _ | _)
      · dsimp; simp_rw [Functor.map_id]
        exact IsPullback.of_horiz_isIso ⟨by rw [Category.comp_id, Category.id_comp]⟩
      exacts [hf, hg]
    · constructor
      · intro h; exact ⟨h WalkingCospan.left, h WalkingCospan.right⟩
      · rintro ⟨h₁, h₂⟩ (_ | _ | _)
        · 

Proof state:
case mpr.refine'_5.mpr.intro.none
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
H✝ : IsPushout f g h i
H : IsVanKampenColimit (PushoutCocone.mk h i (_ : f ≫ h = g ≫ i))
W' X' Y' Z' : C
f' : W' ⟶ X'
g' : W' ⟶ Y'
h' : X' ⟶ Z'
i' : Y' ⟶ Z'
αW : W' ⟶ W
αX : X' ⟶ X
αY : Y' ⟶ Y
αZ : Z' ⟶ Z
hf : IsPullback f' αW αX f
hg : IsPullback g' αW αY g
hh : CommSq h' αX αZ h
hi : CommSq i' αY αZ i
w : CommSq f' g' h' i'
h₁ : IsPullback h' αX αZ h
h₂ : IsPullback i' αY αZ i
⊢ IsPullback ((CommSq.cocone w).ι.app none)
    ((NatTrans.mk fun X_1 => Option.casesOn X_1 αW fun val => WalkingPair.casesOn val αX αY).app none) αZ
    ((PushoutCocone.mk h i (_ : f ≫ h = g ≫ i)).ι.app none)

Next tactic:
dsimp
theorem IsPushout.isVanKampen_iff (H : IsPushout f g h i) :
    H.IsVanKampen ↔ IsVanKampenColimit (PushoutCocone.mk h i H.w) := by
  constructor
  · intro H F' c' α fα eα hα
    refine' Iff.trans _
        ((H (F'.map WalkingSpan.Hom.fst) (F'.map WalkingSpan.Hom.snd) (c'.ι.app _) (c'.ι.app _)
          (α.app _) (α.app _) (α.app _) fα (by convert hα WalkingSpan.Hom.fst)
          (by convert hα WalkingSpan.Hom.snd) _ _ _).trans _)
    · have : F'.map WalkingSpan.Hom.fst ≫ c'.ι.app WalkingSpan.left =
          F'.map WalkingSpan.Hom.snd ≫ c'.ι.app WalkingSpan.right := by
        simp only [Cocone.w]
      rw [(IsColimit.equivOfNatIsoOfIso (diagramIsoSpan F') c' (PushoutCocone.mk _ _ this)
            _).nonempty_congr]
      · exact ⟨fun h => ⟨⟨this⟩, h⟩, fun h => h.2⟩
      · refine' Cocones.ext (Iso.refl c'.pt) _
        rintro (_ | _ | _) <;> dsimp <;>
          simp only [c'.w, Category.assoc, Category.id_comp, Category.comp_id]
    · exact ⟨NatTrans.congr_app eα.symm _⟩
    · exact ⟨NatTrans.congr_app eα.symm _⟩
    · exact ⟨by simp⟩
    constructor
    · rintro ⟨h₁, h₂⟩ (_ | _ | _)
      · rw [← c'.w WalkingSpan.Hom.fst]; exact (hα WalkingSpan.Hom.fst).paste_horiz h₁
      exacts [h₁, h₂]
    · intro h; exact ⟨h _, h _⟩
  · introv H W' hf hg hh hi w
    refine'
      Iff.trans _ ((H w.cocone ⟨by rintro (_ | _ | _); exacts [αW, αX, αY], _⟩ αZ _ _).trans _)
    rotate_left
    · rintro i _ (_ | _ | _)
      · dsimp; simp only [Functor.map_id, Category.comp_id, Category.id_comp]
      exacts [hf.w, hg.w]
    · ext (_ | _ | _)
      · dsimp; rw [PushoutCocone.condition_zero]; erw [Category.assoc, hh.w, hf.w_assoc]
      exacts [hh.w.symm, hi.w.symm]
    · rintro i _ (_ | _ | _)
      · dsimp; simp_rw [Functor.map_id]
        exact IsPullback.of_horiz_isIso ⟨by rw [Category.comp_id, Category.id_comp]⟩
      exacts [hf, hg]
    · constructor
      · intro h; exact ⟨h WalkingCospan.left, h WalkingCospan.right⟩
      · rintro ⟨h₁, h₂⟩ (_ | _ | _)
        · dsimp; 

Proof state:
case mpr.refine'_5.mpr.intro.none
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
H✝ : IsPushout f g h i
H : IsVanKampenColimit (PushoutCocone.mk h i (_ : f ≫ h = g ≫ i))
W' X' Y' Z' : C
f' : W' ⟶ X'
g' : W' ⟶ Y'
h' : X' ⟶ Z'
i' : Y' ⟶ Z'
αW : W' ⟶ W
αX : X' ⟶ X
αY : Y' ⟶ Y
αZ : Z' ⟶ Z
hf : IsPullback f' αW αX f
hg : IsPullback g' αW αY g
hh : CommSq h' αX αZ h
hi : CommSq i' αY αZ i
w : CommSq f' g' h' i'
h₁ : IsPullback h' αX αZ h
h₂ : IsPullback i' αY αZ i
⊢ IsPullback ((CommSq.cocone w).ι.app none) αW αZ (f ≫ h)

Next tactic:
rw [PushoutCocone.condition_zero]
theorem IsPushout.isVanKampen_iff (H : IsPushout f g h i) :
    H.IsVanKampen ↔ IsVanKampenColimit (PushoutCocone.mk h i H.w) := by
  constructor
  · intro H F' c' α fα eα hα
    refine' Iff.trans _
        ((H (F'.map WalkingSpan.Hom.fst) (F'.map WalkingSpan.Hom.snd) (c'.ι.app _) (c'.ι.app _)
          (α.app _) (α.app _) (α.app _) fα (by convert hα WalkingSpan.Hom.fst)
          (by convert hα WalkingSpan.Hom.snd) _ _ _).trans _)
    · have : F'.map WalkingSpan.Hom.fst ≫ c'.ι.app WalkingSpan.left =
          F'.map WalkingSpan.Hom.snd ≫ c'.ι.app WalkingSpan.right := by
        simp only [Cocone.w]
      rw [(IsColimit.equivOfNatIsoOfIso (diagramIsoSpan F') c' (PushoutCocone.mk _ _ this)
            _).nonempty_congr]
      · exact ⟨fun h => ⟨⟨this⟩, h⟩, fun h => h.2⟩
      · refine' Cocones.ext (Iso.refl c'.pt) _
        rintro (_ | _ | _) <;> dsimp <;>
          simp only [c'.w, Category.assoc, Category.id_comp, Category.comp_id]
    · exact ⟨NatTrans.congr_app eα.symm _⟩
    · exact ⟨NatTrans.congr_app eα.symm _⟩
    · exact ⟨by simp⟩
    constructor
    · rintro ⟨h₁, h₂⟩ (_ | _ | _)
      · rw [← c'.w WalkingSpan.Hom.fst]; exact (hα WalkingSpan.Hom.fst).paste_horiz h₁
      exacts [h₁, h₂]
    · intro h; exact ⟨h _, h _⟩
  · introv H W' hf hg hh hi w
    refine'
      Iff.trans _ ((H w.cocone ⟨by rintro (_ | _ | _); exacts [αW, αX, αY], _⟩ αZ _ _).trans _)
    rotate_left
    · rintro i _ (_ | _ | _)
      · dsimp; simp only [Functor.map_id, Category.comp_id, Category.id_comp]
      exacts [hf.w, hg.w]
    · ext (_ | _ | _)
      · dsimp; rw [PushoutCocone.condition_zero]; erw [Category.assoc, hh.w, hf.w_assoc]
      exacts [hh.w.symm, hi.w.symm]
    · rintro i _ (_ | _ | _)
      · dsimp; simp_rw [Functor.map_id]
        exact IsPullback.of_horiz_isIso ⟨by rw [Category.comp_id, Category.id_comp]⟩
      exacts [hf, hg]
    · constructor
      · intro h; exact ⟨h WalkingCospan.left, h WalkingCospan.right⟩
      · rintro ⟨h₁, h₂⟩ (_ | _ | _)
        · dsimp; rw [PushoutCocone.condition_zero]; 

Proof state:
case mpr.refine'_5.mpr.intro.none
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
H✝ : IsPushout f g h i
H : IsVanKampenColimit (PushoutCocone.mk h i (_ : f ≫ h = g ≫ i))
W' X' Y' Z' : C
f' : W' ⟶ X'
g' : W' ⟶ Y'
h' : X' ⟶ Z'
i' : Y' ⟶ Z'
αW : W' ⟶ W
αX : X' ⟶ X
αY : Y' ⟶ Y
αZ : Z' ⟶ Z
hf : IsPullback f' αW αX f
hg : IsPullback g' αW αY g
hh : CommSq h' αX αZ h
hi : CommSq i' αY αZ i
w : CommSq f' g' h' i'
h₁ : IsPullback h' αX αZ h
h₂ : IsPullback i' αY αZ i
⊢ IsPullback (f' ≫ PushoutCocone.inl (CommSq.cocone w)) αW αZ (f ≫ h)

Next tactic:
exact hf.paste_horiz h₁
theorem IsPushout.isVanKampen_iff (H : IsPushout f g h i) :
    H.IsVanKampen ↔ IsVanKampenColimit (PushoutCocone.mk h i H.w) := by
  constructor
  · intro H F' c' α fα eα hα
    refine' Iff.trans _
        ((H (F'.map WalkingSpan.Hom.fst) (F'.map WalkingSpan.Hom.snd) (c'.ι.app _) (c'.ι.app _)
          (α.app _) (α.app _) (α.app _) fα (by convert hα WalkingSpan.Hom.fst)
          (by convert hα WalkingSpan.Hom.snd) _ _ _).trans _)
    · have : F'.map WalkingSpan.Hom.fst ≫ c'.ι.app WalkingSpan.left =
          F'.map WalkingSpan.Hom.snd ≫ c'.ι.app WalkingSpan.right := by
        simp only [Cocone.w]
      rw [(IsColimit.equivOfNatIsoOfIso (diagramIsoSpan F') c' (PushoutCocone.mk _ _ this)
            _).nonempty_congr]
      · exact ⟨fun h => ⟨⟨this⟩, h⟩, fun h => h.2⟩
      · refine' Cocones.ext (Iso.refl c'.pt) _
        rintro (_ | _ | _) <;> dsimp <;>
          simp only [c'.w, Category.assoc, Category.id_comp, Category.comp_id]
    · exact ⟨NatTrans.congr_app eα.symm _⟩
    · exact ⟨NatTrans.congr_app eα.symm _⟩
    · exact ⟨by simp⟩
    constructor
    · rintro ⟨h₁, h₂⟩ (_ | _ | _)
      · rw [← c'.w WalkingSpan.Hom.fst]; exact (hα WalkingSpan.Hom.fst).paste_horiz h₁
      exacts [h₁, h₂]
    · intro h; exact ⟨h _, h _⟩
  · introv H W' hf hg hh hi w
    refine'
      Iff.trans _ ((H w.cocone ⟨by rintro (_ | _ | _); exacts [αW, αX, αY], _⟩ αZ _ _).trans _)
    rotate_left
    · rintro i _ (_ | _ | _)
      · dsimp; simp only [Functor.map_id, Category.comp_id, Category.id_comp]
      exacts [hf.w, hg.w]
    · ext (_ | _ | _)
      · dsimp; rw [PushoutCocone.condition_zero]; erw [Category.assoc, hh.w, hf.w_assoc]
      exacts [hh.w.symm, hi.w.symm]
    · rintro i _ (_ | _ | _)
      · dsimp; simp_rw [Functor.map_id]
        exact IsPullback.of_horiz_isIso ⟨by rw [Category.comp_id, Category.id_comp]⟩
      exacts [hf, hg]
    · constructor
      · intro h; exact ⟨h WalkingCospan.left, h WalkingCospan.right⟩
      · rintro ⟨h₁, h₂⟩ (_ | _ | _)
        · dsimp; rw [PushoutCocone.condition_zero]; exact hf.paste_horiz h₁
        exacts [h₁, h₂]
    · 

Proof state:
case mpr.refine'_1
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
H✝ : IsPushout f g h i
H : IsVanKampenColimit (PushoutCocone.mk h i (_ : f ≫ h = g ≫ i))
W' X' Y' Z' : C
f' : W' ⟶ X'
g' : W' ⟶ Y'
h' : X' ⟶ Z'
i' : Y' ⟶ Z'
αW : W' ⟶ W
αX : X' ⟶ X
αY : Y' ⟶ Y
αZ : Z' ⟶ Z
hf : IsPullback f' αW αX f
hg : IsPullback g' αW αY g
hh : CommSq h' αX αZ h
hi : CommSq i' αY αZ i
w : CommSq f' g' h' i'
⊢ IsPushout f' g' h' i' ↔ Nonempty (IsColimit (CommSq.cocone w))

Next tactic:
exact ⟨fun h => h.2, fun h => ⟨w, 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
  

Proof state:
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
⊢ Nonempty (IsColimit (BinaryCofan.mk (BinaryCofan.inr c ≫ fE) iY)) ↔ IsPushout f (BinaryCofan.inl c) iY fE

Next tactic:
constructor
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
  · 

Proof state:
case mp
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
⊢ Nonempty (IsColimit (BinaryCofan.mk (BinaryCofan.inr c ≫ fE) iY)) → IsPushout f (BinaryCofan.inl c) iY fE

Next tactic:
rintro ⟨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⟩
    

Proof state:
case mp.intro
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)
⊢ IsPushout f (BinaryCofan.inl c) iY fE

Next tactic:
refine' ⟨H, ⟨Limits.PushoutCocone.isColimitAux' _ _⟩⟩
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' _ _⟩⟩
    

Proof state:
case mp.intro
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)) →
    { l //
      PushoutCocone.inl (PushoutCocone.mk iY fE (_ : f ≫ iY = BinaryCofan.inl c ≫ fE)) ≫ l = PushoutCocone.inl s ∧
        PushoutCocone.inr (PushoutCocone.mk iY fE (_ : f ≫ iY = BinaryCofan.inl c ≫ fE)) ≫ l = PushoutCocone.inr s ∧
          ∀ {m : (PushoutCocone.mk iY fE (_ : f ≫ iY = BinaryCofan.inl c ≫ fE)).pt ⟶ s.pt},
            PushoutCocone.inl (PushoutCocone.mk iY fE (_ : f ≫ iY = BinaryCofan.inl c ≫ fE)) ≫ m = PushoutCocone.inl s →
              PushoutCocone.inr (PushoutCocone.mk iY fE (_ : f ≫ iY = BinaryCofan.inl c ≫ fE)) ≫ m =
                  PushoutCocone.inr s →
                m = l }

Next tactic:
intro s
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
    

Proof state:
case mp.intro
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)
⊢ { l //
    PushoutCocone.inl (PushoutCocone.mk iY fE (_ : f ≫ iY = BinaryCofan.inl c ≫ fE)) ≫ l = PushoutCocone.inl s ∧
      PushoutCocone.inr (PushoutCocone.mk iY fE (_ : f ≫ iY = BinaryCofan.inl c ≫ fE)) ≫ l = PushoutCocone.inr s ∧
        ∀ {m : (PushoutCocone.mk iY fE (_ : f ≫ iY = BinaryCofan.inl c ≫ fE)).pt ⟶ s.pt},
          PushoutCocone.inl (PushoutCocone.mk iY fE (_ : f ≫ iY = BinaryCofan.inl c ≫ fE)) ≫ m = PushoutCocone.inl s →
            PushoutCocone.inr (PushoutCocone.mk iY fE (_ : f ≫ iY = BinaryCofan.inl c ≫ fE)) ≫ m = PushoutCocone.inr s →
              m = l }

Next tactic:
dsimp only [PushoutCocone.inr, PushoutCocone.mk]
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`
    

Proof state:
case mp.intro
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)
⊢ { l //
    PushoutCocone.inl
            { pt := YE, ι := NatTrans.mk fun j => Option.rec (f ≫ iY) (fun val => WalkingPair.rec iY fE val) j } ≫
          l =
        PushoutCocone.inl s ∧
      fE ≫ l = s.ι.app WalkingSpan.right ∧
        ∀ {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 = l }

Next tactic:
refine' ⟨h.desc (BinaryCofan.mk (c.inr ≫ s.inr) s.inl), h.fac _ ⟨WalkingPair.right⟩, _, _⟩
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⟩, _, _⟩
    · 

Proof state:
case mp.intro.refine'_1
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)
⊢ fE ≫ IsColimit.desc h (BinaryCofan.mk (BinaryCofan.inr c ≫ PushoutCocone.inr s) (PushoutCocone.inl s)) =
    s.ι.app WalkingSpan.right

Next tactic:
apply BinaryCofan.IsColimit.hom_ext hc
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
      · 

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.inl c ≫
      fE ≫ IsColimit.desc h (BinaryCofan.mk (BinaryCofan.inr c ≫ PushoutCocone.inr s) (PushoutCocone.inl s)) =
    BinaryCofan.inl c ≫ s.ι.app WalkingSpan.right

Next tactic:
rw [← H.w_assoc]
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]; 

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)
⊢ f ≫ iY ≫ IsColimit.desc h (BinaryCofan.mk (BinaryCofan.inr c ≫ PushoutCocone.inr s) (PushoutCocone.inl s)) =
    BinaryCofan.inl c ≫ s.ι.app WalkingSpan.right

Next tactic:
erw [h.fac _ ⟨WalkingPair.right⟩]
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⟩]; 

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)
⊢ f ≫
      (BinaryCofan.mk (BinaryCofan.inr c ≫ PushoutCocone.inr s) (PushoutCocone.inl s)).ι.app
        { as := WalkingPair.right } =
    BinaryCofan.inl c ≫ s.ι.app WalkingSpan.right

Next tactic:
exact s.condition
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
      · 

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:
rw [← Category.assoc]