l3lab/ntp-mathlib huggingface dataset:
/-- The curried version of yoneda lemma when `C` is small. -/
def curriedYonedaLemma {C : Type u₁} [SmallCategory C] :
    (yoneda.op ⋙ coyoneda : Cᵒᵖ ⥤ (Cᵒᵖ ⥤ Type u₁) ⥤ Type u₁) ≅ evaluation Cᵒᵖ (Type u₁) := by
  refine eqToIso ?_ ≪≫ curry.mapIso
    (yonedaLemma C ≪≫ isoWhiskerLeft (evaluationUncurried Cᵒᵖ (Type u₁)) uliftFunctorTrivial) ≪≫
    eqToIso ?_
  · apply Functor.ext
    · intro X Y f
      ext
      

Proof state:
case refine_1.h_map.w.h.h
C✝ : Type u₁
inst✝¹ : Category.{v₁, u₁} C✝
C : Type u₁
inst✝ : SmallCategory C
X Y : Cᵒᵖ
f : X ⟶ Y
x✝ : Cᵒᵖ ⥤ Type u₁
a✝ : ((yoneda.op ⋙ coyoneda).obj X).obj x✝
⊢ ((yoneda.op ⋙ coyoneda).map f).app x✝ a✝ =
    (eqToHom (_ : ?F.obj X = ?G.obj X) ≫
          (curry.obj (yonedaPairing C)).map f ≫
            eqToHom (_ : (curry.obj (yonedaPairing C)).obj Y = (yoneda.op ⋙ coyoneda).obj Y)).app
      x✝ a✝

Next tactic:
simp
/-- The curried version of yoneda lemma when `C` is small. -/
def curriedYonedaLemma {C : Type u₁} [SmallCategory C] :
    (yoneda.op ⋙ coyoneda : Cᵒᵖ ⥤ (Cᵒᵖ ⥤ Type u₁) ⥤ Type u₁) ≅ evaluation Cᵒᵖ (Type u₁) := by
  refine eqToIso ?_ ≪≫ curry.mapIso
    (yonedaLemma C ≪≫ isoWhiskerLeft (evaluationUncurried Cᵒᵖ (Type u₁)) uliftFunctorTrivial) ≪≫
    eqToIso ?_
  · apply Functor.ext
    · intro X Y f
      ext
      simp
    · 

Proof state:
case refine_1.h_obj
C✝ : Type u₁
inst✝¹ : Category.{v₁, u₁} C✝
C : Type u₁
inst✝ : SmallCategory C
⊢ ∀ (X : Cᵒᵖ), (yoneda.op ⋙ coyoneda).obj X = (curry.obj (yonedaPairing C)).obj X

Next tactic:
aesop_cat
/-- The curried version of yoneda lemma when `C` is small. -/
def curriedYonedaLemma {C : Type u₁} [SmallCategory C] :
    (yoneda.op ⋙ coyoneda : Cᵒᵖ ⥤ (Cᵒᵖ ⥤ Type u₁) ⥤ Type u₁) ≅ evaluation Cᵒᵖ (Type u₁) := by
  refine eqToIso ?_ ≪≫ curry.mapIso
    (yonedaLemma C ≪≫ isoWhiskerLeft (evaluationUncurried Cᵒᵖ (Type u₁)) uliftFunctorTrivial) ≪≫
    eqToIso ?_
  · apply Functor.ext
    · intro X Y f
      ext
      simp
    · aesop_cat
  · 

Proof state:
case refine_2
C✝ : Type u₁
inst✝¹ : Category.{v₁, u₁} C✝
C : Type u₁
inst✝ : SmallCategory C
⊢ curry.obj (evaluationUncurried Cᵒᵖ (Type u₁) ⋙ 𝟭 (Type u₁)) = evaluation Cᵒᵖ (Type u₁)

Next tactic:
apply Functor.ext
/-- The curried version of yoneda lemma when `C` is small. -/
def curriedYonedaLemma {C : Type u₁} [SmallCategory C] :
    (yoneda.op ⋙ coyoneda : Cᵒᵖ ⥤ (Cᵒᵖ ⥤ Type u₁) ⥤ Type u₁) ≅ evaluation Cᵒᵖ (Type u₁) := by
  refine eqToIso ?_ ≪≫ curry.mapIso
    (yonedaLemma C ≪≫ isoWhiskerLeft (evaluationUncurried Cᵒᵖ (Type u₁)) uliftFunctorTrivial) ≪≫
    eqToIso ?_
  · apply Functor.ext
    · intro X Y f
      ext
      simp
    · aesop_cat
  · apply Functor.ext
    · 

