l3lab/ntp-mathlib huggingface dataset:
instance : Preregular Profinite where
  exists_fac := by
    intro X Y Z f π hπ
    refine ⟨pullback f π, pullback.fst f π, ?_, pullback.snd f π, (pullback.condition _ _).symm⟩
    have := fun X Y (f : X ⟶ Y) ↦ (effectiveEpi_tfae f).out 0 2
    

Proof state:
X Y Z : Profinite
f : X ⟶ Y
π : Z ⟶ Y
hπ : EffectiveEpi π
this : ∀ (X Y : Profinite) (f : X ⟶ Y), EffectiveEpi f ↔ Function.Surjective ⇑f
⊢ EffectiveEpi (pullback.fst f π)

Next tactic:
rw [this] at hπ ⊢
instance : Preregular Profinite where
  exists_fac := by
    intro X Y Z f π hπ
    refine ⟨pullback f π, pullback.fst f π, ?_, pullback.snd f π, (pullback.condition _ _).symm⟩
    have := fun X Y (f : X ⟶ Y) ↦ (effectiveEpi_tfae f).out 0 2
    rw [this] at hπ ⊢
    

Proof state:
X Y Z : Profinite
f : X ⟶ Y
π : Z ⟶ Y
hπ : Function.Surjective ⇑π
this : ∀ (X Y : Profinite) (f : X ⟶ Y), EffectiveEpi f ↔ Function.Surjective ⇑f
⊢ Function.Surjective ⇑(pullback.fst f π)

Next tactic:
intro y
instance : Preregular Profinite where
  exists_fac := by
    intro X Y Z f π hπ
    refine ⟨pullback f π, pullback.fst f π, ?_, pullback.snd f π, (pullback.condition _ _).symm⟩
    have := fun X Y (f : X ⟶ Y) ↦ (effectiveEpi_tfae f).out 0 2
    rw [this] at hπ ⊢
    intro y
    

Proof state:
X Y Z : Profinite
f : X ⟶ Y
π : Z ⟶ Y
hπ : Function.Surjective ⇑π
this : ∀ (X Y : Profinite) (f : X ⟶ Y), EffectiveEpi f ↔ Function.Surjective ⇑f
y : (forget Profinite).obj X
⊢ ∃ a, (pullback.fst f π) a = y

Next tactic:
obtain ⟨z,hz⟩ := hπ (f y)
instance : Preregular Profinite where
  exists_fac := by
    intro X Y Z f π hπ
    refine ⟨pullback f π, pullback.fst f π, ?_, pullback.snd f π, (pullback.condition _ _).symm⟩
    have := fun X Y (f : X ⟶ Y) ↦ (effectiveEpi_tfae f).out 0 2
    rw [this] at hπ ⊢
    intro y
    obtain ⟨z,hz⟩ := hπ (f y)
    

Proof state:
case intro
X Y Z : Profinite
f : X ⟶ Y
π : Z ⟶ Y
hπ : Function.Surjective ⇑π
this : ∀ (X Y : Profinite) (f : X ⟶ Y), EffectiveEpi f ↔ Function.Surjective ⇑f
y : (forget Profinite).obj X
z : (forget Profinite).obj Z
hz : π z = f y
⊢ ∃ a, (pullback.fst f π) a = y

Next tactic:
exact ⟨⟨(y, z), hz.symm⟩, rfl⟩
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  

Proof state:
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
⊢ TFAE [EffectiveEpiFamily X π, Epi (Sigma.desc π), ∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b]

Next tactic:
tfae_have 2 → 1
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · 

Proof state:
case tfae_2_to_1
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
⊢ Epi (Sigma.desc π) → EffectiveEpiFamily X π

Next tactic:
intro
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    

Proof state:
case tfae_2_to_1
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
✝ : Epi (Sigma.desc π)
⊢ EffectiveEpiFamily X π

Next tactic:
simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  

Proof state:
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
⊢ TFAE [EffectiveEpiFamily X π, Epi (Sigma.desc π), ∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b]

Next tactic:
tfae_have 1 → 2
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · 

Proof state:
case tfae_1_to_2
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
⊢ EffectiveEpiFamily X π → Epi (Sigma.desc π)

Next tactic:
intro
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; 

Proof state:
case tfae_1_to_2
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
✝ : EffectiveEpiFamily X π
⊢ Epi (Sigma.desc π)

Next tactic:
infer_instance
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  

Proof state:
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
⊢ TFAE [EffectiveEpiFamily X π, Epi (Sigma.desc π), ∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b]

Next tactic:
tfae_have 3 → 2
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · 

Proof state:
case tfae_3_to_2
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
⊢ (∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b) → Epi (Sigma.desc π)

