/-
Copyright (c) 2021 Adam Topaz. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Bhavik Mehta, Adam Topaz

! This file was ported from Lean 3 source module category_theory.limits.kan_extension
! leanprover-community/mathlib commit 69c6a5a12d8a2b159f20933e60115a4f2de62b58
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.CategoryTheory.Limits.Shapes.Terminal
import Mathbin.CategoryTheory.Punit
import Mathbin.CategoryTheory.StructuredArrow

/-!

# Kan extensions

> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
> Any changes to this file require a corresponding PR to mathlib4.

This file defines the right and left Kan extensions of a functor.
They exist under the assumption that the target category has enough limits
resp. colimits.

The main definitions are `Ran ι` and `Lan ι`, where `ι : S ⥤ L` is a functor.
Namely, `Ran ι` is the right Kan extension, while `Lan ι` is the left Kan extension,
both as functors `(S ⥤ D) ⥤ (L ⥤ D)`.

To access the right resp. left adjunction associated to these, use `Ran.adjunction`
resp. `Lan.adjunction`.

# Projects

A lot of boilerplate could be generalized by defining and working with pseudofunctors.

-/

noncomputable section

namespace CategoryTheory

open Limits

universe v v₁ v₂ v₃ u₁ u₂ u₃

variable {S : Type u₁} {L : Type u₂} {D : Type u₃}

variable [Category.{v₁} S] [Category.{v₂} L] [Category.{v₃} D]

variable (ι : S ⥤ L)

namespace Ran

attribute [local simp] structured_arrow.proj

#print CategoryTheory.Ran.diagram /-
/-- The diagram indexed by `Ran.index ι x` used to define `Ran`. -/
abbrev diagram (F : S ⥤ D) (x : L) : StructuredArrow x ι ⥤ D :=
  StructuredArrow.proj x ι ⋙ F
#align category_theory.Ran.diagram CategoryTheory.Ran.diagram
-/

variable {ι}

#print CategoryTheory.Ran.cone /-
/-- A cone over `Ran.diagram ι F x` used to define `Ran`. -/
@[simp]
def cone {F : S ⥤ D} {G : L ⥤ D} (x : L) (f : ι ⋙ G ⟶ F) : Cone (diagram ι F x)
    where
  pt := G.obj x
  π :=
    { app := fun i => G.map i.Hom ≫ f.app i.right
      naturality' := by
        rintro ⟨⟨il⟩, ir, i⟩ ⟨⟨jl⟩, jr, j⟩ ⟨⟨⟨fl⟩⟩, fr, ff⟩
        dsimp at *
        simp only [category.id_comp, category.assoc] at *
        rw [ff]
        have := f.naturality
        tidy }
#align category_theory.Ran.cone CategoryTheory.Ran.cone
-/

variable (ι)

#print CategoryTheory.Ran.loc /-
/-- An auxiliary definition used to define `Ran`. -/
@[simps]
def loc (F : S ⥤ D) [∀ x, HasLimit (diagram ι F x)] : L ⥤ D
    where
  obj x := limit (diagram ι F x)
  map x y f := limit.pre (diagram _ _ _) (StructuredArrow.map f : StructuredArrow _ ι ⥤ _)
  map_id' := by
    intro l
    ext j
    simp only [category.id_comp, limit.pre_π]
    congr 1
    simp
  map_comp' := by
    intro x y z f g
    ext j
    erw [limit.pre_pre, limit.pre_π, limit.pre_π]
    congr 1
    tidy
#align category_theory.Ran.loc CategoryTheory.Ran.loc
-/

/- warning: category_theory.Ran.equiv -> CategoryTheory.Ran.equiv is a dubious translation:
lean 3 declaration is
  forall {S : Type.{u4}} {L : Type.{u5}} {D : Type.{u6}} [_inst_1 : CategoryTheory.Category.{u1, u4} S] [_inst_2 : CategoryTheory.Category.{u2, u5} L] [_inst_3 : CategoryTheory.Category.{u3, u6} D] (ι : CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (F : CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) [_inst_4 : forall (x : L), CategoryTheory.Limits.HasLimit.{max u2 u1, max u4 u2, u3, u6} (CategoryTheory.StructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 x ι) (CategoryTheory.StructuredArrow.category.{u2, u5, u4, u1} S _inst_1 L _inst_2 x ι) D _inst_3 (CategoryTheory.Ran.diagram.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι F x)] (G : CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3), Equiv.{succ (max u5 u3), succ (max u4 u3)} (Quiver.Hom.{succ (max u5 u3), max u2 u3 u5 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.CategoryStruct.toQuiver.{max u5 u3, max u2 u3 u5 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Category.toCategoryStruct.{max u5 u3, max u2 u3 u5 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3))) G (CategoryTheory.Ran.loc.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι F (CategoryTheory.Ran.equiv._proof_1.{u4, u5, u6, u1, u2, u3} S L D _inst_1 _inst_2 _inst_3 ι F _inst_4))) (Quiver.Hom.{succ (max u4 u3), max u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.CategoryStruct.toQuiver.{max u4 u3, max u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Category.toCategoryStruct.{max u4 u3, max u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3))) (CategoryTheory.Functor.obj.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.obj.{max u4 u2, max (max u2 u3 u5 u6) u4 u3, max u1 u2 u4 u5, max (max u5 u3) (max u4 u3) (max u2 u3 u5 u6) u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.whiskeringLeft.{u4, u1, u5, u2, u6, u3} S _inst_1 L _inst_2 D _inst_3) ι) G) F)
