l3lab/ntp-mathlib huggingface dataset:
/--
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⟩
      let i₁ : Z' ⟶ A₁ := Over.homMk g₁
      

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) }
i₁ : Z' ⟶ A₁ := Over.homMk g₁
⊢ 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₂
/--
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⟩
      let i₁ : Z' ⟶ A₁ := Over.homMk g₁
      let i₂ : Z' ⟶ A₂ := Over.homMk g₂
      

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) }
i₁ : Z' ⟶ A₁ := Over.homMk g₁
i₂ : Z' ⟶ A₂ := Over.homMk g₂
⊢ 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:
change F.map i₁ ≫ _ = F.map i₂ ≫ _
/--
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⟩
      let i₁ : Z' ⟶ A₁ := Over.homMk g₁
      let i₂ : Z' ⟶ A₂ := Over.homMk g₂
      change F.map i₁ ≫ _ = F.map i₂ ≫ _
      

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) }
i₁ : Z' ⟶ A₁ := Over.homMk g₁
i₂ : Z' ⟶ A₂ := Over.homMk g₂
⊢ F.map i₁ ≫ S.ι.app { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = π a₁) } =
    F.map i₂ ≫ S.ι.app { obj := Over.mk (π a₂), property := (_ : ∃ a g, g ≫ π a = π a₂) }

Next tactic:
simp only [S.w]
/--
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⟩
      let i₁ : Z' ⟶ A₁ := Over.homMk g₁
      let i₂ : Z' ⟶ A₂ := Over.homMk g₂
      change F.map i₁ ≫ _ = F.map i₂ ≫ _
      simp only [S.w]
    fac := 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))
    (j : FullSubcategory fun f => (Sieve.generateFamily X π).arrows f.hom),
    (Presieve.cocone (Sieve.generateFamily X π).arrows).ι.app j ≫
        (fun S =>
            EffectiveEpiFamilyStruct.desc H
              (fun a => S.ι.app { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) })
              (_ :
                ∀ {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₂))
          s =
      s.ι.app j

Next tactic:
intro S ⟨T, a, (g : T.left ⟶ X a), hT⟩
/--
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⟩
      let i₁ : Z' ⟶ A₁ := Over.homMk g₁
      let i₂ : Z' ⟶ A₂ := Over.homMk g₂
      change F.map i₁ ≫ _ = F.map i₂ ≫ _
      simp only [S.w]
    fac := by
      intro S ⟨T, a, (g : T.left ⟶ X a), hT⟩
      

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)
T : Over B
a : α
g : T.left ⟶ X a
hT : g ≫ π a = T.hom
⊢ (Presieve.cocone (Sieve.generateFamily X π).arrows).ι.app { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) } ≫
      (fun S =>
          EffectiveEpiFamilyStruct.desc H
            (fun a => S.ι.app { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) })
            (_ :
              ∀ {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₂))
        S =
    S.ι.app { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) }

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
      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⟩
      let i₁ : Z' ⟶ A₁ := Over.homMk g₁
      let i₂ : Z' ⟶ A₂ := Over.homMk g₂
      change F.map i₁ ≫ _ = F.map i₂ ≫ _
      simp only [S.w]
    fac := by
      intro S ⟨T, a, (g : T.left ⟶ X a), hT⟩
      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)
T : Over B
a : α
g : T.left ⟶ X a
hT : g ≫ π a = T.hom
⊢ T.hom ≫
      EffectiveEpiFamilyStruct.desc H
        (fun a => S.ι.app { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = π a) })
        (_ :
          ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂),
            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₂) }) =
    S.ι.app { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) }

Next tactic:
nth_rewrite 1 [← hT, Category.assoc, H.fac]
/--
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⟩
      let i₁ : Z' ⟶ A₁ := Over.homMk g₁
      let i₂ : Z' ⟶ A₂ := Over.homMk g₂
      change F.map i₁ ≫ _ = F.map i₂ ≫ _
      simp only [S.w]
    fac := by
      intro S ⟨T, a, (g : T.left ⟶ X a), hT⟩
      dsimp
      nth_rewrite 1 [← hT, Category.assoc, H.fac]
      

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)
T : Over B
a : α
g : T.left ⟶ X a
hT : g ≫ π a = T.hom
⊢ g ≫ S.ι.app { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = π a) } =
    S.ι.app { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) }

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 simp⟩
      let Z' : D := ⟨Over.mk (g₁ ≫ π a₁), a₁, g₁, rfl⟩
      let i₁ : Z' ⟶ A₁ := Over.homMk g₁
      let i₂ : Z' ⟶ A₂ := Over.homMk g₂
      change F.map i₁ ≫ _ = F.map i₂ ≫ _
      simp only [S.w]
    fac := by
      intro S ⟨T, a, (g : T.left ⟶ X a), hT⟩
      dsimp
      nth_rewrite 1 [← hT, Category.assoc, H.fac]
      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)
