Affine Arithmetic Expression Evaluator #
This module provides expression evaluation using Affine Arithmetic (AA). Affine arithmetic tracks correlations between variables, solving the "dependency problem" that causes interval arithmetic to over-approximate.
Main definitions #
AffineConfig- Configuration for affine evaluationAffineEnv- Variable environment mapping indices to affine formsevalIntervalAffine- Main evaluator: Expr → AffineForm
Performance #
For expressions with repeated variables:
- Interval:
x - xon [-1, 1] gives [-2, 2] - Affine:
x - xon [-1, 1] gives [0, 0] (exact!)
Affine arithmetic gives 50-90% tighter bounds for many real-world expressions, especially in neural network verification where the same inputs flow through multiple paths.
Limitations #
Some transcendental functions (sin, cos, atan) fall back to interval arithmetic because affine approximations aren't yet implemented.
Configuration #
Configuration for Affine evaluation.
taylorDepth- Number of Taylor terms for transcendental functionsmaxNoiseSymbols- Maximum noise symbols before consolidation (0 = unlimited)
- taylorDepth : ℕ
Number of Taylor series terms for transcendental functions
- maxNoiseSymbols : ℕ
Max noise symbols before consolidation (0 = no limit)
Instances For
Equations
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Variable Environment #
Variable assignment as Affine forms
Equations
Instances For
Create an affine environment from rational intervals.
Each variable gets a unique noise symbol to track correlations.
Equations
- LeanCert.Engine.toAffineEnv intervals = fun (i : ℕ) => have I := intervals.getD i (LeanCert.Core.IntervalRat.singleton 0); LeanCert.Engine.Affine.AffineForm.ofInterval I i intervals.length
Instances For
Main Evaluator #
Evaluate expression using Affine Arithmetic.
This function recursively evaluates an expression, using:
- Exact affine operations for linear functions (add, sub, neg, scale)
- Controlled approximations for nonlinear functions (mul, sq)
- Interval fallbacks for unsupported transcendentals (sin, cos, atan)
The result is an AffineForm that can be converted to an interval via
toInterval, typically giving tighter bounds than pure interval arithmetic.
Equations
- One or more equations did not get rendered due to their size.
- LeanCert.Engine.evalIntervalAffine (LeanCert.Core.Expr.const q) ρ cfg = LeanCert.Engine.Affine.AffineForm.const q
- LeanCert.Engine.evalIntervalAffine (LeanCert.Core.Expr.var idx) ρ cfg = ρ idx
- LeanCert.Engine.evalIntervalAffine (e₁.add e₂) ρ cfg = (LeanCert.Engine.evalIntervalAffine e₁ ρ cfg).add (LeanCert.Engine.evalIntervalAffine e₂ ρ cfg)
- LeanCert.Engine.evalIntervalAffine (e₁.mul e₂) ρ cfg = (LeanCert.Engine.evalIntervalAffine e₁ ρ cfg).mul (LeanCert.Engine.evalIntervalAffine e₂ ρ cfg)
- LeanCert.Engine.evalIntervalAffine e_2.neg ρ cfg = (LeanCert.Engine.evalIntervalAffine e_2 ρ cfg).neg
- LeanCert.Engine.evalIntervalAffine e_2.inv ρ cfg = (LeanCert.Engine.evalIntervalAffine e_2 ρ cfg).inv
- LeanCert.Engine.evalIntervalAffine e_2.exp ρ cfg = (LeanCert.Engine.evalIntervalAffine e_2 ρ cfg).exp cfg.taylorDepth
- LeanCert.Engine.evalIntervalAffine e_2.sinh ρ cfg = (LeanCert.Engine.evalIntervalAffine e_2 ρ cfg).sinh cfg.taylorDepth
- LeanCert.Engine.evalIntervalAffine e_2.cosh ρ cfg = (LeanCert.Engine.evalIntervalAffine e_2 ρ cfg).cosh cfg.taylorDepth
- LeanCert.Engine.evalIntervalAffine e_2.tanh ρ cfg = (LeanCert.Engine.evalIntervalAffine e_2 ρ cfg).tanh
- LeanCert.Engine.evalIntervalAffine e_2.sqrt ρ cfg = (LeanCert.Engine.evalIntervalAffine e_2 ρ cfg).sqrt
- LeanCert.Engine.evalIntervalAffine e_2.atan ρ cfg = { c0 := (-2 + 2) / 2, coeffs := [], r := (2 - -2) / 2, r_nonneg := LeanCert.Engine.evalIntervalAffine._proof_5 }
- LeanCert.Engine.evalIntervalAffine e_2.arsinh ρ cfg = default
- LeanCert.Engine.evalIntervalAffine e_2.atanh ρ cfg = default
- LeanCert.Engine.evalIntervalAffine e_2.sinc ρ cfg = { c0 := 0, coeffs := [], r := 1, r_nonneg := LeanCert.Engine.evalIntervalAffine._proof_6 }
- LeanCert.Engine.evalIntervalAffine e_2.erf ρ cfg = { c0 := 0, coeffs := [], r := 1, r_nonneg := LeanCert.Engine.evalIntervalAffine._proof_6 }
Instances For
Convenience Functions #
Evaluate and convert to interval
Equations
- LeanCert.Engine.evalAffineToInterval e ρ cfg = (LeanCert.Engine.evalIntervalAffine e ρ cfg).toInterval
Instances For
Check if expression is bounded above
Equations
- LeanCert.Engine.checkUpperBoundAffine e ρ bound cfg = decide ((LeanCert.Engine.evalIntervalAffine e ρ cfg).toInterval.hi ≤ bound)
Instances For
Check if expression is bounded below
Equations
- LeanCert.Engine.checkLowerBoundAffine e ρ bound cfg = decide (bound ≤ (LeanCert.Engine.evalIntervalAffine e ρ cfg).toInterval.lo)
Instances For
Correctness Theorem #
Environment membership: real value is represented by the affine form
Equations
- LeanCert.Engine.envMemAffine ρ_real ρ_affine eps = ∀ (i : ℕ), (ρ_affine i).mem_affine eps (ρ_real i)
Instances For
Domain validity for Affine evaluation. This is defined directly in terms of evalIntervalAffine to ensure compatibility. For log, we require the argument's toInterval to have positive lower bound.
Equations
- LeanCert.Engine.evalDomainValidAffine (LeanCert.Core.Expr.const q) ρ cfg = True
- LeanCert.Engine.evalDomainValidAffine (LeanCert.Core.Expr.var idx) ρ cfg = True
- LeanCert.Engine.evalDomainValidAffine (e₁.add e₂) ρ cfg = (LeanCert.Engine.evalDomainValidAffine e₁ ρ cfg ∧ LeanCert.Engine.evalDomainValidAffine e₂ ρ cfg)
- LeanCert.Engine.evalDomainValidAffine (e₁.mul e₂) ρ cfg = (LeanCert.Engine.evalDomainValidAffine e₁ ρ cfg ∧ LeanCert.Engine.evalDomainValidAffine e₂ ρ cfg)
- LeanCert.Engine.evalDomainValidAffine e_2.neg ρ cfg = LeanCert.Engine.evalDomainValidAffine e_2 ρ cfg
- LeanCert.Engine.evalDomainValidAffine e_2.inv ρ cfg = LeanCert.Engine.evalDomainValidAffine e_2 ρ cfg
- LeanCert.Engine.evalDomainValidAffine e_2.exp ρ cfg = LeanCert.Engine.evalDomainValidAffine e_2 ρ cfg
- LeanCert.Engine.evalDomainValidAffine e_2.sin ρ cfg = LeanCert.Engine.evalDomainValidAffine e_2 ρ cfg
- LeanCert.Engine.evalDomainValidAffine e_2.cos ρ cfg = LeanCert.Engine.evalDomainValidAffine e_2 ρ cfg
- LeanCert.Engine.evalDomainValidAffine e_2.log ρ cfg = (LeanCert.Engine.evalDomainValidAffine e_2 ρ cfg ∧ (LeanCert.Engine.evalIntervalAffine e_2 ρ cfg).toInterval.lo > 0)
- LeanCert.Engine.evalDomainValidAffine e_2.atan ρ cfg = LeanCert.Engine.evalDomainValidAffine e_2 ρ cfg
- LeanCert.Engine.evalDomainValidAffine e_2.arsinh ρ cfg = LeanCert.Engine.evalDomainValidAffine e_2 ρ cfg
- LeanCert.Engine.evalDomainValidAffine e_2.atanh ρ cfg = LeanCert.Engine.evalDomainValidAffine e_2 ρ cfg
- LeanCert.Engine.evalDomainValidAffine e_2.sinc ρ cfg = LeanCert.Engine.evalDomainValidAffine e_2 ρ cfg
- LeanCert.Engine.evalDomainValidAffine e_2.erf ρ cfg = LeanCert.Engine.evalDomainValidAffine e_2 ρ cfg
- LeanCert.Engine.evalDomainValidAffine e_2.sinh ρ cfg = LeanCert.Engine.evalDomainValidAffine e_2 ρ cfg
- LeanCert.Engine.evalDomainValidAffine e_2.cosh ρ cfg = LeanCert.Engine.evalDomainValidAffine e_2 ρ cfg
- LeanCert.Engine.evalDomainValidAffine e_2.tanh ρ cfg = LeanCert.Engine.evalDomainValidAffine e_2 ρ cfg
- LeanCert.Engine.evalDomainValidAffine e_2.sqrt ρ cfg = LeanCert.Engine.evalDomainValidAffine e_2 ρ cfg
- LeanCert.Engine.evalDomainValidAffine LeanCert.Core.Expr.pi ρ cfg = True
Instances For
Domain validity is trivially true for ExprSupported expressions (which exclude log).
Correctness theorem for Affine interval evaluation.
If all input variables are represented by their affine forms (via noise assignment eps), then the real evaluation of the expression is represented by the affine result.
This proves soundness: the affine form always contains the true value.
Note: Requires valid noise assignment and domain validity for log. Some transcendental cases (sin, cos, pi) use interval fallback and have separate soundness via interval bounds.
Corollary: The interval produced by toInterval contains the true value.
This is the key result for optimization: if we compute an affine form and convert to an interval, the interval is guaranteed to contain the true value.