Theorem: CategoryTheory.Presheaf.isSheaf_iff_preservesFiniteProducts
File: Mathlib/CategoryTheory/Sites/Coherent/ExtensiveSheaves.lean

tactic: constructor
state_before: C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
⊢ IsSheaf (extensiveTopology C) F ↔ Nonempty (PreservesFiniteProducts F)
state_after: case mp
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
⊢ IsSheaf (extensiveTopology C) F → Nonempty (PreservesFiniteProducts F)

case mpr
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
⊢ Nonempty (PreservesFiniteProducts F) → IsSheaf (extensiveTopology C) F

tactic: intro h
state_before: case mp
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
⊢ IsSheaf (extensiveTopology C) F → Nonempty (PreservesFiniteProducts F)
state_after: case mp
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
h : IsSheaf (extensiveTopology C) F
⊢ Nonempty (PreservesFiniteProducts F)

tactic: rw [IsSheaf] at h
state_before: case mp
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
h : IsSheaf (extensiveTopology C) F
⊢ Nonempty (PreservesFiniteProducts F)
state_after: case mp
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
h : ∀ (E : D), Presieve.IsSheaf (extensiveTopology C) (F ⋙ coyoneda.obj { unop := E })
⊢ Nonempty (PreservesFiniteProducts F)

tactic: refine ⟨⟨fun J _ ↦ ⟨fun {K} ↦ ⟨fun {c} hc ↦ ?_⟩⟩⟩⟩
state_before: case mp
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
h : ∀ (E : D), Presieve.IsSheaf (extensiveTopology C) (F ⋙ coyoneda.obj { unop := E })
⊢ Nonempty (PreservesFiniteProducts F)
state_after: case mp
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
h : ∀ (E : D), Presieve.IsSheaf (extensiveTopology C) (F ⋙ coyoneda.obj { unop := E })
J : Type
x✝ : Fintype J
K : Discrete J ⥤ Cᵒᵖ
c : Cone K
hc : IsLimit c
⊢ IsLimit (F.mapCone c)

tactic: apply coyonedaJointlyReflectsLimits
state_before: case mp
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
h : ∀ (E : D), Presieve.IsSheaf (extensiveTopology C) (F ⋙ coyoneda.obj { unop := E })
J : Type
x✝ : Fintype J
K : Discrete J ⥤ Cᵒᵖ
c : Cone K
hc : IsLimit c
⊢ IsLimit (F.mapCone c)
state_after: case mp.hc
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
h : ∀ (E : D), Presieve.IsSheaf (extensiveTopology C) (F ⋙ coyoneda.obj { unop := E })
J : Type
x✝ : Fintype J
K : Discrete J ⥤ Cᵒᵖ
c : Cone K
hc : IsLimit c
⊢ (X : Dᵒᵖ) → IsLimit ((coyoneda.obj X).mapCone (F.mapCone c))

tactic: intro ⟨E⟩
state_before: case mp.hc
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
h : ∀ (E : D), Presieve.IsSheaf (extensiveTopology C) (F ⋙ coyoneda.obj { unop := E })
J : Type
x✝ : Fintype J
K : Discrete J ⥤ Cᵒᵖ
c : Cone K
hc : IsLimit c
⊢ (X : Dᵒᵖ) → IsLimit ((coyoneda.obj X).mapCone (F.mapCone c))
state_after: case mp.hc
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
h : ∀ (E : D), Presieve.IsSheaf (extensiveTopology C) (F ⋙ coyoneda.obj { unop := E })
J : Type
x✝ : Fintype J
K : Discrete J ⥤ Cᵒᵖ
c : Cone K
hc : IsLimit c
E : D
⊢ IsLimit ((coyoneda.obj { unop := E }).mapCone (F.mapCone c))

tactic: specialize h E
state_before: case mp.hc
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
h : ∀ (E : D), Presieve.IsSheaf (extensiveTopology C) (F ⋙ coyoneda.obj { unop := E })
J : Type
x✝ : Fintype J
K : Discrete J ⥤ Cᵒᵖ
c : Cone K
hc : IsLimit c
E : D
⊢ IsLimit ((coyoneda.obj { unop := E }).mapCone (F.mapCone c))
state_after: case mp.hc
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
J : Type
x✝ : Fintype J
K : Discrete J ⥤ Cᵒᵖ
c : Cone K
hc : IsLimit c
E : D
h : Presieve.IsSheaf (extensiveTopology C) (F ⋙ coyoneda.obj { unop := E })
⊢ IsLimit ((coyoneda.obj { unop := E }).mapCone (F.mapCone c))

tactic: rw [Presieve.isSheaf_iff_preservesFiniteProducts] at h
state_before: case mp.hc
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
J : Type
x✝ : Fintype J
K : Discrete J ⥤ Cᵒᵖ
c : Cone K
hc : IsLimit c
E : D
h : Presieve.IsSheaf (extensiveTopology C) (F ⋙ coyoneda.obj { unop := E })
⊢ IsLimit ((coyoneda.obj { unop := E }).mapCone (F.mapCone c))
state_after: case mp.hc
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
J : Type
x✝ : Fintype J
K : Discrete J ⥤ Cᵒᵖ
c : Cone K
hc : IsLimit c
E : D
h : Nonempty (PreservesFiniteProducts (F ⋙ coyoneda.obj { unop := E }))
⊢ IsLimit ((coyoneda.obj { unop := E }).mapCone (F.mapCone c))

