l3lab/ntp-mathlib huggingface dataset:
/-- The effective epi family structure on the identity -/
def effectiveEpiFamilyStructId {α : Unit → C} : EffectiveEpiFamilyStruct α (fun _ => 𝟙 (α ())) where
  desc := fun e _ => e ()
  fac := by aesop_cat
  uniq := by 

Proof state:
C : Type u_1
inst✝ : Category.{?u.44295, u_1} C
α : Unit → C
⊢ ∀ {W : C} (e : (a : Unit) → α a ⟶ W)
    (h :
      ∀ {Z : C} (a₁ a₂ : Unit) (g₁ : Z ⟶ α a₁) (g₂ : Z ⟶ α a₂), g₁ ≫ 𝟙 (α ()) = g₂ ≫ 𝟙 (α ()) → g₁ ≫ e a₁ = g₂ ≫ e a₂)
    (m : α () ⟶ W),
    (∀ (a : Unit), 𝟙 (α ()) ≫ m = e a) →
      m =
        (fun {W} e x => e ()) e
          (_ :
            ∀ {Z : C} (a₁ a₂ : Unit) (g₁ : Z ⟶ α a₁) (g₂ : Z ⟶ α a₂),
              g₁ ≫ 𝟙 (α ()) = g₂ ≫ 𝟙 (α ()) → g₁ ≫ e a₁ = g₂ ≫ e a₂)

Next tactic:
aesop_cat
example {B W : C} {α : Type*} (X : α → C) (π : (a : α) → (X a ⟶ B))
    [EffectiveEpiFamily X π] (e : (a : α) → (X a ⟶ W))
    (h : ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂),
      g₁ ≫ π _ = g₂ ≫ π _ → g₁ ≫ e _ = g₂ ≫ e _) (a : α) :
    π a ≫ EffectiveEpiFamily.desc X π e h = e a :=
  by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.52521, u_1} C
B W : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
inst✝ : EffectiveEpiFamily X π
e : (a : α) → X a ⟶ W
h : ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂
a : α
⊢ π a ≫
      EffectiveEpiFamily.desc X π e
        (_ : ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) =
    e a

Next tactic:
simp
example {B W Q : C} {α : Type*} (X : α → C) (π : (a : α) → (X a ⟶ B))
    [EffectiveEpiFamily X π] (e : (a : α) → (X a ⟶ W))
    (h : ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂),
      g₁ ≫ π _ = g₂ ≫ π _ → g₁ ≫ e _ = g₂ ≫ e _) (a : α)
    (q : W ⟶ Q) :
    π a ≫ EffectiveEpiFamily.desc X π e h ≫ q = e a ≫ q :=
  by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.53522, u_1} C
B W Q : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
inst✝ : EffectiveEpiFamily X π
e : (a : α) → X a ⟶ W
h : ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂
a : α
q : W ⟶ Q
⊢ π a ≫
      EffectiveEpiFamily.desc X π e
          (_ : ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) ≫
        q =
    e a ≫ q

Next tactic:
simp
lemma EffectiveEpiFamily.hom_ext {B W : C} {α : Type*} (X : α → C) (π : (a : α) → (X a ⟶ B))
    [EffectiveEpiFamily X π] (m₁ m₂ : B ⟶ W) (h : ∀ a, π a ≫ m₁ = π a ≫ m₂) :
    m₁ = m₂ := by
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_3, u_1} C
B W : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
inst✝ : EffectiveEpiFamily X π
m₁ m₂ : B ⟶ W
h : ∀ (a : α), π a ≫ m₁ = π a ≫ m₂
⊢ m₁ = m₂

Next tactic:
have : m₂ = EffectiveEpiFamily.desc X π (fun a => π a ≫ m₂)
      (fun a₁ a₂ g₁ g₂ h => by simp only [← Category.assoc, h]) := by
    apply EffectiveEpiFamily.uniq; intro; rfl
