l3lab/ntp-mathlib huggingface dataset:
/-- `(P ⟶ P⁺)⁺ = P⁺ ⟶ P⁺⁺` -/
@[simp]
theorem plusMap_toPlus : J.plusMap (J.toPlus P) = J.toPlus (J.plusObj P) := by
  ext X : 2
  refine' colimit.hom_ext (fun S => _)
  dsimp only [plusMap, toPlus]
  let e : S.unop ⟶ ⊤ := homOfLE (OrderTop.le_top _)
  rw [ι_colimMap, ← colimit.w _ e.op, ← Category.assoc, ← Category.assoc]
  congr 1
  refine' Multiequalizer.hom_ext _ _ _ (fun I => _)
  erw [Multiequalizer.lift_ι]
  simp only [unop_op, op_unop, diagram_map, Category.assoc, limit.lift_π,
    Multifork.ofι_π_app]
  let ee : (J.pullback (I.map e).f).obj S.unop ⟶ ⊤ := homOfLE (OrderTop.le_top _)
  erw [← colimit.w _ ee.op, ι_colimMap_assoc, colimit.ι_pre, diagramPullback_app,
    ← Category.assoc, ← Category.assoc]
  

Proof state:
case w.h.e_a
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 : Cᵒᵖ
S : (Cover J X.unop)ᵒᵖ
e : S.unop ⟶ ⊤ := homOfLE (_ : S.unop ≤ ⊤)
I : (Cover.index S.unop (plusObj J P)).L
ee : (pullback J (Cover.Arrow.map I e).f).obj S.unop ⟶ ⊤ :=
  homOfLE (_ : (pullback J (Cover.Arrow.map I e).f).obj S.unop ≤ ⊤)
⊢ ((Multiequalizer.ι (Cover.index S.unop P) I ≫ Cover.toMultiequalizer ⊤ P) ≫ (diagram J P I.Y).map ee.op) ≫
      colimit.ι (diagram J P I.Y) (op ((pullback J (Cover.Arrow.map I e).f).obj S.unop)) =
    Multiequalizer.lift
        (Cover.index ((pullback J (Cover.Arrow.map I (homOfLE (_ : S.unop ≤ ⊤)).op.unop).f.op.unop).op.obj S).unop P)
        ((diagram J P X.unop).obj S) (fun I_1 => Multiequalizer.ι (Cover.index S.unop P) (Cover.Arrow.base I_1))
        (_ :
          ∀
            (I_1 :
              (Cover.index ((pullback J (Cover.Arrow.map I (homOfLE (_ : S.unop ≤ ⊤)).op.unop).f.op.unop).op.obj S).unop
                  P).R),
            Multiequalizer.ι (Cover.index S.unop P)
                  (MulticospanIndex.fstTo (Cover.index S.unop P) (Cover.Relation.base I_1)) ≫
                MulticospanIndex.fst (Cover.index S.unop P) (Cover.Relation.base I_1) =
              Multiequalizer.ι (Cover.index S.unop P)
                  (MulticospanIndex.sndTo (Cover.index S.unop P) (Cover.Relation.base I_1)) ≫
                MulticospanIndex.snd (Cover.index S.unop P) (Cover.Relation.base I_1)) ≫
      colimit.ι (diagram J P (op (Cover.Arrow.map I (homOfLE (_ : S.unop ≤ ⊤)).op.unop).Y).unop)
        ((pullback J (Cover.Arrow.map I (homOfLE (_ : S.unop ≤ ⊤)).op.unop).f.op.unop).op.obj S)

