l3lab/ntp-mathlib huggingface dataset:
/--
A presheaf on a category which is `FinitaryExtensive` is a sheaf iff it preserves finite products.
-/
theorem isSheaf_iff_preservesFiniteProducts [FinitaryExtensive C] (F : Cᵒᵖ ⥤ Type max u v) :
    Presieve.IsSheaf (extensiveCoverage C).toGrothendieck F ↔
    Nonempty (PreservesFiniteProducts F) := by
  refine ⟨fun hF ↦ ⟨⟨fun α _ ↦ ⟨fun {K} ↦ ?_⟩⟩⟩, fun hF ↦ ?_⟩
  · rw [Presieve.isSheaf_coverage] at hF
    let Z : α → C := fun i ↦ unop (K.obj ⟨i⟩)
    have : (Presieve.ofArrows Z (Cofan.mk (∐ Z) (Sigma.ι Z)).inj).hasPullbacks :=
      (inferInstance : (Presieve.ofArrows Z (Sigma.ι Z)).hasPullbacks)
    have : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i) :=
      (inferInstance : ∀ (i : α), Mono (Sigma.ι Z i))
    

Proof state:
case refine_1
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ Type (max u v)
hF : ∀ {X : C}, ∀ R ∈ Coverage.covering (extensiveCoverage C) X, IsSheafFor F R
α : Type
x✝ : Fintype α
K : Discrete α ⥤ Cᵒᵖ
Z : α → C := fun i => (K.obj { as := i }).unop
this✝ : hasPullbacks (ofArrows Z (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z))))
this : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i)
⊢ PreservesLimit K F

Next tactic:
let i : K ≅ Discrete.functor (fun i ↦ op (Z i)) := Discrete.natIsoFunctor
/--
A presheaf on a category which is `FinitaryExtensive` is a sheaf iff it preserves finite products.
-/
theorem isSheaf_iff_preservesFiniteProducts [FinitaryExtensive C] (F : Cᵒᵖ ⥤ Type max u v) :
    Presieve.IsSheaf (extensiveCoverage C).toGrothendieck F ↔
    Nonempty (PreservesFiniteProducts F) := by
  refine ⟨fun hF ↦ ⟨⟨fun α _ ↦ ⟨fun {K} ↦ ?_⟩⟩⟩, fun hF ↦ ?_⟩
  · rw [Presieve.isSheaf_coverage] at hF
    let Z : α → C := fun i ↦ unop (K.obj ⟨i⟩)
    have : (Presieve.ofArrows Z (Cofan.mk (∐ Z) (Sigma.ι Z)).inj).hasPullbacks :=
      (inferInstance : (Presieve.ofArrows Z (Sigma.ι Z)).hasPullbacks)
    have : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i) :=
      (inferInstance : ∀ (i : α), Mono (Sigma.ι Z i))
    let i : K ≅ Discrete.functor (fun i ↦ op (Z i)) := Discrete.natIsoFunctor
    

Proof state:
case refine_1
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ Type (max u v)
hF : ∀ {X : C}, ∀ R ∈ Coverage.covering (extensiveCoverage C) X, IsSheafFor F R
α : Type
x✝ : Fintype α
K : Discrete α ⥤ Cᵒᵖ
Z : α → C := fun i => (K.obj { as := i }).unop
this✝ : hasPullbacks (ofArrows Z (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z))))
this : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i)
i : K ≅ Discrete.functor fun i => op (Z i) := Discrete.natIsoFunctor
⊢ PreservesLimit K F

Next tactic:
let _ : PreservesLimit (Discrete.functor (fun i ↦ op (Z i))) F :=
        Presieve.preservesProductOfIsSheafFor F ?_ initialIsInitial _ (coproductIsCoproduct Z)
        (FinitaryExtensive.isPullback_initial_to_sigma_ι Z)
        (hF (Presieve.ofArrows Z (fun i ↦ Sigma.ι Z i)) ?_)
