[GOAL]
C : Type u_1
inst✝ : Category.{?u.873, u_1} C
X Y : C
f : Y ⟶ X
⊢ ∀ {Y_1 Z : C} {f_1 : Y_1 ⟶ X},
    (fun Z => {g | ∃ e, e ≫ f = g}) Y_1 f_1 → ∀ (g : Z ⟶ Y_1), (fun Z => {g | ∃ e, e ≫ f = g}) Z (g ≫ f_1)
[PROOFSTEP]
rintro W Z g ⟨e, rfl⟩ q
[GOAL]
case intro
C : Type u_1
inst✝ : Category.{?u.873, u_1} C
X Y : C
f : Y ⟶ X
W Z : C
e : W ⟶ Y
q : Z ⟶ W
⊢ setOf (fun g => ∃ e, e ≫ f = g) (q ≫ e ≫ f)
[PROOFSTEP]
refine ⟨q ≫ e, by simp⟩
[GOAL]
C : Type u_1
inst✝ : Category.{?u.873, u_1} C
X Y : C
f : Y ⟶ X
W Z : C
e : W ⟶ Y
q : Z ⟶ W
⊢ (q ≫ e) ≫ f = q ≫ e ≫ f
[PROOFSTEP]
simp
[GOAL]
C : Type u_1
inst✝ : Category.{u_2, u_1} C
X Y : C
f : Y ⟶ X
⊢ generate (Presieve.singleton f) = generateSingleton f
[PROOFSTEP]
ext Z g
[GOAL]
case h
C : Type u_1
inst✝ : Category.{u_2, u_1} C
X Y : C
f : Y ⟶ X
Z : C
g : Z ⟶ X
⊢ (generate (Presieve.singleton f)).arrows g ↔ (generateSingleton f).arrows g
[PROOFSTEP]
constructor
[GOAL]
case h.mp
C : Type u_1
inst✝ : Category.{u_2, u_1} C
X Y : C
f : Y ⟶ X
Z : C
g : Z ⟶ X
⊢ (generate (Presieve.singleton f)).arrows g → (generateSingleton f).arrows g
[PROOFSTEP]
rintro ⟨W, i, p, ⟨⟩, rfl⟩
[GOAL]
case h.mp.intro.intro.intro.intro.mk
C : Type u_1
inst✝ : Category.{u_2, u_1} C
X Y✝ : C
f : Y✝ ⟶ X
Z Y : C
i : Z ⟶ Y✝
⊢ (generateSingleton f).arrows (i ≫ f)
[PROOFSTEP]
exact ⟨i, rfl⟩
[GOAL]
case h.mpr
C : Type u_1
inst✝ : Category.{u_2, u_1} C
X Y : C
f : Y ⟶ X
Z : C
g : Z ⟶ X
⊢ (generateSingleton f).arrows g → (generate (Presieve.singleton f)).arrows g
[PROOFSTEP]
rintro ⟨g, h⟩
[GOAL]
case h.mpr.intro
C : Type u_1
inst✝ : Category.{u_2, u_1} C
X Y : C
f : Y ⟶ X
Z : C
g✝ : Z ⟶ X
g : Z ⟶ Y
h : g ≫ f = g✝
⊢ (generate (Presieve.singleton f)).arrows g✝
[PROOFSTEP]
exact ⟨Y, g, f, ⟨⟩, h⟩
[GOAL]
C : Type u_1
inst✝¹ : Category.{?u.7498, u_1} C
X Y : C
f : Y ⟶ X
inst✝ : EffectiveEpi f
⊢ Epi f
[PROOFSTEP]
constructor
[GOAL]
case left_cancellation
C : Type u_1
inst✝¹ : Category.{?u.7498, u_1} C
X Y : C
f : Y ⟶ X
inst✝ : EffectiveEpi f
⊢ ∀ {Z : C} (g h : X ⟶ Z), f ≫ g = f ≫ h → g = h
[PROOFSTEP]
intro W m₁ m₂ h
[GOAL]
case left_cancellation
C : Type u_1
inst✝¹ : Category.{?u.7498, u_1} C
X Y : C
f : Y ⟶ X
inst✝ : EffectiveEpi f
W : C
m₁ m₂ : X ⟶ W
h : f ≫ m₁ = f ≫ m₂
⊢ m₁ = m₂
[PROOFSTEP]
have : m₂ = EffectiveEpi.desc f (f ≫ m₂) (fun {Z} g₁ g₂ h => by simp only [← Category.assoc, h]) :=
  EffectiveEpi.uniq _ _ _ _ rfl
[GOAL]
C : Type u_1
inst✝¹ : Category.{?u.7498, u_1} C
X Y : C
f : Y ⟶ X
inst✝ : EffectiveEpi f
W : C
m₁ m₂ : X ⟶ W
h✝ : f ≫ m₁ = f ≫ m₂
Z : C
g₁ g₂ : Z ⟶ Y
h : g₁ ≫ f = g₂ ≫ f
⊢ g₁ ≫ f ≫ m₂ = g₂ ≫ f ≫ m₂
[PROOFSTEP]
simp only [← Category.assoc, h]
[GOAL]
case left_cancellation
C : Type u_1
inst✝¹ : Category.{?u.7498, u_1} C
X Y : C
f : Y ⟶ X
inst✝ : EffectiveEpi f
W : C
m₁ m₂ : X ⟶ W
h : f ≫ m₁ = f ≫ m₂
this : m₂ = EffectiveEpi.desc f (f ≫ m₂) (_ : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ f ≫ m₂ = g₂ ≫ f ≫ m₂)
⊢ m₁ = m₂
[PROOFSTEP]
rw [this]
[GOAL]
case left_cancellation
C : Type u_1
inst✝¹ : Category.{?u.7498, u_1} C
X Y : C
f : Y ⟶ X
inst✝ : EffectiveEpi f
W : C
m₁ m₂ : X ⟶ W
h : f ≫ m₁ = f ≫ m₂
this : m₂ = EffectiveEpi.desc f (f ≫ m₂) (_ : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ f ≫ m₂ = g₂ ≫ f ≫ m₂)
⊢ m₁ = EffectiveEpi.desc f (f ≫ m₂) (_ : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ f ≫ m₂ = g₂ ≫ f ≫ m₂)
[PROOFSTEP]
exact EffectiveEpi.uniq _ _ _ _ h
[GOAL]
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
⊢ 𝟙 ((𝟭 C).obj (Over.mk f).left) ≫ f = (Over.mk f).hom
[PROOFSTEP]
simp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
⊢ ∀ {Z : C} (g₁ g₂ : Z ⟶ Y),
    g₁ ≫ f = g₂ ≫ f →
      g₁ ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) } =
        g₂ ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
[PROOFSTEP]
intro Z g₁ g₂ h
[GOAL]
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
Z : C
g₁ g₂ : Z ⟶ Y
h : g₁ ≫ f = g₂ ≫ f
⊢ g₁ ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) } =
    g₂ ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
[PROOFSTEP]
let Y' : D := ⟨Over.mk f, 𝟙 _, by simp⟩
[GOAL]
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
Z : C
g₁ g₂ : Z ⟶ Y
h : g₁ ≫ f = g₂ ≫ f
⊢ 𝟙 ((𝟭 C).obj (Over.mk f).left) ≫ f = (Over.mk f).hom
[PROOFSTEP]
simp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
Z : C
g₁ g₂ : Z ⟶ Y
h : g₁ ≫ f = g₂ ≫ f
Y' : D := { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
⊢ g₁ ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) } =
    g₂ ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
[PROOFSTEP]
let Z' : D := ⟨Over.mk (g₁ ≫ f), g₁, rfl⟩
[GOAL]
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
Z : C
g₁ g₂ : Z ⟶ Y
h : g₁ ≫ f = g₂ ≫ f
Y' : D := { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
Z' : D := { obj := Over.mk (g₁ ≫ f), property := (_ : ∃ e, e ≫ f = (Over.mk (g₁ ≫ f)).hom) }
⊢ g₁ ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) } =
    g₂ ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
[PROOFSTEP]
let g₁' : Z' ⟶ Y' := Over.homMk g₁
[GOAL]
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
Z : C
g₁ g₂ : Z ⟶ Y
h : g₁ ≫ f = g₂ ≫ f
Y' : D := { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
Z' : D := { obj := Over.mk (g₁ ≫ f), property := (_ : ∃ e, e ≫ f = (Over.mk (g₁ ≫ f)).hom) }
g₁' : Z' ⟶ Y' := Over.homMk g₁
⊢ g₁ ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) } =
    g₂ ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
