Theorem: CategoryTheory.isSheaf_iff_isSheaf_of_type
File: Mathlib/CategoryTheory/Sites/Sheaf.lean

tactic: constructor
state_before: C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
⊢ Presheaf.IsSheaf J P ↔ Presieve.IsSheaf J P
state_after: case mp
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
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
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
⊢ Presieve.IsSheaf J P → Presheaf.IsSheaf J P

tactic: intro hP
state_before: case mp
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
⊢ Presheaf.IsSheaf J P → Presieve.IsSheaf J P
state_after: case mp
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presheaf.IsSheaf J P
⊢ Presieve.IsSheaf J P

tactic: refine Presieve.isSheaf_iso J ?_ (hP PUnit)
state_before: case mp
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presheaf.IsSheaf J P
⊢ Presieve.IsSheaf J P
state_after: case mp
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presheaf.IsSheaf J P
⊢ P ⋙ coyoneda.obj { unop := PUnit.{w + 1} } ≅ P

tactic: exact isoWhiskerLeft _ Coyoneda.punitIso ≪≫ P.rightUnitor
state_before: case mp
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presheaf.IsSheaf J P
⊢ P ⋙ coyoneda.obj { unop := PUnit.{w + 1} } ≅ P
state_after: no goals

tactic: intro hP X Y S hS z hz
state_before: case mpr
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
⊢ Presieve.IsSheaf J P → Presheaf.IsSheaf J P
state_after: case mpr
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J.sieves Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj { unop := X }) S.arrows
hz : z.Compatible
⊢ ∃! t, z.IsAmalgamation t

tactic: refine ⟨fun x => (hP S hS).amalgamate (fun Z f hf => z f hf x) ?_, ?_, ?_⟩
state_before: case mpr
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J.sieves Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj { unop := X }) S.arrows
hz : z.Compatible
⊢ ∃! t, z.IsAmalgamation t
state_after: case mpr.refine_1
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J.sieves Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj { unop := X }) S.arrows
hz : z.Compatible
x : { unop := X }.unop
⊢ Presieve.FamilyOfElements.Compatible fun Z f hf => z f hf x

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

case mpr.refine_3
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J.sieves Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj { unop := X }) S.arrows
hz : z.Compatible
⊢ ∀ (y : (P ⋙ coyoneda.obj { unop := X }).obj { unop := Y }),
    (fun t => z.IsAmalgamation t) y → y = fun x => ⋯.amalgamate (fun Z f hf => z f hf x) ⋯

tactic: intro Y₁ Y₂ Z g₁ g₂ f₁ f₂ hf₁ hf₂ h
state_before: case mpr.refine_1
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J.sieves Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj { unop := X }) S.arrows
hz : z.Compatible
x : { unop := X }.unop
⊢ Presieve.FamilyOfElements.Compatible fun Z f hf => z f hf x
state_after: case mpr.refine_1
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J.sieves Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj { unop := X }) S.arrows
hz : z.Compatible
x : { unop := X }.unop
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₂)

tactic: exact congr_fun (hz g₁ g₂ hf₁ hf₂ h) x
state_before: case mpr.refine_1
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J.sieves Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj { unop := X }) S.arrows
hz : z.Compatible
x : { unop := X }.unop
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₂)
state_after: no goals

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

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

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

tactic: intro y hy
state_before: case mpr.refine_3
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J.sieves Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj { unop := X }) S.arrows
hz : z.Compatible
⊢ ∀ (y : (P ⋙ coyoneda.obj { unop := X }).obj { unop := Y }),
    (fun t => z.IsAmalgamation t) y → y = fun x => ⋯.amalgamate (fun Z f hf => z f hf x) ⋯
state_after: case mpr.refine_3
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J.sieves Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj { unop := X }) S.arrows
hz : z.Compatible
y : (P ⋙ coyoneda.obj { unop := X }).obj { unop := Y }
hy : z.IsAmalgamation y
⊢ y = fun x => ⋯.amalgamate (fun Z f hf => z f hf x) ⋯

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

tactic: apply (hP S hS).isSeparatedFor.ext
state_before: case mpr.refine_3.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J.sieves Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj { unop := X }) S.arrows
hz : z.Compatible
y : (P ⋙ coyoneda.obj { unop := X }).obj { unop := Y }
hy : z.IsAmalgamation y
x : { unop := X }.unop
⊢ y x = ⋯.amalgamate (fun Z f hf => z f hf x) ⋯
state_after: case mpr.refine_3.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J.sieves Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj { unop := X }) S.arrows
hz : z.Compatible
y : (P ⋙ coyoneda.obj { unop := X }).obj { unop := Y }
hy : z.IsAmalgamation y
x : { unop := X }.unop
⊢ ∀ ⦃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
state_before: case mpr.refine_3.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J.sieves Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj { unop := X }) S.arrows
hz : z.Compatible
y : (P ⋙ coyoneda.obj { unop := X }).obj { unop := Y }
hy : z.IsAmalgamation y
x : { unop := X }.unop
⊢ ∀ ⦃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) ⋯)
state_after: case mpr.refine_3.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J.sieves Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj { unop := X }) S.arrows
hz : z.Compatible
y : (P ⋙ coyoneda.obj { unop := X }).obj { unop := Y }
hy : z.IsAmalgamation y
x : { unop := X }.unop
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) ⋯)

tactic: rw [Presieve.IsSheafFor.valid_glue _ _ _ hf, ← hy _ hf]
state_before: case mpr.refine_3.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J.sieves Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj { unop := X }) S.arrows
hz : z.Compatible
y : (P ⋙ coyoneda.obj { unop := X }).obj { unop := Y }
hy : z.IsAmalgamation y
x : { unop := X }.unop
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) ⋯)
state_after: case mpr.refine_3.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J.sieves Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj { unop := X }) S.arrows
hz : z.Compatible
y : (P ⋙ coyoneda.obj { unop := X }).obj { unop := Y }
hy : z.IsAmalgamation y
x : { unop := X }.unop
Y' : C
f : Y' ⟶ Y
hf : S.arrows f
⊢ P.map f.op (y x) = (P ⋙ coyoneda.obj { unop := X }).map f.op y x

tactic: rfl
state_before: case mpr.refine_3.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ J.sieves Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj { unop := X }) S.arrows
hz : z.Compatible
y : (P ⋙ coyoneda.obj { unop := X }).obj { unop := Y }
hy : z.IsAmalgamation y
x : { unop := X }.unop
Y' : C
f : Y' ⟶ Y
hf : S.arrows f
⊢ P.map f.op (y x) = (P ⋙ coyoneda.obj { unop := X }).map f.op y x
state_after: no goals