/--
A presheaf on a category which is `FinitaryExtensive` is a sheaf iff it preserves finite products.
-/
theorem isSheaf_iff_preservesFiniteProducts [FinitaryExtensive C] (F : Cᵒᵖ ⥤ Type max u v) :
    Presieve.IsSheaf (extensiveCoverage C).toGrothendieck F ↔
    Nonempty (PreservesFiniteProducts F) := by
  refine ⟨fun hF ↦ ⟨⟨fun α _ ↦ ⟨fun {K} ↦ ?_⟩⟩⟩, fun hF ↦ ?_⟩
  · rw [Presieve.isSheaf_coverage] at hF
    let Z : α → C := fun i ↦ unop (K.obj ⟨i⟩)
    have : (Presieve.ofArrows Z (Cofan.mk (∐ Z) (Sigma.ι Z)).inj).hasPullbacks :=
      (inferInstance : (Presieve.ofArrows Z (Sigma.ι Z)).hasPullbacks)
    have : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i) :=
      (inferInstance : ∀ (i : α), Mono (Sigma.ι Z i))
    let i : K ≅ Discrete.functor (fun i ↦ op (Z i)) := Discrete.natIsoFunctor
    let _ : PreservesLimit (Discrete.functor (fun i ↦ op (Z i))) F :=
        Presieve.preservesProductOfIsSheafFor F ?_ initialIsInitial _ (coproductIsCoproduct Z)
        (FinitaryExtensive.isPullback_initial_to_sigma_ι Z)
        (hF (Presieve.ofArrows Z (fun i ↦ Sigma.ι Z i)) ?_)
    · 

Proof state:
case refine_1.refine_3
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ Type (max u v)
hF : ∀ {X : C}, ∀ R ∈ Coverage.covering (extensiveCoverage C) X, IsSheafFor F R
α : Type
x✝¹ : Fintype α
K : Discrete α ⥤ Cᵒᵖ
Z : α → C := fun i => (K.obj { as := i }).unop
this✝ : hasPullbacks (ofArrows Z (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z))))
this : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i)
i : K ≅ Discrete.functor fun i => op (Z i) := Discrete.natIsoFunctor
x✝ : PreservesLimit (Discrete.functor fun i => op (Z i)) F :=
  preservesProductOfIsSheafFor F ?refine_1.refine_1 initialIsInitial (Cofan.mk (∐ Z) (Sigma.ι Z))
    (coproductIsCoproduct Z)
    (_ : ∀ (i j : α), i ≠ j → IsPullback (initial.to (Z i)) (initial.to (Z j)) (Sigma.ι Z i) (Sigma.ι Z j))
    (_ : IsSheafFor F (ofArrows Z fun i => Sigma.ι Z i))
⊢ PreservesLimit K F

Next tactic:
exact preservesLimitOfIsoDiagram F i.symm
/--
A presheaf on a category which is `FinitaryExtensive` is a sheaf iff it preserves finite products.
-/
theorem isSheaf_iff_preservesFiniteProducts [FinitaryExtensive C] (F : Cᵒᵖ ⥤ Type max u v) :
    Presieve.IsSheaf (extensiveCoverage C).toGrothendieck F ↔
    Nonempty (PreservesFiniteProducts F) := by
  refine ⟨fun hF ↦ ⟨⟨fun α _ ↦ ⟨fun {K} ↦ ?_⟩⟩⟩, fun hF ↦ ?_⟩
  · rw [Presieve.isSheaf_coverage] at hF
    let Z : α → C := fun i ↦ unop (K.obj ⟨i⟩)
    have : (Presieve.ofArrows Z (Cofan.mk (∐ Z) (Sigma.ι Z)).inj).hasPullbacks :=
      (inferInstance : (Presieve.ofArrows Z (Sigma.ι Z)).hasPullbacks)
    have : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i) :=
      (inferInstance : ∀ (i : α), Mono (Sigma.ι Z i))
    let i : K ≅ Discrete.functor (fun i ↦ op (Z i)) := Discrete.natIsoFunctor
    let _ : PreservesLimit (Discrete.functor (fun i ↦ op (Z i))) F :=
        Presieve.preservesProductOfIsSheafFor F ?_ initialIsInitial _ (coproductIsCoproduct Z)
        (FinitaryExtensive.isPullback_initial_to_sigma_ι Z)
        (hF (Presieve.ofArrows Z (fun i ↦ Sigma.ι Z i)) ?_)
    · exact preservesLimitOfIsoDiagram F i.symm
    · 

