l3lab/ntp-mathlib huggingface dataset:
/--
For a precoherent category, any sieve that contains an `EffectiveEpiFamily` is a sieve of the
coherent topology.
Note: This is one direction of `mem_sieves_iff_hasEffectiveEpiFamily`, but is needed for the proof.
-/
theorem mem_sieves_of_hasEffectiveEpiFamily (S : Sieve X) :
    (∃ (α : Type) (_ : Fintype α) (Y : α → C) (π : (a : α) → (Y a ⟶ X)),
        EffectiveEpiFamily Y π ∧ (∀ a : α, (S.arrows) (π a)) ) →
          (S ∈ GrothendieckTopology.sieves (coherentTopology C) X) := by
  rintro ⟨α, ⟨h, ⟨Y, ⟨π, hπ⟩⟩⟩⟩
  have h_le : Sieve.generate (Presieve.ofArrows _ π) ≤ S := by
    rw [Sieve.sets_iff_generate (Presieve.ofArrows _ π) S]
    apply Presieve.le_of_factorsThru_sieve (Presieve.ofArrows (fun i => Y i) π) S _
    intro W g f
    use W, 𝟙 W
    

Proof state:
case h
C✝ : Type u_1
inst✝² : Category.{?u.3159, u_1} C✝
C : Type u_2
inst✝¹ : Category.{u_3, u_2} C
inst✝ : Precoherent C
X : C
S : Sieve X
α : Type
h : Fintype α
Y : α → C
π : (a : α) → Y a ⟶ X
hπ : EffectiveEpiFamily Y π ∧ ∀ (a : α), S.arrows (π a)
W : C
g : W ⟶ X
f : Presieve.ofArrows (fun i => Y i) π g
⊢ ∃ e, S.arrows e ∧ 𝟙 W ≫ e = g

Next tactic:
rcases f with ⟨i⟩
/--
For a precoherent category, any sieve that contains an `EffectiveEpiFamily` is a sieve of the
coherent topology.
Note: This is one direction of `mem_sieves_iff_hasEffectiveEpiFamily`, but is needed for the proof.
-/
theorem mem_sieves_of_hasEffectiveEpiFamily (S : Sieve X) :
    (∃ (α : Type) (_ : Fintype α) (Y : α → C) (π : (a : α) → (Y a ⟶ X)),
        EffectiveEpiFamily Y π ∧ (∀ a : α, (S.arrows) (π a)) ) →
          (S ∈ GrothendieckTopology.sieves (coherentTopology C) X) := by
  rintro ⟨α, ⟨h, ⟨Y, ⟨π, hπ⟩⟩⟩⟩
  have h_le : Sieve.generate (Presieve.ofArrows _ π) ≤ S := by
    rw [Sieve.sets_iff_generate (Presieve.ofArrows _ π) S]
    apply Presieve.le_of_factorsThru_sieve (Presieve.ofArrows (fun i => Y i) π) S _
    intro W g f
    use W, 𝟙 W
    rcases f with ⟨i⟩
    

Proof state:
case h.mk
C✝ : Type u_1
inst✝² : Category.{?u.3159, u_1} C✝
C : Type u_2
inst✝¹ : Category.{u_3, u_2} C
inst✝ : Precoherent C
X : C
S : Sieve X
α : Type
h : Fintype α
Y✝ : α → C
π : (a : α) → Y✝ a ⟶ X
hπ : EffectiveEpiFamily Y✝ π ∧ ∀ (a : α), S.arrows (π a)
Y : C
i : α
⊢ ∃ e, S.arrows e ∧ 𝟙 (Y✝ i) ≫ e = π i

Next tactic:
exact ⟨π i, ⟨hπ.2 i,Category.id_comp (π i) ⟩⟩
/--
For a precoherent category, any sieve that contains an `EffectiveEpiFamily` is a sieve of the
coherent topology.
Note: This is one direction of `mem_sieves_iff_hasEffectiveEpiFamily`, but is needed for the proof.
-/
theorem mem_sieves_of_hasEffectiveEpiFamily (S : Sieve X) :
    (∃ (α : Type) (_ : Fintype α) (Y : α → C) (π : (a : α) → (Y a ⟶ X)),
        EffectiveEpiFamily Y π ∧ (∀ a : α, (S.arrows) (π a)) ) →
          (S ∈ GrothendieckTopology.sieves (coherentTopology C) X) := by
  rintro ⟨α, ⟨h, ⟨Y, ⟨π, hπ⟩⟩⟩⟩
  have h_le : Sieve.generate (Presieve.ofArrows _ π) ≤ S := by
    rw [Sieve.sets_iff_generate (Presieve.ofArrows _ π) S]
    apply Presieve.le_of_factorsThru_sieve (Presieve.ofArrows (fun i => Y i) π) S _
    intro W g f
    use W, 𝟙 W
    rcases f with ⟨i⟩
    exact ⟨π i, ⟨hπ.2 i,Category.id_comp (π i) ⟩⟩
  

