The contract of the sieve of one denominator #
The contract of the sieve of one denominator in the packing of its class
(Ratpoints.Sieve.sift), over the search intervals in pieces, as an @[spec] theorem proved with
vcgen, the program logic of Lean core, with loop invariants that are named definitions, on the
contracts of the pieces and of the bits of one interval (Ratpoints.Proof.SiftBits). The sieve
hands the points it finds to the callback of the caller on a delivery (Ratpoints.Delivery), whose
flag of the stop is clear at the start, and returns as soon as a call sets it; its contract says
that the delivery it returns is the reference of the delivery (Ratpoints.Delivery.deliver) of the
list of the points it finds, which passes over the points after the stop, and that, when the
callback does not stop the search, the counters it returns are those it is given plus a closed form
that depends neither on the callback, the delivery and the flags of the output nor on the store of
the tables of rows (Ratpoints.Sieve.siftCounts). The numerators come in with the bits of the
numerators -H, …, H of one denominator; the points of a numerator are those that the exact check
delivers with the flags of the search.
Main definitions #
Ratpoints.Sieve.packedReads: the closed forms of the rows of the sieve entries for a denominator in the packing of a class, with the tests of the bits that they read.Ratpoints.Sieve.SiftIntervalsInvariant,Ratpoints.Sieve.SiftIntervalsLoopInvariant: the invariant of the loop ofRatpoints.Sieve.siftover the search intervals, range after range.Ratpoints.Sieve.IsSiftArgs: what the contract ofRatpoints.Sieve.sifton the ranges of the numerators needs of its arguments.Ratpoints.Sieve.intervalCounts,Ratpoints.Sieve.siftCounts: the counts of one search interval and of the sieve of one denominator;Ratpoints.Sieve.SiftIntervalsCounts: the invariant of the counters of the loop over the search intervals.
Main statements #
Ratpoints.Sieve.eq_map_fst_packedReads_of_eq_run_buildRows,Ratpoints.Sieve.reads_of_mem_packedReads: the rows thatRatpoints.Sieve.setRowsandRatpoints.Sieve.buildRowsgive for the residuesb dinv[k] mod p, the closed forms of the rows of the entries, at the offsets of the class read whether the rows ofbadmit the numerators of the bits (Ratpoints.Sieve.SieveEntry.reads_closedRow).Ratpoints.Sieve.flatMap_filter_bits_eq: the bits ofnumerators_to_bitsof the height in the packing of the class of a class wordwgive the numerators-H, …, Hthat passw;Ratpoints.Sieve.flatMap_filter_intervalBits_eq: the bits of a search interval thatRatpoints.Sieve.intervalBitsgives, neither of the codes1and2, give the numerators-H, …, Hof its range that passw.Ratpoints.Sieve.sift_spec: the pieces of a denominator0 < b < 2 ^ 63in the packing of a classclof the class wordw, forH < 2 ^ 63, entries of the first two stages with their tables of inverses and the row offsets of the packing ofcl, a store of the tables of rows that fits them (Ratpoints.Sieve.RowStore.Fits), and entries of the third stage of the shape ofRatpoints.Sieve.SieveEntry.IsPrimeEntrywith the reciprocals of their moduli, deliver, for the ranges of the numerators that the bounds of the search intervals give (Ratpoints.Sieve.RangesFor), the points of the check with the flags (Ratpoints.Sieve.checkNumWith) of the numerators-H, …, Hin one of the ranges that passwand survive the sieve entries of all three stages, and, when the callback does not stop the search, they add the counts ofRatpoints.Sieve.siftCountsto the counters;Ratpoints.Sieve.run_sift_eq_deliver_checkDen: withoutRATPOINTS_NO_CHECK, these are the points that the plain sieve ofbwith all the entries gives whose numerators lie in the ranges and passw, mapped byRatpoints.Sieve.swapPointafter a reversal, without those withy < 0underRATPOINTS_NO_Y.Ratpoints.Sieve.RowStore.Fits.fits_run_sift: the sieve of one denominator with the first entries of a run as those of its first two stages keeps a store that fits all the entries of the run, since it only adds rows.
Implementation notes #
The file uses Lean core and Std only, as Ratpoints.Proof.SiftBits, Ratpoints.Proof.Stages,
Ratpoints.Proof.Packing, Ratpoints.Proof.BitRange, Ratpoints.Proof.RowStore and
Ratpoints.Proof.Delivery do, whose contracts of the bits of one interval and of the rows built
into the tables of rows of the run and whose lemmas on classes, the bits of an interval and the
delivery it builds on. The hypotheses of the test on the words of the C code, 0 < b < 2 ^ 63 and
|a| ≤ H < 2 ^ 63, come in with the numerators -H, …, H of one denominator
(Ratpoints.Sieve.acceptedPoints_eq_ite). The loop of Ratpoints.Sieve.sift over the search
intervals returns at the first interval above H and at a stop: its invariant holds the delivery of
the points of the ranges done, range after range, which are those of the numerators in one of the
ranges, the ranges being increasing and strictly apart (List.flatMap_filter_eq_filter_any); the
sieve specs, made at the first interval that is neither below -H nor above H, are those of
Ratpoints.Sieve.packedReads from then on, and the store of the tables of rows fits the entries in
both branches. The counters have a contract of their own, on the contract of the bits of one
interval (Ratpoints.Sieve.siftBits_spec, which states the delivery and the counters), which needs
neither the class word nor the ranges, and Ratpoints.Sieve.sift_spec states the two; the store
frame is a contract of its own (Ratpoints.Sieve.RowStore.Fits.fits_run_sift), without the class
word and the ranges. The contracts of one block and of the run over the blocks, which call
Ratpoints.Sieve.sift with the class of each denominator, are in Ratpoints.Proof.Blocks and
Ratpoints.Proof.Correction.
One denominator #
The rows of the sieve entries es for the denominator b in the packing of the class cl,
with the row offsets from position pos of offsets on, as Ratpoints.Sieve.setRows and
Ratpoints.Sieve.buildRows make them: the closed forms of the rows of the residues
b dinv[k] mod p (Ratpoints.Sieve.closedRow), with the start 0 and the end p, each with the
test of the bits that it reads (Ratpoints.Sieve.SieveSpec.Reads): whether the row of b admits
the numerator of the bit (Ratpoints.Sieve.SieveEntry.reads_closedRow).
Equations
- One or more equations did not get rendered due to their size.
Instances For
The sieve specs that Ratpoints.Sieve.buildRows completes for the residues b dinv[k] mod p
of the entries (Ratpoints.Sieve.buildRows_setRows_map_spec), the residues that
Ratpoints.Sieve.fillBpList gives (Ratpoints.Sieve.fillBpList_eq_map), at the offsets of the
class from its position pos on, are those of Ratpoints.Sieve.packedReads.
The rows of Ratpoints.Sieve.packedReads read their tests, for entries whose factors have their
tables of inverses and whose offsets are those of the packing of the class.
For the points of Ratpoints.Sieve.acceptedPoints with the thunks of the products and of what
the third stage needs of the entries es3 of the shape of
Ratpoints.Sieve.SieveEntry.IsPrimeEntry, with the reciprocals of their moduli, for a denominator
0 < b < 2 ^ 63, H < 2 ^ 63 and the flags fl, the numerators -H, …, H that pass a test p
and survive the entries of the first two stages give the points of the check with the flags
(Ratpoints.Sieve.checkNumWith) of the numerators that pass p and survive the entries of all
three stages (Ratpoints.Sieve.acceptedPoints_eq_ite).
The bits from ⌈(-H - a₀) / 2 ^ k⌉ to ⌊(H - a₀) / 2 ^ k⌋ of the packing of a class cl of
the class word w (Ratpoints.Sieve.NumClass.Packs) that pass a test of the numerators of the
bits give the points of the numerators -H, …, H that pass w and the test: the numerators of the
bits are those of the class among -H, …, H
(Ratpoints.Sieve.NumClass.WF.map_range_numerator_eq_filter_numerators), the pattern of the class
lets the numerator of a bit through exactly when w does
(Ratpoints.Sieve.NumClass.Packs.classBit_bits), and w lets nothing off the class through.
The sieve specs of the denominator b that Ratpoints.Sieve.setRows makes and
Ratpoints.Sieve.buildRows completes, for the residues b dinv[k] mod p of the entries, the class
cl with its row offsets from position pos on and a store that fits the entries
(Ratpoints.Sieve.RowStore.Fits), are those of Ratpoints.Sieve.packedReads.
The bits of a search interval with the bounds bd, which give the range lo, …, hi of the
numerators (Ratpoints.Sieve.IntervalBounds.Represents), when Ratpoints.Sieve.intervalBits gives
neither the code 1 nor the code 2, in the packing of a class cl of the class word w, with
the tests that the rows of Ratpoints.Sieve.packedReads read and the points of the check of
Ratpoints.Sieve.acceptedPoints, give the points of the check with the flags
(Ratpoints.Sieve.checkNumWith) of the numerators -H, …, H in lo, …, hi that pass w and
survive the entries of all three stages.
The invariant of the loop of Ratpoints.Sieve.sift over the bounds of the search intervals,
from the delivery r0, after the first k intervals, for the ranges rs of the numerators that
they give, the increasing list l of the numerators, their test q and their points g: the
callback has not stopped the search, the store of the tables of rows fits the sieve entries es,
the sieve specs are specs0 once they are made (doSetup false), and the delivery is that of the
points of the numerators of l that pass q, range after range, for the first k ranges.
The callback has not stopped the search.
- fits : store.Fits es
The store fits the sieve entries of the first two stages.
The sieve specs, once made.
- eq_deliver : r = Delivery.deliver process r0 (List.flatMap (fun (rg : Int × Int) => List.flatMap g (List.filter (fun (a : Int) => decide (rg.fst ≤ a ∧ a ≤ rg.snd) && q a) l)) (List.take k rs))
The delivery is that of the points of the first
kranges.
Instances For
The invariant of the loop of Ratpoints.Sieve.sift over the bounds of the search intervals of
the denominator b, with the class word w, the sieve entries es and es3, the specs of
Ratpoints.Sieve.packedReads with the row offsets from position pos of offsets on, and the
ranges rs of the numerators, whose state is the value of a return, the delivery, the store of the
tables of rows, the flag of the set-up and the sieve specs: before a return,
Ratpoints.Sieve.SiftIntervalsInvariant after the intervals done, for the numerators -H, …, H,
their test by w and the entries, and the points of the check with the flags fl; after the
return at a stop or at an interval above the height bound, the delivery returned is that of the
points of all the ranges.
Equations
- One or more equations did not get rendered due to their size.
Instances For
After the last range, the delivery is that of the points of all the ranges.
When the ranges from the k-th on hold no element of l that passes q, the delivery after
the first k ranges is that of the points of all of them.
A range that holds no element of l that passes q, or none at all, delivers nothing.
A range whose points the delivery r' adds, after which the callback has not stopped the
search, with the store st that fits the entries and the sieve specs made, keeps the invariant.
A range whose points the delivery r' adds, after which the callback has stopped the search:
the delivery is that of the points of all the ranges
(Ratpoints.Delivery.deliver_flatMap_eq_of_prefix).
Once the sieve specs are made, they are specs0, and the store fits the entries.
What the contract of Ratpoints.Sieve.sift on the ranges rs of the numerators that the bounds
iv of the search intervals give (Ratpoints.Sieve.RangesFor) needs of its arguments: a
denominator 0 < b < 2 ^ 63 and H < 2 ^ 63, the sieve entries es3 of the third stage of the
shape that it needs, the class cl that packs the class word w with its row offsets from position
pos of offsets on, and the sieve entries es of the first two stages with their tables of
inverses and the offsets of the packing of cl.
The denominator is positive.
The denominator is below
2 ^ 63.The height bound is below
2 ^ 63.- isPrimeEntry (e : SieveEntry) : e ∈ es3 → e.IsPrimeEntry
The entries of the third stage have the shape that it needs.
- packs : cl.Packs w
The class packs the class word.
The row offsets of the class start at
pos.- hasInverses (e : SieveEntry) : e ∈ es → e.HasInverses
The entries of the first two stages have their tables of inverses.
The entries of the first two stages have the offsets of the packing of the class.
- rangesFor : RangesFor iv b H rs
The bounds of the search intervals give the ranges.
Instances For
After the last interval, the delivery is that of the points of all the ranges.
At an interval with the code 2, above the height bound, the delivery is that of the points of
all the ranges: the ranges from that interval on lie above H.
An interval with the code 1, below -H, keeps the invariant.
The sieve specs that Ratpoints.Sieve.setRows and Ratpoints.Sieve.buildRows make at the first
interval that asks for them are those of Ratpoints.Sieve.packedReads, and the store after them
fits the entries (Ratpoints.Sieve.eq_map_fst_packedReads_of_eq_run_buildRows).
The delivery after Ratpoints.Sieve.siftBits on the bits that Ratpoints.Sieve.intervalBits
gives for the interval at the position pref.length, neither of the codes 1 and 2, with the
sieve specs of Ratpoints.Sieve.packedReads, adds the points of the range of the numerators of
that interval (Ratpoints.Sieve.flatMap_filter_intervalBits_eq).
The sieve of one denominator with the first k entries of the run L as those of its first two
stages only adds rows to the store of the tables of rows, rows of the references of these entries:
a store that fits L still fits L after it.
The counters of one denominator #
The counts that the search interval with the bounds bd adds to the counters in the sieve of
the denominator b (Ratpoints.Sieve.sift), for the height H, the class cl of b, the sieve
entries es of the first two stages, the first stage ending after sp1 of them, and the entries
es3 of the third stage with the reciprocals mgs3 of their moduli: none for an interval with
the code 1 of Ratpoints.Sieve.intervalBits, and otherwise those of its bits
(Ratpoints.Sieve.bitsCounts), with the tests of the rows the survivor tests of the entries.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The counts that the sieve of the denominator b adds to the counters
(Ratpoints.Sieve.sift), for the height H, the class cl of b, the sieve entries es of the
first two stages, the first stage ending after sp1 of them, the entries es3 of the third stage
with the reciprocals mgs3 of their moduli and the bounds iv of the search intervals: one
denominator, in sifts, and the counts of the search intervals (Ratpoints.Sieve.intervalCounts)
before the first with the code 2 of Ratpoints.Sieve.intervalBits, at which the sieve returns.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The invariant of the counters of the loop of Ratpoints.Sieve.sift over the bounds of the
search intervals of the denominator b, after the intervals pref, for the sieve entries es with
the row offsets of the class cl from position pos of offsets on: the callback has not stopped
the search on the delivery r, the store of the tables of rows fits es, the sieve specs are those
of Ratpoints.Sieve.packedReads once they are made (doSetup false), none of the intervals of
pref has the code 2, and the counters are cnt0 plus one denominator and the counts of the
intervals of pref (Ratpoints.Sieve.intervalCounts).
The callback has not stopped the search.
- fits : store.Fits es
The store fits the sieve entries of the first two stages.
The sieve specs, once made.
- ne_two (bd : IntervalBounds) : bd ∈ pref → (intervalBits (Int64.ofNat b) bd (Int64.ofNat H) cl).fst ≠ 2
No interval done has the code
2. - eq_counts : c = cnt0 + List.foldl (fun (x1 x2 : Counters) => x1 + x2) { sifts := 1 } (List.map (intervalCounts b H sp1 es es3 mgs3 cl) pref)
The counters of the intervals done.
Instances For
Ratpoints.Sieve.SiftIntervalsCounts as the invariant of the counters of the loop of
Ratpoints.Sieve.sift over the bounds of the search intervals, whose state is the value of a
return, the delivery, the store of the tables of rows, the counters, the flag of the set-up and the
sieve specs; after a return without a stop, at an interval with the code 2, the counters returned
are those of Ratpoints.Sieve.siftCounts.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The rows of Ratpoints.Sieve.packedReads of the first k sieve entries are its first k.
The counts of the bits of a search interval with the tests that the rows of
Ratpoints.Sieve.packedReads read are those of Ratpoints.Sieve.intervalCounts, for an interval
without the code 1.
After all the search intervals, none with the code 2, the counters are those of
Ratpoints.Sieve.siftCounts.
At an interval with the code 2, the counters are those of Ratpoints.Sieve.siftCounts: the
intervals before it are those that Ratpoints.Sieve.siftCounts counts.
The counters after one more interval with the counts k, not with the code 2.
An interval with the code 1, below -H, counts nothing.
The sieve specs that Ratpoints.Sieve.setRows and Ratpoints.Sieve.buildRows make at the first
interval that asks for them are those of Ratpoints.Sieve.packedReads, and the store after them
fits the entries (Ratpoints.Sieve.eq_map_fst_packedReads_of_eq_run_buildRows).
Once the sieve specs are made, they are those of Ratpoints.Sieve.packedReads, and the store
fits the entries.
An interval whose bits Ratpoints.Sieve.siftBits sifts with the sieve specs of
Ratpoints.Sieve.packedReads, after which the callback has not stopped the search, adds its counts
(Ratpoints.Sieve.bitsCounts_packedReads_eq_intervalCounts).
The sieve of one denominator b delivers, for every class word w that the class cl packs,
the position pos of the row offsets of cl and the ranges rs of the numerators that the bounds
iv of the search intervals give (Ratpoints.Sieve.RangesFor), quantified in the postcondition
since the program does not mention them, the points of the check with the flags fl
(Ratpoints.Sieve.checkNumWith) of the numerators -H, …, H in one of the ranges that pass w
and survive the sieve entries of all three stages; when the callback does not stop the search, it
adds the counts of Ratpoints.Sieve.siftCounts to the counters. The bounds 0 < b < 2 ^ 63 and
H < 2 ^ 63 are those of the test for common factors on the words of the C code
(Ratpoints.Sieve.accepted_spec); the rows built for b at the first interval that asks for them
(the lazy set-up) are read at the offsets of the packing of cl
(Ratpoints.Sieve.SieveEntry.PackedFor), from a store that fits the entries of the first two stages
(Ratpoints.Sieve.RowStore.Fits), with the residues b dinv[k] mod p of
Ratpoints.Sieve.fillBpList_eq_map.
Without RATPOINTS_NO_CHECK, the points that the sieve of one denominator delivers are those of
the plain sieve of b with all the entries and its check, the reference of the bit arrays of words,
whose numerators lie in one of the ranges rs and pass the class word w
(Ratpoints.Sieve.classBit), mapped by Ratpoints.Sieve.swapPoint after a reversal, without those
with y < 0 under RATPOINTS_NO_Y: both give the points of the brute-force reference over b and
the numerators that survive the entries (Ratpoints.Sieve.sift_spec,
Ratpoints.Sieve.sieveDen_spec, Ratpoints.Sieve.checkDen_spec,
Ratpoints.BruteForce.pointsOfDen_filter).