l3lab/ntp-mathlib huggingface dataset:
/-- If there are subsets which are `ε₁`-dense and `ε₃`-dense in two spaces, and
isometric up to `ε₂`, then the Gromov-Hausdorff distance between the spaces is bounded by
`ε₁ + ε₂/2 + ε₃`. -/
theorem ghDist_le_of_approx_subsets {s : Set X} (Φ : s → Y) {ε₁ ε₂ ε₃ : ℝ}
    (hs : ∀ x : X, ∃ y ∈ s, dist x y ≤ ε₁) (hs' : ∀ x : Y, ∃ y : s, dist x (Φ y) ≤ ε₃)
    (H : ∀ x y : s, |dist x y - dist (Φ x) (Φ y)| ≤ ε₂) : ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ := by
  refine' le_of_forall_pos_le_add fun δ δ0 => _
  rcases exists_mem_of_nonempty X with ⟨xX, _⟩
  rcases hs xX with ⟨xs, hxs, Dxs⟩
  have sne : s.Nonempty := ⟨xs, hxs⟩
  letI : Nonempty s := sne.to_subtype
  have : 0 ≤ ε₂ := le_trans (abs_nonneg _) (H ⟨xs, hxs⟩ ⟨xs, hxs⟩)
  have : ∀ p q : s, |dist p q - dist (Φ p) (Φ q)| ≤ 2 * (ε₂ / 2 + δ) := fun p q =>
    calc
      |dist p q - dist (Φ p) (Φ q)| ≤ ε₂ := H p q
      _ ≤ 2 * (ε₂ / 2 + δ) := by linarith
  -- glue `X` and `Y` along the almost matching subsets
  letI : MetricSpace (Sum X Y) :=
    glueMetricApprox (fun x : s => (x : X)) (fun x => Φ x) (ε₂ / 2 + δ) (by linarith) this
  let Fl := @Sum.inl X Y
  let Fr := @Sum.inr X Y
  

Proof state:
case intro.intro.intro
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
s : Set X
Φ : ↑s → Y
ε₁ ε₂ ε₃ : ℝ
hs : ∀ (x : X), ∃ y ∈ s, dist x y ≤ ε₁
hs' : ∀ (x : Y), ∃ y, dist x (Φ y) ≤ ε₃
H : ∀ (x y : ↑s), |dist x y - dist (Φ x) (Φ y)| ≤ ε₂
δ : ℝ
δ0 : 0 < δ
xX : X
h✝ : xX ∈ univ
xs : X
hxs : xs ∈ s
Dxs : dist xX xs ≤ ε₁
sne : Set.Nonempty s
this✝² : Nonempty ↑s := Nonempty.to_subtype sne
this✝¹ : 0 ≤ ε₂
this✝ : ∀ (p q : ↑s), |dist p q - dist (Φ p) (Φ q)| ≤ 2 * (ε₂ / 2 + δ)
this : MetricSpace (X ⊕ Y) := glueMetricApprox (fun x => ↑x) (fun x => Φ x) (ε₂ / 2 + δ) (_ : 0 < ε₂ / 2 + δ) this✝
Fl : X → X ⊕ Y := inl
Fr : Y → X ⊕ Y := inr
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ

Next tactic:
have Il : Isometry Fl := Isometry.of_dist_eq fun x y => rfl
/-- If there are subsets which are `ε₁`-dense and `ε₃`-dense in two spaces, and
isometric up to `ε₂`, then the Gromov-Hausdorff distance between the spaces is bounded by
`ε₁ + ε₂/2 + ε₃`. -/
theorem ghDist_le_of_approx_subsets {s : Set X} (Φ : s → Y) {ε₁ ε₂ ε₃ : ℝ}
    (hs : ∀ x : X, ∃ y ∈ s, dist x y ≤ ε₁) (hs' : ∀ x : Y, ∃ y : s, dist x (Φ y) ≤ ε₃)
    (H : ∀ x y : s, |dist x y - dist (Φ x) (Φ y)| ≤ ε₂) : ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ := by
  refine' le_of_forall_pos_le_add fun δ δ0 => _
  rcases exists_mem_of_nonempty X with ⟨xX, _⟩
  rcases hs xX with ⟨xs, hxs, Dxs⟩
  have sne : s.Nonempty := ⟨xs, hxs⟩
  letI : Nonempty s := sne.to_subtype
  have : 0 ≤ ε₂ := le_trans (abs_nonneg _) (H ⟨xs, hxs⟩ ⟨xs, hxs⟩)
  have : ∀ p q : s, |dist p q - dist (Φ p) (Φ q)| ≤ 2 * (ε₂ / 2 + δ) := fun p q =>
    calc
      |dist p q - dist (Φ p) (Φ q)| ≤ ε₂ := H p q
      _ ≤ 2 * (ε₂ / 2 + δ) := by linarith
  -- glue `X` and `Y` along the almost matching subsets
  letI : MetricSpace (Sum X Y) :=
    glueMetricApprox (fun x : s => (x : X)) (fun x => Φ x) (ε₂ / 2 + δ) (by linarith) this
  let Fl := @Sum.inl X Y
  let Fr := @Sum.inr X Y
  have Il : Isometry Fl := Isometry.of_dist_eq fun x y => rfl
  

Proof state:
case intro.intro.intro
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
s : Set X
Φ : ↑s → Y
ε₁ ε₂ ε₃ : ℝ
hs : ∀ (x : X), ∃ y ∈ s, dist x y ≤ ε₁
hs' : ∀ (x : Y), ∃ y, dist x (Φ y) ≤ ε₃
H : ∀ (x y : ↑s), |dist x y - dist (Φ x) (Φ y)| ≤ ε₂
δ : ℝ
δ0 : 0 < δ
xX : X
h✝ : xX ∈ univ
xs : X
hxs : xs ∈ s
Dxs : dist xX xs ≤ ε₁
sne : Set.Nonempty s
this✝² : Nonempty ↑s := Nonempty.to_subtype sne
this✝¹ : 0 ≤ ε₂
this✝ : ∀ (p q : ↑s), |dist p q - dist (Φ p) (Φ q)| ≤ 2 * (ε₂ / 2 + δ)
this : MetricSpace (X ⊕ Y) := glueMetricApprox (fun x => ↑x) (fun x => Φ x) (ε₂ / 2 + δ) (_ : 0 < ε₂ / 2 + δ) this✝
Fl : X → X ⊕ Y := inl
Fr : Y → X ⊕ Y := inr
Il : Isometry Fl
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ

Next tactic:
have Ir : Isometry Fr := Isometry.of_dist_eq fun x y => rfl
/-- If there are subsets which are `ε₁`-dense and `ε₃`-dense in two spaces, and
isometric up to `ε₂`, then the Gromov-Hausdorff distance between the spaces is bounded by
`ε₁ + ε₂/2 + ε₃`. -/
theorem ghDist_le_of_approx_subsets {s : Set X} (Φ : s → Y) {ε₁ ε₂ ε₃ : ℝ}
    (hs : ∀ x : X, ∃ y ∈ s, dist x y ≤ ε₁) (hs' : ∀ x : Y, ∃ y : s, dist x (Φ y) ≤ ε₃)
    (H : ∀ x y : s, |dist x y - dist (Φ x) (Φ y)| ≤ ε₂) : ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ := by
  refine' le_of_forall_pos_le_add fun δ δ0 => _
  rcases exists_mem_of_nonempty X with ⟨xX, _⟩
  rcases hs xX with ⟨xs, hxs, Dxs⟩
  have sne : s.Nonempty := ⟨xs, hxs⟩
  letI : Nonempty s := sne.to_subtype
  have : 0 ≤ ε₂ := le_trans (abs_nonneg _) (H ⟨xs, hxs⟩ ⟨xs, hxs⟩)
  have : ∀ p q : s, |dist p q - dist (Φ p) (Φ q)| ≤ 2 * (ε₂ / 2 + δ) := fun p q =>
    calc
      |dist p q - dist (Φ p) (Φ q)| ≤ ε₂ := H p q
      _ ≤ 2 * (ε₂ / 2 + δ) := by linarith
  -- glue `X` and `Y` along the almost matching subsets
  letI : MetricSpace (Sum X Y) :=
    glueMetricApprox (fun x : s => (x : X)) (fun x => Φ x) (ε₂ / 2 + δ) (by linarith) this
  let Fl := @Sum.inl X Y
  let Fr := @Sum.inr X Y
  have Il : Isometry Fl := Isometry.of_dist_eq fun x y => rfl
  have Ir : Isometry Fr := Isometry.of_dist_eq fun x y => rfl
  /- The proof goes as follows : the `GH_dist` is bounded by the Hausdorff distance of the images
    in the coupling, which is bounded (using the triangular inequality) by the sum of the Hausdorff
    distances of `X` and `s` (in the coupling or, equivalently in the original space), of `s` and
    `Φ s`, and of `Φ s` and `Y` (in the coupling or, equivalently, in the original space).
    The first term is bounded by `ε₁`, by `ε₁`-density. The third one is bounded by `ε₃`.
    And the middle one is bounded by `ε₂/2` as in the coupling the points `x` and `Φ x` are
    at distance `ε₂/2` by construction of the coupling (in fact `ε₂/2 + δ` where `δ` is an
    arbitrarily small positive constant where positivity is used to ensure that the coupling
    is really a metric space and not a premetric space on `X ⊕ Y`). -/
  

Proof state:
case intro.intro.intro
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
s : Set X
Φ : ↑s → Y
ε₁ ε₂ ε₃ : ℝ
hs : ∀ (x : X), ∃ y ∈ s, dist x y ≤ ε₁
hs' : ∀ (x : Y), ∃ y, dist x (Φ y) ≤ ε₃
H : ∀ (x y : ↑s), |dist x y - dist (Φ x) (Φ y)| ≤ ε₂
δ : ℝ
δ0 : 0 < δ
xX : X
h✝ : xX ∈ univ
xs : X
hxs : xs ∈ s
Dxs : dist xX xs ≤ ε₁
sne : Set.Nonempty s
this✝² : Nonempty ↑s := Nonempty.to_subtype sne
this✝¹ : 0 ≤ ε₂
this✝ : ∀ (p q : ↑s), |dist p q - dist (Φ p) (Φ q)| ≤ 2 * (ε₂ / 2 + δ)
this : MetricSpace (X ⊕ Y) := glueMetricApprox (fun x => ↑x) (fun x => Φ x) (ε₂ / 2 + δ) (_ : 0 < ε₂ / 2 + δ) this✝
Fl : X → X ⊕ Y := inl
Fr : Y → X ⊕ Y := inr
Il : Isometry Fl
Ir : Isometry Fr
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ

Next tactic:
have : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr) := ghDist_le_hausdorffDist Il Ir
/-- The Gromov-Hausdorff space is second countable. -/
instance : SecondCountableTopology GHSpace := by
  

Proof state:
⊢ SecondCountableTopology GHSpace

Next tactic:
refine' secondCountable_of_countable_discretization fun δ δpos => _
/-- The Gromov-Hausdorff space is second countable. -/
instance : SecondCountableTopology GHSpace := by
  refine' secondCountable_of_countable_discretization fun δ δpos => _
  

Proof state:
δ : ℝ
δpos : δ > 0
⊢ ∃ β x F, ∀ (x y : GHSpace), F x = F y → dist x y ≤ δ

Next tactic:
let ε := 2 / 5 * δ
/-- The Gromov-Hausdorff space is second countable. -/
instance : SecondCountableTopology GHSpace := by
  refine' secondCountable_of_countable_discretization fun δ δpos => _
  let ε := 2 / 5 * δ
  

Proof state:
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
⊢ ∃ β x F, ∀ (x y : GHSpace), F x = F y → dist x y ≤ δ

Next tactic:
have εpos : 0 < ε := mul_pos (by norm_num) δpos
/-- The Gromov-Hausdorff space is second countable. -/
instance : SecondCountableTopology GHSpace := by
  refine' secondCountable_of_countable_discretization fun δ δpos => _
  let ε := 2 / 5 * δ
  have εpos : 0 < ε := mul_pos (by 

Proof state:
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
⊢ 0 < 2 / 5

Next tactic:
norm_num
/-- The Gromov-Hausdorff space is second countable. -/
instance : SecondCountableTopology GHSpace := by
  refine' secondCountable_of_countable_discretization fun δ δpos => _
  let ε := 2 / 5 * δ
  have εpos : 0 < ε := mul_pos (by norm_num) δpos
  

Proof state:
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
⊢ ∃ β x F, ∀ (x y : GHSpace), F x = F y → dist x y ≤ δ

Next tactic:
have : ∀ p : GHSpace, ∃ s : Set p.Rep, s.Finite ∧ univ ⊆ ⋃ x ∈ s, ball x ε := fun p => by
    simpa only [subset_univ, true_and] using
      finite_cover_balls_of_compact (α := p.Rep) isCompact_univ εpos
/-- The Gromov-Hausdorff space is second countable. -/
instance : SecondCountableTopology GHSpace := by
  refine' secondCountable_of_countable_discretization fun δ δpos => _
  let ε := 2 / 5 * δ
  have εpos : 0 < ε := mul_pos (by norm_num) δpos
  have : ∀ p : GHSpace, ∃ s : Set p.Rep, s.Finite ∧ univ ⊆ ⋃ x ∈ s, ball x ε := fun p => by
    

Proof state:
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
p : GHSpace
⊢ ∃ s, Set.Finite s ∧ univ ⊆ ⋃ x ∈ s, ball x ε

Next tactic:
simpa only [subset_univ, true_and] using
      finite_cover_balls_of_compact (α := p.Rep) isCompact_univ εpos
/-- The Gromov-Hausdorff space is second countable. -/
instance : SecondCountableTopology GHSpace := by
  refine' secondCountable_of_countable_discretization fun δ δpos => _
  let ε := 2 / 5 * δ
  have εpos : 0 < ε := mul_pos (by norm_num) δpos
  have : ∀ p : GHSpace, ∃ s : Set p.Rep, s.Finite ∧ univ ⊆ ⋃ x ∈ s, ball x ε := fun p => by
    simpa only [subset_univ, true_and] using
      finite_cover_balls_of_compact (α := p.Rep) isCompact_univ εpos
  -- for each `p`, `s p` is a finite `ε`-dense subset of `p` (or rather the metric space
  -- `p.rep` representing `p`)
  

Proof state:
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
this : ∀ (p : GHSpace), ∃ s, Set.Finite s ∧ univ ⊆ ⋃ x ∈ s, ball x ε
⊢ ∃ β x F, ∀ (x y : GHSpace), F x = F y → dist x y ≤ δ

Next tactic:
choose s hs using this
/-- The Gromov-Hausdorff space is second countable. -/
instance : SecondCountableTopology GHSpace := by
  refine' secondCountable_of_countable_discretization fun δ δpos => _
  let ε := 2 / 5 * δ
  have εpos : 0 < ε := mul_pos (by norm_num) δpos
  have : ∀ p : GHSpace, ∃ s : Set p.Rep, s.Finite ∧ univ ⊆ ⋃ x ∈ s, ball x ε := fun p => by
    simpa only [subset_univ, true_and] using
      finite_cover_balls_of_compact (α := p.Rep) isCompact_univ εpos
  -- for each `p`, `s p` is a finite `ε`-dense subset of `p` (or rather the metric space
  -- `p.rep` representing `p`)
  choose s hs using this
  

Proof state:
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ x ∈ s p, ball x ε
⊢ ∃ β x F, ∀ (x y : GHSpace), F x = F y → dist x y ≤ δ

Next tactic:
have : ∀ p : GHSpace, ∀ t : Set p.Rep, t.Finite → ∃ n : ℕ, ∃ _ : Equiv t (Fin n), True := by
    intro p t ht
    letI : Fintype t := Finite.fintype ht
    exact ⟨Fintype.card t, Fintype.equivFin t, trivial⟩
/-- The Gromov-Hausdorff space is second countable. -/
instance : SecondCountableTopology GHSpace := by
  refine' secondCountable_of_countable_discretization fun δ δpos => _
  let ε := 2 / 5 * δ
  have εpos : 0 < ε := mul_pos (by norm_num) δpos
  have : ∀ p : GHSpace, ∃ s : Set p.Rep, s.Finite ∧ univ ⊆ ⋃ x ∈ s, ball x ε := fun p => by
    simpa only [subset_univ, true_and] using
      finite_cover_balls_of_compact (α := p.Rep) isCompact_univ εpos
  -- for each `p`, `s p` is a finite `ε`-dense subset of `p` (or rather the metric space
  -- `p.rep` representing `p`)
  choose s hs using this
  have : ∀ p : GHSpace, ∀ t : Set p.Rep, t.Finite → ∃ n : ℕ, ∃ _ : Equiv t (Fin n), True := by
    

Proof state:
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ x ∈ s p, ball x ε
⊢ ∀ (p : GHSpace) (t : Set (GHSpace.Rep p)), Set.Finite t → ∃ n x, True

Next tactic:
intro p t ht
/-- The Gromov-Hausdorff space is second countable. -/
instance : SecondCountableTopology GHSpace := by
  refine' secondCountable_of_countable_discretization fun δ δpos => _
  let ε := 2 / 5 * δ
  have εpos : 0 < ε := mul_pos (by norm_num) δpos
  have : ∀ p : GHSpace, ∃ s : Set p.Rep, s.Finite ∧ univ ⊆ ⋃ x ∈ s, ball x ε := fun p => by
    simpa only [subset_univ, true_and] using
      finite_cover_balls_of_compact (α := p.Rep) isCompact_univ εpos
  -- for each `p`, `s p` is a finite `ε`-dense subset of `p` (or rather the metric space
  -- `p.rep` representing `p`)
  choose s hs using this
  have : ∀ p : GHSpace, ∀ t : Set p.Rep, t.Finite → ∃ n : ℕ, ∃ _ : Equiv t (Fin n), True := by
    intro p t ht
    

Proof state:
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ x ∈ s p, ball x ε
p : GHSpace
t : Set (GHSpace.Rep p)
ht : Set.Finite t
⊢ ∃ n x, True

Next tactic:
letI : Fintype t := Finite.fintype ht
/-- The Gromov-Hausdorff space is second countable. -/
instance : SecondCountableTopology GHSpace := by
  refine' secondCountable_of_countable_discretization fun δ δpos => _
  let ε := 2 / 5 * δ
  have εpos : 0 < ε := mul_pos (by norm_num) δpos
  have : ∀ p : GHSpace, ∃ s : Set p.Rep, s.Finite ∧ univ ⊆ ⋃ x ∈ s, ball x ε := fun p => by
    simpa only [subset_univ, true_and] using
      finite_cover_balls_of_compact (α := p.Rep) isCompact_univ εpos
  -- for each `p`, `s p` is a finite `ε`-dense subset of `p` (or rather the metric space
  -- `p.rep` representing `p`)
  choose s hs using this
  have : ∀ p : GHSpace, ∀ t : Set p.Rep, t.Finite → ∃ n : ℕ, ∃ _ : Equiv t (Fin n), True := by
    intro p t ht
    letI : Fintype t := Finite.fintype ht
    

Proof state:
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ x ∈ s p, ball x ε
p : GHSpace
t : Set (GHSpace.Rep p)
ht : Set.Finite t
this : Fintype ↑t := Finite.fintype ht
⊢ ∃ n x, True

Next tactic:
exact ⟨Fintype.card t, Fintype.equivFin t, trivial⟩
/-- The Gromov-Hausdorff space is second countable. -/
instance : SecondCountableTopology GHSpace := by
  refine' secondCountable_of_countable_discretization fun δ δpos => _
  let ε := 2 / 5 * δ
  have εpos : 0 < ε := mul_pos (by norm_num) δpos
  have : ∀ p : GHSpace, ∃ s : Set p.Rep, s.Finite ∧ univ ⊆ ⋃ x ∈ s, ball x ε := fun p => by
    simpa only [subset_univ, true_and] using
      finite_cover_balls_of_compact (α := p.Rep) isCompact_univ εpos
  -- for each `p`, `s p` is a finite `ε`-dense subset of `p` (or rather the metric space
  -- `p.rep` representing `p`)
  choose s hs using this
  have : ∀ p : GHSpace, ∀ t : Set p.Rep, t.Finite → ∃ n : ℕ, ∃ _ : Equiv t (Fin n), True := by
    intro p t ht
    letI : Fintype t := Finite.fintype ht
    exact ⟨Fintype.card t, Fintype.equivFin t, trivial⟩
  

Proof state:
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ x ∈ s p, ball x ε
this : ∀ (p : GHSpace) (t : Set (GHSpace.Rep p)), Set.Finite t → ∃ n x, True
⊢ ∃ β x F, ∀ (x y : GHSpace), F x = F y → dist x y ≤ δ

Next tactic:
choose N e _ using this
/-- The Gromov-Hausdorff space is second countable. -/
instance : SecondCountableTopology GHSpace := by
  refine' secondCountable_of_countable_discretization fun δ δpos => _
  let ε := 2 / 5 * δ
  have εpos : 0 < ε := mul_pos (by norm_num) δpos
  have : ∀ p : GHSpace, ∃ s : Set p.Rep, s.Finite ∧ univ ⊆ ⋃ x ∈ s, ball x ε := fun p => by
    simpa only [subset_univ, true_and] using
      finite_cover_balls_of_compact (α := p.Rep) isCompact_univ εpos
  -- for each `p`, `s p` is a finite `ε`-dense subset of `p` (or rather the metric space
  -- `p.rep` representing `p`)
  choose s hs using this
  have : ∀ p : GHSpace, ∀ t : Set p.Rep, t.Finite → ∃ n : ℕ, ∃ _ : Equiv t (Fin n), True := by
    intro p t ht
    letI : Fintype t := Finite.fintype ht
    exact ⟨Fintype.card t, Fintype.equivFin t, trivial⟩
  choose N e _ using this
  -- cardinality of the nice finite subset `s p` of `p.rep`, called `N p`
  

Proof state:
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ x ∈ s p, ball x ε
N : (p : GHSpace) → (t : Set (GHSpace.Rep p)) → Set.Finite t → ℕ
e : (p : GHSpace) → (t : Set (GHSpace.Rep p)) → (a : Set.Finite t) → ↑t ≃ Fin (N p t a)
x✝ : ∀ (p : GHSpace) (t : Set (GHSpace.Rep p)), Set.Finite t → True
⊢ ∃ β x F, ∀ (x y : GHSpace), F x = F y → dist x y ≤ δ

Next tactic:
let N := fun p : GHSpace => N p (s p) (hs p).1
/-- The Gromov-Hausdorff space is second countable. -/
instance : SecondCountableTopology GHSpace := by
  refine' secondCountable_of_countable_discretization fun δ δpos => _
  let ε := 2 / 5 * δ
  have εpos : 0 < ε := mul_pos (by norm_num) δpos
  have : ∀ p : GHSpace, ∃ s : Set p.Rep, s.Finite ∧ univ ⊆ ⋃ x ∈ s, ball x ε := fun p => by
    simpa only [subset_univ, true_and] using
      finite_cover_balls_of_compact (α := p.Rep) isCompact_univ εpos
  -- for each `p`, `s p` is a finite `ε`-dense subset of `p` (or rather the metric space
  -- `p.rep` representing `p`)
  choose s hs using this
  have : ∀ p : GHSpace, ∀ t : Set p.Rep, t.Finite → ∃ n : ℕ, ∃ _ : Equiv t (Fin n), True := by
    intro p t ht
    letI : Fintype t := Finite.fintype ht
    exact ⟨Fintype.card t, Fintype.equivFin t, trivial⟩
  choose N e _ using this
  -- cardinality of the nice finite subset `s p` of `p.rep`, called `N p`
  let N := fun p : GHSpace => N p (s p) (hs p).1
  -- equiv from `s p`, a nice finite subset of `p.rep`, to `fin (N p)`, called `E p`
  

Proof state:
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ x ∈ s p, ball x ε
N✝ : (p : GHSpace) → (t : Set (GHSpace.Rep p)) → Set.Finite t → ℕ
e : (p : GHSpace) → (t : Set (GHSpace.Rep p)) → (a : Set.Finite t) → ↑t ≃ Fin (N✝ p t a)
x✝ : ∀ (p : GHSpace) (t : Set (GHSpace.Rep p)), Set.Finite t → True
N : GHSpace → ℕ := fun p => N✝ p (s p) (_ : Set.Finite (s p))
⊢ ∃ β x F, ∀ (x y : GHSpace), F x = F y → dist x y ≤ δ

Next tactic:
let E := fun p : GHSpace => e p (s p) (hs p).1
/-- The Gromov-Hausdorff space is second countable. -/
instance : SecondCountableTopology GHSpace := by
  refine' secondCountable_of_countable_discretization fun δ δpos => _
  let ε := 2 / 5 * δ
  have εpos : 0 < ε := mul_pos (by norm_num) δpos
  have : ∀ p : GHSpace, ∃ s : Set p.Rep, s.Finite ∧ univ ⊆ ⋃ x ∈ s, ball x ε := fun p => by
    simpa only [subset_univ, true_and] using
      finite_cover_balls_of_compact (α := p.Rep) isCompact_univ εpos
  -- for each `p`, `s p` is a finite `ε`-dense subset of `p` (or rather the metric space
  -- `p.rep` representing `p`)
  choose s hs using this
  have : ∀ p : GHSpace, ∀ t : Set p.Rep, t.Finite → ∃ n : ℕ, ∃ _ : Equiv t (Fin n), True := by
    intro p t ht
    letI : Fintype t := Finite.fintype ht
    exact ⟨Fintype.card t, Fintype.equivFin t, trivial⟩
  choose N e _ using this
  -- cardinality of the nice finite subset `s p` of `p.rep`, called `N p`
  let N := fun p : GHSpace => N p (s p) (hs p).1
  -- equiv from `s p`, a nice finite subset of `p.rep`, to `fin (N p)`, called `E p`
  let E := fun p : GHSpace => e p (s p) (hs p).1
  -- A function `F` associating to `p : GHSpace` the data of all distances between points
  -- in the `ε`-dense set `s p`.
  

Proof state:
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ x ∈ s p, ball x ε
N✝ : (p : GHSpace) → (t : Set (GHSpace.Rep p)) → Set.Finite t → ℕ
e : (p : GHSpace) → (t : Set (GHSpace.Rep p)) → (a : Set.Finite t) → ↑t ≃ Fin (N✝ p t a)
x✝ : ∀ (p : GHSpace) (t : Set (GHSpace.Rep p)), Set.Finite t → True
N : GHSpace → ℕ := fun p => N✝ p (s p) (_ : Set.Finite (s p))
E : (p : GHSpace) → ↑(s p) ≃ Fin (N✝ p (s p) (_ : Set.Finite (s p))) := fun p => e p (s p) (_ : Set.Finite (s p))
⊢ ∃ β x F, ∀ (x y : GHSpace), F x = F y → dist x y ≤ δ

Next tactic:
let F : GHSpace → Σ n : ℕ, Fin n → Fin n → ℤ := fun p =>
    ⟨N p, fun a b => ⌊ε⁻¹ * dist ((E p).symm a) ((E p).symm b)⌋⟩
/-- The Gromov-Hausdorff space is second countable. -/
instance : SecondCountableTopology GHSpace := by
  refine' secondCountable_of_countable_discretization fun δ δpos => _
  let ε := 2 / 5 * δ
  have εpos : 0 < ε := mul_pos (by norm_num) δpos
  have : ∀ p : GHSpace, ∃ s : Set p.Rep, s.Finite ∧ univ ⊆ ⋃ x ∈ s, ball x ε := fun p => by
    simpa only [subset_univ, true_and] using
      finite_cover_balls_of_compact (α := p.Rep) isCompact_univ εpos
  -- for each `p`, `s p` is a finite `ε`-dense subset of `p` (or rather the metric space
  -- `p.rep` representing `p`)
  choose s hs using this
  have : ∀ p : GHSpace, ∀ t : Set p.Rep, t.Finite → ∃ n : ℕ, ∃ _ : Equiv t (Fin n), True := by
    intro p t ht
    letI : Fintype t := Finite.fintype ht
    exact ⟨Fintype.card t, Fintype.equivFin t, trivial⟩
  choose N e _ using this
  -- cardinality of the nice finite subset `s p` of `p.rep`, called `N p`
  let N := fun p : GHSpace => N p (s p) (hs p).1
  -- equiv from `s p`, a nice finite subset of `p.rep`, to `fin (N p)`, called `E p`
  let E := fun p : GHSpace => e p (s p) (hs p).1
  -- A function `F` associating to `p : GHSpace` the data of all distances between points
  -- in the `ε`-dense set `s p`.
  let F : GHSpace → Σ n : ℕ, Fin n → Fin n → ℤ := fun p =>
    ⟨N p, fun a b => ⌊ε⁻¹ * dist ((E p).symm a) ((E p).symm b)⌋⟩
  

Proof state:
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ x ∈ s p, ball x ε
N✝ : (p : GHSpace) → (t : Set (GHSpace.Rep p)) → Set.Finite t → ℕ
e : (p : GHSpace) → (t : Set (GHSpace.Rep p)) → (a : Set.Finite t) → ↑t ≃ Fin (N✝ p t a)
x✝ : ∀ (p : GHSpace) (t : Set (GHSpace.Rep p)), Set.Finite t → True
N : GHSpace → ℕ := fun p => N✝ p (s p) (_ : Set.Finite (s p))
E : (p : GHSpace) → ↑(s p) ≃ Fin (N✝ p (s p) (_ : Set.Finite (s p))) := fun p => e p (s p) (_ : Set.Finite (s p))
F : GHSpace → (n : ℕ) × (Fin n → Fin n → ℤ) :=
  fun p => { fst := N p, snd := fun a b => ⌊ε⁻¹ * dist ((E p).symm a) ((E p).symm b)⌋ }
⊢ ∃ β x F, ∀ (x y : GHSpace), F x = F y → dist x y ≤ δ

Next tactic:
refine' ⟨Σ n, Fin n → Fin n → ℤ, by infer_instance, F, fun p q hpq => _⟩