l3lab/ntp-mathlib huggingface dataset:
/-- If `F` and `G` are naturally isomorphic, then `F.mapCocone c` being a colimit implies
`G.mapCocone c` is also a colimit.
-/
def mapCoconeEquiv {D : Type u₄} [Category.{v₄} D] {K : J ⥤ C} {F G : C ⥤ D} (h : F ≅ G)
    {c : Cocone K} (t : IsColimit (mapCocone F c)) : IsColimit (mapCocone G c) := by
  apply IsColimit.ofIsoColimit _ (precomposeWhiskerLeftMapCocone h c)
  

Proof state:
J : Type u₁
inst✝³ : Category.{v₁, u₁} J
K✝ : Type u₂
inst✝² : Category.{v₂, u₂} K✝
C : Type u₃
inst✝¹ : Category.{v₃, u₃} C
F✝ : J ⥤ C
t✝ : Cocone F✝
D : Type u₄
inst✝ : Category.{v₄, u₄} D
K : J ⥤ C
F G : C ⥤ D
h : F ≅ G
c : Cocone K
t : IsColimit (F.mapCocone c)
⊢ IsColimit ((Cocones.precompose (whiskerLeft K h.inv)).obj (F.mapCocone c))

Next tactic:
apply (precomposeInvEquiv (isoWhiskerLeft K h : _) _).symm t
@[simp]
theorem coconeOfHom_homOfCocone (s : Cocone F) : coconeOfHom h (homOfCocone h s) = s := by
  

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
s : Cocone F
⊢ coconeOfHom h (homOfCocone h s) = s

Next tactic:
dsimp [coconeOfHom, homOfCocone]
@[simp]
theorem coconeOfHom_homOfCocone (s : Cocone F) : coconeOfHom h (homOfCocone h s) = s := by
  dsimp [coconeOfHom, homOfCocone];
  

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
s : Cocone F
⊢ { pt := s.pt, ι := h.hom.app s.pt { down := (h.inv.app s.pt s.ι).down } } = s

Next tactic:
have ⟨s_pt,s_ι⟩ := s
@[simp]
theorem coconeOfHom_homOfCocone (s : Cocone F) : coconeOfHom h (homOfCocone h s) = s := by
  dsimp [coconeOfHom, homOfCocone];
  have ⟨s_pt,s_ι⟩ := s
  

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
s : Cocone F
s_pt : C
s_ι : F ⟶ (const J).obj s_pt
⊢ { pt := { pt := s_pt, ι := s_ι }.pt,
      ι :=
        h.hom.app { pt := s_pt, ι := s_ι }.pt
          { down := (h.inv.app { pt := s_pt, ι := s_ι }.pt { pt := s_pt, ι := s_ι }.ι).down } } =
    { pt := s_pt, ι := s_ι }

Next tactic:
congr
@[simp]
theorem coconeOfHom_homOfCocone (s : Cocone F) : coconeOfHom h (homOfCocone h s) = s := by
  dsimp [coconeOfHom, homOfCocone];
  have ⟨s_pt,s_ι⟩ := s
  congr; 

Proof state:
case e_ι
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
s : Cocone F
s_pt : C
s_ι : F ⟶ (const J).obj s_pt
⊢ h.hom.app { pt := s_pt, ι := s_ι }.pt
      { down := (h.inv.app { pt := s_pt, ι := s_ι }.pt { pt := s_pt, ι := s_ι }.ι).down } =
    s_ι

Next tactic:
dsimp
@[simp]
theorem coconeOfHom_homOfCocone (s : Cocone F) : coconeOfHom h (homOfCocone h s) = s := by
  dsimp [coconeOfHom, homOfCocone];
  have ⟨s_pt,s_ι⟩ := s
  congr; dsimp
  

Proof state:
case e_ι
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
s : Cocone F
s_pt : C
s_ι : F ⟶ (const J).obj s_pt
⊢ h.hom.app s_pt { down := (h.inv.app s_pt s_ι).down } = s_ι

