l3lab/ntp-mathlib huggingface dataset:
theorem linearIndependent_comp_of_eval
    (h₁: ⊤ ≤ Submodule.span ℤ (Set.range (eval (π C (ord I · < o))))) :
    LinearIndependent ℤ (eval (C' C ho)) →
    LinearIndependent ℤ (ModuleCat.ofHom (Linear_CC' C hsC ho) ∘ SumEval C ho ∘ Sum.inr) := by
  dsimp [SumEval, ModuleCat.ofHom]
  erw [max_eq_eval_unapply C hsC ho]
  intro h
  let f := MaxToGood C hC hsC ho h₁
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
h₁ : ⊤ ≤ Submodule.span ℤ (Set.range (eval (π C fun x => ord I x < o)))
h : LinearIndependent ℤ (eval (C' C ho))
f : ↑(MaxProducts C ho) → ↑(GoodProducts (C' C ho)) := MaxToGood C hC hsC ho h₁
⊢ LinearIndependent ℤ fun (l : ↑(MaxProducts C ho)) => Products.eval (C' C ho) (Products.Tail ↑l)

Next tactic:
have hf : f.Injective := maxToGood_injective C hC hsC ho h₁
theorem linearIndependent_comp_of_eval
    (h₁: ⊤ ≤ Submodule.span ℤ (Set.range (eval (π C (ord I · < o))))) :
    LinearIndependent ℤ (eval (C' C ho)) →
    LinearIndependent ℤ (ModuleCat.ofHom (Linear_CC' C hsC ho) ∘ SumEval C ho ∘ Sum.inr) := by
  dsimp [SumEval, ModuleCat.ofHom]
  erw [max_eq_eval_unapply C hsC ho]
  intro h
  let f := MaxToGood C hC hsC ho h₁
  have hf : f.Injective := maxToGood_injective C hC hsC ho h₁
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
h₁ : ⊤ ≤ Submodule.span ℤ (Set.range (eval (π C fun x => ord I x < o)))
h : LinearIndependent ℤ (eval (C' C ho))
f : ↑(MaxProducts C ho) → ↑(GoodProducts (C' C ho)) := MaxToGood C hC hsC ho h₁
hf : Function.Injective f
⊢ LinearIndependent ℤ fun (l : ↑(MaxProducts C ho)) => Products.eval (C' C ho) (Products.Tail ↑l)

Next tactic:
have hh : (fun l ↦ Products.eval (C' C ho) l.val.Tail) = eval (C' C ho) ∘ f := rfl
theorem linearIndependent_comp_of_eval
    (h₁: ⊤ ≤ Submodule.span ℤ (Set.range (eval (π C (ord I · < o))))) :
    LinearIndependent ℤ (eval (C' C ho)) →
    LinearIndependent ℤ (ModuleCat.ofHom (Linear_CC' C hsC ho) ∘ SumEval C ho ∘ Sum.inr) := by
  dsimp [SumEval, ModuleCat.ofHom]
  erw [max_eq_eval_unapply C hsC ho]
  intro h
  let f := MaxToGood C hC hsC ho h₁
  have hf : f.Injective := maxToGood_injective C hC hsC ho h₁
  have hh : (fun l ↦ Products.eval (C' C ho) l.val.Tail) = eval (C' C ho) ∘ f := rfl
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
h₁ : ⊤ ≤ Submodule.span ℤ (Set.range (eval (π C fun x => ord I x < o)))
h : LinearIndependent ℤ (eval (C' C ho))
f : ↑(MaxProducts C ho) → ↑(GoodProducts (C' C ho)) := MaxToGood C hC hsC ho h₁
hf : Function.Injective f
hh : (fun l => Products.eval (C' C ho) (Products.Tail ↑l)) = eval (C' C ho) ∘ f
⊢ LinearIndependent ℤ fun (l : ↑(MaxProducts C ho)) => Products.eval (C' C ho) (Products.Tail ↑l)

Next tactic:
rw [hh]
theorem linearIndependent_comp_of_eval
    (h₁: ⊤ ≤ Submodule.span ℤ (Set.range (eval (π C (ord I · < o))))) :
    LinearIndependent ℤ (eval (C' C ho)) →
    LinearIndependent ℤ (ModuleCat.ofHom (Linear_CC' C hsC ho) ∘ SumEval C ho ∘ Sum.inr) := by
  dsimp [SumEval, ModuleCat.ofHom]
  erw [max_eq_eval_unapply C hsC ho]
  intro h
  let f := MaxToGood C hC hsC ho h₁
  have hf : f.Injective := maxToGood_injective C hC hsC ho h₁
  have hh : (fun l ↦ Products.eval (C' C ho) l.val.Tail) = eval (C' C ho) ∘ f := rfl
  rw [hh]
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
h₁ : ⊤ ≤ Submodule.span ℤ (Set.range (eval (π C fun x => ord I x < o)))
h : LinearIndependent ℤ (eval (C' C ho))
f : ↑(MaxProducts C ho) → ↑(GoodProducts (C' C ho)) := MaxToGood C hC hsC ho h₁
hf : Function.Injective f
hh : (fun l => Products.eval (C' C ho) (Products.Tail ↑l)) = eval (C' C ho) ∘ f
⊢ LinearIndependent (ι := ↑(MaxProducts C ho)) ℤ (eval (C' C ho) ∘ f)

Next tactic:
exact h.comp f hf
theorem GoodProducts.P0 : P I 0 := fun _ C _ hsC ↦ by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C✝ : Set (I → Bool)
x✝¹ : 0 ≤ Ordinal.type fun x x_1 => x < x_1
C : Set (I → Bool)
x✝ : IsClosed C
hsC : contained C 0
⊢ LinearIndependent ℤ (eval C)

Next tactic:
have : C ⊆ {(fun _ ↦ false)} := fun c hc ↦ by
    ext x; exact Bool.eq_false_iff.mpr (fun ht ↦ (Ordinal.not_lt_zero (ord I x)) (hsC c hc x ht))
theorem GoodProducts.P0 : P I 0 := fun _ C _ hsC ↦ by
  have : C ⊆ {(fun _ ↦ false)} := fun c hc ↦ by
    

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C✝ : Set (I → Bool)
x✝¹ : 0 ≤ Ordinal.type fun x x_1 => x < x_1
C : Set (I → Bool)
x✝ : IsClosed C
hsC : contained C 0
c : I → Bool
hc : c ∈ C
⊢ c ∈ {fun x => false}

Next tactic:
ext x
theorem GoodProducts.P0 : P I 0 := fun _ C _ hsC ↦ by
  have : C ⊆ {(fun _ ↦ false)} := fun c hc ↦ by
    ext x; 

Proof state:
case h
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C✝ : Set (I → Bool)
x✝¹ : 0 ≤ Ordinal.type fun x x_1 => x < x_1
C : Set (I → Bool)
x✝ : IsClosed C
hsC : contained C 0
c : I → Bool
hc : c ∈ C
x : I
⊢ c x = false

Next tactic:
exact Bool.eq_false_iff.mpr (fun ht ↦ (Ordinal.not_lt_zero (ord I x)) (hsC c hc x ht))
theorem GoodProducts.P0 : P I 0 := fun _ C _ hsC ↦ by
  have : C ⊆ {(fun _ ↦ false)} := fun c hc ↦ by
    ext x; exact Bool.eq_false_iff.mpr (fun ht ↦ (Ordinal.not_lt_zero (ord I x)) (hsC c hc x ht))
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C✝ : Set (I → Bool)
x✝¹ : 0 ≤ Ordinal.type fun x x_1 => x < x_1
C : Set (I → Bool)
x✝ : IsClosed C
hsC : contained C 0
this : C ⊆ {fun x => false}
⊢ LinearIndependent ℤ (eval C)

Next tactic:
rw [Set.subset_singleton_iff_eq] at this
theorem GoodProducts.P0 : P I 0 := fun _ C _ hsC ↦ by
  have : C ⊆ {(fun _ ↦ false)} := fun c hc ↦ by
    ext x; exact Bool.eq_false_iff.mpr (fun ht ↦ (Ordinal.not_lt_zero (ord I x)) (hsC c hc x ht))
  rw [Set.subset_singleton_iff_eq] at this
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C✝ : Set (I → Bool)
x✝¹ : 0 ≤ Ordinal.type fun x x_1 => x < x_1
C : Set (I → Bool)
x✝ : IsClosed C
hsC : contained C 0
this : C = ∅ ∨ C = {fun x => false}
⊢ LinearIndependent ℤ (eval C)

Next tactic:
cases this
theorem GoodProducts.P0 : P I 0 := fun _ C _ hsC ↦ by
  have : C ⊆ {(fun _ ↦ false)} := fun c hc ↦ by
    ext x; exact Bool.eq_false_iff.mpr (fun ht ↦ (Ordinal.not_lt_zero (ord I x)) (hsC c hc x ht))
  rw [Set.subset_singleton_iff_eq] at this
  cases this
  · 

Proof state:
case inl
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C✝ : Set (I → Bool)
x✝¹ : 0 ≤ Ordinal.type fun x x_1 => x < x_1
C : Set (I → Bool)
x✝ : IsClosed C
hsC : contained C 0
h✝ : C = ∅
⊢ LinearIndependent ℤ (eval C)

Next tactic:
subst C
theorem GoodProducts.P0 : P I 0 := fun _ C _ hsC ↦ by
  have : C ⊆ {(fun _ ↦ false)} := fun c hc ↦ by
    ext x; exact Bool.eq_false_iff.mpr (fun ht ↦ (Ordinal.not_lt_zero (ord I x)) (hsC c hc x ht))
  rw [Set.subset_singleton_iff_eq] at this
  cases this
  · subst C
    

Proof state:
case inl
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
x✝¹ : 0 ≤ Ordinal.type fun x x_1 => x < x_1
x✝ : IsClosed ∅
hsC : contained ∅ 0
⊢ LinearIndependent ℤ (eval ∅)

Next tactic:
exact linearIndependentEmpty
theorem GoodProducts.P0 : P I 0 := fun _ C _ hsC ↦ by
  have : C ⊆ {(fun _ ↦ false)} := fun c hc ↦ by
    ext x; exact Bool.eq_false_iff.mpr (fun ht ↦ (Ordinal.not_lt_zero (ord I x)) (hsC c hc x ht))
  rw [Set.subset_singleton_iff_eq] at this
  cases this
  · subst C
    exact linearIndependentEmpty
  · 

Proof state:
case inr
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C✝ : Set (I → Bool)
x✝¹ : 0 ≤ Ordinal.type fun x x_1 => x < x_1
C : Set (I → Bool)
x✝ : IsClosed C
hsC : contained C 0
h✝ : C = {fun x => false}
⊢ LinearIndependent ℤ (eval C)

Next tactic:
subst C
theorem GoodProducts.P0 : P I 0 := fun _ C _ hsC ↦ by
  have : C ⊆ {(fun _ ↦ false)} := fun c hc ↦ by
    ext x; exact Bool.eq_false_iff.mpr (fun ht ↦ (Ordinal.not_lt_zero (ord I x)) (hsC c hc x ht))
  rw [Set.subset_singleton_iff_eq] at this
  cases this
  · subst C
    exact linearIndependentEmpty
  · subst C
    

Proof state:
case inr
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
x✝¹ : 0 ≤ Ordinal.type fun x x_1 => x < x_1
x✝ : IsClosed {fun x => false}
hsC : contained {fun x => false} 0
⊢ LinearIndependent ℤ (eval {fun x => false})

Next tactic:
exact linearIndependentSingleton
theorem GoodProducts.Plimit (o : Ordinal) (ho : Ordinal.IsLimit o) :
    (∀ (o' : Ordinal), o' < o → P I o') → P I o := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
ho : Ordinal.IsLimit o
⊢ (∀ o' < o, P I o') → P I o

Next tactic:
intro h hho C hC hsC
theorem GoodProducts.Plimit (o : Ordinal) (ho : Ordinal.IsLimit o) :
    (∀ (o' : Ordinal), o' < o → P I o') → P I o := by
  intro h hho C hC hsC
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C✝ : Set (I → Bool)
o : Ordinal.{u}
ho : Ordinal.IsLimit o
h : ∀ o' < o, P I o'
hho : o ≤ Ordinal.type fun x x_1 => x < x_1
C : Set (I → Bool)
hC : IsClosed C
hsC : contained C o
⊢ LinearIndependent ℤ (eval C)

Next tactic:
rw [linearIndependent_iff_union_smaller C ho hsC]
theorem GoodProducts.Plimit (o : Ordinal) (ho : Ordinal.IsLimit o) :
    (∀ (o' : Ordinal), o' < o → P I o') → P I o := by
  intro h hho C hC hsC
  rw [linearIndependent_iff_union_smaller C ho hsC]
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C✝ : Set (I → Bool)
o : Ordinal.{u}
ho : Ordinal.IsLimit o
h : ∀ o' < o, P I o'
hho : o ≤ Ordinal.type fun x x_1 => x < x_1
C : Set (I → Bool)
hC : IsClosed C
hsC : contained C o
⊢ LinearIndependent ℤ fun (p : ↑(⋃ e, smaller C ↑e)) => ↑p

Next tactic:
exact linearIndependent_iUnion_of_directed
    (Monotone.directed_le fun _ _ h ↦ GoodProducts.smaller_mono C h) fun ⟨o', ho'⟩ ↦
    (linearIndependent_iff_smaller _ _).mp (h o' ho' (le_of_lt (lt_of_lt_of_le ho' hho))
    (π C (ord I · < o')) (isClosed_proj _ _ hC) (contained_proj _ _))
theorem GoodProducts.linearIndependentAux (μ : Ordinal) : P I μ := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
μ : Ordinal.{u}
⊢ P I μ

Next tactic:
refine Ordinal.limitRecOn μ P0 (fun o h ho C hC hsC ↦ ?_)
      (fun o ho h ↦ (GoodProducts.Plimit o ho (fun o' ho' ↦ (h o' ho'))))
theorem GoodProducts.linearIndependentAux (μ : Ordinal) : P I μ := by
  refine Ordinal.limitRecOn μ P0 (fun o h ho C hC hsC ↦ ?_)
      (fun o ho h ↦ (GoodProducts.Plimit o ho (fun o' ho' ↦ (h o' ho'))))
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C✝ : Set (I → Bool)
μ o : Ordinal.{u}
h : P I o
ho : Order.succ o ≤ Ordinal.type fun x x_1 => x < x_1
C : Set (I → Bool)
hC : IsClosed C
hsC : contained C (Order.succ o)
⊢ LinearIndependent ℤ (eval C)

Next tactic:
have ho' : o < Ordinal.type (·<· : I → I → Prop) :=
    lt_of_lt_of_le (Order.lt_succ _) ho
theorem GoodProducts.linearIndependentAux (μ : Ordinal) : P I μ := by
  refine Ordinal.limitRecOn μ P0 (fun o h ho C hC hsC ↦ ?_)
      (fun o ho h ↦ (GoodProducts.Plimit o ho (fun o' ho' ↦ (h o' ho'))))
  have ho' : o < Ordinal.type (·<· : I → I → Prop) :=
    lt_of_lt_of_le (Order.lt_succ _) ho
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C✝ : Set (I → Bool)
μ o : Ordinal.{u}
h : P I o
ho : Order.succ o ≤ Ordinal.type fun x x_1 => x < x_1
C : Set (I → Bool)
hC : IsClosed C
hsC : contained C (Order.succ o)
ho' : o < Ordinal.type fun x x_1 => x < x_1
⊢ LinearIndependent ℤ (eval C)

Next tactic:
rw [linearIndependent_iff_sum C hsC ho']
theorem GoodProducts.linearIndependentAux (μ : Ordinal) : P I μ := by
  refine Ordinal.limitRecOn μ P0 (fun o h ho C hC hsC ↦ ?_)
      (fun o ho h ↦ (GoodProducts.Plimit o ho (fun o' ho' ↦ (h o' ho'))))
  have ho' : o < Ordinal.type (·<· : I → I → Prop) :=
    lt_of_lt_of_le (Order.lt_succ _) ho
  rw [linearIndependent_iff_sum C hsC ho']
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C✝ : Set (I → Bool)
μ o : Ordinal.{u}
h : P I o
ho : Order.succ o ≤ Ordinal.type fun x x_1 => x < x_1
C : Set (I → Bool)
hC : IsClosed C
hsC : contained C (Order.succ o)
ho' : o < Ordinal.type fun x x_1 => x < x_1
⊢ LinearIndependent ℤ (SumEval C ho')

Next tactic:
refine' ModuleCat.linearIndependent_leftExact (succ_exact C hC hsC ho') ?_ ?_ (succ_mono C o)
    (square_commutes C ho')
theorem GoodProducts.linearIndependentAux (μ : Ordinal) : P I μ := by
  refine Ordinal.limitRecOn μ P0 (fun o h ho C hC hsC ↦ ?_)
      (fun o ho h ↦ (GoodProducts.Plimit o ho (fun o' ho' ↦ (h o' ho'))))
  have ho' : o < Ordinal.type (·<· : I → I → Prop) :=
    lt_of_lt_of_le (Order.lt_succ _) ho
  rw [linearIndependent_iff_sum C hsC ho']
  refine' ModuleCat.linearIndependent_leftExact (succ_exact C hC hsC ho') ?_ ?_ (succ_mono C o)
    (square_commutes C ho')
  · 

Proof state:
case refine'_1
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C✝ : Set (I → Bool)
μ o : Ordinal.{u}
h : P I o
ho : Order.succ o ≤ Ordinal.type fun x x_1 => x < x_1
C : Set (I → Bool)
hC : IsClosed C
hsC : contained C (Order.succ o)
ho' : o < Ordinal.type fun x x_1 => x < x_1
⊢ LinearIndependent (ι := ↑(GoodProducts (π C fun x => ord I x < o))) ℤ (eval (π C fun x => ord I x < o))

Next tactic:
exact h (le_of_lt ho') (π C (ord I · < o)) (isClosed_proj C o hC) (contained_proj C o)
theorem GoodProducts.linearIndependentAux (μ : Ordinal) : P I μ := by
  refine Ordinal.limitRecOn μ P0 (fun o h ho C hC hsC ↦ ?_)
      (fun o ho h ↦ (GoodProducts.Plimit o ho (fun o' ho' ↦ (h o' ho'))))
  have ho' : o < Ordinal.type (·<· : I → I → Prop) :=
    lt_of_lt_of_le (Order.lt_succ _) ho
  rw [linearIndependent_iff_sum C hsC ho']
  refine' ModuleCat.linearIndependent_leftExact (succ_exact C hC hsC ho') ?_ ?_ (succ_mono C o)
    (square_commutes C ho')
  · exact h (le_of_lt ho') (π C (ord I · < o)) (isClosed_proj C o hC) (contained_proj C o)
  · 

Proof state:
case refine'_2
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C✝ : Set (I → Bool)
μ o : Ordinal.{u}
h : P I o
ho : Order.succ o ≤ Ordinal.type fun x x_1 => x < x_1
C : Set (I → Bool)
hC : IsClosed C
hsC : contained C (Order.succ o)
ho' : o < Ordinal.type fun x x_1 => x < x_1
⊢ LinearIndependent (ι := ↑(MaxProducts C ho')) ℤ
    (⇑(ShortComplex.mk (ModuleCat.ofHom (πs C o)) (ModuleCat.ofHom (Linear_CC' C hsC ho'))
            (_ : ModuleCat.ofHom (πs C o) ≫ ModuleCat.ofHom (Linear_CC' C hsC ho') = 0)).g ∘
      SumEval C ho' ∘ Sum.inr)

Next tactic:
exact linearIndependent_comp_of_eval C hC hsC ho' (span (π C (ord I · < o))
      (isClosed_proj C o hC)) (h (le_of_lt ho') (C' C ho') (isClosed_C' C hC ho')
      (contained_C' C ho'))
open Classical in
/-- The map `Nobeling.ι` is a closed embedding. -/
theorem Nobeling.embedding : ClosedEmbedding (Nobeling.ι S) := by
  

Proof state:
S : Profinite
⊢ ClosedEmbedding (ι S)

Next tactic:
apply Continuous.closedEmbedding
open Classical in
/-- The map `Nobeling.ι` is a closed embedding. -/
theorem Nobeling.embedding : ClosedEmbedding (Nobeling.ι S) := by
  apply Continuous.closedEmbedding
  · 

Proof state:
case h
S : Profinite
⊢ Continuous (ι S)

Next tactic:
dsimp (config := { unfoldPartialApp := true }) [ι]
open Classical in
/-- The map `Nobeling.ι` is a closed embedding. -/
theorem Nobeling.embedding : ClosedEmbedding (Nobeling.ι S) := by
  apply Continuous.closedEmbedding
  · dsimp (config := { unfoldPartialApp := true }) [ι]
    

Proof state:
case h
S : Profinite
⊢ Continuous fun s C => decide (s ∈ ↑C)

Next tactic:
refine continuous_pi ?_
open Classical in
/-- The map `Nobeling.ι` is a closed embedding. -/
theorem Nobeling.embedding : ClosedEmbedding (Nobeling.ι S) := by
  apply Continuous.closedEmbedding
  · dsimp (config := { unfoldPartialApp := true }) [ι]
    refine continuous_pi ?_
    

Proof state:
case h
S : Profinite
⊢ ∀ (i : { C // IsClopen C }), Continuous fun a => decide (a ∈ ↑i)

Next tactic:
intro C
open Classical in
/-- The map `Nobeling.ι` is a closed embedding. -/
theorem Nobeling.embedding : ClosedEmbedding (Nobeling.ι S) := by
  apply Continuous.closedEmbedding
  · dsimp (config := { unfoldPartialApp := true }) [ι]
    refine continuous_pi ?_
    intro C
    

Proof state:
case h
S : Profinite
C : { C // IsClopen C }
⊢ Continuous fun a => decide (a ∈ ↑C)

Next tactic:
rw [← IsLocallyConstant.iff_continuous]
open Classical in
/-- The map `Nobeling.ι` is a closed embedding. -/
theorem Nobeling.embedding : ClosedEmbedding (Nobeling.ι S) := by
  apply Continuous.closedEmbedding
  · dsimp (config := { unfoldPartialApp := true }) [ι]
    refine continuous_pi ?_
    intro C
    rw [← IsLocallyConstant.iff_continuous]
    

Proof state:
case h
S : Profinite
C : { C // IsClopen C }
⊢ IsLocallyConstant fun a => decide (a ∈ ↑C)

Next tactic:
refine ((IsLocallyConstant.tfae _).out 0 3).mpr ?_
open Classical in
/-- The map `Nobeling.ι` is a closed embedding. -/
theorem Nobeling.embedding : ClosedEmbedding (Nobeling.ι S) := by
  apply Continuous.closedEmbedding
  · dsimp (config := { unfoldPartialApp := true }) [ι]
    refine continuous_pi ?_
    intro C
    rw [← IsLocallyConstant.iff_continuous]
    refine ((IsLocallyConstant.tfae _).out 0 3).mpr ?_
    

Proof state:
case h
S : Profinite
C : { C // IsClopen C }
⊢ ∀ (y : Bool), IsOpen ((fun a => decide (a ∈ ↑C)) ⁻¹' {y})

Next tactic:
rintro ⟨⟩
open Classical in
/-- The map `Nobeling.ι` is a closed embedding. -/
theorem Nobeling.embedding : ClosedEmbedding (Nobeling.ι S) := by
  apply Continuous.closedEmbedding
  · dsimp (config := { unfoldPartialApp := true }) [ι]
    refine continuous_pi ?_
    intro C
    rw [← IsLocallyConstant.iff_continuous]
    refine ((IsLocallyConstant.tfae _).out 0 3).mpr ?_
    rintro ⟨⟩
    · 

Proof state:
case h.false
S : Profinite
C : { C // IsClopen C }
⊢ IsOpen ((fun a => decide (a ∈ ↑C)) ⁻¹' {false})

Next tactic:
refine IsClopen.isOpen (isClopen_compl_iff.mp ?_)
open Classical in
/-- The map `Nobeling.ι` is a closed embedding. -/
theorem Nobeling.embedding : ClosedEmbedding (Nobeling.ι S) := by
  apply Continuous.closedEmbedding
  · dsimp (config := { unfoldPartialApp := true }) [ι]
    refine continuous_pi ?_
    intro C
    rw [← IsLocallyConstant.iff_continuous]
    refine ((IsLocallyConstant.tfae _).out 0 3).mpr ?_
    rintro ⟨⟩
    · refine IsClopen.isOpen (isClopen_compl_iff.mp ?_)
      

Proof state:
case h.false
S : Profinite
C : { C // IsClopen C }
⊢ IsClopen ((fun a => decide (a ∈ ↑C)) ⁻¹' {false})ᶜ

Next tactic:
convert C.2
open Classical in
/-- The map `Nobeling.ι` is a closed embedding. -/
theorem Nobeling.embedding : ClosedEmbedding (Nobeling.ι S) := by
  apply Continuous.closedEmbedding
  · dsimp (config := { unfoldPartialApp := true }) [ι]
    refine continuous_pi ?_
    intro C
    rw [← IsLocallyConstant.iff_continuous]
    refine ((IsLocallyConstant.tfae _).out 0 3).mpr ?_
    rintro ⟨⟩
    · refine IsClopen.isOpen (isClopen_compl_iff.mp ?_)
      convert C.2
      

Proof state:
case h.e'_3
S : Profinite
C : { C // IsClopen C }
⊢ ((fun a => decide (a ∈ ↑C)) ⁻¹' {false})ᶜ = ↑C

Next tactic:
ext x
open Classical in
/-- The map `Nobeling.ι` is a closed embedding. -/
theorem Nobeling.embedding : ClosedEmbedding (Nobeling.ι S) := by
  apply Continuous.closedEmbedding
  · dsimp (config := { unfoldPartialApp := true }) [ι]
    refine continuous_pi ?_
    intro C
    rw [← IsLocallyConstant.iff_continuous]
    refine ((IsLocallyConstant.tfae _).out 0 3).mpr ?_
    rintro ⟨⟩
    · refine IsClopen.isOpen (isClopen_compl_iff.mp ?_)
      convert C.2
      ext x
      

Proof state:
case h.e'_3.h
S : Profinite
C : { C // IsClopen C }
x : ↑S.toCompHaus.toTop
⊢ x ∈ ((fun a => decide (a ∈ ↑C)) ⁻¹' {false})ᶜ ↔ x ∈ ↑C

Next tactic:
simp only [Set.mem_compl_iff, Set.mem_preimage, Set.mem_singleton_iff,
        decide_eq_false_iff_not, not_not]
open Classical in
/-- The map `Nobeling.ι` is a closed embedding. -/
theorem Nobeling.embedding : ClosedEmbedding (Nobeling.ι S) := by
  apply Continuous.closedEmbedding
  · dsimp (config := { unfoldPartialApp := true }) [ι]
    refine continuous_pi ?_
    intro C
    rw [← IsLocallyConstant.iff_continuous]
    refine ((IsLocallyConstant.tfae _).out 0 3).mpr ?_
    rintro ⟨⟩
    · refine IsClopen.isOpen (isClopen_compl_iff.mp ?_)
      convert C.2
      ext x
      simp only [Set.mem_compl_iff, Set.mem_preimage, Set.mem_singleton_iff,
        decide_eq_false_iff_not, not_not]
    · 

Proof state:
case h.true
S : Profinite
C : { C // IsClopen C }
⊢ IsOpen ((fun a => decide (a ∈ ↑C)) ⁻¹' {true})

Next tactic:
refine IsClopen.isOpen ?_
open Classical in
/-- The map `Nobeling.ι` is a closed embedding. -/
theorem Nobeling.embedding : ClosedEmbedding (Nobeling.ι S) := by
  apply Continuous.closedEmbedding
  · dsimp (config := { unfoldPartialApp := true }) [ι]
    refine continuous_pi ?_
    intro C
    rw [← IsLocallyConstant.iff_continuous]
    refine ((IsLocallyConstant.tfae _).out 0 3).mpr ?_
    rintro ⟨⟩
    · refine IsClopen.isOpen (isClopen_compl_iff.mp ?_)
      convert C.2
      ext x
      simp only [Set.mem_compl_iff, Set.mem_preimage, Set.mem_singleton_iff,
        decide_eq_false_iff_not, not_not]
    · refine IsClopen.isOpen ?_
      

Proof state:
case h.true
S : Profinite
C : { C // IsClopen C }
⊢ IsClopen ((fun a => decide (a ∈ ↑C)) ⁻¹' {true})

Next tactic:
convert C.2
open Classical in
/-- The map `Nobeling.ι` is a closed embedding. -/
theorem Nobeling.embedding : ClosedEmbedding (Nobeling.ι S) := by
  apply Continuous.closedEmbedding
  · dsimp (config := { unfoldPartialApp := true }) [ι]
    refine continuous_pi ?_
    intro C
    rw [← IsLocallyConstant.iff_continuous]
    refine ((IsLocallyConstant.tfae _).out 0 3).mpr ?_
    rintro ⟨⟩
    · refine IsClopen.isOpen (isClopen_compl_iff.mp ?_)
      convert C.2
      ext x
      simp only [Set.mem_compl_iff, Set.mem_preimage, Set.mem_singleton_iff,
        decide_eq_false_iff_not, not_not]
    · refine IsClopen.isOpen ?_
      convert C.2
      

Proof state:
case h.e'_3
S : Profinite
C : { C // IsClopen C }
⊢ (fun a => decide (a ∈ ↑C)) ⁻¹' {true} = ↑C

Next tactic:
ext x
open Classical in
/-- The map `Nobeling.ι` is a closed embedding. -/
theorem Nobeling.embedding : ClosedEmbedding (Nobeling.ι S) := by
  apply Continuous.closedEmbedding
  · dsimp (config := { unfoldPartialApp := true }) [ι]
    refine continuous_pi ?_
    intro C
    rw [← IsLocallyConstant.iff_continuous]
    refine ((IsLocallyConstant.tfae _).out 0 3).mpr ?_
    rintro ⟨⟩
    · refine IsClopen.isOpen (isClopen_compl_iff.mp ?_)
      convert C.2
      ext x
      simp only [Set.mem_compl_iff, Set.mem_preimage, Set.mem_singleton_iff,
        decide_eq_false_iff_not, not_not]
    · refine IsClopen.isOpen ?_
      convert C.2
      ext x
      

Proof state:
case h.e'_3.h
S : Profinite
C : { C // IsClopen C }
x : ↑S.toCompHaus.toTop
⊢ x ∈ (fun a => decide (a ∈ ↑C)) ⁻¹' {true} ↔ x ∈ ↑C

Next tactic:
simp only [Set.mem_preimage, Set.mem_singleton_iff, decide_eq_true_eq]