lemma EffectiveEpiFamily.hom_ext {B W : C} {α : Type*} (X : α → C) (π : (a : α) → (X a ⟶ B))
    [EffectiveEpiFamily X π] (m₁ m₂ : B ⟶ W) (h : ∀ a, π a ≫ m₁ = π a ≫ m₂) :
    m₁ = m₂ := by
  have : m₂ = EffectiveEpiFamily.desc X π (fun a => π a ≫ m₂)
      (fun a₁ a₂ g₁ g₂ h => by 

Proof state:
C : Type u_1
inst✝¹ : Category.{u_3, u_1} C
B W : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
inst✝ : EffectiveEpiFamily X π
m₁ m₂ : B ⟶ W
h✝ : ∀ (a : α), π a ≫ m₁ = π a ≫ m₂
Z✝ : C
a₁ a₂ : α
g₁ : Z✝ ⟶ X a₁
g₂ : Z✝ ⟶ X a₂
h : g₁ ≫ π a₁ = g₂ ≫ π a₂
⊢ g₁ ≫ (fun a => π a ≫ m₂) a₁ = g₂ ≫ (fun a => π a ≫ m₂) a₂

Next tactic:
simp only [← Category.assoc, h]
lemma EffectiveEpiFamily.hom_ext {B W : C} {α : Type*} (X : α → C) (π : (a : α) → (X a ⟶ B))
    [EffectiveEpiFamily X π] (m₁ m₂ : B ⟶ W) (h : ∀ a, π a ≫ m₁ = π a ≫ m₂) :
    m₁ = m₂ := by
  have : m₂ = EffectiveEpiFamily.desc X π (fun a => π a ≫ m₂)
      (fun a₁ a₂ g₁ g₂ h => by simp only [← Category.assoc, h]) := by
    

Proof state:
C : Type u_1
inst✝¹ : Category.{u_3, u_1} C
B W : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
inst✝ : EffectiveEpiFamily X π
m₁ m₂ : B ⟶ W
h : ∀ (a : α), π a ≫ m₁ = π a ≫ m₂
⊢ m₂ =
    desc X π (fun a => π a ≫ m₂)
      (_ :
        ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ π a₁ ≫ m₂ = g₂ ≫ π a₂ ≫ m₂)

Next tactic:
apply EffectiveEpiFamily.uniq
lemma EffectiveEpiFamily.hom_ext {B W : C} {α : Type*} (X : α → C) (π : (a : α) → (X a ⟶ B))
    [EffectiveEpiFamily X π] (m₁ m₂ : B ⟶ W) (h : ∀ a, π a ≫ m₁ = π a ≫ m₂) :
    m₁ = m₂ := by
  have : m₂ = EffectiveEpiFamily.desc X π (fun a => π a ≫ m₂)
      (fun a₁ a₂ g₁ g₂ h => by simp only [← Category.assoc, h]) := by
    apply EffectiveEpiFamily.uniq; 

Proof state:
case hm
C : Type u_1
inst✝¹ : Category.{u_3, u_1} C
B W : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
inst✝ : EffectiveEpiFamily X π
m₁ m₂ : B ⟶ W
h : ∀ (a : α), π a ≫ m₁ = π a ≫ m₂
⊢ ∀ (a : α), π a ≫ m₂ = π a ≫ m₂

Next tactic:
intro
lemma EffectiveEpiFamily.hom_ext {B W : C} {α : Type*} (X : α → C) (π : (a : α) → (X a ⟶ B))
    [EffectiveEpiFamily X π] (m₁ m₂ : B ⟶ W) (h : ∀ a, π a ≫ m₁ = π a ≫ m₂) :
    m₁ = m₂ := by
  have : m₂ = EffectiveEpiFamily.desc X π (fun a => π a ≫ m₂)
      (fun a₁ a₂ g₁ g₂ h => by simp only [← Category.assoc, h]) := by
    apply EffectiveEpiFamily.uniq; intro; 

Proof state:
case hm
C : Type u_1
inst✝¹ : Category.{u_3, u_1} C
B W : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
inst✝ : EffectiveEpiFamily X π
m₁ m₂ : B ⟶ W
h : ∀ (a : α), π a ≫ m₁ = π a ≫ m₂
a✝ : α
⊢ π a✝ ≫ m₂ = π a✝ ≫ m₂

Next tactic:
rfl
lemma EffectiveEpiFamily.hom_ext {B W : C} {α : Type*} (X : α → C) (π : (a : α) → (X a ⟶ B))
    [EffectiveEpiFamily X π] (m₁ m₂ : B ⟶ W) (h : ∀ a, π a ≫ m₁ = π a ≫ m₂) :
    m₁ = m₂ := by
  have : m₂ = EffectiveEpiFamily.desc X π (fun a => π a ≫ m₂)
      (fun a₁ a₂ g₁ g₂ h => by simp only [← Category.assoc, h]) := by
    apply EffectiveEpiFamily.uniq; intro; rfl
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_3, u_1} C
B W : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
inst✝ : EffectiveEpiFamily X π
m₁ m₂ : B ⟶ W
h : ∀ (a : α), π a ≫ m₁ = π a ≫ m₂
this :
  m₂ =
    desc X π (fun a => π a ≫ m₂)
      (_ :
        ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ π a₁ ≫ m₂ = g₂ ≫ π a₂ ≫ m₂)