Next tactic:
intro e
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    

Proof state:
case tfae_3_to_2
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
e : ∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b
⊢ Epi (Sigma.desc π)

Next tactic:
rw [epi_iff_surjective]
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    rw [epi_iff_surjective]
    

Proof state:
case tfae_3_to_2
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
e : ∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b
⊢ Function.Surjective ⇑(Sigma.desc π)

Next tactic:
intro b
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    rw [epi_iff_surjective]
    intro b
    

Proof state:
case tfae_3_to_2
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
e : ∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b
b : (forget Profinite).obj B
⊢ ∃ a, (Sigma.desc π) a = b

Next tactic:
obtain ⟨t, x, h⟩ := e b
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    rw [epi_iff_surjective]
    intro b
    obtain ⟨t, x, h⟩ := e b
    

Proof state:
case tfae_3_to_2.intro.intro
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
e : ∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b
b : (forget Profinite).obj B
t : α
x : ↑(X t).toCompHaus.toTop
h : (π t) x = b
⊢ ∃ a, (Sigma.desc π) a = b

Next tactic:
refine ⟨Sigma.ι X t x, ?_⟩
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    rw [epi_iff_surjective]
    intro b
    obtain ⟨t, x, h⟩ := e b
    refine ⟨Sigma.ι X t x, ?_⟩
    

Proof state:
case tfae_3_to_2.intro.intro
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
e : ∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b
b : (forget Profinite).obj B
t : α
x : ↑(X t).toCompHaus.toTop
h : (π t) x = b
⊢ (Sigma.desc π) ((Sigma.ι X t) x) = b

Next tactic:
change (Sigma.ι X t ≫ Sigma.desc π) x = _
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    rw [epi_iff_surjective]
    intro b
    obtain ⟨t, x, h⟩ := e b
    refine ⟨Sigma.ι X t x, ?_⟩
    change (Sigma.ι X t ≫ Sigma.desc π) x = _
    

Proof state:
case tfae_3_to_2.intro.intro
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
e : ∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b
b : (forget Profinite).obj B
t : α
x : ↑(X t).toCompHaus.toTop
h : (π t) x = b
⊢ (Sigma.ι X t ≫ Sigma.desc π) x = b

Next tactic:
simpa using h
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    rw [epi_iff_surjective]
    intro b
    obtain ⟨t, x, h⟩ := e b
    refine ⟨Sigma.ι X t x, ?_⟩
    change (Sigma.ι X t ≫ Sigma.desc π) x = _
    simpa using h
  

Proof state:
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
tfae_3_to_2 : (∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b) → Epi (Sigma.desc π)
⊢ TFAE [EffectiveEpiFamily X π, Epi (Sigma.desc π), ∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b]

Next tactic:
tfae_have 2 → 3
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    rw [epi_iff_surjective]
    intro b
    obtain ⟨t, x, h⟩ := e b
    refine ⟨Sigma.ι X t x, ?_⟩
    change (Sigma.ι X t ≫ Sigma.desc π) x = _
    simpa using h
  tfae_have 2 → 3
  · 

Proof state:
case tfae_2_to_3
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
tfae_3_to_2 : (∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b) → Epi (Sigma.desc π)
⊢ Epi (Sigma.desc π) → ∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b

Next tactic:
intro e
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    rw [epi_iff_surjective]
    intro b
    obtain ⟨t, x, h⟩ := e b
    refine ⟨Sigma.ι X t x, ?_⟩
    change (Sigma.ι X t ≫ Sigma.desc π) x = _
    simpa using h
  tfae_have 2 → 3
  · intro e; 

Proof state:
case tfae_2_to_3
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
tfae_3_to_2 : (∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b) → Epi (Sigma.desc π)
e : Epi (Sigma.desc π)
⊢ ∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b

Next tactic:
rw [epi_iff_surjective] at e
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    rw [epi_iff_surjective]
    intro b
    obtain ⟨t, x, h⟩ := e b
    refine ⟨Sigma.ι X t x, ?_⟩
    change (Sigma.ι X t ≫ Sigma.desc π) x = _
    simpa using h
  tfae_have 2 → 3
  · intro e; rw [epi_iff_surjective] at e
    

Proof state:
case tfae_2_to_3
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
tfae_3_to_2 : (∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b) → Epi (Sigma.desc π)
e : Function.Surjective ⇑(Sigma.desc π)
⊢ ∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b