Next tactic:
convert congrFun (congrFun (congrArg NatTrans.app h.inv_hom_id) s_pt) s_ι using 1
/-- If `F.cocones` is corepresented by `X`, the cocone corresponding to a morphism `f : Y ⟶ X` is
the colimit cocone extended by `f`. -/
theorem coconeOfHom_fac {Y : C} (f : X ⟶ Y) : coconeOfHom h f = (colimitCocone h).extend f := by
  

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
Y : C
f : X ⟶ Y
⊢ coconeOfHom h f = Cocone.extend (colimitCocone h) f

Next tactic:
dsimp [coconeOfHom, colimitCocone, Cocone.extend]
/-- If `F.cocones` is corepresented by `X`, the cocone corresponding to a morphism `f : Y ⟶ X` is
the colimit cocone extended by `f`. -/
theorem coconeOfHom_fac {Y : C} (f : X ⟶ Y) : coconeOfHom h f = (colimitCocone h).extend f := by
  dsimp [coconeOfHom, colimitCocone, Cocone.extend]
  

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
Y : C
f : X ⟶ Y
⊢ { pt := Y, ι := h.hom.app Y { down := f } } = { pt := Y, ι := h.hom.app X { down := 𝟙 X } ≫ (const J).map f }

Next tactic:
congr with j
/-- If `F.cocones` is corepresented by `X`, the cocone corresponding to a morphism `f : Y ⟶ X` is
the colimit cocone extended by `f`. -/
theorem coconeOfHom_fac {Y : C} (f : X ⟶ Y) : coconeOfHom h f = (colimitCocone h).extend f := by
  dsimp [coconeOfHom, colimitCocone, Cocone.extend]
  congr with j
  

Proof state:
case e_ι.w.h
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
Y : C
f : X ⟶ Y
j : J
⊢ (h.hom.app Y { down := f }).app j = (h.hom.app X { down := 𝟙 X } ≫ (const J).map f).app j

Next tactic:
have t := congrFun (h.hom.naturality f) ⟨𝟙 X⟩
/-- If `F.cocones` is corepresented by `X`, the cocone corresponding to a morphism `f : Y ⟶ X` is
the colimit cocone extended by `f`. -/
theorem coconeOfHom_fac {Y : C} (f : X ⟶ Y) : coconeOfHom h f = (colimitCocone h).extend f := by
  dsimp [coconeOfHom, colimitCocone, Cocone.extend]
  congr with j
  have t := congrFun (h.hom.naturality f) ⟨𝟙 X⟩
  

Proof state:
case e_ι.w.h
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t✝ : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
Y : C
f : X ⟶ Y
j : J
t :
  ((coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃}).map f ≫ h.hom.app Y) { down := 𝟙 X } =
    (h.hom.app X ≫ (Functor.cocones F).map f) { down := 𝟙 X }
⊢ (h.hom.app Y { down := f }).app j = (h.hom.app X { down := 𝟙 X } ≫ (const J).map f).app j

Next tactic:
dsimp at t
/-- If `F.cocones` is corepresented by `X`, the cocone corresponding to a morphism `f : Y ⟶ X` is
the colimit cocone extended by `f`. -/
theorem coconeOfHom_fac {Y : C} (f : X ⟶ Y) : coconeOfHom h f = (colimitCocone h).extend f := by
  dsimp [coconeOfHom, colimitCocone, Cocone.extend]
  congr with j
  have t := congrFun (h.hom.naturality f) ⟨𝟙 X⟩
  dsimp at t
  

Proof state:
case e_ι.w.h
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t✝ : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
Y : C
f : X ⟶ Y
j : J
t : h.hom.app Y { down := 𝟙 X ≫ f } = (Functor.cocones F).map f (h.hom.app X { down := 𝟙 X })
⊢ (h.hom.app Y { down := f }).app j = (h.hom.app X { down := 𝟙 X } ≫ (const J).map f).app j