⊢ m₁ = m₂

Next tactic:
rw [this]
lemma EffectiveEpiFamily.hom_ext {B W : C} {α : Type*} (X : α → C) (π : (a : α) → (X a ⟶ B))
    [EffectiveEpiFamily X π] (m₁ m₂ : B ⟶ W) (h : ∀ a, π a ≫ m₁ = π a ≫ m₂) :
    m₁ = m₂ := by
  have : m₂ = EffectiveEpiFamily.desc X π (fun a => π a ≫ m₂)
      (fun a₁ a₂ g₁ g₂ h => by simp only [← Category.assoc, h]) := by
    apply EffectiveEpiFamily.uniq; intro; rfl
  rw [this]
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_3, u_1} C
B W : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
inst✝ : EffectiveEpiFamily X π
m₁ m₂ : B ⟶ W
h : ∀ (a : α), π a ≫ m₁ = π a ≫ m₂
this :
  m₂ =
    desc X π (fun a => π a ≫ m₂)
      (_ :
        ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ π a₁ ≫ m₂ = g₂ ≫ π a₂ ≫ m₂)
⊢ m₁ =
    desc X π (fun a => π a ≫ m₂)
      (_ :
        ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ π a₁ ≫ m₂ = g₂ ≫ π a₂ ≫ m₂)

Next tactic:
exact EffectiveEpiFamily.uniq _ _ _ _ _ h
instance epiCoproductDescOfEffectiveEpiFamily {B : C} {α : Type*}
    (X : α → C) (π : (a : α) → (X a ⟶ B)) [EffectiveEpiFamily X π] [HasCoproduct X] :
    Epi (Sigma.desc π) := by
  

