Theorem: Affine.Simplex.orthogonalProjection_eq_circumcenter_of_exists_dist_eq
File: Mathlib/Geometry/Euclidean/Circumcenter.lean

Proof steps:
state_before: V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
n : ℕ
s : Simplex ℝ P n
p : P
hr : ∃ r, ∀ (i : Fin (n + 1)), dist (s.points i) p = r
⊢ ↑(s.orthogonalProjectionSpan p) = s.circumcenter
state_after: V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
n : ℕ
s : Simplex ℝ P n
p : P
hr : ∃ r, ∀ (i : Fin (n + 1)), (fun x => dist x p = r) (s.points i)
⊢ ↑(s.orthogonalProjectionSpan p) = s.circumcenter
tactic: change ∃ r : ℝ, ∀ i, (fun x => dist x p = r) (s.points i) at hr
state_before: V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
n : ℕ
s : Simplex ℝ P n
p : P
hr : ∃ r, ∀ (i : Fin (n + 1)), (fun x => dist x p = r) (s.points i)
⊢ ↑(s.orthogonalProjectionSpan p) = s.circumcenter
state_after: V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
n : ℕ
s : Simplex ℝ P n
p : P
hr✝ : ∃ r, ∀ (i : Fin (n + 1)), (fun x => dist x p = r) (s.points i)
hr : ∃ r, ∀ a ∈ Set.range fun i => s.points i, dist a p = r
⊢ ↑(s.orthogonalProjectionSpan p) = s.circumcenter
tactic: have hr : ∃ (r : ℝ), ∀ (a : P),
      a ∈ Set.range (fun (i : Fin (n + 1)) => s.points i) → dist a p = r := by
    cases' hr with r hr
    use r
    refine Set.forall_mem_range.mpr ?_
    exact hr
state_before: V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
n : ℕ
s : Simplex ℝ P n
p : P
hr✝ : ∃ r, ∀ (i : Fin (n + 1)), (fun x => dist x p = r) (s.points i)
hr : ∃ r, ∀ a ∈ Set.range fun i => s.points i, dist a p = r
⊢ ↑(s.orthogonalProjectionSpan p) = s.circumcenter
state_after: V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
n : ℕ
s : Simplex ℝ P n
p : P
hr✝ : ∃ r, ∀ (i : Fin (n + 1)), (fun x => dist x p = r) (s.points i)
hr :
  ∃ r,
    ∀ p1 ∈ Set.range fun i => s.points i,
      dist p1 ↑((EuclideanGeometry.orthogonalProjection (affineSpan ℝ (Set.range fun i => s.points i))) p) = r
⊢ ↑(s.orthogonalProjectionSpan p) = s.circumcenter
tactic: rw [exists_dist_eq_iff_exists_dist_orthogonalProjection_eq (subset_affineSpan ℝ _) p] at hr
state_before: V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
n : ℕ
s : Simplex ℝ P n
p : P
hr✝ : ∃ r, ∀ (i : Fin (n + 1)), (fun x => dist x p = r) (s.points i)
hr :
  ∃ r,
    ∀ p1 ∈ Set.range fun i => s.points i,
      dist p1 ↑((EuclideanGeometry.orthogonalProjection (affineSpan ℝ (Set.range fun i => s.points i))) p) = r
⊢ ↑(s.orthogonalProjectionSpan p) = s.circumcenter
state_after: case intro
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
n : ℕ
s : Simplex ℝ P n
p : P
hr✝ : ∃ r, ∀ (i : Fin (n + 1)), (fun x => dist x p = r) (s.points i)
r : ℝ
hr :
  ∀ p1 ∈ Set.range fun i => s.points i,
    dist p1 ↑((EuclideanGeometry.orthogonalProjection (affineSpan ℝ (Set.range fun i => s.points i))) p) = r
⊢ ↑(s.orthogonalProjectionSpan p) = s.circumcenter
tactic: cases' hr with r hr
state_before: case intro
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
n : ℕ
s : Simplex ℝ P n
p : P
hr✝ : ∃ r, ∀ (i : Fin (n + 1)), (fun x => dist x p = r) (s.points i)
r : ℝ
hr :
  ∀ p1 ∈ Set.range fun i => s.points i,
    dist p1 ↑((EuclideanGeometry.orthogonalProjection (affineSpan ℝ (Set.range fun i => s.points i))) p) = r
⊢ ↑(s.orthogonalProjectionSpan p) = s.circumcenter
state_after: no goals
tactic: exact
    s.eq_circumcenter_of_dist_eq (orthogonalProjection_mem p) fun i => hr _ (Set.mem_range_self i)