Proof state:
case intro.intro.intro.intro
C✝ : Type u_1
inst✝² : Category.{?u.3159, u_1} C✝
C : Type u_2
inst✝¹ : Category.{u_3, u_2} C
inst✝ : Precoherent C
X : C
S : Sieve X
α : Type
h : Fintype α
Y : α → C
π : (a : α) → Y a ⟶ X
hπ : EffectiveEpiFamily Y π ∧ ∀ (a : α), S.arrows (π a)
h_le : Sieve.generate (Presieve.ofArrows (fun i => Y i) π) ≤ S
⊢ S ∈ GrothendieckTopology.sieves (coherentTopology C) X

Next tactic:
apply Coverage.saturate_of_superset (coherentCoverage C) h_le
/--
For a precoherent category, any sieve that contains an `EffectiveEpiFamily` is a sieve of the
coherent topology.
Note: This is one direction of `mem_sieves_iff_hasEffectiveEpiFamily`, but is needed for the proof.
-/
theorem mem_sieves_of_hasEffectiveEpiFamily (S : Sieve X) :
    (∃ (α : Type) (_ : Fintype α) (Y : α → C) (π : (a : α) → (Y a ⟶ X)),
        EffectiveEpiFamily Y π ∧ (∀ a : α, (S.arrows) (π a)) ) →
          (S ∈ GrothendieckTopology.sieves (coherentTopology C) X) := by
  rintro ⟨α, ⟨h, ⟨Y, ⟨π, hπ⟩⟩⟩⟩
  have h_le : Sieve.generate (Presieve.ofArrows _ π) ≤ S := by
    rw [Sieve.sets_iff_generate (Presieve.ofArrows _ π) S]
    apply Presieve.le_of_factorsThru_sieve (Presieve.ofArrows (fun i => Y i) π) S _
    intro W g f
    use W, 𝟙 W
    rcases f with ⟨i⟩
    exact ⟨π i, ⟨hπ.2 i,Category.id_comp (π i) ⟩⟩
  apply Coverage.saturate_of_superset (coherentCoverage C) h_le
  

Proof state:
case intro.intro.intro.intro
C✝ : Type u_1
inst✝² : Category.{?u.3159, u_1} C✝
C : Type u_2
inst✝¹ : Category.{u_3, u_2} C
inst✝ : Precoherent C
X : C
S : Sieve X
α : Type
h : Fintype α
Y : α → C
π : (a : α) → Y a ⟶ X
hπ : EffectiveEpiFamily Y π ∧ ∀ (a : α), S.arrows (π a)
h_le : Sieve.generate (Presieve.ofArrows (fun i => Y i) π) ≤ S
⊢ Coverage.saturate (coherentCoverage C) X (Sieve.generate (Presieve.ofArrows (fun i => Y i) π))

Next tactic:
exact Coverage.saturate.of X _ ⟨α, inferInstance, Y, π, ⟨rfl, hπ.1⟩⟩
/-- Every Yoneda-presheaf is a sheaf for the coherent topology. -/
theorem isSheaf_yoneda_obj (W : C) : Presieve.IsSheaf (coherentTopology C) (yoneda.obj W) := by
  

Proof state:
C✝ : Type u_1
inst✝² : Category.{?u.4918, u_1} C✝
C : Type u_2
inst✝¹ : Category.{u_3, u_2} C
inst✝ : Precoherent C
X W : C
⊢ Presieve.IsSheaf (coherentTopology C) (yoneda.obj W)

Next tactic:
rw [isSheaf_coherent]
/-- Every Yoneda-presheaf is a sheaf for the coherent topology. -/
theorem isSheaf_yoneda_obj (W : C) : Presieve.IsSheaf (coherentTopology C) (yoneda.obj W) := by
  rw [isSheaf_coherent]
  