Proof state:
C : Type u_1
inst✝² : Category.{?u.56538, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
inst✝¹ : EffectiveEpiFamily X π
inst✝ : HasCoproduct X
⊢ Epi (Sigma.desc π)

Next tactic:
constructor
instance epiCoproductDescOfEffectiveEpiFamily {B : C} {α : Type*}
    (X : α → C) (π : (a : α) → (X a ⟶ B)) [EffectiveEpiFamily X π] [HasCoproduct X] :
    Epi (Sigma.desc π) := by
  constructor
  

Proof state:
case left_cancellation
C : Type u_1
inst✝² : Category.{?u.56538, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
inst✝¹ : EffectiveEpiFamily X π
inst✝ : HasCoproduct X
⊢ ∀ {Z : C} (g h : B ⟶ Z), Sigma.desc π ≫ g = Sigma.desc π ≫ h → g = h

Next tactic:
intro Z g h H
instance epiCoproductDescOfEffectiveEpiFamily {B : C} {α : Type*}
    (X : α → C) (π : (a : α) → (X a ⟶ B)) [EffectiveEpiFamily X π] [HasCoproduct X] :
    Epi (Sigma.desc π) := by
  constructor
  intro Z g h H
  

Proof state:
case left_cancellation
C : Type u_1
inst✝² : Category.{?u.56538, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
inst✝¹ : EffectiveEpiFamily X π
inst✝ : HasCoproduct X
Z : C
g h : B ⟶ Z
H : Sigma.desc π ≫ g = Sigma.desc π ≫ h
⊢ g = h

Next tactic:
apply EffectiveEpiFamily.hom_ext X π
instance epiCoproductDescOfEffectiveEpiFamily {B : C} {α : Type*}
    (X : α → C) (π : (a : α) → (X a ⟶ B)) [EffectiveEpiFamily X π] [HasCoproduct X] :
    Epi (Sigma.desc π) := by
  constructor
  intro Z g h H
  apply EffectiveEpiFamily.hom_ext X π
  

Proof state:
case left_cancellation.h
C : Type u_1
inst✝² : Category.{?u.56538, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
inst✝¹ : EffectiveEpiFamily X π
inst✝ : HasCoproduct X
Z : C
g h : B ⟶ Z
H : Sigma.desc π ≫ g = Sigma.desc π ≫ h
⊢ ∀ (a : α), π a ≫ g = π a ≫ h

Next tactic:
intro a
instance epiCoproductDescOfEffectiveEpiFamily {B : C} {α : Type*}
    (X : α → C) (π : (a : α) → (X a ⟶ B)) [EffectiveEpiFamily X π] [HasCoproduct X] :
    Epi (Sigma.desc π) := by
  constructor
  intro Z g h H
  apply EffectiveEpiFamily.hom_ext X π
  intro a
  

Proof state:
case left_cancellation.h
C : Type u_1
inst✝² : Category.{?u.56538, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
inst✝¹ : EffectiveEpiFamily X π
inst✝ : HasCoproduct X
Z : C
g h : B ⟶ Z
H : Sigma.desc π ≫ g = Sigma.desc π ≫ h
a : α
⊢ π a ≫ g = π a ≫ h

Next tactic:
suffices (Sigma.ι _ a ≫ Sigma.desc π) ≫ g = (Sigma.ι _ a ≫ Sigma.desc π) ≫ h by
    simpa only [colimit.ι_desc] using this
instance epiCoproductDescOfEffectiveEpiFamily {B : C} {α : Type*}
    (X : α → C) (π : (a : α) → (X a ⟶ B)) [EffectiveEpiFamily X π] [HasCoproduct X] :
    Epi (Sigma.desc π) := by
  constructor
  intro Z g h H
  apply EffectiveEpiFamily.hom_ext X π
  intro a
  suffices (Sigma.ι _ a ≫ Sigma.desc π) ≫ g = (Sigma.ι _ a ≫ Sigma.desc π) ≫ h by
    

Proof state:
C : Type u_1
inst✝² : Category.{?u.56538, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
inst✝¹ : EffectiveEpiFamily X π
inst✝ : HasCoproduct X
Z : C
g h : B ⟶ Z
H : Sigma.desc π ≫ g = Sigma.desc π ≫ h
a : α
this : (Sigma.ι (fun b => X b) a ≫ Sigma.desc π) ≫ g = (Sigma.ι (fun b => X b) a ≫ Sigma.desc π) ≫ h
⊢ π a ≫ g = π a ≫ h

Next tactic:
simpa only [colimit.ι_desc] using this
instance epiCoproductDescOfEffectiveEpiFamily {B : C} {α : Type*}
    (X : α → C) (π : (a : α) → (X a ⟶ B)) [EffectiveEpiFamily X π] [HasCoproduct X] :
    Epi (Sigma.desc π) := by
  constructor
  intro Z g h H
  apply EffectiveEpiFamily.hom_ext X π
  intro a
  suffices (Sigma.ι _ a ≫ Sigma.desc π) ≫ g = (Sigma.ι _ a ≫ Sigma.desc π) ≫ h by
    simpa only [colimit.ι_desc] using this
  

Proof state:
case left_cancellation.h
C : Type u_1
inst✝² : Category.{?u.56538, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
inst✝¹ : EffectiveEpiFamily X π
inst✝ : HasCoproduct X
Z : C
g h : B ⟶ Z
H : Sigma.desc π ≫ g = Sigma.desc π ≫ h
a : α
⊢ (Sigma.ι (fun b => X b) a ≫ Sigma.desc π) ≫ g = (Sigma.ι (fun b => X b) a ≫ Sigma.desc π) ≫ h

Next tactic:
simp only [Category.assoc, H]
/--
Implementation: This is a construction which will be used in the proof that
the sieve generated by a family of arrows is effective epimorphic if and only if
the family is an effective epi.
-/
def isColimitOfEffectiveEpiFamilyStruct {B : C} {α : Type*}
    (X : α → C) (π : (a : α) → (X a ⟶ B)) (H : EffectiveEpiFamilyStruct X π) :
    IsColimit (Sieve.generateFamily X π : Presieve B).cocone :=
  letI D := FullSubcategory fun T : Over B => Sieve.generateFamily X π T.hom
  letI F : D ⥤ _ := (Sieve.generateFamily X π).arrows.diagram
  { desc := fun S => H.desc (fun a => S.ι.app ⟨Over.mk (π a), ⟨a,𝟙 _, by 

Proof state:
C : Type u_1
inst✝ : Category.{?u.60909, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.60909) := FullSubcategory fun T => (Sieve.generateFamily X π).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateFamily X π).arrows
S : Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows)
a : α
⊢ 𝟙 ((𝟭 C).obj (Over.mk (π a)).left) ≫ π a = (Over.mk (π a)).hom

Next tactic:
simp
/--
Implementation: This is a construction which will be used in the proof that
the sieve generated by a family of arrows is effective epimorphic if and only if
the family is an effective epi.
-/
def isColimitOfEffectiveEpiFamilyStruct {B : C} {α : Type*}
    (X : α → C) (π : (a : α) → (X a ⟶ B)) (H : EffectiveEpiFamilyStruct X π) :
    IsColimit (Sieve.generateFamily X π : Presieve B).cocone :=
  letI D := FullSubcategory fun T : Over B => Sieve.generateFamily X π T.hom
  letI F : D ⥤ _ := (Sieve.generateFamily X π).arrows.diagram
  { desc := fun S => H.desc (fun a => S.ι.app ⟨Over.mk (π a), ⟨a,𝟙 _, by simp⟩⟩) <| by
      

Proof state:
C : Type u_1
inst✝ : Category.{?u.60909, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.60909) := FullSubcategory fun T => (Sieve.generateFamily X π).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateFamily X π).arrows
S : Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows)
⊢ ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂),
    g₁ ≫ π a₁ = g₂ ≫ π a₂ →
      g₁ ≫ (fun a => S.ι.app { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) }) a₁ =
        g₂ ≫ (fun a => S.ι.app { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) }) a₂

Next tactic:
intro Z a₁ a₂ g₁ g₂ h
/--
Implementation: This is a construction which will be used in the proof that
the sieve generated by a family of arrows is effective epimorphic if and only if
the family is an effective epi.
-/
def isColimitOfEffectiveEpiFamilyStruct {B : C} {α : Type*}
    (X : α → C) (π : (a : α) → (X a ⟶ B)) (H : EffectiveEpiFamilyStruct X π) :
    IsColimit (Sieve.generateFamily X π : Presieve B).cocone :=
  letI D := FullSubcategory fun T : Over B => Sieve.generateFamily X π T.hom
  letI F : D ⥤ _ := (Sieve.generateFamily X π).arrows.diagram
  { desc := fun S => H.desc (fun a => S.ι.app ⟨Over.mk (π a), ⟨a,𝟙 _, by simp⟩⟩) <| by
      intro Z a₁ a₂ g₁ g₂ h
      

Proof state:
C : Type u_1
inst✝ : Category.{?u.60909, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.60909) := FullSubcategory fun T => (Sieve.generateFamily X π).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateFamily X π).arrows
S : Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows)
Z : C
a₁ a₂ : α
g₁ : Z ⟶ X a₁
g₂ : Z ⟶ X a₂
h : g₁ ≫ π a₁ = g₂ ≫ π a₂
⊢ g₁ ≫ (fun a => S.ι.app { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) }) a₁ =
    g₂ ≫ (fun a => S.ι.app { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) }) a₂