Proof state:
case refine_2.h_map
C✝ : Type u₁
inst✝¹ : Category.{v₁, u₁} C✝
C : Type u₁
inst✝ : SmallCategory C
⊢ autoParam
    (∀ (X Y : Cᵒᵖ) (f : X ⟶ Y),
      (curry.obj (evaluationUncurried Cᵒᵖ (Type u₁) ⋙ 𝟭 (Type u₁))).map f =
        eqToHom (_ : ?F.obj X = ?G.obj X) ≫
          (evaluation Cᵒᵖ (Type u₁)).map f ≫
            eqToHom
              (_ :
                (evaluation Cᵒᵖ (Type u₁)).obj Y = (curry.obj (evaluationUncurried Cᵒᵖ (Type u₁) ⋙ 𝟭 (Type u₁))).obj Y))
    _auto✝

Next tactic:
intro X Y f
/-- The curried version of yoneda lemma when `C` is small. -/
def curriedYonedaLemma {C : Type u₁} [SmallCategory C] :
    (yoneda.op ⋙ coyoneda : Cᵒᵖ ⥤ (Cᵒᵖ ⥤ Type u₁) ⥤ Type u₁) ≅ evaluation Cᵒᵖ (Type u₁) := by
  refine eqToIso ?_ ≪≫ curry.mapIso
    (yonedaLemma C ≪≫ isoWhiskerLeft (evaluationUncurried Cᵒᵖ (Type u₁)) uliftFunctorTrivial) ≪≫
    eqToIso ?_
  · apply Functor.ext
    · intro X Y f
      ext
      simp
    · aesop_cat
  · apply Functor.ext
    · intro X Y f
      

Proof state:
case refine_2.h_map
C✝ : Type u₁
inst✝¹ : Category.{v₁, u₁} C✝
C : Type u₁
inst✝ : SmallCategory C
X Y : Cᵒᵖ
f : X ⟶ Y
⊢ (curry.obj (evaluationUncurried Cᵒᵖ (Type u₁) ⋙ 𝟭 (Type u₁))).map f =
    eqToHom (_ : ?F.obj X = ?G.obj X) ≫
      (evaluation Cᵒᵖ (Type u₁)).map f ≫
        eqToHom
          (_ : (evaluation Cᵒᵖ (Type u₁)).obj Y = (curry.obj (evaluationUncurried Cᵒᵖ (Type u₁) ⋙ 𝟭 (Type u₁))).obj Y)

Next tactic:
ext
/-- The curried version of yoneda lemma when `C` is small. -/
def curriedYonedaLemma {C : Type u₁} [SmallCategory C] :
    (yoneda.op ⋙ coyoneda : Cᵒᵖ ⥤ (Cᵒᵖ ⥤ Type u₁) ⥤ Type u₁) ≅ evaluation Cᵒᵖ (Type u₁) := by
  refine eqToIso ?_ ≪≫ curry.mapIso
    (yonedaLemma C ≪≫ isoWhiskerLeft (evaluationUncurried Cᵒᵖ (Type u₁)) uliftFunctorTrivial) ≪≫
    eqToIso ?_
  · apply Functor.ext
    · intro X Y f
      ext
      simp
    · aesop_cat
  · apply Functor.ext
    · intro X Y f
      ext
      

Proof state:
case refine_2.h_map.w.h.h
C✝ : Type u₁
inst✝¹ : Category.{v₁, u₁} C✝
C : Type u₁
inst✝ : SmallCategory C
X Y : Cᵒᵖ
f : X ⟶ Y
x✝ : Cᵒᵖ ⥤ Type u₁
a✝ : ((curry.obj (evaluationUncurried Cᵒᵖ (Type u₁) ⋙ 𝟭 (Type u₁))).obj X).obj x✝
⊢ ((curry.obj (evaluationUncurried Cᵒᵖ (Type u₁) ⋙ 𝟭 (Type u₁))).map f).app x✝ a✝ =
    (eqToHom (_ : ?F.obj X = ?G.obj X) ≫
          (evaluation Cᵒᵖ (Type u₁)).map f ≫
            eqToHom
              (_ :
                (evaluation Cᵒᵖ (Type u₁)).obj Y =
                  (curry.obj (evaluationUncurried Cᵒᵖ (Type u₁) ⋙ 𝟭 (Type u₁))).obj Y)).app
      x✝ a✝

