l3lab/ntp-mathlib huggingface dataset:
/-- A nonempty separable space admits a sequence with dense range. Instead of running `cases` on the
conclusion of this lemma, you might want to use `TopologicalSpace.denseSeq` and
`TopologicalSpace.denseRange_denseSeq`.

If `α` might be empty, then `TopologicalSpace.exists_countable_dense` is the main way to use
separability of `α`. -/
theorem exists_dense_seq [SeparableSpace α] [Nonempty α] : ∃ u : ℕ → α, DenseRange u := by
  obtain ⟨s : Set α, hs, s_dense⟩ := exists_countable_dense α
  cases' Set.countable_iff_exists_subset_range.mp hs with u hu
  

Proof state:
case intro.intro.intro
α : Type u
t : TopologicalSpace α
B : Set (Set α)
s✝ : Set α
inst✝¹ : SeparableSpace α
inst✝ : Nonempty α
s : Set α
hs : Set.Countable s
s_dense : Dense s
u : ℕ → α
hu : s ⊆ range u
⊢ ∃ u, DenseRange u

Next tactic:
exact ⟨u, s_dense.mono hu⟩
/-- The product of two separable spaces is a separable space. -/
instance [TopologicalSpace β] [SeparableSpace α] [SeparableSpace β] : SeparableSpace (α × β) := by
  

Proof state:
α : Type u
t : TopologicalSpace α
B : Set (Set α)
s : Set α
β : Type ?u.27570
inst✝² : TopologicalSpace β
inst✝¹ : SeparableSpace α
inst✝ : SeparableSpace β
⊢ SeparableSpace (α × β)

Next tactic:
rcases exists_countable_dense α with ⟨s, hsc, hsd⟩
/-- The product of two separable spaces is a separable space. -/
instance [TopologicalSpace β] [SeparableSpace α] [SeparableSpace β] : SeparableSpace (α × β) := by
  rcases exists_countable_dense α with ⟨s, hsc, hsd⟩
  

Proof state:
case intro.intro
α : Type u
t : TopologicalSpace α
B : Set (Set α)
s✝ : Set α
β : Type ?u.27570
inst✝² : TopologicalSpace β
inst✝¹ : SeparableSpace α
inst✝ : SeparableSpace β
s : Set α
hsc : Set.Countable s
hsd : Dense s
⊢ SeparableSpace (α × β)

Next tactic:
rcases exists_countable_dense β with ⟨t, htc, htd⟩
/-- The product of two separable spaces is a separable space. -/
instance [TopologicalSpace β] [SeparableSpace α] [SeparableSpace β] : SeparableSpace (α × β) := by
  rcases exists_countable_dense α with ⟨s, hsc, hsd⟩
  rcases exists_countable_dense β with ⟨t, htc, htd⟩
  

Proof state:
case intro.intro.intro.intro
α : Type u
t✝ : TopologicalSpace α
B : Set (Set α)
s✝ : Set α
β : Type ?u.27570
inst✝² : TopologicalSpace β
inst✝¹ : SeparableSpace α
inst✝ : SeparableSpace β
s : Set α
hsc : Set.Countable s
hsd : Dense s
t : Set β
htc : Set.Countable t
htd : Dense t
⊢ SeparableSpace (α × β)

Next tactic:
exact ⟨⟨s ×ˢ t, hsc.prod htc, hsd.prod htd⟩⟩
/-- The product of a countable family of separable spaces is a separable space. -/
instance {ι : Type*} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, SeparableSpace (X i)]
    [Countable ι] : SeparableSpace (∀ i, X i) := by
  

Proof state:
α : Type u
t : TopologicalSpace α
B : Set (Set α)
s : Set α
ι : Type u_1
X : ι → Type u_2
inst✝² : (i : ι) → TopologicalSpace (X i)
inst✝¹ : ∀ (i : ι), SeparableSpace (X i)
inst✝ : Countable ι
⊢ SeparableSpace ((i : ι) → X i)

Next tactic:
choose t htc htd using (exists_countable_dense <| X ·)
/-- The product of a countable family of separable spaces is a separable space. -/
instance {ι : Type*} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, SeparableSpace (X i)]
    [Countable ι] : SeparableSpace (∀ i, X i) := by
  choose t htc htd using (exists_countable_dense <| X ·)
  