Next tactic:
congr 1
/-- `(P ⟶ P⁺)⁺ = P⁺ ⟶ P⁺⁺` -/
@[simp]
theorem plusMap_toPlus : J.plusMap (J.toPlus P) = J.toPlus (J.plusObj P) := by
  ext X : 2
  refine' colimit.hom_ext (fun S => _)
  dsimp only [plusMap, toPlus]
  let e : S.unop ⟶ ⊤ := homOfLE (OrderTop.le_top _)
  rw [ι_colimMap, ← colimit.w _ e.op, ← Category.assoc, ← Category.assoc]
  congr 1
  refine' Multiequalizer.hom_ext _ _ _ (fun I => _)
  erw [Multiequalizer.lift_ι]
  simp only [unop_op, op_unop, diagram_map, Category.assoc, limit.lift_π,
    Multifork.ofι_π_app]
  let ee : (J.pullback (I.map e).f).obj S.unop ⟶ ⊤ := homOfLE (OrderTop.le_top _)
  erw [← colimit.w _ ee.op, ι_colimMap_assoc, colimit.ι_pre, diagramPullback_app,
    ← Category.assoc, ← Category.assoc]
  congr 1
  

Proof state:
case w.h.e_a.e_a
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 : Cᵒᵖ
S : (Cover J X.unop)ᵒᵖ
e : S.unop ⟶ ⊤ := homOfLE (_ : S.unop ≤ ⊤)
I : (Cover.index S.unop (plusObj J P)).L
ee : (pullback J (Cover.Arrow.map I e).f).obj S.unop ⟶ ⊤ :=
  homOfLE (_ : (pullback J (Cover.Arrow.map I e).f).obj S.unop ≤ ⊤)
⊢ (Multiequalizer.ι (Cover.index S.unop P) I ≫ Cover.toMultiequalizer ⊤ P) ≫ (diagram J P I.Y).map ee.op =
    Multiequalizer.lift
      (Cover.index ((pullback J (Cover.Arrow.map I (homOfLE (_ : S.unop ≤ ⊤)).op.unop).f.op.unop).op.obj S).unop P)
      ((diagram J P X.unop).obj S) (fun I_1 => Multiequalizer.ι (Cover.index S.unop P) (Cover.Arrow.base I_1))
      (_ :
        ∀
          (I_1 :
            (Cover.index ((pullback J (Cover.Arrow.map I (homOfLE (_ : S.unop ≤ ⊤)).op.unop).f.op.unop).op.obj S).unop
                P).R),
          Multiequalizer.ι (Cover.index S.unop P)
                (MulticospanIndex.fstTo (Cover.index S.unop P) (Cover.Relation.base I_1)) ≫
              MulticospanIndex.fst (Cover.index S.unop P) (Cover.Relation.base I_1) =
            Multiequalizer.ι (Cover.index S.unop P)
                (MulticospanIndex.sndTo (Cover.index S.unop P) (Cover.Relation.base I_1)) ≫
              MulticospanIndex.snd (Cover.index S.unop P) (Cover.Relation.base I_1))

Next tactic:
refine' Multiequalizer.hom_ext _ _ _ (fun II => _)
/-- `(P ⟶ P⁺)⁺ = P⁺ ⟶ P⁺⁺` -/
@[simp]
theorem plusMap_toPlus : J.plusMap (J.toPlus P) = J.toPlus (J.plusObj P) := by
  ext X : 2
  refine' colimit.hom_ext (fun S => _)
  dsimp only [plusMap, toPlus]
  let e : S.unop ⟶ ⊤ := homOfLE (OrderTop.le_top _)
  rw [ι_colimMap, ← colimit.w _ e.op, ← Category.assoc, ← Category.assoc]
  congr 1
  refine' Multiequalizer.hom_ext _ _ _ (fun I => _)
  erw [Multiequalizer.lift_ι]
  simp only [unop_op, op_unop, diagram_map, Category.assoc, limit.lift_π,
    Multifork.ofι_π_app]
  let ee : (J.pullback (I.map e).f).obj S.unop ⟶ ⊤ := homOfLE (OrderTop.le_top _)
  erw [← colimit.w _ ee.op, ι_colimMap_assoc, colimit.ι_pre, diagramPullback_app,
    ← Category.assoc, ← Category.assoc]
  congr 1
  refine' Multiequalizer.hom_ext _ _ _ (fun II => _)
  