Next tactic:
simp
/-- The curried version of yoneda lemma when `C` is small. -/
def curriedYonedaLemma {C : Type u₁} [SmallCategory C] :
    (yoneda.op ⋙ coyoneda : Cᵒᵖ ⥤ (Cᵒᵖ ⥤ Type u₁) ⥤ Type u₁) ≅ evaluation Cᵒᵖ (Type u₁) := by
  refine eqToIso ?_ ≪≫ curry.mapIso
    (yonedaLemma C ≪≫ isoWhiskerLeft (evaluationUncurried Cᵒᵖ (Type u₁)) uliftFunctorTrivial) ≪≫
    eqToIso ?_
  · apply Functor.ext
    · intro X Y f
      ext
      simp
    · aesop_cat
  · apply Functor.ext
    · intro X Y f
      ext
      simp
    · 

Proof state:
case refine_2.h_obj
C✝ : Type u₁
inst✝¹ : Category.{v₁, u₁} C✝
C : Type u₁
inst✝ : SmallCategory C
⊢ ∀ (X : Cᵒᵖ), (curry.obj (evaluationUncurried Cᵒᵖ (Type u₁) ⋙ 𝟭 (Type u₁))).obj X = (evaluation Cᵒᵖ (Type u₁)).obj X

Next tactic:
intro X
/-- The curried version of yoneda lemma when `C` is small. -/
def curriedYonedaLemma {C : Type u₁} [SmallCategory C] :
    (yoneda.op ⋙ coyoneda : Cᵒᵖ ⥤ (Cᵒᵖ ⥤ Type u₁) ⥤ Type u₁) ≅ evaluation Cᵒᵖ (Type u₁) := by
  refine eqToIso ?_ ≪≫ curry.mapIso
    (yonedaLemma C ≪≫ isoWhiskerLeft (evaluationUncurried Cᵒᵖ (Type u₁)) uliftFunctorTrivial) ≪≫
    eqToIso ?_
  · apply Functor.ext
    · intro X Y f
      ext
      simp
    · aesop_cat
  · apply Functor.ext
    · intro X Y f
      ext
      simp
    · intro X
      

Proof state:
case refine_2.h_obj
C✝ : Type u₁
inst✝¹ : Category.{v₁, u₁} C✝
C : Type u₁
inst✝ : SmallCategory C
X : Cᵒᵖ
⊢ (curry.obj (evaluationUncurried Cᵒᵖ (Type u₁) ⋙ 𝟭 (Type u₁))).obj X = (evaluation Cᵒᵖ (Type u₁)).obj X

Next tactic:
simp only [curry, yoneda, coyoneda, curryObj, yonedaPairing]
/-- The curried version of yoneda lemma when `C` is small. -/
def curriedYonedaLemma {C : Type u₁} [SmallCategory C] :
    (yoneda.op ⋙ coyoneda : Cᵒᵖ ⥤ (Cᵒᵖ ⥤ Type u₁) ⥤ Type u₁) ≅ evaluation Cᵒᵖ (Type u₁) := by
  refine eqToIso ?_ ≪≫ curry.mapIso
    (yonedaLemma C ≪≫ isoWhiskerLeft (evaluationUncurried Cᵒᵖ (Type u₁)) uliftFunctorTrivial) ≪≫
    eqToIso ?_
  · apply Functor.ext
    · intro X Y f
      ext
      simp
    · aesop_cat
  · apply Functor.ext
    · intro X Y f
      ext
      simp
    · intro X
      simp only [curry, yoneda, coyoneda, curryObj, yonedaPairing]
      

Proof state:
case refine_2.h_obj
C✝ : Type u₁
inst✝¹ : Category.{v₁, u₁} C✝
C : Type u₁
inst✝ : SmallCategory C
X : Cᵒᵖ
⊢ Functor.mk
      { obj := fun Y => (evaluationUncurried Cᵒᵖ (Type u₁) ⋙ 𝟭 (Type u₁)).obj (X, Y),
        map := fun {X_1 Y} g => (evaluationUncurried Cᵒᵖ (Type u₁) ⋙ 𝟭 (Type u₁)).map (𝟙 X, g) } =
    (evaluation Cᵒᵖ (Type u₁)).obj X

Next tactic:
aesop_cat
/-- The curried version of yoneda lemma when `C` is small. -/
def curriedYonedaLemma' {C : Type u₁} [SmallCategory C] :
    yoneda ⋙ (whiskeringLeft Cᵒᵖ (Cᵒᵖ ⥤ Type u₁)ᵒᵖ (Type u₁)).obj yoneda.op
      ≅ 𝟭 (Cᵒᵖ ⥤ Type u₁) := by
  