Next tactic:
dsimp
/--
Implementation: This is a construction which will be used in the proof that
the sieve generated by a family of arrows is effective epimorphic if and only if
the family is an effective epi.
-/
def isColimitOfEffectiveEpiFamilyStruct {B : C} {α : Type*}
    (X : α → C) (π : (a : α) → (X a ⟶ B)) (H : EffectiveEpiFamilyStruct X π) :
    IsColimit (Sieve.generateFamily X π : Presieve B).cocone :=
  letI D := FullSubcategory fun T : Over B => Sieve.generateFamily X π T.hom
  letI F : D ⥤ _ := (Sieve.generateFamily X π).arrows.diagram
  { desc := fun S => H.desc (fun a => S.ι.app ⟨Over.mk (π a), ⟨a,𝟙 _, by simp⟩⟩) <| by
      intro Z a₁ a₂ g₁ g₂ h
      dsimp
      

Proof state:
C : Type u_1
inst✝ : Category.{?u.60909, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.60909) := FullSubcategory fun T => (Sieve.generateFamily X π).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateFamily X π).arrows
S : Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows)
Z : C
a₁ a₂ : α
g₁ : Z ⟶ X a₁
g₂ : Z ⟶ X a₂
h : g₁ ≫ π a₁ = g₂ ≫ π a₂
⊢ g₁ ≫ S.ι.app { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = π a₁) } =
    g₂ ≫ S.ι.app { obj := Over.mk (π a₂), property := (_ : ∃ a g, g ≫ π a = π a₂) }

