1-- Limits in a metric space: convergence through open sets and through the2-- real sequence of distances to the limit, sequences agreeing eventually,3-- limits against closed balls, continuous images of convergent and Cauchy4-- sequences, and the closure of a set in metric terms5-- Part of Cumulus, the Grace17 mathematics library.6-- Copyright (c) 2026 Grant Passmore.7-- Released under the Apache License 2.0. See LICENSE in the repository root.8-- Authors: Grant Passmore910module Grace.Cumulus.Metric.Limits11import Product1213theorem SequenceIn.constant (X x : Set)14requires hx : x ∈ X15shows SequenceIn(X, constantFunction(ℕ, X, x))16proof17exact constantFunction.function at ℕ, X, x with hx1819theorem IsCauchy.constant (X d x : Set)20requires metric : IsMetric(X, d)21requires hx : x ∈ X22shows IsCauchy(X, d, constantFunction(ℕ, X, x))23proof24have converges := constantFunction.converges_in with metric, hx25exact ConvergesIn.cauchy with metric, converges2627-- Convergence through open neighbourhoods of the limit.28theorem ConvergesIn.iff_open (X d u x : Set)29requires metric : IsMetric(X, d)30requires sequence : SequenceIn(X, u)31requires hx : x ∈ X32shows ConvergesIn(X, d, u, x) ↔33 (∀ U, MetricOpen(X, d, U) → x ∈ U →∃ N ∈ ℕ, ∀ n ∈ ℕ, (N ≤ n → u(n) ∈ U))34proof35constructor36 . intro converges37intros U open hxU38exact ConvergesIn.eventually_in_open with converges, open, hxU39 . intro neighbourhoods40apply ConvergesIn.of_eventually with sequence, hx41intros ε hε positive42have typedE : Real(ε) byexact hε43haveopen:= ball.open at X, d, x, ε with metric, hx44have center := ball.center with metric, hx, positive45obtain⟨N, hN, inside⟩:= neighbourhoods with ball(X, d, x, ε), open, center46refine⟨N, hN, ?_⟩47intros n hn le48exact ball.distance with (inside with n, hn, le)4950-- Sequences that agree from some index on have the same limits.51theorem ConvergesIn.of_eventually_equal (X d u v x M : Set)52requires converges : ConvergesIn(X, d, u, x)53requires sequence : SequenceIn(X, v)54requires hM : M ∈ ℕ55requires agree : ∀ n ∈ ℕ, (M ≤ n → v(n) = u(n))56shows ConvergesIn(X, d, v, x)57proof58have hx := ConvergesIn.limit_point with converges59apply ConvergesIn.of_eventually with sequence, hx60intros ε hε positive61obtain⟨N, hN, near⟩:= ConvergesIn.eventually with converges, positive62have natM : Nat(M) byexact hM63have natN : Nat(N) byexact hN64obtain⟨K, hK, leM, leN⟩:= naturalPair.upper_bound at M, N65refine⟨K, hK, ?_⟩66intros n hn le67have natK : Nat(K) byexact hK68have natn : Nat(n) byexact hn69have aboveM := LessEqual.transitive with leM, le70have aboveN := LessEqual.transitive with leN, le71have same := agree with n, hn, aboveM72rw same73exact near with n, hn, aboveN7475theorem ConvergesIn.limit_in_closedBall (X d u x y : Set, r : Real)76requires metric : IsMetric(X, d)77requires converges : ConvergesIn(X, d, u, x)78requires hy : y ∈ X79requires terms : ∀ n ∈ ℕ, u(n) ∈ closedBall(X, d, y, r)80shows x ∈ closedBall(X, d, y, r)81proof82have closed := closedBall.closed at X, d, y, r with metric, hy83exact ConvergesIn.limit_in_closed with closed, terms, converges8485theorem ConvergesIn.distance_le (X d u x y : Set, r : Real)86requires metric : IsMetric(X, d)87requires converges : ConvergesIn(X, d, u, x)88requires hy : y ∈ X89requires bounds : ∀ n ∈ ℕ, d(y, u(n)) ≤ r90shows d(y, x) ≤ r91proof92have sequence := ConvergesIn.sequence with converges93have terms : ∀ n ∈ ℕ, u(n) ∈ closedBall(X, d, y, r)94intros n hn95have term := SequenceIn.term_of_member with sequence, hn96exact closedBall.of_distance with term, (bounds with n, hn)97have inBall := ConvergesIn.limit_in_closedBall with98 metric, converges, hy, terms99exact closedBall.distance with inBall100101theorem ConvergesIn.map_continuous (f X d Y e u x : Set)102requires continuous : IsMetricContinuous(f, X, d, Y, e)103requires converges : ConvergesIn(X, d, u, x)104shows ConvergesIn(Y, e, compose(f, u, ℕ, X, Y), f(x))105proof106have hx := ConvergesIn.limit_point with converges107have atX := IsMetricContinuous.at with continuous, hx108exact ConvergesIn.map with atX, converges109110theorem IsLipschitz.cauchy (f X d Y e u : Set) (K : Real)111requires metricD : IsMetric(X, d)112requires metricE : IsMetric(Y, e)113requires lipschitz : IsLipschitz(f, X, d, Y, e, K)114requires cauchy : IsCauchy(X, d, u)115shows IsCauchy(Y, e, compose(f, u, ℕ, X, Y))116proof117have uniform := IsLipschitz.uniformly_continuous with118 metricD, metricE, lipschitz119exact IsUniformlyContinuous.cauchy with uniform, cauchy120121theorem IsIsometry.cauchy (f X d Y e u : Set)122requires isometry : IsIsometry(f, X, d, Y, e)123requires cauchy : IsCauchy(X, d, u)124shows IsCauchy(Y, e, compose(f, u, ℕ, X, Y))125proof126have uniform := IsIsometry.uniformly_continuous with isometry127exact IsUniformlyContinuous.cauchy with uniform, cauchy128129theorem IsIsometry.converges (f X d Y e u x : Set)130requires isometry : IsIsometry(f, X, d, Y, e)131requires converges : ConvergesIn(X, d, u, x)132shows ConvergesIn(Y, e, compose(f, u, ℕ, X, Y), f(x))133proof134have continuous := IsIsometry.continuous with isometry135exact ConvergesIn.map_continuous with continuous, converges136137-- The real sequence of distances to a point.138defgraph distanceSequence (X d u x : Set) (n ∈ ℕ) : ℝ := d(x, u(n))139requires metric : IsMetric(X, d)140requires sequence : SequenceIn(X, u)141requires hx : x ∈ X142proof143have term := SequenceIn.term_of_member with sequence, member144exact IsMetric.real with metric, hx, term145146theorem distanceSequence.real_sequence (X d u x : Set)147requires metric : IsMetric(X, d)148requires sequence : SequenceIn(X, u)149requires hx : x ∈ X150shows RealSequence(distanceSequence(X, d, u, x))151proof152exact distanceSequence.function with metric, sequence, hx153154-- A sequence converges to x exactly when its distances to x tend to zero.155theorem ConvergesIn.distance_converges (X d u x : Set)156requires metric : IsMetric(X, d)157requires converges : ConvergesIn(X, d, u, x)158shows ConvergesTo(distanceSequence(X, d, u, x), (0:R))159proof160have sequence := ConvergesIn.sequence with converges161have hx := ConvergesIn.limit_point with converges162unfold ConvergesTo163constructor164 . exact distanceSequence.real_sequence with metric, sequence, hx165 . intros E hE positive166obtain⟨N, hN, near⟩:= ConvergesIn.eventually with converges, positive167refine⟨N, hN, ?_⟩168intros n hn le169have term := SequenceIn.term_of_member with sequence, hn170have distance := IsMetric.real with metric, hx, term171have nonnegative := IsMetric.nonnegative with metric, hx, term172have close := near with n, hn, le173have value := distanceSequence.value at X, d, u, x, n with174 metric, sequence, hx175rw value176apply openBall.membership.backward177refine⟨distance, ?_⟩178unfold dist179have zero := realSubValue.zero_right at d(x, u(n))180have unfolded := abs.of_nonnegative with nonnegative181rw [zero, unfolded]182exact close183184theorem ConvergesIn.of_distance_converges (X d u x : Set)185requires metric : IsMetric(X, d)186requires sequence : SequenceIn(X, u)187requires hx : x ∈ X188requires converges : ConvergesTo(distanceSequence(X, d, u, x), (0:R))189shows ConvergesIn(X, d, u, x)190proof191obtain⟨realSequence, tail⟩:= converges192apply ConvergesIn.of_eventually with sequence, hx193intros ε hε positive194obtain⟨N, hN, near⟩:= tail with ε, hε, positive195refine⟨N, hN, ?_⟩196intros n hn le197have term := SequenceIn.term_of_member with sequence, hn198have distance := IsMetric.real with metric, hx, term199have nonnegative := IsMetric.nonnegative with metric, hx, term200have inBall := near with n, hn, le201have value := distanceSequence.value at X, d, u, x, n with202 metric, sequence, hx203rw value at inBall204obtain⟨valueReal, close⟩:= openBall.membership.forward with inBall205unfold dist at close206have zero := realSubValue.zero_right at d(x, u(n))207have unfolded := abs.of_nonnegative with nonnegative208rw [zero, unfolded] at close209exact close210211theorem ConvergesIn.iff_distance_converges (X d u x : Set)212requires metric : IsMetric(X, d)213requires sequence : SequenceIn(X, u)214requires hx : x ∈ X215shows216 ConvergesIn(X, d, u, x) ↔ ConvergesTo(distanceSequence(X, d, u, x), (0:R))217proof218constructor219 . intro converges220exact ConvergesIn.distance_converges with metric, converges221 . intro converges222exact ConvergesIn.of_distance_converges with metric, sequence, hx, converges223224-- The closure in metric terms.225theorem metricClosure.closed (X d A : Set)226requires metric : IsMetric(X, d)227requires hA : A ⊆ X228shows MetricClosed(X, d, closure(X, metricTopology(X, d), A))229proof230exact closure.closed with (metricTopology.topology with metric), hA231232theorem metricClosure.contains (X d A : Set)233requires metric : IsMetric(X, d)234requires hA : A ⊆ X235shows A ⊆ closure(X, metricTopology(X, d), A)236proof237exact Grace.Cumulus.Topology.Space.closure.contains with238 (metricTopology.topology with metric), hA239240theorem metricClosure.subset (X d A : Set)241requires metric : IsMetric(X, d)242requires hA : A ⊆ X243shows closure(X, metricTopology(X, d), A) ⊆ X244proof245exact closure.subset with (metricTopology.topology with metric), hA246247theorem metricClosure.least (X d A C : Set)248requires closed : MetricClosed(X, d, C)249requires hAC : A ⊆ C250shows closure(X, metricTopology(X, d), A) ⊆ C251proof252unfold MetricClosed at closed253exact closure.least with closed, hAC254255theorem metricClosure.of_closed (X d C : Set)256requires metric : IsMetric(X, d)257requires closed : MetricClosed(X, d, C)258shows closure(X, metricTopology(X, d), C) = C259proof260unfold MetricClosed at closed261exact closure.of_closed with (metricTopology.topology with metric), closed262263theorem MetricClosed.iff_closure (X d C : Set)264requires metric : IsMetric(X, d)265requires hC : C ⊆ X266shows MetricClosed(X, d, C) ↔ closure(X, metricTopology(X, d), C) = C267proof268constructor269 . intro closed270exact metricClosure.of_closed with metric, closed271 . intro equal272have closed := metricClosure.closed with metric, hC273 rwa equal at closed274275-- The closure of a bounded set is bounded.276theorem IsBounded.closure (X d S : Set)277requires metric : IsMetric(X, d)278requires bounded : IsBounded(X, d, S)279shows IsBounded(X, d, closure(X, metricTopology(X, d), S))280proof281have inside := IsBounded.subset with bounded282havesplit : Nonempty(S) ∨¬Nonempty(S) bytauto283casessplitwith nonempty | empty284 . obtain⟨x, hx⟩:= nonempty285have hxX := inside with x, hx286obtain⟨r, hr, positive, ballInside⟩:=287 IsBounded.ball_around with metric, bounded, hx288have typedR : Real(r) byexact hr289have closed := closedBall.closed at X, d, x, r with metric, hxX290have closedInside := ball.subset_closedBall with metric, hxX291have insideClosed := Subset.transitive with ballInside, closedInside292have least := metricClosure.least with closed, insideClosed293exact IsBounded.of_closedBall with metric, hxX, least294 . have equal : S =∅295apply Subset.antisymmetric296 . intros s hs297exfalso298apply empty299exact⟨s, hs⟩300 . exact empty.subset at S301rw equal302have closedEmpty := MetricClosed.empty at X, d with metric303have same := metricClosure.of_closed with metric, closedEmpty304rw same305exact IsBounded.empty at X, d306307theorem MetricOpen.difference (X d U C : Set)308requires metric : IsMetric(X, d)309requiresopen : MetricOpen(X, d, U)310requires closed : MetricClosed(X, d, C)311shows MetricOpen(X, d, U ∖ C)312proof313have openComplement := MetricClosed.complement_open with closed314have both := MetricOpen.intersection2 with metric, open, openComplement315have same : U ∖ C = U ∩ complement(X, C)316have insideU := MetricOpen.subset withopen317ext y318constructor319 . intro hy320have parts := difference.membership.forward with hy321apply intersection.membership.backward322refine⟨parts.left, ?_⟩323exact complement.membership.backward with⟨(insideU with324 y, parts.left), parts.right⟩325 . intro hy326have parts := intersection.membership.forward with hy327have away := complement.membership.forward with parts.right328exact difference.membership.backward with⟨parts.left, away.right⟩329 rwa same330331theorem MetricClosed.difference (X d C U : Set)332requires metric : IsMetric(X, d)333requires closed : MetricClosed(X, d, C)334requiresopen : MetricOpen(X, d, U)335shows MetricClosed(X, d, C ∖ U)336proof337have closedComplement := MetricOpen.complement_closed with metric, open338have both := MetricClosed.intersection2 with metric, closed, closedComplement339have same : C ∖ U = C ∩ complement(X, U)340have insideC := MetricClosed.subset with closed341ext y342constructor343 . intro hy344have parts := difference.membership.forward with hy345apply intersection.membership.backward346refine⟨parts.left, ?_⟩347exact complement.membership.backward with⟨(insideC with348 y, parts.left), parts.right⟩349 . intro hy350have parts := intersection.membership.forward with hy351have away := complement.membership.forward with parts.right352exact difference.membership.backward with⟨parts.left, away.right⟩353 rwa same354355theorem ball.subset_interior_closedBall (X d x : Set, r : Real)356requires metric : IsMetric(X, d)357requires hx : x ∈ X358shows359 ball(X, d, x, r) ⊆ interiorIn(metricTopology(X, d), closedBall(X, d, x, r))360proof361haveopen:= ball.member_topology at X, d, x, r with metric, hx362have inside := ball.subset_closedBall with metric, hx363exact interiorIn.greatest withopen, inside364365-- A point is isolated exactly when some ball around it is a singleton.366theorem metricTopology.singleton_open_iff (X d x : Set)367requires metric : IsMetric(X, d)368requires hx : x ∈ X369shows MetricOpen(X, d, {x}) ↔∃ r ∈ ℝ, 0 < r ∧ ball(X, d, x, r) = {x}370proof371constructor372 . introopen373obtain⟨r, hr, positive, inside⟩:=374 MetricOpen.ball_inside withopen, (singleton.self at x)375refine⟨r, hr, positive, ?_⟩376apply Subset.antisymmetric377 . exact inside378 . intros y hy379have same := singleton.membership.forward with hy380rw same381exact ball.center with metric, hx, positive382 . intro data383obtain⟨r, hr, positive, same⟩:= data384constructor385 . intros y hy386have equal := singleton.membership.forward with hy387 rwa equal388 . intros y hy389have equal := singleton.membership.forward with hy390rwunder equal391refine⟨r, hr, positive, ?_⟩392rw same393exact Subset.reflexive at {x}394