Proof state:
C✝ : Type u_1
inst✝² : Category.{?u.4918, u_1} C✝
C : Type u_2
inst✝¹ : Category.{u_3, u_2} C
inst✝ : Precoherent C
X W : C
⊢ ∀ (B : C) (α : Type) [inst : Fintype α] (X : α → C) (π : (a : α) → X a ⟶ B),
    EffectiveEpiFamily X π → Presieve.IsSheafFor (yoneda.obj W) (Presieve.ofArrows X π)

Next tactic:
intro X α _ Y π H
/-- Every Yoneda-presheaf is a sheaf for the coherent topology. -/
theorem isSheaf_yoneda_obj (W : C) : Presieve.IsSheaf (coherentTopology C) (yoneda.obj W) := by
  rw [isSheaf_coherent]
  intro X α _ Y π H
  

Proof state:
C✝ : Type u_1
inst✝³ : Category.{?u.4918, u_1} C✝
C : Type u_2
inst✝² : Category.{u_3, u_2} C
inst✝¹ : Precoherent C
X✝ W X : C
α : Type
inst✝ : Fintype α
Y : α → C
π : (a : α) → Y a ⟶ X
H : EffectiveEpiFamily Y π
⊢ Presieve.IsSheafFor (yoneda.obj W) (Presieve.ofArrows Y π)

Next tactic:
have h_colim := isColimitOfEffectiveEpiFamilyStruct Y π H.effectiveEpiFamily.some
/-- Every Yoneda-presheaf is a sheaf for the coherent topology. -/
theorem isSheaf_yoneda_obj (W : C) : Presieve.IsSheaf (coherentTopology C) (yoneda.obj W) := by
  rw [isSheaf_coherent]
  intro X α _ Y π H
  have h_colim := isColimitOfEffectiveEpiFamilyStruct Y π H.effectiveEpiFamily.some
  

Proof state:
C✝ : Type u_1
inst✝³ : Category.{?u.4918, u_1} C✝
C : Type u_2
inst✝² : Category.{u_3, u_2} C
inst✝¹ : Precoherent C
X✝ W X : C
α : Type
inst✝ : Fintype α
Y : α → C
π : (a : α) → Y a ⟶ X
H : EffectiveEpiFamily Y π
h_colim : IsColimit (Presieve.cocone (Sieve.generateFamily Y π).arrows)
⊢ Presieve.IsSheafFor (yoneda.obj W) (Presieve.ofArrows Y π)

Next tactic:
rw [← Sieve.generateFamily_eq] at h_colim
/-- Every Yoneda-presheaf is a sheaf for the coherent topology. -/
theorem isSheaf_yoneda_obj (W : C) : Presieve.IsSheaf (coherentTopology C) (yoneda.obj W) := by
  rw [isSheaf_coherent]
  intro X α _ Y π H
  have h_colim := isColimitOfEffectiveEpiFamilyStruct Y π H.effectiveEpiFamily.some
  rw [← Sieve.generateFamily_eq] at h_colim
  

Proof state:
C✝ : Type u_1
inst✝³ : Category.{?u.4918, u_1} C✝
C : Type u_2
inst✝² : Category.{u_3, u_2} C
inst✝¹ : Precoherent C
X✝ W X : C
α : Type
inst✝ : Fintype α
Y : α → C
π : (a : α) → Y a ⟶ X
H : EffectiveEpiFamily Y π
h_colim : IsColimit (Presieve.cocone (Sieve.generate (Presieve.ofArrows Y π)).arrows)
⊢ Presieve.IsSheafFor (yoneda.obj W) (Presieve.ofArrows Y π)

Next tactic:
intro x hx
/-- Every Yoneda-presheaf is a sheaf for the coherent topology. -/
theorem isSheaf_yoneda_obj (W : C) : Presieve.IsSheaf (coherentTopology C) (yoneda.obj W) := by
  rw [isSheaf_coherent]
  intro X α _ Y π H
  have h_colim := isColimitOfEffectiveEpiFamilyStruct Y π H.effectiveEpiFamily.some
  rw [← Sieve.generateFamily_eq] at h_colim
  intro x hx
  