Next tactic:
let A₁ : D := ⟨Over.mk (π a₁), a₁, 𝟙 _, by simp⟩
/--
Implementation: This is a construction which will be used in the proof that
the sieve generated by a family of arrows is effective epimorphic if and only if
the family is an effective epi.
-/
def isColimitOfEffectiveEpiFamilyStruct {B : C} {α : Type*}
    (X : α → C) (π : (a : α) → (X a ⟶ B)) (H : EffectiveEpiFamilyStruct X π) :
    IsColimit (Sieve.generateFamily X π : Presieve B).cocone :=
  letI D := FullSubcategory fun T : Over B => Sieve.generateFamily X π T.hom
  letI F : D ⥤ _ := (Sieve.generateFamily X π).arrows.diagram
  { desc := fun S => H.desc (fun a => S.ι.app ⟨Over.mk (π a), ⟨a,𝟙 _, by simp⟩⟩) <| by
      intro Z a₁ a₂ g₁ g₂ h
      dsimp
      let A₁ : D := ⟨Over.mk (π a₁), a₁, 𝟙 _, by 

Proof state:
C : Type u_1
inst✝ : Category.{?u.60909, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.60909) := FullSubcategory fun T => (Sieve.generateFamily X π).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateFamily X π).arrows
S : Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows)
Z : C
a₁ a₂ : α
g₁ : Z ⟶ X a₁
g₂ : Z ⟶ X a₂
h : g₁ ≫ π a₁ = g₂ ≫ π a₂
⊢ 𝟙 ((𝟭 C).obj (Over.mk (π a₁)).left) ≫ π a₁ = (Over.mk (π a₁)).hom

