-- Mathlib/CategoryTheory/Sites/Sheaf.lean
theorem isSheaf_iff_isSheaf_of_type (P : Cᵒᵖ ⥤ Type w) :
    Presheaf.IsSheaf J P ↔ Presieve.IsSheaf J P

Proof state:
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
⊢ Presieve.IsSheaf J P → Presheaf.IsSheaf J P

Tactic:
intro hP X Y S hS z hz

Result:
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj (op X)) S.arrows
hz : z.Compatible
⊢ ∃! t, z.IsAmalgamation t

Proof state:
case mpr.refine_1
C : Type u₁
inst✝ : Category.{v₁, u₁} C
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj (op X)) S.arrows
hz : z.Compatible
x : unop (op X)
⊢ Presieve.FamilyOfElements.Compatible fun Z f hf => z f hf x

Tactic:
intro Y₁ Y₂ Z g₁ g₂ f₁ f₂ hf₁ hf₂ h

Result:
case mpr.refine_1
C : Type u₁
inst✝ : Category.{v₁, u₁} C
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj (op X)) S.arrows
hz : z.Compatible
x : unop (op X)
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ Y
f₂ : Y₂ ⟶ Y
hf₁ : S.arrows f₁
hf₂ : S.arrows f₂
h : g₁ ≫ f₁ = g₂ ≫ f₂
⊢ P.map g₁.op ((fun Z f hf => z f hf x) Y₁ f₁ hf₁) = P.map g₂.op ((fun Z f hf => z f hf x) Y₂ f₂ hf₂)

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
⊢ Presheaf.IsSheaf J P ↔ Presieve.IsSheaf J P

Tactic:
constructor

Result:
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
⊢ Presheaf.IsSheaf J P → Presieve.IsSheaf J P

case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
⊢ Presieve.IsSheaf J P → Presheaf.IsSheaf J P

Proof state:
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
⊢ Presheaf.IsSheaf J P → Presieve.IsSheaf J P

Tactic:
intro hP

Result:
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
hP : Presheaf.IsSheaf J P
⊢ Presieve.IsSheaf J P

Proof state:
case mpr.refine_2
C : Type u₁
inst✝ : Category.{v₁, u₁} C
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj (op X)) S.arrows
hz : z.Compatible
Z : C
f : Z ⟶ Y
hf : S.arrows f
⊢ ((P ⋙ coyoneda.obj (op X)).map f.op fun x => ⋯.amalgamate (fun Z f hf => z f hf x) ⋯) = z f hf

Tactic:
funext x

Result:
case mpr.refine_2.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj (op X)) S.arrows
hz : z.Compatible
Z : C
f : Z ⟶ Y
hf : S.arrows f
x : unop (op X)
⊢ (P ⋙ coyoneda.obj (op X)).map f.op (fun x => ⋯.amalgamate (fun Z f hf => z f hf x) ⋯) x = z f hf x

Proof state:
case mpr.refine_3.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj (op X)) S.arrows
hz : z.Compatible
y : (P ⋙ coyoneda.obj (op X)).obj (op Y)
hy : z.IsAmalgamation y
x : unop (op X)
⊢ ∀ ⦃Y_1 : C⦄ ⦃f : Y_1 ⟶ Y⦄, S.arrows f → P.map f.op (y x) = P.map f.op (⋯.amalgamate (fun Z f hf => z f hf x) ⋯)

Tactic:
intro Y' f hf

Result:
case mpr.refine_3.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj (op X)) S.arrows
hz : z.Compatible
y : (P ⋙ coyoneda.obj (op X)).obj (op Y)
hy : z.IsAmalgamation y
x : unop (op X)
Y' : C
f : Y' ⟶ Y
hf : S.arrows f
⊢ P.map f.op (y x) = P.map f.op (⋯.amalgamate (fun Z f hf => z f hf x) ⋯)