[PROOFSTEP]
let g₂' : Z' ⟶ Y' := Over.homMk g₂ (by simp [h])
[GOAL]
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
Z : C
g₁ g₂ : Z ⟶ Y
h : g₁ ≫ f = g₂ ≫ f
Y' : D := { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
Z' : D := { obj := Over.mk (g₁ ≫ f), property := (_ : ∃ e, e ≫ f = (Over.mk (g₁ ≫ f)).hom) }
g₁' : Z' ⟶ Y' := Over.homMk g₁
⊢ g₂ ≫ Y'.obj.hom = Z'.obj.hom
[PROOFSTEP]
simp [h]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
Z : C
g₁ g₂ : Z ⟶ Y
h : g₁ ≫ f = g₂ ≫ f
Y' : D := { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
Z' : D := { obj := Over.mk (g₁ ≫ f), property := (_ : ∃ e, e ≫ f = (Over.mk (g₁ ≫ f)).hom) }
g₁' : Z' ⟶ Y' := Over.homMk g₁
g₂' : Z' ⟶ Y' := Over.homMk g₂
⊢ g₁ ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) } =
    g₂ ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
[PROOFSTEP]
change F.map g₁' ≫ _ = F.map g₂' ≫ _
[GOAL]
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
Z : C
g₁ g₂ : Z ⟶ Y
h : g₁ ≫ f = g₂ ≫ f
Y' : D := { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
Z' : D := { obj := Over.mk (g₁ ≫ f), property := (_ : ∃ e, e ≫ f = (Over.mk (g₁ ≫ f)).hom) }
g₁' : Z' ⟶ Y' := Over.homMk g₁
g₂' : Z' ⟶ Y' := Over.homMk g₂
⊢ F.map g₁' ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) } =
    F.map g₂' ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
[PROOFSTEP]
simp only [S.w]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
⊢ ∀ (s : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows))
    (j : FullSubcategory fun f_1 => (Sieve.generateSingleton f).arrows f_1.hom),
    NatTrans.app (Presieve.cocone (Sieve.generateSingleton f).arrows).ι j ≫
        (fun S =>
            EffectiveEpiStruct.desc Hf
              (NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) })
              (_ :
                ∀ {Z : C} (g₁ g₂ : Z ⟶ Y) (h : g₁ ≫ f = g₂ ≫ f),
                  let Y' := { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) };
                  let Z' := { obj := Over.mk (g₁ ≫ f), property := (_ : ∃ e, e ≫ f = (Over.mk (g₁ ≫ f)).hom) };
                  let g₁' := Over.homMk g₁;
                  let g₂' := Over.homMk g₂;
                  F.map g₁' ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) } =
                    F.map g₂' ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }))
          s =
      NatTrans.app s.ι j
[PROOFSTEP]
rintro S ⟨T, g, hT⟩
[GOAL]
case mk.intro
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
T : Over X
g : (𝟭 C).obj T.left ⟶ Y
hT : g ≫ f = T.hom
⊢ NatTrans.app (Presieve.cocone (Sieve.generateSingleton f).arrows).ι
        { obj := T, property := (_ : ∃ e, e ≫ f = T.hom) } ≫
      (fun S =>
          EffectiveEpiStruct.desc Hf
            (NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) })
            (_ :
              ∀ {Z : C} (g₁ g₂ : Z ⟶ Y) (h : g₁ ≫ f = g₂ ≫ f),
                let Y' := { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) };
                let Z' := { obj := Over.mk (g₁ ≫ f), property := (_ : ∃ e, e ≫ f = (Over.mk (g₁ ≫ f)).hom) };
                let g₁' := Over.homMk g₁;
                let g₂' := Over.homMk g₂;
                F.map g₁' ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) } =
                  F.map g₂' ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }))
        S =
    NatTrans.app S.ι { obj := T, property := (_ : ∃ e, e ≫ f = T.hom) }
[PROOFSTEP]
dsimp
[GOAL]
case mk.intro
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
T : Over X
g : (𝟭 C).obj T.left ⟶ Y
hT : g ≫ f = T.hom
⊢ T.hom ≫
      EffectiveEpiStruct.desc Hf (NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = f) })
        (_ :
          ∀ {Z : C} (g₁ g₂ : Z ⟶ Y),
            g₁ ≫ f = g₂ ≫ f →
              g₁ ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = f) } =
                g₂ ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = f) }) =
    NatTrans.app S.ι { obj := T, property := (_ : ∃ e, e ≫ f = T.hom) }
[PROOFSTEP]
nth_rewrite 1 [← hT, Category.assoc, Hf.fac]
[GOAL]
case mk.intro
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
T : Over X
g : (𝟭 C).obj T.left ⟶ Y
hT : g ≫ f = T.hom
⊢ g ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = f) } =
    NatTrans.app S.ι { obj := T, property := (_ : ∃ e, e ≫ f = T.hom) }
[PROOFSTEP]
let y : D := ⟨Over.mk f, 𝟙 _, by simp⟩
[GOAL]
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
T : Over X
g : (𝟭 C).obj T.left ⟶ Y
hT : g ≫ f = T.hom
⊢ 𝟙 ((𝟭 C).obj (Over.mk f).left) ≫ f = (Over.mk f).hom
[PROOFSTEP]
simp
[GOAL]
case mk.intro
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
T : Over X
g : (𝟭 C).obj T.left ⟶ Y
hT : g ≫ f = T.hom
y : D := { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
⊢ g ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = f) } =
    NatTrans.app S.ι { obj := T, property := (_ : ∃ e, e ≫ f = T.hom) }
[PROOFSTEP]
let x : D := ⟨Over.mk T.hom, g, hT⟩
[GOAL]
case mk.intro
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
T : Over X
g : (𝟭 C).obj T.left ⟶ Y
hT : g ≫ f = T.hom
y : D := { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
x : D := { obj := Over.mk T.hom, property := (_ : ∃ e, e ≫ f = (Over.mk T.hom).hom) }
⊢ g ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = f) } =
    NatTrans.app S.ι { obj := T, property := (_ : ∃ e, e ≫ f = T.hom) }
[PROOFSTEP]
let g' : x ⟶ y := Over.homMk g
[GOAL]
case mk.intro
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
T : Over X
g : (𝟭 C).obj T.left ⟶ Y
hT : g ≫ f = T.hom
y : D := { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
x : D := { obj := Over.mk T.hom, property := (_ : ∃ e, e ≫ f = (Over.mk T.hom).hom) }
g' : x ⟶ y := Over.homMk g
⊢ g ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = f) } =
    NatTrans.app S.ι { obj := T, property := (_ : ∃ e, e ≫ f = T.hom) }
[PROOFSTEP]
change F.map g' ≫ _ = _
[GOAL]
case mk.intro
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
T : Over X
g : (𝟭 C).obj T.left ⟶ Y
hT : g ≫ f = T.hom
y : D := { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
x : D := { obj := Over.mk T.hom, property := (_ : ∃ e, e ≫ f = (Over.mk T.hom).hom) }
g' : x ⟶ y := Over.homMk g
⊢ F.map g' ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = f) } =
    NatTrans.app S.ι { obj := T, property := (_ : ∃ e, e ≫ f = T.hom) }
[PROOFSTEP]
rw [S.w]
[GOAL]
case mk.intro
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
T : Over X
g : (𝟭 C).obj T.left ⟶ Y
hT : g ≫ f = T.hom
y : D := { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
x : D := { obj := Over.mk T.hom, property := (_ : ∃ e, e ≫ f = (Over.mk T.hom).hom) }
g' : x ⟶ y := Over.homMk g
⊢ NatTrans.app S.ι x = NatTrans.app S.ι { obj := T, property := (_ : ∃ e, e ≫ f = T.hom) }
[PROOFSTEP]
rfl
[GOAL]
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
⊢ ∀ (s : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows))
    (m : (Presieve.cocone (Sieve.generateSingleton f).arrows).pt ⟶ s.pt),
    (∀ (j : FullSubcategory fun f_1 => (Sieve.generateSingleton f).arrows f_1.hom),
        NatTrans.app (Presieve.cocone (Sieve.generateSingleton f).arrows).ι j ≫ m = NatTrans.app s.ι j) →
      m =
        (fun S =>
            EffectiveEpiStruct.desc Hf
              (NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) })
              (_ :
                ∀ {Z : C} (g₁ g₂ : Z ⟶ Y) (h : g₁ ≫ f = g₂ ≫ f),
                  let Y' := { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) };
                  let Z' := { obj := Over.mk (g₁ ≫ f), property := (_ : ∃ e, e ≫ f = (Over.mk (g₁ ≫ f)).hom) };
                  let g₁' := Over.homMk g₁;
                  let g₂' := Over.homMk g₂;
                  F.map g₁' ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) } =
                    F.map g₂' ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }))
          s
[PROOFSTEP]
intro S m hm
[GOAL]
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
m : (Presieve.cocone (Sieve.generateSingleton f).arrows).pt ⟶ S.pt
hm :
  ∀ (j : FullSubcategory fun f_1 => (Sieve.generateSingleton f).arrows f_1.hom),
    NatTrans.app (Presieve.cocone (Sieve.generateSingleton f).arrows).ι j ≫ m = NatTrans.app S.ι j
⊢ m =
    (fun S =>
        EffectiveEpiStruct.desc Hf
          (NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) })
          (_ :
            ∀ {Z : C} (g₁ g₂ : Z ⟶ Y) (h : g₁ ≫ f = g₂ ≫ f),
              let Y' := { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) };
              let Z' := { obj := Over.mk (g₁ ≫ f), property := (_ : ∃ e, e ≫ f = (Over.mk (g₁ ≫ f)).hom) };
              let g₁' := Over.homMk g₁;
              let g₂' := Over.homMk g₂;
              F.map g₁' ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) } =
                F.map g₂' ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }))
      S
[PROOFSTEP]
dsimp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
m : (Presieve.cocone (Sieve.generateSingleton f).arrows).pt ⟶ S.pt
hm :
  ∀ (j : FullSubcategory fun f_1 => (Sieve.generateSingleton f).arrows f_1.hom),
    NatTrans.app (Presieve.cocone (Sieve.generateSingleton f).arrows).ι j ≫ m = NatTrans.app S.ι j
⊢ m =
    EffectiveEpiStruct.desc Hf (NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = f) })
      (_ :
        ∀ {Z : C} (g₁ g₂ : Z ⟶ Y),
          g₁ ≫ f = g₂ ≫ f →
            g₁ ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = f) } =
              g₂ ≫ NatTrans.app S.ι { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = f) })
