Theorem: Profinite.Nobeling.embedding
File: Mathlib/Topology/Category/Profinite/Nobeling.lean

tactic: apply Continuous.closedEmbedding
state_before: S : Profinite
⊢ ClosedEmbedding (ι S)
state_after: case h
S : Profinite
⊢ Continuous (ι S)

case hf
S : Profinite
⊢ Function.Injective (ι S)

tactic: dsimp (config := { unfoldPartialApp := true }) [ι]
state_before: case h
S : Profinite
⊢ Continuous (ι S)
state_after: case h
S : Profinite
⊢ Continuous fun s C => decide (s ∈ ↑C)

tactic: refine continuous_pi ?_
state_before: case h
S : Profinite
⊢ Continuous fun s C => decide (s ∈ ↑C)
state_after: case h
S : Profinite
⊢ ∀ (i : { C // IsClopen C }), Continuous fun a => decide (a ∈ ↑i)

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

tactic: rw [← IsLocallyConstant.iff_continuous]
state_before: case h
S : Profinite
C : { C // IsClopen C }
⊢ Continuous fun a => decide (a ∈ ↑C)
state_after: case h
S : Profinite
C : { C // IsClopen C }
⊢ IsLocallyConstant fun a => decide (a ∈ ↑C)

tactic: refine ((IsLocallyConstant.tfae _).out 0 3).mpr ?_
state_before: case h
S : Profinite
C : { C // IsClopen C }
⊢ IsLocallyConstant fun a => decide (a ∈ ↑C)
state_after: case h
S : Profinite
C : { C // IsClopen C }
⊢ ∀ (y : Bool), IsOpen ((fun a => decide (a ∈ ↑C)) ⁻¹' {y})

tactic: rintro ⟨⟩
state_before: case h
S : Profinite
C : { C // IsClopen C }
⊢ ∀ (y : Bool), IsOpen ((fun a => decide (a ∈ ↑C)) ⁻¹' {y})
state_after: case h.false
S : Profinite
C : { C // IsClopen C }
⊢ IsOpen ((fun a => decide (a ∈ ↑C)) ⁻¹' {false})

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

tactic: refine IsClopen.isOpen (isClopen_compl_iff.mp ?_)
state_before: case h.false
S : Profinite
C : { C // IsClopen C }
⊢ IsOpen ((fun a => decide (a ∈ ↑C)) ⁻¹' {false})
state_after: case h.false
S : Profinite
C : { C // IsClopen C }
⊢ IsClopen ((fun a => decide (a ∈ ↑C)) ⁻¹' {false})ᶜ

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

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

tactic: simp only [Set.mem_compl_iff, Set.mem_preimage, Set.mem_singleton_iff,
  decide_eq_false_iff_not, not_not]
state_before: case h.e'_3.h
S : Profinite
C : { C // IsClopen C }
x : ↑S.toCompHaus.toTop
⊢ x ∈ ((fun a => decide (a ∈ ↑C)) ⁻¹' {false})ᶜ ↔ x ∈ ↑C
state_after: no goals

tactic: refine IsClopen.isOpen ?_
state_before: case h.true
S : Profinite
C : { C // IsClopen C }
⊢ IsOpen ((fun a => decide (a ∈ ↑C)) ⁻¹' {true})
state_after: case h.true
S : Profinite
C : { C // IsClopen C }
⊢ IsClopen ((fun a => decide (a ∈ ↑C)) ⁻¹' {true})

tactic: convert C.2
state_before: case h.true
S : Profinite
C : { C // IsClopen C }
⊢ IsClopen ((fun a => decide (a ∈ ↑C)) ⁻¹' {true})
state_after: case h.e'_3
S : Profinite
C : { C // IsClopen C }
⊢ (fun a => decide (a ∈ ↑C)) ⁻¹' {true} = ↑C

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

tactic: simp only [Set.mem_preimage, Set.mem_singleton_iff, decide_eq_true_eq]
state_before: case h.e'_3.h
S : Profinite
C : { C // IsClopen C }
x : ↑S.toCompHaus.toTop
⊢ x ∈ (fun a => decide (a ∈ ↑C)) ⁻¹' {true} ↔ x ∈ ↑C
state_after: no goals

tactic: intro a b h
state_before: case hf
S : Profinite
⊢ Function.Injective (ι S)
state_after: case hf
S : Profinite
a b : ↑S.toCompHaus.toTop
h : ι S a = ι S b
⊢ a = b

tactic: by_contra hn
state_before: case hf
S : Profinite
a b : ↑S.toCompHaus.toTop
h : ι S a = ι S b
⊢ a = b
state_after: case hf
S : Profinite
a b : ↑S.toCompHaus.toTop
h : ι S a = ι S b
hn : ¬a = b
⊢ False

tactic: obtain ⟨C, hC, hh⟩ := exists_isClopen_of_totally_separated hn
state_before: case hf
S : Profinite
a b : ↑S.toCompHaus.toTop
h : ι S a = ι S b
hn : ¬a = b
⊢ False
state_after: case hf.intro.intro
S : Profinite
a b : ↑S.toCompHaus.toTop
h : ι S a = ι S b
hn : ¬a = b
C : Set ↑S.toCompHaus.toTop
hC : IsClopen C
hh : a ∈ C ∧ b ∈ Cᶜ
⊢ False

tactic: apply hh.2 ∘ of_decide_eq_true
state_before: case hf.intro.intro
S : Profinite
a b : ↑S.toCompHaus.toTop
h : ι S a = ι S b
hn : ¬a = b
C : Set ↑S.toCompHaus.toTop
hC : IsClopen C
hh : a ∈ C ∧ b ∈ Cᶜ
⊢ False
state_after: case hf.intro.intro
S : Profinite
a b : ↑S.toCompHaus.toTop
h : ι S a = ι S b
hn : ¬a = b
C : Set ↑S.toCompHaus.toTop
hC : IsClopen C
hh : a ∈ C ∧ b ∈ Cᶜ
⊢ decide (b ∈ C) = true

tactic: dsimp (config := { unfoldPartialApp := true }) [ι] at h
state_before: case hf.intro.intro
S : Profinite
a b : ↑S.toCompHaus.toTop
h : ι S a = ι S b
hn : ¬a = b
C : Set ↑S.toCompHaus.toTop
hC : IsClopen C
hh : a ∈ C ∧ b ∈ Cᶜ
⊢ decide (b ∈ C) = true
state_after: case hf.intro.intro
S : Profinite
a b : ↑S.toCompHaus.toTop
h : (fun C => decide (a ∈ ↑C)) = fun C => decide (b ∈ ↑C)
hn : ¬a = b
C : Set ↑S.toCompHaus.toTop
hC : IsClopen C
hh : a ∈ C ∧ b ∈ Cᶜ
⊢ decide (b ∈ C) = true

tactic: rw [← congr_fun h ⟨C, hC⟩]
state_before: case hf.intro.intro
S : Profinite
a b : ↑S.toCompHaus.toTop
h : (fun C => decide (a ∈ ↑C)) = fun C => decide (b ∈ ↑C)
hn : ¬a = b
C : Set ↑S.toCompHaus.toTop
hC : IsClopen C
hh : a ∈ C ∧ b ∈ Cᶜ
⊢ decide (b ∈ C) = true
state_after: case hf.intro.intro
S : Profinite
a b : ↑S.toCompHaus.toTop
h : (fun C => decide (a ∈ ↑C)) = fun C => decide (b ∈ ↑C)
hn : ¬a = b
C : Set ↑S.toCompHaus.toTop
hC : IsClopen C
hh : a ∈ C ∧ b ∈ Cᶜ
⊢ decide (a ∈ ↑⟨C, hC⟩) = true

tactic: exact decide_eq_true hh.1
state_before: case hf.intro.intro
S : Profinite
a b : ↑S.toCompHaus.toTop
h : (fun C => decide (a ∈ ↑C)) = fun C => decide (b ∈ ↑C)
hn : ¬a = b
C : Set ↑S.toCompHaus.toTop
hC : IsClopen C
hh : a ∈ C ∧ b ∈ Cᶜ
⊢ decide (a ∈ ↑⟨C, hC⟩) = true
state_after: no goals