1-- The metric topology: open sets are those containing a ball around each of2-- their points; they form a Hausdorff topology in which balls are open3-- Part of Cumulus, the Grace17 mathematics library.4-- Copyright (c) 2026 Grant Passmore.5-- Released under the Apache License 2.0. See LICENSE in the repository root.6-- Authors: Grant Passmore78module Grace.Cumulus.Metric.Open9import Ball1011predicate MetricOpen (X d U : Set) :=12 (U ⊆ X) ∧ (∀ x ∈ U, ∃ r ∈ ℝ, 0 < r ∧ ball(X, d, x, r) ⊆ U)1314def metricTopology (X d : Set) : Set:=15 { U ∈𝒫(X) |∀ x ∈ U, ∃ r ∈ ℝ, 0 < r ∧ ball(X, d, x, r) ⊆ U }1617theorem MetricOpen.subset (X d U : Set)18requiresopen : MetricOpen(X, d, U)19shows U ⊆ X20proof21exactopen.left2223theorem MetricOpen.ball_inside (X d U x : Set)24requiresopen : MetricOpen(X, d, U)25requires hx : x ∈ U26shows∃ r ∈ ℝ, 0 < r ∧ ball(X, d, x, r) ⊆ U27proof28exactopen.right with x, hx2930theorem metricTopology.of_open (X d U : Set)31requiresopen : MetricOpen(X, d, U)32shows U ∈ metricTopology(X, d)33proof34obtain⟨inside, balls⟩:=open35apply metricTopology.membership.backward36exact⟨(powerset.membership_iff.backward with inside), balls⟩3738theorem metricTopology.open (X d U : Set)39requires member : U ∈ metricTopology(X, d)40shows MetricOpen(X, d, U)41proof42obtain⟨bound, balls⟩:= metricTopology.membership.forward with member43exact⟨(powerset.membership_iff.forward with bound), balls⟩4445theorem metricTopology.iff (X d U : Set)46shows U ∈ metricTopology(X, d) ↔ MetricOpen(X, d, U)47proof48constructor49 . intro member50exact metricTopology.open with member51 . introopen52exact metricTopology.of_open withopen5354theorem metricTopology.subset (X d U : Set)55requires member : U ∈ metricTopology(X, d)56shows U ⊆ X57proof58exact MetricOpen.subset with (metricTopology.open with member)5960theorem metricTopology.ball_inside (X d U x : Set)61requires member : U ∈ metricTopology(X, d)62requires hx : x ∈ U63shows∃ r ∈ ℝ, 0 < r ∧ ball(X, d, x, r) ⊆ U64proof65exact MetricOpen.ball_inside with (metricTopology.open with member), hx6667theorem metricTopology.subset_powerset (X d : Set)68shows metricTopology(X, d) ⊆𝒫(X)69proof70intros U hU71exact powerset.membership_iff.backward with (metricTopology.subset with hU)7273theorem MetricOpen.whole (X d : Set)74shows MetricOpen(X, d, X)75proof76constructor77 . exact Subset.reflexive at X78 . intros x hx79have one : (1:R) ∈ ℝ bytypecheck80have positive : (0:R) < 1bylinarith81exact⟨(1:R), one, positive, (ball.subset at X, d, x, (1:R))⟩8283theorem MetricOpen.empty (X d : Set)84shows MetricOpen(X, d, ∅)85proof86constructor87 . exact empty.subset at X88 . intros x hx89exfalso90exact empty.membership with hx9192theorem MetricOpen.union (X d S : Set)93requiresopen : ∀ U ∈ S, MetricOpen(X, d, U)94shows MetricOpen(X, d, ⋃(S))95proof96constructor97 . apply union.subset98intros U hU99exact MetricOpen.subset with (openwith U, hU)100 . intros x hx101obtain⟨U, hU, hxU⟩:= union.membership.forward with hx102obtain⟨r, hr, positive, inside⟩:=103 MetricOpen.ball_inside with (openwith U, hU), hxU104refine⟨r, hr, positive, ?_⟩105exact Subset.transitive with inside, (union.subset_of_member with hU)106107theorem MetricOpen.union2 (X d U V : Set)108requires openU : MetricOpen(X, d, U)109requires openV : MetricOpen(X, d, V)110shows MetricOpen(X, d, U ∪ V)111proof112constructor113 . exact union2.subset with openU.left, openV.left114 . intros x hx115havesplit:= union2.membership.forward with hx116casessplitwith inU | inV117 . obtain⟨r, hr, positive, inside⟩:= MetricOpen.ball_inside with openU, inU118refine⟨r, hr, positive, ?_⟩119exact Subset.transitive with inside, (union2.subset_left at U, V)120 . obtain⟨r, hr, positive, inside⟩:= MetricOpen.ball_inside with openV, inV121refine⟨r, hr, positive, ?_⟩122exact Subset.transitive with inside, (union2.subset_right at U, V)123124theorem MetricOpen.intersection2 (X d U V : Set)125requires metric : IsMetric(X, d)126requires openU : MetricOpen(X, d, U)127requires openV : MetricOpen(X, d, V)128shows MetricOpen(X, d, U ∩ V)129proof130constructor131 . exact Subset.transitive with (intersection.subset_left at U, V), openU.left132 . intros x hx133have both := intersection.membership.forward with hx134have hxX := openU.left with x, both.left135obtain⟨r, hr, positiveR, insideU⟩:=136 MetricOpen.ball_inside with openU, both.left137obtain⟨s, hs, positiveS, insideV⟩:=138 MetricOpen.ball_inside with openV, both.right139have centerR := ball.center with metric, hxX, positiveR140have centerS := ball.center with metric, hxX, positiveS141obtain⟨t, ht, positiveT, inR, inS⟩:=142 ball.common_radius with metric, hxX, hxX, centerR, centerS143refine⟨t, ht, positiveT, ?_⟩144apply intersection.greatest145 . exact Subset.transitive with inR, insideU146 . exact Subset.transitive with inS, insideV147148theorem metricTopology.topology (X d : Set)149requires metric : IsMetric(X, d)150shows IsTopology(X, metricTopology(X, d))151proof152constructor153 . exact metricTopology.subset_powerset at X, d154 . constructor155 . exact metricTopology.of_open with (MetricOpen.whole at X, d)156 . constructor157 . intros S hS158apply metricTopology.of_open159apply MetricOpen.union160intros U hU161exact metricTopology.open with (hS with U, hU)162 . intros U hU V hV163have openU := metricTopology.open with hU164have openV := metricTopology.open with hV165exact metricTopology.of_open with (MetricOpen.intersection2 with166 metric, openU, openV)167168theorem metricTopology.empty (X d : Set)169shows∅∈ metricTopology(X, d)170proof171exact metricTopology.of_open with (MetricOpen.empty at X, d)172173theorem metricTopology.whole (X d : Set)174shows X ∈ metricTopology(X, d)175proof176exact metricTopology.of_open with (MetricOpen.whole at X, d)177178-- Balls are open.179theorem ball.open (X d x : Set, r : Real)180requires metric : IsMetric(X, d)181requires hx : x ∈ X182shows MetricOpen(X, d, ball(X, d, x, r))183proof184constructor185 . exact ball.subset at X, d, x, r186 . intros y hy187have hyX := ball.point with hy188have dxy := IsMetric.real with metric, hx, hyX189have positive := ball.inside_radius_positive with metric, hx, hy190have inside := ball.inside with metric, hx, hy191have radiusReal : r - d(x, y) ∈ ℝ bytypecheck192exact⟨r - d(x, y), radiusReal, positive, inside⟩193194theorem ball.member_topology (X d x : Set, r : Real)195requires metric : IsMetric(X, d)196requires hx : x ∈ X197shows ball(X, d, x, r) ∈ metricTopology(X, d)198proof199exact metricTopology.of_open with (ball.open with metric, hx)200201-- Distinct points are separated by disjoint balls, so the metric topology202-- is Hausdorff.203theorem metricTopology.hausdorff (X d : Set)204requires metric : IsMetric(X, d)205shows IsHausdorff(X, metricTopology(X, d))206proof207intros x hx y hy distinct208have dxy := IsMetric.real with metric, hx, hy209have positive := ball.half_positive with metric, hx, hy, distinct210have disjoint := ball.half_disjoint with metric, hx, hy, distinct211refine⟨ball(X, d, x, half(d(x, y))), (ball.member_topology with metric, hx),212 ball(X, d, y, half(d(x, y))), (ball.member_topology with213 metric, hy), ?_, ?_, disjoint⟩214 . exact ball.center with metric, hx, positive215 . exact ball.center with metric, hy, positive216217-- A point is interior to A exactly when some ball around it lies in A.218theorem metricInterior.membership (X d A x : Set)219requires metric : IsMetric(X, d)220shows x ∈ interiorIn(metricTopology(X, d), A) ↔221 x ∈ X ∧ (∃ r ∈ ℝ, 0 < r ∧ ball(X, d, x, r) ⊆ A)222proof223constructor224 . intro hx225unfold interiorIn at hx226obtain⟨U, hU, hxU⟩:= union.membership.forward with hx227obtain⟨openU, inside⟩:= openSubsets.membership.forward with hU228have hxX := metricTopology.subset with openU, x, hxU229obtain⟨r, hr, positive, ballInside⟩:=230 metricTopology.ball_inside with openU, hxU231exact⟨hxX, r, hr, positive, (Subset.transitive with ballInside, inside)⟩232 . intro data233obtain⟨hxX, r, hr, positive, inside⟩:= data234have openBall := ball.member_topology at X, d, x, r with metric, hxX235have greatest := interiorIn.greatest with openBall, inside236exact greatest with x, (ball.center with metric, hxX, positive)237