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)
      

Proof state:
case h.h.h.refine_2.of.intro.intro.intro.intro.intro
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preregular C
inst✝ : FinitaryPreExtensive C
B : C
S : Sieve B
Y : C
T : Presieve Y
I : Type
hI : Fintype I
X : I → C
f : (a : I) → X a ⟶ Y
h : T = Presieve.ofArrows X f
hT : EffectiveEpiFamily X f
φ : (i : I) → X i ⟶ ∐ X := fun i => Sigma.ι X i
F : (∐ fun b => X b) ⟶ Y := Sigma.desc f
Z : Sieve Y := Sieve.generate T
Xs : C := ∐ fun i => X i
⊢ Sieve.generate T ∈ GrothendieckTopology.sieves (Coverage.toGrothendieck C (extensiveCoverage C ⊔ regularCoverage C)) Y

Next tactic:
let Zf := Sieve.generate (Presieve.ofArrows (fun (_ : Unit) ↦ Xs) (fun (_ : Unit) ↦ F))
/-- 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))
      

Proof state:
case h.h.h.refine_2.of.intro.intro.intro.intro.intro
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preregular C
inst✝ : FinitaryPreExtensive C
B : C
S : Sieve B
Y : C
T : Presieve Y
I : Type
hI : Fintype I
X : I → C
f : (a : I) → X a ⟶ Y
h : T = Presieve.ofArrows X f
hT : EffectiveEpiFamily X f
φ : (i : I) → X i ⟶ ∐ X := fun i => Sigma.ι X i
F : (∐ fun b => X b) ⟶ Y := Sigma.desc f
Z : Sieve Y := Sieve.generate T
Xs : C := ∐ fun i => X i
Zf : Sieve Y := Sieve.generate (Presieve.ofArrows (fun x => Xs) fun x => F)
⊢ Sieve.generate T ∈ GrothendieckTopology.sieves (Coverage.toGrothendieck C (extensiveCoverage C ⊔ regularCoverage C)) Y

Next tactic:
apply Coverage.saturate.transitive Y Zf
/-- 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
      · 

Proof state:
case h.h.h.refine_2.of.intro.intro.intro.intro.intro.a
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preregular C
inst✝ : FinitaryPreExtensive C
B : C
S : Sieve B
Y : C
T : Presieve Y
I : Type
hI : Fintype I
X : I → C
f : (a : I) → X a ⟶ Y
h : T = Presieve.ofArrows X f
hT : EffectiveEpiFamily X f
φ : (i : I) → X i ⟶ ∐ X := fun i => Sigma.ι X i
F : (∐ fun b => X b) ⟶ Y := Sigma.desc f
Z : Sieve Y := Sieve.generate T
Xs : C := ∐ fun i => X i
Zf : Sieve Y := Sieve.generate (Presieve.ofArrows (fun x => Xs) fun x => F)
⊢ Coverage.saturate (extensiveCoverage C ⊔ regularCoverage C) Y Zf

Next tactic:
apply Coverage.saturate.of
/-- 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
        

Proof state:
case h.h.h.refine_2.of.intro.intro.intro.intro.intro.a.hS
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preregular C
inst✝ : FinitaryPreExtensive C
B : C
S : Sieve B
Y : C
T : Presieve Y
I : Type
hI : Fintype I
X : I → C
f : (a : I) → X a ⟶ Y
h : T = Presieve.ofArrows X f
hT : EffectiveEpiFamily X f
φ : (i : I) → X i ⟶ ∐ X := fun i => Sigma.ι X i
F : (∐ fun b => X b) ⟶ Y := Sigma.desc f
Z : Sieve Y := Sieve.generate T
Xs : C := ∐ fun i => X i
Zf : Sieve Y := Sieve.generate (Presieve.ofArrows (fun x => Xs) fun x => F)
⊢ (Presieve.ofArrows (fun x => Xs) fun x => F) ∈ Coverage.covering (extensiveCoverage C ⊔ regularCoverage C) Y

Next tactic:
simp only [Coverage.sup_covering, extensiveCoverage, regularCoverage, Set.mem_union,
          Set.mem_setOf_eq]
/-- 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]
        

