Directed-rounding primitives for interval propagation #
TorchLean’s IBP/CROWN code represents bounds as endpoint pairs (lo/hi) inside Box/FlatBox.
To make those bounds meaningful under different numeric semantics, we abstract the primitive
endpoint operations (directed rounding).
Intuition:
- For pure real/interval backends, using ordinary
+/*is already enclosure-safe (because the scalar itself is an interval type with outward rounding). - For finite-precision backends with discrete grids (e.g.
ExecFloat.Binary 8 23), we want directed rounding primitives likeaddDown/addUpandmulDown/mulUpso that interval propagation encloses the corresponding exact real operation.
This file defines two small numeric interfaces:
BoundOpsfor directed elementary arithmetic; andNonlinearBoundOpsfor interval transfers that may be unavailable on a backend.
There is intentionally no generic fallback for BoundOps: ordinary finite-precision arithmetic is
not directed rounding and must not silently enter a sound bound-propagation path. The nonlinear
interface does have a conservative fallback for bounded activations, but operations with unbounded
ranges return none unless the scalar backend supplies an implementation. Soundness is a separate
obligation, recorded by LawfulNonlinearBoundOps.
Integration points in the current codebase #
The intended usage is:
- Keep graphs/layers scalar-polymorphic over
[TorchLean.Storage α] [Context α]. - When a routine propagates bounds (IBP/affine/CROWN), also require
[BoundOps α]and useaddDown/addUp/subDown/subUp/mulDown/mulUpat the endpoints.
Concretely:
NN/MLTheory/CROWN/Core.leanNN.MLTheory.CROWN.GraphboxAdd,boxSub,boxMulElem: endpoint propagation usesBoundOps.
Executable certificate replay relies on this separation. A backend may support directed binary
arithmetic without having a correctly rounded exp or log; in that case the graph checker leaves
the corresponding node unresolved instead of treating an ordinary library call as an enclosure.
BoundOps α #
BoundOps supplies directed-rounding versions of the arithmetic
primitives that appear in IBP for affine/linear layers and basic arithmetic nodes.
If you want to swap in a quantized backend, the key is to provide an instance of BoundOps for
your scalar type.
- addDown : α → α → α
- addUp : α → α → α
- subDown : α → α → α
- subUp : α → α → α
- mulDown : α → α → α
- mulUp : α → α → α
- supportsExactAffineReassociation : Bool
Whether ordinary scalar algebra may be reassociated without a rounding error.
Instances
Minimum of two scalar endpoints.
Instances For
Maximum of two scalar endpoints.
Instances For
Nonlinear enclosure operations #
Each method consumes a closed interval [lo, hi]. A successful result is another endpoint pair;
none means that this backend does not implement a finite transfer for the requested operation.
Division receives both numerator and denominator intervals. The executable result alone makes no
soundness claim; LawfulNonlinearBoundOps supplies that claim when a theorem needs it.
The interface is deliberately operational, like BoundOps. The proof layer establishes soundness
for the concrete implementations used by checked workflows; an external instance without a lawful
instance remains part of the backend trust boundary.
Interval enclosures for the nonlinear scalar operations a bound-propagation pass needs.
Each method takes the endpoints of the input interval (division takes both operands' endpoints) and
returns the endpoints of an enclosure of the image, or none when the backend declines to bound
that input, for example a logarithm on an interval reaching zero.
Enclose
x / yfrom the endpoints ofxand then ofy.Enclose
exp xon[l, u].Enclose
log xon[l, u].Enclose
sqrt xon[l, u].Enclose
sigmoid xon[l, u].Enclose
tanh xon[l, u].Enclose
sin xon[l, u].Enclose
cos xon[l, u].Uniform absolute bound for one last-axis layer-normalization row.
- supportsIdealCoupledDerivatives : Bool
Whether coupled softmax/layer-normalization derivative formulas use exact scalar arithmetic.
Instances
Minimum of four endpoints.
Instances For
Maximum of four endpoints.
Instances For
The denominator interval avoids zero.
Instances For
A coarse softplus enclosure that stays finite without evaluating an exponential.
For a real input, max x 0 ≤ softplus x ≤ max x 0 + 1: after the sign branch, the
remaining logarithm lies between zero and log 2 < 1. Directed addition therefore gives an
enclosure even when an endpoint is too large for an exponential-based transfer. The graph checker
can use this range as a constant affine bound on every backend that supplies directed arithmetic.
Instances For
Enclose safeLog using the complete input and epsilon intervals.
The lower endpoint of softplus(x) + epsilon must be positive. This checks the supplied epsilon,
including values smaller than the context default. A backend's logarithm transfer gives the first
choice of bounds. If it is unavailable, 1 - 1/z ≤ log z ≤ z - 1 supplies a coarser enclosure
using directed reciprocal and subtraction. Neither route evaluates an unbounded exponential.
Instances For
Conservative nonlinear ranges available for every scalar context.
Sigmoid, tanh, sine, and cosine have format-independent codomain bounds. Unbounded operations and layer normalization remain unavailable until a concrete backend provides directed implementations.
Host binary64 endpoints #
Lean's Float operations round to nearest on the host binary64 format. For executable checking we
widen every finite result by one adjacent representable value. This is deliberately an explicit
instance rather than a generic fallback: its soundness depends on the host IEEE-754 arithmetic
boundary documented by Lean, whereas instBoundOpsReal is exact and the ExecFloat.Binary 8 23
instance is
connected to TorchLean's bit-level binary32 proofs.
Sign bit of a binary64 word: clearing it gives the magnitude, testing it gives the sign.
Instances For
Bit pattern of +∞ in binary64. Stepping up from here has to stay put.
Instances For
Bit pattern of -∞ in binary64. Stepping down from here has to stay put.
Instances For
Adjacent binary64 value above x, with the usual IEEE behavior at infinities and zeros.
Instances For
Adjacent binary64 value below x, with the usual IEEE behavior at infinities and zeros.
Instances For
Outward-widened host binary64 operations.
This instance is suitable for executable certificate replay under the trusted host-Float boundary.
Use ExecFloat.Binary 8 23 when the binary32 endpoint calculation itself must be connected to Lean
proofs.
Nonlinear enclosures supplied by host binary64 arithmetic.
Division and square root use hardware operations widened by one adjacent binary64 value. We do not
make the same claim for host transcendental-library calls, so exp and log remain unsupported.
Native binary32 endpoints #
The same one-ULP widening policy is available for Lean's native Float32. The operations execute
with binary32 rounding; moving to the adjacent representable value turns each nearest-rounded
result into an outward endpoint.
Sign bit of a binary32 word, the Float32 counterpart of HostFloat.signMask.
Instances For
Bit pattern of +∞ in binary32.
Instances For
Bit pattern of -∞ in binary32.
Instances For
Adjacent binary32 value above x, preserving NaNs and positive infinity.
Instances For
Adjacent binary32 value below x, preserving NaNs and negative infinity.
Instances For
Outward-widened native binary32 operations.
Native binary32 nonlinear enclosures for division and square root.