[GOAL]
X : Type u
inst✝² : MetricSpace X
inst✝¹ : CompactSpace X
inst✝ : Nonempty X
p : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
⊢ Quotient.mk IsometryRel.setoid p = toGHSpace X ↔ ∃ Ψ, Isometry Ψ ∧ range Ψ = ↑p
[PROOFSTEP]
simp only [toGHSpace, Quotient.eq]
[GOAL]
X : Type u
inst✝² : MetricSpace X
inst✝¹ : CompactSpace X
inst✝ : Nonempty X
p : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
⊢ p ≈ NonemptyCompacts.kuratowskiEmbedding X ↔ ∃ Ψ, Isometry Ψ ∧ range Ψ = ↑p
[PROOFSTEP]
refine' ⟨fun h => _, _⟩
[GOAL]
case refine'_1
X : Type u
inst✝² : MetricSpace X
inst✝¹ : CompactSpace X
inst✝ : Nonempty X
p : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
h : p ≈ NonemptyCompacts.kuratowskiEmbedding X
⊢ ∃ Ψ, Isometry Ψ ∧ range Ψ = ↑p
[PROOFSTEP]
rcases Setoid.symm h with ⟨e⟩
[GOAL]
case refine'_1.intro
X : Type u
inst✝² : MetricSpace X
inst✝¹ : CompactSpace X
inst✝ : Nonempty X
p : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
h : p ≈ NonemptyCompacts.kuratowskiEmbedding X
e : { x // x ∈ NonemptyCompacts.kuratowskiEmbedding X } ≃ᵢ { x // x ∈ p }
⊢ ∃ Ψ, Isometry Ψ ∧ range Ψ = ↑p
[PROOFSTEP]
have f := (kuratowskiEmbedding.isometry X).isometryEquivOnRange.trans e
[GOAL]
case refine'_1.intro
X : Type u
inst✝² : MetricSpace X
inst✝¹ : CompactSpace X
inst✝ : Nonempty X
p : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
h : p ≈ NonemptyCompacts.kuratowskiEmbedding X
e : { x // x ∈ NonemptyCompacts.kuratowskiEmbedding X } ≃ᵢ { x // x ∈ p }
f : X ≃ᵢ { x // x ∈ p }
⊢ ∃ Ψ, Isometry Ψ ∧ range Ψ = ↑p
[PROOFSTEP]
use fun x => f x, isometry_subtype_coe.comp f.isometry
[GOAL]
case right
X : Type u
inst✝² : MetricSpace X
inst✝¹ : CompactSpace X
inst✝ : Nonempty X
p : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
h : p ≈ NonemptyCompacts.kuratowskiEmbedding X
e : { x // x ∈ NonemptyCompacts.kuratowskiEmbedding X } ≃ᵢ { x // x ∈ p }
f : X ≃ᵢ { x // x ∈ p }
⊢ (range fun x => ↑(↑f x)) = ↑p
[PROOFSTEP]
erw [range_comp, f.range_eq_univ, Set.image_univ, Subtype.range_coe]
[GOAL]
case refine'_2
X : Type u
inst✝² : MetricSpace X
inst✝¹ : CompactSpace X
inst✝ : Nonempty X
p : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
⊢ (∃ Ψ, Isometry Ψ ∧ range Ψ = ↑p) → p ≈ NonemptyCompacts.kuratowskiEmbedding X
[PROOFSTEP]
rintro ⟨Ψ, ⟨isomΨ, rangeΨ⟩⟩
[GOAL]
case refine'_2.intro.intro
X : Type u
inst✝² : MetricSpace X
inst✝¹ : CompactSpace X
inst✝ : Nonempty X
p : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
isomΨ : Isometry Ψ
rangeΨ : range Ψ = ↑p
⊢ p ≈ NonemptyCompacts.kuratowskiEmbedding X
[PROOFSTEP]
have f := ((kuratowskiEmbedding.isometry X).isometryEquivOnRange.symm.trans isomΨ.isometryEquivOnRange).symm
[GOAL]
case refine'_2.intro.intro
X : Type u
inst✝² : MetricSpace X
inst✝¹ : CompactSpace X
inst✝ : Nonempty X
p : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
isomΨ : Isometry Ψ
rangeΨ : range Ψ = ↑p
f : ↑(range Ψ) ≃ᵢ ↑(range (kuratowskiEmbedding X))
⊢ p ≈ NonemptyCompacts.kuratowskiEmbedding X
[PROOFSTEP]
have E : (range Ψ ≃ᵢ NonemptyCompacts.kuratowskiEmbedding X) = (p ≃ᵢ range (kuratowskiEmbedding X)) := by
  dsimp only [NonemptyCompacts.kuratowskiEmbedding]; rw [rangeΨ]; rfl
[GOAL]
X : Type u
inst✝² : MetricSpace X
inst✝¹ : CompactSpace X
inst✝ : Nonempty X
p : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
isomΨ : Isometry Ψ
rangeΨ : range Ψ = ↑p
f : ↑(range Ψ) ≃ᵢ ↑(range (kuratowskiEmbedding X))
⊢ (↑(range Ψ) ≃ᵢ { x // x ∈ NonemptyCompacts.kuratowskiEmbedding X }) =
    ({ x // x ∈ p } ≃ᵢ ↑(range (kuratowskiEmbedding X)))
[PROOFSTEP]
dsimp only [NonemptyCompacts.kuratowskiEmbedding]
[GOAL]
X : Type u
inst✝² : MetricSpace X
inst✝¹ : CompactSpace X
inst✝ : Nonempty X
p : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
isomΨ : Isometry Ψ
rangeΨ : range Ψ = ↑p
f : ↑(range Ψ) ≃ᵢ ↑(range (kuratowskiEmbedding X))
⊢ (↑(range Ψ) ≃ᵢ
      { x //
        x ∈
          {
            toCompacts :=
              { carrier := range (kuratowskiEmbedding X),
                isCompact' := (_ : IsCompact (range (kuratowskiEmbedding X))) },
            nonempty' := (_ : Set.Nonempty (range fun y => kuratowskiEmbedding X y)) } }) =
    ({ x // x ∈ p } ≃ᵢ ↑(range (kuratowskiEmbedding X)))
[PROOFSTEP]
rw [rangeΨ]
[GOAL]
X : Type u
inst✝² : MetricSpace X
inst✝¹ : CompactSpace X
inst✝ : Nonempty X
p : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
isomΨ : Isometry Ψ
rangeΨ : range Ψ = ↑p
f : ↑(range Ψ) ≃ᵢ ↑(range (kuratowskiEmbedding X))
⊢ (↑↑p ≃ᵢ
      { x //
        x ∈
          {
            toCompacts :=
              { carrier := range (kuratowskiEmbedding X),
                isCompact' := (_ : IsCompact (range (kuratowskiEmbedding X))) },
            nonempty' := (_ : Set.Nonempty (range fun y => kuratowskiEmbedding X y)) } }) =
    ({ x // x ∈ p } ≃ᵢ ↑(range (kuratowskiEmbedding X)))
[PROOFSTEP]
rfl
[GOAL]
case refine'_2.intro.intro
X : Type u
inst✝² : MetricSpace X
inst✝¹ : CompactSpace X
inst✝ : Nonempty X
p : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
isomΨ : Isometry Ψ
rangeΨ : range Ψ = ↑p
f : ↑(range Ψ) ≃ᵢ ↑(range (kuratowskiEmbedding X))
E :
  (↑(range Ψ) ≃ᵢ { x // x ∈ NonemptyCompacts.kuratowskiEmbedding X }) =
    ({ x // x ∈ p } ≃ᵢ ↑(range (kuratowskiEmbedding X)))
⊢ p ≈ NonemptyCompacts.kuratowskiEmbedding X
[PROOFSTEP]
exact ⟨cast E f⟩
[GOAL]
p : GHSpace
⊢ toGHSpace (Rep p) = p
[PROOFSTEP]
change toGHSpace (Quot.out p : NonemptyCompacts ℓ_infty_ℝ) = p
[GOAL]
p : GHSpace
⊢ toGHSpace { x // x ∈ Quot.out p } = p
[PROOFSTEP]
rw [← eq_toGHSpace]
[GOAL]
p : GHSpace
⊢ Quotient.mk IsometryRel.setoid (Quot.out p) = p
[PROOFSTEP]
exact Quot.out_eq p
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
⊢ toGHSpace X = toGHSpace Y → Nonempty (X ≃ᵢ Y)
[PROOFSTEP]
simp only [toGHSpace]
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
⊢ Quotient.mk IsometryRel.setoid (NonemptyCompacts.kuratowskiEmbedding X) =
      Quotient.mk IsometryRel.setoid (NonemptyCompacts.kuratowskiEmbedding Y) →
    Nonempty (X ≃ᵢ Y)
[PROOFSTEP]
rw [Quotient.eq]
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
⊢ NonemptyCompacts.kuratowskiEmbedding X ≈ NonemptyCompacts.kuratowskiEmbedding Y → Nonempty (X ≃ᵢ Y)
[PROOFSTEP]
rintro ⟨e⟩
[GOAL]
case 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
e : { x // x ∈ NonemptyCompacts.kuratowskiEmbedding X } ≃ᵢ { x // x ∈ NonemptyCompacts.kuratowskiEmbedding Y }
⊢ Nonempty (X ≃ᵢ Y)
[PROOFSTEP]
have I :
  (NonemptyCompacts.kuratowskiEmbedding X ≃ᵢ NonemptyCompacts.kuratowskiEmbedding Y) =
    (range (kuratowskiEmbedding X) ≃ᵢ range (kuratowskiEmbedding Y)) :=
  by dsimp only [NonemptyCompacts.kuratowskiEmbedding]; rfl
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
e : { x // x ∈ NonemptyCompacts.kuratowskiEmbedding X } ≃ᵢ { x // x ∈ NonemptyCompacts.kuratowskiEmbedding Y }
⊢ ({ x // x ∈ NonemptyCompacts.kuratowskiEmbedding X } ≃ᵢ { x // x ∈ NonemptyCompacts.kuratowskiEmbedding Y }) =
    (↑(range (kuratowskiEmbedding X)) ≃ᵢ ↑(range (kuratowskiEmbedding Y)))
[PROOFSTEP]
dsimp only [NonemptyCompacts.kuratowskiEmbedding]
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
e : { x // x ∈ NonemptyCompacts.kuratowskiEmbedding X } ≃ᵢ { x // x ∈ NonemptyCompacts.kuratowskiEmbedding Y }
⊢ ({ x //
        x ∈
          {
            toCompacts :=
              { carrier := range (kuratowskiEmbedding X),
                isCompact' := (_ : IsCompact (range (kuratowskiEmbedding X))) },
            nonempty' := (_ : Set.Nonempty (range fun y => kuratowskiEmbedding X y)) } } ≃ᵢ
      { x //
        x ∈
          {
            toCompacts :=
              { carrier := range (kuratowskiEmbedding Y),
                isCompact' := (_ : IsCompact (range (kuratowskiEmbedding Y))) },
            nonempty' := (_ : Set.Nonempty (range fun y => kuratowskiEmbedding Y y)) } }) =
    (↑(range (kuratowskiEmbedding X)) ≃ᵢ ↑(range (kuratowskiEmbedding Y)))
[PROOFSTEP]
rfl
[GOAL]
case 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
e : { x // x ∈ NonemptyCompacts.kuratowskiEmbedding X } ≃ᵢ { x // x ∈ NonemptyCompacts.kuratowskiEmbedding Y }
I :
  ({ x // x ∈ NonemptyCompacts.kuratowskiEmbedding X } ≃ᵢ { x // x ∈ NonemptyCompacts.kuratowskiEmbedding Y }) =
    (↑(range (kuratowskiEmbedding X)) ≃ᵢ ↑(range (kuratowskiEmbedding Y)))
⊢ Nonempty (X ≃ᵢ Y)
[PROOFSTEP]
have f := (kuratowskiEmbedding.isometry X).isometryEquivOnRange
[GOAL]
case 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
e : { x // x ∈ NonemptyCompacts.kuratowskiEmbedding X } ≃ᵢ { x // x ∈ NonemptyCompacts.kuratowskiEmbedding Y }
I :
  ({ x // x ∈ NonemptyCompacts.kuratowskiEmbedding X } ≃ᵢ { x // x ∈ NonemptyCompacts.kuratowskiEmbedding Y }) =
    (↑(range (kuratowskiEmbedding X)) ≃ᵢ ↑(range (kuratowskiEmbedding Y)))
f : X ≃ᵢ ↑(range (kuratowskiEmbedding X))
⊢ Nonempty (X ≃ᵢ Y)
[PROOFSTEP]
have g := (kuratowskiEmbedding.isometry Y).isometryEquivOnRange.symm
[GOAL]
case 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
e : { x // x ∈ NonemptyCompacts.kuratowskiEmbedding X } ≃ᵢ { x // x ∈ NonemptyCompacts.kuratowskiEmbedding Y }
I :
  ({ x // x ∈ NonemptyCompacts.kuratowskiEmbedding X } ≃ᵢ { x // x ∈ NonemptyCompacts.kuratowskiEmbedding Y }) =
    (↑(range (kuratowskiEmbedding X)) ≃ᵢ ↑(range (kuratowskiEmbedding Y)))
f : X ≃ᵢ ↑(range (kuratowskiEmbedding X))
g : ↑(range (kuratowskiEmbedding Y)) ≃ᵢ Y
⊢ Nonempty (X ≃ᵢ Y)
[PROOFSTEP]
exact ⟨f.trans <| (cast I e).trans g⟩
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
⊢ Nonempty (X ≃ᵢ Y) → toGHSpace X = toGHSpace Y
[PROOFSTEP]
rintro ⟨e⟩
[GOAL]
case 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
e : X ≃ᵢ Y
⊢ toGHSpace X = toGHSpace Y
[PROOFSTEP]
simp only [toGHSpace, Quotient.eq']
[GOAL]
case 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
e : X ≃ᵢ Y
⊢ Quotient.mk IsometryRel.setoid (NonemptyCompacts.kuratowskiEmbedding X) =
    Quotient.mk IsometryRel.setoid (NonemptyCompacts.kuratowskiEmbedding Y)
[PROOFSTEP]
have f := (kuratowskiEmbedding.isometry X).isometryEquivOnRange.symm
[GOAL]
case 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
e : X ≃ᵢ Y
f : ↑(range (kuratowskiEmbedding X)) ≃ᵢ X
⊢ Quotient.mk IsometryRel.setoid (NonemptyCompacts.kuratowskiEmbedding X) =
    Quotient.mk IsometryRel.setoid (NonemptyCompacts.kuratowskiEmbedding Y)
[PROOFSTEP]
have g := (kuratowskiEmbedding.isometry Y).isometryEquivOnRange
[GOAL]
case 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
e : X ≃ᵢ Y
f : ↑(range (kuratowskiEmbedding X)) ≃ᵢ X
g : Y ≃ᵢ ↑(range (kuratowskiEmbedding Y))
⊢ Quotient.mk IsometryRel.setoid (NonemptyCompacts.kuratowskiEmbedding X) =
    Quotient.mk IsometryRel.setoid (NonemptyCompacts.kuratowskiEmbedding Y)
[PROOFSTEP]
have I :
  (range (kuratowskiEmbedding X) ≃ᵢ range (kuratowskiEmbedding Y)) =
    (NonemptyCompacts.kuratowskiEmbedding X ≃ᵢ NonemptyCompacts.kuratowskiEmbedding Y) :=
  by dsimp only [NonemptyCompacts.kuratowskiEmbedding]; rfl
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
e : X ≃ᵢ Y
f : ↑(range (kuratowskiEmbedding X)) ≃ᵢ X
g : Y ≃ᵢ ↑(range (kuratowskiEmbedding Y))
⊢ (↑(range (kuratowskiEmbedding X)) ≃ᵢ ↑(range (kuratowskiEmbedding Y))) =
    ({ x // x ∈ NonemptyCompacts.kuratowskiEmbedding X } ≃ᵢ { x // x ∈ NonemptyCompacts.kuratowskiEmbedding Y })
[PROOFSTEP]
dsimp only [NonemptyCompacts.kuratowskiEmbedding]
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
e : X ≃ᵢ Y
f : ↑(range (kuratowskiEmbedding X)) ≃ᵢ X
g : Y ≃ᵢ ↑(range (kuratowskiEmbedding Y))
⊢ (↑(range (kuratowskiEmbedding X)) ≃ᵢ ↑(range (kuratowskiEmbedding Y))) =
    ({ x //
        x ∈
          {
            toCompacts :=
              { carrier := range (kuratowskiEmbedding X),
                isCompact' := (_ : IsCompact (range (kuratowskiEmbedding X))) },
            nonempty' := (_ : Set.Nonempty (range fun y => kuratowskiEmbedding X y)) } } ≃ᵢ
      { x //
        x ∈
          {
            toCompacts :=
              { carrier := range (kuratowskiEmbedding Y),
                isCompact' := (_ : IsCompact (range (kuratowskiEmbedding Y))) },
            nonempty' := (_ : Set.Nonempty (range fun y => kuratowskiEmbedding Y y)) } })
[PROOFSTEP]
rfl
[GOAL]
case 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
e : X ≃ᵢ Y
f : ↑(range (kuratowskiEmbedding X)) ≃ᵢ X
g : Y ≃ᵢ ↑(range (kuratowskiEmbedding Y))
I :
  (↑(range (kuratowskiEmbedding X)) ≃ᵢ ↑(range (kuratowskiEmbedding Y))) =
    ({ x // x ∈ NonemptyCompacts.kuratowskiEmbedding X } ≃ᵢ { x // x ∈ NonemptyCompacts.kuratowskiEmbedding Y })
⊢ Quotient.mk IsometryRel.setoid (NonemptyCompacts.kuratowskiEmbedding X) =
    Quotient.mk IsometryRel.setoid (NonemptyCompacts.kuratowskiEmbedding Y)
[PROOFSTEP]
rw [Quotient.eq]
[GOAL]
case 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
e : X ≃ᵢ Y
f : ↑(range (kuratowskiEmbedding X)) ≃ᵢ X
g : Y ≃ᵢ ↑(range (kuratowskiEmbedding Y))
I :
  (↑(range (kuratowskiEmbedding X)) ≃ᵢ ↑(range (kuratowskiEmbedding Y))) =
    ({ x // x ∈ NonemptyCompacts.kuratowskiEmbedding X } ≃ᵢ { x // x ∈ NonemptyCompacts.kuratowskiEmbedding Y })
⊢ NonemptyCompacts.kuratowskiEmbedding X ≈ NonemptyCompacts.kuratowskiEmbedding Y
[PROOFSTEP]
exact ⟨cast I ((f.trans e).trans g)⟩
[GOAL]
p q : GHSpace
⊢ dist p q = ghDist (GHSpace.Rep p) (GHSpace.Rep q)
[PROOFSTEP]
rw [ghDist, p.toGHSpace_rep, q.toGHSpace_rep]
[GOAL]
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
⊢ ghDist X Y ≤ hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
rcases exists_mem_of_nonempty X with ⟨xX, _⟩
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
⊢ ghDist X Y ≤ hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
let s : Set γ := range Φ ∪ range Ψ
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
⊢ ghDist X Y ≤ hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
let Φ' : X → Subtype s := fun y => ⟨Φ y, mem_union_left _ (mem_range_self _)⟩
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
⊢ ghDist X Y ≤ hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
let Ψ' : Y → Subtype s := fun y => ⟨Ψ y, mem_union_right _ (mem_range_self _)⟩
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
⊢ ghDist X Y ≤ hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
have IΦ' : Isometry Φ' := fun x y => ha x y
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
⊢ ghDist X Y ≤ hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
have IΨ' : Isometry Ψ' := fun x y => hb x y
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
⊢ ghDist X Y ≤ hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
have : IsCompact s := (isCompact_range ha.continuous).union (isCompact_range hb.continuous)
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this : IsCompact s
⊢ ghDist X Y ≤ hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
letI : MetricSpace (Subtype s) := by infer_instance
[GOAL]
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this : IsCompact s
⊢ MetricSpace (Subtype s)
[PROOFSTEP]
infer_instance
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝ : IsCompact s
this : MetricSpace (Subtype s) := inferInstance
⊢ ghDist X Y ≤ hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
haveI : CompactSpace (Subtype s) := ⟨isCompact_iff_isCompact_univ.1 ‹IsCompact s›⟩
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝¹ : IsCompact s
this✝ : MetricSpace (Subtype s) := inferInstance
this : CompactSpace (Subtype s)
⊢ ghDist X Y ≤ hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
haveI : Nonempty (Subtype s) := ⟨Φ' xX⟩
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝² : IsCompact s
this✝¹ : MetricSpace (Subtype s) := inferInstance
this✝ : CompactSpace (Subtype s)
this : Nonempty (Subtype s)
⊢ ghDist X Y ≤ hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
have ΦΦ' : Φ = Subtype.val ∘ Φ' := by funext; rfl
[GOAL]
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝² : IsCompact s
this✝¹ : MetricSpace (Subtype s) := inferInstance
this✝ : CompactSpace (Subtype s)
this : Nonempty (Subtype s)
⊢ Φ = Subtype.val ∘ Φ'
[PROOFSTEP]
funext
[GOAL]
case h
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝² : IsCompact s
this✝¹ : MetricSpace (Subtype s) := inferInstance
this✝ : CompactSpace (Subtype s)
this : Nonempty (Subtype s)
x✝ : X
⊢ Φ x✝ = (Subtype.val ∘ Φ') x✝
[PROOFSTEP]
rfl
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝² : IsCompact s
this✝¹ : MetricSpace (Subtype s) := inferInstance
this✝ : CompactSpace (Subtype s)
this : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
⊢ ghDist X Y ≤ hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
have ΨΨ' : Ψ = Subtype.val ∘ Ψ' := by funext; rfl
[GOAL]
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝² : IsCompact s
this✝¹ : MetricSpace (Subtype s) := inferInstance
this✝ : CompactSpace (Subtype s)
this : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
⊢ Ψ = Subtype.val ∘ Ψ'
[PROOFSTEP]
funext
[GOAL]
case h
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝² : IsCompact s
this✝¹ : MetricSpace (Subtype s) := inferInstance
this✝ : CompactSpace (Subtype s)
this : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
x✝ : Y
⊢ Ψ x✝ = (Subtype.val ∘ Ψ') x✝
[PROOFSTEP]
rfl
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝² : IsCompact s
this✝¹ : MetricSpace (Subtype s) := inferInstance
this✝ : CompactSpace (Subtype s)
this : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
⊢ ghDist X Y ≤ hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
have : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ') :=
  by
  rw [ΦΦ', ΨΨ', range_comp, range_comp]
  exact hausdorffDist_image isometry_subtype_coe
[GOAL]
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝² : IsCompact s
this✝¹ : MetricSpace (Subtype s) := inferInstance
this✝ : CompactSpace (Subtype s)
this : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
⊢ hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
[PROOFSTEP]
rw [ΦΦ', ΨΨ', range_comp, range_comp]
[GOAL]
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝² : IsCompact s
this✝¹ : MetricSpace (Subtype s) := inferInstance
this✝ : CompactSpace (Subtype s)
this : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
⊢ hausdorffDist (Subtype.val '' range Φ') (Subtype.val '' range Ψ') = hausdorffDist (range Φ') (range Ψ')
[PROOFSTEP]
exact hausdorffDist_image isometry_subtype_coe
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝³ : IsCompact s
this✝² : MetricSpace (Subtype s) := inferInstance
this✝¹ : CompactSpace (Subtype s)
this✝ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
⊢ ghDist X Y ≤ hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
rw [this]
  -- Embed `s` in `ℓ^∞(ℝ)` through its Kuratowski embedding
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝³ : IsCompact s
this✝² : MetricSpace (Subtype s) := inferInstance
this✝¹ : CompactSpace (Subtype s)
this✝ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
⊢ ghDist X Y ≤ hausdorffDist (range Φ') (range Ψ')
[PROOFSTEP]
let F := kuratowskiEmbedding (Subtype s)
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝³ : IsCompact s
this✝² : MetricSpace (Subtype s) := inferInstance
this✝¹ : CompactSpace (Subtype s)
this✝ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
F : Subtype s → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (Subtype s)
⊢ ghDist X Y ≤ hausdorffDist (range Φ') (range Ψ')
[PROOFSTEP]
have : hausdorffDist (F '' range Φ') (F '' range Ψ') = hausdorffDist (range Φ') (range Ψ') :=
  hausdorffDist_image (kuratowskiEmbedding.isometry _)
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝⁴ : IsCompact s
this✝³ : MetricSpace (Subtype s) := inferInstance
this✝² : CompactSpace (Subtype s)
this✝¹ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this✝ : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
F : Subtype s → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (Subtype s)
this : hausdorffDist (F '' range Φ') (F '' range Ψ') = hausdorffDist (range Φ') (range Ψ')
⊢ ghDist X Y ≤ hausdorffDist (range Φ') (range Ψ')
[PROOFSTEP]
rw [← this]
  -- Let `A` and `B` be the images of `X` and `Y` under this embedding. They are in `ℓ^∞(ℝ)`, and
    -- their Hausdorff distance is the same as in the original space.
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝⁴ : IsCompact s
this✝³ : MetricSpace (Subtype s) := inferInstance
this✝² : CompactSpace (Subtype s)
this✝¹ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this✝ : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
F : Subtype s → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (Subtype s)
this : hausdorffDist (F '' range Φ') (F '' range Ψ') = hausdorffDist (range Φ') (range Ψ')
⊢ ghDist X Y ≤ hausdorffDist (F '' range Φ') (F '' range Ψ')
[PROOFSTEP]
let A : NonemptyCompacts ℓ_infty_ℝ :=
  ⟨⟨F '' range Φ', (isCompact_range IΦ'.continuous).image (kuratowskiEmbedding.isometry _).continuous⟩,
    (range_nonempty _).image _⟩
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝⁴ : IsCompact s
this✝³ : MetricSpace (Subtype s) := inferInstance
this✝² : CompactSpace (Subtype s)
this✝¹ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this✝ : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
F : Subtype s → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (Subtype s)
this : hausdorffDist (F '' range Φ') (F '' range Ψ') = hausdorffDist (range Φ') (range Ψ')
A : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Φ', isCompact' := (_ : IsCompact (F '' range Φ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Φ')) }
⊢ ghDist X Y ≤ hausdorffDist (F '' range Φ') (F '' range Ψ')
[PROOFSTEP]
let B : NonemptyCompacts ℓ_infty_ℝ :=
  ⟨⟨F '' range Ψ', (isCompact_range IΨ'.continuous).image (kuratowskiEmbedding.isometry _).continuous⟩,
    (range_nonempty _).image _⟩
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝⁴ : IsCompact s
this✝³ : MetricSpace (Subtype s) := inferInstance
this✝² : CompactSpace (Subtype s)
this✝¹ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this✝ : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
F : Subtype s → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (Subtype s)
this : hausdorffDist (F '' range Φ') (F '' range Ψ') = hausdorffDist (range Φ') (range Ψ')
A : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Φ', isCompact' := (_ : IsCompact (F '' range Φ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Φ')) }
B : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Ψ', isCompact' := (_ : IsCompact (F '' range Ψ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Ψ')) }
⊢ ghDist X Y ≤ hausdorffDist (F '' range Φ') (F '' range Ψ')
[PROOFSTEP]
have AX : ⟦A⟧ = toGHSpace X := by
  rw [eq_toGHSpace_iff]
  exact ⟨fun x => F (Φ' x), (kuratowskiEmbedding.isometry _).comp IΦ', range_comp _ _⟩
[GOAL]
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝⁴ : IsCompact s
this✝³ : MetricSpace (Subtype s) := inferInstance
this✝² : CompactSpace (Subtype s)
this✝¹ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this✝ : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
F : Subtype s → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (Subtype s)
this : hausdorffDist (F '' range Φ') (F '' range Ψ') = hausdorffDist (range Φ') (range Ψ')
A : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Φ', isCompact' := (_ : IsCompact (F '' range Φ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Φ')) }
B : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Ψ', isCompact' := (_ : IsCompact (F '' range Ψ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Ψ')) }
⊢ Quotient.mk IsometryRel.setoid A = toGHSpace X
[PROOFSTEP]
rw [eq_toGHSpace_iff]
[GOAL]
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝⁴ : IsCompact s
this✝³ : MetricSpace (Subtype s) := inferInstance
this✝² : CompactSpace (Subtype s)
this✝¹ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this✝ : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
F : Subtype s → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (Subtype s)
this : hausdorffDist (F '' range Φ') (F '' range Ψ') = hausdorffDist (range Φ') (range Ψ')
A : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Φ', isCompact' := (_ : IsCompact (F '' range Φ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Φ')) }
B : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Ψ', isCompact' := (_ : IsCompact (F '' range Ψ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Ψ')) }
⊢ ∃ Ψ, Isometry Ψ ∧ range Ψ = ↑A
[PROOFSTEP]
exact ⟨fun x => F (Φ' x), (kuratowskiEmbedding.isometry _).comp IΦ', range_comp _ _⟩
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝⁴ : IsCompact s
this✝³ : MetricSpace (Subtype s) := inferInstance
this✝² : CompactSpace (Subtype s)
this✝¹ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this✝ : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
F : Subtype s → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (Subtype s)
this : hausdorffDist (F '' range Φ') (F '' range Ψ') = hausdorffDist (range Φ') (range Ψ')
A : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Φ', isCompact' := (_ : IsCompact (F '' range Φ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Φ')) }
B : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Ψ', isCompact' := (_ : IsCompact (F '' range Ψ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Ψ')) }
AX : Quotient.mk IsometryRel.setoid A = toGHSpace X
⊢ ghDist X Y ≤ hausdorffDist (F '' range Φ') (F '' range Ψ')
[PROOFSTEP]
have BY : ⟦B⟧ = toGHSpace Y := by
  rw [eq_toGHSpace_iff]
  exact ⟨fun x => F (Ψ' x), (kuratowskiEmbedding.isometry _).comp IΨ', range_comp _ _⟩
[GOAL]
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝⁴ : IsCompact s
this✝³ : MetricSpace (Subtype s) := inferInstance
this✝² : CompactSpace (Subtype s)
this✝¹ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this✝ : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
F : Subtype s → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (Subtype s)
this : hausdorffDist (F '' range Φ') (F '' range Ψ') = hausdorffDist (range Φ') (range Ψ')
A : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Φ', isCompact' := (_ : IsCompact (F '' range Φ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Φ')) }
B : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Ψ', isCompact' := (_ : IsCompact (F '' range Ψ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Ψ')) }
AX : Quotient.mk IsometryRel.setoid A = toGHSpace X
⊢ Quotient.mk IsometryRel.setoid B = toGHSpace Y
[PROOFSTEP]
rw [eq_toGHSpace_iff]
[GOAL]
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝⁴ : IsCompact s
this✝³ : MetricSpace (Subtype s) := inferInstance
this✝² : CompactSpace (Subtype s)
this✝¹ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this✝ : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
F : Subtype s → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (Subtype s)
this : hausdorffDist (F '' range Φ') (F '' range Ψ') = hausdorffDist (range Φ') (range Ψ')
A : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Φ', isCompact' := (_ : IsCompact (F '' range Φ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Φ')) }
B : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Ψ', isCompact' := (_ : IsCompact (F '' range Ψ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Ψ')) }
AX : Quotient.mk IsometryRel.setoid A = toGHSpace X
⊢ ∃ Ψ, Isometry Ψ ∧ range Ψ = ↑B
[PROOFSTEP]
exact ⟨fun x => F (Ψ' x), (kuratowskiEmbedding.isometry _).comp IΨ', range_comp _ _⟩
[GOAL]
case 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
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝⁴ : IsCompact s
this✝³ : MetricSpace (Subtype s) := inferInstance
this✝² : CompactSpace (Subtype s)
this✝¹ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this✝ : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
F : Subtype s → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (Subtype s)
this : hausdorffDist (F '' range Φ') (F '' range Ψ') = hausdorffDist (range Φ') (range Ψ')
A : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Φ', isCompact' := (_ : IsCompact (F '' range Φ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Φ')) }
B : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Ψ', isCompact' := (_ : IsCompact (F '' range Ψ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Ψ')) }
AX : Quotient.mk IsometryRel.setoid A = toGHSpace X
BY : Quotient.mk IsometryRel.setoid B = toGHSpace Y
⊢ ghDist X Y ≤ hausdorffDist (F '' range Φ') (F '' range Ψ')
[PROOFSTEP]
refine' csInf_le ⟨0, _⟩ _
[GOAL]
case intro.refine'_1
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝⁴ : IsCompact s
this✝³ : MetricSpace (Subtype s) := inferInstance
this✝² : CompactSpace (Subtype s)
this✝¹ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this✝ : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
F : Subtype s → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (Subtype s)
this : hausdorffDist (F '' range Φ') (F '' range Ψ') = hausdorffDist (range Φ') (range Ψ')
A : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Φ', isCompact' := (_ : IsCompact (F '' range Φ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Φ')) }
B : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Ψ', isCompact' := (_ : IsCompact (F '' range Ψ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Ψ')) }
AX : Quotient.mk IsometryRel.setoid A = toGHSpace X
BY : Quotient.mk IsometryRel.setoid B = toGHSpace Y
⊢ 0 ∈
    lowerBounds
      ((fun p => hausdorffDist ↑p.fst ↑p.snd) ''
        {a | Quotient.mk IsometryRel.setoid a = toGHSpace X} ×ˢ {b | Quotient.mk IsometryRel.setoid b = toGHSpace Y})
[PROOFSTEP]
simp only [lowerBounds, mem_image, mem_prod, mem_setOf_eq, Prod.exists, and_imp, forall_exists_index]
[GOAL]
case intro.refine'_1
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝⁴ : IsCompact s
this✝³ : MetricSpace (Subtype s) := inferInstance
this✝² : CompactSpace (Subtype s)
this✝¹ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this✝ : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
F : Subtype s → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (Subtype s)
this : hausdorffDist (F '' range Φ') (F '' range Ψ') = hausdorffDist (range Φ') (range Ψ')
A : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Φ', isCompact' := (_ : IsCompact (F '' range Φ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Φ')) }
B : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Ψ', isCompact' := (_ : IsCompact (F '' range Ψ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Ψ')) }
AX : Quotient.mk IsometryRel.setoid A = toGHSpace X
BY : Quotient.mk IsometryRel.setoid B = toGHSpace Y
⊢ ∀ ⦃a : ℝ⦄ (x x_1 : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid x = toGHSpace X →
      Quotient.mk IsometryRel.setoid x_1 = toGHSpace Y → hausdorffDist ↑x ↑x_1 = a → 0 ≤ a
[PROOFSTEP]
intro t _ _ _ _ ht
[GOAL]
case intro.refine'_1
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝⁴ : IsCompact s
this✝³ : MetricSpace (Subtype s) := inferInstance
this✝² : CompactSpace (Subtype s)
this✝¹ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this✝ : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
F : Subtype s → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (Subtype s)
this : hausdorffDist (F '' range Φ') (F '' range Ψ') = hausdorffDist (range Φ') (range Ψ')
A : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Φ', isCompact' := (_ : IsCompact (F '' range Φ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Φ')) }
B : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Ψ', isCompact' := (_ : IsCompact (F '' range Ψ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Ψ')) }
AX : Quotient.mk IsometryRel.setoid A = toGHSpace X
BY : Quotient.mk IsometryRel.setoid B = toGHSpace Y
t : ℝ
x✝¹ x✝ : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
a✝¹ : Quotient.mk IsometryRel.setoid x✝¹ = toGHSpace X
a✝ : Quotient.mk IsometryRel.setoid x✝ = toGHSpace Y
ht : hausdorffDist ↑x✝¹ ↑x✝ = t
⊢ 0 ≤ t
[PROOFSTEP]
rw [← ht]
[GOAL]
case intro.refine'_1
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝⁴ : IsCompact s
this✝³ : MetricSpace (Subtype s) := inferInstance
this✝² : CompactSpace (Subtype s)
this✝¹ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this✝ : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
F : Subtype s → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (Subtype s)
this : hausdorffDist (F '' range Φ') (F '' range Ψ') = hausdorffDist (range Φ') (range Ψ')
A : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Φ', isCompact' := (_ : IsCompact (F '' range Φ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Φ')) }
B : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Ψ', isCompact' := (_ : IsCompact (F '' range Ψ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Ψ')) }
AX : Quotient.mk IsometryRel.setoid A = toGHSpace X
BY : Quotient.mk IsometryRel.setoid B = toGHSpace Y
t : ℝ
x✝¹ x✝ : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
a✝¹ : Quotient.mk IsometryRel.setoid x✝¹ = toGHSpace X
a✝ : Quotient.mk IsometryRel.setoid x✝ = toGHSpace Y
ht : hausdorffDist ↑x✝¹ ↑x✝ = t
⊢ 0 ≤ hausdorffDist ↑x✝¹ ↑x✝
[PROOFSTEP]
exact hausdorffDist_nonneg
[GOAL]
case intro.refine'_2
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝⁴ : IsCompact s
this✝³ : MetricSpace (Subtype s) := inferInstance
this✝² : CompactSpace (Subtype s)
this✝¹ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this✝ : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
F : Subtype s → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (Subtype s)
this : hausdorffDist (F '' range Φ') (F '' range Ψ') = hausdorffDist (range Φ') (range Ψ')
A : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Φ', isCompact' := (_ : IsCompact (F '' range Φ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Φ')) }
B : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Ψ', isCompact' := (_ : IsCompact (F '' range Ψ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Ψ')) }
AX : Quotient.mk IsometryRel.setoid A = toGHSpace X
BY : Quotient.mk IsometryRel.setoid B = toGHSpace Y
⊢ hausdorffDist (F '' range Φ') (F '' range Ψ') ∈
    (fun p => hausdorffDist ↑p.fst ↑p.snd) ''
      {a | Quotient.mk IsometryRel.setoid a = toGHSpace X} ×ˢ {b | Quotient.mk IsometryRel.setoid b = toGHSpace Y}
[PROOFSTEP]
apply (mem_image _ _ _).2
[GOAL]
case intro.refine'_2
X : Type u
inst✝⁶ : MetricSpace X
inst✝⁵ : CompactSpace X
inst✝⁴ : Nonempty X
Y : Type v
inst✝³ : MetricSpace Y
inst✝² : CompactSpace Y
inst✝¹ : Nonempty Y
γ : Type w
inst✝ : MetricSpace γ
Φ : X → γ
Ψ : Y → γ
ha : Isometry Φ
hb : Isometry Ψ
xX : X
h✝ : xX ∈ univ
s : Set γ := range Φ ∪ range Ψ
Φ' : X → Subtype s := fun y => { val := Φ y, property := (_ : Φ y ∈ range Φ ∪ range Ψ) }
Ψ' : Y → Subtype s := fun y => { val := Ψ y, property := (_ : Ψ y ∈ range Φ ∪ range Ψ) }
IΦ' : Isometry Φ'
IΨ' : Isometry Ψ'
this✝⁴ : IsCompact s
this✝³ : MetricSpace (Subtype s) := inferInstance
this✝² : CompactSpace (Subtype s)
this✝¹ : Nonempty (Subtype s)
ΦΦ' : Φ = Subtype.val ∘ Φ'
ΨΨ' : Ψ = Subtype.val ∘ Ψ'
this✝ : hausdorffDist (range Φ) (range Ψ) = hausdorffDist (range Φ') (range Ψ')
F : Subtype s → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (Subtype s)
this : hausdorffDist (F '' range Φ') (F '' range Ψ') = hausdorffDist (range Φ') (range Ψ')
A : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Φ', isCompact' := (_ : IsCompact (F '' range Φ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Φ')) }
B : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  { toCompacts := { carrier := F '' range Ψ', isCompact' := (_ : IsCompact (F '' range Ψ')) },
    nonempty' := (_ : Set.Nonempty ((fun a => F a) '' range Ψ')) }
AX : Quotient.mk IsometryRel.setoid A = toGHSpace X
BY : Quotient.mk IsometryRel.setoid B = toGHSpace Y
⊢ ∃ x,
    x ∈ {a | Quotient.mk IsometryRel.setoid a = toGHSpace X} ×ˢ {b | Quotient.mk IsometryRel.setoid b = toGHSpace Y} ∧
      hausdorffDist ↑x.fst ↑x.snd = hausdorffDist (F '' range Φ') (F '' range Ψ')
[PROOFSTEP]
exists (⟨A, B⟩ : NonemptyCompacts ℓ_infty_ℝ × NonemptyCompacts ℓ_infty_ℝ)
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) = ghDist X Y
[PROOFSTEP]
inhabit X
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h : Inhabited X
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) = ghDist X Y
[PROOFSTEP]
inhabit Y
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) = ghDist X Y
[PROOFSTEP]
have A :
  ∀ p q : NonemptyCompacts ℓ_infty_ℝ,
    ⟦p⟧ = toGHSpace X →
      ⟦q⟧ = toGHSpace Y →
        hausdorffDist (p : Set ℓ_infty_ℝ) q < diam (univ : Set X) + 1 + diam (univ : Set Y) →
          hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist (p : Set ℓ_infty_ℝ) q :=
  by
  intro p q hp hq bound
  rcases eq_toGHSpace_iff.1 hp with ⟨Φ, ⟨Φisom, Φrange⟩⟩
  rcases eq_toGHSpace_iff.1 hq with ⟨Ψ, ⟨Ψisom, Ψrange⟩⟩
  have I : diam (range Φ ∪ range Ψ) ≤ 2 * diam (univ : Set X) + 1 + 2 * diam (univ : Set Y) :=
    by
    rcases exists_mem_of_nonempty X with ⟨xX, _⟩
    have : ∃ y ∈ range Ψ, dist (Φ xX) y < diam (univ : Set X) + 1 + diam (univ : Set Y) :=
      by
      rw [Ψrange]
      have : Φ xX ∈ ↑p := Φrange.subst (mem_range_self _)
      exact
        exists_dist_lt_of_hausdorffDist_lt this bound
          (hausdorffEdist_ne_top_of_nonempty_of_bounded p.nonempty q.nonempty p.isCompact.bounded q.isCompact.bounded)
    rcases this with ⟨y, hy, dy⟩
    rcases mem_range.1 hy with ⟨z, hzy⟩
    rw [← hzy] at dy 
    have DΦ : diam (range Φ) = diam (univ : Set X) := Φisom.diam_range
    have DΨ : diam (range Ψ) = diam (univ : Set Y) := Ψisom.diam_range
    calc
      diam (range Φ ∪ range Ψ) ≤ diam (range Φ) + dist (Φ xX) (Ψ z) + diam (range Ψ) :=
        diam_union (mem_range_self _) (mem_range_self _)
      _ ≤ diam (univ : Set X) + (diam (univ : Set X) + 1 + diam (univ : Set Y)) + diam (univ : Set Y) :=
        by
        rw [DΦ, DΨ]
        gcongr
          -- apply add_le_add (add_le_add le_rfl (le_of_lt dy)) le_rfl
      _ = 2 * diam (univ : Set X) + 1 + 2 * diam (univ : Set Y) := by ring
  let f : Sum X Y → ℓ_infty_ℝ := fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
  let F : Sum X Y × Sum X Y → ℝ := fun p =>
    dist (f p.1)
      (f p.2)
        -- check that the induced "distance" is a candidate
  have Fgood : F ∈ candidates X Y :=
    by
    simp only [candidates, forall_const, and_true_iff, add_comm, eq_self_iff_true, dist_eq_zero, and_self_iff,
      Set.mem_setOf_eq]
    repeat' constructor
    ·
      exact fun x y =>
        calc
          F (inl x, inl y) = dist (Φ x) (Φ y) := rfl
          _ = dist x y := Φisom.dist_eq x y
    ·
      exact fun x y =>
        calc
          F (inr x, inr y) = dist (Ψ x) (Ψ y) := rfl
          _ = dist x y := Ψisom.dist_eq x y
    · exact fun x y => dist_comm _ _
    · exact fun x y z => dist_triangle _ _ _
    ·
      exact fun x y =>
        calc
          F (x, y) ≤ diam (range Φ ∪ range Ψ) :=
            by
            have A : ∀ z : Sum X Y, f z ∈ range Φ ∪ range Ψ :=
              by
              intro z
              cases z
              · apply mem_union_left; apply mem_range_self
              · apply mem_union_right; apply mem_range_self
            refine' dist_le_diam_of_mem _ (A _) (A _)
            rw [Φrange, Ψrange]
            exact (p ⊔ q).isCompact.bounded
          _ ≤ 2 * diam (univ : Set X) + 1 + 2 * diam (univ : Set Y) := I
  let Fb := candidatesBOfCandidates F Fgood
  have : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb :=
    hausdorffDist_optimal_le_HD _ _ (candidatesBOfCandidates_mem F Fgood)
  refine' le_trans this (le_of_forall_le_of_dense fun r hr => _)
  have I1 : ∀ x : X, (⨅ y, Fb (inl x, inr y)) ≤ r := by
    intro x
    have : f (inl x) ∈ ↑p := Φrange.subst (mem_range_self _)
    rcases exists_dist_lt_of_hausdorffDist_lt this hr
        (hausdorffEdist_ne_top_of_nonempty_of_bounded p.nonempty q.nonempty p.isCompact.bounded
          q.isCompact.bounded) with
      ⟨z, zq, hz⟩
    have : z ∈ range Ψ := by rwa [← Ψrange] at zq 
    rcases mem_range.1 this with ⟨y, hy⟩
    calc
      (⨅ y, Fb (inl x, inr y)) ≤ Fb (inl x, inr y) := ciInf_le (by simpa only [add_zero] using HD_below_aux1 0) y
      _ = dist (Φ x) (Ψ y) := rfl
      _ = dist (f (inl x)) z := by rw [hy]
      _ ≤ r := le_of_lt hz
  have I2 : ∀ y : Y, (⨅ x, Fb (inl x, inr y)) ≤ r := by
    intro y
    have : f (inr y) ∈ ↑q := Ψrange.subst (mem_range_self _)
    rcases exists_dist_lt_of_hausdorffDist_lt' this hr
        (hausdorffEdist_ne_top_of_nonempty_of_bounded p.nonempty q.nonempty p.isCompact.bounded
          q.isCompact.bounded) with
      ⟨z, zq, hz⟩
    have : z ∈ range Φ := by rwa [← Φrange] at zq 
    rcases mem_range.1 this with ⟨x, hx⟩
    calc
      (⨅ x, Fb (inl x, inr y)) ≤ Fb (inl x, inr y) := ciInf_le (by simpa only [add_zero] using HD_below_aux2 0) x
      _ = dist (Φ x) (Ψ y) := rfl
      _ = dist z (f (inr y)) := by rw [hx]
      _ ≤ r := le_of_lt hz
  simp only [HD, ciSup_le I1, ciSup_le I2, max_le_iff, and_self_iff]
    /- Get the same inequality for any coupling. If the coupling is quite good, the desired
        inequality has been proved above. If it is bad, then the inequality is obvious. -/
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
⊢ ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist ↑p ↑q < diam univ + 1 + diam univ →
          hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
[PROOFSTEP]
intro p q hp hq bound
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
[PROOFSTEP]
rcases eq_toGHSpace_iff.1 hp with ⟨Φ, ⟨Φisom, Φrange⟩⟩
[GOAL]
case 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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
[PROOFSTEP]
rcases eq_toGHSpace_iff.1 hq with ⟨Ψ, ⟨Ψisom, Ψrange⟩⟩
[GOAL]
case intro.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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
[PROOFSTEP]
have I : diam (range Φ ∪ range Ψ) ≤ 2 * diam (univ : Set X) + 1 + 2 * diam (univ : Set Y) :=
  by
  rcases exists_mem_of_nonempty X with ⟨xX, _⟩
  have : ∃ y ∈ range Ψ, dist (Φ xX) y < diam (univ : Set X) + 1 + diam (univ : Set Y) :=
    by
    rw [Ψrange]
    have : Φ xX ∈ ↑p := Φrange.subst (mem_range_self _)
    exact
      exists_dist_lt_of_hausdorffDist_lt this bound
        (hausdorffEdist_ne_top_of_nonempty_of_bounded p.nonempty q.nonempty p.isCompact.bounded q.isCompact.bounded)
  rcases this with ⟨y, hy, dy⟩
  rcases mem_range.1 hy with ⟨z, hzy⟩
  rw [← hzy] at dy 
  have DΦ : diam (range Φ) = diam (univ : Set X) := Φisom.diam_range
  have DΨ : diam (range Ψ) = diam (univ : Set Y) := Ψisom.diam_range
  calc
    diam (range Φ ∪ range Ψ) ≤ diam (range Φ) + dist (Φ xX) (Ψ z) + diam (range Ψ) :=
      diam_union (mem_range_self _) (mem_range_self _)
    _ ≤ diam (univ : Set X) + (diam (univ : Set X) + 1 + diam (univ : Set Y)) + diam (univ : Set Y) :=
      by
      rw [DΦ, DΨ]
      gcongr
        -- apply add_le_add (add_le_add le_rfl (le_of_lt dy)) le_rfl
    _ = 2 * diam (univ : Set X) + 1 + 2 * diam (univ : Set Y) := by ring
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
⊢ diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
[PROOFSTEP]
rcases exists_mem_of_nonempty X with ⟨xX, _⟩
[GOAL]
case 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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
xX : X
h✝ : xX ∈ univ
⊢ diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
[PROOFSTEP]
have : ∃ y ∈ range Ψ, dist (Φ xX) y < diam (univ : Set X) + 1 + diam (univ : Set Y) :=
  by
  rw [Ψrange]
  have : Φ xX ∈ ↑p := Φrange.subst (mem_range_self _)
  exact
    exists_dist_lt_of_hausdorffDist_lt this bound
      (hausdorffEdist_ne_top_of_nonempty_of_bounded p.nonempty q.nonempty p.isCompact.bounded q.isCompact.bounded)
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
xX : X
h✝ : xX ∈ univ
⊢ ∃ y, y ∈ range Ψ ∧ dist (Φ xX) y < diam univ + 1 + diam univ
[PROOFSTEP]
rw [Ψrange]
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
xX : X
h✝ : xX ∈ univ
⊢ ∃ y, y ∈ ↑q ∧ dist (Φ xX) y < diam univ + 1 + diam univ
[PROOFSTEP]
have : Φ xX ∈ ↑p := Φrange.subst (mem_range_self _)
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
xX : X
h✝ : xX ∈ univ
this : Φ xX ∈ ↑p
⊢ ∃ y, y ∈ ↑q ∧ dist (Φ xX) y < diam univ + 1 + diam univ
[PROOFSTEP]
exact
  exists_dist_lt_of_hausdorffDist_lt this bound
    (hausdorffEdist_ne_top_of_nonempty_of_bounded p.nonempty q.nonempty p.isCompact.bounded q.isCompact.bounded)
[GOAL]
case 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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
xX : X
h✝ : xX ∈ univ
this : ∃ y, y ∈ range Ψ ∧ dist (Φ xX) y < diam univ + 1 + diam univ
⊢ diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
[PROOFSTEP]
rcases this with ⟨y, hy, dy⟩
[GOAL]
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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
xX : X
h✝ : xX ∈ univ
y : { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : y ∈ range Ψ
dy : dist (Φ xX) y < diam univ + 1 + diam univ
⊢ diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
[PROOFSTEP]
rcases mem_range.1 hy with ⟨z, hzy⟩
[GOAL]
case intro.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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
xX : X
h✝ : xX ∈ univ
y : { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : y ∈ range Ψ
dy : dist (Φ xX) y < diam univ + 1 + diam univ
z : Y
hzy : Ψ z = y
⊢ diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
[PROOFSTEP]
rw [← hzy] at dy 
[GOAL]
case intro.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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
xX : X
h✝ : xX ∈ univ
y : { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : y ∈ range Ψ
z : Y
dy : dist (Φ xX) (Ψ z) < diam univ + 1 + diam univ
hzy : Ψ z = y
⊢ diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
[PROOFSTEP]
have DΦ : diam (range Φ) = diam (univ : Set X) := Φisom.diam_range
[GOAL]
case intro.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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
xX : X
h✝ : xX ∈ univ
y : { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : y ∈ range Ψ
z : Y
dy : dist (Φ xX) (Ψ z) < diam univ + 1 + diam univ
hzy : Ψ z = y
DΦ : diam (range Φ) = diam univ
⊢ diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
[PROOFSTEP]
have DΨ : diam (range Ψ) = diam (univ : Set Y) := Ψisom.diam_range
[GOAL]
case intro.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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
xX : X
h✝ : xX ∈ univ
y : { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : y ∈ range Ψ
z : Y
dy : dist (Φ xX) (Ψ z) < diam univ + 1 + diam univ
hzy : Ψ z = y
DΦ : diam (range Φ) = diam univ
DΨ : diam (range Ψ) = diam univ
⊢ diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
[PROOFSTEP]
calc
  diam (range Φ ∪ range Ψ) ≤ diam (range Φ) + dist (Φ xX) (Ψ z) + diam (range Ψ) :=
    diam_union (mem_range_self _) (mem_range_self _)
  _ ≤ diam (univ : Set X) + (diam (univ : Set X) + 1 + diam (univ : Set Y)) + diam (univ : Set Y) :=
    by
    rw [DΦ, DΨ]
    gcongr
      -- apply add_le_add (add_le_add le_rfl (le_of_lt dy)) le_rfl
  _ = 2 * diam (univ : Set X) + 1 + 2 * diam (univ : Set Y) := by ring
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
xX : X
h✝ : xX ∈ univ
y : { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : y ∈ range Ψ
z : Y
dy : dist (Φ xX) (Ψ z) < diam univ + 1 + diam univ
hzy : Ψ z = y
DΦ : diam (range Φ) = diam univ
DΨ : diam (range Ψ) = diam univ
⊢ diam (range Φ) + dist (Φ xX) (Ψ z) + diam (range Ψ) ≤ diam univ + (diam univ + 1 + diam univ) + diam univ
[PROOFSTEP]
rw [DΦ, DΨ]
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
xX : X
h✝ : xX ∈ univ
y : { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : y ∈ range Ψ
z : Y
dy : dist (Φ xX) (Ψ z) < diam univ + 1 + diam univ
hzy : Ψ z = y
DΦ : diam (range Φ) = diam univ
DΨ : diam (range Ψ) = diam univ
⊢ diam univ + dist (Φ xX) (Ψ z) + diam univ ≤ diam univ + (diam univ + 1 + diam univ) + diam univ
[PROOFSTEP]
gcongr
  -- apply add_le_add (add_le_add le_rfl (le_of_lt dy)) le_rfl
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
xX : X
h✝ : xX ∈ univ
y : { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : y ∈ range Ψ
z : Y
dy : dist (Φ xX) (Ψ z) < diam univ + 1 + diam univ
hzy : Ψ z = y
DΦ : diam (range Φ) = diam univ
DΨ : diam (range Ψ) = diam univ
⊢ diam univ + (diam univ + 1 + diam univ) + diam univ = 2 * diam univ + 1 + 2 * diam univ
[PROOFSTEP]
ring
[GOAL]
case intro.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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
[PROOFSTEP]
let f : Sum X Y → ℓ_infty_ℝ := fun x =>
  match x with
  | inl y => Φ y
  | inr z => Ψ z
[GOAL]
case intro.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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
[PROOFSTEP]
let F : Sum X Y × Sum X Y → ℝ := fun p =>
  dist (f p.1)
    (f p.2)
      -- check that the induced "distance" is a candidate
[GOAL]
case intro.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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
[PROOFSTEP]
have Fgood : F ∈ candidates X Y :=
  by
  simp only [candidates, forall_const, and_true_iff, add_comm, eq_self_iff_true, dist_eq_zero, and_self_iff,
    Set.mem_setOf_eq]
  repeat' constructor
  ·
    exact fun x y =>
      calc
        F (inl x, inl y) = dist (Φ x) (Φ y) := rfl
        _ = dist x y := Φisom.dist_eq x y
  ·
    exact fun x y =>
      calc
        F (inr x, inr y) = dist (Ψ x) (Ψ y) := rfl
        _ = dist x y := Ψisom.dist_eq x y
  · exact fun x y => dist_comm _ _
  · exact fun x y z => dist_triangle _ _ _
  ·
    exact fun x y =>
      calc
        F (x, y) ≤ diam (range Φ ∪ range Ψ) :=
          by
          have A : ∀ z : Sum X Y, f z ∈ range Φ ∪ range Ψ := by
            intro z
            cases z
            · apply mem_union_left; apply mem_range_self
            · apply mem_union_right; apply mem_range_self
          refine' dist_le_diam_of_mem _ (A _) (A _)
          rw [Φrange, Ψrange]
          exact (p ⊔ q).isCompact.bounded
        _ ≤ 2 * diam (univ : Set X) + 1 + 2 * diam (univ : Set Y) := I
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
⊢ F ∈ candidates X Y
[PROOFSTEP]
simp only [candidates, forall_const, and_true_iff, add_comm, eq_self_iff_true, dist_eq_zero, and_self_iff,
  Set.mem_setOf_eq]
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
⊢ ((((∀ (x y : X), dist (Φ x) (Φ y) = dist x y) ∧ ∀ (x y : Y), dist (Ψ x) (Ψ y) = dist x y) ∧
        ∀ (x y : X ⊕ Y),
          dist
              (match x with
              | inl y => Φ y
              | inr z => Ψ z)
              (match y with
              | inl y => Φ y
              | inr z => Ψ z) =
            dist
              (match y with
              | inl y => Φ y
              | inr z => Ψ z)
              (match x with
              | inl y => Φ y
              | inr z => Ψ z)) ∧
      ∀ (x y z : X ⊕ Y),
        dist
            (match x with
            | inl y => Φ y
            | inr z => Ψ z)
            (match z with
            | inl y => Φ y
            | inr z => Ψ z) ≤
          dist
              (match x with
              | inl y => Φ y
              | inr z => Ψ z)
              (match y with
              | inl y => Φ y
              | inr z => Ψ z) +
            dist
              (match y with
              | inl y => Φ y
              | inr z => Ψ z)
              (match z with
              | inl y => Φ y
              | inr z => Ψ z)) ∧
    ∀ (x y : X ⊕ Y),
      dist
          (match x with
          | inl y => Φ y
          | inr z => Ψ z)
          (match y with
          | inl y => Φ y
          | inr z => Ψ z) ≤
        ↑(GromovHausdorff.maxVar X Y)
[PROOFSTEP]
repeat' constructor
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
⊢ ((((∀ (x y : X), dist (Φ x) (Φ y) = dist x y) ∧ ∀ (x y : Y), dist (Ψ x) (Ψ y) = dist x y) ∧
        ∀ (x y : X ⊕ Y),
          dist
              (match x with
              | inl y => Φ y
              | inr z => Ψ z)
              (match y with
              | inl y => Φ y
              | inr z => Ψ z) =
            dist
              (match y with
              | inl y => Φ y
              | inr z => Ψ z)
              (match x with
              | inl y => Φ y
              | inr z => Ψ z)) ∧
      ∀ (x y z : X ⊕ Y),
        dist
            (match x with
            | inl y => Φ y
            | inr z => Ψ z)
            (match z with
            | inl y => Φ y
            | inr z => Ψ z) ≤
          dist
              (match x with
              | inl y => Φ y
              | inr z => Ψ z)
              (match y with
              | inl y => Φ y
              | inr z => Ψ z) +
            dist
              (match y with
              | inl y => Φ y
              | inr z => Ψ z)
              (match z with
              | inl y => Φ y
              | inr z => Ψ z)) ∧
    ∀ (x y : X ⊕ Y),
      dist
          (match x with
          | inl y => Φ y
          | inr z => Ψ z)
          (match y with
          | inl y => Φ y
          | inr z => Ψ z) ≤
        ↑(GromovHausdorff.maxVar X Y)
[PROOFSTEP]
constructor
[GOAL]
case left
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
⊢ (((∀ (x y : X), dist (Φ x) (Φ y) = dist x y) ∧ ∀ (x y : Y), dist (Ψ x) (Ψ y) = dist x y) ∧
      ∀ (x y : X ⊕ Y),
        dist
            (match x with
            | inl y => Φ y
            | inr z => Ψ z)
            (match y with
            | inl y => Φ y
            | inr z => Ψ z) =
          dist
            (match y with
            | inl y => Φ y
            | inr z => Ψ z)
            (match x with
            | inl y => Φ y
            | inr z => Ψ z)) ∧
    ∀ (x y z : X ⊕ Y),
      dist
          (match x with
          | inl y => Φ y
          | inr z => Ψ z)
          (match z with
          | inl y => Φ y
          | inr z => Ψ z) ≤
        dist
            (match x with
            | inl y => Φ y
            | inr z => Ψ z)
            (match y with
            | inl y => Φ y
            | inr z => Ψ z) +
          dist
            (match y with
            | inl y => Φ y
            | inr z => Ψ z)
            (match z with
            | inl y => Φ y
            | inr z => Ψ z)
[PROOFSTEP]
constructor
[GOAL]
case left.left
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
⊢ ((∀ (x y : X), dist (Φ x) (Φ y) = dist x y) ∧ ∀ (x y : Y), dist (Ψ x) (Ψ y) = dist x y) ∧
    ∀ (x y : X ⊕ Y),
      dist
          (match x with
          | inl y => Φ y
          | inr z => Ψ z)
          (match y with
          | inl y => Φ y
          | inr z => Ψ z) =
        dist
          (match y with
          | inl y => Φ y
          | inr z => Ψ z)
          (match x with
          | inl y => Φ y
          | inr z => Ψ z)
[PROOFSTEP]
constructor
[GOAL]
case left.left.left
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
⊢ (∀ (x y : X), dist (Φ x) (Φ y) = dist x y) ∧ ∀ (x y : Y), dist (Ψ x) (Ψ y) = dist x y
[PROOFSTEP]
constructor
[GOAL]
case left.left.left.left
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
⊢ ∀ (x y : X), dist (Φ x) (Φ y) = dist x y
[PROOFSTEP]
constructor
[GOAL]
case left.left.left.right
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
⊢ ∀ (x y : Y), dist (Ψ x) (Ψ y) = dist x y
[PROOFSTEP]
constructor
[GOAL]
case left.left.right
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
⊢ ∀ (x y : X ⊕ Y),
    dist
        (match x with
        | inl y => Φ y
        | inr z => Ψ z)
        (match y with
        | inl y => Φ y
        | inr z => Ψ z) =
      dist
        (match y with
        | inl y => Φ y
        | inr z => Ψ z)
        (match x with
        | inl y => Φ y
        | inr z => Ψ z)
[PROOFSTEP]
constructor
[GOAL]
case left.right
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
⊢ ∀ (x y z : X ⊕ Y),
    dist
        (match x with
        | inl y => Φ y
        | inr z => Ψ z)
        (match z with
        | inl y => Φ y
        | inr z => Ψ z) ≤
      dist
          (match x with
          | inl y => Φ y
          | inr z => Ψ z)
          (match y with
          | inl y => Φ y
          | inr z => Ψ z) +
        dist
          (match y with
          | inl y => Φ y
          | inr z => Ψ z)
          (match z with
          | inl y => Φ y
          | inr z => Ψ z)
[PROOFSTEP]
constructor
[GOAL]
case right
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
⊢ ∀ (x y : X ⊕ Y),
    dist
        (match x with
        | inl y => Φ y
        | inr z => Ψ z)
        (match y with
        | inl y => Φ y
        | inr z => Ψ z) ≤
      ↑(GromovHausdorff.maxVar X Y)
[PROOFSTEP]
constructor
[GOAL]
case left.left.left.left
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
⊢ ∀ (x y : X), dist (Φ x) (Φ y) = dist x y
[PROOFSTEP]
exact fun x y =>
  calc
    F (inl x, inl y) = dist (Φ x) (Φ y) := rfl
    _ = dist x y := Φisom.dist_eq x y
[GOAL]
case left.left.left.right
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
⊢ ∀ (x y : Y), dist (Ψ x) (Ψ y) = dist x y
[PROOFSTEP]
exact fun x y =>
  calc
    F (inr x, inr y) = dist (Ψ x) (Ψ y) := rfl
    _ = dist x y := Ψisom.dist_eq x y
[GOAL]
case left.left.right
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
⊢ ∀ (x y : X ⊕ Y),
    dist
        (match x with
        | inl y => Φ y
        | inr z => Ψ z)
        (match y with
        | inl y => Φ y
        | inr z => Ψ z) =
      dist
        (match y with
        | inl y => Φ y
        | inr z => Ψ z)
        (match x with
        | inl y => Φ y
        | inr z => Ψ z)
[PROOFSTEP]
exact fun x y => dist_comm _ _
[GOAL]
case left.right
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
⊢ ∀ (x y z : X ⊕ Y),
    dist
        (match x with
        | inl y => Φ y
        | inr z => Ψ z)
        (match z with
        | inl y => Φ y
        | inr z => Ψ z) ≤
      dist
          (match x with
          | inl y => Φ y
          | inr z => Ψ z)
          (match y with
          | inl y => Φ y
          | inr z => Ψ z) +
        dist
          (match y with
          | inl y => Φ y
          | inr z => Ψ z)
          (match z with
          | inl y => Φ y
          | inr z => Ψ z)
[PROOFSTEP]
exact fun x y z => dist_triangle _ _ _
[GOAL]
case right
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
⊢ ∀ (x y : X ⊕ Y),
    dist
        (match x with
        | inl y => Φ y
        | inr z => Ψ z)
        (match y with
        | inl y => Φ y
        | inr z => Ψ z) ≤
      ↑(GromovHausdorff.maxVar X Y)
[PROOFSTEP]
exact fun x y =>
  calc
    F (x, y) ≤ diam (range Φ ∪ range Ψ) :=
      by
      have A : ∀ z : Sum X Y, f z ∈ range Φ ∪ range Ψ := by
        intro z
        cases z
        · apply mem_union_left; apply mem_range_self
        · apply mem_union_right; apply mem_range_self
      refine' dist_le_diam_of_mem _ (A _) (A _)
      rw [Φrange, Ψrange]
      exact (p ⊔ q).isCompact.bounded
    _ ≤ 2 * diam (univ : Set X) + 1 + 2 * diam (univ : Set Y) := I
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
x y : X ⊕ Y
⊢ F (x, y) ≤ diam (range Φ ∪ range Ψ)
[PROOFSTEP]
have A : ∀ z : Sum X Y, f z ∈ range Φ ∪ range Ψ := by
  intro z
  cases z
  · apply mem_union_left; apply mem_range_self
  · apply mem_union_right; apply mem_range_self
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
x y : X ⊕ Y
⊢ ∀ (z : X ⊕ Y), f z ∈ range Φ ∪ range Ψ
[PROOFSTEP]
intro z
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
x y z : X ⊕ Y
⊢ f z ∈ range Φ ∪ range Ψ
[PROOFSTEP]
cases z
[GOAL]
case inl
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
x y : X ⊕ Y
val✝ : X
⊢ f (inl val✝) ∈ range Φ ∪ range Ψ
[PROOFSTEP]
apply mem_union_left
[GOAL]
case inl.a
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
x y : X ⊕ Y
val✝ : X
⊢ f (inl val✝) ∈ range Φ
[PROOFSTEP]
apply mem_range_self
[GOAL]
case inr
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
x y : X ⊕ Y
val✝ : Y
⊢ f (inr val✝) ∈ range Φ ∪ range Ψ
[PROOFSTEP]
apply mem_union_right
[GOAL]
case inr.a
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
x y : X ⊕ Y
val✝ : Y
⊢ f (inr val✝) ∈ range Ψ
[PROOFSTEP]
apply mem_range_self
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
x y : X ⊕ Y
A : ∀ (z : X ⊕ Y), f z ∈ range Φ ∪ range Ψ
⊢ F (x, y) ≤ diam (range Φ ∪ range Ψ)
[PROOFSTEP]
refine' dist_le_diam_of_mem _ (A _) (A _)
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
x y : X ⊕ Y
A : ∀ (z : X ⊕ Y), f z ∈ range Φ ∪ range Ψ
⊢ Metric.Bounded (range Φ ∪ range Ψ)
[PROOFSTEP]
rw [Φrange, Ψrange]
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
x y : X ⊕ Y
A : ∀ (z : X ⊕ Y), f z ∈ range Φ ∪ range Ψ
⊢ Metric.Bounded (↑p ∪ ↑q)
[PROOFSTEP]
exact (p ⊔ q).isCompact.bounded
[GOAL]
case intro.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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
[PROOFSTEP]
let Fb := candidatesBOfCandidates F Fgood
[GOAL]
case intro.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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
[PROOFSTEP]
have : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb :=
  hausdorffDist_optimal_le_HD _ _ (candidatesBOfCandidates_mem F Fgood)
[GOAL]
case intro.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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
[PROOFSTEP]
refine' le_trans this (le_of_forall_le_of_dense fun r hr => _)
[GOAL]
case intro.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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
⊢ HD Fb ≤ r
[PROOFSTEP]
have I1 : ∀ x : X, (⨅ y, Fb (inl x, inr y)) ≤ r := by
  intro x
  have : f (inl x) ∈ ↑p := Φrange.subst (mem_range_self _)
  rcases exists_dist_lt_of_hausdorffDist_lt this hr
      (hausdorffEdist_ne_top_of_nonempty_of_bounded p.nonempty q.nonempty p.isCompact.bounded q.isCompact.bounded) with
    ⟨z, zq, hz⟩
  have : z ∈ range Ψ := by rwa [← Ψrange] at zq 
  rcases mem_range.1 this with ⟨y, hy⟩
  calc
    (⨅ y, Fb (inl x, inr y)) ≤ Fb (inl x, inr y) := ciInf_le (by simpa only [add_zero] using HD_below_aux1 0) y
    _ = dist (Φ x) (Ψ y) := rfl
    _ = dist (f (inl x)) z := by rw [hy]
    _ ≤ r := le_of_lt hz
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
⊢ ∀ (x : X), ⨅ (y : Y), ↑Fb (inl x, inr y) ≤ r
[PROOFSTEP]
intro x
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
x : X
⊢ ⨅ (y : Y), ↑Fb (inl x, inr y) ≤ r
[PROOFSTEP]
have : f (inl x) ∈ ↑p := Φrange.subst (mem_range_self _)
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this✝ : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
x : X
this : f (inl x) ∈ ↑p
⊢ ⨅ (y : Y), ↑Fb (inl x, inr y) ≤ r
[PROOFSTEP]
rcases exists_dist_lt_of_hausdorffDist_lt this hr
    (hausdorffEdist_ne_top_of_nonempty_of_bounded p.nonempty q.nonempty p.isCompact.bounded q.isCompact.bounded) with
  ⟨z, zq, hz⟩
[GOAL]
case 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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this✝ : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
x : X
this : f (inl x) ∈ ↑p
z : { x // x ∈ lp (fun n => ℝ) ⊤ }
zq : z ∈ ↑q
hz : dist (f (inl x)) z < r
⊢ ⨅ (y : Y), ↑Fb (inl x, inr y) ≤ r
[PROOFSTEP]
have : z ∈ range Ψ := by rwa [← Ψrange] at zq 
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this✝ : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
x : X
this : f (inl x) ∈ ↑p
z : { x // x ∈ lp (fun n => ℝ) ⊤ }
zq : z ∈ ↑q
hz : dist (f (inl x)) z < r
⊢ z ∈ range Ψ
[PROOFSTEP]
rwa [← Ψrange] at zq 
[GOAL]
case 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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this✝¹ : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
x : X
this✝ : f (inl x) ∈ ↑p
z : { x // x ∈ lp (fun n => ℝ) ⊤ }
zq : z ∈ ↑q
hz : dist (f (inl x)) z < r
this : z ∈ range Ψ
⊢ ⨅ (y : Y), ↑Fb (inl x, inr y) ≤ r
[PROOFSTEP]
rcases mem_range.1 this with ⟨y, hy⟩
[GOAL]
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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this✝¹ : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
x : X
this✝ : f (inl x) ∈ ↑p
z : { x // x ∈ lp (fun n => ℝ) ⊤ }
zq : z ∈ ↑q
hz : dist (f (inl x)) z < r
this : z ∈ range Ψ
y : Y
hy : Ψ y = z
⊢ ⨅ (y : Y), ↑Fb (inl x, inr y) ≤ r
[PROOFSTEP]
calc
  (⨅ y, Fb (inl x, inr y)) ≤ Fb (inl x, inr y) := ciInf_le (by simpa only [add_zero] using HD_below_aux1 0) y
  _ = dist (Φ x) (Ψ y) := rfl
  _ = dist (f (inl x)) z := by rw [hy]
  _ ≤ r := le_of_lt hz
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this✝¹ : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
x : X
this✝ : f (inl x) ∈ ↑p
z : { x // x ∈ lp (fun n => ℝ) ⊤ }
zq : z ∈ ↑q
hz : dist (f (inl x)) z < r
this : z ∈ range Ψ
y : Y
hy : Ψ y = z
⊢ BddBelow (range fun y => ↑Fb (inl x, inr y))
[PROOFSTEP]
simpa only [add_zero] using HD_below_aux1 0
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this✝¹ : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
x : X
this✝ : f (inl x) ∈ ↑p
z : { x // x ∈ lp (fun n => ℝ) ⊤ }
zq : z ∈ ↑q
hz : dist (f (inl x)) z < r
this : z ∈ range Ψ
y : Y
hy : Ψ y = z
⊢ dist (Φ x) (Ψ y) = dist (f (inl x)) z
[PROOFSTEP]
rw [hy]
[GOAL]
case intro.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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
I1 : ∀ (x : X), ⨅ (y : Y), ↑Fb (inl x, inr y) ≤ r
⊢ HD Fb ≤ r
[PROOFSTEP]
have I2 : ∀ y : Y, (⨅ x, Fb (inl x, inr y)) ≤ r := by
  intro y
  have : f (inr y) ∈ ↑q := Ψrange.subst (mem_range_self _)
  rcases exists_dist_lt_of_hausdorffDist_lt' this hr
      (hausdorffEdist_ne_top_of_nonempty_of_bounded p.nonempty q.nonempty p.isCompact.bounded q.isCompact.bounded) with
    ⟨z, zq, hz⟩
  have : z ∈ range Φ := by rwa [← Φrange] at zq 
  rcases mem_range.1 this with ⟨x, hx⟩
  calc
    (⨅ x, Fb (inl x, inr y)) ≤ Fb (inl x, inr y) := ciInf_le (by simpa only [add_zero] using HD_below_aux2 0) x
    _ = dist (Φ x) (Ψ y) := rfl
    _ = dist z (f (inr y)) := by rw [hx]
    _ ≤ r := le_of_lt hz
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
I1 : ∀ (x : X), ⨅ (y : Y), ↑Fb (inl x, inr y) ≤ r
⊢ ∀ (y : Y), ⨅ (x : X), ↑Fb (inl x, inr y) ≤ r
[PROOFSTEP]
intro y
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
I1 : ∀ (x : X), ⨅ (y : Y), ↑Fb (inl x, inr y) ≤ r
y : Y
⊢ ⨅ (x : X), ↑Fb (inl x, inr y) ≤ r
[PROOFSTEP]
have : f (inr y) ∈ ↑q := Ψrange.subst (mem_range_self _)
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this✝ : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
I1 : ∀ (x : X), ⨅ (y : Y), ↑Fb (inl x, inr y) ≤ r
y : Y
this : f (inr y) ∈ ↑q
⊢ ⨅ (x : X), ↑Fb (inl x, inr y) ≤ r
[PROOFSTEP]
rcases exists_dist_lt_of_hausdorffDist_lt' this hr
    (hausdorffEdist_ne_top_of_nonempty_of_bounded p.nonempty q.nonempty p.isCompact.bounded q.isCompact.bounded) with
  ⟨z, zq, hz⟩
[GOAL]
case 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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this✝ : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
I1 : ∀ (x : X), ⨅ (y : Y), ↑Fb (inl x, inr y) ≤ r
y : Y
this : f (inr y) ∈ ↑q
z : { x // x ∈ lp (fun n => ℝ) ⊤ }
zq : z ∈ ↑p
hz : dist z (f (inr y)) < r
⊢ ⨅ (x : X), ↑Fb (inl x, inr y) ≤ r
[PROOFSTEP]
have : z ∈ range Φ := by rwa [← Φrange] at zq 
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this✝ : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
I1 : ∀ (x : X), ⨅ (y : Y), ↑Fb (inl x, inr y) ≤ r
y : Y
this : f (inr y) ∈ ↑q
z : { x // x ∈ lp (fun n => ℝ) ⊤ }
zq : z ∈ ↑p
hz : dist z (f (inr y)) < r
⊢ z ∈ range Φ
[PROOFSTEP]
rwa [← Φrange] at zq 
[GOAL]
case 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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this✝¹ : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
I1 : ∀ (x : X), ⨅ (y : Y), ↑Fb (inl x, inr y) ≤ r
y : Y
this✝ : f (inr y) ∈ ↑q
z : { x // x ∈ lp (fun n => ℝ) ⊤ }
zq : z ∈ ↑p
hz : dist z (f (inr y)) < r
this : z ∈ range Φ
⊢ ⨅ (x : X), ↑Fb (inl x, inr y) ≤ r
[PROOFSTEP]
rcases mem_range.1 this with ⟨x, hx⟩
[GOAL]
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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this✝¹ : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
I1 : ∀ (x : X), ⨅ (y : Y), ↑Fb (inl x, inr y) ≤ r
y : Y
this✝ : f (inr y) ∈ ↑q
z : { x // x ∈ lp (fun n => ℝ) ⊤ }
zq : z ∈ ↑p
hz : dist z (f (inr y)) < r
this : z ∈ range Φ
x : X
hx : Φ x = z
⊢ ⨅ (x : X), ↑Fb (inl x, inr y) ≤ r
[PROOFSTEP]
calc
  (⨅ x, Fb (inl x, inr y)) ≤ Fb (inl x, inr y) := ciInf_le (by simpa only [add_zero] using HD_below_aux2 0) x
  _ = dist (Φ x) (Ψ y) := rfl
  _ = dist z (f (inr y)) := by rw [hx]
  _ ≤ r := le_of_lt hz
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this✝¹ : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
I1 : ∀ (x : X), ⨅ (y : Y), ↑Fb (inl x, inr y) ≤ r
y : Y
this✝ : f (inr y) ∈ ↑q
z : { x // x ∈ lp (fun n => ℝ) ⊤ }
zq : z ∈ ↑p
hz : dist z (f (inr y)) < r
this : z ∈ range Φ
x : X
hx : Φ x = z
⊢ BddBelow (range fun x => ↑Fb (inl x, inr y))
[PROOFSTEP]
simpa only [add_zero] using HD_below_aux2 0
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this✝¹ : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
I1 : ∀ (x : X), ⨅ (y : Y), ↑Fb (inl x, inr y) ≤ r
y : Y
this✝ : f (inr y) ∈ ↑q
z : { x // x ∈ lp (fun n => ℝ) ⊤ }
zq : z ∈ ↑p
hz : dist z (f (inr y)) < r
this : z ∈ range Φ
x : X
hx : Φ x = z
⊢ dist (Φ x) (Ψ y) = dist z (f (inr y))
[PROOFSTEP]
rw [hx]
[GOAL]
case intro.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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
bound : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
Φ : X → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Φrange : range Φ = ↑p
Ψ : Y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψisom : Isometry Ψ
Ψrange : range Ψ = ↑q
I : diam (range Φ ∪ range Ψ) ≤ 2 * diam univ + 1 + 2 * diam univ
f : X ⊕ Y → { x // x ∈ lp (fun n => ℝ) ⊤ } :=
  fun x =>
    match x with
    | inl y => Φ y
    | inr z => Ψ z
F : (X ⊕ Y) × (X ⊕ Y) → ℝ := fun p => dist (f p.fst) (f p.snd)
Fgood : F ∈ candidates X Y
Fb : GromovHausdorff.Cb X Y := candidatesBOfCandidates F Fgood
this : hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD Fb
r : ℝ
hr : hausdorffDist ↑p ↑q < r
I1 : ∀ (x : X), ⨅ (y : Y), ↑Fb (inl x, inr y) ≤ r
I2 : ∀ (y : Y), ⨅ (x : X), ↑Fb (inl x, inr y) ≤ r
⊢ HD Fb ≤ r
[PROOFSTEP]
simp only [HD, ciSup_le I1, ciSup_le I2, max_le_iff, and_self_iff]
  /- Get the same inequality for any coupling. If the coupling is quite good, the desired
      inequality has been proved above. If it is bad, then the inequality is obvious. -/
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
A :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist ↑p ↑q < diam univ + 1 + diam univ →
          hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) = ghDist X Y
[PROOFSTEP]
have B :
  ∀ p q : NonemptyCompacts ℓ_infty_ℝ,
    ⟦p⟧ = toGHSpace X →
      ⟦q⟧ = toGHSpace Y →
        hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist (p : Set ℓ_infty_ℝ) q :=
  by
  intro p q hp hq
  by_cases h : hausdorffDist (p : Set ℓ_infty_ℝ) q < diam (univ : Set X) + 1 + diam (univ : Set Y)
  · exact A p q hp hq h
  ·
    calc
      hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD (candidatesBDist X Y) :=
        hausdorffDist_optimal_le_HD _ _ candidatesBDist_mem_candidatesB
      _ ≤ diam (univ : Set X) + 1 + diam (univ : Set Y) := HD_candidatesBDist_le
      _ ≤ hausdorffDist (p : Set ℓ_infty_ℝ) q := not_lt.1 h
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
A :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist ↑p ↑q < diam univ + 1 + diam univ →
          hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
⊢ ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
[PROOFSTEP]
intro p q hp hq
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
A :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist ↑p ↑q < diam univ + 1 + diam univ →
          hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
[PROOFSTEP]
by_cases h : hausdorffDist (p : Set ℓ_infty_ℝ) q < diam (univ : Set X) + 1 + diam (univ : Set Y)
[GOAL]
case pos
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
A :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist ↑p ↑q < diam univ + 1 + diam univ →
          hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
h : hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
[PROOFSTEP]
exact A p q hp hq h
[GOAL]
case neg
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
A :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist ↑p ↑q < diam univ + 1 + diam univ →
          hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : Quotient.mk IsometryRel.setoid p = toGHSpace X
hq : Quotient.mk IsometryRel.setoid q = toGHSpace Y
h : ¬hausdorffDist ↑p ↑q < diam univ + 1 + diam univ
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
[PROOFSTEP]
calc
  hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD (candidatesBDist X Y) :=
    hausdorffDist_optimal_le_HD _ _ candidatesBDist_mem_candidatesB
  _ ≤ diam (univ : Set X) + 1 + diam (univ : Set Y) := HD_candidatesBDist_le
  _ ≤ hausdorffDist (p : Set ℓ_infty_ℝ) q := not_lt.1 h
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
A :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist ↑p ↑q < diam univ + 1 + diam univ →
          hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
B :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) = ghDist X Y
[PROOFSTEP]
refine' le_antisymm _ _
[GOAL]
case refine'_1
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
A :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist ↑p ↑q < diam univ + 1 + diam univ →
          hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
B :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ ghDist X Y
[PROOFSTEP]
apply le_csInf
[GOAL]
case refine'_1.h₁
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
A :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist ↑p ↑q < diam univ + 1 + diam univ →
          hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
B :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
⊢ Set.Nonempty
    ((fun p => hausdorffDist ↑p.fst ↑p.snd) ''
      {a | Quotient.mk IsometryRel.setoid a = toGHSpace X} ×ˢ {b | Quotient.mk IsometryRel.setoid b = toGHSpace Y})
[PROOFSTEP]
refine' (Set.Nonempty.prod _ _).image _
[GOAL]
case refine'_1.h₁.refine'_1
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
A :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist ↑p ↑q < diam univ + 1 + diam univ →
          hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
B :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
⊢ Set.Nonempty {a | Quotient.mk IsometryRel.setoid a = toGHSpace X}
[PROOFSTEP]
exact ⟨_, rfl⟩
[GOAL]
case refine'_1.h₁.refine'_2
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
A :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist ↑p ↑q < diam univ + 1 + diam univ →
          hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
B :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
⊢ Set.Nonempty {b | Quotient.mk IsometryRel.setoid b = toGHSpace Y}
[PROOFSTEP]
exact ⟨_, rfl⟩
[GOAL]
case refine'_1.h₂
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
A :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist ↑p ↑q < diam univ + 1 + diam univ →
          hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
B :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
⊢ ∀ (b : ℝ),
    b ∈
        (fun p => hausdorffDist ↑p.fst ↑p.snd) ''
          {a | Quotient.mk IsometryRel.setoid a = toGHSpace X} ×ˢ {b | Quotient.mk IsometryRel.setoid b = toGHSpace Y} →
      hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ b
[PROOFSTEP]
rintro b ⟨⟨p, q⟩, ⟨hp, hq⟩, rfl⟩
[GOAL]
case refine'_1.h₂.intro.mk.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
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
A :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist ↑p ↑q < diam univ + 1 + diam univ →
          hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
B :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hp : (p, q).fst ∈ {a | Quotient.mk IsometryRel.setoid a = toGHSpace X}
hq : (p, q).snd ∈ {b | Quotient.mk IsometryRel.setoid b = toGHSpace Y}
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ (fun p => hausdorffDist ↑p.fst ↑p.snd) (p, q)
[PROOFSTEP]
exact B p q hp hq
[GOAL]
case refine'_2
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
inhabited_h✝ : Inhabited X
inhabited_h : Inhabited Y
A :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist ↑p ↑q < diam univ + 1 + diam univ →
          hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
B :
  ∀ (p q : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }),
    Quotient.mk IsometryRel.setoid p = toGHSpace X →
      Quotient.mk IsometryRel.setoid q = toGHSpace Y →
        hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ hausdorffDist ↑p ↑q
⊢ ghDist X Y ≤ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y))
[PROOFSTEP]
exact ghDist_le_hausdorffDist (isometry_optimalGHInjl X Y) (isometry_optimalGHInjr X Y)
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
⊢ ∃ Φ Ψ, Isometry Φ ∧ Isometry Ψ ∧ ghDist X Y = hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
let F := kuratowskiEmbedding (OptimalGHCoupling X Y)
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
F : OptimalGHCoupling X Y → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (OptimalGHCoupling X Y)
⊢ ∃ Φ Ψ, Isometry Φ ∧ Isometry Ψ ∧ ghDist X Y = hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
let Φ := F ∘ optimalGHInjl X Y
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
F : OptimalGHCoupling X Y → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (OptimalGHCoupling X Y)
Φ : X → { x // x ∈ lp (fun i => ℝ) ⊤ } := F ∘ optimalGHInjl X Y
⊢ ∃ Φ Ψ, Isometry Φ ∧ Isometry Ψ ∧ ghDist X Y = hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
let Ψ := F ∘ optimalGHInjr X Y
[GOAL]
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
F : OptimalGHCoupling X Y → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (OptimalGHCoupling X Y)
Φ : X → { x // x ∈ lp (fun i => ℝ) ⊤ } := F ∘ optimalGHInjl X Y
Ψ : Y → { x // x ∈ lp (fun i => ℝ) ⊤ } := F ∘ optimalGHInjr X Y
⊢ ∃ Φ Ψ, Isometry Φ ∧ Isometry Ψ ∧ ghDist X Y = hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
refine' ⟨Φ, Ψ, _, _, _⟩
[GOAL]
case refine'_1
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
F : OptimalGHCoupling X Y → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (OptimalGHCoupling X Y)
Φ : X → { x // x ∈ lp (fun i => ℝ) ⊤ } := F ∘ optimalGHInjl X Y
Ψ : Y → { x // x ∈ lp (fun i => ℝ) ⊤ } := F ∘ optimalGHInjr X Y
⊢ Isometry Φ
[PROOFSTEP]
exact (kuratowskiEmbedding.isometry _).comp (isometry_optimalGHInjl X Y)
[GOAL]
case refine'_2
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
F : OptimalGHCoupling X Y → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (OptimalGHCoupling X Y)
Φ : X → { x // x ∈ lp (fun i => ℝ) ⊤ } := F ∘ optimalGHInjl X Y
Ψ : Y → { x // x ∈ lp (fun i => ℝ) ⊤ } := F ∘ optimalGHInjr X Y
⊢ Isometry Ψ
[PROOFSTEP]
exact (kuratowskiEmbedding.isometry _).comp (isometry_optimalGHInjr X Y)
[GOAL]
case refine'_3
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
F : OptimalGHCoupling X Y → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (OptimalGHCoupling X Y)
Φ : X → { x // x ∈ lp (fun i => ℝ) ⊤ } := F ∘ optimalGHInjl X Y
Ψ : Y → { x // x ∈ lp (fun i => ℝ) ⊤ } := F ∘ optimalGHInjr X Y
⊢ ghDist X Y = hausdorffDist (range Φ) (range Ψ)
[PROOFSTEP]
rw [← image_univ, ← image_univ, image_comp F, image_univ, image_comp F (optimalGHInjr X Y), image_univ, ←
  hausdorffDist_optimal]
[GOAL]
case refine'_3
X : Type u
inst✝⁵ : MetricSpace X
inst✝⁴ : CompactSpace X
inst✝³ : Nonempty X
Y : Type v
inst✝² : MetricSpace Y
inst✝¹ : CompactSpace Y
inst✝ : Nonempty Y
F : OptimalGHCoupling X Y → { x // x ∈ lp (fun i => ℝ) ⊤ } := kuratowskiEmbedding (OptimalGHCoupling X Y)
Φ : X → { x // x ∈ lp (fun i => ℝ) ⊤ } := F ∘ optimalGHInjl X Y
Ψ : Y → { x // x ∈ lp (fun i => ℝ) ⊤ } := F ∘ optimalGHInjr X Y
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) =
    hausdorffDist (F '' range (optimalGHInjl X Y)) (F '' range (optimalGHInjr X Y))
[PROOFSTEP]
exact (hausdorffDist_image (kuratowskiEmbedding.isometry _)).symm
[GOAL]
x : GHSpace
⊢ dist x x = 0
[PROOFSTEP]
rcases exists_rep x with ⟨y, hy⟩
[GOAL]
case intro
x : GHSpace
y : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : Quotient.mk IsometryRel.setoid y = x
⊢ dist x x = 0
[PROOFSTEP]
refine' le_antisymm _ _
[GOAL]
case intro.refine'_1
x : GHSpace
y : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : Quotient.mk IsometryRel.setoid y = x
⊢ dist x x ≤ 0
[PROOFSTEP]
apply csInf_le
[GOAL]
case intro.refine'_1.h₁
x : GHSpace
y : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : Quotient.mk IsometryRel.setoid y = x
⊢ BddBelow
    ((fun p => hausdorffDist ↑p.fst ↑p.snd) ''
      {a | Quotient.mk IsometryRel.setoid a = x} ×ˢ {b | Quotient.mk IsometryRel.setoid b = x})
[PROOFSTEP]
exact ⟨0, by rintro b ⟨⟨u, v⟩, -, rfl⟩; exact hausdorffDist_nonneg⟩
[GOAL]
x : GHSpace
y : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : Quotient.mk IsometryRel.setoid y = x
⊢ 0 ∈
    lowerBounds
      ((fun p => hausdorffDist ↑p.fst ↑p.snd) ''
        {a | Quotient.mk IsometryRel.setoid a = x} ×ˢ {b | Quotient.mk IsometryRel.setoid b = x})
[PROOFSTEP]
rintro b ⟨⟨u, v⟩, -, rfl⟩
[GOAL]
case intro.mk.intro
x : GHSpace
y : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : Quotient.mk IsometryRel.setoid y = x
u v : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
⊢ 0 ≤ (fun p => hausdorffDist ↑p.fst ↑p.snd) (u, v)
[PROOFSTEP]
exact hausdorffDist_nonneg
[GOAL]
case intro.refine'_1.h₂
x : GHSpace
y : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : Quotient.mk IsometryRel.setoid y = x
⊢ 0 ∈
    (fun p => hausdorffDist ↑p.fst ↑p.snd) ''
      {a | Quotient.mk IsometryRel.setoid a = x} ×ˢ {b | Quotient.mk IsometryRel.setoid b = x}
[PROOFSTEP]
simp only [mem_image, mem_prod, mem_setOf_eq, Prod.exists]
[GOAL]
case intro.refine'_1.h₂
x : GHSpace
y : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : Quotient.mk IsometryRel.setoid y = x
⊢ ∃ a b, (Quotient.mk IsometryRel.setoid a = x ∧ Quotient.mk IsometryRel.setoid b = x) ∧ hausdorffDist ↑a ↑b = 0
[PROOFSTEP]
exists y, y
[GOAL]
case intro.refine'_1.h₂
x : GHSpace
y : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : Quotient.mk IsometryRel.setoid y = x
⊢ (Quotient.mk IsometryRel.setoid y = x ∧ Quotient.mk IsometryRel.setoid y = x) ∧ hausdorffDist ↑y ↑y = 0
[PROOFSTEP]
simpa only [and_self_iff, hausdorffDist_self_zero, eq_self_iff_true, and_true_iff]
[GOAL]
case intro.refine'_2
x : GHSpace
y : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : Quotient.mk IsometryRel.setoid y = x
⊢ 0 ≤ dist x x
[PROOFSTEP]
apply le_csInf
[GOAL]
case intro.refine'_2.h₁
x : GHSpace
y : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : Quotient.mk IsometryRel.setoid y = x
⊢ Set.Nonempty
    ((fun p => hausdorffDist ↑p.fst ↑p.snd) ''
      {a | Quotient.mk IsometryRel.setoid a = x} ×ˢ {b | Quotient.mk IsometryRel.setoid b = x})
[PROOFSTEP]
exact Set.Nonempty.image _ <| Set.Nonempty.prod ⟨y, hy⟩ ⟨y, hy⟩
[GOAL]
case intro.refine'_2.h₂
x : GHSpace
y : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : Quotient.mk IsometryRel.setoid y = x
⊢ ∀ (b : ℝ),
    b ∈
        (fun p => hausdorffDist ↑p.fst ↑p.snd) ''
          {a | Quotient.mk IsometryRel.setoid a = x} ×ˢ {b | Quotient.mk IsometryRel.setoid b = x} →
      0 ≤ b
[PROOFSTEP]
rintro b ⟨⟨u, v⟩, -, rfl⟩
[GOAL]
case intro.refine'_2.h₂.intro.mk.intro
x : GHSpace
y : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
hy : Quotient.mk IsometryRel.setoid y = x
u v : NonemptyCompacts { x // x ∈ lp (fun n => ℝ) ⊤ }
⊢ 0 ≤ (fun p => hausdorffDist ↑p.fst ↑p.snd) (u, v)
[PROOFSTEP]
exact hausdorffDist_nonneg
[GOAL]
x y : GHSpace
⊢ dist x y = dist y x
[PROOFSTEP]
have A :
  (fun p : NonemptyCompacts ℓ_infty_ℝ × NonemptyCompacts ℓ_infty_ℝ => hausdorffDist (p.1 : Set ℓ_infty_ℝ) p.2) ''
      {a | ⟦a⟧ = x} ×ˢ {b | ⟦b⟧ = y} =
    (fun p : NonemptyCompacts ℓ_infty_ℝ × NonemptyCompacts ℓ_infty_ℝ => hausdorffDist (p.1 : Set ℓ_infty_ℝ) p.2) ∘
        Prod.swap ''
      {a | ⟦a⟧ = x} ×ˢ {b | ⟦b⟧ = y} :=
  by
  congr
  funext
  simp only [comp_apply, Prod.fst_swap, Prod.snd_swap]
  congr
  simp (config := { singlePass := true }) only [hausdorffDist_comm]
[GOAL]
x y : GHSpace
⊢ (fun p => hausdorffDist ↑p.fst ↑p.snd) ''
      {a | Quotient.mk IsometryRel.setoid a = x} ×ˢ {b | Quotient.mk IsometryRel.setoid b = y} =
    (fun p => hausdorffDist ↑p.fst ↑p.snd) ∘ Prod.swap ''
      {a | Quotient.mk IsometryRel.setoid a = x} ×ˢ {b | Quotient.mk IsometryRel.setoid b = y}
[PROOFSTEP]
congr
[GOAL]
x y : GHSpace
⊢ (fun p => hausdorffDist ↑p.fst ↑p.snd) ''
      {a | Quotient.mk IsometryRel.setoid a = x} ×ˢ {b | Quotient.mk IsometryRel.setoid b = y} =
    (fun p => hausdorffDist ↑p.fst ↑p.snd) ∘ Prod.swap ''
      {a | Quotient.mk IsometryRel.setoid a = x} ×ˢ {b | Quotient.mk IsometryRel.setoid b = y}
[PROOFSTEP]
funext
[GOAL]
case h
x y : GHSpace
x✝ : ℝ
⊢ ((fun p => hausdorffDist ↑p.fst ↑p.snd) ''
        {a | Quotient.mk IsometryRel.setoid a = x} ×ˢ {b | Quotient.mk IsometryRel.setoid b = y})
      x✝ =
    ((fun p => hausdorffDist ↑p.fst ↑p.snd) ∘ Prod.swap ''
        {a | Quotient.mk IsometryRel.setoid a = x} ×ˢ {b | Quotient.mk IsometryRel.setoid b = y})
      x✝
[PROOFSTEP]
simp only [comp_apply, Prod.fst_swap, Prod.snd_swap]
[GOAL]
case h
x y : GHSpace
x✝ : ℝ
⊢ ((fun p => hausdorffDist ↑p.fst ↑p.snd) ''
        {a | Quotient.mk IsometryRel.setoid a = x} ×ˢ {b | Quotient.mk IsometryRel.setoid b = y})
      x✝ =
    ((fun a => hausdorffDist ↑a.snd ↑a.fst) ''
        {a | Quotient.mk IsometryRel.setoid a = x} ×ˢ {b | Quotient.mk IsometryRel.setoid b = y})
      x✝
[PROOFSTEP]
congr
[GOAL]
case h.e_f
x y : GHSpace
x✝ : ℝ
⊢ (fun p => hausdorffDist ↑p.fst ↑p.snd) = fun a => hausdorffDist ↑a.snd ↑a.fst
[PROOFSTEP]
simp (config := { singlePass := true }) only [hausdorffDist_comm]
[GOAL]
x y : GHSpace
A :
  (fun p => hausdorffDist ↑p.fst ↑p.snd) ''
      {a | Quotient.mk IsometryRel.setoid a = x} ×ˢ {b | Quotient.mk IsometryRel.setoid b = y} =
    (fun p => hausdorffDist ↑p.fst ↑p.snd) ∘ Prod.swap ''
      {a | Quotient.mk IsometryRel.setoid a = x} ×ˢ {b | Quotient.mk IsometryRel.setoid b = y}
⊢ dist x y = dist y x
[PROOFSTEP]
simp only [dist, A, image_comp, image_swap_prod]
[GOAL]
x y z : GHSpace
⊢ dist x z ≤ dist x y + dist y z
[PROOFSTEP]
let X := x.Rep
[GOAL]
x y z : GHSpace
X : Type := GHSpace.Rep x
⊢ dist x z ≤ dist x y + dist y z
[PROOFSTEP]
let Y := y.Rep
[GOAL]
x y z : GHSpace
X : Type := GHSpace.Rep x
Y : Type := GHSpace.Rep y
⊢ dist x z ≤ dist x y + dist y z
[PROOFSTEP]
let Z := z.Rep
[GOAL]
x y z : GHSpace
X : Type := GHSpace.Rep x
Y : Type := GHSpace.Rep y
Z : Type := GHSpace.Rep z
⊢ dist x z ≤ dist x y + dist y z
[PROOFSTEP]
let γ1 := OptimalGHCoupling X Y
[GOAL]
x y z : GHSpace
X : Type := GHSpace.Rep x
Y : Type := GHSpace.Rep y
Z : Type := GHSpace.Rep z
γ1 : Type := OptimalGHCoupling X Y
⊢ dist x z ≤ dist x y + dist y z
[PROOFSTEP]
let γ2 := OptimalGHCoupling Y Z
[GOAL]
x y z : GHSpace
X : Type := GHSpace.Rep x
Y : Type := GHSpace.Rep y
Z : Type := GHSpace.Rep z
γ1 : Type := OptimalGHCoupling X Y
γ2 : Type := OptimalGHCoupling Y Z
⊢ dist x z ≤ dist x y + dist y z
[PROOFSTEP]
let Φ : Y → γ1 := optimalGHInjr X Y
[GOAL]
x y z : GHSpace
X : Type := GHSpace.Rep x
Y : Type := GHSpace.Rep y
Z : Type := GHSpace.Rep z
γ1 : Type := OptimalGHCoupling X Y
γ2 : Type := OptimalGHCoupling Y Z
Φ : Y → γ1 := optimalGHInjr X Y
⊢ dist x z ≤ dist x y + dist y z
[PROOFSTEP]
have hΦ : Isometry Φ := isometry_optimalGHInjr X Y
[GOAL]
x y z : GHSpace
X : Type := GHSpace.Rep x
Y : Type := GHSpace.Rep y
Z : Type := GHSpace.Rep z
γ1 : Type := OptimalGHCoupling X Y
γ2 : Type := OptimalGHCoupling Y Z
Φ : Y → γ1 := optimalGHInjr X Y
hΦ : Isometry Φ
⊢ dist x z ≤ dist x y + dist y z
[PROOFSTEP]
let Ψ : Y → γ2 := optimalGHInjl Y Z
[GOAL]
x y z : GHSpace
X : Type := GHSpace.Rep x
Y : Type := GHSpace.Rep y
Z : Type := GHSpace.Rep z
γ1 : Type := OptimalGHCoupling X Y
γ2 : Type := OptimalGHCoupling Y Z
Φ : Y → γ1 := optimalGHInjr X Y
hΦ : Isometry Φ
Ψ : Y → γ2 := optimalGHInjl Y Z
⊢ dist x z ≤ dist x y + dist y z
[PROOFSTEP]
have hΨ : Isometry Ψ := isometry_optimalGHInjl Y Z
[GOAL]
x y z : GHSpace
X : Type := GHSpace.Rep x
Y : Type := GHSpace.Rep y
Z : Type := GHSpace.Rep z
γ1 : Type := OptimalGHCoupling X Y
γ2 : Type := OptimalGHCoupling Y Z
Φ : Y → γ1 := optimalGHInjr X Y
hΦ : Isometry Φ
Ψ : Y → γ2 := optimalGHInjl Y Z
hΨ : Isometry Ψ
⊢ dist x z ≤ dist x y + dist y z
[PROOFSTEP]
have Comm : toGlueL hΦ hΨ ∘ optimalGHInjr X Y = toGlueR hΦ hΨ ∘ optimalGHInjl Y Z := toGlue_commute hΦ hΨ
[GOAL]
x y z : GHSpace
X : Type := GHSpace.Rep x
Y : Type := GHSpace.Rep y
Z : Type := GHSpace.Rep z
γ1 : Type := OptimalGHCoupling X Y
γ2 : Type := OptimalGHCoupling Y Z
Φ : Y → γ1 := optimalGHInjr X Y
hΦ : Isometry Φ
Ψ : Y → γ2 := optimalGHInjl Y Z
hΨ : Isometry Ψ
Comm : toGlueL hΦ hΨ ∘ optimalGHInjr X Y = toGlueR hΦ hΨ ∘ optimalGHInjl Y Z
⊢ dist x z ≤ dist x y + dist y z
[PROOFSTEP]
calc
  dist x z = dist (toGHSpace X) (toGHSpace Z) := by rw [x.toGHSpace_rep, z.toGHSpace_rep]
  _ ≤ hausdorffDist (range (toGlueL hΦ hΨ ∘ optimalGHInjl X Y)) (range (toGlueR hΦ hΨ ∘ optimalGHInjr Y Z)) :=
    (ghDist_le_hausdorffDist ((toGlueL_isometry hΦ hΨ).comp (isometry_optimalGHInjl X Y))
      ((toGlueR_isometry hΦ hΨ).comp (isometry_optimalGHInjr Y Z)))
  _ ≤
      hausdorffDist (range (toGlueL hΦ hΨ ∘ optimalGHInjl X Y)) (range (toGlueL hΦ hΨ ∘ optimalGHInjr X Y)) +
        hausdorffDist (range (toGlueL hΦ hΨ ∘ optimalGHInjr X Y)) (range (toGlueR hΦ hΨ ∘ optimalGHInjr Y Z)) :=
    by
    refine'
      hausdorffDist_triangle <| hausdorffEdist_ne_top_of_nonempty_of_bounded (range_nonempty _) (range_nonempty _) _ _
    · exact (isCompact_range (Isometry.continuous ((toGlueL_isometry hΦ hΨ).comp (isometry_optimalGHInjl X Y)))).bounded
    · exact (isCompact_range (Isometry.continuous ((toGlueL_isometry hΦ hΨ).comp (isometry_optimalGHInjr X Y)))).bounded
  _ =
      hausdorffDist (toGlueL hΦ hΨ '' range (optimalGHInjl X Y)) (toGlueL hΦ hΨ '' range (optimalGHInjr X Y)) +
        hausdorffDist (toGlueR hΦ hΨ '' range (optimalGHInjl Y Z)) (toGlueR hΦ hΨ '' range (optimalGHInjr Y Z)) :=
    by simp only [← range_comp, Comm, eq_self_iff_true, add_right_inj]
  _ =
      hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) +
        hausdorffDist (range (optimalGHInjl Y Z)) (range (optimalGHInjr Y Z)) :=
    by rw [hausdorffDist_image (toGlueL_isometry hΦ hΨ), hausdorffDist_image (toGlueR_isometry hΦ hΨ)]
  _ = dist (toGHSpace X) (toGHSpace Y) + dist (toGHSpace Y) (toGHSpace Z) := by
    rw [hausdorffDist_optimal, hausdorffDist_optimal, ghDist, ghDist]
  _ = dist x y + dist y z := by rw [x.toGHSpace_rep, y.toGHSpace_rep, z.toGHSpace_rep]
[GOAL]
x y z : GHSpace
X : Type := GHSpace.Rep x
Y : Type := GHSpace.Rep y
Z : Type := GHSpace.Rep z
γ1 : Type := OptimalGHCoupling X Y
γ2 : Type := OptimalGHCoupling Y Z
Φ : Y → γ1 := optimalGHInjr X Y
hΦ : Isometry Φ
Ψ : Y → γ2 := optimalGHInjl Y Z
hΨ : Isometry Ψ
Comm : toGlueL hΦ hΨ ∘ optimalGHInjr X Y = toGlueR hΦ hΨ ∘ optimalGHInjl Y Z
⊢ dist x z = dist (toGHSpace X) (toGHSpace Z)
[PROOFSTEP]
rw [x.toGHSpace_rep, z.toGHSpace_rep]
[GOAL]
x y z : GHSpace
X : Type := GHSpace.Rep x
Y : Type := GHSpace.Rep y
Z : Type := GHSpace.Rep z
γ1 : Type := OptimalGHCoupling X Y
γ2 : Type := OptimalGHCoupling Y Z
Φ : Y → γ1 := optimalGHInjr X Y
hΦ : Isometry Φ
Ψ : Y → γ2 := optimalGHInjl Y Z
hΨ : Isometry Ψ
Comm : toGlueL hΦ hΨ ∘ optimalGHInjr X Y = toGlueR hΦ hΨ ∘ optimalGHInjl Y Z
⊢ hausdorffDist (range (toGlueL hΦ hΨ ∘ optimalGHInjl X Y)) (range (toGlueR hΦ hΨ ∘ optimalGHInjr Y Z)) ≤
    hausdorffDist (range (toGlueL hΦ hΨ ∘ optimalGHInjl X Y)) (range (toGlueL hΦ hΨ ∘ optimalGHInjr X Y)) +
      hausdorffDist (range (toGlueL hΦ hΨ ∘ optimalGHInjr X Y)) (range (toGlueR hΦ hΨ ∘ optimalGHInjr Y Z))
[PROOFSTEP]
refine' hausdorffDist_triangle <| hausdorffEdist_ne_top_of_nonempty_of_bounded (range_nonempty _) (range_nonempty _) _ _
[GOAL]
case refine'_1
x y z : GHSpace
X : Type := GHSpace.Rep x
Y : Type := GHSpace.Rep y
Z : Type := GHSpace.Rep z
γ1 : Type := OptimalGHCoupling X Y
γ2 : Type := OptimalGHCoupling Y Z
Φ : Y → γ1 := optimalGHInjr X Y
hΦ : Isometry Φ
Ψ : Y → γ2 := optimalGHInjl Y Z
hΨ : Isometry Ψ
Comm : toGlueL hΦ hΨ ∘ optimalGHInjr X Y = toGlueR hΦ hΨ ∘ optimalGHInjl Y Z
⊢ Metric.Bounded (range (toGlueL hΦ hΨ ∘ optimalGHInjl X Y))
[PROOFSTEP]
exact (isCompact_range (Isometry.continuous ((toGlueL_isometry hΦ hΨ).comp (isometry_optimalGHInjl X Y)))).bounded
[GOAL]
case refine'_2
x y z : GHSpace
X : Type := GHSpace.Rep x
Y : Type := GHSpace.Rep y
Z : Type := GHSpace.Rep z
γ1 : Type := OptimalGHCoupling X Y
γ2 : Type := OptimalGHCoupling Y Z
Φ : Y → γ1 := optimalGHInjr X Y
hΦ : Isometry Φ
Ψ : Y → γ2 := optimalGHInjl Y Z
hΨ : Isometry Ψ
Comm : toGlueL hΦ hΨ ∘ optimalGHInjr X Y = toGlueR hΦ hΨ ∘ optimalGHInjl Y Z
⊢ Metric.Bounded (range (toGlueL hΦ hΨ ∘ optimalGHInjr X Y))
[PROOFSTEP]
exact (isCompact_range (Isometry.continuous ((toGlueL_isometry hΦ hΨ).comp (isometry_optimalGHInjr X Y)))).bounded
[GOAL]
x y z : GHSpace
X : Type := GHSpace.Rep x
Y : Type := GHSpace.Rep y
Z : Type := GHSpace.Rep z
γ1 : Type := OptimalGHCoupling X Y
γ2 : Type := OptimalGHCoupling Y Z
Φ : Y → γ1 := optimalGHInjr X Y
hΦ : Isometry Φ
Ψ : Y → γ2 := optimalGHInjl Y Z
hΨ : Isometry Ψ
Comm : toGlueL hΦ hΨ ∘ optimalGHInjr X Y = toGlueR hΦ hΨ ∘ optimalGHInjl Y Z
⊢ hausdorffDist (range (toGlueL hΦ hΨ ∘ optimalGHInjl X Y)) (range (toGlueL hΦ hΨ ∘ optimalGHInjr X Y)) +
      hausdorffDist (range (toGlueL hΦ hΨ ∘ optimalGHInjr X Y)) (range (toGlueR hΦ hΨ ∘ optimalGHInjr Y Z)) =
    hausdorffDist (toGlueL hΦ hΨ '' range (optimalGHInjl X Y)) (toGlueL hΦ hΨ '' range (optimalGHInjr X Y)) +
      hausdorffDist (toGlueR hΦ hΨ '' range (optimalGHInjl Y Z)) (toGlueR hΦ hΨ '' range (optimalGHInjr Y Z))
[PROOFSTEP]
simp only [← range_comp, Comm, eq_self_iff_true, add_right_inj]
[GOAL]
x y z : GHSpace
X : Type := GHSpace.Rep x
Y : Type := GHSpace.Rep y
Z : Type := GHSpace.Rep z
γ1 : Type := OptimalGHCoupling X Y
γ2 : Type := OptimalGHCoupling Y Z
Φ : Y → γ1 := optimalGHInjr X Y
hΦ : Isometry Φ
Ψ : Y → γ2 := optimalGHInjl Y Z
hΨ : Isometry Ψ
Comm : toGlueL hΦ hΨ ∘ optimalGHInjr X Y = toGlueR hΦ hΨ ∘ optimalGHInjl Y Z
⊢ hausdorffDist (toGlueL hΦ hΨ '' range (optimalGHInjl X Y)) (toGlueL hΦ hΨ '' range (optimalGHInjr X Y)) +
      hausdorffDist (toGlueR hΦ hΨ '' range (optimalGHInjl Y Z)) (toGlueR hΦ hΨ '' range (optimalGHInjr Y Z)) =
    hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) +
      hausdorffDist (range (optimalGHInjl Y Z)) (range (optimalGHInjr Y Z))
[PROOFSTEP]
rw [hausdorffDist_image (toGlueL_isometry hΦ hΨ), hausdorffDist_image (toGlueR_isometry hΦ hΨ)]
[GOAL]
x y z : GHSpace
X : Type := GHSpace.Rep x
Y : Type := GHSpace.Rep y
Z : Type := GHSpace.Rep z
γ1 : Type := OptimalGHCoupling X Y
γ2 : Type := OptimalGHCoupling Y Z
Φ : Y → γ1 := optimalGHInjr X Y
hΦ : Isometry Φ
Ψ : Y → γ2 := optimalGHInjl Y Z
hΨ : Isometry Ψ
Comm : toGlueL hΦ hΨ ∘ optimalGHInjr X Y = toGlueR hΦ hΨ ∘ optimalGHInjl Y Z
⊢ hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) +
      hausdorffDist (range (optimalGHInjl Y Z)) (range (optimalGHInjr Y Z)) =
    dist (toGHSpace X) (toGHSpace Y) + dist (toGHSpace Y) (toGHSpace Z)
[PROOFSTEP]
rw [hausdorffDist_optimal, hausdorffDist_optimal, ghDist, ghDist]
[GOAL]
x y z : GHSpace
X : Type := GHSpace.Rep x
Y : Type := GHSpace.Rep y
Z : Type := GHSpace.Rep z
γ1 : Type := OptimalGHCoupling X Y
γ2 : Type := OptimalGHCoupling Y Z
Φ : Y → γ1 := optimalGHInjr X Y
hΦ : Isometry Φ
Ψ : Y → γ2 := optimalGHInjl Y Z
hΨ : Isometry Ψ
Comm : toGlueL hΦ hΨ ∘ optimalGHInjr X Y = toGlueR hΦ hΨ ∘ optimalGHInjl Y Z
⊢ dist (toGHSpace X) (toGHSpace Y) + dist (toGHSpace Y) (toGHSpace Z) = dist x y + dist y z
[PROOFSTEP]
rw [x.toGHSpace_rep, y.toGHSpace_rep, z.toGHSpace_rep]
[GOAL]
x✝¹ x✝ : GHSpace
⊢ (fun x y =>
        ↑{
            val :=
              sInf
                ((fun p => hausdorffDist ↑p.fst ↑p.snd) ''
                  {a | Quotient.mk IsometryRel.setoid a = x} ×ˢ {b | Quotient.mk IsometryRel.setoid b = y}),
            property :=
              (_ :
                0 ≤
                  sInf
                    ((fun p => hausdorffDist ↑p.fst ↑p.snd) ''
                      {a | Quotient.mk IsometryRel.setoid a = x} ×ˢ {b | Quotient.mk IsometryRel.setoid b = y})) })
      x✝¹ x✝ =
    ENNReal.ofReal (dist x✝¹ x✝)
[PROOFSTEP]
exact ENNReal.coe_nnreal_eq _
[GOAL]
x y : GHSpace
hxy : dist x y = 0
⊢ x = y
[PROOFSTEP]
rcases ghDist_eq_hausdorffDist x.Rep y.Rep with ⟨Φ, Ψ, Φisom, Ψisom, DΦΨ⟩
[GOAL]
case intro.intro.intro.intro
x y : GHSpace
hxy : dist x y = 0
Φ : GHSpace.Rep x → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : GHSpace.Rep y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Ψisom : Isometry Ψ
DΦΨ : ghDist (GHSpace.Rep x) (GHSpace.Rep y) = hausdorffDist (range Φ) (range Ψ)
⊢ x = y
[PROOFSTEP]
rw [← dist_ghDist] at DΦΨ 
[GOAL]
case intro.intro.intro.intro
x y : GHSpace
hxy : dist x y = 0
Φ : GHSpace.Rep x → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : GHSpace.Rep y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Ψisom : Isometry Ψ
DΦΨ : dist x y = hausdorffDist (range Φ) (range Ψ)
⊢ x = y
[PROOFSTEP]
simp_rw [hxy] at DΦΨ 
[GOAL]
case intro.intro.intro.intro
x y : GHSpace
hxy : dist x y = 0
Φ : GHSpace.Rep x → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : GHSpace.Rep y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Ψisom : Isometry Ψ
DΦΨ : 0 = hausdorffDist (range Φ) (range Ψ)
⊢ x = y
[PROOFSTEP]
have : range Φ = range Ψ :=
  by
  have hΦ : IsCompact (range Φ) := isCompact_range Φisom.continuous
  have hΨ : IsCompact (range Ψ) := isCompact_range Ψisom.continuous
  apply (IsClosed.hausdorffDist_zero_iff_eq _ _ _).1 DΦΨ.symm
  · exact hΦ.isClosed
  · exact hΨ.isClosed
  · exact hausdorffEdist_ne_top_of_nonempty_of_bounded (range_nonempty _) (range_nonempty _) hΦ.bounded hΨ.bounded
[GOAL]
x y : GHSpace
hxy : dist x y = 0
Φ : GHSpace.Rep x → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : GHSpace.Rep y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Ψisom : Isometry Ψ
DΦΨ : 0 = hausdorffDist (range Φ) (range Ψ)
⊢ range Φ = range Ψ
[PROOFSTEP]
have hΦ : IsCompact (range Φ) := isCompact_range Φisom.continuous
[GOAL]
x y : GHSpace
hxy : dist x y = 0
Φ : GHSpace.Rep x → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : GHSpace.Rep y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Ψisom : Isometry Ψ
DΦΨ : 0 = hausdorffDist (range Φ) (range Ψ)
hΦ : IsCompact (range Φ)
⊢ range Φ = range Ψ
[PROOFSTEP]
have hΨ : IsCompact (range Ψ) := isCompact_range Ψisom.continuous
[GOAL]
x y : GHSpace
hxy : dist x y = 0
Φ : GHSpace.Rep x → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : GHSpace.Rep y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Ψisom : Isometry Ψ
DΦΨ : 0 = hausdorffDist (range Φ) (range Ψ)
hΦ : IsCompact (range Φ)
hΨ : IsCompact (range Ψ)
⊢ range Φ = range Ψ
[PROOFSTEP]
apply (IsClosed.hausdorffDist_zero_iff_eq _ _ _).1 DΦΨ.symm
[GOAL]
x y : GHSpace
hxy : dist x y = 0
Φ : GHSpace.Rep x → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : GHSpace.Rep y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Ψisom : Isometry Ψ
DΦΨ : 0 = hausdorffDist (range Φ) (range Ψ)
hΦ : IsCompact (range Φ)
hΨ : IsCompact (range Ψ)
⊢ IsClosed (range Φ)
[PROOFSTEP]
exact hΦ.isClosed
[GOAL]
x y : GHSpace
hxy : dist x y = 0
Φ : GHSpace.Rep x → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : GHSpace.Rep y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Ψisom : Isometry Ψ
DΦΨ : 0 = hausdorffDist (range Φ) (range Ψ)
hΦ : IsCompact (range Φ)
hΨ : IsCompact (range Ψ)
⊢ IsClosed (range Ψ)
[PROOFSTEP]
exact hΨ.isClosed
[GOAL]
x y : GHSpace
hxy : dist x y = 0
Φ : GHSpace.Rep x → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : GHSpace.Rep y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Ψisom : Isometry Ψ
DΦΨ : 0 = hausdorffDist (range Φ) (range Ψ)
hΦ : IsCompact (range Φ)
hΨ : IsCompact (range Ψ)
⊢ EMetric.hausdorffEdist (range Φ) (range Ψ) ≠ ⊤
[PROOFSTEP]
exact hausdorffEdist_ne_top_of_nonempty_of_bounded (range_nonempty _) (range_nonempty _) hΦ.bounded hΨ.bounded
[GOAL]
case intro.intro.intro.intro
x y : GHSpace
hxy : dist x y = 0
Φ : GHSpace.Rep x → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : GHSpace.Rep y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Ψisom : Isometry Ψ
DΦΨ : 0 = hausdorffDist (range Φ) (range Ψ)
this : range Φ = range Ψ
⊢ x = y
[PROOFSTEP]
have T : (range Ψ ≃ᵢ y.Rep) = (range Φ ≃ᵢ y.Rep) := by rw [this]
[GOAL]
x y : GHSpace
hxy : dist x y = 0
Φ : GHSpace.Rep x → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : GHSpace.Rep y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Ψisom : Isometry Ψ
DΦΨ : 0 = hausdorffDist (range Φ) (range Ψ)
this : range Φ = range Ψ
⊢ (↑(range Ψ) ≃ᵢ GHSpace.Rep y) = (↑(range Φ) ≃ᵢ GHSpace.Rep y)
[PROOFSTEP]
rw [this]
[GOAL]
case intro.intro.intro.intro
x y : GHSpace
hxy : dist x y = 0
Φ : GHSpace.Rep x → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : GHSpace.Rep y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Ψisom : Isometry Ψ
DΦΨ : 0 = hausdorffDist (range Φ) (range Ψ)
this : range Φ = range Ψ
T : (↑(range Ψ) ≃ᵢ GHSpace.Rep y) = (↑(range Φ) ≃ᵢ GHSpace.Rep y)
⊢ x = y
[PROOFSTEP]
have eΨ := cast T Ψisom.isometryEquivOnRange.symm
[GOAL]
case intro.intro.intro.intro
x y : GHSpace
hxy : dist x y = 0
Φ : GHSpace.Rep x → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : GHSpace.Rep y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Ψisom : Isometry Ψ
DΦΨ : 0 = hausdorffDist (range Φ) (range Ψ)
this : range Φ = range Ψ
T : (↑(range Ψ) ≃ᵢ GHSpace.Rep y) = (↑(range Φ) ≃ᵢ GHSpace.Rep y)
eΨ : ↑(range Φ) ≃ᵢ GHSpace.Rep y
⊢ x = y
[PROOFSTEP]
have e := Φisom.isometryEquivOnRange.trans eΨ
[GOAL]
case intro.intro.intro.intro
x y : GHSpace
hxy : dist x y = 0
Φ : GHSpace.Rep x → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : GHSpace.Rep y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Ψisom : Isometry Ψ
DΦΨ : 0 = hausdorffDist (range Φ) (range Ψ)
this : range Φ = range Ψ
T : (↑(range Ψ) ≃ᵢ GHSpace.Rep y) = (↑(range Φ) ≃ᵢ GHSpace.Rep y)
eΨ : ↑(range Φ) ≃ᵢ GHSpace.Rep y
e : GHSpace.Rep x ≃ᵢ GHSpace.Rep y
⊢ x = y
[PROOFSTEP]
rw [← x.toGHSpace_rep, ← y.toGHSpace_rep, toGHSpace_eq_toGHSpace_iff_isometryEquiv]
[GOAL]
case intro.intro.intro.intro
x y : GHSpace
hxy : dist x y = 0
Φ : GHSpace.Rep x → { x // x ∈ lp (fun n => ℝ) ⊤ }
Ψ : GHSpace.Rep y → { x // x ∈ lp (fun n => ℝ) ⊤ }
Φisom : Isometry Φ
Ψisom : Isometry Ψ
DΦΨ : 0 = hausdorffDist (range Φ) (range Ψ)
this : range Φ = range Ψ
T : (↑(range Ψ) ≃ᵢ GHSpace.Rep y) = (↑(range Φ) ≃ᵢ GHSpace.Rep y)
eΨ : ↑(range Φ) ≃ᵢ GHSpace.Rep y
e : GHSpace.Rep x ≃ᵢ GHSpace.Rep y
⊢ Nonempty (GHSpace.Rep x ≃ᵢ GHSpace.Rep y)
[PROOFSTEP]
exact ⟨e⟩
[GOAL]
X : Type u
inst✝ : MetricSpace X
p q : NonemptyCompacts X
⊢ dist (NonemptyCompacts.toGHSpace p) (NonemptyCompacts.toGHSpace q) ≤ dist p q
[PROOFSTEP]
have ha : Isometry ((↑) : p → X) := isometry_subtype_coe
[GOAL]
X : Type u
inst✝ : MetricSpace X
p q : NonemptyCompacts X
ha : Isometry Subtype.val
⊢ dist (NonemptyCompacts.toGHSpace p) (NonemptyCompacts.toGHSpace q) ≤ dist p q
[PROOFSTEP]
have hb : Isometry ((↑) : q → X) := isometry_subtype_coe
[GOAL]
X : Type u
inst✝ : MetricSpace X
p q : NonemptyCompacts X
ha : Isometry Subtype.val
hb : Isometry Subtype.val
⊢ dist (NonemptyCompacts.toGHSpace p) (NonemptyCompacts.toGHSpace q) ≤ dist p q
[PROOFSTEP]
have A : dist p q = hausdorffDist (p : Set X) q := rfl
[GOAL]
X : Type u
inst✝ : MetricSpace X
p q : NonemptyCompacts X
ha : Isometry Subtype.val
hb : Isometry Subtype.val
A : dist p q = hausdorffDist ↑p ↑q
⊢ dist (NonemptyCompacts.toGHSpace p) (NonemptyCompacts.toGHSpace q) ≤ dist p q
[PROOFSTEP]
have I : ↑p = range ((↑) : p → X) := Subtype.range_coe_subtype.symm
[GOAL]
X : Type u
inst✝ : MetricSpace X
p q : NonemptyCompacts X
ha : Isometry Subtype.val
hb : Isometry Subtype.val
A : dist p q = hausdorffDist ↑p ↑q
I : ↑p = range Subtype.val
⊢ dist (NonemptyCompacts.toGHSpace p) (NonemptyCompacts.toGHSpace q) ≤ dist p q
[PROOFSTEP]
have J : ↑q = range ((↑) : q → X) := Subtype.range_coe_subtype.symm
[GOAL]
X : Type u
inst✝ : MetricSpace X
p q : NonemptyCompacts X
ha : Isometry Subtype.val
hb : Isometry Subtype.val
A : dist p q = hausdorffDist ↑p ↑q
I : ↑p = range Subtype.val
J : ↑q = range Subtype.val
⊢ dist (NonemptyCompacts.toGHSpace p) (NonemptyCompacts.toGHSpace q) ≤ dist p q
[PROOFSTEP]
rw [A, I, J]
[GOAL]
X : Type u
inst✝ : MetricSpace X
p q : NonemptyCompacts X
ha : Isometry Subtype.val
hb : Isometry Subtype.val
A : dist p q = hausdorffDist ↑p ↑q
I : ↑p = range Subtype.val
J : ↑q = range Subtype.val
⊢ dist (NonemptyCompacts.toGHSpace p) (NonemptyCompacts.toGHSpace q) ≤
    hausdorffDist (range Subtype.val) (range Subtype.val)
[PROOFSTEP]
exact ghDist_le_hausdorffDist ha hb
[GOAL]
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, y ∈ s ∧ dist x y ≤ ε₁
hs' : ∀ (x : Y), ∃ y, dist x (Φ y) ≤ ε₃
H : ∀ (x y : ↑s), |dist x y - dist (Φ x) (Φ y)| ≤ ε₂
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃
[PROOFSTEP]
refine' le_of_forall_pos_le_add fun δ δ0 => _
[GOAL]
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, y ∈ s ∧ dist x y ≤ ε₁
hs' : ∀ (x : Y), ∃ y, dist x (Φ y) ≤ ε₃
H : ∀ (x y : ↑s), |dist x y - dist (Φ x) (Φ y)| ≤ ε₂
δ : ℝ
δ0 : 0 < δ
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ
[PROOFSTEP]
rcases exists_mem_of_nonempty X with ⟨xX, _⟩
[GOAL]
case 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, 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
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ
[PROOFSTEP]
rcases hs xX with ⟨xs, hxs, Dxs⟩
[GOAL]
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, 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 ≤ ε₁
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ
[PROOFSTEP]
have sne : s.Nonempty := ⟨xs, hxs⟩
[GOAL]
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, 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
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ
[PROOFSTEP]
letI : Nonempty s := sne.to_subtype
[GOAL]
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, 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
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ
[PROOFSTEP]
have : 0 ≤ ε₂ := le_trans (abs_nonneg _) (H ⟨xs, hxs⟩ ⟨xs, hxs⟩)
[GOAL]
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, 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 ≤ ε₂
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ
[PROOFSTEP]
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
[GOAL]
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, 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 ≤ ε₂
p q : ↑s
⊢ ε₂ ≤ 2 * (ε₂ / 2 + δ)
[PROOFSTEP]
linarith
  -- glue `X` and `Y` along the almost matching subsets
[GOAL]
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, 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 + δ)
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ
[PROOFSTEP]
letI : MetricSpace (Sum X Y) := glueMetricApprox (fun x : s => (x : X)) (fun x => Φ x) (ε₂ / 2 + δ) (by linarith) this
[GOAL]
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, 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 + δ)
⊢ 0 < ε₂ / 2 + δ
[PROOFSTEP]
linarith
[GOAL]
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, 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✝
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ
[PROOFSTEP]
let Fl := @Sum.inl X Y
[GOAL]
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, 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
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ
[PROOFSTEP]
let Fr := @Sum.inr X Y
[GOAL]
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, 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 + ε₃ + δ
[PROOFSTEP]
have Il : Isometry Fl := Isometry.of_dist_eq fun x y => rfl
[GOAL]
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, 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 + ε₃ + δ
[PROOFSTEP]
have Ir : Isometry Fr := Isometry.of_dist_eq fun x y => rfl
[GOAL]
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, 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 + ε₃ + δ
[PROOFSTEP]
have : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr) := ghDist_le_hausdorffDist Il Ir
[GOAL]
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, 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
this : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ
[PROOFSTEP]
have : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr) :=
  haveI B : Bounded (range Fl) := (isCompact_range Il.continuous).bounded
  hausdorffDist_triangle
    (hausdorffEdist_ne_top_of_nonempty_of_bounded (range_nonempty _) (sne.image _) B (B.mono (image_subset_range _ _)))
[GOAL]
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, 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
this✝ : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ
[PROOFSTEP]
have :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr) :=
  haveI B : Bounded (range Fr) := (isCompact_range Ir.continuous).bounded
  hausdorffDist_triangle'
    (hausdorffEdist_ne_top_of_nonempty_of_bounded ((range_nonempty _).image _) (range_nonempty _)
      (Bounded.mono (image_subset_range _ _) B) B)
[GOAL]
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, 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
this✝¹ : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ
[PROOFSTEP]
have : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁ :=
  by
  rw [← image_univ, hausdorffDist_image Il]
  have : 0 ≤ ε₁ := le_trans dist_nonneg Dxs
  refine' hausdorffDist_le_of_mem_dist this (fun x _ => hs x) fun x _ => ⟨x, mem_univ _, by simpa only [dist_self]⟩
[GOAL]
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, 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
this✝¹ : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
⊢ hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
[PROOFSTEP]
rw [← image_univ, hausdorffDist_image Il]
[GOAL]
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, 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
this✝¹ : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
⊢ hausdorffDist univ s ≤ ε₁
[PROOFSTEP]
have : 0 ≤ ε₁ := le_trans dist_nonneg Dxs
[GOAL]
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, 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
this✝² : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝¹ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this : 0 ≤ ε₁
⊢ hausdorffDist univ s ≤ ε₁
[PROOFSTEP]
refine' hausdorffDist_le_of_mem_dist this (fun x _ => hs x) fun x _ => ⟨x, mem_univ _, by simpa only [dist_self]⟩
[GOAL]
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, 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
this✝² : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝¹ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this : 0 ≤ ε₁
x : X
x✝ : x ∈ s
⊢ dist x x ≤ ε₁
[PROOFSTEP]
simpa only [dist_self]
[GOAL]
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, 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
this✝² : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝¹ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ
[PROOFSTEP]
have : hausdorffDist (Fl '' s) (Fr '' range Φ) ≤ ε₂ / 2 + δ :=
  by
  refine' hausdorffDist_le_of_mem_dist (by linarith) _ _
  · intro x' hx'
    rcases(Set.mem_image _ _ _).1 hx' with ⟨x, ⟨x_in_s, xx'⟩⟩
    rw [← xx']
    use Fr (Φ ⟨x, x_in_s⟩), mem_image_of_mem Fr (mem_range_self _)
    exact le_of_eq (glueDist_glued_points (fun x : s => (x : X)) Φ (ε₂ / 2 + δ) ⟨x, x_in_s⟩)
  · intro x' hx'
    rcases(Set.mem_image _ _ _).1 hx' with ⟨y, ⟨y_in_s', yx'⟩⟩
    rcases mem_range.1 y_in_s' with ⟨x, xy⟩
    use Fl x, mem_image_of_mem _ x.2
    rw [← yx', ← xy, dist_comm]
    exact le_of_eq (glueDist_glued_points (Z := s) (@Subtype.val X s) Φ (ε₂ / 2 + δ) x)
[GOAL]
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, 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
this✝² : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝¹ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
⊢ hausdorffDist (Fl '' s) (Fr '' range Φ) ≤ ε₂ / 2 + δ
[PROOFSTEP]
refine' hausdorffDist_le_of_mem_dist (by linarith) _ _
[GOAL]
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, 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
this✝² : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝¹ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
⊢ 0 ≤ ε₂ / 2 + δ
[PROOFSTEP]
linarith
[GOAL]
case refine'_1
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, 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
this✝² : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝¹ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
⊢ ∀ (x : X ⊕ Y), x ∈ Fl '' s → ∃ y, y ∈ Fr '' range Φ ∧ dist x y ≤ ε₂ / 2 + δ
[PROOFSTEP]
intro x' hx'
[GOAL]
case refine'_1
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, 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
this✝² : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝¹ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
x' : X ⊕ Y
hx' : x' ∈ Fl '' s
⊢ ∃ y, y ∈ Fr '' range Φ ∧ dist x' y ≤ ε₂ / 2 + δ
[PROOFSTEP]
rcases(Set.mem_image _ _ _).1 hx' with ⟨x, ⟨x_in_s, xx'⟩⟩
[GOAL]
case refine'_1.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, 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
this✝² : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝¹ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
x' : X ⊕ Y
hx' : x' ∈ Fl '' s
x : X
x_in_s : x ∈ s
xx' : Fl x = x'
⊢ ∃ y, y ∈ Fr '' range Φ ∧ dist x' y ≤ ε₂ / 2 + δ
[PROOFSTEP]
rw [← xx']
[GOAL]
case refine'_1.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, 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
this✝² : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝¹ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
x' : X ⊕ Y
hx' : x' ∈ Fl '' s
x : X
x_in_s : x ∈ s
xx' : Fl x = x'
⊢ ∃ y, y ∈ Fr '' range Φ ∧ dist (Fl x) y ≤ ε₂ / 2 + δ
[PROOFSTEP]
use Fr (Φ ⟨x, x_in_s⟩), mem_image_of_mem Fr (mem_range_self _)
[GOAL]
case right
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, 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
this✝² : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝¹ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
x' : X ⊕ Y
hx' : x' ∈ Fl '' s
x : X
x_in_s : x ∈ s
xx' : Fl x = x'
⊢ dist (Fl x) (Fr (Φ { val := x, property := x_in_s })) ≤ ε₂ / 2 + δ
[PROOFSTEP]
exact le_of_eq (glueDist_glued_points (fun x : s => (x : X)) Φ (ε₂ / 2 + δ) ⟨x, x_in_s⟩)
[GOAL]
case refine'_2
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, 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
this✝² : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝¹ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
⊢ ∀ (x : X ⊕ Y), x ∈ Fr '' range Φ → ∃ y, y ∈ Fl '' s ∧ dist x y ≤ ε₂ / 2 + δ
[PROOFSTEP]
intro x' hx'
[GOAL]
case refine'_2
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, 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
this✝² : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝¹ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
x' : X ⊕ Y
hx' : x' ∈ Fr '' range Φ
⊢ ∃ y, y ∈ Fl '' s ∧ dist x' y ≤ ε₂ / 2 + δ
[PROOFSTEP]
rcases(Set.mem_image _ _ _).1 hx' with ⟨y, ⟨y_in_s', yx'⟩⟩
[GOAL]
case refine'_2.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, 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
this✝² : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝¹ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
x' : X ⊕ Y
hx' : x' ∈ Fr '' range Φ
y : Y
y_in_s' : y ∈ range Φ
yx' : Fr y = x'
⊢ ∃ y, y ∈ Fl '' s ∧ dist x' y ≤ ε₂ / 2 + δ
[PROOFSTEP]
rcases mem_range.1 y_in_s' with ⟨x, xy⟩
[GOAL]
case refine'_2.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, 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
this✝² : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝¹ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
x' : X ⊕ Y
hx' : x' ∈ Fr '' range Φ
y : Y
y_in_s' : y ∈ range Φ
yx' : Fr y = x'
x : ↑s
xy : Φ x = y
⊢ ∃ y, y ∈ Fl '' s ∧ dist x' y ≤ ε₂ / 2 + δ
[PROOFSTEP]
use Fl x, mem_image_of_mem _ x.2
[GOAL]
case right
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, 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
this✝² : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝¹ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
x' : X ⊕ Y
hx' : x' ∈ Fr '' range Φ
y : Y
y_in_s' : y ∈ range Φ
yx' : Fr y = x'
x : ↑s
xy : Φ x = y
⊢ dist x' (Fl ↑x) ≤ ε₂ / 2 + δ
[PROOFSTEP]
rw [← yx', ← xy, dist_comm]
[GOAL]
case right
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, 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
this✝² : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝¹ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
x' : X ⊕ Y
hx' : x' ∈ Fr '' range Φ
y : Y
y_in_s' : y ∈ range Φ
yx' : Fr y = x'
x : ↑s
xy : Φ x = y
⊢ dist (Fl ↑x) (Fr (Φ x)) ≤ ε₂ / 2 + δ
[PROOFSTEP]
exact le_of_eq (glueDist_glued_points (Z := s) (@Subtype.val X s) Φ (ε₂ / 2 + δ) x)
[GOAL]
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, 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
this✝³ : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝² : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝¹ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this✝ : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
this : hausdorffDist (Fl '' s) (Fr '' range Φ) ≤ ε₂ / 2 + δ
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ
[PROOFSTEP]
have : hausdorffDist (Fr '' range Φ) (range Fr) ≤ ε₃ :=
  by
  rw [← @image_univ _ _ Fr, hausdorffDist_image Ir]
  rcases exists_mem_of_nonempty Y with ⟨xY, _⟩
  rcases hs' xY with ⟨xs', Dxs'⟩
  have : 0 ≤ ε₃ := le_trans dist_nonneg Dxs'
  refine hausdorffDist_le_of_mem_dist this (fun x _ => ⟨x, mem_univ _, by simpa only [dist_self]⟩) fun x _ => ?_
  rcases hs' x with ⟨y, Dy⟩
  exact ⟨Φ y, mem_range_self _, Dy⟩
[GOAL]
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, 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
this✝³ : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝² : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝¹ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this✝ : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
this : hausdorffDist (Fl '' s) (Fr '' range Φ) ≤ ε₂ / 2 + δ
⊢ hausdorffDist (Fr '' range Φ) (range Fr) ≤ ε₃
[PROOFSTEP]
rw [← @image_univ _ _ Fr, hausdorffDist_image Ir]
[GOAL]
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, 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
this✝³ : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝² : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝¹ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this✝ : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
this : hausdorffDist (Fl '' s) (Fr '' range Φ) ≤ ε₂ / 2 + δ
⊢ hausdorffDist (range Φ) univ ≤ ε₃
[PROOFSTEP]
rcases exists_mem_of_nonempty Y with ⟨xY, _⟩
[GOAL]
case 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, 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
this✝³ : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝² : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝¹ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this✝ : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
this : hausdorffDist (Fl '' s) (Fr '' range Φ) ≤ ε₂ / 2 + δ
xY : Y
h✝ : xY ∈ univ
⊢ hausdorffDist (range Φ) univ ≤ ε₃
[PROOFSTEP]
rcases hs' xY with ⟨xs', Dxs'⟩
[GOAL]
case 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, 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
this✝³ : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝² : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝¹ :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this✝ : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
this : hausdorffDist (Fl '' s) (Fr '' range Φ) ≤ ε₂ / 2 + δ
xY : Y
h✝ : xY ∈ univ
xs' : ↑s
Dxs' : dist xY (Φ xs') ≤ ε₃
⊢ hausdorffDist (range Φ) univ ≤ ε₃
[PROOFSTEP]
have : 0 ≤ ε₃ := le_trans dist_nonneg Dxs'
[GOAL]
case 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, 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
this✝⁴ : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝³ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝² :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this✝¹ : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
this✝ : hausdorffDist (Fl '' s) (Fr '' range Φ) ≤ ε₂ / 2 + δ
xY : Y
h✝ : xY ∈ univ
xs' : ↑s
Dxs' : dist xY (Φ xs') ≤ ε₃
this : 0 ≤ ε₃
⊢ hausdorffDist (range Φ) univ ≤ ε₃
[PROOFSTEP]
refine hausdorffDist_le_of_mem_dist this (fun x _ => ⟨x, mem_univ _, by simpa only [dist_self]⟩) fun x _ => ?_
[GOAL]
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, 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
this✝⁴ : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝³ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝² :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this✝¹ : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
this✝ : hausdorffDist (Fl '' s) (Fr '' range Φ) ≤ ε₂ / 2 + δ
xY : Y
h✝ : xY ∈ univ
xs' : ↑s
Dxs' : dist xY (Φ xs') ≤ ε₃
this : 0 ≤ ε₃
x : Y
x✝ : x ∈ range Φ
⊢ dist x x ≤ ε₃
[PROOFSTEP]
simpa only [dist_self]
[GOAL]
case 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, 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
this✝⁴ : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝³ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝² :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this✝¹ : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
this✝ : hausdorffDist (Fl '' s) (Fr '' range Φ) ≤ ε₂ / 2 + δ
xY : Y
h✝ : xY ∈ univ
xs' : ↑s
Dxs' : dist xY (Φ xs') ≤ ε₃
this : 0 ≤ ε₃
x : Y
x✝ : x ∈ univ
⊢ ∃ y, y ∈ range Φ ∧ dist x y ≤ ε₃
[PROOFSTEP]
rcases hs' x with ⟨y, Dy⟩
[GOAL]
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, 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
this✝⁴ : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝³ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝² :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this✝¹ : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
this✝ : hausdorffDist (Fl '' s) (Fr '' range Φ) ≤ ε₂ / 2 + δ
xY : Y
h✝ : xY ∈ univ
xs' : ↑s
Dxs' : dist xY (Φ xs') ≤ ε₃
this : 0 ≤ ε₃
x : Y
x✝ : x ∈ univ
y : ↑s
Dy : dist x (Φ y) ≤ ε₃
⊢ ∃ y, y ∈ range Φ ∧ dist x y ≤ ε₃
[PROOFSTEP]
exact ⟨Φ y, mem_range_self _, Dy⟩
[GOAL]
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, 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
this✝⁴ : ghDist X Y ≤ hausdorffDist (range Fl) (range Fr)
this✝³ : hausdorffDist (range Fl) (range Fr) ≤ hausdorffDist (range Fl) (Fl '' s) + hausdorffDist (Fl '' s) (range Fr)
this✝² :
  hausdorffDist (Fl '' s) (range Fr) ≤
    hausdorffDist (Fl '' s) (Fr '' range Φ) + hausdorffDist (Fr '' range Φ) (range Fr)
this✝¹ : hausdorffDist (range Fl) (Fl '' s) ≤ ε₁
this✝ : hausdorffDist (Fl '' s) (Fr '' range Φ) ≤ ε₂ / 2 + δ
this : hausdorffDist (Fr '' range Φ) (range Fr) ≤ ε₃
⊢ ghDist X Y ≤ ε₁ + ε₂ / 2 + ε₃ + δ
[PROOFSTEP]
linarith
[GOAL]
⊢ SecondCountableTopology GHSpace
[PROOFSTEP]
refine' secondCountable_of_countable_discretization fun δ δpos => _
[GOAL]
δ : ℝ
δpos : δ > 0
⊢ ∃ β x F, ∀ (x y : GHSpace), F x = F y → dist x y ≤ δ
[PROOFSTEP]
let ε := 2 / 5 * δ
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
⊢ ∃ β x F, ∀ (x y : GHSpace), F x = F y → dist x y ≤ δ
[PROOFSTEP]
have εpos : 0 < ε := mul_pos (by norm_num) δpos
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
⊢ 0 < 2 / 5
[PROOFSTEP]
norm_num
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
⊢ ∃ β x F, ∀ (x y : GHSpace), F x = F y → dist x y ≤ δ
[PROOFSTEP]
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
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
p : GHSpace
⊢ ∃ s, Set.Finite s ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x ε
[PROOFSTEP]
simpa only [subset_univ, true_and] using finite_cover_balls_of_compact (α := p.Rep) isCompact_univ εpos
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
this : ∀ (p : GHSpace), ∃ s, Set.Finite s ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x ε
⊢ ∃ β x F, ∀ (x y : GHSpace), F x = F y → dist x y ≤ δ
[PROOFSTEP]
choose s hs using this
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x ε
⊢ ∃ β x F, ∀ (x y : GHSpace), F x = F y → dist x y ≤ δ
[PROOFSTEP]
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⟩
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x ε
⊢ ∀ (p : GHSpace) (t : Set (GHSpace.Rep p)), Set.Finite t → ∃ n x, True
[PROOFSTEP]
intro p t ht
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x ε
p : GHSpace
t : Set (GHSpace.Rep p)
ht : Set.Finite t
⊢ ∃ n x, True
[PROOFSTEP]
letI : Fintype t := Finite.fintype ht
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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
[PROOFSTEP]
exact ⟨Fintype.card t, Fintype.equivFin t, trivial⟩
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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 ≤ δ
[PROOFSTEP]
choose N e _ using this
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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 ≤ δ
[PROOFSTEP]
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`
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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 ≤ δ
[PROOFSTEP]
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`.
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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 ≤ δ
[PROOFSTEP]
let F : GHSpace → Σ n : ℕ, Fin n → Fin n → ℤ := fun p => ⟨N p, fun a b => ⌊ε⁻¹ * dist ((E p).symm a) ((E p).symm b)⌋⟩
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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 ≤ δ
[PROOFSTEP]
refine'
  ⟨Σ n, Fin n → Fin n → ℤ, by infer_instance, F, fun p q hpq => _⟩
    /- As the target space of F is countable, it suffices to show that two points
        `p` and `q` with `F p = F q` are at distance `≤ δ`.
        For this, we construct a map `Φ` from `s p ⊆ p.rep` (representing `p`)
        to `q.rep` (representing `q`) which is almost an isometry on `s p`, and
        with image `s q`. For this, we compose the identification of `s p` with `fin (N p)`
        and the inverse of the identification of `s q` with `fin (N q)`. Together with
        the fact that `N p = N q`, this constructs `Ψ` between `s p` and `s q`, and then
        composing with the canonical inclusion we get `Φ`. -/
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
⊢ Encodable ((n : ℕ) × (Fin n → Fin n → ℤ))
[PROOFSTEP]
infer_instance
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
⊢ dist p q ≤ δ
[PROOFSTEP]
have Npq : N p = N q := (Sigma.mk.inj_iff.1 hpq).1
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
⊢ dist p q ≤ δ
[PROOFSTEP]
let Ψ : s p → s q := fun x => (E q).symm (Fin.castIso Npq ((E p) x))
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
⊢ dist p q ≤ δ
[PROOFSTEP]
let Φ : s p → q.Rep := fun x => Ψ x
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ dist p q ≤ δ
[PROOFSTEP]
have main : ghDist p.Rep q.Rep ≤ ε + ε / 2 + ε :=
  by
  refine' ghDist_le_of_approx_subsets Φ _ _ _
  show ∀ x : p.Rep, ∃ y ∈ s p, dist x y ≤ ε
  ·
    -- by construction, `s p` is `ε`-dense
    intro x
    have : x ∈ ⋃ y ∈ s p, ball y ε := (hs p).2 (mem_univ _)
    rcases mem_iUnion₂.1 this with ⟨y, ys, hy⟩
    exact ⟨y, ys, le_of_lt hy⟩
  show ∀ x : q.Rep, ∃ z : s p, dist x (Φ z) ≤ ε
  ·
    -- by construction, `s q` is `ε`-dense, and it is the range of `Φ`
    intro x
    have : x ∈ ⋃ y ∈ s q, ball y ε := (hs q).2 (mem_univ _)
    rcases mem_iUnion₂.1 this with ⟨y, ys, hy⟩
    let i : ℕ := E q ⟨y, ys⟩
    let hi := ((E q) ⟨y, ys⟩).is_lt
    have ihi_eq : (⟨i, hi⟩ : Fin (N q)) = (E q) ⟨y, ys⟩ := by rw [Fin.ext_iff, Fin.val_mk]
    have hiq : i < N q := hi
    have hip : i < N p := by rwa [Npq.symm] at hiq 
    let z := (E p).symm ⟨i, hip⟩
    use z
    have C1 : (E p) z = ⟨i, hip⟩ := (E p).apply_symm_apply ⟨i, hip⟩
    have C2 : Fin.castIso Npq ⟨i, hip⟩ = ⟨i, hi⟩ := rfl
    have C3 : (E q).symm ⟨i, hi⟩ = ⟨y, ys⟩ := by rw [ihi_eq]; exact (E q).symm_apply_apply ⟨y, ys⟩
    have : Φ z = y := by simp only; rw [C1, C2, C3]
    rw [this]
    exact le_of_lt hy
  show ∀ x y : s p, |dist x y - dist (Φ x) (Φ y)| ≤ ε
  ·
    /- the distance between `x` and `y` is encoded in `F p`, and the distance between
                `Φ x` and `Φ y` (two points of `s q`) is encoded in `F q`, all this up to `ε`.
                As `F p = F q`, the distances are almost equal. -/
          -- porting note : we have to circumvent the absence of `change … with … `
    intro x y
    rw [show dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y) from rfl]
      -- introduce `i`, that codes both `x` and `Φ x` in `fin (N p) = fin (N q)`
    let i : ℕ := E p x
    have hip : i < N p := ((E p) x).2
    have hiq : i < N q := by rwa [Npq] at hip 
    have i' : i = (E q) (Ψ x) := by
      simp only [Equiv.apply_symm_apply, Fin.coe_castIso]
        -- introduce `j`, that codes both `y` and `Φ y` in `fin (N p) = fin (N q)`
    let j : ℕ := E p y
    have hjp : j < N p := ((E p) y).2
    have hjq : j < N q := by rwa [Npq] at hjp 
    have j' : j = ((E q) (Ψ y)).1 := by
      simp only [Equiv.apply_symm_apply, Fin.coe_castIso]
        -- Express `dist x y` in terms of `F p`
    have : (F p).2 ((E p) x) ((E p) y) = ⌊ε⁻¹ * dist x y⌋ := by simp only [(E p).symm_apply_apply]
    have Ap : (F p).2 ⟨i, hip⟩ ⟨j, hjp⟩ = ⌊ε⁻¹ * dist x y⌋ := by
      rw [← this]
        -- Express `dist (Φ x) (Φ y)` in terms of `F q`
    have : (F q).2 ((E q) (Ψ x)) ((E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋ := by simp only [(E q).symm_apply_apply]
    have Aq : (F q).2 ⟨i, hiq⟩ ⟨j, hjq⟩ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋ :=
      by
      rw [← this]
        -- porting note: `congr` fails to make progress
      refine congr_arg₂ (F q).2 ?_ ?_ <;> ext1
      exacts [i', j']
        -- use the equality between `F p` and `F q` to deduce that the distances have equal
              -- integer parts
    have : (F p).2 ⟨i, hip⟩ ⟨j, hjp⟩ = (F q).2 ⟨i, hiq⟩ ⟨j, hjq⟩ :=
      by
      have hpq' : HEq (F p).snd (F q).snd := (Sigma.mk.inj_iff.1 hpq).2
      rw [Fin.heq_fun₂_iff Npq Npq] at hpq' 
      rw [← hpq']
        -- porting note : new version above, because `change … with…` is not implemented
                -- we want to `subst hpq` where `hpq : F p = F q`, except that `subst` only works
                -- with a constant, so replace `F q` (and everything that depends on it) by a constant `f`
                -- then `subst`
                -- revert hiq hjq
                -- change N q with (F q).1
                -- generalize F q = f at hpq ⊢
                -- subst hpq
                -- rfl
    rw [Ap, Aq] at this 
    have I :=
      calc
        |ε⁻¹| * |dist x y - dist (Ψ x) (Ψ y)| = |ε⁻¹ * (dist x y - dist (Ψ x) (Ψ y))| := (abs_mul _ _).symm
        _ = |ε⁻¹ * dist x y - ε⁻¹ * dist (Ψ x) (Ψ y)| := by congr; ring
        _ ≤ 1 := le_of_lt (abs_sub_lt_one_of_floor_eq_floor this)
    calc
      |dist x y - dist (Ψ x) (Ψ y)| = ε * ε⁻¹ * |dist x y - dist (Ψ x) (Ψ y)| := by
        rw [mul_inv_cancel (ne_of_gt εpos), one_mul]
      _ = ε * (|ε⁻¹| * |dist x y - dist (Ψ x) (Ψ y)|) := by rw [abs_of_nonneg (le_of_lt (inv_pos.2 εpos)), mul_assoc]
      _ ≤ ε * 1 := (mul_le_mul_of_nonneg_left I (le_of_lt εpos))
      _ = ε := mul_one _
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ghDist (GHSpace.Rep p) (GHSpace.Rep q) ≤ ε + ε / 2 + ε
[PROOFSTEP]
refine' ghDist_le_of_approx_subsets Φ _ _ _
[GOAL]
case refine'_1
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x : GHSpace.Rep p), ∃ y, y ∈ s p ∧ dist x y ≤ ε
case refine'_2
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x : GHSpace.Rep q), ∃ y, dist x (Φ y) ≤ ε
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x y : ↑(s p)), |dist x y - dist (Φ x) (Φ y)| ≤ ε
[PROOFSTEP]
show ∀ x : p.Rep, ∃ y ∈ s p, dist x y ≤ ε
[GOAL]
case refine'_1
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x : GHSpace.Rep p), ∃ y, y ∈ s p ∧ dist x y ≤ ε
[PROOFSTEP]
intro x
[GOAL]
case refine'_1
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep p
⊢ ∃ y, y ∈ s p ∧ dist x y ≤ ε
[PROOFSTEP]
have : x ∈ ⋃ y ∈ s p, ball y ε := (hs p).2 (mem_univ _)
[GOAL]
case refine'_1
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep p
this : x ∈ ⋃ (y : GHSpace.Rep p) (_ : y ∈ s p), ball y ε
⊢ ∃ y, y ∈ s p ∧ dist x y ≤ ε
[PROOFSTEP]
rcases mem_iUnion₂.1 this with ⟨y, ys, hy⟩
[GOAL]
case refine'_1.intro.intro
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep p
this : x ∈ ⋃ (y : GHSpace.Rep p) (_ : y ∈ s p), ball y ε
y : GHSpace.Rep p
ys : y ∈ s p
hy : x ∈ ball y ε
⊢ ∃ y, y ∈ s p ∧ dist x y ≤ ε
[PROOFSTEP]
exact ⟨y, ys, le_of_lt hy⟩
[GOAL]
case refine'_2
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x : GHSpace.Rep q), ∃ y, dist x (Φ y) ≤ ε
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x y : ↑(s p)), |dist x y - dist (Φ x) (Φ y)| ≤ ε
[PROOFSTEP]
show ∀ x : q.Rep, ∃ z : s p, dist x (Φ z) ≤ ε
[GOAL]
case refine'_2
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x : GHSpace.Rep q), ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
intro x
[GOAL]
case refine'_2
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
have : x ∈ ⋃ y ∈ s q, ball y ε := (hs q).2 (mem_univ _)
[GOAL]
case refine'_2
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
rcases mem_iUnion₂.1 this with ⟨y, ys, hy⟩
[GOAL]
case refine'_2.intro.intro
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
let i : ℕ := E q ⟨y, ys⟩
[GOAL]
case refine'_2.intro.intro
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
let hi := ((E q) ⟨y, ys⟩).is_lt
[GOAL]
case refine'_2.intro.intro
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N✝ q (s q) (_ : Set.Finite (s q)) :=
  Fin.is_lt (↑(E q) { val := y, property := ys })
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
have ihi_eq : (⟨i, hi⟩ : Fin (N q)) = (E q) ⟨y, ys⟩ := by rw [Fin.ext_iff, Fin.val_mk]
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N✝ q (s q) (_ : Set.Finite (s q)) :=
  Fin.is_lt (↑(E q) { val := y, property := ys })
⊢ { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
[PROOFSTEP]
rw [Fin.ext_iff, Fin.val_mk]
[GOAL]
case refine'_2.intro.intro
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N✝ q (s q) (_ : Set.Finite (s q)) :=
  Fin.is_lt (↑(E q) { val := y, property := ys })
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
have hiq : i < N q := hi
[GOAL]
case refine'_2.intro.intro
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N✝ q (s q) (_ : Set.Finite (s q)) :=
  Fin.is_lt (↑(E q) { val := y, property := ys })
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
have hip : i < N p := by rwa [Npq.symm] at hiq 
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N✝ q (s q) (_ : Set.Finite (s q)) :=
  Fin.is_lt (↑(E q) { val := y, property := ys })
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
⊢ i < N p
[PROOFSTEP]
rwa [Npq.symm] at hiq 
[GOAL]
case refine'_2.intro.intro
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N✝ q (s q) (_ : Set.Finite (s q)) :=
  Fin.is_lt (↑(E q) { val := y, property := ys })
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
let z := (E p).symm ⟨i, hip⟩
[GOAL]
case refine'_2.intro.intro
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N✝ q (s q) (_ : Set.Finite (s q)) :=
  Fin.is_lt (↑(E q) { val := y, property := ys })
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
use z
[GOAL]
case h
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N✝ q (s q) (_ : Set.Finite (s q)) :=
  Fin.is_lt (↑(E q) { val := y, property := ys })
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
⊢ dist x (Φ z) ≤ ε
[PROOFSTEP]
have C1 : (E p) z = ⟨i, hip⟩ := (E p).apply_symm_apply ⟨i, hip⟩
[GOAL]
case h
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N✝ q (s q) (_ : Set.Finite (s q)) :=
  Fin.is_lt (↑(E q) { val := y, property := ys })
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
⊢ dist x (Φ z) ≤ ε
[PROOFSTEP]
have C2 : Fin.castIso Npq ⟨i, hip⟩ = ⟨i, hi⟩ := rfl
[GOAL]
case h
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N✝ q (s q) (_ : Set.Finite (s q)) :=
  Fin.is_lt (↑(E q) { val := y, property := ys })
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
C2 : ↑(Fin.castIso Npq) { val := i, isLt := hip } = { val := i, isLt := hi }
⊢ dist x (Φ z) ≤ ε
[PROOFSTEP]
have C3 : (E q).symm ⟨i, hi⟩ = ⟨y, ys⟩ := by rw [ihi_eq]; exact (E q).symm_apply_apply ⟨y, ys⟩
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N✝ q (s q) (_ : Set.Finite (s q)) :=
  Fin.is_lt (↑(E q) { val := y, property := ys })
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
C2 : ↑(Fin.castIso Npq) { val := i, isLt := hip } = { val := i, isLt := hi }
⊢ ↑(E q).symm { val := i, isLt := hi } = { val := y, property := ys }
[PROOFSTEP]
rw [ihi_eq]
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N✝ q (s q) (_ : Set.Finite (s q)) :=
  Fin.is_lt (↑(E q) { val := y, property := ys })
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
C2 : ↑(Fin.castIso Npq) { val := i, isLt := hip } = { val := i, isLt := hi }
⊢ ↑(E q).symm (↑(E q) { val := y, property := ys }) = { val := y, property := ys }
[PROOFSTEP]
exact (E q).symm_apply_apply ⟨y, ys⟩
[GOAL]
case h
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N✝ q (s q) (_ : Set.Finite (s q)) :=
  Fin.is_lt (↑(E q) { val := y, property := ys })
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
C2 : ↑(Fin.castIso Npq) { val := i, isLt := hip } = { val := i, isLt := hi }
C3 : ↑(E q).symm { val := i, isLt := hi } = { val := y, property := ys }
⊢ dist x (Φ z) ≤ ε
[PROOFSTEP]
have : Φ z = y := by simp only; rw [C1, C2, C3]
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N✝ q (s q) (_ : Set.Finite (s q)) :=
  Fin.is_lt (↑(E q) { val := y, property := ys })
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
C2 : ↑(Fin.castIso Npq) { val := i, isLt := hip } = { val := i, isLt := hi }
C3 : ↑(E q).symm { val := i, isLt := hi } = { val := y, property := ys }
⊢ Φ z = y
[PROOFSTEP]
simp only
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N✝ q (s q) (_ : Set.Finite (s q)) :=
  Fin.is_lt (↑(E q) { val := y, property := ys })
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
C2 : ↑(Fin.castIso Npq) { val := i, isLt := hip } = { val := i, isLt := hi }
C3 : ↑(E q).symm { val := i, isLt := hi } = { val := y, property := ys }
⊢ ↑(↑(e q (s q) (_ : Set.Finite (s q))).symm
        (↑(Fin.castIso Npq)
          (↑(e p (s p) (_ : Set.Finite (s p)))
            (↑(e p (s p) (_ : Set.Finite (s p))).symm
              { val := ↑(↑(e q (s q) (_ : Set.Finite (s q))) { val := y, property := ys }), isLt := hip })))) =
    y
[PROOFSTEP]
rw [C1, C2, C3]
[GOAL]
case h
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this✝ : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N✝ q (s q) (_ : Set.Finite (s q)) :=
  Fin.is_lt (↑(E q) { val := y, property := ys })
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
C2 : ↑(Fin.castIso Npq) { val := i, isLt := hip } = { val := i, isLt := hi }
C3 : ↑(E q).symm { val := i, isLt := hi } = { val := y, property := ys }
this : Φ z = y
⊢ dist x (Φ z) ≤ ε
[PROOFSTEP]
rw [this]
[GOAL]
case h
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this✝ : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y ε
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y ε
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N✝ q (s q) (_ : Set.Finite (s q)) :=
  Fin.is_lt (↑(E q) { val := y, property := ys })
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
C2 : ↑(Fin.castIso Npq) { val := i, isLt := hip } = { val := i, isLt := hi }
C3 : ↑(E q).symm { val := i, isLt := hi } = { val := y, property := ys }
this : Φ z = y
⊢ dist x y ≤ ε
[PROOFSTEP]
exact le_of_lt hy
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x y : ↑(s p)), |dist x y - dist (Φ x) (Φ y)| ≤ ε
[PROOFSTEP]
show ∀ x y : s p, |dist x y - dist (Φ x) (Φ y)| ≤ ε
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x y : ↑(s p)), |dist x y - dist (Φ x) (Φ y)| ≤ ε
[PROOFSTEP]
intro x y
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
⊢ |dist x y - dist (Φ x) (Φ y)| ≤ ε
[PROOFSTEP]
rw [show dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y) from rfl]
  -- introduce `i`, that codes both `x` and `Φ x` in `fin (N p) = fin (N q)`
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
let i : ℕ := E p x
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have hip : i < N p := ((E p) x).2
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have hiq : i < N q := by rwa [Npq] at hip 
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
⊢ i < N q
[PROOFSTEP]
rwa [Npq] at hip 
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have i' : i = (E q) (Ψ x) := by
  simp only [Equiv.apply_symm_apply, Fin.coe_castIso]
    -- introduce `j`, that codes both `y` and `Φ y` in `fin (N p) = fin (N q)`
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
⊢ i = ↑(↑(E q) (Ψ x))
[PROOFSTEP]
simp only [Equiv.apply_symm_apply, Fin.coe_castIso]
  -- introduce `j`, that codes both `y` and `Φ y` in `fin (N p) = fin (N q)`
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
let j : ℕ := E p y
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have hjp : j < N p := ((E p) y).2
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have hjq : j < N q := by rwa [Npq] at hjp 
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
⊢ j < N q
[PROOFSTEP]
rwa [Npq] at hjp 
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have j' : j = ((E q) (Ψ y)).1 := by
  simp only [Equiv.apply_symm_apply, Fin.coe_castIso]
    -- Express `dist x y` in terms of `F p`
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
⊢ j = ↑(↑(E q) (Ψ y))
[PROOFSTEP]
simp only [Equiv.apply_symm_apply, Fin.coe_castIso]
  -- Express `dist x y` in terms of `F p`
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have : (F p).2 ((E p) x) ((E p) y) = ⌊ε⁻¹ * dist x y⌋ := by simp only [(E p).symm_apply_apply]
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
⊢ Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
[PROOFSTEP]
simp only [(E p).symm_apply_apply]
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have Ap : (F p).2 ⟨i, hip⟩ ⟨j, hjp⟩ = ⌊ε⁻¹ * dist x y⌋ := by
  rw [← this]
    -- Express `dist (Φ x) (Φ y)` in terms of `F q`
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
⊢ Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
[PROOFSTEP]
rw [← this]
  -- Express `dist (Φ x) (Φ y)` in terms of `F q`
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have : (F q).2 ((E q) (Ψ x)) ((E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋ := by simp only [(E q).symm_apply_apply]
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
⊢ Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
[PROOFSTEP]
simp only [(E q).symm_apply_apply]
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have Aq : (F q).2 ⟨i, hiq⟩ ⟨j, hjq⟩ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋ :=
  by
  rw [← this]
    -- porting note: `congr` fails to make progress
  refine congr_arg₂ (F q).2 ?_ ?_ <;> ext1
  exacts [i', j']
    -- use the equality between `F p` and `F q` to deduce that the distances have equal
          -- integer parts
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
⊢ Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq } = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
[PROOFSTEP]
rw [← this]
  -- porting note: `congr` fails to make progress
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
⊢ Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq } = Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y))
[PROOFSTEP]
refine congr_arg₂ (F q).2 ?_ ?_
[GOAL]
case refine_1
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
⊢ { val := i, isLt := hiq } = ↑(E q) (Ψ x)
[PROOFSTEP]
ext1
[GOAL]
case refine_2
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
⊢ { val := j, isLt := hjq } = ↑(E q) (Ψ y)
[PROOFSTEP]
ext1
[GOAL]
case refine_1.h
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
⊢ ↑{ val := i, isLt := hiq } = ↑(↑(E q) (Ψ x))
case refine_2.h
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
⊢ ↑{ val := j, isLt := hjq } = ↑(↑(E q) (Ψ y))
[PROOFSTEP]
exacts [i', j']
  -- use the equality between `F p` and `F q` to deduce that the distances have equal
        -- integer parts
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
Aq : Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq } = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have : (F p).2 ⟨i, hip⟩ ⟨j, hjp⟩ = (F q).2 ⟨i, hiq⟩ ⟨j, hjq⟩ :=
  by
  have hpq' : HEq (F p).snd (F q).snd := (Sigma.mk.inj_iff.1 hpq).2
  rw [Fin.heq_fun₂_iff Npq Npq] at hpq' 
  rw [← hpq']
    -- porting note : new version above, because `change … with…` is not implemented
            -- we want to `subst hpq` where `hpq : F p = F q`, except that `subst` only works
            -- with a constant, so replace `F q` (and everything that depends on it) by a constant `f`
            -- then `subst`
            -- revert hiq hjq
            -- change N q with (F q).1
            -- generalize F q = f at hpq ⊢
            -- subst hpq
            -- rfl
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
Aq : Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq } = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
⊢ Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } =
    Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }
[PROOFSTEP]
have hpq' : HEq (F p).snd (F q).snd := (Sigma.mk.inj_iff.1 hpq).2
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
Aq : Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq } = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
hpq' : HEq (F p).snd (F q).snd
⊢ Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } =
    Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }
[PROOFSTEP]
rw [Fin.heq_fun₂_iff Npq Npq] at hpq' 
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
Aq : Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq } = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
hpq' :
  ∀ (i j : Fin (N p)),
    Sigma.snd (F p) i j = Sigma.snd (F q) { val := ↑i, isLt := (_ : ↑i < N q) } { val := ↑j, isLt := (_ : ↑j < N q) }
⊢ Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } =
    Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }
[PROOFSTEP]
rw [← hpq']
  -- porting note : new version above, because `change … with…` is not implemented
          -- we want to `subst hpq` where `hpq : F p = F q`, except that `subst` only works
          -- with a constant, so replace `F q` (and everything that depends on it) by a constant `f`
          -- then `subst`
          -- revert hiq hjq
          -- change N q with (F q).1
          -- generalize F q = f at hpq ⊢
          -- subst hpq
          -- rfl
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝¹ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this✝ : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
Aq : Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq } = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
this :
  Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } =
    Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
rw [Ap, Aq] at this 
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝¹ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this✝ : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
Aq : Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq } = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
this : ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have I :=
  calc
    |ε⁻¹| * |dist x y - dist (Ψ x) (Ψ y)| = |ε⁻¹ * (dist x y - dist (Ψ x) (Ψ y))| := (abs_mul _ _).symm
    _ = |ε⁻¹ * dist x y - ε⁻¹ * dist (Ψ x) (Ψ y)| := by congr; ring
    _ ≤ 1 := le_of_lt (abs_sub_lt_one_of_floor_eq_floor this)
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝¹ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this✝ : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
Aq : Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq } = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
this : ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
⊢ |ε⁻¹ * (dist x y - dist (Ψ x) (Ψ y))| = |ε⁻¹ * dist x y - ε⁻¹ * dist (Ψ x) (Ψ y)|
[PROOFSTEP]
congr
[GOAL]
case e_a
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝¹ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this✝ : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
Aq : Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq } = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
this : ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
⊢ ε⁻¹ * (dist x y - dist (Ψ x) (Ψ y)) = ε⁻¹ * dist x y - ε⁻¹ * dist (Ψ x) (Ψ y)
[PROOFSTEP]
ring
[GOAL]
case refine'_3
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝¹ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this✝ : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
Aq : Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq } = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
this : ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
I : |ε⁻¹| * |dist x y - dist (Ψ x) (Ψ y)| ≤ 1
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
calc
  |dist x y - dist (Ψ x) (Ψ y)| = ε * ε⁻¹ * |dist x y - dist (Ψ x) (Ψ y)| := by
    rw [mul_inv_cancel (ne_of_gt εpos), one_mul]
  _ = ε * (|ε⁻¹| * |dist x y - dist (Ψ x) (Ψ y)|) := by rw [abs_of_nonneg (le_of_lt (inv_pos.2 εpos)), mul_assoc]
  _ ≤ ε * 1 := (mul_le_mul_of_nonneg_left I (le_of_lt εpos))
  _ = ε := mul_one _
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝¹ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this✝ : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
Aq : Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq } = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
this : ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
I : |ε⁻¹| * |dist x y - dist (Ψ x) (Ψ y)| ≤ 1
⊢ |dist x y - dist (Ψ x) (Ψ y)| = ε * ε⁻¹ * |dist x y - dist (Ψ x) (Ψ y)|
[PROOFSTEP]
rw [mul_inv_cancel (ne_of_gt εpos), one_mul]
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
this✝¹ : Sigma.snd (F p) (↑(E p) x) (↑(E p) y) = ⌊ε⁻¹ * dist x y⌋
Ap : Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp } = ⌊ε⁻¹ * dist x y⌋
this✝ : Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
Aq : Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq } = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
this : ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
I : |ε⁻¹| * |dist x y - dist (Ψ x) (Ψ y)| ≤ 1
⊢ ε * ε⁻¹ * |dist x y - dist (Ψ x) (Ψ y)| = ε * (|ε⁻¹| * |dist x y - dist (Ψ x) (Ψ y)|)
[PROOFSTEP]
rw [abs_of_nonneg (le_of_lt (inv_pos.2 εpos)), mul_assoc]
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
main : ghDist (GHSpace.Rep p) (GHSpace.Rep q) ≤ ε + ε / 2 + ε
⊢ dist p q ≤ δ
[PROOFSTEP]
calc
  dist p q = ghDist p.Rep q.Rep := dist_ghDist p q
  _ ≤ ε + ε / 2 + ε := main
  _ = δ := by ring
[GOAL]
δ : ℝ
δpos : δ > 0
ε : ℝ := 2 / 5 * δ
εpos : 0 < ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
hs : ∀ (p : GHSpace), Set.Finite (s p) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : 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)⌋ }
p q : GHSpace
hpq : F p = F q
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
main : ghDist (GHSpace.Rep p) (GHSpace.Rep q) ≤ ε + ε / 2 + ε
⊢ ε + ε / 2 + ε = δ
[PROOFSTEP]
ring
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
⊢ TotallyBounded t
[PROOFSTEP]
refine' Metric.totallyBounded_of_finite_discretization fun δ δpos => _
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
⊢ ∃ β x F, ∀ (x y : ↑t), F x = F y → dist ↑x ↑y < δ
[PROOFSTEP]
let ε := 1 / 5 * δ
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
⊢ ∃ β x F, ∀ (x y : ↑t), F x = F y → dist ↑x ↑y < δ
[PROOFSTEP]
have εpos : 0 < ε := mul_pos (by norm_num) δpos
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
⊢ 0 < 1 / 5
[PROOFSTEP]
norm_num
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
⊢ ∃ β x F, ∀ (x y : ↑t), F x = F y → dist ↑x ↑y < δ
[PROOFSTEP]
rcases Metric.tendsto_atTop.1 ulim ε εpos with ⟨n, hn⟩
[GOAL]
case intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
⊢ ∃ β x F, ∀ (x y : ↑t), F x = F y → dist ↑x ↑y < δ
[PROOFSTEP]
have u_le_ε : u n ≤ ε := by
  have := hn n le_rfl
  simp only [Real.dist_eq, add_zero, sub_eq_add_neg, neg_zero] at this 
  exact
    le_of_lt
      (lt_of_le_of_lt (le_abs_self _) this)
        -- construct a finite subset `s p` of `p` which is `ε`-dense and has cardinal `≤ K n`
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
⊢ u n ≤ ε
[PROOFSTEP]
have := hn n le_rfl
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
this : dist (u n) 0 < ε
⊢ u n ≤ ε
[PROOFSTEP]
simp only [Real.dist_eq, add_zero, sub_eq_add_neg, neg_zero] at this 
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
this : |u n| < 1 / 5 * δ
⊢ u n ≤ ε
[PROOFSTEP]
exact
  le_of_lt
    (lt_of_le_of_lt (le_abs_self _) this)
      -- construct a finite subset `s p` of `p` which is `ε`-dense and has cardinal `≤ K n`
[GOAL]
case intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
⊢ ∃ β x F, ∀ (x y : ↑t), F x = F y → dist ↑x ↑y < δ
[PROOFSTEP]
have : ∀ p : GHSpace, ∃ s : Set p.Rep, ∃ N ≤ K n, ∃ _ : Equiv s (Fin N), p ∈ t → univ ⊆ ⋃ x ∈ s, ball x (u n) :=
  by
  intro p
  by_cases hp : p ∉ t
  · have : Nonempty (Equiv (∅ : Set p.Rep) (Fin 0)) := by rw [← Fintype.card_eq];
      simp only [empty_card', Fintype.card_fin]
    use∅, 0, bot_le, choice this
    exact fun hp' => (hp hp').elim
  · rcases hcov _ (Set.not_not_mem.1 hp) n with ⟨s, ⟨scard, scover⟩⟩
    rcases Cardinal.lt_aleph0.1 (lt_of_le_of_lt scard (Cardinal.nat_lt_aleph0 _)) with ⟨N, hN⟩
    rw [hN, Cardinal.natCast_le] at scard 
    have : #s = #(Fin N) := by rw [hN, Cardinal.mk_fin]
    cases' Quotient.exact this with E
    use s, N, scard, E
    simp only [scover, imp_true_iff]
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
⊢ ∀ (p : GHSpace), ∃ s N, N ≤ K n ∧ ∃ x, p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
[PROOFSTEP]
intro p
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
p : GHSpace
⊢ ∃ s N, N ≤ K n ∧ ∃ x, p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
[PROOFSTEP]
by_cases hp : p ∉ t
[GOAL]
case pos
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
p : GHSpace
hp : ¬p ∈ t
⊢ ∃ s N, N ≤ K n ∧ ∃ x, p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
[PROOFSTEP]
have : Nonempty (Equiv (∅ : Set p.Rep) (Fin 0)) := by rw [← Fintype.card_eq]; simp only [empty_card', Fintype.card_fin]
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
p : GHSpace
hp : ¬p ∈ t
⊢ Nonempty (↑∅ ≃ Fin 0)
[PROOFSTEP]
rw [← Fintype.card_eq]
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
p : GHSpace
hp : ¬p ∈ t
⊢ Fintype.card ↑∅ = Fintype.card (Fin 0)
[PROOFSTEP]
simp only [empty_card', Fintype.card_fin]
[GOAL]
case pos
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
p : GHSpace
hp : ¬p ∈ t
this : Nonempty (↑∅ ≃ Fin 0)
⊢ ∃ s N, N ≤ K n ∧ ∃ x, p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
[PROOFSTEP]
use∅, 0, bot_le, choice this
[GOAL]
case h
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
p : GHSpace
hp : ¬p ∈ t
this : Nonempty (↑∅ ≃ Fin 0)
⊢ p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ ∅), ball x (u n)
[PROOFSTEP]
exact fun hp' => (hp hp').elim
[GOAL]
case neg
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
p : GHSpace
hp : ¬¬p ∈ t
⊢ ∃ s N, N ≤ K n ∧ ∃ x, p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
[PROOFSTEP]
rcases hcov _ (Set.not_not_mem.1 hp) n with ⟨s, ⟨scard, scover⟩⟩
[GOAL]
case neg.intro.intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
p : GHSpace
hp : ¬¬p ∈ t
s : Set (GHSpace.Rep p)
scard : #↑s ≤ ↑(K n)
scover : univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
⊢ ∃ s N, N ≤ K n ∧ ∃ x, p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
[PROOFSTEP]
rcases Cardinal.lt_aleph0.1 (lt_of_le_of_lt scard (Cardinal.nat_lt_aleph0 _)) with ⟨N, hN⟩
[GOAL]
case neg.intro.intro.intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
p : GHSpace
hp : ¬¬p ∈ t
s : Set (GHSpace.Rep p)
scard : #↑s ≤ ↑(K n)
scover : univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
N : ℕ
hN : #↑s = ↑N
⊢ ∃ s N, N ≤ K n ∧ ∃ x, p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
[PROOFSTEP]
rw [hN, Cardinal.natCast_le] at scard 
[GOAL]
case neg.intro.intro.intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
p : GHSpace
hp : ¬¬p ∈ t
s : Set (GHSpace.Rep p)
scover : univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
N : ℕ
scard : N ≤ K n
hN : #↑s = ↑N
⊢ ∃ s N, N ≤ K n ∧ ∃ x, p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
[PROOFSTEP]
have : #s = #(Fin N) := by rw [hN, Cardinal.mk_fin]
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
p : GHSpace
hp : ¬¬p ∈ t
s : Set (GHSpace.Rep p)
scover : univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
N : ℕ
scard : N ≤ K n
hN : #↑s = ↑N
⊢ #↑s = #(Fin N)
[PROOFSTEP]
rw [hN, Cardinal.mk_fin]
[GOAL]
case neg.intro.intro.intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
p : GHSpace
hp : ¬¬p ∈ t
s : Set (GHSpace.Rep p)
scover : univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
N : ℕ
scard : N ≤ K n
hN : #↑s = ↑N
this : #↑s = #(Fin N)
⊢ ∃ s N, N ≤ K n ∧ ∃ x, p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
[PROOFSTEP]
cases' Quotient.exact this with E
[GOAL]
case neg.intro.intro.intro.intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
p : GHSpace
hp : ¬¬p ∈ t
s : Set (GHSpace.Rep p)
scover : univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
N : ℕ
scard : N ≤ K n
hN : #↑s = ↑N
this : #↑s = #(Fin N)
E : ↑s ≃ Fin N
⊢ ∃ s N, N ≤ K n ∧ ∃ x, p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
[PROOFSTEP]
use s, N, scard, E
[GOAL]
case h
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
p : GHSpace
hp : ¬¬p ∈ t
s : Set (GHSpace.Rep p)
scover : univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
N : ℕ
scard : N ≤ K n
hN : #↑s = ↑N
this : #↑s = #(Fin N)
E : ↑s ≃ Fin N
⊢ p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
[PROOFSTEP]
simp only [scover, imp_true_iff]
[GOAL]
case intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
this : ∀ (p : GHSpace), ∃ s N, N ≤ K n ∧ ∃ x, p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
⊢ ∃ β x F, ∀ (x y : ↑t), F x = F y → dist ↑x ↑y < δ
[PROOFSTEP]
choose s N hN E hs using this
[GOAL]
case intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
⊢ ∃ β x F, ∀ (x y : ↑t), F x = F y → dist ↑x ↑y < δ
[PROOFSTEP]
let M := ⌊ε⁻¹ * max C 0⌋₊
[GOAL]
case intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
⊢ ∃ β x F, ∀ (x y : ↑t), F x = F y → dist ↑x ↑y < δ
[PROOFSTEP]
let F : GHSpace → Σ k : Fin (K n).succ, Fin k → Fin k → Fin M.succ := fun p =>
  ⟨⟨N p, lt_of_le_of_lt (hN p) (Nat.lt_succ_self _)⟩, fun a b =>
    ⟨min M ⌊ε⁻¹ * dist ((E p).symm a) ((E p).symm b)⌋₊, (min_le_left _ _).trans_lt (Nat.lt_succ_self _)⟩⟩
[GOAL]
case intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
⊢ ∃ β x F, ∀ (x y : ↑t), F x = F y → dist ↑x ↑y < δ
[PROOFSTEP]
refine' ⟨_, _, fun p => F p, _⟩
[GOAL]
case intro.refine'_1
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
⊢ Fintype ((k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)))
case intro.refine'_2
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
⊢ ∀ (x y : ↑t), (fun p => F ↑p) x = (fun p => F ↑p) y → dist ↑x ↑y < δ
[PROOFSTEP]
infer_instance
  -- It remains to show that if `F p = F q`, then `p` and `q` are `ε`-close
[GOAL]
case intro.refine'_2
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
⊢ ∀ (x y : ↑t), (fun p => F ↑p) x = (fun p => F ↑p) y → dist ↑x ↑y < δ
[PROOFSTEP]
rintro ⟨p, pt⟩ ⟨q, qt⟩ hpq
[GOAL]
case intro.refine'_2.mk.mk
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
⊢ dist ↑{ val := p, property := pt } ↑{ val := q, property := qt } < δ
[PROOFSTEP]
have Npq : N p = N q := Fin.ext_iff.1 (Sigma.mk.inj_iff.1 hpq).1
[GOAL]
case intro.refine'_2.mk.mk
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
⊢ dist ↑{ val := p, property := pt } ↑{ val := q, property := qt } < δ
[PROOFSTEP]
let Ψ : s p → s q := fun x => (E q).symm (Fin.castIso Npq ((E p) x))
[GOAL]
case intro.refine'_2.mk.mk
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
⊢ dist ↑{ val := p, property := pt } ↑{ val := q, property := qt } < δ
[PROOFSTEP]
let Φ : s p → q.Rep := fun x => Ψ x
[GOAL]
case intro.refine'_2.mk.mk
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ dist ↑{ val := p, property := pt } ↑{ val := q, property := qt } < δ
[PROOFSTEP]
have main : ghDist p.Rep q.Rep ≤ ε + ε / 2 + ε := by
  -- to prove the main inequality, argue that `s p` is `ε`-dense in `p`, and `s q` is `ε`-dense
      -- in `q`, and `s p` and `s q` are almost isometric. Then closeness follows
      -- from `ghDist_le_of_approx_subsets`
  refine' ghDist_le_of_approx_subsets Φ _ _ _
  show ∀ x : p.Rep, ∃ y ∈ s p, dist x y ≤ ε
  ·
    -- by construction, `s p` is `ε`-dense
    intro x
    have : x ∈ ⋃ y ∈ s p, ball y (u n) := (hs p pt) (mem_univ _)
    rcases mem_iUnion₂.1 this with ⟨y, ys, hy⟩
    exact ⟨y, ys, le_trans (le_of_lt hy) u_le_ε⟩
  show ∀ x : q.Rep, ∃ z : s p, dist x (Φ z) ≤ ε
  ·
    -- by construction, `s q` is `ε`-dense, and it is the range of `Φ`
    intro x
    have : x ∈ ⋃ y ∈ s q, ball y (u n) := (hs q qt) (mem_univ _)
    rcases mem_iUnion₂.1 this with ⟨y, ys, hy⟩
    let i : ℕ := E q ⟨y, ys⟩
    let hi := ((E q) ⟨y, ys⟩).2
    have ihi_eq : (⟨i, hi⟩ : Fin (N q)) = (E q) ⟨y, ys⟩ := by rw [Fin.ext_iff, Fin.val_mk]
    have hiq : i < N q := hi
    have hip : i < N p := by rwa [Npq.symm] at hiq 
    let z := (E p).symm ⟨i, hip⟩
    use z
    have C1 : (E p) z = ⟨i, hip⟩ := (E p).apply_symm_apply ⟨i, hip⟩
    have C2 : Fin.castIso Npq ⟨i, hip⟩ = ⟨i, hi⟩ := rfl
    have C3 : (E q).symm ⟨i, hi⟩ = ⟨y, ys⟩ := by rw [ihi_eq]; exact (E q).symm_apply_apply ⟨y, ys⟩
    have : Φ z = y := by simp only; rw [C1, C2, C3]
    rw [this]
    exact le_trans (le_of_lt hy) u_le_ε
  show ∀ x y : s p, |dist x y - dist (Φ x) (Φ y)| ≤ ε
  ·
    /- the distance between `x` and `y` is encoded in `F p`, and the distance between
                `Φ x` and `Φ y` (two points of `s q`) is encoded in `F q`, all this up to `ε`.
                As `F p = F q`, the distances are almost equal. -/
    intro x y
    have : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y) := rfl
    rw [this]
      -- introduce `i`, that codes both `x` and `Φ x` in `fin (N p) = fin (N q)`
    let i : ℕ := E p x
    have hip : i < N p := ((E p) x).2
    have hiq : i < N q := by rwa [Npq] at hip 
    have i' : i = (E q) (Ψ x) := by
      simp only [Equiv.apply_symm_apply, Fin.coe_castIso]
        -- introduce `j`, that codes both `y` and `Φ y` in `fin (N p) = fin (N q)`
    let j : ℕ := E p y
    have hjp : j < N p := ((E p) y).2
    have hjq : j < N q := by rwa [Npq] at hjp 
    have j' : j = (E q) (Ψ y) := by
      simp only [Equiv.apply_symm_apply, Fin.coe_castIso]
        -- Express `dist x y` in terms of `F p`
    have Ap : ((F p).2 ⟨i, hip⟩ ⟨j, hjp⟩).1 = ⌊ε⁻¹ * dist x y⌋₊ :=
      calc
        ((F p).2 ⟨i, hip⟩ ⟨j, hjp⟩).1 = ((F p).2 ((E p) x) ((E p) y)).1 := by congr
        _ = min M ⌊ε⁻¹ * dist x y⌋₊ := by simp only [(E p).symm_apply_apply]
        _ = ⌊ε⁻¹ * dist x y⌋₊ := by
          refine' min_eq_right (Nat.floor_mono _)
          refine' mul_le_mul_of_nonneg_left (le_trans _ (le_max_left _ _)) (inv_pos.2 εpos).le
          change dist (x : p.Rep) y ≤ C
          refine' (dist_le_diam_of_mem isCompact_univ.bounded (mem_univ _) (mem_univ _)).trans _
          exact hdiam p pt
    have Aq : ((F q).2 ⟨i, hiq⟩ ⟨j, hjq⟩).1 = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊ :=
      calc
        ((F q).2 ⟨i, hiq⟩ ⟨j, hjq⟩).1 = ((F q).2 ((E q) (Ψ x)) ((E q) (Ψ y))).1 := by
          -- Porting note: `congr` drops `Fin.val` but fails to make further progressexact
            congr_arg₂ (Fin.val <| (F q).2 · ·) (Fin.ext i') (Fin.ext j')
        _ = min M ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊ := by simp only [(E q).symm_apply_apply]
        _ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊ := by
          refine' min_eq_right (Nat.floor_mono _)
          refine' mul_le_mul_of_nonneg_left (le_trans _ (le_max_left _ _)) (inv_pos.2 εpos).le
          change dist (Ψ x : q.Rep) (Ψ y) ≤ C
          refine (dist_le_diam_of_mem isCompact_univ.bounded (mem_univ _) (mem_univ _)).trans ?_
          exact hdiam q qt
    have : ((F p).2 ⟨i, hip⟩ ⟨j, hjp⟩).1 = ((F q).2 ⟨i, hiq⟩ ⟨j, hjq⟩).1 :=
      by
      have hpq' : HEq (F p).snd (F q).snd := (Sigma.mk.inj_iff.1 hpq).2
      rw [Fin.heq_fun₂_iff Npq Npq] at hpq' 
      rw [← hpq']
        -- porting note: new version above because `subst…` does not work
                -- we want to `subst hpq` where `hpq : F p = F q`, except that `subst` only works
                -- with a constant, so replace `F q` (and everything that depends on it) by a constant `f`
                -- then `subst`
                -- dsimp only [show N q = (F q).1 from rfl] at hiq hjq ⊢
                -- generalize F q = f at hpq ⊢
                -- subst hpq
                -- intros
                -- rfl
    have : ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋ :=
      by
      rw [Ap, Aq] at this 
      have D : 0 ≤ ⌊ε⁻¹ * dist x y⌋ := floor_nonneg.2 (mul_nonneg (le_of_lt (inv_pos.2 εpos)) dist_nonneg)
      have D' : 0 ≤ ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋ := floor_nonneg.2 (mul_nonneg (le_of_lt (inv_pos.2 εpos)) dist_nonneg)
      rw [← Int.toNat_of_nonneg D, ← Int.toNat_of_nonneg D', Int.floor_toNat, Int.floor_toNat, this]
        -- deduce that the distances coincide up to `ε`, by a straightforward computation
              -- that should be automated
    have I :=
      calc
        |ε⁻¹| * |dist x y - dist (Ψ x) (Ψ y)| = |ε⁻¹ * (dist x y - dist (Ψ x) (Ψ y))| := (abs_mul _ _).symm
        _ = |ε⁻¹ * dist x y - ε⁻¹ * dist (Ψ x) (Ψ y)| := by congr; ring
        _ ≤ 1 := le_of_lt (abs_sub_lt_one_of_floor_eq_floor this)
    calc
      |dist x y - dist (Ψ x) (Ψ y)| = ε * ε⁻¹ * |dist x y - dist (Ψ x) (Ψ y)| := by
        rw [mul_inv_cancel (ne_of_gt εpos), one_mul]
      _ = ε * (|ε⁻¹| * |dist x y - dist (Ψ x) (Ψ y)|) := by rw [abs_of_nonneg (le_of_lt (inv_pos.2 εpos)), mul_assoc]
      _ ≤ ε * 1 := (mul_le_mul_of_nonneg_left I (le_of_lt εpos))
      _ = ε := mul_one _
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ghDist (GHSpace.Rep p) (GHSpace.Rep q) ≤ ε + ε / 2 + ε
[PROOFSTEP]
refine' ghDist_le_of_approx_subsets Φ _ _ _
[GOAL]
case refine'_1
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x : GHSpace.Rep p), ∃ y, y ∈ s p ∧ dist x y ≤ ε
case refine'_2
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x : GHSpace.Rep q), ∃ y, dist x (Φ y) ≤ ε
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x y : ↑(s p)), |dist x y - dist (Φ x) (Φ y)| ≤ ε
[PROOFSTEP]
show ∀ x : p.Rep, ∃ y ∈ s p, dist x y ≤ ε
[GOAL]
case refine'_1
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x : GHSpace.Rep p), ∃ y, y ∈ s p ∧ dist x y ≤ ε
[PROOFSTEP]
intro x
[GOAL]
case refine'_1
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep p
⊢ ∃ y, y ∈ s p ∧ dist x y ≤ ε
[PROOFSTEP]
have : x ∈ ⋃ y ∈ s p, ball y (u n) := (hs p pt) (mem_univ _)
[GOAL]
case refine'_1
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep p
this : x ∈ ⋃ (y : GHSpace.Rep p) (_ : y ∈ s p), ball y (u n)
⊢ ∃ y, y ∈ s p ∧ dist x y ≤ ε
[PROOFSTEP]
rcases mem_iUnion₂.1 this with ⟨y, ys, hy⟩
[GOAL]
case refine'_1.intro.intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep p
this : x ∈ ⋃ (y : GHSpace.Rep p) (_ : y ∈ s p), ball y (u n)
y : GHSpace.Rep p
ys : y ∈ s p
hy : x ∈ ball y (u n)
⊢ ∃ y, y ∈ s p ∧ dist x y ≤ ε
[PROOFSTEP]
exact ⟨y, ys, le_trans (le_of_lt hy) u_le_ε⟩
[GOAL]
case refine'_2
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x : GHSpace.Rep q), ∃ y, dist x (Φ y) ≤ ε
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x y : ↑(s p)), |dist x y - dist (Φ x) (Φ y)| ≤ ε
[PROOFSTEP]
show ∀ x : q.Rep, ∃ z : s p, dist x (Φ z) ≤ ε
[GOAL]
case refine'_2
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x : GHSpace.Rep q), ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
intro x
[GOAL]
case refine'_2
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
have : x ∈ ⋃ y ∈ s q, ball y (u n) := (hs q qt) (mem_univ _)
[GOAL]
case refine'_2
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
rcases mem_iUnion₂.1 this with ⟨y, ys, hy⟩
[GOAL]
case refine'_2.intro.intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
let i : ℕ := E q ⟨y, ys⟩
[GOAL]
case refine'_2.intro.intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
let hi := ((E q) ⟨y, ys⟩).2
[GOAL]
case refine'_2.intro.intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N q := (↑(E q) { val := y, property := ys }).isLt
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
have ihi_eq : (⟨i, hi⟩ : Fin (N q)) = (E q) ⟨y, ys⟩ := by rw [Fin.ext_iff, Fin.val_mk]
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N q := (↑(E q) { val := y, property := ys }).isLt
⊢ { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
[PROOFSTEP]
rw [Fin.ext_iff, Fin.val_mk]
[GOAL]
case refine'_2.intro.intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N q := (↑(E q) { val := y, property := ys }).isLt
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
have hiq : i < N q := hi
[GOAL]
case refine'_2.intro.intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N q := (↑(E q) { val := y, property := ys }).isLt
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
have hip : i < N p := by rwa [Npq.symm] at hiq 
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N q := (↑(E q) { val := y, property := ys }).isLt
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
⊢ i < N p
[PROOFSTEP]
rwa [Npq.symm] at hiq 
[GOAL]
case refine'_2.intro.intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N q := (↑(E q) { val := y, property := ys }).isLt
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
let z := (E p).symm ⟨i, hip⟩
[GOAL]
case refine'_2.intro.intro
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N q := (↑(E q) { val := y, property := ys }).isLt
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
⊢ ∃ z, dist x (Φ z) ≤ ε
[PROOFSTEP]
use z
[GOAL]
case h
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N q := (↑(E q) { val := y, property := ys }).isLt
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
⊢ dist x (Φ z) ≤ ε
[PROOFSTEP]
have C1 : (E p) z = ⟨i, hip⟩ := (E p).apply_symm_apply ⟨i, hip⟩
[GOAL]
case h
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N q := (↑(E q) { val := y, property := ys }).isLt
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
⊢ dist x (Φ z) ≤ ε
[PROOFSTEP]
have C2 : Fin.castIso Npq ⟨i, hip⟩ = ⟨i, hi⟩ := rfl
[GOAL]
case h
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N q := (↑(E q) { val := y, property := ys }).isLt
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
C2 : ↑(Fin.castIso Npq) { val := i, isLt := hip } = { val := i, isLt := hi }
⊢ dist x (Φ z) ≤ ε
[PROOFSTEP]
have C3 : (E q).symm ⟨i, hi⟩ = ⟨y, ys⟩ := by rw [ihi_eq]; exact (E q).symm_apply_apply ⟨y, ys⟩
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N q := (↑(E q) { val := y, property := ys }).isLt
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
C2 : ↑(Fin.castIso Npq) { val := i, isLt := hip } = { val := i, isLt := hi }
⊢ ↑(E q).symm { val := i, isLt := hi } = { val := y, property := ys }
[PROOFSTEP]
rw [ihi_eq]
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N q := (↑(E q) { val := y, property := ys }).isLt
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
C2 : ↑(Fin.castIso Npq) { val := i, isLt := hip } = { val := i, isLt := hi }
⊢ ↑(E q).symm (↑(E q) { val := y, property := ys }) = { val := y, property := ys }
[PROOFSTEP]
exact (E q).symm_apply_apply ⟨y, ys⟩
[GOAL]
case h
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N q := (↑(E q) { val := y, property := ys }).isLt
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
C2 : ↑(Fin.castIso Npq) { val := i, isLt := hip } = { val := i, isLt := hi }
C3 : ↑(E q).symm { val := i, isLt := hi } = { val := y, property := ys }
⊢ dist x (Φ z) ≤ ε
[PROOFSTEP]
have : Φ z = y := by simp only; rw [C1, C2, C3]
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N q := (↑(E q) { val := y, property := ys }).isLt
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
C2 : ↑(Fin.castIso Npq) { val := i, isLt := hip } = { val := i, isLt := hi }
C3 : ↑(E q).symm { val := i, isLt := hi } = { val := y, property := ys }
⊢ Φ z = y
[PROOFSTEP]
simp only
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N q := (↑(E q) { val := y, property := ys }).isLt
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
C2 : ↑(Fin.castIso Npq) { val := i, isLt := hip } = { val := i, isLt := hi }
C3 : ↑(E q).symm { val := i, isLt := hi } = { val := y, property := ys }
⊢ ↑(↑(E q).symm
        (↑(Fin.castIso Npq) (↑(E p) (↑(E p).symm { val := ↑(↑(E q) { val := y, property := ys }), isLt := hip })))) =
    y
[PROOFSTEP]
rw [C1, C2, C3]
[GOAL]
case h
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this✝ : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N q := (↑(E q) { val := y, property := ys }).isLt
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
C2 : ↑(Fin.castIso Npq) { val := i, isLt := hip } = { val := i, isLt := hi }
C3 : ↑(E q).symm { val := i, isLt := hi } = { val := y, property := ys }
this : Φ z = y
⊢ dist x (Φ z) ≤ ε
[PROOFSTEP]
rw [this]
[GOAL]
case h
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x : GHSpace.Rep q
this✝ : x ∈ ⋃ (y : GHSpace.Rep q) (_ : y ∈ s q), ball y (u n)
y : GHSpace.Rep q
ys : y ∈ s q
hy : x ∈ ball y (u n)
i : ℕ := ↑(↑(E q) { val := y, property := ys })
hi : ↑(↑(E q) { val := y, property := ys }) < N q := (↑(E q) { val := y, property := ys }).isLt
ihi_eq : { val := i, isLt := hi } = ↑(E q) { val := y, property := ys }
hiq : i < N q
hip : i < N p
z : (fun x => ↑(s p)) { val := i, isLt := hip } := ↑(E p).symm { val := i, isLt := hip }
C1 : ↑(E p) z = { val := i, isLt := hip }
C2 : ↑(Fin.castIso Npq) { val := i, isLt := hip } = { val := i, isLt := hi }
C3 : ↑(E q).symm { val := i, isLt := hi } = { val := y, property := ys }
this : Φ z = y
⊢ dist x y ≤ ε
[PROOFSTEP]
exact le_trans (le_of_lt hy) u_le_ε
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x y : ↑(s p)), |dist x y - dist (Φ x) (Φ y)| ≤ ε
[PROOFSTEP]
show ∀ x y : s p, |dist x y - dist (Φ x) (Φ y)| ≤ ε
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
⊢ ∀ (x y : ↑(s p)), |dist x y - dist (Φ x) (Φ y)| ≤ ε
[PROOFSTEP]
intro x y
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
⊢ |dist x y - dist (Φ x) (Φ y)| ≤ ε
[PROOFSTEP]
have : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y) := rfl
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
⊢ |dist x y - dist (Φ x) (Φ y)| ≤ ε
[PROOFSTEP]
rw [this]
  -- introduce `i`, that codes both `x` and `Φ x` in `fin (N p) = fin (N q)`
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
let i : ℕ := E p x
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have hip : i < N p := ((E p) x).2
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have hiq : i < N q := by rwa [Npq] at hip 
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
⊢ i < N q
[PROOFSTEP]
rwa [Npq] at hip 
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have i' : i = (E q) (Ψ x) := by
  simp only [Equiv.apply_symm_apply, Fin.coe_castIso]
    -- introduce `j`, that codes both `y` and `Φ y` in `fin (N p) = fin (N q)`
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
⊢ i = ↑(↑(E q) (Ψ x))
[PROOFSTEP]
simp only [Equiv.apply_symm_apply, Fin.coe_castIso]
  -- introduce `j`, that codes both `y` and `Φ y` in `fin (N p) = fin (N q)`
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
let j : ℕ := E p y
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have hjp : j < N p := ((E p) y).2
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have hjq : j < N q := by rwa [Npq] at hjp 
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
⊢ j < N q
[PROOFSTEP]
rwa [Npq] at hjp 
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have j' : j = (E q) (Ψ y) := by
  simp only [Equiv.apply_symm_apply, Fin.coe_castIso]
    -- Express `dist x y` in terms of `F p`
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
⊢ j = ↑(↑(E q) (Ψ y))
[PROOFSTEP]
simp only [Equiv.apply_symm_apply, Fin.coe_castIso]
  -- Express `dist x y` in terms of `F p`
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have Ap : ((F p).2 ⟨i, hip⟩ ⟨j, hjp⟩).1 = ⌊ε⁻¹ * dist x y⌋₊ :=
  calc
    ((F p).2 ⟨i, hip⟩ ⟨j, hjp⟩).1 = ((F p).2 ((E p) x) ((E p) y)).1 := by congr
    _ = min M ⌊ε⁻¹ * dist x y⌋₊ := by simp only [(E p).symm_apply_apply]
    _ = ⌊ε⁻¹ * dist x y⌋₊ := by
      refine' min_eq_right (Nat.floor_mono _)
      refine' mul_le_mul_of_nonneg_left (le_trans _ (le_max_left _ _)) (inv_pos.2 εpos).le
      change dist (x : p.Rep) y ≤ C
      refine' (dist_le_diam_of_mem isCompact_univ.bounded (mem_univ _) (mem_univ _)).trans _
      exact hdiam p pt
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
⊢ ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ↑(Sigma.snd (F p) (↑(E p) x) (↑(E p) y))
[PROOFSTEP]
congr
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
⊢ ↑(Sigma.snd (F p) (↑(E p) x) (↑(E p) y)) = min M ⌊ε⁻¹ * dist x y⌋₊
[PROOFSTEP]
simp only [(E p).symm_apply_apply]
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
⊢ min M ⌊ε⁻¹ * dist x y⌋₊ = ⌊ε⁻¹ * dist x y⌋₊
[PROOFSTEP]
refine' min_eq_right (Nat.floor_mono _)
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
⊢ ε⁻¹ * dist x y ≤ ε⁻¹ * max C 0
[PROOFSTEP]
refine' mul_le_mul_of_nonneg_left (le_trans _ (le_max_left _ _)) (inv_pos.2 εpos).le
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
⊢ dist x y ≤ C
[PROOFSTEP]
change dist (x : p.Rep) y ≤ C
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
⊢ dist ↑x ↑y ≤ C
[PROOFSTEP]
refine' (dist_le_diam_of_mem isCompact_univ.bounded (mem_univ _) (mem_univ _)).trans _
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
⊢ diam univ ≤ C
[PROOFSTEP]
exact hdiam p pt
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have Aq : ((F q).2 ⟨i, hiq⟩ ⟨j, hjq⟩).1 = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊ :=
  calc
    ((F q).2 ⟨i, hiq⟩ ⟨j, hjq⟩).1 = ((F q).2 ((E q) (Ψ x)) ((E q) (Ψ y))).1 := by
      -- Porting note: `congr` drops `Fin.val` but fails to make further progressexact
        congr_arg₂ (Fin.val <| (F q).2 · ·) (Fin.ext i') (Fin.ext j')
    _ = min M ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊ := by simp only [(E q).symm_apply_apply]
    _ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊ := by
      refine' min_eq_right (Nat.floor_mono _)
      refine' mul_le_mul_of_nonneg_left (le_trans _ (le_max_left _ _)) (inv_pos.2 εpos).le
      change dist (Ψ x : q.Rep) (Ψ y) ≤ C
      refine (dist_le_diam_of_mem isCompact_univ.bounded (mem_univ _) (mem_univ _)).trans ?_
      exact hdiam q qt
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
⊢ ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }) =
    ↑(Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y)))
[PROOFSTEP]
exact congr_arg₂ (Fin.val <| (F q).2 · ·) (Fin.ext i') (Fin.ext j')
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
⊢ ↑(Sigma.snd (F q) (↑(E q) (Ψ x)) (↑(E q) (Ψ y))) = min M ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
[PROOFSTEP]
simp only [(E q).symm_apply_apply]
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
⊢ min M ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
[PROOFSTEP]
refine' min_eq_right (Nat.floor_mono _)
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
⊢ ε⁻¹ * dist (Ψ x) (Ψ y) ≤ ε⁻¹ * max C 0
[PROOFSTEP]
refine' mul_le_mul_of_nonneg_left (le_trans _ (le_max_left _ _)) (inv_pos.2 εpos).le
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
⊢ dist (Ψ x) (Ψ y) ≤ C
[PROOFSTEP]
change dist (Ψ x : q.Rep) (Ψ y) ≤ C
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
⊢ dist ↑(Ψ x) ↑(Ψ y) ≤ C
[PROOFSTEP]
refine (dist_le_diam_of_mem isCompact_univ.bounded (mem_univ _) (mem_univ _)).trans ?_
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
⊢ diam univ ≤ C
[PROOFSTEP]
exact hdiam q qt
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
Aq : ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have : ((F p).2 ⟨i, hip⟩ ⟨j, hjp⟩).1 = ((F q).2 ⟨i, hiq⟩ ⟨j, hjq⟩).1 :=
  by
  have hpq' : HEq (F p).snd (F q).snd := (Sigma.mk.inj_iff.1 hpq).2
  rw [Fin.heq_fun₂_iff Npq Npq] at hpq' 
  rw [← hpq']
    -- porting note: new version above because `subst…` does not work
            -- we want to `subst hpq` where `hpq : F p = F q`, except that `subst` only works
            -- with a constant, so replace `F q` (and everything that depends on it) by a constant `f`
            -- then `subst`
            -- dsimp only [show N q = (F q).1 from rfl] at hiq hjq ⊢
            -- generalize F q = f at hpq ⊢
            -- subst hpq
            -- intros
            -- rfl
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
Aq : ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
⊢ ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) =
    ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq })
[PROOFSTEP]
have hpq' : HEq (F p).snd (F q).snd := (Sigma.mk.inj_iff.1 hpq).2
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
Aq : ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
hpq' : HEq (F p).snd (F q).snd
⊢ ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) =
    ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq })
[PROOFSTEP]
rw [Fin.heq_fun₂_iff Npq Npq] at hpq' 
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
Aq : ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
hpq' :
  ∀ (i j : Fin (N p)),
    Sigma.snd (F p) i j = Sigma.snd (F q) { val := ↑i, isLt := (_ : ↑i < N q) } { val := ↑j, isLt := (_ : ↑j < N q) }
⊢ ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) =
    ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq })
[PROOFSTEP]
rw [← hpq']
  -- porting note: new version above because `subst…` does not work
          -- we want to `subst hpq` where `hpq : F p = F q`, except that `subst` only works
          -- with a constant, so replace `F q` (and everything that depends on it) by a constant `f`
          -- then `subst`
          -- dsimp only [show N q = (F q).1 from rfl] at hiq hjq ⊢
          -- generalize F q = f at hpq ⊢
          -- subst hpq
          -- intros
          -- rfl
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this✝ : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
Aq : ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
this :
  ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) =
    ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq })
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have : ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋ :=
  by
  rw [Ap, Aq] at this 
  have D : 0 ≤ ⌊ε⁻¹ * dist x y⌋ := floor_nonneg.2 (mul_nonneg (le_of_lt (inv_pos.2 εpos)) dist_nonneg)
  have D' : 0 ≤ ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋ := floor_nonneg.2 (mul_nonneg (le_of_lt (inv_pos.2 εpos)) dist_nonneg)
  rw [← Int.toNat_of_nonneg D, ← Int.toNat_of_nonneg D', Int.floor_toNat, Int.floor_toNat, this]
    -- deduce that the distances coincide up to `ε`, by a straightforward computation
          -- that should be automated
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this✝ : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
Aq : ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
this :
  ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) =
    ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq })
⊢ ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
[PROOFSTEP]
rw [Ap, Aq] at this 
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this✝ : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
Aq : ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
this : ⌊ε⁻¹ * dist x y⌋₊ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
⊢ ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
[PROOFSTEP]
have D : 0 ≤ ⌊ε⁻¹ * dist x y⌋ := floor_nonneg.2 (mul_nonneg (le_of_lt (inv_pos.2 εpos)) dist_nonneg)
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this✝ : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
Aq : ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
this : ⌊ε⁻¹ * dist x y⌋₊ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
D : 0 ≤ ⌊ε⁻¹ * dist x y⌋
⊢ ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
[PROOFSTEP]
have D' : 0 ≤ ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋ := floor_nonneg.2 (mul_nonneg (le_of_lt (inv_pos.2 εpos)) dist_nonneg)
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this✝ : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
Aq : ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
this : ⌊ε⁻¹ * dist x y⌋₊ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
D : 0 ≤ ⌊ε⁻¹ * dist x y⌋
D' : 0 ≤ ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
⊢ ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
[PROOFSTEP]
rw [← Int.toNat_of_nonneg D, ← Int.toNat_of_nonneg D', Int.floor_toNat, Int.floor_toNat, this]
  -- deduce that the distances coincide up to `ε`, by a straightforward computation
        -- that should be automated
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this✝¹ : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
Aq : ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
this✝ :
  ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) =
    ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq })
this : ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
have I :=
  calc
    |ε⁻¹| * |dist x y - dist (Ψ x) (Ψ y)| = |ε⁻¹ * (dist x y - dist (Ψ x) (Ψ y))| := (abs_mul _ _).symm
    _ = |ε⁻¹ * dist x y - ε⁻¹ * dist (Ψ x) (Ψ y)| := by congr; ring
    _ ≤ 1 := le_of_lt (abs_sub_lt_one_of_floor_eq_floor this)
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this✝¹ : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
Aq : ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
this✝ :
  ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) =
    ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq })
this : ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
⊢ |ε⁻¹ * (dist x y - dist (Ψ x) (Ψ y))| = |ε⁻¹ * dist x y - ε⁻¹ * dist (Ψ x) (Ψ y)|
[PROOFSTEP]
congr
[GOAL]
case e_a
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this✝¹ : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
Aq : ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
this✝ :
  ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) =
    ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq })
this : ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
⊢ ε⁻¹ * (dist x y - dist (Ψ x) (Ψ y)) = ε⁻¹ * dist x y - ε⁻¹ * dist (Ψ x) (Ψ y)
[PROOFSTEP]
ring
[GOAL]
case refine'_3
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this✝¹ : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
Aq : ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
this✝ :
  ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) =
    ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq })
this : ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
I : |ε⁻¹| * |dist x y - dist (Ψ x) (Ψ y)| ≤ 1
⊢ |dist x y - dist (Ψ x) (Ψ y)| ≤ ε
[PROOFSTEP]
calc
  |dist x y - dist (Ψ x) (Ψ y)| = ε * ε⁻¹ * |dist x y - dist (Ψ x) (Ψ y)| := by
    rw [mul_inv_cancel (ne_of_gt εpos), one_mul]
  _ = ε * (|ε⁻¹| * |dist x y - dist (Ψ x) (Ψ y)|) := by rw [abs_of_nonneg (le_of_lt (inv_pos.2 εpos)), mul_assoc]
  _ ≤ ε * 1 := (mul_le_mul_of_nonneg_left I (le_of_lt εpos))
  _ = ε := mul_one _
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this✝¹ : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
Aq : ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
this✝ :
  ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) =
    ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq })
this : ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
I : |ε⁻¹| * |dist x y - dist (Ψ x) (Ψ y)| ≤ 1
⊢ |dist x y - dist (Ψ x) (Ψ y)| = ε * ε⁻¹ * |dist x y - dist (Ψ x) (Ψ y)|
[PROOFSTEP]
rw [mul_inv_cancel (ne_of_gt εpos), one_mul]
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
x y : ↑(s p)
this✝¹ : dist (Φ x) (Φ y) = dist (Ψ x) (Ψ y)
i : ℕ := ↑(↑(E p) x)
hip : i < N p
hiq : i < N q
i' : i = ↑(↑(E q) (Ψ x))
j : ℕ := ↑(↑(E p) y)
hjp : j < N p
hjq : j < N q
j' : j = ↑(↑(E q) (Ψ y))
Ap : ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) = ⌊ε⁻¹ * dist x y⌋₊
Aq : ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq }) = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋₊
this✝ :
  ↑(Sigma.snd (F p) { val := i, isLt := hip } { val := j, isLt := hjp }) =
    ↑(Sigma.snd (F q) { val := i, isLt := hiq } { val := j, isLt := hjq })
this : ⌊ε⁻¹ * dist x y⌋ = ⌊ε⁻¹ * dist (Ψ x) (Ψ y)⌋
I : |ε⁻¹| * |dist x y - dist (Ψ x) (Ψ y)| ≤ 1
⊢ ε * ε⁻¹ * |dist x y - dist (Ψ x) (Ψ y)| = ε * (|ε⁻¹| * |dist x y - dist (Ψ x) (Ψ y)|)
[PROOFSTEP]
rw [abs_of_nonneg (le_of_lt (inv_pos.2 εpos)), mul_assoc]
[GOAL]
case intro.refine'_2.mk.mk
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
main : ghDist (GHSpace.Rep p) (GHSpace.Rep q) ≤ ε + ε / 2 + ε
⊢ dist ↑{ val := p, property := pt } ↑{ val := q, property := qt } < δ
[PROOFSTEP]
calc
  dist p q = ghDist p.Rep q.Rep := dist_ghDist p q
  _ ≤ ε + ε / 2 + ε := main
  _ = δ / 2 := by simp only [one_div]; ring
  _ < δ := half_lt_self δpos
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
main : ghDist (GHSpace.Rep p) (GHSpace.Rep q) ≤ ε + ε / 2 + ε
⊢ ε + ε / 2 + ε = δ / 2
[PROOFSTEP]
simp only [one_div]
[GOAL]
t : Set GHSpace
C : ℝ
u : ℕ → ℝ
K : ℕ → ℕ
ulim : Tendsto u atTop (𝓝 0)
hdiam : ∀ (p : GHSpace), p ∈ t → diam univ ≤ C
hcov : ∀ (p : GHSpace), p ∈ t → ∀ (n : ℕ), ∃ s, #↑s ≤ ↑(K n) ∧ univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s), ball x (u n)
δ : ℝ
δpos : δ > 0
ε : ℝ := 1 / 5 * δ
εpos : 0 < ε
n : ℕ
hn : ∀ (n_1 : ℕ), n_1 ≥ n → dist (u n_1) 0 < ε
u_le_ε : u n ≤ ε
s : (p : GHSpace) → Set (GHSpace.Rep p)
N : GHSpace → ℕ
hN : ∀ (p : GHSpace), N p ≤ K n
E : (p : GHSpace) → ↑(s p) ≃ Fin (N p)
hs : ∀ (p : GHSpace), p ∈ t → univ ⊆ ⋃ (x : GHSpace.Rep p) (_ : x ∈ s p), ball x (u n)
M : ℕ := ⌊ε⁻¹ * max C 0⌋₊
F : GHSpace → (k : Fin (Nat.succ (K n))) × (Fin ↑k → Fin ↑k → Fin (Nat.succ M)) :=
  fun p =>
    { fst := { val := N p, isLt := (_ : N p < Nat.succ (K n)) },
      snd := fun a b =>
        { val := min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊,
          isLt := (_ : min M ⌊ε⁻¹ * dist (↑(E p).symm a) (↑(E p).symm b)⌋₊ < Nat.succ M) } }
p : GHSpace
pt : p ∈ t
q : GHSpace
qt : q ∈ t
hpq : (fun p => F ↑p) { val := p, property := pt } = (fun p => F ↑p) { val := q, property := qt }
Npq : N p = N q
Ψ : ↑(s p) → ↑(s q) := fun x => ↑(E q).symm (↑(Fin.castIso Npq) (↑(E p) x))
Φ : ↑(s p) → GHSpace.Rep q := fun x => ↑(Ψ x)
main : ghDist (GHSpace.Rep p) (GHSpace.Rep q) ≤ ε + ε / 2 + ε
⊢ 5⁻¹ * δ + 5⁻¹ * δ / 2 + 5⁻¹ * δ = δ / 2
[PROOFSTEP]
ring
[GOAL]
X : ℕ → Type
inst✝³ : (n : ℕ) → MetricSpace (X n)
inst✝² : ∀ (n : ℕ), CompactSpace (X n)
inst✝¹ : ∀ (n : ℕ), Nonempty (X n)
A : Type
inst✝ : MetricSpace A
⊢ MetricSpace A
[PROOFSTEP]
infer_instance
[GOAL]
X : ℕ → Type
inst✝³ : (n : ℕ) → MetricSpace (X n)
inst✝² : ∀ (n : ℕ), CompactSpace (X n)
inst✝¹ : ∀ (n : ℕ), Nonempty (X n)
A : Type
inst✝ : MetricSpace A
x y : A
⊢ edist (id x) (id y) = edist x y
[PROOFSTEP]
exact rfl
[GOAL]
X : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X n)
inst✝ : ∀ (n : ℕ), Nonempty (X n)
n✝ n : ℕ
Y : AuxGluingStruct (X n)
⊢ MetricSpace (GlueSpace (_ : Isometry Y.embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))))
[PROOFSTEP]
infer_instance
[GOAL]
X : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X n)
inst✝ : ∀ (n : ℕ), Nonempty (X n)
⊢ CompleteSpace GHSpace
[PROOFSTEP]
set d := fun n : ℕ ↦ ((1 : ℝ) / 2) ^ n
[GOAL]
X : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X n)
inst✝ : ∀ (n : ℕ), Nonempty (X n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
⊢ CompleteSpace GHSpace
[PROOFSTEP]
have : ∀ n : ℕ, 0 < d n := fun _ ↦ by
  positivity
    -- start from a sequence of nonempty compact metric spaces within distance `1/2^n` of each other
[GOAL]
X : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X n)
inst✝ : ∀ (n : ℕ), Nonempty (X n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
x✝ : ℕ
⊢ 0 < d x✝
[PROOFSTEP]
positivity
  -- start from a sequence of nonempty compact metric spaces within distance `1/2^n` of each other
[GOAL]
X : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X n)
inst✝ : ∀ (n : ℕ), Nonempty (X n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
⊢ CompleteSpace GHSpace
[PROOFSTEP]
refine'
  Metric.complete_of_convergent_controlled_sequences d this fun u hu =>
    _
      -- `X n` is a representative of `u n`
[GOAL]
X : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X n)
inst✝ : ∀ (n : ℕ), Nonempty (X n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
let X n := (u n).Rep
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
let Y := auxGluing X
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
have E : ∀ n : ℕ, GlueSpace (Y n).isom (isometry_optimalGHInjl (X n) (X (n + 1))) = (Y (n + 1)).Space := fun n => by
  dsimp only [auxGluing]; rfl
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
n : ℕ
⊢ GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
[PROOFSTEP]
dsimp only [auxGluing]
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
n : ℕ
⊢ GlueSpace
      (_ :
        Isometry
          (Nat.rec default
              (fun n Y =>
                {
                  Space :=
                    GlueSpace (_ : Isometry Y.embed)
                      (_ : Isometry (optimalGHInjl (GHSpace.Rep (u n)) (GHSpace.Rep (u (n + 1))))),
                  metric := inferInstance,
                  embed :=
                    toGlueR (_ : Isometry Y.embed)
                        (_ : Isometry (optimalGHInjl (GHSpace.Rep (u n)) (GHSpace.Rep (u (n + 1))))) ∘
                      optimalGHInjr (GHSpace.Rep (u n)) (GHSpace.Rep (u (n + 1))),
                  isom :=
                    (_ :
                      Isometry
                        (toGlueR (_ : Isometry Y.embed)
                            (_ : Isometry (optimalGHInjl (GHSpace.Rep (u n)) (GHSpace.Rep (u (n + 1))))) ∘
                          optimalGHInjr (GHSpace.Rep (u n)) (GHSpace.Rep (u (n + 1))))) })
              n).embed)
      (_ : Isometry (optimalGHInjl (GHSpace.Rep (u n)) (GHSpace.Rep (u (n + 1))))) =
    (Nat.rec default
        (fun n Y =>
          {
            Space :=
              GlueSpace (_ : Isometry Y.embed)
                (_ : Isometry (optimalGHInjl (GHSpace.Rep (u n)) (GHSpace.Rep (u (n + 1))))),
            metric := inferInstance,
            embed :=
              toGlueR (_ : Isometry Y.embed)
                  (_ : Isometry (optimalGHInjl (GHSpace.Rep (u n)) (GHSpace.Rep (u (n + 1))))) ∘
                optimalGHInjr (GHSpace.Rep (u n)) (GHSpace.Rep (u (n + 1))),
            isom :=
              (_ :
                Isometry
                  (toGlueR (_ : Isometry Y.embed)
                      (_ : Isometry (optimalGHInjl (GHSpace.Rep (u n)) (GHSpace.Rep (u (n + 1))))) ∘
                    optimalGHInjr (GHSpace.Rep (u n)) (GHSpace.Rep (u (n + 1))))) })
        (n + 1)).Space
[PROOFSTEP]
rfl
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
let c n := cast (E n)
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
have ic : ∀ n, Isometry (c n) := fun n x y => by dsimp only [auxGluing]; exact rfl
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
n : ℕ
x y : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1))))
⊢ edist (c n x) (c n y) = edist x y
[PROOFSTEP]
dsimp only [auxGluing]
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
n : ℕ
x y : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1))))
⊢ edist
      (cast
        (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
        x)
      (cast
        (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
        y) =
    edist x y
[PROOFSTEP]
exact rfl
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
let f : ∀ n, (Y n).Space → (Y (n + 1)).Space := fun n =>
  c n ∘ toGlueL (Y n).isom (isometry_optimalGHInjl (X n) (X n.succ))
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
have I : ∀ n, Isometry (f n) := fun n =>
  (ic n).comp
    (toGlueL_isometry _ _)
      -- consider the inductive limit `Z0` of the `Y n`, and then its completion `Z`
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
let Z0 := Metric.InductiveLimit I
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
let Z := UniformSpace.Completion Z0
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
let Φ := toInductiveLimit I
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
let coeZ :=
  ((↑) : Z0 → Z)
    -- let `X2 n` be the image of `X n` in the space `Z`
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
let X2 n := range (coeZ ∘ Φ n ∘ (Y n).embed)
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
have isom : ∀ n, Isometry (coeZ ∘ Φ n ∘ (Y n).embed) := by
  intro n
  refine' UniformSpace.Completion.coe_isometry.comp _
  exact (toInductiveLimit_isometry _ _).comp (Y n).isom
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
⊢ ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
[PROOFSTEP]
intro n
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
n : ℕ
⊢ Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
[PROOFSTEP]
refine' UniformSpace.Completion.coe_isometry.comp _
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
n : ℕ
⊢ Isometry (Φ n ∘ (Y n).embed)
[PROOFSTEP]
exact (toInductiveLimit_isometry _ _).comp (Y n).isom
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
have X2n :
  ∀ n,
    X2 n =
      range
        ((coeZ ∘ Φ n.succ ∘ c n ∘ toGlueR (Y n).isom (isometry_optimalGHInjl (X n) (X n.succ))) ∘
          optimalGHInjl (X n) (X n.succ)) :=
  by
  intro n
  change
    X2 n =
      range
        (coeZ ∘
          Φ n.succ ∘
            c n ∘ toGlueR (Y n).isom (isometry_optimalGHInjl (X n) (X n.succ)) ∘ optimalGHInjl (X n) (X n.succ))
  simp only
    --[X2, Φ]
  rw [← toInductiveLimit_commute I]
  simp only
    --[f]
  rw [← toGlue_commute]
  rfl
    -- simp_rw [range_comp] at X2n
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
⊢ ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
[PROOFSTEP]
intro n
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
n : ℕ
⊢ X2 n =
    range
      ((coeZ ∘
          Φ (Nat.succ n) ∘
            c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
        optimalGHInjl (X n) (X (Nat.succ n)))
[PROOFSTEP]
change
  X2 n =
    range
      (coeZ ∘
        Φ n.succ ∘ c n ∘ toGlueR (Y n).isom (isometry_optimalGHInjl (X n) (X n.succ)) ∘ optimalGHInjl (X n) (X n.succ))
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
n : ℕ
⊢ X2 n =
    range
      (coeZ ∘
        Φ (Nat.succ n) ∘
          c n ∘
            toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n)))) ∘
              optimalGHInjl (X n) (X (Nat.succ n)))
[PROOFSTEP]
simp only
  --[X2, Φ]
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
n : ℕ
⊢ range (↑(InductiveLimit I) ∘ toInductiveLimit I n ∘ (auxGluing (fun n => GHSpace.Rep (u n)) n).embed) =
    range
      (↑(InductiveLimit I) ∘
        toInductiveLimit I (Nat.succ n) ∘
          cast
              (_ :
                GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) =
                  (Y (n + 1)).Space) ∘
            toGlueR (_ : Isometry (auxGluing (fun n => GHSpace.Rep (u n)) n).embed)
                (_ : Isometry (optimalGHInjl (GHSpace.Rep (u n)) (GHSpace.Rep (u (Nat.succ n))))) ∘
              optimalGHInjl (GHSpace.Rep (u n)) (GHSpace.Rep (u (Nat.succ n))))
[PROOFSTEP]
rw [← toInductiveLimit_commute I]
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
n : ℕ
⊢ range
      (↑(InductiveLimit I) ∘
        (toInductiveLimit I (Nat.succ n) ∘ f n) ∘ (auxGluing (fun n => GHSpace.Rep (u n)) n).embed) =
    range
      (↑(InductiveLimit I) ∘
        toInductiveLimit I (Nat.succ n) ∘
          cast
              (_ :
                GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) =
                  (Y (n + 1)).Space) ∘
            toGlueR (_ : Isometry (auxGluing (fun n => GHSpace.Rep (u n)) n).embed)
                (_ : Isometry (optimalGHInjl (GHSpace.Rep (u n)) (GHSpace.Rep (u (Nat.succ n))))) ∘
              optimalGHInjl (GHSpace.Rep (u n)) (GHSpace.Rep (u (Nat.succ n))))
[PROOFSTEP]
simp only
  --[f]
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
n : ℕ
⊢ range
      (↑(InductiveLimit I) ∘
        (toInductiveLimit I (Nat.succ n) ∘
            cast
                (_ :
                  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) =
                    (Y (n + 1)).Space) ∘
              toGlueL (_ : Isometry (auxGluing (fun n => GHSpace.Rep (u n)) n).embed)
                (_ : Isometry (optimalGHInjl (GHSpace.Rep (u n)) (GHSpace.Rep (u (Nat.succ n)))))) ∘
          (auxGluing (fun n => GHSpace.Rep (u n)) n).embed) =
    range
      (↑(InductiveLimit I) ∘
        toInductiveLimit I (Nat.succ n) ∘
          cast
              (_ :
                GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) =
                  (Y (n + 1)).Space) ∘
            toGlueR (_ : Isometry (auxGluing (fun n => GHSpace.Rep (u n)) n).embed)
                (_ : Isometry (optimalGHInjl (GHSpace.Rep (u n)) (GHSpace.Rep (u (Nat.succ n))))) ∘
              optimalGHInjl (GHSpace.Rep (u n)) (GHSpace.Rep (u (Nat.succ n))))
[PROOFSTEP]
rw [← toGlue_commute]
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
n : ℕ
⊢ range
      (↑(InductiveLimit I) ∘
        (toInductiveLimit I (Nat.succ n) ∘
            cast
                (_ :
                  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) =
                    (Y (n + 1)).Space) ∘
              toGlueL (_ : Isometry (auxGluing (fun n => GHSpace.Rep (u n)) n).embed)
                (_ : Isometry (optimalGHInjl (GHSpace.Rep (u n)) (GHSpace.Rep (u (Nat.succ n)))))) ∘
          (auxGluing (fun n => GHSpace.Rep (u n)) n).embed) =
    range
      (↑(InductiveLimit I) ∘
        toInductiveLimit I (Nat.succ n) ∘
          cast
              (_ :
                GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) =
                  (Y (n + 1)).Space) ∘
            toGlueL (_ : Isometry (auxGluing (fun n => GHSpace.Rep (u n)) n).embed)
                (_ : Isometry (optimalGHInjl (GHSpace.Rep (u n)) (GHSpace.Rep (u (Nat.succ n))))) ∘
              (auxGluing (fun n => GHSpace.Rep (u n)) n).embed)
[PROOFSTEP]
rfl
  -- simp_rw [range_comp] at X2n
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
have X2nsucc :
  ∀ n,
    X2 n.succ =
      range
        ((coeZ ∘ Φ n.succ ∘ c n ∘ toGlueR (Y n).isom (isometry_optimalGHInjl (X n) (X n.succ))) ∘
          optimalGHInjr (X n) (X n.succ)) :=
  by
  intro n
  rfl
    -- simp_rw [range_comp] at X2nsucc
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
⊢ ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
[PROOFSTEP]
intro n
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
n : ℕ
⊢ X2 (Nat.succ n) =
    range
      ((coeZ ∘
          Φ (Nat.succ n) ∘
            c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
        optimalGHInjr (X n) (X (Nat.succ n)))
[PROOFSTEP]
rfl
  -- simp_rw [range_comp] at X2nsucc
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
have D2 : ∀ n, hausdorffDist (X2 n) (X2 n.succ) < d n := fun n ↦
  by
  rw [X2n n, X2nsucc n, range_comp, range_comp, hausdorffDist_image, hausdorffDist_optimal, ← dist_ghDist]
  · exact hu n n n.succ (le_refl n) (le_succ n)
  · apply UniformSpace.Completion.coe_isometry.comp _
    exact
      (toInductiveLimit_isometry _ _).comp
        ((ic n).comp (toGlueR_isometry _ _))
          -- consider `X2 n` as a member `X3 n` of the type of nonempty compact subsets of `Z`, which
            -- is a metric space
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
n : ℕ
⊢ hausdorffDist (X2 n) (X2 (Nat.succ n)) < d n
[PROOFSTEP]
rw [X2n n, X2nsucc n, range_comp, range_comp, hausdorffDist_image, hausdorffDist_optimal, ← dist_ghDist]
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
n : ℕ
⊢ dist (u n) (u (Nat.succ n)) < d n
[PROOFSTEP]
exact hu n n n.succ (le_refl n) (le_succ n)
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
n : ℕ
⊢ Isometry
    (coeZ ∘
      Φ (Nat.succ n) ∘ c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n)))))
[PROOFSTEP]
apply UniformSpace.Completion.coe_isometry.comp _
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
n : ℕ
⊢ Isometry
    (Φ (Nat.succ n) ∘ c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n)))))
[PROOFSTEP]
exact
  (toInductiveLimit_isometry _ _).comp
    ((ic n).comp (toGlueR_isometry _ _))
      -- consider `X2 n` as a member `X3 n` of the type of nonempty compact subsets of `Z`, which
        -- is a metric space
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
D2 : ∀ (n : ℕ), hausdorffDist (X2 n) (X2 (Nat.succ n)) < d n
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
let X3 : ℕ → NonemptyCompacts Z := fun n =>
  ⟨⟨X2 n, isCompact_range (isom n).continuous⟩, range_nonempty _⟩
    -- `X3 n` is a Cauchy sequence by construction, as the successive distances are
      -- bounded by `(1/2)^n`
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
D2 : ∀ (n : ℕ), hausdorffDist (X2 n) (X2 (Nat.succ n)) < d n
X3 : ℕ → NonemptyCompacts Z :=
  fun n =>
    { toCompacts := { carrier := X2 n, isCompact' := (_ : IsCompact (range (coeZ ∘ Φ n ∘ (Y n).embed))) },
      nonempty' := (_ : Set.Nonempty (range fun y => (coeZ ∘ Φ n ∘ (Y n).embed) y)) }
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
have : CauchySeq X3 := by
  refine' cauchySeq_of_le_geometric (1 / 2) 1 (by norm_num) fun n => _
  rw [one_mul]
  exact
    le_of_lt
      (D2 n)
        -- therefore, it converges to a limit `L`
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
D2 : ∀ (n : ℕ), hausdorffDist (X2 n) (X2 (Nat.succ n)) < d n
X3 : ℕ → NonemptyCompacts Z :=
  fun n =>
    { toCompacts := { carrier := X2 n, isCompact' := (_ : IsCompact (range (coeZ ∘ Φ n ∘ (Y n).embed))) },
      nonempty' := (_ : Set.Nonempty (range fun y => (coeZ ∘ Φ n ∘ (Y n).embed) y)) }
⊢ CauchySeq X3
[PROOFSTEP]
refine' cauchySeq_of_le_geometric (1 / 2) 1 (by norm_num) fun n => _
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
D2 : ∀ (n : ℕ), hausdorffDist (X2 n) (X2 (Nat.succ n)) < d n
X3 : ℕ → NonemptyCompacts Z :=
  fun n =>
    { toCompacts := { carrier := X2 n, isCompact' := (_ : IsCompact (range (coeZ ∘ Φ n ∘ (Y n).embed))) },
      nonempty' := (_ : Set.Nonempty (range fun y => (coeZ ∘ Φ n ∘ (Y n).embed) y)) }
⊢ 1 / 2 < 1
[PROOFSTEP]
norm_num
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
D2 : ∀ (n : ℕ), hausdorffDist (X2 n) (X2 (Nat.succ n)) < d n
X3 : ℕ → NonemptyCompacts Z :=
  fun n =>
    { toCompacts := { carrier := X2 n, isCompact' := (_ : IsCompact (range (coeZ ∘ Φ n ∘ (Y n).embed))) },
      nonempty' := (_ : Set.Nonempty (range fun y => (coeZ ∘ Φ n ∘ (Y n).embed) y)) }
n : ℕ
⊢ dist (X3 n) (X3 (n + 1)) ≤ 1 * (1 / 2) ^ n
[PROOFSTEP]
rw [one_mul]
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
D2 : ∀ (n : ℕ), hausdorffDist (X2 n) (X2 (Nat.succ n)) < d n
X3 : ℕ → NonemptyCompacts Z :=
  fun n =>
    { toCompacts := { carrier := X2 n, isCompact' := (_ : IsCompact (range (coeZ ∘ Φ n ∘ (Y n).embed))) },
      nonempty' := (_ : Set.Nonempty (range fun y => (coeZ ∘ Φ n ∘ (Y n).embed) y)) }
n : ℕ
⊢ dist (X3 n) (X3 (n + 1)) ≤ (1 / 2) ^ n
[PROOFSTEP]
exact
  le_of_lt
    (D2 n)
      -- therefore, it converges to a limit `L`
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this✝ : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
D2 : ∀ (n : ℕ), hausdorffDist (X2 n) (X2 (Nat.succ n)) < d n
X3 : ℕ → NonemptyCompacts Z :=
  fun n =>
    { toCompacts := { carrier := X2 n, isCompact' := (_ : IsCompact (range (coeZ ∘ Φ n ∘ (Y n).embed))) },
      nonempty' := (_ : Set.Nonempty (range fun y => (coeZ ∘ Φ n ∘ (Y n).embed) y)) }
this : CauchySeq X3
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
rcases cauchySeq_tendsto_of_complete this with
  ⟨L, hL⟩
    -- By construction, the image of `X3 n` in the Gromov-Hausdorff space is `u n`.
[GOAL]
case intro
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this✝ : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
D2 : ∀ (n : ℕ), hausdorffDist (X2 n) (X2 (Nat.succ n)) < d n
X3 : ℕ → NonemptyCompacts Z :=
  fun n =>
    { toCompacts := { carrier := X2 n, isCompact' := (_ : IsCompact (range (coeZ ∘ Φ n ∘ (Y n).embed))) },
      nonempty' := (_ : Set.Nonempty (range fun y => (coeZ ∘ Φ n ∘ (Y n).embed) y)) }
this : CauchySeq X3
L : NonemptyCompacts Z
hL : Tendsto X3 atTop (𝓝 L)
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
have : ∀ n, (NonemptyCompacts.toGHSpace ∘ X3) n = u n :=
  by
  intro n
  rw [Function.comp_apply, NonemptyCompacts.toGHSpace, ← (u n).toGHSpace_rep, toGHSpace_eq_toGHSpace_iff_isometryEquiv]
  constructor
  convert (isom n).isometryEquivOnRange.symm
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this✝ : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
D2 : ∀ (n : ℕ), hausdorffDist (X2 n) (X2 (Nat.succ n)) < d n
X3 : ℕ → NonemptyCompacts Z :=
  fun n =>
    { toCompacts := { carrier := X2 n, isCompact' := (_ : IsCompact (range (coeZ ∘ Φ n ∘ (Y n).embed))) },
      nonempty' := (_ : Set.Nonempty (range fun y => (coeZ ∘ Φ n ∘ (Y n).embed) y)) }
this : CauchySeq X3
L : NonemptyCompacts Z
hL : Tendsto X3 atTop (𝓝 L)
⊢ ∀ (n : ℕ), (NonemptyCompacts.toGHSpace ∘ X3) n = u n
[PROOFSTEP]
intro n
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this✝ : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
D2 : ∀ (n : ℕ), hausdorffDist (X2 n) (X2 (Nat.succ n)) < d n
X3 : ℕ → NonemptyCompacts Z :=
  fun n =>
    { toCompacts := { carrier := X2 n, isCompact' := (_ : IsCompact (range (coeZ ∘ Φ n ∘ (Y n).embed))) },
      nonempty' := (_ : Set.Nonempty (range fun y => (coeZ ∘ Φ n ∘ (Y n).embed) y)) }
this : CauchySeq X3
L : NonemptyCompacts Z
hL : Tendsto X3 atTop (𝓝 L)
n : ℕ
⊢ (NonemptyCompacts.toGHSpace ∘ X3) n = u n
[PROOFSTEP]
rw [Function.comp_apply, NonemptyCompacts.toGHSpace, ← (u n).toGHSpace_rep, toGHSpace_eq_toGHSpace_iff_isometryEquiv]
[GOAL]
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this✝ : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
D2 : ∀ (n : ℕ), hausdorffDist (X2 n) (X2 (Nat.succ n)) < d n
X3 : ℕ → NonemptyCompacts Z :=
  fun n =>
    { toCompacts := { carrier := X2 n, isCompact' := (_ : IsCompact (range (coeZ ∘ Φ n ∘ (Y n).embed))) },
      nonempty' := (_ : Set.Nonempty (range fun y => (coeZ ∘ Φ n ∘ (Y n).embed) y)) }
this : CauchySeq X3
L : NonemptyCompacts Z
hL : Tendsto X3 atTop (𝓝 L)
n : ℕ
⊢ Nonempty ({ x // x ∈ X3 n } ≃ᵢ GHSpace.Rep (u n))
[PROOFSTEP]
constructor
[GOAL]
case val
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this✝ : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
D2 : ∀ (n : ℕ), hausdorffDist (X2 n) (X2 (Nat.succ n)) < d n
X3 : ℕ → NonemptyCompacts Z :=
  fun n =>
    { toCompacts := { carrier := X2 n, isCompact' := (_ : IsCompact (range (coeZ ∘ Φ n ∘ (Y n).embed))) },
      nonempty' := (_ : Set.Nonempty (range fun y => (coeZ ∘ Φ n ∘ (Y n).embed) y)) }
this : CauchySeq X3
L : NonemptyCompacts Z
hL : Tendsto X3 atTop (𝓝 L)
n : ℕ
⊢ { x // x ∈ X3 n } ≃ᵢ GHSpace.Rep (u n)
[PROOFSTEP]
convert (isom n).isometryEquivOnRange.symm
[GOAL]
case intro
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this✝¹ : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
D2 : ∀ (n : ℕ), hausdorffDist (X2 n) (X2 (Nat.succ n)) < d n
X3 : ℕ → NonemptyCompacts Z :=
  fun n =>
    { toCompacts := { carrier := X2 n, isCompact' := (_ : IsCompact (range (coeZ ∘ Φ n ∘ (Y n).embed))) },
      nonempty' := (_ : Set.Nonempty (range fun y => (coeZ ∘ Φ n ∘ (Y n).embed) y)) }
this✝ : CauchySeq X3
L : NonemptyCompacts Z
hL : Tendsto X3 atTop (𝓝 L)
this : ∀ (n : ℕ), (NonemptyCompacts.toGHSpace ∘ X3) n = u n
⊢ ∃ x, Tendsto u atTop (𝓝 x)
[PROOFSTEP]
use L.toGHSpace
[GOAL]
case h
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this✝¹ : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
D2 : ∀ (n : ℕ), hausdorffDist (X2 n) (X2 (Nat.succ n)) < d n
X3 : ℕ → NonemptyCompacts Z :=
  fun n =>
    { toCompacts := { carrier := X2 n, isCompact' := (_ : IsCompact (range (coeZ ∘ Φ n ∘ (Y n).embed))) },
      nonempty' := (_ : Set.Nonempty (range fun y => (coeZ ∘ Φ n ∘ (Y n).embed) y)) }
this✝ : CauchySeq X3
L : NonemptyCompacts Z
hL : Tendsto X3 atTop (𝓝 L)
this : ∀ (n : ℕ), (NonemptyCompacts.toGHSpace ∘ X3) n = u n
⊢ Tendsto u atTop (𝓝 (NonemptyCompacts.toGHSpace L))
[PROOFSTEP]
apply Filter.Tendsto.congr this
[GOAL]
case h
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this✝¹ : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
D2 : ∀ (n : ℕ), hausdorffDist (X2 n) (X2 (Nat.succ n)) < d n
X3 : ℕ → NonemptyCompacts Z :=
  fun n =>
    { toCompacts := { carrier := X2 n, isCompact' := (_ : IsCompact (range (coeZ ∘ Φ n ∘ (Y n).embed))) },
      nonempty' := (_ : Set.Nonempty (range fun y => (coeZ ∘ Φ n ∘ (Y n).embed) y)) }
this✝ : CauchySeq X3
L : NonemptyCompacts Z
hL : Tendsto X3 atTop (𝓝 L)
this : ∀ (n : ℕ), (NonemptyCompacts.toGHSpace ∘ X3) n = u n
⊢ Tendsto (fun x => (NonemptyCompacts.toGHSpace ∘ X3) x) atTop (𝓝 (NonemptyCompacts.toGHSpace L))
[PROOFSTEP]
refine' Tendsto.comp _ hL
[GOAL]
case h
X✝ : ℕ → Type
inst✝² : (n : ℕ) → MetricSpace (X✝ n)
inst✝¹ : ∀ (n : ℕ), CompactSpace (X✝ n)
inst✝ : ∀ (n : ℕ), Nonempty (X✝ n)
d : ℕ → ℝ := fun n => (1 / 2) ^ n
this✝¹ : ∀ (n : ℕ), 0 < d n
u : ℕ → GHSpace
hu : ∀ (N n m : ℕ), N ≤ n → N ≤ m → dist (u n) (u m) < d N
X : ℕ → Type := fun n => GHSpace.Rep (u n)
Y : (n : ℕ) → AuxGluingStruct (X n) := auxGluing X
E : ∀ (n : ℕ), GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space
c : (n : ℕ) →
  GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) → (Y (n + 1)).Space :=
  fun n =>
    cast (_ : GlueSpace (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (n + 1)))) = (Y (n + 1)).Space)
ic : ∀ (n : ℕ), Isometry (c n)
f : (n : ℕ) → (Y n).Space → (Y (n + 1)).Space :=
  fun n => c n ∘ toGlueL (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))
I : ∀ (n : ℕ), Isometry (f n)
Z0 : Type := InductiveLimit I
Z : Type := UniformSpace.Completion Z0
Φ : (n : ℕ) → (Y n).Space → InductiveLimit I := toInductiveLimit I
coeZ : Z0 → UniformSpace.Completion Z0 := ↑Z0
X2 : ℕ → Set (UniformSpace.Completion Z0) := fun n => range (coeZ ∘ Φ n ∘ (Y n).embed)
isom : ∀ (n : ℕ), Isometry (coeZ ∘ Φ n ∘ (Y n).embed)
X2n :
  ∀ (n : ℕ),
    X2 n =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjl (X n) (X (Nat.succ n)))
X2nsucc :
  ∀ (n : ℕ),
    X2 (Nat.succ n) =
      range
        ((coeZ ∘
            Φ (Nat.succ n) ∘
              c n ∘ toGlueR (_ : Isometry (Y n).embed) (_ : Isometry (optimalGHInjl (X n) (X (Nat.succ n))))) ∘
          optimalGHInjr (X n) (X (Nat.succ n)))
D2 : ∀ (n : ℕ), hausdorffDist (X2 n) (X2 (Nat.succ n)) < d n
X3 : ℕ → NonemptyCompacts Z :=
  fun n =>
    { toCompacts := { carrier := X2 n, isCompact' := (_ : IsCompact (range (coeZ ∘ Φ n ∘ (Y n).embed))) },
      nonempty' := (_ : Set.Nonempty (range fun y => (coeZ ∘ Φ n ∘ (Y n).embed) y)) }
this✝ : CauchySeq X3
L : NonemptyCompacts Z
hL : Tendsto X3 atTop (𝓝 L)
this : ∀ (n : ℕ), (NonemptyCompacts.toGHSpace ∘ X3) n = u n
⊢ Tendsto NonemptyCompacts.toGHSpace (𝓝 L) (𝓝 (NonemptyCompacts.toGHSpace L))
[PROOFSTEP]
apply toGHSpace_continuous.tendsto