Next tactic:
simp only [id_comp] at t
/-- If `F.cocones` is corepresented by `X`, the cocone corresponding to a morphism `f : Y ⟶ X` is
the colimit cocone extended by `f`. -/
theorem coconeOfHom_fac {Y : C} (f : X ⟶ Y) : coconeOfHom h f = (colimitCocone h).extend f := by
  dsimp [coconeOfHom, colimitCocone, Cocone.extend]
  congr with j
  have t := congrFun (h.hom.naturality f) ⟨𝟙 X⟩
  dsimp at t
  simp only [id_comp] at t
  

Proof state:
case e_ι.w.h
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t✝ : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
Y : C
f : X ⟶ Y
j : J
t : h.hom.app Y { down := f } = (Functor.cocones F).map f (h.hom.app X { down := 𝟙 X })
⊢ (h.hom.app Y { down := f }).app j = (h.hom.app X { down := 𝟙 X } ≫ (const J).map f).app j

Next tactic:
rw [congrFun (congrArg NatTrans.app t) j]
/-- If `F.cocones` is corepresented by `X`, the cocone corresponding to a morphism `f : Y ⟶ X` is
the colimit cocone extended by `f`. -/
theorem coconeOfHom_fac {Y : C} (f : X ⟶ Y) : coconeOfHom h f = (colimitCocone h).extend f := by
  dsimp [coconeOfHom, colimitCocone, Cocone.extend]
  congr with j
  have t := congrFun (h.hom.naturality f) ⟨𝟙 X⟩
  dsimp at t
  simp only [id_comp] at t
  rw [congrFun (congrArg NatTrans.app t) j]
  

Proof state:
case e_ι.w.h
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t✝ : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
Y : C
f : X ⟶ Y
j : J
t : h.hom.app Y { down := f } = (Functor.cocones F).map f (h.hom.app X { down := 𝟙 X })
⊢ ((Functor.cocones F).map f (h.hom.app X { down := 𝟙 X })).app j =
    (h.hom.app X { down := 𝟙 X } ≫ (const J).map f).app j

Next tactic:
rfl
/-- If `F.cocones` is corepresented by `X`, any cocone is the extension of the colimit cocone by the
corresponding morphism. -/
theorem cocone_fac (s : Cocone F) : (colimitCocone h).extend (homOfCocone h s) = s := by
  

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
s : Cocone F
⊢ Cocone.extend (colimitCocone h) (homOfCocone h s) = s

Next tactic:
rw [← coconeOfHom_homOfCocone h s]
/-- If `F.cocones` is corepresented by `X`, any cocone is the extension of the colimit cocone by the
corresponding morphism. -/
theorem cocone_fac (s : Cocone F) : (colimitCocone h).extend (homOfCocone h s) = s := by
  rw [← coconeOfHom_homOfCocone h s]
  

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
s : Cocone F
⊢ Cocone.extend (colimitCocone h) (homOfCocone h (coconeOfHom h (homOfCocone h s))) = coconeOfHom h (homOfCocone h s)

Next tactic:
conv_lhs => simp only [homOfCocone_cooneOfHom]
/-- If `F.cocones` is corepresented by `X`, any cocone is the extension of the colimit cocone by the
corresponding morphism. -/
theorem cocone_fac (s : Cocone F) : (colimitCocone h).extend (homOfCocone h s) = s := by
  rw [← coconeOfHom_homOfCocone h s]
  conv_lhs => 

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
s : Cocone F
| Cocone.extend (colimitCocone h) (homOfCocone h (coconeOfHom h (homOfCocone h s)))

Next tactic:
simp only [homOfCocone_cooneOfHom]
/-- If `F.cocones` is corepresented by `X`, any cocone is the extension of the colimit cocone by the
corresponding morphism. -/
theorem cocone_fac (s : Cocone F) : (colimitCocone h).extend (homOfCocone h s) = s := by
  rw [← coconeOfHom_homOfCocone h s]
  conv_lhs => simp only [homOfCocone_cooneOfHom]
  

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
s : Cocone F
⊢ Cocone.extend (colimitCocone h) (homOfCocone h s) = coconeOfHom h (homOfCocone h s)