[PROOFSTEP]
generalize_proofs h1 h2
[GOAL]
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
m : (Presieve.cocone (Sieve.generateSingleton f).arrows).pt ⟶ S.pt
hm :
  ∀ (j : FullSubcategory fun f_1 => (Sieve.generateSingleton f).arrows f_1.hom),
    NatTrans.app (Presieve.cocone (Sieve.generateSingleton f).arrows).ι j ≫ m = NatTrans.app S.ι j
h1 : ∃ e, e ≫ f = f
h2 :
  ∀ {Z : C} (g₁ g₂ : Z ⟶ Y),
    g₁ ≫ f = g₂ ≫ f →
      g₁ ≫ NatTrans.app S.ι { obj := Over.mk f, property := h1 } =
        g₂ ≫ NatTrans.app S.ι { obj := Over.mk f, property := h1 }
⊢ m = EffectiveEpiStruct.desc Hf (NatTrans.app S.ι { obj := Over.mk f, property := h1 }) h2
[PROOFSTEP]
apply Hf.uniq _ h2
[GOAL]
case a
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
m : (Presieve.cocone (Sieve.generateSingleton f).arrows).pt ⟶ S.pt
hm :
  ∀ (j : FullSubcategory fun f_1 => (Sieve.generateSingleton f).arrows f_1.hom),
    NatTrans.app (Presieve.cocone (Sieve.generateSingleton f).arrows).ι j ≫ m = NatTrans.app S.ι j
h1 : ∃ e, e ≫ f = f
h2 :
  ∀ {Z : C} (g₁ g₂ : Z ⟶ Y),
    g₁ ≫ f = g₂ ≫ f →
      g₁ ≫ NatTrans.app S.ι { obj := Over.mk f, property := h1 } =
        g₂ ≫ NatTrans.app S.ι { obj := Over.mk f, property := h1 }
⊢ f ≫ m = NatTrans.app S.ι { obj := Over.mk f, property := h1 }
[PROOFSTEP]
exact hm ⟨Over.mk f, 𝟙 _, by simp⟩
[GOAL]
C : Type u_1
inst✝ : Category.{?u.8526, u_1} C
X Y : C
f : Y ⟶ X
Hf : EffectiveEpiStruct f
D : Type (max u_1 ?u.8526) := FullSubcategory fun T => (Sieve.generateSingleton f).arrows T.hom
F : D ⥤ C := Presieve.diagram (Sieve.generateSingleton f).arrows
S : Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows)
m : (Presieve.cocone (Sieve.generateSingleton f).arrows).pt ⟶ S.pt
hm :
  ∀ (j : FullSubcategory fun f_1 => (Sieve.generateSingleton f).arrows f_1.hom),
    NatTrans.app (Presieve.cocone (Sieve.generateSingleton f).arrows).ι j ≫ m = NatTrans.app S.ι j
h1 : ∃ e, e ≫ f = f
h2 :
  ∀ {Z : C} (g₁ g₂ : Z ⟶ Y),
    g₁ ≫ f = g₂ ≫ f →
      g₁ ≫ NatTrans.app S.ι { obj := Over.mk f, property := h1 } =
        g₂ ≫ NatTrans.app S.ι { obj := Over.mk f, property := h1 }
⊢ 𝟙 ((𝟭 C).obj (Over.mk f).left) ≫ f = (Over.mk f).hom
[PROOFSTEP]
simp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
⊢ ∀ ⦃X_1 Y_1 : FullSubcategory fun f_1 => (Sieve.generateSingleton f).arrows f_1.hom⦄ (f_1 : X_1 ⟶ Y_1),
    (Presieve.diagram (Sieve.generateSingleton f).arrows).map f_1 ≫
        (fun x =>
            match x with
            | { obj := T, property := hT } => Exists.choose hT ≫ e)
          Y_1 =
      (fun x =>
            match x with
            | { obj := T, property := hT } => Exists.choose hT ≫ e)
          X_1 ≫
        ((Functor.const (FullSubcategory fun f_2 => (Sieve.generateSingleton f).arrows f_2.hom)).obj W).map f_1
[PROOFSTEP]
rintro ⟨A, hA⟩ ⟨B, hB⟩ (q : A ⟶ B)
[GOAL]
case mk.mk
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
A : Over X
hA : (Sieve.generateSingleton f).arrows A.hom
B : Over X
hB : (Sieve.generateSingleton f).arrows B.hom
q : A ⟶ B
⊢ (Presieve.diagram (Sieve.generateSingleton f).arrows).map q ≫
      (fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e)
        { obj := B, property := hB } =
    (fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e)
        { obj := A, property := hA } ≫
      ((Functor.const (FullSubcategory fun f_1 => (Sieve.generateSingleton f).arrows f_1.hom)).obj W).map q
[PROOFSTEP]
dsimp
[GOAL]
case mk.mk
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
A : Over X
hA : (Sieve.generateSingleton f).arrows A.hom
B : Over X
hB : (Sieve.generateSingleton f).arrows B.hom
q : A ⟶ B
⊢ q.left ≫ Exists.choose hB ≫ e = (Exists.choose hA ≫ e) ≫ 𝟙 W
[PROOFSTEP]
simp only [← Category.assoc, Category.comp_id]
[GOAL]
case mk.mk
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
A : Over X
hA : (Sieve.generateSingleton f).arrows A.hom
B : Over X
hB : (Sieve.generateSingleton f).arrows B.hom
q : A ⟶ B
⊢ (q.left ≫ Exists.choose hB) ≫ e = Exists.choose hA ≫ e
[PROOFSTEP]
apply h
[GOAL]
case mk.mk.a
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
A : Over X
hA : (Sieve.generateSingleton f).arrows A.hom
B : Over X
hB : (Sieve.generateSingleton f).arrows B.hom
q : A ⟶ B
⊢ (q.left ≫ Exists.choose hB) ≫ f = Exists.choose hA ≫ f
[PROOFSTEP]
rw [Category.assoc, hB.choose_spec, hA.choose_spec, Over.w]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
⊢ ∀ {W : C} (e : Y ⟶ W) (h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e),
    f ≫
        (fun {W} e h => IsColimit.desc Hf (aux e (_ : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e))) e
          (_ : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) =
      e
[PROOFSTEP]
intro W e h
[GOAL]
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
⊢ f ≫
      (fun {W} e h => IsColimit.desc Hf (aux e (_ : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e))) e
        (_ : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) =
    e
[PROOFSTEP]
dsimp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
⊢ f ≫
      IsColimit.desc Hf
        { pt := W, ι := NatTrans.mk fun x => Exists.choose (_ : (Sieve.generateSingleton f).arrows x.obj.hom) ≫ e } =
    e
[PROOFSTEP]
have := Hf.fac (aux e h) ⟨Over.mk f, 𝟙 _, by simp⟩
[GOAL]
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
⊢ 𝟙 ((𝟭 C).obj (Over.mk f).left) ≫ f = (Over.mk f).hom
[PROOFSTEP]
simp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
this :
  NatTrans.app (Presieve.cocone (Sieve.generateSingleton f).arrows).ι
        { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) } ≫
      IsColimit.desc Hf (aux e (_ : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e)) =
    NatTrans.app (aux e (_ : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e)).ι
      { obj := Over.mk f, property := (_ : ∃ e, e ≫ f = (Over.mk f).hom) }
⊢ f ≫
      IsColimit.desc Hf
        { pt := W, ι := NatTrans.mk fun x => Exists.choose (_ : (Sieve.generateSingleton f).arrows x.obj.hom) ≫ e } =
    e