Proof state:
C✝ : Type u₁
inst✝¹ : Category.{v₁, u₁} C✝
C : Type u₁
inst✝ : SmallCategory C
⊢ yoneda ⋙ (whiskeringLeft Cᵒᵖ (Cᵒᵖ ⥤ Type u₁)ᵒᵖ (Type u₁)).obj yoneda.op ≅ 𝟭 (Cᵒᵖ ⥤ Type u₁)

Next tactic:
refine eqToIso ?_ ≪≫ curry.mapIso (isoWhiskerLeft (Prod.swap _ _)
    (yonedaLemma C ≪≫ isoWhiskerLeft (evaluationUncurried Cᵒᵖ (Type u₁)) uliftFunctorTrivial :_))
    ≪≫ eqToIso ?_
/-- The curried version of yoneda lemma when `C` is small. -/
def curriedYonedaLemma' {C : Type u₁} [SmallCategory C] :
    yoneda ⋙ (whiskeringLeft Cᵒᵖ (Cᵒᵖ ⥤ Type u₁)ᵒᵖ (Type u₁)).obj yoneda.op
      ≅ 𝟭 (Cᵒᵖ ⥤ Type u₁) := by
  refine eqToIso ?_ ≪≫ curry.mapIso (isoWhiskerLeft (Prod.swap _ _)
    (yonedaLemma C ≪≫ isoWhiskerLeft (evaluationUncurried Cᵒᵖ (Type u₁)) uliftFunctorTrivial :_))
    ≪≫ eqToIso ?_
  · 

Proof state:
case refine_1
C✝ : Type u₁
inst✝¹ : Category.{v₁, u₁} C✝
C : Type u₁
inst✝ : SmallCategory C
⊢ yoneda ⋙ (whiskeringLeft Cᵒᵖ (Cᵒᵖ ⥤ Type u₁)ᵒᵖ (Type u₁)).obj yoneda.op =
    curry.obj (Prod.swap (Cᵒᵖ ⥤ Type u₁) Cᵒᵖ ⋙ yonedaPairing C)

Next tactic:
apply Functor.ext
/-- The curried version of yoneda lemma when `C` is small. -/
def curriedYonedaLemma' {C : Type u₁} [SmallCategory C] :
    yoneda ⋙ (whiskeringLeft Cᵒᵖ (Cᵒᵖ ⥤ Type u₁)ᵒᵖ (Type u₁)).obj yoneda.op
      ≅ 𝟭 (Cᵒᵖ ⥤ Type u₁) := by
  refine eqToIso ?_ ≪≫ curry.mapIso (isoWhiskerLeft (Prod.swap _ _)
    (yonedaLemma C ≪≫ isoWhiskerLeft (evaluationUncurried Cᵒᵖ (Type u₁)) uliftFunctorTrivial :_))
    ≪≫ eqToIso ?_
  · apply Functor.ext
    · 

Proof state:
case refine_1.h_map
C✝ : Type u₁
inst✝¹ : Category.{v₁, u₁} C✝
C : Type u₁
inst✝ : SmallCategory C
⊢ autoParam
    (∀ (X Y : Cᵒᵖ ⥤ Type u₁) (f : X ⟶ Y),
      (yoneda ⋙ (whiskeringLeft Cᵒᵖ (Cᵒᵖ ⥤ Type u₁)ᵒᵖ (Type u₁)).obj yoneda.op).map f =
        eqToHom (_ : ?F.obj X = ?G.obj X) ≫
          (curry.obj (Prod.swap (Cᵒᵖ ⥤ Type u₁) Cᵒᵖ ⋙ yonedaPairing C)).map f ≫
            eqToHom
              (_ :
                (curry.obj (Prod.swap (Cᵒᵖ ⥤ Type u₁) Cᵒᵖ ⋙ yonedaPairing C)).obj Y =
                  (yoneda ⋙ (whiskeringLeft Cᵒᵖ (Cᵒᵖ ⥤ Type u₁)ᵒᵖ (Type u₁)).obj yoneda.op).obj Y))
    _auto✝

Next tactic:
intro X Y f
/-- The curried version of yoneda lemma when `C` is small. -/
def curriedYonedaLemma' {C : Type u₁} [SmallCategory C] :
    yoneda ⋙ (whiskeringLeft Cᵒᵖ (Cᵒᵖ ⥤ Type u₁)ᵒᵖ (Type u₁)).obj yoneda.op
      ≅ 𝟭 (Cᵒᵖ ⥤ Type u₁) := by
  refine eqToIso ?_ ≪≫ curry.mapIso (isoWhiskerLeft (Prod.swap _ _)
    (yonedaLemma C ≪≫ isoWhiskerLeft (evaluationUncurried Cᵒᵖ (Type u₁)) uliftFunctorTrivial :_))
    ≪≫ eqToIso ?_
  · apply Functor.ext
    · intro X Y f
      

