TorchLean API

FloatLib.Floats.Formats.BinaryInterchange.ModelRounding.Proof

Correctness of normalization through Lean's logical float model #

The executable rounding primitives in ModelRounding.Runtime agree with Lean 4's width-parameterized Float.Model.UnpackedFloat.round. The normalization theorem is generic in the model format. Lemmas using FloatFormat.toModel use the conventional IEEE bias at the descriptor's field widths.

The model represents discarded information with a round bit and a sticky bit. Model uses an integer shift followed by nearest-even rounding. The main result, round_exact_eq_finishRoundedMantissa, proves that these two representations compute the same rounded mantissa and target exponent.

References #

Lean's quotient-plus-accuracy representation makes the same nearest-even choice as Numerics.roundQuotientEven.

Shifting an exact mantissa and rounding its discarded bits agrees with the executable nearest-even shift for every shift distance.

A positive right shift rounds to zero below the half-way point.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.roundShiftRightEven_shiftLeft_add_of_lt_half (mantissa remainder shift : ) (hshift : 0 < shift) (hremainder : remainder < pow2 (shift - 1)) :
Numerics.roundShiftRightEven (mantissa <<< shift + remainder) shift = mantissa

Adding a remainder below half an ulp to a left-shifted mantissa does not change nearest-even rounding.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.roundShiftRightEven_shiftLeft_sub_of_lt_half (mantissa remainder shift : ) (hmantissa : 0 < mantissa) (hshift : 0 < shift) (hremainder : remainder < pow2 (shift - 1)) :
Numerics.roundShiftRightEven (mantissa <<< shift - remainder) shift = mantissa

Subtracting a remainder below half an ulp from a positive left-shifted mantissa does not change nearest-even rounding.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.pow2_le_roundMantissaToLeadingBitEven (mantissa leadingBit : ) (hm : mantissa 0) :
pow2 leadingBit roundMantissaToLeadingBitEven mantissa leadingBit

A nonzero mantissa rounded to leading position p is at least 2^p.

Rounding to leading position p can produce at most the one-bit carry 2^(p+1).

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.roundMantissaAtExponentEven_eq_roundMantissaToLeadingBitEven (mantissa leadingBit : ) (exponent : ) :
roundMantissaAtExponentEven mantissa exponent (mantissa.log2 + exponent - leadingBit) = roundMantissaToLeadingBitEven mantissa leadingBit

Rounding at the exponent that places the leading bit at leadingBit is direct shift-round.

@[simp]

Lean's logical model and FloatFormat compute the same minimum dyadic exponent.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.totalExponent_sub_mantissaBits (fmt : FloatFormat) (mantissa : ) (exponent : ) :
Float.Model.totalExponent mantissa exponent - fmt.toModel.mantissaBits = mantissa.log2 + exponent - fmt.fracWidth

Removing the model precision from a total exponent leaves the usual normal scale.

Below the normal range, every exact dyadic is rounded on the subnormal exponent grid.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.targetExponent_eq_normal (fmt : FloatFormat) (mantissa : ) (exponent : ) (h : fmt.ieeeMinNormalExponent mantissa.log2 + exponent) :
fmt.toModel.targetExponent (Float.Model.totalExponent mantissa exponent) = mantissa.log2 + exponent - fmt.fracWidth

In the normal range, the target exponent places the leading bit at fmt.fracWidth.

A nonzero mantissa at most 2^fmt.fracWidth stays on the minimum-exponent grid.

No bits move when a fitting mantissa is already represented at the minimum exponent.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.log2_eq_fracWidth_of_normalized (fmt : FloatFormat) (mantissa : ) (hlow : pow2 fmt.fracWidth mantissa) (hhigh : mantissa < pow2 (fmt.fracWidth + 1)) :
mantissa.log2 = fmt.fracWidth

A mantissa between 2^p and 2^(p+1) has leading bit exactly at position p.

A normalized mantissa at leading exponent k needs no second normalization shift.

An exact dyadic below the normal range rounds to at most 2^p units of the minimum exponent.

Here p = fmt.fracWidth; equality is the carry from the largest subnormal neighborhood to the smallest normal value.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.roundedMantissa_decrease_shift_exact (mantissa : ) (exponent targetExponent : ) :
have decreased := Float.Model.UnpackedFloat.decreaseExponent mantissa exponent targetExponent; have shifted := Float.Model.UnpackedFloat.shiftToExponent decreased.1 decreased.2 Float.Model.UnpackedFloat.Accuracy.exact targetExponent; (shifted.1.roundedMantissa, shifted.2) = (roundMantissaAtExponentEven mantissa exponent targetExponent, targetExponent)

Lean's decrease-then-shift normalization agrees with direct nearest-even rounding.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.totalExponent_decreaseExponent (mantissa : ) (exponent targetExponent : ) (hm : mantissa 0) :
have decreased := Float.Model.UnpackedFloat.decreaseExponent mantissa exponent targetExponent; Float.Model.totalExponent decreased.1 decreased.2 = Float.Model.totalExponent mantissa exponent

Decreasing an exact dyadic exponent preserves the leading binary position.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.roundedMantissa_decrease_shiftToTarget_exact (spec : Float.Model.Format) (mantissa : ) (exponent : ) (hm : mantissa 0) :
have targetExponent := spec.targetExponent (Float.Model.totalExponent mantissa exponent); have decreased := Float.Model.UnpackedFloat.decreaseExponent mantissa exponent targetExponent; have shifted := Float.Model.UnpackedFloat.shiftToTargetExponent spec decreased.1 decreased.2 Float.Model.UnpackedFloat.Accuracy.exact; (shifted.1.roundedMantissa, shifted.2) = (roundMantissaAtExponentEven mantissa exponent targetExponent, targetExponent)

The first exact model-rounding stage uses the original dyadic's target exponent.

@[simp]

A zero rounded mantissa remains signed zero, independently of the provisional exponent.

A nonzero rounded mantissa on the minimum-exponent grid, up to the smallest normal value, needs no second shift.

theorem FloatLib.Floats.Formats.BinaryInterchange.Model.finishRoundedMantissa_normalized (fmt : FloatFormat) (sign : Float.Model.UnpackedFloat.Sign) (mantissa : ) (k : ) (hlow : pow2 fmt.fracWidth mantissa) (hhigh : mantissa < pow2 (fmt.fracWidth + 1)) (hk : fmt.ieeeMinNormalExponent k) :
finishRoundedMantissa fmt.toModel sign (mantissa, k - fmt.fracWidth) = Float.Model.UnpackedFloat.finite sign mantissa (k - fmt.fracWidth)

A normalized rounded mantissa remains unchanged in the second rounding stage.

The final stage of roundWithAccuracy is finishRoundedMantissa.

roundWithAccuracy agrees with unrestricted rounding when no preliminary left shift is needed.

Exact dyadic model rounding factors through the direct target-exponent rounder.