Next tactic:
simp
/--
Implementation: This is a construction which will be used in the proof that
the sieve generated by a family of arrows is effective epimorphic if and only if
the family is an effective epi.
-/
def isColimitOfEffectiveEpiFamilyStruct {B : C} {α : Type*}
    (X : α → C) (π : (a : α) → (X a ⟶ B)) (H : EffectiveEpiFamilyStruct X π) :
    IsColimit (Sieve.generateFamily X π : Presieve B).cocone :=
  letI D := FullSubcategory fun T : Over B => Sieve.generateFamily X π T.hom
  letI F : D ⥤ _ := (Sieve.generateFamily X π).arrows.diagram
  { desc := fun S => H.desc (fun a => S.ι.app ⟨Over.mk (π a), ⟨a,𝟙 _, by simp⟩⟩) <| by
      intro Z a₁ a₂ g₁ g₂ h
      dsimp
      let A₁ : D := ⟨Over.mk (π a₁), a₁, 𝟙 _, by simp⟩
      

Proof state:
C : Type u_1
inst✝ : Category.{?u.60909, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.60909) := FullSubcategory fun T => (Sieve.generateFamily X π).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateFamily X π).arrows
S : Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows)
Z : C
a₁ a₂ : α
g₁ : Z ⟶ X a₁
g₂ : Z ⟶ X a₂
h : g₁ ≫ π a₁ = g₂ ≫ π a₂
A₁ : D := { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = (Over.mk (π a₁)).hom) }
⊢ g₁ ≫ S.ι.app { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = π a₁) } =
    g₂ ≫ S.ι.app { obj := Over.mk (π a₂), property := (_ : ∃ a g, g ≫ π a = π a₂) }

Next tactic:
let A₂ : D := ⟨Over.mk (π a₂), a₂, 𝟙 _, by simp⟩
/--
Implementation: This is a construction which will be used in the proof that
the sieve generated by a family of arrows is effective epimorphic if and only if
the family is an effective epi.
-/
def isColimitOfEffectiveEpiFamilyStruct {B : C} {α : Type*}
    (X : α → C) (π : (a : α) → (X a ⟶ B)) (H : EffectiveEpiFamilyStruct X π) :
    IsColimit (Sieve.generateFamily X π : Presieve B).cocone :=
  letI D := FullSubcategory fun T : Over B => Sieve.generateFamily X π T.hom
  letI F : D ⥤ _ := (Sieve.generateFamily X π).arrows.diagram
  { desc := fun S => H.desc (fun a => S.ι.app ⟨Over.mk (π a), ⟨a,𝟙 _, by simp⟩⟩) <| by
      intro Z a₁ a₂ g₁ g₂ h
      dsimp
      let A₁ : D := ⟨Over.mk (π a₁), a₁, 𝟙 _, by simp⟩
      let A₂ : D := ⟨Over.mk (π a₂), a₂, 𝟙 _, by 

Proof state:
C : Type u_1
inst✝ : Category.{?u.60909, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.60909) := FullSubcategory fun T => (Sieve.generateFamily X π).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateFamily X π).arrows
S : Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows)
Z : C
a₁ a₂ : α
g₁ : Z ⟶ X a₁
g₂ : Z ⟶ X a₂
h : g₁ ≫ π a₁ = g₂ ≫ π a₂
A₁ : D := { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = (Over.mk (π a₁)).hom) }
⊢ 𝟙 ((𝟭 C).obj (Over.mk (π a₂)).left) ≫ π a₂ = (Over.mk (π a₂)).hom