tactic: have : PreservesLimit K (F.comp (coyoneda.obj ⟨E⟩)) := (h.some.preserves J).preservesLimit
state_before: case mp.hc
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
J : Type
x✝ : Fintype J
K : Discrete J ⥤ Cᵒᵖ
c : Cone K
hc : IsLimit c
E : D
h : Nonempty (PreservesFiniteProducts (F ⋙ coyoneda.obj { unop := E }))
⊢ IsLimit ((coyoneda.obj { unop := E }).mapCone (F.mapCone c))
state_after: case mp.hc
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
J : Type
x✝ : Fintype J
K : Discrete J ⥤ Cᵒᵖ
c : Cone K
hc : IsLimit c
E : D
h : Nonempty (PreservesFiniteProducts (F ⋙ coyoneda.obj { unop := E }))
this : PreservesLimit K (F ⋙ coyoneda.obj { unop := E })
⊢ IsLimit ((coyoneda.obj { unop := E }).mapCone (F.mapCone c))

tactic: change IsLimit ((F.comp (coyoneda.obj ⟨E⟩)).mapCone c)
state_before: case mp.hc
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
J : Type
x✝ : Fintype J
K : Discrete J ⥤ Cᵒᵖ
c : Cone K
hc : IsLimit c
E : D
h : Nonempty (PreservesFiniteProducts (F ⋙ coyoneda.obj { unop := E }))
this : PreservesLimit K (F ⋙ coyoneda.obj { unop := E })
⊢ IsLimit ((coyoneda.obj { unop := E }).mapCone (F.mapCone c))
state_after: case mp.hc
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
J : Type
x✝ : Fintype J
K : Discrete J ⥤ Cᵒᵖ
c : Cone K
hc : IsLimit c
E : D
h : Nonempty (PreservesFiniteProducts (F ⋙ coyoneda.obj { unop := E }))
this : PreservesLimit K (F ⋙ coyoneda.obj { unop := E })
⊢ IsLimit ((F ⋙ coyoneda.obj { unop := E }).mapCone c)

tactic: apply this.preserves
state_before: case mp.hc
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
J : Type
x✝ : Fintype J
K : Discrete J ⥤ Cᵒᵖ
c : Cone K
hc : IsLimit c
E : D
h : Nonempty (PreservesFiniteProducts (F ⋙ coyoneda.obj { unop := E }))
this : PreservesLimit K (F ⋙ coyoneda.obj { unop := E })
⊢ IsLimit ((F ⋙ coyoneda.obj { unop := E }).mapCone c)
state_after: case mp.hc
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
J : Type
x✝ : Fintype J
K : Discrete J ⥤ Cᵒᵖ
c : Cone K
hc : IsLimit c
E : D
h : Nonempty (PreservesFiniteProducts (F ⋙ coyoneda.obj { unop := E }))
this : PreservesLimit K (F ⋙ coyoneda.obj { unop := E })
⊢ IsLimit c

tactic: exact hc
state_before: case mp.hc
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
J : Type
x✝ : Fintype J
K : Discrete J ⥤ Cᵒᵖ
c : Cone K
hc : IsLimit c
E : D
h : Nonempty (PreservesFiniteProducts (F ⋙ coyoneda.obj { unop := E }))
this : PreservesLimit K (F ⋙ coyoneda.obj { unop := E })
⊢ IsLimit c
state_after: no goals

tactic: intro ⟨_⟩ E
state_before: case mpr
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
⊢ Nonempty (PreservesFiniteProducts F) → IsSheaf (extensiveTopology C) F
state_after: case mpr
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
val✝ : PreservesFiniteProducts F
E : D
⊢ Presieve.IsSheaf (extensiveTopology C) (F ⋙ coyoneda.obj { unop := E })

tactic: rw [Presieve.isSheaf_iff_preservesFiniteProducts]
state_before: case mpr
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
val✝ : PreservesFiniteProducts F
E : D
⊢ Presieve.IsSheaf (extensiveTopology C) (F ⋙ coyoneda.obj { unop := E })
state_after: case mpr
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
val✝ : PreservesFiniteProducts F
E : D
⊢ Nonempty (PreservesFiniteProducts (F ⋙ coyoneda.obj { unop := E }))

tactic: exact ⟨inferInstance⟩
state_before: case mpr
C : Type u_1
inst✝³ : Category.{u_3, u_1} C
D : Type u_2
inst✝² : Category.{u_4, u_2} D
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ D
val✝ : PreservesFiniteProducts F
E : D
⊢ Nonempty (PreservesFiniteProducts (F ⋙ coyoneda.obj { unop := E }))
state_after: no goals