Documentation

Ratpoints.Proof.CompositeRows

The contracts of the builders of the rows of a prime power and of a product #

The contracts of lay_out_pattern (Ratpoints.Sieve.repeatPattern, Ratpoints.Sieve.layOutPattern), of the builder of the rows of a prime power (Ratpoints.Sieve.sieveInitPower, with the patterns Ratpoints.Sieve.powerPatternUnit and Ratpoints.Sieve.powerPatternNonunit), and of the blocks of the builder of the rows of a product (Ratpoints.Sieve.productCopy, Ratpoints.Sieve.productAnd), as @[spec] theorems proved with vcgen, the program logic of Lean core, with loop invariants that are named definitions: the row of the residue b < m of a prime power m is the closed form of the row of b of its tables (Ratpoints.Sieve.closedRow of Ratpoints.Sieve.Power.admits), stored into the table of rows of its entry, and the blocks of the rows of the factors of a product, and-ed, are the and of the rows of the factors.

Main definitions #

Main statements #

Implementation notes #

The file uses Lean core and Std only, as the contracts of the sieve do. The proofs use only that Ratpoints.rbaPack and Ratpoints.chunk are positive, never their values. The bits of the words of a pattern (Ratpoints.Sieve.bitAt_eq_getLsbD) are in Ratpoints.Proof.Rows, the contracts of the builders of the rows of a prime in Ratpoints.Proof.PrimeRows, and those of the builders through the tables of rows in Ratpoints.Proof.RowStore, and the row of a sieve entry as the and of the rows of its factors in Ratpoints.Proof.Words (Ratpoints.Sieve.SieveEntry.admits_eq_all), with the rows of a factor read at residues modulo its modulus (Ratpoints.Sieve.Factor.admits_congr).

The pattern repeated through words #

The words pat hold a pattern of period m: their bits from m to 64 ⌈m / 64⌉ are clear.

