Documentation

LeanCert.Engine.Integrate

Verified Numerical Integration #

This file implements numerical integration with rigorous error bounds. Given an expression and an interval, we compute an interval guaranteed to contain the definite integral.

Main definitions #

Algorithm #

We use uniform partitioning with interval evaluation:

  1. Partition [a, b] into n subintervals
  2. On each subinterval, bound f using interval arithmetic
  3. Sum the bounds: ∫ ≤ Σ (width * upper_bound)

Verification status #

The integrateInterval_correct_n1 theorem is fully proved for ExprSupported expressions. This demonstrates the end-to-end verification pipeline.

Auxiliary lemmas for integration bounds #

theorem LeanCert.Engine.integral_bounds_of_bounds {a b lo hi : } (hab : a b) {f : } (hf : IntervalIntegrable f MeasureTheory.volume a b) (hlo : xSet.Icc a b, lo f x) (hhi : xSet.Icc a b, f x hi) :
lo * (b - a) (x : ) in a..b, f x (x : ) in a..b, f x hi * (b - a)

If lo ≤ f(x) ≤ hi for all x ∈ [a, b], then lo * (b - a) ≤ ∫_a^b f ≤ hi * (b - a). This is the fundamental lemma for bounding integrals.

Uniform partition integration #

Partition an interval into n equal parts