Proof state:
case h.h.h.refine_2.of.intro.intro.intro.intro.intro.a.hS
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preregular C
inst✝ : FinitaryPreExtensive C
B : C
S : Sieve B
Y : C
T : Presieve Y
I : Type
hI : Fintype I
X : I → C
f : (a : I) → X a ⟶ Y
h : T = Presieve.ofArrows X f
hT : EffectiveEpiFamily X f
φ : (i : I) → X i ⟶ ∐ X := fun i => Sigma.ι X i
F : (∐ fun b => X b) ⟶ Y := Sigma.desc f
Z : Sieve Y := Sieve.generate T
Xs : C := ∐ fun i => X i
Zf : Sieve Y := Sieve.generate (Presieve.ofArrows (fun x => Xs) fun x => F)
⊢ (∃ α x X_1 π,
      (Presieve.ofArrows (fun x => ∐ fun i => X i) fun x => Sigma.desc f) = Presieve.ofArrows X_1 π ∧
        IsIso (Sigma.desc π)) ∨
    ∃ X_1 f_1,
      ((Presieve.ofArrows (fun x => ∐ fun i => X i) fun x => Sigma.desc f) =
          Presieve.ofArrows (fun x => X_1) fun x => f_1) ∧
        EffectiveEpi f_1

Next tactic:
exact Or.inr ⟨Xs, F, ⟨rfl, inferInstance⟩⟩
/-- 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⟩⟩
      · 

Proof state:
case h.h.h.refine_2.of.intro.intro.intro.intro.intro.a
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preregular C
inst✝ : FinitaryPreExtensive C
B : C
S : Sieve B
Y : C
T : Presieve Y
I : Type
hI : Fintype I
X : I → C
f : (a : I) → X a ⟶ Y
h : T = Presieve.ofArrows X f
hT : EffectiveEpiFamily X f
φ : (i : I) → X i ⟶ ∐ X := fun i => Sigma.ι X i
F : (∐ fun b => X b) ⟶ Y := Sigma.desc f
Z : Sieve Y := Sieve.generate T
Xs : C := ∐ fun i => X i
Zf : Sieve Y := Sieve.generate (Presieve.ofArrows (fun x => Xs) fun x => F)
⊢ ∀ ⦃Y_1 : C⦄ ⦃f : Y_1 ⟶ Y⦄,
    Zf.arrows f → Coverage.saturate (extensiveCoverage C ⊔ regularCoverage C) Y_1 (Sieve.pullback f (Sieve.generate T))

Next tactic:
intro R g hZfg
/-- 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
        

Proof state:
case h.h.h.refine_2.of.intro.intro.intro.intro.intro.a
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preregular C
inst✝ : FinitaryPreExtensive C
B : C
S : Sieve B
Y : C
T : Presieve Y
I : Type
hI : Fintype I
X : I → C
f : (a : I) → X a ⟶ Y
h : T = Presieve.ofArrows X f
hT : EffectiveEpiFamily X f
φ : (i : I) → X i ⟶ ∐ X := fun i => Sigma.ι X i
F : (∐ fun b => X b) ⟶ Y := Sigma.desc f
Z : Sieve Y := Sieve.generate T
Xs : C := ∐ fun i => X i
Zf : Sieve Y := Sieve.generate (Presieve.ofArrows (fun x => Xs) fun x => F)
R : C
g : R ⟶ Y
hZfg : Zf.arrows g
⊢ Coverage.saturate (extensiveCoverage C ⊔ regularCoverage C) R (Sieve.pullback g (Sieve.generate T))

Next tactic:
dsimp at hZfg
/-- 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
        

Proof state:
case h.h.h.refine_2.of.intro.intro.intro.intro.intro.a
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preregular C
inst✝ : FinitaryPreExtensive C
B : C
S : Sieve B
Y : C
T : Presieve Y
I : Type
hI : Fintype I
X : I → C
f : (a : I) → X a ⟶ Y
h : T = Presieve.ofArrows X f
hT : EffectiveEpiFamily X f
φ : (i : I) → X i ⟶ ∐ X := fun i => Sigma.ι X i
F : (∐ fun b => X b) ⟶ Y := Sigma.desc f
Z : Sieve Y := Sieve.generate T
Xs : C := ∐ fun i => X i
Zf : Sieve Y := Sieve.generate (Presieve.ofArrows (fun x => Xs) fun x => F)
R : C
g : R ⟶ Y
hZfg : ∃ Y_1 h g_1, Presieve.ofArrows (fun x => ∐ fun i => X i) (fun x => Sigma.desc f) g_1 ∧ h ≫ g_1 = g
⊢ Coverage.saturate (extensiveCoverage C ⊔ regularCoverage C) R (Sieve.pullback g (Sieve.generate T))

