TorchLean API

FloatLib.Floats.ExecFloat.Backends.Generic.Kernel.Proof

Correctness of width-generic finite arithmetic #

The executable arbitrary-precision kernels live in Kernel.Runtime. This module proves that the compact field-scale implementations agree with the exact dyadic specifications and installs the verified compiler substitutions.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.FiniteKernel.decode?_neg {fmt : FloatFormat} (hieee : fmt.isIEEE = true) (m : Model fmt) :
decode? m.neg = Option.map (fun (c : Components) => { sign := !c.sign, exponent := c.exponent, mantissa := c.mantissa }) (decode? m)

Negating a conventional IEEE value flips only the decoded sign.

@[simp]

The dyadic of a component triple carries the component sign.

@[simp]

The dyadic of a component triple has the component mantissa as significand.

For a nonzero mantissa, the dyadic exponent is the descriptor-adjusted component exponent.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.FiniteKernel.withFinite_eq {fmt : FloatFormat} {α : Type} (x : Model fmt) (k : BoolOption α) :
withFinite? x k = (decode? x).bind fun (value : Components) => k value.sign value.exponent value.mantissa

Scalar finite decoding is extensionally equal to binding the component decoder.

The unsigned finite scale denotes the same signed exponent as the public decoder.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.FiniteKernel.addComponents_sameSign_sameExponent (fmt : FloatFormat) (hfmt : fmt.isIEEE = true) (sign : Bool) (left right exponent : ) (hleft : left 0) (hright : right 0) :
addComponents fmt { sign := sign, exponent := exponent, mantissa := left } { sign := sign, exponent := exponent, mantissa := right } = FiniteProductRound.round fmt sign (left + right) (scale exponent + finiteScaleOffset fmt)

Adding nonzero components with the same sign and exponent reduces to one product-round call.

The scale is derived entirely from the format descriptor, so fixed-width backends do not need their own binary32, binary64, or binary128 versions of this argument.

Compact decoding produces exactly the same finite dyadic as toDyadic?.

Finite component addition is commutative for every format descriptor.

Unsigned-scale finite addition is extensionally equal to the public component operation.

@[csimp]

Compile finite addition through unsigned scale alignment on conventional IEEE formats.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.FiniteKernel.add_eq_spec {fmt : FloatFormat} (x y : Model fmt) :
add? x y = match x.toDyadic?, y.toDyadic? with | some dx, some dy => some (roundDyadic fmt (addDyadic dx dy)) | x, x_1 => none

Compact finite addition equals the public exact-dyadic finite path.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.FiniteKernel.mul_eq_spec {fmt : FloatFormat} (x y : Model fmt) :
mul? x y = match x.toDyadic?, y.toDyadic? with | some dx, some dy => have sign := dx.negative ^^ dy.negative; if (dx.significand == 0 || dy.significand == 0) = true then some (zero fmt sign) else some (roundDyadic fmt { negative := sign, significand := dx.significand * dy.significand, exponent := dx.exponent + dy.exponent }) | x, x_1 => none

The compact finite multiplication kernel equals the public exact-dyadic finite path.

The compact finite division kernel equals the public exact-dyadic finite path.

Unsigned-scale FMA is extensionally equal to the public exact component operation.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.FiniteKernel.fmaComponents_sameSign_aligned (fmt : FloatFormat) (hfmt : fmt.isIEEE = true) (alignment : ) (xSign ySign : Bool) (xExponent yExponent zExponent xMantissa yMantissa zMantissa : ) (hxExponent : xExponent 0) (hyExponent : yExponent 0) (hzExponent : zExponent 0) (hxMantissa : xMantissa 0) (hyMantissa : yMantissa 0) (hzMantissa : zMantissa 0) (haligned : xExponent - 1 + (yExponent - 1) + alignment = zExponent - 1 + finiteScaleOffset fmt) :
fmaComponents fmt { sign := xSign, exponent := xExponent, mantissa := xMantissa } { sign := ySign, exponent := yExponent, mantissa := yMantissa } { sign := xSign ^^ ySign, exponent := zExponent, mantissa := zMantissa } = FiniteProductRound.round fmt (xSign ^^ ySign) (xMantissa * yMantissa + zMantissa <<< alignment) (xExponent - 1 + (yExponent - 1))

An aligned same-sign FMA reduces to one product-round call for every IEEE binary format.

The caller supplies the significand alignment width. The exponent offset remains descriptor derived, so binary32, binary64, binary128, and custom IEEE descriptors share this proof.

@[csimp]

Compile finite FMA through the verified unsigned-scale implementation on IEEE formats.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.FiniteKernel.fma_eq_spec {fmt : FloatFormat} (x y z : Model fmt) :
fma? x y z = match x.toDyadic?, y.toDyadic?, z.toDyadic? with | some dx, some dy, some dz => have product := { negative := dx.negative ^^ dy.negative, significand := dx.significand * dy.significand, exponent := dx.exponent + dy.exponent }; some (roundDyadic fmt (addDyadic product dz)) | x, x_1, x_2 => none

The compact finite FMA kernel equals the public exact-dyadic finite path.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.FiniteKernel.addFields_eq (fmt : FloatFormat) (xSign : Bool) (xExponent xMantissa : ) (ySign : Bool) (yExponent yMantissa : ) :
addFields fmt xSign xExponent xMantissa ySign yExponent yMantissa = addComponents fmt { sign := xSign, exponent := xExponent, mantissa := xMantissa } { sign := ySign, exponent := yExponent, mantissa := yMantissa }

Scalar-field addition agrees with component addition.

The scalar-field addition entry point preserves add?.

@[csimp]

Compile finite addition through the scalar decoder.

The scalar-field multiplication entry point preserves mul?.

@[csimp]

Compile finite multiplication through the scalar decoder.

The scalar-field division entry point preserves div?.

@[csimp]

Compile finite division through the scalar decoder.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.FiniteKernel.fmaFields_eq (fmt : FloatFormat) (xSign : Bool) (xExponent xMantissa : ) (ySign : Bool) (yExponent yMantissa : ) (zSign : Bool) (zExponent zMantissa : ) :
fmaFields fmt xSign xExponent xMantissa ySign yExponent yMantissa zSign zExponent zMantissa = fmaComponents fmt { sign := xSign, exponent := xExponent, mantissa := xMantissa } { sign := ySign, exponent := yExponent, mantissa := yMantissa } { sign := zSign, exponent := zExponent, mantissa := zMantissa }

Scalar-field FMA agrees with component FMA.

The scalar-field FMA entry point preserves fma?.

The straight-line decoder agrees with the continuation decoder.