File: Mathlib/Topology/MetricSpace/GromovHausdorffRealized.lean

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.ProdSpaceFun
code: private abbrev ProdSpaceFun : Type _ 
goal: Type (max u v)

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.Cb
code: private abbrev Cb : Type _ 
goal: Type (max v u)

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.maxVar
code: private def maxVar : ℝ≥0 
goal: ℝ≥0

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.one_le_maxVar
code: private theorem one_le_maxVar : 1 ≤ maxVar X Y 
goal: 1 ≤ GromovHausdorff.maxVar X Y

full_name: GromovHausdorff.candidates
code: /-- The set of functions on `X ⊕ Y` that are candidates distances to realize the
minimum of the Hausdorff distances between `X` and `Y` in a coupling. -/
def candidates : Set (ProdSpaceFun X Y) 
goal: Set (GromovHausdorff.ProdSpaceFun X Y)

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.candidatesB
code: /-- Version of the set of candidates in bounded_continuous_functions, to apply Arzela-Ascoli. -/
private def candidatesB : Set (Cb X Y) 
goal: Set (GromovHausdorff.Cb X Y)

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.maxVar_bound
code: private theorem maxVar_bound : dist x y ≤ maxVar X Y 
goal: dist x y ≤ ↑(GromovHausdorff.maxVar X Y)

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.candidates_symm
code: private theorem candidates_symm (fA : f ∈ candidates X Y) : f (x, y) = f (y, x) 
goal: f (x, y) = f (y, x)

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.candidates_triangle
code: private theorem candidates_triangle (fA : f ∈ candidates X Y) : f (x, z) ≤ f (x, y) + f (y, z) 
goal: f (x, z) ≤ f (x, y) + f (y, z)

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.candidates_refl
code: private theorem candidates_refl (fA : f ∈ candidates X Y) : f (x, x) = 0 
goal: f (x, x) = 0

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.candidates_nonneg
code: private theorem candidates_nonneg (fA : f ∈ candidates X Y) : 0 ≤ f (x, y) 
goal: 0 ≤ f (x, y)

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.candidates_dist_inl
code: private theorem candidates_dist_inl (fA : f ∈ candidates X Y) (x y : X) :
    f (inl x, inl y) = dist x y 
goal: f (Sum.inl x, Sum.inl y) = dist x y

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.candidates_dist_inr
code: private theorem candidates_dist_inr (fA : f ∈ candidates X Y) (x y : Y) :
    f (inr x, inr y) = dist x y 
goal: f (Sum.inr x, Sum.inr y) = dist x y

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.candidates_le_maxVar
code: private theorem candidates_le_maxVar (fA : f ∈ candidates X Y) : f (x, y) ≤ maxVar X Y 
goal: f (x, y) ≤ ↑(GromovHausdorff.maxVar X Y)

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.candidates_dist_bound
code: /-- candidates are bounded by `maxVar X Y` -/
private theorem candidates_dist_bound (fA : f ∈ candidates X Y) :
    ∀ {x y : X ⊕ Y}, f (x, y) ≤ maxVar X Y * dist x y
  
goal: f (x, y) ≤ ↑(GromovHausdorff.maxVar X Y) * dist x y

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.candidates_lipschitz_aux
code: /-- Technical lemma to prove that candidates are Lipschitz -/
private theorem candidates_lipschitz_aux (fA : f ∈ candidates X Y) :
    f (x, y) - f (z, t) ≤ 2 * maxVar X Y * dist (x, y) (z, t) 
goal: f (x, y) - f (z, t) ≤ 2 * ↑(GromovHausdorff.maxVar X Y) * dist (x, y) (z, t)

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.candidates_lipschitz
code: /-- Candidates are Lipschitz -/
private theorem candidates_lipschitz (fA : f ∈ candidates X Y) :
    LipschitzWith (2 * maxVar X Y) f 
goal: LipschitzWith (2 * GromovHausdorff.maxVar X Y) f

full_name: GromovHausdorff.candidatesBOfCandidates
code: /-- candidates give rise to elements of `BoundedContinuousFunction`s -/
def candidatesBOfCandidates (f : ProdSpaceFun X Y) (fA : f ∈ candidates X Y) : Cb X Y 
goal: GromovHausdorff.Cb X Y

full_name: GromovHausdorff.candidatesBOfCandidates_mem
code: theorem candidatesBOfCandidates_mem (f : ProdSpaceFun X Y) (fA : f ∈ candidates X Y) :
    candidatesBOfCandidates f fA ∈ candidatesB X Y 
goal: GromovHausdorff.candidatesBOfCandidates f fA ∈ GromovHausdorff.candidatesB X Y

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.dist_mem_candidates
code: /-- The distance on `X ⊕ Y` is a candidate -/
private theorem dist_mem_candidates :
    (fun p : (X ⊕ Y) × (X ⊕ Y) => dist p.1 p.2) ∈ candidates X Y 