Proof state:
C✝ : Type u_1
inst✝³ : Category.{?u.4918, u_1} C✝
C : Type u_2
inst✝² : Category.{u_3, u_2} C
inst✝¹ : Precoherent C
X✝ W X : C
α : Type
inst✝ : Fintype α
Y : α → C
π : (a : α) → Y a ⟶ X
H : EffectiveEpiFamily Y π
h_colim : IsColimit (Presieve.cocone (Sieve.generate (Presieve.ofArrows Y π)).arrows)
x : Presieve.FamilyOfElements (yoneda.obj W) (Presieve.ofArrows Y π)
hx : Presieve.FamilyOfElements.Compatible x
⊢ ∃! t, Presieve.FamilyOfElements.IsAmalgamation x t

Next tactic:
let x_ext := Presieve.FamilyOfElements.sieveExtend x
/-- Every Yoneda-presheaf is a sheaf for the coherent topology. -/
theorem isSheaf_yoneda_obj (W : C) : Presieve.IsSheaf (coherentTopology C) (yoneda.obj W) := by
  rw [isSheaf_coherent]
  intro X α _ Y π H
  have h_colim := isColimitOfEffectiveEpiFamilyStruct Y π H.effectiveEpiFamily.some
  rw [← Sieve.generateFamily_eq] at h_colim
  intro x hx
  let x_ext := Presieve.FamilyOfElements.sieveExtend x
  

Proof state:
C✝ : Type u_1
inst✝³ : Category.{?u.4918, u_1} C✝
C : Type u_2
inst✝² : Category.{u_3, u_2} C
inst✝¹ : Precoherent C
X✝ W X : C
α : Type
inst✝ : Fintype α
Y : α → C
π : (a : α) → Y a ⟶ X
H : EffectiveEpiFamily Y π
h_colim : IsColimit (Presieve.cocone (Sieve.generate (Presieve.ofArrows Y π)).arrows)
x : Presieve.FamilyOfElements (yoneda.obj W) (Presieve.ofArrows Y π)
hx : Presieve.FamilyOfElements.Compatible x
x_ext : Presieve.FamilyOfElements (yoneda.obj W) (Sieve.generate (Presieve.ofArrows Y π)).arrows :=
  Presieve.FamilyOfElements.sieveExtend x
⊢ ∃! t, Presieve.FamilyOfElements.IsAmalgamation x t

Next tactic:
have hx_ext := Presieve.FamilyOfElements.Compatible.sieveExtend hx
/-- Every Yoneda-presheaf is a sheaf for the coherent topology. -/
theorem isSheaf_yoneda_obj (W : C) : Presieve.IsSheaf (coherentTopology C) (yoneda.obj W) := by
  rw [isSheaf_coherent]
  intro X α _ Y π H
  have h_colim := isColimitOfEffectiveEpiFamilyStruct Y π H.effectiveEpiFamily.some
  rw [← Sieve.generateFamily_eq] at h_colim
  intro x hx
  let x_ext := Presieve.FamilyOfElements.sieveExtend x
  have hx_ext := Presieve.FamilyOfElements.Compatible.sieveExtend hx
  

Proof state:
C✝ : Type u_1
inst✝³ : Category.{?u.4918, u_1} C✝
C : Type u_2
inst✝² : Category.{u_3, u_2} C
inst✝¹ : Precoherent C
X✝ W X : C
α : Type
inst✝ : Fintype α
Y : α → C
π : (a : α) → Y a ⟶ X
H : EffectiveEpiFamily Y π
h_colim : IsColimit (Presieve.cocone (Sieve.generate (Presieve.ofArrows Y π)).arrows)
x : Presieve.FamilyOfElements (yoneda.obj W) (Presieve.ofArrows Y π)
hx : Presieve.FamilyOfElements.Compatible x
x_ext : Presieve.FamilyOfElements (yoneda.obj W) (Sieve.generate (Presieve.ofArrows Y π)).arrows :=
  Presieve.FamilyOfElements.sieveExtend x
hx_ext : Presieve.FamilyOfElements.Compatible (Presieve.FamilyOfElements.sieveExtend x)
⊢ ∃! t, Presieve.FamilyOfElements.IsAmalgamation x t