[PROOFSTEP]
dsimp at this
[GOAL]
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
this :
  f ≫
      IsColimit.desc Hf
        { pt := W, ι := NatTrans.mk fun x => Exists.choose (_ : (Sieve.generateSingleton f).arrows x.obj.hom) ≫ e } =
    Exists.choose (_ : ∃ e, e ≫ f = f) ≫ e
⊢ f ≫
      IsColimit.desc Hf
        { pt := W, ι := NatTrans.mk fun x => Exists.choose (_ : (Sieve.generateSingleton f).arrows x.obj.hom) ≫ e } =
    e
[PROOFSTEP]
rw [this]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
this :
  f ≫
      IsColimit.desc Hf
        { pt := W, ι := NatTrans.mk fun x => Exists.choose (_ : (Sieve.generateSingleton f).arrows x.obj.hom) ≫ e } =
    Exists.choose (_ : ∃ e, e ≫ f = f) ≫ e
⊢ Exists.choose (_ : ∃ e, e ≫ f = f) ≫ e = e
[PROOFSTEP]
clear this
[GOAL]
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
⊢ Exists.choose (_ : ∃ e, e ≫ f = f) ≫ e = e
[PROOFSTEP]
nth_rewrite 2 [← Category.id_comp e]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
⊢ Exists.choose (_ : ∃ e, e ≫ f = f) ≫ e = 𝟙 Y ≫ e
[PROOFSTEP]
apply h
[GOAL]
case a
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
⊢ Exists.choose (_ : ∃ e, e ≫ f = f) ≫ f = 𝟙 Y ≫ f
[PROOFSTEP]
generalize_proofs hh
[GOAL]
case a
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
hh : ∃ e, e ≫ f = f
⊢ Exists.choose hh ≫ f = 𝟙 Y ≫ f
[PROOFSTEP]
rw [hh.choose_spec, Category.id_comp]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
⊢ ∀ {W : C} (e : Y ⟶ W) (h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) (m : X ⟶ W),
    f ≫ m = e →
      m =
        (fun {W} e h => IsColimit.desc Hf (aux e (_ : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e))) e
          (_ : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e)
[PROOFSTEP]
intro W e h m hm
[GOAL]
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
m : X ⟶ W
hm : f ≫ m = e
⊢ m =
    (fun {W} e h => IsColimit.desc Hf (aux e (_ : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e))) e
      (_ : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e)
[PROOFSTEP]
dsimp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
m : X ⟶ W
hm : f ≫ m = e
⊢ m =
    IsColimit.desc Hf
      { pt := W, ι := NatTrans.mk fun x => Exists.choose (_ : (Sieve.generateSingleton f).arrows x.obj.hom) ≫ e }
[PROOFSTEP]
apply Hf.uniq (aux e h)
[GOAL]
case x
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
m : X ⟶ W
hm : f ≫ m = e
⊢ ∀ (j : FullSubcategory fun f_1 => (Sieve.generateSingleton f).arrows f_1.hom),
    NatTrans.app (Presieve.cocone (Sieve.generateSingleton f).arrows).ι j ≫ m =
      NatTrans.app (aux e (_ : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e)).ι j
[PROOFSTEP]
rintro ⟨A, g, hA⟩
[GOAL]
case x.mk.intro
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
m : X ⟶ W
hm : f ≫ m = e
A : Over X
g : (𝟭 C).obj A.left ⟶ Y
hA : g ≫ f = A.hom
⊢ NatTrans.app (Presieve.cocone (Sieve.generateSingleton f).arrows).ι
        { obj := A, property := (_ : ∃ e, e ≫ f = A.hom) } ≫
      m =
    NatTrans.app (aux e (_ : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e)).ι
      { obj := A, property := (_ : ∃ e, e ≫ f = A.hom) }
[PROOFSTEP]
dsimp
[GOAL]
case x.mk.intro
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
m : X ⟶ W
hm : f ≫ m = e
A : Over X
g : (𝟭 C).obj A.left ⟶ Y
hA : g ≫ f = A.hom
⊢ A.hom ≫ m = Exists.choose (_ : ∃ e, e ≫ f = A.hom) ≫ e
[PROOFSTEP]
nth_rewrite 1 [← hA, Category.assoc, hm]
[GOAL]
case x.mk.intro
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
m : X ⟶ W
hm : f ≫ m = e
A : Over X
g : (𝟭 C).obj A.left ⟶ Y
hA : g ≫ f = A.hom
⊢ g ≫ e = Exists.choose (_ : ∃ e, e ≫ f = A.hom) ≫ e
[PROOFSTEP]
apply h
[GOAL]
case x.mk.intro.a
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
m : X ⟶ W
hm : f ≫ m = e
A : Over X
g : (𝟭 C).obj A.left ⟶ Y
hA : g ≫ f = A.hom
⊢ g ≫ f = Exists.choose (_ : ∃ e, e ≫ f = A.hom) ≫ f
[PROOFSTEP]
generalize_proofs hh
[GOAL]
case x.mk.intro.a
C : Type u_1
inst✝ : Category.{?u.20742, u_1} C
X Y : C
f : Y ⟶ X
Hf : IsColimit (Presieve.cocone (Sieve.generateSingleton f).arrows)
aux : {W : C} →
  (e : Y ⟶ W) →
    (∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e) →
      Cocone (Presieve.diagram (Sieve.generateSingleton f).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } => Exists.choose hT ≫ e }