Next tactic:
apply (coconeOfHom_fac _ _).symm
/-- If `F.cocones` is corepresentable, then the cocone corresponding to the identity morphism on
the representing object is a colimit cocone.
-/
def ofNatIso {X : C} (h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁} ≅ F.cocones) :
    IsColimit (colimitCocone h) where
  desc s := homOfCocone h s
  fac s j := by
    

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
s : Cocone F
j : J
⊢ (colimitCocone h).ι.app j ≫ (fun s => homOfCocone h s) s = s.ι.app j

Next tactic:
have h := cocone_fac h s
/-- If `F.cocones` is corepresentable, then the cocone corresponding to the identity morphism on
the representing object is a colimit cocone.
-/
def ofNatIso {X : C} (h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁} ≅ F.cocones) :
    IsColimit (colimitCocone h) where
  desc s := homOfCocone h s
  fac s j := by
    have h := cocone_fac h s
    

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h✝ : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
s : Cocone F
j : J
h : Cocone.extend (colimitCocone h✝) (homOfCocone h✝ s) = s
⊢ (colimitCocone h✝).ι.app j ≫ (fun s => homOfCocone h✝ s) s = s.ι.app j

Next tactic:
cases s
/-- If `F.cocones` is corepresentable, then the cocone corresponding to the identity morphism on
the representing object is a colimit cocone.
-/
def ofNatIso {X : C} (h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁} ≅ F.cocones) :
    IsColimit (colimitCocone h) where
  desc s := homOfCocone h s
  fac s j := by
    have h := cocone_fac h s
    cases s
    

Proof state:
case mk
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h✝ : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
j : J
pt✝ : C
ι✝ : F ⟶ (const J).obj pt✝
h : Cocone.extend (colimitCocone h✝) (homOfCocone h✝ { pt := pt✝, ι := ι✝ }) = { pt := pt✝, ι := ι✝ }
⊢ (colimitCocone h✝).ι.app j ≫ (fun s => homOfCocone h✝ s) { pt := pt✝, ι := ι✝ } = { pt := pt✝, ι := ι✝ }.ι.app j

Next tactic:
injection h with h₁ h₂
/-- If `F.cocones` is corepresentable, then the cocone corresponding to the identity morphism on
the representing object is a colimit cocone.
-/
def ofNatIso {X : C} (h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁} ≅ F.cocones) :
    IsColimit (colimitCocone h) where
  desc s := homOfCocone h s
  fac s j := by
    have h := cocone_fac h s
    cases s
    injection h with h₁ h₂
    

Proof state:
case mk
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
j : J
pt✝ : C
ι✝ : F ⟶ (const J).obj pt✝
h₁ : { pt := pt✝, ι := ι✝ }.pt = pt✝
h₂ :
  (Cocone.extensions (colimitCocone h)).app { pt := pt✝, ι := ι✝ }.pt { down := homOfCocone h { pt := pt✝, ι := ι✝ } } =
    ι✝
⊢ (colimitCocone h).ι.app j ≫ (fun s => homOfCocone h s) { pt := pt✝, ι := ι✝ } = { pt := pt✝, ι := ι✝ }.ι.app j

Next tactic:
simp only [heq_iff_eq] at h₂
/-- If `F.cocones` is corepresentable, then the cocone corresponding to the identity morphism on
the representing object is a colimit cocone.
-/
def ofNatIso {X : C} (h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁} ≅ F.cocones) :
    IsColimit (colimitCocone h) where
  desc s := homOfCocone h s
  fac s j := by
    have h := cocone_fac h s
    cases s
    injection h with h₁ h₂
    simp only [heq_iff_eq] at h₂
    

Proof state:
case mk
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
j : J
pt✝ : C
ι✝ : F ⟶ (const J).obj pt✝
h₁ : { pt := pt✝, ι := ι✝ }.pt = pt✝
h₂ : (Cocone.extensions (colimitCocone h)).app pt✝ { down := homOfCocone h { pt := pt✝, ι := ι✝ } } = ι✝
⊢ (colimitCocone h).ι.app j ≫ (fun s => homOfCocone h s) { pt := pt✝, ι := ι✝ } = { pt := pt✝, ι := ι✝ }.ι.app j