Proof state:
case refine_1.refine_1
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ Type (max u v)
hF : ∀ {X : C}, ∀ R ∈ Coverage.covering (extensiveCoverage C) X, IsSheafFor F R
α : Type
x✝ : Fintype α
K : Discrete α ⥤ Cᵒᵖ
Z : α → C := fun i => (K.obj { as := i }).unop
this✝ : hasPullbacks (ofArrows Z (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z))))
this : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i)
i : K ≅ Discrete.functor fun i => op (Z i) := Discrete.natIsoFunctor
⊢ IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)

Next tactic:
apply hF
/--
A presheaf on a category which is `FinitaryExtensive` is a sheaf iff it preserves finite products.
-/
theorem isSheaf_iff_preservesFiniteProducts [FinitaryExtensive C] (F : Cᵒᵖ ⥤ Type max u v) :
    Presieve.IsSheaf (extensiveCoverage C).toGrothendieck F ↔
    Nonempty (PreservesFiniteProducts F) := by
  refine ⟨fun hF ↦ ⟨⟨fun α _ ↦ ⟨fun {K} ↦ ?_⟩⟩⟩, fun hF ↦ ?_⟩
  · rw [Presieve.isSheaf_coverage] at hF
    let Z : α → C := fun i ↦ unop (K.obj ⟨i⟩)
    have : (Presieve.ofArrows Z (Cofan.mk (∐ Z) (Sigma.ι Z)).inj).hasPullbacks :=
      (inferInstance : (Presieve.ofArrows Z (Sigma.ι Z)).hasPullbacks)
    have : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i) :=
      (inferInstance : ∀ (i : α), Mono (Sigma.ι Z i))
    let i : K ≅ Discrete.functor (fun i ↦ op (Z i)) := Discrete.natIsoFunctor
    let _ : PreservesLimit (Discrete.functor (fun i ↦ op (Z i))) F :=
        Presieve.preservesProductOfIsSheafFor F ?_ initialIsInitial _ (coproductIsCoproduct Z)
        (FinitaryExtensive.isPullback_initial_to_sigma_ι Z)
        (hF (Presieve.ofArrows Z (fun i ↦ Sigma.ι Z i)) ?_)
    · exact preservesLimitOfIsoDiagram F i.symm
    · apply hF
      

Proof state:
case refine_1.refine_1.a
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ Type (max u v)
hF : ∀ {X : C}, ∀ R ∈ Coverage.covering (extensiveCoverage C) X, IsSheafFor F R
α : Type
x✝ : Fintype α
K : Discrete α ⥤ Cᵒᵖ
Z : α → C := fun i => (K.obj { as := i }).unop
this✝ : hasPullbacks (ofArrows Z (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z))))
this : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i)
i : K ≅ Discrete.functor fun i => op (Z i) := Discrete.natIsoFunctor
⊢ (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a) ∈ Coverage.covering (extensiveCoverage C) (⊥_ C)

