l3lab/ntp-mathlib huggingface dataset:
/-- The union of the extensive and regular coverages generates the coherent topology on `C`. -/
lemma extensive_regular_generate_coherent [Preregular C] [FinitaryPreExtensive C] :
    ((extensiveCoverage C) ⊔ (regularCoverage C)).toGrothendieck =
    (coherentTopology C) := by
  ext B S
  refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩
  · induction h with
    | of Y T hT =>
      apply Coverage.saturate.of
      simp only [Coverage.sup_covering, Set.mem_union] at hT
      exact Or.elim hT
        (fun ⟨α, x, X, π, ⟨h, _⟩⟩ ↦ ⟨α, x, X, π, ⟨h, inferInstance⟩⟩)
        (fun ⟨Z, f, ⟨h, _⟩⟩ ↦ ⟨Unit, inferInstance, fun _ ↦ Z, fun _ ↦ f, ⟨h, inferInstance⟩⟩)
    | top => apply Coverage.saturate.top
    | transitive Y T => apply Coverage.saturate.transitive Y T<;> [assumption; assumption]
  · induction h with
    | of Y T hT =>
      obtain ⟨I, hI, X, f, ⟨h, hT⟩⟩ := hT
      let φ := fun (i : I) ↦ Sigma.ι X i
      let F := Sigma.desc f
      let Z := Sieve.generate T
      let Xs := (∐ fun (i : I) => X i)
      let Zf := Sieve.generate (Presieve.ofArrows (fun (_ : Unit) ↦ Xs) (fun (_ : Unit) ↦ F))
      apply Coverage.saturate.transitive Y Zf
      · apply Coverage.saturate.of
        simp only [Coverage.sup_covering, extensiveCoverage, regularCoverage, Set.mem_union,
          Set.mem_setOf_eq]
        exact Or.inr ⟨Xs, F, ⟨rfl, inferInstance⟩⟩
      · intro R g hZfg
        dsimp at hZfg
        rw [Presieve.ofArrows_pUnit] at hZfg
        obtain ⟨W, ψ, σ, ⟨hW, hW'⟩⟩ := hZfg
        induction hW
        rw [← hW', Sieve.pullback_comp Z]
        suffices Sieve.pullback ψ ((Sieve.pullback F) Z) ∈ GrothendieckTopology.sieves
          ((extensiveCoverage C) ⊔ (regularCoverage C)).toGrothendieck R by assumption
        apply GrothendieckTopology.pullback_stable'
        suffices Coverage.saturate ((extensiveCoverage C) ⊔ (regularCoverage C)) Xs
          (Z.pullback F) by assumption
        suffices : Sieve.generate (Presieve.ofArrows X φ) ≤ Z.pullback F
        · apply Coverage.saturate_of_superset _ this
          apply Coverage.saturate.of
          simp only [Coverage.sup_covering, extensiveCoverage, regularCoverage, Set.mem_union,
            Set.mem_setOf_eq]
          refine Or.inl ⟨I, hI, X, φ, ⟨rfl, ?_⟩⟩
          suffices Sigma.desc φ = 𝟙 _ by rw [this]; infer_instance
          ext
          simp only [colimit.ι_desc, Cofan.mk_pt, Cofan.mk_ι_app, Category.comp_id]
        intro Q q hq
        simp only [Sieve.pullback_apply, Sieve.generate_apply]
        simp only [Sieve.generate_apply] at hq
        obtain ⟨E, e, r, hq⟩ := hq
        refine' ⟨E, e, r ≫ F, ⟨_, _⟩⟩
        · rw [h]
          induction hq.1
          simp only [colimit.ι_desc, Cofan.mk_pt, Cofan.mk_ι_app]
          exact Presieve.ofArrows.mk _
        · rw [← hq.2]
          simp only [Category.assoc]
    

Proof state:
case h.h.h.refine_2.top
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preregular C
inst✝ : FinitaryPreExtensive C
B : C
S : Sieve B
X✝ : C
⊢ ⊤ ∈ GrothendieckTopology.sieves (Coverage.toGrothendieck C (extensiveCoverage C ⊔ regularCoverage C)) X✝

Next tactic:
| top => apply Coverage.saturate.top
/-- The union of the extensive and regular coverages generates the coherent topology on `C`. -/
lemma extensive_regular_generate_coherent [Preregular C] [FinitaryPreExtensive C] :
    ((extensiveCoverage C) ⊔ (regularCoverage C)).toGrothendieck =
    (coherentTopology C) := by
  ext B S
  refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩
  · induction h with
    | of Y T hT =>
      apply Coverage.saturate.of
      simp only [Coverage.sup_covering, Set.mem_union] at hT
      exact Or.elim hT
        (fun ⟨α, x, X, π, ⟨h, _⟩⟩ ↦ ⟨α, x, X, π, ⟨h, inferInstance⟩⟩)
        (fun ⟨Z, f, ⟨h, _⟩⟩ ↦ ⟨Unit, inferInstance, fun _ ↦ Z, fun _ ↦ f, ⟨h, inferInstance⟩⟩)
    | top => apply Coverage.saturate.top
    | transitive Y T => apply Coverage.saturate.transitive Y T<;> [assumption; assumption]
  · induction h with
    | of Y T hT =>
      obtain ⟨I, hI, X, f, ⟨h, hT⟩⟩ := hT
      let φ := fun (i : I) ↦ Sigma.ι X i
      let F := Sigma.desc f
      let Z := Sieve.generate T
      let Xs := (∐ fun (i : I) => X i)
      let Zf := Sieve.generate (Presieve.ofArrows (fun (_ : Unit) ↦ Xs) (fun (_ : Unit) ↦ F))
      apply Coverage.saturate.transitive Y Zf
      · apply Coverage.saturate.of
        simp only [Coverage.sup_covering, extensiveCoverage, regularCoverage, Set.mem_union,
          Set.mem_setOf_eq]
        exact Or.inr ⟨Xs, F, ⟨rfl, inferInstance⟩⟩
      · intro R g hZfg
        dsimp at hZfg
        rw [Presieve.ofArrows_pUnit] at hZfg
        obtain ⟨W, ψ, σ, ⟨hW, hW'⟩⟩ := hZfg
        induction hW
        rw [← hW', Sieve.pullback_comp Z]
        suffices Sieve.pullback ψ ((Sieve.pullback F) Z) ∈ GrothendieckTopology.sieves
          ((extensiveCoverage C) ⊔ (regularCoverage C)).toGrothendieck R by assumption
        apply GrothendieckTopology.pullback_stable'
        suffices Coverage.saturate ((extensiveCoverage C) ⊔ (regularCoverage C)) Xs
          (Z.pullback F) by assumption
        suffices : Sieve.generate (Presieve.ofArrows X φ) ≤ Z.pullback F
        · apply Coverage.saturate_of_superset _ this
          apply Coverage.saturate.of
          simp only [Coverage.sup_covering, extensiveCoverage, regularCoverage, Set.mem_union,
            Set.mem_setOf_eq]
          refine Or.inl ⟨I, hI, X, φ, ⟨rfl, ?_⟩⟩
          suffices Sigma.desc φ = 𝟙 _ by rw [this]; infer_instance
          ext
          simp only [colimit.ι_desc, Cofan.mk_pt, Cofan.mk_ι_app, Category.comp_id]
        intro Q q hq
        simp only [Sieve.pullback_apply, Sieve.generate_apply]
        simp only [Sieve.generate_apply] at hq
        obtain ⟨E, e, r, hq⟩ := hq
        refine' ⟨E, e, r ≫ F, ⟨_, _⟩⟩
        · rw [h]
          induction hq.1
          simp only [colimit.ι_desc, Cofan.mk_pt, Cofan.mk_ι_app]
          exact Presieve.ofArrows.mk _
        · rw [← hq.2]
          simp only [Category.assoc]
    | top => 

Proof state:
case h.h.h.refine_2.top
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preregular C
inst✝ : FinitaryPreExtensive C
B : C
S : Sieve B
X✝ : C
⊢ ⊤ ∈ GrothendieckTopology.sieves (Coverage.toGrothendieck C (extensiveCoverage C ⊔ regularCoverage C)) X✝

Next tactic:
apply Coverage.saturate.top
/--
The map to the explicit equalizer used in the sheaf condition.
-/
def MapToEqualizer (P : Cᵒᵖ ⥤ Type (max u v)) {W X B : C} (f : X ⟶ B)
    (g₁ g₂ : W ⟶ X) (w : g₁ ≫ f = g₂ ≫ f) :
    P.obj (op B) → { x : P.obj (op X) | P.map g₁.op x = P.map g₂.op x } := fun t ↦
  ⟨P.map f.op t, by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
P : Cᵒᵖ ⥤ Type (max u v)
W X B : C
f : X ⟶ B
g₁ g₂ : W ⟶ X
w : g₁ ≫ f = g₂ ≫ f
t : P.obj (op B)
⊢ P.map f.op t ∈ {x | P.map g₁.op x = P.map g₂.op x}

Next tactic:
simp only [Set.mem_setOf_eq, ← FunctorToTypes.map_comp_apply, ← op_comp, w]
lemma EqualizerCondition.isSheafFor {B : C} {S : Presieve B} [S.regular] [S.hasPullbacks]
    {F : Cᵒᵖ ⥤ Type (max u v)}
    (hF : EqualizerCondition F) : S.IsSheafFor F := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
B : C
S : Presieve B
inst✝¹ : regular S
inst✝ : hasPullbacks S
F : Cᵒᵖ ⥤ Type (max u v)
hF : EqualizerCondition F
⊢ IsSheafFor F S

Next tactic:
obtain ⟨X, π, hS, πsurj⟩ := Presieve.regular.single_epi (R := S)
lemma EqualizerCondition.isSheafFor {B : C} {S : Presieve B} [S.regular] [S.hasPullbacks]
    {F : Cᵒᵖ ⥤ Type (max u v)}
    (hF : EqualizerCondition F) : S.IsSheafFor F := by
  obtain ⟨X, π, hS, πsurj⟩ := Presieve.regular.single_epi (R := S)
  

Proof state:
case intro.intro.intro
C : Type u
inst✝² : Category.{v, u} C
B : C
S : Presieve B
inst✝¹ : regular S
inst✝ : hasPullbacks S
F : Cᵒᵖ ⥤ Type (max u v)
hF : EqualizerCondition F
X : C
π : X ⟶ B
hS : S = ofArrows (fun x => X) fun x => π
πsurj : EffectiveEpi π
⊢ IsSheafFor F S

Next tactic:
subst hS
lemma EqualizerCondition.isSheafFor {B : C} {S : Presieve B} [S.regular] [S.hasPullbacks]
    {F : Cᵒᵖ ⥤ Type (max u v)}
    (hF : EqualizerCondition F) : S.IsSheafFor F := by
  obtain ⟨X, π, hS, πsurj⟩ := Presieve.regular.single_epi (R := S)
  subst hS
  

Proof state:
case intro.intro.intro
C : Type u
inst✝² : Category.{v, u} C
B : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : EqualizerCondition F
X : C
π : X ⟶ B
πsurj : EffectiveEpi π
inst✝¹ : regular (ofArrows (fun x => X) fun x => π)
inst✝ : hasPullbacks (ofArrows (fun x => X) fun x => π)
⊢ IsSheafFor F (ofArrows (fun x => X) fun x => π)

Next tactic:
rw [isSheafFor_arrows_iff_pullbacks]
lemma EqualizerCondition.isSheafFor {B : C} {S : Presieve B} [S.regular] [S.hasPullbacks]
    {F : Cᵒᵖ ⥤ Type (max u v)}
    (hF : EqualizerCondition F) : S.IsSheafFor F := by
  obtain ⟨X, π, hS, πsurj⟩ := Presieve.regular.single_epi (R := S)
  subst hS
  rw [isSheafFor_arrows_iff_pullbacks]
  

Proof state:
case intro.intro.intro
C : Type u
inst✝² : Category.{v, u} C
B : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : EqualizerCondition F
X : C
π : X ⟶ B
πsurj : EffectiveEpi π
inst✝¹ : regular (ofArrows (fun x => X) fun x => π)
inst✝ : hasPullbacks (ofArrows (fun x => X) fun x => π)
⊢ ∀ (x : Unit → F.obj (op X)), Arrows.PullbackCompatible F (fun x => π) x → ∃! t, ∀ (i : Unit), F.map π.op t = x i

Next tactic:
intro y h
lemma EqualizerCondition.isSheafFor {B : C} {S : Presieve B} [S.regular] [S.hasPullbacks]
    {F : Cᵒᵖ ⥤ Type (max u v)}
    (hF : EqualizerCondition F) : S.IsSheafFor F := by
  obtain ⟨X, π, hS, πsurj⟩ := Presieve.regular.single_epi (R := S)
  subst hS
  rw [isSheafFor_arrows_iff_pullbacks]
  intro y h
  

Proof state:
case intro.intro.intro
C : Type u
inst✝² : Category.{v, u} C
B : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : EqualizerCondition F
X : C
π : X ⟶ B
πsurj : EffectiveEpi π
inst✝¹ : regular (ofArrows (fun x => X) fun x => π)
inst✝ : hasPullbacks (ofArrows (fun x => X) fun x => π)
y : Unit → F.obj (op X)
h : Arrows.PullbackCompatible F (fun x => π) y
⊢ ∃! t, ∀ (i : Unit), F.map π.op t = y i

Next tactic:
have : (Presieve.singleton π).hasPullbacks := by rw [← ofArrows_pUnit]; infer_instance
lemma EqualizerCondition.isSheafFor {B : C} {S : Presieve B} [S.regular] [S.hasPullbacks]
    {F : Cᵒᵖ ⥤ Type (max u v)}
    (hF : EqualizerCondition F) : S.IsSheafFor F := by
  obtain ⟨X, π, hS, πsurj⟩ := Presieve.regular.single_epi (R := S)
  subst hS
  rw [isSheafFor_arrows_iff_pullbacks]
  intro y h
  have : (Presieve.singleton π).hasPullbacks := by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
B : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : EqualizerCondition F
X : C
π : X ⟶ B
πsurj : EffectiveEpi π
inst✝¹ : regular (ofArrows (fun x => X) fun x => π)
inst✝ : hasPullbacks (ofArrows (fun x => X) fun x => π)
y : Unit → F.obj (op X)
h : Arrows.PullbackCompatible F (fun x => π) y
⊢ hasPullbacks (Presieve.singleton π)

Next tactic:
rw [← ofArrows_pUnit]
lemma EqualizerCondition.isSheafFor {B : C} {S : Presieve B} [S.regular] [S.hasPullbacks]
    {F : Cᵒᵖ ⥤ Type (max u v)}
    (hF : EqualizerCondition F) : S.IsSheafFor F := by
  obtain ⟨X, π, hS, πsurj⟩ := Presieve.regular.single_epi (R := S)
  subst hS
  rw [isSheafFor_arrows_iff_pullbacks]
  intro y h
  have : (Presieve.singleton π).hasPullbacks := by rw [← ofArrows_pUnit]; 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
B : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : EqualizerCondition F
X : C
π : X ⟶ B
πsurj : EffectiveEpi π
inst✝¹ : regular (ofArrows (fun x => X) fun x => π)
inst✝ : hasPullbacks (ofArrows (fun x => X) fun x => π)
y : Unit → F.obj (op X)
h : Arrows.PullbackCompatible F (fun x => π) y
⊢ hasPullbacks (ofArrows (fun x => X) fun x => π)

Next tactic:
infer_instance
lemma EqualizerCondition.isSheafFor {B : C} {S : Presieve B} [S.regular] [S.hasPullbacks]
    {F : Cᵒᵖ ⥤ Type (max u v)}
    (hF : EqualizerCondition F) : S.IsSheafFor F := by
  obtain ⟨X, π, hS, πsurj⟩ := Presieve.regular.single_epi (R := S)
  subst hS
  rw [isSheafFor_arrows_iff_pullbacks]
  intro y h
  have : (Presieve.singleton π).hasPullbacks := by rw [← ofArrows_pUnit]; infer_instance
  

Proof state:
case intro.intro.intro
C : Type u
inst✝² : Category.{v, u} C
B : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : EqualizerCondition F
X : C
π : X ⟶ B
πsurj : EffectiveEpi π
inst✝¹ : regular (ofArrows (fun x => X) fun x => π)
inst✝ : hasPullbacks (ofArrows (fun x => X) fun x => π)
y : Unit → F.obj (op X)
h : Arrows.PullbackCompatible F (fun x => π) y
this : hasPullbacks (Presieve.singleton π)
⊢ ∃! t, ∀ (i : Unit), F.map π.op t = y i

Next tactic:
have : HasPullback π π := hasPullbacks.has_pullbacks Presieve.singleton.mk Presieve.singleton.mk
lemma EqualizerCondition.isSheafFor {B : C} {S : Presieve B} [S.regular] [S.hasPullbacks]
    {F : Cᵒᵖ ⥤ Type (max u v)}
    (hF : EqualizerCondition F) : S.IsSheafFor F := by
  obtain ⟨X, π, hS, πsurj⟩ := Presieve.regular.single_epi (R := S)
  subst hS
  rw [isSheafFor_arrows_iff_pullbacks]
  intro y h
  have : (Presieve.singleton π).hasPullbacks := by rw [← ofArrows_pUnit]; infer_instance
  have : HasPullback π π := hasPullbacks.has_pullbacks Presieve.singleton.mk Presieve.singleton.mk
  

Proof state:
case intro.intro.intro
C : Type u
inst✝² : Category.{v, u} C
B : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : EqualizerCondition F
X : C
π : X ⟶ B
πsurj : EffectiveEpi π
inst✝¹ : regular (ofArrows (fun x => X) fun x => π)
inst✝ : hasPullbacks (ofArrows (fun x => X) fun x => π)
y : Unit → F.obj (op X)
h : Arrows.PullbackCompatible F (fun x => π) y
this✝ : hasPullbacks (Presieve.singleton π)
this : HasPullback π π
⊢ ∃! t, ∀ (i : Unit), F.map π.op t = y i

Next tactic:
specialize hF X B π
lemma EqualizerCondition.isSheafFor {B : C} {S : Presieve B} [S.regular] [S.hasPullbacks]
    {F : Cᵒᵖ ⥤ Type (max u v)}
    (hF : EqualizerCondition F) : S.IsSheafFor F := by
  obtain ⟨X, π, hS, πsurj⟩ := Presieve.regular.single_epi (R := S)
  subst hS
  rw [isSheafFor_arrows_iff_pullbacks]
  intro y h
  have : (Presieve.singleton π).hasPullbacks := by rw [← ofArrows_pUnit]; infer_instance
  have : HasPullback π π := hasPullbacks.has_pullbacks Presieve.singleton.mk Presieve.singleton.mk
  specialize hF X B π
  

Proof state:
case intro.intro.intro
C : Type u
inst✝² : Category.{v, u} C
B : C
F : Cᵒᵖ ⥤ Type (max u v)
X : C
π : X ⟶ B
πsurj : EffectiveEpi π
inst✝¹ : regular (ofArrows (fun x => X) fun x => π)
inst✝ : hasPullbacks (ofArrows (fun x => X) fun x => π)
y : Unit → F.obj (op X)
h : Arrows.PullbackCompatible F (fun x => π) y
this✝ : hasPullbacks (Presieve.singleton π)
this : HasPullback π π
hF : Function.Bijective (MapToEqualizer F π pullback.fst pullback.snd (_ : pullback.fst ≫ π = pullback.snd ≫ π))
⊢ ∃! t, ∀ (i : Unit), F.map π.op t = y i

Next tactic:
rw [Function.bijective_iff_existsUnique] at hF
lemma EqualizerCondition.isSheafFor {B : C} {S : Presieve B} [S.regular] [S.hasPullbacks]
    {F : Cᵒᵖ ⥤ Type (max u v)}
    (hF : EqualizerCondition F) : S.IsSheafFor F := by
  obtain ⟨X, π, hS, πsurj⟩ := Presieve.regular.single_epi (R := S)
  subst hS
  rw [isSheafFor_arrows_iff_pullbacks]
  intro y h
  have : (Presieve.singleton π).hasPullbacks := by rw [← ofArrows_pUnit]; infer_instance
  have : HasPullback π π := hasPullbacks.has_pullbacks Presieve.singleton.mk Presieve.singleton.mk
  specialize hF X B π
  rw [Function.bijective_iff_existsUnique] at hF
  

Proof state:
case intro.intro.intro
C : Type u
inst✝² : Category.{v, u} C
B : C
F : Cᵒᵖ ⥤ Type (max u v)
X : C
π : X ⟶ B
πsurj : EffectiveEpi π
inst✝¹ : regular (ofArrows (fun x => X) fun x => π)
inst✝ : hasPullbacks (ofArrows (fun x => X) fun x => π)
y : Unit → F.obj (op X)
h : Arrows.PullbackCompatible F (fun x => π) y
this✝ : hasPullbacks (Presieve.singleton π)
this : HasPullback π π
hF :
  ∀ (b : ↑{x | F.map pullback.fst.op x = F.map pullback.snd.op x}),
    ∃! a, MapToEqualizer F π pullback.fst pullback.snd (_ : pullback.fst ≫ π = pullback.snd ≫ π) a = b
⊢ ∃! t, ∀ (i : Unit), F.map π.op t = y i

Next tactic:
obtain ⟨t, ht, ht'⟩ := hF ⟨y (), h () ()⟩
lemma EqualizerCondition.isSheafFor {B : C} {S : Presieve B} [S.regular] [S.hasPullbacks]
    {F : Cᵒᵖ ⥤ Type (max u v)}
    (hF : EqualizerCondition F) : S.IsSheafFor F := by
  obtain ⟨X, π, hS, πsurj⟩ := Presieve.regular.single_epi (R := S)
  subst hS
  rw [isSheafFor_arrows_iff_pullbacks]
  intro y h
  have : (Presieve.singleton π).hasPullbacks := by rw [← ofArrows_pUnit]; infer_instance
  have : HasPullback π π := hasPullbacks.has_pullbacks Presieve.singleton.mk Presieve.singleton.mk
  specialize hF X B π
  rw [Function.bijective_iff_existsUnique] at hF
  obtain ⟨t, ht, ht'⟩ := hF ⟨y (), h () ()⟩
  

Proof state:
case intro.intro.intro.intro.intro
C : Type u
inst✝² : Category.{v, u} C
B : C
F : Cᵒᵖ ⥤ Type (max u v)
X : C
π : X ⟶ B
πsurj : EffectiveEpi π
inst✝¹ : regular (ofArrows (fun x => X) fun x => π)
inst✝ : hasPullbacks (ofArrows (fun x => X) fun x => π)
y : Unit → F.obj (op X)
h : Arrows.PullbackCompatible F (fun x => π) y
this✝ : hasPullbacks (Presieve.singleton π)
this : HasPullback π π
hF :
  ∀ (b : ↑{x | F.map pullback.fst.op x = F.map pullback.snd.op x}),
    ∃! a, MapToEqualizer F π pullback.fst pullback.snd (_ : pullback.fst ≫ π = pullback.snd ≫ π) a = b
t : F.obj (op B)
ht :
  MapToEqualizer F π pullback.fst pullback.snd (_ : pullback.fst ≫ π = pullback.snd ≫ π) t =
    { val := y (), property := (_ : F.map pullback.fst.op (y ()) = F.map pullback.snd.op (y ())) }
ht' :
  ∀ (y_1 : F.obj (op B)),
    (fun a =>
          MapToEqualizer F π pullback.fst pullback.snd (_ : pullback.fst ≫ π = pullback.snd ≫ π) a =
            { val := y (), property := (_ : F.map pullback.fst.op (y ()) = F.map pullback.snd.op (y ())) })
        y_1 →
      y_1 = t
⊢ ∃! t, ∀ (i : Unit), F.map π.op t = y i

Next tactic:
refine ⟨t, fun _ ↦ ?_, fun x h ↦ ht' x ?_⟩
lemma EqualizerCondition.isSheafFor {B : C} {S : Presieve B} [S.regular] [S.hasPullbacks]
    {F : Cᵒᵖ ⥤ Type (max u v)}
    (hF : EqualizerCondition F) : S.IsSheafFor F := by
  obtain ⟨X, π, hS, πsurj⟩ := Presieve.regular.single_epi (R := S)
  subst hS
  rw [isSheafFor_arrows_iff_pullbacks]
  intro y h
  have : (Presieve.singleton π).hasPullbacks := by rw [← ofArrows_pUnit]; infer_instance
  have : HasPullback π π := hasPullbacks.has_pullbacks Presieve.singleton.mk Presieve.singleton.mk
  specialize hF X B π
  rw [Function.bijective_iff_existsUnique] at hF
  obtain ⟨t, ht, ht'⟩ := hF ⟨y (), h () ()⟩
  refine ⟨t, fun _ ↦ ?_, fun x h ↦ ht' x ?_⟩
  · 

Proof state:
case intro.intro.intro.intro.intro.refine_1
C : Type u
inst✝² : Category.{v, u} C
B : C
F : Cᵒᵖ ⥤ Type (max u v)
X : C
π : X ⟶ B
πsurj : EffectiveEpi π
inst✝¹ : regular (ofArrows (fun x => X) fun x => π)
inst✝ : hasPullbacks (ofArrows (fun x => X) fun x => π)
y : Unit → F.obj (op X)
h : Arrows.PullbackCompatible F (fun x => π) y
this✝ : hasPullbacks (Presieve.singleton π)
this : HasPullback π π
hF :
  ∀ (b : ↑{x | F.map pullback.fst.op x = F.map pullback.snd.op x}),
    ∃! a, MapToEqualizer F π pullback.fst pullback.snd (_ : pullback.fst ≫ π = pullback.snd ≫ π) a = b
t : F.obj (op B)
ht :
  MapToEqualizer F π pullback.fst pullback.snd (_ : pullback.fst ≫ π = pullback.snd ≫ π) t =
    { val := y (), property := (_ : F.map pullback.fst.op (y ()) = F.map pullback.snd.op (y ())) }
ht' :
  ∀ (y_1 : F.obj (op B)),
    (fun a =>
          MapToEqualizer F π pullback.fst pullback.snd (_ : pullback.fst ≫ π = pullback.snd ≫ π) a =
            { val := y (), property := (_ : F.map pullback.fst.op (y ()) = F.map pullback.snd.op (y ())) })
        y_1 →
      y_1 = t
x✝ : Unit
⊢ F.map π.op t = y x✝

Next tactic:
simpa [MapToEqualizer] using ht
lemma EqualizerCondition.isSheafFor {B : C} {S : Presieve B} [S.regular] [S.hasPullbacks]
    {F : Cᵒᵖ ⥤ Type (max u v)}
    (hF : EqualizerCondition F) : S.IsSheafFor F := by
  obtain ⟨X, π, hS, πsurj⟩ := Presieve.regular.single_epi (R := S)
  subst hS
  rw [isSheafFor_arrows_iff_pullbacks]
  intro y h
  have : (Presieve.singleton π).hasPullbacks := by rw [← ofArrows_pUnit]; infer_instance
  have : HasPullback π π := hasPullbacks.has_pullbacks Presieve.singleton.mk Presieve.singleton.mk
  specialize hF X B π
  rw [Function.bijective_iff_existsUnique] at hF
  obtain ⟨t, ht, ht'⟩ := hF ⟨y (), h () ()⟩
  refine ⟨t, fun _ ↦ ?_, fun x h ↦ ht' x ?_⟩
  · simpa [MapToEqualizer] using ht
  · 

Proof state:
case intro.intro.intro.intro.intro.refine_2
C : Type u
inst✝² : Category.{v, u} C
B : C
F : Cᵒᵖ ⥤ Type (max u v)
X : C
π : X ⟶ B
πsurj : EffectiveEpi π
inst✝¹ : regular (ofArrows (fun x => X) fun x => π)
inst✝ : hasPullbacks (ofArrows (fun x => X) fun x => π)
y : Unit → F.obj (op X)
h✝ : Arrows.PullbackCompatible F (fun x => π) y
this✝ : hasPullbacks (Presieve.singleton π)
this : HasPullback π π
hF :
  ∀ (b : ↑{x | F.map pullback.fst.op x = F.map pullback.snd.op x}),
    ∃! a, MapToEqualizer F π pullback.fst pullback.snd (_ : pullback.fst ≫ π = pullback.snd ≫ π) a = b
t : F.obj (op B)
ht :
  MapToEqualizer F π pullback.fst pullback.snd (_ : pullback.fst ≫ π = pullback.snd ≫ π) t =
    { val := y (), property := (_ : F.map pullback.fst.op (y ()) = F.map pullback.snd.op (y ())) }
ht' :
  ∀ (y_1 : F.obj (op B)),
    (fun a =>
          MapToEqualizer F π pullback.fst pullback.snd (_ : pullback.fst ≫ π = pullback.snd ≫ π) a =
            { val := y (), property := (_ : F.map pullback.fst.op (y ()) = F.map pullback.snd.op (y ())) })
        y_1 →
      y_1 = t
x : F.obj (op B)
h : (fun t => ∀ (i : Unit), F.map π.op t = y i) x
⊢ (fun a =>
      MapToEqualizer F π pullback.fst pullback.snd (_ : pullback.fst ≫ π = pullback.snd ≫ π) a =
        { val := y (), property := (_ : F.map pullback.fst.op (y ()) = F.map pullback.snd.op (y ())) })
    x

Next tactic:
simpa [MapToEqualizer] using h ()
lemma equalizerCondition_of_regular {F : Cᵒᵖ ⥤ Type (max u v)}
    (hSF : ∀ {B : C} (S : Presieve B) [S.regular] [S.hasPullbacks], S.IsSheafFor F) :
    EqualizerCondition F := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F : Cᵒᵖ ⥤ Type (max u v)
hSF : ∀ {B : C} (S : Presieve B) [inst : regular S] [inst : hasPullbacks S], IsSheafFor F S
⊢ EqualizerCondition F

Next tactic:
intro X B π _ _
lemma equalizerCondition_of_regular {F : Cᵒᵖ ⥤ Type (max u v)}
    (hSF : ∀ {B : C} (S : Presieve B) [S.regular] [S.hasPullbacks], S.IsSheafFor F) :
    EqualizerCondition F := by
  intro X B π _ _
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
F : Cᵒᵖ ⥤ Type (max u v)
hSF : ∀ {B : C} (S : Presieve B) [inst : regular S] [inst : hasPullbacks S], IsSheafFor F S
X B : C
π : X ⟶ B
inst✝¹ : EffectiveEpi π
inst✝ : HasPullback π π
⊢ Function.Bijective (MapToEqualizer F π pullback.fst pullback.snd (_ : pullback.fst ≫ π = pullback.snd ≫ π))

Next tactic:
have : (ofArrows (fun _ ↦ X) (fun _ ↦ π)).regular := ⟨X, π, rfl, inferInstance⟩
lemma equalizerCondition_of_regular {F : Cᵒᵖ ⥤ Type (max u v)}
    (hSF : ∀ {B : C} (S : Presieve B) [S.regular] [S.hasPullbacks], S.IsSheafFor F) :
    EqualizerCondition F := by
  intro X B π _ _
  have : (ofArrows (fun _ ↦ X) (fun _ ↦ π)).regular := ⟨X, π, rfl, inferInstance⟩
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
F : Cᵒᵖ ⥤ Type (max u v)
hSF : ∀ {B : C} (S : Presieve B) [inst : regular S] [inst : hasPullbacks S], IsSheafFor F S
X B : C
π : X ⟶ B
inst✝¹ : EffectiveEpi π
inst✝ : HasPullback π π
this : regular (ofArrows (fun x => X) fun x => π)
⊢ Function.Bijective (MapToEqualizer F π pullback.fst pullback.snd (_ : pullback.fst ≫ π = pullback.snd ≫ π))

Next tactic:
have : (ofArrows (fun () ↦ X) (fun _ ↦ π)).hasPullbacks := ⟨
      fun hf _ hg ↦ (by cases hf; cases hg; infer_instance)⟩
lemma equalizerCondition_of_regular {F : Cᵒᵖ ⥤ Type (max u v)}
    (hSF : ∀ {B : C} (S : Presieve B) [S.regular] [S.hasPullbacks], S.IsSheafFor F) :
    EqualizerCondition F := by
  intro X B π _ _
  have : (ofArrows (fun _ ↦ X) (fun _ ↦ π)).regular := ⟨X, π, rfl, inferInstance⟩
  have : (ofArrows (fun () ↦ X) (fun _ ↦ π)).hasPullbacks := ⟨
      fun hf _ hg ↦ (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
F : Cᵒᵖ ⥤ Type (max u v)
hSF : ∀ {B : C} (S : Presieve B) [inst : regular S] [inst : hasPullbacks S], IsSheafFor F S
X B : C
π : X ⟶ B
inst✝¹ : EffectiveEpi π
inst✝ : HasPullback π π
this : regular (ofArrows (fun x => X) fun x => π)
Y✝ Z✝ : C
f✝ : Y✝ ⟶ B
hf : ofArrows (fun x => X) (fun x => π) f✝
x✝ : Z✝ ⟶ B
hg : ofArrows (fun x => X) (fun x => π) x✝
⊢ HasPullback f✝ x✝

Next tactic:
cases hf