Next tactic:
conv_rhs => rw [← h₂]; rfl
/-- If `F.cocones` is corepresentable, then the cocone corresponding to the identity morphism on
the representing object is a colimit cocone.
-/
def ofNatIso {X : C} (h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁} ≅ F.cocones) :
    IsColimit (colimitCocone h) where
  desc s := homOfCocone h s
  fac s j := by
    have h := cocone_fac h s
    cases s
    injection h with h₁ h₂
    simp only [heq_iff_eq] at h₂
    conv_rhs => 

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
j : J
pt✝ : C
ι✝ : F ⟶ (const J).obj pt✝
h₁ : { pt := pt✝, ι := ι✝ }.pt = pt✝
h₂ : (Cocone.extensions (colimitCocone h)).app pt✝ { down := homOfCocone h { pt := pt✝, ι := ι✝ } } = ι✝
| { pt := pt✝, ι := ι✝ }.ι.app j

Next tactic:
rw [← h₂]; rfl
/-- If `F.cocones` is corepresentable, then the cocone corresponding to the identity morphism on
the representing object is a colimit cocone.
-/
def ofNatIso {X : C} (h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁} ≅ F.cocones) :
    IsColimit (colimitCocone h) where
  desc s := homOfCocone h s
  fac s j := by
    have h := cocone_fac h s
    cases s
    injection h with h₁ h₂
    simp only [heq_iff_eq] at h₂
    conv_rhs => 

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
j : J
pt✝ : C
ι✝ : F ⟶ (const J).obj pt✝
h₁ : { pt := pt✝, ι := ι✝ }.pt = pt✝
h₂ : (Cocone.extensions (colimitCocone h)).app pt✝ { down := homOfCocone h { pt := pt✝, ι := ι✝ } } = ι✝
| { pt := pt✝, ι := ι✝ }.ι.app j

Next tactic:
rw [← h₂]
/-- If `F.cocones` is corepresentable, then the cocone corresponding to the identity morphism on
the representing object is a colimit cocone.
-/
def ofNatIso {X : C} (h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁} ≅ F.cocones) :
    IsColimit (colimitCocone h) where
  desc s := homOfCocone h s
  fac s j := by
    have h := cocone_fac h s
    cases s
    injection h with h₁ h₂
    simp only [heq_iff_eq] at h₂
    conv_rhs => rw [← h₂]; 

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
j : J
pt✝ : C
ι✝ : F ⟶ (const J).obj pt✝
h₁ : { pt := pt✝, ι := ι✝ }.pt = pt✝
h₂ : (Cocone.extensions (colimitCocone h)).app pt✝ { down := homOfCocone h { pt := pt✝, ι := ι✝ } } = ι✝
| { pt := pt✝,
          ι := (Cocone.extensions (colimitCocone h)).app pt✝ { down := homOfCocone h { pt := pt✝, ι := ι✝ } } }.ι.app
    j

Next tactic:
rfl
/-- If `F.cocones` is corepresentable, then the cocone corresponding to the identity morphism on
the representing object is a colimit cocone.
-/
def ofNatIso {X : C} (h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁} ≅ F.cocones) :
    IsColimit (colimitCocone h) where
  desc s := homOfCocone h s
  fac s j := by
    have h := cocone_fac h s
    cases s
    injection h with h₁ h₂
    simp only [heq_iff_eq] at h₂
    conv_rhs => rw [← h₂]; rfl
  uniq s m w := by
    

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
s : Cocone F
m : (colimitCocone h).pt ⟶ s.pt
w : ∀ (j : J), (colimitCocone h).ι.app j ≫ m = s.ι.app j
⊢ m = (fun s => homOfCocone h s) s

