Documentation

LeanCert.Engine.RootFinding.Basic

Root Finding: Basic Definitions #

This file provides the core definitions and basic correctness lemmas for root finding.

Main definitions #

Main theorems #

Root status #

Result of checking an interval for roots

  • noRoot : RootStatus

    No root in this interval (interval evaluation doesn't contain 0)

  • hasRoot : RootStatus

    At least one root exists (by intermediate value theorem)

  • uniqueRoot : RootStatus

    Exactly one root exists (Newton contraction)

  • unknown : RootStatus

    Cannot determine

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

      Basic root checks #

      Check if interval evaluation excludes zero

      Equations
      Instances For

        Check if function values have opposite signs at endpoints (IVT applicable)

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

          Initial root status check

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

            Core correctness lemmas #

            theorem LeanCert.Engine.excludesZero_correct (e : Core.Expr) (hsupp : ExprSupported e) (I : Core.IntervalRat) (hexcl : excludesZero (evalInterval1 e I) = true) (x : ) :
            x ICore.Expr.eval (fun (x_1 : ) => x) e 0

            If interval evaluation excludes zero, then f(x) ≠ 0 for all x in I. This is the key lemma for proving noRoot correctness.

            theorem LeanCert.Engine.signChange_correct (e : Core.Expr) (hsupp : ExprSupported e) (I : Core.IntervalRat) (hsign : signChange e I = true) (hCont : ContinuousOn (fun (x : ) => Core.Expr.eval (fun (x_1 : ) => x) e) (Set.Icc I.lo I.hi)) :
            xI, Core.Expr.eval (fun (x_1 : ) => x) e = 0

            If there is a sign change, then by IVT there exists a root. This uses Mathlib's intermediate_value_Icc theorem.

            Proof strategy:

            1. signChange means f(lo) < 0 < f(hi) or f(hi) < 0 < f(lo)
            2. Use evalInterval1_correct on singletons to get actual values at endpoints
            3. Apply intermediate_value_Icc to conclude 0 is in the image

            N-Variable Root Finding Infrastructure #

            The following section provides infrastructure for root finding in multi-variable expressions. The key idea is that we search for roots along a specific coordinate while holding other variables fixed.

            For a multi-variable expression e with environment ρ, we can find roots of evalAlong e ρ idx - the function obtained by varying coordinate idx while keeping all other coordinates fixed according to ρ.

            N-variable root checks #

            noncomputable def LeanCert.Engine.excludesZero_idx (e : Core.Expr) (ρ_int : IntervalEnv) (_idx : ) :

            Check if interval evaluation along coordinate idx excludes zero. Note: idx is kept for API consistency though the full box is checked.

            Equations
            Instances For
              noncomputable def LeanCert.Engine.signChange_idx (e : Core.Expr) (ρ_int : IntervalEnv) (idx : ) :

              Check if function has opposite signs at endpoints along coordinate idx

              Equations
              • One or more equations did not get rendered due to their size.
              Instances For
                noncomputable def LeanCert.Engine.checkRootStatus_idx (e : Core.Expr) (ρ_int : IntervalEnv) (idx : ) :

                Initial root status check along coordinate idx

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

                  N-variable correctness lemmas #

                  theorem LeanCert.Engine.excludesZero_correct_idx (e : Core.Expr) (hsupp : ExprSupported e) (ρ_int : IntervalEnv) (hexcl : excludesZero (evalInterval e ρ_int) = true) (ρ_real : ) :
                  (∀ (i : ), ρ_real i ρ_int i)Core.Expr.eval ρ_real e 0

                  If interval evaluation excludes zero, then f(x) ≠ 0 for all x in the box. N-variable version: the function has no zeros in the entire box.

                  theorem LeanCert.Engine.signChange_correct_idx (e : Core.Expr) (hsupp : ExprSupported e) (ρ_int : IntervalEnv) (idx : ) (ρ_real : ) ( : ∀ (i : ), i idxρ_real i ρ_int i) (hsign : signChange_idx e ρ_int idx = true) (hCont : ContinuousOn (e.evalAlong ρ_real idx) (Set.Icc (ρ_int idx).lo (ρ_int idx).hi)) :
                  xρ_int idx, e.evalAlong ρ_real idx x = 0

                  If there is a sign change along coordinate idx, then by IVT there exists a root along that coordinate. N-variable version: for any fixed values of other coordinates satisfying ρ_int, there exists a value of coordinate idx where the function is zero.

                  N-variable bisection root finding #

                  Result of bisection root finding

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

                      Update an interval environment at a specific index

                      Equations
                      Instances For
                        theorem LeanCert.Engine.mem_bisect_cases (J : Core.IntervalRat) (t : ) (ht : t J) :
                        t J.bisect.1 t J.bisect.2

                        Helper: membership in bisected intervals

                        noncomputable def LeanCert.Engine.bisectRootIdx (e : Core.Expr) (ρ : IntervalEnv) (idx maxDepth : ) :

                        N-variable bisection root finding along coordinate idx.

                        This searches for a root of e by bisecting the interval ρ idx while keeping other coordinates fixed. It uses interval arithmetic to:

                        1. Exclude intervals where the function cannot be zero
                        2. Detect sign changes indicating a root exists (by IVT)
                        3. Bisect when neither condition is met

                        Returns a BisectResult indicating whether a root was found, excluded, or uncertain.

                        Equations
                        Instances For
                          @[irreducible]
                          noncomputable def LeanCert.Engine.bisectRootIdx.go (e : Core.Expr) (ρ : IntervalEnv) (idx maxDepth : ) (J : Core.IntervalRat) (depth : ) :
                          Equations
                          • One or more equations did not get rendered due to their size.
                          Instances For
                            theorem LeanCert.Engine.bisectRootIdx_go_found_signChange (e : Core.Expr) (ρ_int : IntervalEnv) (idx maxDepth depth : ) (J I : Core.IntervalRat) (d : ) (hJ_sub : tJ, t ρ_int idx) (hfound : bisectRootIdx.go e ρ_int idx maxDepth J depth = BisectResult.found I d) :
                            signChange_idx e (updateIntervalEnv' ρ_int idx I) idx = true tI, t ρ_int idx

                            Helper: when go returns found, signChange_idx was true for that interval

                            theorem LeanCert.Engine.bisectRootIdx_found_correct (e : Core.Expr) (hsupp : ExprSupported e) (ρ_int : IntervalEnv) (idx maxDepth : ) (I : Core.IntervalRat) (d : ) (hfound : bisectRootIdx e ρ_int idx maxDepth = BisectResult.found I d) (ρ_real : ) ( : ∀ (i : ), i idxρ_real i ρ_int i) (hCont : ContinuousOn (e.evalAlong ρ_real idx) (Set.Icc I.lo I.hi)) :
                            xI, e.evalAlong ρ_real idx x = 0

                            Correctness theorem for bisectRootIdx when it finds a root. If bisectRootIdx returns found I d, then for any ρ_real satisfying ρ_int, there exists a root of evalAlong e ρ_real idx in the returned interval I.

                            theorem LeanCert.Engine.bisectRootIdx_go_noRoot_correct (e : Core.Expr) (hsupp : ExprSupported e) (ρ_int : IntervalEnv) (idx maxDepth depth : ) (J : Core.IntervalRat) (hJ_sub : tJ, t ρ_int idx) (hnoRoot : bisectRootIdx.go e ρ_int idx maxDepth J depth = BisectResult.noRoot) (ρ_real : ) :
                            (∀ (i : ), ρ_real i ρ_int i)tJ, e.evalAlong ρ_real idx t 0

                            Helper: noRoot is preserved through bisection. The proof is complex due to the match structure in bisectRootIdx.go. The key insight is that noRoot can only be returned if excludesZero is true at some level of the recursion, and excludesZero implies the function is nonzero.

                            theorem LeanCert.Engine.bisectRootIdx_noRoot_correct (e : Core.Expr) (hsupp : ExprSupported e) (ρ_int : IntervalEnv) (idx maxDepth : ) (hnoRoot : bisectRootIdx e ρ_int idx maxDepth = BisectResult.noRoot) (ρ_real : ) :
                            (∀ (i : ), ρ_real i ρ_int i)tρ_int idx, e.evalAlong ρ_real idx t 0

                            Correctness theorem for bisectRootIdx when it reports no root. If bisectRootIdx returns noRoot, then for any ρ_real satisfying ρ_int, the function evalAlong e ρ_real idx has no zeros in ρ_int idx.