W : C
e : Y ⟶ W
h : ∀ {Z : C} (g₁ g₂ : Z ⟶ Y), g₁ ≫ f = g₂ ≫ f → g₁ ≫ e = g₂ ≫ e
m : X ⟶ W
hm : f ≫ m = e
A : Over X
g : (𝟭 C).obj A.left ⟶ Y
hA : g ≫ f = A.hom
hh : ∃ e, e ≫ f = A.hom
⊢ g ≫ f = Exists.choose hh ≫ f
[PROOFSTEP]
rwa [hh.choose_spec]
[GOAL]
C : Type u_1
inst✝ : Category.{u_2, u_1} C
X Y : C
f : Y ⟶ X
⊢ Presieve.EffectiveEpimorphic (Presieve.singleton f) ↔ EffectiveEpi f
[PROOFSTEP]
constructor
[GOAL]
case mp
C : Type u_1
inst✝ : Category.{u_2, u_1} C
X Y : C
f : Y ⟶ X
⊢ Presieve.EffectiveEpimorphic (Presieve.singleton f) → EffectiveEpi f
[PROOFSTEP]
intro (h : Nonempty _)
[GOAL]
case mp
C : Type u_1
inst✝ : Category.{u_2, u_1} C
X Y : C
f : Y ⟶ X
h : Nonempty (IsColimit (Presieve.cocone (generate (Presieve.singleton f)).arrows))
⊢ EffectiveEpi f
[PROOFSTEP]
rw [Sieve.generateSingleton_eq] at h
[GOAL]
case mp
C : Type u_1
inst✝ : Category.{u_2, u_1} C
X Y : C
f : Y ⟶ X
h : Nonempty (IsColimit (Presieve.cocone (generateSingleton f).arrows))
⊢ EffectiveEpi f
[PROOFSTEP]
constructor
[GOAL]
case mp.effectiveEpi
C : Type u_1
inst✝ : Category.{u_2, u_1} C
X Y : C
f : Y ⟶ X
h : Nonempty (IsColimit (Presieve.cocone (generateSingleton f).arrows))
⊢ Nonempty (EffectiveEpiStruct f)
[PROOFSTEP]
apply Nonempty.map (effectiveEpiStructOfIsColimit _) h
[GOAL]
case mpr
C : Type u_1
inst✝ : Category.{u_2, u_1} C
X Y : C
f : Y ⟶ X
⊢ EffectiveEpi f → Presieve.EffectiveEpimorphic (Presieve.singleton f)
[PROOFSTEP]
rintro ⟨h⟩
[GOAL]
case mpr.mk
C : Type u_1
inst✝ : Category.{u_2, u_1} C
X Y : C
f : Y ⟶ X
h : Nonempty (EffectiveEpiStruct f)
⊢ Presieve.EffectiveEpimorphic (Presieve.singleton f)
[PROOFSTEP]
show Nonempty _
[GOAL]
case mpr.mk
C : Type u_1
inst✝ : Category.{u_2, u_1} C
X Y : C
f : Y ⟶ X
h : Nonempty (EffectiveEpiStruct f)
⊢ Nonempty (IsColimit (Presieve.cocone (generate (Presieve.singleton f)).arrows))
[PROOFSTEP]
rw [Sieve.generateSingleton_eq]
[GOAL]
case mpr.mk
C : Type u_1
inst✝ : Category.{u_2, u_1} C
X Y : C
f : Y ⟶ X
h : Nonempty (EffectiveEpiStruct f)
⊢ Nonempty (IsColimit (Presieve.cocone (generateSingleton f).arrows))
[PROOFSTEP]
apply Nonempty.map (isColimitOfEffectiveEpiStruct _) h
[GOAL]
C : Type u_1
inst✝ : Category.{?u.36898, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
⊢ ∀ {Y Z : C} {f : Y ⟶ B},
    (fun Y => {f | ∃ a g, g ≫ π a = f}) Y f → ∀ (g : Z ⟶ Y), (fun Y => {f | ∃ a g, g ≫ π a = f}) Z (g ≫ f)
[PROOFSTEP]
rintro Y₁ Y₂ g₁ ⟨a, q, rfl⟩ e
[GOAL]
case intro.intro
C : Type u_1
inst✝ : Category.{?u.36898, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
Y₁ Y₂ : C
a : α
q : Y₁ ⟶ X a
e : Y₂ ⟶ Y₁
⊢ setOf (fun f => ∃ a g, g ≫ π a = f) (e ≫ q ≫ π a)
[PROOFSTEP]
refine ⟨a, e ≫ q, by simp⟩
[GOAL]
C : Type u_1
inst✝ : Category.{?u.36898, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
Y₁ Y₂ : C
a : α
q : Y₁ ⟶ X a
e : Y₂ ⟶ Y₁
⊢ (e ≫ q) ≫ π a = e ≫ q ≫ π a
[PROOFSTEP]
simp
[GOAL]
C : Type u_1
inst✝ : Category.{u_3, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
⊢ generate (Presieve.ofArrows X π) = generateFamily X π
[PROOFSTEP]
ext Y g
[GOAL]
case h
C : Type u_1
inst✝ : Category.{u_3, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
Y : C
g : Y ⟶ B
⊢ (generate (Presieve.ofArrows X π)).arrows g ↔ (generateFamily X π).arrows g
[PROOFSTEP]
constructor
[GOAL]
case h.mp
C : Type u_1
inst✝ : Category.{u_3, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
Y : C
g : Y ⟶ B
⊢ (generate (Presieve.ofArrows X π)).arrows g → (generateFamily X π).arrows g
[PROOFSTEP]
rintro ⟨W, g, f, ⟨a⟩, rfl⟩
[GOAL]
case h.mp.intro.intro.intro.intro.mk
C : Type u_1
inst✝ : Category.{u_3, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
Y✝ Y : C
a : α
g : Y✝ ⟶ X a
⊢ (generateFamily X π).arrows (g ≫ π a)
[PROOFSTEP]
exact ⟨a, g, rfl⟩
[GOAL]
case h.mpr
C : Type u_1
inst✝ : Category.{u_3, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
Y : C
g : Y ⟶ B
⊢ (generateFamily X π).arrows g → (generate (Presieve.ofArrows X π)).arrows g
[PROOFSTEP]
rintro ⟨a, g, rfl⟩
[GOAL]
case h.mpr.intro.intro
C : Type u_1
inst✝ : Category.{u_3, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
Y : C
a : α
g : Y ⟶ X a
⊢ (generate (Presieve.ofArrows X π)).arrows (g ≫ π a)
[PROOFSTEP]
refine ⟨_, g, π a, ⟨a⟩, rfl⟩
[GOAL]
C : Type u_1
inst✝ : Category.{?u.43458, 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₂)
    (a : Unit),
    𝟙 (α ()) ≫
        (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₂) =
      e a
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u_1
inst✝ : Category.{?u.43458, 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₂)
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u_1
inst✝¹ : Category.{?u.51706, 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
[PROOFSTEP]
simp
[GOAL]
C : Type u_1
inst✝¹ : Category.{?u.52695, 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
[PROOFSTEP]
simp
[GOAL]
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₂
[PROOFSTEP]
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
[GOAL]
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₂
[PROOFSTEP]
simp only [← Category.assoc, h]
[GOAL]
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₂)
[PROOFSTEP]
apply EffectiveEpiFamily.uniq
[GOAL]
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₂
[PROOFSTEP]
intro
[GOAL]
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₂
[PROOFSTEP]
rfl
[GOAL]
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₂
[PROOFSTEP]
rw [this]
[GOAL]
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₂)
[PROOFSTEP]
exact EffectiveEpiFamily.uniq _ _ _ _ _ h
[GOAL]
C : Type u_1
inst✝² : Category.{?u.55691, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
inst✝¹ : EffectiveEpiFamily X π
inst✝ : HasCoproduct X
⊢ Epi (Sigma.desc π)
[PROOFSTEP]
constructor
[GOAL]
case left_cancellation
C : Type u_1
inst✝² : Category.{?u.55691, 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
[PROOFSTEP]
intro Z g h H
[GOAL]
case left_cancellation
C : Type u_1
inst✝² : Category.{?u.55691, 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
[PROOFSTEP]
apply EffectiveEpiFamily.hom_ext X π
[GOAL]
case left_cancellation.h
C : Type u_1
inst✝² : Category.{?u.55691, 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
[PROOFSTEP]
intro a
[GOAL]
case left_cancellation.h
C : Type u_1
inst✝² : Category.{?u.55691, 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
[PROOFSTEP]
suffices (Sigma.ι _ a ≫ Sigma.desc π) ≫ g = (Sigma.ι _ a ≫ Sigma.desc π) ≫ h by simpa only [colimit.ι_desc] using this
[GOAL]
C : Type u_1
inst✝² : Category.{?u.55691, 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
[PROOFSTEP]
simpa only [colimit.ι_desc] using this
[GOAL]
case left_cancellation.h
C : Type u_1
inst✝² : Category.{?u.55691, 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
[PROOFSTEP]
simp only [Category.assoc, H]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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
[PROOFSTEP]
simp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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 =>
              NatTrans.app S.ι { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) })
            a₁ =
        g₂ ≫
          (fun a =>
              NatTrans.app S.ι { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) })
            a₂
[PROOFSTEP]
intro Z a₁ a₂ g₁ g₂ h
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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 => NatTrans.app S.ι { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) })
        a₁ =
    g₂ ≫
      (fun a => NatTrans.app S.ι { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) })
        a₂
[PROOFSTEP]
dsimp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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₁ ≫ NatTrans.app S.ι { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = π a₁) } =
    g₂ ≫ NatTrans.app S.ι { obj := Over.mk (π a₂), property := (_ : ∃ a g, g ≫ π a = π a₂) }
[PROOFSTEP]
let A₁ : D := ⟨Over.mk (π a₁), a₁, 𝟙 _, by simp⟩
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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
[PROOFSTEP]
simp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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₁ ≫ NatTrans.app S.ι { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = π a₁) } =
    g₂ ≫ NatTrans.app S.ι { obj := Over.mk (π a₂), property := (_ : ∃ a g, g ≫ π a = π a₂) }
[PROOFSTEP]
let A₂ : D := ⟨Over.mk (π a₂), a₂, 𝟙 _, by simp⟩
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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
[PROOFSTEP]
simp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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₁ ≫ NatTrans.app S.ι { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = π a₁) } =
    g₂ ≫ NatTrans.app S.ι { obj := Over.mk (π a₂), property := (_ : ∃ a g, g ≫ π a = π a₂) }
[PROOFSTEP]
let Z' : D := ⟨Over.mk (g₁ ≫ π a₁), a₁, g₁, rfl⟩
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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₁ ≫ NatTrans.app S.ι { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = π a₁) } =
    g₂ ≫ NatTrans.app S.ι { obj := Over.mk (π a₂), property := (_ : ∃ a g, g ≫ π a = π a₂) }
[PROOFSTEP]
let i₁ : Z' ⟶ A₁ := Over.homMk g₁
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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₁ ≫ NatTrans.app S.ι { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = π a₁) } =
    g₂ ≫ NatTrans.app S.ι { obj := Over.mk (π a₂), property := (_ : ∃ a g, g ≫ π a = π a₂) }
[PROOFSTEP]
let i₂ : Z' ⟶ A₂ := Over.homMk g₂
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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₁ ≫ NatTrans.app S.ι { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = π a₁) } =
    g₂ ≫ NatTrans.app S.ι { obj := Over.mk (π a₂), property := (_ : ∃ a g, g ≫ π a = π a₂) }
[PROOFSTEP]
change F.map i₁ ≫ _ = F.map i₂ ≫ _
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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₁ ≫ NatTrans.app S.ι { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = π a₁) } =
    F.map i₂ ≫ NatTrans.app S.ι { obj := Over.mk (π a₂), property := (_ : ∃ a g, g ≫ π a = π a₂) }
[PROOFSTEP]
simp only [S.w]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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),
    NatTrans.app (Presieve.cocone (Sieve.generateFamily X π).arrows).ι j ≫
        (fun S =>
            EffectiveEpiFamilyStruct.desc H
              (fun a =>
                NatTrans.app S.ι { 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 =>
                            NatTrans.app S.ι
                              { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) })
                          a₁ =
                      g₂ ≫
                        (fun a =>
                            NatTrans.app S.ι
                              { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) })
                          a₂))
          s =
      NatTrans.app s.ι j