Next tactic:
refine ⟨Empty, inferInstance, Empty.elim, IsEmpty.elim inferInstance, rfl, ⟨default,?_, ?_⟩⟩
/--
A presheaf on a category which is `FinitaryExtensive` is a sheaf iff it preserves finite products.
-/
theorem isSheaf_iff_preservesFiniteProducts [FinitaryExtensive C] (F : Cᵒᵖ ⥤ Type max u v) :
    Presieve.IsSheaf (extensiveCoverage C).toGrothendieck F ↔
    Nonempty (PreservesFiniteProducts F) := by
  refine ⟨fun hF ↦ ⟨⟨fun α _ ↦ ⟨fun {K} ↦ ?_⟩⟩⟩, fun hF ↦ ?_⟩
  · rw [Presieve.isSheaf_coverage] at hF
    let Z : α → C := fun i ↦ unop (K.obj ⟨i⟩)
    have : (Presieve.ofArrows Z (Cofan.mk (∐ Z) (Sigma.ι Z)).inj).hasPullbacks :=
      (inferInstance : (Presieve.ofArrows Z (Sigma.ι Z)).hasPullbacks)
    have : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i) :=
      (inferInstance : ∀ (i : α), Mono (Sigma.ι Z i))
    let i : K ≅ Discrete.functor (fun i ↦ op (Z i)) := Discrete.natIsoFunctor
    let _ : PreservesLimit (Discrete.functor (fun i ↦ op (Z i))) F :=
        Presieve.preservesProductOfIsSheafFor F ?_ initialIsInitial _ (coproductIsCoproduct Z)
        (FinitaryExtensive.isPullback_initial_to_sigma_ι Z)
        (hF (Presieve.ofArrows Z (fun i ↦ Sigma.ι Z i)) ?_)
    · exact preservesLimitOfIsoDiagram F i.symm
    · apply hF
      refine ⟨Empty, inferInstance, Empty.elim, IsEmpty.elim inferInstance, rfl, ⟨default,?_, ?_⟩⟩
      · 

Proof state:
case refine_1.refine_1.a.refine_1
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ Type (max u v)
hF : ∀ {X : C}, ∀ R ∈ Coverage.covering (extensiveCoverage C) X, IsSheafFor F R
α : Type
x✝ : Fintype α
K : Discrete α ⥤ Cᵒᵖ
Z : α → C := fun i => (K.obj { as := i }).unop
this✝ : hasPullbacks (ofArrows Z (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z))))
this : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i)
i : K ≅ Discrete.functor fun i => op (Z i) := Discrete.natIsoFunctor
⊢ (Sigma.desc fun a => IsEmpty.elim (_ : IsEmpty Empty) a) ≫ default = 𝟙 (∐ fun b => Empty.elim b)

Next tactic:
ext b
/--
A presheaf on a category which is `FinitaryExtensive` is a sheaf iff it preserves finite products.
-/
theorem isSheaf_iff_preservesFiniteProducts [FinitaryExtensive C] (F : Cᵒᵖ ⥤ Type max u v) :
    Presieve.IsSheaf (extensiveCoverage C).toGrothendieck F ↔
    Nonempty (PreservesFiniteProducts F) := by
  refine ⟨fun hF ↦ ⟨⟨fun α _ ↦ ⟨fun {K} ↦ ?_⟩⟩⟩, fun hF ↦ ?_⟩
  · rw [Presieve.isSheaf_coverage] at hF
    let Z : α → C := fun i ↦ unop (K.obj ⟨i⟩)
    have : (Presieve.ofArrows Z (Cofan.mk (∐ Z) (Sigma.ι Z)).inj).hasPullbacks :=
      (inferInstance : (Presieve.ofArrows Z (Sigma.ι Z)).hasPullbacks)
    have : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i) :=
      (inferInstance : ∀ (i : α), Mono (Sigma.ι Z i))
    let i : K ≅ Discrete.functor (fun i ↦ op (Z i)) := Discrete.natIsoFunctor
    let _ : PreservesLimit (Discrete.functor (fun i ↦ op (Z i))) F :=
        Presieve.preservesProductOfIsSheafFor F ?_ initialIsInitial _ (coproductIsCoproduct Z)
        (FinitaryExtensive.isPullback_initial_to_sigma_ι Z)
        (hF (Presieve.ofArrows Z (fun i ↦ Sigma.ι Z i)) ?_)
    · exact preservesLimitOfIsoDiagram F i.symm
    · apply hF
      refine ⟨Empty, inferInstance, Empty.elim, IsEmpty.elim inferInstance, rfl, ⟨default,?_, ?_⟩⟩
      · ext b
        