Proof state:
α : Type u
t✝ : TopologicalSpace α
B : Set (Set α)
s : Set α
ι : Type u_1
X : ι → Type u_2
inst✝² : (i : ι) → TopologicalSpace (X i)
inst✝¹ : ∀ (i : ι), SeparableSpace (X i)
inst✝ : Countable ι
t : (x : ι) → Set (X x)
htc : ∀ (x : ι), Set.Countable (t x)
htd : ∀ (x : ι), Dense (t x)
⊢ SeparableSpace ((i : ι) → X i)

Next tactic:
haveI := fun i ↦ (htc i).to_subtype
/-- The product of a countable family of separable spaces is a separable space. -/
instance {ι : Type*} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, SeparableSpace (X i)]
    [Countable ι] : SeparableSpace (∀ i, X i) := by
  choose t htc htd using (exists_countable_dense <| X ·)
  haveI := fun i ↦ (htc i).to_subtype
  

Proof state:
α : Type u
t✝ : TopologicalSpace α
B : Set (Set α)
s : Set α
ι : Type u_1
X : ι → Type u_2
inst✝² : (i : ι) → TopologicalSpace (X i)
inst✝¹ : ∀ (i : ι), SeparableSpace (X i)
inst✝ : Countable ι
t : (x : ι) → Set (X x)
htc : ∀ (x : ι), Set.Countable (t x)
htd : ∀ (x : ι), Dense (t x)
this : ∀ (i : ι), Countable ↑(t i)
⊢ SeparableSpace ((i : ι) → X i)

Next tactic:
nontriviality ∀ i, X i
/-- The product of a countable family of separable spaces is a separable space. -/
instance {ι : Type*} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, SeparableSpace (X i)]
    [Countable ι] : SeparableSpace (∀ i, X i) := by
  choose t htc htd using (exists_countable_dense <| X ·)
  haveI := fun i ↦ (htc i).to_subtype
  nontriviality ∀ i, X i; 

Proof state:
α : Type u
t✝ : TopologicalSpace α
B : Set (Set α)
s : Set α
ι : Type u_1
X : ι → Type u_2
inst✝² : (i : ι) → TopologicalSpace (X i)
inst✝¹ : ∀ (i : ι), SeparableSpace (X i)
inst✝ : Countable ι
t : (x : ι) → Set (X x)
htc : ∀ (x : ι), Set.Countable (t x)
htd : ∀ (x : ι), Dense (t x)
this : ∀ (i : ι), Countable ↑(t i)
✝ : Nontrivial ((i : ι) → X i)
⊢ SeparableSpace ((i : ι) → X i)

Next tactic:
inhabit ∀ i, X i
/-- The product of a countable family of separable spaces is a separable space. -/
instance {ι : Type*} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, SeparableSpace (X i)]
    [Countable ι] : SeparableSpace (∀ i, X i) := by
  choose t htc htd using (exists_countable_dense <| X ·)
  haveI := fun i ↦ (htc i).to_subtype
  nontriviality ∀ i, X i; inhabit ∀ i, X i
  

Proof state:
α : Type u
t✝ : TopologicalSpace α
B : Set (Set α)
s : Set α
ι : Type u_1
X : ι → Type u_2
inst✝² : (i : ι) → TopologicalSpace (X i)
inst✝¹ : ∀ (i : ι), SeparableSpace (X i)
inst✝ : Countable ι
t : (x : ι) → Set (X x)
htc : ∀ (x : ι), Set.Countable (t x)
htd : ∀ (x : ι), Dense (t x)
this : ∀ (i : ι), Countable ↑(t i)
✝ : Nontrivial ((i : ι) → X i)
inhabited_h : Inhabited ((i : ι) → X i)
⊢ SeparableSpace ((i : ι) → X i)

Next tactic:
classical
    set f : (Σ I : Finset ι, ∀ i : I, t i) → ∀ i, X i := fun ⟨I, g⟩ i ↦
      if hi : i ∈ I then g ⟨i, hi⟩ else (default : ∀ i, X i) i
    refine ⟨⟨range f, countable_range f, dense_iff_inter_open.2 fun U hU ⟨g, hg⟩ ↦ ?_⟩⟩
    rcases isOpen_pi_iff.1 hU g hg with ⟨I, u, huo, huU⟩
    have : ∀ i : I, ∃ y ∈ t i, y ∈ u i := fun i ↦
      (htd i).exists_mem_open (huo i i.2).1 ⟨_, (huo i i.2).2⟩
    choose y hyt hyu using this
    lift y to ∀ i : I, t i using hyt
    refine ⟨f ⟨I, y⟩, huU fun i (hi : i ∈ I) ↦ ?_, mem_range_self _⟩
    simp only [dif_pos hi]
    exact hyu _