Next tactic:
rw [Presieve.ofArrows_pUnit] at hZfg
/-- 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
        

Proof state:
case h.h.h.refine_2.of.intro.intro.intro.intro.intro.a
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preregular C
inst✝ : FinitaryPreExtensive C
B : C
S : Sieve B
Y : C
T : Presieve Y
I : Type
hI : Fintype I
X : I → C
f : (a : I) → X a ⟶ Y
h : T = Presieve.ofArrows X f
hT : EffectiveEpiFamily X f
φ : (i : I) → X i ⟶ ∐ X := fun i => Sigma.ι X i
F : (∐ fun b => X b) ⟶ Y := Sigma.desc f
Z : Sieve Y := Sieve.generate T
Xs : C := ∐ fun i => X i
Zf : Sieve Y := Sieve.generate (Presieve.ofArrows (fun x => Xs) fun x => F)
R : C
g : R ⟶ Y
hZfg : ∃ Y_1 h g_1, Presieve.singleton (Sigma.desc f) g_1 ∧ h ≫ g_1 = g
⊢ Coverage.saturate (extensiveCoverage C ⊔ regularCoverage C) R (Sieve.pullback g (Sieve.generate T))

Next tactic:
obtain ⟨W, ψ, σ, ⟨hW, hW'⟩⟩ := hZfg
/-- 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
        

Proof state:
case h.h.h.refine_2.of.intro.intro.intro.intro.intro.a.intro.intro.intro.intro
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preregular C
inst✝ : FinitaryPreExtensive C
B : C
S : Sieve B
Y : C
T : Presieve Y
I : Type
hI : Fintype I
X : I → C
f : (a : I) → X a ⟶ Y
h : T = Presieve.ofArrows X f
hT : EffectiveEpiFamily X f
φ : (i : I) → X i ⟶ ∐ X := fun i => Sigma.ι X i
F : (∐ fun b => X b) ⟶ Y := Sigma.desc f
Z : Sieve Y := Sieve.generate T
Xs : C := ∐ fun i => X i
Zf : Sieve Y := Sieve.generate (Presieve.ofArrows (fun x => Xs) fun x => F)
R : C
g : R ⟶ Y
W : C
ψ : R ⟶ W
σ : W ⟶ Y
hW : Presieve.singleton (Sigma.desc f) σ
hW' : ψ ≫ σ = g
⊢ Coverage.saturate (extensiveCoverage C ⊔ regularCoverage C) R (Sieve.pullback g (Sieve.generate T))

Next tactic:
induction hW
/-- 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
        

Proof state:
case h.h.h.refine_2.of.intro.intro.intro.intro.intro.a.intro.intro.intro.intro.mk
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preregular C
inst✝ : FinitaryPreExtensive C
B : C
S : Sieve B
Y : C
T : Presieve Y
I : Type
hI : Fintype I
X : I → C
f : (a : I) → X a ⟶ Y
h : T = Presieve.ofArrows X f
hT : EffectiveEpiFamily X f
φ : (i : I) → X i ⟶ ∐ X := fun i => Sigma.ι X i
F : (∐ fun b => X b) ⟶ Y := Sigma.desc f
Z : Sieve Y := Sieve.generate T
Xs : C := ∐ fun i => X i
Zf : Sieve Y := Sieve.generate (Presieve.ofArrows (fun x => Xs) fun x => F)
R : C
g : R ⟶ Y
W : C
σ : W ⟶ Y
ψ : R ⟶ ∐ fun i => X i
hW' : ψ ≫ Sigma.desc f = g
⊢ Coverage.saturate (extensiveCoverage C ⊔ regularCoverage C) R (Sieve.pullback g (Sieve.generate T))

Next tactic:
rw [← hW', Sieve.pullback_comp Z]