but is expected to have type
  forall {S : Type.{u4}} {L : Type.{u5}} {D : Type.{u6}} [_inst_1 : CategoryTheory.Category.{u1, u4} S] [_inst_2 : CategoryTheory.Category.{u2, u5} L] [_inst_3 : CategoryTheory.Category.{u3, u6} D] (ι : CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (F : CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) [_inst_4 : forall (x : L), CategoryTheory.Limits.HasLimit.{max u1 u2, max u4 u2, u3, u6} (CategoryTheory.StructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 x ι) (CategoryTheory.instCategoryStructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 x ι) D _inst_3 (CategoryTheory.Ran.diagram.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι F x)] (G : CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3), Equiv.{max (succ u5) (succ u3), max (succ u4) (succ u3)} (Quiver.Hom.{max (succ u5) (succ u3), max (max (max u5 u6) u2) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.CategoryStruct.toQuiver.{max u5 u3, max (max (max u5 u6) u2) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Category.toCategoryStruct.{max u5 u3, max (max (max u5 u6) u2) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3))) G (CategoryTheory.Ran.loc.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι F (fun (x : L) => _inst_4 x))) (Quiver.Hom.{max (succ u4) (succ u3), max (max (max u4 u1) u3) u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.CategoryStruct.toQuiver.{max u4 u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Category.toCategoryStruct.{max u4 u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3))) (Prefunctor.obj.{max (succ u5) (succ u3), max (succ u4) (succ u3), max (max (max u5 u2) u3) u6, max (max (max u4 u1) u3) u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.CategoryStruct.toQuiver.{max u5 u3, max (max (max u5 u2) u3) u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Category.toCategoryStruct.{max u5 u3, max (max (max u5 u2) u3) u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3))) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.CategoryStruct.toQuiver.{max u4 u3, max (max (max u4 u1) u3) u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Category.toCategoryStruct.{max u4 u3, max (max (max u4 u1) u3) u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3))) (CategoryTheory.Functor.toPrefunctor.{max u5 u3, max u4 u3, max (max (max u5 u2) u3) u6, max (max (max u4 u1) u3) u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (Prefunctor.obj.{max (succ u2) (succ u4), max (max (max (max (succ u3) (succ u6)) (succ u2)) (succ u5)) (succ u4), max (max (max u2 u5) u1) u4, max (max (max (max (max u3 u6) u2) u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.CategoryStruct.toQuiver.{max u2 u4, max (max (max u2 u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Category.toCategoryStruct.{max u2 u4, max (max (max u2 u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2))) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.CategoryStruct.toQuiver.{max (max (max (max u3 u6) u2) u5) u4, max (max (max (max (max u3 u6) u2) u5) u1) u4} (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Category.toCategoryStruct.{max (max (max (max u3 u6) u2) u5) u4, max (max (max (max (max u3 u6) u2) u5) u1) u4} (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)))) (CategoryTheory.Functor.toPrefunctor.{max u2 u4, max (max (max (max u3 u6) u2) u5) u4, max (max (max u2 u5) u1) u4, max (max (max (max (max u3 u6) u2) u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.whiskeringLeft.{u4, u1, u5, u2, u6, u3} S _inst_1 L _inst_2 D _inst_3)) ι)) G) F)
Case conversion may be inaccurate. Consider using '#align category_theory.Ran.equiv CategoryTheory.Ran.equivₓ'. -/
/-- An auxiliary definition used to define `Ran` and `Ran.adjunction`. -/
@[simps]
def equiv (F : S ⥤ D) [∀ x, HasLimit (diagram ι F x)] (G : L ⥤ D) :
    (G ⟶ loc ι F) ≃ (((whiskeringLeft _ _ _).obj ι).obj G ⟶ F)
    where
  toFun f :=
    { app := fun x => f.app _ ≫ limit.π (diagram ι F (ι.obj x)) (StructuredArrow.mk (𝟙 _))
      naturality' := by
        intro x y ff
        dsimp only [whiskering_left]
        simp only [functor.comp_map, nat_trans.naturality_assoc, loc_map, category.assoc]
        congr 1
        erw [limit.pre_π]
        change _ = _ ≫ (diagram ι F (ι.obj x)).map (structured_arrow.hom_mk _ _)
        rw [limit.w]
        tidy }
  invFun f :=
    { app := fun x => limit.lift (diagram ι F x) (cone _ f)
      naturality' := by
        intro x y ff
        ext j
        erw [limit.lift_pre, limit.lift_π, category.assoc, limit.lift_π (cone _ f) j]
        tidy }
  left_inv := by
    intro x
    ext (k j)
    dsimp only [cone]
    rw [limit.lift_π]
    simp only [nat_trans.naturality_assoc, loc_map]
    erw [limit.pre_π]
    congr
    rcases j with ⟨⟨⟩, _, _⟩
    tidy
  right_inv := by tidy
#align category_theory.Ran.equiv CategoryTheory.Ran.equiv

end Ran

#print CategoryTheory.ran /-
/-- The right Kan extension of a functor. -/
@[simps]
def ran [∀ X, HasLimitsOfShape (StructuredArrow X ι) D] : (S ⥤ D) ⥤ L ⥤ D :=
  Adjunction.rightAdjointOfEquiv (fun F G => (Ran.equiv ι G F).symm) (by tidy)
#align category_theory.Ran CategoryTheory.ran
-/

namespace Ran

variable (D)

/- warning: category_theory.Ran.adjunction -> CategoryTheory.Ran.adjunction is a dubious translation:
lean 3 declaration is
  forall {S : Type.{u4}} {L : Type.{u5}} (D : Type.{u6}) [_inst_1 : CategoryTheory.Category.{u1, u4} S] [_inst_2 : CategoryTheory.Category.{u2, u5} L] [_inst_3 : CategoryTheory.Category.{u3, u6} D] (ι : CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) [_inst_4 : forall (X : L), CategoryTheory.Limits.HasLimitsOfShape.{max u2 u1, max u4 u2, u3, u6} (CategoryTheory.StructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 X ι) (CategoryTheory.StructuredArrow.category.{u2, u5, u4, u1} S _inst_1 L _inst_2 X ι) D _inst_3], CategoryTheory.Adjunction.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.obj.{max u4 u2, max (max u2 u3 u5 u6) u4 u3, max u1 u2 u4 u5, max (max u5 u3) (max u4 u3) (max u2 u3 u5 u6) u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.whiskeringLeft.{u4, u1, u5, u2, u6, u3} S _inst_1 L _inst_2 D _inst_3) ι) (CategoryTheory.ran.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι (CategoryTheory.Ran.adjunction._proof_1.{u4, u5, u6, u1, u2, u3} S L D _inst_1 _inst_2 _inst_3 ι _inst_4))
but is expected to have type
  forall {S : Type.{u4}} {L : Type.{u5}} (D : Type.{u6}) [_inst_1 : CategoryTheory.Category.{u1, u4} S] [_inst_2 : CategoryTheory.Category.{u2, u5} L] [_inst_3 : CategoryTheory.Category.{u3, u6} D] (ι : CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) [_inst_4 : forall (X : L), CategoryTheory.Limits.HasLimitsOfShape.{max u1 u2, max u4 u2, u3, u6} (CategoryTheory.StructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 X ι) (CategoryTheory.instCategoryStructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 X ι) D _inst_3], CategoryTheory.Adjunction.{max u3 u5, max u3 u4, max (max (max u6 u3) u2) u5, max (max (max u6 u3) u1) u4} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (Prefunctor.obj.{max (succ u2) (succ u4), max (max (max (max (succ u6) (succ u3)) (succ u2)) (succ u5)) (succ u4), max (max (max u2 u5) u1) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.CategoryStruct.toQuiver.{max u2 u4, max (max (max u2 u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Category.toCategoryStruct.{max u2 u4, max (max (max u2 u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2))) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.CategoryStruct.toQuiver.{max (max (max (max u6 u3) u2) u5) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Category.toCategoryStruct.{max (max (max (max u6 u3) u2) u5) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)))) (CategoryTheory.Functor.toPrefunctor.{max u2 u4, max (max (max (max u6 u3) u2) u5) u4, max (max (max u2 u5) u1) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.whiskeringLeft.{u4, u1, u5, u2, u6, u3} S _inst_1 L _inst_2 D _inst_3)) ι) (CategoryTheory.ran.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι (fun (X : L) => _inst_4 X))
Case conversion may be inaccurate. Consider using '#align category_theory.Ran.adjunction CategoryTheory.Ran.adjunctionₓ'. -/
/-- The adjunction associated to `Ran`. -/
def adjunction [∀ X, HasLimitsOfShape (StructuredArrow X ι) D] :
    (whiskeringLeft _ _ D).obj ι ⊣ ran ι :=
  Adjunction.adjunctionOfEquivRight _ _
#align category_theory.Ran.adjunction CategoryTheory.Ran.adjunction

/- warning: category_theory.Ran.reflective -> CategoryTheory.Ran.reflective is a dubious translation:
lean 3 declaration is
  forall {S : Type.{u4}} {L : Type.{u5}} (D : Type.{u6}) [_inst_1 : CategoryTheory.Category.{u1, u4} S] [_inst_2 : CategoryTheory.Category.{u2, u5} L] [_inst_3 : CategoryTheory.Category.{u3, u6} D] (ι : CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) [_inst_4 : CategoryTheory.Full.{u1, u2, u4, u5} S _inst_1 L _inst_2 ι] [_inst_5 : CategoryTheory.Faithful.{u1, u2, u4, u5} S _inst_1 L _inst_2 ι] [_inst_6 : forall (X : L), CategoryTheory.Limits.HasLimitsOfShape.{max u2 u1, max u4 u2, u3, u6} (CategoryTheory.StructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 X ι) (CategoryTheory.StructuredArrow.category.{u2, u5, u4, u1} S _inst_1 L _inst_2 X ι) D _inst_3], CategoryTheory.IsIso.{max (max u1 u3 u4 u6) u4 u3, max (max u4 u3) u1 u3 u4 u6} (CategoryTheory.Functor.{max u4 u3, max u4 u3, max u1 u3 u4 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u4 u3, max u4 u3, max u1 u3 u4 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.comp.{max u4 u3, max u5 u3, max u4 u3, max u1 u3 u4 u6, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.ran.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι (CategoryTheory.Ran.adjunction._proof_1.{u4, u5, u6, u1, u2, u3} S L D _inst_1 _inst_2 _inst_3 ι (fun (X : L) => _inst_6 X))) (CategoryTheory.Functor.obj.{max u4 u2, max (max u2 u3 u5 u6) u4 u3, max u1 u2 u4 u5, max (max u5 u3) (max u4 u3) (max u2 u3 u5 u6) u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.whiskeringLeft.{u4, u1, u5, u2, u6, u3} S _inst_1 L _inst_2 D _inst_3) ι)) (CategoryTheory.Functor.id.{max u4 u3, max u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Adjunction.counit.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.obj.{max u4 u2, max (max u2 u3 u5 u6) u4 u3, max u1 u2 u4 u5, max (max u5 u3) (max u4 u3) (max u2 u3 u5 u6) u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.whiskeringLeft.{u4, u1, u5, u2, u6, u3} S _inst_1 L _inst_2 D _inst_3) ι) (CategoryTheory.ran.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι (CategoryTheory.Ran.adjunction._proof_1.{u4, u5, u6, u1, u2, u3} S L D _inst_1 _inst_2 _inst_3 ι (fun (X : L) => _inst_6 X))) (CategoryTheory.Ran.adjunction.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι (fun (X : L) => _inst_6 X)))
but is expected to have type
  forall {S : Type.{u4}} {L : Type.{u5}} (D : Type.{u6}) [_inst_1 : CategoryTheory.Category.{u1, u4} S] [_inst_2 : CategoryTheory.Category.{u2, u5} L] [_inst_3 : CategoryTheory.Category.{u3, u6} D] (ι : CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) [_inst_4 : CategoryTheory.Full.{u1, u2, u4, u5} S _inst_1 L _inst_2 ι] [_inst_5 : CategoryTheory.Faithful.{u1, u2, u4, u5} S _inst_1 L _inst_2 ι] [_inst_6 : forall (X : L), CategoryTheory.Limits.HasLimitsOfShape.{max u1 u2, max u4 u2, u3, u6} (CategoryTheory.StructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 X ι) (CategoryTheory.instCategoryStructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 X ι) D _inst_3], CategoryTheory.IsIso.{max (max (max u4 u6) u1) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{max u4 u3, max u4 u3, max (max (max u4 u6) u1) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u4 u3, max u4 u3, max (max (max u4 u6) u1) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.comp.{max u4 u3, max u5 u3, max u4 u3, max (max (max u4 u6) u1) u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.ran.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι (fun (X : L) => _inst_6 X)) (Prefunctor.obj.{max (succ u2) (succ u4), max (max (max (max (succ u6) (succ u3)) (succ u2)) (succ u5)) (succ u4), max (max (max u2 u5) u1) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.CategoryStruct.toQuiver.{max u2 u4, max (max (max u2 u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Category.toCategoryStruct.{max u2 u4, max (max (max u2 u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2))) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.CategoryStruct.toQuiver.{max (max (max (max u6 u3) u2) u5) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Category.toCategoryStruct.{max (max (max (max u6 u3) u2) u5) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)))) (CategoryTheory.Functor.toPrefunctor.{max u2 u4, max (max (max (max u6 u3) u2) u5) u4, max (max (max u2 u5) u1) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.whiskeringLeft.{u4, u1, u5, u2, u6, u3} S _inst_1 L _inst_2 D _inst_3)) ι)) (CategoryTheory.Functor.id.{max u4 u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Adjunction.counit.{max u5 u3, max u4 u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (Prefunctor.obj.{max (succ u2) (succ u4), max (max (max (max (succ u6) (succ u3)) (succ u2)) (succ u5)) (succ u4), max (max (max u2 u5) u1) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.CategoryStruct.toQuiver.{max u2 u4, max (max (max u2 u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Category.toCategoryStruct.{max u2 u4, max (max (max u2 u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2))) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.CategoryStruct.toQuiver.{max (max (max (max u6 u3) u2) u5) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Category.toCategoryStruct.{max (max (max (max u6 u3) u2) u5) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)))) (CategoryTheory.Functor.toPrefunctor.{max u2 u4, max (max (max (max u6 u3) u2) u5) u4, max (max (max u2 u5) u1) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.whiskeringLeft.{u4, u1, u5, u2, u6, u3} S _inst_1 L _inst_2 D _inst_3)) ι) (CategoryTheory.ran.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι (fun (X : L) => _inst_6 X)) (CategoryTheory.Ran.adjunction.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι (fun (X : L) => _inst_6 X)))
Case conversion may be inaccurate. Consider using '#align category_theory.Ran.reflective CategoryTheory.Ran.reflectiveₓ'. -/
theorem reflective [Full ι] [Faithful ι] [∀ X, HasLimitsOfShape (StructuredArrow X ι) D] :
    IsIso (adjunction D ι).counit :=
  by
  apply nat_iso.is_iso_of_is_iso_app _
  intro F
  apply nat_iso.is_iso_of_is_iso_app _
  intro X
  dsimp [adjunction]
  simp only [category.id_comp]
  exact
    is_iso.of_iso
      ((limit.is_limit _).conePointUniqueUpToIso
        (limit_of_diagram_initial structured_arrow.mk_id_initial _))
#align category_theory.Ran.reflective CategoryTheory.Ran.reflective

end Ran

namespace Lan

attribute [local simp] costructured_arrow.proj

#print CategoryTheory.Lan.diagram /-
/-- The diagram indexed by `Ran.index ι x` used to define `Ran`. -/
abbrev diagram (F : S ⥤ D) (x : L) : CostructuredArrow ι x ⥤ D :=
  CostructuredArrow.proj ι x ⋙ F
#align category_theory.Lan.diagram CategoryTheory.Lan.diagram
-/

variable {ι}

#print CategoryTheory.Lan.cocone /-
/-- A cocone over `Lan.diagram ι F x` used to define `Lan`. -/
@[simp]
def cocone {F : S ⥤ D} {G : L ⥤ D} (x : L) (f : F ⟶ ι ⋙ G) : Cocone (diagram ι F x)
    where
  pt := G.obj x
  ι :=
    { app := fun i => f.app i.left ≫ G.map i.Hom
      naturality' := by
        rintro ⟨ir, ⟨il⟩, i⟩ ⟨jl, ⟨jr⟩, j⟩ ⟨fl, ⟨⟨fl⟩⟩, ff⟩
        dsimp at *
        simp only [functor.comp_map, category.comp_id, nat_trans.naturality_assoc]
        rw [← G.map_comp, ff]
        tidy }
#align category_theory.Lan.cocone CategoryTheory.Lan.cocone
-/

variable (ι)

#print CategoryTheory.Lan.loc /-
/-- An auxiliary definition used to define `Lan`. -/
@[simps]
def loc (F : S ⥤ D) [I : ∀ x, HasColimit (diagram ι F x)] : L ⥤ D
    where
  obj x := colimit (diagram ι F x)
  map x y f := colimit.pre (diagram _ _ _) (CostructuredArrow.map f : CostructuredArrow ι _ ⥤ _)
  map_id' := by
    intro l
    ext j
    erw [colimit.ι_pre, category.comp_id]
    congr 1
    simp
  map_comp' := by
    intro x y z f g
    ext j
    let ff : costructured_arrow ι _ ⥤ _ := costructured_arrow.map f
    let gg : costructured_arrow ι _ ⥤ _ := costructured_arrow.map g
    let dd := diagram ι F z
    -- I don't know why lean can't deduce the following three instances...
    haveI : has_colimit (ff ⋙ gg ⋙ dd) := I _
    haveI : has_colimit ((ff ⋙ gg) ⋙ dd) := I _
    haveI : has_colimit (gg ⋙ dd) := I _
    change _ = colimit.ι ((ff ⋙ gg) ⋙ dd) j ≫ _ ≫ _
    erw [colimit.pre_pre dd gg ff, colimit.ι_pre, colimit.ι_pre]
    congr 1
    simp
#align category_theory.Lan.loc CategoryTheory.Lan.loc
-/

/- warning: category_theory.Lan.equiv -> CategoryTheory.Lan.equiv is a dubious translation:
lean 3 declaration is
  forall {S : Type.{u4}} {L : Type.{u5}} {D : Type.{u6}} [_inst_1 : CategoryTheory.Category.{u1, u4} S] [_inst_2 : CategoryTheory.Category.{u2, u5} L] [_inst_3 : CategoryTheory.Category.{u3, u6} D] (ι : CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (F : CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) [I : forall (x : L), CategoryTheory.Limits.HasColimit.{max u1 u2, max u4 u2, u3, u6} (CategoryTheory.CostructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 ι x) (CategoryTheory.CostructuredArrow.category.{u2, u5, u4, u1} S _inst_1 L _inst_2 ι x) D _inst_3 (CategoryTheory.Lan.diagram.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι F x)] (G : CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3), Equiv.{succ (max u5 u3), succ (max u4 u3)} (Quiver.Hom.{succ (max u5 u3), max u2 u3 u5 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.CategoryStruct.toQuiver.{max u5 u3, max u2 u3 u5 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Category.toCategoryStruct.{max u5 u3, max u2 u3 u5 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3))) (CategoryTheory.Lan.loc.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι F (CategoryTheory.Lan.equiv._proof_1.{u4, u5, u6, u1, u2, u3} S L D _inst_1 _inst_2 _inst_3 ι F I)) G) (Quiver.Hom.{succ (max u4 u3), max u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.CategoryStruct.toQuiver.{max u4 u3, max u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Category.toCategoryStruct.{max u4 u3, max u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3))) F (CategoryTheory.Functor.obj.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.obj.{max u4 u2, max (max u2 u3 u5 u6) u4 u3, max u1 u2 u4 u5, max (max u5 u3) (max u4 u3) (max u2 u3 u5 u6) u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.whiskeringLeft.{u4, u1, u5, u2, u6, u3} S _inst_1 L _inst_2 D _inst_3) ι) G))
but is expected to have type
  forall {S : Type.{u4}} {L : Type.{u5}} {D : Type.{u6}} [_inst_1 : CategoryTheory.Category.{u1, u4} S] [_inst_2 : CategoryTheory.Category.{u2, u5} L] [_inst_3 : CategoryTheory.Category.{u3, u6} D] (ι : CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (F : CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) [I : forall (x : L), CategoryTheory.Limits.HasColimit.{max u1 u2, max u4 u2, u3, u6} (CategoryTheory.CostructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 ι x) (CategoryTheory.instCategoryCostructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 ι x) D _inst_3 (CategoryTheory.Lan.diagram.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι F x)] (G : CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3), Equiv.{max (succ u5) (succ u3), max (succ u4) (succ u3)} (Quiver.Hom.{max (succ u5) (succ u3), max (max (max u6 u5) u3) u2} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.CategoryStruct.toQuiver.{max u5 u3, max (max (max u5 u6) u2) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Category.toCategoryStruct.{max u5 u3, max (max (max u5 u6) u2) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3))) (CategoryTheory.Lan.loc.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι F (fun (x : L) => I x)) G) (Quiver.Hom.{max (succ u4) (succ u3), max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.CategoryStruct.toQuiver.{max u4 u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Category.toCategoryStruct.{max u4 u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3))) F (Prefunctor.obj.{max (succ u5) (succ u3), max (succ u4) (succ u3), max (max (max u5 u2) u3) u6, max (max (max u4 u1) u3) u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.CategoryStruct.toQuiver.{max u5 u3, max (max (max u5 u2) u3) u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Category.toCategoryStruct.{max u5 u3, max (max (max u5 u2) u3) u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3))) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.CategoryStruct.toQuiver.{max u4 u3, max (max (max u4 u1) u3) u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Category.toCategoryStruct.{max u4 u3, max (max (max u4 u1) u3) u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3))) (CategoryTheory.Functor.toPrefunctor.{max u5 u3, max u4 u3, max (max (max u5 u2) u3) u6, max (max (max u4 u1) u3) u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (Prefunctor.obj.{max (succ u2) (succ u4), max (max (max (max (succ u3) (succ u6)) (succ u2)) (succ u5)) (succ u4), max (max (max u2 u5) u1) u4, max (max (max (max (max u3 u6) u2) u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.CategoryStruct.toQuiver.{max u2 u4, max (max (max u2 u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Category.toCategoryStruct.{max u2 u4, max (max (max u2 u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2))) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.CategoryStruct.toQuiver.{max (max (max (max u3 u6) u2) u5) u4, max (max (max (max (max u3 u6) u2) u5) u1) u4} (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Category.toCategoryStruct.{max (max (max (max u3 u6) u2) u5) u4, max (max (max (max (max u3 u6) u2) u5) u1) u4} (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)))) (CategoryTheory.Functor.toPrefunctor.{max u2 u4, max (max (max (max u3 u6) u2) u5) u4, max (max (max u2 u5) u1) u4, max (max (max (max (max u3 u6) u2) u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.whiskeringLeft.{u4, u1, u5, u2, u6, u3} S _inst_1 L _inst_2 D _inst_3)) ι)) G))
Case conversion may be inaccurate. Consider using '#align category_theory.Lan.equiv CategoryTheory.Lan.equivₓ'. -/
/-- An auxiliary definition used to define `Lan` and `Lan.adjunction`. -/
@[simps]
def equiv (F : S ⥤ D) [I : ∀ x, HasColimit (diagram ι F x)] (G : L ⥤ D) :
    (loc ι F ⟶ G) ≃ (F ⟶ ((whiskeringLeft _ _ _).obj ι).obj G)
    where
  toFun f :=
    { app := fun x => by
        apply colimit.ι (diagram ι F (ι.obj x)) (costructured_arrow.mk (𝟙 _)) ≫ f.app _
      -- sigh
      naturality' := by
        intro x y ff
        dsimp only [whiskering_left]
        simp only [functor.comp_map, category.assoc]
        rw [← f.naturality (ι.map ff), ← category.assoc, ← category.assoc]
        let fff : costructured_arrow ι _ ⥤ _ := costructured_arrow.map (ι.map ff)
        -- same issue :-(
        haveI : has_colimit (fff ⋙ diagram ι F (ι.obj y)) := I _
        erw [colimit.ι_pre (diagram ι F (ι.obj y)) fff (costructured_arrow.mk (𝟙 _))]
        let xx : costructured_arrow ι (ι.obj y) := costructured_arrow.mk (ι.map ff)
        let yy : costructured_arrow ι (ι.obj y) := costructured_arrow.mk (𝟙 _)
        let fff : xx ⟶ yy :=
          costructured_arrow.hom_mk ff
            (by
              simp only [costructured_arrow.mk_hom_eq_self]
              erw [category.comp_id])
        erw [colimit.w (diagram ι F (ι.obj y)) fff]
        congr
        simp }
  invFun f :=
    { app := fun x => colimit.desc (diagram ι F x) (cocone _ f)
      naturality' := by
        intro x y ff
        ext j
        erw [colimit.pre_desc, ← category.assoc, colimit.ι_desc, colimit.ι_desc]
        tidy }
  left_inv := by
    intro x
    ext (k j)
    rw [colimit.ι_desc]
    dsimp only [cocone]
    rw [category.assoc, ← x.naturality j.hom, ← category.assoc]
    congr 1
    change colimit.ι _ _ ≫ colimit.pre (diagram ι F k) (costructured_arrow.map _) = _
    rw [colimit.ι_pre]
    congr
    rcases j with ⟨_, ⟨⟩, _⟩
    tidy
  right_inv := by tidy
#align category_theory.Lan.equiv CategoryTheory.Lan.equiv

end Lan

#print CategoryTheory.lan /-
/-- The left Kan extension of a functor. -/
@[simps]
def lan [∀ X, HasColimitsOfShape (CostructuredArrow ι X) D] : (S ⥤ D) ⥤ L ⥤ D :=
  Adjunction.leftAdjointOfEquiv (fun F G => Lan.equiv ι F G) (by tidy)
#align category_theory.Lan CategoryTheory.lan
-/

namespace Lan

variable (D)

/- warning: category_theory.Lan.adjunction -> CategoryTheory.Lan.adjunction is a dubious translation:
lean 3 declaration is
  forall {S : Type.{u4}} {L : Type.{u5}} (D : Type.{u6}) [_inst_1 : CategoryTheory.Category.{u1, u4} S] [_inst_2 : CategoryTheory.Category.{u2, u5} L] [_inst_3 : CategoryTheory.Category.{u3, u6} D] (ι : CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) [_inst_4 : forall (X : L), CategoryTheory.Limits.HasColimitsOfShape.{max u1 u2, max u4 u2, u3, u6} (CategoryTheory.CostructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 ι X) (CategoryTheory.CostructuredArrow.category.{u2, u5, u4, u1} S _inst_1 L _inst_2 ι X) D _inst_3], CategoryTheory.Adjunction.{max u4 u3, max u5 u3, max u1 u3 u4 u6, max u2 u3 u5 u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.lan.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι (CategoryTheory.Lan.adjunction._proof_1.{u4, u5, u6, u1, u2, u3} S L D _inst_1 _inst_2 _inst_3 ι _inst_4)) (CategoryTheory.Functor.obj.{max u4 u2, max (max u2 u3 u5 u6) u4 u3, max u1 u2 u4 u5, max (max u5 u3) (max u4 u3) (max u2 u3 u5 u6) u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.whiskeringLeft.{u4, u1, u5, u2, u6, u3} S _inst_1 L _inst_2 D _inst_3) ι)
but is expected to have type
  forall {S : Type.{u4}} {L : Type.{u5}} (D : Type.{u6}) [_inst_1 : CategoryTheory.Category.{u1, u4} S] [_inst_2 : CategoryTheory.Category.{u2, u5} L] [_inst_3 : CategoryTheory.Category.{u3, u6} D] (ι : CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) [_inst_4 : forall (X : L), CategoryTheory.Limits.HasColimitsOfShape.{max u1 u2, max u4 u2, u3, u6} (CategoryTheory.CostructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 ι X) (CategoryTheory.instCategoryCostructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 ι X) D _inst_3], CategoryTheory.Adjunction.{max u4 u3, max u5 u3, max (max (max u6 u4) u3) u1, max (max (max u6 u5) u3) u2} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.lan.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι (fun (X : L) => _inst_4 X)) (Prefunctor.obj.{max (succ u2) (succ u4), max (max (max (max (succ u6) (succ u3)) (succ u2)) (succ u5)) (succ u4), max (max (max u2 u5) u1) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.CategoryStruct.toQuiver.{max u2 u4, max (max (max u2 u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Category.toCategoryStruct.{max u2 u4, max (max (max u2 u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2))) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.CategoryStruct.toQuiver.{max (max (max (max u6 u3) u2) u5) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Category.toCategoryStruct.{max (max (max (max u6 u3) u2) u5) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)))) (CategoryTheory.Functor.toPrefunctor.{max u2 u4, max (max (max (max u6 u3) u2) u5) u4, max (max (max u2 u5) u1) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.whiskeringLeft.{u4, u1, u5, u2, u6, u3} S _inst_1 L _inst_2 D _inst_3)) ι)
Case conversion may be inaccurate. Consider using '#align category_theory.Lan.adjunction CategoryTheory.Lan.adjunctionₓ'. -/
/-- The adjunction associated to `Lan`. -/
def adjunction [∀ X, HasColimitsOfShape (CostructuredArrow ι X) D] :
    lan ι ⊣ (whiskeringLeft _ _ D).obj ι :=
  Adjunction.adjunctionOfEquivLeft _ _
#align category_theory.Lan.adjunction CategoryTheory.Lan.adjunction

/- warning: category_theory.Lan.coreflective -> CategoryTheory.Lan.coreflective is a dubious translation:
lean 3 declaration is
  forall {S : Type.{u4}} {L : Type.{u5}} (D : Type.{u6}) [_inst_1 : CategoryTheory.Category.{u1, u4} S] [_inst_2 : CategoryTheory.Category.{u2, u5} L] [_inst_3 : CategoryTheory.Category.{u3, u6} D] (ι : CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) [_inst_4 : CategoryTheory.Full.{u1, u2, u4, u5} S _inst_1 L _inst_2 ι] [_inst_5 : CategoryTheory.Faithful.{u1, u2, u4, u5} S _inst_1 L _inst_2 ι] [_inst_6 : forall (X : L), CategoryTheory.Limits.HasColimitsOfShape.{max u1 u2, max u4 u2, u3, u6} (CategoryTheory.CostructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 ι X) (CategoryTheory.CostructuredArrow.category.{u2, u5, u4, u1} S _inst_1 L _inst_2 ι X) D _inst_3], CategoryTheory.IsIso.{max (max u1 u3 u4 u6) u4 u3, max (max u4 u3) u1 u3 u4 u6} (CategoryTheory.Functor.{max u4 u3, max u4 u3, max u1 u3 u4 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u4 u3, max u4 u3, max u1 u3 u4 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.id.{max u4 u3, max u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.comp.{max u4 u3, max u5 u3, max u4 u3, max u1 u3 u4 u6, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.lan.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι (CategoryTheory.Lan.adjunction._proof_1.{u4, u5, u6, u1, u2, u3} S L D _inst_1 _inst_2 _inst_3 ι (fun (X : L) => _inst_6 X))) (CategoryTheory.Functor.obj.{max u4 u2, max (max u2 u3 u5 u6) u4 u3, max u1 u2 u4 u5, max (max u5 u3) (max u4 u3) (max u2 u3 u5 u6) u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.whiskeringLeft.{u4, u1, u5, u2, u6, u3} S _inst_1 L _inst_2 D _inst_3) ι)) (CategoryTheory.Adjunction.unit.{max u4 u3, max u5 u3, max u1 u3 u4 u6, max u2 u3 u5 u6} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.lan.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι (CategoryTheory.Lan.adjunction._proof_1.{u4, u5, u6, u1, u2, u3} S L D _inst_1 _inst_2 _inst_3 ι (fun (X : L) => _inst_6 X))) (CategoryTheory.Functor.obj.{max u4 u2, max (max u2 u3 u5 u6) u4 u3, max u1 u2 u4 u5, max (max u5 u3) (max u4 u3) (max u2 u3 u5 u6) u1 u3 u4 u6} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max u2 u3 u5 u6, max u1 u3 u4 u6} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.whiskeringLeft.{u4, u1, u5, u2, u6, u3} S _inst_1 L _inst_2 D _inst_3) ι) (CategoryTheory.Lan.adjunction.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι (fun (X : L) => _inst_6 X)))
but is expected to have type
  forall {S : Type.{u4}} {L : Type.{u5}} (D : Type.{u6}) [_inst_1 : CategoryTheory.Category.{u1, u4} S] [_inst_2 : CategoryTheory.Category.{u2, u5} L] [_inst_3 : CategoryTheory.Category.{u3, u6} D] (ι : CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) [_inst_4 : CategoryTheory.Full.{u1, u2, u4, u5} S _inst_1 L _inst_2 ι] [_inst_5 : CategoryTheory.Faithful.{u1, u2, u4, u5} S _inst_1 L _inst_2 ι] [_inst_6 : forall (X : L), CategoryTheory.Limits.HasColimitsOfShape.{max u1 u2, max u4 u2, u3, u6} (CategoryTheory.CostructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 ι X) (CategoryTheory.instCategoryCostructuredArrow.{u1, u2, u4, u5} S _inst_1 L _inst_2 ι X) D _inst_3], CategoryTheory.IsIso.{max (max (max u4 u6) u1) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{max u4 u3, max u4 u3, max (max (max u4 u6) u1) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u4 u3, max u4 u3, max (max (max u4 u6) u1) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.id.{max u4 u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.comp.{max u4 u3, max u5 u3, max u4 u3, max (max (max u4 u6) u1) u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.lan.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι (fun (X : L) => _inst_6 X)) (Prefunctor.obj.{max (succ u2) (succ u4), max (max (max (max (succ u6) (succ u3)) (succ u2)) (succ u5)) (succ u4), max (max (max u2 u5) u1) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.CategoryStruct.toQuiver.{max u2 u4, max (max (max u2 u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Category.toCategoryStruct.{max u2 u4, max (max (max u2 u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2))) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.CategoryStruct.toQuiver.{max (max (max (max u6 u3) u2) u5) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Category.toCategoryStruct.{max (max (max (max u6 u3) u2) u5) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)))) (CategoryTheory.Functor.toPrefunctor.{max u2 u4, max (max (max (max u6 u3) u2) u5) u4, max (max (max u2 u5) u1) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.whiskeringLeft.{u4, u1, u5, u2, u6, u3} S _inst_1 L _inst_2 D _inst_3)) ι)) (CategoryTheory.Adjunction.unit.{max u4 u3, max u5 u3, max (max (max u4 u6) u1) u3, max (max (max u5 u6) u2) u3} (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.lan.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι (fun (X : L) => _inst_6 X)) (Prefunctor.obj.{max (succ u2) (succ u4), max (max (max (max (succ u6) (succ u3)) (succ u2)) (succ u5)) (succ u4), max (max (max u2 u5) u1) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.CategoryStruct.toQuiver.{max u2 u4, max (max (max u2 u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Category.toCategoryStruct.{max u2 u4, max (max (max u2 u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2))) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.CategoryStruct.toQuiver.{max (max (max (max u6 u3) u2) u5) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Category.toCategoryStruct.{max (max (max (max u6 u3) u2) u5) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)))) (CategoryTheory.Functor.toPrefunctor.{max u2 u4, max (max (max (max u6 u3) u2) u5) u4, max (max (max u2 u5) u1) u4, max (max (max (max (max u6 u3) u2) u5) u1) u4} (CategoryTheory.Functor.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.category.{u1, u2, u4, u5} S _inst_1 L _inst_2) (CategoryTheory.Functor.{max u5 u3, max u4 u3, max (max (max u6 u5) u3) u2, max (max (max u6 u4) u3) u1} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.Functor.category.{max u5 u3, max u4 u3, max (max (max u5 u6) u2) u3, max (max (max u4 u6) u1) u3} (CategoryTheory.Functor.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.category.{u2, u3, u5, u6} L _inst_2 D _inst_3) (CategoryTheory.Functor.{u1, u3, u4, u6} S _inst_1 D _inst_3) (CategoryTheory.Functor.category.{u1, u3, u4, u6} S _inst_1 D _inst_3)) (CategoryTheory.whiskeringLeft.{u4, u1, u5, u2, u6, u3} S _inst_1 L _inst_2 D _inst_3)) ι) (CategoryTheory.Lan.adjunction.{u1, u2, u3, u4, u5, u6} S L D _inst_1 _inst_2 _inst_3 ι (fun (X : L) => _inst_6 X)))
Case conversion may be inaccurate. Consider using '#align category_theory.Lan.coreflective CategoryTheory.Lan.coreflectiveₓ'. -/
theorem coreflective [Full ι] [Faithful ι] [∀ X, HasColimitsOfShape (CostructuredArrow ι X) D] :
    IsIso (adjunction D ι).Unit :=
  by
  apply nat_iso.is_iso_of_is_iso_app _
  intro F
  apply nat_iso.is_iso_of_is_iso_app _
  intro X
  dsimp [adjunction]
  simp only [category.comp_id]
  exact
    is_iso.of_iso
      ((colimit.is_colimit _).coconePointUniqueUpToIso
          (colimit_of_diagram_terminal costructured_arrow.mk_id_terminal _)).symm
#align category_theory.Lan.coreflective CategoryTheory.Lan.coreflective

end Lan

end CategoryTheory


/-
Copyright (c) 2022 Joël Riou. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Joël Riou
-/

import algebraic_topology.simplicial_object
import category_theory.limits.shapes.finite_products

/-!

# Split simplicial objects

In this file, we introduce the notion of split simplicial object.
If `C` is a category that has finite coproducts, a splitting
`s : splitting X` of a simplical object `X` in `C` consists
of the datum of a sequence of objects `s.N : ℕ → C` (which
we shall refer to as "nondegenerate simplices") and a
sequence of morphisms `s.ι n : s.N n → X _[n]` that have
the property that a certain canonical map identifies `X _[n]`
with the coproduct of objects `s.N i` indexed by all possible
epimorphisms `[n] ⟶ [i]` in `simplex_category`. (We do not
assume that the morphisms `s.ι n` are monomorphisms: in the
most common categories, this would be a consequence of the
axioms.)

Simplicial objects equipped with a splitting form a category
`simplicial_object.split C`.

## References
* [Stacks: Splitting simplicial objects] https://stacks.math.columbia.edu/tag/017O

-/

noncomputable theory

open category_theory category_theory.category category_theory.limits
  opposite simplex_category
open_locale simplicial

universe u

variables {C : Type*} [category C]

namespace simplicial_object

namespace splitting

/-- The index set which appears in the definition of split simplicial objects. -/
def index_set (Δ : simplex_categoryᵒᵖ) :=
Σ (Δ' : simplex_categoryᵒᵖ), { α : Δ.unop ⟶ Δ'.unop // epi α }

namespace index_set

/-- The element in `splitting.index_set Δ` attached to an epimorphism `f : Δ ⟶ Δ'`. -/
@[simps]
def mk {Δ Δ' : simplex_category} (f : Δ ⟶ Δ') [epi f] : index_set (op Δ) :=
⟨op Δ', f, infer_instance⟩

variables {Δ' Δ : simplex_categoryᵒᵖ} (A : index_set Δ) (θ : Δ ⟶ Δ')

/-- The epimorphism in `simplex_category` associated to `A : splitting.index_set Δ` -/
def e := A.2.1

instance : epi A.e := A.2.2

lemma ext' : A = ⟨A.1, ⟨A.e, A.2.2⟩⟩ := by tidy

lemma ext (A₁ A₂ : index_set Δ) (h₁ : A₁.1 = A₂.1)
  (h₂ : A₁.e ≫ eq_to_hom (by rw h₁) = A₂.e) : A₁ = A₂ :=
begin
  rcases A₁ with ⟨Δ₁, ⟨α₁, hα₁⟩⟩,
  rcases A₂ with ⟨Δ₂, ⟨α₂, hα₂⟩⟩,
  simp only at h₁,
  subst h₁,
  simp only [eq_to_hom_refl, comp_id, index_set.e] at h₂,
  simp only [h₂],
end

instance : fintype (index_set Δ) :=
fintype.of_injective
  ((λ A, ⟨⟨A.1.unop.len, nat.lt_succ_iff.mpr
    (len_le_of_epi (infer_instance : epi A.e))⟩, A.e.to_order_hom⟩) :
    index_set Δ → (sigma (λ (k : fin (Δ.unop.len+1)), (fin (Δ.unop.len+1) → fin (k+1)))))
begin
  rintros ⟨Δ₁, α₁⟩ ⟨Δ₂, α₂⟩ h₁,
  induction Δ₁ using opposite.rec,
  induction Δ₂ using opposite.rec,
  simp only at h₁,
  have h₂ : Δ₁ = Δ₂ := by { ext1, simpa only [fin.mk_eq_mk] using h₁.1, },
  subst h₂,
  refine ext _ _ rfl _,
  ext : 2,
  exact eq_of_heq h₁.2,
end

variable (Δ)

/-- The distinguished element in `splitting.index_set Δ` which corresponds to the
identity of `Δ`. -/
def id : index_set Δ := ⟨Δ, ⟨𝟙 _, by apply_instance,⟩⟩

instance : inhabited (index_set Δ) := ⟨id Δ⟩

variable {Δ}

/-- The condition that an element `splitting.index_set Δ` is the distinguished
element `splitting.index_set.id Δ`. -/
@[simp]
def eq_id : Prop := A = id _

lemma eq_id_iff_eq : A.eq_id ↔ A.1 = Δ :=
begin
  split,
  { intro h,
    dsimp at h,
    rw h,
    refl, },
  { intro h,
    rcases A with ⟨Δ', ⟨f, hf⟩⟩,
    simp only at h,
    subst h,
    refine ext _ _ rfl _,
    { haveI := hf,
      simp only [eq_to_hom_refl, comp_id],
      exact eq_id_of_epi f, }, },
end

lemma eq_id_iff_len_eq : A.eq_id ↔ A.1.unop.len = Δ.unop.len :=
begin
  rw eq_id_iff_eq,
  split,
  { intro h,
    rw h, },
  { intro h,
    rw ← unop_inj_iff,
    ext,
    exact h, },
end

lemma eq_id_iff_len_le : A.eq_id ↔ Δ.unop.len ≤ A.1.unop.len :=
begin
  rw eq_id_iff_len_eq,
  split,
  { intro h,
    rw h, },
  { exact le_antisymm (len_le_of_epi (infer_instance : epi A.e)), },
end

lemma eq_id_iff_mono : A.eq_id ↔ mono A.e :=
begin
  split,
  { intro h,
    dsimp at h,
    subst h,
    dsimp only [id, e],
    apply_instance, },
  { intro h,
    rw eq_id_iff_len_le,
    exact len_le_of_mono h, }
end

/-- Given `A : index_set Δ₁`, if `p.unop : unop Δ₂ ⟶ unop Δ₁` is an epi, this
is the obvious element in `A : index_set Δ₂` associated to the composition
of epimorphisms `p.unop ≫ A.e`. -/
@[simps]
def epi_comp {Δ₁ Δ₂ : simplex_categoryᵒᵖ} (A : index_set Δ₁) (p : Δ₁ ⟶ Δ₂) [epi p.unop] :
  index_set Δ₂ := ⟨A.1, ⟨p.unop ≫ A.e, epi_comp _ _⟩⟩

/--
When `A : index_set Δ` and `θ : Δ → Δ'` is a morphism in `simplex_categoryᵒᵖ`,
an element in `index_set Δ'` can be defined by using the epi-mono factorisation
of `θ.unop ≫ A.e`. -/
def pull : index_set Δ' := mk (factor_thru_image (θ.unop ≫ A.e))

@[reassoc]
lemma fac_pull : (A.pull θ).e ≫ image.ι (θ.unop ≫ A.e) = θ.unop ≫ A.e := image.fac _

end index_set

variables (N : ℕ → C) (Δ : simplex_categoryᵒᵖ)
  (X : simplicial_object C) (φ : Π n, N n ⟶ X _[n])

/-- Given a sequences of objects `N : ℕ → C` in a category `C`, this is
a family of objects indexed by the elements `A : splitting.index_set Δ`.
The `Δ`-simplices of a split simplicial objects shall identify to the
coproduct of objects in such a family. -/
@[simp, nolint unused_arguments]
def summand (A : index_set Δ) : C := N A.1.unop.len

variable [has_finite_coproducts C]

/-- The coproduct of the family `summand N Δ` -/
@[simp]
def coprod := ∐ summand N Δ

variable {Δ}

/-- The inclusion of a summand in the coproduct. -/
@[simp]
def ι_coprod (A : index_set Δ) : N A.1.unop.len ⟶ coprod N Δ := sigma.ι _ A

variables {N}

/-- The canonical morphism `coprod N Δ ⟶ X.obj Δ` attached to a sequence
of objects `N` and a sequence of morphisms `N n ⟶ X _[n]`. -/
@[simp]
def map (Δ : simplex_categoryᵒᵖ) : coprod N Δ ⟶ X.obj Δ :=
sigma.desc (λ A, φ A.1.unop.len ≫ X.map A.e.op)

end splitting

variable [has_finite_coproducts C]

/-- A splitting of a simplicial object `X` consists of the datum of a sequence
of objects `N`, a sequence of morphisms `ι : N n ⟶ X _[n]` such that
for all `Δ : simplex_categoryhᵒᵖ`, the canonical map `splitting.map X ι Δ`
is an isomorphism. -/
@[nolint has_nonempty_instance]
structure splitting (X : simplicial_object C) :=
(N : ℕ → C)
(ι : Π n, N n ⟶ X _[n])
(map_is_iso' : ∀ (Δ : simplex_categoryᵒᵖ), is_iso (splitting.map X ι Δ))

namespace splitting

variables {X Y : simplicial_object C} (s : splitting X)

instance map_is_iso (Δ : simplex_categoryᵒᵖ) : is_iso (splitting.map X s.ι Δ) :=
s.map_is_iso' Δ

/-- The isomorphism on simplices given by the axiom `splitting.map_is_iso'` -/
@[simps]
def iso (Δ : simplex_categoryᵒᵖ) : coprod s.N Δ ≅ X.obj Δ :=
as_iso (splitting.map X s.ι Δ)

/-- Via the isomorphism `s.iso Δ`, this is the inclusion of a summand
in the direct sum decomposition given by the splitting `s : splitting X`. -/
def ι_summand {Δ : simplex_categoryᵒᵖ} (A : index_set Δ) :
  s.N A.1.unop.len ⟶ X.obj Δ :=
splitting.ι_coprod s.N A ≫ (s.iso Δ).hom

@[reassoc]
lemma ι_summand_eq {Δ : simplex_categoryᵒᵖ} (A : index_set Δ) :
  s.ι_summand A = s.ι A.1.unop.len ≫ X.map A.e.op :=
begin
  dsimp only [ι_summand, iso.hom],
  erw [colimit.ι_desc, cofan.mk_ι_app],
end

lemma ι_summand_id (n : ℕ) : s.ι_summand (index_set.id (op [n])) = s.ι n :=
by { erw [ι_summand_eq, X.map_id, comp_id], refl, }

/-- As it is stated in `splitting.hom_ext`, a morphism `f : X ⟶ Y` from a split
simplicial object to any simplicial object is determined by its restrictions
`s.φ f n : s.N n ⟶ Y _[n]` to the distinguished summands in each degree `n`. -/
@[simp]
def φ (f : X ⟶ Y) (n : ℕ) : s.N n ⟶ Y _[n] := s.ι n ≫ f.app (op [n])

@[simp, reassoc]
lemma ι_summand_comp_app (f : X ⟶ Y) {Δ : simplex_categoryᵒᵖ} (A : index_set Δ) :
  s.ι_summand A ≫ f.app Δ = s.φ f A.1.unop.len ≫ Y.map A.e.op :=
by simp only [ι_summand_eq_assoc, φ, nat_trans.naturality, assoc]

lemma hom_ext' {Z : C} {Δ : simplex_categoryᵒᵖ} (f g : X.obj Δ ⟶ Z)
  (h : ∀ (A : index_set Δ), s.ι_summand A ≫ f = s.ι_summand A ≫ g) :
    f = g :=
begin
  rw ← cancel_epi (s.iso Δ).hom,
  ext A,
  discrete_cases,
  simpa only [ι_summand_eq, iso_hom, colimit.ι_desc_assoc, cofan.mk_ι_app, assoc] using h A,
end

lemma hom_ext (f g : X ⟶ Y) (h : ∀ n : ℕ, s.φ f n = s.φ g n) : f = g :=
begin
  ext Δ,
  apply s.hom_ext',
  intro A,
  induction Δ using opposite.rec,
  induction Δ using simplex_category.rec with n,
  dsimp,
  simp only [s.ι_summand_comp_app, h],
end

/-- The map `X.obj Δ ⟶ Z` obtained by providing a family of morphisms on all the
terms of decomposition given by a splitting `s : splitting X`  -/
def desc {Z : C} (Δ : simplex_categoryᵒᵖ)
  (F : Π (A : index_set Δ), s.N A.1.unop.len ⟶ Z) : X.obj Δ ⟶ Z :=
(s.iso Δ).inv ≫ sigma.desc F

@[simp, reassoc]
lemma ι_desc {Z : C} (Δ : simplex_categoryᵒᵖ)
  (F : Π (A : index_set Δ), s.N A.1.unop.len ⟶ Z) (A : index_set Δ) :
  s.ι_summand A ≫ s.desc Δ F = F A :=
begin
  dsimp only [ι_summand, desc],
  simp only [assoc, iso.hom_inv_id_assoc, ι_coprod],
  erw [colimit.ι_desc, cofan.mk_ι_app],
end

/-- A simplicial object that is isomorphic to a split simplicial object is split. -/
@[simps]
def of_iso (e : X ≅ Y) : splitting Y :=
{ N := s.N,
  ι := λ n, s.ι n ≫ e.hom.app (op [n]),
  map_is_iso' := λ Δ, begin
    convert (infer_instance : is_iso ((s.iso Δ).hom ≫ e.hom.app Δ)),
    tidy,
  end, }

@[reassoc]
lemma ι_summand_epi_naturality {Δ₁ Δ₂ : simplex_categoryᵒᵖ} (A : index_set Δ₁)
  (p : Δ₁ ⟶ Δ₂) [epi p.unop] :
  s.ι_summand A ≫ X.map p = s.ι_summand (A.epi_comp p) :=
begin
  dsimp [ι_summand],
  erw [colimit.ι_desc, colimit.ι_desc, cofan.mk_ι_app, cofan.mk_ι_app],
  dsimp only [index_set.epi_comp, index_set.e],
  rw [op_comp, X.map_comp, assoc, quiver.hom.op_unop],
end

end splitting

variable (C)

/-- The category `simplicial_object.split C` is the category of simplicial objects
in `C` equipped with a splitting, and morphisms are morphisms of simplicial objects
which are compatible with the splittings. -/
@[ext, nolint has_nonempty_instance]
structure split := (X : simplicial_object C) (s : splitting X)

namespace split

variable {C}

/-- The object in `simplicial_object.split C` attached to a splitting `s : splitting X`
of a simplicial object `X`. -/
@[simps]
def mk' {X : simplicial_object C} (s : splitting X) : split C := ⟨X, s⟩

/-- Morphisms in `simplicial_object.split C` are morphisms of simplicial objects that
are compatible with the splittings. -/
@[nolint has_nonempty_instance]
structure hom (S₁ S₂ : split C) :=
(F : S₁.X ⟶ S₂.X)
(f : Π (n : ℕ), S₁.s.N n ⟶ S₂.s.N n)
(comm' : ∀ (n : ℕ), S₁.s.ι n ≫ F.app (op [n]) = f n ≫ S₂.s.ι n)

@[ext]
lemma hom.ext {S₁ S₂ : split C} (Φ₁ Φ₂ : hom S₁ S₂) (h : ∀ (n : ℕ), Φ₁.f n = Φ₂.f n) :
  Φ₁ = Φ₂ :=
begin
  rcases Φ₁ with ⟨F₁, f₁, c₁⟩,
  rcases Φ₂ with ⟨F₂, f₂, c₂⟩,
  have h' : f₁ = f₂ := by { ext, apply h, },
  subst h',
  simp only [eq_self_iff_true, and_true],
  apply S₁.s.hom_ext,
  intro n,
  dsimp,
  rw [c₁, c₂],
end

restate_axiom hom.comm'
attribute [simp, reassoc] hom.comm

end split

instance : category (split C) :=
{ hom      := split.hom,
  id       := λ S, { F := 𝟙 _, f := λ n, 𝟙 _, comm' := by tidy, },
  comp     := λ S₁ S₂ S₃ Φ₁₂ Φ₂₃,
    { F := Φ₁₂.F ≫ Φ₂₃.F, f := λ n, Φ₁₂.f n ≫ Φ₂₃.f n, comm' := by tidy, }, }

variable {C}

namespace split

lemma congr_F {S₁ S₂ : split C} {Φ₁ Φ₂ : S₁ ⟶ S₂} (h : Φ₁ = Φ₂) : Φ₁.F = Φ₂.F := by rw h
lemma congr_f {S₁ S₂ : split C} {Φ₁ Φ₂ : S₁ ⟶ S₂} (h : Φ₁ = Φ₂) (n : ℕ) :
  Φ₁.f n = Φ₂.f n := by rw h

@[simp]
lemma id_F (S : split C) : (𝟙 S : S ⟶ S).F = 𝟙 (S.X) := rfl

@[simp]
lemma id_f (S : split C) (n : ℕ) : (𝟙 S : S ⟶ S).f n = 𝟙 (S.s.N n) := rfl

@[simp]
lemma comp_F {S₁ S₂ S₃ : split C} (Φ₁₂ : S₁ ⟶ S₂) (Φ₂₃ : S₂ ⟶ S₃) :
  (Φ₁₂ ≫ Φ₂₃).F = Φ₁₂.F ≫ Φ₂₃.F := rfl

@[simp]
lemma comp_f {S₁ S₂ S₃ : split C} (Φ₁₂ : S₁ ⟶ S₂) (Φ₂₃ : S₂ ⟶ S₃) (n : ℕ) :
  (Φ₁₂ ≫ Φ₂₃).f n = Φ₁₂.f n ≫ Φ₂₃.f n := rfl

@[simp, reassoc]
lemma ι_summand_naturality_symm {S₁ S₂ : split C} (Φ : S₁ ⟶ S₂)
  {Δ : simplex_categoryᵒᵖ} (A : splitting.index_set Δ) :
  S₁.s.ι_summand A ≫ Φ.F.app Δ = Φ.f A.1.unop.len ≫ S₂.s.ι_summand A :=
by rw [S₁.s.ι_summand_eq, S₂.s.ι_summand_eq, assoc, Φ.F.naturality, ← Φ.comm_assoc]

variable (C)

/-- The functor `simplicial_object.split C ⥤ simplicial_object C` which forgets
the splitting. -/
@[simps]
def forget : split C ⥤ simplicial_object C :=
{ obj := λ S, S.X,
  map := λ S₁ S₂ Φ, Φ.F, }

/-- The functor `simplicial_object.split C ⥤ C` which sends a simplicial object equipped
with a splitting to its nondegenerate `n`-simplices. -/
@[simps]
def eval_N (n : ℕ) : split C ⥤ C :=
{ obj := λ S, S.s.N n,
  map := λ S₁ S₂ Φ, Φ.f n, }

/-- The inclusion of each summand in the coproduct decomposition of simplices
in split simplicial objects is a natural transformation of functors
`simplicial_object.split C ⥤ C` -/
@[simps]
def nat_trans_ι_summand {Δ : simplex_categoryᵒᵖ} (A : splitting.index_set Δ) :
  eval_N C A.1.unop.len ⟶ forget C ⋙ (evaluation simplex_categoryᵒᵖ C).obj Δ :=
{ app := λ S, S.s.ι_summand A,
  naturality' := λ S₁ S₂ Φ, (ι_summand_naturality_symm Φ A).symm, }

end split

end simplicial_object


import tactic

noncomputable theory

variables {R S T U : Type} [comm_ring R] [comm_ring S] [comm_ring T] [comm_ring U]

constant polynomial (R : Type) [comm_ring R] : Type

@[instance] constant polynomial.comm_ring : comm_ring (polynomial R)

namespace polynomial

constant C : R →+* polynomial R

constant X : polynomial R

constant eval₂ (f : R →+* S) (x : S) : polynomial R →+* S

@[simp] constant eval₂_X (f : R →+* S) (x : S) : eval₂ f x X = x

@[simp] constant eval₂_comp_C (f : R →+* S) (x : S) : (eval₂ f x).comp C = f

@[simp] constant eval₂_C (f : R →+* S) (x : S) (r : R) : eval₂ f x (C r) = f r

@[ext] constant hom_ext {f g : polynomial R →+* S} (h1 : f X = g X)
  (h2 : f.comp C = g.comp C) : f = g

example (f : polynomial R →+* S) : eval₂ (f.comp C) (f X) = f :=
by ext; simp

def map (f : R →+* S) : polynomial R →+* polynomial S :=
eval₂ (C.comp f) X

set_option trace.simplify.rewrite true

example (f : R →+* S) (g : S →+* T) (x : T) :
  (eval₂ g x).comp (map f) = eval₂ (g.comp f) x :=
begin
  unfold map,
  ext; simp only [ring_hom.coe_comp, function.comp_app, eval₂_X, eval₂_C, map],
end
-- hom_ext (by simp [map])
--   begin
--     ext,
--     simp [map]
--   end
--   begin
--     rw [map, eval₂_comp_C, ring_hom.comp_assoc, eval₂_comp_C,
--       ← ring_hom.comp_assoc, eval₂_comp_C],
--   end

example (f : R →+* S) (g : S →+* T) (h : U →+* polynomial R) (x : T) :
  ((eval₂ g x).comp (map f)).comp h = (eval₂ (g.comp f) x).comp h :=
begin
  ext; simp only [ring_hom.coe_comp, function.comp_app, eval₂_X, eval₂_C, map],
end

end polynomial