Next tactic:
let S := Sieve.generate (Presieve.ofArrows Y π)
/-- Every Yoneda-presheaf is a sheaf for the coherent topology. -/
theorem isSheaf_yoneda_obj (W : C) : Presieve.IsSheaf (coherentTopology C) (yoneda.obj W) := by
  rw [isSheaf_coherent]
  intro X α _ Y π H
  have h_colim := isColimitOfEffectiveEpiFamilyStruct Y π H.effectiveEpiFamily.some
  rw [← Sieve.generateFamily_eq] at h_colim
  intro x hx
  let x_ext := Presieve.FamilyOfElements.sieveExtend x
  have hx_ext := Presieve.FamilyOfElements.Compatible.sieveExtend hx
  let S := Sieve.generate (Presieve.ofArrows Y π)
  

Proof state:
C✝ : Type u_1
inst✝³ : Category.{?u.4918, u_1} C✝
C : Type u_2
inst✝² : Category.{u_3, u_2} C
inst✝¹ : Precoherent C
X✝ W X : C
α : Type
inst✝ : Fintype α
Y : α → C
π : (a : α) → Y a ⟶ X
H : EffectiveEpiFamily Y π
h_colim : IsColimit (Presieve.cocone (Sieve.generate (Presieve.ofArrows Y π)).arrows)
x : Presieve.FamilyOfElements (yoneda.obj W) (Presieve.ofArrows Y π)
hx : Presieve.FamilyOfElements.Compatible x
x_ext : Presieve.FamilyOfElements (yoneda.obj W) (Sieve.generate (Presieve.ofArrows Y π)).arrows :=
  Presieve.FamilyOfElements.sieveExtend x
hx_ext : Presieve.FamilyOfElements.Compatible (Presieve.FamilyOfElements.sieveExtend x)
S : Sieve X := Sieve.generate (Presieve.ofArrows Y π)
⊢ ∃! t, Presieve.FamilyOfElements.IsAmalgamation x t

Next tactic:
obtain ⟨t, t_amalg, t_uniq⟩ : ∃! t, x_ext.IsAmalgamation t :=
    (Sieve.forallYonedaIsSheaf_iff_colimit S).mpr ⟨h_colim⟩ W x_ext hx_ext
/-- Every Yoneda-presheaf is a sheaf for the coherent topology. -/
theorem isSheaf_yoneda_obj (W : C) : Presieve.IsSheaf (coherentTopology C) (yoneda.obj W) := by
  rw [isSheaf_coherent]
  intro X α _ Y π H
  have h_colim := isColimitOfEffectiveEpiFamilyStruct Y π H.effectiveEpiFamily.some
  rw [← Sieve.generateFamily_eq] at h_colim
  intro x hx
  let x_ext := Presieve.FamilyOfElements.sieveExtend x
  have hx_ext := Presieve.FamilyOfElements.Compatible.sieveExtend hx
  let S := Sieve.generate (Presieve.ofArrows Y π)
  obtain ⟨t, t_amalg, t_uniq⟩ : ∃! t, x_ext.IsAmalgamation t :=
    (Sieve.forallYonedaIsSheaf_iff_colimit S).mpr ⟨h_colim⟩ W x_ext hx_ext
  

Proof state:
case intro.intro
C✝ : Type u_1
inst✝³ : Category.{?u.4918, u_1} C✝
C : Type u_2
inst✝² : Category.{u_3, u_2} C
inst✝¹ : Precoherent C
X✝ W X : C
α : Type
inst✝ : Fintype α
Y : α → C
π : (a : α) → Y a ⟶ X
H : EffectiveEpiFamily Y π
h_colim : IsColimit (Presieve.cocone (Sieve.generate (Presieve.ofArrows Y π)).arrows)
x : Presieve.FamilyOfElements (yoneda.obj W) (Presieve.ofArrows Y π)
hx : Presieve.FamilyOfElements.Compatible x
x_ext : Presieve.FamilyOfElements (yoneda.obj W) (Sieve.generate (Presieve.ofArrows Y π)).arrows :=
  Presieve.FamilyOfElements.sieveExtend x
hx_ext : Presieve.FamilyOfElements.Compatible (Presieve.FamilyOfElements.sieveExtend x)
S : Sieve X := Sieve.generate (Presieve.ofArrows Y π)
t : (yoneda.obj W).obj (Opposite.op X)
t_amalg : Presieve.FamilyOfElements.IsAmalgamation x_ext t
t_uniq :
  ∀ (y : (yoneda.obj W).obj (Opposite.op X)), (fun t => Presieve.FamilyOfElements.IsAmalgamation x_ext t) y → y = t