Proof state:
case refine_1.refine_1.a.refine_1.h
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ Type (max u v)
hF : ∀ {X : C}, ∀ R ∈ Coverage.covering (extensiveCoverage C) X, IsSheafFor F R
α : Type
x✝ : Fintype α
K : Discrete α ⥤ Cᵒᵖ
Z : α → C := fun i => (K.obj { as := i }).unop
this✝ : hasPullbacks (ofArrows Z (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z))))
this : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i)
i : K ≅ Discrete.functor fun i => op (Z i) := Discrete.natIsoFunctor
b : Empty
⊢ Sigma.ι (fun b => Empty.elim b) b ≫ (Sigma.desc fun a => IsEmpty.elim (_ : IsEmpty Empty) a) ≫ default =
    Sigma.ι (fun b => Empty.elim b) b ≫ 𝟙 (∐ fun b => Empty.elim b)

Next tactic:
cases b
/--
A presheaf on a category which is `FinitaryExtensive` is a sheaf iff it preserves finite products.
-/
theorem isSheaf_iff_preservesFiniteProducts [FinitaryExtensive C] (F : Cᵒᵖ ⥤ Type max u v) :
    Presieve.IsSheaf (extensiveCoverage C).toGrothendieck F ↔
    Nonempty (PreservesFiniteProducts F) := by
  refine ⟨fun hF ↦ ⟨⟨fun α _ ↦ ⟨fun {K} ↦ ?_⟩⟩⟩, fun hF ↦ ?_⟩
  · rw [Presieve.isSheaf_coverage] at hF
    let Z : α → C := fun i ↦ unop (K.obj ⟨i⟩)
    have : (Presieve.ofArrows Z (Cofan.mk (∐ Z) (Sigma.ι Z)).inj).hasPullbacks :=
      (inferInstance : (Presieve.ofArrows Z (Sigma.ι Z)).hasPullbacks)
    have : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i) :=
      (inferInstance : ∀ (i : α), Mono (Sigma.ι Z i))
    let i : K ≅ Discrete.functor (fun i ↦ op (Z i)) := Discrete.natIsoFunctor
    let _ : PreservesLimit (Discrete.functor (fun i ↦ op (Z i))) F :=
        Presieve.preservesProductOfIsSheafFor F ?_ initialIsInitial _ (coproductIsCoproduct Z)
        (FinitaryExtensive.isPullback_initial_to_sigma_ι Z)
        (hF (Presieve.ofArrows Z (fun i ↦ Sigma.ι Z i)) ?_)
    · exact preservesLimitOfIsoDiagram F i.symm
    · apply hF
      refine ⟨Empty, inferInstance, Empty.elim, IsEmpty.elim inferInstance, rfl, ⟨default,?_, ?_⟩⟩
      · ext b
        cases b
      · 

Proof state:
case refine_1.refine_1.a.refine_2
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ Type (max u v)
hF : ∀ {X : C}, ∀ R ∈ Coverage.covering (extensiveCoverage C) X, IsSheafFor F R
α : Type
x✝ : Fintype α
K : Discrete α ⥤ Cᵒᵖ
Z : α → C := fun i => (K.obj { as := i }).unop
this✝ : hasPullbacks (ofArrows Z (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z))))
this : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i)
i : K ≅ Discrete.functor fun i => op (Z i) := Discrete.natIsoFunctor
⊢ (default ≫ Sigma.desc fun a => IsEmpty.elim (_ : IsEmpty Empty) a) = 𝟙 (⊥_ C)