/-- The product of a countable family of separable spaces is a separable space. -/
instance {ι : Type*} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, SeparableSpace (X i)]
    [Countable ι] : SeparableSpace (∀ i, X i) := by
  choose t htc htd using (exists_countable_dense <| X ·)
  haveI := fun i ↦ (htc i).to_subtype
  nontriviality ∀ i, X i; inhabit ∀ i, X i
  classical
    

Proof state:
α : Type u
t✝ : TopologicalSpace α
B : Set (Set α)
s : Set α
ι : Type u_1
X : ι → Type u_2
inst✝² : (i : ι) → TopologicalSpace (X i)
inst✝¹ : ∀ (i : ι), SeparableSpace (X i)
inst✝ : Countable ι
t : (x : ι) → Set (X x)
htc : ∀ (x : ι), Set.Countable (t x)
htd : ∀ (x : ι), Dense (t x)
this : ∀ (i : ι), Countable ↑(t i)
✝ : Nontrivial ((i : ι) → X i)
inhabited_h : Inhabited ((i : ι) → X i)
⊢ SeparableSpace ((i : ι) → X i)

Next tactic:
set f : (Σ I : Finset ι, ∀ i : I, t i) → ∀ i, X i := fun ⟨I, g⟩ i ↦
      if hi : i ∈ I then g ⟨i, hi⟩ else (default : ∀ i, X i) i
/-- The product of a countable family of separable spaces is a separable space. -/
instance {ι : Type*} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, SeparableSpace (X i)]
    [Countable ι] : SeparableSpace (∀ i, X i) := by
  choose t htc htd using (exists_countable_dense <| X ·)
  haveI := fun i ↦ (htc i).to_subtype
  nontriviality ∀ i, X i; inhabit ∀ i, X i
  classical
    set f : (Σ I : Finset ι, ∀ i : I, t i) → ∀ i, X i := fun ⟨I, g⟩ i ↦
      if hi : i ∈ I then g ⟨i, hi⟩ else (default : ∀ i, X i) i
    