⊢ ∃! t, Presieve.FamilyOfElements.IsAmalgamation x t

Next tactic:
refine ⟨t, ?_, ?_⟩
/-- Every Yoneda-presheaf is a sheaf for the coherent topology. -/
theorem isSheaf_yoneda_obj (W : C) : Presieve.IsSheaf (coherentTopology C) (yoneda.obj W) := by
  rw [isSheaf_coherent]
  intro X α _ Y π H
  have h_colim := isColimitOfEffectiveEpiFamilyStruct Y π H.effectiveEpiFamily.some
  rw [← Sieve.generateFamily_eq] at h_colim
  intro x hx
  let x_ext := Presieve.FamilyOfElements.sieveExtend x
  have hx_ext := Presieve.FamilyOfElements.Compatible.sieveExtend hx
  let S := Sieve.generate (Presieve.ofArrows Y π)
  obtain ⟨t, t_amalg, t_uniq⟩ : ∃! t, x_ext.IsAmalgamation t :=
    (Sieve.forallYonedaIsSheaf_iff_colimit S).mpr ⟨h_colim⟩ W x_ext hx_ext
  refine ⟨t, ?_, ?_⟩
  · 

Proof state:
case intro.intro.refine_1
C✝ : Type u_1
inst✝³ : Category.{?u.4918, u_1} C✝
C : Type u_2
inst✝² : Category.{u_3, u_2} C
inst✝¹ : Precoherent C
X✝ W X : C
α : Type
inst✝ : Fintype α
Y : α → C
π : (a : α) → Y a ⟶ X
H : EffectiveEpiFamily Y π
h_colim : IsColimit (Presieve.cocone (Sieve.generate (Presieve.ofArrows Y π)).arrows)
x : Presieve.FamilyOfElements (yoneda.obj W) (Presieve.ofArrows Y π)
hx : Presieve.FamilyOfElements.Compatible x
x_ext : Presieve.FamilyOfElements (yoneda.obj W) (Sieve.generate (Presieve.ofArrows Y π)).arrows :=
  Presieve.FamilyOfElements.sieveExtend x
hx_ext : Presieve.FamilyOfElements.Compatible (Presieve.FamilyOfElements.sieveExtend x)
S : Sieve X := Sieve.generate (Presieve.ofArrows Y π)
t : (yoneda.obj W).obj (Opposite.op X)
t_amalg : Presieve.FamilyOfElements.IsAmalgamation x_ext t
t_uniq :
  ∀ (y : (yoneda.obj W).obj (Opposite.op X)), (fun t => Presieve.FamilyOfElements.IsAmalgamation x_ext t) y → y = t
⊢ (fun t => Presieve.FamilyOfElements.IsAmalgamation x t) t

Next tactic:
convert Presieve.isAmalgamation_restrict (Sieve.le_generate (Presieve.ofArrows Y π)) _ _ t_amalg
/-- Every Yoneda-presheaf is a sheaf for the coherent topology. -/
theorem isSheaf_yoneda_obj (W : C) : Presieve.IsSheaf (coherentTopology C) (yoneda.obj W) := by
  rw [isSheaf_coherent]
  intro X α _ Y π H
  have h_colim := isColimitOfEffectiveEpiFamilyStruct Y π H.effectiveEpiFamily.some
  rw [← Sieve.generateFamily_eq] at h_colim
  intro x hx
  let x_ext := Presieve.FamilyOfElements.sieveExtend x
  have hx_ext := Presieve.FamilyOfElements.Compatible.sieveExtend hx
  let S := Sieve.generate (Presieve.ofArrows Y π)
  obtain ⟨t, t_amalg, t_uniq⟩ : ∃! t, x_ext.IsAmalgamation t :=
    (Sieve.forallYonedaIsSheaf_iff_colimit S).mpr ⟨h_colim⟩ W x_ext hx_ext
  refine ⟨t, ?_, ?_⟩
  · convert Presieve.isAmalgamation_restrict (Sieve.le_generate (Presieve.ofArrows Y π)) _ _ t_amalg
    

