Documentation

Ratpoints.Proof.SiftBits

The contracts of the pieces and the bits of one interval #

The contracts of the components of the model on words from one piece on up to the bits of one interval in pieces, as @[spec] theorems proved with vcgen, the program logic of Lean core, with loop invariants that are named definitions. Each component 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. The contracts speak of the bits j of the packing of a class cl (Ratpoints.Sieve.NumClass), each standing for the numerator a₀ + 2 ^ k j (Ratpoints.Sieve.NumClass.numerator), and of the tests of the bits that the rows of the moduli read at their offsets (Ratpoints.Sieve.SieveSpec.Reads); the points of a numerator are those that the exact check delivers with the flags of the search (Ratpoints.Sieve.acceptedPoints).

Main definitions #

Main statements #

Implementation notes #

The file uses Lean core and Std only, as Ratpoints.Proof.Words, Ratpoints.Proof.FirstStage, Ratpoints.Proof.Stages, Ratpoints.Proof.Packing, Ratpoints.Proof.Delivery and Ratpoints.Proof.Scan do, whose lemmas on bit arrays, rows, classes and the delivery and whose contracts of both arms of the first stage and of the scan of a piece it builds on. The contracts read the test of a candidate as its value (Ratpoints.Sieve.acceptedPoints), so that they need nothing of the numerators and the denominator. The loop over the pieces returns at a stop: its invariant holds the delivery of the points found so far with the flag clear before a return, and the value returned after it, the delivery of all the points, since the reference passes over the points after the first call that sets the flag (Ratpoints.Delivery.deliver_eq_of_prefix); its verification conditions are closed by lemmas in their shape. A piece has a contract of the delivery and one of the counters, as the scan has (Ratpoints.Proof.ScanCounts), whose proofs name the contracts of the counters of the components they call; the loop over the pieces holds the delivery and the counters in one invariant, and the contract of the bits of one interval states both. The counts of the tests of a candidate, of the bit arrays and of the bits of one interval are irreducible in their verification conditions. The contract of the sieve of one denominator, which calls Ratpoints.Sieve.siftBits for each search interval, is in Ratpoints.Proof.Sift.

The masks and one piece #

@[simp]
theorem Ratpoints.Sieve.survives_append (l₁ l₂ : List SieveEntry) (b : Nat) (a : Int) :
survives (l₁ ++ l₂) b a = (survives l₁ b a && survives l₂ b a)
theorem Ratpoints.Sieve.getLsbD_clearHighBits_sub_one {m n s : Nat} (v : Vector UInt64 m) (hs : s < rbaLength) {y : Nat} (hy : y < m) (hyn : y < n * rbaPack) (t : Nat) :
(clearHighBits v (n - 1) s)[y]!.toBitVec.getLsbD t = (v[y]!.toBitVec.getLsbD t && decide (64 * y + t + s < rbaLength * n))
def Ratpoints.Sieve.IsMasked {m : Nat} (n maskLow maskHigh : Nat) (surv v : Vector UInt64 m) :

The words v of a piece of n bit arrays are the words surv with the masks at its two ends applied, as far as the bits t < 64 of the words y < n rbaPack go: bit t of word y is set in v exactly when it is set in surv, maskLow ≤ 64 y + t and 64 y + t + maskHigh < rbaLength n, for the number rbaPack of words of a bit array (Ratpoints.rbaPack).

Equations
  • One or more equations did not get rendered due to their size.
