1-- Real analysis: Taylor's theorem with the Lagrange remainder2-- 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.Taylor8import TaylorPolynomial910-- Section: Taylor11-- Taylor's theorem with the Lagrange remainder: when f is n + 1 times12-- differentiable on [A, B], some C strictly between A and B has13-- f(B) = ∑_{k ≤ n} f⁽ᵏ⁾(A)(B − A)ᵏ/k! + f⁽ⁿ⁺¹⁾(C)(B − A)ⁿ⁺¹/(n + 1)!.14-- The proof applies the Cauchy mean value theorem to the approximant15-- x ↦ ∑_{k ≤ n} f⁽ᵏ⁾(x)(B − x)ᵏ/k! and to x ↦ (B − x)ⁿ⁺¹.16theorem Taylor.theorem (f : ℝ → ℝ) (A B : Real, n : Nat)17requiresordered : A < B18requires smooth : ∀ k ≤ n,19∀ X ∈ closedInterval(A, B), DifferentiableAt(f⁽ᵏ⁾, X)20shows∃ C ∈ ℝ, A < C ∧ C < B ∧21 f(B) = ∑ k ≤ n, f⁽ᵏ⁾(A) * (B - A) ^ k / k! +22 f⁽ⁿ⁺¹⁾(C) * (B - A) ^ (n +1) / (n +1)!23proof24have orderedWeak := realLess.implies_le withordered25have memberA := closedInterval.left_mem with orderedWeak26have function : f : ℝ → ℝ byassumption27have approximantFunction := taylorApproximant.function at f, B, n with28 function29have powerFunction := basePower.function at B, n +130have intervalReal := closedInterval.subset_reals at A, B31have pointwise : ∀ X ∈ closedInterval(A, B), ∀ k, Nat(k) → k ≤ n →32 DifferentiableAt(iteratedDerivative(f, k), X)33intros X memberX k naturalK below34have onInterval := smooth with k, naturalK, below35exact onInterval with X, memberX36have approximantDifferentiable : ∀ X ∈ closedInterval(A, B),37 DifferentiableAt(taylorApproximant(f, B, n), X)38intros X memberX39have realX := intervalReal with X, memberX40have typedX : Real(X) byexact realX41have atX := pointwise with X, memberX42have implication := taylorApproximant.derivative at f, B, X, n with function43have hasDerivative := implication with atX44exact HasDerivativeAt.differentiable_at with hasDerivative45have powerDifferentiable : ∀ X ∈ closedInterval(A, B),46 DifferentiableAt(basePower(B, n +1), X)47intros X memberX48have realX := intervalReal with X, memberX49have typedX : Real(X) byexact realX50have hasDerivative := basePower.derivative at B, X, n51exact HasDerivativeAt.differentiable_at with hasDerivative52have continuousApproximant := ContinuousOn.of_differentiable with53 approximantFunction, intervalReal, approximantDifferentiable54have continuousPower := ContinuousOn.of_differentiable with55 powerFunction, intervalReal, powerDifferentiable56have interior : ∀ C ∈ ℝ, A < C → C < B → C ∈ closedInterval(A, B)57intros C realC leftright58have lower := realLess.implies_le withleft59have upper := realLess.implies_le withright60have data : C ∈ ℝ ∧ A ≤ C ∧ C ≤ B byrefine⟨realC, lower, upper⟩61exact closedInterval.membership.backward with data62have interiorApproximant : ∀ C ∈ ℝ, A < C → C < B →63 DifferentiableAt(taylorApproximant(f, B, n), C)64intros C realC leftright65have member := interior with C, realC, left, right66exact approximantDifferentiable with C, member67have interiorPower : ∀ C ∈ ℝ, A < C → C < B →68 DifferentiableAt(basePower(B, n +1), C)69intros C realC leftright70have member := interior with C, realC, left, right71exact powerDifferentiable with C, member72obtain⟨C, realC, left, right, equation⟩:= CauchyMeanValue.theorem with73 approximantFunction, powerFunction, ordered, continuousApproximant,74 continuousPower, interiorApproximant, interiorPower75have typedC : Real(C) byexact realC76have memberC := interior with C, realC, left, right77have atC := pointwise with C, memberC78have implication := taylorApproximant.derivative at f, B, C, n with function79have approximantDerivative := implication with atC80have approximantValue := derivative.of_has_derivative with81 approximantDerivative82have powerDerivative := basePower.derivative at B, C, n83have powerDerivativeValue := derivative.of_has_derivative with powerDerivative84have powerAtB : basePower(B, n +1)(B) = (0:R)85have value := basePower.value at B, B, n +186haveself:= realSubValue.self at B87have one : n +1= succ(n) := add.right_one with*88rw [value, self, one]89exact realPow.zero_succ at n90have powerAtA := basePower.value at B, A, n +191have approximantAtB := taylorApproximant.at_endpoint at f, B, n with function92have approximantAtA := taylorApproximant.value at f, B, A, n with function93rw [approximantValue, powerDerivativeValue, powerAtB, powerAtA,94 approximantAtB, approximantAtA] at equation95have realB : B ∈ ℝ bysimp [Real]96have typedFB : Real(f(B))97exact FunctionBetween.apply_closed with function, realB98have nextFunction := iteratedDerivative.function at f, n +1with function99have typedNext : Real(iteratedDerivative(f, n +1)(C))100exact FunctionBetween.apply_closed with nextFunction, realC101have typedWidth := realSubValue.real at B, A102have typedGap := realSubValue.real at B, C103have gapNonzero : B - C ≠0104intro zero105linarith106have powerNonzero := realPow.nonzero at B - C, n with typedGap, gapNonzero107have typedPowerGap := realPow.real at B - C, n108have typedPowerWidth := realPow.real at B - A, n +1109have typedNat := realNat.real at n110have successorNonzero := realNat.succ_nonzero at n111have factorialNat := factorial.closed at n112have factorialSuccNat := factorial.closed at n +1113have typedFactorial := realNat.real at n!114have typedFactorialSucc := realNat.real at (n +1)!115have factorialNonzero := realNat.factorial_nonzero at n116have factorialSplit := realNat.factorial_succ at n117have inverseSplit : realInvValue(realNat((n +1)!)) =118 realInvValue((realNat(n):R) +1) * realInvValue(realNat(n!))119rw factorialSplit120exact realInvValue.mul with successorNonzero, factorialNonzero121have unitGap := realInvValue.mul_right with powerNonzero122have unitSuccessor := realInvValue.mul_right with successorNonzero123have typedGapInverse := realInvValue.real with typedPowerGap124have typedSuccessorInverse := realInvValue.real at (realNat(n):R) +1125have typedFactorialInverse := realInvValue.real with typedFactorial126have typedFactorialSuccInverse := realInvValue.real with typedFactorialSucc127have sequence : RealSequence(taylorTerms(f, A, B))128unfold RealSequence129exact taylorTerms.function at f, A, B with function130have typedSum := realPartialSum.real at taylorTerms(f, A, B), n +1with131 sequence132have typedProductGap := realMulValue.real with typedNext, typedPowerGap133have typedProductWidth := realMulValue.real with typedNext, typedPowerWidth134have divisionGap := realDiv.eq_mul_inv with typedProductGap, typedFactorial135have divisionWidth := realDiv.eq_mul_inv with136 typedProductWidth, typedFactorialSucc137rw divisionGap at equation138witness C139refine⟨realC, left, right, _⟩140rw divisionWidth141 symm142linear_combination ((f(B) - (∑ k < n +1, taylorTerms(f, A, B)(k):R)) *143 ((realNat(n):R) +1) * realInvValue((realNat(n):R) +1) -144 iteratedDerivative(f, n +1)(C) * realInvValue(realNat(n!)) *145 (B - A) ^ (n +1) * realInvValue((realNat(n):R) +1)) * unitGap +146 (f(B) - (∑ k < n +1, taylorTerms(f, A, B)(k):R)) * unitSuccessor +147 (iteratedDerivative(f, n +1)(C) * (B - A) ^ (n +1)) * inverseSplit -148 (realInvValue((B - C) ^ n) * realInvValue((realNat(n):R) +1)) * equation149150-- With n = 0 the sum is the single term f(A) and the remainder is151-- f′(C)(B − A): Taylor's theorem specializes to the mean value theorem.152theorem Taylor.mean_value (f : ℝ → ℝ) (A B : Real)153requiresordered : A < B154requires differentiable : ∀ X ∈ closedInterval(A, B), DifferentiableAt(f, X)155shows∃ C ∈ ℝ, A < C ∧ C < B ∧ f(B) = f(A) + f′(C) * (B - A)156proof157have function : f : ℝ → ℝ byassumption158have smooth : ∀ k ≤ (0:N),159∀ X ∈ closedInterval(A, B), DifferentiableAt(f⁽ᵏ⁾, X)160intros k naturalK below161havesplit:= natural.zero_or_successor with naturalK162casessplitwith zero | successor163 . intros X memberX164rw [zero, iteratedDerivative.zero]165exact differentiable with X, memberX166 . obtain⟨j, naturalJ, equal⟩:= successor167rw equal at below168exfalso169arith170obtain⟨C, realC, left, right, expansion⟩:= Taylor.theorem at f, A, B, (0:N) with171 function, ordered, smooth172have typedC : Real(C) byexact realC173have one : (0:N) +1= succ(0) := add.right_one at (0:N)174rw one at expansion175rw [realPartialSum.succ, realPartialSum.zero] at expansion176have termValue := taylorTerms.value at f, A, B, (0:N) with function177rw [termValue, iteratedDerivative.zero, realPow.zero] at expansion178have factorialZero : (0:N)! =1bysimp [factorial]179have factorialOne : succ(0)! =1bysimp [factorial]180rw [factorialZero, factorialOne, realNat.one] at expansion181rw [← one, iteratedDerivative.succ, iteratedDerivative.zero, one] at expansion182have realA : A ∈ ℝ bysimp [Real]183have typedFA : Real(f(A)) byexact FunctionBetween.apply_closed with function, realA184have typedDerivative := derivative.real at f, C185have typedWidth := realSubValue.real at B, A186have powerOne : (B - A) ^ succ(0) = B - A187rw [realPow.succ, realPow.zero]188exact realMulValue.one_right with typedWidth189have unitA := realMulValue.one_right with typedFA190have typedProduct := realMulValue.real with typedDerivative, typedWidth191rw [powerOne, unitA, realDiv.one_right, realDiv.one_right] at expansion192have zeroLeft := realAddValue.zero_left with typedFA193unfold call2 at zeroLeft194unfold realAddValue at expansion195rw zeroLeft at expansion196witness C197refine⟨realC, left, right, _⟩198exact expansion199