Proof state:
case h.e.h.e'_6.h.h.h
C✝ : Type u_1
inst✝³ : Category.{?u.4918, u_1} C✝
C : Type u_2
inst✝² : Category.{u_3, u_2} C
inst✝¹ : Precoherent C
X✝ W X : C
α : Type
inst✝ : Fintype α
Y : α → C
π : (a : α) → Y a ⟶ X
H : EffectiveEpiFamily Y π
h_colim : IsColimit (Presieve.cocone (Sieve.generate (Presieve.ofArrows Y π)).arrows)
x : Presieve.FamilyOfElements (yoneda.obj W) (Presieve.ofArrows Y π)
hx : Presieve.FamilyOfElements.Compatible x
x_ext : Presieve.FamilyOfElements (yoneda.obj W) (Sieve.generate (Presieve.ofArrows Y π)).arrows :=
  Presieve.FamilyOfElements.sieveExtend x
hx_ext : Presieve.FamilyOfElements.Compatible (Presieve.FamilyOfElements.sieveExtend x)
S : Sieve X := Sieve.generate (Presieve.ofArrows Y π)
t : (yoneda.obj W).obj (Opposite.op X)
t_amalg : Presieve.FamilyOfElements.IsAmalgamation x_ext t
t_uniq :
  ∀ (y : (yoneda.obj W).obj (Opposite.op X)), (fun t => Presieve.FamilyOfElements.IsAmalgamation x_ext t) y → y = t
⊢ x =
    Presieve.FamilyOfElements.restrict (_ : Presieve.ofArrows Y π ≤ (Sieve.generate (Presieve.ofArrows Y π)).arrows)
      x_ext

Next tactic:
exact (Presieve.restrict_extend hx).symm
/-- Every Yoneda-presheaf is a sheaf for the coherent topology. -/
theorem isSheaf_yoneda_obj (W : C) : Presieve.IsSheaf (coherentTopology C) (yoneda.obj W) := by
  rw [isSheaf_coherent]
  intro X α _ Y π H
  have h_colim := isColimitOfEffectiveEpiFamilyStruct Y π H.effectiveEpiFamily.some
  rw [← Sieve.generateFamily_eq] at h_colim
  intro x hx
  let x_ext := Presieve.FamilyOfElements.sieveExtend x
  have hx_ext := Presieve.FamilyOfElements.Compatible.sieveExtend hx
  let S := Sieve.generate (Presieve.ofArrows Y π)
  obtain ⟨t, t_amalg, t_uniq⟩ : ∃! t, x_ext.IsAmalgamation t :=
    (Sieve.forallYonedaIsSheaf_iff_colimit S).mpr ⟨h_colim⟩ W x_ext hx_ext
  refine ⟨t, ?_, ?_⟩
  · convert Presieve.isAmalgamation_restrict (Sieve.le_generate (Presieve.ofArrows Y π)) _ _ t_amalg
    exact (Presieve.restrict_extend hx).symm
  · 

Proof state:
case intro.intro.refine_2
C✝ : Type u_1
inst✝³ : Category.{?u.4918, u_1} C✝
C : Type u_2
inst✝² : Category.{u_3, u_2} C
inst✝¹ : Precoherent C
X✝ W X : C
α : Type
inst✝ : Fintype α
Y : α → C
π : (a : α) → Y a ⟶ X
H : EffectiveEpiFamily Y π
h_colim : IsColimit (Presieve.cocone (Sieve.generate (Presieve.ofArrows Y π)).arrows)
x : Presieve.FamilyOfElements (yoneda.obj W) (Presieve.ofArrows Y π)
hx : Presieve.FamilyOfElements.Compatible x
x_ext : Presieve.FamilyOfElements (yoneda.obj W) (Sieve.generate (Presieve.ofArrows Y π)).arrows :=
  Presieve.FamilyOfElements.sieveExtend x
hx_ext : Presieve.FamilyOfElements.Compatible (Presieve.FamilyOfElements.sieveExtend x)
S : Sieve X := Sieve.generate (Presieve.ofArrows Y π)
t : (yoneda.obj W).obj (Opposite.op X)
t_amalg : Presieve.FamilyOfElements.IsAmalgamation x_ext t
t_uniq :
  ∀ (y : (yoneda.obj W).obj (Opposite.op X)), (fun t => Presieve.FamilyOfElements.IsAmalgamation x_ext t) y → y = t
⊢ ∀ (y : (yoneda.obj W).obj (Opposite.op X)), (fun t => Presieve.FamilyOfElements.IsAmalgamation x t) y → y = t

