1-- Subspaces of a metric space: the restricted metric, its balls as traces2-- of balls, open and closed sets, convergence and Cauchy sequences, closed3-- subspaces of complete spaces, restricted maps, and the inclusion isometry4-- Part of Cumulus, the Grace17 mathematics library.5-- Copyright (c) 2026 Grant Passmore.6-- Released under the Apache License 2.0. See LICENSE in the repository root.7-- Authors: Grant Passmore89module Grace.Cumulus.Metric.Subspace10import Discrete1112def subspaceMetric (d S : Set) : Set:= restrict(d, S × S)1314theorem subspaceMetric.function (X d S : Set)15requires metric : IsMetric(X, d)16requires inside : S ⊆ X17shows subspaceMetric(d, S) : S × S → ℝ18proof19have function := IsMetric.function with metric20have product := product.monotone with inside, inside21unfold subspaceMetric22exact restrict.domain_function with function, product2324theorem subspaceMetric.apply (X d S x y : Set)25requires metric : IsMetric(X, d)26requires inside : S ⊆ X27requires hx : x ∈ S28requires hy : y ∈ S29shows subspaceMetric(d, S)(x, y) = d(x, y)30proof31have function := IsMetric.function with metric32have product := product.monotone with inside, inside33have pair := product.pair at x, y, S, S with hx, hy34unfold call235unfold subspaceMetric36exact restrict.domain_apply with function, product, pair3738theorem subspaceMetric.metric (X d S : Set)39requires metric : IsMetric(X, d)40requires inside : S ⊆ X41shows IsMetric(S, subspaceMetric(d, S))42proof43constructor44 . exact subspaceMetric.function with metric, inside45 . constructor46 . intros x hx y hy47have value := subspaceMetric.apply with metric, inside, hx, hy48rw value49exact IsMetric.nonnegative with metric, (inside with x, hx), (inside with50 y, hy)51 . constructor52 . intros x hx y hy53have value := subspaceMetric.apply with metric, inside, hx, hy54rw value55exact IsMetric.eq_zero_iff with metric, (inside with x, hx),56 (inside with57 y, hy)58 . constructor59 . intros x hx y hy60have valueXY := subspaceMetric.apply with metric, inside, hx, hy61have valueYX := subspaceMetric.apply with metric, inside, hy, hx62rw [valueXY, valueYX]63exact IsMetric.symmetric with metric, (inside with x, hx),64 (inside with65 y, hy)66 . intros x hx y hy z hz67have valueXZ := subspaceMetric.apply with metric, inside, hx, hz68have valueXY := subspaceMetric.apply with metric, inside, hx, hy69have valueYZ := subspaceMetric.apply with metric, inside, hy, hz70rw [valueXZ, valueXY, valueYZ]71exact IsMetric.triangle with metric, (inside with x, hx), (inside with72 y, hy),73 (inside with z, hz)7475theorem subspaceMetric.whole (X d : Set)76requires metric : IsMetric(X, d)77shows subspaceMetric(d, X) = d78proof79have function := IsMetric.function with metric80have restricted := subspaceMetric.function with81 metric, (Subset.reflexive at X)82apply FunctionBetween.ext with restricted, function83intros p hp84obtain⟨bound, x, hx, y, hy, rfl⟩:= product.membership.forward with hp85have value := subspaceMetric.apply with86 metric, (Subset.reflexive at X), hx, hy87unfold call2 at value88exact value8990theorem subspaceMetric.nested (d S T : Set)91requires inside : T ⊆ S92shows subspaceMetric(subspaceMetric(d, S), T) = subspaceMetric(d, T)93proof94have product := product.monotone with inside, inside95unfold subspaceMetric96exact restrict.nested with product9798-- Balls of the subspace are traces of balls of the space.99theorem subspaceMetric.ball (X d S x : Set, r : Real)100requires metric : IsMetric(X, d)101requires inside : S ⊆ X102requires hx : x ∈ S103shows ball(S, subspaceMetric(d, S), x, r) = ball(X, d, x, r) ∩ S104proof105ext y106constructor107 . intro hy108have hyS := ball.point with hy109have near := ball.distance with hy110have value := subspaceMetric.apply with metric, inside, hx, hyS111rw value at near112apply intersection.membership.backward113exact⟨(ball.of_distance with (inside with y, hyS), near), hyS⟩114 . intro hy115have both := intersection.membership.forward with hy116have near := ball.distance with both.left117have value := subspaceMetric.apply with metric, inside, hx, both.right118apply ball.of_distance with both.right119rw value120exact near121122theorem subspaceMetric.closedBall (X d S x : Set, r : Real)123requires metric : IsMetric(X, d)124requires inside : S ⊆ X125requires hx : x ∈ S126shows closedBall(S, subspaceMetric(d, S), x, r) = closedBall(X, d, x, r) ∩ S127proof128ext y129constructor130 . intro hy131have hyS := closedBall.point with hy132have near := closedBall.distance with hy133have value := subspaceMetric.apply with metric, inside, hx, hyS134rw value at near135apply intersection.membership.backward136exact⟨(closedBall.of_distance with (inside with y, hyS), near), hyS⟩137 . intro hy138have both := intersection.membership.forward with hy139have near := closedBall.distance with both.left140have value := subspaceMetric.apply with metric, inside, hx, both.right141apply closedBall.of_distance with both.right142rw value143exact near144145theorem subspaceMetric.open_of_open (X d S U : Set)146requires metric : IsMetric(X, d)147requires inside : S ⊆ X148requiresopen : MetricOpen(X, d, U)149shows MetricOpen(S, subspaceMetric(d, S), U ∩ S)150proof151constructor152 . exact intersection.subset_right at U, S153 . intros x hx154have both := intersection.membership.forward with hx155obtain⟨r, hr, positive, ballInside⟩:=156 MetricOpen.ball_inside withopen, both.left157refine⟨r, hr, positive, ?_⟩158have typedR : Real(r) byexact hr159have trace := subspaceMetric.ball at X, d, S, x, r with160 metric, inside, both.right161rw trace162exact intersection.monotone_left with ballInside163164theorem subspaceMetric.closed_of_closed (X d S C : Set)165requires metric : IsMetric(X, d)166requires inside : S ⊆ X167requires closed : MetricClosed(X, d, C)168shows MetricClosed(S, subspaceMetric(d, S), C ∩ S)169proof170apply MetricClosed.of_ball_disjoint with (intersection.subset_right at C, S)171intros x hx outside172have hxX := inside with x, hx173have away : ¬x ∈ C174intro hxC175apply outside176exact intersection.membership.backward with⟨hxC, hx⟩177obtain⟨r, hr, positive, disjoint⟩:=178 MetricClosed.ball_disjoint with closed, hxX, away179refine⟨r, hr, positive, ?_⟩180have typedR : Real(r) byexact hr181have trace := subspaceMetric.ball at X, d, S, x, r with metric, inside, hx182rw trace183have separated := Disjoint.iff.forward with disjoint184apply Disjoint.iff.backward185intros y hy hyC186have inBall := intersection.membership.forward with hy187have inC := intersection.membership.forward with hyC188exact separated with y, inBall.left, inC.left189190-- Convergence and the Cauchy property are the same in the subspace.191theorem subspaceMetric.converges_iff (X d S u x : Set)192requires metric : IsMetric(X, d)193requires inside : S ⊆ X194requires sequence : SequenceIn(S, u)195requires hx : x ∈ S196shows ConvergesIn(S, subspaceMetric(d, S), u, x) ↔ ConvergesIn(X, d, u, x)197proof198have uFunction := SequenceIn.function with sequence199have ambient : SequenceIn(X, u)200have closed : ∀ n ∈ ℕ, u(n) ∈ X201intros n hn202exact inside with u(n), (SequenceIn.term_of_member with sequence, hn)203exact FunctionBetween.codomain_of_values with uFunction, closed204constructor205 . intro converges206apply ConvergesIn.of_eventually with ambient, (inside with x, hx)207intros ε hε positive208obtain⟨N, hN, near⟩:= ConvergesIn.eventually with converges, positive209refine⟨N, hN, ?_⟩210intros n hn le211have term := SequenceIn.term_of_member with sequence, hn212have value := subspaceMetric.apply with metric, inside, hx, term213have close := near with n, hn, le214 rwa value at close215 . intro converges216apply ConvergesIn.of_eventually with sequence, hx217intros ε hε positive218obtain⟨N, hN, near⟩:= ConvergesIn.eventually with converges, positive219refine⟨N, hN, ?_⟩220intros n hn le221have term := SequenceIn.term_of_member with sequence, hn222have value := subspaceMetric.apply with metric, inside, hx, term223rw value224exact near with n, hn, le225226theorem subspaceMetric.cauchy_iff (X d S u : Set)227requires metric : IsMetric(X, d)228requires inside : S ⊆ X229requires sequence : SequenceIn(S, u)230shows IsCauchy(S, subspaceMetric(d, S), u) ↔ IsCauchy(X, d, u)231proof232have uFunction := SequenceIn.function with sequence233have ambient : SequenceIn(X, u)234have closed : ∀ n ∈ ℕ, u(n) ∈ X235intros n hn236exact inside with u(n), (SequenceIn.term_of_member with sequence, hn)237exact FunctionBetween.codomain_of_values with uFunction, closed238constructor239 . intro cauchy240apply IsCauchy.of_eventually with ambient241intros ε hε positive242obtain⟨N, hN, close⟩:= IsCauchy.eventually with cauchy, positive243refine⟨N, hN, ?_⟩244intros m hm n hn leM leN245have termM := SequenceIn.term_of_member with sequence, hm246have termN := SequenceIn.term_of_member with sequence, hn247have value := subspaceMetric.apply with metric, inside, termM, termN248have near := close with m, hm, n, hn, leM, leN249 rwa value at near250 . intro cauchy251apply IsCauchy.of_eventually with sequence252intros ε hε positive253obtain⟨N, hN, close⟩:= IsCauchy.eventually with cauchy, positive254refine⟨N, hN, ?_⟩255intros m hm n hn leM leN256have termM := SequenceIn.term_of_member with sequence, hm257have termN := SequenceIn.term_of_member with sequence, hn258have value := subspaceMetric.apply with metric, inside, termM, termN259rw value260exact close with m, hm, n, hn, leM, leN261262-- A closed subspace of a complete space is complete.263theorem IsComplete.closed_subspace (X d S : Set)264requires complete : IsComplete(X, d)265requires closed : MetricClosed(X, d, S)266shows IsComplete(S, subspaceMetric(d, S))267proof268have metric := IsComplete.metric with complete269have inside := MetricClosed.subset with closed270apply IsComplete.of_limits with (subspaceMetric.metric with metric, inside)271intros u cauchy272have sequence := IsCauchy.sequence with cauchy273have bridge := subspaceMetric.cauchy_iff at X, d, S, u with274 metric, inside, sequence275have ambient := bridge.forward with cauchy276obtain⟨x, hx, converges⟩:= IsComplete.limit with complete, ambient277have terms : ∀ n ∈ ℕ, u(n) ∈ S278intros n hn279exact SequenceIn.term_of_member with sequence, hn280have hxS := ConvergesIn.limit_in_closed with closed, terms, converges281have same := subspaceMetric.converges_iff at X, d, S, u, x with282 metric, inside, sequence, hxS283exact⟨x, hxS, (same.backward with converges)⟩284285theorem IsBounded.subspace (X d S T : Set)286requires metric : IsMetric(X, d)287requires inside : S ⊆ X288requires bounded : IsBounded(X, d, T)289requires hT : T ⊆ S290shows IsBounded(S, subspaceMetric(d, S), T)291proof292obtain⟨insideT, r, hr, bound⟩:= bounded293refine⟨hT, r, hr, ?_⟩294intros x hx y hy295have value :=296 subspaceMetric.apply with metric, inside, (hT with x, hx), (hT with y, hy)297rw value298exact bound with x, hx, y, hy299300-- Restricting a continuous map to a subspace keeps it continuous.301theorem IsMetricContinuous.restrict (f X d Y e S : Set)302requires metric : IsMetric(X, d)303requires inside : S ⊆ X304requires continuous : IsMetricContinuous(f, X, d, Y, e)305shows IsMetricContinuous(restrict(f, S), S, subspaceMetric(d, S), Y, e)306proof307have function := IsMetricContinuous.function with continuous308have restricted := restrict.domain_function with function, inside309apply IsMetricContinuous.of_pointwise with restricted310intros x hx311have hxX := inside with x, hx312have atX := IsMetricContinuous.at with continuous, hxX313apply MetricContinuousAt.of_control with restricted, hx314intros ε hε positive315obtain⟨δ, hδ, positiveD, maps⟩:=316 MetricContinuousAt.control with atX, positive317refine⟨δ, hδ, positiveD, ?_⟩318intros y hy near319have valueX := restrict.domain_apply with function, inside, hx320have valueY := restrict.domain_apply with function, inside, hy321have distance := subspaceMetric.apply with metric, inside, hx, hy322rw distance at near323rw [valueX, valueY]324exact maps with y, (inside with y, hy), near325326theorem inclusionMap.isometry (X d S : Set)327requires metric : IsMetric(X, d)328requires inside : S ⊆ X329shows IsIsometry(inclusionMap(S, X), S, subspaceMetric(d, S), X, d)330proof331have function := inclusionMap.function at S, X with inside332constructor333 . exact function334 . intros x hx y hy335have valueX := inclusionMap.value at S, X, x with inside, hx336have valueY := inclusionMap.value at S, X, y with inside, hy337rw [valueX, valueY]338have value := subspaceMetric.apply with metric, inside, hx, hy339 symm at value340exact value341342theorem inclusionMap.metric_continuous (X d S : Set)343requires metric : IsMetric(X, d)344requires inside : S ⊆ X345shows IsMetricContinuous(inclusionMap(S, X), S, subspaceMetric(d, S), X, d)346proof347exact IsIsometry.continuous with (inclusionMap.isometry with metric, inside)348