Scalar expression refinement #
toReal_evalRuntime_eq_evalSpec composes FloatLib's arithmetic refinement results along an
Expr tree. evalRuntime uses encoded binary32 operations; evalSpec rounds each real operation
with Model.roundAt FloatFormat.binary32. Fused multiply-add rounds once, not after its product.
The theorem requires a FiniteEval witness for every intermediate result, including finite
leaves and a nonzero divisor. Subnormals and underflow to zero are allowed. The decoded real
equality does not distinguish signed zeros or establish native CPU/GPU kernel correspondence.
References / background (for the rounding model itself, not this AST wrapper):
- IEEE 754-2019: https://doi.org/10.1109/IEEESTD.2019.8766229
- Goldberg (1991): https://doi.org/10.1145/103162.103163
- Flocq (Boldo–Melquiond, 2011): https://doi.org/10.1109/ARITH.2011.40
A small scalar expression language #
Expr is a small, scalar-only AST. TorchLean's main IRs live elsewhere; this wrapper exists to
state expression-level refinement theorems for straight-line float32 computations.
A compact AST for scalar float32 expressions evaluated using ExecFloat.Binary 8 23.
- var : ℕ → Expr
- const : FloatLib.Floats.ExecFloat.Binary 8 23 FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee (FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8) _proof_1 _proof_2 _proof_3 _proof_4 → Expr
- add : Expr → Expr → Expr
- sub : Expr → Expr → Expr
- mul : Expr → Expr → Expr
- div : Expr → Expr → Expr
- fma : Expr → Expr → Expr → Expr
- sqrt : Expr → Expr
Instances For
Evaluate an Expr using the executable float32 kernel (ExecFloat.Binary 8 23).
Instances For
"Finite evaluation" witnesses (finite at every intermediate node) #
The arithmetic adapter bridges finite ExecFloat.Binary 8 23 behavior to binary32 rounding on the
reals.
For expression-level statements, every intermediate evaluation must remain finite.
FiniteEval env e d records the result's decoded dyadic d and finite-evaluation witnesses
for every subtree. A successful toDyadic? observation rules out NaN and infinity.
Finite-evaluation witness for the compact scalar expression language.
- var {env : ℕ → FloatLib.Floats.ExecFloat.Binary 8 23 FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee (FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8) Expr._proof_1 Expr._proof_2 Expr._proof_3 Expr._proof_4} (i : ℕ) (d : FloatLib.Numerics.Dyadic) (h : (env i).toModel.toDyadic? = some d) : FiniteEval env (Expr.var i) d
- const {env : ℕ → FloatLib.Floats.ExecFloat.Binary 8 23 FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee (FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8) Expr._proof_1 Expr._proof_2 Expr._proof_3 Expr._proof_4} (x : FloatLib.Floats.ExecFloat.Binary 8 23 FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee (FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8) Expr._proof_1 Expr._proof_2 Expr._proof_3 Expr._proof_4) (d : FloatLib.Numerics.Dyadic) (h : x.toModel.toDyadic? = some d) : FiniteEval env (Expr.const x) d
- add {env : ℕ → FloatLib.Floats.ExecFloat.Binary 8 23 FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee (FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8) Expr._proof_1 Expr._proof_2 Expr._proof_3 Expr._proof_4} {a b : Expr} {da db dout : FloatLib.Numerics.Dyadic} (ha : FiniteEval env a da) (hb : FiniteEval env b db) (hout : (FloatLib.Floats.ExecFloat.Binary.toModel (FloatLib.Floats.ExecFloat.add (evalRuntime env a) (evalRuntime env b))).toDyadic? = some dout) : FiniteEval env (a.add b) dout
- sub {env : ℕ → FloatLib.Floats.ExecFloat.Binary 8 23 FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee (FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8) Expr._proof_1 Expr._proof_2 Expr._proof_3 Expr._proof_4} {a b : Expr} {da db dout : FloatLib.Numerics.Dyadic} (ha : FiniteEval env a da) (hb : FiniteEval env b db) (hout : (FloatLib.Floats.ExecFloat.Binary.toModel (FloatLib.Floats.ExecFloat.sub (evalRuntime env a) (evalRuntime env b))).toDyadic? = some dout) : FiniteEval env (a.sub b) dout
- mul {env : ℕ → FloatLib.Floats.ExecFloat.Binary 8 23 FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee (FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8) Expr._proof_1 Expr._proof_2 Expr._proof_3 Expr._proof_4} {a b : Expr} {da db dout : FloatLib.Numerics.Dyadic} (ha : FiniteEval env a da) (hb : FiniteEval env b db) (hout : (FloatLib.Floats.ExecFloat.Binary.toModel (FloatLib.Floats.ExecFloat.mul (evalRuntime env a) (evalRuntime env b))).toDyadic? = some dout) : FiniteEval env (a.mul b) dout
- div {env : ℕ → FloatLib.Floats.ExecFloat.Binary 8 23 FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee (FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8) Expr._proof_1 Expr._proof_2 Expr._proof_3 Expr._proof_4} {a b : Expr} {da db dout : FloatLib.Numerics.Dyadic} (ha : FiniteEval env a da) (hb : FiniteEval env b db) (hden : db.significand ≠ 0) (hout : (FloatLib.Floats.ExecFloat.Binary.toModel (FloatLib.Floats.ExecFloat.div (evalRuntime env a) (evalRuntime env b))).toDyadic? = some dout) : FiniteEval env (a.div b) dout
- fma {env : ℕ → FloatLib.Floats.ExecFloat.Binary 8 23 FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee (FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8) Expr._proof_1 Expr._proof_2 Expr._proof_3 Expr._proof_4} {a b c : Expr} {da db dc dout : FloatLib.Numerics.Dyadic} (ha : FiniteEval env a da) (hb : FiniteEval env b db) (hc : FiniteEval env c dc) (hout : (FloatLib.Floats.ExecFloat.Binary.toModel ((fun (left right addend : FloatLib.Floats.ExecFloat.Binary { expWidth := 8, expWidth_ge_two := Expr._proof_1, fracWidth := 23, fracWidth_pos := Expr._proof_2, exponentBias := FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8, encoding := FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee, exponentBias_pos := Expr._proof_3, exponentBias_le_maxFinite := Expr._proof_4 }.expWidth { expWidth := 8, expWidth_ge_two := Expr._proof_1, fracWidth := 23, fracWidth_pos := Expr._proof_2, exponentBias := FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8, encoding := FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee, exponentBias_pos := Expr._proof_3, exponentBias_le_maxFinite := Expr._proof_4 }.fracWidth { expWidth := 8, expWidth_ge_two := Expr._proof_1, fracWidth := 23, fracWidth_pos := Expr._proof_2, exponentBias := FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8, encoding := FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee, exponentBias_pos := Expr._proof_3, exponentBias_le_maxFinite := Expr._proof_4 }.encoding { expWidth := 8, expWidth_ge_two := Expr._proof_1, fracWidth := 23, fracWidth_pos := Expr._proof_2, exponentBias := FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8, encoding := FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee, exponentBias_pos := Expr._proof_3, exponentBias_le_maxFinite := Expr._proof_4 }.exponentBias ⋯ ⋯ ⋯ ⋯ (FloatLib.Floats.Formats.BinaryInterchange.Configured.StoragePlan.forKnownWidth (FloatLib.Floats.ExecFloat.Binary.descriptor 8 23 FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee (FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8) Expr._proof_1 Expr._proof_2 Expr._proof_3 Expr._proof_4) (1 + 8 + 23) ⋯) (FloatLib.Floats.Formats.BinaryInterchange.Configured.Code (FloatLib.Floats.Formats.BinaryInterchange.Configured.StoragePlan.forKnownWidth (FloatLib.Floats.ExecFloat.Binary.descriptor 8 23 FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee (FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8) Expr._proof_1 Expr._proof_2 Expr._proof_3 Expr._proof_4) (1 + 8 + 23) ⋯))) => left.fma right addend) (evalRuntime env a) (evalRuntime env b) (evalRuntime env c))).toDyadic? = some dout) : FiniteEval env (a.fma b c) dout
- sqrt {env : ℕ → FloatLib.Floats.ExecFloat.Binary 8 23 FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee (FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8) Expr._proof_1 Expr._proof_2 Expr._proof_3 Expr._proof_4} {a : Expr} {da dout : FloatLib.Numerics.Dyadic} (ha : FiniteEval env a da) (hout : (FloatLib.Floats.ExecFloat.Binary.toModel ((fun (value : FloatLib.Floats.ExecFloat.Binary { expWidth := 8, expWidth_ge_two := Expr._proof_1, fracWidth := 23, fracWidth_pos := Expr._proof_2, exponentBias := FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8, encoding := FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee, exponentBias_pos := Expr._proof_3, exponentBias_le_maxFinite := Expr._proof_4 }.expWidth { expWidth := 8, expWidth_ge_two := Expr._proof_1, fracWidth := 23, fracWidth_pos := Expr._proof_2, exponentBias := FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8, encoding := FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee, exponentBias_pos := Expr._proof_3, exponentBias_le_maxFinite := Expr._proof_4 }.fracWidth { expWidth := 8, expWidth_ge_two := Expr._proof_1, fracWidth := 23, fracWidth_pos := Expr._proof_2, exponentBias := FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8, encoding := FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee, exponentBias_pos := Expr._proof_3, exponentBias_le_maxFinite := Expr._proof_4 }.encoding { expWidth := 8, expWidth_ge_two := Expr._proof_1, fracWidth := 23, fracWidth_pos := Expr._proof_2, exponentBias := FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8, encoding := FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee, exponentBias_pos := Expr._proof_3, exponentBias_le_maxFinite := Expr._proof_4 }.exponentBias ⋯ ⋯ ⋯ ⋯ (FloatLib.Floats.Formats.BinaryInterchange.Configured.StoragePlan.forKnownWidth (FloatLib.Floats.ExecFloat.Binary.descriptor 8 23 FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee (FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8) Expr._proof_1 Expr._proof_2 Expr._proof_3 Expr._proof_4) (1 + 8 + 23) ⋯) (FloatLib.Floats.Formats.BinaryInterchange.Configured.Code (FloatLib.Floats.Formats.BinaryInterchange.Configured.StoragePlan.forKnownWidth (FloatLib.Floats.ExecFloat.Binary.descriptor 8 23 FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee (FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8) Expr._proof_1 Expr._proof_2 Expr._proof_3 Expr._proof_4) (1 + 8 + 23) ⋯))) => value.sqrt) (evalRuntime env a))).toDyadic? = some dout) : FiniteEval env a.sqrt dout
Instances For
Extract the decoded dyadic of the runtime evaluation from a FiniteEval witness.
Whole-expression refinement #
Induction on FiniteEval applies the arithmetic refinement theorem at each operation.
Main expression-level refinement theorem for IEEEExec.