Proof state:
case refine_1.h_map
C✝ : Type u₁
inst✝¹ : Category.{v₁, u₁} C✝
C : Type u₁
inst✝ : SmallCategory C
X Y : Cᵒᵖ ⥤ Type u₁
f : X ⟶ Y
⊢ (yoneda ⋙ (whiskeringLeft Cᵒᵖ (Cᵒᵖ ⥤ Type u₁)ᵒᵖ (Type u₁)).obj yoneda.op).map f =
    eqToHom (_ : ?F.obj X = ?G.obj X) ≫
      (curry.obj (Prod.swap (Cᵒᵖ ⥤ Type u₁) Cᵒᵖ ⋙ yonedaPairing C)).map f ≫
        eqToHom
          (_ :
            (curry.obj (Prod.swap (Cᵒᵖ ⥤ Type u₁) Cᵒᵖ ⋙ yonedaPairing C)).obj Y =
              (yoneda ⋙ (whiskeringLeft Cᵒᵖ (Cᵒᵖ ⥤ Type u₁)ᵒᵖ (Type u₁)).obj yoneda.op).obj Y)

Next tactic:
aesop_cat
/-- The curried version of yoneda lemma when `C` is small. -/
def curriedYonedaLemma' {C : Type u₁} [SmallCategory C] :
    yoneda ⋙ (whiskeringLeft Cᵒᵖ (Cᵒᵖ ⥤ Type u₁)ᵒᵖ (Type u₁)).obj yoneda.op
      ≅ 𝟭 (Cᵒᵖ ⥤ Type u₁) := by
  refine eqToIso ?_ ≪≫ curry.mapIso (isoWhiskerLeft (Prod.swap _ _)
    (yonedaLemma C ≪≫ isoWhiskerLeft (evaluationUncurried Cᵒᵖ (Type u₁)) uliftFunctorTrivial :_))
    ≪≫ eqToIso ?_
  · apply Functor.ext
    · intro X Y f
      aesop_cat
  · 

Proof state:
case refine_2
C✝ : Type u₁
inst✝¹ : Category.{v₁, u₁} C✝
C : Type u₁
inst✝ : SmallCategory C
⊢ curry.obj (Prod.swap (Cᵒᵖ ⥤ Type u₁) Cᵒᵖ ⋙ evaluationUncurried Cᵒᵖ (Type u₁) ⋙ 𝟭 (Type u₁)) = 𝟭 (Cᵒᵖ ⥤ Type u₁)

Next tactic:
apply Functor.ext
/-- The curried version of yoneda lemma when `C` is small. -/
def curriedYonedaLemma' {C : Type u₁} [SmallCategory C] :
    yoneda ⋙ (whiskeringLeft Cᵒᵖ (Cᵒᵖ ⥤ Type u₁)ᵒᵖ (Type u₁)).obj yoneda.op
      ≅ 𝟭 (Cᵒᵖ ⥤ Type u₁) := by
  refine eqToIso ?_ ≪≫ curry.mapIso (isoWhiskerLeft (Prod.swap _ _)
    (yonedaLemma C ≪≫ isoWhiskerLeft (evaluationUncurried Cᵒᵖ (Type u₁)) uliftFunctorTrivial :_))
    ≪≫ eqToIso ?_
  · apply Functor.ext
    · intro X Y f
      aesop_cat
  · apply Functor.ext
    · 

Proof state:
case refine_2.h_map
C✝ : Type u₁
inst✝¹ : Category.{v₁, u₁} C✝
C : Type u₁
inst✝ : SmallCategory C
⊢ autoParam
    (∀ (X Y : Cᵒᵖ ⥤ Type u₁) (f : X ⟶ Y),
      (curry.obj (Prod.swap (Cᵒᵖ ⥤ Type u₁) Cᵒᵖ ⋙ evaluationUncurried Cᵒᵖ (Type u₁) ⋙ 𝟭 (Type u₁))).map f =
        eqToHom (_ : ?F.obj X = ?G.obj X) ≫
          (𝟭 (Cᵒᵖ ⥤ Type u₁)).map f ≫
            eqToHom
              (_ :
                (𝟭 (Cᵒᵖ ⥤ Type u₁)).obj Y =
                  (curry.obj (Prod.swap (Cᵒᵖ ⥤ Type u₁) Cᵒᵖ ⋙ evaluationUncurried Cᵒᵖ (Type u₁) ⋙ 𝟭 (Type u₁))).obj Y))
    _auto✝

