File: Mathlib/CategoryTheory/Limits/Final.lean

full_name: CategoryTheory.Functor.Final
code: /--
A functor `F : C ⥤ D` is final if for every `d : D`, the comma category of morphisms `d ⟶ F.obj c`
is connected.

See <https://stacks.math.columbia.edu/tag/04E6>
-/
class Final (F : C ⥤ D) : Prop where
  out (d : D) : IsConnected (StructuredArrow d F)
goal: Prop

full_name: CategoryTheory.Functor.Final.out
code: /--
A functor `F : C ⥤ D` is final if for every `d : D`, the comma category of morphisms `d ⟶ F.obj c`
is connected.

See <https://stacks.math.columbia.edu/tag/04E6>
-/
class Final (F : C ⥤ D) : Prop where
  out (d : D) : IsConnected (StructuredArrow d F)
goal: CategoryTheory.IsConnected (CategoryTheory.StructuredArrow d F)

full_name: CategoryTheory.Functor.Initial.out
code: /-- A functor `F : C ⥤ D` is initial if for every `d : D`, the comma category of morphisms
`F.obj c ⟶ d` is connected.
-/
class Initial (F : C ⥤ D) : Prop where
  out (d : D) : IsConnected (CostructuredArrow F d)
goal: CategoryTheory.IsConnected (CategoryTheory.CostructuredArrow F d)

full_name: CategoryTheory.Functor.Initial
code: /-- A functor `F : C ⥤ D` is initial if for every `d : D`, the comma category of morphisms
`F.obj c ⟶ d` is connected.
-/
class Initial (F : C ⥤ D) : Prop where
  out (d : D) : IsConnected (CostructuredArrow F d)
goal: Prop

full_name: CategoryTheory.Functor.final_op_of_initial
code: instance final_op_of_initial (F : C ⥤ D) [Initial F] : Final F.op 
goal: F.op.Final

full_name: CategoryTheory.Functor.initial_op_of_final
code: instance initial_op_of_final (F : C ⥤ D) [Final F] : Initial F.op 
goal: F.op.Initial

full_name: CategoryTheory.Functor.final_of_initial_op
code: theorem final_of_initial_op (F : C ⥤ D) [Initial F.op] : Final F 
goal: F.Final

full_name: CategoryTheory.Functor.initial_of_final_op
code: theorem initial_of_final_op (F : C ⥤ D) [Final F.op] : Initial F 
goal: F.Initial

full_name: CategoryTheory.Functor.final_of_adjunction
code: /-- If a functor `R : D ⥤ C` is a right adjoint, it is final. -/
theorem final_of_adjunction {L : C ⥤ D} {R : D ⥤ C} (adj : L ⊣ R) : Final R 
goal: R.Final

full_name: CategoryTheory.Functor.initial_of_adjunction
code: /-- If a functor `L : C ⥤ D` is a left adjoint, it is initial. -/
theorem initial_of_adjunction {L : C ⥤ D} {R : D ⥤ C} (adj : L ⊣ R) : Initial L 
goal: L.Initial

full_name: CategoryTheory.Functor.final_of_isRightAdjoint
code: instance (priority := 100) final_of_isRightAdjoint (F : C ⥤ D) [IsRightAdjoint F] : Final F 
goal: F.Final

full_name: CategoryTheory.Functor.initial_of_isLeftAdjoint
code: instance (priority := 100) initial_of_isLeftAdjoint (F : C ⥤ D) [IsLeftAdjoint F] : Initial F 
goal: F.Initial

full_name: CategoryTheory.Functor.final_of_natIso
code: theorem final_of_natIso {F F' : C ⥤ D} [Final F] (i : F ≅ F') : Final F' 
goal: F'.Final

full_name: CategoryTheory.Functor.final_natIso_iff
code: theorem final_natIso_iff {F F' : C ⥤ D} (i : F ≅ F') : Final F ↔ Final F' 
goal: F.Final ↔ F'.Final

full_name: CategoryTheory.Functor.initial_of_natIso
code: theorem initial_of_natIso {F F' : C ⥤ D} [Initial F] (i : F ≅ F') : Initial F' 
goal: F'.Initial

full_name: CategoryTheory.Functor.initial_natIso_iff
code: theorem initial_natIso_iff {F F' : C ⥤ D} (i : F ≅ F') : Initial F ↔ Initial F' 
goal: F.Initial ↔ F'.Initial

full_name: CategoryTheory.Functor.Final.instNonemptyStructuredArrow
code: instance (d : D) : Nonempty (StructuredArrow d F) 
goal: Nonempty (CategoryTheory.StructuredArrow d F)

full_name: CategoryTheory.Functor.Final.lift
code: /--
When `F : C ⥤ D` is cofinal, we denote by `lift F d` an arbitrary choice of object in `C` such that
there exists a morphism `d ⟶ F.obj (lift F d)`.
-/
def lift (d : D) : C 
goal: C

full_name: CategoryTheory.Functor.Final.homToLift
code: /-- When `F : C ⥤ D` is cofinal, we denote by `homToLift` an arbitrary choice of morphism
`d ⟶ F.obj (lift F d)`.
-/
def homToLift (d : D) : d ⟶ F.obj (lift F d) 
goal: d ⟶ F.obj (CategoryTheory.Functor.Final.lift F d)