[PROOFSTEP]
intro S ⟨T, a, (g : T.left ⟶ X a), hT⟩
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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
⊢ NatTrans.app (Presieve.cocone (Sieve.generateFamily X π).arrows).ι
        { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) } ≫
      (fun S =>
          EffectiveEpiFamilyStruct.desc H
            (fun a =>
              NatTrans.app S.ι { 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 =>
                          NatTrans.app S.ι
                            { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) })
                        a₁ =
                    g₂ ≫
                      (fun a =>
                          NatTrans.app S.ι
                            { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) })
                        a₂))
        S =
    NatTrans.app S.ι { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) }
[PROOFSTEP]
dsimp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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 => NatTrans.app S.ι { 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₁ ≫ NatTrans.app S.ι { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = π a₁) } =
                g₂ ≫ NatTrans.app S.ι { obj := Over.mk (π a₂), property := (_ : ∃ a g, g ≫ π a = π a₂) }) =
    NatTrans.app S.ι { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) }
[PROOFSTEP]
nth_rewrite 1 [← hT, Category.assoc, H.fac]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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 ≫ NatTrans.app S.ι { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = π a) } =
    NatTrans.app S.ι { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) }
[PROOFSTEP]
let A : D := ⟨Over.mk (π a), a, 𝟙 _, by simp⟩
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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
[PROOFSTEP]
simp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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 ≫ NatTrans.app S.ι { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = π a) } =
    NatTrans.app S.ι { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) }
[PROOFSTEP]
let B : D := ⟨Over.mk T.hom, a, g, hT⟩
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B✝ : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B✝
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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 ≫ NatTrans.app S.ι { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = π a) } =
    NatTrans.app S.ι { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) }
[PROOFSTEP]
let i : B ⟶ A := Over.homMk g
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B✝ : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B✝
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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 ≫ NatTrans.app S.ι { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = π a) } =
    NatTrans.app S.ι { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) }
[PROOFSTEP]
change F.map i ≫ _ = _
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B✝ : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B✝
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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 ≫ NatTrans.app S.ι { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = π a) } =
    NatTrans.app S.ι { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) }
[PROOFSTEP]
rw [S.w]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B✝ : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B✝
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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
⊢ NatTrans.app S.ι B = NatTrans.app S.ι { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) }
[PROOFSTEP]
rfl
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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))
    (m : (Presieve.cocone (Sieve.generateFamily X π).arrows).pt ⟶ s.pt),
    (∀ (j : FullSubcategory fun f => (Sieve.generateFamily X π).arrows f.hom),
        NatTrans.app (Presieve.cocone (Sieve.generateFamily X π).arrows).ι j ≫ m = NatTrans.app s.ι j) →
      m =
        (fun S =>
            EffectiveEpiFamilyStruct.desc H
              (fun a =>
                NatTrans.app S.ι { 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 =>
                            NatTrans.app S.ι
                              { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) })
                          a₁ =
                      g₂ ≫
                        (fun a =>
                            NatTrans.app S.ι
                              { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) })
                          a₂))
          s
[PROOFSTEP]
intro S m hm
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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)
m : (Presieve.cocone (Sieve.generateFamily X π).arrows).pt ⟶ S.pt
hm :
  ∀ (j : FullSubcategory fun f => (Sieve.generateFamily X π).arrows f.hom),
    NatTrans.app (Presieve.cocone (Sieve.generateFamily X π).arrows).ι j ≫ m = NatTrans.app S.ι j
⊢ m =
    (fun S =>
        EffectiveEpiFamilyStruct.desc H
          (fun a =>
            NatTrans.app S.ι { 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 =>
                        NatTrans.app S.ι
                          { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) })
                      a₁ =
                  g₂ ≫
                    (fun a =>
                        NatTrans.app S.ι
                          { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) })
                      a₂))
      S
[PROOFSTEP]
dsimp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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)
m : (Presieve.cocone (Sieve.generateFamily X π).arrows).pt ⟶ S.pt
hm :
  ∀ (j : FullSubcategory fun f => (Sieve.generateFamily X π).arrows f.hom),
    NatTrans.app (Presieve.cocone (Sieve.generateFamily X π).arrows).ι j ≫ m = NatTrans.app S.ι j
⊢ m =
    EffectiveEpiFamilyStruct.desc H
      (fun a => NatTrans.app S.ι { 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₁ ≫ NatTrans.app S.ι { obj := Over.mk (π a₁), property := (_ : ∃ a g, g ≫ π a = π a₁) } =
              g₂ ≫ NatTrans.app S.ι { obj := Over.mk (π a₂), property := (_ : ∃ a g, g ≫ π a = π a₂) })
[PROOFSTEP]
apply H.uniq
[GOAL]
case a
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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)
m : (Presieve.cocone (Sieve.generateFamily X π).arrows).pt ⟶ S.pt
hm :
  ∀ (j : FullSubcategory fun f => (Sieve.generateFamily X π).arrows f.hom),
    NatTrans.app (Presieve.cocone (Sieve.generateFamily X π).arrows).ι j ≫ m = NatTrans.app S.ι j
⊢ ∀ (a : α), π a ≫ m = NatTrans.app S.ι { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = π a) }
[PROOFSTEP]
intro a
[GOAL]
case a
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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)
m : (Presieve.cocone (Sieve.generateFamily X π).arrows).pt ⟶ S.pt
hm :
  ∀ (j : FullSubcategory fun f => (Sieve.generateFamily X π).arrows f.hom),
    NatTrans.app (Presieve.cocone (Sieve.generateFamily X π).arrows).ι j ≫ m = NatTrans.app S.ι j
a : α
⊢ π a ≫ m = NatTrans.app S.ι { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = π a) }
[PROOFSTEP]
exact hm ⟨Over.mk (π a), a, 𝟙 _, by simp⟩
[GOAL]
C : Type u_1
inst✝ : Category.{?u.59810, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : EffectiveEpiFamilyStruct X π
D : Type (max u_1 ?u.59810) := 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)
m : (Presieve.cocone (Sieve.generateFamily X π).arrows).pt ⟶ S.pt
hm :
  ∀ (j : FullSubcategory fun f => (Sieve.generateFamily X π).arrows f.hom),
    NatTrans.app (Presieve.cocone (Sieve.generateFamily X π).arrows).ι j ≫ m = NatTrans.app S.ι j
a : α
⊢ 𝟙 ((𝟭 C).obj (Over.mk (π a)).left) ≫ π a = (Over.mk (π a)).hom
[PROOFSTEP]
simp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
W : C
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₂
⊢ ∀ ⦃X_1 Y : FullSubcategory fun f => (Sieve.generateFamily X π).arrows f.hom⦄ (f : X_1 ⟶ Y),
    (Presieve.diagram (Sieve.generateFamily X π).arrows).map f ≫
        (fun x =>
            match x with
            | { obj := T, property := hT } =>
              Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT))
          Y =
      (fun x =>
            match x with
            | { obj := T, property := hT } =>
              Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT))
          X_1 ≫
        ((Functor.const (FullSubcategory fun f => (Sieve.generateFamily X π).arrows f.hom)).obj W).map f
[PROOFSTEP]
intro ⟨A, a, (g₁ : A.left ⟶ _), ha⟩ ⟨B, b, (g₂ : B.left ⟶ _), hb⟩ (q : A ⟶ B)
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B✝ : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B✝
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
W : C
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 : Over B✝
a : α
g₁ : A.left ⟶ X a
ha : g₁ ≫ π a = A.hom
B : Over B✝
b : α
g₂ : B.left ⟶ X b
hb : g₂ ≫ π b = B.hom
q : A ⟶ B
⊢ (Presieve.diagram (Sieve.generateFamily X π).arrows).map q ≫
      (fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT))
        { obj := B, property := (_ : ∃ a g, g ≫ π a = B.hom) } =
    (fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT))
        { obj := A, property := (_ : ∃ a g, g ≫ π a = A.hom) } ≫
      ((Functor.const (FullSubcategory fun f => (Sieve.generateFamily X π).arrows f.hom)).obj W).map q
[PROOFSTEP]
dsimp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B✝ : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B✝
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
W : C
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 : Over B✝
a : α
g₁ : A.left ⟶ X a
ha : g₁ ≫ π a = A.hom
B : Over B✝
b : α
g₂ : B.left ⟶ X b
hb : g₂ ≫ π b = B.hom
q : A ⟶ B
⊢ q.left ≫
      Exists.choose (_ : ∃ g, g ≫ π (Exists.choose (_ : ∃ a g, g ≫ π a = B.hom)) = B.hom) ≫
        e (Exists.choose (_ : ∃ a g, g ≫ π a = B.hom)) =
    (Exists.choose (_ : ∃ g, g ≫ π (Exists.choose (_ : ∃ a g, g ≫ π a = A.hom)) = A.hom) ≫
        e (Exists.choose (_ : ∃ a g, g ≫ π a = A.hom))) ≫
      𝟙 W
