Documentation

Complexity.Computability.GenericRAM.Native.SubsetPairFold

Combinatorial subset-pair unranking and streaming folds #

For Boolean Möbius reconstruction of low-degree polynomials ([OAI26c], Lemma 3.3, eq. (3.10) and Proposition 3.4, pp. 24–26), the outer loop visits all subset pairs (E, U) of Fin n with #E ≤ q and U ⊆ E, weighted by (-1) ^ (#E - #U), in C_q = ∑ s ≤ min q n, 2 ^ s * n.choose s steps without materializing exponentially many subsets.

Main definitions #

Main results #

References #

Append one dynamic-programming Pascal row of width width to rows.

Instances For

    One step of scanning bucket capacities 2 ^ s * C(n, s) for s = 0, …, min q n.

    Instances For

      Locate (s, offset) for j < C_q, or none when j ≥ C_q.

      Instances For

        One step of combinatorial unranking of rank r < C(n, k) into an n-bit indicator.

        Instances For

          Unrank r < C(n, k) using table = pascalTable n into a length-n weight-k bit list.

          Instances For

            One step of scattering low-order bits of uMask onto the true entries of indE.

            Instances For

              Scatter the bits of uMask across the true positions of indE.

              Instances For

                Section 1: Dynamic-programming Pascal table and exact binary clock C_q #

                Dynamic-programming (n + 1) × (n + 1) Pascal table of i.choose s by row addition.

                Instances For

                  In-bounds lookup in pascalTable n returns i.choose s.

                  Defaulted lookup in row i ≤ n of pascalTable n equals i.choose s for every s : ℕ.

                  Every binomial coefficient i.choose s for i ≤ n has binary length at most n + 1.

                  Every entry stored in pascalTable n has binary encoding length at most n + 1.

                  Executable subset-pair count C_q = ∑ s ≤ min q n, 2 ^ s * n.choose s ([OAI26c]).

                  Instances For

                    subsetPairCount n q equals ∑ s ∈ Finset.range (min q n + 1), 2 ^ s * n.choose s.

                    subsetPairCount n q is strictly positive for all n, q (since (∅, ∅) is always valid).

                    When n ≤ q, subsetPairCount n q = 3 ^ n ([OAI26c], eq. (3.14)).

                    The binary index bound subsetPairCount n q occupies at most 2 * n + 1 bits in encNat.

                    Section 2: Polynomial-time combinatorial (E, U) unranker and bijection #

                    @[reducible, inline]

                    Decoded (indE, indU, negSign) triple: length-n indicators and Odd (#E - #U) flag.

                    Instances For

                      Combinatorial (E, U) unranker: decodes j < subsetPairCount n q into (indE, indU, negSign) without materializing subsets, with deterministic empty-pair fallback for j ≥ C_q.

                      Instances For

                        Out-of-range indices j ≥ subsetPairCount n q return the empty-pair fallback.

                        @[simp]

                        The first indicator indE returned by unrankSubsetPair n q j has exact length n.

                        @[simp]

                        The second indicator indU returned by unrankSubsetPair n q j has exact length n.

                        Pointwise containment: every true position of indU is also true in indE.

                        Weight bound: indE has at most min q n (hence at most q) true entries.

                        The third component negSign is decide (Odd (indE.count true - indU.count true)).

                        @[reducible, inline]

                        Valid (E, U) subset pairs on Fin n with #E ≤ q and U ⊆ E ([OAI26c]).

                        Instances For

                          Map a valid index j : Fin (subsetPairCount n q) to its ValidSubsetPair n q.

                          Instances For

                            Summing 2 ^ #E over all E ⊆ Fin n with #E ≤ q yields subsetPairCount n q.

                            Equivalence between binary indices Fin (subsetPairCount n q) and ValidSubsetPair n q.

                            Instances For

                              Mapping unrankSubsetPair n q over List.range (subsetPairCount n q) has no duplicates.

                              theorem Cslib.GenericRAM.SubsetPairFold.existsUnique_unrankSubsetPair (n q : ℕ) {E U : Finset (Fin n)} (hE : E.card ≤ q) (hU : U ⊆ E) :
                              ∃! j : ℕ, j < subsetPairCount n q ∧ unrankSubsetPair n q j = (List.ofFn fun (i : Fin n) => decide (i ∈ E), List.ofFn fun (i : Fin n) => decide (i ∈ U), decide (Odd (E.card - U.card)))

                              Exact completeness: every valid pair (E, U) with #E ≤ q and U ⊆ E is decoded at a unique index j < subsetPairCount n q.

                              Section 3: Plain ComputableInPolyTime and NativeCertificate witnesses #

                              @[reducible, inline]

                              Encoding for unary (n, q) dimension/degree parameters.

                              Instances For
                                @[reducible, inline]

                                Encoding for decoded (indE, indU, negSign) triples.

                                Instances For

                                  Native certificate for subsetPairCount, selected via NativeCertificate.ofPolyTime.

                                  Instances For

                                    Native certificate for unrankSubsetPair, selected via NativeCertificate.ofPolyTime.

                                    Instances For

                                      Section 4: Streaming IndexFold combinator (SubsetPairFold.run & computableInO) #

                                      @[reducible, inline]

                                      Retained accumulator encoding pairing unary (n, q) parameters with the caller's encB.

                                      Instances For
                                        def Cslib.GenericRAM.SubsetPairFold.indexBody {β : Type} (body : DecodedPair × β → β) (p : ℕ × (ℕ × ℕ) × β) :
                                        (ℕ × ℕ) × β

                                        Per-index round body for IndexFold.run, retaining (n, q) and decoding j on the fly.

                                        Instances For
                                          def Cslib.GenericRAM.SubsetPairFold.runPrefix {β : Type} (body : DecodedPair × β → β) (n q m : ℕ) (initial : β) :
                                          ℕ × (ℕ × ℕ) × β

                                          Streaming prefix after m binary-indexed steps of IndexFold.run.

                                          Instances For
                                            def Cslib.GenericRAM.SubsetPairFold.run {β : Type} (body : DecodedPair × β → β) (n q : ℕ) (initial : β) :
                                            β

                                            Stream all subsetPairCount n q valid (E, U) subset pairs through IndexFold.run.

                                            Instances For
                                              @[simp]
                                              theorem Cslib.GenericRAM.SubsetPairFold.runPrefix_index {β : Type} (body : DecodedPair × β → β) (n q m : ℕ) (initial : β) :
                                              (runPrefix body n q m initial).1 = m
                                              @[simp]
                                              theorem Cslib.GenericRAM.SubsetPairFold.runPrefix_params {β : Type} (body : DecodedPair × β → β) (n q m : ℕ) (initial : β) :
                                              (runPrefix body n q m initial).2.1 = (n, q)

                                              The retained unary parameter pair (n, q) is invariant across all streaming prefixes.

                                              theorem Cslib.GenericRAM.SubsetPairFold.runPrefix_acc {β : Type} (body : DecodedPair × β → β) (n q m : ℕ) (initial : β) :
                                              (runPrefix body n q m initial).2.2 = List.foldl (fun (acc : β) (j : ℕ) => body (unrankSubsetPair n q j, acc)) initial (List.range m)

                                              Every prefix accumulator equals the ordered range fold over decoded indices 0, …, m - 1.

                                              theorem Cslib.GenericRAM.SubsetPairFold.run_eq_foldl_range {β : Type} (body : DecodedPair × β → β) (n q : ℕ) (initial : β) :
                                              run body n q initial = List.foldl (fun (acc : β) (j : ℕ) => body (unrankSubsetPair n q j, acc)) initial (List.range (subsetPairCount n q))

                                              SubsetPairFold.run agrees with folding over List.range (subsetPairCount n q).

                                              theorem Cslib.GenericRAM.SubsetPairFold.run_eq_foldl_map {β : Type} (body : DecodedPair × β → β) (n q : ℕ) (initial : β) :
                                              run body n q initial = List.foldl (fun (acc : β) (item : DecodedPair) => body (item, acc)) initial (List.map (unrankSubsetPair n q) (List.range (subsetPairCount n q)))

                                              SubsetPairFold.run agrees with folding over the mapped list of decoded pairs.

                                              theorem Cslib.GenericRAM.SubsetPairFold.run_add_eq_sum_validSubsetPairs {M : Type} [AddCommMonoid M] (n q : ℕ) (f : Finset (Fin n) → Finset (Fin n) → Bool → M) :
                                              run (fun (p : DecodedPair × M) => p.2 + f (BitString.supportOfList n p.1.1) (BitString.supportOfList n p.1.2.1) p.1.2.2) n q 0 = ∑ E ∈ Finset.univ.powerset with E.card ≤ q, ∑ U ∈ E.powerset, f E U (decide (Odd (E.card - U.card)))

                                              Commutative-monoid accumulation via run sums over all E ⊆ Fin n (#E ≤ q) and U ⊆ E.

                                              theorem Cslib.GenericRAM.SubsetPairFold.run_mobius_eq_sum_restricted_subsets {R : Type} [CommRing R] (n q : ℕ) (g : Finset (Fin n) → Finset (Fin n) → R) :
                                              run (fun (p : DecodedPair × R) => have term := g (BitString.supportOfList n p.1.1) (BitString.supportOfList n p.1.2.1); if p.1.2.2 = true then p.2 - term else p.2 + term) n q 0 = ∑ E ∈ Finset.univ.powerset with E.card ≤ q, ∑ U ∈ E.powerset, (-1) ^ (E.card - U.card) * g E U

                                              Signed Möbius accumulation via run computes ∑_{#E ≤ q} ∑_{U ⊆ E} (-1) ^ (#E - #U) * g E U over any commutative ring R ([OAI26c], Lemma 3.3 eq. (3.10), Proposition 3.4).

                                              Native certificate for one indexBody round, retaining (n, q) in unary.

                                              Instances For
                                                noncomputable def Cslib.GenericRAM.SubsetPairFold.certificate {α β : Type} {encB : β ↪ List Bool} {encIn : α ↪ List Bool} {dim deg : α → ℕ} {initial : α → β} {body : DecodedPair × β → β} (cn : NativeCertificate dim encIn Turing.MultiTapeTM.encUnary) (cq : NativeCertificate deg encIn Turing.MultiTapeTM.encUnary) (ci : NativeCertificate initial encIn encB) (cb : NativeCertificate body (Turing.MultiTapeTM.encPair encDecodedPair encB) encB) :
                                                NativeCertificate (fun (a : α) => run body (dim a) (deg a) (initial a)) encIn encB

                                                Native certificate for SubsetPairFold.run, built on IndexFold.certificate.

                                                Instances For

                                                  Polynomial overhead in n + q for subsetPairCount, unranking, and index maintenance.

                                                  Instances For
                                                    theorem Cslib.GenericRAM.SubsetPairFold.computableInO {α β : Type} {encB : β ↪ List Bool} {encIn : α ↪ List Bool} {dim deg : α → ℕ} {initial : α → β} {body : DecodedPair × β → β} (cn : NativeCertificate dim encIn Turing.MultiTapeTM.encUnary) (cq : NativeCertificate deg encIn Turing.MultiTapeTM.encUnary) (ci : NativeCertificate initial encIn encB) (cb : NativeCertificate body (Turing.MultiTapeTM.encPair encDecodedPair encB) encB) (R Q B : α → ℕ) (hR : ∀ (a : α), ∀ j ≤ subsetPairCount (dim a) (deg a), cb.time (unrankSubsetPair (dim a) (deg a) j, (runPrefix body (dim a) (deg a) j (initial a)).2.2) ≤ R a) (hQ : ∀ (a : α), ∀ j ≤ subsetPairCount (dim a) (deg a), cb.space (unrankSubsetPair (dim a) (deg a) j, (runPrefix body (dim a) (deg a) j (initial a)).2.2) ≤ Q a) (hB : ∀ (a : α), ∀ j ≤ subsetPairCount (dim a) (deg a), (encB (runPrefix body (dim a) (deg a) j (initial a)).2.2).length ≤ B a) :
                                                    Turing.MultiTapeTM.ComputableInO (fun (a : α) => run body (dim a) (deg a) (initial a)) encIn encB (fun (a : α) => (encIn a).length + cn.time a + cq.time a + ci.time a + decodeOverhead (dim a + deg a) + (subsetPairCount (dim a) (deg a) + 1) * (decodeOverhead (dim a + deg a) + B a + R a)) fun (a : α) => (encIn a).length + cn.space a + cq.space a + ci.space a + decodeOverhead (dim a + deg a) + B a + Q a

                                                    Streaming resource bound for SubsetPairFold.run via IndexFold.computableInO: time scales with subsetPairCount (dim a) (deg a) + 1 while live workspace is independent of C_q.

                                                    theorem Cslib.GenericRAM.SubsetPairFold.polyBounded_space_of_polyBounded {α β : Type} {encB : β ↪ List Bool} {encIn : α ↪ List Bool} {dim deg : α → ℕ} {initial : α → β} {B Q : α → ℕ} (cn : NativeCertificate dim encIn Turing.MultiTapeTM.encUnary) (cq : NativeCertificate deg encIn Turing.MultiTapeTM.encUnary) (ci : NativeCertificate initial encIn encB) (hcn : cn.IsPolynomial) (hcq : cq.IsPolynomial) (hci : ci.IsPolynomial) (hB : Turing.MultiTapeTM.PolyBounded (fun (a : α) => (encIn a).length) B) (hQ : Turing.MultiTapeTM.PolyBounded (fun (a : α) => (encIn a).length) Q) :
                                                    Turing.MultiTapeTM.PolyBounded (fun (a : α) => (encIn a).length) fun (a : α) => (encIn a).length + cn.space a + cq.space a + ci.space a + decodeOverhead (dim a + deg a) + B a + Q a

                                                    When dim, deg, and initial have polynomial certificates and B and Q are polynomially bounded in the input length, the live workspace of SubsetPairFold.computableInO is polynomial.