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

tactic: constructor
state_before: C : Type u₁
inst✝¹ : Category C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category A
P : Cᵒᵖ ⥤ Type w
⊢ Presheaf.IsSheaf J P ↔ Presieve.IsSheaf J P

tactic: intro hP
state_before: case mp
C : Type u₁
inst✝¹ : Category C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category A
P : Cᵒᵖ ⥤ Type w
⊢ 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 C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category A
P : Cᵒᵖ ⥤ Type w
hP : Presheaf.IsSheaf J P
⊢ Presieve.IsSheaf J P

tactic: refine' isoWhiskerLeft _ Coyoneda.punitIso ≪≫ P.rightUnitor
state_before: case mp
C : Type u₁
inst✝¹ : Category C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category A
P : Cᵒᵖ ⥤ Type w
hP : Presheaf.IsSheaf J P
⊢ P ⋙ coyoneda.obj PUnit.op ≅ P

tactic: intro hP X Y S hS z hz
state_before: case mpr
C : Type u₁
inst✝¹ : Category C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category A
P : Cᵒᵖ ⥤ Type w
⊢ Presieve.IsSheaf J P → Presheaf.IsSheaf J P

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 C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ GrothendieckTopology.sieves J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj X.op) S.arrows
hz : Presieve.FamilyOfElements.Compatible z
⊢ ∃! t, Presieve.FamilyOfElements.IsAmalgamation z t

tactic: intro Y₁ Y₂ Z g₁ g₂ f₁ f₂ hf₁ hf₂ h
state_before: case mpr.refine'_1
C : Type u₁
inst✝¹ : Category C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ GrothendieckTopology.sieves J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj X.op) S.arrows
hz : Presieve.FamilyOfElements.Compatible z
x : X.op.unop
⊢ Presieve.FamilyOfElements.Compatible fun Z f hf => z f hf x

tactic: exact congr_fun (hz g₁ g₂ hf₁ hf₂ h) x
state_before: case mpr.refine'_1
C : Type u₁
inst✝¹ : Category C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ GrothendieckTopology.sieves J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj X.op) S.arrows
hz : Presieve.FamilyOfElements.Compatible z
x : X.op.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: intro Z f hf
state_before: case mpr.refine'_2
C : Type u₁
inst✝¹ : Category C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ GrothendieckTopology.sieves J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj X.op) S.arrows
hz : Presieve.FamilyOfElements.Compatible z
⊢ (fun t => Presieve.FamilyOfElements.IsAmalgamation z t) fun x =>
    Presieve.IsSheafFor.amalgamate (_ : Presieve.IsSheafFor P S.arrows) (fun Z f hf => z f hf 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₂),
          g₁ ≫ f₁ = g₂ ≫ f₂ →
            (P ⋙ coyoneda.obj X.op).map g₁.op (z f₁ hf₁) x = (P ⋙ coyoneda.obj X.op).map g₂.op (z f₂ hf₂) x)

tactic: funext x
state_before: case mpr.refine'_2
C : Type u₁
inst✝¹ : Category C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ GrothendieckTopology.sieves J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj X.op) S.arrows
hz : Presieve.FamilyOfElements.Compatible z
Z : C
f : Z ⟶ Y
hf : S.arrows f
⊢ ((P ⋙ coyoneda.obj X.op).map f.op fun x =>
      Presieve.IsSheafFor.amalgamate (_ : Presieve.IsSheafFor P S.arrows) (fun Z f hf => z f hf 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₂),
            g₁ ≫ f₁ = g₂ ≫ f₂ →
              (P ⋙ coyoneda.obj X.op).map g₁.op (z f₁ hf₁) x = (P ⋙ coyoneda.obj X.op).map g₂.op (z f₂ hf₂) x)) =
    z f hf

tactic: apply Presieve.IsSheafFor.valid_glue
state_before: case mpr.refine'_2.h
C : Type u₁
inst✝¹ : Category C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ GrothendieckTopology.sieves J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj X.op) S.arrows
hz : Presieve.FamilyOfElements.Compatible z
Z : C
f : Z ⟶ Y
hf : S.arrows f
x : X.op.unop
⊢ (P ⋙ coyoneda.obj X.op).map f.op
      (fun x =>
        Presieve.IsSheafFor.amalgamate (_ : Presieve.IsSheafFor P S.arrows) (fun Z f hf => z f hf 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₂),
              g₁ ≫ f₁ = g₂ ≫ f₂ →
                (P ⋙ coyoneda.obj X.op).map g₁.op (z f₁ hf₁) x = (P ⋙ coyoneda.obj X.op).map g₂.op (z f₂ hf₂) x))
      x =
    z f hf x