Proof state:
case w.h.e_a.e_a
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 : Cᵒᵖ
S : (Cover J X.unop)ᵒᵖ
e : S.unop ⟶ ⊤ := homOfLE (_ : S.unop ≤ ⊤)
I : (Cover.index S.unop (plusObj J P)).L
ee : (pullback J (Cover.Arrow.map I e).f).obj S.unop ⟶ ⊤ :=
  homOfLE (_ : (pullback J (Cover.Arrow.map I e).f).obj S.unop ≤ ⊤)
II : (Cover.index (op ((pullback J (Cover.Arrow.map I e).f).obj S.unop)).unop P).L
⊢ ((Multiequalizer.ι (Cover.index S.unop P) I ≫ Cover.toMultiequalizer ⊤ P) ≫ (diagram J P I.Y).map ee.op) ≫
      Multiequalizer.ι (Cover.index (op ((pullback J (Cover.Arrow.map I e).f).obj S.unop)).unop P) II =
    Multiequalizer.lift
        (Cover.index ((pullback J (Cover.Arrow.map I (homOfLE (_ : S.unop ≤ ⊤)).op.unop).f.op.unop).op.obj S).unop P)
        ((diagram J P X.unop).obj S) (fun I_1 => Multiequalizer.ι (Cover.index S.unop P) (Cover.Arrow.base I_1))
        (_ :
          ∀
            (I_1 :
              (Cover.index ((pullback J (Cover.Arrow.map I (homOfLE (_ : S.unop ≤ ⊤)).op.unop).f.op.unop).op.obj S).unop
                  P).R),
            Multiequalizer.ι (Cover.index S.unop P)
                  (MulticospanIndex.fstTo (Cover.index S.unop P) (Cover.Relation.base I_1)) ≫
                MulticospanIndex.fst (Cover.index S.unop P) (Cover.Relation.base I_1) =
              Multiequalizer.ι (Cover.index S.unop P)
                  (MulticospanIndex.sndTo (Cover.index S.unop P) (Cover.Relation.base I_1)) ≫
                MulticospanIndex.snd (Cover.index S.unop P) (Cover.Relation.base I_1)) ≫
      Multiequalizer.ι (Cover.index (op ((pullback J (Cover.Arrow.map I e).f).obj S.unop)).unop P) II

Next tactic:
convert (Multiequalizer.condition (S.unop.index P)
      ⟨_, _, _, II.f, 𝟙 _, I.f, II.f ≫ I.f, I.hf,
        Sieve.downward_closed _ I.hf _, by simp⟩) using 1
