-- Mathlib/CategoryTheory/Limits/MonoCoprod.lean
theorem monoCoprod_of_preservesCoprod_of_reflectsMono [MonoCoprod D]
    [PreservesColimitsOfShape (Discrete WalkingPair) F]
    [ReflectsMonomorphisms F] : MonoCoprod C where
  binaryCofan_inl {A B} c h

Proof state:
C : Type u_1
inst✝⁴ : Category.{u_4, u_1} C
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
F : C ⥤ D
inst✝² : MonoCoprod D
inst✝¹ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝ : F.ReflectsMonomorphisms
A B : C
c : BinaryCofan A B
h : IsColimit c
c' : BinaryCofan (F.obj ((pair A B).obj { as := WalkingPair.left }))
  (F.obj ((pair A B).obj { as := WalkingPair.right })) :=
  BinaryCofan.mk (F.map c.inl) (F.map c.inr)
⊢ Mono c.inl

Tactic:
apply mono_of_mono_map F

Result:
C : Type u_1
inst✝⁴ : Category.{u_4, u_1} C
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
F : C ⥤ D
inst✝² : MonoCoprod D
inst✝¹ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝ : F.ReflectsMonomorphisms
A B : C
c : BinaryCofan A B
h : IsColimit c
c' : BinaryCofan (F.obj ((pair A B).obj { as := WalkingPair.left }))
  (F.obj ((pair A B).obj { as := WalkingPair.right })) :=
  BinaryCofan.mk (F.map c.inl) (F.map c.inr)
⊢ Mono (F.map c.inl)

Proof state:
case x
C : Type u_1
inst✝⁴ : Category.{u_4, u_1} C
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
F : C ⥤ D
inst✝² : MonoCoprod D
inst✝¹ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝ : F.ReflectsMonomorphisms
A B : C
c : BinaryCofan A B
h : IsColimit c
c' : BinaryCofan (F.obj ((pair A B).obj { as := WalkingPair.left }))
  (F.obj ((pair A B).obj { as := WalkingPair.right })) :=
  BinaryCofan.mk (F.map c.inl) (F.map c.inr)
⊢ IsColimit c'

Tactic:
apply mapIsColimitOfPreservesOfIsColimit F

Result:
case x.l
C : Type u_1
inst✝⁴ : Category.{u_4, u_1} C
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
F : C ⥤ D
inst✝² : MonoCoprod D
inst✝¹ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝ : F.ReflectsMonomorphisms
A B : C
c : BinaryCofan A B
h : IsColimit c
c' : BinaryCofan (F.obj ((pair A B).obj { as := WalkingPair.left }))
  (F.obj ((pair A B).obj { as := WalkingPair.right })) :=
  BinaryCofan.mk (F.map c.inl) (F.map c.inr)
⊢ IsColimit (BinaryCofan.mk c.inl c.inr)

Proof state:
case x.l
C : Type u_1
inst✝⁴ : Category.{u_4, u_1} C
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
F : C ⥤ D
inst✝² : MonoCoprod D
inst✝¹ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝ : F.ReflectsMonomorphisms
A B : C
c : BinaryCofan A B
h : IsColimit c
c' : BinaryCofan (F.obj ((pair A B).obj { as := WalkingPair.left }))
  (F.obj ((pair A B).obj { as := WalkingPair.right })) :=
  BinaryCofan.mk (F.map c.inl) (F.map c.inr)
⊢ ∀ (j : Discrete WalkingPair), c.ι.app j ≫ (eqToIso ⋯).hom = (BinaryCofan.mk c.inl c.inr).ι.app j

Tactic:
rintro ⟨(j₁|j₂)⟩ <;> simp only [const_obj_obj, eqToIso_refl, Iso.refl_hom,
  Category.comp_id, BinaryCofan.mk_inl, BinaryCofan.mk_inr]

Result:
no goals

Proof state:
C : Type u_1
inst✝⁴ : Category.{u_4, u_1} C
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
F : C ⥤ D
inst✝² : MonoCoprod D
inst✝¹ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝ : F.ReflectsMonomorphisms
A B : C
c : BinaryCofan A B
h : IsColimit c
⊢ Mono c.inl

Tactic:
let c' := BinaryCofan.mk (F.map c.inl) (F.map c.inr)

Result:
C : Type u_1
inst✝⁴ : Category.{u_4, u_1} C
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
F : C ⥤ D
inst✝² : MonoCoprod D
inst✝¹ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝ : F.ReflectsMonomorphisms
A B : C
c : BinaryCofan A B
h : IsColimit c
c' : BinaryCofan (F.obj ((pair A B).obj { as := WalkingPair.left }))
  (F.obj ((pair A B).obj { as := WalkingPair.right })) :=
  BinaryCofan.mk (F.map c.inl) (F.map c.inr)
⊢ Mono c.inl