Equations
Instances For
    def Ratpoints.Sieve.IsPattern (g : Nat → Bool) (m : Nat) (pat : Array UInt64) :

    The pattern of period m in the words pat: bit j of word i < ⌈m / 64⌉ the bit of the pattern at 64 i + j below m, clear from m on.

    Equations
    Instances For
      theorem Ratpoints.Sieve.isPattern_bitAt {m : Nat} {pat : Array UInt64} (h : PatClear m pat) :
      IsPattern (bitAt pat) m pat
      def Ratpoints.Sieve.RepeatedBits (g : Nat → Bool) (m W L : Nat) {n : Nat} (rep : Vector UInt64 n) :

      The words rep below W hold the bits of the pattern of period m below the bound L, and 0 from L on.

      Equations
      Instances For
        theorem Ratpoints.Sieve.RepeatedBits.mono {g : Nat → Bool} {m W L L' n : Nat} {rep : Vector UInt64 n} (h : RepeatedBits g m W L rep) (hL : min L (64 * W) = min L' (64 * W)) :
        RepeatedBits g m W L' rep
        theorem Ratpoints.Sieve.RepeatedBits.first {g : Nat → Bool} {m W n o i : Nat} {rep : Vector UInt64 n} {pat : Array UInt64} (hpat : IsPattern g m pat) (hmo : m ∣ o) (hi : i < (m + 64 - 1) / 64) (hWn : W ≤ n) (h : RepeatedBits g m W (o + min m (64 * i)) rep) :
        RepeatedBits g m W (min (64 * (o / 64 + i + 1)) (o + m)) (rep.set! (o / 64 + i) (rep[o / 64 + i]! ||| pat[i]! <<< UInt64.ofNat (o % 64)))

        The first or of word i of the copy of the pattern at the offset o = 64 q + s, a multiple of m: word q + i gets the word shifted left by s.

        theorem Ratpoints.Sieve.RepeatedBits.second {g : Nat → Bool} {m W n o i : Nat} {rep : Vector UInt64 n} {pat : Array UInt64} (hpat : IsPattern g m pat) (hmo : m ∣ o) (hi : i < (m + 64 - 1) / 64) (hs0 : o % 64 ≠ 0) (hWn : W ≤ n) (h : RepeatedBits g m W (min (64 * (o / 64 + i + 1)) (o + m)) rep) :
        RepeatedBits g m W (o + min m (64 * (i + 1))) (rep.set! (o / 64 + i + 1) (rep[o / 64 + i + 1]! ||| pat[i]! >>> UInt64.ofNat (64 - o % 64)))

        The second or of word i of the copy at the offset o = 64 q + s, s ≠ 0: word q + i + 1 gets the word shifted right by 64 - s.

        The invariant of the loop of Ratpoints.Sieve.repeatPattern over the copies of the pattern: the offset o is a multiple of m, the words of rep hold the bits below it, and at the exit o has reached 64 W.

        Equations
        • One or more equations did not get rendered due to their size.
        Instances For

          The invariant of the loop over the words i of the copy at the offset o: the words of rep hold the bits below o + 64 i (and below o + m), and at the exit the copy is done or cut at the end of the words.

          Equations
          • One or more equations did not get rendered due to their size.
          Instances For
            theorem Ratpoints.Sieve.RepeatedBits.set!_zero {g : Nat → Bool} {m n cur : Nat} {pref suff : List Nat} {W : Nat} {rep : Vector UInt64 n} (hl : ForIn.toList [:W] = pref ++ cur :: suff) (h : RepeatedBits g m pref.length 0 rep) :
            RepeatedBits g m (pref ++ [cur]).length 0 (rep.set! cur 0)

            A word cleared, by the loop that clears the first words of rep.

            theorem Ratpoints.Sieve.repeatedBits_nil (g : Nat → Bool) (m : Nat) {n : Nat} (rep : Vector UInt64 n) :
            theorem Ratpoints.Sieve.layOuterInvariant_init {g : Nat → Bool} {m W n : Nat} {rep : Vector UInt64 n} (h : RepeatedBits g m (ForIn.toList [:W]).length 0 rep) :
            theorem Ratpoints.Sieve.LayOuterInvariant.inner {g : Nat → Bool} {m W o n mb : Nat} {rep : Vector UInt64 n} (h : W * 64 - o = mb ∧ LayOuterInvariant g m W false (rep, o)) :
            theorem Ratpoints.Sieve.LayInnerInvariant.or_shift {m W o n i mb mb' : Nat} {pat : Array UInt64} {rep rep0 : Vector UInt64 n} (pre : 0 < m ∧ W ≤ n ∧ PatClear m pat) (hout : W * 64 - o = mb' ∧ LayOuterInvariant (bitAt pat) m W false (rep0, o)) (h : (m + 64 - 1) / 64 - i = mb ∧ LayInnerInvariant (bitAt pat) m W o false (rep, i)) (hc : i < (m + 64 - 1) / 64 ∧ o / 64 + i < W) :
            (m + 64 - 1) / 64 - (i + 1) < mb ∧ LayInnerInvariant (bitAt pat) m W o false (if ¬o % 64 = 0 ∧ o / 64 + i + 1 < W then (rep.set! (o / 64 + i) (rep[o / 64 + i]! ||| pat[i]! <<< UInt64.ofNat (o % 64))).set! (o / 64 + i + 1) ((rep.set! (o / 64 + i) (rep[o / 64 + i]! ||| pat[i]! <<< UInt64.ofNat (o % 64)))[o / 64 + i + 1]! ||| pat[i]! >>> UInt64.ofNat (64 - o % 64)) else rep.set! (o / 64 + i) (rep[o / 64 + i]! ||| pat[i]! <<< UInt64.ofNat (o % 64)), i + 1)

            A step of the loop over the words of a copy: the first or, and the second for s ≠ 0 when it lies below W.

            theorem Ratpoints.Sieve.LayInnerInvariant.exit {g : Nat → Bool} {m W o n i mb : Nat} {rep : Vector UInt64 n} (h : (m + 64 - 1) / 64 - i = mb ∧ LayInnerInvariant g m W o false (rep, i)) (hc : ¬(i < (m + 64 - 1) / 64 ∧ o / 64 + i < W)) :
            theorem Ratpoints.Sieve.LayOuterInvariant.add {g : Nat → Bool} {m W o n mb : Nat} {rep rep' : Vector UInt64 n} {i : Nat} (hm : 0 < m) (h : W * 64 - o = mb ∧ LayOuterInvariant g m W false (rep, o)) (ho : o < W * 64) (h' : LayInnerInvariant g m W o true (rep', i)) :
            W * 64 - (o + m) < mb ∧ LayOuterInvariant g m W false (rep', o + m)

            The copy at o done: the bits below o + m are in the words, the offset moves on by m.

            theorem Ratpoints.Sieve.LayOuterInvariant.exit {g : Nat → Bool} {m W o n mb : Nat} {rep : Vector UInt64 n} (h : W * 64 - o = mb ∧ LayOuterInvariant g m W false (rep, o)) (ho : ¬o < W * 64) :
            theorem Ratpoints.Sieve.LayOuterInvariant.full {g : Nat → Bool} {m W n o : Nat} {rep : Vector UInt64 n} (h : LayOuterInvariant g m W true (rep, o)) :
            RepeatedBits g m W (64 * W) rep
            theorem Ratpoints.Sieve.repeatPattern_spec (pat : Array UInt64) (m words : Nat) (rep : Vector UInt64 (modWords + 2)) :
            ⦃ 0 < m ∧ words ≤ modWords + 2 ∧ PatClear m pat ⦄ repeatPattern pat m words rep ⦃ fun (rep' : Vector UInt64 (modWords + 2)) => RepeatedBits (bitAt pat) m words (64 * words) rep' ⦄

            The words of rep below words ≤ modWords + 2 hold the pattern of period m > 0 of the words pat repeated from 0 on (Ratpoints.Sieve.RepeatedBits), for a pattern without bits from m on.

            The pattern laid out as a row #

            theorem Ratpoints.Sieve.getLsbD_window (E : Array UInt64) (s t : Nat) :
            (window E s).toBitVec.getLsbD t = (decide (t < 64) && E[(s + t) / 64]!.toBitVec.getLsbD ((s + t) % 64))
            theorem Ratpoints.Sieve.PatternBits.window_rep {g : Nat → Bool} {m W n o x : Nat} {rep : Vector UInt64 n} (hfull : RepeatedBits g m W (64 * W) rep) (hW : m + 64 ≤ 64 * W) (ho : o < m) (hox : o = 64 * x % m) :
            PatternBits g m (64 * x) 64 (window rep.toArray o)

            The window of the repeated pattern at the offset o ≡ 64 x (mod m), o < m, is the window of the pattern at 64 x.

            def Ratpoints.Sieve.RowLoopInvariant (g : Nat → Bool) (m x : Nat) {n : Nat} (st : Vector UInt64 n × Nat) :

            The invariant of the loop of the words of the row of Ratpoints.Sieve.layOutPattern, after the words below x: those words the windows of the pattern, and the offset o ≡ 64 x (mod m).

            Equations
            Instances For
              theorem Ratpoints.Sieve.RowLoopInvariant.set!_window {m cur o : Nat} {pref suff : List Nat} {pat : Array UInt64} {rep : Vector UInt64 (modWords + 2)} {si : Vector UInt64 ((m + chunk - 1) * rbaPack)} (pre : 0 < m ∧ m ≤ 64 * modWords ∧ PatClear m pat) (hfull : RepeatedBits (bitAt pat) m ((m + 64 + 64 - 1) / 64) (64 * ((m + 64 + 64 - 1) / 64)) rep) (hl : ForIn.toList [:m * rbaPack] = pref ++ cur :: suff) (h : RowLoopInvariant (bitAt pat) m pref.length (si, o)) :
              RowLoopInvariant (bitAt pat) m (pref ++ [cur]).length (si.set! cur (window rep.toArray o), if m ≤ o + 64 % m then o + 64 % m - m else o + 64 % m)

              A step of the loop of the words of the row: word cur the window at the offset, which steps on by 64 mod m modulo m.

              theorem Ratpoints.Sieve.RowWords.set!_copy {g : Nat → Bool} {m cur : Nat} {pref suff : List Nat} {si : Vector UInt64 ((m + chunk - 1) * rbaPack)} (hm : 0 < m) (hl : ForIn.toList [:(chunk - 1) * rbaPack] = pref ++ cur :: suff) (h : RowWords g m (m * rbaPack + pref.length) si) :
              RowWords g m (m * rbaPack + (pref ++ [cur]).length) (si.set! (m * rbaPack + cur) si[cur]!)

              A copy of word k to word m rbaPack + k, the window there being that at 64 k, since m ∣ 64 m rbaPack.

              theorem Ratpoints.Sieve.RowWords.post_copy {g : Nat → Bool} {m n : Nat} {si : Vector UInt64 n} (h : RowWords g m (m * rbaPack + (ForIn.toList [:(chunk - 1) * rbaPack]).length) si) :
              RowWords g m ((m + chunk - 1) * rbaPack) si
              theorem Ratpoints.Sieve.layOutPattern_spec (pat : Array UInt64) (m : Nat) :
              ⦃ 0 < m ∧ m ≤ 64 * modWords ∧ PatClear m pat ⦄ layOutPattern pat m ⦃ fun (si : Vector UInt64 ((m + chunk - 1) * rbaPack)) => RowWords (bitAt pat) m ((m + chunk - 1) * rbaPack) si ⦄

              The row of the pattern of period 0 < m ≤ 64 Ratpoints.modWords in the words pat, without bits from m on, as lay_out_pattern lays it out: m + chunk - 1 bit arrays, word j the window of the pattern at 64 j.

              The rows of a prime power #

              The words of a cleared pattern: Ratpoints.modWords words, every bit clear.

              Equations
              Instances For

                The invariant of the loop of Ratpoints.Sieve.powerPatternUnit after the residues below x: the residue r = x b⁻¹ mod m and the bits below x set where Ratpoints.Sieve.Power.fsq has the bit of y b⁻¹.

                Equations
                • One or more equations did not get rendered due to their size.
                Instances For
                  theorem Ratpoints.Sieve.bitAt_ite_setBitAt {pw : Power} {binv cur r : Nat} {pat : Array UInt64} (hr : r = cur * binv % pw.m) (hs : cur / 64 < pat.size) (hp : ∀ (y : Nat), bitAt pat y = (decide (y < cur) && bitAt pw.fsq (y * binv % pw.m))) (y : Nat) :
                  bitAt (if bitAt pw.fsq r = true then setBitAt pat cur else pat) y = (decide (y < cur + 1) && bitAt pw.fsq (y * binv % pw.m))

                  The bits of the pattern of a unit after the residue cur, its bit set when Ratpoints.Sieve.Power.fsq has the bit of cur b⁻¹.

                  theorem Ratpoints.Sieve.UnitPatternInvariant.append_ite {pw : Power} {b cur : Nat} {pref suff : List Nat} {pat : Array UInt64} {r : Nat} (pre : 0 < pw.m ∧ pw.m ≤ 64 * modWords ∧ pw.inv[b]! < pw.m ∧ PatZero pat) (hl : ForIn.toList [:pw.m] = pref ++ cur :: suff) {pat' : Array UInt64} (h : UnitPatternInvariant pw pw.inv[b]! pref.length (pat', r)) :
                  UnitPatternInvariant pw pw.inv[b]! (pref ++ [cur]).length (if bitAt pw.fsq r = true then Sieve.setBitAt pat' cur else pat', if pw.m ≤ r + pw.inv[b]! then r + pw.inv[b]! - pw.m else r + pw.inv[b]!)
                  theorem Ratpoints.Sieve.UnitPatternInvariant.setBitAt {pw : Power} {b cur : Nat} {pref suff : List Nat} {pat : Array UInt64} {r : Nat} (pre : 0 < pw.m ∧ pw.m ≤ 64 * modWords ∧ pw.inv[b]! < pw.m ∧ PatZero pat) (hl : ForIn.toList [:pw.m] = pref ++ cur :: suff) {pat' : Array UInt64} (h : UnitPatternInvariant pw pw.inv[b]! pref.length (pat', r)) (hbit : bitAt pw.fsq r = true) :
                  UnitPatternInvariant pw pw.inv[b]! (pref ++ [cur]).length (Sieve.setBitAt pat' cur, if pw.m ≤ r + pw.inv[b]! then r + pw.inv[b]! - pw.m else r + pw.inv[b]!)
                  theorem Ratpoints.Sieve.UnitPatternInvariant.skip {pw : Power} {b cur : Nat} {pref suff : List Nat} {pat : Array UInt64} {r : Nat} (pre : 0 < pw.m ∧ pw.m ≤ 64 * modWords ∧ pw.inv[b]! < pw.m ∧ PatZero pat) (hl : ForIn.toList [:pw.m] = pref ++ cur :: suff) {pat' : Array UInt64} (h : UnitPatternInvariant pw pw.inv[b]! pref.length (pat', r)) (hbit : ¬bitAt pw.fsq r = true) :
                  UnitPatternInvariant pw pw.inv[b]! (pref ++ [cur]).length (pat', if pw.m ≤ r + pw.inv[b]! then r + pw.inv[b]! - pw.m else r + pw.inv[b]!)
                  theorem Ratpoints.Sieve.UnitPatternInvariant.post {pw : Power} {binv : Nat} {st : Array UInt64 × Nat} (h : UnitPatternInvariant pw binv (ForIn.toList [:pw.m]).length st) :
                  st.fst.size = modWords ∧ ∀ (y : Nat), bitAt st.fst y = (decide (y < pw.m) && bitAt pw.fsq (y * binv % pw.m))
                  theorem Ratpoints.Sieve.powerPatternUnit_spec (pw : Power) (b : Nat) (pat : Array UInt64) :
                  ⦃ 0 < pw.m ∧ pw.m ≤ 64 * modWords ∧ pw.inv[b]! < pw.m ∧ PatZero pat ⦄ powerPatternUnit pw b pat ⦃ fun (pat' : Array UInt64) => pat'.size = modWords ∧ ∀ (y : Nat), bitAt pat' y = (decide (y < pw.m) && bitAt pw.fsq (y * pw.inv[b]! % pw.m)) ⦄

                  The pattern of the row of a unit b modulo the prime power m, from a cleared pattern: bit x < m set when bit x b⁻¹ mod m of Ratpoints.Sieve.Power.fsq is, for the inverse of b below m.

                  The invariant of the loop of Ratpoints.Sieve.powerPatternNonunit after the residues below 1 + c: the bits 1 ≤ y < 1 + c of the units y set where Ratpoints.Sieve.Power.gsq has the bit of b y⁻¹.

                  Equations
                  • One or more equations did not get rendered due to their size.
                  Instances For
                    theorem Ratpoints.Sieve.NonunitPatternInvariant.setBitAt {pw : Power} {b cur : Nat} {pref suff : List Nat} {pat : Array UInt64} (pre : 0 < pw.m ∧ pw.m ≤ 64 * modWords ∧ PatZero pat) (hl : ForIn.toList [1:pw.m] = pref ++ cur :: suff) {pat' : Array UInt64} (h : NonunitPatternInvariant pw b pref.length pat') (hc0 : ¬cur % pw.p = 0) (hbit : bitAt pw.gsq (b * pw.inv[cur]! % pw.m) = true) :
                    theorem Ratpoints.Sieve.NonunitPatternInvariant.skip {pw : Power} {b cur : Nat} {pref suff : List Nat} {pat : Array UInt64} (hl : ForIn.toList [1:pw.m] = pref ++ cur :: suff) (h : NonunitPatternInvariant pw b pref.length pat) (hbit : cur % pw.p = 0 ∨ ¬bitAt pw.gsq (b * pw.inv[cur]! % pw.m) = true) :
                    NonunitPatternInvariant pw b (pref ++ [cur]).length pat
                    theorem Ratpoints.Sieve.NonunitPatternInvariant.post {pw : Power} {b : Nat} {pat : Array UInt64} (hm : 0 < pw.m) (h : NonunitPatternInvariant pw b (ForIn.toList [1:pw.m]).length pat) :
                    pat.size = modWords ∧ ∀ (y : Nat), bitAt pat y = (decide (1 ≤ y ∧ y < pw.m) && (y % pw.p != 0 && bitAt pw.gsq (b * pw.inv[y]! % pw.m)))
                    theorem Ratpoints.Sieve.powerPatternNonunit_spec (pw : Power) (b : Nat) (pat : Array UInt64) :
                    ⦃ 0 < pw.m ∧ pw.m ≤ 64 * modWords ∧ PatZero pat ⦄ powerPatternNonunit pw b pat ⦃ fun (pat' : Array UInt64) => pat'.size = modWords ∧ ∀ (y : Nat), bitAt pat' y = (decide (1 ≤ y ∧ y < pw.m) && (y % pw.p != 0 && bitAt pw.gsq (b * pw.inv[y]! % pw.m))) ⦄

                    The pattern of the row of a residue b divisible by p modulo the prime power m, from a cleared pattern: bit x of a unit x < m set when bit b x⁻¹ mod m of Ratpoints.Sieve.Power.gsq is.

                    theorem Ratpoints.Sieve.PatZero.set!_zero {pat : Array UInt64} (h : PatZero pat) (x : Nat) :
                    PatZero (pat.set! x 0)
                    theorem Ratpoints.Sieve.bitAt_mod_eq_admits_of_unit {pw : Power} {b : Nat} {pat : Array UInt64} (hb : b < pw.m) (hbp : b % pw.p ≠ 0) (hpat : ∀ (y : Nat), bitAt pat y = (decide (y < pw.m) && bitAt pw.fsq (y * pw.inv[b]! % pw.m))) (N : Nat) :
                    bitAt pat (N % pw.m) = pw.admits b ↑N

                    The pattern of a unit b < m read at the residue of a numerator is the row of b of the prime power.

                    theorem Ratpoints.Sieve.bitAt_mod_eq_admits_of_dvd {pw : Power} {b : Nat} {pat : Array UInt64} (hb : b < pw.m) (hbp : ¬b % pw.p ≠ 0) (hpat : ∀ (y : Nat), bitAt pat y = (decide (1 ≤ y ∧ y < pw.m) && (y % pw.p != 0 && bitAt pw.gsq (b * pw.inv[y]! % pw.m)))) (N : Nat) :
                    bitAt pat (N % pw.m) = pw.admits b ↑N

                    The pattern of a residue b < m divisible by p read at the residue of a numerator is the row of b of the prime power.

                    theorem Ratpoints.Sieve.sieveInitPower_pre_layOut_unit {pw : Power} {b : Nat} {pat : Array UInt64} (pre : b < pw.m ∧ pw.m ≤ 64 * modWords ∧ pw.inv[b]! < pw.m) {g : Nat → Bool} (hpat : pat.size = modWords ∧ ∀ (y : Nat), bitAt pat y = (decide (y < pw.m) && g y)) :
                    0 < pw.m ∧ pw.m ≤ 64 * modWords ∧ PatClear pw.m pat
                    theorem Ratpoints.Sieve.sieveInitPower_pre_layOut_nonunit {pw : Power} {b : Nat} {pat : Array UInt64} (pre : b < pw.m ∧ pw.m ≤ 64 * modWords ∧ pw.inv[b]! < pw.m) {g : Nat → Bool} (hpat : pat.size = modWords ∧ ∀ (y : Nat), bitAt pat y = (decide (1 ≤ y ∧ y < pw.m) && g y)) :
                    0 < pw.m ∧ pw.m ≤ 64 * modWords ∧ PatClear pw.m pat
                    theorem Ratpoints.Sieve.sieveInitPower_post {pw : Power} {ref : EntryRef} {b : Nat} {store : RowStore} {pat : Array UInt64} {row : Vector UInt64 ((pw.m + chunk - 1) * rbaPack)} (hg : ∀ (N : Nat), bitAt pat (N % pw.m) = pw.admits b ↑N) (hrow : RowWords (bitAt pat) pw.m ((pw.m + chunk - 1) * rbaPack) row) :
                    (row, store.publish ref b row.toArray).fst.toArray = closedRow pw.admits pw.m b ∧ (row, store.publish ref b row.toArray).snd = store.publish ref b (closedRow pw.admits pw.m b)

                    The row laid out from the pattern of the residue b is the closed form of the row of b, and so is what the builder stores.

                    theorem Ratpoints.Sieve.sieveInitPower_spec (pw : Power) (ref : EntryRef) (b : Nat) (store : RowStore) :
                    ⦃ b < pw.m ∧ pw.m ≤ 64 * modWords ∧ pw.inv[b]! < pw.m ⦄ sieveInitPower pw ref b store ⦃ fun (r : Vector UInt64 ((pw.m + chunk - 1) * rbaPack) × RowStore) => r.fst.toArray = closedRow pw.admits pw.m b ∧ r.snd = store.publish ref b (closedRow pw.admits pw.m b) ⦄

                    The row of the residue b < m of the prime power m ≤ 64 Ratpoints.modWords with the tables pw, for the inverse of b below m, is the closed form of the row of b of its tables, and the builder stores it into the table of rows of the entry ref.

                    The blocks of the rows of a product #

                    Word y of the row of factor i of the product e, read in the blocks of the length q of its modulus: word y mod rbaPack of bit array ⌊y / rbaPack⌋ mod q of the row frows[i].

                    Equations
                    Instances For

                      Word y of the row of the product e after its first K ≥ 1 factors: the and of their words (Ratpoints.Sieve.factorWord).

                      Equations
                      • One or more equations did not get rendered due to their size.
                      Instances For
                        theorem Ratpoints.Sieve.productWord_succ (e : SieveEntry) (frows : Array (Array UInt64)) {K : Nat} (hK : 1 ≤ K) (y : Nat) :
                        productWord e frows (K + 1) y = productWord e frows K y &&& factorWord e frows K y

                        The invariant of the loop of Ratpoints.Sieve.productCopy over the blocks of the first factor: the bit arrays below x, a multiple of its modulus up to m, laid down.

                        Equations
                        • One or more equations did not get rendered due to their size.
                        Instances For
                          theorem Ratpoints.Sieve.FirstInvariant.storeBitArray {e : SieveEntry} {frows : Array (Array UInt64)} {n x cur mb : Nat} {pref suff : List Nat} {row row0 : Vector UInt64 n} (pre : 0 < e.factors[0]!.modulus ∧ e.factors[0]!.modulus ∣ e.p ∧ e.p * rbaPack ≤ n) (hinv : e.p - x = mb ∧ FirstInvariant e frows false (row0, x)) (hxm : x < e.p) (hl : ForIn.toList [:e.factors[0]!.modulus] = pref ++ cur :: suff) (h : ∀ (y : Nat), y < (x + pref.length) * rbaPack → row[y]! = factorWord e frows 0 y) (y : Nat) :
                          y < (x + (pref ++ [cur]).length) * rbaPack → (Sieve.storeBitArray row (x + cur) frows[0]!.toVector cur)[y]! = factorWord e frows 0 y

                          A copy of bit array j of the first factor into bit array x + j.

                          theorem Ratpoints.Sieve.FirstInvariant.add {e : SieveEntry} {frows : Array (Array UInt64)} {n x mb : Nat} {row row0 : Vector UInt64 n} (pre : 0 < e.factors[0]!.modulus ∧ e.factors[0]!.modulus ∣ e.p ∧ e.p * rbaPack ≤ n) (hinv : e.p - x = mb ∧ FirstInvariant e frows false (row0, x)) (hxm : x < e.p) (h : ∀ (y : Nat), y < (x + (ForIn.toList [:e.factors[0]!.modulus]).length) * rbaPack → row[y]! = factorWord e frows 0 y) :
                          theorem Ratpoints.Sieve.FirstInvariant.exit {e : SieveEntry} {frows : Array (Array UInt64)} {n x mb : Nat} {row : Vector UInt64 n} (h : e.p - x = mb ∧ FirstInvariant e frows false (row, x)) (hxm : ¬x < e.p) :
                          FirstInvariant e frows true (row, x)
                          theorem Ratpoints.Sieve.FirstInvariant.post {e : SieveEntry} {frows : Array (Array UInt64)} {n x : Nat} {row : Vector UInt64 n} (h : FirstInvariant e frows true (row, x)) {y : Nat} (hy : y < e.p * rbaPack) :
                          row[y]! = factorWord e frows 0 y
                          theorem Ratpoints.Sieve.firstInvariant_inner {e : SieveEntry} {frows : Array (Array UInt64)} {n x mb : Nat} {row : Vector UInt64 n} (h : e.p - x = mb ∧ FirstInvariant e frows false (row, x)) {y : Nat} (hy : y < (x + [].length) * rbaPack) :
                          row[y]! = factorWord e frows 0 y
                          theorem Ratpoints.Sieve.productCopy_spec {n : Nat} (row : Vector UInt64 n) (e : SieveEntry) (frows : Array (Array UInt64)) :
                          ⦃ 0 < e.factors[0]!.modulus ∧ e.factors[0]!.modulus ∣ e.p ∧ e.p * rbaPack ≤ n ⦄ productCopy row e frows ⦃ fun (row' : Vector UInt64 n) => ∀ (y : Nat), y < e.p * rbaPack → row'[y]! = factorWord e frows 0 y ⦄

                          The row of the first factor of the product e, of a modulus q ∣ m = e.p, laid down in the blocks of its length: word y < m rbaPack of the row is word y of the factor read in those blocks (Ratpoints.Sieve.factorWord).

                          The invariant of the loop of Ratpoints.Sieve.productAnd over the blocks of the factor i ≥ 1: the bit arrays below x, a multiple of its modulus up to m, and-ed with it.

                          Equations
                          • One or more equations did not get rendered due to their size.
                          Instances For
                            theorem Ratpoints.Sieve.productAnd_init {e : SieveEntry} {frows : Array (Array UInt64)} {n : Nat} {row : Vector UInt64 n} (h : ∀ (y : Nat), y < e.p * rbaPack → row[y]! = factorWord e frows 0 y) {y : Nat} (hy : y < e.p * rbaPack) :
                            row[y]! = productWord e frows (1 + [].length) y
                            theorem Ratpoints.Sieve.factorInvariant_init {e : SieveEntry} {frows : Array (Array UInt64)} {n cur : Nat} {pref suff : List Nat} {row : Vector UInt64 n} (hl : ForIn.toList [1:e.factors.length] = pref ++ cur :: suff) (h : ∀ (y : Nat), y < e.p * rbaPack → row[y]! = productWord e frows (1 + pref.length) y) :
                            FactorInvariant e frows cur false (row, 0)
                            theorem Ratpoints.Sieve.FactorInvariant.inner {e : SieveEntry} {frows : Array (Array UInt64)} {n i x mb : Nat} {row : Vector UInt64 n} (h : e.p - x = mb ∧ FactorInvariant e frows i false (row, x)) (y : Nat) (hy : y < e.p * rbaPack) :
                            row[y]! = if y / rbaPack < x + [].length then productWord e frows (i + 1) y else productWord e frows i y
                            theorem Ratpoints.Sieve.FactorInvariant.andBitArray {e : SieveEntry} {frows : Array (Array UInt64)} {n i x cur mb : Nat} {pref' suff' pref suff : List Nat} {row row0 : Vector UInt64 n} (pre : (∀ (i : Nat), i < e.factors.length → 0 < e.factors[i]!.modulus ∧ e.factors[i]!.modulus ∣ e.p) ∧ e.p * rbaPack ≤ n ∧ ∀ (y : Nat), y < e.p * rbaPack → row0[y]! = factorWord e frows 0 y) (hl' : ForIn.toList [1:e.factors.length] = pref' ++ i :: suff') (hinv : e.p - x = mb ∧ FactorInvariant e frows i false (row, x)) (hl : ForIn.toList [:e.factors[i]!.modulus] = pref ++ cur :: suff) {row' : Vector UInt64 n} (h : ∀ (y : Nat), y < e.p * rbaPack → row'[y]! = if y / rbaPack < x + pref.length then productWord e frows (i + 1) y else productWord e frows i y) (y : Nat) :
                            y < e.p * rbaPack → (Sieve.andBitArray row' (x + cur) frows[i]! cur)[y]! = if y / rbaPack < x + (pref ++ [cur]).length then productWord e frows (i + 1) y else productWord e frows i y

                            An and of bit array j of the factor i into bit array x + j.

                            theorem Ratpoints.Sieve.FactorInvariant.add {e : SieveEntry} {frows : Array (Array UInt64)} {n i x mb : Nat} {pref' suff' : List Nat} {row row0 row' : Vector UInt64 n} (pre : (∀ (i : Nat), i < e.factors.length → 0 < e.factors[i]!.modulus ∧ e.factors[i]!.modulus ∣ e.p) ∧ e.p * rbaPack ≤ n ∧ ∀ (y : Nat), y < e.p * rbaPack → row0[y]! = factorWord e frows 0 y) (hl' : ForIn.toList [1:e.factors.length] = pref' ++ i :: suff') (hinv : e.p - x = mb ∧ FactorInvariant e frows i false (row, x)) (hxm : x < e.p) (h : ∀ (y : Nat), y < e.p * rbaPack → row'[y]! = if y / rbaPack < x + (ForIn.toList [:e.factors[i]!.modulus]).length then productWord e frows (i + 1) y else productWord e frows i y) :
                            theorem Ratpoints.Sieve.FactorInvariant.exit {e : SieveEntry} {frows : Array (Array UInt64)} {n i x mb : Nat} {row : Vector UInt64 n} (h : e.p - x = mb ∧ FactorInvariant e frows i false (row, x)) (hxm : ¬x < e.p) :
                            FactorInvariant e frows i true (row, x)
                            theorem Ratpoints.Sieve.FactorInvariant.next {e : SieveEntry} {frows : Array (Array UInt64)} {n i x : Nat} {pref suff : List Nat} {row : Vector UInt64 n} (hl : ForIn.toList [1:e.factors.length] = pref ++ i :: suff) (h : FactorInvariant e frows i true (row, x)) (y : Nat) :
                            y < e.p * rbaPack → row[y]! = productWord e frows (1 + (pref ++ [i]).length) y
                            theorem Ratpoints.Sieve.productAnd_post {e : SieveEntry} {frows : Array (Array UInt64)} {n : Nat} {row : Vector UInt64 n} (h : ∀ (y : Nat), y < e.p * rbaPack → row[y]! = productWord e frows (1 + (ForIn.toList [1:e.factors.length]).length) y) {y : Nat} (hy : y < e.p * rbaPack) :
                            row[y]! = productWord e frows e.factors.length y
                            theorem Ratpoints.Sieve.productAnd_spec {n : Nat} (row : Vector UInt64 n) (e : SieveEntry) (frows : Array (Array UInt64)) :
                            ⦃ (∀ (i : Nat), i < e.factors.length → 0 < e.factors[i]!.modulus ∧ e.factors[i]!.modulus ∣ e.p) ∧ e.p * rbaPack ≤ n ∧ ∀ (y : Nat), y < e.p * rbaPack → row[y]! = factorWord e frows 0 y ⦄ productAnd row e frows ⦃ fun (row' : Vector UInt64 n) => ∀ (y : Nat), y < e.p * rbaPack → row'[y]! = productWord e frows e.factors.length y ⦄

                            The rows of the factors i ≥ 1 of the product e, each of a positive modulus q ∣ m = e.p, and-ed into the row in the blocks of their lengths: from the row of the first factor laid down, word y < m rbaPack of the row is the and of the words of all the factors read in their blocks (Ratpoints.Sieve.productWord).

                            The closed form of the rows of a product #

                            theorem Ratpoints.Sieve.getLsbD_factorWord {e : SieveEntry} {frows : Array (Array UInt64)} {b i : Nat} (hq : 0 < e.factors[i]!.modulus) (hf : frows[i]! = closedRow e.factors[i]!.admits e.factors[i]!.modulus (b % e.factors[i]!.modulus)) (y t : Nat) :
                            (factorWord e frows i y).toBitVec.getLsbD t = (decide (t < 64) && e.factors[i]!.admits b (64 * ↑y + ↑t))

                            Bit t of word y of the row of the residue b mod q of factor i of a product, in closed form, read in the blocks of the length q of its modulus: whether the factor admits 64 y + t.

                            theorem Ratpoints.Sieve.getLsbD_productWord (e : SieveEntry) (frows : Array (Array UInt64)) {K : Nat} (hK : 1 ≤ K) (y t : Nat) :
                            (productWord e frows K y).toBitVec.getLsbD t = (List.range K).all fun (i : Nat) => (factorWord e frows i y).toBitVec.getLsbD t
                            theorem Ratpoints.Sieve.toArray_eq_closedRow_of_productWord {e : SieveEntry} {frows : Array (Array UInt64)} {b : Nat} {row : Vector UInt64 ((e.p + chunk - 1) * rbaPack)} (hL : 1 ≤ e.factors.length) (hq : ∀ (i : Nat), i < e.factors.length → 0 < e.factors[i]!.modulus ∧ e.factors[i]!.modulus ∣ e.p) (hf : ∀ (i : Nat), i < e.factors.length → frows[i]! = closedRow e.factors[i]!.admits e.factors[i]!.modulus (b % e.factors[i]!.modulus)) (hrow : ∀ (y : Nat), y < (e.p + chunk - 1) * rbaPack → row[y]! = productWord e frows e.factors.length (y % (e.p * rbaPack))) :

                            The row of a product whose words are those of the rows of its factors, in closed form at the residue b modulo their moduli, and-ed in the blocks of their lengths and repeated after the first m bit arrays, is the closed form of the row of b of the product: the moduli of the factors divide m, so each factor reads the numerators modulo its own modulus.