1-- Archimedean limits: reciprocals, successor ratios, and powers below one2-- 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.Real.Analysis.ArchimedeanLimits8import Series9import HarmonicSeries1011-- Section: NullSequences12-- A sequence whose absolute values are eventually below every positive13-- radius converges to zero.14theorem ConvergesTo.zero_of_abs_bounds (u : Set)15requires sequence : RealSequence(u)16requires small : ∀ E ∈ ℝ, 0 < E →17∃ N ∈ ℕ, ∀ n ∈ ℕ, N ≤ n → abs(u[n]) < E18shows ConvergesTo(u, (0:R))19proof20constructor21 . exact sequence22 . intros E realE positive23have typedE : Real(E) byexact realE24obtain⟨N, naturalN, close⟩:= small with E, realE, positive25witness N26constructor27 . exact naturalN28 . intros n naturalIndex after29have typedN : Nat(n) byexact nat.omega.backward at n with naturalIndex30have typedValue := RealSequence.value at u, n with sequence31have bound := close with n, naturalIndex, after32have zero := realSubValue.zero_right with typedValue33apply openBall.membership.backward34constructor35 . exact typedValue36 . unfold dist37 rwa zero3839theorem realInvValue.involutive (A : Real)40requires nonzero : A ≠041shows realInvValue(realInvValue(A)) = A42proof43have inverseNonzero := realInvValue.nonzero with nonzero44have law := realInvValue.mul_left with nonzero45have equal := realInvValue.eq_of_mul_right with inverseNonzero, law46 symm at equal47exact equal4849-- Section: Reciprocals50-- The reciprocals 1/(n + 1) tend to zero: this is the Archimedean property.51theorem harmonicTerms.converges_zero52shows ConvergesTo(harmonicTerms, (0:R))53proof54have sequence := harmonicTerms.sequence55apply ConvergesTo.zero_of_abs_bounds with sequence56intros E realE positive57have typedE : Real(E) byexact realE58have nonzeroE : E ≠059intro zero60rw zero at positive61linarith62have scaleReal := realInvValue.real at E63have scalePositive := realInvValue.positive with positive64have unscaled := realInvValue.involutive with nonzeroE65obtain⟨N, typedN, above⟩:=Real.below_natural at realInvValue(E)66have naturalN := nat.omega.forward with typedN67witness N68constructor69 . exact naturalN70 . intros n naturalIndex after71have typedIndex : Nat(n) byexact nat.omega.backward at n with naturalIndex72have countReal := realNat.real at n73have denominatorReal : (realNat(n):R) +1∈ ℝ bytypecheck74have monotone := realNat.monotone with after75have one := realZero.lt_one76have denominatorAbove : realInvValue(E) < (realNat(n):R) +1bylinarith77have termReal := RealSequence.value at harmonicTerms, n with sequence78have value := harmonicTerms.value at n79have termPositive := harmonicTerms.positive at n80have termNonnegative := realLess.implies_le with termPositive81have absolute := abs.of_nonnegative with termNonnegative82have inverted := realInvValue.antitone_positive at83 realInvValue(E), (realNat(n):R) +1with scalePositive, denominatorAbove84rw unscaled at inverted85rw [absolute, value]86exact inverted8788-- The harmonic series is the standard example of a series that fails to sum.89theorem harmonicSeries.not_summable90shows¬Summable(harmonicTerms)91proof92intro summable93obtain⟨L, realL, sums⟩:= summable94have converges := SumsTo.converges with sums95have limit : ∃ L ∈ ℝ, ConvergesTo(prefixSums(harmonicTerms), L)96witness L97constructor98 . exact realL99 . exact converges100exact harmonicSeries.diverges with limit101102-- Section: SuccessorRatios103-- The ratios n/(n + 1).104defgraph successorRatios (n ∈ ℕ) : ℝ :=105 (realNat(n):R) / ((realNat(n):R) +1)106proof107have typedN := nat.omega.backward with member108have countReal := realNat.real at n109exact realDiv.real at (realNat(n):R), (realNat(n):R) +1with*110111theorem successorRatios.sequence112shows RealSequence(successorRatios)113proof114exact successorRatios.function115116-- n/(n + 1) = 1 - 1/(n + 1).117theorem successorRatios.sub_harmonic (n : Nat)118shows successorRatios[n] = (1:R) - harmonicTerms(n)119proof120have countReal := realNat.real at n121have denominatorReal : (realNat(n):R) +1∈ ℝ bytypecheck122have nonzero := realNat.successor_nonzero at n123have inverseReal := realInvValue.real at (realNat(n):R) +1124have law := realInvValue.mul_left with nonzero125have product : ((1:R) - realInvValue((realNat(n):R) +1)) *126 ((realNat(n):R) +1) = (realNat(n):R)127have expand : ((1:R) - realInvValue((realNat(n):R) +1)) *128 ((realNat(n):R) +1) =129 ((realNat(n):R) +1) -130 realInvValue((realNat(n):R) +1) * ((realNat(n):R) +1) byring131rw [expand, law]132ring133have quotient := realDiv.of_mul_right with nonzero, product134have value := successorRatios.value at n135have termValue := harmonicTerms.value at n136rw [value, termValue]137 symm at quotient138exact quotient139140theorem successorRatios.converges_one141shows ConvergesTo(successorRatios, (1:R))142proof143have sequence := successorRatios.sequence144have harmonics := harmonicTerms.sequence145have constants := constantSequence.sequence at (1:R) with realOne.real146have constantConverges := constantSequence.converges at (1:R) with147 realOne.real148have limit := ConvergesTo.sub with149 constantConverges, harmonicTerms.converges_zero150have zero := realSubValue.zero_right with realOne.real151rw zero at limit152have equal : ∀ n ∈ ℕ, successorRatios[n] =153 subSequence(constantSequence((1:R)), harmonicTerms)[n]154intros n naturalN155have typedN : Nat(n) byexact nat.omega.backward at n with naturalN156have constantReal := RealSequence.value at157 constantSequence((1:R)), n with constants158have termReal := RealSequence.value at harmonicTerms, n with harmonics159have difference := subSequence.value at160 constantSequence((1:R)), harmonicTerms, n with161 constants, harmonics, constantReal, termReal162have constant := constantSequence.value at (1:R), n with*163have ratio := successorRatios.sub_harmonic at n164rw [difference, constant, ratio]165rfl166exact ConvergesTo.of_equal_terms with sequence, limit, equal167168-- Section: Powers169theorem realPow.nonnegative (A : Real, n : Nat)170requires nonnegative : 0≤ A171shows0≤ A ^ n172proof173induction n174| zero =>175rw realPow.zero176exact realLess.implies_le with realZero.lt_one177| succ(k) using ih =>178have power := realPow.real at A, k179rw realPow.succ180exact realMulValue.nonnegative with nonnegative, ih181182theorem realPow.le_one (A : Real, n : Nat)183requires nonnegative : 0≤ A184requires bounded : A ≤1185shows A ^ n ≤1186proof187induction n188| zero =>189rw realPow.zero190exact realLe.reflexive with realOne.real191| succ(k) using ih =>192have power := realPow.real at A, k193have scaled := realLe.mul_left_of_nonnegative with ih, nonnegative194have one := realMulValue.one_right at A195rw one at scaled196rw realPow.succ197exact realLe.transitive with scaled, bounded198199theorem realPow.abs (A : Real, n : Nat)200shows abs(A ^ n) = abs(A) ^ n201proof202induction n203| zero =>204rw [realPow.zero, realPow.zero]205have oneNonnegative := realLess.implies_le with realZero.lt_one206exact abs.of_nonnegative with oneNonnegative207| succ(k) using ih =>208have power := realPow.real at A, k209have product := abs.mul at A, A ^ k withassumption, power210rw [realPow.succ, realPow.succ, product, ih]211rfl212213-- Bernoulli's inequality.214theorem realPow.bernoulli (H : Real, n : Nat)215requires nonnegative : 0≤ H216shows (1:R) + (realNat(n):R) * H ≤ ((1:R) + H) ^ n217proof218induction n219| zero =>220rw [realPow.zero, realNat.zero]221have zeroProduct : (1:R) + (0:R) * H = (1:R) byring222rw zeroProduct223exact realLe.reflexive with realOne.real224| succ(k) using ih =>225have countReal := realNat.real at k226have baseReal : (1:R) + H ∈ ℝ bytypecheck227have one := realZero.lt_one228have baseNonnegative : 0≤ (1:R) + H bylinarith229have power := realPow.real at (1:R) + H, k230have scaled := realLe.mul_left_of_nonnegative with ih, baseNonnegative231have countNonnegative := realNat.nonnegative at k232have square := realMulValue.square_nonnegative at H233have cross := realMulValue.nonnegative with countNonnegative, square234have expand : ((1:R) + H) * ((1:R) + (realNat(k):R) * H) =235 (1:R) + ((realNat(k):R) +1) * H + (realNat(k):R) * (H * H) byring236rw [realPow.succ, realNat.succ_add]237rw expand at scaled238linarith239240-- For 0 ≤ A < 1 the powers decay at least like 1/(1 + n(1 - A)).241theorem realPow.decay_bound (A : Real, n : Nat)242requires nonnegative : 0≤ A243requires below : A < 1244shows A ^ n * ((1:R) + (realNat(n):R) * ((1:R) - A)) ≤1245proof246have gapReal := realSubValue.real at (1:R), A with realOne.real, assumption247have gapPositive := realLess.iff_pos_sub.forward with below248have gapNonnegative := realLess.implies_le with gapPositive249have countReal := realNat.real at n250have power := realPow.real at A, n251have powerNonnegative := realPow.nonnegative at A, n with nonnegative252have bernoulli := realPow.bernoulli at (1:R) - A, n with gapNonnegative253have baseReal : (1:R) + ((1:R) - A) ∈ ℝ bytypecheck254have basePower := realPow.real at (1:R) + ((1:R) - A), n255have factorReal : (1:R) + (realNat(n):R) * ((1:R) - A) ∈ ℝ bytypecheck256have scaled := realLe.mul_left_of_nonnegative with bernoulli, powerNonnegative257have combined := realPow.mul at A, (1:R) + ((1:R) - A), n258have productReal : A * ((1:R) + ((1:R) - A)) ∈ ℝ bytypecheck259have one := realZero.lt_one260have baseNonnegative : 0≤ (1:R) + ((1:R) - A) bylinarith261have productNonnegative := realMulValue.nonnegative with262 nonnegative, baseNonnegative263have productBounded : A * ((1:R) + ((1:R) - A)) ≤1264have square := realMulValue.square_nonnegative at (1:R) - A265have expand : A * ((1:R) + ((1:R) - A)) =266 (1:R) - ((1:R) - A) * ((1:R) - A) byring267rw expand268linarith269have small := realPow.le_one at A * ((1:R) + ((1:R) - A)), n with270 productNonnegative, productBounded271rw combined at small272exact realLe.transitive with scaled, small273274-- Powers of a number in [0, 1) eventually fall below every positive bound.275theorem realPow.eventually_small (A E : Real)276requires nonnegative : 0≤ A277requires below : A < 1278requires positive : 0 < E279shows∃ N ∈ ℕ, ∀ n ∈ ℕ, N ≤ n → A ^ n < E280proof281have gapReal := realSubValue.real at (1:R), A with realOne.real, assumption282have gapPositive := realLess.iff_pos_sub.forward with below283have gapNonnegative := realLess.implies_le with gapPositive284have scaleReal := realMulValue.real at E, (1:R) - A withassumption, gapReal285have scalePositive := realMulValue.positive with positive, gapPositive286have scaleNonzero : E * ((1:R) - A) ≠0287intro zero288rw zero at scalePositive289linarith290have thresholdReal := realInvValue.real at E * ((1:R) - A)291have law := realInvValue.mul_left with scaleNonzero292obtain⟨N, typedN, above⟩:=293Real.below_natural at realInvValue(E * ((1:R) - A))294have naturalN := nat.omega.forward with typedN295witness N296constructor297 . exact naturalN298 . intros n naturalIndex after299have typedIndex : Nat(n) byexact nat.omega.backward at n with naturalIndex300have countReal := realNat.real at n301have monotone := realNat.monotone with after302have aboveIndex : realInvValue(E * ((1:R) - A)) < realNat(n) bylinarith303have multiplied := realLess.mul_right_of_positive with304 aboveIndex, scalePositive305rw law at multiplied306have power := realPow.real at A, n307have bound := realPow.decay_bound at A, n with nonnegative, below308have factorReal : (1:R) + (realNat(n):R) * ((1:R) - A) ∈ ℝ bytypecheck309have countNonnegative := realNat.nonnegative at n310have cross := realMulValue.nonnegative with countNonnegative, gapNonnegative311have one := realZero.lt_one312have factorNonnegative : 0≤ (1:R) + (realNat(n):R) * ((1:R) - A) by313linarith314by_contra notLess315have reversed := realLe.of_not_less with notLess316have scaledReverse := realLe.mul_right_of_nonnegative with317 reversed, factorNonnegative318have expand : E * ((1:R) + (realNat(n):R) * ((1:R) - A)) =319 E + (realNat(n):R) * (E * ((1:R) - A)) byring320rw expand at scaledReverse321linarith322323-- The geometric sequence X^n tends to zero when |X| < 1.324theorem geometricTerms.converges_zero (X : Real)325requires small : abs(X) < 1326shows ConvergesTo(geometricTerms(X), (0:R))327proof328have sequence := geometricTerms.sequence at X329have absReal := abs.real at X330have absNonnegative := abs.nonnegative at X331apply ConvergesTo.zero_of_abs_bounds with sequence332intros E realE positive333have typedE : Real(E) byexact realE334obtain⟨N, naturalN, eventually⟩:= realPow.eventually_small at335 abs(X), E with absNonnegative, small, positive336witness N337constructor338 . exact naturalN339 . intros n naturalIndex after340have typedN : Nat(n) byexact nat.omega.backward at n with naturalIndex341have value := geometricTerms.value at X, n with*342have absolute := realPow.abs at X, n343have bound := eventually with n, naturalIndex, after344rw [value, absolute]345exact bound346