Instances For
    theorem Ratpoints.Sieve.isMasked_clearHighBits_clearLowBits {n maskHigh : Nat} (v : Vector UInt64 ((n + 1) * rbaPack)) (maskLow : Nat) (hH : maskHigh < rbaLength) :
    IsMasked n maskLow maskHigh v (clearHighBits (clearLowBits v maskLow) (n - 1) maskHigh)
    theorem Ratpoints.Sieve.isMasked_clearLowBits {n maskHigh : Nat} (v : Vector UInt64 ((n + 1) * rbaPack)) (maskLow : Nat) (hH : maskHigh = 0) :
    IsMasked n maskLow maskHigh v (clearLowBits v maskLow)
    theorem Ratpoints.Sieve.isMasked_clearHighBits {n maskLow maskHigh : Nat} (v : Vector UInt64 ((n + 1) * rbaPack)) (hL : maskLow = 0) (hH : maskHigh < rbaLength) :
    IsMasked n maskLow maskHigh v (clearHighBits v (n - 1) maskHigh)
    theorem Ratpoints.Sieve.isMasked_self {m maskLow maskHigh : Nat} (n : Nat) (v : Vector UInt64 m) (hL : maskLow = 0) (hH : maskHigh = 0) :
    IsMasked n maskLow maskHigh v v
    theorem Ratpoints.Sieve.IsMasked.getLsbD_eq {n sp1 : Nat} {specs : List SieveSpec} {cw : UInt64} {w0 : Int} {maskLow maskHigh : Nat} {surv v : Vector UInt64 ((n + 1) * rbaPack)} (hand : ∀ (y : Nat), y < n * rbaPack → surv[y]! = andWords (List.take sp1 specs) cw w0 y) (h : IsMasked n maskLow maskHigh surv v) {sfs : List (SieveSpec × (Int → Bool))} (hspecs : specs = List.map Prod.fst sfs) (hsfs : ∀ (sf : SieveSpec × (Int → Bool)), sf ∈ sfs → sf.fst.Reads sf.snd) (y : Nat) (hy : y < n * rbaPack) (t : Nat) :
    v[y]!.toBitVec.getLsbD t = (decide (t < 64) && (fun (j : Int) => (classBit cw j && (List.take sp1 sfs).all fun (x : SieveSpec × (Int → Bool)) => x.snd j) && decide (↑rbaLength * w0 + ↑maskLow ≤ j ∧ j + ↑maskHigh < ↑rbaLength * w0 + ↑(n * rbaLength))) (↑rbaLength * w0 + 64 * ↑y + ↑t))

    The bits of the words v of a piece of n bit arrays from the word number w0 on, the words of its first stage with the first sp1 moduli of specs from the class word cw on (hand, as Ratpoints.Sieve.andRows_spec states it) with the masks at its two ends applied, when the rows of the moduli read the tests sf.2 of the bits (Ratpoints.Sieve.SieveSpec.Reads): bit t of word y stands for the bit rbaLength w0 + 64 y + t, which is set when it passes the class word, the tests of the first stage and the masks.

    theorem Ratpoints.Sieve.IsMasked.getLsbD_andWords_drop {n sp1 : Nat} {specs : List SieveSpec} {cw : UInt64} {w0 : Int} {maskLow maskHigh : Nat} {surv v : Vector UInt64 ((n + 1) * rbaPack)} (hand : ∀ (y : Nat), y < n * rbaPack → surv[y]! = andWords (List.take sp1 specs) cw w0 y) (h : IsMasked n maskLow maskHigh surv v) {sfs : List (SieveSpec × (Int → Bool))} (hspecs : specs = List.map Prod.fst sfs) (hsfs : ∀ (sf : SieveSpec × (Int → Bool)), sf ∈ sfs → sf.fst.Reads sf.snd) (y : Nat) (hy : y < n * rbaPack) (t : Nat) :
    (andWords (List.drop sp1 specs) v[y]! w0 y).toBitVec.getLsbD t = (decide (t < 64) && (fun (j : Int) => (classBit cw j && sfs.all fun (x : SieveSpec × (Int → Bool)) => x.snd j) && decide (↑rbaLength * w0 + ↑maskLow ≤ j ∧ j + ↑maskHigh < ↑rbaLength * w0 + ↑(n * rbaLength))) (↑rbaLength * w0 + 64 * ↑y + ↑t))

    The words of the scan of a piece of n bit arrays from the word number w0 on, the words v of its first stage with the first sp1 moduli of specs from the class word cw on (hand) with the masks at its two ends applied, and-ed with the rows of the other moduli, when the rows of the moduli read the tests sf.2 of the bits (Ratpoints.Sieve.SieveSpec.Reads): bit t of word y stands for the bit rbaLength w0 + 64 y + t, which is set when it passes the class word, the tests of all the moduli and the masks.

    theorem Ratpoints.Sieve.IsMasked.eq_deliver {σ : Type} {process : Int → Int → Int → σ → Answer σ} {n : Nat} {g : Int → List (Int × Int × Int)} {sp1 : Nat} {specs : List SieveSpec} {cw : UInt64} {w0 : Int} {maskLow maskHigh : Nat} {surv v : Vector UInt64 ((n + 1) * rbaPack)} {r r' : Delivery σ} (hand : ∀ (y : Nat), y < n * rbaPack → surv[y]! = andWords (List.take sp1 specs) cw w0 y) (h : IsMasked n maskLow maskHigh surv v) (hout : ∀ (keep : Int → Bool), (∀ (y : Nat), y < n * rbaPack → ∀ (t : Nat), (andWords (List.drop sp1 specs) v[y]! w0 y).toBitVec.getLsbD t = (decide (t < 64) && keep (↑rbaLength * w0 + 64 * ↑y + ↑t))) → r' = Delivery.deliver process r (List.flatMap g (List.filter keep (List.map (fun (k : Nat) => ↑rbaLength * w0 + ↑k) (List.range (n * rbaLength)))))) {sfs : List (SieveSpec × (Int → Bool))} (hspecs : specs = List.map Prod.fst sfs) (hsfs : ∀ (sf : SieveSpec × (Int → Bool)), sf ∈ sfs → sf.fst.Reads sf.snd) :
    r' = Delivery.deliver process r (List.flatMap g (List.filter (fun (j : Int) => classBit cw j && sfs.all fun (x : SieveSpec × (Int → Bool)) => x.snd j) (List.map (fun (k : Nat) => ↑rbaLength * w0 + ↑maskLow + ↑k) (List.range (n * rbaLength - maskLow - maskHigh)))))

    The points of a piece of n bit arrays from the word number w0 on, given the contracts of its first stage with the first sp1 moduli of specs from the class word cw on the words surv (hand, as Ratpoints.Sieve.andRows_spec states it) and of its scan with the other moduli on the words v (hout, as Ratpoints.Sieve.scanPiece_spec states it, with the points g j of a bit j), when v is surv with the masks applied and the rows of the moduli read the tests sf.2 of the bits (Ratpoints.Sieve.SieveSpec.Reads): the points of the bits from rbaLength w0 + maskLow to rbaLength (w0 + n) - 1 - maskHigh that pass the class word (Ratpoints.Sieve.classBit) and all the tests.

    theorem Ratpoints.Sieve.siftPiece_spec {σ : Type} (process : Int → Int → Int → σ → Answer σ) (w : Thunk (List Int)) (d b : Nat) (fl : CheckFlags) (sp1 : Nat) (specs : List SieveSpec) (mgs : List Nat) (checks : Thunk (List CheckSpec)) (cl : NumClass) (w0 : Int) (n maskLow maskHigh : Nat) (r : Delivery σ) (cnt : Counters) :
    ⦃ r.quit = false ∧ maskHigh < rbaLength ∧ (∀ (s : SieveSpec), s ∈ specs → s.Fits) ∧ mgs = List.map (fun (x : SieveSpec) => magic x.p) specs ⦄ siftPiece process w d b fl sp1 specs mgs checks cl w0 n maskLow maskHigh r cnt ⦃ fun (r' : Delivery σ × Counters) => ∀ (sfs : List (SieveSpec × (Int → Bool))), specs = List.map Prod.fst sfs → (∀ (sf : SieveSpec × (Int → Bool)), sf ∈ sfs → sf.fst.Reads sf.snd) → r'.fst = Delivery.deliver process r (List.flatMap (fun (j : Int) => acceptedPoints w d b fl checks (cl.numerator j)) (List.filter (fun (j : Int) => classBit cl.bits j && sfs.all fun (x : SieveSpec × (Int → Bool)) => x.snd j) (List.map (fun (k : Nat) => ↑rbaLength * w0 + ↑maskLow + ↑k) (List.range (n * rbaLength - maskLow - maskHigh))))) ⦄

    The rows of the moduli, read at their offsets, are given by the tests sf.2 of the bits that they read (Ratpoints.Sieve.SieveSpec.Reads), quantified in the postcondition since the program does not mention them; the first sp1 moduli go to the first stage, in the chunked arm (Ratpoints.Sieve.andRowsChunked_spec) for 1 < chunk ≤ 16 and in the other otherwise (Ratpoints.Sieve.andRows_spec), the others to the second, with their reciprocals and the test small, which keeps the values that the reductions by the reciprocals see in range (Ratpoints.Sieve.SieveSpec.Fits); the bound on maskHigh is that of the high mask (Ratpoints.Sieve.getLsbD_clearHighBits), and the low mask needs none.

    The counters of one piece #

    def Ratpoints.Sieve.arraysWith (keep : Int → Bool) (w0 : Int) (n : Nat) :

    The number of the bit arrays with the word numbers w0, …, w0 + n - 1, of Ratpoints.rbaLength bits each, that hold a bit that passes keep.

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For
      @[simp]
      theorem Ratpoints.Sieve.arraysWith_zero (keep : Int → Bool) (w0 : Int) :
      arraysWith keep w0 0 = 0
      theorem Ratpoints.Sieve.arraysWith_add (keep : Int → Bool) (w0 : Int) (m k : Nat) :
      arraysWith keep w0 (m + k) = arraysWith keep w0 m + arraysWith keep (w0 + ↑m) k
      theorem Ratpoints.Sieve.arraysWith_add_of_eq (keep : Int → Bool) {w0 w0' : Int} {m : Nat} (h : w0' + ↑m = w0) (k : Nat) :
      arraysWith keep w0' (m + k) = arraysWith keep w0' m + arraysWith keep w0 k
      theorem Ratpoints.Sieve.arraysWith_congr {keep keep' : Int → Bool} {w0 : Int} {n : Nat} (h : ∀ (pos : Nat), pos < n → ∀ (t : Nat), t < rbaLength → keep (↑rbaLength * (w0 + ↑pos) + ↑t) = keep' (↑rbaLength * (w0 + ↑pos) + ↑t)) :
      arraysWith keep w0 n = arraysWith keep' w0 n
      theorem Ratpoints.Sieve.IsMasked.eq_counters {σ : Type} {n sp1 : Nat} {specs : List SieveSpec} {cw : UInt64} {w0 : Int} {maskLow maskHigh : Nat} {surv v : Vector UInt64 ((n + 1) * rbaPack)} {b : Nat} {checks : Thunk (List CheckSpec)} {cl : NumClass} {c c' : Counters} {r : Delivery σ} (hand : ∀ (y : Nat), y < n * rbaPack → surv[y]! = andWords (List.take sp1 specs) cw w0 y) (h : IsMasked n maskLow maskHigh surv v) (hout : ∀ (keep : Int → Bool), (∀ (y : Nat), y < n * rbaPack → ∀ (t : Nat), (andWords (List.drop sp1 specs) v[y]! w0 y).toBitVec.getLsbD t = (decide (t < 64) && keep (↑rbaLength * w0 + 64 * ↑y + ↑t))) → r.quit = false → c' = { words := c.words + n.toUInt64 * rbaPack.toUInt64, arrays := c.arrays, bits := c.bits, coprime := c.coprime, checks := c.checks, sifts := c.sifts } + { arrays := (List.countP (fun (p : Nat) => !isZeroAt v p) (List.range n)).toUInt64 } + testedCounts b checks (List.map cl.numerator (List.filter keep (List.map (fun (k : Nat) => ↑rbaLength * w0 + ↑k) (List.range (n * rbaLength)))))) {sfs : List (SieveSpec × (Int → Bool))} (hspecs : specs = List.map Prod.fst sfs) (hsfs : ∀ (sf : SieveSpec × (Int → Bool)), sf ∈ sfs → sf.fst.Reads sf.snd) (hq : r.quit = false) :
      c' = c + { words := (n * rbaPack).toUInt64 } + { arrays := (arraysWith (fun (j : Int) => (classBit cw j && (List.take sp1 sfs).all fun (x : SieveSpec × (Int → Bool)) => x.snd j) && decide (↑rbaLength * w0 + ↑maskLow ≤ j ∧ j + ↑maskHigh < ↑rbaLength * w0 + ↑(n * rbaLength))) w0 n).toUInt64 } + testedCounts b checks (List.map cl.numerator (List.filter (fun (j : Int) => classBit cw j && sfs.all fun (x : SieveSpec × (Int → Bool)) => x.snd j) (List.map (fun (k : Nat) => ↑rbaLength * w0 + ↑maskLow + ↑k) (List.range (n * rbaLength - maskLow - maskHigh)))))

      The counters of a piece of n bit arrays from the word number w0 on, given the contracts of its first stage with the first sp1 moduli of specs from the class word cw on the words surv (hand) and of the counters of its scan with the other moduli on the words v (hout, as Ratpoints.Sieve.scanPiece_counters_spec states it), when v is surv with the masks applied and the rows of the moduli read the tests sf.2 of the bits: the bit arrays that hold a bit that the masks leave and that passes the class word and the tests of the first stage, and the counts of the tests of a candidate of the numerators of the bits from rbaLength w0 + maskLow to rbaLength (w0 + n) - 1 - maskHigh that pass the class word and all the tests.

      theorem Ratpoints.Sieve.siftPiece_counters_spec {σ : Type} (process : Int → Int → Int → σ → Answer σ) (w : Thunk (List Int)) (d b : Nat) (fl : CheckFlags) (sp1 : Nat) (specs : List SieveSpec) (mgs : List Nat) (checks : Thunk (List CheckSpec)) (cl : NumClass) (w0 : Int) (n maskLow maskHigh : Nat) (r : Delivery σ) (cnt : Counters) :
      ⦃ maskHigh < rbaLength ∧ (∀ (s : SieveSpec), s ∈ specs → s.Fits) ∧ mgs = List.map (fun (x : SieveSpec) => magic x.p) specs ⦄ siftPiece process w d b fl sp1 specs mgs checks cl w0 n maskLow maskHigh r cnt ⦃ fun (r' : Delivery σ × Counters) => ∀ (sfs : List (SieveSpec × (Int → Bool))), specs = List.map Prod.fst sfs → (∀ (sf : SieveSpec × (Int → Bool)), sf ∈ sfs → sf.fst.Reads sf.snd) → r'.fst.quit = false → r'.snd = cnt + { words := (n * rbaPack).toUInt64 } + { arrays := (arraysWith (fun (j : Int) => (classBit cl.bits j && (List.take sp1 sfs).all fun (x : SieveSpec × (Int → Bool)) => x.snd j) && decide (↑rbaLength * w0 + ↑maskLow ≤ j ∧ j + ↑maskHigh < ↑rbaLength * w0 + ↑(n * rbaLength))) w0 n).toUInt64 } + testedCounts b checks (List.map cl.numerator (List.filter (fun (j : Int) => classBit cl.bits j && sfs.all fun (x : SieveSpec × (Int → Bool)) => x.snd j) (List.map (fun (k : Nat) => ↑rbaLength * w0 + ↑maskLow + ↑k) (List.range (n * rbaLength - maskLow - maskHigh))))) ⦄

      When the callback does not stop the search, one piece of n bit arrays adds to the counters its n Ratpoints.rbaPack words, in words, the number of its bit arrays that hold a bit that the masks leave and that passes the pattern of the class (Ratpoints.Sieve.classBit) and the tests of the rows of the first stage, the first sp1 moduli of specs, in arrays, and the counts of the tests of a candidate (Ratpoints.Sieve.testedCounts) of the numerators of the bits that the masks leave and that pass the pattern of the class and the tests of the rows of all the moduli; the tests sf.2 that the rows read (Ratpoints.Sieve.SieveSpec.Reads) are quantified in the postcondition.

      The bits of one interval #

      @[reducible, inline]
      abbrev Ratpoints.Sieve.lowMask (low w0 : Int) :

      The low mask of Ratpoints.Sieve.siftBits on the piece from the word number w0 on: the number of the bits of the first piece below low, 0 on the others.

      Equations
      Instances For
        theorem Ratpoints.Sieve.lowMask_eq {low w0 : Int} (hw0 : low / ↑rbaLength ≤ w0) :
        lowMask low w0 = (low - ↑rbaLength * w0).toNat

        The low mask on a piece from the word number w0 on: the number of its bits below low.

        @[reducible, inline]
        abbrev Ratpoints.Sieve.highMask (high w1 : Int) :

        The high mask of Ratpoints.Sieve.siftBits on the piece that ends at the word number w1: the number of the bits of the last piece above high, 0 on the others.

        Equations
        Instances For
          theorem Ratpoints.Sieve.highMask_eq {high w1 : Int} (hw1 : w1 ≤ high / ↑rbaLength + 1) :
          highMask high w1 = (↑rbaLength * w1 - 1 - high).toNat

          The high mask on a piece that ends at the word number w1: the number of its bits above high.

          @[reducible, inline]
          abbrev Ratpoints.Sieve.bitsBefore (low high w0 : Int) :

          The bits from that of low up to the word number w0 that lie in low, …, high: those of the pieces of Ratpoints.Sieve.siftBits before w0.

          Equations
          • One or more equations did not get rendered due to their size.
          Instances For
            @[reducible, inline]
            abbrev Ratpoints.Sieve.pieceBits (w0 : Int) (n maskLow maskHigh : Nat) :

            The bits of a piece of n bit arrays from the word number w0 on that the masks maskLow and maskHigh at its two ends leave.

            Equations
            Instances For
              theorem Ratpoints.Sieve.flatMap_filter_range_append {β : Type} {g : Int → List β} {keep : Int → Bool} {low high : Int} {r mH : Nat} {w0 w1' : Int} (hle : low / ↑rbaLength ≤ w0) (hr : w1' = w0 + ↑r) (hmH : mH = (↑rbaLength * w1' - 1 - high).toNat) :
              List.flatMap g (List.filter keep (bitsBefore low high w0)) ++ List.flatMap g (List.filter keep (pieceBits w0 r (lowMask low w0) mH)) = List.flatMap g (List.filter keep (bitsBefore low high w1'))

              The bits up to the word number w0 and those of the next piece of r bit arrays, with the low mask of Ratpoints.Sieve.siftBits and a high mask mH, the number of its bits above high, that pass keep, with their points g: those up to the word number w1' = w0 + r.

              theorem Ratpoints.Sieve.flatMap_filter_range_prefix {β : Type} (g : Int → List β) (keep : Int → Bool) (low high : Int) {w0 w0' : Int} (h : w0 ≤ w0') :
              List.flatMap g (List.filter keep (bitsBefore low high w0)) <+: List.flatMap g (List.filter keep (bitsBefore low high w0'))

              The bits up to the word number w0 come first among those up to w0' ≥ w0.

              theorem Ratpoints.Sieve.flatMap_filter_range_eq {β : Type} (g : Int → List β) (keep : Int → Bool) {low high : Int} (hlh : low / ↑rbaLength ≤ high / ↑rbaLength + 1) :
              List.flatMap g (List.filter keep (bitsBefore low high (high / ↑rbaLength + 1))) = List.flatMap g (List.filter keep (List.map (fun (k : Nat) => low + ↑k) (List.range (high + 1 - low).toNat)))

              The bits from that of low up to the word number one past that of high that lie in low, …, high are the bits low, …, high.

              theorem Ratpoints.Sieve.arraysWith_masked_eq {low high w0 w1' : Int} {rr mH : Nat} (hle : low / ↑rbaLength ≤ w0) (hr : w1' = w0 + ↑rr) (hmH : mH = (↑rbaLength * w1' - 1 - high).toNat) (keep : Int → Bool) :
              arraysWith (fun (j : Int) => keep j && decide (↑rbaLength * w0 + ↑(lowMask low w0) ≤ j ∧ j + ↑mH < ↑rbaLength * w0 + ↑(rr * rbaLength))) w0 rr = arraysWith (fun (j : Int) => keep j && decide (low ≤ j ∧ j ≤ high)) w0 rr

              On the words of a piece from the word number w0 ≥ ⌊low / rbaLength⌋ on that ends at w1' = w0 + rr, with the low mask of Ratpoints.Sieve.siftBits and a high mask mH, the number of its bits above high, the masks leave the bits in low, …, high.

              def Ratpoints.Sieve.bitsCounts (b : Nat) (checks : Thunk (List CheckSpec)) (cl : NumClass) (keep1 keep : Int → Bool) (low high : Int) :

              The counts that the bits low, …, high of the class cl of the denominator b add to the counters when they go through the sieve in pieces (Ratpoints.Sieve.siftBits), for the tests keep1 and keep of the bits that the rows of the first stage and of the first two stages read, with the thunk checks of the third stage: none if high < low, and otherwise the Ratpoints.rbaPack words of each of the bit arrays from that of low to that of high, in words, the number of these bit arrays that hold one of the bits that passes the pattern of the class (Ratpoints.Sieve.classBit) and keep1, in arrays, and the counts of the tests of a candidate (Ratpoints.Sieve.testedCounts) of the numerators of the bits that pass the pattern of the class and keep, each as a UInt64, wrapping.

              Equations
              • One or more equations did not get rendered due to their size.
              Instances For
                def Ratpoints.Sieve.PieceResult {σ : Type} (process : Int → Int → Int → σ → Answer σ) (g : Int → List (Int × Int × Int)) (b : Nat) (checks : Thunk (List CheckSpec)) (cl : NumClass) (keep1 keep : Int → Bool) (w0 : Int) (n mL mH : Nat) (r r' : Delivery σ) (c c' : Counters) :

                What a piece of n bit arrays from the word number w0 on with the masks mL and mH at its two ends returns in the loop of Ratpoints.Sieve.siftBits over the pieces of the class cl, from the delivery r and the counters c, for the tests keep1 and keep of the bits that the rows of the first stage and of the first two stages read and the points g of the bits: the delivery r' of the points of its bits that the masks leave and that pass the pattern of the class and keep, and, when the callback does not stop the search in it, the counters c' with its words, the number of its bit arrays that hold a bit that the masks leave and that passes the pattern of the class and keep1, and the counts of the tests of a candidate, with the thunk checks of the third stage over the denominator b, of the numerators whose points it delivers.

                Equations
                • One or more equations did not get rendered due to their size.
                Instances For
                  structure Ratpoints.Sieve.SiftBitsInvariant {σ : Type} (process : Int → Int → Int → σ → Answer σ) (g : Int → List (Int × Int × Int)) (b : Nat) (checks : Thunk (List CheckSpec)) (cl : NumClass) (keep1 keep : Int → Bool) (low high : Int) (r0 : Delivery σ) (cnt0 : Counters) (exit : Bool) (range : Nat) (w0 w1 : Int) (r : Delivery σ) (c : Counters) :

                  The invariant of the loop of Ratpoints.Sieve.siftBits over the pieces, for the bits from low to high of the packing of the class cl, the tests keep1 and keep of the bits that the rows of the first stage and of the first two stages read and the points g of the bits, from the delivery r0 and the counters cnt0, at the exit of the loop or not: the bit arrays from that of low up to the word number w0 are done, the callback has not stopped the search, the delivery is that of the points of their bits in low, …, high that pass the pattern of the class and keep, and the counters are cnt0 plus their words, the number of them that hold a bit in low, …, high that passes the pattern of the class and keep1, and the counts of the tests of a candidate, with the thunk checks of the third stage over the denominator b, of the numerators whose points are delivered.

                  Instances For
                    def Ratpoints.Sieve.SiftBitsWhileInvariant {σ : Type} (process : Int → Int → Int → σ → Answer σ) (g : Int → List (Int × Int × Int)) (b : Nat) (checks : Thunk (List CheckSpec)) (cl : NumClass) (keep1 keep : Int → Bool) (low high : Int) (r0 : Delivery σ) (cnt0 : Counters) :

                    Ratpoints.Sieve.SiftBitsInvariant as the invariant of the while loop of Ratpoints.Sieve.siftBits, with the value of a return at a stop: the delivery of the points of all the bits low, …, high that pass the pattern of the class and keep, whose flag of the stop is set.

                    Equations
                    • One or more equations did not get rendered due to their size.
                    Instances For
                      theorem Ratpoints.Sieve.siftBitsInvariant_init {σ : Type} {process : Int → Int → Int → σ → Answer σ} {g : Int → List (Int × Int × Int)} {b : Nat} {checks : Thunk (List CheckSpec)} {cl : NumClass} {keep1 keep : Int → Bool} {low high : Int} {r0 : Delivery σ} {cnt0 : Counters} (h : low ≤ high) {A : Nat} (hA : 1 ≤ A) (hr : r0.quit = false) :
                      SiftBitsInvariant process g b checks cl keep1 keep low high r0 cnt0 false A (low / ↑rbaLength) (low / ↑rbaLength + ↑A) r0 cnt0
                      theorem Ratpoints.Sieve.SiftBitsInvariant.append {σ : Type} {process : Int → Int → Int → σ → Answer σ} {g : Int → List (Int × Int × Int)} {b : Nat} {checks : Thunk (List CheckSpec)} {cl : NumClass} {keep1 keep : Int → Bool} {low high : Int} {r0 r r' : Delivery σ} {cnt0 c c' : Counters} {range rr mH : Nat} {w0 w1 w1' : Int} (h : SiftBitsInvariant process g b checks cl keep1 keep low high r0 cnt0 false range w0 w1 r c) (hr : w1' = w0 + ↑rr) (hr1 : 1 ≤ rr) (hw1' : w1' ≤ high / ↑rbaLength + 1) (hmH : mH = (↑rbaLength * w1' - 1 - high).toNat) (hp : PieceResult process g b checks cl keep1 keep w0 rr (lowMask low w0) mH r r' c c') (hq : ¬r'.quit = true) :
                      SiftBitsInvariant process g b checks cl keep1 keep low high r0 cnt0 false rr w1' (w1' + ↑rr) r' c'

                      A piece of rr ≥ 1 bit arrays from the word number w0 on, which ends at w1' ≤ high / rbaLength + 1, with the low mask of Ratpoints.Sieve.siftBits and a high mask mH, the number of its bits above high, when the callback does not stop the search in it.

                      theorem Ratpoints.Sieve.SiftBitsInvariant.eq_deliver_of_quit {σ : Type} {process : Int → Int → Int → σ → Answer σ} {g : Int → List (Int × Int × Int)} {b : Nat} {checks : Thunk (List CheckSpec)} {cl : NumClass} {keep1 keep : Int → Bool} {low high : Int} {r0 r r' : Delivery σ} {cnt0 c c' : Counters} {range rr mH : Nat} {w0 w1 w1' : Int} (h : SiftBitsInvariant process g b checks cl keep1 keep low high r0 cnt0 false range w0 w1 r c) (hr : w1' = w0 + ↑rr) (hw1' : w1' ≤ high / ↑rbaLength + 1) (hmH : mH = (↑rbaLength * w1' - 1 - high).toNat) (hp : PieceResult process g b checks cl keep1 keep w0 rr (lowMask low w0) mH r r' c c') (hq : r'.quit = true) :
                      r' = Delivery.deliver process r0 (List.flatMap g (List.filter (fun (j : Int) => classBit cl.bits j && keep j) (List.map (fun (k : Nat) => low + ↑k) (List.range (high + 1 - low).toNat))))

                      A piece that ends at w1' ≤ high / rbaLength + 1, when the callback stops the search in it: the delivery is that of all the bits low, …, high that pass the pattern of the class and keep.

                      theorem Ratpoints.Sieve.SiftBitsInvariant.toNat_sub_lt {σ : Type} {process : Int → Int → Int → σ → Answer σ} {g : Int → List (Int × Int × Int)} {b : Nat} {checks : Thunk (List CheckSpec)} {cl : NumClass} {keep1 keep : Int → Bool} {low high : Int} {r0 r : Delivery σ} {cnt0 c : Counters} {range : Nat} {w0 w1 : Int} (h : SiftBitsInvariant process g b checks cl keep1 keep low high r0 cnt0 false range w0 w1 r c) (hw0 : w0 < high / ↑rbaLength + 1) :
                      (high / ↑rbaLength + 1 - w1).toNat < (high / ↑rbaLength + 1 - w0).toNat

                      The pieces advance: the measure high / rbaLength + 1 - w0 of the loop of Ratpoints.Sieve.siftBits decreases from one piece to the next.

                      theorem Ratpoints.Sieve.SiftBitsInvariant.exit_of_not_lt {σ : Type} {process : Int → Int → Int → σ → Answer σ} {g : Int → List (Int × Int × Int)} {b : Nat} {checks : Thunk (List CheckSpec)} {cl : NumClass} {keep1 keep : Int → Bool} {low high : Int} {r0 r : Delivery σ} {cnt0 c : Counters} {range : Nat} {w0 w1 : Int} (h : SiftBitsInvariant process g b checks cl keep1 keep low high r0 cnt0 false range w0 w1 r c) (hw0 : ¬w0 < high / ↑rbaLength + 1) :
                      SiftBitsInvariant process g b checks cl keep1 keep low high r0 cnt0 true range w0 w1 r c

                      The loop of Ratpoints.Sieve.siftBits ends at the word number one past that of high.

                      theorem Ratpoints.Sieve.SiftBitsInvariant.append_of_not_lt {σ : Type} {process : Int → Int → Int → σ → Answer σ} {g : Int → List (Int × Int × Int)} {b : Nat} {checks : Thunk (List CheckSpec)} {cl : NumClass} {keep1 keep : Int → Bool} {low high : Int} {r0 r r' : Delivery σ} {cnt0 c c' : Counters} {range mb : Nat} {w0 w1 : Int} {o : Option (Delivery σ × Counters)} (hm : (high / ↑rbaLength + 1 - w0).toNat = mb ∧ o = none ∧ SiftBitsInvariant process g b checks cl keep1 keep low high r0 cnt0 false range w0 w1 r c) (hlt : w0 < high / ↑rbaLength + 1) (hw : ¬high / ↑rbaLength + 1 < w1) (hp : PieceResult process g b checks cl keep1 keep w0 range (lowMask low w0) (highMask high w1) r r' c c') (hq : ¬r'.quit = true) :
                      (high / ↑rbaLength + 1 - w1).toNat < mb ∧ SiftBitsInvariant process g b checks cl keep1 keep low high r0 cnt0 false range w1 (w1 + ↑range) r' c'

                      A middle piece, which ends at the word number w1 ≤ high / rbaLength + 1, when the callback does not stop the search in it, in the shape of the verification condition.

                      theorem Ratpoints.Sieve.SiftBitsInvariant.append_of_lt {σ : Type} {process : Int → Int → Int → σ → Answer σ} {g : Int → List (Int × Int × Int)} {b : Nat} {checks : Thunk (List CheckSpec)} {cl : NumClass} {keep1 keep : Int → Bool} {low high : Int} {r0 r r' : Delivery σ} {cnt0 c c' : Counters} {range mb : Nat} {w0 w1 : Int} {o : Option (Delivery σ × Counters)} (hm : (high / ↑rbaLength + 1 - w0).toNat = mb ∧ o = none ∧ SiftBitsInvariant process g b checks cl keep1 keep low high r0 cnt0 false range w0 w1 r c) (hlt : w0 < high / ↑rbaLength + 1) (hp : PieceResult process g b checks cl keep1 keep w0 (high / ↑rbaLength + 1 - w0).toNat (lowMask low w0) (rbaLength - 1 - (high % ↑rbaLength).toNat) r r' c c') (hq : ¬r'.quit = true) :
                      (high / ↑rbaLength + 1 - (high / ↑rbaLength + 1)).toNat < mb ∧ SiftBitsInvariant process g b checks cl keep1 keep low high r0 cnt0 false (high / ↑rbaLength + 1 - w0).toNat (high / ↑rbaLength + 1) (high / ↑rbaLength + 1 + ↑(high / ↑rbaLength + 1 - w0).toNat) r' c'

                      The last piece, which ends at the word number high / rbaLength + 1, when the callback does not stop the search in it, in the shape of the verification condition.

                      theorem Ratpoints.Sieve.SiftBitsInvariant.eq_deliver_of_quit_of_not_lt {σ : Type} {process : Int → Int → Int → σ → Answer σ} {g : Int → List (Int × Int × Int)} {b : Nat} {checks : Thunk (List CheckSpec)} {cl : NumClass} {keep1 keep : Int → Bool} {low high : Int} {r0 r r' : Delivery σ} {cnt0 c c' : Counters} {range mb : Nat} {w0 w1 : Int} {o : Option (Delivery σ × Counters)} (hm : (high / ↑rbaLength + 1 - w0).toNat = mb ∧ o = none ∧ SiftBitsInvariant process g b checks cl keep1 keep low high r0 cnt0 false range w0 w1 r c) (hw : ¬high / ↑rbaLength + 1 < w1) (hp : PieceResult process g b checks cl keep1 keep w0 range (lowMask low w0) (highMask high w1) r r' c c') (hq : r'.quit = true) :
                      r' = Delivery.deliver process r0 (List.flatMap g (List.filter (fun (j : Int) => classBit cl.bits j && keep j) (List.map (fun (k : Nat) => low + ↑k) (List.range (high + 1 - low).toNat)))) ∧ r'.quit = true

                      A middle piece, when the callback stops the search in it, in the shape of the verification condition: the delivery is that of all the bits low, …, high that pass the pattern of the class and keep.

                      theorem Ratpoints.Sieve.SiftBitsInvariant.eq_deliver_of_quit_of_lt {σ : Type} {process : Int → Int → Int → σ → Answer σ} {g : Int → List (Int × Int × Int)} {b : Nat} {checks : Thunk (List CheckSpec)} {cl : NumClass} {keep1 keep : Int → Bool} {low high : Int} {r0 r r' : Delivery σ} {cnt0 c c' : Counters} {range mb : Nat} {w0 w1 : Int} {o : Option (Delivery σ × Counters)} (hm : (high / ↑rbaLength + 1 - w0).toNat = mb ∧ o = none ∧ SiftBitsInvariant process g b checks cl keep1 keep low high r0 cnt0 false range w0 w1 r c) (hlt : w0 < high / ↑rbaLength + 1) (hp : PieceResult process g b checks cl keep1 keep w0 (high / ↑rbaLength + 1 - w0).toNat (lowMask low w0) (rbaLength - 1 - (high % ↑rbaLength).toNat) r r' c c') (hq : r'.quit = true) :
                      r' = Delivery.deliver process r0 (List.flatMap g (List.filter (fun (j : Int) => classBit cl.bits j && keep j) (List.map (fun (k : Nat) => low + ↑k) (List.range (high + 1 - low).toNat)))) ∧ r'.quit = true

                      The last piece, when the callback stops the search in it, in the shape of the verification condition: the delivery is that of all the bits low, …, high that pass the pattern of the class and keep.

                      theorem Ratpoints.Sieve.SiftBitsInvariant.quit_eq_false_and {σ : Type} {process : Int → Int → Int → σ → Answer σ} {g : Int → List (Int × Int × Int)} {b : Nat} {checks : Thunk (List CheckSpec)} {cl : NumClass} {keep1 keep : Int → Bool} {low high : Int} {r0 r : Delivery σ} {cnt0 c : Counters} {range mb mH : Nat} {w0 w1 : Int} {o : Option (Delivery σ × Counters)} {P : Prop} (hm : (high / ↑rbaLength + 1 - w0).toNat = mb ∧ o = none ∧ SiftBitsInvariant process g b checks cl keep1 keep low high r0 cnt0 false range w0 w1 r c) (hP : P) (hmH : mH < rbaLength) :

                      What the piece of the verification condition needs of the invariant: the callback has not stopped the search.

                      theorem Ratpoints.Sieve.SiftBitsInvariant.post {σ : Type} {process : Int → Int → Int → σ → Answer σ} {g : Int → List (Int × Int × Int)} {b : Nat} {checks : Thunk (List CheckSpec)} {cl : NumClass} {keep1 keep : Int → Bool} {low high : Int} {r0 r : Delivery σ} {cnt0 c : Counters} {range : Nat} {w0 w1 : Int} (hlh : low ≤ high) (h : SiftBitsInvariant process g b checks cl keep1 keep low high r0 cnt0 true range w0 w1 r c) :
                      r = Delivery.deliver process r0 (List.flatMap g (List.filter (fun (j : Int) => classBit cl.bits j && keep j) (List.map (fun (k : Nat) => low + ↑k) (List.range (high + 1 - low).toNat)))) ∧ (r.quit = false → c = cnt0 + bitsCounts b checks cl keep1 keep low high)

                      At the exit of the loop of Ratpoints.Sieve.siftBits, the delivery is that of the points of the bits low, …, high that pass the pattern of the class and keep, and the counters are those of Ratpoints.Sieve.bitsCounts.

                      theorem Ratpoints.Sieve.eq_deliver_and_of_not_le {σ : Type} {process : Int → Int → Int → σ → Answer σ} {g : Int → List (Int × Int × Int)} {b : Nat} {checks : Thunk (List CheckSpec)} {cl : NumClass} {keep1 keep : Int → Bool} {low high : Int} (h : ¬low ≤ high) (r : Delivery σ) (c : Counters) :
                      r = Delivery.deliver process r (List.flatMap g (List.filter (fun (j : Int) => classBit cl.bits j && keep j) (List.map (fun (k : Nat) => low + ↑k) (List.range (high + 1 - low).toNat)))) ∧ (r.quit = false → c = c + bitsCounts b checks cl keep1 keep low high)

                      An empty interval of bits delivers nothing and counts nothing.

                      theorem Ratpoints.Sieve.siftBits_spec {σ : Type} (process : Int → Int → Int → σ → Answer σ) (w : Thunk (List Int)) (d b A : Nat) (fl : CheckFlags) (sp1 : Nat) (specs : List SieveSpec) (mgs : List Nat) (checks : Thunk (List CheckSpec)) (cl : NumClass) (low high : Int) (r : Delivery σ) (cnt : Counters) :
                      ⦃ r.quit = false ∧ 1 ≤ A ∧ (∀ (s : SieveSpec), s ∈ specs → s.Fits) ∧ mgs = List.map (fun (x : SieveSpec) => magic x.p) specs ⦄ siftBits process w d b A fl sp1 specs mgs checks cl low high r cnt ⦃ fun (r' : Delivery σ × Counters) => ∀ (sfs : List (SieveSpec × (Int → Bool))), specs = List.map Prod.fst sfs → (∀ (sf : SieveSpec × (Int → Bool)), sf ∈ sfs → sf.fst.Reads sf.snd) → r'.fst = Delivery.deliver process r (List.flatMap (fun (j : Int) => acceptedPoints w d b fl checks (cl.numerator j)) (List.filter (fun (j : Int) => classBit cl.bits j && sfs.all fun (x : SieveSpec × (Int → Bool)) => x.snd j) (List.map (fun (k : Nat) => low + ↑k) (List.range (high + 1 - low).toNat)))) ∧ (r'.fst.quit = false → r'.snd = cnt + bitsCounts b checks cl (fun (j : Int) => (List.take sp1 sfs).all fun (x : SieveSpec × (Int → Bool)) => x.snd j) (fun (j : Int) => sfs.all fun (x : SieveSpec × (Int → Bool)) => x.snd j) low high) ⦄

                      The bits from low to high in pieces of A ≥ 1 bit arrays, with the moduli specs and their reciprocals, deliver the points of the numerators of the bits that pass the class word of cl and the tests sf.2 that the rows of the moduli read (Ratpoints.Sieve.SieveSpec.Reads), quantified in the postcondition since the program does not mention them, and, when the callback does not stop the search, add to the counters the counts of Ratpoints.Sieve.bitsCounts, with the tests of the first sp1 moduli for the first stage; an empty interval delivers and counts nothing; the loop over the pieces ends by the measure high / rbaLength + 1 - w0, since every piece has at least one bit array, or at a stop.