Proof state:
C : Type u_1
inst✝⁴ : Category.{u_4, u_1} C
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
F : C ⥤ D
inst✝² : MonoCoprod D
inst✝¹ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝ : F.ReflectsMonomorphisms
A B : C
c : BinaryCofan A B
h : IsColimit c
c' : BinaryCofan (F.obj ((pair A B).obj { as := WalkingPair.left }))
  (F.obj ((pair A B).obj { as := WalkingPair.right })) :=
  BinaryCofan.mk (F.map c.inl) (F.map c.inr)
⊢ Mono (F.map c.inl)

Tactic:
show Mono c'.inl

Result:
C : Type u_1
inst✝⁴ : Category.{u_4, u_1} C
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
F : C ⥤ D
inst✝² : MonoCoprod D
inst✝¹ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝ : F.ReflectsMonomorphisms
A B : C
c : BinaryCofan A B
h : IsColimit c
c' : BinaryCofan (F.obj ((pair A B).obj { as := WalkingPair.left }))
  (F.obj ((pair A B).obj { as := WalkingPair.right })) :=
  BinaryCofan.mk (F.map c.inl) (F.map c.inr)
⊢ Mono c'.inl

Proof state:
case x.l
C : Type u_1
inst✝⁴ : Category.{u_4, u_1} C
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
F : C ⥤ D
inst✝² : MonoCoprod D
inst✝¹ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝ : F.ReflectsMonomorphisms
A B : C
c : BinaryCofan A B
h : IsColimit c
c' : BinaryCofan (F.obj ((pair A B).obj { as := WalkingPair.left }))
  (F.obj ((pair A B).obj { as := WalkingPair.right })) :=
  BinaryCofan.mk (F.map c.inl) (F.map c.inr)
⊢ c ≅ BinaryCofan.mk c.inl c.inr

Tactic:
refine Cocones.ext (φ := eqToIso rfl) ?_

Result:
case x.l
C : Type u_1
inst✝⁴ : Category.{u_4, u_1} C
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
F : C ⥤ D
inst✝² : MonoCoprod D
inst✝¹ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝ : F.ReflectsMonomorphisms
A B : C
c : BinaryCofan A B
h : IsColimit c
c' : BinaryCofan (F.obj ((pair A B).obj { as := WalkingPair.left }))
  (F.obj ((pair A B).obj { as := WalkingPair.right })) :=
  BinaryCofan.mk (F.map c.inl) (F.map c.inr)
⊢ ∀ (j : Discrete WalkingPair), c.ι.app j ≫ (eqToIso ⋯).hom = (BinaryCofan.mk c.inl c.inr).ι.app j

Proof state:
case x.l
C : Type u_1
inst✝⁴ : Category.{u_4, u_1} C
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
F : C ⥤ D
inst✝² : MonoCoprod D
inst✝¹ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝ : F.ReflectsMonomorphisms
A B : C
c : BinaryCofan A B
h : IsColimit c
c' : BinaryCofan (F.obj ((pair A B).obj { as := WalkingPair.left }))
  (F.obj ((pair A B).obj { as := WalkingPair.right })) :=
  BinaryCofan.mk (F.map c.inl) (F.map c.inr)
⊢ IsColimit (BinaryCofan.mk c.inl c.inr)

Tactic:
apply IsColimit.ofIsoColimit h

Result:
case x.l
C : Type u_1
inst✝⁴ : Category.{u_4, u_1} C
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
F : C ⥤ D
inst✝² : MonoCoprod D
inst✝¹ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝ : F.ReflectsMonomorphisms
A B : C
c : BinaryCofan A B
h : IsColimit c
c' : BinaryCofan (F.obj ((pair A B).obj { as := WalkingPair.left }))
  (F.obj ((pair A B).obj { as := WalkingPair.right })) :=
  BinaryCofan.mk (F.map c.inl) (F.map c.inr)
⊢ c ≅ BinaryCofan.mk c.inl c.inr

Proof state:
C : Type u_1
inst✝⁴ : Category.{u_4, u_1} C
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
F : C ⥤ D
inst✝² : MonoCoprod D
inst✝¹ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝ : F.ReflectsMonomorphisms
A B : C
c : BinaryCofan A B
h : IsColimit c
c' : BinaryCofan (F.obj ((pair A B).obj { as := WalkingPair.left }))
  (F.obj ((pair A B).obj { as := WalkingPair.right })) :=
  BinaryCofan.mk (F.map c.inl) (F.map c.inr)
⊢ Mono c'.inl

Tactic:
apply MonoCoprod.binaryCofan_inl

Result:
case x
C : Type u_1
inst✝⁴ : Category.{u_4, u_1} C
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
F : C ⥤ D
inst✝² : MonoCoprod D
inst✝¹ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝ : F.ReflectsMonomorphisms
A B : C
c : BinaryCofan A B
h : IsColimit c
c' : BinaryCofan (F.obj ((pair A B).obj { as := WalkingPair.left }))
  (F.obj ((pair A B).obj { as := WalkingPair.right })) :=
  BinaryCofan.mk (F.map c.inl) (F.map c.inr)
⊢ IsColimit c'