1-- Open balls, closed balls, and spheres in a metric space2-- Part of Cumulus, the Grace17 mathematics library.3-- Copyright (c) 2026 Grant Passmore.4-- Released under the Apache License 2.0. See LICENSE in the repository root.5-- Authors: Grant Passmore67module Grace.Cumulus.Metric.Ball8import Space910def ball (X d x : Set, r : Real) : Set:=11 { y ∈ X | relates(realLess, d(x, y), r) }1213theorem ball.subset (X d x : Set, r : Real)14shows ball(X, d, x, r) ⊆ X15proof16intros y hy17have parts := ball.membership.forward with hy18exact parts.left1920theorem ball.powerset (X d x : Set, r : Real)21shows ball(X, d, x, r) ∈𝒫(X)22proof23exact powerset.membership_iff.backward with (ball.subset at X, d, x, r)2425theorem ball.point (X d x y : Set, r : Real)26requires member : y ∈ ball(X, d, x, r)27shows y ∈ X28proof29have parts := ball.membership.forward with member30exact parts.left3132theorem ball.distance (X d x y : Set, r : Real)33requires member : y ∈ ball(X, d, x, r)34shows d(x, y) < r35proof36have parts := ball.membership.forward with member37exact parts.right3839theorem ball.of_distance (X d x y : Set, r : Real)40requires hy : y ∈ X41requires near : d(x, y) < r42shows y ∈ ball(X, d, x, r)43proof44exact ball.membership.backward with⟨hy, near⟩4546theorem ball.center (X d x : Set, r : Real)47requires metric : IsMetric(X, d)48requires hx : x ∈ X49requires positive : 0 < r50shows x ∈ ball(X, d, x, r)51proof52haveself:= IsMetric.self with metric, hx53apply ball.of_distance with hx54rwself55exact positive5657theorem ball.nonempty (X d x : Set, r : Real)58requires metric : IsMetric(X, d)59requires hx : x ∈ X60requires positive : 0 < r61shows Nonempty(ball(X, d, x, r))62proof63witness x64exact ball.center with metric, hx, positive6566theorem ball.positive_of_member (X d x y : Set, r : Real)67requires metric : IsMetric(X, d)68requires hx : x ∈ X69requires member : y ∈ ball(X, d, x, r)70shows0 < r71proof72have hy := ball.point with member73have near := ball.distance with member74have nonnegative := IsMetric.nonnegative with metric, hx, hy75have real := IsMetric.real with metric, hx, hy76linarith7778theorem ball.empty_of_nonpositive (X d x : Set, r : Real)79requires metric : IsMetric(X, d)80requires hx : x ∈ X81requires nonpositive : r ≤082shows ball(X, d, x, r) =∅83proof84ext y85constructor86 . intro hy87have positive := ball.positive_of_member with metric, hx, hy88exfalso89linarith90 . intro hy91exfalso92exact empty.membership with hy9394theorem ball.symmetric_membership (X d x y : Set, r : Real)95requires metric : IsMetric(X, d)96requires hx : x ∈ X97requires hy : y ∈ X98shows y ∈ ball(X, d, x, r) ↔ x ∈ ball(X, d, y, r)99proof100have symmetric := IsMetric.symmetric with metric, hx, hy101constructor102 . intro member103have near := ball.distance with member104apply ball.of_distance with hx105 rwa symmetric at near106 . intro member107have near := ball.distance with member108apply ball.of_distance with hy109 rwa symmetric110111theorem ball.mono (X d x : Set, r s : Real)112requires metric : IsMetric(X, d)113requires hx : x ∈ X114requires radii : r ≤ s115shows ball(X, d, x, r) ⊆ ball(X, d, x, s)116proof117intros y hy118have point := ball.point with hy119have near := ball.distance with hy120have real := IsMetric.real with metric, hx, point121apply ball.of_distance with point122linarith123124theorem ball.mono_member (X d x y : Set, r s : Real)125requires metric : IsMetric(X, d)126requires hx : x ∈ X127requires member : y ∈ ball(X, d, x, r)128requires radii : r ≤ s129shows y ∈ ball(X, d, x, s)130proof131have inside := ball.mono with metric, hx, radii132exact inside with y, member133134-- Stepping from the center of one ball into another adds the radii.135theorem ball.step (X d x y z : Set, r s : Real)136requires metric : IsMetric(X, d)137requires hx : x ∈ X138requires first : y ∈ ball(X, d, x, r)139requires second : z ∈ ball(X, d, y, s)140shows z ∈ ball(X, d, x, r + s)141proof142have hy := ball.point with first143have hz := ball.point with second144have nearY := ball.distance with first145have nearZ := ball.distance with second146have bound := IsMetric.lt_add_of_lt with metric, hx, hy, hz, nearY, nearZ147exact ball.of_distance with hz, bound148149-- A ball around a point of a ball, with the remaining radius, stays inside.150theorem ball.inside_of_le (X d x y : Set, r s : Real)151requires metric : IsMetric(X, d)152requires hx : x ∈ X153requires hy : y ∈ X154requires room : realAdd(d(x, y), s) ≤ r155shows ball(X, d, y, s) ⊆ ball(X, d, x, r)156proof157intros z hz158have point := ball.point with hz159have near := ball.distance with hz160have triangle := IsMetric.triangle with metric, hx, hy, point161have dxy := IsMetric.real with metric, hx, hy162have dyz := IsMetric.real with metric, hy, point163have dxz := IsMetric.real with metric, hx, point164apply ball.of_distance with point165linarith166167theorem ball.inside (X d x y : Set, r : Real)168requires metric : IsMetric(X, d)169requires hx : x ∈ X170requires member : y ∈ ball(X, d, x, r)171shows ball(X, d, y, realSubValue(r, d(x, y))) ⊆ ball(X, d, x, r)172proof173have hy := ball.point with member174have dxy := IsMetric.real with metric, hx, hy175have room : d(x, y) + (r - d(x, y)) ≤ r bylinarith176exact ball.inside_of_le with metric, hx, hy, room177178theorem ball.inside_radius_positive (X d x y : Set, r : Real)179requires metric : IsMetric(X, d)180requires hx : x ∈ X181requires member : y ∈ ball(X, d, x, r)182shows0 < realSubValue(r, d(x, y))183proof184have hy := ball.point with member185have near := ball.distance with member186have dxy := IsMetric.real with metric, hx, hy187linarith188189-- Balls whose radii together do not reach the distance between the centers190-- are disjoint.191theorem ball.disjoint_of_separated (X d x y : Set, r s : Real)192requires metric : IsMetric(X, d)193requires hx : x ∈ X194requires hy : y ∈ X195requires separated : r + s ≤ d(x, y)196shows Disjoint(ball(X, d, x, r), ball(X, d, y, s))197proof198apply Disjoint.iff.backward199intros z hzx hzy200have point := ball.point with hzx201have nearX := ball.distance with hzx202have nearY := ball.distance with hzy203have triangle := IsMetric.triangle_to with metric, hx, hy, point204have dxy := IsMetric.real with metric, hx, hy205have dxz := IsMetric.real with metric, hx, point206have dyz := IsMetric.real with metric, hy, point207linarith208209-- Distinct points have disjoint balls of half their distance.210theorem ball.half_disjoint (X d x y : Set)211requires metric : IsMetric(X, d)212requires hx : x ∈ X213requires hy : y ∈ X214requires distinct : x ≠ y215shows Disjoint(ball(X, d, x, half(d(x, y))), ball(X, d, y, half(d(x, y))))216proof217have dxy := IsMetric.real with metric, hx, hy218have doubled := half.add_self at d(x, y)219have separated : half(d(x, y)) + half(d(x, y)) ≤ d(x, y) bylinarith220exact ball.disjoint_of_separated with metric, hx, hy, separated221222theorem ball.half_positive (X d x y : Set)223requires metric : IsMetric(X, d)224requires hx : x ∈ X225requires hy : y ∈ X226requires distinct : x ≠ y227shows0 < half(d(x, y))228proof229have positive := IsMetric.positive_of_ne with metric, hx, hy, distinct230have dxy := IsMetric.real with metric, hx, hy231exact half.positive with positive232233-- A point of two balls has a ball inside both.234theorem ball.common_radius (X d x y z : Set, r s : Real)235requires metric : IsMetric(X, d)236requires hx : x ∈ X237requires hy : y ∈ X238requires first : z ∈ ball(X, d, x, r)239requires second : z ∈ ball(X, d, y, s)240shows∃ t ∈ ℝ, 0 < t ∧241 ball(X, d, z, t) ⊆ ball(X, d, x, r) ∧ ball(X, d, z, t) ⊆ ball(X, d, y, s)242proof243have hz := ball.point with first244have dxz := IsMetric.real with metric, hx, hz245have dyz := IsMetric.real with metric, hy, hz246have positiveX := ball.inside_radius_positive with metric, hx, first247have positiveY := ball.inside_radius_positive with metric, hy, second248have insideX := ball.inside with metric, hx, first249have insideY := ball.inside with metric, hy, second250have order := realLess.trichotomy at r - d(x, z), s - d(y, z)251rcases order with smaller | equal | larger252 . have le := realLess.implies_le with smaller253have realT : r - d(x, z) ∈ ℝ bytypecheck254refine⟨r - d(x, z), realT, positiveX, insideX, ?_⟩255have mono := ball.mono with metric, hz, le256exact Subset.transitive with mono, insideY257 . have realT : r - d(x, z) ∈ ℝ bytypecheck258refine⟨r - d(x, z), realT, positiveX, insideX, ?_⟩259rw equal260exact insideY261 . have le := realLess.implies_le with larger262have realT : s - d(y, z) ∈ ℝ bytypecheck263refine⟨s - d(y, z), realT, positiveY, ?_, insideY⟩264have mono := ball.mono with metric, hz, le265exact Subset.transitive with mono, insideX266267-- Closed balls268269def closedBall (X d x : Set, r : Real) : Set:=270 { y ∈ X | relates(realLe, d(x, y), r) }271272theorem closedBall.subset (X d x : Set, r : Real)273shows closedBall(X, d, x, r) ⊆ X274proof275intros y hy276have parts := closedBall.membership.forward with hy277exact parts.left278279theorem closedBall.point (X d x y : Set, r : Real)280requires member : y ∈ closedBall(X, d, x, r)281shows y ∈ X282proof283have parts := closedBall.membership.forward with member284exact parts.left285286theorem closedBall.distance (X d x y : Set, r : Real)287requires member : y ∈ closedBall(X, d, x, r)288shows d(x, y) ≤ r289proof290have parts := closedBall.membership.forward with member291exact parts.right292293theorem closedBall.of_distance (X d x y : Set, r : Real)294requires hy : y ∈ X295requires near : d(x, y) ≤ r296shows y ∈ closedBall(X, d, x, r)297proof298exact closedBall.membership.backward with⟨hy, near⟩299300theorem closedBall.center (X d x : Set, r : Real)301requires metric : IsMetric(X, d)302requires hx : x ∈ X303requires nonnegative : 0≤ r304shows x ∈ closedBall(X, d, x, r)305proof306haveself:= IsMetric.self with metric, hx307apply closedBall.of_distance with hx308rwself309exact nonnegative310311theorem ball.subset_closedBall (X d x : Set, r : Real)312requires metric : IsMetric(X, d)313requires hx : x ∈ X314shows ball(X, d, x, r) ⊆ closedBall(X, d, x, r)315proof316intros y hy317have point := ball.point with hy318have near := ball.distance with hy319have real := IsMetric.real with metric, hx, point320apply closedBall.of_distance with point321exact realLess.implies_le with near322323theorem closedBall.subset_ball (X d x : Set, r s : Real)324requires metric : IsMetric(X, d)325requires hx : x ∈ X326requires radii : r < s327shows closedBall(X, d, x, r) ⊆ ball(X, d, x, s)328proof329intros y hy330have point := closedBall.point with hy331have near := closedBall.distance with hy332have real := IsMetric.real with metric, hx, point333apply ball.of_distance with point334linarith335336theorem closedBall.mono (X d x : Set, r s : Real)337requires metric : IsMetric(X, d)338requires hx : x ∈ X339requires radii : r ≤ s340shows closedBall(X, d, x, r) ⊆ closedBall(X, d, x, s)341proof342intros y hy343have point := closedBall.point with hy344have near := closedBall.distance with hy345have real := IsMetric.real with metric, hx, point346apply closedBall.of_distance with point347linarith348349theorem closedBall.empty_of_negative (X d x : Set, r : Real)350requires metric : IsMetric(X, d)351requires hx : x ∈ X352requires negative : r < 0353shows closedBall(X, d, x, r) =∅354proof355ext y356constructor357 . intro hy358have point := closedBall.point with hy359have near := closedBall.distance with hy360have nonnegative := IsMetric.nonnegative with metric, hx, point361have real := IsMetric.real with metric, hx, point362exfalso363linarith364 . intro hy365exfalso366exact empty.membership with hy367368theorem closedBall.zero (X d x : Set)369requires metric : IsMetric(X, d)370requires hx : x ∈ X371shows closedBall(X, d, x, 0) = {x}372proof373ext y374constructor375 . intro hy376have point := closedBall.point with hy377have near := closedBall.distance with hy378have nonnegative := IsMetric.nonnegative with metric, hx, point379have real := IsMetric.real with metric, hx, point380have zero : d(x, y) = (0:R) bylinarith381have same := IsMetric.eq_of_zero with metric, hx, point, zero382rw same383exact singleton.self at y384 . intro hy385have same := singleton.membership.forward with hy386rw same387have reflexive : (0:R) ≤0bylinarith388exact closedBall.center with metric, hx, reflexive389390theorem closedBall.symmetric_membership (X d x y : Set, r : Real)391requires metric : IsMetric(X, d)392requires hx : x ∈ X393requires hy : y ∈ X394shows y ∈ closedBall(X, d, x, r) ↔ x ∈ closedBall(X, d, y, r)395proof396have symmetric := IsMetric.symmetric with metric, hx, hy397constructor398 . intro member399have near := closedBall.distance with member400apply closedBall.of_distance with hx401 rwa symmetric at near402 . intro member403have near := closedBall.distance with member404apply closedBall.of_distance with hy405 rwa symmetric406407theorem closedBall.step (X d x y z : Set, r s : Real)408requires metric : IsMetric(X, d)409requires hx : x ∈ X410requires first : y ∈ closedBall(X, d, x, r)411requires second : z ∈ closedBall(X, d, y, s)412shows z ∈ closedBall(X, d, x, r + s)413proof414have hy := closedBall.point with first415have hz := closedBall.point with second416have nearY := closedBall.distance with first417have nearZ := closedBall.distance with second418have bound := IsMetric.le_add_of_le with metric, hx, hy, hz, nearY, nearZ419exact closedBall.of_distance with hz, bound420421-- Spheres422423def sphere (X d x : Set, r : Real) : Set:= { y ∈ X | d(x, y) = r }424425theorem sphere.subset (X d x : Set, r : Real)426shows sphere(X, d, x, r) ⊆ X427proof428intros y hy429have parts := sphere.membership.forward with hy430exact parts.left431432theorem sphere.subset_closedBall (X d x : Set, r : Real)433requires metric : IsMetric(X, d)434requires hx : x ∈ X435shows sphere(X, d, x, r) ⊆ closedBall(X, d, x, r)436proof437intros y hy438obtain⟨point, equal⟩:= sphere.membership.forward with hy439have real := IsMetric.real with metric, hx, point440apply closedBall.of_distance with point441rw equal442exact realLe.reflexive443444theorem sphere.disjoint_ball (X d x : Set, r : Real)445shows Disjoint(sphere(X, d, x, r), ball(X, d, x, r))446proof447apply Disjoint.iff.backward448intros y onSphere inBall449obtain⟨point, equal⟩:= sphere.membership.forward with onSphere450have near := ball.distance with inBall451rw equal at near452exact realLess.not_self with near453454theorem closedBall.eq_ball_union_sphere (X d x : Set, r : Real)455requires metric : IsMetric(X, d)456requires hx : x ∈ X457shows closedBall(X, d, x, r) = ball(X, d, x, r) ∪ sphere(X, d, x, r)458proof459apply Subset.antisymmetric460 . intros y hy461have point := closedBall.point with hy462have near := closedBall.distance with hy463have real := IsMetric.real with metric, hx, point464have order := realLess.trichotomy at d(x, y), r465rcases order with less | equal | greater466 . exact union2.left with (ball.of_distance with point, less)467 . have onSphere : y ∈ sphere(X, d, x, r) := sphere.membership.backward with468⟨point, equal⟩469exact union2.right with onSphere470 . exfalso471linarith472 . apply union2.subset473 . exact ball.subset_closedBall with metric, hx474 . exact sphere.subset_closedBall with metric, hx475476theorem sphere.zero (X d x : Set)477requires metric : IsMetric(X, d)478requires hx : x ∈ X479shows sphere(X, d, x, 0) = {x}480proof481ext y482constructor483 . intro hy484obtain⟨point, zero⟩:= sphere.membership.forward with hy485have same := IsMetric.eq_of_zero with metric, hx, point, zero486rw same487exact singleton.self at y488 . intro hy489have same := singleton.membership.forward with hy490rw same491haveself:= IsMetric.self with metric, hx492exact sphere.membership.backward with⟨hx, self⟩493494theorem sphere.empty_of_negative (X d x : Set, r : Real)495requires metric : IsMetric(X, d)496requires hx : x ∈ X497requires negative : r < 0498shows sphere(X, d, x, r) =∅499proof500ext y501constructor502 . intro hy503obtain⟨point, equal⟩:= sphere.membership.forward with hy504have nonnegative := IsMetric.nonnegative with metric, hx, point505rw equal at nonnegative506exfalso507linarith508 . intro hy509exfalso510exact empty.membership with hy511