Next tactic:
exact fun y hy ↦ t_uniq y <| Presieve.isAmalgamation_sieveExtend x y hy
/--
Effective epi families in a precoherent category are transitive, in the sense that an
`EffectiveEpiFamily` and an `EffectiveEpiFamily` over each member, the composition is an
`EffectiveEpiFamily`.
Note: The finiteness condition is an artifact of the proof and is probably unnecessary.
-/
theorem EffectiveEpiFamily.transitive_of_finite {α : Type} [Fintype α] {Y : α → C}
    (π : (a : α) → (Y a ⟶ X)) (h : EffectiveEpiFamily Y π) {β : α → Type} [∀ (a: α), Fintype (β a)]
    {Y_n : (a : α) → β a → C} (π_n : (a : α) → (b : β a) → (Y_n a b ⟶ Y a))
    (H : ∀ a, EffectiveEpiFamily (Y_n a) (π_n a)) :
    EffectiveEpiFamily
      (fun (c : Σ a, β a) => Y_n c.fst c.snd) (fun c => π_n c.fst c.snd ≫ π c.fst) := by
  

Proof state:
C✝ : Type u_1
inst✝⁴ : Category.{?u.13173, u_1} C✝
C : Type u_2
inst✝³ : Category.{u_3, u_2} C
inst✝² : Precoherent C
X : C
α : Type
inst✝¹ : Fintype α
Y : α → C
π : (a : α) → Y a ⟶ X
h : EffectiveEpiFamily Y π
β : α → Type
inst✝ : (a : α) → Fintype (β a)
Y_n : (a : α) → β a → C
π_n : (a : α) → (b : β a) → Y_n a b ⟶ Y a
H : ∀ (a : α), EffectiveEpiFamily (Y_n a) (π_n a)
⊢ EffectiveEpiFamily (fun c => Y_n c.fst c.snd) fun c => π_n c.fst c.snd ≫ π c.fst

Next tactic:
rw [← Sieve.effectiveEpimorphic_family]
/--
Effective epi families in a precoherent category are transitive, in the sense that an
`EffectiveEpiFamily` and an `EffectiveEpiFamily` over each member, the composition is an
`EffectiveEpiFamily`.
Note: The finiteness condition is an artifact of the proof and is probably unnecessary.
-/
theorem EffectiveEpiFamily.transitive_of_finite {α : Type} [Fintype α] {Y : α → C}
    (π : (a : α) → (Y a ⟶ X)) (h : EffectiveEpiFamily Y π) {β : α → Type} [∀ (a: α), Fintype (β a)]
    {Y_n : (a : α) → β a → C} (π_n : (a : α) → (b : β a) → (Y_n a b ⟶ Y a))
    (H : ∀ a, EffectiveEpiFamily (Y_n a) (π_n a)) :
    EffectiveEpiFamily
      (fun (c : Σ a, β a) => Y_n c.fst c.snd) (fun c => π_n c.fst c.snd ≫ π c.fst) := by
  rw [← Sieve.effectiveEpimorphic_family]
  

Proof state:
C✝ : Type u_1
inst✝⁴ : Category.{?u.13173, u_1} C✝
C : Type u_2
inst✝³ : Category.{u_3, u_2} C
inst✝² : Precoherent C
X : C
α : Type
inst✝¹ : Fintype α
Y : α → C
π : (a : α) → Y a ⟶ X
h : EffectiveEpiFamily Y π
β : α → Type
inst✝ : (a : α) → Fintype (β a)
Y_n : (a : α) → β a → C
π_n : (a : α) → (b : β a) → Y_n a b ⟶ Y a
H : ∀ (a : α), EffectiveEpiFamily (Y_n a) (π_n a)
⊢ Presieve.EffectiveEpimorphic (Presieve.ofArrows (fun c => Y_n c.fst c.snd) fun c => π_n c.fst c.snd ≫ π c.fst)

Next tactic:
suffices h₂ : (Sieve.generate (Presieve.ofArrows (fun (⟨a, b⟩ : Σ _, β _) => Y_n a b)
        (fun ⟨a,b⟩ => π_n a b ≫ π a))) ∈ GrothendieckTopology.sieves (coherentTopology C) X by
    change Nonempty _
    rw [← Sieve.forallYonedaIsSheaf_iff_colimit]
    exact fun W => coherentTopology.isSheaf_yoneda_obj W _ h₂