Runtime Float32 Bridge #
External (assumption-based) bridge: Lean's Init.Float32 ↔ IEEE32Exec.
Why assumptions are necessary:
Init.Float32 arithmetic in Lean is implemented by external runtime calls. Those calls are opaque
to the Lean kernel, so (inside Lean) we cannot prove that the runtime implementation coincides
bit-for-bit with any particular float32 specification.
We package the finite-result connection as a typeclass interface. If you (or your trusted runtime)
can discharge the assumptions that finite runtime Float32 primitives match the executable kernel
IEEE32Exec bit-for-bit, then you can:
- execute with
Float32(runtime), - rewrite the result to
IEEE32Exec, - reuse
NN/Floats/IEEEExec/Bridge/FP32.leanandNN/Floats/IEEEExec/Bridge/Expressions.leanto connect execution to theFP32rounding-on-ℝmodel on finite/no-overflow inputs.
The trust boundary is explicit: the only unproved part is the external/runtime correctness assumption, which is unavoidable in a pure Lean development.
Background:
- IEEE 754-2019 (what it means to “match float32 semantics”): https://doi.org/10.1109/IEEESTD.2019.8766229
Reinterpret a runtime Float32 as the executable bit-level float32 (IEEE32Exec).
Instances For
What this bridge gives us #
This file does not prove anything about the runtime semantics of Float32. Instead, it gives a
clean interface that you can assume/provide:
- If the runtime
Float32primitives produce the same result bits asIEEE32Exec, then runtime evaluation can be rewritten intoIEEE32Execevaluation. - Once we are in
IEEE32Exec, we can use the internal bridge theorems to connect execution to theFP32rounding-on-ℝmodel on the finite/no-overflow path (NN/Floats/IEEEExec/Bridge/FP32.lean,NN/Floats/IEEEExec/Bridge/FP32Total.lean, andNN/Floats/IEEEExec/Bridge/Expressions.lean).
NaN payloads are deliberately outside the exact-bit contract: Lean runtimes may canonicalize them,
whereas IEEE32Exec preserves a deterministic payload. Classification fields below still relate
NaN, infinity, and finiteness for every runtime value.
External correctness assumptions #
Assumption package relating the finite-result part of Lean's runtime Float32 primitives to
IEEE32Exec. Exact NaN payload agreement is intentionally not required.
- toBits_ofBits_of_isFinite (b : UInt32) : (IEEE32Exec.ofBits b).isFinite = true → (Float32.ofBits b).toBits = b
Instances
Derived bit-level refinement lemmas #
Derived lemmas (rewriting runtime to executable) #
The assumptions above are phrased as bit equalities. In practice we almost always want the more convenient value-level rewriting lemmas below:
toIEEE32Exec (a + b) = IEEE32Exec.add (toIEEE32Exec a) (toIEEE32Exec b), etc.
These are the lemmas you use to “turn a runtime evaluation into an IEEE32Exec evaluation”.
Rewrite runtime float32 addition into executable IEEE32Exec.add.
Rewrite runtime float32 subtraction into executable IEEE32Exec.sub (value-level form).
Rewrite runtime float32 multiplication into executable IEEE32Exec.mul (value-level form).
Rewrite runtime float32 division into executable IEEE32Exec.div (value-level form).
Rewrite runtime float32 negation into executable IEEE32Exec.neg (value-level form).
Rewrite runtime float32 square root into executable IEEE32Exec.sqrt (value-level form).
Converting a finite IEEE32Exec value to runtime Float32 and back preserves its bits.