tactic: intro y hy
state_before: case mpr.refine'_3
C : Type u₁
inst✝¹ : Category C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ GrothendieckTopology.sieves J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj X.op) S.arrows
hz : Presieve.FamilyOfElements.Compatible z
⊢ ∀ (y : (P ⋙ coyoneda.obj X.op).obj Y.op),
    (fun t => Presieve.FamilyOfElements.IsAmalgamation z t) y →
      y = fun x =>
        Presieve.IsSheafFor.amalgamate (_ : Presieve.IsSheafFor P S.arrows) (fun Z f hf => z f hf 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₂),
              g₁ ≫ f₁ = g₂ ≫ f₂ →
                (P ⋙ coyoneda.obj X.op).map g₁.op (z f₁ hf₁) x = (P ⋙ coyoneda.obj X.op).map g₂.op (z f₂ hf₂) x)

tactic: funext x
state_before: case mpr.refine'_3
C : Type u₁
inst✝¹ : Category C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ GrothendieckTopology.sieves J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj X.op) S.arrows
hz : Presieve.FamilyOfElements.Compatible z
y : (P ⋙ coyoneda.obj X.op).obj Y.op
hy : Presieve.FamilyOfElements.IsAmalgamation z y
⊢ y = fun x =>
    Presieve.IsSheafFor.amalgamate (_ : Presieve.IsSheafFor P S.arrows) (fun Z f hf => z f hf 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₂),
          g₁ ≫ f₁ = g₂ ≫ f₂ →
            (P ⋙ coyoneda.obj X.op).map g₁.op (z f₁ hf₁) x = (P ⋙ coyoneda.obj X.op).map g₂.op (z f₂ hf₂) x)

tactic: apply (hP S hS).isSeparatedFor.ext
state_before: case mpr.refine'_3.h
C : Type u₁
inst✝¹ : Category C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ GrothendieckTopology.sieves J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj X.op) S.arrows
hz : Presieve.FamilyOfElements.Compatible z
y : (P ⋙ coyoneda.obj X.op).obj Y.op
hy : Presieve.FamilyOfElements.IsAmalgamation z y
x : X.op.unop
⊢ y x =
    Presieve.IsSheafFor.amalgamate (_ : Presieve.IsSheafFor P S.arrows) (fun Z f hf => z f hf 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₂),
          g₁ ≫ f₁ = g₂ ≫ f₂ →
            (P ⋙ coyoneda.obj X.op).map g₁.op (z f₁ hf₁) x = (P ⋙ coyoneda.obj X.op).map g₂.op (z f₂ hf₂) x)

tactic: intro Y' f hf
state_before: case mpr.refine'_3.h
C : Type u₁
inst✝¹ : Category C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ GrothendieckTopology.sieves J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj X.op) S.arrows
hz : Presieve.FamilyOfElements.Compatible z
y : (P ⋙ coyoneda.obj X.op).obj Y.op
hy : Presieve.FamilyOfElements.IsAmalgamation z y
x : X.op.unop
⊢ ∀ ⦃Y_1 : C⦄ ⦃f : Y_1 ⟶ Y⦄,
    S.arrows f →
      P.map f.op (y x) =
        P.map f.op
          (Presieve.IsSheafFor.amalgamate (_ : Presieve.IsSheafFor P S.arrows) (fun Z f hf => z f hf 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₂),
                g₁ ≫ f₁ = g₂ ≫ f₂ →
                  (P ⋙ coyoneda.obj X.op).map g₁.op (z f₁ hf₁) x = (P ⋙ coyoneda.obj X.op).map g₂.op (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 C
J : GrothendieckTopology C
A : Type u₂
inst✝ : Category A
P : Cᵒᵖ ⥤ Type w
hP : Presieve.IsSheaf J P
X : Type w
Y : C
S : Sieve Y
hS : S ∈ GrothendieckTopology.sieves J Y
z : Presieve.FamilyOfElements (P ⋙ coyoneda.obj X.op) S.arrows
hz : Presieve.FamilyOfElements.Compatible z
y : (P ⋙ coyoneda.obj X.op).obj Y.op
hy : Presieve.FamilyOfElements.IsAmalgamation z y
x : X.op.unop
Y' : C
f : Y' ⟶ Y
hf : S.arrows f
⊢ P.map f.op (y x) =
    P.map f.op
      (Presieve.IsSheafFor.amalgamate (_ : Presieve.IsSheafFor P S.arrows) (fun Z f hf => z f hf 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₂),
            g₁ ≫ f₁ = g₂ ≫ f₂ →
              (P ⋙ coyoneda.obj X.op).map g₁.op (z f₁ hf₁) x = (P ⋙ coyoneda.obj X.op).map g₂.op (z f₂ hf₂) x))

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