[PROOFSTEP]
rw [Category.comp_id, ← Category.assoc]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B✝ : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B✝
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
W : C
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 : Over B✝
a : α
g₁ : A.left ⟶ X a
ha : g₁ ≫ π a = A.hom
B : Over B✝
b : α
g₂ : B.left ⟶ X b
hb : g₂ ≫ π b = B.hom
q : A ⟶ B
⊢ (q.left ≫ Exists.choose (_ : ∃ g, g ≫ π (Exists.choose (_ : ∃ a g, g ≫ π a = B.hom)) = B.hom)) ≫
      e (Exists.choose (_ : ∃ a g, g ≫ π a = B.hom)) =
    Exists.choose (_ : ∃ g, g ≫ π (Exists.choose (_ : ∃ a g, g ≫ π a = A.hom)) = A.hom) ≫
      e (Exists.choose (_ : ∃ a g, g ≫ π a = A.hom))
[PROOFSTEP]
apply h
[GOAL]
case a
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B✝ : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B✝
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
W : C
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 : Over B✝
a : α
g₁ : A.left ⟶ X a
ha : g₁ ≫ π a = A.hom
B : Over B✝
b : α
g₂ : B.left ⟶ X b
hb : g₂ ≫ π b = B.hom
q : A ⟶ B
⊢ (q.left ≫ Exists.choose (_ : ∃ g, g ≫ π (Exists.choose (_ : ∃ a g, g ≫ π a = B.hom)) = B.hom)) ≫
      π (Exists.choose (_ : ∃ a g, g ≫ π a = B.hom)) =
    Exists.choose (_ : ∃ g, g ≫ π (Exists.choose (_ : ∃ a g, g ≫ π a = A.hom)) = A.hom) ≫
      π (Exists.choose (_ : ∃ a g, g ≫ π a = A.hom))
[PROOFSTEP]
rw [Category.assoc]
[GOAL]
case a
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B✝ : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B✝
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
W : C
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 : Over B✝
a : α
g₁ : A.left ⟶ X a
ha : g₁ ≫ π a = A.hom
B : Over B✝
b : α
g₂ : B.left ⟶ X b
hb : g₂ ≫ π b = B.hom
q : A ⟶ B
⊢ q.left ≫
      Exists.choose (_ : ∃ g, g ≫ π (Exists.choose (_ : ∃ a g, g ≫ π a = B.hom)) = B.hom) ≫
        π (Exists.choose (_ : ∃ a g, g ≫ π a = B.hom)) =
    Exists.choose (_ : ∃ g, g ≫ π (Exists.choose (_ : ∃ a g, g ≫ π a = A.hom)) = A.hom) ≫
      π (Exists.choose (_ : ∃ a g, g ≫ π a = A.hom))
[PROOFSTEP]
generalize_proofs h1 h2 h3 h4
[GOAL]
case a
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B✝ : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B✝
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
W : C
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 : Over B✝
a : α
g₁ : A.left ⟶ X a
ha : g₁ ≫ π a = A.hom
B : Over B✝
b : α
g₂ : B.left ⟶ X b
hb : g₂ ≫ π b = B.hom
q : A ⟶ B
h1 : ∃ a g, g ≫ π a = B.hom
h2 : ∃ g, g ≫ π (Exists.choose h1) = B.hom
h3 : ∃ a g, g ≫ π a = A.hom
h4 : ∃ g, g ≫ π (Exists.choose h3) = A.hom
⊢ q.left ≫ Exists.choose h2 ≫ π (Exists.choose h1) = Exists.choose h4 ≫ π (Exists.choose h3)
[PROOFSTEP]
rw [h2.choose_spec, h4.choose_spec, Over.w]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
⊢ ∀ {W : C} (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 ≫
        (fun {W} e h =>
            IsColimit.desc H
              (aux e
                (_ :
                  ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂),
                    g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂)))
          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
[PROOFSTEP]
intro W e h a
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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 ≫
      (fun {W} e h =>
          IsColimit.desc H
            (aux e
              (_ :
                ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂)))
        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
[PROOFSTEP]
dsimp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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 ≫
      IsColimit.desc H
        { pt := W,
          ι :=
            NatTrans.mk fun x =>
              Exists.choose
                  (_ : ∃ g, g ≫ π (Exists.choose (_ : (Sieve.generateFamily X π).arrows x.obj.hom)) = x.obj.hom) ≫
                e (Exists.choose (_ : (Sieve.generateFamily X π).arrows x.obj.hom)) } =
    e a
[PROOFSTEP]
have := H.fac (aux e h) ⟨Over.mk (π a), a, 𝟙 _, by simp⟩
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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 : α
⊢ 𝟙 ((𝟭 C).obj (Over.mk (π a)).left) ≫ π a = (Over.mk (π a)).hom
[PROOFSTEP]
simp
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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 : α
this :
  NatTrans.app (Presieve.cocone (Sieve.generateFamily X π).arrows).ι
        { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) } ≫
      IsColimit.desc H
        (aux e
          (_ : ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂)) =
    NatTrans.app
      (aux e
          (_ : ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂)).ι
      { obj := Over.mk (π a), property := (_ : ∃ a_1 g, g ≫ π a_1 = (Over.mk (π a)).hom) }
⊢ π a ≫
      IsColimit.desc H
        { pt := W,
          ι :=
            NatTrans.mk fun x =>
              Exists.choose
                  (_ : ∃ g, g ≫ π (Exists.choose (_ : (Sieve.generateFamily X π).arrows x.obj.hom)) = x.obj.hom) ≫
                e (Exists.choose (_ : (Sieve.generateFamily X π).arrows x.obj.hom)) } =
    e a
[PROOFSTEP]
dsimp at this
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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 : α
this :
  π a ≫
      IsColimit.desc H
        { pt := W,
          ι :=
            NatTrans.mk fun x =>
              Exists.choose
                  (_ : ∃ g, g ≫ π (Exists.choose (_ : (Sieve.generateFamily X π).arrows x.obj.hom)) = x.obj.hom) ≫
                e (Exists.choose (_ : (Sieve.generateFamily X π).arrows x.obj.hom)) } =
    Exists.choose (_ : ∃ g, g ≫ π (Exists.choose (_ : ∃ a_1 g, g ≫ π a_1 = π a)) = π a) ≫
      e (Exists.choose (_ : ∃ a_1 g, g ≫ π a_1 = π a))
⊢ π a ≫
      IsColimit.desc H
        { pt := W,
          ι :=
            NatTrans.mk fun x =>
              Exists.choose
                  (_ : ∃ g, g ≫ π (Exists.choose (_ : (Sieve.generateFamily X π).arrows x.obj.hom)) = x.obj.hom) ≫
                e (Exists.choose (_ : (Sieve.generateFamily X π).arrows x.obj.hom)) } =
    e a
[PROOFSTEP]
rw [this]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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 : α
this :
  π a ≫
      IsColimit.desc H
        { pt := W,
          ι :=
            NatTrans.mk fun x =>
              Exists.choose
                  (_ : ∃ g, g ≫ π (Exists.choose (_ : (Sieve.generateFamily X π).arrows x.obj.hom)) = x.obj.hom) ≫
                e (Exists.choose (_ : (Sieve.generateFamily X π).arrows x.obj.hom)) } =
    Exists.choose (_ : ∃ g, g ≫ π (Exists.choose (_ : ∃ a_1 g, g ≫ π a_1 = π a)) = π a) ≫
      e (Exists.choose (_ : ∃ a_1 g, g ≫ π a_1 = π a))
⊢ Exists.choose (_ : ∃ g, g ≫ π (Exists.choose (_ : ∃ a_1 g, g ≫ π a_1 = π a)) = π a) ≫
      e (Exists.choose (_ : ∃ a_1 g, g ≫ π a_1 = π a)) =
    e a
[PROOFSTEP]
clear this
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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 : α
⊢ Exists.choose (_ : ∃ g, g ≫ π (Exists.choose (_ : ∃ a_1 g, g ≫ π a_1 = π a)) = π a) ≫
      e (Exists.choose (_ : ∃ a_1 g, g ≫ π a_1 = π a)) =
    e a
[PROOFSTEP]
conv_rhs => rw [← Category.id_comp (e a)]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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 : α
| e a
[PROOFSTEP]
rw [← Category.id_comp (e a)]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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 : α
| e a
[PROOFSTEP]
rw [← Category.id_comp (e a)]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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 : α
| e a
[PROOFSTEP]
rw [← Category.id_comp (e a)]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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 : α
⊢ Exists.choose (_ : ∃ g, g ≫ π (Exists.choose (_ : ∃ a_1 g, g ≫ π a_1 = π a)) = π a) ≫
      e (Exists.choose (_ : ∃ a_1 g, g ≫ π a_1 = π a)) =
    𝟙 (X a) ≫ e a