Next tactic:
aesop_cat
lemma isIso_of_yoneda_map_bijective {X Y : C} (f : X ⟶ Y)
    (hf : ∀ (T : C), Function.Bijective (fun (x : T ⟶ X) => x ≫ f)) :
    IsIso f := by
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
hf : ∀ (T : C), Function.Bijective fun x => x ≫ f
⊢ IsIso f

Next tactic:
obtain ⟨g, hg : g ≫ f = 𝟙 Y⟩ := (hf Y).2 (𝟙 Y)
lemma isIso_of_yoneda_map_bijective {X Y : C} (f : X ⟶ Y)
    (hf : ∀ (T : C), Function.Bijective (fun (x : T ⟶ X) => x ≫ f)) :
    IsIso f := by
  obtain ⟨g, hg : g ≫ f = 𝟙 Y⟩ := (hf Y).2 (𝟙 Y)
  

Proof state:
case intro
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
hf : ∀ (T : C), Function.Bijective fun x => x ≫ f
g : Y ⟶ X
hg : g ≫ f = 𝟙 Y
⊢ IsIso f

Next tactic:
exact ⟨g, (hf _).1 (by aesop_cat), hg⟩
lemma isIso_of_yoneda_map_bijective {X Y : C} (f : X ⟶ Y)
    (hf : ∀ (T : C), Function.Bijective (fun (x : T ⟶ X) => x ≫ f)) :
    IsIso f := by
  obtain ⟨g, hg : g ≫ f = 𝟙 Y⟩ := (hf Y).2 (𝟙 Y)
  exact ⟨g, (hf _).1 (by 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
hf : ∀ (T : C), Function.Bijective fun x => x ≫ f
g : Y ⟶ X
hg : g ≫ f = 𝟙 Y
⊢ (fun x => x ≫ f) (f ≫ g) = (fun x => x ≫ f) (𝟙 X)

Next tactic:
aesop_cat
/--
Implementation: If `π` is a surjective morphism in `Stonean`, then it is an effective epi.
The theorem `Stonean.effectiveEpi_tfae` should be used instead.
-/
noncomputable
def struct {B X : Stonean.{u}} (π : X ⟶ B) (hπ : Function.Surjective π) : EffectiveEpiStruct π where
  desc e h := (QuotientMap.of_surjective_continuous hπ π.continuous).lift e fun a b hab ↦
    FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
    (by 

Proof state:
B X : Stonean
π : X ⟶ B
hπ : Function.Surjective ⇑π
W✝ : Stonean
e : X ⟶ W✝
h : ∀ {Z : Stonean} (g₁ g₂ : Z ⟶ X), g₁ ≫ π = g₂ ≫ π → g₁ ≫ e = g₂ ≫ e
a b : CoeSort.coe X
hab : π a = π b
⊢ (ContinuousMap.mk fun x => a) ≫ π = (ContinuousMap.mk fun x => b) ≫ π

Next tactic:
ext
/--
Implementation: If `π` is a surjective morphism in `Stonean`, then it is an effective epi.
The theorem `Stonean.effectiveEpi_tfae` should be used instead.
-/
noncomputable
def struct {B X : Stonean.{u}} (π : X ⟶ B) (hπ : Function.Surjective π) : EffectiveEpiStruct π where
  desc e h := (QuotientMap.of_surjective_continuous hπ π.continuous).lift e fun a b hab ↦
    FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
    (by ext; 

Proof state:
case w
B X : Stonean
π : X ⟶ B
hπ : Function.Surjective ⇑π
W✝ : Stonean
e : X ⟶ W✝
h : ∀ {Z : Stonean} (g₁ g₂ : Z ⟶ X), g₁ ≫ π = g₂ ≫ π → g₁ ≫ e = g₂ ≫ e
a b : CoeSort.coe X
hab : π a = π b
x✝ : (forget Stonean).obj X
⊢ ((ContinuousMap.mk fun x => a) ≫ π) x✝ = ((ContinuousMap.mk fun x => b) ≫ π) x✝

Next tactic:
exact hab
/--
Implementation: If `π` is a surjective morphism in `Stonean`, then it is an effective epi.
The theorem `Stonean.effectiveEpi_tfae` should be used instead.
-/
noncomputable
def struct {B X : Stonean.{u}} (π : X ⟶ B) (hπ : Function.Surjective π) : EffectiveEpiStruct π where
  desc e h := (QuotientMap.of_surjective_continuous hπ π.continuous).lift e fun a b hab ↦
    FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
    (by ext; exact hab)) a
  fac e h := ((QuotientMap.of_surjective_continuous hπ π.continuous).lift_comp e
    fun a b hab ↦ FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
    (by 

Proof state:
B X : Stonean
π : X ⟶ B
hπ : Function.Surjective ⇑π
W✝ : Stonean
e : X ⟶ W✝
h : ∀ {Z : Stonean} (g₁ g₂ : Z ⟶ X), g₁ ≫ π = g₂ ≫ π → g₁ ≫ e = g₂ ≫ e
a b : CoeSort.coe X
hab : π a = π b
⊢ (ContinuousMap.mk fun x => a) ≫ π = (ContinuousMap.mk fun x => b) ≫ π

Next tactic:
ext
/--
Implementation: If `π` is a surjective morphism in `Stonean`, then it is an effective epi.
The theorem `Stonean.effectiveEpi_tfae` should be used instead.
-/
noncomputable
def struct {B X : Stonean.{u}} (π : X ⟶ B) (hπ : Function.Surjective π) : EffectiveEpiStruct π where
  desc e h := (QuotientMap.of_surjective_continuous hπ π.continuous).lift e fun a b hab ↦
    FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
    (by ext; exact hab)) a
  fac e h := ((QuotientMap.of_surjective_continuous hπ π.continuous).lift_comp e
    fun a b hab ↦ FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
    (by ext; 

Proof state:
case w
B X : Stonean
π : X ⟶ B
hπ : Function.Surjective ⇑π
W✝ : Stonean
e : X ⟶ W✝
h : ∀ {Z : Stonean} (g₁ g₂ : Z ⟶ X), g₁ ≫ π = g₂ ≫ π → g₁ ≫ e = g₂ ≫ e
a b : CoeSort.coe X
hab : π a = π b
x✝ : (forget Stonean).obj X
⊢ ((ContinuousMap.mk fun x => a) ≫ π) x✝ = ((ContinuousMap.mk fun x => b) ≫ π) x✝

Next tactic:
exact hab
/--
Implementation: If `π` is a surjective morphism in `Stonean`, then it is an effective epi.
The theorem `Stonean.effectiveEpi_tfae` should be used instead.
-/
noncomputable
def struct {B X : Stonean.{u}} (π : X ⟶ B) (hπ : Function.Surjective π) : EffectiveEpiStruct π where
  desc e h := (QuotientMap.of_surjective_continuous hπ π.continuous).lift e fun a b hab ↦
    FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
    (by ext; exact hab)) a
  fac e h := ((QuotientMap.of_surjective_continuous hπ π.continuous).lift_comp e
    fun a b hab ↦ FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
    (by ext; exact hab)) a)
  uniq e h g hm := by
    

Proof state:
B X : Stonean
π : X ⟶ B
hπ : Function.Surjective ⇑π
W✝ : Stonean
e : X ⟶ W✝
h : ∀ {Z : Stonean} (g₁ g₂ : Z ⟶ X), g₁ ≫ π = g₂ ≫ π → g₁ ≫ e = g₂ ≫ e
g : B ⟶ W✝
hm : π ≫ g = e
⊢ g =
    (fun {W} e h =>
        QuotientMap.lift (_ : QuotientMap ⇑π) e
          (_ :
            ∀ (a b : CoeSort.coe X),
              π a = π b → ((ContinuousMap.mk fun x => a) ≫ e) a = ((ContinuousMap.mk fun x => b) ≫ e) a))
      e (_ : ∀ {Z : Stonean} (g₁ g₂ : Z ⟶ X), g₁ ≫ π = g₂ ≫ π → g₁ ≫ e = g₂ ≫ e)

Next tactic:
suffices g = (QuotientMap.of_surjective_continuous hπ π.continuous).liftEquiv ⟨e,
      fun a b hab ↦ FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
      (by ext; exact hab)) a⟩ by assumption
/--
Implementation: If `π` is a surjective morphism in `Stonean`, then it is an effective epi.
The theorem `Stonean.effectiveEpi_tfae` should be used instead.
-/
noncomputable
def struct {B X : Stonean.{u}} (π : X ⟶ B) (hπ : Function.Surjective π) : EffectiveEpiStruct π where
  desc e h := (QuotientMap.of_surjective_continuous hπ π.continuous).lift e fun a b hab ↦
    FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
    (by ext; exact hab)) a
  fac e h := ((QuotientMap.of_surjective_continuous hπ π.continuous).lift_comp e
    fun a b hab ↦ FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
    (by ext; exact hab)) a)
  uniq e h g hm := by
    suffices g = (QuotientMap.of_surjective_continuous hπ π.continuous).liftEquiv ⟨e,
      fun a b hab ↦ FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
      (by 

Proof state:
B X : Stonean
π : X ⟶ B
hπ : Function.Surjective ⇑π
W✝ : Stonean
e : X ⟶ W✝
h : ∀ {Z : Stonean} (g₁ g₂ : Z ⟶ X), g₁ ≫ π = g₂ ≫ π → g₁ ≫ e = g₂ ≫ e
g : B ⟶ W✝
hm : π ≫ g = e
a b : CoeSort.coe X
hab : π a = π b
⊢ (ContinuousMap.mk fun x => a) ≫ π = (ContinuousMap.mk fun x => b) ≫ π

Next tactic:
ext
/--
Implementation: If `π` is a surjective morphism in `Stonean`, then it is an effective epi.
The theorem `Stonean.effectiveEpi_tfae` should be used instead.
-/
noncomputable
def struct {B X : Stonean.{u}} (π : X ⟶ B) (hπ : Function.Surjective π) : EffectiveEpiStruct π where
  desc e h := (QuotientMap.of_surjective_continuous hπ π.continuous).lift e fun a b hab ↦
    FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
    (by ext; exact hab)) a
  fac e h := ((QuotientMap.of_surjective_continuous hπ π.continuous).lift_comp e
    fun a b hab ↦ FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
    (by ext; exact hab)) a)
  uniq e h g hm := by
    suffices g = (QuotientMap.of_surjective_continuous hπ π.continuous).liftEquiv ⟨e,
      fun a b hab ↦ FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
      (by ext; 

Proof state:
case w
B X : Stonean
π : X ⟶ B
hπ : Function.Surjective ⇑π
W✝ : Stonean
e : X ⟶ W✝
h : ∀ {Z : Stonean} (g₁ g₂ : Z ⟶ X), g₁ ≫ π = g₂ ≫ π → g₁ ≫ e = g₂ ≫ e
g : B ⟶ W✝
hm : π ≫ g = e
a b : CoeSort.coe X
hab : π a = π b
x✝ : (forget Stonean).obj X
⊢ ((ContinuousMap.mk fun x => a) ≫ π) x✝ = ((ContinuousMap.mk fun x => b) ≫ π) x✝

Next tactic:
exact hab
/--
Implementation: If `π` is a surjective morphism in `Stonean`, then it is an effective epi.
The theorem `Stonean.effectiveEpi_tfae` should be used instead.
-/
noncomputable
def struct {B X : Stonean.{u}} (π : X ⟶ B) (hπ : Function.Surjective π) : EffectiveEpiStruct π where
  desc e h := (QuotientMap.of_surjective_continuous hπ π.continuous).lift e fun a b hab ↦
    FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
    (by ext; exact hab)) a
  fac e h := ((QuotientMap.of_surjective_continuous hπ π.continuous).lift_comp e
    fun a b hab ↦ FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
    (by ext; exact hab)) a)
  uniq e h g hm := by
    suffices g = (QuotientMap.of_surjective_continuous hπ π.continuous).liftEquiv ⟨e,
      fun a b hab ↦ FunLike.congr_fun (h ⟨fun _ ↦ a, continuous_const⟩ ⟨fun _ ↦ b, continuous_const⟩
      (by ext; exact hab)) a⟩ by 