Next tactic:
rw [← homOfCocone_cooneOfHom h m]
/-- If `F.cocones` is corepresentable, then the cocone corresponding to the identity morphism on
the representing object is a colimit cocone.
-/
def ofNatIso {X : C} (h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁} ≅ F.cocones) :
    IsColimit (colimitCocone h) where
  desc s := homOfCocone h s
  fac s j := by
    have h := cocone_fac h s
    cases s
    injection h with h₁ h₂
    simp only [heq_iff_eq] at h₂
    conv_rhs => rw [← h₂]; rfl
  uniq s m w := by
    rw [← homOfCocone_cooneOfHom h m]
    

Proof state:
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
s : Cocone F
m : (colimitCocone h).pt ⟶ s.pt
w : ∀ (j : J), (colimitCocone h).ι.app j ≫ m = s.ι.app j
⊢ homOfCocone h (coconeOfHom h m) = (fun s => homOfCocone h s) s

Next tactic:
congr
/-- If `F.cocones` is corepresentable, then the cocone corresponding to the identity morphism on
the representing object is a colimit cocone.
-/
def ofNatIso {X : C} (h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁} ≅ F.cocones) :
    IsColimit (colimitCocone h) where
  desc s := homOfCocone h s
  fac s j := by
    have h := cocone_fac h s
    cases s
    injection h with h₁ h₂
    simp only [heq_iff_eq] at h₂
    conv_rhs => rw [← h₂]; rfl
  uniq s m w := by
    rw [← homOfCocone_cooneOfHom h m]
    congr
    

Proof state:
case h.e_8.h
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
s : Cocone F
m : (colimitCocone h).pt ⟶ s.pt
w : ∀ (j : J), (colimitCocone h).ι.app j ≫ m = s.ι.app j
⊢ coconeOfHom h m = s

Next tactic:
rw [coconeOfHom_fac]
/-- If `F.cocones` is corepresentable, then the cocone corresponding to the identity morphism on
the representing object is a colimit cocone.
-/
def ofNatIso {X : C} (h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁} ≅ F.cocones) :
    IsColimit (colimitCocone h) where
  desc s := homOfCocone h s
  fac s j := by
    have h := cocone_fac h s
    cases s
    injection h with h₁ h₂
    simp only [heq_iff_eq] at h₂
    conv_rhs => rw [← h₂]; rfl
  uniq s m w := by
    rw [← homOfCocone_cooneOfHom h m]
    congr
    rw [coconeOfHom_fac]
    

Proof state:
case h.e_8.h
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
s : Cocone F
m : (colimitCocone h).pt ⟶ s.pt
w : ∀ (j : J), (colimitCocone h).ι.app j ≫ m = s.ι.app j
⊢ Cocone.extend (colimitCocone h) m = s

Next tactic:
dsimp [Cocone.extend]
/-- If `F.cocones` is corepresentable, then the cocone corresponding to the identity morphism on
the representing object is a colimit cocone.
-/
def ofNatIso {X : C} (h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁} ≅ F.cocones) :
    IsColimit (colimitCocone h) where
  desc s := homOfCocone h s
  fac s j := by
    have h := cocone_fac h s
    cases s
    injection h with h₁ h₂
    simp only [heq_iff_eq] at h₂
    conv_rhs => rw [← h₂]; rfl
  uniq s m w := by
    rw [← homOfCocone_cooneOfHom h m]
    congr
    rw [coconeOfHom_fac]
    dsimp [Cocone.extend]; 

Proof state:
case h.e_8.h
J : Type u₁
inst✝² : Category.{v₁, u₁} J
K : Type u₂
inst✝¹ : Category.{v₂, u₂} K
C : Type u₃
inst✝ : Category.{v₃, u₃} C
F : J ⥤ C
t : Cocone F
X : C
h : coyoneda.obj (op X) ⋙ uliftFunctor.{u₁, v₃} ≅ Functor.cocones F
s : Cocone F
m : (colimitCocone h).pt ⟶ s.pt
w : ∀ (j : J), (colimitCocone h).ι.app j ≫ m = s.ι.app j
⊢ { pt := s.pt, ι := (colimitCocone h).ι ≫ (const J).map m } = s

Next tactic:
cases s