/-- `(P ⟶ P⁺)⁺ = P⁺ ⟶ P⁺⁺` -/
@[simp]
theorem plusMap_toPlus : J.plusMap (J.toPlus P) = J.toPlus (J.plusObj P) := by
  ext X : 2
  refine' colimit.hom_ext (fun S => _)
  dsimp only [plusMap, toPlus]
  let e : S.unop ⟶ ⊤ := homOfLE (OrderTop.le_top _)
  rw [ι_colimMap, ← colimit.w _ e.op, ← Category.assoc, ← Category.assoc]
  congr 1
  refine' Multiequalizer.hom_ext _ _ _ (fun I => _)
  erw [Multiequalizer.lift_ι]
  simp only [unop_op, op_unop, diagram_map, Category.assoc, limit.lift_π,
    Multifork.ofι_π_app]
  let ee : (J.pullback (I.map e).f).obj S.unop ⟶ ⊤ := homOfLE (OrderTop.le_top _)
  erw [← colimit.w _ ee.op, ι_colimMap_assoc, colimit.ι_pre, diagramPullback_app,
    ← Category.assoc, ← Category.assoc]
  congr 1
  refine' Multiequalizer.hom_ext _ _ _ (fun II => _)
  convert (Multiequalizer.condition (S.unop.index P)
      ⟨_, _, _, II.f, 𝟙 _, I.f, II.f ≫ I.f, I.hf,
        Sieve.downward_closed _ I.hf _, by 

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 : Cᵒᵖ
S : (Cover J X.unop)ᵒᵖ
e : S.unop ⟶ ⊤ := homOfLE (_ : S.unop ≤ ⊤)
I : (Cover.index S.unop (plusObj J P)).L
ee : (pullback J (Cover.Arrow.map I e).f).obj S.unop ⟶ ⊤ :=
  homOfLE (_ : (pullback J (Cover.Arrow.map I e).f).obj S.unop ≤ ⊤)
II : (Cover.index (op ((pullback J (Cover.Arrow.map I e).f).obj S.unop)).unop P).L
⊢ II.f ≫ I.f = 𝟙 II.Y ≫ II.f ≫ I.f

Next tactic:
simp
/-- `(P ⟶ P⁺)⁺ = P⁺ ⟶ P⁺⁺` -/
@[simp]
theorem plusMap_toPlus : J.plusMap (J.toPlus P) = J.toPlus (J.plusObj P) := by
  ext X : 2
  refine' colimit.hom_ext (fun S => _)
  dsimp only [plusMap, toPlus]
  let e : S.unop ⟶ ⊤ := homOfLE (OrderTop.le_top _)
  rw [ι_colimMap, ← colimit.w _ e.op, ← Category.assoc, ← Category.assoc]
  congr 1
  refine' Multiequalizer.hom_ext _ _ _ (fun I => _)
  erw [Multiequalizer.lift_ι]
  simp only [unop_op, op_unop, diagram_map, Category.assoc, limit.lift_π,
    Multifork.ofι_π_app]
  let ee : (J.pullback (I.map e).f).obj S.unop ⟶ ⊤ := homOfLE (OrderTop.le_top _)
  erw [← colimit.w _ ee.op, ι_colimMap_assoc, colimit.ι_pre, diagramPullback_app,
    ← Category.assoc, ← Category.assoc]
  congr 1
  refine' Multiequalizer.hom_ext _ _ _ (fun II => _)
  convert (Multiequalizer.condition (S.unop.index P)
      ⟨_, _, _, II.f, 𝟙 _, I.f, II.f ≫ I.f, I.hf,
        Sieve.downward_closed _ I.hf _, by simp⟩) using 1
  · 

Proof state:
case h.e'_2.h
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 : Cᵒᵖ
S : (Cover J X.unop)ᵒᵖ
e : S.unop ⟶ ⊤ := homOfLE (_ : S.unop ≤ ⊤)
I : (Cover.index S.unop (plusObj J P)).L
ee : (pullback J (Cover.Arrow.map I e).f).obj S.unop ⟶ ⊤ :=
  homOfLE (_ : (pullback J (Cover.Arrow.map I e).f).obj S.unop ≤ ⊤)
II : (Cover.index (op ((pullback J (Cover.Arrow.map I e).f).obj S.unop)).unop P).L
e_1✝ :
  ((diagram J P X.unop).obj S ⟶
      MulticospanIndex.left (Cover.index (op ((pullback J (Cover.Arrow.map I e).f).obj S.unop)).unop P) II) =
    (multiequalizer (Cover.index S.unop P) ⟶
      MulticospanIndex.right (Cover.index S.unop P)
        { Y₁ := I.Y, Y₂ := II.Y, Z := II.Y, g₁ := II.f, g₂ := 𝟙 II.Y, f₁ := I.f, f₂ := II.f ≫ I.f,
          h₁ := (_ : (Cover.sieve S.unop).arrows I.f), h₂ := (_ : (Cover.sieve S.unop).arrows (II.f ≫ I.f)),
          w := (_ : II.f ≫ I.f = 𝟙 II.Y ≫ II.f ≫ I.f) })
⊢ ((Multiequalizer.ι (Cover.index S.unop P) I ≫ Cover.toMultiequalizer ⊤ P) ≫ (diagram J P I.Y).map ee.op) ≫
      Multiequalizer.ι (Cover.index (op ((pullback J (Cover.Arrow.map I e).f).obj S.unop)).unop P) II =
    Multiequalizer.ι (Cover.index S.unop P)
        (MulticospanIndex.fstTo (Cover.index S.unop P)
          { Y₁ := I.Y, Y₂ := II.Y, Z := II.Y, g₁ := II.f, g₂ := 𝟙 II.Y, f₁ := I.f, f₂ := II.f ≫ I.f,
            h₁ := (_ : (Cover.sieve S.unop).arrows I.f), h₂ := (_ : (Cover.sieve S.unop).arrows (II.f ≫ I.f)),
            w := (_ : II.f ≫ I.f = 𝟙 II.Y ≫ II.f ≫ I.f) }) ≫
      MulticospanIndex.fst (Cover.index S.unop P)
        { Y₁ := I.Y, Y₂ := II.Y, Z := II.Y, g₁ := II.f, g₂ := 𝟙 II.Y, f₁ := I.f, f₂ := II.f ≫ I.f,
          h₁ := (_ : (Cover.sieve S.unop).arrows I.f), h₂ := (_ : (Cover.sieve S.unop).arrows (II.f ≫ I.f)),
          w := (_ : II.f ≫ I.f = 𝟙 II.Y ≫ II.f ≫ I.f) }

Next tactic:
dsimp [diagram]
/-- `(P ⟶ P⁺)⁺ = P⁺ ⟶ P⁺⁺` -/
@[simp]
theorem plusMap_toPlus : J.plusMap (J.toPlus P) = J.toPlus (J.plusObj P) := by
  ext X : 2
  refine' colimit.hom_ext (fun S => _)
  dsimp only [plusMap, toPlus]
  let e : S.unop ⟶ ⊤ := homOfLE (OrderTop.le_top _)
  rw [ι_colimMap, ← colimit.w _ e.op, ← Category.assoc, ← Category.assoc]
  congr 1
  refine' Multiequalizer.hom_ext _ _ _ (fun I => _)
  erw [Multiequalizer.lift_ι]
  simp only [unop_op, op_unop, diagram_map, Category.assoc, limit.lift_π,
    Multifork.ofι_π_app]
  let ee : (J.pullback (I.map e).f).obj S.unop ⟶ ⊤ := homOfLE (OrderTop.le_top _)
  erw [← colimit.w _ ee.op, ι_colimMap_assoc, colimit.ι_pre, diagramPullback_app,
    ← Category.assoc, ← Category.assoc]
  congr 1
  refine' Multiequalizer.hom_ext _ _ _ (fun II => _)
  convert (Multiequalizer.condition (S.unop.index P)
      ⟨_, _, _, II.f, 𝟙 _, I.f, II.f ≫ I.f, I.hf,
        Sieve.downward_closed _ I.hf _, by simp⟩) using 1
  · dsimp [diagram]
    cases I
    simp only [Category.assoc, limit.lift_π, Multifork.ofι_pt, Multifork.ofι_π_app,
      Cover.Arrow.map_Y, Cover.Arrow.map_f]
    rfl
  · erw [Multiequalizer.lift_ι]
    

Proof state:
case h.e'_3.h
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 : Cᵒᵖ
S : (Cover J X.unop)ᵒᵖ
e : S.unop ⟶ ⊤ := homOfLE (_ : S.unop ≤ ⊤)
I : (Cover.index S.unop (plusObj J P)).L
ee : (pullback J (Cover.Arrow.map I e).f).obj S.unop ⟶ ⊤ :=
  homOfLE (_ : (pullback J (Cover.Arrow.map I e).f).obj S.unop ≤ ⊤)
II : (Cover.index (op ((pullback J (Cover.Arrow.map I e).f).obj S.unop)).unop P).L
e_1✝ :
  ((diagram J P X.unop).obj S ⟶
      MulticospanIndex.left (Cover.index (op ((pullback J (Cover.Arrow.map I e).f).obj S.unop)).unop P) II) =
    (multiequalizer (Cover.index S.unop P) ⟶
      MulticospanIndex.right (Cover.index S.unop P)
        { Y₁ := I.Y, Y₂ := II.Y, Z := II.Y, g₁ := II.f, g₂ := 𝟙 II.Y, f₁ := I.f, f₂ := II.f ≫ I.f,
          h₁ := (_ : (Cover.sieve S.unop).arrows I.f), h₂ := (_ : (Cover.sieve S.unop).arrows (II.f ≫ I.f)),
          w := (_ : II.f ≫ I.f = 𝟙 II.Y ≫ II.f ≫ I.f) })
⊢ Multiequalizer.ι (Cover.index S.unop P) (Cover.Arrow.base II) =
    Multiequalizer.ι (Cover.index S.unop P)
        (MulticospanIndex.sndTo (Cover.index S.unop P)
          { Y₁ := I.Y, Y₂ := II.Y, Z := II.Y, g₁ := II.f, g₂ := 𝟙 II.Y, f₁ := I.f, f₂ := II.f ≫ I.f,
            h₁ := (_ : (Cover.sieve S.unop).arrows I.f), h₂ := (_ : (Cover.sieve S.unop).arrows (II.f ≫ I.f)),
            w := (_ : II.f ≫ I.f = 𝟙 II.Y ≫ II.f ≫ I.f) }) ≫
      MulticospanIndex.snd (Cover.index S.unop P)
        { Y₁ := I.Y, Y₂ := II.Y, Z := II.Y, g₁ := II.f, g₂ := 𝟙 II.Y, f₁ := I.f, f₂ := II.f ≫ I.f,
          h₁ := (_ : (Cover.sieve S.unop).arrows I.f), h₂ := (_ : (Cover.sieve S.unop).arrows (II.f ≫ I.f)),
          w := (_ : II.f ≫ I.f = 𝟙 II.Y ≫ II.f ≫ I.f) }

Next tactic:
dsimp [Cover.index]
theorem isIso_toPlus_of_isSheaf (hP : Presheaf.IsSheaf J P) : IsIso (J.toPlus P) := by
  

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
hP : Presheaf.IsSheaf J P
⊢ IsIso (toPlus J P)

Next tactic:
rw [Presheaf.isSheaf_iff_multiequalizer] at hP
theorem isIso_toPlus_of_isSheaf (hP : Presheaf.IsSheaf J P) : IsIso (J.toPlus P) := by
  rw [Presheaf.isSheaf_iff_multiequalizer] at hP
  

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
hP : ∀ (X : C) (S : Cover J X), IsIso (Cover.toMultiequalizer S P)
⊢ IsIso (toPlus J P)

Next tactic:
suffices : ∀ X, IsIso ((J.toPlus P).app X)
theorem isIso_toPlus_of_isSheaf (hP : Presheaf.IsSheaf J P) : IsIso (J.toPlus P) := by
  rw [Presheaf.isSheaf_iff_multiequalizer] at hP
  suffices : ∀ X, IsIso ((J.toPlus P).app X)
  · 

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
hP : ∀ (X : C) (S : Cover J X), IsIso (Cover.toMultiequalizer S P)
this : ∀ (X : Cᵒᵖ), IsIso ((toPlus J P).app X)
⊢ IsIso (toPlus J P)

Next tactic:
apply NatIso.isIso_of_isIso_app
theorem isIso_toPlus_of_isSheaf (hP : Presheaf.IsSheaf J P) : IsIso (J.toPlus P) := by
  rw [Presheaf.isSheaf_iff_multiequalizer] at hP
  suffices : ∀ X, IsIso ((J.toPlus P).app X)
  · apply NatIso.isIso_of_isIso_app
  

Proof state:
case this
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
hP : ∀ (X : C) (S : Cover J X), IsIso (Cover.toMultiequalizer S P)
⊢ ∀ (X : Cᵒᵖ), IsIso ((toPlus J P).app X)

Next tactic:
intro X
theorem isIso_toPlus_of_isSheaf (hP : Presheaf.IsSheaf J P) : IsIso (J.toPlus P) := by
  rw [Presheaf.isSheaf_iff_multiequalizer] at hP
  suffices : ∀ X, IsIso ((J.toPlus P).app X)
  · apply NatIso.isIso_of_isIso_app
  intro X
  

Proof state:
case this
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
hP : ∀ (X : C) (S : Cover J X), IsIso (Cover.toMultiequalizer S P)
X : Cᵒᵖ
⊢ IsIso ((toPlus J P).app X)

Next tactic:
suffices : IsIso (colimit.ι (J.diagram P X.unop) (op ⊤))
theorem isIso_toPlus_of_isSheaf (hP : Presheaf.IsSheaf J P) : IsIso (J.toPlus P) := by
  rw [Presheaf.isSheaf_iff_multiequalizer] at hP
  suffices : ∀ X, IsIso ((J.toPlus P).app X)
  · apply NatIso.isIso_of_isIso_app
  intro X
  suffices : IsIso (colimit.ι (J.diagram P X.unop) (op ⊤))
  · 

Proof state:
case this
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
hP : ∀ (X : C) (S : Cover J X), IsIso (Cover.toMultiequalizer S P)
X : Cᵒᵖ
this : IsIso (colimit.ι (diagram J P X.unop) (op ⊤))
⊢ IsIso ((toPlus J P).app X)

Next tactic:
apply IsIso.comp_isIso
theorem isIso_toPlus_of_isSheaf (hP : Presheaf.IsSheaf J P) : IsIso (J.toPlus P) := by
  rw [Presheaf.isSheaf_iff_multiequalizer] at hP
  suffices : ∀ X, IsIso ((J.toPlus P).app X)
  · apply NatIso.isIso_of_isIso_app
  intro X
  suffices : IsIso (colimit.ι (J.diagram P X.unop) (op ⊤))
  · apply IsIso.comp_isIso
  

Proof state:
case this
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
hP : ∀ (X : C) (S : Cover J X), IsIso (Cover.toMultiequalizer S P)
X : Cᵒᵖ
⊢ IsIso (colimit.ι (diagram J P X.unop) (op ⊤))

Next tactic:
suffices : ∀ (S T : (J.Cover X.unop)ᵒᵖ) (f : S ⟶ T), IsIso ((J.diagram P X.unop).map f)
theorem isIso_toPlus_of_isSheaf (hP : Presheaf.IsSheaf J P) : IsIso (J.toPlus P) := by
  rw [Presheaf.isSheaf_iff_multiequalizer] at hP
  suffices : ∀ X, IsIso ((J.toPlus P).app X)
  · apply NatIso.isIso_of_isIso_app
  intro X
  suffices : IsIso (colimit.ι (J.diagram P X.unop) (op ⊤))
  · apply IsIso.comp_isIso
  suffices : ∀ (S T : (J.Cover X.unop)ᵒᵖ) (f : S ⟶ T), IsIso ((J.diagram P X.unop).map f)
  · 

Proof state:
case this
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
hP : ∀ (X : C) (S : Cover J X), IsIso (Cover.toMultiequalizer S P)
X : Cᵒᵖ
this : ∀ (S T : (Cover J X.unop)ᵒᵖ) (f : S ⟶ T), IsIso ((diagram J P X.unop).map f)
⊢ IsIso (colimit.ι (diagram J P X.unop) (op ⊤))

Next tactic:
apply isIso_ι_of_isInitial (initialOpOfTerminal isTerminalTop)
theorem isIso_toPlus_of_isSheaf (hP : Presheaf.IsSheaf J P) : IsIso (J.toPlus P) := by
  rw [Presheaf.isSheaf_iff_multiequalizer] at hP
  suffices : ∀ X, IsIso ((J.toPlus P).app X)
  · apply NatIso.isIso_of_isIso_app
  intro X
  suffices : IsIso (colimit.ι (J.diagram P X.unop) (op ⊤))
  · apply IsIso.comp_isIso
  suffices : ∀ (S T : (J.Cover X.unop)ᵒᵖ) (f : S ⟶ T), IsIso ((J.diagram P X.unop).map f)
  · apply isIso_ι_of_isInitial (initialOpOfTerminal isTerminalTop)
  

Proof state:
case this
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
hP : ∀ (X : C) (S : Cover J X), IsIso (Cover.toMultiequalizer S P)
X : Cᵒᵖ
⊢ ∀ (S T : (Cover J X.unop)ᵒᵖ) (f : S ⟶ T), IsIso ((diagram J P X.unop).map f)

Next tactic:
intro S T e
theorem isIso_toPlus_of_isSheaf (hP : Presheaf.IsSheaf J P) : IsIso (J.toPlus P) := by
  rw [Presheaf.isSheaf_iff_multiequalizer] at hP
  suffices : ∀ X, IsIso ((J.toPlus P).app X)
  · apply NatIso.isIso_of_isIso_app
  intro X
  suffices : IsIso (colimit.ι (J.diagram P X.unop) (op ⊤))
  · apply IsIso.comp_isIso
  suffices : ∀ (S T : (J.Cover X.unop)ᵒᵖ) (f : S ⟶ T), IsIso ((J.diagram P X.unop).map f)
  · apply isIso_ι_of_isInitial (initialOpOfTerminal isTerminalTop)
  intro S T e
  

Proof state:
case this
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
hP : ∀ (X : C) (S : Cover J X), IsIso (Cover.toMultiequalizer S P)
X : Cᵒᵖ
S T : (Cover J X.unop)ᵒᵖ
e : S ⟶ T
⊢ IsIso ((diagram J P X.unop).map e)

Next tactic:
have : S.unop.toMultiequalizer P ≫ (J.diagram P X.unop).map e = T.unop.toMultiequalizer P :=
    Multiequalizer.hom_ext _ _ _ (fun II => by dsimp; simp)
theorem isIso_toPlus_of_isSheaf (hP : Presheaf.IsSheaf J P) : IsIso (J.toPlus P) := by
  rw [Presheaf.isSheaf_iff_multiequalizer] at hP
  suffices : ∀ X, IsIso ((J.toPlus P).app X)
  · apply NatIso.isIso_of_isIso_app
  intro X
  suffices : IsIso (colimit.ι (J.diagram P X.unop) (op ⊤))
  · apply IsIso.comp_isIso
  suffices : ∀ (S T : (J.Cover X.unop)ᵒᵖ) (f : S ⟶ T), IsIso ((J.diagram P X.unop).map f)
  · apply isIso_ι_of_isInitial (initialOpOfTerminal isTerminalTop)
  intro S T e
  have : S.unop.toMultiequalizer P ≫ (J.diagram P X.unop).map e = T.unop.toMultiequalizer P :=
    Multiequalizer.hom_ext _ _ _ (fun II => by 

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
hP : ∀ (X : C) (S : Cover J X), IsIso (Cover.toMultiequalizer S P)
X : Cᵒᵖ
S T : (Cover J X.unop)ᵒᵖ
e : S ⟶ T
II : (Cover.index T.unop P).L
⊢ (Cover.toMultiequalizer S.unop P ≫ (diagram J P X.unop).map e) ≫ Multiequalizer.ι (Cover.index T.unop P) II =
    Cover.toMultiequalizer T.unop P ≫ Multiequalizer.ι (Cover.index T.unop P) II

Next tactic:
dsimp