[PROOFSTEP]
apply h
[GOAL]
case a
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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 : α
⊢ Exists.choose (_ : ∃ g, g ≫ π (Exists.choose (_ : ∃ a_1 g, g ≫ π a_1 = π a)) = π a) ≫
      π (Exists.choose (_ : ∃ a_1 g, g ≫ π a_1 = π a)) =
    𝟙 (X a) ≫ π a
[PROOFSTEP]
generalize_proofs h1 h2
[GOAL]
case a
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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 : α
h1 : ∃ a_1 g, g ≫ π a_1 = π a
h2 : ∃ g, g ≫ π (Exists.choose h1) = π a
⊢ Exists.choose h2 ≫ π (Exists.choose h1) = 𝟙 (X a) ≫ π a
[PROOFSTEP]
rw [h2.choose_spec, Category.id_comp]
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
⊢ ∀ {W : C} (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₂)
    (m : B ⟶ W),
    (∀ (a : α), π a ≫ m = e a) →
      m =
        (fun {W} e h =>
            IsColimit.desc H
              (aux e
                (_ :
                  ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂),
                    g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂)))
          e (_ : ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂)
[PROOFSTEP]
intro W e h m hm
[GOAL]
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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₂
m : B ⟶ W
hm : ∀ (a : α), π a ≫ m = e a
⊢ m =
    (fun {W} e h =>
        IsColimit.desc H
          (aux e
            (_ : ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂)))
      e (_ : ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂)
[PROOFSTEP]
apply H.uniq (aux e h)
[GOAL]
case x
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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₂
m : B ⟶ W
hm : ∀ (a : α), π a ≫ m = e a
⊢ ∀ (j : FullSubcategory fun f => (Sieve.generateFamily X π).arrows f.hom),
    NatTrans.app (Presieve.cocone (Sieve.generateFamily X π).arrows).ι j ≫ m =
      NatTrans.app
        (aux e
            (_ :
              ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂)).ι
        j
[PROOFSTEP]
rintro ⟨T, a, (g : T.left ⟶ _), ha⟩
[GOAL]
case x.mk.intro.intro
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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₂
m : B ⟶ W
hm : ∀ (a : α), π a ≫ m = e a
T : Over B
a : α
g : T.left ⟶ X a
ha : g ≫ π a = T.hom
⊢ NatTrans.app (Presieve.cocone (Sieve.generateFamily X π).arrows).ι
        { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) } ≫
      m =
    NatTrans.app
      (aux e
          (_ : ∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂)).ι
      { obj := T, property := (_ : ∃ a g, g ≫ π a = T.hom) }
[PROOFSTEP]
dsimp
[GOAL]
case x.mk.intro.intro
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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₂
m : B ⟶ W
hm : ∀ (a : α), π a ≫ m = e a
T : Over B
a : α
g : T.left ⟶ X a
ha : g ≫ π a = T.hom
⊢ T.hom ≫ m =
    Exists.choose (_ : ∃ g_1, g_1 ≫ π (Exists.choose (_ : ∃ a g, g ≫ π a = T.hom)) = T.hom) ≫
      e (Exists.choose (_ : ∃ a g, g ≫ π a = T.hom))
[PROOFSTEP]
nth_rewrite 1 [← ha, Category.assoc, hm]
[GOAL]
case x.mk.intro.intro
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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₂
m : B ⟶ W
hm : ∀ (a : α), π a ≫ m = e a
T : Over B
a : α
g : T.left ⟶ X a
ha : g ≫ π a = T.hom
⊢ g ≫ e a =
    Exists.choose (_ : ∃ g_1, g_1 ≫ π (Exists.choose (_ : ∃ a g, g ≫ π a = T.hom)) = T.hom) ≫
      e (Exists.choose (_ : ∃ a g, g ≫ π a = T.hom))
[PROOFSTEP]
apply h
[GOAL]
case x.mk.intro.intro.a
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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₂
m : B ⟶ W
hm : ∀ (a : α), π a ≫ m = e a
T : Over B
a : α
g : T.left ⟶ X a
ha : g ≫ π a = T.hom
⊢ g ≫ π a =
    Exists.choose (_ : ∃ g_1, g_1 ≫ π (Exists.choose (_ : ∃ a g, g ≫ π a = T.hom)) = T.hom) ≫
      π (Exists.choose (_ : ∃ a g, g ≫ π a = T.hom))
[PROOFSTEP]
generalize_proofs h1 h2
[GOAL]
case x.mk.intro.intro.a
C : Type u_1
inst✝ : Category.{?u.74817, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
H : IsColimit (Presieve.cocone (Sieve.generateFamily X π).arrows)
aux : {W : C} →
  (e : (a : α) → X a ⟶ W) →
    (∀ {Z : C} (a₁ a₂ : α) (g₁ : Z ⟶ X a₁) (g₂ : Z ⟶ X a₂), g₁ ≫ π a₁ = g₂ ≫ π a₂ → g₁ ≫ e a₁ = g₂ ≫ e a₂) →
      Cocone (Presieve.diagram (Sieve.generateFamily X π).arrows) :=
  fun {W} e h =>
    { pt := W,
      ι :=
        NatTrans.mk fun x =>
          match x with
          | { obj := T, property := hT } =>
            Exists.choose (_ : ∃ g, g ≫ π (Exists.choose hT) = T.hom) ≫ e (Exists.choose hT) }
W : C
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₂
m : B ⟶ W
hm : ∀ (a : α), π a ≫ m = e a
T : Over B
a : α
g : T.left ⟶ X a
ha : g ≫ π a = T.hom
h1 : ∃ a g, g ≫ π a = T.hom
h2 : ∃ g, g ≫ π (Exists.choose h1) = T.hom
⊢ g ≫ π a = Exists.choose h2 ≫ π (Exists.choose h1)
[PROOFSTEP]
rwa [h2.choose_spec]
[GOAL]
C : Type u_1
inst✝ : Category.{u_3, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
⊢ Presieve.EffectiveEpimorphic (Presieve.ofArrows X π) ↔ EffectiveEpiFamily X π
[PROOFSTEP]
constructor
[GOAL]
case mp
C : Type u_1
inst✝ : Category.{u_3, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
⊢ Presieve.EffectiveEpimorphic (Presieve.ofArrows X π) → EffectiveEpiFamily X π
[PROOFSTEP]
intro (h : Nonempty _)
[GOAL]
case mp
C : Type u_1
inst✝ : Category.{u_3, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
h : Nonempty (IsColimit (Presieve.cocone (generate (Presieve.ofArrows X π)).arrows))
⊢ EffectiveEpiFamily X π
[PROOFSTEP]
rw [Sieve.generateFamily_eq] at h
[GOAL]
case mp
C : Type u_1
inst✝ : Category.{u_3, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
h : Nonempty (IsColimit (Presieve.cocone (generateFamily X π).arrows))
⊢ EffectiveEpiFamily X π
[PROOFSTEP]
constructor
[GOAL]
case mp.effectiveEpiFamily
C : Type u_1
inst✝ : Category.{u_3, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
h : Nonempty (IsColimit (Presieve.cocone (generateFamily X π).arrows))
⊢ Nonempty (EffectiveEpiFamilyStruct X π)
[PROOFSTEP]
apply Nonempty.map (effectiveEpiFamilyStructOfIsColimit _ _) h
[GOAL]
case mpr
C : Type u_1
inst✝ : Category.{u_3, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
⊢ EffectiveEpiFamily X π → Presieve.EffectiveEpimorphic (Presieve.ofArrows X π)
[PROOFSTEP]
rintro ⟨h⟩
[GOAL]
case mpr.mk
C : Type u_1
inst✝ : Category.{u_3, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
h : Nonempty (EffectiveEpiFamilyStruct X π)
⊢ Presieve.EffectiveEpimorphic (Presieve.ofArrows X π)
[PROOFSTEP]
show Nonempty _
[GOAL]
case mpr.mk
C : Type u_1
inst✝ : Category.{u_3, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
h : Nonempty (EffectiveEpiFamilyStruct X π)
⊢ Nonempty (IsColimit (Presieve.cocone (generate (Presieve.ofArrows X π)).arrows))
[PROOFSTEP]
rw [Sieve.generateFamily_eq]
[GOAL]
case mpr.mk
C : Type u_1
inst✝ : Category.{u_3, u_1} C
B : C
α : Type u_2
X : α → C
π : (a : α) → X a ⟶ B
h : Nonempty (EffectiveEpiFamilyStruct X π)
⊢ Nonempty (IsColimit (Presieve.cocone (generateFamily X π).arrows))
[PROOFSTEP]
apply Nonempty.map (isColimitOfEffectiveEpiFamilyStruct _ _) h