Theorem: CategoryTheory.Presheaf.isSheaf_iff_isSheaf'
File: Mathlib/CategoryTheory/Sites/Sheaf.lean

tactic: constructor
state_before: C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
⊢ IsSheaf J P' ↔ IsSheaf' J P'
state_after: case mp
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
⊢ IsSheaf J P' → IsSheaf' J P'

case mpr
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
⊢ IsSheaf' J P' → IsSheaf J P'

tactic: intro h U R hR
state_before: case mp
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
⊢ IsSheaf J P' → IsSheaf' J P'
state_after: case mp
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf J P'
U : C
R : Presieve U
hR : generate R ∈ J.sieves U
⊢ Nonempty (IsLimit (Fork.ofι (forkMap R P') ⋯))

tactic: refine ⟨?_⟩
state_before: case mp
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf J P'
U : C
R : Presieve U
hR : generate R ∈ J.sieves U
⊢ Nonempty (IsLimit (Fork.ofι (forkMap R P') ⋯))
state_after: case mp
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf J P'
U : C
R : Presieve U
hR : generate R ∈ J.sieves U
⊢ IsLimit (Fork.ofι (forkMap R P') ⋯)

tactic: apply coyonedaJointlyReflectsLimits
state_before: case mp
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf J P'
U : C
R : Presieve U
hR : generate R ∈ J.sieves U
⊢ IsLimit (Fork.ofι (forkMap R P') ⋯)
state_after: case mp.hc
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf J P'
U : C
R : Presieve U
hR : generate R ∈ J.sieves U
⊢ (X : A'ᵒᵖ) → IsLimit ((coyoneda.obj X).mapCone (Fork.ofι (forkMap R P') ⋯))

tactic: intro X
state_before: case mp.hc
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf J P'
U : C
R : Presieve U
hR : generate R ∈ J.sieves U
⊢ (X : A'ᵒᵖ) → IsLimit ((coyoneda.obj X).mapCone (Fork.ofι (forkMap R P') ⋯))
state_after: case mp.hc
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf J P'
U : C
R : Presieve U
hR : generate R ∈ J.sieves U
X : A'ᵒᵖ
⊢ IsLimit ((coyoneda.obj X).mapCone (Fork.ofι (forkMap R P') ⋯))

tactic: have q : Presieve.IsSheafFor (P' ⋙ coyoneda.obj X) _ := h X.unop _ hR
state_before: case mp.hc
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf J P'
U : C
R : Presieve U
hR : generate R ∈ J.sieves U
X : A'ᵒᵖ
⊢ IsLimit ((coyoneda.obj X).mapCone (Fork.ofι (forkMap R P') ⋯))
state_after: case mp.hc
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf J P'
U : C
R : Presieve U
hR : generate R ∈ J.sieves U
X : A'ᵒᵖ
q : Presieve.IsSheafFor (P' ⋙ coyoneda.obj X) (generate R).arrows
⊢ IsLimit ((coyoneda.obj X).mapCone (Fork.ofι (forkMap R P') ⋯))

tactic: rw [← Presieve.isSheafFor_iff_generate] at q
state_before: case mp.hc
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf J P'
U : C
R : Presieve U
hR : generate R ∈ J.sieves U
X : A'ᵒᵖ
q : Presieve.IsSheafFor (P' ⋙ coyoneda.obj X) (generate R).arrows
⊢ IsLimit ((coyoneda.obj X).mapCone (Fork.ofι (forkMap R P') ⋯))
state_after: case mp.hc
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf J P'
U : C
R : Presieve U
hR : generate R ∈ J.sieves U
X : A'ᵒᵖ
q : Presieve.IsSheafFor (P' ⋙ coyoneda.obj X) R
⊢ IsLimit ((coyoneda.obj X).mapCone (Fork.ofι (forkMap R P') ⋯))

tactic: rw [Equalizer.Presieve.sheaf_condition] at q
state_before: case mp.hc
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf J P'
U : C
R : Presieve U
hR : generate R ∈ J.sieves U
X : A'ᵒᵖ
q : Presieve.IsSheafFor (P' ⋙ coyoneda.obj X) R
⊢ IsLimit ((coyoneda.obj X).mapCone (Fork.ofι (forkMap R P') ⋯))
state_after: case mp.hc
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf J P'
U : C
R : Presieve U
hR : generate R ∈ J.sieves U
X : A'ᵒᵖ
q : Nonempty (IsLimit (Fork.ofι (Equalizer.forkMap (P' ⋙ coyoneda.obj X) R) ⋯))
⊢ IsLimit ((coyoneda.obj X).mapCone (Fork.ofι (forkMap R P') ⋯))

tactic: replace q := Classical.choice q
state_before: case mp.hc
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf J P'
U : C
R : Presieve U
hR : generate R ∈ J.sieves U
X : A'ᵒᵖ
q : Nonempty (IsLimit (Fork.ofι (Equalizer.forkMap (P' ⋙ coyoneda.obj X) R) ⋯))
⊢ IsLimit ((coyoneda.obj X).mapCone (Fork.ofι (forkMap R P') ⋯))
state_after: case mp.hc
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf J P'
U : C
R : Presieve U
hR : generate R ∈ J.sieves U
X : A'ᵒᵖ
q : IsLimit (Fork.ofι (Equalizer.forkMap (P' ⋙ coyoneda.obj X) R) ⋯)
⊢ IsLimit ((coyoneda.obj X).mapCone (Fork.ofι (forkMap R P') ⋯))

tactic: apply (isSheafForIsSheafFor' _ _ _ _).symm q
state_before: case mp.hc
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf J P'
U : C
R : Presieve U
hR : generate R ∈ J.sieves U
X : A'ᵒᵖ
q : IsLimit (Fork.ofι (Equalizer.forkMap (P' ⋙ coyoneda.obj X) R) ⋯)
⊢ IsLimit ((coyoneda.obj X).mapCone (Fork.ofι (forkMap R P') ⋯))
state_after: no goals

tactic: intro h U X S hS
state_before: case mpr
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
⊢ IsSheaf' J P' → IsSheaf J P'
state_after: case mpr
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf' J P'
U : A'
X : C
S : Sieve X
hS : S ∈ J.sieves X
⊢ Presieve.IsSheafFor (P' ⋙ coyoneda.obj { unop := U }) S.arrows

tactic: rw [Equalizer.Presieve.sheaf_condition]
state_before: case mpr
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf' J P'
U : A'
X : C
S : Sieve X
hS : S ∈ J.sieves X
⊢ Presieve.IsSheafFor (P' ⋙ coyoneda.obj { unop := U }) S.arrows
state_after: case mpr
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf' J P'
U : A'
X : C
S : Sieve X
hS : S ∈ J.sieves X
⊢ Nonempty (IsLimit (Fork.ofι (Equalizer.forkMap (P' ⋙ coyoneda.obj { unop := U }) S.arrows) ⋯))

tactic: refine ⟨?_⟩
state_before: case mpr
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf' J P'
U : A'
X : C
S : Sieve X
hS : S ∈ J.sieves X
⊢ Nonempty (IsLimit (Fork.ofι (Equalizer.forkMap (P' ⋙ coyoneda.obj { unop := U }) S.arrows) ⋯))
state_after: case mpr
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf' J P'
U : A'
X : C
S : Sieve X
hS : S ∈ J.sieves X
⊢ IsLimit (Fork.ofι (Equalizer.forkMap (P' ⋙ coyoneda.obj { unop := U }) S.arrows) ⋯)

tactic: refine isSheafForIsSheafFor' _ _ _ _ ?_
state_before: case mpr
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf' J P'
U : A'
X : C
S : Sieve X
hS : S ∈ J.sieves X
⊢ IsLimit (Fork.ofι (Equalizer.forkMap (P' ⋙ coyoneda.obj { unop := U }) S.arrows) ⋯)
state_after: case mpr
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf' J P'
U : A'
X : C
S : Sieve X
hS : S ∈ J.sieves X
⊢ IsLimit ((coyoneda.obj { unop := U }).mapCone (Fork.ofι (forkMap S.arrows P') ⋯))

tactic: letI := preservesSmallestLimitsOfPreservesLimits (coyoneda.obj (op U))
state_before: case mpr
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf' J P'
U : A'
X : C
S : Sieve X
hS : S ∈ J.sieves X
⊢ IsLimit ((coyoneda.obj { unop := U }).mapCone (Fork.ofι (forkMap S.arrows P') ⋯))
state_after: case mpr
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf' J P'
U : A'
X : C
S : Sieve X
hS : S ∈ J.sieves X
this : PreservesLimitsOfSize.{0, 0, max u₁ v₁, max u₁ v₁, u₂, (max u₁ v₁) + 1} (coyoneda.obj { unop := U }) :=
  preservesSmallestLimitsOfPreservesLimits (coyoneda.obj { unop := U })
⊢ IsLimit ((coyoneda.obj { unop := U }).mapCone (Fork.ofι (forkMap S.arrows P') ⋯))

tactic: apply isLimitOfPreserves
state_before: case mpr
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf' J P'
U : A'
X : C
S : Sieve X
hS : S ∈ J.sieves X
this : PreservesLimitsOfSize.{0, 0, max u₁ v₁, max u₁ v₁, u₂, (max u₁ v₁) + 1} (coyoneda.obj { unop := U }) :=
  preservesSmallestLimitsOfPreservesLimits (coyoneda.obj { unop := U })
⊢ IsLimit ((coyoneda.obj { unop := U }).mapCone (Fork.ofι (forkMap S.arrows P') ⋯))
state_after: case mpr.t
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf' J P'
U : A'
X : C
S : Sieve X
hS : S ∈ J.sieves X
this : PreservesLimitsOfSize.{0, 0, max u₁ v₁, max u₁ v₁, u₂, (max u₁ v₁) + 1} (coyoneda.obj { unop := U }) :=
  preservesSmallestLimitsOfPreservesLimits (coyoneda.obj { unop := U })
⊢ IsLimit (Fork.ofι (forkMap S.arrows P') ⋯)

tactic: apply Classical.choice (h _ S.arrows _)
state_before: case mpr.t
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf' J P'
U : A'
X : C
S : Sieve X
hS : S ∈ J.sieves X
this : PreservesLimitsOfSize.{0, 0, max u₁ v₁, max u₁ v₁, u₂, (max u₁ v₁) + 1} (coyoneda.obj { unop := U }) :=
  preservesSmallestLimitsOfPreservesLimits (coyoneda.obj { unop := U })
⊢ IsLimit (Fork.ofι (forkMap S.arrows P') ⋯)
state_after: C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf' J P'
U : A'
X : C
S : Sieve X
hS : S ∈ J.sieves X
this : PreservesLimitsOfSize.{0, 0, max u₁ v₁, max u₁ v₁, u₂, (max u₁ v₁) + 1} (coyoneda.obj { unop := U }) :=
  preservesSmallestLimitsOfPreservesLimits (coyoneda.obj { unop := U })
⊢ generate S.arrows ∈ J.sieves X

tactic: simpa
state_before: C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁵ : Category.{v₂, u₂} A
A' : Type u₂
inst✝⁴ : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U✝ : C
R : Presieve U✝
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝² : HasProducts A
inst✝¹ : HasProducts A'
inst✝ : HasPullbacks C
h : IsSheaf' J P'
U : A'
X : C
S : Sieve X
hS : S ∈ J.sieves X
this : PreservesLimitsOfSize.{0, 0, max u₁ v₁, max u₁ v₁, u₂, (max u₁ v₁) + 1} (coyoneda.obj { unop := U }) :=
  preservesSmallestLimitsOfPreservesLimits (coyoneda.obj { unop := U })
⊢ generate S.arrows ∈ J.sieves X
state_after: no goals