Equations
Instances For

    Sum of interval bounds over a partition

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For
      noncomputable def LeanCert.Engine.integrateInterval (e : Core.Expr) (I : Core.IntervalRat) (n : ) (hn : 0 < n) :

      Compute interval bounds on ∫_a^b f(x) dx using uniform partitioning

      Equations
      Instances For

        Integration correctness for n = 1 #

        For single-interval integration (n=1), we can compute the result directly.

        Equations
        Instances For

          The single-interval integration is contained in the general integration for n=1

          theorem LeanCert.Engine.integrateInterval1_correct (e : Core.Expr) (hsupp : ExprSupported e) (I : Core.IntervalRat) (hInt : IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume I.lo I.hi) :
          (x : ) in I.lo..I.hi, Core.Expr.eval (fun (x_1 : ) => x) e integrateInterval1 e I

          The single-interval correctness theorem. This is FULLY PROVED - no sorry, no axioms.

          Adding zero on the left preserves interval membership

          theorem LeanCert.Engine.integrateInterval_correct_n1 (e : Core.Expr) (hsupp : ExprSupported e) (I : Core.IntervalRat) (hInt : IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume I.lo I.hi) :
          (x : ) in I.lo..I.hi, Core.Expr.eval (fun (x_1 : ) => x) e integrateInterval e I 1

          Correctness for n = 1 (single interval, no partition). This is FULLY PROVED - no sorry, no axioms.

          Integration correctness for general n #

          noncomputable def LeanCert.Engine.partitionPoints (I : Core.IntervalRat) (n i : ) :

          The real sequence of partition points for uniform partition. x_i = I.lo + (I.hi - I.lo) * i / n

          Equations
          Instances For
            theorem LeanCert.Engine.partitionPoints_zero (I : Core.IntervalRat) (n : ) (_hn : 0 < n) :
            partitionPoints I n 0 = I.lo

            x_0 = I.lo

            theorem LeanCert.Engine.partitionPoints_n (I : Core.IntervalRat) (n : ) (hn : 0 < n) :
            partitionPoints I n n = I.hi

            x_n = I.hi

            theorem LeanCert.Engine.partitionPoints_mono (I : Core.IntervalRat) (n : ) (_hn : 0 < n) (i j : ) (hij : i j) (_hjn : j n) :

            The partition points are monotone

            def LeanCert.Engine.partitionInterval (I : Core.IntervalRat) (n : ) (hn : 0 < n) (k : ) (hk : k < n) :

            The i-th subinterval of the uniform partition

            Equations
            Instances For
              theorem LeanCert.Engine.partitionInterval_lo (I : Core.IntervalRat) (n : ) (hn : 0 < n) (k : ) (hk : k < n) :
              (partitionInterval I n hn k hk).lo = I.lo + (I.hi - I.lo) / n * k

              The lo of the k-th partition interval

              theorem LeanCert.Engine.partitionInterval_hi (I : Core.IntervalRat) (n : ) (hn : 0 < n) (k : ) (hk : k < n) :
              (partitionInterval I n hn k hk).hi = I.lo + (I.hi - I.lo) / n * (k + 1)

              The hi of the k-th partition interval

              theorem LeanCert.Engine.partitionPoints_eq_lo (I : Core.IntervalRat) (n : ) (hn : 0 < n) (k : ) (hk : k < n) :
              partitionPoints I n k = (partitionInterval I n hn k hk).lo

              Partition points match partition interval bounds (real version)

              theorem LeanCert.Engine.partitionPoints_eq_hi (I : Core.IntervalRat) (n : ) (hn : 0 < n) (k : ) (hk : k < n) :
              partitionPoints I n (k + 1) = (partitionInterval I n hn k hk).hi
              theorem LeanCert.Engine.intervalIntegrable_on_partition (e : Core.Expr) (I : Core.IntervalRat) (n : ) (hn : 0 < n) (hInt : IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume I.lo I.hi) (k : ) (hk : k < n) :
              IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume (partitionInterval I n hn k hk).lo (partitionInterval I n hn k hk).hi

              Integrability on a subinterval

              theorem LeanCert.Engine.intervalIntegrable_partitionPoints (e : Core.Expr) (I : Core.IntervalRat) (n : ) (hn : 0 < n) (hInt : IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume I.lo I.hi) (k : ) (hk : k < n) :
              IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume (partitionPoints I n k) (partitionPoints I n (k + 1))

              Integrability using partition points

              theorem LeanCert.Engine.integral_partition_sum (e : Core.Expr) (I : Core.IntervalRat) (n : ) (hn : 0 < n) (hInt : IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume I.lo I.hi) :
              (x : ) in I.lo..I.hi, Core.Expr.eval (fun (x_1 : ) => x) e = kFinset.range n, (x : ) in partitionPoints I n k..partitionPoints I n (k + 1), Core.Expr.eval (fun (x_1 : ) => x) e

              The integral decomposes over the partition

              Summing interval bounds over partitions #

              theorem LeanCert.Engine.integral_subinterval_bounded (e : Core.Expr) (hsupp : ExprSupported e) (I : Core.IntervalRat) (n : ) (hn : 0 < n) (k : ) (hk : k < n) (hInt : IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume I.lo I.hi) :
              (x : ) in partitionPoints I n k..partitionPoints I n (k + 1), Core.Expr.eval (fun (x_1 : ) => x) e integrateInterval1 e (partitionInterval I n hn k hk)

              Each subinterval integral is bounded by integrateInterval1 on that subinterval

              IntervalRat.add is associative

              Helper: foldl add distributes: foldl (acc.add I) Is = acc.add (foldl I Is)

              Adding singleton 0 on the left is identity

              Adding singleton 0 on the right is identity

              theorem LeanCert.Engine.sum_mem_foldl_add {values : List } {intervals : List Core.IntervalRat} (hlen : values.length = intervals.length) (hmem : ∀ (i : ) (hi : i < values.length), values[i] intervals[i]) :

              Helper: the sum of values in intervals is in the foldl of interval sums

              Helper: generalized foldl lemma relating sumIntervalBounds-style fold with add fold

              theorem LeanCert.Engine.integrateInterval_correct (e : Core.Expr) (hsupp : ExprSupported e) (I : Core.IntervalRat) (n : ) (hn : 0 < n) (hInt : IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume I.lo I.hi) :
              (x : ) in I.lo..I.hi, Core.Expr.eval (fun (x_1 : ) => x) e integrateInterval e I n hn

              Main theorem: the integral lies in integrateInterval for general n

              Adaptive integration #

              Interval operations for error estimation #

              Interval intersection (returns the tighter bound). If intervals don't overlap, returns the first one (conservative).

              Equations
              Instances For
                theorem LeanCert.Engine.mem_intervalInter {x : } {I J : Core.IntervalRat} (hI : x I) (hJ : x J) :

                Intersection is sound: if x ∈ I and x ∈ J, then x ∈ inter I J

                Union of intervals (convex hull)

                Equations
                Instances For

                  Union is sound: if x ∈ I then x ∈ union I J

                  Union is sound: if x ∈ J then x ∈ union I J

                  Splitting intervals #

                  Midpoint definition helper

                  Midpoint is at least lo

                  Midpoint is at most hi

                  Split an interval at its midpoint

                  Equations
                  Instances For

                    The left half of a split covers [lo, mid]

                    The right half of a split covers [mid, hi]

                    theorem LeanCert.Engine.mem_splitMid {x : } {I : Core.IntervalRat} (hx : x I) :
                    x (splitMid I).1 x (splitMid I).2

                    Splitting preserves coverage: any x in I is in one of the halves

                    Adaptive integration result and algorithm #

                    Adaptive integration result

                    • Interval containing the integral

                    • evals :

                      Number of function evaluations used

                    Instances For

                      Compute integration bound for a single interval using n=2 panels

                      Equations
                      Instances For

                        Compute integration bound for a single interval using n=1 panel (coarse)

                        Equations
                        Instances For

                          Error estimate: width of the refined bound (Conservative: could use intersection, but width of refined is simpler)

                          Equations
                          Instances For
                            noncomputable def LeanCert.Engine.integrateAdaptiveAux (e : Core.Expr) (I : Core.IntervalRat) (tol : ) (maxDepth : ) :

                            Recursive adaptive integration. At each level, computes refined bound and either:

                            • Returns if error ≤ tol or maxDepth = 0
                            • Subdivides and recurses
                            Equations
                            Instances For
                              noncomputable def LeanCert.Engine.integrateAdaptive (e : Core.Expr) (I : Core.IntervalRat) (tol : ) (_htol : 0 < tol) (maxDepth : ) :

                              Adaptive integration with error tolerance. Keeps subdividing until the uncertainty is below tol.

                              Equations
                              Instances For

                                Correctness proofs for adaptive integration #

                                theorem LeanCert.Engine.integrateRefined_correct (e : Core.Expr) (hsupp : ExprSupported e) (I : Core.IntervalRat) (hInt : IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume I.lo I.hi) :
                                (x : ) in I.lo..I.hi, Core.Expr.eval (fun (x_1 : ) => x) e integrateRefined e I

                                integrateRefined is correct (direct from integrateInterval_correct)

                                theorem LeanCert.Engine.integrateCoarse_correct (e : Core.Expr) (hsupp : ExprSupported e) (I : Core.IntervalRat) (hInt : IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume I.lo I.hi) :
                                (x : ) in I.lo..I.hi, Core.Expr.eval (fun (x_1 : ) => x) e integrateCoarse e I

                                integrateCoarse is correct

                                Helper: midpoint is between lo and hi (real version)

                                Midpoint is in the interval

                                theorem LeanCert.Engine.integral_split_mid (e : Core.Expr) (I : Core.IntervalRat) (hInt : IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume I.lo I.hi) :
                                (x : ) in I.lo..I.hi, Core.Expr.eval (fun (x_1 : ) => x) e = ( (x : ) in I.lo..I.midpoint, Core.Expr.eval (fun (x_1 : ) => x) e) + (x : ) in I.midpoint..I.hi, Core.Expr.eval (fun (x_1 : ) => x) e

                                Helper: integral over split interval equals sum of integrals over halves

                                theorem LeanCert.Engine.intervalIntegrable_splitMid_left (e : Core.Expr) (I : Core.IntervalRat) (hInt : IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume I.lo I.hi) :
                                IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume (splitMid I).1.lo (splitMid I).1.hi

                                Integrability on left half

                                theorem LeanCert.Engine.intervalIntegrable_splitMid_right (e : Core.Expr) (I : Core.IntervalRat) (hInt : IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume I.lo I.hi) :
                                IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume (splitMid I).2.lo (splitMid I).2.hi

                                Integrability on right half

                                theorem LeanCert.Engine.integrateAdaptiveAux_correct (e : Core.Expr) (hsupp : ExprSupported e) (I : Core.IntervalRat) (tol : ) (maxDepth : ) (hInt : IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume I.lo I.hi) :
                                (x : ) in I.lo..I.hi, Core.Expr.eval (fun (x_1 : ) => x) e (integrateAdaptiveAux e I tol maxDepth).bound

                                Main soundness theorem: adaptive integration returns a bound containing the true integral. This is proved by induction on maxDepth.

                                theorem LeanCert.Engine.integrateAdaptive_correct (e : Core.Expr) (hsupp : ExprSupported e) (I : Core.IntervalRat) (tol : ) (htol : 0 < tol) (maxDepth : ) (hInt : IntervalIntegrable (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) MeasureTheory.volume I.lo I.hi) :
                                (x : ) in I.lo..I.hi, Core.Expr.eval (fun (x_1 : ) => x) e (integrateAdaptive e I tol htol maxDepth).bound

                                Soundness of the main adaptive integration function

                                Non-uniform (geometric) partitioning #

                                def LeanCert.Engine.geometricBreakpoints (start stop w₀ ratio : ) (maxN : ) :

                                Build geometric breakpoints from start, growing by ratio each step. Returns list of breakpoints (not intervals). Stops at stop or after maxN steps.

                                Equations
                                Instances For
                                  @[irreducible]
                                  def LeanCert.Engine.geometricBreakpoints.go (stop ratio cur w : ) (fuel : ) (acc : List ) :
                                  Equations
                                  • One or more equations did not get rendered due to their size.
                                  Instances For
                                    def LeanCert.Engine.nonUniformPartition (I : Core.IntervalRat) (edgeWidth edgeRatio edgeCutoff : ) (nMid : ) (maxEdgeParts : := 200) :

                                    Build a non-uniform partition: geometric near both edges, uniform in the middle. Returns List IntervalRat. Intervals with lo ≥ hi are dropped.

                                    Equations
                                    • One or more equations did not get rendered due to their size.
                                    Instances For