l3lab/ntp-mathlib huggingface dataset:
/-- Verify that `extendAlongYoneda` is indeed the left Kan extension along the yoneda embedding.
-/
@[simps!]
noncomputable def extendAlongYonedaIsoKan :
    extendAlongYoneda A ≅ (lan yoneda : (_ ⥤ ℰ) ⥤ _).obj A :=
  NatIso.ofComponents (extendAlongYonedaIsoKanApp A) (by
    intro X Y f; 

Proof state:
C : Type u₁
inst✝² : SmallCategory C
ℰ : Type u₂
inst✝¹ : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
inst✝ : HasColimits ℰ
X Y : Cᵒᵖ ⥤ Type u₁
f : X ⟶ Y
⊢ (extendAlongYoneda A).map f ≫ (extendAlongYonedaIsoKanApp A Y).hom =
    (extendAlongYonedaIsoKanApp A X).hom ≫ ((lan yoneda).obj A).map f

Next tactic:
simp
/-- Verify that `extendAlongYoneda` is indeed the left Kan extension along the yoneda embedding.
-/
@[simps!]
noncomputable def extendAlongYonedaIsoKan :
    extendAlongYoneda A ≅ (lan yoneda : (_ ⥤ ℰ) ⥤ _).obj A :=
  NatIso.ofComponents (extendAlongYonedaIsoKanApp A) (by
    intro X Y f; simp
    

Proof state:
C : Type u₁
inst✝² : SmallCategory C
ℰ : Type u₂
inst✝¹ : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
inst✝ : HasColimits ℰ
X Y : Cᵒᵖ ⥤ Type u₁
f : X ⟶ Y
⊢ (extendAlongYoneda A).map f ≫
      colimit.pre (Lan.diagram yoneda A Y) (CategoryOfElements.costructuredArrowYonedaEquivalence Y).functor =
    colimit.pre (Lan.diagram yoneda A X) (CategoryOfElements.costructuredArrowYonedaEquivalence X).functor ≫
      colimit.pre (Lan.diagram yoneda A Y) (CostructuredArrow.map f)

Next tactic:
rw [extendAlongYoneda_map]
/-- Verify that `extendAlongYoneda` is indeed the left Kan extension along the yoneda embedding.
-/
@[simps!]
noncomputable def extendAlongYonedaIsoKan :
    extendAlongYoneda A ≅ (lan yoneda : (_ ⥤ ℰ) ⥤ _).obj A :=
  NatIso.ofComponents (extendAlongYonedaIsoKanApp A) (by
    intro X Y f; simp
    rw [extendAlongYoneda_map]
    

Proof state:
C : Type u₁
inst✝² : SmallCategory C
ℰ : Type u₂
inst✝¹ : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
inst✝ : HasColimits ℰ
X Y : Cᵒᵖ ⥤ Type u₁
f : X ⟶ Y
⊢ colimit.pre ((CategoryOfElements.π Y).leftOp ⋙ A) (CategoryOfElements.map f).op ≫
      colimit.pre (Lan.diagram yoneda A Y) (CategoryOfElements.costructuredArrowYonedaEquivalence Y).functor =
    colimit.pre (Lan.diagram yoneda A X) (CategoryOfElements.costructuredArrowYonedaEquivalence X).functor ≫
      colimit.pre (Lan.diagram yoneda A Y) (CostructuredArrow.map f)

Next tactic:
erw [colimit.pre_pre (Lan.diagram (yoneda : C ⥤ _ ⥤ Type u₁) A Y) (CostructuredArrow.map f)]
/-- Verify that `extendAlongYoneda` is indeed the left Kan extension along the yoneda embedding.
-/
@[simps!]
noncomputable def extendAlongYonedaIsoKan :
    extendAlongYoneda A ≅ (lan yoneda : (_ ⥤ ℰ) ⥤ _).obj A :=
  NatIso.ofComponents (extendAlongYonedaIsoKanApp A) (by
    intro X Y f; simp
    rw [extendAlongYoneda_map]
    erw [colimit.pre_pre (Lan.diagram (yoneda : C ⥤ _ ⥤ Type u₁) A Y) (CostructuredArrow.map f)]
    

Proof state:
C : Type u₁
inst✝² : SmallCategory C
ℰ : Type u₂
inst✝¹ : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
inst✝ : HasColimits ℰ
X Y : Cᵒᵖ ⥤ Type u₁
f : X ⟶ Y
⊢ colimit.pre ((CategoryOfElements.π Y).leftOp ⋙ A) (CategoryOfElements.map f).op ≫
      colimit.pre (Lan.diagram yoneda A Y) (CategoryOfElements.costructuredArrowYonedaEquivalence Y).functor =
    colimit.pre (Lan.diagram yoneda A Y)
      ((CategoryOfElements.costructuredArrowYonedaEquivalence X).functor ⋙ CostructuredArrow.map f)

Next tactic:
erw [colimit.pre_pre (Lan.diagram (yoneda : C ⥤ _ ⥤ Type u₁) A Y)
        (CategoryOfElements.costructuredArrowYonedaEquivalence Y).functor]
/-- Verify that `extendAlongYoneda` is indeed the left Kan extension along the yoneda embedding.
-/
@[simps!]
noncomputable def extendAlongYonedaIsoKan :
    extendAlongYoneda A ≅ (lan yoneda : (_ ⥤ ℰ) ⥤ _).obj A :=
  NatIso.ofComponents (extendAlongYonedaIsoKanApp A) (by
    intro X Y f; simp
    rw [extendAlongYoneda_map]
    erw [colimit.pre_pre (Lan.diagram (yoneda : C ⥤ _ ⥤ Type u₁) A Y) (CostructuredArrow.map f)]
    erw [colimit.pre_pre (Lan.diagram (yoneda : C ⥤ _ ⥤ Type u₁) A Y)
        (CategoryOfElements.costructuredArrowYonedaEquivalence Y).functor]
    

Proof state:
C : Type u₁
inst✝² : SmallCategory C
ℰ : Type u₂
inst✝¹ : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
inst✝ : HasColimits ℰ
X Y : Cᵒᵖ ⥤ Type u₁
f : X ⟶ Y
⊢ colimit.pre (Lan.diagram yoneda A Y)
      ((CategoryOfElements.map f).op ⋙ (CategoryOfElements.costructuredArrowYonedaEquivalence Y).functor) =
    colimit.pre (Lan.diagram yoneda A Y)
      ((CategoryOfElements.costructuredArrowYonedaEquivalence X).functor ⋙ CostructuredArrow.map f)

Next tactic:
congr 1
/-- Verify that `extendAlongYoneda` is indeed the left Kan extension along the yoneda embedding.
-/
@[simps!]
noncomputable def extendAlongYonedaIsoKan :
    extendAlongYoneda A ≅ (lan yoneda : (_ ⥤ ℰ) ⥤ _).obj A :=
  NatIso.ofComponents (extendAlongYonedaIsoKanApp A) (by
    intro X Y f; simp
    rw [extendAlongYoneda_map]
    erw [colimit.pre_pre (Lan.diagram (yoneda : C ⥤ _ ⥤ Type u₁) A Y) (CostructuredArrow.map f)]
    erw [colimit.pre_pre (Lan.diagram (yoneda : C ⥤ _ ⥤ Type u₁) A Y)
        (CategoryOfElements.costructuredArrowYonedaEquivalence Y).functor]
    congr 1
    

Proof state:
case h.e_9.h
C : Type u₁
inst✝² : SmallCategory C
ℰ : Type u₂
inst✝¹ : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
inst✝ : HasColimits ℰ
X Y : Cᵒᵖ ⥤ Type u₁
f : X ⟶ Y
⊢ (CategoryOfElements.map f).op ⋙ (CategoryOfElements.costructuredArrowYonedaEquivalence Y).functor =
    (CategoryOfElements.costructuredArrowYonedaEquivalence X).functor ⋙ CostructuredArrow.map f

Next tactic:
apply CategoryOfElements.costructuredArrow_yoneda_equivalence_naturality
/-- The legs of the cocone `coconeOfRepresentable` are natural in the choice of presheaf. -/
theorem coconeOfRepresentable_naturality {P₁ P₂ : Cᵒᵖ ⥤ Type u₁} (α : P₁ ⟶ P₂) (j : P₁.Elementsᵒᵖ) :
    (coconeOfRepresentable P₁).ι.app j ≫ α =
      (coconeOfRepresentable P₂).ι.app ((CategoryOfElements.map α).op.obj j) := by
  

Proof state:
C : Type u₁
inst✝¹ : SmallCategory C
ℰ : Type u₂
inst✝ : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
P₁ P₂ : Cᵒᵖ ⥤ Type u₁
α : P₁ ⟶ P₂
j : (Functor.Elements P₁)ᵒᵖ
⊢ (coconeOfRepresentable P₁).ι.app j ≫ α = (coconeOfRepresentable P₂).ι.app ((CategoryOfElements.map α).op.obj j)

Next tactic:
ext T f
/-- The legs of the cocone `coconeOfRepresentable` are natural in the choice of presheaf. -/
theorem coconeOfRepresentable_naturality {P₁ P₂ : Cᵒᵖ ⥤ Type u₁} (α : P₁ ⟶ P₂) (j : P₁.Elementsᵒᵖ) :
    (coconeOfRepresentable P₁).ι.app j ≫ α =
      (coconeOfRepresentable P₂).ι.app ((CategoryOfElements.map α).op.obj j) := by
  ext T f
  

Proof state:
case w.h.h
C : Type u₁
inst✝¹ : SmallCategory C
ℰ : Type u₂
inst✝ : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
P₁ P₂ : Cᵒᵖ ⥤ Type u₁
α : P₁ ⟶ P₂
j : (Functor.Elements P₁)ᵒᵖ
T : Cᵒᵖ
f : ((functorToRepresentables P₁).obj j).obj T
⊢ ((coconeOfRepresentable P₁).ι.app j ≫ α).app T f =
    ((coconeOfRepresentable P₂).ι.app ((CategoryOfElements.map α).op.obj j)).app T f

Next tactic:
simpa [coconeOfRepresentable_ι_app] using FunctorToTypes.naturality _ _ α f.op _
/-- The cocone with point `P` given by `coconeOfRepresentable` is a colimit:
that is, we have exhibited an arbitrary presheaf `P` as a colimit of representables.

The result of [MM92], Chapter I, Section 5, Corollary 3.
-/
noncomputable def colimitOfRepresentable (P : Cᵒᵖ ⥤ Type u₁) :
    IsColimit (coconeOfRepresentable P) := by
  -- porting note:
  -- the `suffices` was not necessary in mathlib3; the function being `apply`ed has an
  -- `IsIso` input in square brackets; lean 3 was happy to give the user the input as a goal but
  -- lean 4 complains that typeclass inference can't find it.
  

Proof state:
C : Type u₁
inst✝¹ : SmallCategory C
ℰ : Type u₂
inst✝ : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
P : Cᵒᵖ ⥤ Type u₁
⊢ IsColimit (coconeOfRepresentable P)

Next tactic:
suffices IsIso (IsColimit.desc (colimit.isColimit (functorToRepresentables P))
    (coconeOfRepresentable P)) by
    apply IsColimit.ofPointIso (colimit.isColimit (functorToRepresentables P))
/-- The cocone with point `P` given by `coconeOfRepresentable` is a colimit:
that is, we have exhibited an arbitrary presheaf `P` as a colimit of representables.

The result of [MM92], Chapter I, Section 5, Corollary 3.
-/
noncomputable def colimitOfRepresentable (P : Cᵒᵖ ⥤ Type u₁) :
    IsColimit (coconeOfRepresentable P) := by
  -- porting note:
  -- the `suffices` was not necessary in mathlib3; the function being `apply`ed has an
  -- `IsIso` input in square brackets; lean 3 was happy to give the user the input as a goal but
  -- lean 4 complains that typeclass inference can't find it.
  suffices IsIso (IsColimit.desc (colimit.isColimit (functorToRepresentables P))
    (coconeOfRepresentable P)) by
    

Proof state:
C : Type u₁
inst✝¹ : SmallCategory C
ℰ : Type u₂
inst✝ : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
P : Cᵒᵖ ⥤ Type u₁
this : IsIso (IsColimit.desc (colimit.isColimit (functorToRepresentables P)) (coconeOfRepresentable P))
⊢ IsColimit (coconeOfRepresentable P)

Next tactic:
apply IsColimit.ofPointIso (colimit.isColimit (functorToRepresentables P))
/-- The cocone with point `P` given by `coconeOfRepresentable` is a colimit:
that is, we have exhibited an arbitrary presheaf `P` as a colimit of representables.

The result of [MM92], Chapter I, Section 5, Corollary 3.
-/
noncomputable def colimitOfRepresentable (P : Cᵒᵖ ⥤ Type u₁) :
    IsColimit (coconeOfRepresentable P) := by
  -- porting note:
  -- the `suffices` was not necessary in mathlib3; the function being `apply`ed has an
  -- `IsIso` input in square brackets; lean 3 was happy to give the user the input as a goal but
  -- lean 4 complains that typeclass inference can't find it.
  suffices IsIso (IsColimit.desc (colimit.isColimit (functorToRepresentables P))
    (coconeOfRepresentable P)) by
    apply IsColimit.ofPointIso (colimit.isColimit (functorToRepresentables P))
  

Proof state:
C : Type u₁
inst✝¹ : SmallCategory C
ℰ : Type u₂
inst✝ : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
P : Cᵒᵖ ⥤ Type u₁
⊢ IsIso (IsColimit.desc (colimit.isColimit (functorToRepresentables P)) (coconeOfRepresentable P))

Next tactic:
change IsIso (colimit.desc _ (Cocone.extend _ _))
/-- The cocone with point `P` given by `coconeOfRepresentable` is a colimit:
that is, we have exhibited an arbitrary presheaf `P` as a colimit of representables.

The result of [MM92], Chapter I, Section 5, Corollary 3.
-/
noncomputable def colimitOfRepresentable (P : Cᵒᵖ ⥤ Type u₁) :
    IsColimit (coconeOfRepresentable P) := by
  -- porting note:
  -- the `suffices` was not necessary in mathlib3; the function being `apply`ed has an
  -- `IsIso` input in square brackets; lean 3 was happy to give the user the input as a goal but
  -- lean 4 complains that typeclass inference can't find it.
  suffices IsIso (IsColimit.desc (colimit.isColimit (functorToRepresentables P))
    (coconeOfRepresentable P)) by
    apply IsColimit.ofPointIso (colimit.isColimit (functorToRepresentables P))
  change IsIso (colimit.desc _ (Cocone.extend _ _))
  

Proof state:
C : Type u₁
inst✝¹ : SmallCategory C
ℰ : Type u₂
inst✝ : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
P : Cᵒᵖ ⥤ Type u₁
⊢ IsIso
    (colimit.desc (functorToRepresentables P)
      (Cocone.extend (colimit.cocone (functorToRepresentables P)) (extendAlongYonedaYoneda.hom.app P)))

Next tactic:
rw [colimit.desc_extend, colimit.desc_cocone]
/-- The cocone with point `P` given by `coconeOfRepresentable` is a colimit:
that is, we have exhibited an arbitrary presheaf `P` as a colimit of representables.

The result of [MM92], Chapter I, Section 5, Corollary 3.
-/
noncomputable def colimitOfRepresentable (P : Cᵒᵖ ⥤ Type u₁) :
    IsColimit (coconeOfRepresentable P) := by
  -- porting note:
  -- the `suffices` was not necessary in mathlib3; the function being `apply`ed has an
  -- `IsIso` input in square brackets; lean 3 was happy to give the user the input as a goal but
  -- lean 4 complains that typeclass inference can't find it.
  suffices IsIso (IsColimit.desc (colimit.isColimit (functorToRepresentables P))
    (coconeOfRepresentable P)) by
    apply IsColimit.ofPointIso (colimit.isColimit (functorToRepresentables P))
  change IsIso (colimit.desc _ (Cocone.extend _ _))
  rw [colimit.desc_extend, colimit.desc_cocone]
  

Proof state:
C : Type u₁
inst✝¹ : SmallCategory C
ℰ : Type u₂
inst✝ : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
P : Cᵒᵖ ⥤ Type u₁
⊢ IsIso (𝟙 (colimit (functorToRepresentables P)) ≫ extendAlongYonedaYoneda.hom.app P)

Next tactic:
infer_instance
/-- Given two functors L₁ and L₂ which preserve colimits, if they agree when restricted to the
representable presheaves then they agree everywhere.
-/
noncomputable def natIsoOfNatIsoOnRepresentables (L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ)
    [PreservesColimits L₁] [PreservesColimits L₂] (h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂) : L₁ ≅ L₂ := by
  

Proof state:
C : Type u₁
inst✝³ : SmallCategory C
ℰ : Type u₂
inst✝² : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ
inst✝¹ : PreservesColimits L₁
inst✝ : PreservesColimits L₂
h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂
⊢ L₁ ≅ L₂

Next tactic:
apply NatIso.ofComponents _ _
/-- Given two functors L₁ and L₂ which preserve colimits, if they agree when restricted to the
representable presheaves then they agree everywhere.
-/
noncomputable def natIsoOfNatIsoOnRepresentables (L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ)
    [PreservesColimits L₁] [PreservesColimits L₂] (h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂) : L₁ ≅ L₂ := by
  apply NatIso.ofComponents _ _
  · 

Proof state:
C : Type u₁
inst✝³ : SmallCategory C
ℰ : Type u₂
inst✝² : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ
inst✝¹ : PreservesColimits L₁
inst✝ : PreservesColimits L₂
h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂
⊢ (X : Cᵒᵖ ⥤ Type u₁) → L₁.obj X ≅ L₂.obj X

Next tactic:
intro P
/-- Given two functors L₁ and L₂ which preserve colimits, if they agree when restricted to the
representable presheaves then they agree everywhere.
-/
noncomputable def natIsoOfNatIsoOnRepresentables (L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ)
    [PreservesColimits L₁] [PreservesColimits L₂] (h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂) : L₁ ≅ L₂ := by
  apply NatIso.ofComponents _ _
  · intro P
    

Proof state:
C : Type u₁
inst✝³ : SmallCategory C
ℰ : Type u₂
inst✝² : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ
inst✝¹ : PreservesColimits L₁
inst✝ : PreservesColimits L₂
h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂
P : Cᵒᵖ ⥤ Type u₁
⊢ L₁.obj P ≅ L₂.obj P

Next tactic:
refine'
      (isColimitOfPreserves L₁ (colimitOfRepresentable P)).coconePointsIsoOfNatIso
        (isColimitOfPreserves L₂ (colimitOfRepresentable P)) _
/-- Given two functors L₁ and L₂ which preserve colimits, if they agree when restricted to the
representable presheaves then they agree everywhere.
-/
noncomputable def natIsoOfNatIsoOnRepresentables (L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ)
    [PreservesColimits L₁] [PreservesColimits L₂] (h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂) : L₁ ≅ L₂ := by
  apply NatIso.ofComponents _ _
  · intro P
    refine'
      (isColimitOfPreserves L₁ (colimitOfRepresentable P)).coconePointsIsoOfNatIso
        (isColimitOfPreserves L₂ (colimitOfRepresentable P)) _
    

Proof state:
C : Type u₁
inst✝³ : SmallCategory C
ℰ : Type u₂
inst✝² : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ
inst✝¹ : PreservesColimits L₁
inst✝ : PreservesColimits L₂
h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂
P : Cᵒᵖ ⥤ Type u₁
⊢ functorToRepresentables P ⋙ L₁ ≅ functorToRepresentables P ⋙ L₂

Next tactic:
apply Functor.associator _ _ _ ≪≫ _
/-- Given two functors L₁ and L₂ which preserve colimits, if they agree when restricted to the
representable presheaves then they agree everywhere.
-/
noncomputable def natIsoOfNatIsoOnRepresentables (L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ)
    [PreservesColimits L₁] [PreservesColimits L₂] (h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂) : L₁ ≅ L₂ := by
  apply NatIso.ofComponents _ _
  · intro P
    refine'
      (isColimitOfPreserves L₁ (colimitOfRepresentable P)).coconePointsIsoOfNatIso
        (isColimitOfPreserves L₂ (colimitOfRepresentable P)) _
    apply Functor.associator _ _ _ ≪≫ _
    

Proof state:
C : Type u₁
inst✝³ : SmallCategory C
ℰ : Type u₂
inst✝² : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ
inst✝¹ : PreservesColimits L₁
inst✝ : PreservesColimits L₂
h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂
P : Cᵒᵖ ⥤ Type u₁
⊢ (CategoryOfElements.π P).leftOp ⋙ yoneda ⋙ L₁ ≅ functorToRepresentables P ⋙ L₂

Next tactic:
exact isoWhiskerLeft (CategoryOfElements.π P).leftOp h
/-- Given two functors L₁ and L₂ which preserve colimits, if they agree when restricted to the
representable presheaves then they agree everywhere.
-/
noncomputable def natIsoOfNatIsoOnRepresentables (L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ)
    [PreservesColimits L₁] [PreservesColimits L₂] (h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂) : L₁ ≅ L₂ := by
  apply NatIso.ofComponents _ _
  · intro P
    refine'
      (isColimitOfPreserves L₁ (colimitOfRepresentable P)).coconePointsIsoOfNatIso
        (isColimitOfPreserves L₂ (colimitOfRepresentable P)) _
    apply Functor.associator _ _ _ ≪≫ _
    exact isoWhiskerLeft (CategoryOfElements.π P).leftOp h
  · 

Proof state:
C : Type u₁
inst✝³ : SmallCategory C
ℰ : Type u₂
inst✝² : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ
inst✝¹ : PreservesColimits L₁
inst✝ : PreservesColimits L₂
h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂
⊢ ∀ {X Y : Cᵒᵖ ⥤ Type u₁} (f : X ⟶ Y),
    L₁.map f ≫
        (IsColimit.coconePointsIsoOfNatIso (isColimitOfPreserves L₁ (colimitOfRepresentable Y))
            (isColimitOfPreserves L₂ (colimitOfRepresentable Y))
            (Functor.associator (CategoryOfElements.π Y).leftOp yoneda L₁ ≪≫
              isoWhiskerLeft (CategoryOfElements.π Y).leftOp h)).hom =
      (IsColimit.coconePointsIsoOfNatIso (isColimitOfPreserves L₁ (colimitOfRepresentable X))
            (isColimitOfPreserves L₂ (colimitOfRepresentable X))
            (Functor.associator (CategoryOfElements.π X).leftOp yoneda L₁ ≪≫
              isoWhiskerLeft (CategoryOfElements.π X).leftOp h)).hom ≫
        L₂.map f

Next tactic:
intro P₁ P₂ f
/-- Given two functors L₁ and L₂ which preserve colimits, if they agree when restricted to the
representable presheaves then they agree everywhere.
-/
noncomputable def natIsoOfNatIsoOnRepresentables (L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ)
    [PreservesColimits L₁] [PreservesColimits L₂] (h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂) : L₁ ≅ L₂ := by
  apply NatIso.ofComponents _ _
  · intro P
    refine'
      (isColimitOfPreserves L₁ (colimitOfRepresentable P)).coconePointsIsoOfNatIso
        (isColimitOfPreserves L₂ (colimitOfRepresentable P)) _
    apply Functor.associator _ _ _ ≪≫ _
    exact isoWhiskerLeft (CategoryOfElements.π P).leftOp h
  · intro P₁ P₂ f
    

Proof state:
C : Type u₁
inst✝³ : SmallCategory C
ℰ : Type u₂
inst✝² : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ
inst✝¹ : PreservesColimits L₁
inst✝ : PreservesColimits L₂
h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂
P₁ P₂ : Cᵒᵖ ⥤ Type u₁
f : P₁ ⟶ P₂
⊢ L₁.map f ≫
      (IsColimit.coconePointsIsoOfNatIso (isColimitOfPreserves L₁ (colimitOfRepresentable P₂))
          (isColimitOfPreserves L₂ (colimitOfRepresentable P₂))
          (Functor.associator (CategoryOfElements.π P₂).leftOp yoneda L₁ ≪≫
            isoWhiskerLeft (CategoryOfElements.π P₂).leftOp h)).hom =
    (IsColimit.coconePointsIsoOfNatIso (isColimitOfPreserves L₁ (colimitOfRepresentable P₁))
          (isColimitOfPreserves L₂ (colimitOfRepresentable P₁))
          (Functor.associator (CategoryOfElements.π P₁).leftOp yoneda L₁ ≪≫
            isoWhiskerLeft (CategoryOfElements.π P₁).leftOp h)).hom ≫
      L₂.map f

Next tactic:
apply (isColimitOfPreserves L₁ (colimitOfRepresentable P₁)).hom_ext
/-- Given two functors L₁ and L₂ which preserve colimits, if they agree when restricted to the
representable presheaves then they agree everywhere.
-/
noncomputable def natIsoOfNatIsoOnRepresentables (L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ)
    [PreservesColimits L₁] [PreservesColimits L₂] (h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂) : L₁ ≅ L₂ := by
  apply NatIso.ofComponents _ _
  · intro P
    refine'
      (isColimitOfPreserves L₁ (colimitOfRepresentable P)).coconePointsIsoOfNatIso
        (isColimitOfPreserves L₂ (colimitOfRepresentable P)) _
    apply Functor.associator _ _ _ ≪≫ _
    exact isoWhiskerLeft (CategoryOfElements.π P).leftOp h
  · intro P₁ P₂ f
    apply (isColimitOfPreserves L₁ (colimitOfRepresentable P₁)).hom_ext
    

Proof state:
C : Type u₁
inst✝³ : SmallCategory C
ℰ : Type u₂
inst✝² : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ
inst✝¹ : PreservesColimits L₁
inst✝ : PreservesColimits L₂
h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂
P₁ P₂ : Cᵒᵖ ⥤ Type u₁
f : P₁ ⟶ P₂
⊢ ∀ (j : (Functor.Elements P₁)ᵒᵖ),
    (L₁.mapCocone (coconeOfRepresentable P₁)).ι.app j ≫
        L₁.map f ≫
          (IsColimit.coconePointsIsoOfNatIso (isColimitOfPreserves L₁ (colimitOfRepresentable P₂))
              (isColimitOfPreserves L₂ (colimitOfRepresentable P₂))
              (Functor.associator (CategoryOfElements.π P₂).leftOp yoneda L₁ ≪≫
                isoWhiskerLeft (CategoryOfElements.π P₂).leftOp h)).hom =
      (L₁.mapCocone (coconeOfRepresentable P₁)).ι.app j ≫
        (IsColimit.coconePointsIsoOfNatIso (isColimitOfPreserves L₁ (colimitOfRepresentable P₁))
              (isColimitOfPreserves L₂ (colimitOfRepresentable P₁))
              (Functor.associator (CategoryOfElements.π P₁).leftOp yoneda L₁ ≪≫
                isoWhiskerLeft (CategoryOfElements.π P₁).leftOp h)).hom ≫
          L₂.map f

Next tactic:
intro j
/-- Given two functors L₁ and L₂ which preserve colimits, if they agree when restricted to the
representable presheaves then they agree everywhere.
-/
noncomputable def natIsoOfNatIsoOnRepresentables (L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ)
    [PreservesColimits L₁] [PreservesColimits L₂] (h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂) : L₁ ≅ L₂ := by
  apply NatIso.ofComponents _ _
  · intro P
    refine'
      (isColimitOfPreserves L₁ (colimitOfRepresentable P)).coconePointsIsoOfNatIso
        (isColimitOfPreserves L₂ (colimitOfRepresentable P)) _
    apply Functor.associator _ _ _ ≪≫ _
    exact isoWhiskerLeft (CategoryOfElements.π P).leftOp h
  · intro P₁ P₂ f
    apply (isColimitOfPreserves L₁ (colimitOfRepresentable P₁)).hom_ext
    intro j
    

Proof state:
C : Type u₁
inst✝³ : SmallCategory C
ℰ : Type u₂
inst✝² : Category.{u₁, u₂} ℰ
A : C ⥤ ℰ
L₁ L₂ : (Cᵒᵖ ⥤ Type u₁) ⥤ ℰ
inst✝¹ : PreservesColimits L₁
inst✝ : PreservesColimits L₂
h : yoneda ⋙ L₁ ≅ yoneda ⋙ L₂
P₁ P₂ : Cᵒᵖ ⥤ Type u₁
f : P₁ ⟶ P₂
j : (Functor.Elements P₁)ᵒᵖ
⊢ (L₁.mapCocone (coconeOfRepresentable P₁)).ι.app j ≫
      L₁.map f ≫
        (IsColimit.coconePointsIsoOfNatIso (isColimitOfPreserves L₁ (colimitOfRepresentable P₂))
            (isColimitOfPreserves L₂ (colimitOfRepresentable P₂))
            (Functor.associator (CategoryOfElements.π P₂).leftOp yoneda L₁ ≪≫
              isoWhiskerLeft (CategoryOfElements.π P₂).leftOp h)).hom =
    (L₁.mapCocone (coconeOfRepresentable P₁)).ι.app j ≫
      (IsColimit.coconePointsIsoOfNatIso (isColimitOfPreserves L₁ (colimitOfRepresentable P₁))
            (isColimitOfPreserves L₂ (colimitOfRepresentable P₁))
            (Functor.associator (CategoryOfElements.π P₁).leftOp yoneda L₁ ≪≫
              isoWhiskerLeft (CategoryOfElements.π P₁).leftOp h)).hom ≫
        L₂.map f

Next tactic:
dsimp only [id.def, IsColimit.comp_coconePointsIsoOfNatIso_hom, isoWhiskerLeft_hom]