Next tactic:
simp only [eq_iff_true_of_subsingleton]
/--
A presheaf on a category which is `FinitaryExtensive` is a sheaf iff it preserves finite products.
-/
theorem isSheaf_iff_preservesFiniteProducts [FinitaryExtensive C] (F : Cᵒᵖ ⥤ Type max u v) :
    Presieve.IsSheaf (extensiveCoverage C).toGrothendieck F ↔
    Nonempty (PreservesFiniteProducts F) := by
  refine ⟨fun hF ↦ ⟨⟨fun α _ ↦ ⟨fun {K} ↦ ?_⟩⟩⟩, fun hF ↦ ?_⟩
  · rw [Presieve.isSheaf_coverage] at hF
    let Z : α → C := fun i ↦ unop (K.obj ⟨i⟩)
    have : (Presieve.ofArrows Z (Cofan.mk (∐ Z) (Sigma.ι Z)).inj).hasPullbacks :=
      (inferInstance : (Presieve.ofArrows Z (Sigma.ι Z)).hasPullbacks)
    have : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i) :=
      (inferInstance : ∀ (i : α), Mono (Sigma.ι Z i))
    let i : K ≅ Discrete.functor (fun i ↦ op (Z i)) := Discrete.natIsoFunctor
    let _ : PreservesLimit (Discrete.functor (fun i ↦ op (Z i))) F :=
        Presieve.preservesProductOfIsSheafFor F ?_ initialIsInitial _ (coproductIsCoproduct Z)
        (FinitaryExtensive.isPullback_initial_to_sigma_ι Z)
        (hF (Presieve.ofArrows Z (fun i ↦ Sigma.ι Z i)) ?_)
    · exact preservesLimitOfIsoDiagram F i.symm
    · apply hF
      refine ⟨Empty, inferInstance, Empty.elim, IsEmpty.elim inferInstance, rfl, ⟨default,?_, ?_⟩⟩
      · ext b
        cases b
      · simp only [eq_iff_true_of_subsingleton]
    · 

Proof state:
case refine_1.refine_2
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ Type (max u v)
hF : ∀ {X : C}, ∀ R ∈ Coverage.covering (extensiveCoverage C) X, IsSheafFor F R
α : Type
x✝ : Fintype α
K : Discrete α ⥤ Cᵒᵖ
Z : α → C := fun i => (K.obj { as := i }).unop
this✝ : hasPullbacks (ofArrows Z (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z))))
this : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i)
i : K ≅ Discrete.functor fun i => op (Z i) := Discrete.natIsoFunctor
⊢ (ofArrows Z fun i => Sigma.ι Z i) ∈ Coverage.covering (extensiveCoverage C) (∐ Z)

Next tactic:
refine ⟨α, inferInstance, Z, (fun i ↦ Sigma.ι Z i), rfl, ?_⟩
/--
A presheaf on a category which is `FinitaryExtensive` is a sheaf iff it preserves finite products.
-/
theorem isSheaf_iff_preservesFiniteProducts [FinitaryExtensive C] (F : Cᵒᵖ ⥤ Type max u v) :
    Presieve.IsSheaf (extensiveCoverage C).toGrothendieck F ↔
    Nonempty (PreservesFiniteProducts F) := by
  refine ⟨fun hF ↦ ⟨⟨fun α _ ↦ ⟨fun {K} ↦ ?_⟩⟩⟩, fun hF ↦ ?_⟩
  · rw [Presieve.isSheaf_coverage] at hF
    let Z : α → C := fun i ↦ unop (K.obj ⟨i⟩)
    have : (Presieve.ofArrows Z (Cofan.mk (∐ Z) (Sigma.ι Z)).inj).hasPullbacks :=
      (inferInstance : (Presieve.ofArrows Z (Sigma.ι Z)).hasPullbacks)
    have : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i) :=
      (inferInstance : ∀ (i : α), Mono (Sigma.ι Z i))
    let i : K ≅ Discrete.functor (fun i ↦ op (Z i)) := Discrete.natIsoFunctor
    let _ : PreservesLimit (Discrete.functor (fun i ↦ op (Z i))) F :=
        Presieve.preservesProductOfIsSheafFor F ?_ initialIsInitial _ (coproductIsCoproduct Z)
        (FinitaryExtensive.isPullback_initial_to_sigma_ι Z)
        (hF (Presieve.ofArrows Z (fun i ↦ Sigma.ι Z i)) ?_)
    · exact preservesLimitOfIsoDiagram F i.symm
    · apply hF
      refine ⟨Empty, inferInstance, Empty.elim, IsEmpty.elim inferInstance, rfl, ⟨default,?_, ?_⟩⟩
      · ext b
        cases b
      · simp only [eq_iff_true_of_subsingleton]
    · refine ⟨α, inferInstance, Z, (fun i ↦ Sigma.ι Z i), rfl, ?_⟩
      

