Bit masks in byte arrays #
A mask is a ByteArray; bit j is bit j % 8 of byte j / 8. Three operations are primitives
implemented in C (@[extern c inline]), each with a reference definition in Lean that the
proofs use: Ratpoints.Mask.andShr, the AND with a row shifted to the right, in place when the
mask is not shared; Ratpoints.Mask.andRows, the AND with a list of shifted rows, one after the
other until nothing is left, whose reference is the loop of Ratpoints.Mask.andShr and whose C
code, for at most 64 rows with shifts that are multiples of 8 and rows long enough for the
mask, works through the mask in blocks of 128 bytes held in registers, every row ANDed into a
block before the block is written back, and otherwise goes row by row, byte by byte; and
Ratpoints.Mask.nextSet, the first set bit from a position on. The C code reads and writes words
of 64 bits (16-byte vectors in Ratpoints.Mask.andRows) and bytes; it does not depend on the byte
order. It assumes that size_t has 64 bits: a shift or a position that is not a scalar becomes
SIZE_MAX, which lies beyond every array only then, and eight times the size of a mask must not
wrap. On a platform with 32 bits, rows of more than 256 MiB with shifts from 2 ^ 31 on, and masks
of 512 MiB or more, could give other results than the reference definitions.
The compiled program runs the C code, the proofs are about the reference definitions: that the two agree is not proved, it is what one has to trust beyond Lean's runtime.
Bit j of the mask a.
Equations
- Ratpoints.Mask.bit a j = (Ratpoints.Mask.byte a (j / 8)).testBit (j % 8)
Instances For
Byte i of the mask row shifted to the right by s bits.
Equations
- Ratpoints.Mask.shrByte row s i = ((Ratpoints.Mask.byte row (s / 8 + i) + 256 * Ratpoints.Mask.byte row (s / 8 + i + 1)) >>> (s % 8)).toUInt8
Instances For
The reference definition of Ratpoints.Mask.andShr: byte i of the result is byte i of
acc ANDed with byte i of row shifted to the right by s bits, and the result is the empty
array when every byte is 0.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The mask acc ANDed with the mask row shifted to the right by s bits: bit j < 8 n
of the result (n the size of acc) is bit j of acc and bit j + s of row; the result is
the empty array when no bit is set. The C code works in place when acc is not shared.
Equations
- Ratpoints.Mask.andShr acc row s = Ratpoints.Mask.andShrSpec acc row s
Instances For
The reference definition of Ratpoints.Mask.andRows: acc ANDed with the rows rs[i]
shifted to the right by sh[i] + o bits (Ratpoints.Mask.andShr), from position i on, one after
the other until nothing is left.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The mask acc ANDed with the rows rs[i] shifted to the right by sh[i] + o bits, all of
them: bit j < 8 n of the result (n the size of acc) is bit j of acc and bit
j + sh[i] + o of every rs[i], and the result is the empty array when no bit is left (when there
is a row). The C code works in place when acc is not shared.
Equations
- Ratpoints.Mask.andRows acc rs sh o = Ratpoints.Mask.andRowsFrom rs sh o acc 0
Instances For
The reference definition of Ratpoints.Mask.nextSet: the first k from j to 8 n - 1
with bit k of a set (n the size of a), or 8 n.
Equations
- Ratpoints.Mask.nextSetSpec a j = (List.find? (Ratpoints.Mask.bit a) (List.range' j (8 * a.size - j))).getD (8 * a.size)
Instances For
The first set bit of the mask a at or after j, or 8 n (n the size of a) when there
is none.
Equations
Instances For
Whether no bit of the mask a is set.
Equations
- Ratpoints.Mask.isZero a = (a.size == 0 || Ratpoints.Mask.nextSet a 0 == 8 * a.size)
Instances For
The mask of len bits, all set, in whole 64-bit words.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The set bits of the mask a, in ascending order.
Equations
- Ratpoints.Mask.setBits a = Ratpoints.Mask.setBitsFrom a (8 * a.size) 0