1-- Real-valued functions on the unit cube that are continuous in the sup2-- metric, and the operations that preserve continuity: constants,3-- coordinates, sums, negatives, products, absolute values, reciprocals of4-- functions at least one, and maxima5-- 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.FixedPoint.CubeFunctions11import CubeContinuity1213predicate CubeFunction (g n : Set) := FunctionBetween(g, unitCube(n), ℝ)1415predicate CubeFunctionContinuousAt (g n x : Set) :=16∀ E ∈ ℝ, (0:R) < E →∃ D ∈ ℝ, (0:R) < D ∧17 (∀ y ∈ unitCube(n), ((∀ i ∈ n, dist(y(i), x(i)) < D) → dist(g(y), g(x)) < E))1819predicate CubeFunctionContinuous (g n : Set) :=20 CubeFunction(g, n) ∧∀ x ∈ unitCube(n), CubeFunctionContinuousAt(g, n, x)2122theorem CubeFunction.function (g n : Set)23requires function : CubeFunction(g, n)24shows g : unitCube(n) → ℝ25proof26exact function2728theorem CubeFunction.value (g n x : Set)29requires function : CubeFunction(g, n)30requires hx : x ∈ unitCube(n)31shows g(x) ∈ ℝ32proof33have between := CubeFunction.function with function34exact FunctionBetween.apply_closed with between, hx3536theorem CubeFunctionContinuous.function (g n : Set)37requires continuous : CubeFunctionContinuous(g, n)38shows CubeFunction(g, n)39proof40exact continuous.left4142theorem CubeFunctionContinuous.at (g n x : Set)43requires continuous : CubeFunctionContinuous(g, n)44requires hx : x ∈ unitCube(n)45shows CubeFunctionContinuousAt(g, n, x)46proof47exact continuous.right with hx4849-- A smaller tolerance still works.50theorem CubeFunctionContinuousAt.shrink (g n x : Set) (E D C : Real)51requires hx : x ∈ unitCube(n)52requires close : ∀ y ∈ unitCube(n), ((∀ i ∈ n, dist(y(i), x(i)) < D) → dist(g(y), g(x)) < E)53requires below : C ≤ D54shows∀ y ∈ unitCube(n), ((∀ i ∈ n, dist(y(i), x(i)) < C) → dist(g(y), g(x)) < E)55proof56intros y hy near57apply close with hy58intros i hi59have step := near with hi60have yReal := unitCube.coordinate_real with hy, hi61have xReal := unitCube.coordinate_real with hx, hi62linarith6364-- Two positive reals have a common positive lower bound.65theorem positive.below_both (E W : Real)66requires positiveE : 0 < E67requires positiveW : 0 < W68shows∃ H ∈ ℝ, (0:R) < H ∧ H < E ∧ H < W69proof70have halfE := half.lt_self with positiveE71have halfEPos := half.positive with positiveE72have halfEReal := half.real at E73have halfW := half.lt_self with positiveW74have halfWPos := half.positive with positiveW75have halfWReal := half.real at W76havesplit:= realLess.trichotomy at E, W77casessplitwith below | rest78 . witness half(E)79refine⟨halfEReal, halfEPos, halfE, ?_⟩80linarith81 . cases rest with same | above82 . witness half(E)83refine⟨halfEReal, halfEPos, halfE, ?_⟩84 rwa ← same85 . witness half(W)86refine⟨halfWReal, halfWPos, ?_, halfW⟩87linarith8889-- Two tolerances have a common positive lower bound.90theorem CubeFunctionContinuousAt.common (g h n x : Set) (E : Real)91requires hx : x ∈ unitCube(n)92requires gAt : CubeFunctionContinuousAt(g, n, x)93requires hAt : CubeFunctionContinuousAt(h, n, x)94requires positive : 0 < E95shows∃ D ∈ ℝ, (0:R) < D ∧ (∀ y ∈ unitCube(n), ((∀ i ∈ n, dist(y(i), x(i)) < D) → (dist(g(y), g(x)) < E ∧ dist(h(y), h(x)) < E)))96proof97have EReal : E ∈ ℝ bytypecheck98obtain⟨D1, D1Real, D1Pos, gClose⟩:= gAt with EReal, positive99obtain⟨D2, D2Real, D2Pos, hClose⟩:= hAt with EReal, positive100obtain⟨D, DReal, DPos, DBelow1, DBelow2⟩:= positive.below_both with D1Pos, D2Pos101have gShrunk := CubeFunctionContinuousAt.shrink with hx, gClose, (realLess.implies_le with DBelow1)102have hShrunk := CubeFunctionContinuousAt.shrink with hx, hClose, (realLess.implies_le with DBelow2)103witness D104constructor105 . exact DReal106 . constructor107 . exact DPos108 . intros y hy near109constructor110 . exact gShrunk with hy, near111 . exact hShrunk with hy, near112113-- Constants and coordinates.114theorem constantCube.continuous (n : Nat) (c : Set)115requires cReal : c ∈ ℝ116shows CubeFunctionContinuous(constantFunction(unitCube(n), ℝ, c), n)117proof118have function := constantFunction.function at unitCube(n), ℝ, c with cReal119constructor120 . exact function121 . intros x hx E EReal Epos122witness E123constructor124 . exact EReal125 . constructor126 . exact Epos127 . intros y hy near128have yValue := constantFunction.apply with hy, cReal129have xValue := constantFunction.apply with hx, cReal130rw [yValue, xValue]131haveself:= dist.self at c132 rwa self133134defgraph coordinateCube (n i : Set) (x ∈ unitCube(n)) : ℝ := x(i)135requires hi : i ∈ n136proof137exact unitCube.coordinate_real with member, hi138139theorem coordinateCube.continuous (n : Nat) (i : Set)140requires hi : i ∈ n141shows CubeFunctionContinuous(coordinateCube(n, i), n)142proof143have function := coordinateCube.function with hi144constructor145 . exact function146 . intros x hx E EReal Epos147witness E148constructor149 . exact EReal150 . constructor151 . exact Epos152 . intros y hy near153have yValue := coordinateCube.value with hi, hy154have xValue := coordinateCube.value with hi, hx155rw [yValue, xValue]156exact near with hi157158-- Sums, negatives, and products of cube functions.159defgraph addCube (n g h : Set) (x ∈ unitCube(n)) : ℝ := (g(x):R) + (h(x):R)160requires gFunction : CubeFunction(g, n)161requires hFunction : CubeFunction(h, n)162proof163have gValue := CubeFunction.value with gFunction, member164have hValue := CubeFunction.value with hFunction, member165exact realAddValue.real at g(x), h(x)166167defgraph negCube (n g : Set) (x ∈ unitCube(n)) : ℝ := -(g(x):R)168requires gFunction : CubeFunction(g, n)169proof170have gValue := CubeFunction.value with gFunction, member171have neg : Real(-(g(x):R)) bytypecheck172exact neg173174defgraph mulCube (n g h : Set) (x ∈ unitCube(n)) : ℝ := (g(x):R) * (h(x):R)175requires gFunction : CubeFunction(g, n)176requires hFunction : CubeFunction(h, n)177proof178have gValue := CubeFunction.value with gFunction, member179have hValue := CubeFunction.value with hFunction, member180exact realMulValue.real at g(x), h(x)181182theorem addCube.continuous (n : Nat) (g h : Set)183requires gContinuous : CubeFunctionContinuous(g, n)184requires hContinuous : CubeFunctionContinuous(h, n)185shows CubeFunctionContinuous(addCube(n, g, h), n)186proof187have gFunction := CubeFunctionContinuous.function with gContinuous188have hFunction := CubeFunctionContinuous.function with hContinuous189have function := addCube.function with gFunction, hFunction190constructor191 . exact function192 . intros x hx E EReal Epos193have halfPos := half.positive with Epos194have gAt := CubeFunctionContinuous.at with gContinuous, hx195have hAt := CubeFunctionContinuous.at with hContinuous, hx196obtain⟨D, DReal, DPos, close⟩:= CubeFunctionContinuousAt.common with hx, gAt, hAt, halfPos197witness D198constructor199 . exact DReal200 . constructor201 . exact DPos202 . intros y hy near203obtain⟨gNear, hNear⟩:= close with hy, near204have yValue := addCube.value with gFunction, hFunction, hy205have xValue := addCube.value with gFunction, hFunction, hx206rw [yValue, xValue]207have gy := CubeFunction.value with gFunction, hy208have gx := CubeFunction.value with gFunction, hx209have hy2 := CubeFunction.value with hFunction, hy210have hx2 := CubeFunction.value with hFunction, hx211have bound := dist.add_add at g(y), h(y), g(x), h(x)212have halves := half.add_self at E213linarith214215theorem negCube.continuous (n : Nat) (g : Set)216requires gContinuous : CubeFunctionContinuous(g, n)217shows CubeFunctionContinuous(negCube(n, g), n)218proof219have gFunction := CubeFunctionContinuous.function with gContinuous220have function := negCube.function with gFunction221constructor222 . exact function223 . intros x hx E EReal Epos224have gAt := CubeFunctionContinuous.at with gContinuous, hx225obtain⟨D, DReal, DPos, close⟩:= gAt with EReal, Epos226witness D227constructor228 . exact DReal229 . constructor230 . exact DPos231 . intros y hy near232have gNear := close with hy, near233have yValue := negCube.value with gFunction, hy234have xValue := negCube.value with gFunction, hx235rw [yValue, xValue]236have gy := CubeFunction.value with gFunction, hy237have gx := CubeFunction.value with gFunction, hx238have same := dist.neg at g(y), g(x)239 rwa same240241theorem mulCube.continuous (n : Nat) (g h : Set)242requires gContinuous : CubeFunctionContinuous(g, n)243requires hContinuous : CubeFunctionContinuous(h, n)244shows CubeFunctionContinuous(mulCube(n, g, h), n)245proof246have gFunction := CubeFunctionContinuous.function with gContinuous247have hFunction := CubeFunctionContinuous.function with hContinuous248have function := mulCube.function with gFunction, hFunction249constructor250 . exact function251 . intros x hx E EReal Epos252have gx := CubeFunction.value with gFunction, hx253have hx2 := CubeFunction.value with hFunction, hx254have gAbs := abs.nonnegative at g(x)255have hAbs := abs.nonnegative at h(x)256have gAbsReal := abs.real at g(x)257have hAbsReal := abs.real at h(x)258have gScale : (0:R) < abs(g(x)) +1bylinarith259have hScale : (0:R) < abs(h(x)) +1bylinarith260have gScaleReal : Real(abs(g(x)) +1) bytypecheck261have hScaleReal : Real(abs(h(x)) +1) bytypecheck262-- g moves by less than E / (2(|h(x)| + 1)) and h by less than E / (2(|g(x)| + 1)).263have gRadiusPos := scaledRadius.positive with Epos, hScale264have hRadiusPos := scaledRadius.positive with Epos, gScale265have gRadiusReal := scaledRadius.real at E, abs(h(x)) +1266have hRadiusReal := scaledRadius.real at E, abs(g(x)) +1267have gCancel := scaledRadius.cancel at E, abs(h(x)) +1with hScale268have hCancel := scaledRadius.cancel at E, abs(g(x)) +1with gScale269have onePos : (0:R) < (1:R) bylinarith270obtain⟨R1, R1Real, R1Pos, R1Below, R1One⟩:= positive.below_both with gRadiusPos, onePos271have gAt := CubeFunctionContinuous.at with gContinuous, hx272have hAt := CubeFunctionContinuous.at with hContinuous, hx273obtain⟨D1, D1Real, D1Pos, gClose⟩:= gAt with R1Real, R1Pos274have hRadiusIn : scaledRadius(E, abs(g(x)) +1) ∈ ℝ bytypecheck275obtain⟨D2, D2Real, D2Pos, hClose⟩:= hAt with hRadiusIn, hRadiusPos276obtain⟨D, DReal, DPos, DBelow1, DBelow2⟩:= positive.below_both with D1Pos, D2Pos277have gShrunk := CubeFunctionContinuousAt.shrink with hx, gClose, (realLess.implies_le with DBelow1)278have hShrunk := CubeFunctionContinuousAt.shrink with hx, hClose, (realLess.implies_le with DBelow2)279witness D280constructor281 . exact DReal282 . constructor283 . exact DPos284 . intros y hy near285have gNear := gShrunk with hy, near286have hNear := hShrunk with hy, near287have yValue := mulCube.value with gFunction, hFunction, hy288have xValue := mulCube.value with gFunction, hFunction, hx289rw [yValue, xValue]290have gy := CubeFunction.value with gFunction, hy291have hy2 := CubeFunction.value with hFunction, hy292have bound := dist.mul_mul at g(y), h(y), g(x), h(x)293have gyAbs := abs.le_dist_add_abs at g(y), g(x)294have gyAbsNonneg := abs.nonnegative at g(y)295have d1Nonneg := dist.nonnegative at g(y), g(x)296have d2Nonneg := dist.nonnegative at h(y), h(x)297-- |g(y)| ≤ |g(x)| + 1, so |g(y)| · dist(h(y), h(x)) ≤ (|g(x)| + 1) · dist(h(y), h(x)) < half(E).298have gyBound : abs(g(y)) ≤ abs(g(x)) +1bylinarith299have first := realLe.mul_right_of_nonnegative with gyBound, d2Nonneg300have hRadiusLe := realLess.implies_le with hNear301have second := realLe.mul_left_of_nonnegative with hRadiusLe, (realLess.implies_le with gScale)302rw hCancel at second303-- |h(x)| · dist(g(y), g(x)) ≤ (|h(x)| + 1) · dist(g(y), g(x)) < half(E).304have hxBound : abs(h(x)) ≤ abs(h(x)) +1bylinarith305have third := realLe.mul_right_of_nonnegative with hxBound, d1Nonneg306have gRadiusLe : dist(g(y), g(x)) ≤ scaledRadius(E, abs(h(x)) +1) bylinarith307have fourth := realLe.mul_left_of_nonnegative with gRadiusLe, (realLess.implies_le with hScale)308rw gCancel at fourth309have halves := half.add_self at E310have strict1 : (abs(g(x)) +1) * dist(h(y), h(x)) < half(E)311have step := realLess.mul_left_of_positive with hNear, gScale312 rwa hCancel at step313have strict2 : (abs(h(x)) +1) * dist(g(y), g(x)) < half(E)314have gStrict : dist(g(y), g(x)) < scaledRadius(E, abs(h(x)) +1) bylinarith315have step := realLess.mul_left_of_positive with gStrict, hScale316 rwa gCancel at step317linarith318319-- The absolute value does not increase distances.320theorem abs.le_of_bounds (A M : Real)321requires upper : A ≤ M322requires lower : -A ≤ M323shows abs(A) ≤ M324proof325havesplit:= realLess.trichotomy at (0:R), A326casessplitwith positive | rest327 . have value := abs.of_nonnegative with (realLess.implies_le with positive)328 rwa value329 . cases rest with zero | negative330 . have nonneg : (0:R) ≤ A bylinarith331have value := abs.of_nonnegative with nonneg332 rwa value333 . have value := abs.of_nonpositive with (realLess.implies_le with negative)334 rwa value335336theorem dist.abs_le (A B : Real)337shows dist(abs(A), abs(B)) ≤ dist(A, B)338proof339have first := abs.le_dist_add_abs at A, B340have second := abs.le_dist_add_abs at B, A341have symmetric := dist.symmetric at B, A342rw symmetric at second343have same : dist(abs(A), abs(B)) = abs(abs(A) - abs(B))344unfold dist345rfl346rw same347apply abs.le_of_bounds348 . linarith349 . linarith350351defgraph absCube (n g : Set) (x ∈ unitCube(n)) : ℝ := abs((g(x):R))352requires gFunction : CubeFunction(g, n)353proof354have gValue := CubeFunction.value with gFunction, member355exact abs.real at g(x)356357theorem absCube.continuous (n : Nat) (g : Set)358requires gContinuous : CubeFunctionContinuous(g, n)359shows CubeFunctionContinuous(absCube(n, g), n)360proof361have gFunction := CubeFunctionContinuous.function with gContinuous362have function := absCube.function with gFunction363constructor364 . exact function365 . intros x hx E EReal Epos366have gAt := CubeFunctionContinuous.at with gContinuous, hx367obtain⟨D, DReal, DPos, close⟩:= gAt with EReal, Epos368witness D369constructor370 . exact DReal371 . constructor372 . exact DPos373 . intros y hy near374have gNear := close with hy, near375have yValue := absCube.value with gFunction, hy376have xValue := absCube.value with gFunction, hx377rw [yValue, xValue]378have gy := CubeFunction.value with gFunction, hy379have gx := CubeFunction.value with gFunction, hx380have bound := dist.abs_le at g(y), g(x)381linarith382383-- Reciprocals of functions that stay at least one.384theorem realInvValue.le_one (A : Real)385requires atLeastOne : (1:R) ≤ A386shows (0:R) < realInvValue(A) ∧ realInvValue(A) ≤ (1:R)387proof388have positive : (0:R) < A bylinarith389have nonzero : A ≠ (0:R)390intro zero391rw zero at positive392linarith393have cut := realInvValue.of_positive with positive394have cutPositive := positiveRealInvCut.positive with positive395have invPositive : (0:R) < realInvValue(A) by rwa cut396have cancel := realInvValue.mul_right with nonzero397have step := realLe.mul_left_of_nonnegative with atLeastOne, (realLess.implies_le with invPositive)398have one := realMulValue.one_right at realInvValue(A)399have commute := realMulValue.commutative at realInvValue(A), A400rw [one, commute, cancel] at step401exact⟨invPositive, step⟩402403defgraph invCube (n g : Set) (x ∈ unitCube(n)) : ℝ := realInvValue((g(x):R))404requires gFunction : CubeFunction(g, n)405proof406have gValue := CubeFunction.value with gFunction, member407exact realInvValue.real at g(x)408409theorem invCube.continuous (n : Nat) (g : Set)410requires gContinuous : CubeFunctionContinuous(g, n)411requires atLeastOne : ∀ x ∈ unitCube(n), (1:R) ≤ (g(x):R)412shows CubeFunctionContinuous(invCube(n, g), n)413proof414have gFunction := CubeFunctionContinuous.function with gContinuous415have function := invCube.function with gFunction416constructor417 . exact function418 . intros x hx E EReal Epos419have gAt := CubeFunctionContinuous.at with gContinuous, hx420obtain⟨D, DReal, DPos, close⟩:= gAt with EReal, Epos421witness D422constructor423 . exact DReal424 . constructor425 . exact DPos426 . intros y hy near427have gNear := close with hy, near428have yValue := invCube.value with gFunction, hy429have xValue := invCube.value with gFunction, hx430rw [yValue, xValue]431have gy := CubeFunction.value with gFunction, hy432have gx := CubeFunction.value with gFunction, hx433obtain⟨yPos, yLe⟩:= realInvValue.le_one with (atLeastOne with hy)434obtain⟨xPos, xLe⟩:= realInvValue.le_one with (atLeastOne with hx)435have yNonzero : (g(y):R) ≠ (0:R)436intro zero437have bound := atLeastOne with hy438rw zero at bound439linarith440have xNonzero : (g(x):R) ≠ (0:R)441intro zero442have bound := atLeastOne with hx443rw zero at bound444linarith445have formula := dist.inv_inv with yNonzero, xNonzero446have yAbs := abs.of_nonnegative with (realLess.implies_le with yPos)447have xAbs := abs.of_nonnegative with (realLess.implies_le with xPos)448rw [yAbs, xAbs] at formula449have dNonneg := dist.nonnegative at g(y), g(x)450have productLe : realInvValue(g(y)) * realInvValue(g(x)) ≤ (1:R)451have step := realLe.mul_left_of_nonnegative with xLe, (realLess.implies_le with yPos)452have one := realMulValue.one_right at realInvValue(g(y))453rw one at step454linarith455have productNonneg : (0:R) ≤ realInvValue(g(y)) * realInvValue(g(x))456have step := realLe.mul_left_of_nonnegative with (realLess.implies_le with xPos), (realLess.implies_le with yPos)457have zero := realMulValue.zero_right at realInvValue(g(y))458 rwa zero at step459have scaled := realLe.mul_left_of_nonnegative with productLe, dNonneg460have one := realMulValue.one_right at dist(g(y), g(x))461rw one at scaled462rw formula463linarith464465-- The larger of two reals, written so that it is built from sums, absolute466-- values, and a constant factor.467def realMax (A B : Real) : Real:= half(realOne) * (A + B + abs(A + -B))468469theorem realMax.real (A B : Real)470showsReal(realMax(A, B))471proof472have product : Real(half(realOne) * (A + B + abs(A + -B))) bytypecheck473unfold realMax474exact product475476theorem realMax.of_le (A B : Real)477requires below : B ≤ A478shows realMax(A, B) = A479proof480have nonneg : (0:R) ≤ A + -B bylinarith481have value := abs.of_nonnegative with nonneg482have halves := half.add_self at realOne483have same : realMax(A, B) = half(realOne) * (A + B + abs(A + -B))484unfold realMax485rfl486rw [same, value]487have twoA : A + B + (A + -B) = A + A byring488have expand : half(realOne) * (A + A) = (half(realOne) + half(realOne)) * A byring489rw [twoA, expand, halves]490exact realMulValue.one_left491492theorem realMax.of_ge (A B : Real)493requires below : A ≤ B494shows realMax(A, B) = B495proof496have nonpos : A + -B ≤ (0:R) bylinarith497have value := abs.of_nonpositive with nonpos498have halves := half.add_self at realOne499have same : realMax(A, B) = half(realOne) * (A + B + abs(A + -B))500unfold realMax501rfl502rw [same, value]503have twoB : A + B + -(A + -B) = B + B byring504have expand : half(realOne) * (B + B) = (half(realOne) + half(realOne)) * B byring505rw [twoB, expand, halves]506exact realMulValue.one_left507508theorem realMax.ge_left (A B : Real)509shows A ≤ realMax(A, B)510proof511havesplit:= realLess.trichotomy at A, B512casessplitwith less | rest513 . have value := realMax.of_ge with (realLess.implies_le with less)514rw value515linarith516 . cases rest with same | greater517 . have le : A ≤ B bylinarith518have value := realMax.of_ge with le519rw value520linarith521 . have value := realMax.of_le with (realLess.implies_le with greater)522rw value523linarith524525theorem realMax.ge_right (A B : Real)526shows B ≤ realMax(A, B)527proof528havesplit:= realLess.trichotomy at A, B529casessplitwith less | rest530 . have value := realMax.of_ge with (realLess.implies_le with less)531rw value532linarith533 . cases rest with same | greater534 . have le : A ≤ B bylinarith535have value := realMax.of_ge with le536rw value537linarith538 . have value := realMax.of_le with (realLess.implies_le with greater)539rw value540linarith541542def maxCube (n g h : Set) : Set:=543 mulCube(n, constantFunction(unitCube(n), ℝ, half(realOne)), addCube(n, addCube(n, g, h), absCube(n, addCube(n, g, negCube(n, h)))))544545theorem maxCube.value (n : Nat) (g h x : Set)546requires gFunction : CubeFunction(g, n)547requires hFunction : CubeFunction(h, n)548requires hx : x ∈ unitCube(n)549shows maxCube(n, g, h)(x) = realMax((g(x):R), (h(x):R))550proof551have gx := CubeFunction.value with gFunction, hx552have hx2 := CubeFunction.value with hFunction, hx553have hReal := half.real at realOne554have hIn : half(realOne) ∈ ℝ bytypecheck555have negFunction : CubeFunction(negCube(n, h), n) := negCube.function with hFunction556have diffFunction : CubeFunction(addCube(n, g, negCube(n, h)), n) := addCube.function with557 gFunction, negFunction558have absFunction : CubeFunction(absCube(n, addCube(n, g, negCube(n, h))), n) := absCube.function with559 diffFunction560have sumFunction : CubeFunction(addCube(n, g, h), n) := addCube.function with gFunction, hFunction561have totalFunction : CubeFunction(addCube(n, addCube(n, g, h), absCube(n, addCube(n, g, negCube(n, h)))), n) := addCube.function with562 sumFunction, absFunction563have constantFunction2 : CubeFunction(constantFunction(unitCube(n), ℝ, half(realOne)), n) := constantFunction.function at unitCube(n), ℝ, half(1) with hIn564have same : maxCube(n, g, h)(x) = mulCube(n, constantFunction(unitCube(n), ℝ, half(realOne)), addCube(n, addCube(n, g, h), absCube(n, addCube(n, g, negCube(n, h)))))(x)565unfold maxCube566rfl567rw same568have v1 := mulCube.value with constantFunction2, totalFunction, hx569have v2 := constantFunction.apply at unitCube(n), ℝ, x, half(realOne) with hx570have v3 := addCube.value with sumFunction, absFunction, hx571have v4 := addCube.value with gFunction, hFunction, hx572have v5 := absCube.value with diffFunction, hx573have v6 := addCube.value with gFunction, negFunction, hx574have v7 := negCube.value with hFunction, hx575rw [v1, v2, v3, v4, v5, v6, v7]576unfold realMax577rfl578579theorem maxCube.continuous (n : Nat) (g h : Set)580requires gContinuous : CubeFunctionContinuous(g, n)581requires hContinuous : CubeFunctionContinuous(h, n)582shows CubeFunctionContinuous(maxCube(n, g, h), n)583proof584have hIn : half(realOne) ∈ ℝ bytypecheck585have constant := constantCube.continuous with hIn586have neg := negCube.continuous with hContinuous587have diff := addCube.continuous with gContinuous, neg588have absolute := absCube.continuous with diff589have sum := addCube.continuous with gContinuous, hContinuous590have total := addCube.continuous with sum, absolute591have product := mulCube.continuous with constant, total592unfold maxCube593exact product594