Proof state:
case refine_1.refine_2
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ Type (max u v)
hF : ∀ {X : C}, ∀ R ∈ Coverage.covering (extensiveCoverage C) X, IsSheafFor F R
α : Type
x✝ : Fintype α
K : Discrete α ⥤ Cᵒᵖ
Z : α → C := fun i => (K.obj { as := i }).unop
this✝ : hasPullbacks (ofArrows Z (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z))))
this : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i)
i : K ≅ Discrete.functor fun i => op (Z i) := Discrete.natIsoFunctor
⊢ IsIso (Sigma.desc fun i => Sigma.ι Z i)

Next tactic:
suffices Sigma.desc (fun i ↦ Sigma.ι Z i) = 𝟙 _ by rw [this]; infer_instance
/--
A presheaf on a category which is `FinitaryExtensive` is a sheaf iff it preserves finite products.
-/
theorem isSheaf_iff_preservesFiniteProducts [FinitaryExtensive C] (F : Cᵒᵖ ⥤ Type max u v) :
    Presieve.IsSheaf (extensiveCoverage C).toGrothendieck F ↔
    Nonempty (PreservesFiniteProducts F) := by
  refine ⟨fun hF ↦ ⟨⟨fun α _ ↦ ⟨fun {K} ↦ ?_⟩⟩⟩, fun hF ↦ ?_⟩
  · rw [Presieve.isSheaf_coverage] at hF
    let Z : α → C := fun i ↦ unop (K.obj ⟨i⟩)
    have : (Presieve.ofArrows Z (Cofan.mk (∐ Z) (Sigma.ι Z)).inj).hasPullbacks :=
      (inferInstance : (Presieve.ofArrows Z (Sigma.ι Z)).hasPullbacks)
    have : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i) :=
      (inferInstance : ∀ (i : α), Mono (Sigma.ι Z i))
    let i : K ≅ Discrete.functor (fun i ↦ op (Z i)) := Discrete.natIsoFunctor
    let _ : PreservesLimit (Discrete.functor (fun i ↦ op (Z i))) F :=
        Presieve.preservesProductOfIsSheafFor F ?_ initialIsInitial _ (coproductIsCoproduct Z)
        (FinitaryExtensive.isPullback_initial_to_sigma_ι Z)
        (hF (Presieve.ofArrows Z (fun i ↦ Sigma.ι Z i)) ?_)
    · exact preservesLimitOfIsoDiagram F i.symm
    · apply hF
      refine ⟨Empty, inferInstance, Empty.elim, IsEmpty.elim inferInstance, rfl, ⟨default,?_, ?_⟩⟩
      · ext b
        cases b
      · simp only [eq_iff_true_of_subsingleton]
    · refine ⟨α, inferInstance, Z, (fun i ↦ Sigma.ι Z i), rfl, ?_⟩
      suffices Sigma.desc (fun i ↦ Sigma.ι Z i) = 𝟙 _ by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ Type (max u v)
