Documentation

LeanCert.Core.Expr

Unified Expression AST #

This file defines the unified AST for real expressions (Expr) and its evaluation semantics. All numerical algorithms in LeanCert operate on this single expression type.

Main definitions #

Design notes #

The expression type uses natural number indices for variables. This simplifies the interval evaluation and automatic differentiation implementations.

Auxiliary definition for atanh #

Since Mathlib doesn't provide Real.atanh, we define it here using the standard formula: atanh x = (1/2) * log((1+x)/(1-x)) for |x| < 1.

noncomputable def LeanCert.Core.Real.atanh (x : ) :

The inverse hyperbolic tangent function. Defined as atanh x = (1/2) * log((1+x)/(1-x)) for |x| < 1.

Equations
Instances For
    theorem LeanCert.Core.Real.atanh_arg_pos {x : } (hx : |x| < 1) :
    0 < (1 + x) / (1 - x)

    For |x| < 1, the argument (1+x)/(1-x) is positive.

    @[simp]

    atanh(0) = 0

    theorem LeanCert.Core.Real.atanh_neg {x : } (hx : |x| < 1) :

    atanh(-x) = -atanh(x) for |x| < 1

    atanh is strictly monotone on (-1, 1)

    theorem LeanCert.Core.Real.atanh_mono {x y : } (hx : |x| < 1) (hy : |y| < 1) (hxy : x y) :

    atanh is monotone on (-1, 1): if x ≤ y then atanh x ≤ atanh y

    noncomputable def LeanCert.Core.Real.erf (x : ) :

    The error function: erf(x) = (2/√π) ∫₀ˣ exp(-t²) dt. Essential for statistical and financial modeling (normal distribution CDF). Uses interval integral notation (∫ t in 0..x) which handles negative x correctly.

    Equations
    Instances For

      The error function is bounded above by 1.

      The error function is bounded below by -1.

      Unified AST for real-valued expressions.

      • const (q : ) : Expr

        Rational constant

      • var (idx : ) : Expr

        Variable with de Bruijn-style index

      • add (e₁ e₂ : Expr) : Expr

        Addition

      • mul (e₁ e₂ : Expr) : Expr

        Multiplication

      • neg (e : Expr) : Expr

        Negation

      • inv (e : Expr) : Expr

        Multiplicative inverse (partial: undefined at 0)

      • exp (e : Expr) : Expr

        Exponential function

      • sin (e : Expr) : Expr

        Sine function

      • cos (e : Expr) : Expr

        Cosine function

      • log (e : Expr) : Expr

        Natural logarithm (partial: undefined for x ≤ 0)

      • atan (e : Expr) : Expr

        Arctangent function

      • arsinh (e : Expr) : Expr

        Inverse hyperbolic sine (arsinh)

      • atanh (e : Expr) : Expr

        Inverse hyperbolic tangent (partial: undefined for |x| ≥ 1)

      • sinc (e : Expr) : Expr

        Sinc function: sinc(x) = sin(x)/x for x ≠ 0, sinc(0) = 1

      • erf (e : Expr) : Expr

        Error function: erf(x) = (2/√π) ∫₀ˣ exp(-t²) dt

      • sinh (e : Expr) : Expr

        Hyperbolic sine: sinh(x) = (exp(x) - exp(-x)) / 2

      • cosh (e : Expr) : Expr

        Hyperbolic cosine: cosh(x) = (exp(x) + exp(-x)) / 2

      • tanh (e : Expr) : Expr

        Hyperbolic tangent: tanh(x) = sinh(x) / cosh(x) ∈ (-1, 1)

      • sqrt (e : Expr) : Expr

        Square root (partial: undefined for x < 0)

      • pi : Expr

        The mathematical constant π

      Instances For
        Equations
        Instances For
          def LeanCert.Core.instDecidableEqExpr.decEq (x✝ x✝¹ : Expr) :
          Decidable (x✝ = x✝¹)
          Equations
          • One or more equations did not get rendered due to their size.
          Instances For
            def LeanCert.Core.Expr.sub (e₁ e₂ : Expr) :

            Subtraction as a derived operation

            Equations
            Instances For
              def LeanCert.Core.Expr.div (e₁ e₂ : Expr) :

              Division as a derived operation

              Equations
              Instances For

                Integer power (non-negative exponent)

                Equations
                Instances For

                  Absolute value as a derived operation: |x| = sqrt(x²) This gives correct results for all real x (except at 0 for interval purposes)

                  Equations
                  Instances For
                    noncomputable def LeanCert.Core.Expr.eval (ρ : ) :
                    Expr

                    Evaluate an expression given a variable assignment ρ : Nat → ℝ

                    Equations
                    Instances For
                      def LeanCert.Core.Expr.updateVar (ρ : ) (idx : ) (x : ) :

                      Update variable assignment at a specific index

                      Equations
                      Instances For
                        Equations
                        • One or more equations did not get rendered due to their size.
                        Instances For
                          @[simp]
                          theorem LeanCert.Core.Expr.updateVar_same (ρ : ) (idx : ) (x : ) :
                          (ρ[idx x]) idx = x
                          @[simp]
                          theorem LeanCert.Core.Expr.updateVar_other (ρ : ) (idx i : ) (x : ) (h : i idx) :
                          (ρ[idx x]) i = ρ i
                          theorem LeanCert.Core.Expr.updateVar_self (ρ : ) (idx : ) :
                          ρ[idx ρ idx] = ρ
                          @[reducible, inline]
                          noncomputable abbrev LeanCert.Core.Expr.evalAlong (e : Expr) (ρ : ) (idx : ) :

                          Evaluate e as a scalar function of variable idx, with all other variables fixed by ρ. This represents the map t ↦ eval ρ[idx ↦ t] e.

                          Equations
                          Instances For

                            An expression is closed if it has no free variables

                            Equations
                            Instances For
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_const (ρ : ) (q : ) :
                              eval ρ (const q) = q
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_var (ρ : ) (idx : ) :
                              eval ρ (var idx) = ρ idx
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_add (ρ : ) (e₁ e₂ : Expr) :
                              eval ρ (e₁.add e₂) = eval ρ e₁ + eval ρ e₂
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_mul (ρ : ) (e₁ e₂ : Expr) :
                              eval ρ (e₁.mul e₂) = eval ρ e₁ * eval ρ e₂
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_neg (ρ : ) (e : Expr) :
                              eval ρ e.neg = -eval ρ e
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_inv (ρ : ) (e : Expr) :
                              eval ρ e.inv = (eval ρ e)⁻¹
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_exp (ρ : ) (e : Expr) :
                              eval ρ e.exp = Real.exp (eval ρ e)
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_sin (ρ : ) (e : Expr) :
                              eval ρ e.sin = Real.sin (eval ρ e)
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_cos (ρ : ) (e : Expr) :
                              eval ρ e.cos = Real.cos (eval ρ e)
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_log (ρ : ) (e : Expr) :
                              eval ρ e.log = Real.log (eval ρ e)
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_atan (ρ : ) (e : Expr) :
                              eval ρ e.atan = Real.arctan (eval ρ e)
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_arsinh (ρ : ) (e : Expr) :
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_atanh (ρ : ) (e : Expr) :
                              eval ρ e.atanh = Real.atanh (eval ρ e)
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_sinc (ρ : ) (e : Expr) :
                              eval ρ e.sinc = Real.sinc (eval ρ e)
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_erf (ρ : ) (e : Expr) :
                              eval ρ e.erf = Real.erf (eval ρ e)
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_sinh (ρ : ) (e : Expr) :
                              eval ρ e.sinh = Real.sinh (eval ρ e)
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_cosh (ρ : ) (e : Expr) :
                              eval ρ e.cosh = Real.cosh (eval ρ e)
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_tanh (ρ : ) (e : Expr) :
                              eval ρ e.tanh = Real.tanh (eval ρ e)
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_sqrt (ρ : ) (e : Expr) :
                              eval ρ e.sqrt = (eval ρ e)
                              @[simp]
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_sub (ρ : ) (e₁ e₂ : Expr) :
                              eval ρ (e₁.sub e₂) = eval ρ e₁ - eval ρ e₂
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_div (ρ : ) (e₁ e₂ : Expr) :
                              eval ρ (e₁.div e₂) = eval ρ e₁ / eval ρ e₂
                              @[simp]
                              theorem LeanCert.Core.Expr.eval_pow (ρ : ) (e : Expr) (n : ) :
                              eval ρ (e.pow n) = eval ρ e ^ n
                              theorem LeanCert.Core.Expr.eval_abs (ρ : ) (e : Expr) :
                              eval ρ e.abs = |eval ρ e|

                              Evaluation of abs for any argument: |x| = sqrt(x²)

                              theorem LeanCert.Core.Expr.eval_sqrt_sq_of_pos (ρ : ) (e : Expr) (hpos : 0 < eval ρ e) :
                              eval ρ (e.mul e).sqrt = eval ρ e

                              For positive x, sqrt(x²) = x

                              theorem LeanCert.Core.Expr.eval_abs_of_pos (ρ : ) (e : Expr) (hpos : 0 < eval ρ e) :
                              eval ρ e.abs = eval ρ e

                              Abs correctly computes absolute value for positive inputs

                              theorem LeanCert.Core.Expr.eval_abs_of_neg (ρ : ) (e : Expr) (hneg : eval ρ e < 0) :
                              eval ρ e.abs = -eval ρ e

                              Abs correctly computes absolute value for negative inputs

                              theorem LeanCert.Core.Expr.evalAlong_eq (e : Expr) (ρ : ) (idx : ) (t : ) :
                              e.evalAlong ρ idx t = eval (ρ[idx t]) e
                              theorem LeanCert.Core.Expr.evalAlong_at_ρ (e : Expr) (ρ : ) (idx : ) :
                              e.evalAlong ρ idx (ρ idx) = eval ρ e
                              theorem LeanCert.Core.Expr.evalAlong_const' (ρ : ) (idx : ) (q : ) :
                              (const q).evalAlong ρ idx = fun (x : ) => q

                              evalAlong for a constant is constant

                              theorem LeanCert.Core.Expr.evalAlong_var_active (ρ : ) (idx : ) :
                              (var idx).evalAlong ρ idx = id

                              evalAlong for the active variable is the identity

                              theorem LeanCert.Core.Expr.evalAlong_var_passive (ρ : ) (idx i : ) (h : i idx) :
                              (var i).evalAlong ρ idx = fun (x : ) => ρ i

                              evalAlong for a passive variable is constant

                              theorem LeanCert.Core.Expr.evalAlong_add (e₁ e₂ : Expr) (ρ : ) (idx : ) :
                              (e₁.add e₂).evalAlong ρ idx = fun (t : ) => e₁.evalAlong ρ idx t + e₂.evalAlong ρ idx t

                              evalAlong for addition

                              theorem LeanCert.Core.Expr.evalAlong_add_pi (e₁ e₂ : Expr) (ρ : ) (idx : ) :
                              (e₁.add e₂).evalAlong ρ idx = e₁.evalAlong ρ idx + e₂.evalAlong ρ idx

                              evalAlong for addition (Pi form for compatibility with deriv_add)

                              theorem LeanCert.Core.Expr.evalAlong_mul (e₁ e₂ : Expr) (ρ : ) (idx : ) :
                              (e₁.mul e₂).evalAlong ρ idx = fun (t : ) => e₁.evalAlong ρ idx t * e₂.evalAlong ρ idx t

                              evalAlong for multiplication

                              theorem LeanCert.Core.Expr.evalAlong_mul_pi (e₁ e₂ : Expr) (ρ : ) (idx : ) :
                              (e₁.mul e₂).evalAlong ρ idx = e₁.evalAlong ρ idx * e₂.evalAlong ρ idx

                              evalAlong for multiplication (Pi form for compatibility with deriv_mul)

                              theorem LeanCert.Core.Expr.evalAlong_neg (e : Expr) (ρ : ) (idx : ) :
                              e.neg.evalAlong ρ idx = fun (t : ) => -e.evalAlong ρ idx t

                              evalAlong for negation

                              theorem LeanCert.Core.Expr.evalAlong_neg_pi (e : Expr) (ρ : ) (idx : ) :
                              e.neg.evalAlong ρ idx = -e.evalAlong ρ idx

                              evalAlong for negation (Pi form for compatibility with deriv.neg)

                              theorem LeanCert.Core.Expr.evalAlong_sin (e : Expr) (ρ : ) (idx : ) :
                              e.sin.evalAlong ρ idx = fun (t : ) => Real.sin (e.evalAlong ρ idx t)

                              evalAlong for sin

                              theorem LeanCert.Core.Expr.evalAlong_cos (e : Expr) (ρ : ) (idx : ) :
                              e.cos.evalAlong ρ idx = fun (t : ) => Real.cos (e.evalAlong ρ idx t)

                              evalAlong for cos

                              theorem LeanCert.Core.Expr.evalAlong_exp (e : Expr) (ρ : ) (idx : ) :
                              e.exp.evalAlong ρ idx = fun (t : ) => Real.exp (e.evalAlong ρ idx t)

                              evalAlong for exp

                              theorem LeanCert.Core.Expr.evalAlong_inv (e : Expr) (ρ : ) (idx : ) :
                              e.inv.evalAlong ρ idx = fun (t : ) => (e.evalAlong ρ idx t)⁻¹

                              evalAlong for inv

                              theorem LeanCert.Core.Expr.evalAlong_log (e : Expr) (ρ : ) (idx : ) :
                              e.log.evalAlong ρ idx = fun (t : ) => Real.log (e.evalAlong ρ idx t)

                              evalAlong for log

                              theorem LeanCert.Core.Expr.evalAlong_atan (e : Expr) (ρ : ) (idx : ) :
                              e.atan.evalAlong ρ idx = fun (t : ) => Real.arctan (e.evalAlong ρ idx t)

                              evalAlong for atan

                              theorem LeanCert.Core.Expr.evalAlong_arsinh (e : Expr) (ρ : ) (idx : ) :
                              e.arsinh.evalAlong ρ idx = fun (t : ) => Real.arsinh (e.evalAlong ρ idx t)

                              evalAlong for arsinh

                              theorem LeanCert.Core.Expr.evalAlong_atanh (e : Expr) (ρ : ) (idx : ) :
                              e.atanh.evalAlong ρ idx = fun (t : ) => Real.atanh (e.evalAlong ρ idx t)

                              evalAlong for atanh

                              Single-variable expressions #

                              For 1D optimization and root finding, we often work with expressions that only use variable 0. These lemmas establish that such expressions can be evaluated equivalently with different environment representations.

                              theorem LeanCert.Core.Expr.eval_usesOnlyVar0_eq (e : Expr) (he : e.usesOnlyVar0 = true) (ρ₁ ρ₂ : ) (h0 : ρ₁ 0 = ρ₂ 0) :
                              eval ρ₁ e = eval ρ₂ e

                              If two environments agree on variable 0, then a usesOnlyVar0 expression evaluates the same

                              theorem LeanCert.Core.Expr.eval_1d_equiv (e : Expr) (he : e.usesOnlyVar0 = true) (x : ) :
                              eval (fun (n : ) => if n = 0 then x else 0) e = eval (fun (x_1 : ) => x) e

                              For single-variable expressions, fun n => if n = 0 then x else 0 and fun _ => x give the same evaluation result.

                              theorem LeanCert.Core.Expr.eval_box1d_eq_eval1d (e : Expr) (he : e.usesOnlyVar0 = true) (x : ) :
                              eval (fun (n : ) => if n = 0 then x else 0) e = eval (fun (x_1 : ) => x) e

                              Alternative: evaluation with Box-style environment equals 1D evaluation