Next tactic:
simp
/--
Implementation: This is a construction which will be used in the proof that
the sieve generated by a family of arrows is effective epimorphic if and only if
the family is an effective epi.
-/
def isColimitOfEffectiveEpiFamilyStruct {B : C} {α : Type*}
    (X : α → C) (π : (a : α) → (X a ⟶ B)) (H : EffectiveEpiFamilyStruct X π) :
    IsColimit (Sieve.generateFamily X π : Presieve B).cocone :=
  letI D := FullSubcategory fun T : Over B => Sieve.generateFamily X π T.hom
  letI F : D ⥤ _ := (Sieve.generateFamily X π).arrows.diagram
  { desc := fun S => H.desc (fun a => S.ι.app ⟨Over.mk (π a), ⟨a,𝟙 _, by simp⟩⟩) <| by
      intro Z a₁ a₂ g₁ g₂ h
      dsimp
      let A₁ : D := ⟨Over.mk (π a₁), a₁, 𝟙 _, by simp⟩
      let A₂ : D := ⟨Over.mk (π a₂), a₂, 𝟙 _, by simp⟩
      

Proof state:
C : Type u_1
inst✝ : Category.{?u.60909, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.60909) := FullSubcategory fun T => (Sieve.generateFamily X π).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateFamily X π).arrows
S : Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows)
Z : C
a₁ a₂ : α
g₁ : Z ⟶ X a₁
g₂ : Z ⟶ X a₂
h : g₁ ≫ π a₁ = g₂ ≫ π a₂
A₁ : D := { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = (Over.mk (π a₁)).hom) }
A₂ : D := { obj := Over.mk (π a₂), property := (_ : ∃ a g, g ≫ π a = (Over.mk (π a₂)).hom) }
⊢ g₁ ≫ S.ι.app { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = π a₁) } =
    g₂ ≫ S.ι.app { obj := Over.mk (π a₂), property := (_ : ∃ a g, g ≫ π a = π a₂) }

Next tactic:
let Z' : D := ⟨Over.mk (g₁ ≫ π a₁), a₁, g₁, rfl⟩
/--
Implementation: This is a construction which will be used in the proof that
the sieve generated by a family of arrows is effective epimorphic if and only if
the family is an effective epi.
-/
def isColimitOfEffectiveEpiFamilyStruct {B : C} {α : Type*}
    (X : α → C) (π : (a : α) → (X a ⟶ B)) (H : EffectiveEpiFamilyStruct X π) :
    IsColimit (Sieve.generateFamily X π : Presieve B).cocone :=
  letI D := FullSubcategory fun T : Over B => Sieve.generateFamily X π T.hom
  letI F : D ⥤ _ := (Sieve.generateFamily X π).arrows.diagram
  { desc := fun S => H.desc (fun a => S.ι.app ⟨Over.mk (π a), ⟨a,𝟙 _, by simp⟩⟩) <| by
      intro Z a₁ a₂ g₁ g₂ h
      dsimp
      let A₁ : D := ⟨Over.mk (π a₁), a₁, 𝟙 _, by simp⟩
      let A₂ : D := ⟨Over.mk (π a₂), a₂, 𝟙 _, by simp⟩
      let Z' : D := ⟨Over.mk (g₁ ≫ π a₁), a₁, g₁, rfl⟩
      

Proof state:
C : Type u_1
inst✝ : Category.{?u.60909, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.60909) := FullSubcategory fun T => (Sieve.generateFamily X π).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateFamily X π).arrows
S : Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows)
Z : C
a₁ a₂ : α
g₁ : Z ⟶ X a₁
g₂ : Z ⟶ X a₂
h : g₁ ≫ π a₁ = g₂ ≫ π a₂
A₁ : D := { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = (Over.mk (π a₁)).hom) }
A₂ : D := { obj := Over.mk (π a₂), property := (_ : ∃ a g, g ≫ π a = (Over.mk (π a₂)).hom) }
Z' : D := { obj := Over.mk (g₁ ≫ π a₁), property := (_ : ∃ a g, g ≫ π a = (Over.mk (g₁ ≫ π a₁)).hom) }
⊢ g₁ ≫ S.ι.app { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = π a₁) } =
    g₂ ≫ S.ι.app { obj := Over.mk (π a₂), property := (_ : ∃ a g, g ≫ π a = π a₂) }

Next tactic:
let i₁ : Z' ⟶ A₁ := Over.homMk g₁