Lemmas on 64-bit words for the contracts #
Lemmas on the 64-bit words, unsigned and signed, that the contracts of the model need and Lean core
lacks, under their names in the namespaces of Lean core: their bits, masks and shifts, their lowest
set bit, the arithmetic of longs that does not overflow, and the branch-free minimum, distance and
absolute value of longs. The lemmas on vectors, arrays, lists, ranges, natural numbers and
integers are in Ratpoints.Proof.Containers.
Main statements #
UInt64.eq_of_getLsbD_eq: two words are equal when their bits are.UInt64.getLsbD_allOnes_shiftLeft,UInt64.getLsbD_allOnes_shiftRight: the bits of the masks.UInt64.getLsbD_and_sub_one,UInt64.toNat_and_sub_one_lt: forx ≠ 0,x &&& (x - 1)isxwith its lowest set bit cleared, and smaller thanx.UInt64.getLsbD_fold_or_one_shiftLeft,UInt64.getLsbD_fold_or_one_shiftLeft_comp: the bits of a word set one at a time, at their own positions or at the positions that a function gives.UInt64.getLsbD_shiftRight_or_shiftLeft: the 64 bits from positionron of the 128 bits of two words, for0 < r < 64.UInt64.getLsbD_shiftLeft_ofNat,UInt64.getLsbD_shiftRight_ofNat,UInt64.getLsbD_toUInt64_shiftLeft: the bits of a word and of a Boolean shifted by an amount below 64.UInt64.getLsbD_foldl_and: the bits of a word and-ed in turn with the words of a list.UInt64.two_pow_ctz_mul_shiftRight_ofNat,UInt64.shiftRight_ctz_ofNat_mod_two: a number0 < b < 2 ^ 64is2 ^ ttimes the odd numberb >>> t, for the positiontof the lowest set bit of the wordb.Int64.toInt_shiftRight_ofNat,Int64.shiftRight_63: the arithmetic shift of alongbyk < 64, and the maskx >>> 63,-1for a negativexand0otherwise.Int64.toNatClampNeg_add_and_shiftRight_63,Int64.toNatClampNeg_xor_shiftRight_63_sub: ford = m - n,n + (d &&& d >>> 63)and(d ^^^ d >>> 63) - d >>> 63are the smaller and the distance of two non-negativelongs.Int64.two_pow_ctz_mul_toNatClampNeg_shiftRight,Int64.toNatClampNeg_shiftRight_ctz_mod_two: a positivelongxis2 ^ ttimes the odd numberx >>> t, for the positiontof the lowest set bit of the wordxread as unsigned.Int64.toNatClampNeg_ite_neg: the absolute value of alongother than-2 ^ 63.Int64.minValue_lt_ofInt,Int64.ofNat_pos: the word of an integer|a| < 2 ^ 63is not-2 ^ 63, and that of a natural number0 < n < 2 ^ 63is positive.Int64.toInt_add_of_lt,Int64.toInt_sub_of_lt,Int64.toInt_neg_of_lt,Int64.toInt_mul_of_lt: the sums, differences, negations and products oflongs that do not overflow.Int64.toInt_and_one,Int64.toInt_shiftRight_one,Int64.toInt_one_shiftLeft: the lowest bit, the half and the powers of2oflongs, for the midpoints of the bisection of the Sturm step.Int64.toInt_and_ofNat_two_pow_sub_one: alongand-ed with the mask2 ^ k - 1is its Euclidean remainder modulo2 ^ k.UInt64.toNat_shift_words_of_lt,UInt64.toNat_shift_words_of_le: the two words of a 128-bit number shifted right by0 < s < 64and by64 ≤ s ≤ 127.
Implementation notes #
The file uses Lean core only, so that the grind calls of the proofs see only the lemmas of core,
untouched by the updates of Mathlib.
Words #
The bits i < k for which c i holds, set one after the other in the word 0: the case
f i = i of UInt64.getLsbD_fold_or_one_shiftLeft_comp.
For 0 < b < 2 ^ 64, b is 2 ^ t times b >>> t, for the position t of the lowest set
bit of the word b, since the bits of b below it are clear.
One doubling of a pattern g of period P ∣ s, s < 64, that fills the bits below s: the
pattern then fills the bits below min (2 s) 64.
The two words of a 128-bit number hi 2 ^ 64 + lo shifted right by 0 < s < 64.
Signed words #
n + (d &&& d >>> 63) for d = m - n is the smaller of two non-negative longs m and n,
without a branch.
(d ^^^ d >>> 63) - d >>> 63 for d = m - n is the distance of two non-negative longs m
and n, without a branch.
A positive long x is 2 ^ t times x >>> t, for the position t of the lowest set bit of
the word x read as unsigned.