TorchLean API

FloatLib.Kernels.FixedWord.Product.Proof

Verified fixed-limb significand products #

mul128_toNat proves exact 128 × 128 → 256 multiplication using the mul64_toNat theorem from Core.Proof.UInt128. The addition theorems reconstruct the exact sum from its low limbs and outgoing carry. The UInt256 lemmas describe widening, projection, and leading-bit selection.

@[simp]

Embedding a two-limb value in four limbs preserves its mathematical value.

theorem FloatLib.Numerics.FixedWord.UInt256.toNat_ofUInt128ShiftedLeft (value : UInt128) (shift : ) (hlower : 64 < shift) (hupper : shift < 128) :
(ofUInt128ShiftedLeft value shift).toNat = value.toNat <<< shift

The generic widening shuffle has the expected unbounded value for in-range shifts.

theorem FloatLib.Numerics.FixedWord.UInt256.low128_toNat_of_lt (value : UInt256) (hvalue : value.toNat < 2 ^ 128) :
value.low128.toNat = value.toNat

The low-half projection is exact whenever the four-limb value fits in two limbs.

@[simp]
theorem FloatLib.Numerics.FixedWord.UInt256.toNat_eq_zero_iff (value : UInt256) :
value.toNat = 0 value = { limb3 := 0, limb2 := 0, limb1 := 0, limb0 := 0 }

A four-limb value has mathematical value zero exactly when every limb is zero.

The natural-number interpretation determines every limb of a four-word value.

theorem FloatLib.Numerics.FixedWord.add64_toNat (x y : UInt64) :
have result := add64 x y; result.value.toNat + result.carry.toNat * 2 ^ 64 = x.toNat + y.toNat

Native addition with carry represents the corresponding exact natural-number sum.

The carry returned by add64 is always either zero or one.

theorem FloatLib.Numerics.FixedWord.addCarry64_toNat (x y carry : UInt64) :
have result := addCarry64 x y carry; result.value.toNat + result.carry.toNat * 2 ^ 64 = x.toNat + y.toNat + carry.toNat

addCarry64 represents exact addition.

theorem FloatLib.Numerics.FixedWord.addCarry64_carry_le_one (x y carry : UInt64) (hcarry : carry.toNat 1) :
(addCarry64 x y carry).carry.toNat 1

The outgoing carry from addCarry64 is a bit when the incoming carry is a bit.

theorem FloatLib.Numerics.FixedWord.add128_toNat (x y : UInt128) :
have result := add128 x y; result.value.toNat + result.carry.toNat * 2 ^ 128 = x.toNat + y.toNat

add128 represents exact addition, including its carry above bit 127.

The carry returned by add128 is zero or one.

A 128-bit addition has no carry when its mathematical sum fits in 128 bits.

The value limbs of add128 contain the exact sum when its carry is zero.

The low two limbs of add128 contain the ordinary sum whenever that sum fits in 128 bits.

This is the common refinement fact needed by fixed-limb midpoint, significand, and remainder kernels. Keeping it next to add128 avoids backend-local copies of the same carry argument.

theorem FloatLib.Numerics.FixedWord.add256_toNat (x y : UInt256) :
have result := add256 x y; result.value.toNat + result.carry.toNat * 2 ^ 256 = x.toNat + y.toNat

add256 represents exact addition, including its carry above bit 255.

The value limbs of add256 contain the exact sum when its carry is zero.

@[simp]

Native four-limb leading-bit selection agrees with Nat.log2.

Every four-word unsigned value lies below the first unrepresentable 256-bit integer.

@[simp]

mul128 represents the exact mathematical product of its operands.