full_name: CategoryTheory.Functor.Final.induction
code: /-- We provide an induction principle for reasoning about `lift` and `homToLift`.
We want to perform some construction (usually just a proof) about
the particular choices `lift F d` and `homToLift F d`,
it suffices to perform that construction for some other pair of choices
(denoted `X₀ : C` and `k₀ : d ⟶ F.obj X₀` below),
and to show how to transport such a construction
*both* directions along a morphism between such choices.
-/
def induction {d : D} (Z : ∀ (X : C) (_ : d ⟶ F.obj X), Sort*)
    (h₁ :
      ∀ (X₁ X₂) (k₁ : d ⟶ F.obj X₁) (k₂ : d ⟶ F.obj X₂) (f : X₁ ⟶ X₂),
        k₁ ≫ F.map f = k₂ → Z X₁ k₁ → Z X₂ k₂)
    (h₂ :
      ∀ (X₁ X₂) (k₁ : d ⟶ F.obj X₁) (k₂ : d ⟶ F.obj X₂) (f : X₁ ⟶ X₂),
        k₁ ≫ F.map f = k₂ → Z X₂ k₂ → Z X₁ k₁)
    {X₀ : C} {k₀ : d ⟶ F.obj X₀} (z : Z X₀ k₀) : Z (lift F d) (homToLift F d) 
goal: Z (CategoryTheory.Functor.Final.lift F d) (CategoryTheory.Functor.Final.homToLift F d)

full_name: CategoryTheory.Functor.Final.extendCocone_obj_pt
code: /-- Given a cocone over `F ⋙ G`, we can construct a `Cocone G` with the same cocone point.
-/
@[simps]
def extendCocone : Cocone (F ⋙ G) ⥤ Cocone G 
goal: (CategoryTheory.Functor.Final.extendCocone.obj c).pt = c.pt

full_name: CategoryTheory.Functor.Final.extendCocone
code: /-- Given a cocone over `F ⋙ G`, we can construct a `Cocone G` with the same cocone point.
-/
@[simps]
def extendCocone : Cocone (F ⋙ G) ⥤ Cocone G 
goal: CategoryTheory.Functor (CategoryTheory.Limits.Cocone (F.comp G)) (CategoryTheory.Limits.Cocone G)

full_name: CategoryTheory.Functor.Final.extendCocone_obj_ι_app
code: /-- Given a cocone over `F ⋙ G`, we can construct a `Cocone G` with the same cocone point.
-/
@[simps]
def extendCocone : Cocone (F ⋙ G) ⥤ Cocone G 
goal: (CategoryTheory.Functor.Final.extendCocone.obj c).ι.app X =
  CategoryTheory.CategoryStruct.comp (G.map (CategoryTheory.Functor.Final.homToLift F X))
    (c.ι.app (CategoryTheory.Functor.Final.lift F X))

full_name: CategoryTheory.Functor.Final.extendCocone_map_hom
code: /-- Given a cocone over `F ⋙ G`, we can construct a `Cocone G` with the same cocone point.
-/
@[simps]
def extendCocone : Cocone (F ⋙ G) ⥤ Cocone G 
goal: ∀ {X Y : CategoryTheory.Limits.Cocone (F.comp G)} (f : X ⟶ Y),
  (CategoryTheory.Functor.Final.extendCocone.map f).hom = f.hom

full_name: CategoryTheory.Functor.Final.colimit_cocone_comp_aux
code: @[simp]
theorem colimit_cocone_comp_aux (s : Cocone (F ⋙ G)) (j : C) :
    G.map (homToLift F (F.obj j)) ≫ s.ι.app (lift F (F.obj j)) = s.ι.app j 
goal: CategoryTheory.CategoryStruct.comp (G.map (CategoryTheory.Functor.Final.homToLift F (F.obj j)))
    (s.ι.app (CategoryTheory.Functor.Final.lift F (F.obj j))) =
  s.ι.app j

full_name: CategoryTheory.Functor.Final.coconesEquiv
code: /-- If `F` is cofinal,
the category of cocones on `F ⋙ G` is equivalent to the category of cocones on `G`,
for any `G : D ⥤ E`.
-/
@[simps]
def coconesEquiv : Cocone (F ⋙ G) ≌ Cocone G 
goal: CategoryTheory.Limits.Cocone (F.comp G) ≌ CategoryTheory.Limits.Cocone G

full_name: CategoryTheory.Functor.Final.coconesEquiv_inverse
code: /-- If `F` is cofinal,
the category of cocones on `F ⋙ G` is equivalent to the category of cocones on `G`,
for any `G : D ⥤ E`.
-/
@[simps]
def coconesEquiv : Cocone (F ⋙ G) ≌ Cocone G 
goal: (CategoryTheory.Functor.Final.coconesEquiv F G).inverse = CategoryTheory.Limits.Cocones.whiskering F

full_name: CategoryTheory.Functor.Final.coconesEquiv_unitIso
code: /-- If `F` is cofinal,
the category of cocones on `F ⋙ G` is equivalent to the category of cocones on `G`,
for any `G : D ⥤ E`.
-/
@[simps]
def coconesEquiv : Cocone (F ⋙ G) ≌ Cocone G 
goal: (CategoryTheory.Functor.Final.coconesEquiv F G).unitIso =
  CategoryTheory.NatIso.ofComponents
    (fun c =>
      CategoryTheory.Limits.Cocones.ext
        (CategoryTheory.Iso.refl ((CategoryTheory.Functor.id (CategoryTheory.Limits.Cocone (F.comp G))).obj c).pt) ⋯)
    ⋯

