Lemmas on vectors, arrays, lists, ranges and numbers for the contracts #
Lemmas that Lean core lacks, under their names in the namespaces of core, on vectors (the entries
after Vector.set! and after a fold of it, of Vector.ofFn f and of the array of a vector), arrays
(the entries after Array.set!, Array.push, Array.pop, Array.map, a concatenation and
Array.eraseIdxIfInBounds, the cursor of a loop over an array, an array that extends another, the
entries of an array whose list extends that of another), byte arrays (the size of a byte array made
from an array, the bytes after ByteArray.set!), lists (filters and List.flatMap over ranges, a
list read by its indices, tests by the entries, prefixes, the cursors of loops over two lists),
ranges (the cursor of a loop over [a:m]), natural numbers and integers (residues and quotients,
Barrett's estimate, the remainder and the quotient by a reciprocal, the steps of the binary
algorithm for the gcd), Except and strings. The lemmas on 64-bit words are in
Ratpoints.Proof.Bits.
Main definitions #
Array.Extends: an array extends another, position by position.
Implementation notes #
The file uses Lean core and Std only, so that the grind calls of the proofs see only the lemmas
of core, untouched by the updates of Mathlib.
Vectors #
Arrays #
Setting the entries f y to true for the y of a list keeps the entries that are true
and makes those entries true (within the size).
The entries of an array of Booleans that a fold of setIfInBounds · true over the list l
marks: entry t in range is set when it was set before or one of the positions f i is t.
A property of the members of the list of an array holds after a push of a member that has it:
Array.forall_mem_push for the members of the list, as invariants of loops state them.
The images under f of the members of the list of an array after a push of x are pairwise
related by R exactly when those before are and each of them is related to the image of x, as
invariants of loops state the order of the entries.
The cursor of a loop over the array xs is an entry of xs.
A list over the positions of an array whose list is (List.range n).map f, read with [i]!,
is that over the values of f.
The array b extends the array a: each entry of a is at its index in b. This is
a.toList <+: b.toList (List.prefix_iff_getElem?), stated entry by entry, so that an entry of a
is read off b in one step.
Instances For
Byte arrays #
Lists #
Of the integers s, …, s + m - 1, those from s + k₁ to s + m - 1 - k₂: the m - k₁ - k₂
integers from s + k₁ on; for m ≤ k₁ + k₂ there are none, and the truncated subtraction gives
0.
Of the integers s, …, s + m - 1, those from lo to hi: the integers from
s + (lo - s).toNat, the larger of s and lo, on, as many as m less the truncated differences
(lo - s).toNat and (s + m - 1 - hi).toNat.
The positions t of the blocks y < m that pass the test g y, read as the integers
a + 64 y + t, in increasing order, are the integers a, …, a + 64 m - 1 that pass p, when
g y t is t < 64 and p (a + 64 y + t): for g y the bits of a word y, the numerators of the
set bits of m words.
The positions t < 64 of the blocks w = w0, …, w0 + n - 1 that pass the test g w, read as
the numbers 64 w + t, in increasing order, are the numbers 64 w0, …, 64 (w0 + n) - 1 that pass
p, when g w t is p (64 w + t): for g w the bits of a word w, the numbers of the set bits
of n words; List.flatMap_range_map_filter for natural numbers and blocks from w0 on.
The filter of the outer list of a double List.flatMap moved into the filter of the inner
one.
The cursor of the second list of a loop for x in l, y in l.map f, after the entries pref of
l, at the entry a: the next value is f a, and the rest of the list follows.
The elements of a list that pass p followed by those that pass q are those that pass one of
the two, for a list whose elements are pairwise in an asymmetric relation R that holds from every
element that passes p to every element that passes q: none passes both, and those that pass p
come first.
Over ranges lo, …, hi of integers that are increasing and strictly apart, the elements of an
increasing list l that lie in each range and pass q, range after range, are the elements of l
that lie in one of the ranges and pass q: the loop of Ratpoints.Sieve.sift over the search
intervals.
A property of the elements of l.drop n and of the entries l[k]! for m ≤ k < n holds for
the elements of l.drop m.
The image f cur of the cursor cur of a loop over [a:e + 1] is among the images of
a, …, e that pass keep, when it passes keep.
A list whose elements all pass p is its own longest prefix that passes p: the direction from
right to left of Mathlib's List.takeWhile_eq_self_iff, restated for the files without Mathlib.
Ranges #
The form of List.eq_of_range'_eq_append_cons for the list ForIn.toList [a:m] of a loop over
[a:m], in which the verification conditions state the cursor: the cursor is a plus the length of
the list before it.
The form of List.eq_of_range'_eq_append_cons for the list ForIn.toList [0:m] of a loop over
[0:m], in which the verification conditions state the cursor: the cursor is the length of the list
before it.
The form of List.mem_of_range'_eq_append_cons for the list ForIn.toList [a:m] of a loop over
[a:m]: the cursor is below m.
A number below m is in the list of a loop over [0:m].
The form of List.length_of_range'_eq_append_cons for the list ForIn.toList [a:m] of a loop
over [a:m]: the lists before and after the cursor have m - a - 1 entries together.
Natural numbers #
Word κ < k of block j < c of c blocks of k words is below c k: the statement of
Batteries' Nat.mul_add_lt_mul_of_lt_of_lt, for the files that use Lean core only.
For m p = N + δ and u δ < N, the product m u is L + N ⌊u / p⌋ for some L < N with
L p = u δ + N (u mod p): the product of u with a reciprocal m of p scaled by N, rounded
up when δ ≥ 0 is small.
The odd part y of the distance of two odd numbers m and n has with the smaller of the two
the gcd of m and n: the step of the binary algorithm for the gcd.
A part y of the distance of two positive numbers, together with the smaller of the two, is
less than their sum: the measure of the binary algorithm for the gcd decreases.
The residue x i mod q, for an inverse i of r modulo q, is unchanged when x and r
are both scaled by u: x' i' ≡ x i for x' ≡ u x, r' ≡ u r, i r ≡ 1 and i' r' ≡ 1.
Integers #
⌊lo / m⌋ + ⌈(lo mod m - a₀) / m⌉ = ⌈(lo - a₀) / m⌉ for m > 0: the first bit of the split
form of numerators_to_bits (Ratpoints.Sieve.numeratorsToBits), from the multiple of m in lo
and its rest.