Proof state:
B X : Stonean
π : X ⟶ B
hπ : Function.Surjective ⇑π
W✝ : Stonean
e : X ⟶ W✝
h : ∀ {Z : Stonean} (g₁ g₂ : Z ⟶ X), g₁ ≫ π = g₂ ≫ π → g₁ ≫ e = g₂ ≫ e
g : B ⟶ W✝
hm : π ≫ g = e
this :
  g =
    (QuotientMap.liftEquiv (_ : QuotientMap ⇑π))
      { val := e,
        property :=
          (_ :
            ∀ (a b : CoeSort.coe X),
              π a = π b → ((ContinuousMap.mk fun x => a) ≫ e) a = ((ContinuousMap.mk fun x => b) ≫ e) a) }
⊢ g =
    (fun {W} e h =>
        QuotientMap.lift (_ : QuotientMap ⇑π) e
          (_ :
            ∀ (a b : CoeSort.coe X),
              π a = π b → ((ContinuousMap.mk fun x => a) ≫ e) a = ((ContinuousMap.mk fun x => b) ≫ e) a))
      e (_ : ∀ {Z : Stonean} (g₁ g₂ : Z ⟶ X), g₁ ≫ π = g₂ ≫ π → g₁ ≫ e = g₂ ≫ e)

Next tactic:
assumption