full_name: CategoryTheory.Functor.Final.coconesEquiv_functor
code: /-- If `F` is cofinal,
the category of cocones on `F ⋙ G` is equivalent to the category of cocones on `G`,
for any `G : D ⥤ E`.
-/
@[simps]
def coconesEquiv : Cocone (F ⋙ G) ≌ Cocone G 
goal: (CategoryTheory.Functor.Final.coconesEquiv F G).functor = CategoryTheory.Functor.Final.extendCocone

full_name: CategoryTheory.Functor.Final.coconesEquiv_counitIso
code: /-- If `F` is cofinal,
the category of cocones on `F ⋙ G` is equivalent to the category of cocones on `G`,
for any `G : D ⥤ E`.
-/
@[simps]
def coconesEquiv : Cocone (F ⋙ G) ≌ Cocone G 
goal: (CategoryTheory.Functor.Final.coconesEquiv F G).counitIso =
  CategoryTheory.NatIso.ofComponents
    (fun c =>
      CategoryTheory.Limits.Cocones.ext
        (CategoryTheory.Iso.refl
          (((CategoryTheory.Limits.Cocones.whiskering F).comp CategoryTheory.Functor.Final.extendCocone).obj c).pt)
        ⋯)
    ⋯

full_name: CategoryTheory.Functor.Final.isColimitWhiskerEquiv
code: /-- When `F : C ⥤ D` is cofinal, and `t : Cocone G` for some `G : D ⥤ E`,
`t.whisker F` is a colimit cocone exactly when `t` is.
-/
def isColimitWhiskerEquiv (t : Cocone G) : IsColimit (t.whisker F) ≃ IsColimit t 
goal: CategoryTheory.Limits.IsColimit (CategoryTheory.Limits.Cocone.whisker F t) ≃ CategoryTheory.Limits.IsColimit t

full_name: CategoryTheory.Functor.Final.isColimitExtendCoconeEquiv
code: /-- When `F` is cofinal, and `t : Cocone (F ⋙ G)`,
`extendCocone.obj t` is a colimit cocone exactly when `t` is.
-/
def isColimitExtendCoconeEquiv (t : Cocone (F ⋙ G)) :
    IsColimit (extendCocone.obj t) ≃ IsColimit t 
goal: CategoryTheory.Limits.IsColimit (CategoryTheory.Functor.Final.extendCocone.obj t) ≃ CategoryTheory.Limits.IsColimit t

full_name: CategoryTheory.Functor.Final.colimitCoconeComp_isColimit
code: /-- Given a colimit cocone over `G : D ⥤ E` we can construct a colimit cocone over `F ⋙ G`. -/
@[simps]
def colimitCoconeComp (t : ColimitCocone G) : ColimitCocone (F ⋙ G) 
goal: (CategoryTheory.Functor.Final.colimitCoconeComp F t).isColimit =
  (CategoryTheory.Functor.Final.isColimitWhiskerEquiv F t.cocone).symm t.isColimit

full_name: CategoryTheory.Functor.Final.colimitCoconeComp_cocone
code: /-- Given a colimit cocone over `G : D ⥤ E` we can construct a colimit cocone over `F ⋙ G`. -/
@[simps]
def colimitCoconeComp (t : ColimitCocone G) : ColimitCocone (F ⋙ G) 
goal: (CategoryTheory.Functor.Final.colimitCoconeComp F t).cocone = CategoryTheory.Limits.Cocone.whisker F t.cocone

full_name: CategoryTheory.Functor.Final.colimitCoconeComp
code: /-- Given a colimit cocone over `G : D ⥤ E` we can construct a colimit cocone over `F ⋙ G`. -/
@[simps]
def colimitCoconeComp (t : ColimitCocone G) : ColimitCocone (F ⋙ G) 
goal: CategoryTheory.Limits.ColimitCocone (F.comp G)

full_name: CategoryTheory.Functor.Final.comp_hasColimit
code: instance (priority := 100) comp_hasColimit [HasColimit G] : HasColimit (F ⋙ G) 
goal: CategoryTheory.Limits.HasColimit (F.comp G)

full_name: CategoryTheory.Functor.Final.colimit_pre_isIso
code: instance colimit_pre_isIso [HasColimit G] : IsIso (colimit.pre G F) 
goal: CategoryTheory.IsIso (CategoryTheory.Limits.colimit.pre G F)

full_name: CategoryTheory.Functor.Final.colimitIso
code: /-- When `F : C ⥤ D` is cofinal, and `G : D ⥤ E` has a colimit, then `F ⋙ G` has a colimit also and
`colimit (F ⋙ G) ≅ colimit G`

https://stacks.math.columbia.edu/tag/04E7
-/
def colimitIso [HasColimit G] : colimit (F ⋙ G) ≅ colimit G 
goal: CategoryTheory.Limits.colimit (F.comp G) ≅ CategoryTheory.Limits.colimit G

full_name: CategoryTheory.Functor.Final.colimitCoconeOfComp
code: /-- Given a colimit cocone over `F ⋙ G` we can construct a colimit cocone over `G`. -/
@[simps]
def colimitCoconeOfComp (t : ColimitCocone (F ⋙ G)) : ColimitCocone G 
goal: CategoryTheory.Limits.ColimitCocone G