hF : ∀ {X : C}, ∀ R ∈ Coverage.covering (extensiveCoverage C) X, IsSheafFor F R
α : Type
x✝ : Fintype α
K : Discrete α ⥤ Cᵒᵖ
Z : α → C := fun i => (K.obj { as := i }).unop
this✝¹ : hasPullbacks (ofArrows Z (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z))))
this✝ : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i)
i : K ≅ Discrete.functor fun i => op (Z i) := Discrete.natIsoFunctor
this : (Sigma.desc fun i => Sigma.ι Z i) = 𝟙 (∐ fun i => Z i)
⊢ IsIso (Sigma.desc fun i => Sigma.ι Z i)

Next tactic:
rw [this]
/--
A presheaf on a category which is `FinitaryExtensive` is a sheaf iff it preserves finite products.
-/
theorem isSheaf_iff_preservesFiniteProducts [FinitaryExtensive C] (F : Cᵒᵖ ⥤ Type max u v) :
    Presieve.IsSheaf (extensiveCoverage C).toGrothendieck F ↔
    Nonempty (PreservesFiniteProducts F) := by
  refine ⟨fun hF ↦ ⟨⟨fun α _ ↦ ⟨fun {K} ↦ ?_⟩⟩⟩, fun hF ↦ ?_⟩
  · rw [Presieve.isSheaf_coverage] at hF
    let Z : α → C := fun i ↦ unop (K.obj ⟨i⟩)
    have : (Presieve.ofArrows Z (Cofan.mk (∐ Z) (Sigma.ι Z)).inj).hasPullbacks :=
      (inferInstance : (Presieve.ofArrows Z (Sigma.ι Z)).hasPullbacks)
    have : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i) :=
      (inferInstance : ∀ (i : α), Mono (Sigma.ι Z i))
    let i : K ≅ Discrete.functor (fun i ↦ op (Z i)) := Discrete.natIsoFunctor
    let _ : PreservesLimit (Discrete.functor (fun i ↦ op (Z i))) F :=
        Presieve.preservesProductOfIsSheafFor F ?_ initialIsInitial _ (coproductIsCoproduct Z)
        (FinitaryExtensive.isPullback_initial_to_sigma_ι Z)
        (hF (Presieve.ofArrows Z (fun i ↦ Sigma.ι Z i)) ?_)
    · exact preservesLimitOfIsoDiagram F i.symm
    · apply hF
      refine ⟨Empty, inferInstance, Empty.elim, IsEmpty.elim inferInstance, rfl, ⟨default,?_, ?_⟩⟩
      · ext b
        cases b
      · simp only [eq_iff_true_of_subsingleton]
    · refine ⟨α, inferInstance, Z, (fun i ↦ Sigma.ι Z i), rfl, ?_⟩
      suffices Sigma.desc (fun i ↦ Sigma.ι Z i) = 𝟙 _ by rw [this]; 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : FinitaryPreExtensive C
inst✝ : FinitaryExtensive C
F : Cᵒᵖ ⥤ Type (max u v)
hF : ∀ {X : C}, ∀ R ∈ Coverage.covering (extensiveCoverage C) X, IsSheafFor F R
α : Type
x✝ : Fintype α
K : Discrete α ⥤ Cᵒᵖ
Z : α → C := fun i => (K.obj { as := i }).unop
this✝¹ : hasPullbacks (ofArrows Z (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z))))
this✝ : ∀ (i : α), Mono (Cofan.inj (Cofan.mk (∐ Z) (Sigma.ι Z)) i)
i : K ≅ Discrete.functor fun i => op (Z i) := Discrete.natIsoFunctor
this : (Sigma.desc fun i => Sigma.ι Z i) = 𝟙 (∐ fun i => Z i)
⊢ IsIso (𝟙 (∐ fun i => Z i))

Next tactic:
infer_instance