/-- The plus construction, associating a presheaf to any presheaf.
See `plusFunctor` below for a functorial version. -/
def plusObj : Cᵒᵖ ⥤ D where
  obj X := colimit (J.diagram P X.unop)
  map f := colimMap (J.diagramPullback P f.unop) ≫ colimit.pre _ _
  map_id := by
    intro X
    refine' colimit.hom_ext (fun S => _)
    dsimp
    simp only [diagramPullback_app, colimit.ι_pre, ι_colimMap_assoc, Category.comp_id]
    let e := S.unop.pullbackId
    dsimp only [Functor.op, pullback_obj]
    erw [← colimit.w _ e.inv.op, ← Category.assoc]
    convert Category.id_comp (colimit.ι (diagram J P (unop X)) S)
    refine' Multiequalizer.hom_ext _ _ _ (fun I => _)
    dsimp
    simp only [Multiequalizer.lift_ι, Category.id_comp, Category.assoc]
    dsimp [Cover.Arrow.map, Cover.Arrow.base]
    cases I
    congr
    simp
  map_comp := by
    intro X Y Z f g
    refine' colimit.hom_ext (fun S => _)
    dsimp
    simp only [diagramPullback_app, colimit.ι_pre_assoc, colimit.ι_pre, ι_colimMap_assoc,
      Category.assoc]
    

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝² : Category.{max v u, w} D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : Cover J X), HasMultiequalizer (Cover.index S P)
P : Cᵒᵖ ⥤ D
inst✝ : ∀ (X : C), HasColimitsOfShape (Cover J X)ᵒᵖ D
X Y Z : Cᵒᵖ
f : X ⟶ Y
g : Y ⟶ Z
S : (Cover J X.unop)ᵒᵖ
⊢ Multiequalizer.lift (Cover.index ((pullback J (g.unop ≫ f.unop)).op.obj S).unop P) ((diagram J P X.unop).obj S)
        (fun I => Multiequalizer.ι (Cover.index S.unop P) (Cover.Arrow.base I))
        (_ :
          ∀ (I : (Cover.index ((pullback J (g.unop ≫ f.unop)).op.obj S).unop P).R),
            Multiequalizer.ι (Cover.index S.unop P)
                  (MulticospanIndex.fstTo (Cover.index S.unop P) (Cover.Relation.base I)) ≫
                MulticospanIndex.fst (Cover.index S.unop P) (Cover.Relation.base I) =
              Multiequalizer.ι (Cover.index S.unop P)
                  (MulticospanIndex.sndTo (Cover.index S.unop P) (Cover.Relation.base I)) ≫
                MulticospanIndex.snd (Cover.index S.unop P) (Cover.Relation.base I)) ≫
      colimit.ι (diagram J P Z.unop) ((pullback J (g.unop ≫ f.unop)).op.obj S) =
    Multiequalizer.lift (Cover.index ((pullback J f.unop).op.obj S).unop P) ((diagram J P X.unop).obj S)
        (fun I => Multiequalizer.ι (Cover.index S.unop P) (Cover.Arrow.base I))
        (_ :
          ∀ (I : (Cover.index ((pullback J f.unop).op.obj S).unop P).R),
            Multiequalizer.ι (Cover.index S.unop P)
                  (MulticospanIndex.fstTo (Cover.index S.unop P) (Cover.Relation.base I)) ≫
                MulticospanIndex.fst (Cover.index S.unop P) (Cover.Relation.base I) =
              Multiequalizer.ι (Cover.index S.unop P)
                  (MulticospanIndex.sndTo (Cover.index S.unop P) (Cover.Relation.base I)) ≫
                MulticospanIndex.snd (Cover.index S.unop P) (Cover.Relation.base I)) ≫
      Multiequalizer.lift (Cover.index ((pullback J g.unop).op.obj ((pullback J f.unop).op.obj S)).unop P)
          ((diagram J P Y.unop).obj ((pullback J f.unop).op.obj S))
          (fun I => Multiequalizer.ι (Cover.index ((pullback J f.unop).op.obj S).unop P) (Cover.Arrow.base I))
          (_ :
            ∀ (I : (Cover.index ((pullback J g.unop).op.obj ((pullback J f.unop).op.obj S)).unop P).R),
              Multiequalizer.ι (Cover.index ((pullback J f.unop).op.obj S).unop P)
                    (MulticospanIndex.fstTo (Cover.index ((pullback J f.unop).op.obj S).unop P)
                      (Cover.Relation.base I)) ≫
                  MulticospanIndex.fst (Cover.index ((pullback J f.unop).op.obj S).unop P) (Cover.Relation.base I) =
                Multiequalizer.ι (Cover.index ((pullback J f.unop).op.obj S).unop P)
                    (MulticospanIndex.sndTo (Cover.index ((pullback J f.unop).op.obj S).unop P)
                      (Cover.Relation.base I)) ≫
                  MulticospanIndex.snd (Cover.index ((pullback J f.unop).op.obj S).unop P) (Cover.Relation.base I)) ≫
        colimit.ι (diagram J P Z.unop) ((pullback J g.unop).op.obj ((pullback J f.unop).op.obj S))

Next tactic:
let e := S.unop.pullbackComp g.unop f.unop