goal: (fun p => dist p.1 p.2) ∈ GromovHausdorff.candidates X Y

full_name: GromovHausdorff.candidatesBDist
code: /-- The distance on `X ⊕ Y` as a candidate -/
def candidatesBDist (X : Type u) (Y : Type v) [MetricSpace X] [CompactSpace X] [Nonempty X]
    [MetricSpace Y] [CompactSpace Y] [Nonempty Y] : Cb X Y 
goal: GromovHausdorff.Cb X Y

full_name: GromovHausdorff.candidatesBDist_mem_candidatesB
code: theorem candidatesBDist_mem_candidatesB : candidatesBDist X Y ∈ candidatesB X Y 
goal: GromovHausdorff.candidatesBDist X Y ∈ GromovHausdorff.candidatesB X Y

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.candidatesB_nonempty
code: private theorem candidatesB_nonempty : (candidatesB X Y).Nonempty 
goal: (GromovHausdorff.candidatesB X Y).Nonempty

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.closed_candidatesB
code: /-- To apply Arzela-Ascoli, we need to check that the set of candidates is closed and
equicontinuous. Equicontinuity follows from the Lipschitz control, we check closedness. -/
private theorem closed_candidatesB : IsClosed (candidatesB X Y) 
goal: IsClosed (GromovHausdorff.candidatesB X Y)

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.isCompact_candidatesB
code: /-- Compactness of candidates (in `BoundedContinuousFunction`s) follows. -/
private theorem isCompact_candidatesB : IsCompact (candidatesB X Y) 
goal: IsCompact (GromovHausdorff.candidatesB X Y)

full_name: GromovHausdorff.HD
code: /-- We will then choose the candidate minimizing the Hausdorff distance. Except that we are not
in a metric space setting, so we need to define our custom version of Hausdorff distance,
called `HD`, and prove its basic properties. -/
def HD (f : Cb X Y) 
goal: ℝ

full_name: GromovHausdorff.HD_below_aux1
code: theorem HD_below_aux1 {f : Cb X Y} (C : ℝ) {x : X} :
    BddBelow (range fun y : Y => f (inl x, inr y) + C) 
goal: BddBelow (Set.range fun y => f (Sum.inl x, Sum.inr y) + C)

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.HD_bound_aux1
code: private theorem HD_bound_aux1 (f : Cb X Y) (C : ℝ) :
    BddAbove (range fun x : X => ⨅ y, f (inl x, inr y) + C) 
goal: BddAbove (Set.range fun x => ⨅ y, f (Sum.inl x, Sum.inr y) + C)

full_name: GromovHausdorff.HD_below_aux2
code: theorem HD_below_aux2 {f : Cb X Y} (C : ℝ) {y : Y} :
    BddBelow (range fun x : X => f (inl x, inr y) + C) 
goal: BddBelow (Set.range fun x => f (Sum.inl x, Sum.inr y) + C)

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.HD_bound_aux2
code: private theorem HD_bound_aux2 (f : Cb X Y) (C : ℝ) :
    BddAbove (range fun y : Y => ⨅ x, f (inl x, inr y) + C) 
goal: BddAbove (Set.range fun y => ⨅ x, f (Sum.inl x, Sum.inr y) + C)

full_name: GromovHausdorff.HD_candidatesBDist_le
code: /-- Explicit bound on `HD (dist)`. This means that when looking for minimizers it will
be sufficient to look for functions with `HD(f)` bounded by this bound. -/
theorem HD_candidatesBDist_le :
    HD (candidatesBDist X Y) ≤ diam (univ : Set X) + 1 + diam (univ : Set Y) 
goal: GromovHausdorff.HD (GromovHausdorff.candidatesBDist X Y) ≤ Metric.diam Set.univ + 1 + Metric.diam Set.univ

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.HD_lipschitz_aux1
code: private theorem HD_lipschitz_aux1 (f g : Cb X Y) :
    (⨆ x, ⨅ y, f (inl x, inr y)) ≤ (⨆ x, ⨅ y, g (inl x, inr y)) + dist f g 
goal: ⨆ x, ⨅ y, f (Sum.inl x, Sum.inr y) ≤ (⨆ x, ⨅ y, g (Sum.inl x, Sum.inr y)) + dist f g

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.HD_lipschitz_aux2
code: private theorem HD_lipschitz_aux2 (f g : Cb X Y) :
    (⨆ y, ⨅ x, f (inl x, inr y)) ≤ (⨆ y, ⨅ x, g (inl x, inr y)) + dist f g 