Proof state:
α : Type u
t✝ : TopologicalSpace α
B : Set (Set α)
s : Set α
ι : Type u_1
X : ι → Type u_2
inst✝² : (i : ι) → TopologicalSpace (X i)
inst✝¹ : ∀ (i : ι), SeparableSpace (X i)
inst✝ : Countable ι
t : (x : ι) → Set (X x)
htc : ∀ (x : ι), Set.Countable (t x)
htd : ∀ (x : ι), Dense (t x)
this : ∀ (i : ι), Countable ↑(t i)
✝ : Nontrivial ((i : ι) → X i)
inhabited_h : Inhabited ((i : ι) → X i)
f : (I : Finset ι) × ((i : { x // x ∈ I }) → ↑(t ↑i)) → (i : ι) → X i :=
  fun x i =>
    match x with
    | { fst := I, snd := g } => if hi : i ∈ I then ↑(g { val := i, property := hi }) else default i
⊢ SeparableSpace ((i : ι) → X i)

Next tactic:
refine ⟨⟨range f, countable_range f, dense_iff_inter_open.2 fun U hU ⟨g, hg⟩ ↦ ?_⟩⟩
/-- The product of a countable family of separable spaces is a separable space. -/
instance {ι : Type*} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, SeparableSpace (X i)]
    [Countable ι] : SeparableSpace (∀ i, X i) := by
  choose t htc htd using (exists_countable_dense <| X ·)
  haveI := fun i ↦ (htc i).to_subtype
  nontriviality ∀ i, X i; inhabit ∀ i, X i
  classical
    set f : (Σ I : Finset ι, ∀ i : I, t i) → ∀ i, X i := fun ⟨I, g⟩ i ↦
      if hi : i ∈ I then g ⟨i, hi⟩ else (default : ∀ i, X i) i
    refine ⟨⟨range f, countable_range f, dense_iff_inter_open.2 fun U hU ⟨g, hg⟩ ↦ ?_⟩⟩
    

Proof state:
α : Type u
t✝ : TopologicalSpace α
B : Set (Set α)
s : Set α
ι : Type u_1
X : ι → Type u_2
inst✝² : (i : ι) → TopologicalSpace (X i)
inst✝¹ : ∀ (i : ι), SeparableSpace (X i)
inst✝ : Countable ι
t : (x : ι) → Set (X x)
htc : ∀ (x : ι), Set.Countable (t x)
htd : ∀ (x : ι), Dense (t x)
this : ∀ (i : ι), Countable ↑(t i)
✝ : Nontrivial ((i : ι) → X i)
inhabited_h : Inhabited ((i : ι) → X i)
f : (I : Finset ι) × ((i : { x // x ∈ I }) → ↑(t ↑i)) → (i : ι) → X i :=
  fun x i =>
    match x with
    | { fst := I, snd := g } => if hi : i ∈ I then ↑(g { val := i, property := hi }) else default i
U : Set ((i : ι) → X i)
hU : IsOpen U
x✝ : Set.Nonempty U
g : (i : ι) → X i
hg : g ∈ U
⊢ Set.Nonempty (U ∩ range f)

Next tactic:
rcases isOpen_pi_iff.1 hU g hg with ⟨I, u, huo, huU⟩
/-- The product of a countable family of separable spaces is a separable space. -/
instance {ι : Type*} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, SeparableSpace (X i)]
    [Countable ι] : SeparableSpace (∀ i, X i) := by
  choose t htc htd using (exists_countable_dense <| X ·)
  haveI := fun i ↦ (htc i).to_subtype
  nontriviality ∀ i, X i; inhabit ∀ i, X i
  classical
    set f : (Σ I : Finset ι, ∀ i : I, t i) → ∀ i, X i := fun ⟨I, g⟩ i ↦
      if hi : i ∈ I then g ⟨i, hi⟩ else (default : ∀ i, X i) i
    refine ⟨⟨range f, countable_range f, dense_iff_inter_open.2 fun U hU ⟨g, hg⟩ ↦ ?_⟩⟩
    rcases isOpen_pi_iff.1 hU g hg with ⟨I, u, huo, huU⟩
    

Proof state:
case intro.intro.intro
α : Type u
t✝ : TopologicalSpace α
B : Set (Set α)
s : Set α
ι : Type u_1
X : ι → Type u_2
inst✝² : (i : ι) → TopologicalSpace (X i)
inst✝¹ : ∀ (i : ι), SeparableSpace (X i)
inst✝ : Countable ι
t : (x : ι) → Set (X x)
htc : ∀ (x : ι), Set.Countable (t x)
htd : ∀ (x : ι), Dense (t x)
this : ∀ (i : ι), Countable ↑(t i)
✝ : Nontrivial ((i : ι) → X i)
inhabited_h : Inhabited ((i : ι) → X i)
f : (I : Finset ι) × ((i : { x // x ∈ I }) → ↑(t ↑i)) → (i : ι) → X i :=
  fun x i =>
    match x with
    | { fst := I, snd := g } => if hi : i ∈ I then ↑(g { val := i, property := hi }) else default i
U : Set ((i : ι) → X i)
hU : IsOpen U
x✝ : Set.Nonempty U
g : (i : ι) → X i
hg : g ∈ U
I : Finset ι
u : (a : ι) → Set (X a)
huo : ∀ a ∈ I, IsOpen (u a) ∧ g a ∈ u a
huU : Set.pi (↑I) u ⊆ U
⊢ Set.Nonempty (U ∩ range f)

Next tactic:
have : ∀ i : I, ∃ y ∈ t i, y ∈ u i := fun i ↦
      (htd i).exists_mem_open (huo i i.2).1 ⟨_, (huo i i.2).2⟩
/-- The product of a countable family of separable spaces is a separable space. -/
instance {ι : Type*} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, SeparableSpace (X i)]
    [Countable ι] : SeparableSpace (∀ i, X i) := by
  choose t htc htd using (exists_countable_dense <| X ·)
  haveI := fun i ↦ (htc i).to_subtype
  nontriviality ∀ i, X i; inhabit ∀ i, X i
  classical
    set f : (Σ I : Finset ι, ∀ i : I, t i) → ∀ i, X i := fun ⟨I, g⟩ i ↦
      if hi : i ∈ I then g ⟨i, hi⟩ else (default : ∀ i, X i) i
    refine ⟨⟨range f, countable_range f, dense_iff_inter_open.2 fun U hU ⟨g, hg⟩ ↦ ?_⟩⟩
    rcases isOpen_pi_iff.1 hU g hg with ⟨I, u, huo, huU⟩
    have : ∀ i : I, ∃ y ∈ t i, y ∈ u i := fun i ↦
      (htd i).exists_mem_open (huo i i.2).1 ⟨_, (huo i i.2).2⟩
    

Proof state:
case intro.intro.intro
α : Type u
t✝ : TopologicalSpace α
B : Set (Set α)
s : Set α
ι : Type u_1
X : ι → Type u_2
inst✝² : (i : ι) → TopologicalSpace (X i)
inst✝¹ : ∀ (i : ι), SeparableSpace (X i)
inst✝ : Countable ι
t : (x : ι) → Set (X x)
htc : ∀ (x : ι), Set.Countable (t x)
htd : ∀ (x : ι), Dense (t x)
this✝ : ∀ (i : ι), Countable ↑(t i)
✝ : Nontrivial ((i : ι) → X i)
inhabited_h : Inhabited ((i : ι) → X i)
f : (I : Finset ι) × ((i : { x // x ∈ I }) → ↑(t ↑i)) → (i : ι) → X i :=
  fun x i =>
    match x with
    | { fst := I, snd := g } => if hi : i ∈ I then ↑(g { val := i, property := hi }) else default i
U : Set ((i : ι) → X i)
hU : IsOpen U
x✝ : Set.Nonempty U
g : (i : ι) → X i
hg : g ∈ U
I : Finset ι
u : (a : ι) → Set (X a)
huo : ∀ a ∈ I, IsOpen (u a) ∧ g a ∈ u a
huU : Set.pi (↑I) u ⊆ U
this : ∀ (i : { x // x ∈ I }), ∃ y ∈ t ↑i, y ∈ u ↑i
⊢ Set.Nonempty (U ∩ range f)

Next tactic:
choose y hyt hyu using this
/-- The product of a countable family of separable spaces is a separable space. -/
instance {ι : Type*} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, SeparableSpace (X i)]
    [Countable ι] : SeparableSpace (∀ i, X i) := by
  choose t htc htd using (exists_countable_dense <| X ·)
  haveI := fun i ↦ (htc i).to_subtype
  nontriviality ∀ i, X i; inhabit ∀ i, X i
  classical
    set f : (Σ I : Finset ι, ∀ i : I, t i) → ∀ i, X i := fun ⟨I, g⟩ i ↦
      if hi : i ∈ I then g ⟨i, hi⟩ else (default : ∀ i, X i) i
    refine ⟨⟨range f, countable_range f, dense_iff_inter_open.2 fun U hU ⟨g, hg⟩ ↦ ?_⟩⟩
    rcases isOpen_pi_iff.1 hU g hg with ⟨I, u, huo, huU⟩
    have : ∀ i : I, ∃ y ∈ t i, y ∈ u i := fun i ↦
      (htd i).exists_mem_open (huo i i.2).1 ⟨_, (huo i i.2).2⟩
    choose y hyt hyu using this
    

Proof state:
case intro.intro.intro
α : Type u
t✝ : TopologicalSpace α
B : Set (Set α)
s : Set α
ι : Type u_1
X : ι → Type u_2
inst✝² : (i : ι) → TopologicalSpace (X i)
inst✝¹ : ∀ (i : ι), SeparableSpace (X i)
inst✝ : Countable ι
t : (x : ι) → Set (X x)
htc : ∀ (x : ι), Set.Countable (t x)
htd : ∀ (x : ι), Dense (t x)
this : ∀ (i : ι), Countable ↑(t i)
✝ : Nontrivial ((i : ι) → X i)
inhabited_h : Inhabited ((i : ι) → X i)
f : (I : Finset ι) × ((i : { x // x ∈ I }) → ↑(t ↑i)) → (i : ι) → X i :=
  fun x i =>
    match x with
    | { fst := I, snd := g } => if hi : i ∈ I then ↑(g { val := i, property := hi }) else default i
U : Set ((i : ι) → X i)
hU : IsOpen U
x✝ : Set.Nonempty U
g : (i : ι) → X i
hg : g ∈ U
I : Finset ι
u : (a : ι) → Set (X a)
huo : ∀ a ∈ I, IsOpen (u a) ∧ g a ∈ u a
huU : Set.pi (↑I) u ⊆ U
y : (i : { x // x ∈ I }) → X ↑i
hyt : ∀ (i : { x // x ∈ I }), y i ∈ t ↑i
hyu : ∀ (i : { x // x ∈ I }), y i ∈ u ↑i
⊢ Set.Nonempty (U ∩ range f)

Next tactic:
lift y to ∀ i : I, t i using hyt
/-- The product of a countable family of separable spaces is a separable space. -/
instance {ι : Type*} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, SeparableSpace (X i)]
    [Countable ι] : SeparableSpace (∀ i, X i) := by
  choose t htc htd using (exists_countable_dense <| X ·)
  haveI := fun i ↦ (htc i).to_subtype
  nontriviality ∀ i, X i; inhabit ∀ i, X i
  classical
    set f : (Σ I : Finset ι, ∀ i : I, t i) → ∀ i, X i := fun ⟨I, g⟩ i ↦
      if hi : i ∈ I then g ⟨i, hi⟩ else (default : ∀ i, X i) i
    refine ⟨⟨range f, countable_range f, dense_iff_inter_open.2 fun U hU ⟨g, hg⟩ ↦ ?_⟩⟩
    rcases isOpen_pi_iff.1 hU g hg with ⟨I, u, huo, huU⟩
    have : ∀ i : I, ∃ y ∈ t i, y ∈ u i := fun i ↦
      (htd i).exists_mem_open (huo i i.2).1 ⟨_, (huo i i.2).2⟩
    choose y hyt hyu using this
    lift y to ∀ i : I, t i using hyt
    

Proof state:
case intro.intro.intro.intro
α : Type u
t✝ : TopologicalSpace α
B : Set (Set α)
s : Set α
ι : Type u_1
X : ι → Type u_2
inst✝² : (i : ι) → TopologicalSpace (X i)
inst✝¹ : ∀ (i : ι), SeparableSpace (X i)
inst✝ : Countable ι
t : (x : ι) → Set (X x)
htc : ∀ (x : ι), Set.Countable (t x)
htd : ∀ (x : ι), Dense (t x)
this : ∀ (i : ι), Countable ↑(t i)
✝ : Nontrivial ((i : ι) → X i)
inhabited_h : Inhabited ((i : ι) → X i)
f : (I : Finset ι) × ((i : { x // x ∈ I }) → ↑(t ↑i)) → (i : ι) → X i :=
  fun x i =>
    match x with
    | { fst := I, snd := g } => if hi : i ∈ I then ↑(g { val := i, property := hi }) else default i
U : Set ((i : ι) → X i)
hU : IsOpen U
x✝ : Set.Nonempty U
g : (i : ι) → X i
hg : g ∈ U
I : Finset ι
u : (a : ι) → Set (X a)
huo : ∀ a ∈ I, IsOpen (u a) ∧ g a ∈ u a
huU : Set.pi (↑I) u ⊆ U
y : (i : { x // x ∈ I }) → ↑(t ↑i)
hyu : ∀ (i : { x // x ∈ I }), (fun i => ↑(y i)) i ∈ u ↑i
⊢ Set.Nonempty (U ∩ range f)

Next tactic:
refine ⟨f ⟨I, y⟩, huU fun i (hi : i ∈ I) ↦ ?_, mem_range_self _⟩
/-- The product of a countable family of separable spaces is a separable space. -/
instance {ι : Type*} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, SeparableSpace (X i)]
    [Countable ι] : SeparableSpace (∀ i, X i) := by
  choose t htc htd using (exists_countable_dense <| X ·)
  haveI := fun i ↦ (htc i).to_subtype
  nontriviality ∀ i, X i; inhabit ∀ i, X i
  classical
    set f : (Σ I : Finset ι, ∀ i : I, t i) → ∀ i, X i := fun ⟨I, g⟩ i ↦
      if hi : i ∈ I then g ⟨i, hi⟩ else (default : ∀ i, X i) i
    refine ⟨⟨range f, countable_range f, dense_iff_inter_open.2 fun U hU ⟨g, hg⟩ ↦ ?_⟩⟩
    rcases isOpen_pi_iff.1 hU g hg with ⟨I, u, huo, huU⟩
    have : ∀ i : I, ∃ y ∈ t i, y ∈ u i := fun i ↦
      (htd i).exists_mem_open (huo i i.2).1 ⟨_, (huo i i.2).2⟩
    choose y hyt hyu using this
    lift y to ∀ i : I, t i using hyt
    refine ⟨f ⟨I, y⟩, huU fun i (hi : i ∈ I) ↦ ?_, mem_range_self _⟩
    

Proof state:
case intro.intro.intro.intro
α : Type u
t✝ : TopologicalSpace α
B : Set (Set α)
s : Set α
ι : Type u_1
X : ι → Type u_2
inst✝² : (i : ι) → TopologicalSpace (X i)
inst✝¹ : ∀ (i : ι), SeparableSpace (X i)
inst✝ : Countable ι
t : (x : ι) → Set (X x)
htc : ∀ (x : ι), Set.Countable (t x)
htd : ∀ (x : ι), Dense (t x)
this : ∀ (i : ι), Countable ↑(t i)
✝ : Nontrivial ((i : ι) → X i)
inhabited_h : Inhabited ((i : ι) → X i)
f : (I : Finset ι) × ((i : { x // x ∈ I }) → ↑(t ↑i)) → (i : ι) → X i :=
  fun x i =>
    match x with
    | { fst := I, snd := g } => if hi : i ∈ I then ↑(g { val := i, property := hi }) else default i
U : Set ((i : ι) → X i)
hU : IsOpen U
x✝ : Set.Nonempty U
g : (i : ι) → X i
hg : g ∈ U
I : Finset ι
u : (a : ι) → Set (X a)
huo : ∀ a ∈ I, IsOpen (u a) ∧ g a ∈ u a
huU : Set.pi (↑I) u ⊆ U
y : (i : { x // x ∈ I }) → ↑(t ↑i)
hyu : ∀ (i : { x // x ∈ I }), (fun i => ↑(y i)) i ∈ u ↑i
i : ι
hi : i ∈ I
⊢ f { fst := I, snd := y } i ∈ u i

Next tactic:
simp only [dif_pos hi]
/-- The product of a countable family of separable spaces is a separable space. -/
instance {ι : Type*} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, SeparableSpace (X i)]
    [Countable ι] : SeparableSpace (∀ i, X i) := by
  choose t htc htd using (exists_countable_dense <| X ·)
  haveI := fun i ↦ (htc i).to_subtype
  nontriviality ∀ i, X i; inhabit ∀ i, X i
  classical
    set f : (Σ I : Finset ι, ∀ i : I, t i) → ∀ i, X i := fun ⟨I, g⟩ i ↦
      if hi : i ∈ I then g ⟨i, hi⟩ else (default : ∀ i, X i) i
    refine ⟨⟨range f, countable_range f, dense_iff_inter_open.2 fun U hU ⟨g, hg⟩ ↦ ?_⟩⟩
    rcases isOpen_pi_iff.1 hU g hg with ⟨I, u, huo, huU⟩
    have : ∀ i : I, ∃ y ∈ t i, y ∈ u i := fun i ↦
      (htd i).exists_mem_open (huo i i.2).1 ⟨_, (huo i i.2).2⟩
    choose y hyt hyu using this
    lift y to ∀ i : I, t i using hyt
    refine ⟨f ⟨I, y⟩, huU fun i (hi : i ∈ I) ↦ ?_, mem_range_self _⟩
    simp only [dif_pos hi]
    

Proof state:
case intro.intro.intro.intro
α : Type u
t✝ : TopologicalSpace α
B : Set (Set α)
s : Set α
ι : Type u_1
X : ι → Type u_2
inst✝² : (i : ι) → TopologicalSpace (X i)
inst✝¹ : ∀ (i : ι), SeparableSpace (X i)
inst✝ : Countable ι
t : (x : ι) → Set (X x)
htc : ∀ (x : ι), Set.Countable (t x)
htd : ∀ (x : ι), Dense (t x)
this : ∀ (i : ι), Countable ↑(t i)
✝ : Nontrivial ((i : ι) → X i)
inhabited_h : Inhabited ((i : ι) → X i)
f : (I : Finset ι) × ((i : { x // x ∈ I }) → ↑(t ↑i)) → (i : ι) → X i :=
  fun x i =>
    match x with
    | { fst := I, snd := g } => if hi : i ∈ I then ↑(g { val := i, property := hi }) else default i
U : Set ((i : ι) → X i)
hU : IsOpen U
x✝ : Set.Nonempty U
g : (i : ι) → X i
hg : g ∈ U
I : Finset ι
u : (a : ι) → Set (X a)
huo : ∀ a ∈ I, IsOpen (u a) ∧ g a ∈ u a
huU : Set.pi (↑I) u ⊆ U
y : (i : { x // x ∈ I }) → ↑(t ↑i)
hyu : ∀ (i : { x // x ∈ I }), (fun i => ↑(y i)) i ∈ u ↑i
i : ι
hi : i ∈ I
⊢ ↑(y { val := i, property := (_ : i ∈ I) }) ∈ u i

Next tactic:
exact hyu _
/-- A topological space with discrete topology is separable iff it is countable. -/
theorem separableSpace_iff_countable [DiscreteTopology α] : SeparableSpace α ↔ Countable α := by
  

Proof state:
α : Type u
t : TopologicalSpace α
B : Set (Set α)
s : Set α
inst✝ : DiscreteTopology α
⊢ SeparableSpace α ↔ Countable α

Next tactic:
simp [SeparableSpace_iff, countable_univ_iff]
/-- In a separable space, a family of nonempty disjoint open sets is countable. -/
theorem _root_.Set.PairwiseDisjoint.countable_of_isOpen [SeparableSpace α] {ι : Type*}
    {s : ι → Set α} {a : Set ι} (h : a.PairwiseDisjoint s) (ha : ∀ i ∈ a, IsOpen (s i))
    (h'a : ∀ i ∈ a, (s i).Nonempty) : a.Countable := by
  

Proof state:
α : Type u
t : TopologicalSpace α
B : Set (Set α)
s✝ : Set α
inst✝ : SeparableSpace α
ι : Type u_1
s : ι → Set α
a : Set ι
h : PairwiseDisjoint a s
ha : ∀ i ∈ a, IsOpen (s i)
h'a : ∀ i ∈ a, Set.Nonempty (s i)
⊢ Set.Countable a

Next tactic:
rcases exists_countable_dense α with ⟨u, ⟨u_encodable⟩, u_dense⟩
/-- In a separable space, a family of nonempty disjoint open sets is countable. -/
theorem _root_.Set.PairwiseDisjoint.countable_of_isOpen [SeparableSpace α] {ι : Type*}
    {s : ι → Set α} {a : Set ι} (h : a.PairwiseDisjoint s) (ha : ∀ i ∈ a, IsOpen (s i))
    (h'a : ∀ i ∈ a, (s i).Nonempty) : a.Countable := by
  rcases exists_countable_dense α with ⟨u, ⟨u_encodable⟩, u_dense⟩
  

Proof state:
case intro.intro.intro
α : Type u
t : TopologicalSpace α
B : Set (Set α)
s✝ : Set α
inst✝ : SeparableSpace α
ι : Type u_1
s : ι → Set α
a : Set ι
h : PairwiseDisjoint a s
ha : ∀ i ∈ a, IsOpen (s i)
h'a : ∀ i ∈ a, Set.Nonempty (s i)
u : Set α
u_dense : Dense u
u_encodable : Encodable ↑u
⊢ Set.Countable a

Next tactic:
have : ∀ i : a, ∃ y, y ∈ s i ∩ u := fun i =>
    dense_iff_inter_open.1 u_dense (s i) (ha i i.2) (h'a i i.2)
/-- In a separable space, a family of nonempty disjoint open sets is countable. -/
theorem _root_.Set.PairwiseDisjoint.countable_of_isOpen [SeparableSpace α] {ι : Type*}
    {s : ι → Set α} {a : Set ι} (h : a.PairwiseDisjoint s) (ha : ∀ i ∈ a, IsOpen (s i))
    (h'a : ∀ i ∈ a, (s i).Nonempty) : a.Countable := by
  rcases exists_countable_dense α with ⟨u, ⟨u_encodable⟩, u_dense⟩
  have : ∀ i : a, ∃ y, y ∈ s i ∩ u := fun i =>
    dense_iff_inter_open.1 u_dense (s i) (ha i i.2) (h'a i i.2)
  

Proof state:
case intro.intro.intro
α : Type u
t : TopologicalSpace α
B : Set (Set α)
s✝ : Set α
inst✝ : SeparableSpace α
ι : Type u_1
s : ι → Set α
a : Set ι
h : PairwiseDisjoint a s
ha : ∀ i ∈ a, IsOpen (s i)
h'a : ∀ i ∈ a, Set.Nonempty (s i)
u : Set α
u_dense : Dense u
u_encodable : Encodable ↑u
this : ∀ (i : ↑a), ∃ y, y ∈ s ↑i ∩ u
⊢ Set.Countable a

Next tactic:
choose f hfs hfu using this