T : Over B
a : α
g : T.left ⟶ X a
hT : g ≫ π a = T.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⟩
      let Z' : D := ⟨Over.mk (g₁ ≫ π a₁), a₁, g₁, rfl⟩
      let i₁ : Z' ⟶ A₁ := Over.homMk g₁
      let i₂ : Z' ⟶ A₂ := Over.homMk g₂
      change F.map i₁ ≫ _ = F.map i₂ ≫ _
      simp only [S.w]
    fac := by
      intro S ⟨T, a, (g : T.left ⟶ X a), hT⟩
      dsimp
      nth_rewrite 1 [← hT, Category.assoc, H.fac]
      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)
T : Over B
a : α
g : T.left ⟶ X a
hT : g ≫ π a = T.hom
A : D := { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) }
⊢ g ≫ S.ι.app { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = π a) } =
    S.ι.app { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) }

Next tactic:
let B : D := ⟨Over.mk T.hom, a, g, hT⟩
/--
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⟩
      let i₁ : Z' ⟶ A₁ := Over.homMk g₁
      let i₂ : Z' ⟶ A₂ := Over.homMk g₂
      change F.map i₁ ≫ _ = F.map i₂ ≫ _
      simp only [S.w]
    fac := by
      intro S ⟨T, a, (g : T.left ⟶ X a), hT⟩
      dsimp
      nth_rewrite 1 [← hT, Category.assoc, H.fac]
      let A : D := ⟨Over.mk (π a), a, 𝟙 _, by simp⟩
      let B : D := ⟨Over.mk T.hom, a, g, hT⟩
      

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)
T : Over B✝
a : α
g : T.left ⟶ X a
hT : g ≫ π a = T.hom
A : D := { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) }
B : D := { obj := Over.mk T.hom, property := (_ : ∃ a g, g ≫ π a = (Over.mk T.hom).hom) }
⊢ g ≫ S.ι.app { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = π a) } =
    S.ι.app { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) }

Next tactic:
let i : B ⟶ A := Over.homMk g
/--
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⟩
      let i₁ : Z' ⟶ A₁ := Over.homMk g₁
      let i₂ : Z' ⟶ A₂ := Over.homMk g₂
      change F.map i₁ ≫ _ = F.map i₂ ≫ _
      simp only [S.w]
    fac := by
      intro S ⟨T, a, (g : T.left ⟶ X a), hT⟩
      dsimp
      nth_rewrite 1 [← hT, Category.assoc, H.fac]
      let A : D := ⟨Over.mk (π a), a, 𝟙 _, by simp⟩
      let B : D := ⟨Over.mk T.hom, a, g, hT⟩
      let i : B ⟶ A := Over.homMk g
      

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)
T : Over B✝
a : α
g : T.left ⟶ X a
hT : g ≫ π a = T.hom
A : D := { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) }
B : D := { obj := Over.mk T.hom, property := (_ : ∃ a g, g ≫ π a = (Over.mk T.hom).hom) }
i : B ⟶ A := Over.homMk g
⊢ g ≫ S.ι.app { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = π a) } =
    S.ι.app { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) }

Next tactic:
change F.map i ≫ _ = _
/--
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⟩
      let i₁ : Z' ⟶ A₁ := Over.homMk g₁
      let i₂ : Z' ⟶ A₂ := Over.homMk g₂
      change F.map i₁ ≫ _ = F.map i₂ ≫ _
      simp only [S.w]
    fac := by
      intro S ⟨T, a, (g : T.left ⟶ X a), hT⟩
      dsimp
      nth_rewrite 1 [← hT, Category.assoc, H.fac]
      let A : D := ⟨Over.mk (π a), a, 𝟙 _, by simp⟩
      let B : D := ⟨Over.mk T.hom, a, g, hT⟩
      let i : B ⟶ A := Over.homMk g
      change F.map i ≫ _ = _
      

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)
T : Over B✝
a : α
g : T.left ⟶ X a
hT : g ≫ π a = T.hom
A : D := { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) }
B : D := { obj := Over.mk T.hom, property := (_ : ∃ a g, g ≫ π a = (Over.mk T.hom).hom) }
i : B ⟶ A := Over.homMk g
⊢ F.map i ≫ S.ι.app { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = π a) } =
    S.ι.app { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) }

Next tactic:
rw [S.w]