goal: ⨆ y, ⨅ x, f (Sum.inl x, Sum.inr y) ≤ (⨆ y, ⨅ x, g (Sum.inl x, Sum.inr y)) + dist f g

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.HD_lipschitz_aux3
code: private theorem HD_lipschitz_aux3 (f g : Cb X Y) : HD f ≤ HD g + dist f g 
goal: GromovHausdorff.HD f ≤ GromovHausdorff.HD g + dist f g

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.HD_continuous
code: /-- Conclude that `HD`, being Lipschitz, is continuous -/
private theorem HD_continuous : Continuous (HD : Cb X Y → ℝ) 
goal: Continuous GromovHausdorff.HD

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.exists_minimizer
code: private theorem exists_minimizer : ∃ f ∈ candidatesB X Y, ∀ g ∈ candidatesB X Y, HD f ≤ HD g 
goal: ∃ f ∈ GromovHausdorff.candidatesB X Y,
  ∀ g ∈ GromovHausdorff.candidatesB X Y, GromovHausdorff.HD f ≤ GromovHausdorff.HD g

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.optimalGHDist
code: private def optimalGHDist : Cb X Y 
goal: GromovHausdorff.Cb X Y

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.optimalGHDist_mem_candidatesB
code: private theorem optimalGHDist_mem_candidatesB : optimalGHDist X Y ∈ candidatesB X Y 
goal: GromovHausdorff.optimalGHDist X Y ∈ GromovHausdorff.candidatesB X Y

full_name: _private.Mathlib.Topology.MetricSpace.GromovHausdorffRealized.0.GromovHausdorff.HD_optimalGHDist_le
code: private theorem HD_optimalGHDist_le (g : Cb X Y) (hg : g ∈ candidatesB X Y) :
    HD (optimalGHDist X Y) ≤ HD g 
goal: GromovHausdorff.HD (GromovHausdorff.optimalGHDist X Y) ≤ GromovHausdorff.HD g

full_name: GromovHausdorff.premetricOptimalGHDist
code: /-- With the optimal candidate, construct a premetric space structure on `X ⊕ Y`, on which the
predistance is given by the candidate. Then, we will identify points at `0` predistance
to obtain a genuine metric space. -/
def premetricOptimalGHDist : PseudoMetricSpace (X ⊕ Y) 
goal: PseudoMetricSpace (X ⊕ Y)

full_name: GromovHausdorff.OptimalGHCoupling
code: /-- A metric space which realizes the optimal coupling between `X` and `Y` -/
-- @[nolint has_nonempty_instance] -- Porting note(#5171): This linter does not exist yet.
def OptimalGHCoupling : Type _ 
goal: Type (max v u)

full_name: GromovHausdorff.instMetricSpaceOptimalGHCoupling
code: instance : MetricSpace (OptimalGHCoupling X Y) 
goal: MetricSpace (GromovHausdorff.OptimalGHCoupling X Y)

full_name: GromovHausdorff.optimalGHInjl
code: /-- Injection of `X` in the optimal coupling between `X` and `Y` -/
def optimalGHInjl (x : X) : OptimalGHCoupling X Y 
goal: GromovHausdorff.OptimalGHCoupling X Y

full_name: GromovHausdorff.isometry_optimalGHInjl
code: /-- The injection of `X` in the optimal coupling between `X` and `Y` is an isometry. -/
theorem isometry_optimalGHInjl : Isometry (optimalGHInjl X Y) 
goal: Isometry (GromovHausdorff.optimalGHInjl X Y)

full_name: GromovHausdorff.optimalGHInjr
code: /-- Injection of `Y` in the optimal coupling between `X` and `Y` -/
def optimalGHInjr (y : Y) : OptimalGHCoupling X Y 
goal: GromovHausdorff.OptimalGHCoupling X Y

full_name: GromovHausdorff.isometry_optimalGHInjr
code: /-- The injection of `Y` in the optimal coupling between `X` and `Y` is an isometry. -/
theorem isometry_optimalGHInjr : Isometry (optimalGHInjr X Y) 
goal: Isometry (GromovHausdorff.optimalGHInjr X Y)

full_name: GromovHausdorff.compactSpace_optimalGHCoupling
code: /-- The optimal coupling between two compact spaces `X` and `Y` is still a compact space -/
instance compactSpace_optimalGHCoupling : CompactSpace (OptimalGHCoupling X Y) 
goal: CompactSpace (GromovHausdorff.OptimalGHCoupling X Y)

full_name: GromovHausdorff.hausdorffDist_optimal_le_HD
code: /-- For any candidate `f`, `HD(f)` is larger than or equal to the Hausdorff distance in the
optimal coupling. This follows from the fact that `HD` of the optimal candidate is exactly
the Hausdorff distance in the optimal coupling, although we only prove here the inequality
we need. -/
theorem hausdorffDist_optimal_le_HD {f} (h : f ∈ candidatesB X Y) :
    hausdorffDist (range (optimalGHInjl X Y)) (range (optimalGHInjr X Y)) ≤ HD f 
goal: Metric.hausdorffDist (Set.range (GromovHausdorff.optimalGHInjl X Y)) (Set.range (GromovHausdorff.optimalGHInjr X Y)) ≤
  GromovHausdorff.HD f