Next tactic:
let i : ∐ X ≅ finiteCoproduct X :=
      (colimit.isColimit _).coconePointUniqueUpToIso (finiteCoproduct.isColimit _)
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    rw [epi_iff_surjective]
    intro b
    obtain ⟨t, x, h⟩ := e b
    refine ⟨Sigma.ι X t x, ?_⟩
    change (Sigma.ι X t ≫ Sigma.desc π) x = _
    simpa using h
  tfae_have 2 → 3
  · intro e; rw [epi_iff_surjective] at e
    let i : ∐ X ≅ finiteCoproduct X :=
      (colimit.isColimit _).coconePointUniqueUpToIso (finiteCoproduct.isColimit _)
    

Proof state:
case tfae_2_to_3
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
tfae_3_to_2 : (∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b) → Epi (Sigma.desc π)
e : Function.Surjective ⇑(Sigma.desc π)
i : ∐ X ≅ finiteCoproduct X :=
  IsColimit.coconePointUniqueUpToIso (colimit.isColimit (Discrete.functor X)) (finiteCoproduct.isColimit X)
⊢ ∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b

Next tactic:
intro b
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    rw [epi_iff_surjective]
    intro b
    obtain ⟨t, x, h⟩ := e b
    refine ⟨Sigma.ι X t x, ?_⟩
    change (Sigma.ι X t ≫ Sigma.desc π) x = _
    simpa using h
  tfae_have 2 → 3
  · intro e; rw [epi_iff_surjective] at e
    let i : ∐ X ≅ finiteCoproduct X :=
      (colimit.isColimit _).coconePointUniqueUpToIso (finiteCoproduct.isColimit _)
    intro b
    

Proof state:
case tfae_2_to_3
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
tfae_3_to_2 : (∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b) → Epi (Sigma.desc π)
e : Function.Surjective ⇑(Sigma.desc π)
i : ∐ X ≅ finiteCoproduct X :=
  IsColimit.coconePointUniqueUpToIso (colimit.isColimit (Discrete.functor X)) (finiteCoproduct.isColimit X)
b : ↑B.toCompHaus.toTop
⊢ ∃ a x, (π a) x = b

Next tactic:
obtain ⟨t, rfl⟩ := e b
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    rw [epi_iff_surjective]
    intro b
    obtain ⟨t, x, h⟩ := e b
    refine ⟨Sigma.ι X t x, ?_⟩
    change (Sigma.ι X t ≫ Sigma.desc π) x = _
    simpa using h
  tfae_have 2 → 3
  · intro e; rw [epi_iff_surjective] at e
    let i : ∐ X ≅ finiteCoproduct X :=
      (colimit.isColimit _).coconePointUniqueUpToIso (finiteCoproduct.isColimit _)
    intro b
    obtain ⟨t, rfl⟩ := e b
    

Proof state:
case tfae_2_to_3.intro
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
tfae_3_to_2 : (∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b) → Epi (Sigma.desc π)
e : Function.Surjective ⇑(Sigma.desc π)
i : ∐ X ≅ finiteCoproduct X :=
  IsColimit.coconePointUniqueUpToIso (colimit.isColimit (Discrete.functor X)) (finiteCoproduct.isColimit X)
t : (forget Profinite).obj (∐ fun b => X b)
⊢ ∃ a x, (π a) x = (Sigma.desc π) t

Next tactic:
let q := i.hom t
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : Profinite.{u}}
    (X : α → Profinite.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    rw [epi_iff_surjective]
    intro b
    obtain ⟨t, x, h⟩ := e b
    refine ⟨Sigma.ι X t x, ?_⟩
    change (Sigma.ι X t ≫ Sigma.desc π) x = _
    simpa using h
  tfae_have 2 → 3
  · intro e; rw [epi_iff_surjective] at e
    let i : ∐ X ≅ finiteCoproduct X :=
      (colimit.isColimit _).coconePointUniqueUpToIso (finiteCoproduct.isColimit _)
    intro b
    obtain ⟨t, rfl⟩ := e b
    let q := i.hom t
    

Proof state:
case tfae_2_to_3.intro
α : Type
inst✝ : Fintype α
B : Profinite
X : α → Profinite
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
tfae_3_to_2 : (∀ (b : ↑B.toCompHaus.toTop), ∃ a x, (π a) x = b) → Epi (Sigma.desc π)
e : Function.Surjective ⇑(Sigma.desc π)
i : ∐ X ≅ finiteCoproduct X :=
  IsColimit.coconePointUniqueUpToIso (colimit.isColimit (Discrete.functor X)) (finiteCoproduct.isColimit X)
t : (forget Profinite).obj (∐ fun b => X b)
q : (forget Profinite).obj (finiteCoproduct X) := i.hom t
⊢ ∃ a x, (π a) x = (Sigma.desc π) t

Next tactic:
refine ⟨q.1,q.2,?_⟩