full_name: CategoryTheory.Functor.Final.colimitCoconeOfComp_isColimit
code: /-- Given a colimit cocone over `F ⋙ G` we can construct a colimit cocone over `G`. -/
@[simps]
def colimitCoconeOfComp (t : ColimitCocone (F ⋙ G)) : ColimitCocone G 
goal: (CategoryTheory.Functor.Final.colimitCoconeOfComp F t).isColimit =
  (CategoryTheory.Functor.Final.isColimitExtendCoconeEquiv F t.cocone).symm t.isColimit

full_name: CategoryTheory.Functor.Final.colimitCoconeOfComp_cocone
code: /-- Given a colimit cocone over `F ⋙ G` we can construct a colimit cocone over `G`. -/
@[simps]
def colimitCoconeOfComp (t : ColimitCocone (F ⋙ G)) : ColimitCocone G 
goal: (CategoryTheory.Functor.Final.colimitCoconeOfComp F t).cocone = CategoryTheory.Functor.Final.extendCocone.obj t.cocone

full_name: CategoryTheory.Functor.Final.hasColimit_of_comp
code: /-- When `F` is cofinal, and `F ⋙ G` has a colimit, then `G` has a colimit also.

We can't make this an instance, because `F` is not determined by the goal.
(Even if this weren't a problem, it would cause a loop with `comp_hasColimit`.)
-/
theorem hasColimit_of_comp [HasColimit (F ⋙ G)] : HasColimit G 
goal: CategoryTheory.Limits.HasColimit G

full_name: CategoryTheory.Functor.Final.hasColimitsOfShape_of_final
code: theorem hasColimitsOfShape_of_final [HasColimitsOfShape C E] : HasColimitsOfShape D E 
goal: CategoryTheory.Limits.HasColimitsOfShape D E

full_name: CategoryTheory.Functor.Final.colimitIso'
code: /-- When `F` is cofinal, and `F ⋙ G` has a colimit, then `G` has a colimit also and
`colimit (F ⋙ G) ≅ colimit G`

https://stacks.math.columbia.edu/tag/04E7
-/
def colimitIso' [HasColimit (F ⋙ G)] :
    haveI : HasColimit G := hasColimit_of_comp F
    colimit (F ⋙ G) ≅ colimit G 
goal: CategoryTheory.Limits.colimit (F.comp G) ≅ CategoryTheory.Limits.colimit G

full_name: CategoryTheory.Functor.Final.zigzag_of_eqvGen_quot_rel
code: theorem zigzag_of_eqvGen_quot_rel {F : C ⥤ D} {d : D} {f₁ f₂ : ΣX, d ⟶ F.obj X}
    (t : EqvGen (Types.Quot.Rel.{v, v} (F ⋙ coyoneda.obj (op d))) f₁ f₂) :
    Zigzag (StructuredArrow.mk f₁.2) (StructuredArrow.mk f₂.2) 
goal: CategoryTheory.Zigzag (CategoryTheory.StructuredArrow.mk f₁.snd) (CategoryTheory.StructuredArrow.mk f₂.snd)

full_name: CategoryTheory.Functor.cofinal_of_colimit_comp_coyoneda_iso_pUnit
code: /-- If `colimit (F ⋙ coyoneda.obj (op d)) ≅ PUnit` for all `d : D`, then `F` is cofinal.
-/
theorem cofinal_of_colimit_comp_coyoneda_iso_pUnit
    (I : ∀ d, colimit (F ⋙ coyoneda.obj (op d)) ≅ PUnit) : Final F 
goal: F.Final

full_name: CategoryTheory.Functor.cofinal_of_isTerminal_colimit_comp_yoneda
code: /-- A variant of `cofinal_of_colimit_comp_coyoneda_iso_pUnit` where we bind the various claims
    about `colimit (F ⋙ coyoneda.obj (Opposite.op d))` for each `d : D` into a single claim about
    the presheaf `colimit (F ⋙ yoneda)`. -/
theorem cofinal_of_isTerminal_colimit_comp_yoneda
    (h : IsTerminal (colimit (F ⋙ yoneda))) : Final F 
goal: F.Final

full_name: CategoryTheory.Functor.Final.colimitCompCoyonedaIso
code: /-- If the universal morphism `colimit (F ⋙ coyoneda.obj (op d)) ⟶ colimit (coyoneda.obj (op d))`
is an isomorphism (as it always is when `F` is cofinal),
then `colimit (F ⋙ coyoneda.obj (op d)) ≅ PUnit`
(simply because `colimit (coyoneda.obj (op d)) ≅ PUnit`).
-/
def Final.colimitCompCoyonedaIso (d : D) [IsIso (colimit.pre (coyoneda.obj (op d)) F)] :
    colimit (F ⋙ coyoneda.obj (op d)) ≅ PUnit 
goal: CategoryTheory.Limits.colimit (F.comp (CategoryTheory.coyoneda.obj (Opposite.op d))) ≅ PUnit.{v + 1}

full_name: CategoryTheory.Functor.final_iff_isIso_colimit_pre
code: theorem final_iff_isIso_colimit_pre : Final F ↔ ∀ G : D ⥤ Type v, IsIso (colimit.pre G F) 
goal: F.Final ↔ ∀ (G : CategoryTheory.Functor D (Type v)), CategoryTheory.IsIso (CategoryTheory.Limits.colimit.pre G F)

full_name: CategoryTheory.Functor.Initial.instNonemptyCostructuredArrow
code: instance (d : D) : Nonempty (CostructuredArrow F d) 
goal: Nonempty (CategoryTheory.CostructuredArrow F d)

full_name: CategoryTheory.Functor.Initial.lift
code: /--
When `F : C ⥤ D` is initial, we denote by `lift F d` an arbitrary choice of object in `C` such that
there exists a morphism `F.obj (lift F d) ⟶ d`.
-/
def lift (d : D) : C 
goal: C

full_name: CategoryTheory.Functor.Initial.homToLift
code: /-- When `F : C ⥤ D` is initial, we denote by `homToLift` an arbitrary choice of morphism
`F.obj (lift F d) ⟶ d`.
-/
def homToLift (d : D) : F.obj (lift F d) ⟶ d 
goal: F.obj (CategoryTheory.Functor.Initial.lift F d) ⟶ d

full_name: CategoryTheory.Functor.Initial.induction
code: /-- We provide an induction principle for reasoning about `lift` and `homToLift`.
We want to perform some construction (usually just a proof) about
the particular choices `lift F d` and `homToLift F d`,
it suffices to perform that construction for some other pair of choices
(denoted `X₀ : C` and `k₀ : F.obj X₀ ⟶ d` below),
and to show how to transport such a construction
*both* directions along a morphism between such choices.
-/
def induction {d : D} (Z : ∀ (X : C) (_ : F.obj X ⟶ d), Sort*)
    (h₁ :
      ∀ (X₁ X₂) (k₁ : F.obj X₁ ⟶ d) (k₂ : F.obj X₂ ⟶ d) (f : X₁ ⟶ X₂),
        F.map f ≫ k₂ = k₁ → Z X₁ k₁ → Z X₂ k₂)
    (h₂ :
      ∀ (X₁ X₂) (k₁ : F.obj X₁ ⟶ d) (k₂ : F.obj X₂ ⟶ d) (f : X₁ ⟶ X₂),
        F.map f ≫ k₂ = k₁ → Z X₂ k₂ → Z X₁ k₁)
    {X₀ : C} {k₀ : F.obj X₀ ⟶ d} (z : Z X₀ k₀) : Z (lift F d) (homToLift F d) 
goal: Z (CategoryTheory.Functor.Initial.lift F d) (CategoryTheory.Functor.Initial.homToLift F d)

full_name: CategoryTheory.Functor.Initial.extendCone_map_hom
code: /-- Given a cone over `F ⋙ G`, we can construct a `Cone G` with the same cocone point.
-/
@[simps]
def extendCone : Cone (F ⋙ G) ⥤ Cone G 
goal: ∀ {X Y : CategoryTheory.Limits.Cone (F.comp G)} (f : X ⟶ Y),
  (CategoryTheory.Functor.Initial.extendCone.map f).hom = f.hom

full_name: CategoryTheory.Functor.Initial.extendCone
code: /-- Given a cone over `F ⋙ G`, we can construct a `Cone G` with the same cocone point.
-/
@[simps]
def extendCone : Cone (F ⋙ G) ⥤ Cone G 
goal: CategoryTheory.Functor (CategoryTheory.Limits.Cone (F.comp G)) (CategoryTheory.Limits.Cone G)

full_name: CategoryTheory.Functor.Initial.extendCone_obj_pt
code: /-- Given a cone over `F ⋙ G`, we can construct a `Cone G` with the same cocone point.
-/
@[simps]
def extendCone : Cone (F ⋙ G) ⥤ Cone G 
goal: (CategoryTheory.Functor.Initial.extendCone.obj c).pt = c.pt

full_name: CategoryTheory.Functor.Initial.extendCone_obj_π_app
code: /-- Given a cone over `F ⋙ G`, we can construct a `Cone G` with the same cocone point.
-/
@[simps]
def extendCone : Cone (F ⋙ G) ⥤ Cone G 
goal: (CategoryTheory.Functor.Initial.extendCone.obj c).π.app d =
  CategoryTheory.CategoryStruct.comp (c.π.app (CategoryTheory.Functor.Initial.lift F d))
    (G.map (CategoryTheory.Functor.Initial.homToLift F d))

full_name: CategoryTheory.Functor.Initial.limit_cone_comp_aux
code: @[simp]
theorem limit_cone_comp_aux (s : Cone (F ⋙ G)) (j : C) :
    s.π.app (lift F (F.obj j)) ≫ G.map (homToLift F (F.obj j)) = s.π.app j 
goal: CategoryTheory.CategoryStruct.comp (s.π.app (CategoryTheory.Functor.Initial.lift F (F.obj j)))
    (G.map (CategoryTheory.Functor.Initial.homToLift F (F.obj j))) =
  s.π.app j

full_name: CategoryTheory.Functor.Initial.conesEquiv_counitIso
code: /-- If `F` is initial,
the category of cones on `F ⋙ G` is equivalent to the category of cones on `G`,
for any `G : D ⥤ E`.
-/
@[simps]
def conesEquiv : Cone (F ⋙ G) ≌ Cone G 
goal: (CategoryTheory.Functor.Initial.conesEquiv F G).counitIso =
  CategoryTheory.NatIso.ofComponents
    (fun c =>
      CategoryTheory.Limits.Cones.ext
        (CategoryTheory.Iso.refl
          (((CategoryTheory.Limits.Cones.whiskering F).comp CategoryTheory.Functor.Initial.extendCone).obj c).pt)
        ⋯)
    ⋯

full_name: CategoryTheory.Functor.Initial.conesEquiv_inverse
code: /-- If `F` is initial,
the category of cones on `F ⋙ G` is equivalent to the category of cones on `G`,
for any `G : D ⥤ E`.
-/
@[simps]
def conesEquiv : Cone (F ⋙ G) ≌ Cone G 
goal: (CategoryTheory.Functor.Initial.conesEquiv F G).inverse = CategoryTheory.Limits.Cones.whiskering F

full_name: CategoryTheory.Functor.Initial.conesEquiv_functor
code: /-- If `F` is initial,
the category of cones on `F ⋙ G` is equivalent to the category of cones on `G`,
for any `G : D ⥤ E`.
-/
@[simps]
def conesEquiv : Cone (F ⋙ G) ≌ Cone G 
goal: (CategoryTheory.Functor.Initial.conesEquiv F G).functor = CategoryTheory.Functor.Initial.extendCone

full_name: CategoryTheory.Functor.Initial.conesEquiv
code: /-- If `F` is initial,
the category of cones on `F ⋙ G` is equivalent to the category of cones on `G`,
for any `G : D ⥤ E`.
-/
@[simps]
def conesEquiv : Cone (F ⋙ G) ≌ Cone G 
goal: CategoryTheory.Limits.Cone (F.comp G) ≌ CategoryTheory.Limits.Cone G

full_name: CategoryTheory.Functor.Initial.conesEquiv_unitIso
code: /-- If `F` is initial,
the category of cones on `F ⋙ G` is equivalent to the category of cones on `G`,
for any `G : D ⥤ E`.
-/
@[simps]
def conesEquiv : Cone (F ⋙ G) ≌ Cone G 
goal: (CategoryTheory.Functor.Initial.conesEquiv F G).unitIso =
  CategoryTheory.NatIso.ofComponents
    (fun c =>
      CategoryTheory.Limits.Cones.ext
        (CategoryTheory.Iso.refl ((CategoryTheory.Functor.id (CategoryTheory.Limits.Cone (F.comp G))).obj c).pt) ⋯)
    ⋯

full_name: CategoryTheory.Functor.Initial.isLimitWhiskerEquiv
code: /-- When `F : C ⥤ D` is initial, and `t : Cone G` for some `G : D ⥤ E`,
`t.whisker F` is a limit cone exactly when `t` is.
-/
def isLimitWhiskerEquiv (t : Cone G) : IsLimit (t.whisker F) ≃ IsLimit t 
goal: CategoryTheory.Limits.IsLimit (CategoryTheory.Limits.Cone.whisker F t) ≃ CategoryTheory.Limits.IsLimit t

full_name: CategoryTheory.Functor.Initial.isLimitExtendConeEquiv
code: /-- When `F` is initial, and `t : Cone (F ⋙ G)`,
`extendCone.obj t` is a limit cone exactly when `t` is.
-/
def isLimitExtendConeEquiv (t : Cone (F ⋙ G)) : IsLimit (extendCone.obj t) ≃ IsLimit t 
goal: CategoryTheory.Limits.IsLimit (CategoryTheory.Functor.Initial.extendCone.obj t) ≃ CategoryTheory.Limits.IsLimit t

full_name: CategoryTheory.Functor.Initial.limitConeComp_isLimit
code: /-- Given a limit cone over `G : D ⥤ E` we can construct a limit cone over `F ⋙ G`. -/
@[simps]
def limitConeComp (t : LimitCone G) : LimitCone (F ⋙ G) 
goal: (CategoryTheory.Functor.Initial.limitConeComp F t).isLimit =
  (CategoryTheory.Functor.Initial.isLimitWhiskerEquiv F t.cone).symm t.isLimit

full_name: CategoryTheory.Functor.Initial.limitConeComp
code: /-- Given a limit cone over `G : D ⥤ E` we can construct a limit cone over `F ⋙ G`. -/
@[simps]
def limitConeComp (t : LimitCone G) : LimitCone (F ⋙ G) 
goal: CategoryTheory.Limits.LimitCone (F.comp G)

full_name: CategoryTheory.Functor.Initial.limitConeComp_cone
code: /-- Given a limit cone over `G : D ⥤ E` we can construct a limit cone over `F ⋙ G`. -/
@[simps]
def limitConeComp (t : LimitCone G) : LimitCone (F ⋙ G) 
goal: (CategoryTheory.Functor.Initial.limitConeComp F t).cone = CategoryTheory.Limits.Cone.whisker F t.cone

full_name: CategoryTheory.Functor.Initial.comp_hasLimit
code: instance (priority := 100) comp_hasLimit [HasLimit G] : HasLimit (F ⋙ G) 
goal: CategoryTheory.Limits.HasLimit (F.comp G)

full_name: CategoryTheory.Functor.Initial.limit_pre_isIso
code: instance limit_pre_isIso [HasLimit G] : IsIso (limit.pre G F) 
goal: CategoryTheory.IsIso (CategoryTheory.Limits.limit.pre G F)

full_name: CategoryTheory.Functor.Initial.limitIso
code: /-- When `F : C ⥤ D` is initial, and `G : D ⥤ E` has a limit, then `F ⋙ G` has a limit also and
`limit (F ⋙ G) ≅ limit G`

https://stacks.math.columbia.edu/tag/04E7
-/
def limitIso [HasLimit G] : limit (F ⋙ G) ≅ limit G 
goal: CategoryTheory.Limits.limit (F.comp G) ≅ CategoryTheory.Limits.limit G

full_name: CategoryTheory.Functor.Initial.limitConeOfComp_cone
code: /-- Given a limit cone over `F ⋙ G` we can construct a limit cone over `G`. -/
@[simps]
def limitConeOfComp (t : LimitCone (F ⋙ G)) : LimitCone G 
goal: (CategoryTheory.Functor.Initial.limitConeOfComp F t).cone = CategoryTheory.Functor.Initial.extendCone.obj t.cone

full_name: CategoryTheory.Functor.Initial.limitConeOfComp_isLimit
code: /-- Given a limit cone over `F ⋙ G` we can construct a limit cone over `G`. -/
@[simps]
def limitConeOfComp (t : LimitCone (F ⋙ G)) : LimitCone G 
goal: (CategoryTheory.Functor.Initial.limitConeOfComp F t).isLimit =
  (CategoryTheory.Functor.Initial.isLimitExtendConeEquiv F t.cone).symm t.isLimit

full_name: CategoryTheory.Functor.Initial.limitConeOfComp
code: /-- Given a limit cone over `F ⋙ G` we can construct a limit cone over `G`. -/
@[simps]
def limitConeOfComp (t : LimitCone (F ⋙ G)) : LimitCone G 
goal: CategoryTheory.Limits.LimitCone G

full_name: CategoryTheory.Functor.Initial.hasLimit_of_comp
code: /-- When `F` is initial, and `F ⋙ G` has a limit, then `G` has a limit also.

We can't make this an instance, because `F` is not determined by the goal.
(Even if this weren't a problem, it would cause a loop with `comp_hasLimit`.)
-/
theorem hasLimit_of_comp [HasLimit (F ⋙ G)] : HasLimit G 
goal: CategoryTheory.Limits.HasLimit G

full_name: CategoryTheory.Functor.Initial.hasLimitsOfShape_of_initial
code: theorem hasLimitsOfShape_of_initial [HasLimitsOfShape C E] : HasLimitsOfShape D E 
goal: CategoryTheory.Limits.HasLimitsOfShape D E

full_name: CategoryTheory.Functor.Initial.limitIso'
code: /-- When `F` is initial, and `F ⋙ G` has a limit, then `G` has a limit also and
`limit (F ⋙ G) ≅ limit G`

https://stacks.math.columbia.edu/tag/04E7
-/
def limitIso' [HasLimit (F ⋙ G)] :
    haveI : HasLimit G := hasLimit_of_comp F
    limit (F ⋙ G) ≅ limit G 
goal: CategoryTheory.Limits.limit (F.comp G) ≅ CategoryTheory.Limits.limit G

full_name: CategoryTheory.Functor.final_of_comp_full_faithful
code: /-- The hypotheses also imply that `G` is final, see `final_of_comp_full_faithful'`. -/
theorem final_of_comp_full_faithful [Full G] [Faithful G] [Final (F ⋙ G)] : Final F 
goal: F.Final

full_name: CategoryTheory.Functor.initial_of_comp_full_faithful
code: /-- The hypotheses also imply that `G` is initial, see `initial_of_comp_full_faithful'`. -/
theorem initial_of_comp_full_faithful [Full G] [Faithful G] [Initial (F ⋙ G)] : Initial F 
goal: F.Initial

full_name: CategoryTheory.Functor.final_comp_equivalence
code: /-- See also the strictly more general `final_comp` below. -/
theorem final_comp_equivalence [Final F] [IsEquivalence G] : Final (F ⋙ G) 
goal: (F.comp G).Final

full_name: CategoryTheory.Functor.initial_comp_equivalence
code: /-- See also the strictly more general `initial_comp` below. -/
theorem initial_comp_equivalence [Initial F] [IsEquivalence G] : Initial (F ⋙ G) 
goal: (F.comp G).Initial

full_name: CategoryTheory.Functor.final_equivalence_comp
code: /-- See also the strictly more general `final_comp` below. -/
theorem final_equivalence_comp [IsEquivalence F] [Final G] : Final (F ⋙ G) 
goal: (F.comp G).Final

full_name: CategoryTheory.Functor.initial_equivalence_comp
code: /-- See also the strictly more general `inital_comp` below. -/
theorem initial_equivalence_comp [IsEquivalence F] [Initial G] : Initial (F ⋙ G) 
goal: (F.comp G).Initial

full_name: CategoryTheory.Functor.final_of_equivalence_comp
code: /-- See also the strictly more general `final_of_final_comp` below. -/
theorem final_of_equivalence_comp [IsEquivalence F] [Final (F ⋙ G)] : Final G 
goal: G.Final

full_name: CategoryTheory.Functor.initial_of_equivalence_comp
code: /-- See also the strictly more general `initial_of_initial_comp` below. -/
theorem initial_of_equivalence_comp [IsEquivalence F] [Initial (F ⋙ G)] : Initial G 
goal: G.Initial

full_name: CategoryTheory.Functor.final_iff_comp_equivalence
code: /-- See also the strictly more general `final_iff_comp_final_full_faithful` below. -/
theorem final_iff_comp_equivalence [IsEquivalence G] : Final F ↔ Final (F ⋙ G) 
goal: F.Final ↔ (F.comp G).Final

full_name: CategoryTheory.Functor.final_iff_equivalence_comp
code: /-- See also the strictly more general `final_iff_final_comp` below. -/
theorem final_iff_equivalence_comp [IsEquivalence F] : Final G ↔ Final (F ⋙ G) 
goal: G.Final ↔ (F.comp G).Final

full_name: CategoryTheory.Functor.initial_iff_comp_equivalence
code: /-- See also the strictly more general `initial_iff_comp_initial_full_faithful` below. -/
theorem initial_iff_comp_equivalence [IsEquivalence G] : Initial F ↔ Initial (F ⋙ G) 
goal: F.Initial ↔ (F.comp G).Initial

full_name: CategoryTheory.Functor.initial_iff_equivalence_comp
code: /-- See also the strictly more general `initial_iff_initial_comp` below. -/
theorem initial_iff_equivalence_comp [IsEquivalence F] : Initial G ↔ Initial (F ⋙ G) 
goal: G.Initial ↔ (F.comp G).Initial

full_name: CategoryTheory.Functor.final_comp
code: instance final_comp [hF : Final F] [hG : Final G] : Final (F ⋙ G) 
goal: (F.comp G).Final

full_name: CategoryTheory.Functor.initial_comp
code: instance initial_comp [Initial F] [Initial G] : Initial (F ⋙ G) 
goal: (F.comp G).Initial

full_name: CategoryTheory.Functor.final_of_final_comp
code: theorem final_of_final_comp [hF : Final F] [hFG : Final (F ⋙ G)] : Final G 
goal: G.Final

full_name: CategoryTheory.Functor.initial_of_initial_comp
code: theorem initial_of_initial_comp [Initial F] [Initial (F ⋙ G)] : Initial G 
goal: G.Initial

full_name: CategoryTheory.Functor.final_of_comp_full_faithful'
code: /-- The hypotheses also imply that `F` is final, see `final_of_comp_full_faithful`. -/
theorem final_of_comp_full_faithful' [Full G] [Faithful G] [Final (F ⋙ G)] : Final G 
goal: G.Final

full_name: CategoryTheory.Functor.initial_of_comp_full_faithful'
code: /-- The hypotheses also imply that `F` is initial, see `initial_of_comp_full_faithful`. -/
theorem initial_of_comp_full_faithful' [Full G] [Faithful G] [Initial (F ⋙ G)] : Initial G 
goal: G.Initial

full_name: CategoryTheory.Functor.final_iff_comp_final_full_faithful
code: theorem final_iff_comp_final_full_faithful [Final G] [Full G] [Faithful G] :
    Final F ↔ Final (F ⋙ G) 
goal: F.Final ↔ (F.comp G).Final

full_name: CategoryTheory.Functor.initial_iff_comp_initial_full_faithful
code: theorem initial_iff_comp_initial_full_faithful [Initial G] [Full G] [Faithful G] :
    Initial F ↔ Initial (F ⋙ G) 
goal: F.Initial ↔ (F.comp G).Initial

full_name: CategoryTheory.Functor.final_iff_final_comp
code: theorem final_iff_final_comp [Final F] : Final G ↔ Final (F ⋙ G) 
goal: G.Final ↔ (F.comp G).Final

full_name: CategoryTheory.Functor.initial_iff_initial_comp
code: theorem initial_iff_initial_comp [Initial F] : Initial G ↔ Initial (F ⋙ G) 
goal: G.Initial ↔ (F.comp G).Initial

full_name: CategoryTheory.IsFilteredOrEmpty.of_final
code: /-- Final functors preserve filteredness.

This can be seen as a generalization of `IsFiltered.of_right_adjoint` (which states that right
adjoints preserve filteredness), as right adjoints are always final, see `final_of_adjunction`.
-/
theorem IsFilteredOrEmpty.of_final (F : C ⥤ D) [Final F] [IsFilteredOrEmpty C] :
    IsFilteredOrEmpty D 
goal: CategoryTheory.IsFilteredOrEmpty D

full_name: CategoryTheory.IsFiltered.of_final
code: /-- Final functors preserve filteredness.

This can be seen as a generalization of `IsFiltered.of_right_adjoint` (which states that right
adjoints preserve filteredness), as right adjoints are always final, see `final_of_adjunction`.
-/
theorem IsFiltered.of_final (F : C ⥤ D) [Final F] [IsFiltered C] : IsFiltered D 
goal: CategoryTheory.IsFiltered D

full_name: CategoryTheory.IsCofilteredOrEmpty.of_initial
code: /-- Initial functors preserve cofilteredness.

This can be seen as a generalization of `IsCofiltered.of_left_adjoint` (which states that left
adjoints preserve cofilteredness), as right adjoints are always initial, see `intial_of_adjunction`.
-/
theorem IsCofilteredOrEmpty.of_initial (F : C ⥤ D) [Initial F] [IsCofilteredOrEmpty C] :
    IsCofilteredOrEmpty D 
goal: CategoryTheory.IsCofilteredOrEmpty D

full_name: CategoryTheory.IsCofiltered.of_initial
code: /-- Initial functors preserve cofilteredness.

This can be seen as a generalization of `IsCofiltered.of_left_adjoint` (which states that left
adjoints preserve cofilteredness), as right adjoints are always initial, see `intial_of_adjunction`.
-/
theorem IsCofiltered.of_initial (F : C ⥤ D) [Initial F] [IsCofiltered C] : IsCofiltered D 
goal: CategoryTheory.IsCofiltered D