From 3ebccd4564f306724892fbb5b5ff63c11b18cd2e Mon Sep 17 00:00:00 2001 From: Samuel Schlesinger Date: Mon, 26 Oct 2026 23:52:20 +0000 Subject: [PATCH 01/20] feat(Foundations/Data/Polynomial): integer parity amplifier and shared-order truncation (#1226) --- Complexity.lean | 1 + .../Data/Polynomial/ParityAmplifier.lean | 1100 +++++++++++++++++ ComplexityTests/ParityAmplifier.lean | 127 ++ 3 files changed, 1228 insertions(+) create mode 100644 Complexity/Foundations/Data/Polynomial/ParityAmplifier.lean create mode 100644 ComplexityTests/ParityAmplifier.lean diff --git a/Complexity.lean b/Complexity.lean index 7dabe2f651..2e33abe093 100644 --- a/Complexity.lean +++ b/Complexity.lean @@ -1968,6 +1968,7 @@ public import Complexity.Foundations.Data.Option public import Complexity.Foundations.Data.OrderedSet public import Complexity.Foundations.Data.OrderedSet.Spec public import Complexity.Foundations.Data.Polynomial.CoeffList +public import Complexity.Foundations.Data.Polynomial.ParityAmplifier public import Complexity.Foundations.Data.Polynomial.SignQueries public import Complexity.Foundations.Data.Rat.Basic public import Complexity.Foundations.Data.Seq.Computation diff --git a/Complexity/Foundations/Data/Polynomial/ParityAmplifier.lean b/Complexity/Foundations/Data/Polynomial/ParityAmplifier.lean new file mode 100644 index 0000000000..5cde854056 --- /dev/null +++ b/Complexity/Foundations/Data/Polynomial/ParityAmplifier.lean @@ -0,0 +1,1100 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Mathlib.Algebra.MvPolynomial.Degrees +public import Mathlib.Algebra.Polynomial.AlgebraMap +public import Mathlib.Algebra.Polynomial.BigOperators +public import Mathlib.Algebra.Polynomial.Div +public import Mathlib.Data.Int.ModEq +import Mathlib.Algebra.BigOperators.Intervals +import Mathlib.Algebra.BigOperators.Ring.Finset +import Mathlib.Algebra.Ring.Int.Parity +import Mathlib.Data.Nat.Choose.Sum +import Mathlib.Tactic.Linarith +import Mathlib.Tactic.Ring + +/-! +# Integer parity-amplifying polynomials and shared-total-order truncation + +For `ℓ ≥ 1`, the complement of the Beigel–Tarui modulus-amplifying polynomial [Toda][Toda1991], +[Arora and Barak, Section 17.4][AroraBarak09], +$$p_\ell(Y) = (1 - Y)^\ell \sum_{j=0}^{\ell-1} \binom{\ell - 1 + j}{j} Y^j \in \mathbb{Z}[Y],$$ +satisfies $p_\ell(Y) \equiv 1 \pmod{Y^\ell}$ and $p_\ell(Y) \equiv 0 \pmod{(1 - Y)^\ell}$, so +for every integer $y \in \mathbb{Z}$, $p_\ell(y) \equiv \mathbf{1}_{\{2 \mid y\}} \pmod{2^\ell}$ +(`Polynomial.parityAmplifier_eval_modEq_two_pow`). + +Writing $p_\ell$ in powers of the monic quadratic $h(Y) = Y^2 - Y = Y(Y - 1)$ +(`Polynomial.hPoly`) by successive monic division produces remainders +$e_0, \dots, e_{\ell-1} \in \mathbb{Z}[Y]$ (`Polynomial.parityBaseDigit`) of degree at most $1$ +with $p_\ell(Y) = \sum_{j=0}^{\ell-1} e_j(Y) h(Y)^j$ (`Polynomial.parityAmplifier_eq_sum_baseDigit`) +and explicit coefficient bounds (`Polynomial.natAbs_coeff_parityBaseDigit_le`, +`Polynomial.coeffNorm1_parityBaseDigit_le`). + +Since $h(y) = y(y - 1)$ is even for every $y \in \mathbb{Z}$, introducing a shared formal variable +$V$ (`Polynomial.parityFactor`) across a family of equations and discarding powers $V^s$ with +$s \ge \ell$ via `Polynomial.sumCoeffsBelow` preserves the product of evenness indicators modulo +$2^\ell$ (`Polynomial.sumCoeffsBelow_prod_parityFactor_modEq`), while bounding the multivariate +total degree of every retained coefficient and of their sum by $d_* (\#I + 2(\ell - 1))$ when each +input polynomial has total degree at most $d_*$ +(`Polynomial.totalDegree_sumCoeffsBelow_prod_parityFactor_le`). + +## Main definitions + +* `Polynomial.hPoly`: the monic quadratic `X ^ 2 - X` in `ℤ[X]`. +* `Polynomial.parityKernel`: the partial binomial series `∑ j < ℓ, choose (ℓ - 1 + j) j * X ^ j`. +* `Polynomial.parityAmplifier`: the even-parity amplifying polynomial `p_ℓ(X) ∈ ℤ[X]`. +* `Polynomial.iterDivByH`, `Polynomial.baseDigitByH`, `Polynomial.parityBaseDigit`: successive + monic quotients and linear remainders `e_j(X)` on division by `X ^ 2 - X`. +* `Polynomial.coeffNorm1`: the `ℓ₁` coefficient norm `∑ i ∈ p.support, (p.coeff i).natAbs`. +* `Polynomial.parityFactor`: the `V`-series factor `B(y; V) = ∑ j < ℓ, e_j(y) h(y)^j V^j`. +* `Polynomial.sumCoeffsBelow`: the truncated coefficient sum `S_ℓ(P) = ∑ s < ℓ, P.coeff s`. + +## Main results + +* `Polynomial.parityAmplifier_add_X_pow_mul_eq_one`: Bezout identity + `p_ℓ(X) + X ^ ℓ * ∑ m < ℓ, choose (m + ℓ - 1) (ℓ - 1) * (1 - X) ^ m = 1` for `ℓ ≥ 1`. +* `Polynomial.parityAmplifier_eval_modEq_two_pow`: + `p_ℓ(y) ≡ (if Even y then 1 else 0) [ZMOD 2 ^ ℓ]`. +* `Polynomial.parityAmplifier_eq_sum_baseDigit`: `p_ℓ = ∑ j < ℓ, e_j * (X ^ 2 - X) ^ j`. +* `Polynomial.coeffNorm1_parityAmplifier_le`: `‖p_ℓ‖₁ ≤ 2 ^ (3 * ℓ)`. +* `Polynomial.natAbs_coeff_parityBaseDigit_le`: `|coeff k (e_j)| ≤ (2 * ℓ) ^ j * 2 ^ (3 * ℓ)`. +* `Polynomial.coeffNorm1_parityBaseDigit_le`: `‖e_j‖₁ ≤ 2 * ((2 * ℓ) ^ j * 2 ^ (3 * ℓ))`. +* `Polynomial.sumCoeffsBelow_prod_parityFactor_modEq`: shared-`V` truncation modulo `2 ^ ℓ`. +* `Polynomial.totalDegree_sumCoeffsBelow_prod_parityFactor_le`: linear total-degree bound + `totalDegree ≤ d_* * (#I + 2 * (ℓ - 1))`. + +## References + +* [S. Toda, *PP is as hard as the polynomial-time hierarchy*][Toda1991] +* [S. Arora, B. Barak, *Computational Complexity: A Modern Approach*][AroraBarak09] +-/ + +@[expose] public noncomputable section + +namespace Polynomial + +open Finset + +/-! ### 1. The univariate even-parity amplifier `p_ℓ(X)` -/ + +/-- The partial binomial series `g(m, K) = ∑ j ∈ range K, choose (m + j) j * X ^ j` in `ℤ[X]`. -/ +def paritySeriesAux (m K : ℕ) : ℤ[X] := + ∑ j ∈ range K, (Nat.choose (m + j) j : ℤ[X]) * X ^ j + +/-- The kernel `∑ j ∈ range ℓ, choose (ℓ - 1 + j) j * X ^ j` of the even-parity amplifier. -/ +def parityKernel (ℓ : ℕ) : ℤ[X] := + paritySeriesAux (ℓ - 1) ℓ + +/-- The even-parity amplifying polynomial +`p_ℓ(X) = (1 - X) ^ ℓ * ∑ j ∈ range ℓ, choose (ℓ - 1 + j) j * X ^ j` in `ℤ[X]`. -/ +def parityAmplifier (ℓ : ℕ) : ℤ[X] := + (1 - X) ^ ℓ * parityKernel ℓ + +/-- At precision `0`, `parityAmplifier 0` is `0`. -/ +@[simp] +theorem parityAmplifier_zero : parityAmplifier 0 = 0 := by + simp only [parityAmplifier, parityKernel, paritySeriesAux, range_zero, sum_empty, mul_zero] + +/-- At precision `1`, `parityAmplifier 1 = 1 - X`. -/ +theorem parityAmplifier_one : parityAmplifier 1 = 1 - X := by + simp only [parityAmplifier, parityKernel, paritySeriesAux, tsub_self, range_one, sum_singleton, + add_zero, Nat.choose_zero_right, Nat.cast_one, pow_zero, mul_one, pow_one] + +/-- At precision `2`, `parityAmplifier 2 = 1 - 3 * X ^ 2 + 2 * X ^ 3`. -/ +theorem parityAmplifier_two : parityAmplifier 2 = 1 - 3 * X ^ 2 + 2 * X ^ 3 := by + have hkern : parityKernel 2 = 1 + 2 * X := by + unfold parityKernel paritySeriesAux + rw [sum_range_succ, sum_range_one] + simp only [Nat.reduceSub, add_zero, Nat.choose_zero_right, Nat.cast_one, pow_zero, mul_one, + Nat.reduceAdd, Nat.choose_one_right, Nat.cast_ofNat, pow_one] + rw [parityAmplifier, hkern] + ring + +/-- `(1 - X) ^ ℓ` divides `parityAmplifier ℓ` in `ℤ[X]`. -/ +theorem one_sub_X_pow_dvd_parityAmplifier (ℓ : ℕ) : + (1 - X : ℤ[X]) ^ ℓ ∣ parityAmplifier ℓ := + dvd_mul_right _ _ + +private theorem one_sub_X_mul_paritySeriesAux_zero (K : ℕ) : + (1 - X) * paritySeriesAux 0 K = 1 - X ^ K := by + induction K with + | zero => + simp only [paritySeriesAux, range_zero, sum_empty, mul_zero, pow_zero, sub_self] + | succ K ih => + rw [paritySeriesAux, sum_range_succ, zero_add, Nat.choose_self, Nat.cast_one, one_mul, + mul_add, ← paritySeriesAux, ih] + ring + +private theorem one_sub_X_mul_paritySeriesAux_succ (m k : ℕ) : + (1 - X) * paritySeriesAux (m + 1) (k + 1) = + paritySeriesAux m (k + 1) - (Nat.choose (m + k + 1) k : ℤ[X]) * X ^ (k + 1) := by + induction k with + | zero => + change (1 - X) * ∑ j ∈ range 1, (Nat.choose (m + 1 + j) j : ℤ[X]) * X ^ j = + (∑ j ∈ range 1, (Nat.choose (m + j) j : ℤ[X]) * X ^ j) - + (Nat.choose (m + 0 + 1) 0 : ℤ[X]) * X ^ 1 + simp only [range_one, sum_singleton, add_zero, Nat.choose_zero_right, Nat.cast_one, + pow_zero, mul_one, pow_one] + ring + | succ k ih => + have hchoose : + (Nat.choose (m + 1 + (k + 1)) (k + 1) : ℤ[X]) = + (Nat.choose (m + k + 1) k : ℤ[X]) + (Nat.choose (m + (k + 1)) (k + 1) : ℤ[X]) := by + have hpas : Nat.choose (m + k + 1 + 1) (k + 1) = + Nat.choose (m + k + 1) k + Nat.choose (m + k + 1) (k + 1) := + Nat.choose_succ_succ (m + k + 1) k + have hm : m + 1 + (k + 1) = m + k + 1 + 1 := by omega + have hm2 : m + (k + 1) = m + k + 1 := by omega + rw [hm, hm2, hpas, Nat.cast_add] + have hstep1 : paritySeriesAux (m + 1) (k + 1 + 1) = + paritySeriesAux (m + 1) (k + 1) + + (Nat.choose (m + 1 + (k + 1)) (k + 1) : ℤ[X]) * X ^ (k + 1) := by + unfold paritySeriesAux + exact sum_range_succ _ (k + 1) + have hstep2 : paritySeriesAux m (k + 1 + 1) = + paritySeriesAux m (k + 1) + + (Nat.choose (m + (k + 1)) (k + 1) : ℤ[X]) * X ^ (k + 1) := by + unfold paritySeriesAux + exact sum_range_succ _ (k + 1) + have hm : m + (k + 1) + 1 = m + 1 + (k + 1) := by omega + rw [hstep1, mul_add, ih, hstep2, hm, hchoose] + ring + +private theorem one_sub_X_pow_mul_paritySeriesAux_add_sum (m k : ℕ) : + (1 - X) ^ (m + 1) * paritySeriesAux m (k + 1) + + X ^ (k + 1) * ∑ i ∈ range (m + 1), (Nat.choose (i + k) k : ℤ[X]) * (1 - X) ^ i = 1 := by + induction m with + | zero => + change (1 - X) ^ 1 * paritySeriesAux 0 (k + 1) + + X ^ (k + 1) * ∑ i ∈ range 1, (Nat.choose (i + k) k : ℤ[X]) * (1 - X) ^ i = 1 + simp only [pow_one, one_sub_X_mul_paritySeriesAux_zero, range_one, sum_singleton, zero_add, + Nat.choose_self, Nat.cast_one, pow_zero, mul_one, sub_add_cancel] + | succ m ih => + have hstep : + (1 - X) ^ (m + 1 + 1) * paritySeriesAux (m + 1) (k + 1) = + (1 - X) ^ (m + 1) * paritySeriesAux m (k + 1) - + X ^ (k + 1) * ((Nat.choose (m + 1 + k) k : ℤ[X]) * (1 - X) ^ (m + 1)) := by + calc + (1 - X) ^ (m + 1 + 1) * paritySeriesAux (m + 1) (k + 1) + = (1 - X) ^ (m + 1) * ((1 - X) * paritySeriesAux (m + 1) (k + 1)) := by ring + _ = (1 - X) ^ (m + 1) * + (paritySeriesAux m (k + 1) - (Nat.choose (m + k + 1) k : ℤ[X]) * X ^ (k + 1)) := by + rw [one_sub_X_mul_paritySeriesAux_succ] + _ = (1 - X) ^ (m + 1) * paritySeriesAux m (k + 1) - + X ^ (k + 1) * ((Nat.choose (m + 1 + k) k : ℤ[X]) * (1 - X) ^ (m + 1)) := by + have hm : m + k + 1 = m + 1 + k := by omega + rw [hm] + ring + rw [sum_range_succ, mul_add, hstep] + calc + (1 - X) ^ (m + 1) * paritySeriesAux m (k + 1) - + X ^ (k + 1) * ((Nat.choose (m + 1 + k) k : ℤ[X]) * (1 - X) ^ (m + 1)) + + (X ^ (k + 1) * ∑ i ∈ range (m + 1), (Nat.choose (i + k) k : ℤ[X]) * (1 - X) ^ i + + X ^ (k + 1) * ((Nat.choose (m + 1 + k) k : ℤ[X]) * (1 - X) ^ (m + 1))) + = (1 - X) ^ (m + 1) * paritySeriesAux m (k + 1) + + X ^ (k + 1) * ∑ i ∈ range (m + 1), (Nat.choose (i + k) k : ℤ[X]) * (1 - X) ^ i := by + ring + _ = 1 := ih + +/-- Exact Bezout identity for `parityAmplifier ℓ` (`ℓ ≥ 1`): +`p_ℓ(X) + X ^ ℓ * ∑ i ∈ range ℓ, choose (i + ℓ - 1) (ℓ - 1) * (1 - X) ^ i = 1`. -/ +theorem parityAmplifier_add_X_pow_mul_eq_one {ℓ : ℕ} (hℓ : 1 ≤ ℓ) : + parityAmplifier ℓ + + X ^ ℓ * ∑ i ∈ range ℓ, (Nat.choose (i + (ℓ - 1)) (ℓ - 1) : ℤ[X]) * (1 - X) ^ i = 1 := by + obtain ⟨k, rfl⟩ : ∃ k, ℓ = k + 1 := Nat.exists_eq_succ_of_ne_zero (by omega) + simpa only [parityAmplifier, parityKernel, add_tsub_cancel_right] using + one_sub_X_pow_mul_paritySeriesAux_add_sum k k + +/-- For `ℓ ≥ 1`, `X ^ ℓ` divides `1 - parityAmplifier ℓ` in `ℤ[X]`. -/ +theorem X_pow_dvd_one_sub_parityAmplifier {ℓ : ℕ} (hℓ : 1 ≤ ℓ) : + X ^ ℓ ∣ 1 - parityAmplifier ℓ := by + refine ⟨∑ i ∈ range ℓ, (Nat.choose (i + (ℓ - 1)) (ℓ - 1) : ℤ[X]) * (1 - X) ^ i, ?_⟩ + exact (eq_sub_of_add_eq' (parityAmplifier_add_X_pow_mul_eq_one hℓ)).symm + +/-- At any even integer `y`, `parityAmplifier ℓ` (`ℓ ≥ 1`) evaluates to `1` modulo `2 ^ ℓ`. -/ +theorem parityAmplifier_eval_modEq_one_of_even {ℓ : ℕ} (hℓ : 1 ≤ ℓ) {y : ℤ} (hy : Even y) : + (parityAmplifier ℓ).eval y ≡ 1 [ZMOD (2 : ℤ) ^ ℓ] := by + rw [Int.modEq_iff_dvd] + obtain ⟨q, hq⟩ := X_pow_dvd_one_sub_parityAmplifier hℓ + have heval : 1 - (parityAmplifier ℓ).eval y = y ^ ℓ * q.eval y := by + have := congr_arg (eval y) hq + simpa only [eval_sub, eval_one, eval_mul, eval_pow, eval_X] using this + rw [heval] + obtain ⟨k, rfl⟩ := hy + have h2 : (2 : ℤ) ∣ k + k := ⟨k, by ring⟩ + exact dvd_mul_of_dvd_left (pow_dvd_pow_of_dvd h2 ℓ) _ + +/-- At any odd integer `y`, `parityAmplifier ℓ` evaluates to `0` modulo `2 ^ ℓ`. -/ +theorem parityAmplifier_eval_modEq_zero_of_odd (ℓ : ℕ) {y : ℤ} (hy : Odd y) : + (parityAmplifier ℓ).eval y ≡ 0 [ZMOD (2 : ℤ) ^ ℓ] := by + rw [Int.modEq_iff_dvd, zero_sub, dvd_neg] + obtain ⟨q, hq⟩ := one_sub_X_pow_dvd_parityAmplifier ℓ + have heval : (parityAmplifier ℓ).eval y = (1 - y) ^ ℓ * q.eval y := by + have := congr_arg (eval y) hq + simpa only [eval_mul, eval_pow, eval_sub, eval_one, eval_X] using this + rw [heval] + obtain ⟨k, rfl⟩ := hy + have h2 : (2 : ℤ) ∣ 1 - (2 * k + 1) := ⟨-k, by ring⟩ + exact dvd_mul_of_dvd_left (pow_dvd_pow_of_dvd h2 ℓ) _ + +/-- **Lemma 5.1 (parity congruence)**: for `ℓ ≥ 1` and `y ∈ ℤ`, +`p_ℓ(y) ≡ (if Even y then 1 else 0) (mod 2 ^ ℓ)`. -/ +theorem parityAmplifier_eval_modEq_two_pow {ℓ : ℕ} (hℓ : 1 ≤ ℓ) (y : ℤ) [Decidable (Even y)] : + (parityAmplifier ℓ).eval y ≡ (if Even y then 1 else 0) [ZMOD (2 : ℤ) ^ ℓ] := by + split_ifs with hy + · exact parityAmplifier_eval_modEq_one_of_even hℓ hy + · exact parityAmplifier_eval_modEq_zero_of_odd ℓ (Int.not_even_iff_odd.mp hy) + +/-! ### 2. Base-`h(X)` expansion (`h(X) = X ^ 2 - X`) and degree bounds -/ + +/-- The monic quadratic `h(X) = X ^ 2 - X = X * (X - 1)` in `ℤ[X]`. -/ +def hPoly : ℤ[X] := + X ^ 2 - X + +/-- `hPoly = X ^ 2 - X` is monic. -/ +theorem monic_hPoly : hPoly.Monic := by + apply Monic.sub_of_left (monic_X_pow 2) + rw [degree_X, degree_X_pow] + decide + +/-- `hPoly` has degree `2`. -/ +@[simp] +theorem natDegree_hPoly : hPoly.natDegree = 2 := by + rw [hPoly, natDegree_sub_eq_left_of_natDegree_lt] + · exact natDegree_X_pow 2 + · rw [natDegree_X, natDegree_X_pow] + omega + +/-- `hPoly` is not equal to `1`. -/ +theorem hPoly_ne_one : hPoly ≠ 1 := by + intro h + have := congr_arg natDegree h + rw [natDegree_hPoly, natDegree_one] at this + omega + +/-- Evaluation of an integer polynomial `P : ℤ[X]` at `y : A` via the canonical cast `ℤ →+* A`. -/ +def evalInt {A : Type*} [CommRing A] (y : A) (P : ℤ[X]) : A := + P.eval₂ (Int.castRingHom A) y + +/-- On `ℤ`, `evalInt` coincides with `Polynomial.eval`. -/ +@[simp] +theorem evalInt_int (y : ℤ) (P : ℤ[X]) : evalInt y P = P.eval y := by + simp only [evalInt, Int.castRingHom_int, eval₂_id] + +/-- Evaluating `hPoly` at `y : A` gives `y ^ 2 - y`. -/ +@[simp] +theorem evalInt_hPoly {A : Type*} [CommRing A] (y : A) : + evalInt y hPoly = y ^ 2 - y := by + simp only [evalInt, hPoly, eval₂_sub, eval₂_X_pow, eval₂_X] + +/-- Evaluating `hPoly` at `y : ℤ` gives `y ^ 2 - y`. -/ +@[simp] +theorem eval_hPoly (y : ℤ) : hPoly.eval y = y ^ 2 - y := by + simp only [hPoly, eval_sub, eval_pow, eval_X] + +/-- For every integer `y`, `h(y) = y ^ 2 - y` is even. -/ +theorem two_dvd_eval_hPoly (y : ℤ) : (2 : ℤ) ∣ hPoly.eval y := by + rw [eval_hPoly] + rcases Int.even_or_odd y with ⟨k, rfl⟩ | ⟨k, rfl⟩ + · refine ⟨(k + k) * k - k, by ring⟩ + · refine ⟨(2 * k + 1) * k, by ring⟩ + +/-- Iterated monic quotient of `P : ℤ[X]` on division by `hPoly = X ^ 2 - X`. -/ +def iterDivByH (P : ℤ[X]) : ℕ → ℤ[X] + | 0 => P + | j + 1 => iterDivByH P j /ₘ hPoly + +/-- The `j`-th remainder `(iterDivByH P j) %ₘ hPoly` in the base-`hPoly` expansion of `P`. -/ +def baseDigitByH (P : ℤ[X]) (j : ℕ) : ℤ[X] := + iterDivByH P j %ₘ hPoly + +/-- The `j`-th linear remainder `e_j(X)` in the base-`(X ^ 2 - X)` expansion of `p_ℓ(X)`. -/ +def parityBaseDigit (ℓ j : ℕ) : ℤ[X] := + baseDigitByH (parityAmplifier ℓ) j + +/-- Remainder modulo `hPoly` has degree at most `1`. -/ +theorem natDegree_modByMonic_hPoly_le (P : ℤ[X]) : (P %ₘ hPoly).natDegree ≤ 1 := by + have hlt := natDegree_modByMonic_lt P monic_hPoly hPoly_ne_one + rw [natDegree_hPoly] at hlt + omega + +/-- Each `baseDigitByH P j` has degree at most `1`. -/ +theorem natDegree_baseDigitByH_le (P : ℤ[X]) (j : ℕ) : + (baseDigitByH P j).natDegree ≤ 1 := + natDegree_modByMonic_hPoly_le (iterDivByH P j) + +/-- Each `parityBaseDigit ℓ j` (`e_j`) has degree at most `1`. -/ +theorem natDegree_parityBaseDigit_le (ℓ j : ℕ) : + (parityBaseDigit ℓ j).natDegree ≤ 1 := + natDegree_baseDigitByH_le (parityAmplifier ℓ) j + +/-- Any polynomial of degree at most `1` equals `C (q.coeff 0) + C (q.coeff 1) * X`. -/ +theorem eq_C_add_C_mul_X_of_natDegree_le_one {R : Type*} [Semiring R] {q : R[X]} + (hq : q.natDegree ≤ 1) : + q = C (q.coeff 0) + C (q.coeff 1) * X := by + ext n + rcases n with _ | _ | n + · simp only [coeff_add, coeff_C_zero, coeff_mul_X_zero, add_zero] + · simp only [coeff_add, coeff_C_succ, coeff_mul_X, coeff_C_zero, zero_add] + · have hn : q.natDegree < n + 2 := by omega + rw [coeff_eq_zero_of_natDegree_lt hn] + simp only [coeff_add, coeff_C_succ, coeff_mul_X, zero_add] + +/-- Explicit affine decomposition `e_j(X) = a_j + b_j X` of `parityBaseDigit ℓ j`. -/ +theorem parityBaseDigit_eq_C_add_C_mul_X (ℓ j : ℕ) : + parityBaseDigit ℓ j = + C ((parityBaseDigit ℓ j).coeff 0) + C ((parityBaseDigit ℓ j).coeff 1) * X := + eq_C_add_C_mul_X_of_natDegree_le_one (natDegree_parityBaseDigit_le ℓ j) + +/-- Division expansion after `m` steps of monic division by `hPoly`: +`P = (∑ j ∈ range m, baseDigitByH P j * hPoly ^ j) + iterDivByH P m * hPoly ^ m`. -/ +theorem eq_sum_baseDigitByH_add_iterDivByH (P : ℤ[X]) (m : ℕ) : + P = (∑ j ∈ range m, baseDigitByH P j * hPoly ^ j) + iterDivByH P m * hPoly ^ m := by + induction m with + | zero => + simp only [range_zero, sum_empty, iterDivByH, pow_zero, mul_one, zero_add] + | succ m ih => + have hstep := modByMonic_add_div (iterDivByH P m) hPoly + calc + P = (∑ j ∈ range m, baseDigitByH P j * hPoly ^ j) + iterDivByH P m * hPoly ^ m := ih + _ = (∑ j ∈ range m, baseDigitByH P j * hPoly ^ j) + + (iterDivByH P m %ₘ hPoly + hPoly * (iterDivByH P m /ₘ hPoly)) * hPoly ^ m := by + rw [hstep] + _ = (∑ j ∈ range (m + 1), baseDigitByH P j * hPoly ^ j) + + iterDivByH P (m + 1) * hPoly ^ (m + 1) := by + rw [sum_range_succ] + simp only [baseDigitByH, iterDivByH, pow_succ] + ring + +/-- `iterDivByH P j` has degree `P.natDegree - 2 * j`. -/ +theorem natDegree_iterDivByH (P : ℤ[X]) (j : ℕ) : + (iterDivByH P j).natDegree = P.natDegree - 2 * j := by + induction j with + | zero => simp only [iterDivByH, mul_zero, Nat.sub_zero] + | succ j ih => + rw [iterDivByH, natDegree_divByMonic _ monic_hPoly, ih, natDegree_hPoly] + omega + +/-- `iterDivByH P j` vanishes once `P.natDegree < 2 * j` (or `P = 0`). -/ +theorem iterDivByH_eq_zero_of_natDegree_lt {P : ℤ[X]} {j : ℕ} + (h : P = 0 ∨ P.natDegree < 2 * j) : + iterDivByH P j = 0 := by + induction j with + | zero => + rcases h with rfl | hlt + · rfl + · omega + | succ j ih => + by_cases h0 : iterDivByH P j = 0 + · simp only [iterDivByH, h0, zero_divByMonic] + · rw [iterDivByH, (divByMonic_eq_zero_iff monic_hPoly).mpr] + rw [degree_eq_natDegree h0, degree_eq_natDegree monic_hPoly.ne_zero, Nat.cast_lt, + natDegree_iterDivByH, natDegree_hPoly] + rcases h with rfl | hlt + · exfalso + apply h0 + exact ih (Or.inl rfl) + · omega + +private theorem natDegree_paritySeriesAux_le (m K : ℕ) : + (paritySeriesAux m K).natDegree ≤ K - 1 := by + refine natDegree_sum_le_of_forall_le (range K) _ fun j hj => ?_ + rw [mem_range] at hj + refine natDegree_mul_le.trans ?_ + rw [natDegree_natCast, zero_add, natDegree_X_pow] + omega + +/-- `parityKernel ℓ` has degree at most `ℓ - 1`. -/ +theorem natDegree_parityKernel_le (ℓ : ℕ) : + (parityKernel ℓ).natDegree ≤ ℓ - 1 := + natDegree_paritySeriesAux_le (ℓ - 1) ℓ + +/-- `parityAmplifier ℓ` has degree at most `2 * ℓ - 1`. -/ +theorem natDegree_parityAmplifier_le (ℓ : ℕ) : + (parityAmplifier ℓ).natDegree ≤ 2 * ℓ - 1 := by + rw [parityAmplifier] + refine natDegree_mul_le.trans ?_ + have h1 : ((1 - X : ℤ[X]) ^ ℓ).natDegree ≤ ℓ := by + refine natDegree_pow_le.trans ?_ + have h1X : (1 - X : ℤ[X]).natDegree ≤ 1 := by + refine (natDegree_sub_le 1 X).trans ?_ + simp only [natDegree_one, natDegree_X, max_le_iff, zero_le, le_refl, and_self] + nlinarith + have h2 := natDegree_parityKernel_le ℓ + omega + +/-- After `ℓ` divisions by `hPoly`, the quotient of `parityAmplifier ℓ` is `0`. -/ +theorem iterDivByH_parityAmplifier_self (ℓ : ℕ) : + iterDivByH (parityAmplifier ℓ) ℓ = 0 := by + rcases Nat.eq_zero_or_pos ℓ with rfl | hℓ + · exact iterDivByH_eq_zero_of_natDegree_lt (Or.inl parityAmplifier_zero) + · apply iterDivByH_eq_zero_of_natDegree_lt + right + have := natDegree_parityAmplifier_le ℓ + omega + +/-- **Lemma 5.1 (base-`h` decomposition)**: for every `ℓ : ℕ`, +`parityAmplifier ℓ = ∑ j ∈ range ℓ, parityBaseDigit ℓ j * hPoly ^ j`. -/ +theorem parityAmplifier_eq_sum_baseDigit (ℓ : ℕ) : + parityAmplifier ℓ = ∑ j ∈ range ℓ, parityBaseDigit ℓ j * hPoly ^ j := by + have h := eq_sum_baseDigitByH_add_iterDivByH (parityAmplifier ℓ) ℓ + rw [iterDivByH_parityAmplifier_self, zero_mul, add_zero] at h + exact h + +/-- Evaluation of `parityAmplifier ℓ` in any commutative ring `A` via `parityBaseDigit`. -/ +theorem evalInt_parityAmplifier_eq_sum {A : Type*} [CommRing A] (ℓ : ℕ) (y : A) : + evalInt y (parityAmplifier ℓ) = + ∑ j ∈ range ℓ, evalInt y (parityBaseDigit ℓ j) * (y ^ 2 - y) ^ j := by + unfold evalInt + rw [← coe_eval₂RingHom] + conv_lhs => rw [parityAmplifier_eq_sum_baseDigit ℓ] + rw [map_sum] + refine sum_congr rfl fun j _ => ?_ + rw [map_mul, map_pow, coe_eval₂RingHom] + congr 2 + exact evalInt_hPoly y + +/-! ### 3. Coefficient and `ℓ₁`-norm bounds (Lemma B.1) -/ + +/-- The `ℓ₁` coefficient norm `∑ i ∈ p.support, (p.coeff i).natAbs` of an integer polynomial. -/ +def coeffNorm1 (p : ℤ[X]) : ℕ := + ∑ i ∈ p.support, (p.coeff i).natAbs + +/-- The `ℓ₁` norm of `0` is `0`. -/ +@[simp] +theorem coeffNorm1_zero : coeffNorm1 0 = 0 := by + simp only [coeffNorm1, support_zero, sum_empty] + +/-- Every individual coefficient of `p` has absolute value at most `coeffNorm1 p`. -/ +theorem natAbs_coeff_le_coeffNorm1 (p : ℤ[X]) (k : ℕ) : + (p.coeff k).natAbs ≤ coeffNorm1 p := by + by_cases hk : k ∈ p.support + · exact single_le_sum (f := fun i => (p.coeff i).natAbs) (fun _ _ => Nat.zero_le _) hk + · rw [notMem_support_iff.mp hk, Int.natAbs_zero] + exact Nat.zero_le _ + +/-- The sum of `|p.coeff i|` over any finite set of indices is at most `coeffNorm1 p`. -/ +theorem sum_natAbs_coeff_le_coeffNorm1 (p : ℤ[X]) (s : Finset ℕ) : + ∑ i ∈ s, (p.coeff i).natAbs ≤ coeffNorm1 p := by + have hsub : ∑ i ∈ s, (p.coeff i).natAbs = ∑ i ∈ s ∩ p.support, (p.coeff i).natAbs := by + refine (sum_subset inter_subset_left ?_).symm + intro i hi his + rw [mem_inter, not_and_or, notMem_support_iff] at his + rcases his with hns | hp0 + · exact absurd hi hns + · simp only [hp0, Int.natAbs_zero] + rw [hsub, coeffNorm1] + exact sum_le_sum_of_subset inter_subset_right + +/-- Triangle inequality for `coeffNorm1`. -/ +theorem coeffNorm1_add_le (p q : ℤ[X]) : + coeffNorm1 (p + q) ≤ coeffNorm1 p + coeffNorm1 q := by + have hsub : (p + q).support ⊆ p.support ∪ q.support := support_add + calc + coeffNorm1 (p + q) + ≤ ∑ i ∈ p.support ∪ q.support, ((p + q).coeff i).natAbs := + sum_le_sum_of_subset hsub + _ ≤ ∑ i ∈ p.support ∪ q.support, ((p.coeff i).natAbs + (q.coeff i).natAbs) := by + refine sum_le_sum fun i _ => ?_ + rw [coeff_add] + exact Int.natAbs_add_le _ _ + _ = (∑ i ∈ p.support ∪ q.support, (p.coeff i).natAbs) + + ∑ i ∈ p.support ∪ q.support, (q.coeff i).natAbs := sum_add_distrib + _ ≤ coeffNorm1 p + coeffNorm1 q := + add_le_add (sum_natAbs_coeff_le_coeffNorm1 p _) (sum_natAbs_coeff_le_coeffNorm1 q _) + +/-- Multiplying by `X ^ k` does not increase `coeffNorm1`. -/ +theorem coeffNorm1_mul_X_pow_le (p : ℤ[X]) (k : ℕ) : + coeffNorm1 (p * X ^ k) ≤ coeffNorm1 p := by + rw [coeffNorm1] + have hsub : (p * X ^ k).support ⊆ p.support.map ⟨fun i => i + k, add_left_injective k⟩ := by + intro i hi + rw [mem_support_iff] at hi + rw [mem_map] + by_cases hik : k ≤ i + · refine ⟨i - k, ?_, by simp only [Function.Embedding.coeFn_mk]; omega⟩ + rw [mem_support_iff] + intro h0 + apply hi + have hi_eq : i = i - k + k := (Nat.sub_add_cancel hik).symm + rw [hi_eq, coeff_mul_X_pow, h0] + · exfalso + apply hi + rw [mul_comm, coeff_X_pow_mul'] + simp only [hik, ↓reduceIte] + refine (sum_le_sum_of_subset hsub).trans ?_ + rw [sum_map] + refine le_of_eq (sum_congr rfl fun i _ => ?_) + simp only [Function.Embedding.coeFn_mk, coeff_mul_X_pow] + +/-- The `ℓ₁` norm of a constant polynomial `C a` is `a.natAbs`. -/ +theorem coeffNorm1_C (a : ℤ) : coeffNorm1 (C a) = a.natAbs := by + by_cases ha : a = 0 + · subst ha + simp only [map_zero, coeffNorm1_zero, Int.natAbs_zero] + · rw [coeffNorm1, support_C ha, sum_singleton, coeff_C_zero] + +/-- Scaling by `C a` scales `coeffNorm1` by at most `a.natAbs`. -/ +theorem coeffNorm1_C_mul_le (a : ℤ) (p : ℤ[X]) : + coeffNorm1 (C a * p) ≤ a.natAbs * coeffNorm1 p := by + have hsub : (C a * p).support ⊆ p.support := by + intro i hi + rw [mem_support_iff, coeff_C_mul] at hi + exact mem_support_iff.mpr (right_ne_zero_of_mul hi) + calc + coeffNorm1 (C a * p) ≤ ∑ i ∈ p.support, ((C a * p).coeff i).natAbs := + sum_le_sum_of_subset hsub + _ = a.natAbs * coeffNorm1 p := by + rw [coeffNorm1, mul_sum] + refine sum_congr rfl fun i _ => ?_ + rw [coeff_C_mul, Int.natAbs_mul] + +/-- Multiplying by `1 - X` increases `coeffNorm1` by at most a factor of `2`. -/ +theorem coeffNorm1_one_sub_X_mul_le (p : ℤ[X]) : + coeffNorm1 ((1 - X) * p) ≤ 2 * coeffNorm1 p := by + have hEq : (1 - X) * p = p + C (-1) * (p * X ^ 1) := by + rw [map_neg, map_one] + ring + rw [hEq, two_mul] + refine (coeffNorm1_add_le _ _).trans (add_le_add le_rfl ?_) + have h1 := coeffNorm1_C_mul_le (-1) (p * X ^ 1) + have h2 := coeffNorm1_mul_X_pow_le p 1 + simp only [Int.natAbs_neg, Int.natAbs_one, one_mul] at h1 + exact h1.trans h2 + +/-- Multiplying by `(1 - X) ^ ℓ` increases `coeffNorm1` by at most a factor of `2 ^ ℓ`. -/ +theorem coeffNorm1_one_sub_X_pow_mul_le (ℓ : ℕ) (p : ℤ[X]) : + coeffNorm1 ((1 - X) ^ ℓ * p) ≤ 2 ^ ℓ * coeffNorm1 p := by + induction ℓ with + | zero => simp only [pow_zero, one_mul, le_refl] + | succ ℓ ih => + have hEq : (1 - X) ^ (ℓ + 1) * p = (1 - X) * ((1 - X) ^ ℓ * p) := by ring + rw [hEq, pow_succ', mul_assoc] + exact (coeffNorm1_one_sub_X_mul_le _).trans (Nat.mul_le_mul_left 2 ih) + +private theorem sum_range_choose_add (m k : ℕ) : + ∑ j ∈ range (k + 1), Nat.choose (m + j) j = Nat.choose (m + k + 1) k := by + induction k with + | zero => + change ∑ j ∈ range 1, Nat.choose (m + j) j = Nat.choose (m + 0 + 1) 0 + simp only [range_one, sum_singleton, add_zero, Nat.choose_zero_right] + | succ k ih => + rw [sum_range_succ, ih] + have hpas : Nat.choose (m + k + 1 + 1) (k + 1) = + Nat.choose (m + k + 1) k + Nat.choose (m + k + 1) (k + 1) := + Nat.choose_succ_succ (m + k + 1) k + have hm1 : m + (k + 1) = m + k + 1 := by omega + rw [hm1, ← hpas] + +private theorem choose_le_two_pow (n k : ℕ) : Nat.choose n k ≤ 2 ^ n := by + by_cases hk : k ≤ n + · rw [← Nat.sum_range_choose n] + exact single_le_sum (f := fun i => Nat.choose n i) (fun _ _ => Nat.zero_le _) + (mem_range.mpr (by omega)) + · rw [Nat.choose_eq_zero_of_lt (by omega)] + exact Nat.zero_le _ + +/-- The `ℓ₁` norm of `parityKernel ℓ` is at most `2 ^ (2 * ℓ)`. -/ +theorem coeffNorm1_parityKernel_le (ℓ : ℕ) : + coeffNorm1 (parityKernel ℓ) ≤ 2 ^ (2 * ℓ) := by + have hsum : ∀ K, coeffNorm1 (paritySeriesAux (ℓ - 1) K) ≤ + ∑ j ∈ range K, Nat.choose (ℓ - 1 + j) j := by + intro K + induction K with + | zero => + simp only [paritySeriesAux, range_zero, sum_empty, coeffNorm1_zero, le_refl] + | succ K ih => + rw [paritySeriesAux, sum_range_succ, ← paritySeriesAux, sum_range_succ] + refine (coeffNorm1_add_le _ _).trans (add_le_add ih ?_) + have hterm : ((Nat.choose (ℓ - 1 + K) K : ℤ[X]) * X ^ K) = + C (Nat.choose (ℓ - 1 + K) K : ℤ) * X ^ K := by simp only [eq_intCast, Int.cast_natCast] + rw [hterm] + refine (coeffNorm1_mul_X_pow_le _ _).trans ?_ + rw [coeffNorm1_C, Int.natAbs_natCast] + rcases Nat.eq_zero_or_pos ℓ with rfl | hℓ + · exact (hsum 0).trans (by simp only [range_zero, sum_empty, zero_le]) + · obtain ⟨k, rfl⟩ : ∃ k, ℓ = k + 1 := Nat.exists_eq_succ_of_ne_zero (by omega) + refine (hsum (k + 1)).trans ?_ + simp only [add_tsub_cancel_right] + rw [sum_range_choose_add k k] + exact (choose_le_two_pow (k + k + 1) k).trans + (Nat.pow_le_pow_right (by omega) (by omega)) + +/-- **Lemma B.1 (`ℓ₁`-norm of `p_ℓ`)**: `‖p_ℓ‖₁ ≤ 2 ^ (3 * ℓ)`. -/ +theorem coeffNorm1_parityAmplifier_le (ℓ : ℕ) : + coeffNorm1 (parityAmplifier ℓ) ≤ 2 ^ (3 * ℓ) := by + rw [parityAmplifier] + calc + coeffNorm1 ((1 - X) ^ ℓ * parityKernel ℓ) + ≤ 2 ^ ℓ * coeffNorm1 (parityKernel ℓ) := coeffNorm1_one_sub_X_pow_mul_le ℓ _ + _ ≤ 2 ^ ℓ * 2 ^ (2 * ℓ) := Nat.mul_le_mul_left (2 ^ ℓ) (coeffNorm1_parityKernel_le ℓ) + _ = 2 ^ (3 * ℓ) := by + rw [← pow_add] + congr 1 + omega + +/-- Recurrence for the coefficients of the quotient `p /ₘ hPoly`. -/ +theorem coeff_divByMonic_hPoly_rec (p : ℤ[X]) (n : ℕ) : + (p /ₘ hPoly).coeff n = p.coeff (n + 2) + (p /ₘ hPoly).coeff (n + 1) := by + have h := congr_arg (fun q : ℤ[X] => q.coeff (n + 2)) (modByMonic_add_div p hPoly) + rw [coeff_add] at h + have hmod : (p %ₘ hPoly).coeff (n + 2) = 0 := by + apply coeff_eq_zero_of_natDegree_lt + have := natDegree_modByMonic_hPoly_le p + omega + have hmul : (hPoly * (p /ₘ hPoly)).coeff (n + 2) = + (p /ₘ hPoly).coeff n - (p /ₘ hPoly).coeff (n + 1) := by + have hEq : hPoly * (p /ₘ hPoly) = (p /ₘ hPoly) * X ^ 2 - (p /ₘ hPoly) * X := by + rw [hPoly] + ring + rw [hEq, coeff_sub, coeff_mul_X_pow, coeff_mul_X] + linarith + +/-- Telescoping sum formula for the coefficients of `p /ₘ hPoly`. -/ +theorem coeff_divByMonic_hPoly_sum (p : ℤ[X]) (n m : ℕ) : + (p /ₘ hPoly).coeff n = + (∑ t ∈ range m, p.coeff (n + 2 + t)) + (p /ₘ hPoly).coeff (n + m) := by + induction m with + | zero => simp only [range_zero, sum_empty, add_zero, zero_add] + | succ m ih => + rw [sum_range_succ, ih, coeff_divByMonic_hPoly_rec p (n + m)] + have hidx : n + m + 2 = n + 2 + m := by omega + have hidx2 : n + (m + 1) = n + m + 1 := by omega + rw [hidx, hidx2] + ring + +/-- The constant coefficient of `p %ₘ hPoly` equals `p.coeff 0`. -/ +theorem coeff_modByMonic_hPoly_zero (p : ℤ[X]) : + (p %ₘ hPoly).coeff 0 = p.coeff 0 := by + have h := congr_arg (fun q : ℤ[X] => q.coeff 0) (modByMonic_add_div p hPoly) + rw [coeff_add] at h + have hmul : (hPoly * (p /ₘ hPoly)).coeff 0 = 0 := by + have hEq : hPoly * (p /ₘ hPoly) = (p /ₘ hPoly) * X * X - (p /ₘ hPoly) * X := by + rw [hPoly] + ring + rw [hEq, coeff_sub, coeff_mul_X_zero, coeff_mul_X_zero, sub_self] + linarith + +/-- The linear coefficient of `p %ₘ hPoly` equals `p.coeff 1 + (p /ₘ hPoly).coeff 0`. -/ +theorem coeff_modByMonic_hPoly_one (p : ℤ[X]) : + (p %ₘ hPoly).coeff 1 = p.coeff 1 + (p /ₘ hPoly).coeff 0 := by + have h := congr_arg (fun q : ℤ[X] => q.coeff 1) (modByMonic_add_div p hPoly) + rw [coeff_add] at h + have hmul : (hPoly * (p /ₘ hPoly)).coeff 1 = -(p /ₘ hPoly).coeff 0 := by + have hEq : hPoly * (p /ₘ hPoly) = (p /ₘ hPoly) * X ^ 2 - (p /ₘ hPoly) * X := by + rw [hPoly] + ring + rw [hEq, coeff_sub, coeff_mul_X] + have hsq : ((p /ₘ hPoly) * X ^ 2).coeff 1 = 0 := by + rw [mul_comm, coeff_X_pow_mul'] + simp only [Nat.not_le_of_gt (by decide : 1 < 2), ↓reduceIte] + rw [hsq, zero_sub] + linarith + +private theorem natAbs_sum_le {ι : Type*} (s : Finset ι) (f : ι → ℤ) : + (∑ i ∈ s, f i).natAbs ≤ ∑ i ∈ s, (f i).natAbs := by + classical + induction s using Finset.induction_on with + | empty => simp only [sum_empty, Int.natAbs_zero, le_refl] + | insert a s ha ih => + rw [sum_insert ha, sum_insert ha] + exact (Int.natAbs_add_le _ _).trans (add_le_add le_rfl ih) + +/-- Every coefficient of `p /ₘ hPoly` has absolute value at most `coeffNorm1 p`. -/ +theorem natAbs_coeff_divByMonic_hPoly_le (p : ℤ[X]) (n : ℕ) : + ((p /ₘ hPoly).coeff n).natAbs ≤ coeffNorm1 p := by + rw [coeff_divByMonic_hPoly_sum p n (p.natDegree + 1)] + have htail : (p /ₘ hPoly).coeff (n + (p.natDegree + 1)) = 0 := by + apply coeff_eq_zero_of_natDegree_lt + rw [natDegree_divByMonic p monic_hPoly, natDegree_hPoly] + omega + rw [htail, add_zero] + refine (natAbs_sum_le _ _).trans ?_ + let emb : ℕ ↪ ℕ := ⟨fun t => n + 2 + t, add_right_injective (n + 2)⟩ + have hmap : ∑ t ∈ range (p.natDegree + 1), (p.coeff (n + 2 + t)).natAbs = + ∑ i ∈ (range (p.natDegree + 1)).map emb, (p.coeff i).natAbs := by + rw [sum_map] + rfl + rw [hmap] + exact sum_natAbs_coeff_le_coeffNorm1 p _ + +/-- Every coefficient of `p %ₘ hPoly` has absolute value at most `coeffNorm1 p`. -/ +theorem natAbs_coeff_modByMonic_hPoly_le (p : ℤ[X]) (k : ℕ) : + ((p %ₘ hPoly).coeff k).natAbs ≤ coeffNorm1 p := by + rcases k with _ | _ | k + · rw [coeff_modByMonic_hPoly_zero] + exact natAbs_coeff_le_coeffNorm1 p 0 + · rw [coeff_modByMonic_hPoly_one, coeff_divByMonic_hPoly_sum p 0 (p.natDegree + 1)] + have htail : (p /ₘ hPoly).coeff (0 + (p.natDegree + 1)) = 0 := by + apply coeff_eq_zero_of_natDegree_lt + rw [natDegree_divByMonic p monic_hPoly, natDegree_hPoly] + omega + rw [htail, add_zero] + have hsum : p.coeff 1 + ∑ t ∈ range (p.natDegree + 1), p.coeff (0 + 2 + t) = + ∑ t ∈ range (p.natDegree + 2), p.coeff (1 + t) := by + rw [sum_range_succ' (fun t => p.coeff (1 + t)) (p.natDegree + 1), add_zero, add_comm] + congr 1 + refine sum_congr rfl fun t _ => ?_ + congr 1 + omega + rw [hsum] + refine (natAbs_sum_le _ _).trans ?_ + let emb : ℕ ↪ ℕ := ⟨fun t => 1 + t, add_right_injective 1⟩ + have hmap : ∑ t ∈ range (p.natDegree + 2), (p.coeff (1 + t)).natAbs = + ∑ i ∈ (range (p.natDegree + 2)).map emb, (p.coeff i).natAbs := by + rw [sum_map] + rfl + rw [hmap] + exact sum_natAbs_coeff_le_coeffNorm1 p _ + · have h0 : (p %ₘ hPoly).coeff (k + 2) = 0 := by + apply coeff_eq_zero_of_natDegree_lt + have := natDegree_modByMonic_hPoly_le p + omega + rw [h0, Int.natAbs_zero] + exact Nat.zero_le _ + +/-- The `ℓ₁` norm of `p %ₘ hPoly` is at most `2 * coeffNorm1 p`. -/ +theorem coeffNorm1_modByMonic_hPoly_le (p : ℤ[X]) : + coeffNorm1 (p %ₘ hPoly) ≤ 2 * coeffNorm1 p := by + have hsub : (p %ₘ hPoly).support ⊆ range 2 := by + intro i hi + rw [mem_support_iff] at hi + rw [mem_range] + by_contra hge + apply hi + apply coeff_eq_zero_of_natDegree_lt + have := natDegree_modByMonic_hPoly_le p + omega + calc + coeffNorm1 (p %ₘ hPoly) ≤ ∑ i ∈ range 2, ((p %ₘ hPoly).coeff i).natAbs := + sum_le_sum_of_subset hsub + _ ≤ ∑ _i ∈ range 2, coeffNorm1 p := + sum_le_sum fun i _ => natAbs_coeff_modByMonic_hPoly_le p i + _ = 2 * coeffNorm1 p := by + rw [sum_const, card_range, smul_eq_mul] + +/-- The `ℓ₁` norm of `p /ₘ hPoly` is at most `p.natDegree * coeffNorm1 p`. -/ +theorem coeffNorm1_divByMonic_hPoly_le (p : ℤ[X]) : + coeffNorm1 (p /ₘ hPoly) ≤ p.natDegree * coeffNorm1 p := by + by_cases hdiv : p /ₘ hPoly = 0 + · rw [hdiv, coeffNorm1_zero] + exact Nat.zero_le _ + · have hdeg : 2 ≤ p.natDegree := by + by_contra hlt + apply hdiv + rw [divByMonic_eq_zero_iff monic_hPoly] + by_cases hp0 : p = 0 + · subst hp0 + rw [degree_zero, degree_eq_natDegree monic_hPoly.ne_zero] + exact WithBot.bot_lt_coe _ + · rw [degree_eq_natDegree hp0, degree_eq_natDegree monic_hPoly.ne_zero, Nat.cast_lt, + natDegree_hPoly] + omega + have hsub : (p /ₘ hPoly).support ⊆ range p.natDegree := by + intro i hi + rw [mem_support_iff] at hi + rw [mem_range] + by_contra hge + apply hi + apply coeff_eq_zero_of_natDegree_lt + rw [natDegree_divByMonic p monic_hPoly, natDegree_hPoly] + omega + calc + coeffNorm1 (p /ₘ hPoly) ≤ ∑ i ∈ range p.natDegree, ((p /ₘ hPoly).coeff i).natAbs := + sum_le_sum_of_subset hsub + _ ≤ ∑ _i ∈ range p.natDegree, coeffNorm1 p := + sum_le_sum fun i _ => natAbs_coeff_divByMonic_hPoly_le p i + _ = p.natDegree * coeffNorm1 p := by + rw [sum_const, card_range, smul_eq_mul] + +/-- After `j` monic divisions by `hPoly`, `coeffNorm1 (iterDivByH p j)` is at most +`p.natDegree ^ j * coeffNorm1 p`. -/ +theorem coeffNorm1_iterDivByH_le (p : ℤ[X]) (j : ℕ) : + coeffNorm1 (iterDivByH p j) ≤ p.natDegree ^ j * coeffNorm1 p := by + induction j with + | zero => simp only [iterDivByH, pow_zero, one_mul, le_refl] + | succ j ih => + rw [iterDivByH] + calc + coeffNorm1 (iterDivByH p j /ₘ hPoly) + ≤ (iterDivByH p j).natDegree * coeffNorm1 (iterDivByH p j) := + coeffNorm1_divByMonic_hPoly_le _ + _ ≤ p.natDegree * (p.natDegree ^ j * coeffNorm1 p) := by + refine Nat.mul_le_mul ?_ ih + rw [natDegree_iterDivByH] + omega + _ = p.natDegree ^ (j + 1) * coeffNorm1 p := by + rw [pow_succ'] + ring + +/-- **Lemma B.1 (coefficient bound for `e_j`)**: every coefficient of `parityBaseDigit ℓ j` has +absolute value at most `(2 * ℓ) ^ j * 2 ^ (3 * ℓ)`. -/ +theorem natAbs_coeff_parityBaseDigit_le (ℓ j k : ℕ) : + ((parityBaseDigit ℓ j).coeff k).natAbs ≤ (2 * ℓ) ^ j * 2 ^ (3 * ℓ) := by + rw [parityBaseDigit, baseDigitByH] + calc + ((iterDivByH (parityAmplifier ℓ) j %ₘ hPoly).coeff k).natAbs + ≤ coeffNorm1 (iterDivByH (parityAmplifier ℓ) j) := + natAbs_coeff_modByMonic_hPoly_le _ k + _ ≤ (parityAmplifier ℓ).natDegree ^ j * coeffNorm1 (parityAmplifier ℓ) := + coeffNorm1_iterDivByH_le _ j + _ ≤ (2 * ℓ) ^ j * 2 ^ (3 * ℓ) := by + refine Nat.mul_le_mul (Nat.pow_le_pow_left ?_ j) (coeffNorm1_parityAmplifier_le ℓ) + have := natDegree_parityAmplifier_le ℓ + omega + +/-- **Lemma B.1 (`ℓ₁`-norm bound for `e_j`)**: `‖parityBaseDigit ℓ j‖₁` is at most +`2 * ((2 * ℓ) ^ j * 2 ^ (3 * ℓ))`. -/ +theorem coeffNorm1_parityBaseDigit_le (ℓ j : ℕ) : + coeffNorm1 (parityBaseDigit ℓ j) ≤ 2 * ((2 * ℓ) ^ j * 2 ^ (3 * ℓ)) := by + rw [parityBaseDigit, baseDigitByH] + calc + coeffNorm1 (iterDivByH (parityAmplifier ℓ) j %ₘ hPoly) + ≤ 2 * coeffNorm1 (iterDivByH (parityAmplifier ℓ) j) := + coeffNorm1_modByMonic_hPoly_le _ + _ ≤ 2 * ((parityAmplifier ℓ).natDegree ^ j * coeffNorm1 (parityAmplifier ℓ)) := + Nat.mul_le_mul_left 2 (coeffNorm1_iterDivByH_le _ j) + _ ≤ 2 * ((2 * ℓ) ^ j * 2 ^ (3 * ℓ)) := by + refine Nat.mul_le_mul_left 2 + (Nat.mul_le_mul (Nat.pow_le_pow_left ?_ j) (coeffNorm1_parityAmplifier_le ℓ)) + have := natDegree_parityAmplifier_le ℓ + omega + +/-! ### 4. Shared-total-order truncation and multivariate total-degree bound (Lemma 5.2) -/ + +/-- The `V`-series factor `B(y; V) = ∑ j ∈ range ℓ, e_j(y) h(y)^j V^j` in `A[X]`, where the +polynomial indeterminate `X` represents the shared formal truncation marker `V`. -/ +def parityFactor {A : Type*} [CommRing A] (ℓ : ℕ) (y : A) : A[X] := + ∑ j ∈ range ℓ, C (evalInt y (parityBaseDigit ℓ j) * evalInt y hPoly ^ j) * X ^ j + +/-- The linear map `S_ℓ(∑_s b_s V^s) = ∑ s ∈ range ℓ, b_s` summing the coefficients of +`V ^ 0, …, V ^ (ℓ - 1)`. -/ +def sumCoeffsBelow {A : Type*} [Semiring A] (ℓ : ℕ) (P : A[X]) : A := + ∑ s ∈ range ℓ, P.coeff s + +/-- The `s`-th coefficient of `parityFactor ℓ y` is `e_s(y) h(y)^s` for `s < ℓ` and `0` +otherwise. -/ +theorem coeff_parityFactor {A : Type*} [CommRing A] (ℓ : ℕ) (y : A) (s : ℕ) : + (parityFactor ℓ y).coeff s = + if s < ℓ then evalInt y (parityBaseDigit ℓ s) * evalInt y hPoly ^ s else 0 := by + rw [parityFactor, finsetSum_coeff] + simp only [coeff_C_mul, coeff_X_pow, mul_ite, mul_one, mul_zero] + by_cases hs : s < ℓ + · rw [ite_eq_left hs, sum_eq_single s] + · simp only [↓reduceIte] + · intro j _ hjs + exact ite_eq_right (Ne.symm hjs) + · intro hns + exact absurd (mem_range.mpr hs) hns + · rw [ite_eq_right hs] + refine sum_eq_zero fun j hj => ?_ + rw [mem_range] at hj + exact ite_eq_right (by omega) + +/-- Evaluating `parityFactor ℓ y` at `V = 1` recovers `p_ℓ(y)`. -/ +theorem eval_one_parityFactor {A : Type*} [CommRing A] (ℓ : ℕ) (y : A) : + (parityFactor ℓ y).eval 1 = evalInt y (parityAmplifier ℓ) := by + rw [parityFactor, ← coe_evalRingHom, map_sum, evalInt_parityAmplifier_eq_sum] + refine sum_congr rfl fun j _ => ?_ + simp only [coe_evalRingHom, eval_mul, eval_C, eval_pow, eval_X, one_pow, mul_one, evalInt_hPoly] + +/-- At an integer `y`, the `s`-th coefficient of `parityFactor ℓ y` is divisible by `2 ^ s`. -/ +theorem two_pow_dvd_coeff_parityFactor (ℓ : ℕ) (y : ℤ) (s : ℕ) : + (2 : ℤ) ^ s ∣ (parityFactor ℓ y).coeff s := by + rw [coeff_parityFactor] + split_ifs with hs + · rw [evalInt_int y hPoly] + exact dvd_mul_of_dvd_right (pow_dvd_pow_of_dvd (two_dvd_eval_hPoly y) s) _ + · exact dvd_zero _ + +/-- Graded divisibility `2 ^ s ∣ coeff s` is preserved under polynomial multiplication. -/ +theorem two_pow_dvd_coeff_mul {P Q : ℤ[X]} + (hP : ∀ s, (2 : ℤ) ^ s ∣ P.coeff s) (hQ : ∀ s, (2 : ℤ) ^ s ∣ Q.coeff s) (s : ℕ) : + (2 : ℤ) ^ s ∣ (P * Q).coeff s := by + rw [coeff_mul] + refine dvd_sum fun ij hij => ?_ + rw [mem_antidiagonal] at hij + rw [← hij, pow_add] + exact mul_dvd_mul (hP ij.1) (hQ ij.2) + +/-- Every `V ^ s`-coefficient of `∏ i ∈ I, parityFactor ℓ (y i)` at integer arguments `y i` is +divisible by `2 ^ s`. -/ +theorem two_pow_dvd_coeff_prod_parityFactor {ι : Type*} (I : Finset ι) (ℓ : ℕ) (y : ι → ℤ) + (s : ℕ) : + (2 : ℤ) ^ s ∣ (∏ i ∈ I, parityFactor ℓ (y i)).coeff s := by + classical + induction I using Finset.induction_on generalizing s with + | empty => + rw [prod_empty] + rcases s with _ | s + · simp only [pow_zero, coeff_one_zero, dvd_refl] + · rw [coeff_one, ite_eq_right (Nat.succ_ne_zero s)] + exact dvd_zero _ + | insert a I ha ih => + rw [prod_insert ha] + exact two_pow_dvd_coeff_mul (two_pow_dvd_coeff_parityFactor ℓ (y a)) ih s + +/-- If `2 ^ s ∣ P.coeff s` for all `s`, then `sumCoeffsBelow ℓ P ≡ P.eval 1 (mod 2 ^ ℓ)`. -/ +theorem sumCoeffsBelow_modEq_eval_one {P : ℤ[X]} {ℓ : ℕ} + (hP : ∀ s, (2 : ℤ) ^ s ∣ P.coeff s) : + sumCoeffsBelow ℓ P ≡ P.eval 1 [ZMOD (2 : ℤ) ^ ℓ] := by + have heval : P.eval 1 = ∑ s ∈ range (max ℓ (P.natDegree + 1)), P.coeff s := by + rw [eval_eq_sum_range' (Nat.lt_of_lt_of_le (Nat.lt_succ_self _) (le_max_right ℓ _))] + simp only [one_pow, mul_one] + have hsplit : + ∑ s ∈ range (max ℓ (P.natDegree + 1)), P.coeff s = + sumCoeffsBelow ℓ P + ∑ s ∈ Ico ℓ (max ℓ (P.natDegree + 1)), P.coeff s := by + rw [sumCoeffsBelow, sum_range_add_sum_Ico _ (le_max_left ℓ _)] + rw [heval, hsplit, Int.modEq_iff_dvd, add_sub_cancel_left] + refine dvd_sum fun s hs => ?_ + rw [mem_Ico] at hs + exact (pow_dvd_pow (2 : ℤ) hs.1).trans (hP s) + +private theorem prod_modEq {ι : Type*} (I : Finset ι) {f g : ι → ℤ} {m : ℤ} + (h : ∀ i ∈ I, f i ≡ g i [ZMOD m]) : + (∏ i ∈ I, f i) ≡ (∏ i ∈ I, g i) [ZMOD m] := by + classical + induction I using Finset.induction_on with + | empty => simp only [prod_empty, Int.ModEq.refl] + | insert a I ha ih => + rw [prod_insert ha, prod_insert ha] + exact (h a (mem_insert_self a I)).mul (ih fun i hi => h i (mem_insert_of_mem hi)) + +/-- **Lemma 5.2 (shared-`V` truncation congruence)**: for `ℓ ≥ 1` and integers `y i`, +`S_ℓ(∏ i ∈ I, B_i(V)) ≡ ∏ i ∈ I, (if Even (y i) then 1 else 0) (mod 2 ^ ℓ)`. -/ +theorem sumCoeffsBelow_prod_parityFactor_modEq {ι : Type*} (I : Finset ι) {ℓ : ℕ} (hℓ : 1 ≤ ℓ) + (y : ι → ℤ) [∀ i, Decidable (Even (y i))] : + sumCoeffsBelow ℓ (∏ i ∈ I, parityFactor ℓ (y i)) ≡ + (∏ i ∈ I, if Even (y i) then (1 : ℤ) else 0) [ZMOD (2 : ℤ) ^ ℓ] := by + refine (sumCoeffsBelow_modEq_eval_one (two_pow_dvd_coeff_prod_parityFactor I ℓ y)).trans ?_ + rw [eval_prod] + have heval : (∏ i ∈ I, (parityFactor ℓ (y i)).eval 1) = + ∏ i ∈ I, (parityAmplifier ℓ).eval (y i) := by + refine prod_congr rfl fun i _ => ?_ + rw [eval_one_parityFactor, evalInt_int] + rw [heval] + exact prod_modEq I fun i _ => parityAmplifier_eval_modEq_two_pow hℓ (y i) + +private theorem totalDegree_neg_le {σ R : Type*} [CommRing R] (f : MvPolynomial σ R) : + (-f).totalDegree ≤ f.totalDegree := by + have hEq : -f = (-1 : ℤ) • f := by simp only [neg_smul, one_smul] + rw [hEq] + exact MvPolynomial.totalDegree_smul_le (-1 : ℤ) f + +private theorem totalDegree_sub_le {σ R : Type*} [CommRing R] (f g : MvPolynomial σ R) : + (f - g).totalDegree ≤ max f.totalDegree g.totalDegree := by + rw [sub_eq_add_neg] + exact (MvPolynomial.totalDegree_add f (-g)).trans (max_le_max le_rfl (totalDegree_neg_le g)) + +/-- Evaluating an affine integer polynomial (`natDegree ≤ 1`) at `y : MvPolynomial σ R` preserves +any upper bound `d` on `y.totalDegree`. -/ +theorem totalDegree_evalInt_of_natDegree_le_one {σ R : Type*} [CommRing R] {q : ℤ[X]} + (hq : q.natDegree ≤ 1) {y : MvPolynomial σ R} {d : ℕ} (hy : y.totalDegree ≤ d) : + (evalInt y q).totalDegree ≤ d := by + rw [evalInt, eq_C_add_C_mul_X_of_natDegree_le_one hq, eval₂_add, eval₂_mul, eval₂_X, eval₂_C, + eval₂_C] + have hcast : ∀ a : ℤ, (Int.castRingHom (MvPolynomial σ R) a) = a • (1 : MvPolynomial σ R) := by + intro a + simp only [eq_intCast, zsmul_one] + rw [hcast, hcast, smul_mul_assoc, one_mul] + refine (MvPolynomial.totalDegree_add _ _).trans (max_le ?_ ?_) + · exact (MvPolynomial.totalDegree_smul_le _ _).trans + (by simp only [MvPolynomial.totalDegree_one, zero_le]) + · exact (MvPolynomial.totalDegree_smul_le _ _).trans hy + +/-- Evaluating `hPoly = X ^ 2 - X` at `y : MvPolynomial σ R` of total degree at most `d` gives +a polynomial of total degree at most `2 * d`. -/ +theorem totalDegree_evalInt_hPoly_le {σ R : Type*} [CommRing R] {y : MvPolynomial σ R} {d : ℕ} + (hy : y.totalDegree ≤ d) : + (evalInt y hPoly).totalDegree ≤ 2 * d := by + rw [evalInt_hPoly] + refine (totalDegree_sub_le (y ^ 2) y).trans (max_le ?_ (hy.trans (by omega))) + exact (MvPolynomial.totalDegree_pow y 2).trans (Nat.mul_le_mul_left 2 hy) + +/-- For `y : MvPolynomial σ R` of total degree at most `d`, the `V ^ s`-coefficient of +`parityFactor ℓ y` has total degree at most `d + 2 * d * s`. -/ +theorem totalDegree_coeff_parityFactor_le {σ R : Type*} [CommRing R] (ℓ : ℕ) + {y : MvPolynomial σ R} {d : ℕ} (hy : y.totalDegree ≤ d) (s : ℕ) : + ((parityFactor ℓ y).coeff s).totalDegree ≤ d + 2 * d * s := by + rw [coeff_parityFactor] + split_ifs with hs + · refine (MvPolynomial.totalDegree_mul _ _).trans (add_le_add ?_ ?_) + · exact totalDegree_evalInt_of_natDegree_le_one (natDegree_parityBaseDigit_le ℓ s) hy + · refine (MvPolynomial.totalDegree_pow _ s).trans ?_ + have h1 := Nat.mul_le_mul_left s (totalDegree_evalInt_hPoly_le hy) + have h2 : s * (2 * d) = 2 * d * s := by ring + omega + · simp only [MvPolynomial.totalDegree_zero, zero_le] + +/-- Graded total-degree bounds `totalDegree (coeff s) ≤ M + 2 * d * s` add in the offset `M` +under multiplication in `(MvPolynomial σ R)[X]`. -/ +theorem totalDegree_coeff_mul_le {σ R : Type*} [CommRing R] {P Q : (MvPolynomial σ R)[X]} + {M₁ M₂ d : ℕ} + (hP : ∀ s, (P.coeff s).totalDegree ≤ M₁ + 2 * d * s) + (hQ : ∀ s, (Q.coeff s).totalDegree ≤ M₂ + 2 * d * s) (s : ℕ) : + ((P * Q).coeff s).totalDegree ≤ (M₁ + M₂) + 2 * d * s := by + rw [coeff_mul] + refine (MvPolynomial.totalDegree_finsetSum _ _).trans (Finset.sup_le fun ij hij => ?_) + rw [mem_antidiagonal] at hij + refine (MvPolynomial.totalDegree_mul _ _).trans ?_ + have h1 := hP ij.1 + have h2 := hQ ij.2 + have hsum : 2 * d * ij.1 + 2 * d * ij.2 = 2 * d * s := by + rw [← hij] + ring + linarith + +/-- **Lemma 5.2 (graded total-degree bound)**: if every `y i` (`i ∈ I`) has multivariate total +degree at most `d`, then the `V ^ s`-coefficient of `∏ i ∈ I, parityFactor ℓ (y i)` has total +degree at most `d * (#I + 2 * s)`. -/ +theorem totalDegree_coeff_prod_parityFactor_le {ι σ R : Type*} [CommRing R] (I : Finset ι) + (ℓ : ℕ) {y : ι → MvPolynomial σ R} {d : ℕ} (hy : ∀ i ∈ I, (y i).totalDegree ≤ d) (s : ℕ) : + ((∏ i ∈ I, parityFactor ℓ (y i)).coeff s).totalDegree ≤ d * (#I + 2 * s) := by + classical + induction I using Finset.induction_on generalizing s with + | empty => + rw [prod_empty, card_empty, zero_add] + rcases s with _ | s + · simp only [coeff_one_zero, MvPolynomial.totalDegree_one, zero_le] + · rw [coeff_one, ite_eq_right (Nat.succ_ne_zero s), MvPolynomial.totalDegree_zero] + exact Nat.zero_le _ + | insert a I ha ih => + rw [prod_insert ha, card_insert_of_notMem ha] + have hstep := totalDegree_coeff_mul_le (M₁ := d) (M₂ := d * #I) (d := d) + (totalDegree_coeff_parityFactor_le ℓ (hy a (mem_insert_self a I))) + (fun k => (ih (fun i hi => hy i (mem_insert_of_mem hi)) k).trans + (le_of_eq (by ring))) + s + exact hstep.trans (le_of_eq (by ring)) + +/-- **Lemma 5.2 (retained coefficient total-degree bound)**: for `s < ℓ`, the `V ^ s`-coefficient +of `∏ i ∈ I, parityFactor ℓ (y i)` has total degree at most `d * (#I + 2 * (ℓ - 1))`. -/ +theorem totalDegree_coeff_prod_parityFactor_le_of_lt {ι σ R : Type*} [CommRing R] (I : Finset ι) + {ℓ s : ℕ} (hs : s < ℓ) {y : ι → MvPolynomial σ R} {d : ℕ} + (hy : ∀ i ∈ I, (y i).totalDegree ≤ d) : + ((∏ i ∈ I, parityFactor ℓ (y i)).coeff s).totalDegree ≤ d * (#I + 2 * (ℓ - 1)) := by + refine (totalDegree_coeff_prod_parityFactor_le I ℓ hy s).trans ?_ + refine Nat.mul_le_mul_left d ?_ + omega + +/-- **Lemma 5.2 (truncated sum total-degree bound)**: the truncated coefficient sum +`sumCoeffsBelow ℓ (∏ i ∈ I, parityFactor ℓ (y i))` has total degree at most +`d * (#I + 2 * (ℓ - 1))`. -/ +theorem totalDegree_sumCoeffsBelow_prod_parityFactor_le {ι σ R : Type*} [CommRing R] + (I : Finset ι) (ℓ : ℕ) {y : ι → MvPolynomial σ R} {d : ℕ} + (hy : ∀ i ∈ I, (y i).totalDegree ≤ d) : + (sumCoeffsBelow ℓ (∏ i ∈ I, parityFactor ℓ (y i))).totalDegree ≤ + d * (#I + 2 * (ℓ - 1)) := by + rw [sumCoeffsBelow] + refine (MvPolynomial.totalDegree_finsetSum _ _).trans (Finset.sup_le fun s hs => ?_) + rw [mem_range] at hs + exact totalDegree_coeff_prod_parityFactor_le_of_lt I hs hy + +end Polynomial diff --git a/ComplexityTests/ParityAmplifier.lean b/ComplexityTests/ParityAmplifier.lean new file mode 100644 index 0000000000..2203ca49eb --- /dev/null +++ b/ComplexityTests/ParityAmplifier.lean @@ -0,0 +1,127 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +import Complexity.Foundations.Data.Polynomial.ParityAmplifier +import Mathlib.Data.Rat.Defs + +/-! Concrete witnesses and worked examples for +`Complexity.Foundations.Data.Polynomial.ParityAmplifier` (Lemmas 5.1, 5.2, and B.1 of the +subexponential `#k-SAT` manuscript). -/ + +namespace ComplexityTests.ParityAmplifier + +open Finset Polynomial + +/-! ### 1. Explicit formulas and the manuscript's `ℓ = 2` decomposition (p. 37) -/ + +/-- `p_2(X) = (1 - X) + (2X - 1)(X^2 - X)`, matching `p_2(Y) = 1 - 3Y^2 + 2Y^3` on p. 37. -/ +theorem parityAmplifier_two_decomp : + parityAmplifier 2 = (1 - X) + hPoly * (2 * X - 1) := by + rw [parityAmplifier_two, hPoly] + ring + +/-- The quotient and remainder of `p_2(X)` on division by `h(X) = X^2 - X` are `2X - 1` and +`1 - X`. -/ +theorem div_mod_parityAmplifier_two : + parityAmplifier 2 /ₘ hPoly = 2 * X - 1 ∧ parityAmplifier 2 %ₘ hPoly = 1 - X := by + apply div_modByMonic_unique (2 * X - 1) (1 - X) monic_hPoly + refine ⟨parityAmplifier_two_decomp.symm, ?_⟩ + rw [degree_eq_natDegree monic_hPoly.ne_zero, natDegree_hPoly] + refine (degree_sub_le 1 X).trans_lt ?_ + rw [degree_one, degree_X] + decide + +/-- First base-`h` digit of `p_2`: `e_0(X) = 1 - X`. -/ +theorem parityBaseDigit_two_zero : parityBaseDigit 2 0 = 1 - X := + div_mod_parityAmplifier_two.2 + +/-- Second base-`h` digit of `p_2`: `e_1(X) = 2 * X - 1`. -/ +theorem parityBaseDigit_two_one : parityBaseDigit 2 1 = 2 * X - 1 := by + change (parityAmplifier 2 /ₘ hPoly) %ₘ hPoly = 2 * X - 1 + rw [div_mod_parityAmplifier_two.1, (modByMonic_eq_self_iff monic_hPoly).mpr] + rw [degree_eq_natDegree monic_hPoly.ne_zero, natDegree_hPoly] + refine degree_le_natDegree.trans_lt ?_ + rw [Nat.cast_lt] + have h1 : (2 * X - 1 : ℤ[X]).natDegree ≤ max (2 * X : ℤ[X]).natDegree (1 : ℤ[X]).natDegree := + natDegree_sub_le (2 * X) 1 + have h2 : (2 * X : ℤ[X]).natDegree ≤ (2 : ℤ[X]).natDegree + (X : ℤ[X]).natDegree := + natDegree_mul_le + rw [natDegree_ofNat, natDegree_X] at h2 + rw [natDegree_one] at h1 + omega + +/-! ### 2. Concrete parity amplification congruences (Lemma 5.1) -/ + +example : (parityAmplifier 3).eval 6 ≡ 1 [ZMOD (2 : ℤ) ^ 3] := + parityAmplifier_eval_modEq_one_of_even (by decide) ⟨3, by ring⟩ + +example : (parityAmplifier 3).eval (-4) ≡ 1 [ZMOD (2 : ℤ) ^ 3] := + parityAmplifier_eval_modEq_one_of_even (by decide) ⟨-2, by ring⟩ + +example : (parityAmplifier 3).eval 5 ≡ 0 [ZMOD (2 : ℤ) ^ 3] := + parityAmplifier_eval_modEq_zero_of_odd 3 ⟨2, by ring⟩ + +example : (parityAmplifier 3).eval (-3) ≡ 0 [ZMOD (2 : ℤ) ^ 3] := + parityAmplifier_eval_modEq_zero_of_odd 3 ⟨-2, by ring⟩ + +/-! ### 3. Coefficient norm bounds (Lemma B.1) -/ + +example : coeffNorm1 (parityAmplifier 3) ≤ 512 := + coeffNorm1_parityAmplifier_le 3 + +example (j k : ℕ) : ((parityBaseDigit 3 j).coeff k).natAbs ≤ 6 ^ j * 512 := + natAbs_coeff_parityBaseDigit_le 3 j k + +example (j : ℕ) : coeffNorm1 (parityBaseDigit 3 j) ≤ 2 * (6 ^ j * 512) := + coeffNorm1_parityBaseDigit_le 3 j + +/-! ### 4. Shared-`V` truncation and multivariate degree bound (Lemma 5.2) -/ + +/-- Empty equation set: the truncated sum is `1 ≡ 1 (mod 2 ^ ℓ)`. -/ +example : + sumCoeffsBelow 2 (∏ i ∈ (∅ : Finset (Fin 0)), parityFactor 2 (![] i)) ≡ + 1 [ZMOD (2 : ℤ) ^ 2] := by + simpa only [prod_empty] using + sumCoeffsBelow_prod_parityFactor_modEq (∅ : Finset (Fin 0)) (by decide : 1 ≤ 2) ![] + +/-- Two equations with both values even (`y = ![4, -2]`): truncated product is `≡ 1 (mod 4)`. -/ +example : + sumCoeffsBelow 2 (∏ i : Fin 2, parityFactor 2 (![(4 : ℤ), -2] i)) ≡ + 1 [ZMOD (2 : ℤ) ^ 2] := by + have h := sumCoeffsBelow_prod_parityFactor_modEq (univ : Finset (Fin 2)) (by decide : 1 ≤ 2) + ![(4 : ℤ), -2] + have hrhs : (∏ i : Fin 2, if Even (![(4 : ℤ), -2] i) then (1 : ℤ) else 0) = 1 := by + rw [Fin.prod_univ_two] + have h0 : Even (![(4 : ℤ), -2] 0) := ⟨2, by decide⟩ + have h1 : Even (![(4 : ℤ), -2] 1) := ⟨-1, by decide⟩ + simp only [h0, h1, ↓reduceIte, mul_one] + rwa [hrhs] at h + +/-- Two equations with one odd value (`y = ![4, 3]`): truncated product is `≡ 0 (mod 4)`. -/ +example : + sumCoeffsBelow 2 (∏ i : Fin 2, parityFactor 2 (![(4 : ℤ), 3] i)) ≡ + 0 [ZMOD (2 : ℤ) ^ 2] := by + have h := sumCoeffsBelow_prod_parityFactor_modEq (univ : Finset (Fin 2)) (by decide : 1 ≤ 2) + ![(4 : ℤ), 3] + have hrhs : (∏ i : Fin 2, if Even (![(4 : ℤ), 3] i) then (1 : ℤ) else 0) = 0 := by + rw [Fin.prod_univ_two] + have h1 : ¬Even (![(4 : ℤ), 3] 1) := by decide + simp only [h1, ↓reduceIte, mul_zero] + rwa [hrhs] at h + +/-- Manuscript p. 37 worked degree bound: for `ℓ = 2` and two linear equations (`d = 1`, `#I = 2`) +over `ℚ`, the truncated sum `S_2(B_0(V) B_1(V))` has total degree at most `1 * (2 + 2 * 1) = 4`. -/ +example : + (sumCoeffsBelow 2 + (∏ i ∈ (univ : Finset (Fin 2)), + parityFactor 2 (MvPolynomial.X i : MvPolynomial (Fin 2) ℚ))).totalDegree ≤ 4 := by + have h := totalDegree_sumCoeffsBelow_prod_parityFactor_le + (I := (univ : Finset (Fin 2))) 2 + (y := fun i : Fin 2 => (MvPolynomial.X i : MvPolynomial (Fin 2) ℚ)) (d := 1) + (fun i _ => by rw [MvPolynomial.totalDegree_X]) + simpa only [card_univ, Fintype.card_fin] using h + +end ComplexityTests.ParityAmplifier From c22f67d5a1988b1c45be7d26d0212a03588074c1 Mon Sep 17 00:00:00 2001 From: Samuel Giuseppe Schlesinger Date: Mon, 26 Oct 2026 19:22:54 -0400 Subject: [PATCH 02/20] doc(references): pin the subexponential SAT manuscript --- references.bib | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/references.bib b/references.bib index a7fe763be3..a6877e2938 100644 --- a/references.bib +++ b/references.bib @@ -3210,6 +3210,15 @@ @inproceedings{OliveiraSanthanam2018 note = {Full version: ECCC TR18-139} } +@misc{OpenAI2026ETH, + author = {{OpenAI}}, + title = {The Exponential Time Hypothesis is False}, + year = {2026}, + howpublished = {Manuscript}, + note = {Dated 17 October 2026, revised 25 October 2026; source revision 7ef5c0cc5ca4b0e072b7a050fca09ab24bc6fa3a}, + url = {https://github.com/openai/math/blob/7ef5c0cc5ca4b0e072b7a050fca09ab24bc6fa3a/preprints/The-Exponential-Time-Hypothesis-is-False-October-25-2026/paper.pdf} +} + @misc{OpenAI2026RationalHitting, author = {{OpenAI}}, title = {{Rational} matrix hitting lists for noncommutative rational formulas}, From 93847908cc9dab3fe8f03a90c8edda99d359de2f Mon Sep 17 00:00:00 2001 From: Samuel Schlesinger Date: Tue, 27 Oct 2026 00:23:42 +0000 Subject: [PATCH 03/20] refactor(Polynomial): reuse Mathlib helpers and cite OpenAI2026ETH in ParityAmplifier (#1235) --- .../Data/Polynomial/ParityAmplifier.lean | 93 +++++-------------- 1 file changed, 24 insertions(+), 69 deletions(-) diff --git a/Complexity/Foundations/Data/Polynomial/ParityAmplifier.lean b/Complexity/Foundations/Data/Polynomial/ParityAmplifier.lean index 5cde854056..94f67a10e2 100644 --- a/Complexity/Foundations/Data/Polynomial/ParityAmplifier.lean +++ b/Complexity/Foundations/Data/Polynomial/ParityAmplifier.lean @@ -14,8 +14,12 @@ public import Mathlib.Algebra.Polynomial.BigOperators public import Mathlib.Algebra.Polynomial.Div public import Mathlib.Data.Int.ModEq import Mathlib.Algebra.BigOperators.Intervals +import Mathlib.Algebra.BigOperators.ModEq import Mathlib.Algebra.BigOperators.Ring.Finset +import Mathlib.Algebra.MvPolynomial.CommRing +import Mathlib.Algebra.Polynomial.Degree.SmallDegree import Mathlib.Algebra.Ring.Int.Parity +import Mathlib.Data.Nat.Choose.Bounds import Mathlib.Data.Nat.Choose.Sum import Mathlib.Tactic.Linarith import Mathlib.Tactic.Ring @@ -30,19 +34,20 @@ satisfies $p_\ell(Y) \equiv 1 \pmod{Y^\ell}$ and $p_\ell(Y) \equiv 0 \pmod{(1 - for every integer $y \in \mathbb{Z}$, $p_\ell(y) \equiv \mathbf{1}_{\{2 \mid y\}} \pmod{2^\ell}$ (`Polynomial.parityAmplifier_eval_modEq_two_pow`). -Writing $p_\ell$ in powers of the monic quadratic $h(Y) = Y^2 - Y = Y(Y - 1)$ -(`Polynomial.hPoly`) by successive monic division produces remainders -$e_0, \dots, e_{\ell-1} \in \mathbb{Z}[Y]$ (`Polynomial.parityBaseDigit`) of degree at most $1$ -with $p_\ell(Y) = \sum_{j=0}^{\ell-1} e_j(Y) h(Y)^j$ (`Polynomial.parityAmplifier_eq_sum_baseDigit`) -and explicit coefficient bounds (`Polynomial.natAbs_coeff_parityBaseDigit_le`, -`Polynomial.coeffNorm1_parityBaseDigit_le`). +Following Lemma 5.1 and Lemma B.1 of +[OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH], writing $p_\ell$ in powers of +the monic quadratic $h(Y) = Y^2 - Y = Y(Y - 1)$ (`Polynomial.hPoly`) by successive monic division +produces remainders $e_0, \dots, e_{\ell-1} \in \mathbb{Z}[Y]$ (`Polynomial.parityBaseDigit`) of +degree at most $1$ with $p_\ell(Y) = \sum_{j=0}^{\ell-1} e_j(Y) h(Y)^j$ +(`Polynomial.parityAmplifier_eq_sum_baseDigit`) and explicit coefficient bounds +(`Polynomial.natAbs_coeff_parityBaseDigit_le`, `Polynomial.coeffNorm1_parityBaseDigit_le`). Since $h(y) = y(y - 1)$ is even for every $y \in \mathbb{Z}$, introducing a shared formal variable $V$ (`Polynomial.parityFactor`) across a family of equations and discarding powers $V^s$ with -$s \ge \ell$ via `Polynomial.sumCoeffsBelow` preserves the product of evenness indicators modulo -$2^\ell$ (`Polynomial.sumCoeffsBelow_prod_parityFactor_modEq`), while bounding the multivariate -total degree of every retained coefficient and of their sum by $d_* (\#I + 2(\ell - 1))$ when each -input polynomial has total degree at most $d_*$ +$s \ge \ell$ via `Polynomial.sumCoeffsBelow` (Lemma 5.2 of [OpenAI2026ETH]) preserves the product +of evenness indicators modulo $2^\ell$ (`Polynomial.sumCoeffsBelow_prod_parityFactor_modEq`), while +bounding the multivariate total degree of every retained coefficient and of their sum by +$d_* (\#I + 2(\ell - 1))$ when each input polynomial has total degree at most $d_*$ (`Polynomial.totalDegree_sumCoeffsBelow_prod_parityFactor_le`). ## Main definitions @@ -74,6 +79,7 @@ input polynomial has total degree at most $d_*$ * [S. Toda, *PP is as hard as the polynomial-time hierarchy*][Toda1991] * [S. Arora, B. Barak, *Computational Complexity: A Modern Approach*][AroraBarak09] +* [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (Lemmas 5.1, 5.2, and B.1) -/ @[expose] public noncomputable section @@ -335,23 +341,11 @@ theorem natDegree_parityBaseDigit_le (ℓ j : ℕ) : (parityBaseDigit ℓ j).natDegree ≤ 1 := natDegree_baseDigitByH_le (parityAmplifier ℓ) j -/-- Any polynomial of degree at most `1` equals `C (q.coeff 0) + C (q.coeff 1) * X`. -/ -theorem eq_C_add_C_mul_X_of_natDegree_le_one {R : Type*} [Semiring R] {q : R[X]} - (hq : q.natDegree ≤ 1) : - q = C (q.coeff 0) + C (q.coeff 1) * X := by - ext n - rcases n with _ | _ | n - · simp only [coeff_add, coeff_C_zero, coeff_mul_X_zero, add_zero] - · simp only [coeff_add, coeff_C_succ, coeff_mul_X, coeff_C_zero, zero_add] - · have hn : q.natDegree < n + 2 := by omega - rw [coeff_eq_zero_of_natDegree_lt hn] - simp only [coeff_add, coeff_C_succ, coeff_mul_X, zero_add] - /-- Explicit affine decomposition `e_j(X) = a_j + b_j X` of `parityBaseDigit ℓ j`. -/ theorem parityBaseDigit_eq_C_add_C_mul_X (ℓ j : ℕ) : parityBaseDigit ℓ j = C ((parityBaseDigit ℓ j).coeff 0) + C ((parityBaseDigit ℓ j).coeff 1) * X := - eq_C_add_C_mul_X_of_natDegree_le_one (natDegree_parityBaseDigit_le ℓ j) + (eq_X_add_C_of_natDegree_le_one (natDegree_parityBaseDigit_le ℓ j)).trans (add_comm _ _) /-- Division expansion after `m` steps of monic division by `hPoly`: `P = (∑ j ∈ range m, baseDigitByH P j * hPoly ^ j) + iterDivByH P m * hPoly ^ m`. -/ @@ -593,14 +587,6 @@ private theorem sum_range_choose_add (m k : ℕ) : have hm1 : m + (k + 1) = m + k + 1 := by omega rw [hm1, ← hpas] -private theorem choose_le_two_pow (n k : ℕ) : Nat.choose n k ≤ 2 ^ n := by - by_cases hk : k ≤ n - · rw [← Nat.sum_range_choose n] - exact single_le_sum (f := fun i => Nat.choose n i) (fun _ _ => Nat.zero_le _) - (mem_range.mpr (by omega)) - · rw [Nat.choose_eq_zero_of_lt (by omega)] - exact Nat.zero_le _ - /-- The `ℓ₁` norm of `parityKernel ℓ` is at most `2 ^ (2 * ℓ)`. -/ theorem coeffNorm1_parityKernel_le (ℓ : ℕ) : coeffNorm1 (parityKernel ℓ) ≤ 2 ^ (2 * ℓ) := by @@ -624,7 +610,7 @@ theorem coeffNorm1_parityKernel_le (ℓ : ℕ) : refine (hsum (k + 1)).trans ?_ simp only [add_tsub_cancel_right] rw [sum_range_choose_add k k] - exact (choose_le_two_pow (k + k + 1) k).trans + exact (Nat.choose_le_two_pow (k + k + 1) k).trans (Nat.pow_le_pow_right (by omega) (by omega)) /-- **Lemma B.1 (`ℓ₁`-norm of `p_ℓ`)**: `‖p_ℓ‖₁ ≤ 2 ^ (3 * ℓ)`. -/ @@ -698,15 +684,6 @@ theorem coeff_modByMonic_hPoly_one (p : ℤ[X]) : rw [hsq, zero_sub] linarith -private theorem natAbs_sum_le {ι : Type*} (s : Finset ι) (f : ι → ℤ) : - (∑ i ∈ s, f i).natAbs ≤ ∑ i ∈ s, (f i).natAbs := by - classical - induction s using Finset.induction_on with - | empty => simp only [sum_empty, Int.natAbs_zero, le_refl] - | insert a s ha ih => - rw [sum_insert ha, sum_insert ha] - exact (Int.natAbs_add_le _ _).trans (add_le_add le_rfl ih) - /-- Every coefficient of `p /ₘ hPoly` has absolute value at most `coeffNorm1 p`. -/ theorem natAbs_coeff_divByMonic_hPoly_le (p : ℤ[X]) (n : ℕ) : ((p /ₘ hPoly).coeff n).natAbs ≤ coeffNorm1 p := by @@ -716,7 +693,7 @@ theorem natAbs_coeff_divByMonic_hPoly_le (p : ℤ[X]) (n : ℕ) : rw [natDegree_divByMonic p monic_hPoly, natDegree_hPoly] omega rw [htail, add_zero] - refine (natAbs_sum_le _ _).trans ?_ + refine (Int.natAbs_sum_le _ _).trans ?_ let emb : ℕ ↪ ℕ := ⟨fun t => n + 2 + t, add_right_injective (n + 2)⟩ have hmap : ∑ t ∈ range (p.natDegree + 1), (p.coeff (n + 2 + t)).natAbs = ∑ i ∈ (range (p.natDegree + 1)).map emb, (p.coeff i).natAbs := by @@ -745,7 +722,7 @@ theorem natAbs_coeff_modByMonic_hPoly_le (p : ℤ[X]) (k : ℕ) : congr 1 omega rw [hsum] - refine (natAbs_sum_le _ _).trans ?_ + refine (Int.natAbs_sum_le _ _).trans ?_ let emb : ℕ ↪ ℕ := ⟨fun t => 1 + t, add_right_injective 1⟩ have hmap : ∑ t ∈ range (p.natDegree + 2), (p.coeff (1 + t)).natAbs = ∑ i ∈ (range (p.natDegree + 2)).map emb, (p.coeff i).natAbs := by @@ -957,16 +934,6 @@ theorem sumCoeffsBelow_modEq_eval_one {P : ℤ[X]} {ℓ : ℕ} rw [mem_Ico] at hs exact (pow_dvd_pow (2 : ℤ) hs.1).trans (hP s) -private theorem prod_modEq {ι : Type*} (I : Finset ι) {f g : ι → ℤ} {m : ℤ} - (h : ∀ i ∈ I, f i ≡ g i [ZMOD m]) : - (∏ i ∈ I, f i) ≡ (∏ i ∈ I, g i) [ZMOD m] := by - classical - induction I using Finset.induction_on with - | empty => simp only [prod_empty, Int.ModEq.refl] - | insert a I ha ih => - rw [prod_insert ha, prod_insert ha] - exact (h a (mem_insert_self a I)).mul (ih fun i hi => h i (mem_insert_of_mem hi)) - /-- **Lemma 5.2 (shared-`V` truncation congruence)**: for `ℓ ≥ 1` and integers `y i`, `S_ℓ(∏ i ∈ I, B_i(V)) ≡ ∏ i ∈ I, (if Even (y i) then 1 else 0) (mod 2 ^ ℓ)`. -/ theorem sumCoeffsBelow_prod_parityFactor_modEq {ι : Type*} (I : Finset ι) {ℓ : ℕ} (hℓ : 1 ≤ ℓ) @@ -980,34 +947,22 @@ theorem sumCoeffsBelow_prod_parityFactor_modEq {ι : Type*} (I : Finset ι) {ℓ refine prod_congr rfl fun i _ => ?_ rw [eval_one_parityFactor, evalInt_int] rw [heval] - exact prod_modEq I fun i _ => parityAmplifier_eval_modEq_two_pow hℓ (y i) - -private theorem totalDegree_neg_le {σ R : Type*} [CommRing R] (f : MvPolynomial σ R) : - (-f).totalDegree ≤ f.totalDegree := by - have hEq : -f = (-1 : ℤ) • f := by simp only [neg_smul, one_smul] - rw [hEq] - exact MvPolynomial.totalDegree_smul_le (-1 : ℤ) f - -private theorem totalDegree_sub_le {σ R : Type*} [CommRing R] (f g : MvPolynomial σ R) : - (f - g).totalDegree ≤ max f.totalDegree g.totalDegree := by - rw [sub_eq_add_neg] - exact (MvPolynomial.totalDegree_add f (-g)).trans (max_le_max le_rfl (totalDegree_neg_le g)) + exact Int.ModEq.prod fun i _ => parityAmplifier_eval_modEq_two_pow hℓ (y i) /-- Evaluating an affine integer polynomial (`natDegree ≤ 1`) at `y : MvPolynomial σ R` preserves any upper bound `d` on `y.totalDegree`. -/ theorem totalDegree_evalInt_of_natDegree_le_one {σ R : Type*} [CommRing R] {q : ℤ[X]} (hq : q.natDegree ≤ 1) {y : MvPolynomial σ R} {d : ℕ} (hy : y.totalDegree ≤ d) : (evalInt y q).totalDegree ≤ d := by - rw [evalInt, eq_C_add_C_mul_X_of_natDegree_le_one hq, eval₂_add, eval₂_mul, eval₂_X, eval₂_C, - eval₂_C] + rw [evalInt, eq_X_add_C_of_natDegree_le_one hq, eval₂_add, eval₂_mul, eval₂_X, eval₂_C, eval₂_C] have hcast : ∀ a : ℤ, (Int.castRingHom (MvPolynomial σ R) a) = a • (1 : MvPolynomial σ R) := by intro a simp only [eq_intCast, zsmul_one] rw [hcast, hcast, smul_mul_assoc, one_mul] refine (MvPolynomial.totalDegree_add _ _).trans (max_le ?_ ?_) + · exact (MvPolynomial.totalDegree_smul_le _ _).trans hy · exact (MvPolynomial.totalDegree_smul_le _ _).trans (by simp only [MvPolynomial.totalDegree_one, zero_le]) - · exact (MvPolynomial.totalDegree_smul_le _ _).trans hy /-- Evaluating `hPoly = X ^ 2 - X` at `y : MvPolynomial σ R` of total degree at most `d` gives a polynomial of total degree at most `2 * d`. -/ @@ -1015,7 +970,7 @@ theorem totalDegree_evalInt_hPoly_le {σ R : Type*} [CommRing R] {y : MvPolynomi (hy : y.totalDegree ≤ d) : (evalInt y hPoly).totalDegree ≤ 2 * d := by rw [evalInt_hPoly] - refine (totalDegree_sub_le (y ^ 2) y).trans (max_le ?_ (hy.trans (by omega))) + refine (MvPolynomial.totalDegree_sub (y ^ 2) y).trans (max_le ?_ (hy.trans (by omega))) exact (MvPolynomial.totalDegree_pow y 2).trans (Nat.mul_le_mul_left 2 hy) /-- For `y : MvPolynomial σ R` of total degree at most `d`, the `V ^ s`-coefficient of From f4ccf6c4e01d72741c94990c956ce34af2a5e439 Mon Sep 17 00:00:00 2001 From: Samuel Schlesinger Date: Tue, 27 Oct 2026 00:12:49 +0000 Subject: [PATCH 04/20] feat(BooleanAnalysis): sparse F2 equation zero counting, cleared denominators, and heavy-variable branching (#1226) --- Complexity.lean | 1 + .../BooleanAnalysis/SparseEquations.lean | 1116 +++++++++++++++++ ComplexityTests/SparseEquations.lean | 163 +++ 3 files changed, 1280 insertions(+) create mode 100644 Complexity/Foundations/BooleanAnalysis/SparseEquations.lean create mode 100644 ComplexityTests/SparseEquations.lean diff --git a/Complexity.lean b/Complexity.lean index 2e33abe093..9de53176aa 100644 --- a/Complexity.lean +++ b/Complexity.lean @@ -1772,6 +1772,7 @@ public import Complexity.Foundations.BooleanAnalysis.PolynomialCorrelation public import Complexity.Foundations.BooleanAnalysis.QuadraticForm public import Complexity.Foundations.BooleanAnalysis.RelevantCoordinates public import Complexity.Foundations.BooleanAnalysis.SignApproximation +public import Complexity.Foundations.BooleanAnalysis.SparseEquations public import Complexity.Foundations.BooleanAnalysis.Symmetrization public import Complexity.Foundations.Combinatorics.AffineDisperser public import Complexity.Foundations.Combinatorics.AffineDisperser.AffineSubspace diff --git a/Complexity/Foundations/BooleanAnalysis/SparseEquations.lean b/Complexity/Foundations/BooleanAnalysis/SparseEquations.lean new file mode 100644 index 0000000000..c5043f568b --- /dev/null +++ b/Complexity/Foundations/BooleanAnalysis/SparseEquations.lean @@ -0,0 +1,1116 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Foundations.BooleanAnalysis.LowDegree +public import Complexity.Foundations.Data.Polynomial.ParityAmplifier +public import Mathlib.Algebra.Ring.Int.Parity +public import Mathlib.Data.ZMod.Basic +import Mathlib.Algebra.BigOperators.Group.Finset.Piecewise +import Mathlib.Algebra.BigOperators.ModEq +import Mathlib.Algebra.BigOperators.Ring.Finset +import Mathlib.Algebra.CharP.Two +import Mathlib.Data.Fintype.Card +import Mathlib.Tactic.Linarith +import Mathlib.Tactic.Ring + +/-! +# Sparse polynomial equations over `𝔽₂`, common-zero counting, and heavy-variable branching + +A sparse degree-`k` polynomial over `𝔽₂` on the Boolean cube `ι → Bool` is represented by a finite +family `𝓜 : Finset (Finset ι)` of monomials `M ⊆ ι` of size at most `k`, evaluated in any +commutative ring `R` via `Cslib.BitString.monomialSum R 𝓜 x = ∑ M ∈ 𝓜, monomial R M x` and lifted +to `MvPolynomial ι R` via `Cslib.BitString.monomialSumPoly R 𝓜`. + +Over `ZMod 2`, `monomialSum (ZMod 2) 𝓜 x = 0` holds if and only if the integer evaluation +`monomialSum ℤ 𝓜 x` is even (`Cslib.BitString.monomialSum_zmod_two_eq_zero_iff_even`). Consequently, +the number of common zeros `Cslib.BitString.commonZeroCount I P` of a system `{P i}_{i ∈ I}` of +polynomial equations over `𝔽₂` equals the sum over the Boolean cube of the product of evenness +indicators of their integer evaluations +(`Cslib.BitString.sum_prod_even_monomialSum_eq_commonZeroCount`). + +Combining this identity with the Beigel–Tarui parity-amplifying polynomials and shared-`V` +truncation from `Complexity.Foundations.Data.Polynomial.ParityAmplifier` [Toda][Toda1991], +[Arora and Barak, Section 17.4][AroraBarak09]: +* Substituting any family of polynomials `q : ι → MvPolynomial σ R` of total degree at most `d₀` + into `monomialSumPoly R (P i)` of degree at most `k` produces a lifted polynomial of total degree + at most `k * d₀` (`Cslib.BitString.totalDegree_eval₂_monomialSumPoly_le`), so the truncated + shared-`V` product `S_ℓ(∏ i ∈ I, B_i(V))` has total degree at most `(k * d₀) * (#I + 2 * (ℓ - 1))` + (`Cslib.BitString.totalDegree_sumCoeffsBelow_prod_parityFactor_eval₂_le`). +* Summing the truncated product over `x : ι → Bool` recovers `commonZeroCount I P` modulo `2 ^ ℓ` + (`Cslib.BitString.sum_sumCoeffsBelow_prod_parityFactor_modEq_commonZeroCount`), and recovers + `commonZeroCount I P` on the nose via `(· % 2 ^ ℓ)` whenever `Fintype.card ι < ℓ` + (`Cslib.BitString.emod_sum_sumCoeffsBelow_prod_parityFactor_eq_commonZeroCount`). + +Finally, for any system of equations with variable scopes `scope : κ → Finset ι` and incidence +threshold `b₀`, the set `Cslib.BitString.heavyVars` of variables appearing in more than `b₀` +scopes has cardinality at most `totalIncidence F scope / b₀` +(`Cslib.BitString.card_heavyVars_le_div`), while every remaining variable has incidence at most +`b₀`. Branching on all `2 ^ #S` assignments to a variable subset `S` and simplifying each equation +via `Cslib.BitString.restrictMonomials` preserves degree bounds, never increases the number of +monomials per equation, and decomposes `commonZeroCount` additively across the branches +(`Cslib.BitString.commonZeroCount_eq_sum_branches`). + +## Main definitions + +* `Cslib.BitString.monomialSum`: evaluation `∑ M ∈ 𝓜, monomial R M x` of a family of monomials. +* `Cslib.BitString.monomialPoly`, `Cslib.BitString.monomialSumPoly`: formal multilinear polynomial + lifts in `MvPolynomial ι R`. +* `Cslib.BitString.IsCommonZero`, `Cslib.BitString.commonZeroCount`: common zeros of a system of + `𝔽₂` polynomial equations on `ι → Bool` and their count. +* `Cslib.BitString.varIncidence`, `Cslib.BitString.totalIncidence`, `Cslib.BitString.heavyVars`: + variable-equation incidence counts and heavy-variable set above threshold `b₀`. +* `Cslib.BitString.patchAssignment`, `Cslib.BitString.restrictMonomials`: patching a branch + assignment on `S` and reducing a monomial family modulo `2` after specializing `S`. +* `Cslib.BitString.parityBaseDigitCleared`, `Cslib.BitString.hPolyCleared`, + `Cslib.BitString.parityFactorCleared`, `Cslib.BitString.clearedMonomialPoly`, + `Cslib.BitString.clearedMonomialSumPoly`: cleared-denominator parity factors and degree-`k` + homogenized monomial sums from §5.4 and Appendix B.2. + +## Main results + +* `Cslib.BitString.monomialSum_zmod_two_eq_zero_iff_even`: `𝔽₂` vanishing iff even `ℤ` evaluation. +* `Cslib.BitString.sum_prod_even_monomialSum_eq_commonZeroCount`: equation (5.1) expressing + `commonZeroCount` as the cube sum of products of evenness indicators. +* `Cslib.BitString.totalDegree_sumCoeffsBelow_prod_parityFactor_eval₂_le`: total-degree bound + `(k * d₀) * (#I + 2 * (ℓ - 1))` for the truncated product under degree-`d₀` replacements. +* `Cslib.BitString.emod_sum_sumCoeffsBelow_prod_parityFactor_eq_commonZeroCount`: exact recovery of + `commonZeroCount` modulo `2 ^ ℓ` when `Fintype.card ι < ℓ`. +* `Cslib.BitString.card_heavyVars_le_div` and `Cslib.BitString.varIncidence_sdiff_heavyVars_le`: + heavy-variable cardinality bound and light-variable incidence bound. +* `Cslib.BitString.monomialSum_zmod_two_restrictMonomials` and + `Cslib.BitString.commonZeroCount_eq_sum_branches`: exact `𝔽₂` specialization and additive branch + decomposition of `commonZeroCount`. +* `Cslib.BitString.prod_parityFactorCleared_mul`, + `Cslib.BitString.coeffNorm1_clearedMonomialSumPoly_le`, and + `Cslib.BitString.coeffNorm1_coeff_parityFactorCleared_le`: cleared-denominator homogenization + ($\Delta = d_{\text{den}}^k$, $\Gamma = \Delta^{2\ell-1}$, $\Omega = \Gamma^{\#I}$) and numerator + `ℓ₁`-norm bounds from §5.4 and Appendix B.2. + +## References + +* [S. Toda, *PP is as hard as the polynomial-time hierarchy*][Toda1991] +* [S. Arora, B. Barak, *Computational Complexity: A Modern Approach*][AroraBarak09] +* [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] + (Sections 5.1, 5.3, 5.4, 5.5, and Appendix B.2) +-/ + +@[expose] public noncomputable section + +namespace Cslib.BitString + +open Finset MvPolynomial + +variable {ι κ σ R : Type*} + +/-! ### 1. Monomial sums, integer lifts, and `commonZeroCount` -/ + +/-- The sum of the monomials in `𝓜 : Finset (Finset ι)` evaluated at `x : ι → Bool` in `R`. -/ +def monomialSum (R : Type*) [CommRing R] (𝓜 : Finset (Finset ι)) (x : ι → Bool) : R := + ∑ M ∈ 𝓜, monomial R M x + +/-- The empty family of monomials evaluates to `0`. -/ +@[simp] +theorem monomialSum_empty (R : Type*) [CommRing R] (x : ι → Bool) : + monomialSum R (∅ : Finset (Finset ι)) x = 0 := by + simp only [monomialSum, sum_empty] + +/-- A singleton family `{M}` evaluates to `monomial R M x`. -/ +@[simp] +theorem monomialSum_singleton (R : Type*) [CommRing R] (M : Finset ι) (x : ι → Bool) : + monomialSum R {M} x = monomial R M x := by + simp only [monomialSum, sum_singleton] + +/-- `monomialSum R 𝓜 x` equals the cast to `R` of the number of monomials `M ∈ 𝓜` satisfied by +`x`. -/ +theorem monomialSum_eq_card_filter (R : Type*) [CommRing R] (𝓜 : Finset (Finset ι)) + (x : ι → Bool) : + monomialSum R 𝓜 x = (#{M ∈ 𝓜 | ∀ v ∈ M, x v = true} : R) := by + unfold monomialSum + simp only [monomial_apply, sum_boole] + +/-- If every monomial in `𝓜` has size at most `k`, then `monomialSum R 𝓜` has degree at most `k` +on the Boolean cube. -/ +theorem monomialSum_mem_lowDegree (R : Type*) [CommRing R] {𝓜 : Finset (Finset ι)} {k : ℕ} + (hk : ∀ M ∈ 𝓜, #M ≤ k) : + monomialSum R 𝓜 ∈ lowDegree R ι k := by + have hEq : monomialSum R 𝓜 = ∑ M ∈ 𝓜, monomial R M := by + funext x + simp only [monomialSum, Finset.sum_apply] + rw [hEq] + exact sum_mem_lowDegree 𝓜 fun M hM => monomial_mem_lowDegree (hk M hM) + +/-- Over `ℤ`, `monomialSum ℤ 𝓜 x` is nonnegative. -/ +theorem monomialSum_int_nonneg (𝓜 : Finset (Finset ι)) (x : ι → Bool) : + 0 ≤ monomialSum ℤ 𝓜 x := by + rw [monomialSum_eq_card_filter] + exact Nat.cast_nonneg _ + +/-- Over `ℤ`, `monomialSum ℤ 𝓜 x` is at most `#𝓜`. -/ +theorem monomialSum_int_le_card (𝓜 : Finset (Finset ι)) (x : ι → Bool) : + monomialSum ℤ 𝓜 x ≤ #𝓜 := by + rw [monomialSum_eq_card_filter] + exact Nat.cast_le.mpr (card_filter_le _ _) + +/-- A monomial sum vanishes in `ZMod 2` at `x` if and only if its integer lift `monomialSum ℤ 𝓜 x` +is even. -/ +theorem monomialSum_zmod_two_eq_zero_iff_even (𝓜 : Finset (Finset ι)) (x : ι → Bool) : + monomialSum (ZMod 2) 𝓜 x = 0 ↔ Even (monomialSum ℤ 𝓜 x) := by + rw [monomialSum_eq_card_filter (ZMod 2), monomialSum_eq_card_filter ℤ, + ZMod.natCast_eq_zero_iff_even, Int.even_coe_nat] + +/-- An assignment `x : ι → Bool` is a common zero of the family `{P i}_{i ∈ I}` over `𝔽₂` if every +equation `P i` (`i ∈ I`) evaluates to `0` in `ZMod 2` at `x`. -/ +def IsCommonZero (I : Finset κ) (P : κ → Finset (Finset ι)) (x : ι → Bool) : Prop := + ∀ i ∈ I, monomialSum (ZMod 2) (P i) x = 0 + +instance instDecidableIsCommonZero (I : Finset κ) (P : κ → Finset (Finset ι)) + (x : ι → Bool) : Decidable (IsCommonZero I P x) := by + unfold IsCommonZero + infer_instance + +/-- `x` is a common zero over `𝔽₂` if and only if all integer evaluations `monomialSum ℤ (P i) x` +(`i ∈ I`) are even. -/ +theorem isCommonZero_iff_forall_even (I : Finset κ) (P : κ → Finset (Finset ι)) (x : ι → Bool) : + IsCommonZero I P x ↔ ∀ i ∈ I, Even (monomialSum ℤ (P i) x) := by + unfold IsCommonZero + exact forall₂_congr fun i _ => monomialSum_zmod_two_eq_zero_iff_even (P i) x + +/-- The number of common zeros `x : ι → Bool` of the polynomial system `{P i}_{i ∈ I}` over `𝔽₂`. -/ +def commonZeroCount [Fintype ι] [DecidableEq ι] (I : Finset κ) (P : κ → Finset (Finset ι)) : ℕ := + #{x : ι → Bool | IsCommonZero I P x} + +/-- At any assignment `x`, the product of the evenness indicators of `monomialSum ℤ (P i) x` over +`i ∈ I` is `1` if `IsCommonZero I P x` and `0` otherwise. -/ +theorem prod_even_monomialSum_eq_ite (I : Finset κ) (P : κ → Finset (Finset ι)) (x : ι → Bool) : + (∏ i ∈ I, if Even (monomialSum ℤ (P i) x) then (1 : ℤ) else 0) = + if IsCommonZero I P x then 1 else 0 := by + simp only [prod_boole, isCommonZero_iff_forall_even] + +/-- **Equation (5.1)**: the common-zero count of `{P i}_{i ∈ I}` over `𝔽₂` equals the sum over the +Boolean cube of the product of evenness indicators of the integer lifts `monomialSum ℤ (P i) x`. -/ +theorem sum_prod_even_monomialSum_eq_commonZeroCount [Fintype ι] [DecidableEq ι] (I : Finset κ) + (P : κ → Finset (Finset ι)) : + (∑ x : ι → Bool, ∏ i ∈ I, if Even (monomialSum ℤ (P i) x) then (1 : ℤ) else 0) = + commonZeroCount I P := by + calc + (∑ x : ι → Bool, ∏ i ∈ I, if Even (monomialSum ℤ (P i) x) then (1 : ℤ) else 0) + = ∑ x : ι → Bool, if IsCommonZero I P x then (1 : ℤ) else 0 := by + refine sum_congr rfl fun x _ => ?_ + exact prod_even_monomialSum_eq_ite I P x + _ = commonZeroCount I P := by + rw [commonZeroCount, sum_boole] + +/-- An empty system of equations has `2 ^ Fintype.card ι` common zeros. -/ +@[simp] +theorem commonZeroCount_empty [Fintype ι] [DecidableEq ι] (P : κ → Finset (Finset ι)) : + commonZeroCount (∅ : Finset κ) P = 2 ^ Fintype.card ι := by + have htrue : ∀ x ∈ (univ : Finset (ι → Bool)), IsCommonZero (∅ : Finset κ) P x := by + intro x _ i hi + exact False.elim (notMem_empty i hi) + rw [commonZeroCount, filter_true_of_mem htrue, card_univ, Fintype.card_fun, Fintype.card_bool] + +/-- If some equation `i ∈ I` is the constant polynomial `1` (`P i = {∅}`), there are no common +zeros. -/ +theorem commonZeroCount_eq_zero_of_singleton_empty [Fintype ι] [DecidableEq ι] {I : Finset κ} + {P : κ → Finset (Finset ι)} {i : κ} (hi : i ∈ I) (hP : P i = {∅}) : + commonZeroCount I P = 0 := by + rw [commonZeroCount, card_eq_zero, filter_eq_empty_iff] + intro x _ hcz + have h1 := hcz i hi + rw [hP, monomialSum_singleton, monomial_empty, Pi.one_apply] at h1 + exact one_ne_zero h1 + +/-- `commonZeroCount I P` is at most `2 ^ Fintype.card ι`. -/ +theorem commonZeroCount_le_two_pow [Fintype ι] [DecidableEq ι] (I : Finset κ) + (P : κ → Finset (Finset ι)) : + commonZeroCount I P ≤ 2 ^ Fintype.card ι := by + rw [commonZeroCount] + calc + #{x : ι → Bool | IsCommonZero I P x} ≤ #(univ : Finset (ι → Bool)) := card_filter_le _ _ + _ = 2 ^ Fintype.card ι := by + rw [card_univ, Fintype.card_fun, Fintype.card_bool] + +/-! ### 2. Formal multilinear lifts and replacement total-degree bounds -/ + +/-- The formal multilinear monomial `∏ v ∈ M, X v` in `MvPolynomial ι R`. -/ +def monomialPoly (R : Type*) [CommSemiring R] (M : Finset ι) : MvPolynomial ι R := + ∏ v ∈ M, X v + +/-- The formal multilinear polynomial `∑ M ∈ 𝓜, ∏ v ∈ M, X v` in `MvPolynomial ι R`. -/ +def monomialSumPoly (R : Type*) [CommSemiring R] (𝓜 : Finset (Finset ι)) : MvPolynomial ι R := + ∑ M ∈ 𝓜, monomialPoly R M + +/-- Evaluating `monomialPoly R M` at `v ↦ bitVal R (x v)` gives `monomial R M x`. -/ +@[simp] +theorem aeval_bitVal_monomialPoly (R : Type*) [CommRing R] (M : Finset ι) (x : ι → Bool) : + aeval (fun v => bitVal R (x v)) (monomialPoly R M) = monomial R M x := by + simp only [monomialPoly, monomial, map_prod, aeval_X] + +/-- Evaluating `monomialSumPoly R 𝓜` at `v ↦ bitVal R (x v)` gives `monomialSum R 𝓜 x`. -/ +@[simp] +theorem aeval_bitVal_monomialSumPoly (R : Type*) [CommRing R] (𝓜 : Finset (Finset ι)) + (x : ι → Bool) : + aeval (fun v => bitVal R (x v)) (monomialSumPoly R 𝓜) = monomialSum R 𝓜 x := by + simp only [monomialSumPoly, monomialSum, map_sum, aeval_bitVal_monomialPoly] + +/-- Evaluating `monomialPoly R M` via `eval₂ f q` gives `∏ v ∈ M, q v`. -/ +theorem eval₂_monomialPoly {S : Type*} [CommSemiring R] [CommSemiring S] (f : R →+* S) + (q : ι → S) (M : Finset ι) : + (monomialPoly R M).eval₂ f q = ∏ v ∈ M, q v := by + unfold monomialPoly + rw [← coe_eval₂Hom, map_prod] + refine prod_congr rfl fun v _ => ?_ + simp only [coe_eval₂Hom, eval₂_X] + +/-- Evaluating `monomialSumPoly R 𝓜` via `eval₂ f q` gives `∑ M ∈ 𝓜, ∏ v ∈ M, q v`. -/ +theorem eval₂_monomialSumPoly {S : Type*} [CommSemiring R] [CommSemiring S] (f : R →+* S) + (q : ι → S) (𝓜 : Finset (Finset ι)) : + (monomialSumPoly R 𝓜).eval₂ f q = ∑ M ∈ 𝓜, ∏ v ∈ M, q v := by + unfold monomialSumPoly + rw [← coe_eval₂Hom, map_sum] + refine sum_congr rfl fun M _ => ?_ + rw [coe_eval₂Hom, eval₂_monomialPoly] + +/-- `monomialPoly R M` has total degree at most `#M`. -/ +theorem totalDegree_monomialPoly_le (R : Type*) [CommSemiring R] (M : Finset ι) : + (monomialPoly R M).totalDegree ≤ #M := by + unfold monomialPoly + refine (totalDegree_finsetProd M _).trans ?_ + refine (sum_le_card_nsmul M _ 1 fun v _ => ?_).trans ?_ + · exact (totalDegree_monomial_le _ _).trans (by simp) + · simp only [smul_eq_mul, mul_one, le_rfl] + +/-- If every monomial `M ∈ 𝓜` has size at most `k`, then `monomialSumPoly R 𝓜` has total degree +at most `k`. -/ +theorem totalDegree_monomialSumPoly_le (R : Type*) [CommSemiring R] {𝓜 : Finset (Finset ι)} + {k : ℕ} (hk : ∀ M ∈ 𝓜, #M ≤ k) : + (monomialSumPoly R 𝓜).totalDegree ≤ k := by + unfold monomialSumPoly + refine (totalDegree_finsetSum 𝓜 _).trans (Finset.sup_le fun M hM => ?_) + exact (totalDegree_monomialPoly_le R M).trans (hk M hM) + +/-- Substituting polynomials `q v` of total degree at most `d₀` into `monomialPoly R M` produces a +polynomial of total degree at most `#M * d₀`. -/ +theorem totalDegree_eval₂_monomialPoly_le [CommSemiring R] (f : R →+* MvPolynomial σ R) + (q : ι → MvPolynomial σ R) {M : Finset ι} {d₀ : ℕ} + (hq : ∀ v ∈ M, (q v).totalDegree ≤ d₀) : + ((monomialPoly R M).eval₂ f q).totalDegree ≤ #M * d₀ := by + rw [eval₂_monomialPoly] + refine (totalDegree_finsetProd M q).trans ?_ + exact (sum_le_card_nsmul M (fun v => (q v).totalDegree) d₀ hq).trans + (by simp only [smul_eq_mul, le_rfl]) + +/-- Substituting polynomials `q v` of total degree at most `d₀` into `monomialSumPoly R 𝓜` of +degree at most `k` produces a polynomial of total degree at most `k * d₀`. -/ +theorem totalDegree_eval₂_monomialSumPoly_le [CommSemiring R] (f : R →+* MvPolynomial σ R) + (q : ι → MvPolynomial σ R) {𝓜 : Finset (Finset ι)} {k d₀ : ℕ} + (hk : ∀ M ∈ 𝓜, #M ≤ k) + (hq : ∀ M ∈ 𝓜, ∀ v ∈ M, (q v).totalDegree ≤ d₀) : + ((monomialSumPoly R 𝓜).eval₂ f q).totalDegree ≤ k * d₀ := by + unfold monomialSumPoly + rw [← coe_eval₂Hom, map_sum] + refine (totalDegree_finsetSum 𝓜 _).trans (Finset.sup_le fun M hM => ?_) + rw [coe_eval₂Hom] + exact (totalDegree_eval₂_monomialPoly_le f q (hq M hM)).trans + (Nat.mul_le_mul_right d₀ (hk M hM)) + +/-! ### 3. Truncated parity-factor degree bound (eq. 5.5) and count recovery (eq. 5.4) -/ + +/-- **Equation (5.5) (retained coefficient degree bound under variable replacement)**: if every +equation `P i` (`i ∈ I`) has degree at most `k` and each variable is replaced by a polynomial +`q i v` of total degree at most `d₀`, then for `s < ℓ` the `V ^ s`-coefficient of the product of +parity factors has total degree at most `(k * d₀) * (#I + 2 * (ℓ - 1))`. -/ +theorem totalDegree_coeff_prod_parityFactor_eval₂_le_of_lt [CommRing R] (I : Finset κ) + {P : κ → Finset (Finset ι)} {ℓ s k d₀ : ℕ} (hs : s < ℓ) + (f : R →+* MvPolynomial σ R) (q : κ → ι → MvPolynomial σ R) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hq : ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, (q i v).totalDegree ≤ d₀) : + ((∏ i ∈ I, Polynomial.parityFactor ℓ ((monomialSumPoly R (P i)).eval₂ f (q i))).coeff + s).totalDegree ≤ (k * d₀) * (#I + 2 * (ℓ - 1)) := + Polynomial.totalDegree_coeff_prod_parityFactor_le_of_lt I hs fun i hi => + totalDegree_eval₂_monomialSumPoly_le f (q i) (hk i hi) (hq i hi) + +/-- **Equation (5.5) (truncated product degree bound under variable replacement)**: under the same +hypotheses, the truncated sum `S_ℓ(∏ i ∈ I, B_i(V))` has total degree at most +`(k * d₀) * (#I + 2 * (ℓ - 1))`. -/ +theorem totalDegree_sumCoeffsBelow_prod_parityFactor_eval₂_le [CommRing R] (I : Finset κ) + {P : κ → Finset (Finset ι)} (ℓ : ℕ) {k d₀ : ℕ} + (f : R →+* MvPolynomial σ R) (q : κ → ι → MvPolynomial σ R) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hq : ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, (q i v).totalDegree ≤ d₀) : + (Polynomial.sumCoeffsBelow ℓ + (∏ i ∈ I, Polynomial.parityFactor ℓ ((monomialSumPoly R (P i)).eval₂ f (q i)))).totalDegree ≤ + (k * d₀) * (#I + 2 * (ℓ - 1)) := + Polynomial.totalDegree_sumCoeffsBelow_prod_parityFactor_le I ℓ fun i hi => + totalDegree_eval₂_monomialSumPoly_le f (q i) (hk i hi) (hq i hi) + +/-- `Polynomial.sumCoeffsBelow ℓ` commutes with finite sums. -/ +theorem sumCoeffsBelow_sum {α A : Type*} [Semiring A] (s : Finset α) (ℓ : ℕ) + (F : α → Polynomial A) : + Polynomial.sumCoeffsBelow ℓ (∑ a ∈ s, F a) = + ∑ a ∈ s, Polynomial.sumCoeffsBelow ℓ (F a) := by + unfold Polynomial.sumCoeffsBelow + rw [sum_comm] + refine sum_congr rfl fun j _ => ?_ + rw [Polynomial.finsetSum_coeff] + +/-- **Equation (5.4) (congruence modulo `2 ^ ℓ`)**: for `ℓ ≥ 1`, summing the truncated product of +parity factors of `monomialSum ℤ (P i) x` over `x : ι → Bool` recovers `commonZeroCount I P` +modulo `2 ^ ℓ`. -/ +theorem sum_sumCoeffsBelow_prod_parityFactor_modEq_commonZeroCount [Fintype ι] [DecidableEq ι] + (I : Finset κ) (P : κ → Finset (Finset ι)) {ℓ : ℕ} (hℓ : 1 ≤ ℓ) : + (∑ x : ι → Bool, + Polynomial.sumCoeffsBelow ℓ (∏ i ∈ I, Polynomial.parityFactor ℓ (monomialSum ℤ (P i) x))) ≡ + (commonZeroCount I P : ℤ) [ZMOD (2 : ℤ) ^ ℓ] := by + rw [← sum_prod_even_monomialSum_eq_commonZeroCount I P] + exact Int.ModEq.sum fun x _ => + Polynomial.sumCoeffsBelow_prod_parityFactor_modEq I hℓ (fun i => monomialSum ℤ (P i) x) + +/-- **Equation (5.4) (exact recovery via `% 2 ^ ℓ`)**: when `Fintype.card ι < ℓ` (in particular for +`ℓ = Fintype.card ι + 1`), reducing the cube sum of truncated parity-factor products modulo +`2 ^ ℓ` recovers `commonZeroCount I P` on the nose. -/ +theorem emod_sum_sumCoeffsBelow_prod_parityFactor_eq_commonZeroCount [Fintype ι] [DecidableEq ι] + (I : Finset κ) (P : κ → Finset (Finset ι)) {ℓ : ℕ} (hℓ : Fintype.card ι < ℓ) : + (∑ x : ι → Bool, + Polynomial.sumCoeffsBelow ℓ (∏ i ∈ I, Polynomial.parityFactor ℓ (monomialSum ℤ (P i) x))) % + ((2 : ℤ) ^ ℓ) = commonZeroCount I P := by + have hℓ1 : 1 ≤ ℓ := by omega + have hmod : + (∑ x : ι → Bool, + Polynomial.sumCoeffsBelow ℓ (∏ i ∈ I, Polynomial.parityFactor ℓ (monomialSum ℤ (P i) x))) % + ((2 : ℤ) ^ ℓ) = (commonZeroCount I P : ℤ) % ((2 : ℤ) ^ ℓ) := + sum_sumCoeffsBelow_prod_parityFactor_modEq_commonZeroCount I P hℓ1 + rw [hmod, Int.emod_eq_of_lt (Nat.cast_nonneg _)] + have hle : (commonZeroCount I P : ℤ) ≤ (2 : ℤ) ^ Fintype.card ι := by + exact_mod_cast commonZeroCount_le_two_pow I P + have hlt : (2 : ℤ) ^ Fintype.card ι < (2 : ℤ) ^ ℓ := by + exact_mod_cast Nat.pow_lt_pow_right (by omega : 1 < 2) hℓ + exact lt_of_le_of_lt hle hlt + +/-! ### 4. Heavy-variable incidence bounds (§5.5) -/ + +/-- The number of constraints `i ∈ F` whose scope `scope i` contains variable `v`. -/ +def varIncidence [DecidableEq ι] (F : Finset κ) (scope : κ → Finset ι) (v : ι) : ℕ := + #{i ∈ F | v ∈ scope i} + +/-- The total variable-constraint incidence `∑ i ∈ F, #(scope i)`. -/ +def totalIncidence (F : Finset κ) (scope : κ → Finset ι) : ℕ := + ∑ i ∈ F, #(scope i) + +/-- Double-counting variable-constraint incidences over a universe `U` containing all scopes. -/ +theorem sum_varIncidence_eq_totalIncidence [DecidableEq ι] (U : Finset ι) (F : Finset κ) + (scope : κ → Finset ι) (hU : ∀ i ∈ F, scope i ⊆ U) : + ∑ v ∈ U, varIncidence F scope v = totalIncidence F scope := by + unfold varIncidence totalIncidence + simp only [card_eq_sum_ones] + have h1 : (∑ v ∈ U, ∑ x ∈ {i ∈ F | v ∈ scope i}, 1) = + ∑ v ∈ U, ∑ i ∈ F, if v ∈ scope i then 1 else 0 := by + refine sum_congr rfl fun v _ => ?_ + rw [sum_filter] + rw [h1, sum_comm] + refine sum_congr rfl fun i hi => ?_ + rw [← sum_filter, filter_mem_eq_inter, inter_eq_right.mpr (hU i hi)] + +/-- If every constraint in `F` has scope size at most `k`, then `totalIncidence F scope` is at +most `k * #F`. -/ +theorem totalIncidence_le_mul_card (F : Finset κ) (scope : κ → Finset ι) {k : ℕ} + (hk : ∀ i ∈ F, #(scope i) ≤ k) : + totalIncidence F scope ≤ k * #F := by + unfold totalIncidence + refine (sum_le_card_nsmul F (fun i => #(scope i)) k hk).trans ?_ + rw [smul_eq_mul, mul_comm] + +/-- The set of heavy variables in `U` whose incidence in `F` strictly exceeds `b₀`. -/ +def heavyVars [DecidableEq ι] (U : Finset ι) (F : Finset κ) (scope : κ → Finset ι) + (b₀ : ℕ) : Finset ι := + {v ∈ U | b₀ < varIncidence F scope v} + +/-- Markov / counting bound: `#(heavyVars U F scope b₀) * (b₀ + 1) ≤ totalIncidence F scope`. -/ +theorem card_heavyVars_mul_succ_le_totalIncidence [DecidableEq ι] (U : Finset ι) (F : Finset κ) + (scope : κ → Finset ι) (b₀ : ℕ) (hU : ∀ i ∈ F, scope i ⊆ U) : + #(heavyVars U F scope b₀) * (b₀ + 1) ≤ totalIncidence F scope := by + rw [← sum_varIncidence_eq_totalIncidence U F scope hU] + calc + #(heavyVars U F scope b₀) * (b₀ + 1) + = ∑ _v ∈ heavyVars U F scope b₀, (b₀ + 1) := by + rw [sum_const, smul_eq_mul] + _ ≤ ∑ v ∈ heavyVars U F scope b₀, varIncidence F scope v := by + refine sum_le_sum fun v hv => ?_ + rw [heavyVars, mem_filter] at hv + exact hv.2 + _ ≤ ∑ v ∈ U, varIncidence F scope v := + sum_le_sum_of_subset (filter_subset _ U) + +/-- `#(heavyVars U F scope b₀) * b₀ ≤ totalIncidence F scope`. -/ +theorem card_heavyVars_mul_le_totalIncidence [DecidableEq ι] (U : Finset ι) (F : Finset κ) + (scope : κ → Finset ι) (b₀ : ℕ) (hU : ∀ i ∈ F, scope i ⊆ U) : + #(heavyVars U F scope b₀) * b₀ ≤ totalIncidence F scope := by + refine (Nat.mul_le_mul_left _ (Nat.le_succ b₀)).trans ?_ + exact card_heavyVars_mul_succ_le_totalIncidence U F scope b₀ hU + +/-- **§5.5 (heavy-variable cardinality bound)**: for `b₀ > 0`, the number of heavy variables is at +most `totalIncidence F scope / b₀`. -/ +theorem card_heavyVars_le_div [DecidableEq ι] (U : Finset ι) (F : Finset κ) + (scope : κ → Finset ι) {b₀ : ℕ} (hb₀ : 0 < b₀) (hU : ∀ i ∈ F, scope i ⊆ U) : + #(heavyVars U F scope b₀) ≤ totalIncidence F scope / b₀ := + (Nat.le_div_iff_mul_le hb₀).mpr (card_heavyVars_mul_le_totalIncidence U F scope b₀ hU) + +/-- **§5.5 (heavy-variable bound for `k`-bounded scopes)**: if `b₀ > 0` and every scope has size at +most `k`, then `#(heavyVars U F scope b₀) ≤ (k * #F) / b₀`. -/ +theorem card_heavyVars_le_mul_card_div [DecidableEq ι] (U : Finset ι) (F : Finset κ) + (scope : κ → Finset ι) {k b₀ : ℕ} (hb₀ : 0 < b₀) (hU : ∀ i ∈ F, scope i ⊆ U) + (hk : ∀ i ∈ F, #(scope i) ≤ k) : + #(heavyVars U F scope b₀) ≤ (k * #F) / b₀ := + (card_heavyVars_le_div U F scope hb₀ hU).trans + (Nat.div_le_div_right (totalIncidence_le_mul_card F scope hk)) + +/-- Every variable in `U \ heavyVars U F scope b₀` has incidence at most `b₀`. -/ +theorem varIncidence_le_of_mem_sdiff_heavyVars [DecidableEq ι] {U : Finset ι} {F : Finset κ} + {scope : κ → Finset ι} {b₀ : ℕ} {v : ι} (hv : v ∈ U \ heavyVars U F scope b₀) : + varIncidence F scope v ≤ b₀ := by + rw [mem_sdiff, heavyVars, mem_filter, not_and] at hv + exact Nat.le_of_not_lt (hv.2 hv.1) + +/-- Removing `heavyVars U F scope b₀` from every scope reduces the incidence of **every** variable +`v : ι` to at most `b₀`. -/ +theorem varIncidence_sdiff_heavyVars_le [DecidableEq ι] (U : Finset ι) (F : Finset κ) + (scope : κ → Finset ι) (b₀ : ℕ) (hU : ∀ i ∈ F, scope i ⊆ U) (v : ι) : + varIncidence F (fun i => scope i \ heavyVars U F scope b₀) v ≤ b₀ := by + by_cases hv : v ∈ U \ heavyVars U F scope b₀ + · have hsub : {i ∈ F | v ∈ scope i \ heavyVars U F scope b₀} ⊆ {i ∈ F | v ∈ scope i} := by + intro i hi + rw [mem_filter] at hi ⊢ + exact ⟨hi.1, (mem_sdiff.mp hi.2).1⟩ + exact (card_le_card hsub).trans (varIncidence_le_of_mem_sdiff_heavyVars hv) + · have hzero : varIncidence F (fun i => scope i \ heavyVars U F scope b₀) v = 0 := by + rw [varIncidence, card_eq_zero, filter_eq_empty_iff] + intro i hi hvi + rw [mem_sdiff] at hvi + apply hv + exact mem_sdiff.mpr ⟨hU i hi hvi.1, hvi.2⟩ + rw [hzero] + exact Nat.zero_le _ + +/-! ### 5. Exact branching on a variable subset `S` (§5.5) -/ + +/-- The assignment that takes values from `b` on `S` and from `y` outside `S`. -/ +def patchAssignment [DecidableEq ι] (S : Finset ι) (b y : ι → Bool) (v : ι) : Bool := + if v ∈ S then b v else y v + +/-- On `S`, `patchAssignment S b y` agrees with `b`. -/ +@[simp] +theorem patchAssignment_of_mem [DecidableEq ι] {S : Finset ι} {b y : ι → Bool} {v : ι} + (hv : v ∈ S) : + patchAssignment S b y v = b v := + ite_eq_left hv + +/-- Outside `S`, `patchAssignment S b y` agrees with `y`. -/ +@[simp] +theorem patchAssignment_of_notMem [DecidableEq ι] {S : Finset ι} {b y : ι → Bool} {v : ι} + (hv : v ∉ S) : + patchAssignment S b y v = y v := + ite_eq_right hv + +/-- A monomial `M` evaluated on `patchAssignment S b y` factors into the indicator that `b` is all +`true` on `M ∩ S` times `monomial R (M \ S) y`. -/ +theorem monomial_patchAssignment (R : Type*) [CommRing R] [DecidableEq ι] (S : Finset ι) + (b y : ι → Bool) (M : Finset ι) : + monomial R M (patchAssignment S b y) = + (if ∀ v ∈ M ∩ S, b v = true then 1 else 0) * monomial R (M \ S) y := by + rw [monomial_apply, monomial_apply] + have hiff : (∀ v ∈ M, patchAssignment S b y v = true) ↔ + (∀ v ∈ M ∩ S, b v = true) ∧ (∀ v ∈ M \ S, y v = true) := by + constructor + · intro h + refine ⟨fun v hv => ?_, fun v hv => ?_⟩ + · rw [mem_inter] at hv + simpa only [patchAssignment, hv.2, ↓reduceIte] using h v hv.1 + · rw [mem_sdiff] at hv + simpa only [patchAssignment, hv.2, ↓reduceIte] using h v hv.1 + · rintro ⟨h1, h2⟩ v hv + by_cases hvs : v ∈ S + · simp only [patchAssignment, hvs, ↓reduceIte] + exact h1 v (mem_inter.mpr ⟨hv, hvs⟩) + · simp only [patchAssignment, hvs, ↓reduceIte] + exact h2 v (mem_sdiff.mpr ⟨hv, hvs⟩) + by_cases h1 : ∀ v ∈ M ∩ S, b v = true + · by_cases h2 : ∀ v ∈ M \ S, y v = true + · rw [ite_eq_left (hiff.mpr ⟨h1, h2⟩), ite_eq_left h1, ite_eq_left h2, mul_one] + · rw [ite_eq_right (fun hc => h2 (hiff.mp hc).2), ite_eq_right h2, mul_zero] + · rw [ite_eq_right (fun hc => h1 (hiff.mp hc).1), ite_eq_right h1, zero_mul] + +/-- The reduced family of monomials in the remaining variables after specializing `S` to `b` and +combining duplicate restricted monomials `M \ S` modulo `2`. -/ +def restrictMonomials [DecidableEq ι] (S : Finset ι) (b : ι → Bool) + (𝓜 : Finset (Finset ι)) : Finset (Finset ι) := + {M' ∈ 𝓜.image (· \ S) | Odd #{M ∈ 𝓜 | M \ S = M' ∧ ∀ v ∈ M ∩ S, b v = true}} + +/-- Every monomial in `restrictMonomials S b 𝓜` is disjoint from `S`. -/ +theorem disjoint_of_mem_restrictMonomials [DecidableEq ι] {S : Finset ι} {b : ι → Bool} + {𝓜 : Finset (Finset ι)} {M' : Finset ι} (hM' : M' ∈ restrictMonomials S b 𝓜) : + Disjoint M' S := by + rw [restrictMonomials, mem_filter, mem_image] at hM' + rcases hM'.1 with ⟨M, _, rfl⟩ + exact sdiff_disjoint + +/-- Specializing `S` never increases the degree of any monomial: if `∀ M ∈ 𝓜, #M ≤ k`, then +`∀ M' ∈ restrictMonomials S b 𝓜, #M' ≤ k`. -/ +theorem card_le_of_mem_restrictMonomials [DecidableEq ι] {S : Finset ι} {b : ι → Bool} + {𝓜 : Finset (Finset ι)} {k : ℕ} (hk : ∀ M ∈ 𝓜, #M ≤ k) + {M' : Finset ι} (hM' : M' ∈ restrictMonomials S b 𝓜) : + #M' ≤ k := by + rw [restrictMonomials, mem_filter, mem_image] at hM' + rcases hM'.1 with ⟨M, hM, rfl⟩ + exact (card_le_card sdiff_subset).trans (hk M hM) + +/-- Specializing `S` and reducing modulo `2` never increases the number of monomials: +`#(restrictMonomials S b 𝓜) ≤ #𝓜`. -/ +theorem card_restrictMonomials_le [DecidableEq ι] (S : Finset ι) (b : ι → Bool) + (𝓜 : Finset (Finset ι)) : + #(restrictMonomials S b 𝓜) ≤ #𝓜 := + (card_filter_le _ _).trans card_image_le + +/-- Over any commutative ring `R`, `monomialSum R 𝓜 (patchAssignment S b y)` groups by restricted +monomials `M' ∈ 𝓜.image (· \ S)`. -/ +theorem monomialSum_patchAssignment_eq_sum_image (R : Type*) [CommRing R] [DecidableEq ι] + (S : Finset ι) (b y : ι → Bool) (𝓜 : Finset (Finset ι)) : + monomialSum R 𝓜 (patchAssignment S b y) = + ∑ M' ∈ 𝓜.image (· \ S), + (#{M ∈ 𝓜 | M \ S = M' ∧ ∀ v ∈ M ∩ S, b v = true} : R) * monomial R M' y := by + unfold monomialSum + rw [← sum_fiberwise_of_maps_to (fun M hM => mem_image_of_mem (· \ S) hM)] + refine sum_congr rfl fun M' _ => ?_ + have hcongr : + (∑ M ∈ {M ∈ 𝓜 | M \ S = M'}, monomial R M (patchAssignment S b y)) = + ∑ M ∈ {M ∈ 𝓜 | M \ S = M'}, + (if ∀ v ∈ M ∩ S, b v = true then (1 : R) else 0) * monomial R M' y := by + refine sum_congr rfl fun M hM => ?_ + rw [mem_filter] at hM + rw [monomial_patchAssignment, hM.2] + rw [hcongr, ← sum_mul, sum_boole, filter_filter] + +/-- **§5.5 (exact `𝔽₂` specialization)**: over `ZMod 2`, evaluating `restrictMonomials S b 𝓜` at +`y` equals evaluating the original family `𝓜` at `patchAssignment S b y`. -/ +theorem monomialSum_zmod_two_restrictMonomials [DecidableEq ι] (S : Finset ι) (b y : ι → Bool) + (𝓜 : Finset (Finset ι)) : + monomialSum (ZMod 2) (restrictMonomials S b 𝓜) y = + monomialSum (ZMod 2) 𝓜 (patchAssignment S b y) := by + rw [monomialSum_patchAssignment_eq_sum_image, monomialSum, restrictMonomials, sum_filter] + refine sum_congr rfl fun M' _ => ?_ + by_cases hodd : Odd #{M ∈ 𝓜 | M \ S = M' ∧ ∀ v ∈ M ∩ S, b v = true} + · have hcast : (#{M ∈ 𝓜 | M \ S = M' ∧ ∀ v ∈ M ∩ S, b v = true} : ZMod 2) = 1 := by + rcases hodd with ⟨m, hm⟩ + have h2 : (2 : ZMod 2) = 0 := rfl + rw [hm, Nat.cast_add, Nat.cast_mul, Nat.cast_ofNat, Nat.cast_one, h2, zero_mul, zero_add] + simp only [hodd, ↓reduceIte, hcast, one_mul] + · have heven : Even #{M ∈ 𝓜 | M \ S = M' ∧ ∀ v ∈ M ∩ S, b v = true} := + Nat.not_odd_iff_even.mp hodd + have hcast : (#{M ∈ 𝓜 | M \ S = M' ∧ ∀ v ∈ M ∩ S, b v = true} : ZMod 2) = 0 := + (ZMod.natCast_eq_zero_iff_even.mpr heven) + simp only [hodd, ↓reduceIte, hcast, zero_mul] + +/-- `patchAssignment S b y` is a common zero of `P` if and only if `y` is a common zero of the +specialized system `fun i => restrictMonomials S b (P i)`. -/ +theorem isCommonZero_patchAssignment_iff [DecidableEq ι] (S : Finset ι) (b y : ι → Bool) + (I : Finset κ) (P : κ → Finset (Finset ι)) : + IsCommonZero I P (patchAssignment S b y) ↔ + IsCommonZero I (fun i => restrictMonomials S b (P i)) y := by + unfold IsCommonZero + refine forall₂_congr fun i _ => ?_ + rw [monomialSum_zmod_two_restrictMonomials] + +/-- Canonical branch assignments supported on `S` (`false` outside `S`). -/ +def branchAssignments [Fintype ι] [DecidableEq ι] (S : Finset ι) : Finset (ι → Bool) := + {b : ι → Bool | ∀ v ∉ S, b v = false} + +/-- Canonical subproblem assignments supported outside `S` (`false` on `S`). -/ +def subproblemAssignments [Fintype ι] [DecidableEq ι] (S : Finset ι) : Finset (ι → Bool) := + {y : ι → Bool | ∀ v ∈ S, y v = false} + +/-- There are `2 ^ #S` canonical branch assignments in `branchAssignments S`. -/ +theorem card_branchAssignments [Fintype ι] [DecidableEq ι] (S : Finset ι) : + #(branchAssignments S) = 2 ^ #S := by + have hbij : + #(branchAssignments S) = #(univ : Finset (S → Bool)) := by + refine card_nbij' (fun b (v : S) => b v.1) + (fun g v => if hv : v ∈ S then g ⟨v, hv⟩ else false) ?_ ?_ ?_ ?_ + · intro b _ + exact mem_coe.mpr (mem_univ _) + · intro g _ + rw [mem_coe, branchAssignments, mem_filter] + refine ⟨mem_univ _, fun v hv => dite_eq_right hv⟩ + · intro b hb + rw [mem_coe, branchAssignments, mem_filter] at hb + funext v + by_cases hv : v ∈ S + · exact dite_eq_left hv + · exact (dite_eq_right hv).trans (hb.2 v hv).symm + · intro g _ + funext ⟨v, hv⟩ + exact dite_eq_left hv + rw [hbij, card_univ, Fintype.card_fun, Fintype.card_bool, Fintype.card_coe] + +/-- The variable scope `⋃ M ∈ 𝓜, M` of a family `𝓜` of monomials. -/ +def equationScope [DecidableEq ι] (𝓜 : Finset (Finset ι)) : Finset ι := + 𝓜.biUnion id + +/-- If every monomial in `𝓜` has size at most `k`, then `#(equationScope 𝓜) ≤ k * #𝓜`. -/ +theorem card_equationScope_le [DecidableEq ι] {𝓜 : Finset (Finset ι)} {k : ℕ} + (hk : ∀ M ∈ 𝓜, #M ≤ k) : + #(equationScope 𝓜) ≤ k * #𝓜 := by + unfold equationScope + refine card_biUnion_le.trans ?_ + refine (sum_le_card_nsmul 𝓜 (fun M => #M) k hk).trans ?_ + rw [smul_eq_mul, mul_comm] + +/-- After specializing `S`, the variable scope of `restrictMonomials S b 𝓜` is contained in +`equationScope 𝓜 \ S`. -/ +theorem equationScope_restrictMonomials_subset_sdiff [DecidableEq ι] (S : Finset ι) + (b : ι → Bool) (𝓜 : Finset (Finset ι)) : + equationScope (restrictMonomials S b 𝓜) ⊆ equationScope 𝓜 \ S := by + intro v hv + rw [equationScope, mem_biUnion] at hv + rcases hv with ⟨M', hM', hvM'⟩ + rw [restrictMonomials, mem_filter, mem_image] at hM' + rcases hM'.1 with ⟨M, hM, rfl⟩ + rw [id_eq, mem_sdiff] at hvM' + rw [mem_sdiff, equationScope, mem_biUnion] + exact ⟨⟨M, hM, hvM'.1⟩, hvM'.2⟩ + +/-- **§5.5 (post-branching incidence bound)**: after branching on the heavy variables +`S = heavyVars U F (fun i => equationScope (P i)) b₀`, every variable `v : ι` appears in at most +`b₀` reduced scopes `equationScope (restrictMonomials S b (P i))` (`i ∈ F`). -/ +theorem varIncidence_equationScope_restrictMonomials_heavyVars_le [DecidableEq ι] + (U : Finset ι) (F : Finset κ) (P : κ → Finset (Finset ι)) (b₀ : ℕ) + (hU : ∀ i ∈ F, equationScope (P i) ⊆ U) (b : ι → Bool) (v : ι) : + varIncidence F + (fun i => equationScope + (restrictMonomials (heavyVars U F (fun i => equationScope (P i)) b₀) b (P i))) v ≤ + b₀ := by + let S := heavyVars U F (fun i => equationScope (P i)) b₀ + have hsub : + {i ∈ F | v ∈ equationScope (restrictMonomials S b (P i))} ⊆ + {i ∈ F | v ∈ equationScope (P i) \ S} := by + intro i hi + rw [mem_filter] at hi ⊢ + exact ⟨hi.1, equationScope_restrictMonomials_subset_sdiff S b (P i) hi.2⟩ + exact (card_le_card hsub).trans + (varIncidence_sdiff_heavyVars_le U F (fun i => equationScope (P i)) b₀ hU v) + +/-- **§5.5 (heavy-variable branch count bound)**: for `b₀ > 0`, the number of canonical branches on +`heavyVars U F scope b₀` is at most `2 ^ (totalIncidence F scope / b₀)`. -/ +theorem card_branchAssignments_heavyVars_le [Fintype ι] [DecidableEq ι] (U : Finset ι) + (F : Finset κ) (scope : κ → Finset ι) {b₀ : ℕ} (hb₀ : 0 < b₀) + (hU : ∀ i ∈ F, scope i ⊆ U) : + #(branchAssignments (heavyVars U F scope b₀)) ≤ 2 ^ (totalIncidence F scope / b₀) := by + rw [card_branchAssignments] + exact Nat.pow_le_pow_right (by omega) (card_heavyVars_le_div U F scope hb₀ hU) + +/-- **§5.5 (additive branch decomposition of `commonZeroCount`)**: branching over all canonical +assignments `b ∈ branchAssignments S` to `S` partitions `commonZeroCount I P` into the sum of +common-zero counts on `subproblemAssignments S` of the reduced systems +`fun i => restrictMonomials S b (P i)`. -/ +theorem commonZeroCount_eq_sum_branches [Fintype ι] [DecidableEq ι] (S : Finset ι) + (I : Finset κ) (P : κ → Finset (Finset ι)) : + commonZeroCount I P = + ∑ b ∈ branchAssignments S, + #{y ∈ subproblemAssignments S | + IsCommonZero I (fun i => restrictMonomials S b (P i)) y} := by + classical + have hbij : + #{x : ι → Bool | IsCommonZero I P x} = + ∑ p ∈ branchAssignments S ×ˢ subproblemAssignments S, + if IsCommonZero I P (patchAssignment S p.1 p.2) then 1 else 0 := by + rw [card_filter] + refine sum_nbij' (fun x => (fun v => if v ∈ S then x v else false, + fun v => if v ∈ S then false else x v)) + (fun p => patchAssignment S p.1 p.2) ?_ ?_ ?_ ?_ ?_ + · intro x _ + rw [mem_product, branchAssignments, subproblemAssignments, mem_filter, mem_filter] + refine ⟨⟨mem_univ _, fun v hv => ite_eq_right hv⟩, ⟨mem_univ _, fun v hv => ite_eq_left hv⟩⟩ + · intro p _ + exact mem_univ _ + · intro x _ + funext v + by_cases hv : v ∈ S <;> simp only [patchAssignment, hv, ↓reduceIte] + · intro p hp + rw [mem_product, branchAssignments, subproblemAssignments, mem_filter, mem_filter] at hp + ext v + · by_cases hv : v ∈ S + · simp only [patchAssignment, hv, ↓reduceIte] + · simp only [hv, ↓reduceIte, (hp.1.2 v hv).symm] + · by_cases hv : v ∈ S + · simp only [hv, ↓reduceIte, (hp.2.2 v hv).symm] + · simp only [patchAssignment, hv, ↓reduceIte] + · intro x _ + have hx : + patchAssignment S (fun v => if v ∈ S then x v else false) + (fun v => if v ∈ S then false else x v) = x := by + funext v + by_cases hv : v ∈ S <;> simp only [patchAssignment, hv, ↓reduceIte] + rw [hx] + rw [commonZeroCount, hbij, sum_product] + refine sum_congr rfl fun b _ => ?_ + rw [card_filter] + refine sum_congr rfl fun y _ => ?_ + simp only [isCommonZero_patchAssignment_iff] + +/-! ### 6. Cleared-denominator homogenization and `ℓ₁`-norm bounds (§5.4 & Appendix B.2) -/ + +/-- `Polynomial.coeffNorm1` satisfies the finite-sum triangle inequality. -/ +theorem coeffNorm1_sum_le {α : Type*} (s : Finset α) (f : α → Polynomial ℤ) : + Polynomial.coeffNorm1 (∑ a ∈ s, f a) ≤ ∑ a ∈ s, Polynomial.coeffNorm1 (f a) := by + classical + induction s using Finset.induction_on with + | empty => simp only [sum_empty, Polynomial.coeffNorm1_zero, le_refl] + | insert a s ha ih => + rw [sum_insert ha, sum_insert ha] + exact (Polynomial.coeffNorm1_add_le _ _).trans (add_le_add le_rfl ih) + +/-- `Polynomial.coeffNorm1` is invariant under negation. -/ +@[simp] +theorem coeffNorm1_neg (p : Polynomial ℤ) : + Polynomial.coeffNorm1 (-p) = Polynomial.coeffNorm1 p := by + rw [Polynomial.coeffNorm1, Polynomial.coeffNorm1, Polynomial.support_neg] + refine sum_congr rfl fun i _ => ?_ + rw [Polynomial.coeff_neg, Int.natAbs_neg] + +/-- `Polynomial.coeffNorm1 (p - q) ≤ Polynomial.coeffNorm1 p + Polynomial.coeffNorm1 q`. -/ +theorem coeffNorm1_sub_le (p q : Polynomial ℤ) : + Polynomial.coeffNorm1 (p - q) ≤ Polynomial.coeffNorm1 p + Polynomial.coeffNorm1 q := by + rw [sub_eq_add_neg] + exact (Polynomial.coeffNorm1_add_le p (-q)).trans (by rw [coeffNorm1_neg]) + +/-- `Polynomial.coeffNorm1` is submultiplicative on `ℤ[X]`. -/ +theorem coeffNorm1_mul_le (p q : Polynomial ℤ) : + Polynomial.coeffNorm1 (p * q) ≤ Polynomial.coeffNorm1 p * Polynomial.coeffNorm1 q := by + have hdecomp : p * q = ∑ i ∈ p.support, Polynomial.C (p.coeff i) * (q * Polynomial.X ^ i) := by + conv_lhs => rw [p.as_sum_support_C_mul_X_pow] + rw [sum_mul] + refine sum_congr rfl fun i _ => ?_ + ring + rw [hdecomp] + calc + Polynomial.coeffNorm1 (∑ i ∈ p.support, Polynomial.C (p.coeff i) * (q * Polynomial.X ^ i)) + ≤ ∑ i ∈ p.support, + Polynomial.coeffNorm1 (Polynomial.C (p.coeff i) * (q * Polynomial.X ^ i)) := + coeffNorm1_sum_le _ _ + _ ≤ ∑ i ∈ p.support, (p.coeff i).natAbs * Polynomial.coeffNorm1 q := by + refine sum_le_sum fun i _ => ?_ + exact (Polynomial.coeffNorm1_C_mul_le (p.coeff i) _).trans + (Nat.mul_le_mul_left _ (Polynomial.coeffNorm1_mul_X_pow_le q i)) + _ = Polynomial.coeffNorm1 p * Polynomial.coeffNorm1 q := by + rw [← sum_mul, ← Polynomial.coeffNorm1] + +/-- `Polynomial.coeffNorm1 (p ^ k) ≤ Polynomial.coeffNorm1 p ^ k`. -/ +theorem coeffNorm1_pow_le (p : Polynomial ℤ) (k : ℕ) : + Polynomial.coeffNorm1 (p ^ k) ≤ Polynomial.coeffNorm1 p ^ k := by + induction k with + | zero => + have h1 : (1 : Polynomial ℤ) = Polynomial.C 1 := by simp only [map_one] + simp only [pow_zero, h1, Polynomial.coeffNorm1_C, Int.natAbs_one, le_refl] + | succ k ih => + rw [pow_succ, pow_succ] + exact (coeffNorm1_mul_le _ _).trans (Nat.mul_le_mul_right _ ih) + +/-- `Polynomial.coeffNorm1` of a finite product is at most the product of the `coeffNorm1`s. -/ +theorem coeffNorm1_prod_le {α : Type*} (s : Finset α) (f : α → Polynomial ℤ) : + Polynomial.coeffNorm1 (∏ a ∈ s, f a) ≤ ∏ a ∈ s, Polynomial.coeffNorm1 (f a) := by + classical + induction s using Finset.induction_on with + | empty => + have h1 : (1 : Polynomial ℤ) = Polynomial.C 1 := by simp only [map_one] + simp only [prod_empty, h1, Polynomial.coeffNorm1_C, Int.natAbs_one, le_refl] + | insert a s ha ih => + rw [prod_insert ha, prod_insert ha] + exact (coeffNorm1_mul_le _ _).trans (Nat.mul_le_mul_left _ ih) + +/-- Cleared-denominator evaluation `a_j * Δ + b_j * A_i` of `parityBaseDigit ℓ j = a_j + b_j X` at +`L_i = A_i / Δ`. -/ +def parityBaseDigitCleared {A : Type*} [CommRing A] (ℓ j : ℕ) (Δ A_i : A) : A := + ((Polynomial.parityBaseDigit ℓ j).coeff 0 : A) * Δ + + ((Polynomial.parityBaseDigit ℓ j).coeff 1 : A) * A_i + +/-- Homogenization of `parityBaseDigit ℓ j`: `parityBaseDigitCleared ℓ j Δ (Δ * y) = +Δ * evalInt y (parityBaseDigit ℓ j)`. -/ +theorem parityBaseDigitCleared_mul {A : Type*} [CommRing A] (ℓ j : ℕ) (Δ y : A) : + parityBaseDigitCleared ℓ j Δ (Δ * y) = + Δ * Polynomial.evalInt y (Polynomial.parityBaseDigit ℓ j) := by + conv_rhs => + rw [Polynomial.evalInt, Polynomial.parityBaseDigit_eq_C_add_C_mul_X ℓ j, Polynomial.eval₂_add, + Polynomial.eval₂_mul, Polynomial.eval₂_X, Polynomial.eval₂_C, Polynomial.eval₂_C] + rw [parityBaseDigitCleared] + simp only [eq_intCast] + ring + +/-- Cleared-denominator evaluation `A_i * (A_i - Δ)` of `hPoly = X ^ 2 - X` at `L_i = A_i / Δ`. -/ +def hPolyCleared {A : Type*} [CommRing A] (Δ A_i : A) : A := + A_i * (A_i - Δ) + +/-- Homogenization of `hPoly`: `hPolyCleared Δ (Δ * y) = Δ ^ 2 * evalInt y hPoly`. -/ +theorem hPolyCleared_mul {A : Type*} [CommRing A] (Δ y : A) : + hPolyCleared Δ (Δ * y) = Δ ^ 2 * Polynomial.evalInt y Polynomial.hPoly := by + rw [hPolyCleared, Polynomial.evalInt_hPoly] + ring + +/-- The cleared-denominator parity factor `Γ B_i(V)` with uniform factor denominator +`Γ = Δ ^ (2 * ℓ - 1)`: +`∑ j ∈ range ℓ, C (Δ ^ (2 * (ℓ - 1 - j)) * parityBaseDigitCleared ℓ j Δ A_i * + hPolyCleared Δ A_i ^ j) * X ^ j`. -/ +def parityFactorCleared {A : Type*} [CommRing A] (ℓ : ℕ) (Δ A_i : A) : Polynomial A := + ∑ j ∈ range ℓ, + Polynomial.C + (Δ ^ (2 * (ℓ - 1 - j)) * parityBaseDigitCleared ℓ j Δ A_i * hPolyCleared Δ A_i ^ j) * + Polynomial.X ^ j + +/-- The `s`-th coefficient of `parityFactorCleared ℓ Δ A_i`. -/ +theorem coeff_parityFactorCleared {A : Type*} [CommRing A] (ℓ : ℕ) (Δ A_i : A) (s : ℕ) : + (parityFactorCleared ℓ Δ A_i).coeff s = + if s < ℓ then + Δ ^ (2 * (ℓ - 1 - s)) * parityBaseDigitCleared ℓ s Δ A_i * hPolyCleared Δ A_i ^ s + else 0 := by + rw [parityFactorCleared, Polynomial.finsetSum_coeff] + simp only [Polynomial.coeff_C_mul, Polynomial.coeff_X_pow, mul_ite, mul_one, mul_zero] + by_cases hs : s < ℓ + · rw [ite_eq_left hs, sum_eq_single s] + · simp only [↓reduceIte] + · intro j _ hjs + exact ite_eq_right (Ne.symm hjs) + · intro hns + exact absurd (mem_range.mpr hs) hns + · rw [ite_eq_right hs] + refine sum_eq_zero fun j hj => ?_ + rw [mem_range] at hj + exact ite_eq_right (by omega) + +/-- **§5.4 & Appendix B.2 (single-factor denominator clearing, $\Gamma = \Delta^{2\ell-1}$)**: for +`ℓ ≥ 1`, `parityFactorCleared ℓ Δ (Δ * y) = C (Δ ^ (2 * ℓ - 1)) * parityFactor ℓ y`. -/ +theorem parityFactorCleared_mul {A : Type*} [CommRing A] {ℓ : ℕ} (hℓ : 1 ≤ ℓ) (Δ y : A) : + parityFactorCleared ℓ Δ (Δ * y) = + Polynomial.C (Δ ^ (2 * ℓ - 1)) * Polynomial.parityFactor ℓ y := by + rw [parityFactorCleared, Polynomial.parityFactor, mul_sum] + refine sum_congr rfl fun j hj => ?_ + rw [mem_range] at hj + rw [parityBaseDigitCleared_mul, hPolyCleared_mul, mul_pow, ← pow_mul, + ← mul_assoc (Polynomial.C (Δ ^ (2 * ℓ - 1))), ← Polynomial.C_mul] + congr 2 + have hexp : 2 * (ℓ - 1 - j) + 1 + 2 * j = 2 * ℓ - 1 := by omega + calc + Δ ^ (2 * (ℓ - 1 - j)) * (Δ * Polynomial.evalInt y (Polynomial.parityBaseDigit ℓ j)) * + (Δ ^ (2 * j) * Polynomial.evalInt y Polynomial.hPoly ^ j) + = (Δ ^ (2 * (ℓ - 1 - j)) * Δ ^ 1 * Δ ^ (2 * j)) * + (Polynomial.evalInt y (Polynomial.parityBaseDigit ℓ j) * + Polynomial.evalInt y Polynomial.hPoly ^ j) := by ring + _ = Δ ^ (2 * ℓ - 1) * + (Polynomial.evalInt y (Polynomial.parityBaseDigit ℓ j) * + Polynomial.evalInt y Polynomial.hPoly ^ j) := by + rw [← pow_add, ← pow_add, hexp] + +/-- **§5.4 & Appendix B.2 (product denominator clearing, $\Omega = \Gamma^{\#I}$)**: for `ℓ ≥ 1`, +the product of cleared factors over `i ∈ I` equals `C ((Δ ^ (2 * ℓ - 1)) ^ #I)` times the product +of `parityFactor ℓ (y i)`. -/ +theorem prod_parityFactorCleared_mul {A : Type*} [CommRing A] (I : Finset κ) {ℓ : ℕ} (hℓ : 1 ≤ ℓ) + (Δ : A) (y : κ → A) : + (∏ i ∈ I, parityFactorCleared ℓ Δ (Δ * y i)) = + Polynomial.C ((Δ ^ (2 * ℓ - 1)) ^ #I) * ∏ i ∈ I, Polynomial.parityFactor ℓ (y i) := by + classical + induction I using Finset.induction_on with + | empty => + simp only [prod_empty, card_empty, pow_zero, map_one, one_mul] + | insert a I ha ih => + rw [prod_insert ha, prod_insert ha, card_insert_of_notMem ha, pow_succ', + parityFactorCleared_mul hℓ Δ (y a), ih, map_mul] + ring + +/-- Scaling a polynomial by `C c` scales `sumCoeffsBelow m` by `c`. -/ +theorem sumCoeffsBelow_C_mul {A : Type*} [CommRing A] (c : A) (p : Polynomial A) (m : ℕ) : + (Polynomial.C c * p).sumCoeffsBelow m = c * p.sumCoeffsBelow m := by + rw [Polynomial.sumCoeffsBelow, Polynomial.sumCoeffsBelow, mul_sum] + refine sum_congr rfl fun j _ => ?_ + exact Polynomial.coeff_C_mul p + +/-- **§5.4 (truncated cleared-denominator product)**: for `ℓ ≥ 1`, the sum of the first `m` +coefficients of `∏ i ∈ I, parityFactorCleared ℓ Δ (Δ * y i)` equals `(Δ ^ (2 * ℓ - 1)) ^ #I` +times the sum of the first `m` coefficients of `∏ i ∈ I, parityFactor ℓ (y i)`. -/ +theorem sumCoeffsBelow_prod_parityFactorCleared_mul {A : Type*} [CommRing A] (I : Finset κ) + {ℓ : ℕ} (hℓ : 1 ≤ ℓ) (Δ : A) (y : κ → A) (m : ℕ) : + (∏ i ∈ I, parityFactorCleared ℓ Δ (Δ * y i)).sumCoeffsBelow m = + (Δ ^ (2 * ℓ - 1)) ^ #I * (∏ i ∈ I, Polynomial.parityFactor ℓ (y i)).sumCoeffsBelow m := by + rw [prod_parityFactorCleared_mul I hℓ Δ y, sumCoeffsBelow_C_mul] + +/-- The cleared-denominator monomial `C (d_den ^ (k - #M)) * ∏ v ∈ M, θ v` in `ℤ[X]` for a monomial +`M` of degree at most `k` when each input has denominator `d_den`. -/ +def clearedMonomialPoly (d_den : ℤ) (k : ℕ) (θ : ι → Polynomial ℤ) (M : Finset ι) : Polynomial ℤ := + Polynomial.C (d_den ^ (k - #M)) * ∏ v ∈ M, θ v + +/-- The cleared-denominator monomial sum `A_i = ∑ M ∈ 𝓜, clearedMonomialPoly d_den k θ M` in +`ℤ[X]`. -/ +def clearedMonomialSumPoly (d_den : ℤ) (k : ℕ) (θ : ι → Polynomial ℤ) + (𝓜 : Finset (Finset ι)) : Polynomial ℤ := + ∑ M ∈ 𝓜, clearedMonomialPoly d_den k θ M + +/-- **Appendix B.2 (monomial numerator norm bound)**: if `d_den.natAbs ≤ B₀`, `#M ≤ k`, and every +`θ v` (`v ∈ M`) has `coeffNorm1 (θ v) ≤ B₀`, then +`coeffNorm1 (clearedMonomialPoly d_den k θ M) ≤ B₀ ^ k`. -/ +theorem coeffNorm1_clearedMonomialPoly_le {d_den : ℤ} {k B₀ : ℕ} {θ : ι → Polynomial ℤ} + {M : Finset ι} (hd : d_den.natAbs ≤ B₀) (hM : #M ≤ k) + (hθ : ∀ v ∈ M, Polynomial.coeffNorm1 (θ v) ≤ B₀) : + Polynomial.coeffNorm1 (clearedMonomialPoly d_den k θ M) ≤ B₀ ^ k := by + unfold clearedMonomialPoly + calc + Polynomial.coeffNorm1 (Polynomial.C (d_den ^ (k - #M)) * ∏ v ∈ M, θ v) + ≤ (d_den ^ (k - #M)).natAbs * Polynomial.coeffNorm1 (∏ v ∈ M, θ v) := + Polynomial.coeffNorm1_C_mul_le _ _ + _ ≤ B₀ ^ (k - #M) * ∏ v ∈ M, Polynomial.coeffNorm1 (θ v) := by + rw [Int.natAbs_pow] + exact Nat.mul_le_mul (Nat.pow_le_pow_left hd _) (coeffNorm1_prod_le M θ) + _ ≤ B₀ ^ (k - #M) * ∏ _v ∈ M, B₀ := + Nat.mul_le_mul_left _ (prod_le_prod hθ) + _ = B₀ ^ k := by + rw [prod_const, ← pow_add, Nat.sub_add_cancel hM] + +/-- **Appendix B.2 (equation numerator norm bound `∥Δ L_i∥₁ ≤ #𝓜 * B₀ ^ k`)**: under the same +hypotheses for all `M ∈ 𝓜`, `coeffNorm1 (clearedMonomialSumPoly d_den k θ 𝓜) ≤ #𝓜 * B₀ ^ k`. -/ +theorem coeffNorm1_clearedMonomialSumPoly_le {d_den : ℤ} {k B₀ : ℕ} {θ : ι → Polynomial ℤ} + {𝓜 : Finset (Finset ι)} (hd : d_den.natAbs ≤ B₀) (hk : ∀ M ∈ 𝓜, #M ≤ k) + (hθ : ∀ M ∈ 𝓜, ∀ v ∈ M, Polynomial.coeffNorm1 (θ v) ≤ B₀) : + Polynomial.coeffNorm1 (clearedMonomialSumPoly d_den k θ 𝓜) ≤ #𝓜 * B₀ ^ k := by + unfold clearedMonomialSumPoly + calc + Polynomial.coeffNorm1 (∑ M ∈ 𝓜, clearedMonomialPoly d_den k θ M) + ≤ ∑ M ∈ 𝓜, Polynomial.coeffNorm1 (clearedMonomialPoly d_den k θ M) := + coeffNorm1_sum_le 𝓜 _ + _ ≤ ∑ _M ∈ 𝓜, B₀ ^ k := + sum_le_sum fun M hM => coeffNorm1_clearedMonomialPoly_le hd (hk M hM) (hθ M hM) + _ = #𝓜 * B₀ ^ k := by + rw [sum_const, smul_eq_mul] + +/-- **Appendix B.2 (`∥Δ e_j(L_i)∥₁` bound)**: if `coeffNorm1 A_i ≤ B`, then +`coeffNorm1 (parityBaseDigitCleared ℓ j (C Δ) A_i) ≤ coeffNorm1 (parityBaseDigit ℓ j) * +(B + Δ.natAbs)`. -/ +theorem coeffNorm1_parityBaseDigitCleared_le (ℓ j : ℕ) (Δ : ℤ) {A_i : Polynomial ℤ} {B : ℕ} + (hA : Polynomial.coeffNorm1 A_i ≤ B) : + Polynomial.coeffNorm1 (parityBaseDigitCleared ℓ j (Polynomial.C Δ) A_i) ≤ + Polynomial.coeffNorm1 (Polynomial.parityBaseDigit ℓ j) * (B + Δ.natAbs) := by + rw [parityBaseDigitCleared] + have hcast : ∀ c : ℤ, (c : Polynomial ℤ) = Polynomial.C c := fun c => + (eq_intCast Polynomial.C c).symm + rw [hcast, hcast] + let a₀ := ((Polynomial.parityBaseDigit ℓ j).coeff 0).natAbs + let a₁ := ((Polynomial.parityBaseDigit ℓ j).coeff 1).natAbs + have h0 : Polynomial.coeffNorm1 + (Polynomial.C ((Polynomial.parityBaseDigit ℓ j).coeff 0) * Polynomial.C Δ) ≤ + a₀ * Δ.natAbs := by + refine (Polynomial.coeffNorm1_C_mul_le _ _).trans ?_ + rw [Polynomial.coeffNorm1_C] + have h1 : Polynomial.coeffNorm1 + (Polynomial.C ((Polynomial.parityBaseDigit ℓ j).coeff 1) * A_i) ≤ a₁ * B := + (Polynomial.coeffNorm1_C_mul_le _ _).trans (Nat.mul_le_mul_left a₁ hA) + have ha0 : a₀ ≤ Polynomial.coeffNorm1 (Polynomial.parityBaseDigit ℓ j) := + Polynomial.natAbs_coeff_le_coeffNorm1 _ 0 + have ha1 : a₁ ≤ Polynomial.coeffNorm1 (Polynomial.parityBaseDigit ℓ j) := + Polynomial.natAbs_coeff_le_coeffNorm1 _ 1 + calc + Polynomial.coeffNorm1 + (Polynomial.C ((Polynomial.parityBaseDigit ℓ j).coeff 0) * Polynomial.C Δ + + Polynomial.C ((Polynomial.parityBaseDigit ℓ j).coeff 1) * A_i) + ≤ a₀ * Δ.natAbs + a₁ * B := (Polynomial.coeffNorm1_add_le _ _).trans (add_le_add h0 h1) + _ ≤ Polynomial.coeffNorm1 (Polynomial.parityBaseDigit ℓ j) * Δ.natAbs + + Polynomial.coeffNorm1 (Polynomial.parityBaseDigit ℓ j) * B := + add_le_add (Nat.mul_le_mul_right _ ha0) (Nat.mul_le_mul_right _ ha1) + _ = Polynomial.coeffNorm1 (Polynomial.parityBaseDigit ℓ j) * (B + Δ.natAbs) := by ring + +/-- **Appendix B.2 (`∥A_i (A_i - Δ)∥₁` bound)**: if `coeffNorm1 A_i ≤ B`, then +`coeffNorm1 (hPolyCleared (C Δ) A_i) ≤ B * (B + Δ.natAbs)`. -/ +theorem coeffNorm1_hPolyCleared_le (Δ : ℤ) {A_i : Polynomial ℤ} {B : ℕ} + (hA : Polynomial.coeffNorm1 A_i ≤ B) : + Polynomial.coeffNorm1 (hPolyCleared (Polynomial.C Δ) A_i) ≤ B * (B + Δ.natAbs) := by + unfold hPolyCleared + calc + Polynomial.coeffNorm1 (A_i * (A_i - Polynomial.C Δ)) + ≤ Polynomial.coeffNorm1 A_i * Polynomial.coeffNorm1 (A_i - Polynomial.C Δ) := + coeffNorm1_mul_le _ _ + _ ≤ B * (Polynomial.coeffNorm1 A_i + Polynomial.coeffNorm1 (Polynomial.C Δ)) := + Nat.mul_le_mul hA (coeffNorm1_sub_le A_i (Polynomial.C Δ)) + _ ≤ B * (B + Δ.natAbs) := by + rw [Polynomial.coeffNorm1_C] + exact Nat.mul_le_mul_left B (add_le_add hA le_rfl) + +/-- **Appendix B.2 (`∥[V ^ s] (Γ B_i)∥₁` bound)**: if `coeffNorm1 A_i ≤ B`, then every `V ^ s`- +coefficient of `parityFactorCleared ℓ (C Δ) A_i` has `coeffNorm1` at most +`coeffNorm1 (parityBaseDigit ℓ s) * (B + Δ.natAbs) ^ (2 * ℓ - 1)`. -/ +theorem coeffNorm1_coeff_parityFactorCleared_le (ℓ : ℕ) (Δ : ℤ) {A_i : Polynomial ℤ} {B : ℕ} + (hA : Polynomial.coeffNorm1 A_i ≤ B) (s : ℕ) : + Polynomial.coeffNorm1 ((parityFactorCleared ℓ (Polynomial.C Δ) A_i).coeff s) ≤ + Polynomial.coeffNorm1 (Polynomial.parityBaseDigit ℓ s) * (B + Δ.natAbs) ^ (2 * ℓ - 1) := by + rw [coeff_parityFactorCleared] + split_ifs with hs + · have hpowΔ : + Polynomial.coeffNorm1 ((Polynomial.C Δ) ^ (2 * (ℓ - 1 - s))) ≤ + (B + Δ.natAbs) ^ (2 * (ℓ - 1 - s)) := by + refine (coeffNorm1_pow_le (Polynomial.C Δ) _).trans ?_ + rw [Polynomial.coeffNorm1_C] + exact Nat.pow_le_pow_left (Nat.le_add_left Δ.natAbs B) _ + have he : + Polynomial.coeffNorm1 (parityBaseDigitCleared ℓ s (Polynomial.C Δ) A_i) ≤ + Polynomial.coeffNorm1 (Polynomial.parityBaseDigit ℓ s) * (B + Δ.natAbs) := + coeffNorm1_parityBaseDigitCleared_le ℓ s Δ hA + have hh : + Polynomial.coeffNorm1 (hPolyCleared (Polynomial.C Δ) A_i ^ s) ≤ + (B + Δ.natAbs) ^ (2 * s) := by + calc + Polynomial.coeffNorm1 (hPolyCleared (Polynomial.C Δ) A_i ^ s) + ≤ Polynomial.coeffNorm1 (hPolyCleared (Polynomial.C Δ) A_i) ^ s := + coeffNorm1_pow_le _ s + _ ≤ (B * (B + Δ.natAbs)) ^ s := + Nat.pow_le_pow_left (coeffNorm1_hPolyCleared_le Δ hA) s + _ ≤ ((B + Δ.natAbs) * (B + Δ.natAbs)) ^ s := + Nat.pow_le_pow_left (Nat.mul_le_mul_right _ (Nat.le_add_right B Δ.natAbs)) s + _ = (B + Δ.natAbs) ^ (2 * s) := by + rw [← sq, ← pow_mul] + have hexp : 2 * (ℓ - 1 - s) + 1 + 2 * s = 2 * ℓ - 1 := by omega + calc + Polynomial.coeffNorm1 + ((Polynomial.C Δ) ^ (2 * (ℓ - 1 - s)) * + parityBaseDigitCleared ℓ s (Polynomial.C Δ) A_i * + hPolyCleared (Polynomial.C Δ) A_i ^ s) + ≤ Polynomial.coeffNorm1 + ((Polynomial.C Δ) ^ (2 * (ℓ - 1 - s)) * + parityBaseDigitCleared ℓ s (Polynomial.C Δ) A_i) * + Polynomial.coeffNorm1 (hPolyCleared (Polynomial.C Δ) A_i ^ s) := + coeffNorm1_mul_le _ _ + _ ≤ (Polynomial.coeffNorm1 ((Polynomial.C Δ) ^ (2 * (ℓ - 1 - s))) * + Polynomial.coeffNorm1 (parityBaseDigitCleared ℓ s (Polynomial.C Δ) A_i)) * + Polynomial.coeffNorm1 (hPolyCleared (Polynomial.C Δ) A_i ^ s) := + Nat.mul_le_mul_right _ (coeffNorm1_mul_le _ _) + _ ≤ ((B + Δ.natAbs) ^ (2 * (ℓ - 1 - s)) * + (Polynomial.coeffNorm1 (Polynomial.parityBaseDigit ℓ s) * (B + Δ.natAbs))) * + (B + Δ.natAbs) ^ (2 * s) := + Nat.mul_le_mul (Nat.mul_le_mul hpowΔ he) hh + _ = Polynomial.coeffNorm1 (Polynomial.parityBaseDigit ℓ s) * + ((B + Δ.natAbs) ^ (2 * (ℓ - 1 - s)) * (B + Δ.natAbs) ^ 1 * + (B + Δ.natAbs) ^ (2 * s)) := by ring + _ = Polynomial.coeffNorm1 (Polynomial.parityBaseDigit ℓ s) * + (B + Δ.natAbs) ^ (2 * ℓ - 1) := by + rw [← pow_add, ← pow_add, hexp] + · simp only [Polynomial.coeffNorm1_zero, zero_le] + +/-- **Appendix B.2 (explicit `∥[V ^ s] (Γ B_i)∥₁` bound)**: combining +`coeffNorm1_coeff_parityFactorCleared_le` with `coeffNorm1_parityBaseDigit_le` yields the explicit +exponential bound `2 * ((2 * ℓ) ^ s * 2 ^ (3 * ℓ)) * (B + Δ.natAbs) ^ (2 * ℓ - 1)` for every +`V ^ s`-coefficient of `parityFactorCleared ℓ (C Δ) A_i`. -/ +theorem coeffNorm1_coeff_parityFactorCleared_le_explicit (ℓ : ℕ) (Δ : ℤ) + {A_i : Polynomial ℤ} {B : ℕ} (hA : Polynomial.coeffNorm1 A_i ≤ B) (s : ℕ) : + Polynomial.coeffNorm1 ((parityFactorCleared ℓ (Polynomial.C Δ) A_i).coeff s) ≤ + 2 * ((2 * ℓ) ^ s * 2 ^ (3 * ℓ)) * (B + Δ.natAbs) ^ (2 * ℓ - 1) := + (coeffNorm1_coeff_parityFactorCleared_le ℓ Δ hA s).trans + (Nat.mul_le_mul_right _ (Polynomial.coeffNorm1_parityBaseDigit_le ℓ s)) + +end Cslib.BitString diff --git a/ComplexityTests/SparseEquations.lean b/ComplexityTests/SparseEquations.lean new file mode 100644 index 0000000000..1664c1c46b --- /dev/null +++ b/ComplexityTests/SparseEquations.lean @@ -0,0 +1,163 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Foundations.BooleanAnalysis.SparseEquations + +/-! +# Tests for sparse `𝔽₂` polynomial equations, common-zero recovery, and heavy-variable branching + +Concrete non-vacuity checks and edge-case controls for +`Complexity.Foundations.BooleanAnalysis.SparseEquations`. +-/ + +@[expose] public section + +namespace Cslib.BitString + +open Finset MvPolynomial + +/-- Equation `x₀ x₁ + 1 = 0` on `Fin 2 → Bool`: only `(true, true)` is a root over `𝔽₂`. -/ +def testEq0 : Finset (Finset (Fin 2)) := + {{0, 1}, ∅} + +/-- Equation `x₀ + x₁ = 0` on `Fin 2 → Bool`: `(false, false)` and `(true, true)` are roots. -/ +def testEq1 : Finset (Finset (Fin 2)) := + {{0}, {1}} + +/-- Concrete 2-equation system `{testEq0, testEq1}` on `Fin 2 → Bool` with unique common zero +`(true, true)`. -/ +def testSys : Fin 2 → Finset (Finset (Fin 2)) + | 0 => testEq0 + | 1 => testEq1 + +/-- At `(true, true)`, `testEq0` has `2` satisfied monomials (`{0, 1}` and `∅`), so its integer +evaluation is `2` (even) and its `ZMod 2` evaluation is `0`. -/ +example : monomialSum ℤ testEq0 (fun _ => true) = 2 := by + decide + +example : monomialSum (ZMod 2) testEq0 (fun _ => true) = 0 := by + decide + +/-- `testSys` has a unique common zero `(true, true)` on `Fin 2 → Bool`. -/ +example : commonZeroCount (univ : Finset (Fin 2)) testSys = 1 := by + decide + +/-- Both variables `0` and `1` appear in both equations of `testSys`, so both are heavy at +threshold `b₀ = 1`. -/ +example : heavyVars univ univ (fun i => equationScope (testSys i)) 1 = {0, 1} := by + decide + +/-- Equation (5.1) on `testSys`: the cube sum of products of evenness indicators equals +`commonZeroCount univ testSys`. -/ +example : + (∑ x : Fin 2 → Bool, + ∏ i ∈ (univ : Finset (Fin 2)), + if Even (monomialSum ℤ (testSys i) x) then (1 : ℤ) else 0) = + commonZeroCount (univ : Finset (Fin 2)) testSys := + sum_prod_even_monomialSum_eq_commonZeroCount univ testSys + +/-- Equation (5.4) exact recovery on `testSys` at precision `ℓ = 3 > Fintype.card (Fin 2)`: +reducing the cube sum of truncated parity-factor products modulo `2 ^ 3 = 8` recovers +`commonZeroCount univ testSys` on the nose. -/ +example : + (∑ x : Fin 2 → Bool, + Polynomial.sumCoeffsBelow 3 + (∏ i ∈ (univ : Finset (Fin 2)), + Polynomial.parityFactor 3 (monomialSum ℤ (testSys i) x))) % ((2 : ℤ) ^ 3) = + commonZeroCount (univ : Finset (Fin 2)) testSys := + emod_sum_sumCoeffsBelow_prod_parityFactor_eq_commonZeroCount univ testSys (by decide) + +/-- Edge cases: empty equation set has `2 ^ 2 = 4` common zeros, while a system containing `{∅}` +(`1 = 0`) has `0` common zeros. -/ +example : commonZeroCount (∅ : Finset (Fin 2)) testSys = 4 := + commonZeroCount_empty testSys + +example : + commonZeroCount ({0} : Finset (Fin 1)) (fun _ => ({∅} : Finset (Finset (Fin 2)))) = 0 := + commonZeroCount_eq_zero_of_singleton_empty (mem_singleton_self 0) rfl + +/-- Equation (5.5) total-degree bound under degree-`d₀` variable replacement (`k = 2`, `d₀ = 3`, +`#I = 2`, `ℓ = 2`): the truncated product has total degree at most `(2 * 3) * (2 + 2 * 1) = 24`. -/ +example (q : Fin 2 → Fin 2 → MvPolynomial (Fin 3) ℤ) + (hq : ∀ i ∈ (univ : Finset (Fin 2)), ∀ M ∈ testSys i, ∀ v ∈ M, (q i v).totalDegree ≤ 3) : + (Polynomial.sumCoeffsBelow 2 + (∏ i ∈ (univ : Finset (Fin 2)), + Polynomial.parityFactor 2 + ((monomialSumPoly ℤ (testSys i)).eval₂ MvPolynomial.C (q i)))).totalDegree ≤ 24 := by + have hk : ∀ i ∈ (univ : Finset (Fin 2)), ∀ M ∈ testSys i, #M ≤ 2 := by + intro i _ M _ + exact (card_le_univ M).trans (by decide) + have h := totalDegree_sumCoeffsBelow_prod_parityFactor_eval₂_le + (I := (univ : Finset (Fin 2))) (P := testSys) 2 (k := 2) (d₀ := 3) + MvPolynomial.C q hk hq + exact h.trans (by decide) + +/-- Modulo-`2` cancellation under `restrictMonomials`: specializing `S = {0}` to `b 0 = true` in +`{{0, 1}, {1}}` (`x₀ x₁ + x₁`) maps both monomials to `{1}`, so their coefficients cancel modulo +`2` and `restrictMonomials {0} (fun _ => true) {{0, 1}, {1}} = ∅`. -/ +example : + restrictMonomials ({0} : Finset (Fin 2)) (fun _ => true) + ({{0, 1}, {1}} : Finset (Finset (Fin 2))) = ∅ := by + decide + +/-- Under `b 0 = false`, only `{1}` survives, so `restrictMonomials` retains `{{1}}`. -/ +example : + restrictMonomials ({0} : Finset (Fin 2)) (fun _ => false) + ({{0, 1}, {1}} : Finset (Finset (Fin 2))) = {{1}} := by + decide + +/-- Heavy-variable bound and post-branching incidence bound for `testSys` with threshold `b₀ = 1`: +both variables have incidence `2 > 1`, and after branching on `heavyVars`, every variable has +incidence `0 ≤ 1` in the reduced scopes. -/ +example (b : Fin 2 → Bool) (v : Fin 2) : + varIncidence (univ : Finset (Fin 2)) + (fun i => equationScope + (restrictMonomials + (heavyVars univ univ (fun i => equationScope (testSys i)) 1) b (testSys i))) v ≤ 1 := + varIncidence_equationScope_restrictMonomials_heavyVars_le univ univ testSys 1 + (fun _ _ => subset_univ _) b v + +/-- Additive branch decomposition of `commonZeroCount` when branching on `S = {0}`. -/ +example : + commonZeroCount (univ : Finset (Fin 2)) testSys = + ∑ b ∈ branchAssignments ({0} : Finset (Fin 2)), + #{y ∈ subproblemAssignments ({0} : Finset (Fin 2)) | + IsCommonZero univ (fun i => restrictMonomials ({0} : Finset (Fin 2)) b (testSys i)) y} := + commonZeroCount_eq_sum_branches {0} univ testSys + +/-- Section 5.4 & Appendix B.2: cleared-denominator homogenization of the truncated parity-factor +product (`ℓ = 3`, `2 * ℓ - 1 = 5`, `#I = 2`, so `Ω = (Δ ^ 5) ^ 2`). -/ +example (Δ : ℤ) (x : Fin 2 → Bool) : + (∏ i ∈ (univ : Finset (Fin 2)), + parityFactorCleared 3 Δ (Δ * monomialSum ℤ (testSys i) x)).sumCoeffsBelow 3 = + (Δ ^ (2 * 3 - 1)) ^ #(univ : Finset (Fin 2)) * + (∏ i ∈ (univ : Finset (Fin 2)), + Polynomial.parityFactor 3 (monomialSum ℤ (testSys i) x)).sumCoeffsBelow 3 := + sumCoeffsBelow_prod_parityFactorCleared_mul univ (by decide) Δ + (fun i => monomialSum ℤ (testSys i) x) 3 + +/-- Appendix B.2 `ℓ₁`-norm bound for a cleared degree-`2` monomial sum `testEq0` (`#testEq0 = 2`) +when `d_den` and every replacement numerator `θ v` have `coeffNorm1 ≤ 4`: +`coeffNorm1 ≤ 2 * 4 ^ 2 = 32`. -/ +example (d_den : ℤ) (θ : Fin 2 → Polynomial ℤ) + (hd : d_den.natAbs ≤ 4) + (hθ : ∀ M ∈ testEq0, ∀ v ∈ M, Polynomial.coeffNorm1 (θ v) ≤ 4) : + Polynomial.coeffNorm1 (clearedMonomialSumPoly d_den 2 θ testEq0) ≤ 32 := by + have hk : ∀ M ∈ testEq0, #M ≤ 2 := fun M _ => (card_le_univ M).trans (by decide) + exact (coeffNorm1_clearedMonomialSumPoly_le hd hk hθ).trans (by decide) + +/-- Appendix B.2 `ℓ₁`-norm bound for the `V ^ 1`-coefficient of `parityFactorCleared` (`ℓ = 2`, +`B = 10`, `Δ = 3`): `coeffNorm1 ≤ 2 * (4 ^ 1 * 2 ^ 6) * (10 + 3) ^ 3 = 1124864`. -/ +example (A_i : Polynomial ℤ) (hA : Polynomial.coeffNorm1 A_i ≤ 10) : + Polynomial.coeffNorm1 ((parityFactorCleared 2 (Polynomial.C (3 : ℤ)) A_i).coeff 1) ≤ + 1124864 := + (coeffNorm1_coeff_parityFactorCleared_le_explicit 2 3 hA 1).trans (by decide) + +end Cslib.BitString From 14ea8f83a376ca41e6e73239a8d1b90baea6439f Mon Sep 17 00:00:00 2001 From: Samuel Schlesinger Date: Tue, 27 Oct 2026 01:05:39 +0000 Subject: [PATCH 05/20] feat(BooleanAnalysis): univariate parity-product specialization and heavy-variable branch reduction (#1226) --- Complexity.lean | 1 + .../BooleanAnalysis/SparseBranching.lean | 865 ++++++++++++++++++ ComplexityTests/SparseBranching.lean | 103 +++ 3 files changed, 969 insertions(+) create mode 100644 Complexity/Foundations/BooleanAnalysis/SparseBranching.lean create mode 100644 ComplexityTests/SparseBranching.lean diff --git a/Complexity.lean b/Complexity.lean index 9de53176aa..7e2ce8ed8f 100644 --- a/Complexity.lean +++ b/Complexity.lean @@ -1772,6 +1772,7 @@ public import Complexity.Foundations.BooleanAnalysis.PolynomialCorrelation public import Complexity.Foundations.BooleanAnalysis.QuadraticForm public import Complexity.Foundations.BooleanAnalysis.RelevantCoordinates public import Complexity.Foundations.BooleanAnalysis.SignApproximation +public import Complexity.Foundations.BooleanAnalysis.SparseBranching public import Complexity.Foundations.BooleanAnalysis.SparseEquations public import Complexity.Foundations.BooleanAnalysis.Symmetrization public import Complexity.Foundations.Combinatorics.AffineDisperser diff --git a/Complexity/Foundations/BooleanAnalysis/SparseBranching.lean b/Complexity/Foundations/BooleanAnalysis/SparseBranching.lean new file mode 100644 index 0000000000..843598f194 --- /dev/null +++ b/Complexity/Foundations/BooleanAnalysis/SparseBranching.lean @@ -0,0 +1,865 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Foundations.BooleanAnalysis.SparseEquations +import Mathlib.Data.Finset.Sum +import Mathlib.Data.Fintype.Pi + +/-! +# Univariate parity-product specialization and heavy-variable branch reduction + +This module completes the algebraic and combinatorial infrastructure of Sections 5.3, 5.5, and 5.6 +of [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (pp. 37–39), building on +`Complexity.Foundations.BooleanAnalysis.SparseEquations`: + +1. **Univariate $H(T)$ and coordinatewise $H_s(T) = [V^s] H(T)$ specialization (§5.3, eq. 5.5)**: + When each variable $v \in \iota$ in equation $i \in I$ is replaced by a univariate polynomial + $q_{x, i, v}(T) \in R[T]$ of degree at most $R_{\mathrm{deg}}$ that restores the Boolean input + $\mathrm{bitVal}(x_v)$ at $T = 0$, the substituted equation polynomial + `Cslib.BitString.univariateMonomialSumPoly` has `natDegree ≤ k * R_deg` and evaluates to + `monomialSum R (P i) x` at $T = 0$. Summing the parity-factor product over $x \in \{0, 1\}^\iota$ + yields `Cslib.BitString.univariateParityProduct`, whose $V^s$-coordinate polynomials + `Cslib.BitString.univariateParityCoord` ($s < \ell$) and truncated sum + `Cslib.BitString.univariateParityTruncatedSum` have `natDegree` at most + `(k * R_deg) * (#I + 2 * (ℓ - 1))` (`Cslib.BitString.natDegree_univariateParityCoord_le`, + `Cslib.BitString.natDegree_univariateParityTruncatedSum_le`) and recover `commonZeroCount I P` + modulo $2^\ell$ at $T = 0$ + (`Cslib.BitString.eval_zero_univariateParityTruncatedSum_modEq_commonZeroCount`, + `Cslib.BitString.emod_eval_zero_univariateParityTruncatedSum_eq_commonZeroCount`). +2. **Free-variable branch relabeling (§5.5–5.6, Proof of Theorem 2.2)**: + After branching on a subset $S \subseteq \iota$ of heavy variables, every restricted equation + `restrictMonomials S b (P i)` is supported on `univ \ S`. Transporting along an equivalence + `e : ↥(univ \ S) ≃ ι'` (such as `Fin n'` with $n' = n - |S|$) via + `Cslib.BitString.relabelRestrictedMonomials` preserves degree bounds `#M ≤ k`, never increases + monomial counts, bounds every free variable's equation incidence by `b₀` when $S$ is the + heavy-variable set (`Cslib.BitString.varIncidence_relabelRestrictedMonomials_heavyVars_le`), and + decomposes `commonZeroCount I P` additively as the sum of `commonZeroCount` on the relabeled + free-variable cube `ι' → Bool` + (`Cslib.BitString.commonZeroCount_eq_sum_relabelRestrictedMonomials`). +3. **Neutral variable-coverage scopes and Theorem 2.2 threshold bounds (§5.5–5.6)**: + Adjoining a singleton neutral scope `{v}` for each declared variable $v \in \iota'$ via + `Cslib.BitString.withNeutralFactors` and `Cslib.BitString.withNeutralScope` increments each + variable's incidence by `1`, ensuring positive variable incidence (`1 ≤ varIncidence`), + total incidence $M' \ge n'$ (`Cslib.BitString.card_le_totalIncidence_withNeutralFactors`), and + light-variable incidence at most $b_0 + 1$. Finally, when $M \cdot s \le b_0 \cdot n$ (as for + $b_0 = \lceil M s / n \rceil$ with $s = \lceil \sqrt{\lambda} \rceil$), the heavy-variable set + has size at most $n / s$, at most $2^{n / s}$ branches, and leaves $n' \ge n - n / s \ge n / 2$ + free variables when $s \ge 2$. + +## Main definitions + +* `Cslib.BitString.univariateMonomialPoly`, `Cslib.BitString.univariateMonomialSumPoly`: univariate + polynomial replacement in a monomial and a sparse polynomial equation. +* `Cslib.BitString.univariateParityProduct`, `Cslib.BitString.univariateParityCoord`, + `Cslib.BitString.univariateParityTruncatedSum`: the cube-summed bivariate polynomial $H(T, V)$, + its $V^s$-coordinate polynomials $[V^s] H(T)$, and its truncated sum $S_\ell(H(T))$. +* `Cslib.BitString.relabelMonomials`, `Cslib.BitString.relabelRestrictedMonomials`: relabeling + monomial families and restricted branch equations onto a free-variable index type `ι'`. +* `Cslib.BitString.withNeutralFactors`, `Cslib.BitString.withNeutralScope`: adjoining neutral + singleton scopes `{v}` for every variable $v \in \iota'$. +* `Cslib.BitString.heavyThreshold`: integer ceiling $\lceil M s / n \rceil$ for the heavy-variable + incidence threshold $b_0$. + +## Main results + +* `Cslib.BitString.natDegree_univariateParityCoord_le` and + `Cslib.BitString.natDegree_univariateParityTruncatedSum_le`: equation (5.5) degree bound + $\deg_T \le (k R_{\mathrm{deg}})(m_{\mathrm{test}} + 2(\ell - 1))$. +* `Cslib.BitString.eval_zero_univariateParityTruncatedSum_modEq_commonZeroCount` and + `Cslib.BitString.emod_eval_zero_univariateParityTruncatedSum_eq_commonZeroCount`: equation (5.5) + congruence and exact recovery of `commonZeroCount` at $T = 0$. +* `Cslib.BitString.commonZeroCount_eq_sum_relabelRestrictedMonomials`: additive branch decomposition + of `commonZeroCount` into `commonZeroCount` over the relabeled free-variable cube `ι' → Bool`. +* `Cslib.BitString.varIncidence_relabelRestrictedMonomials_heavyVars_le`: post-branching + free-variable incidence bound $\le b_0$ on `ι'`. +* `Cslib.BitString.card_le_totalIncidence_withNeutralFactors`: neutral scopes guarantee $M' \ge n'$. +* `Cslib.BitString.card_heavyVars_le_card_div` and + `Cslib.BitString.card_sdiff_heavyVars_ge_half`: $|S| \le n / s$ and $n' \ge n / 2$ for $s \ge 2$. + +## References + +* [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] + (Sections 5.3, 5.5, and 5.6) +-/ + +@[expose] public noncomputable section + +namespace Cslib.BitString + +open Finset + +variable {ι ι' κ R : Type*} + +/-! ### Section 1: Univariate replacement forms and degree / restoration lemmas (§5.3) -/ + +section UnivariateReplacement + +/-- Replacing each variable `v ∈ M` by a univariate polynomial `q v : Polynomial R` in a monomial +`M`. -/ +def univariateMonomialPoly (R : Type*) [CommSemiring R] (q : ι → Polynomial R) + (M : Finset ι) : Polynomial R := + ∏ v ∈ M, q v + +/-- Replacing each variable `v` by `q v : Polynomial R` in a sparse polynomial `𝓜`. -/ +def univariateMonomialSumPoly (R : Type*) [CommSemiring R] (q : ι → Polynomial R) + (𝓜 : Finset (Finset ι)) : Polynomial R := + ∑ M ∈ 𝓜, univariateMonomialPoly R q M + +/-- `univariateMonomialPoly R q M` agrees with evaluating `monomialPoly R M` at `q`. -/ +theorem univariateMonomialPoly_eq_eval₂ [CommSemiring R] (q : ι → Polynomial R) (M : Finset ι) : + univariateMonomialPoly R q M = (monomialPoly R M).eval₂ Polynomial.C q := by + rw [univariateMonomialPoly, monomialPoly, MvPolynomial.eval₂_prod] + refine prod_congr rfl fun v _ => ?_ + rw [MvPolynomial.eval₂_X] + +/-- `univariateMonomialSumPoly R q 𝓜` agrees with evaluating `monomialSumPoly R 𝓜` at `q`. -/ +theorem univariateMonomialSumPoly_eq_eval₂ [CommSemiring R] (q : ι → Polynomial R) + (𝓜 : Finset (Finset ι)) : + univariateMonomialSumPoly R q 𝓜 = (monomialSumPoly R 𝓜).eval₂ Polynomial.C q := by + rw [univariateMonomialSumPoly, monomialSumPoly, MvPolynomial.eval₂_sum] + exact sum_congr rfl fun M _ => univariateMonomialPoly_eq_eval₂ q M + +/-- Pointwise evaluation of `univariateMonomialPoly R q M` at `t : R`. -/ +theorem eval_univariateMonomialPoly [CommSemiring R] (q : ι → Polynomial R) (M : Finset ι) + (t : R) : + (univariateMonomialPoly R q M).eval t = ∏ v ∈ M, (q v).eval t := by + rw [univariateMonomialPoly, Polynomial.eval_prod] + +private theorem eval_sum {α : Type*} [CommSemiring R] (S : Finset α) (f : α → Polynomial R) + (t : R) : + (∑ x ∈ S, f x).eval t = ∑ x ∈ S, (f x).eval t := by + change Polynomial.evalRingHom t (∑ x ∈ S, f x) = _ + rw [map_sum] + rfl + +/-- Pointwise evaluation of `univariateMonomialSumPoly R q 𝓜` at `t : R`. -/ +theorem eval_univariateMonomialSumPoly [CommSemiring R] (q : ι → Polynomial R) + (𝓜 : Finset (Finset ι)) (t : R) : + (univariateMonomialSumPoly R q 𝓜).eval t = ∑ M ∈ 𝓜, ∏ v ∈ M, (q v).eval t := by + rw [univariateMonomialSumPoly, eval_sum] + exact sum_congr rfl fun M _ => eval_univariateMonomialPoly q M t + +/-- **Restoration at `T = 0`**: if every `q v` (`v ∈ M`) evaluates at `0` to `bitVal R (x v)`, then +`univariateMonomialSumPoly R q 𝓜` evaluates at `0` to `monomialSum R 𝓜 x`. -/ +theorem eval_zero_univariateMonomialSumPoly [CommRing R] {q : ι → Polynomial R} + {𝓜 : Finset (Finset ι)} {x : ι → Bool} + (hq0 : ∀ M ∈ 𝓜, ∀ v ∈ M, (q v).eval 0 = bitVal R (x v)) : + (univariateMonomialSumPoly R q 𝓜).eval 0 = monomialSum R 𝓜 x := by + rw [eval_univariateMonomialSumPoly, monomialSum] + refine sum_congr rfl fun M hM => ?_ + rw [monomial] + exact prod_congr rfl fun v hv => hq0 M hM v hv + +/-- If `#M ≤ k` and every `q v` (`v ∈ M`) has `natDegree ≤ d₀`, then +`univariateMonomialPoly R q M` has `natDegree ≤ k * d₀`. -/ +theorem natDegree_univariateMonomialPoly_le [CommSemiring R] {q : ι → Polynomial R} + {M : Finset ι} {k d₀ : ℕ} (hk : #M ≤ k) (hd : ∀ v ∈ M, (q v).natDegree ≤ d₀) : + (univariateMonomialPoly R q M).natDegree ≤ k * d₀ := by + calc + (∏ v ∈ M, q v).natDegree + ≤ ∑ v ∈ M, (q v).natDegree := Polynomial.natDegree_prod_le M q + _ ≤ ∑ _v ∈ M, d₀ := sum_le_sum hd + _ = #M * d₀ := by rw [sum_const, smul_eq_mul] + _ ≤ k * d₀ := Nat.mul_le_mul_right d₀ hk + +/-- If every monomial `M ∈ 𝓜` has `#M ≤ k` and every `q v` has `natDegree ≤ d₀`, then +`univariateMonomialSumPoly R q 𝓜` has `natDegree ≤ k * d₀`. -/ +theorem natDegree_univariateMonomialSumPoly_le [CommSemiring R] {q : ι → Polynomial R} + {𝓜 : Finset (Finset ι)} {k d₀ : ℕ} (hk : ∀ M ∈ 𝓜, #M ≤ k) + (hd : ∀ M ∈ 𝓜, ∀ v ∈ M, (q v).natDegree ≤ d₀) : + (univariateMonomialSumPoly R q 𝓜).natDegree ≤ k * d₀ := by + refine (Polynomial.natDegree_sum_le 𝓜 (univariateMonomialPoly R q)).trans ?_ + rw [Finset.fold_max_le] + exact ⟨Nat.zero_le _, fun M hM => natDegree_univariateMonomialPoly_le (hk M hM) (hd M hM)⟩ + +end UnivariateReplacement + +/-! ### Section 2: Ring-homomorphism transport and `natDegree` bounds for `parityFactor` -/ + +section UnivariateParityFactor + +/-- Any ring homomorphism `φ : A →+* B` commutes with `Polynomial.evalInt`. -/ +theorem map_evalInt {A B : Type*} [CommRing A] [CommRing B] (φ : A →+* B) (y : A) + (p : Polynomial ℤ) : + φ (Polynomial.evalInt y p) = Polynomial.evalInt (φ y) p := by + induction p using Polynomial.induction_on' with + | add p q ihp ihq => + rw [Polynomial.evalInt, Polynomial.eval₂_add, map_add, ← Polynomial.evalInt, + ← Polynomial.evalInt, ihp, ihq, Polynomial.evalInt, Polynomial.evalInt, + ← Polynomial.eval₂_add] + rfl + | monomial n a => + rw [Polynomial.evalInt, Polynomial.evalInt, Polynomial.eval₂_monomial, + Polynomial.eval₂_monomial, map_mul, map_pow] + congr 1 + rw [eq_intCast, eq_intCast, map_intCast] + +/-- Mapping `parityFactor ℓ y` coefficientwise by `φ : A →+* B` yields `parityFactor ℓ (φ y)`. -/ +theorem map_parityFactor {A B : Type*} [CommRing A] [CommRing B] (φ : A →+* B) (ℓ : ℕ) (y : A) : + (Polynomial.parityFactor ℓ y).map φ = Polynomial.parityFactor ℓ (φ y) := by + ext s + rw [Polynomial.coeff_map, Polynomial.coeff_parityFactor, Polynomial.coeff_parityFactor] + split_ifs with hs + · rw [map_mul, map_pow, map_evalInt, map_evalInt] + · exact map_zero φ + +/-- Any ring homomorphism `φ : A →+* B` commutes with `sumCoeffsBelow`. -/ +theorem map_sumCoeffsBelow {A B : Type*} [Semiring A] [Semiring B] (φ : A →+* B) + (P : Polynomial A) (m : ℕ) : + φ (P.sumCoeffsBelow m) = (P.map φ).sumCoeffsBelow m := by + rw [Polynomial.sumCoeffsBelow, Polynomial.sumCoeffsBelow, map_sum] + refine sum_congr rfl fun j _ => ?_ + rw [Polynomial.coeff_map] + +/-- Evaluating the `s`-th coefficient of `∏ i ∈ I, parityFactor ℓ (L i)` at `t : R` agrees with +the `s`-th coefficient of `∏ i ∈ I, parityFactor ℓ ((L i).eval t)`. -/ +theorem eval_coeff_prod_parityFactor [CommRing R] (I : Finset κ) (ℓ : ℕ) + (L : κ → Polynomial R) (s : ℕ) (t : R) : + ((∏ i ∈ I, Polynomial.parityFactor ℓ (L i)).coeff s).eval t = + (∏ i ∈ I, Polynomial.parityFactor ℓ ((L i).eval t)).coeff s := by + let φ : Polynomial R →+* R := Polynomial.evalRingHom t + change φ ((∏ i ∈ I, Polynomial.parityFactor ℓ (L i)).coeff s) = _ + rw [← Polynomial.coeff_map, Polynomial.map_prod] + refine congrArg (fun Q : Polynomial R => Q.coeff s) (prod_congr rfl fun i _ => ?_) + exact map_parityFactor φ ℓ (L i) + +/-- Evaluating `sumCoeffsBelow m` of `∏ i ∈ I, parityFactor ℓ (L i)` at `t : R` agrees with +`sumCoeffsBelow m` of `∏ i ∈ I, parityFactor ℓ ((L i).eval t)`. -/ +theorem eval_sumCoeffsBelow_prod_parityFactor [CommRing R] (I : Finset κ) (ℓ : ℕ) + (L : κ → Polynomial R) (m : ℕ) (t : R) : + ((∏ i ∈ I, Polynomial.parityFactor ℓ (L i)).sumCoeffsBelow m).eval t = + (∏ i ∈ I, Polynomial.parityFactor ℓ ((L i).eval t)).sumCoeffsBelow m := by + rw [Polynomial.sumCoeffsBelow, eval_sum, Polynomial.sumCoeffsBelow] + exact sum_congr rfl fun s _ => eval_coeff_prod_parityFactor I ℓ L s t + +/-- For `y : Polynomial R` and `p : Polynomial ℤ`, +`(evalInt y p).natDegree ≤ p.natDegree * y.natDegree`. -/ +theorem natDegree_evalInt_le [CommRing R] (y : Polynomial R) (p : Polynomial ℤ) : + (Polynomial.evalInt y p).natDegree ≤ p.natDegree * y.natDegree := by + rw [Polynomial.evalInt, Polynomial.eval₂_eq_sum_range] + refine (Polynomial.natDegree_sum_le _ _).trans ?_ + rw [Finset.fold_max_le] + refine ⟨Nat.zero_le _, fun i hi => ?_⟩ + rw [mem_range, Nat.lt_succ_iff] at hi + dsimp only [Function.comp_apply] + have hcast : (Int.castRingHom (Polynomial R) (p.coeff i)) = Polynomial.C (p.coeff i : R) := by + rw [eq_intCast, ← Polynomial.C_eq_intCast] + rw [hcast] + calc + (Polynomial.C (p.coeff i : R) * y ^ i).natDegree + ≤ (Polynomial.C (p.coeff i : R)).natDegree + (y ^ i).natDegree := + Polynomial.natDegree_mul_le + _ ≤ 0 + i * y.natDegree := by + rw [Polynomial.natDegree_C] + exact add_le_add le_rfl Polynomial.natDegree_pow_le + _ ≤ p.natDegree * y.natDegree := by + rw [zero_add] + exact Nat.mul_le_mul_right _ hi + +/-- `evalInt y (parityBaseDigit ℓ j)` has `natDegree ≤ y.natDegree`. -/ +theorem natDegree_evalInt_parityBaseDigit_le [CommRing R] (ℓ j : ℕ) (y : Polynomial R) : + (Polynomial.evalInt y (Polynomial.parityBaseDigit ℓ j)).natDegree ≤ y.natDegree := by + calc + (Polynomial.evalInt y (Polynomial.parityBaseDigit ℓ j)).natDegree + ≤ (Polynomial.parityBaseDigit ℓ j).natDegree * y.natDegree := + natDegree_evalInt_le y _ + _ ≤ 1 * y.natDegree := + Nat.mul_le_mul_right _ (Polynomial.natDegree_parityBaseDigit_le ℓ j) + _ = y.natDegree := one_mul _ + +/-- `evalInt y hPoly` has `natDegree ≤ 2 * y.natDegree`. -/ +theorem natDegree_evalInt_hPoly_le [CommRing R] (y : Polynomial R) : + (Polynomial.evalInt y Polynomial.hPoly).natDegree ≤ 2 * y.natDegree := by + rw [Polynomial.evalInt_hPoly] + calc + (y ^ 2 - y).natDegree + ≤ max (y ^ 2).natDegree y.natDegree := Polynomial.natDegree_sub_le _ _ + _ ≤ max (2 * y.natDegree) y.natDegree := + max_le_max Polynomial.natDegree_pow_le le_rfl + _ = 2 * y.natDegree := max_eq_left (by omega) + +/-- The `j`-th coefficient of `parityFactor ℓ y` has `natDegree ≤ (1 + 2 * j) * y.natDegree`. -/ +theorem natDegree_coeff_parityFactor_le [CommRing R] (ℓ : ℕ) (y : Polynomial R) (j : ℕ) : + ((Polynomial.parityFactor ℓ y).coeff j).natDegree ≤ (1 + 2 * j) * y.natDegree := by + rw [Polynomial.coeff_parityFactor] + split_ifs with hj + · calc + (Polynomial.evalInt y (Polynomial.parityBaseDigit ℓ j) * + Polynomial.evalInt y Polynomial.hPoly ^ j).natDegree + ≤ (Polynomial.evalInt y (Polynomial.parityBaseDigit ℓ j)).natDegree + + (Polynomial.evalInt y Polynomial.hPoly ^ j).natDegree := + Polynomial.natDegree_mul_le + _ ≤ y.natDegree + j * (Polynomial.evalInt y Polynomial.hPoly).natDegree := + add_le_add (natDegree_evalInt_parityBaseDigit_le ℓ j y) Polynomial.natDegree_pow_le + _ ≤ y.natDegree + j * (2 * y.natDegree) := + add_le_add le_rfl (Nat.mul_le_mul_left j (natDegree_evalInt_hPoly_le y)) + _ = (1 + 2 * j) * y.natDegree := by ring + · simp only [Polynomial.natDegree_zero, zero_le] + +/-- If every `L i` (`i ∈ I`) has `natDegree ≤ d`, then the `V ^ s`-coefficient of +`∏ i ∈ I, parityFactor ℓ (L i)` has `natDegree ≤ d * (#I + 2 * s)`. -/ +theorem natDegree_coeff_prod_parityFactor_le [CommRing R] (I : Finset κ) (ℓ : ℕ) + (L : κ → Polynomial R) {d : ℕ} (hL : ∀ i ∈ I, (L i).natDegree ≤ d) : + ∀ s : ℕ, ((∏ i ∈ I, Polynomial.parityFactor ℓ (L i)).coeff s).natDegree ≤ d * (#I + 2 * s) := by + classical + induction I using Finset.induction_on with + | empty => + intro s + simp only [prod_empty, card_empty, zero_add] + rcases eq_or_ne s 0 with rfl | hs + · simp only [Polynomial.coeff_one_zero, Polynomial.natDegree_one, zero_le] + · rw [Polynomial.coeff_one, ite_eq_right hs, Polynomial.natDegree_zero] + exact Nat.zero_le _ + | insert a I ha ih => + intro s + rw [prod_insert ha, card_insert_of_notMem ha, Polynomial.coeff_mul] + have haL : (L a).natDegree ≤ d := hL a (mem_insert_self a I) + have hIL : ∀ i ∈ I, (L i).natDegree ≤ d := fun i hi => hL i (mem_insert_of_mem hi) + refine (Polynomial.natDegree_sum_le _ _).trans ?_ + rw [Finset.fold_max_le] + refine ⟨Nat.zero_le _, fun p hp => ?_⟩ + rw [mem_antidiagonal] at hp + calc + (((Polynomial.parityFactor ℓ (L a)).coeff p.1) * + ((∏ i ∈ I, Polynomial.parityFactor ℓ (L i)).coeff p.2)).natDegree + ≤ ((Polynomial.parityFactor ℓ (L a)).coeff p.1).natDegree + + ((∏ i ∈ I, Polynomial.parityFactor ℓ (L i)).coeff p.2).natDegree := + Polynomial.natDegree_mul_le + _ ≤ (1 + 2 * p.1) * (L a).natDegree + d * (#I + 2 * p.2) := + add_le_add (natDegree_coeff_parityFactor_le ℓ (L a) p.1) (ih hIL p.2) + _ ≤ (1 + 2 * p.1) * d + d * (#I + 2 * p.2) := + add_le_add (Nat.mul_le_mul_left _ haL) le_rfl + _ = d * (#I + 1 + 2 * (p.1 + p.2)) := by ring + _ = d * (#I + 1 + 2 * s) := by rw [hp] + +/-- For `s < ℓ`, the `V ^ s`-coefficient of `∏ i ∈ I, parityFactor ℓ (L i)` has +`natDegree ≤ d * (#I + 2 * (ℓ - 1))`. -/ +theorem natDegree_coeff_prod_parityFactor_le_of_lt [CommRing R] (I : Finset κ) (ℓ : ℕ) + (L : κ → Polynomial R) {d : ℕ} (hL : ∀ i ∈ I, (L i).natDegree ≤ d) {s : ℕ} (hs : s < ℓ) : + ((∏ i ∈ I, Polynomial.parityFactor ℓ (L i)).coeff s).natDegree ≤ + d * (#I + 2 * (ℓ - 1)) := by + refine (natDegree_coeff_prod_parityFactor_le I ℓ L hL s).trans ?_ + exact Nat.mul_le_mul_left d (by omega) + +/-- The truncated sum `sumCoeffsBelow ℓ (∏ i ∈ I, parityFactor ℓ (L i))` has +`natDegree ≤ d * (#I + 2 * (ℓ - 1))`. -/ +theorem natDegree_sumCoeffsBelow_prod_parityFactor_le [CommRing R] (I : Finset κ) (ℓ : ℕ) + (L : κ → Polynomial R) {d : ℕ} (hL : ∀ i ∈ I, (L i).natDegree ≤ d) : + ((∏ i ∈ I, Polynomial.parityFactor ℓ (L i)).sumCoeffsBelow ℓ).natDegree ≤ + d * (#I + 2 * (ℓ - 1)) := by + rw [Polynomial.sumCoeffsBelow] + refine (Polynomial.natDegree_sum_le _ _).trans ?_ + rw [Finset.fold_max_le] + refine ⟨Nat.zero_le _, fun s hs => ?_⟩ + exact natDegree_coeff_prod_parityFactor_le_of_lt I ℓ L hL (mem_range.mp hs) + +end UnivariateParityFactor + +/-! ### Section 3: Cube-summed univariate polynomial $H(T)$ and equation (5.5) -/ + +section CubeSummedUnivariate + +/-- **§5.3 (`H(T)` in `R[T][V]`)**: the cube sum over `x : ι → Bool` of the product of parity +factors evaluated at the univariate replacement forms `q x i : ι → Polynomial R`. -/ +def univariateParityProduct [Fintype ι] [DecidableEq ι] [CommRing R] (I : Finset κ) + (P : κ → Finset (Finset ι)) (ℓ : ℕ) + (q : (ι → Bool) → κ → ι → Polynomial R) : Polynomial (Polynomial R) := + ∑ x : ι → Bool, + ∏ i ∈ I, Polynomial.parityFactor ℓ (univariateMonomialSumPoly R (q x i) (P i)) + +/-- **§5.3 (`[V ^ s] H(T)`)**: the `s`-th `V`-coefficient polynomial of `univariateParityProduct` +in `R[T]`. -/ +def univariateParityCoord [Fintype ι] [DecidableEq ι] [CommRing R] (I : Finset κ) + (P : κ → Finset (Finset ι)) (ℓ : ℕ) + (q : (ι → Bool) → κ → ι → Polynomial R) (s : ℕ) : Polynomial R := + (univariateParityProduct I P ℓ q).coeff s + +/-- **§5.3 (`S_ℓ(H(T))`)**: the sum of the first `ℓ` `V`-coefficient polynomials of +`univariateParityProduct` in `R[T]`. -/ +def univariateParityTruncatedSum [Fintype ι] [DecidableEq ι] [CommRing R] (I : Finset κ) + (P : κ → Finset (Finset ι)) (ℓ : ℕ) + (q : (ι → Bool) → κ → ι → Polynomial R) : Polynomial R := + (univariateParityProduct I P ℓ q).sumCoeffsBelow ℓ + +/-- `univariateParityTruncatedSum` is the sum of `univariateParityCoord I P ℓ q s` for +`s ∈ range ℓ`. -/ +theorem univariateParityTruncatedSum_eq_sum_coord [Fintype ι] [DecidableEq ι] [CommRing R] + (I : Finset κ) (P : κ → Finset (Finset ι)) (ℓ : ℕ) + (q : (ι → Bool) → κ → ι → Polynomial R) : + univariateParityTruncatedSum I P ℓ q = + ∑ s ∈ range ℓ, univariateParityCoord I P ℓ q s := + rfl + +/-- `univariateParityCoord` expands as the cube sum of the `V ^ s`-coefficients of each `x`-term. -/ +theorem univariateParityCoord_eq_sum [Fintype ι] [DecidableEq ι] [CommRing R] (I : Finset κ) + (P : κ → Finset (Finset ι)) (ℓ : ℕ) (q : (ι → Bool) → κ → ι → Polynomial R) (s : ℕ) : + univariateParityCoord I P ℓ q s = + ∑ x : ι → Bool, + (∏ i ∈ I, + Polynomial.parityFactor ℓ (univariateMonomialSumPoly R (q x i) (P i))).coeff s := by + rw [univariateParityCoord, univariateParityProduct, Polynomial.finsetSum_coeff] + +/-- `univariateParityTruncatedSum` expands as the cube sum of `sumCoeffsBelow ℓ` of each +`x`-term. -/ +theorem univariateParityTruncatedSum_eq_sum [Fintype ι] [DecidableEq ι] [CommRing R] + (I : Finset κ) (P : κ → Finset (Finset ι)) (ℓ : ℕ) + (q : (ι → Bool) → κ → ι → Polynomial R) : + univariateParityTruncatedSum I P ℓ q = + ∑ x : ι → Bool, + (∏ i ∈ I, + Polynomial.parityFactor ℓ + (univariateMonomialSumPoly R (q x i) (P i))).sumCoeffsBelow ℓ := by + rw [univariateParityTruncatedSum, univariateParityProduct, Polynomial.sumCoeffsBelow] + simp only [Polynomial.finsetSum_coeff] + rw [sum_comm] + rfl + +/-- **§5.3, eq. (5.5a) (coordinatewise degree bound $\deg_T [V^s] H(T) \le k R_{\mathrm{deg}} +(\#I + 2(\ell - 1))$)**: if every equation has degree at most `k` and every replacement polynomial +`q x i v` has `natDegree ≤ R_deg`, then for `s < ℓ`, `univariateParityCoord I P ℓ q s` has +`natDegree ≤ (k * R_deg) * (#I + 2 * (ℓ - 1))`. -/ +theorem natDegree_univariateParityCoord_le [Fintype ι] [DecidableEq ι] [CommRing R] + (I : Finset κ) (P : κ → Finset (Finset ι)) (ℓ : ℕ) + (q : (ι → Bool) → κ → ι → Polynomial R) {k R_deg : ℕ} + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hq : ∀ x : ι → Bool, ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, (q x i v).natDegree ≤ R_deg) + {s : ℕ} (hs : s < ℓ) : + (univariateParityCoord I P ℓ q s).natDegree ≤ (k * R_deg) * (#I + 2 * (ℓ - 1)) := by + rw [univariateParityCoord_eq_sum] + refine (Polynomial.natDegree_sum_le _ _).trans ?_ + rw [Finset.fold_max_le] + refine ⟨Nat.zero_le _, fun x _ => ?_⟩ + refine natDegree_coeff_prod_parityFactor_le_of_lt I ℓ + (fun i => univariateMonomialSumPoly R (q x i) (P i)) (fun i hi => ?_) hs + exact natDegree_univariateMonomialSumPoly_le (hk i hi) (hq x i hi) + +/-- **§5.3, eq. (5.5a) ($\deg_T S_\ell(H(T)) \le k R_{\mathrm{deg}} (\#I + 2(\ell - 1))$)**: if +every equation has degree at most `k` and every replacement polynomial `q x i v` has +`natDegree ≤ R_deg`, then `univariateParityTruncatedSum I P ℓ q` has +`natDegree ≤ (k * R_deg) * (#I + 2 * (ℓ - 1))`. -/ +theorem natDegree_univariateParityTruncatedSum_le [Fintype ι] [DecidableEq ι] [CommRing R] + (I : Finset κ) (P : κ → Finset (Finset ι)) (ℓ : ℕ) + (q : (ι → Bool) → κ → ι → Polynomial R) {k R_deg : ℕ} + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hq : ∀ x : ι → Bool, ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, (q x i v).natDegree ≤ R_deg) : + (univariateParityTruncatedSum I P ℓ q).natDegree ≤ (k * R_deg) * (#I + 2 * (ℓ - 1)) := by + rw [univariateParityTruncatedSum_eq_sum_coord] + refine (Polynomial.natDegree_sum_le _ _).trans ?_ + rw [Finset.fold_max_le] + refine ⟨Nat.zero_le _, fun s hs => ?_⟩ + exact natDegree_univariateParityCoord_le I P ℓ q hk hq (mem_range.mp hs) + +/-- **§5.3, eq. (5.5b) (evaluation restoration at `T = 0`)**: when every replacement polynomial +`q x i v` restores `bitVal R (x v)` at `T = 0`, evaluating `univariateParityTruncatedSum` at `0` +yields the cube sum of truncated parity-factor products at `monomialSum R (P i) x`. -/ +theorem eval_zero_univariateParityTruncatedSum [Fintype ι] [DecidableEq ι] [CommRing R] + (I : Finset κ) (P : κ → Finset (Finset ι)) (ℓ : ℕ) + (q : (ι → Bool) → κ → ι → Polynomial R) + (hq0 : ∀ x : ι → Bool, ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, (q x i v).eval 0 = bitVal R (x v)) : + (univariateParityTruncatedSum I P ℓ q).eval 0 = + ∑ x : ι → Bool, + (∏ i ∈ I, Polynomial.parityFactor ℓ (monomialSum R (P i) x)).sumCoeffsBelow ℓ := by + rw [univariateParityTruncatedSum_eq_sum, eval_sum] + refine sum_congr rfl fun x _ => ?_ + rw [eval_sumCoeffsBelow_prod_parityFactor] + congr 1 + refine prod_congr rfl fun i hi => ?_ + rw [eval_zero_univariateMonomialSumPoly (hq0 x i hi)] + +/-- **§5.3, eq. (5.5b) ($S_\ell(H(0)) \equiv N(\mathcal{P}) \pmod{2^\ell}$)**: when every integer +replacement polynomial `q x i v` restores `bitVal ℤ (x v)` at `T = 0`, +`(univariateParityTruncatedSum I P ℓ q).eval 0 ≡ commonZeroCount I P [ZMOD 2 ^ ℓ]`. -/ +theorem eval_zero_univariateParityTruncatedSum_modEq_commonZeroCount [Fintype ι] [DecidableEq ι] + (I : Finset κ) (P : κ → Finset (Finset ι)) {ℓ : ℕ} (hℓ : 1 ≤ ℓ) + (q : (ι → Bool) → κ → ι → Polynomial ℤ) + (hq0 : ∀ x : ι → Bool, ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, (q x i v).eval 0 = bitVal ℤ (x v)) : + (univariateParityTruncatedSum I P ℓ q).eval 0 ≡ + (commonZeroCount I P : ℤ) [ZMOD (2 : ℤ) ^ ℓ] := by + rw [eval_zero_univariateParityTruncatedSum I P ℓ q hq0] + exact sum_sumCoeffsBelow_prod_parityFactor_modEq_commonZeroCount I P hℓ + +/-- **§5.3, eq. (5.5b) (exact recovery of $N(\mathcal{P})$ from $S_\ell(H(0)) \bmod 2^\ell$)**: +when `Fintype.card ι < ℓ` and every replacement polynomial `q x i v` restores `bitVal ℤ (x v)` at +`T = 0`, the least nonnegative residue of `(univariateParityTruncatedSum I P ℓ q).eval 0` modulo +`2 ^ ℓ` equals `commonZeroCount I P`. -/ +theorem emod_eval_zero_univariateParityTruncatedSum_eq_commonZeroCount [Fintype ι] [DecidableEq ι] + (I : Finset κ) (P : κ → Finset (Finset ι)) {ℓ : ℕ} (hℓ : Fintype.card ι < ℓ) + (q : (ι → Bool) → κ → ι → Polynomial ℤ) + (hq0 : ∀ x : ι → Bool, ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, (q x i v).eval 0 = bitVal ℤ (x v)) : + ((univariateParityTruncatedSum I P ℓ q).eval 0) % ((2 : ℤ) ^ ℓ) = + (commonZeroCount I P : ℤ) := by + rw [eval_zero_univariateParityTruncatedSum I P ℓ q hq0] + exact emod_sum_sumCoeffsBelow_prod_parityFactor_eq_commonZeroCount I P hℓ + +end CubeSummedUnivariate + +/-! ### Section 4: Free-variable branch relabeling (§5.5–5.6, Proof of Theorem 2.2) -/ + +section BranchRelabeling + +/-- Relabeling every monomial `M ∈ 𝓜` along a map `f : ι → ι'`. -/ +def relabelMonomials [DecidableEq ι'] (f : ι → ι') (𝓜 : Finset (Finset ι)) : + Finset (Finset ι') := + 𝓜.image fun M => M.image f + +/-- Relabeling a restricted branch equation `restrictMonomials S b 𝓜` (whose monomials are subsets +of `univ \ S`) across an equivalence `e : ↥(univ \ S) ≃ ι'` onto a free-variable index type `ι'`. -/ +def relabelRestrictedMonomials [Fintype ι] [DecidableEq ι] [DecidableEq ι'] + (S : Finset ι) (e : ↥(univ \ S) ≃ ι') (b : ι → Bool) (𝓜 : Finset (Finset ι)) : + Finset (Finset ι') := + (restrictMonomials S b 𝓜).image fun M => (M.subtype (· ∈ univ \ S)).image e + +/-- Extending a free-variable assignment `y : ι' → Bool` by `false` on `S` to obtain a canonical +representative in `subproblemAssignments S`. -/ +def extendFreeAssignment [Fintype ι] [DecidableEq ι] (S : Finset ι) (e : ↥(univ \ S) ≃ ι') + (y : ι' → Bool) (v : ι) : Bool := + if hv : v ∈ univ \ S then y (e ⟨v, hv⟩) else false + +/-- Restricting an assignment `z : ι → Bool` to `ι'` along `e : ↥(univ \ S) ≃ ι'`. -/ +def restrictToFreeVars [Fintype ι] [DecidableEq ι] (S : Finset ι) (e : ↥(univ \ S) ≃ ι') + (z : ι → Bool) (w : ι') : Bool := + z (e.symm w).1 + +@[simp] +theorem restrictToFreeVars_extendFreeAssignment [Fintype ι] [DecidableEq ι] (S : Finset ι) + (e : ↥(univ \ S) ≃ ι') (y : ι' → Bool) : + restrictToFreeVars S e (extendFreeAssignment S e y) = y := by + ext w + simp only [restrictToFreeVars, extendFreeAssignment, (e.symm w).2, ↓reduceDIte, Subtype.coe_eta, + Equiv.apply_symm_apply] + +theorem extendFreeAssignment_mem_subproblemAssignments [Fintype ι] [DecidableEq ι] + (S : Finset ι) (e : ↥(univ \ S) ≃ ι') (y : ι' → Bool) : + extendFreeAssignment S e y ∈ subproblemAssignments S := by + rw [subproblemAssignments, mem_filter] + refine ⟨mem_univ _, fun v hv => ?_⟩ + have hnot : v ∉ univ \ S := fun h => (mem_sdiff.mp h).2 hv + simp only [extendFreeAssignment, hnot, ↓reduceDIte] + +theorem extendFreeAssignment_restrictToFreeVars [Fintype ι] [DecidableEq ι] + (S : Finset ι) (e : ↥(univ \ S) ≃ ι') {z : ι → Bool} (hz : z ∈ subproblemAssignments S) : + extendFreeAssignment S e (restrictToFreeVars S e z) = z := by + rw [subproblemAssignments, mem_filter] at hz + ext v + by_cases hv : v ∈ univ \ S + · simp only [extendFreeAssignment, hv, ↓reduceDIte, restrictToFreeVars, + Equiv.symm_apply_apply] + · have hvS : v ∈ S := by + by_contra hnotS + exact hv (mem_sdiff.mpr ⟨mem_univ v, hnotS⟩) + simp only [extendFreeAssignment, hv, ↓reduceDIte, hz.2 v hvS] + +/-- Every monomial in `relabelRestrictedMonomials S e b 𝓜` has degree at most `k` when every +monomial in `𝓜` has degree at most `k`. -/ +theorem card_mem_relabelRestrictedMonomials_le [Fintype ι] [DecidableEq ι] [DecidableEq ι'] + {S : Finset ι} {e : ↥(univ \ S) ≃ ι'} {b : ι → Bool} {𝓜 : Finset (Finset ι)} {k : ℕ} + (hk : ∀ M ∈ 𝓜, #M ≤ k) : + ∀ M' ∈ relabelRestrictedMonomials S e b 𝓜, #M' ≤ k := by + intro M' hM' + rw [relabelRestrictedMonomials, mem_image] at hM' + rcases hM' with ⟨M, hM, rfl⟩ + calc + #((M.subtype (· ∈ univ \ S)).image e) + ≤ #(M.subtype (· ∈ univ \ S)) := card_image_le + _ = #(M.filter (· ∈ univ \ S)) := card_subtype _ _ + _ ≤ #M := card_filter_le _ _ + _ ≤ k := card_le_of_mem_restrictMonomials hk hM + +/-- `relabelRestrictedMonomials` never increases the number of monomials. -/ +theorem card_relabelRestrictedMonomials_le [Fintype ι] [DecidableEq ι] [DecidableEq ι'] + (S : Finset ι) (e : ↥(univ \ S) ≃ ι') (b : ι → Bool) (𝓜 : Finset (Finset ι)) : + #(relabelRestrictedMonomials S e b 𝓜) ≤ #𝓜 := + card_image_le.trans (card_restrictMonomials_le S b 𝓜) + +/-- On any monomial `M ⊆ univ \ S`, the subtype-image map `M ↦ (M.subtype (· ∈ univ \ S)).image e` +is injective. -/ +private theorem subtype_image_injOn_restrictMonomials [Fintype ι] [DecidableEq ι] [DecidableEq ι'] + (S : Finset ι) (e : ↥(univ \ S) ≃ ι') (b : ι → Bool) (𝓜 : Finset (Finset ι)) : + Set.InjOn (fun M : Finset ι => (M.subtype (· ∈ univ \ S)).image e) + (restrictMonomials S b 𝓜) := by + intro M₁ hM₁ M₂ hM₂ hEq + dsimp only at hEq + have hsub₁ : M₁ ⊆ univ \ S := fun v hv => + mem_sdiff.mpr ⟨mem_univ v, disjoint_left.mp (disjoint_of_mem_restrictMonomials hM₁) hv⟩ + have hsub₂ : M₂ ⊆ univ \ S := fun v hv => + mem_sdiff.mpr ⟨mem_univ v, disjoint_left.mp (disjoint_of_mem_restrictMonomials hM₂) hv⟩ + ext v + constructor + · intro hv₁ + have hvU : v ∈ univ \ S := hsub₁ hv₁ + have hin : e ⟨v, hvU⟩ ∈ (M₁.subtype (· ∈ univ \ S)).image e := + mem_image.mpr ⟨⟨v, hvU⟩, mem_subtype.mpr hv₁, rfl⟩ + rw [hEq, mem_image] at hin + rcases hin with ⟨u, hu, hue⟩ + have huv := e.injective hue + subst huv + exact mem_subtype.mp hu + · intro hv₂ + have hvU : v ∈ univ \ S := hsub₂ hv₂ + have hin : e ⟨v, hvU⟩ ∈ (M₂.subtype (· ∈ univ \ S)).image e := + mem_image.mpr ⟨⟨v, hvU⟩, mem_subtype.mpr hv₂, rfl⟩ + rw [← hEq, mem_image] at hin + rcases hin with ⟨u, hu, hue⟩ + have huv := e.injective hue + subst huv + exact mem_subtype.mp hu + +/-- Evaluating `relabelRestrictedMonomials S e b 𝓜` at `y : ι' → Bool` in any commutative ring `R` +agrees with evaluating `restrictMonomials S b 𝓜` at `extendFreeAssignment S e y`. -/ +theorem monomialSum_relabelRestrictedMonomials [Fintype ι] [DecidableEq ι] [DecidableEq ι'] + (R : Type*) [CommRing R] (S : Finset ι) (e : ↥(univ \ S) ≃ ι') (b : ι → Bool) + (𝓜 : Finset (Finset ι)) (y : ι' → Bool) : + monomialSum R (relabelRestrictedMonomials S e b 𝓜) y = + monomialSum R (restrictMonomials S b 𝓜) (extendFreeAssignment S e y) := by + rw [monomialSum, monomialSum, relabelRestrictedMonomials, + sum_image (subtype_image_injOn_restrictMonomials S e b 𝓜)] + refine sum_congr rfl fun M hM => ?_ + have hsub : M ⊆ univ \ S := fun v hv => + mem_sdiff.mpr ⟨mem_univ v, disjoint_left.mp (disjoint_of_mem_restrictMonomials hM) hv⟩ + rw [monomial, monomial, prod_image (fun u _ v _ huv => e.injective huv)] + refine prod_nbij Subtype.val (fun x hx => mem_coe.mpr (mem_subtype.mp hx)) + Subtype.val_injective.injOn + (fun v hv => ⟨⟨v, hsub hv⟩, mem_coe.mpr (mem_subtype.mpr hv), rfl⟩) + (fun x _ => ?_) + simp only [extendFreeAssignment, x.2, ↓reduceDIte] + +/-- Over `ZMod 2`, evaluating `relabelRestrictedMonomials S e b 𝓜` at `y : ι' → Bool` equals +evaluating the original equation `𝓜` at `patchAssignment S b (extendFreeAssignment S e y)`. -/ +theorem monomialSum_zmod_two_relabelRestrictedMonomials [Fintype ι] [DecidableEq ι] + [DecidableEq ι'] (S : Finset ι) (e : ↥(univ \ S) ≃ ι') (b : ι → Bool) + (𝓜 : Finset (Finset ι)) (y : ι' → Bool) : + monomialSum (ZMod 2) (relabelRestrictedMonomials S e b 𝓜) y = + monomialSum (ZMod 2) 𝓜 (patchAssignment S b (extendFreeAssignment S e y)) := by + rw [monomialSum_relabelRestrictedMonomials, monomialSum_zmod_two_restrictMonomials] + +/-- **§5.5–5.6 (Theorem 2.2 additive branch decomposition on the relabeled free-variable cube +`ι' → Bool`)**: for any branch variable set `S` and equivalence `e : ↥(univ \ S) ≃ ι'`, the +common-zero count `commonZeroCount I P` equals the sum over `b ∈ branchAssignments S` of +`commonZeroCount` of the relabeled restricted equations on `ι' → Bool`. -/ +theorem commonZeroCount_eq_sum_relabelRestrictedMonomials [Fintype ι] [DecidableEq ι] + [Fintype ι'] [DecidableEq ι'] (S : Finset ι) (e : ↥(univ \ S) ≃ ι') (I : Finset κ) + (P : κ → Finset (Finset ι)) : + commonZeroCount I P = + ∑ b ∈ branchAssignments S, + commonZeroCount I (fun i => relabelRestrictedMonomials S e b (P i)) := by + rw [commonZeroCount_eq_sum_branches S I P] + refine sum_congr rfl fun b _ => ?_ + rw [commonZeroCount] + refine card_bij (fun z _ => restrictToFreeVars S e z) + (fun z hz => ?_) (fun z₁ hz₁ z₂ hz₂ hEq => ?_) (fun y hy => ?_) + · rw [mem_filter] at hz ⊢ + refine ⟨mem_univ _, fun i hi => ?_⟩ + rw [monomialSum_relabelRestrictedMonomials, + extendFreeAssignment_restrictToFreeVars S e hz.1] + exact hz.2 i hi + · rw [mem_filter] at hz₁ hz₂ + rw [← extendFreeAssignment_restrictToFreeVars S e hz₁.1, + ← extendFreeAssignment_restrictToFreeVars S e hz₂.1, hEq] + · rw [mem_filter] at hy + refine ⟨extendFreeAssignment S e y, mem_filter.mpr + ⟨extendFreeAssignment_mem_subproblemAssignments S e y, fun i hi => ?_⟩, + restrictToFreeVars_extendFreeAssignment S e y⟩ + rw [← monomialSum_relabelRestrictedMonomials] + exact hy.2 i hi + +/-- The variable scope of `relabelRestrictedMonomials S e b 𝓜` is contained in the image under `e` +of `(equationScope 𝓜 \ S).subtype (· ∈ univ \ S)`. -/ +theorem equationScope_relabelRestrictedMonomials_subset [Fintype ι] [DecidableEq ι] + [DecidableEq ι'] (S : Finset ι) (e : ↥(univ \ S) ≃ ι') (b : ι → Bool) + (𝓜 : Finset (Finset ι)) : + equationScope (relabelRestrictedMonomials S e b 𝓜) ⊆ + ((equationScope 𝓜 \ S).subtype (· ∈ univ \ S)).image e := by + intro w hw + rw [equationScope, mem_biUnion] at hw + rcases hw with ⟨M', hM', hwM'⟩ + rw [relabelRestrictedMonomials, mem_image] at hM' + rcases hM' with ⟨M, hM, rfl⟩ + rw [id_eq, mem_image] at hwM' + rcases hwM' with ⟨v, hv, rfl⟩ + rw [mem_subtype] at hv + have hvScope : v.1 ∈ equationScope 𝓜 \ S := + equationScope_restrictMonomials_subset_sdiff S b 𝓜 + (mem_biUnion.mpr ⟨M, hM, hv⟩) + exact mem_image.mpr ⟨v, mem_subtype.mpr hvScope, rfl⟩ + +/-- **§5.5–5.6 (free-variable incidence bound on `ι'` after branching on `heavyVars`)**: for +`S = heavyVars univ F (fun i => equationScope (P i)) b₀` and `I ⊆ F`, every variable `w : ι'` has +incidence at most `b₀` in the relabeled restricted system. -/ +theorem varIncidence_relabelRestrictedMonomials_heavyVars_le [Fintype ι] [DecidableEq ι] + [DecidableEq ι'] (F I : Finset κ) (P : κ → Finset (Finset ι)) (b₀ : ℕ) + (hIF : I ⊆ F) (e : ↥(univ \ heavyVars univ F (fun i => equationScope (P i)) b₀) ≃ ι') + (b : ι → Bool) (w : ι') : + varIncidence I + (fun i => equationScope + (relabelRestrictedMonomials + (heavyVars univ F (fun i => equationScope (P i)) b₀) e b (P i))) w ≤ b₀ := by + let S := heavyVars univ F (fun i => equationScope (P i)) b₀ + have hsub : + {i ∈ I | w ∈ equationScope (relabelRestrictedMonomials S e b (P i))} ⊆ + {i ∈ F | (e.symm w).1 ∈ equationScope (restrictMonomials S b (P i))} := by + intro i hi + rw [mem_filter] at hi ⊢ + refine ⟨hIF hi.1, ?_⟩ + rcases hi with ⟨_, hw⟩ + rw [equationScope, mem_biUnion] at hw ⊢ + rcases hw with ⟨M', hM', hwM'⟩ + rw [relabelRestrictedMonomials, mem_image] at hM' + rcases hM' with ⟨M, hM, rfl⟩ + rw [id_eq, mem_image] at hwM' + rcases hwM' with ⟨v, hv, rfl⟩ + rw [Equiv.symm_apply_apply] + exact ⟨M, hM, mem_subtype.mp hv⟩ + calc + varIncidence I + (fun i => equationScope (relabelRestrictedMonomials S e b (P i))) w + ≤ varIncidence F + (fun i => equationScope (restrictMonomials S b (P i))) (e.symm w).1 := + card_le_card hsub + _ ≤ b₀ := + varIncidence_equationScope_restrictMonomials_heavyVars_le univ F P b₀ + (fun _ _ => subset_univ _) b (e.symm w).1 + +end BranchRelabeling + +/-! ### Section 5: Neutral variable-coverage scopes and Theorem 2.2 threshold bounds (§5.5–5.6) -/ + +section NeutralScopesAndThresholds + +/-- **§5.5 (neutral variable-coverage factor index set)**: adjoins one neutral factor `Sum.inr v` +for each declared variable `v : ι'` to the equation index set `I`. -/ +def withNeutralFactors [Fintype ι'] (I : Finset κ) : Finset (κ ⊕ ι') := + I.disjSum univ + +/-- **§5.5 (neutral variable-coverage scopes)**: retains `scope i` for `Sum.inl i` and assigns the +singleton scope `{v}` to each neutral factor `Sum.inr v`. -/ +def withNeutralScope (scope : κ → Finset ι') : κ ⊕ ι' → Finset ι' + | Sum.inl i => scope i + | Sum.inr v => {v} + +/-- Adjoining neutral singleton scopes increments the incidence of every variable `v : ι'` by +exactly `1`. -/ +theorem varIncidence_withNeutralFactors [Fintype ι'] [DecidableEq ι'] (I : Finset κ) + (scope : κ → Finset ι') (v : ι') : + varIncidence (withNeutralFactors I) (withNeutralScope scope) v = + varIncidence I scope v + 1 := by + classical + unfold varIncidence withNeutralFactors + rw [card_filter, sum_disjSum, ← card_filter, ← card_filter] + congr 1 + have hfilter : + ({w : ι' | v ∈ ({w} : Finset ι')} : Finset ι') = {v} := by + ext w + simp only [mem_filter, mem_univ, true_and, mem_singleton, eq_comm] + change #({w ∈ (univ : Finset ι') | v ∈ ({w} : Finset ι')}) = 1 + rw [hfilter, card_singleton] + +/-- Every declared variable `v : ι'` has incidence at least `1` after adjoining neutral scopes. -/ +theorem one_le_varIncidence_withNeutralFactors [Fintype ι'] [DecidableEq ι'] (I : Finset κ) + (scope : κ → Finset ι') (v : ι') : + 1 ≤ varIncidence (withNeutralFactors I) (withNeutralScope scope) v := by + rw [varIncidence_withNeutralFactors] + omega + +/-- If `varIncidence I scope v ≤ b₀`, then after adjoining neutral scopes the variable incidence is +at most `b₀ + 1`. -/ +theorem varIncidence_withNeutralFactors_le [Fintype ι'] [DecidableEq ι'] {I : Finset κ} + {scope : κ → Finset ι'} {v : ι'} {b₀ : ℕ} (hv : varIncidence I scope v ≤ b₀) : + varIncidence (withNeutralFactors I) (withNeutralScope scope) v ≤ b₀ + 1 := by + rw [varIncidence_withNeutralFactors] + exact Nat.add_le_add_right hv 1 + +/-- Adjoining neutral singleton scopes adds `Fintype.card ι'` to `totalIncidence`. -/ +theorem totalIncidence_withNeutralFactors [Fintype ι'] (I : Finset κ) (scope : κ → Finset ι') : + totalIncidence (withNeutralFactors I) (withNeutralScope scope) = + totalIncidence I scope + Fintype.card ι' := by + rw [totalIncidence, withNeutralFactors, sum_disjSum, totalIncidence] + congr 1 + simp only [withNeutralScope, card_singleton, sum_const, card_univ, smul_eq_mul, mul_one] + +/-- **§5.5 ($M' \ge n'$)**: after adjoining neutral singleton scopes, the total incidence is at +least `Fintype.card ι'`. -/ +theorem card_le_totalIncidence_withNeutralFactors [Fintype ι'] (I : Finset κ) + (scope : κ → Finset ι') : + Fintype.card ι' ≤ totalIncidence (withNeutralFactors I) (withNeutralScope scope) := by + rw [totalIncidence_withNeutralFactors] + exact Nat.le_add_left _ _ + +/-- **§5.5 (heavy-variable threshold $b_0 = \lceil M s / n \rceil$)**: integer ceiling of +`M * s / n`. -/ +def heavyThreshold (M n s : ℕ) : ℕ := + (M * s + n - 1) / n + +/-- When `1 ≤ n`, `M * s ≤ heavyThreshold M n s * n`. -/ +theorem mul_le_heavyThreshold_mul {M n s : ℕ} (hn : 1 ≤ n) : + M * s ≤ heavyThreshold M n s * n := by + unfold heavyThreshold + have hmod := Nat.div_add_mod (M * s + n - 1) n + have hlt : (M * s + n - 1) % n < n := Nat.mod_lt _ hn + rw [Nat.mul_comm ((M * s + n - 1) / n) n] + omega + +/-- **§5.5 ($|S| \le n / s$)**: whenever `totalIncidence F scope * s ≤ b₀ * #V`, `1 ≤ b₀`, +`1 ≤ s`, and `∀ i ∈ F, scope i ⊆ V`, the heavy-variable set `heavyVars V F scope b₀` has +cardinality at most `#V / s`. -/ +theorem card_heavyVars_le_card_div [DecidableEq ι] (V : Finset ι) (F : Finset κ) + (scope : κ → Finset ι) {b₀ s : ℕ} (hb₀ : 1 ≤ b₀) (hs : 1 ≤ s) + (hV : ∀ i ∈ F, scope i ⊆ V) (hM : totalIncidence F scope * s ≤ b₀ * #V) : + #(heavyVars V F scope b₀) ≤ #V / s := by + refine (Nat.le_div_iff_mul_le hs).mpr ?_ + have hcard := card_heavyVars_mul_le_totalIncidence V F scope b₀ hV + have hmul : (#(heavyVars V F scope b₀) * s) * b₀ ≤ #V * b₀ := by + calc + (#(heavyVars V F scope b₀) * s) * b₀ + = (#(heavyVars V F scope b₀) * b₀) * s := by ring + _ ≤ totalIncidence F scope * s := Nat.mul_le_mul_right s hcard + _ ≤ b₀ * #V := hM + _ = #V * b₀ := Nat.mul_comm _ _ + exact Nat.le_of_mul_le_mul_right hmul hb₀ + +/-- **§5.5 ($2^{|S|} \le 2^{n / s}$)**: under `totalIncidence F scope * s ≤ b₀ * Fintype.card ι`, +`1 ≤ b₀`, and `1 ≤ s`, there are at most `2 ^ (Fintype.card ι / s)` heavy-variable branches. -/ +theorem card_branchAssignments_heavyVars_le_two_pow_div [Fintype ι] [DecidableEq ι] + (F : Finset κ) (scope : κ → Finset ι) {b₀ s : ℕ} (hb₀ : 1 ≤ b₀) (hs : 1 ≤ s) + (hM : totalIncidence F scope * s ≤ b₀ * Fintype.card ι) : + #(branchAssignments (heavyVars univ F scope b₀)) ≤ 2 ^ (Fintype.card ι / s) := by + rw [card_branchAssignments] + have hle := card_heavyVars_le_card_div univ F scope hb₀ hs (fun _ _ => subset_univ _) + (by simpa [card_univ] using hM) + rw [card_univ] at hle + exact Nat.pow_le_pow_right (by decide) hle + +/-- **§5.5 ($n' = n - |S| \ge n - n / s$)**: under `totalIncidence F scope * s ≤ b₀ * #V`, +`1 ≤ b₀`, `1 ≤ s`, and `∀ i ∈ F, scope i ⊆ V`, the set `V \ heavyVars V F scope b₀` of free +variables has cardinality at least `#V - #V / s`. -/ +theorem card_sdiff_heavyVars_ge [DecidableEq ι] (V : Finset ι) (F : Finset κ) + (scope : κ → Finset ι) {b₀ s : ℕ} (hb₀ : 1 ≤ b₀) (hs : 1 ≤ s) + (hV : ∀ i ∈ F, scope i ⊆ V) (hM : totalIncidence F scope * s ≤ b₀ * #V) : + #V - #V / s ≤ #(V \ heavyVars V F scope b₀) := by + have hsub : heavyVars V F scope b₀ ⊆ V := filter_subset _ V + rw [card_sdiff, inter_eq_left.mpr hsub] + have hle := card_heavyVars_le_card_div V F scope hb₀ hs hV hM + omega + +/-- **§5.5 ($n' \ge n / 2$ for $s \ge 2$)**: when `2 ≤ s`, `1 ≤ b₀`, `∀ i ∈ F, scope i ⊆ V`, and +`totalIncidence F scope * s ≤ b₀ * #V`, at least half of the variables in `V` remain free after +removing `heavyVars V F scope b₀`: `#V ≤ 2 * #(V \ heavyVars V F scope b₀)` and +`#V / 2 ≤ #(V \ heavyVars V F scope b₀)`. -/ +theorem card_sdiff_heavyVars_ge_half [DecidableEq ι] (V : Finset ι) (F : Finset κ) + (scope : κ → Finset ι) {b₀ s : ℕ} (hb₀ : 1 ≤ b₀) (hs : 2 ≤ s) + (hV : ∀ i ∈ F, scope i ⊆ V) (hM : totalIncidence F scope * s ≤ b₀ * #V) : + #V ≤ 2 * #(V \ heavyVars V F scope b₀) ∧ + #V / 2 ≤ #(V \ heavyVars V F scope b₀) := by + have hdiv : #V / s ≤ #V / 2 := Nat.div_le_div_left hs (by decide) + have hge := card_sdiff_heavyVars_ge V F scope hb₀ (by omega) hV hM + constructor <;> omega + +end NeutralScopesAndThresholds + +end Cslib.BitString diff --git a/ComplexityTests/SparseBranching.lean b/ComplexityTests/SparseBranching.lean new file mode 100644 index 0000000000..980ed00d9b --- /dev/null +++ b/ComplexityTests/SparseBranching.lean @@ -0,0 +1,103 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Foundations.BooleanAnalysis.SparseBranching +public import ComplexityTests.SparseEquations + +/-! +# Tests for univariate parity-product specialization and heavy-variable branch reduction + +Concrete non-vacuity checks and edge-case controls for +`Complexity.Foundations.BooleanAnalysis.SparseBranching`. +-/ + +@[expose] public noncomputable section + +namespace Cslib.BitString + +open Finset + +/-- Linear univariate replacement polynomial `bitVal ℤ (x v) + T` of degree `1`, which restores +`bitVal ℤ (x v)` at `T = 0`. -/ +def testLinearReplacement (x : Fin 2 → Bool) (_i : Fin 2) (v : Fin 2) : Polynomial ℤ := + Polynomial.C (bitVal ℤ (x v)) + Polynomial.X + +/-- At `T = 0`, `testLinearReplacement x i v` restores `bitVal ℤ (x v)`. -/ +theorem eval_zero_testLinearReplacement (x : Fin 2 → Bool) (i v : Fin 2) : + (testLinearReplacement x i v).eval 0 = bitVal ℤ (x v) := by + simp only [testLinearReplacement, Polynomial.eval_add, Polynomial.eval_C, Polynomial.eval_X, + add_zero] + +/-- Equation (5.5a) univariate `natDegree` bound (`k = 2`, `R_deg = 3`, `#I = 2`, `ℓ = 2`): +both `[V ^ 1] H(T)` and `S_2(H(T))` have `natDegree ≤ (2 * 3) * (2 + 2 * 1) = 24`. -/ +example (q : (Fin 2 → Bool) → Fin 2 → Fin 2 → Polynomial ℤ) + (hq : ∀ x : Fin 2 → Bool, ∀ i ∈ (univ : Finset (Fin 2)), ∀ M ∈ testSys i, ∀ v ∈ M, + (q x i v).natDegree ≤ 3) : + (univariateParityCoord (univ : Finset (Fin 2)) testSys 2 q 1).natDegree ≤ 24 ∧ + (univariateParityTruncatedSum (univ : Finset (Fin 2)) testSys 2 q).natDegree ≤ 24 := by + have hk : ∀ i ∈ (univ : Finset (Fin 2)), ∀ M ∈ testSys i, #M ≤ 2 := by + intro i _ M _ + exact (card_le_univ M).trans (by decide) + exact ⟨(natDegree_univariateParityCoord_le univ testSys 2 q hk hq (by decide)).trans (by decide), + (natDegree_univariateParityTruncatedSum_le univ testSys 2 q hk hq).trans (by decide)⟩ + +/-- Equation (5.5b) exact recovery at `T = 0` on `testSys` with `testLinearReplacement` and +precision `ℓ = 3 > Fintype.card (Fin 2)`: reducing `S_3(H(0))` modulo `2 ^ 3 = 8` recovers +`commonZeroCount univ testSys = 1`. -/ +example : + ((univariateParityTruncatedSum (univ : Finset (Fin 2)) testSys 3 + testLinearReplacement).eval 0) % ((2 : ℤ) ^ 3) = + commonZeroCount (univ : Finset (Fin 2)) testSys := + emod_eval_zero_univariateParityTruncatedSum_eq_commonZeroCount univ testSys (by decide) + testLinearReplacement (fun x i _ _ _ v _ => eval_zero_testLinearReplacement x i v) + +/-- Theorem 2.2 additive branch decomposition on the relabeled free-variable cube `Fin n' → Bool` +when branching on `S = {0}` (`n' = #(univ \ {0})`). -/ +example : + commonZeroCount (univ : Finset (Fin 2)) testSys = + ∑ b ∈ branchAssignments ({0} : Finset (Fin 2)), + commonZeroCount (univ : Finset (Fin 2)) + (fun i => relabelRestrictedMonomials ({0} : Finset (Fin 2)) + (equivFin (univ \ ({0} : Finset (Fin 2)))) b (testSys i)) := + commonZeroCount_eq_sum_relabelRestrictedMonomials {0} + (equivFin (univ \ ({0} : Finset (Fin 2)))) univ testSys + +/-- Post-branching free-variable incidence bound `≤ b₀` on the relabeled variable type `Fin n'` +for `testSys` with `b₀ = 1`. -/ +example (b : Fin 2 → Bool) + (w : Fin #(univ \ heavyVars univ univ (fun i => equationScope (testSys i)) 1)) : + varIncidence (univ : Finset (Fin 2)) + (fun i => equationScope + (relabelRestrictedMonomials + (heavyVars univ univ (fun i => equationScope (testSys i)) 1) + (equivFin (univ \ heavyVars univ univ (fun i => equationScope (testSys i)) 1)) + b (testSys i))) w ≤ 1 := + varIncidence_relabelRestrictedMonomials_heavyVars_le univ univ testSys 1 + (subset_univ _) + (equivFin (univ \ heavyVars univ univ (fun i => equationScope (testSys i)) 1)) b w + +/-- Neutral singleton variable-coverage scopes guarantee `1 ≤ varIncidence` for every variable and +`Fintype.card (Fin 2) ≤ totalIncidence`. -/ +example (v : Fin 2) : + 1 ≤ varIncidence (withNeutralFactors (univ : Finset (Fin 2))) + (withNeutralScope (fun i => equationScope (testSys i))) v ∧ + Fintype.card (Fin 2) ≤ + totalIncidence (withNeutralFactors (univ : Finset (Fin 2))) + (withNeutralScope (fun i => equationScope (testSys i))) := + ⟨one_le_varIncidence_withNeutralFactors univ (fun i => equationScope (testSys i)) v, + card_le_totalIncidence_withNeutralFactors univ (fun i => equationScope (testSys i))⟩ + +/-- Heavy-variable threshold ceiling `heavyThreshold M n s` satisfies `M * s ≤ b₀ * n` and yields +at least `n / 2` free variables when `s ≥ 2`. -/ +example : + 4 * 2 ≤ heavyThreshold 4 20 2 * 20 := + mul_le_heavyThreshold_mul (by decide) + +end Cslib.BitString From f731bcd6dc57de896ef81f8d715a8042a0826d8a Mon Sep 17 00:00:00 2001 From: Samuel Schlesinger Date: Tue, 27 Oct 2026 01:23:16 +0000 Subject: [PATCH 06/20] =?UTF-8?q?feat(BooleanAnalysis):=20add=20=C2=A75.6?= =?UTF-8?q?=20shared-precision=20branch=20recovery=20and=20linear=20degree?= =?UTF-8?q?=20bound=20(#1253)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BooleanAnalysis/SparseBranching.lean | 126 ++++++++++++++++++ ComplexityTests/SparseBranching.lean | 37 +++++ 2 files changed, 163 insertions(+) diff --git a/Complexity/Foundations/BooleanAnalysis/SparseBranching.lean b/Complexity/Foundations/BooleanAnalysis/SparseBranching.lean index 843598f194..6f3b262a4f 100644 --- a/Complexity/Foundations/BooleanAnalysis/SparseBranching.lean +++ b/Complexity/Foundations/BooleanAnalysis/SparseBranching.lean @@ -66,6 +66,8 @@ of [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (pp. 37 singleton scopes `{v}` for every variable $v \in \iota'$. * `Cslib.BitString.heavyThreshold`: integer ceiling $\lceil M s / n \rceil$ for the heavy-variable incidence threshold $b_0$. +* `Cslib.BitString.branchPrecision`: the shared modular precision $\ell = n + 1$ used across the + unrestricted system and all free-variable branches. ## Main results @@ -82,6 +84,11 @@ of [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (pp. 37 * `Cslib.BitString.card_le_totalIncidence_withNeutralFactors`: neutral scopes guarantee $M' \ge n'$. * `Cslib.BitString.card_heavyVars_le_card_div` and `Cslib.BitString.card_sdiff_heavyVars_ge_half`: $|S| \le n / s$ and $n' \ge n / 2$ for $s \ge 2$. +* `Cslib.BitString.commonZeroCount_eq_sum_branch_emod_eval_zero` and + `Cslib.BitString.natDegree_univariateParityTruncatedSum_branch_le`: §5.6 shared-precision + $\ell = n + 1$ branch recovery and linear degree bound + $\deg_T \le (k R_{\mathrm{deg}})((2 c + 4) n')$ when $m_{\mathrm{test}} \le c n$ and + $n \le 2 n'$. ## References @@ -860,6 +867,125 @@ theorem card_sdiff_heavyVars_ge_half [DecidableEq ι] (V : Finset ι) (F : Finse have hge := card_sdiff_heavyVars_ge V F scope hb₀ (by omega) hV hM constructor <;> omega +/-- **§5.1 & §5.6 ($\ell = n + 1$)**: the shared modular precision `n + 1` used for both the +unrestricted system on `n` variables and every free-variable branch. -/ +def branchPrecision (n : ℕ) : ℕ := + n + 1 + +/-- The branch precision `branchPrecision n` is always at least `1`. -/ +theorem one_le_branchPrecision (n : ℕ) : 1 ≤ branchPrecision n := + Nat.succ_pos n + +/-- Strict inequality `2 ^ n < 2 ^ branchPrecision n`. -/ +theorem two_pow_lt_two_pow_branchPrecision (n : ℕ) : + 2 ^ n < 2 ^ branchPrecision n := + Nat.pow_lt_pow_right (by decide) (Nat.lt_succ_self n) + +/-- **§5.1 ($N(\mathcal{P}) < 2^\ell$)**: the common-zero count on `ι` is strictly smaller than +`2 ^ branchPrecision (Fintype.card ι)`. -/ +theorem commonZeroCount_lt_two_pow_branchPrecision [Fintype ι] [DecidableEq ι] (I : Finset κ) + (P : κ → Finset (Finset ι)) : + commonZeroCount I P < 2 ^ branchPrecision (Fintype.card ι) := + lt_of_le_of_lt (commonZeroCount_le_two_pow I P) + (two_pow_lt_two_pow_branchPrecision (Fintype.card ι)) + +/-- **§5.6 (branch count $< 2^\ell$ at original precision $\ell = n + 1$)**: for any subset `S` +and branch assignment `b : ι → Bool`, the relabeled branch common-zero count on `ι'` is strictly +smaller than `2 ^ branchPrecision (Fintype.card ι)` whenever `e : ↥(univ \ S) ≃ ι'`. -/ +theorem commonZeroCount_relabelRestrictedMonomials_lt_two_pow_branchPrecision [Fintype ι] + [Fintype ι'] [DecidableEq ι] [DecidableEq ι'] (S : Finset ι) (e : ↥(univ \ S) ≃ ι') + (I : Finset κ) (P : κ → Finset (Finset ι)) (b : ι → Bool) : + commonZeroCount I (fun i => relabelRestrictedMonomials S e b (P i)) < + 2 ^ branchPrecision (Fintype.card ι) := by + have hcard : Fintype.card ι' ≤ Fintype.card ι := by + rw [← Fintype.card_congr e, Fintype.card_coe] + exact card_le_univ (univ \ S) + calc + commonZeroCount I (fun i => relabelRestrictedMonomials S e b (P i)) + ≤ 2 ^ Fintype.card ι' := commonZeroCount_le_two_pow _ _ + _ ≤ 2 ^ Fintype.card ι := Nat.pow_le_pow_right (by decide) hcard + _ < 2 ^ branchPrecision (Fintype.card ι) := + two_pow_lt_two_pow_branchPrecision (Fintype.card ι) + +/-- **§5.6 (exact branch recovery at original precision $\ell = n + 1$)**: on any branch `(S, b)` +relabeled along `e : ↥(univ \ S) ≃ ι'`, evaluating `univariateParityTruncatedSum` at `T = 0` with +the original precision `branchPrecision (Fintype.card ι) = n + 1` and taking the remainder modulo +`2 ^ branchPrecision (Fintype.card ι)` yields the exact branch common-zero count. -/ +theorem emod_eval_zero_univariateParityTruncatedSum_branch_eq [Fintype ι] [Fintype ι'] + [DecidableEq ι] [DecidableEq ι'] (S : Finset ι) (e : ↥(univ \ S) ≃ ι') (I : Finset κ) + (P : κ → Finset (Finset ι)) (b : ι → Bool) + (q : (ι' → Bool) → κ → ι' → Polynomial ℤ) + (hq0 : ∀ x : ι' → Bool, ∀ i ∈ I, ∀ M ∈ relabelRestrictedMonomials S e b (P i), + ∀ v ∈ M, (q x i v).eval 0 = bitVal ℤ (x v)) : + ((univariateParityTruncatedSum I (fun i => relabelRestrictedMonomials S e b (P i)) + (branchPrecision (Fintype.card ι)) q).eval 0) % + ((2 : ℤ) ^ branchPrecision (Fintype.card ι)) = + (commonZeroCount I (fun i => relabelRestrictedMonomials S e b (P i)) : ℤ) := by + have hcard : Fintype.card ι' < branchPrecision (Fintype.card ι) := by + rw [branchPrecision, ← Fintype.card_congr e, Fintype.card_coe] + exact Nat.lt_succ_of_le (card_le_univ (univ \ S)) + exact emod_eval_zero_univariateParityTruncatedSum_eq_commonZeroCount I + (fun i => relabelRestrictedMonomials S e b (P i)) hcard q hq0 + +/-- **§5.6 (Theorem 2.2 branch-summed modular recovery)**: summing the per-branch `T = 0` +remainders modulo `2 ^ branchPrecision (Fintype.card ι)` across all `b ∈ branchAssignments S` +recovers the exact unrestricted count `(commonZeroCount I P : ℤ)`. -/ +theorem commonZeroCount_eq_sum_branch_emod_eval_zero [Fintype ι] [Fintype ι'] + [DecidableEq ι] [DecidableEq ι'] (S : Finset ι) (e : ↥(univ \ S) ≃ ι') + (I : Finset κ) (P : κ → Finset (Finset ι)) + (q : (ι → Bool) → (ι' → Bool) → κ → ι' → Polynomial ℤ) + (hq0 : ∀ b ∈ branchAssignments S, ∀ x : ι' → Bool, ∀ i ∈ I, + ∀ M ∈ relabelRestrictedMonomials S e b (P i), ∀ v ∈ M, + (q b x i v).eval 0 = bitVal ℤ (x v)) : + (commonZeroCount I P : ℤ) = + ∑ b ∈ branchAssignments S, + ((univariateParityTruncatedSum I + (fun i => relabelRestrictedMonomials S e b (P i)) + (branchPrecision (Fintype.card ι)) (q b)).eval 0) % + ((2 : ℤ) ^ branchPrecision (Fintype.card ι)) := by + rw [commonZeroCount_eq_sum_relabelRestrictedMonomials S e I P, Nat.cast_sum] + refine sum_congr rfl fun b hb => ?_ + exact (emod_eval_zero_univariateParityTruncatedSum_branch_eq S e I P b (q b) (hq0 b hb)).symm + +/-- **§5.6 ($m_{\mathrm{test}} + 2(\ell - 1) \le (2c + 4)n'$ when $n \le 2n'$)**: when `m ≤ c * n` +and `n ≤ 2 * n'`, the equation-plus-precision factor `m + 2 * (branchPrecision n - 1)` is at most +`(2 * c + 4) * n'`. -/ +theorem branchEquationBudget_le {m c n n' : ℕ} (hm : m ≤ c * n) (hn : n ≤ 2 * n') : + m + 2 * (branchPrecision n - 1) ≤ (2 * c + 4) * n' := by + unfold branchPrecision + calc + m + 2 * (n + 1 - 1) = m + 2 * n := by omega + _ ≤ c * n + 2 * n := Nat.add_le_add_right hm (2 * n) + _ = (c + 2) * n := by ring + _ ≤ (c + 2) * (2 * n') := Nat.mul_le_mul_left (c + 2) hn + _ = (2 * c + 4) * n' := by ring + +/-- **§5.6 ($d_H = O_{k, c}(n' R)$ per-branch degree bound)**: on any branch `(S, b)` relabeled +along `e : ↥(univ \ S) ≃ ι'`, if `#I ≤ c * Fintype.card ι`, `Fintype.card ι ≤ 2 * Fintype.card ι'`, +every monomial in the unrestricted system `P` has degree at most `k`, and every branch replacement +polynomial `q x i v` has `natDegree ≤ R_deg`, then `univariateParityTruncatedSum` at precision +`branchPrecision (Fintype.card ι)` has `natDegree` at most +`(k * R_deg) * ((2 * c + 4) * Fintype.card ι')`. -/ +theorem natDegree_univariateParityTruncatedSum_branch_le [CommRing R] [Fintype ι] [Fintype ι'] + [DecidableEq ι] [DecidableEq ι'] (S : Finset ι) (e : ↥(univ \ S) ≃ ι') (I : Finset κ) + (P : κ → Finset (Finset ι)) (b : ι → Bool) (q : (ι' → Bool) → κ → ι' → Polynomial R) + {k R_deg c : ℕ} (hm : #I ≤ c * Fintype.card ι) + (hn : Fintype.card ι ≤ 2 * Fintype.card ι') + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hdeg : ∀ x : ι' → Bool, ∀ i ∈ I, + ∀ M ∈ relabelRestrictedMonomials S e b (P i), ∀ v ∈ M, + (q x i v).natDegree ≤ R_deg) : + (univariateParityTruncatedSum I + (fun i => relabelRestrictedMonomials S e b (P i)) + (branchPrecision (Fintype.card ι)) q).natDegree ≤ + (k * R_deg) * ((2 * c + 4) * Fintype.card ι') := by + have hk_branch : ∀ i ∈ I, ∀ M' ∈ relabelRestrictedMonomials S e b (P i), #M' ≤ k := + fun i hi => card_mem_relabelRestrictedMonomials_le (hk i hi) + refine (natDegree_univariateParityTruncatedSum_le I + (fun i => relabelRestrictedMonomials S e b (P i)) + (branchPrecision (Fintype.card ι)) q hk_branch hdeg).trans ?_ + exact Nat.mul_le_mul_left (k * R_deg) (branchEquationBudget_le hm hn) + end NeutralScopesAndThresholds end Cslib.BitString diff --git a/ComplexityTests/SparseBranching.lean b/ComplexityTests/SparseBranching.lean index 980ed00d9b..f69342c3bf 100644 --- a/ComplexityTests/SparseBranching.lean +++ b/ComplexityTests/SparseBranching.lean @@ -100,4 +100,41 @@ example : 4 * 2 ≤ heavyThreshold 4 20 2 * 20 := mul_le_heavyThreshold_mul (by decide) +/-- §5.6 shared-precision (`ℓ = n + 1 = 3`) branch-summed modular recovery on `testSys` when +branching on `S = {0}`. -/ +example : + (commonZeroCount (univ : Finset (Fin 2)) testSys : ℤ) = + ∑ b ∈ branchAssignments ({0} : Finset (Fin 2)), + ((univariateParityTruncatedSum (univ : Finset (Fin 2)) + (fun i => relabelRestrictedMonomials ({0} : Finset (Fin 2)) + (equivFin (univ \ ({0} : Finset (Fin 2)))) b (testSys i)) + (branchPrecision (Fintype.card (Fin 2))) + (fun x _i w => Polynomial.C (bitVal ℤ (x w)) + Polynomial.X)).eval 0) % + ((2 : ℤ) ^ branchPrecision (Fintype.card (Fin 2))) := by + refine commonZeroCount_eq_sum_branch_emod_eval_zero {0} + (equivFin (univ \ ({0} : Finset (Fin 2)))) univ testSys _ ?_ + intro _b _hb x _i _hi _M _hM w _hw + simp only [Polynomial.eval_add, Polynomial.eval_C, Polynomial.eval_X, add_zero] + +/-- §5.6 linear per-branch degree bound `d_H ≤ (k * R_deg) * ((2 * c + 4) * n')` (`k = 2`, +`R_deg = 3`, `c = 1`, `n = 2`, `n' = 1`). -/ +example (b : Fin 2 → Bool) + (q : (Fin #(univ \ ({0} : Finset (Fin 2))) → Bool) → Fin 2 → + Fin #(univ \ ({0} : Finset (Fin 2))) → Polynomial ℤ) + (hdeg : ∀ x, ∀ i ∈ (univ : Finset (Fin 2)), + ∀ M ∈ relabelRestrictedMonomials ({0} : Finset (Fin 2)) + (equivFin (univ \ ({0} : Finset (Fin 2)))) b (testSys i), + ∀ v ∈ M, (q x i v).natDegree ≤ 3) : + (univariateParityTruncatedSum (univ : Finset (Fin 2)) + (fun i => relabelRestrictedMonomials ({0} : Finset (Fin 2)) + (equivFin (univ \ ({0} : Finset (Fin 2)))) b (testSys i)) + (branchPrecision (Fintype.card (Fin 2))) q).natDegree ≤ + (2 * 3) * ((2 * 1 + 4) * Fintype.card (Fin #(univ \ ({0} : Finset (Fin 2))))) := by + have hk : ∀ i ∈ (univ : Finset (Fin 2)), ∀ M ∈ testSys i, #M ≤ 2 := by + intro _i _ M _ + exact (card_le_univ M).trans (by decide) + exact natDegree_univariateParityTruncatedSum_branch_le {0} + (equivFin (univ \ ({0} : Finset (Fin 2)))) univ testSys b q + (by decide) (by decide) hk hdeg + end Cslib.BitString From 01ba2278a93e5b58ffae3721deaef4e30b9ab979 Mon Sep 17 00:00:00 2001 From: Samuel Schlesinger Date: Tue, 27 Oct 2026 01:33:51 +0000 Subject: [PATCH 07/20] refactor(Polynomial,BooleanAnalysis): extract shared CoeffNorm1 and address review on #1248 --- Complexity.lean | 1 + .../BooleanAnalysis/SparseEquations.lean | 98 +----- .../Data/Polynomial/CoeffNorm1.lean | 293 ++++++++++++++++++ .../Data/Polynomial/ParityAmplifier.lean | 117 +------ .../Data/Polynomial/CoeffNorm1.lean | 38 +++ 5 files changed, 350 insertions(+), 197 deletions(-) create mode 100644 Complexity/Foundations/Data/Polynomial/CoeffNorm1.lean create mode 100644 ComplexityTests/Foundations/Data/Polynomial/CoeffNorm1.lean diff --git a/Complexity.lean b/Complexity.lean index f8b4692130..aaf637ea1e 100644 --- a/Complexity.lean +++ b/Complexity.lean @@ -1976,6 +1976,7 @@ public import Complexity.Foundations.Data.Option public import Complexity.Foundations.Data.OrderedSet public import Complexity.Foundations.Data.OrderedSet.Spec public import Complexity.Foundations.Data.Polynomial.CoeffList +public import Complexity.Foundations.Data.Polynomial.CoeffNorm1 public import Complexity.Foundations.Data.Polynomial.HermiteInterpolation public import Complexity.Foundations.Data.Polynomial.ParityAmplifier public import Complexity.Foundations.Data.Polynomial.SignQueries diff --git a/Complexity/Foundations/BooleanAnalysis/SparseEquations.lean b/Complexity/Foundations/BooleanAnalysis/SparseEquations.lean index c5043f568b..6f1f9bcfa7 100644 --- a/Complexity/Foundations/BooleanAnalysis/SparseEquations.lean +++ b/Complexity/Foundations/BooleanAnalysis/SparseEquations.lean @@ -48,12 +48,16 @@ truncation from `Complexity.Foundations.Data.Polynomial.ParityAmplifier` [Toda][ `commonZeroCount I P` on the nose via `(· % 2 ^ ℓ)` whenever `Fintype.card ι < ℓ` (`Cslib.BitString.emod_sum_sumCoeffsBelow_prod_parityFactor_eq_commonZeroCount`). -Finally, for any system of equations with variable scopes `scope : κ → Finset ι` and incidence -threshold `b₀`, the set `Cslib.BitString.heavyVars` of variables appearing in more than `b₀` +Finally, for any system of equations with variable scopes `scope : κ → Finset ι` contained in a +candidate variable set `V` (`∀ i ∈ F, scope i ⊆ V`) and positive incidence threshold `1 ≤ b₀`, +the set `Cslib.BitString.heavyVars V F scope b₀` of variables in `V` appearing in more than `b₀` scopes has cardinality at most `totalIncidence F scope / b₀` -(`Cslib.BitString.card_heavyVars_le_div`), while every remaining variable has incidence at most -`b₀`. Branching on all `2 ^ #S` assignments to a variable subset `S` and simplifying each equation -via `Cslib.BitString.restrictMonomials` preserves degree bounds, never increases the number of +(`Cslib.BitString.card_heavyVars_le_div`; and at most `(k_scope * #F) / b₀` when every scope has +cardinality at most `k_scope`, `Cslib.BitString.card_heavyVars_le_mul_card_div`), while every +remaining variable in `V \ heavyVars V F scope b₀` (and in any post-branching restricted equation +scope when `∀ i ∈ I, equationScope (P i) ⊆ V`) has incidence at most `b₀`. Branching on all +`2 ^ #S` assignments to a variable subset `S` and simplifying each equation via +`Cslib.BitString.restrictMonomials` preserves degree bounds, never increases the number of monomials per equation, and decomposes `commonZeroCount` additively across the branches (`Cslib.BitString.commonZeroCount_eq_sum_branches`). @@ -764,74 +768,6 @@ theorem commonZeroCount_eq_sum_branches [Fintype ι] [DecidableEq ι] (S : Finse /-! ### 6. Cleared-denominator homogenization and `ℓ₁`-norm bounds (§5.4 & Appendix B.2) -/ -/-- `Polynomial.coeffNorm1` satisfies the finite-sum triangle inequality. -/ -theorem coeffNorm1_sum_le {α : Type*} (s : Finset α) (f : α → Polynomial ℤ) : - Polynomial.coeffNorm1 (∑ a ∈ s, f a) ≤ ∑ a ∈ s, Polynomial.coeffNorm1 (f a) := by - classical - induction s using Finset.induction_on with - | empty => simp only [sum_empty, Polynomial.coeffNorm1_zero, le_refl] - | insert a s ha ih => - rw [sum_insert ha, sum_insert ha] - exact (Polynomial.coeffNorm1_add_le _ _).trans (add_le_add le_rfl ih) - -/-- `Polynomial.coeffNorm1` is invariant under negation. -/ -@[simp] -theorem coeffNorm1_neg (p : Polynomial ℤ) : - Polynomial.coeffNorm1 (-p) = Polynomial.coeffNorm1 p := by - rw [Polynomial.coeffNorm1, Polynomial.coeffNorm1, Polynomial.support_neg] - refine sum_congr rfl fun i _ => ?_ - rw [Polynomial.coeff_neg, Int.natAbs_neg] - -/-- `Polynomial.coeffNorm1 (p - q) ≤ Polynomial.coeffNorm1 p + Polynomial.coeffNorm1 q`. -/ -theorem coeffNorm1_sub_le (p q : Polynomial ℤ) : - Polynomial.coeffNorm1 (p - q) ≤ Polynomial.coeffNorm1 p + Polynomial.coeffNorm1 q := by - rw [sub_eq_add_neg] - exact (Polynomial.coeffNorm1_add_le p (-q)).trans (by rw [coeffNorm1_neg]) - -/-- `Polynomial.coeffNorm1` is submultiplicative on `ℤ[X]`. -/ -theorem coeffNorm1_mul_le (p q : Polynomial ℤ) : - Polynomial.coeffNorm1 (p * q) ≤ Polynomial.coeffNorm1 p * Polynomial.coeffNorm1 q := by - have hdecomp : p * q = ∑ i ∈ p.support, Polynomial.C (p.coeff i) * (q * Polynomial.X ^ i) := by - conv_lhs => rw [p.as_sum_support_C_mul_X_pow] - rw [sum_mul] - refine sum_congr rfl fun i _ => ?_ - ring - rw [hdecomp] - calc - Polynomial.coeffNorm1 (∑ i ∈ p.support, Polynomial.C (p.coeff i) * (q * Polynomial.X ^ i)) - ≤ ∑ i ∈ p.support, - Polynomial.coeffNorm1 (Polynomial.C (p.coeff i) * (q * Polynomial.X ^ i)) := - coeffNorm1_sum_le _ _ - _ ≤ ∑ i ∈ p.support, (p.coeff i).natAbs * Polynomial.coeffNorm1 q := by - refine sum_le_sum fun i _ => ?_ - exact (Polynomial.coeffNorm1_C_mul_le (p.coeff i) _).trans - (Nat.mul_le_mul_left _ (Polynomial.coeffNorm1_mul_X_pow_le q i)) - _ = Polynomial.coeffNorm1 p * Polynomial.coeffNorm1 q := by - rw [← sum_mul, ← Polynomial.coeffNorm1] - -/-- `Polynomial.coeffNorm1 (p ^ k) ≤ Polynomial.coeffNorm1 p ^ k`. -/ -theorem coeffNorm1_pow_le (p : Polynomial ℤ) (k : ℕ) : - Polynomial.coeffNorm1 (p ^ k) ≤ Polynomial.coeffNorm1 p ^ k := by - induction k with - | zero => - have h1 : (1 : Polynomial ℤ) = Polynomial.C 1 := by simp only [map_one] - simp only [pow_zero, h1, Polynomial.coeffNorm1_C, Int.natAbs_one, le_refl] - | succ k ih => - rw [pow_succ, pow_succ] - exact (coeffNorm1_mul_le _ _).trans (Nat.mul_le_mul_right _ ih) - -/-- `Polynomial.coeffNorm1` of a finite product is at most the product of the `coeffNorm1`s. -/ -theorem coeffNorm1_prod_le {α : Type*} (s : Finset α) (f : α → Polynomial ℤ) : - Polynomial.coeffNorm1 (∏ a ∈ s, f a) ≤ ∏ a ∈ s, Polynomial.coeffNorm1 (f a) := by - classical - induction s using Finset.induction_on with - | empty => - have h1 : (1 : Polynomial ℤ) = Polynomial.C 1 := by simp only [map_one] - simp only [prod_empty, h1, Polynomial.coeffNorm1_C, Int.natAbs_one, le_refl] - | insert a s ha ih => - rw [prod_insert ha, prod_insert ha] - exact (coeffNorm1_mul_le _ _).trans (Nat.mul_le_mul_left _ ih) - /-- Cleared-denominator evaluation `a_j * Δ + b_j * A_i` of `parityBaseDigit ℓ j = a_j + b_j X` at `L_i = A_i / Δ`. -/ def parityBaseDigitCleared {A : Type*} [CommRing A] (ℓ j : ℕ) (Δ A_i : A) : A := @@ -970,7 +906,7 @@ theorem coeffNorm1_clearedMonomialPoly_le {d_den : ℤ} {k B₀ : ℕ} {θ : ι Polynomial.coeffNorm1_C_mul_le _ _ _ ≤ B₀ ^ (k - #M) * ∏ v ∈ M, Polynomial.coeffNorm1 (θ v) := by rw [Int.natAbs_pow] - exact Nat.mul_le_mul (Nat.pow_le_pow_left hd _) (coeffNorm1_prod_le M θ) + exact Nat.mul_le_mul (Nat.pow_le_pow_left hd _) (Polynomial.coeffNorm1_prod_le M θ) _ ≤ B₀ ^ (k - #M) * ∏ _v ∈ M, B₀ := Nat.mul_le_mul_left _ (prod_le_prod hθ) _ = B₀ ^ k := by @@ -986,7 +922,7 @@ theorem coeffNorm1_clearedMonomialSumPoly_le {d_den : ℤ} {k B₀ : ℕ} {θ : calc Polynomial.coeffNorm1 (∑ M ∈ 𝓜, clearedMonomialPoly d_den k θ M) ≤ ∑ M ∈ 𝓜, Polynomial.coeffNorm1 (clearedMonomialPoly d_den k θ M) := - coeffNorm1_sum_le 𝓜 _ + Polynomial.coeffNorm1_sum_le 𝓜 _ _ ≤ ∑ _M ∈ 𝓜, B₀ ^ k := sum_le_sum fun M hM => coeffNorm1_clearedMonomialPoly_le hd (hk M hM) (hθ M hM) _ = #𝓜 * B₀ ^ k := by @@ -1036,9 +972,9 @@ theorem coeffNorm1_hPolyCleared_le (Δ : ℤ) {A_i : Polynomial ℤ} {B : ℕ} calc Polynomial.coeffNorm1 (A_i * (A_i - Polynomial.C Δ)) ≤ Polynomial.coeffNorm1 A_i * Polynomial.coeffNorm1 (A_i - Polynomial.C Δ) := - coeffNorm1_mul_le _ _ + Polynomial.coeffNorm1_mul_le _ _ _ ≤ B * (Polynomial.coeffNorm1 A_i + Polynomial.coeffNorm1 (Polynomial.C Δ)) := - Nat.mul_le_mul hA (coeffNorm1_sub_le A_i (Polynomial.C Δ)) + Nat.mul_le_mul hA (Polynomial.coeffNorm1_sub_le A_i (Polynomial.C Δ)) _ ≤ B * (B + Δ.natAbs) := by rw [Polynomial.coeffNorm1_C] exact Nat.mul_le_mul_left B (add_le_add hA le_rfl) @@ -1055,7 +991,7 @@ theorem coeffNorm1_coeff_parityFactorCleared_le (ℓ : ℕ) (Δ : ℤ) {A_i : Po · have hpowΔ : Polynomial.coeffNorm1 ((Polynomial.C Δ) ^ (2 * (ℓ - 1 - s))) ≤ (B + Δ.natAbs) ^ (2 * (ℓ - 1 - s)) := by - refine (coeffNorm1_pow_le (Polynomial.C Δ) _).trans ?_ + refine (Polynomial.coeffNorm1_pow_le (Polynomial.C Δ) _).trans ?_ rw [Polynomial.coeffNorm1_C] exact Nat.pow_le_pow_left (Nat.le_add_left Δ.natAbs B) _ have he : @@ -1068,7 +1004,7 @@ theorem coeffNorm1_coeff_parityFactorCleared_le (ℓ : ℕ) (Δ : ℤ) {A_i : Po calc Polynomial.coeffNorm1 (hPolyCleared (Polynomial.C Δ) A_i ^ s) ≤ Polynomial.coeffNorm1 (hPolyCleared (Polynomial.C Δ) A_i) ^ s := - coeffNorm1_pow_le _ s + Polynomial.coeffNorm1_pow_le _ s _ ≤ (B * (B + Δ.natAbs)) ^ s := Nat.pow_le_pow_left (coeffNorm1_hPolyCleared_le Δ hA) s _ ≤ ((B + Δ.natAbs) * (B + Δ.natAbs)) ^ s := @@ -1085,11 +1021,11 @@ theorem coeffNorm1_coeff_parityFactorCleared_le (ℓ : ℕ) (Δ : ℤ) {A_i : Po ((Polynomial.C Δ) ^ (2 * (ℓ - 1 - s)) * parityBaseDigitCleared ℓ s (Polynomial.C Δ) A_i) * Polynomial.coeffNorm1 (hPolyCleared (Polynomial.C Δ) A_i ^ s) := - coeffNorm1_mul_le _ _ + Polynomial.coeffNorm1_mul_le _ _ _ ≤ (Polynomial.coeffNorm1 ((Polynomial.C Δ) ^ (2 * (ℓ - 1 - s))) * Polynomial.coeffNorm1 (parityBaseDigitCleared ℓ s (Polynomial.C Δ) A_i)) * Polynomial.coeffNorm1 (hPolyCleared (Polynomial.C Δ) A_i ^ s) := - Nat.mul_le_mul_right _ (coeffNorm1_mul_le _ _) + Nat.mul_le_mul_right _ (Polynomial.coeffNorm1_mul_le _ _) _ ≤ ((B + Δ.natAbs) ^ (2 * (ℓ - 1 - s)) * (Polynomial.coeffNorm1 (Polynomial.parityBaseDigit ℓ s) * (B + Δ.natAbs))) * (B + Δ.natAbs) ^ (2 * s) := diff --git a/Complexity/Foundations/Data/Polynomial/CoeffNorm1.lean b/Complexity/Foundations/Data/Polynomial/CoeffNorm1.lean new file mode 100644 index 0000000000..6781c52e43 --- /dev/null +++ b/Complexity/Foundations/Data/Polynomial/CoeffNorm1.lean @@ -0,0 +1,293 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Mathlib.Algebra.Polynomial.BigOperators +public import Mathlib.Algebra.Order.BigOperators.Group.Finset +import Mathlib.Algebra.Order.Ring.Abs +import Mathlib.Tactic.Linarith +import Mathlib.Tactic.Ring + +/-! +# The `ℓ₁` coefficient norm of an integer polynomial + +This module defines the `ℓ₁` coefficient norm `Polynomial.coeffNorm1` of a univariate integer +polynomial `p : ℤ[X]`: +$$\|p\|_1 = \sum_{i \in \mathrm{supp}(p)} |p_i|,$$ +together with its basic triangle, scaling, shift, linear-factor, submultiplicative, and +integer-cast inequalities used in Lemma 4.6, Lemma 5.1, and Appendix B of `[OpenAI2026ETH]`. + +## Main definitions + +* `Polynomial.coeffNorm1`: the `ℓ₁` coefficient norm `∑ i ∈ p.support, (p.coeff i).natAbs`. + +## Main results + +* `Polynomial.natAbs_coeff_le_coeffNorm1`, `Polynomial.sum_natAbs_coeff_le_coeffNorm1`: + individual and finite-subset coefficient bounds by `coeffNorm1`. +* `Polynomial.coeffNorm1_add_le`, `Polynomial.coeffNorm1_sub_le`, `Polynomial.coeffNorm1_sum_le`: + triangle inequalities for binary sums, differences, and finite sums. +* `Polynomial.coeffNorm1_C_mul_le`, `Polynomial.coeffNorm1_X_mul`, + `Polynomial.coeffNorm1_mul_X_pow_le`, `Polynomial.coeffNorm1_C_sub_X_mul_le`, + `Polynomial.coeffNorm1_one_sub_X_mul_le`, `Polynomial.coeffNorm1_one_sub_X_pow_mul_le`: + norm bounds under scalar multiplication, monomial shifts, and linear factors. +* `Polynomial.coeffNorm1_mul_le`, `Polynomial.coeffNorm1_pow_le`, `Polynomial.coeffNorm1_prod_le`: + submultiplicativity for binary products, powers, and finite products. +* `Polynomial.natCast_coeffNorm1`: integer cast identity + `(p.coeffNorm1 : ℤ) = ∑ i ∈ p.support, |p.coeff i|`. + +## References + +* [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] + (Lemma 4.6, Appendix B.1, and Appendix B.2) +-/ + +@[expose] public noncomputable section + +namespace Polynomial + +open Finset + +/-- The `ℓ₁` coefficient norm `∑ i ∈ p.support, (p.coeff i).natAbs` of an integer polynomial. -/ +def coeffNorm1 (p : ℤ[X]) : ℕ := + ∑ i ∈ p.support, (p.coeff i).natAbs + +/-- The `ℓ₁` norm of `0` is `0`. -/ +@[simp] +theorem coeffNorm1_zero : coeffNorm1 0 = 0 := by + simp only [coeffNorm1, support_zero, sum_empty] + +/-- Sum expression for `coeffNorm1` over any superset `S ⊇ p.support`. -/ +theorem coeffNorm1_eq_sum_of_support_subset {p : ℤ[X]} {S : Finset ℕ} (hS : p.support ⊆ S) : + coeffNorm1 p = ∑ i ∈ S, (p.coeff i).natAbs := by + unfold coeffNorm1 + refine sum_subset hS fun i _ hi => ?_ + rw [notMem_support_iff.mp hi, Int.natAbs_zero] + +/-- Every individual coefficient of `p` has absolute value at most `coeffNorm1 p`. -/ +theorem natAbs_coeff_le_coeffNorm1 (p : ℤ[X]) (k : ℕ) : + (p.coeff k).natAbs ≤ coeffNorm1 p := by + by_cases hk : k ∈ p.support + · exact single_le_sum (f := fun i => (p.coeff i).natAbs) (fun _ _ => Nat.zero_le _) hk + · rw [notMem_support_iff.mp hk, Int.natAbs_zero] + exact Nat.zero_le _ + +/-- The sum of `(p.coeff i).natAbs` over any finite set of indices is at most `coeffNorm1 p`. -/ +theorem sum_natAbs_coeff_le_coeffNorm1 (p : ℤ[X]) (s : Finset ℕ) : + ∑ i ∈ s, (p.coeff i).natAbs ≤ coeffNorm1 p := by + have hsub : ∑ i ∈ s, (p.coeff i).natAbs = ∑ i ∈ s ∩ p.support, (p.coeff i).natAbs := by + refine (sum_subset inter_subset_left ?_).symm + intro i hi his + rw [mem_inter, not_and_or, notMem_support_iff] at his + rcases his with hns | hp0 + · exact absurd hi hns + · simp only [hp0, Int.natAbs_zero] + rw [hsub, coeffNorm1] + exact sum_le_sum_of_subset inter_subset_right + +/-- The `ℓ₁` norm of a constant polynomial `C a` is `a.natAbs`. -/ +theorem coeffNorm1_C (a : ℤ) : coeffNorm1 (C a) = a.natAbs := by + by_cases ha : a = 0 + · subst ha + simp only [map_zero, coeffNorm1_zero, Int.natAbs_zero] + · rw [coeffNorm1, support_C ha, sum_singleton, coeff_C_zero] + +/-- The `ℓ₁` norm of `1` is `1`. -/ +@[simp] +theorem coeffNorm1_one : coeffNorm1 1 = 1 := by + rw [← C_1, coeffNorm1_C, Int.natAbs_one] + +/-- Negating a polynomial preserves `coeffNorm1`. -/ +@[simp] +theorem coeffNorm1_neg (p : ℤ[X]) : coeffNorm1 (-p) = coeffNorm1 p := by + rw [coeffNorm1_eq_sum_of_support_subset (S := p.support) (by simp), coeffNorm1] + refine sum_congr rfl fun i _ => ?_ + rw [coeff_neg, Int.natAbs_neg] + +/-- Triangle inequality for `coeffNorm1`. -/ +theorem coeffNorm1_add_le (p q : ℤ[X]) : + coeffNorm1 (p + q) ≤ coeffNorm1 p + coeffNorm1 q := by + have hsub : (p + q).support ⊆ p.support ∪ q.support := support_add + calc + coeffNorm1 (p + q) + ≤ ∑ i ∈ p.support ∪ q.support, ((p + q).coeff i).natAbs := + sum_le_sum_of_subset hsub + _ ≤ ∑ i ∈ p.support ∪ q.support, ((p.coeff i).natAbs + (q.coeff i).natAbs) := by + refine sum_le_sum fun i _ => ?_ + rw [coeff_add] + exact Int.natAbs_add_le _ _ + _ = (∑ i ∈ p.support ∪ q.support, (p.coeff i).natAbs) + + ∑ i ∈ p.support ∪ q.support, (q.coeff i).natAbs := sum_add_distrib + _ ≤ coeffNorm1 p + coeffNorm1 q := + add_le_add (sum_natAbs_coeff_le_coeffNorm1 p _) (sum_natAbs_coeff_le_coeffNorm1 q _) + +/-- Difference triangle inequality for `coeffNorm1`. -/ +theorem coeffNorm1_sub_le (p q : ℤ[X]) : + coeffNorm1 (p - q) ≤ coeffNorm1 p + coeffNorm1 q := by + rw [sub_eq_add_neg, ← coeffNorm1_neg q] + exact coeffNorm1_add_le p (-q) + +/-- Finite-sum triangle inequality for `coeffNorm1`. -/ +theorem coeffNorm1_sum_le {ι : Type*} (s : Finset ι) (f : ι → ℤ[X]) : + coeffNorm1 (∑ i ∈ s, f i) ≤ ∑ i ∈ s, coeffNorm1 (f i) := by + classical + induction s using Finset.induction_on with + | empty => simp only [sum_empty, coeffNorm1_zero, le_refl] + | insert a s ha ih => + rw [sum_insert ha, sum_insert ha] + exact (coeffNorm1_add_le (f a) (∑ i ∈ s, f i)).trans (Nat.add_le_add_left ih _) + +/-- Scaling by `C a` scales `coeffNorm1` by at most `a.natAbs`. -/ +theorem coeffNorm1_C_mul_le (a : ℤ) (p : ℤ[X]) : + coeffNorm1 (C a * p) ≤ a.natAbs * coeffNorm1 p := by + have hsub : (C a * p).support ⊆ p.support := by + intro i hi + rw [mem_support_iff, coeff_C_mul] at hi + exact mem_support_iff.mpr (right_ne_zero_of_mul hi) + calc + coeffNorm1 (C a * p) ≤ ∑ i ∈ p.support, ((C a * p).coeff i).natAbs := + sum_le_sum_of_subset hsub + _ = a.natAbs * coeffNorm1 p := by + rw [coeffNorm1, mul_sum] + refine sum_congr rfl fun i _ => ?_ + rw [coeff_C_mul, Int.natAbs_mul] + +/-- Multiplying by `X` preserves `coeffNorm1`. -/ +theorem coeffNorm1_X_mul (p : ℤ[X]) : coeffNorm1 (X * p) = coeffNorm1 p := by + let S := p.support.map ⟨Nat.succ, Nat.succ_injective⟩ + have hsub : (X * p).support ⊆ S := by + intro i hi + rw [mem_support_iff] at hi + rcases i with _ | i + · rw [mul_comm, coeff_mul_X_zero] at hi + exact (hi rfl).elim + · rw [mul_comm, coeff_mul_X] at hi + exact mem_map.mpr ⟨i, mem_support_iff.mpr hi, rfl⟩ + rw [coeffNorm1_eq_sum_of_support_subset hsub, sum_map, coeffNorm1] + refine sum_congr rfl fun i _ => ?_ + change ((X * p).coeff (i + 1)).natAbs = (p.coeff i).natAbs + rw [mul_comm, coeff_mul_X] + +/-- Multiplying by `X ^ k` does not increase `coeffNorm1`. -/ +theorem coeffNorm1_mul_X_pow_le (p : ℤ[X]) (k : ℕ) : + coeffNorm1 (p * X ^ k) ≤ coeffNorm1 p := by + rw [coeffNorm1] + have hsub : (p * X ^ k).support ⊆ p.support.map ⟨fun i => i + k, add_left_injective k⟩ := by + intro i hi + rw [mem_support_iff] at hi + rw [mem_map] + by_cases hik : k ≤ i + · refine ⟨i - k, ?_, by simp only [Function.Embedding.coeFn_mk]; omega⟩ + rw [mem_support_iff] + intro h0 + apply hi + have hi_eq : i = i - k + k := (Nat.sub_add_cancel hik).symm + rw [hi_eq, coeff_mul_X_pow, h0] + · exfalso + apply hi + rw [mul_comm, coeff_X_pow_mul'] + simp only [hik, ↓reduceIte] + refine (sum_le_sum_of_subset hsub).trans ?_ + rw [sum_map] + refine le_of_eq (sum_congr rfl fun i _ => ?_) + simp only [Function.Embedding.coeFn_mk, coeff_mul_X_pow] + +/-- Multiplying by `C a - X` scales `coeffNorm1` by at most `a.natAbs + 1`. -/ +theorem coeffNorm1_C_sub_X_mul_le (a : ℤ) (p : ℤ[X]) : + coeffNorm1 ((C a - X) * p) ≤ (a.natAbs + 1) * coeffNorm1 p := by + rw [sub_mul, add_one_mul] + have h1 := coeffNorm1_sub_le (C a * p) (X * p) + rw [coeffNorm1_X_mul] at h1 + exact h1.trans (Nat.add_le_add_right (coeffNorm1_C_mul_le a p) _) + +/-- Multiplying by `1 - X` increases `coeffNorm1` by at most a factor of `2`. -/ +theorem coeffNorm1_one_sub_X_mul_le (p : ℤ[X]) : + coeffNorm1 ((1 - X) * p) ≤ 2 * coeffNorm1 p := by + simpa only [C_1, Int.natAbs_one, Nat.reduceAdd] using coeffNorm1_C_sub_X_mul_le 1 p + +/-- Multiplying by `(1 - X) ^ ℓ` increases `coeffNorm1` by at most a factor of `2 ^ ℓ`. -/ +theorem coeffNorm1_one_sub_X_pow_mul_le (ℓ : ℕ) (p : ℤ[X]) : + coeffNorm1 ((1 - X) ^ ℓ * p) ≤ 2 ^ ℓ * coeffNorm1 p := by + induction ℓ with + | zero => simp only [pow_zero, one_mul, le_refl] + | succ ℓ ih => + have hEq : (1 - X) ^ (ℓ + 1) * p = (1 - X) * ((1 - X) ^ ℓ * p) := by ring + rw [hEq, pow_succ', mul_assoc] + exact (coeffNorm1_one_sub_X_mul_le _).trans (Nat.mul_le_mul_left 2 ih) + +/-- `coeffNorm1` is submultiplicative on `ℤ[X]`. -/ +theorem coeffNorm1_mul_le (p q : ℤ[X]) : + coeffNorm1 (p * q) ≤ coeffNorm1 p * coeffNorm1 q := by + have hdecomp : p * q = ∑ i ∈ p.support, C (p.coeff i) * (q * X ^ i) := by + conv_lhs => rw [p.as_sum_support_C_mul_X_pow] + rw [sum_mul] + refine sum_congr rfl fun i _ => ?_ + ring + rw [hdecomp] + calc + coeffNorm1 (∑ i ∈ p.support, C (p.coeff i) * (q * X ^ i)) + ≤ ∑ i ∈ p.support, coeffNorm1 (C (p.coeff i) * (q * X ^ i)) := + coeffNorm1_sum_le _ _ + _ ≤ ∑ i ∈ p.support, (p.coeff i).natAbs * coeffNorm1 q := by + refine sum_le_sum fun i _ => ?_ + exact (coeffNorm1_C_mul_le (p.coeff i) _).trans + (Nat.mul_le_mul_left _ (coeffNorm1_mul_X_pow_le q i)) + _ = coeffNorm1 p * coeffNorm1 q := by + rw [← sum_mul, ← coeffNorm1] + +/-- `coeffNorm1 (p ^ k) ≤ coeffNorm1 p ^ k`. -/ +theorem coeffNorm1_pow_le (p : ℤ[X]) (k : ℕ) : + coeffNorm1 (p ^ k) ≤ coeffNorm1 p ^ k := by + induction k with + | zero => + simp only [pow_zero, coeffNorm1_one, le_refl] + | succ k ih => + rw [pow_succ, pow_succ] + exact (coeffNorm1_mul_le _ _).trans (Nat.mul_le_mul_right _ ih) + +/-- `coeffNorm1` of a finite product is at most the product of the `coeffNorm1`s. -/ +theorem coeffNorm1_prod_le {ι : Type*} (s : Finset ι) (f : ι → ℤ[X]) : + coeffNorm1 (∏ a ∈ s, f a) ≤ ∏ a ∈ s, coeffNorm1 (f a) := by + classical + induction s using Finset.induction_on with + | empty => + simp only [prod_empty, coeffNorm1_one, le_refl] + | insert a s ha ih => + rw [prod_insert ha, prod_insert ha] + exact (coeffNorm1_mul_le _ _).trans (Nat.mul_le_mul_left _ ih) + +/-- Casting `coeffNorm1 p` to `ℤ` gives the sum of integer absolute values `|p.coeff i|`. -/ +theorem natCast_coeffNorm1 (p : ℤ[X]) : + (coeffNorm1 p : ℤ) = ∑ i ∈ p.support, |p.coeff i| := by + unfold coeffNorm1 + rw [Nat.cast_sum] + refine sum_congr rfl fun i _ => Int.natCast_natAbs (p.coeff i) + +/-- Integer-cast constant norm `(coeffNorm1 (C a) : ℤ) = |a|`. -/ +theorem natCast_coeffNorm1_C (a : ℤ) : (coeffNorm1 (C a) : ℤ) = |a| := by + rw [coeffNorm1_C, Int.natCast_natAbs] + +/-- Integer-cast triangle inequality for `coeffNorm1`. -/ +theorem natCast_coeffNorm1_add_le (p q : ℤ[X]) : + (coeffNorm1 (p + q) : ℤ) ≤ (coeffNorm1 p : ℤ) + (coeffNorm1 q : ℤ) := by + exact_mod_cast coeffNorm1_add_le p q + +/-- Integer-cast finite-sum triangle inequality for `coeffNorm1`. -/ +theorem natCast_coeffNorm1_sum_le {ι : Type*} (s : Finset ι) (f : ι → ℤ[X]) : + (coeffNorm1 (∑ i ∈ s, f i) : ℤ) ≤ ∑ i ∈ s, (coeffNorm1 (f i) : ℤ) := by + rw [← Nat.cast_sum] + exact_mod_cast coeffNorm1_sum_le s f + +/-- Integer-cast scalar multiplication bound for `coeffNorm1`. -/ +theorem natCast_coeffNorm1_C_mul_le (a : ℤ) (p : ℤ[X]) : + (coeffNorm1 (C a * p) : ℤ) ≤ |a| * (coeffNorm1 p : ℤ) := by + rw [← Int.natCast_natAbs, ← Nat.cast_mul] + exact_mod_cast coeffNorm1_C_mul_le a p + +end Polynomial diff --git a/Complexity/Foundations/Data/Polynomial/ParityAmplifier.lean b/Complexity/Foundations/Data/Polynomial/ParityAmplifier.lean index 94f67a10e2..4a7b1cbb5c 100644 --- a/Complexity/Foundations/Data/Polynomial/ParityAmplifier.lean +++ b/Complexity/Foundations/Data/Polynomial/ParityAmplifier.lean @@ -8,6 +8,7 @@ module -- upstream: candidate public import Complexity.Init +public import Complexity.Foundations.Data.Polynomial.CoeffNorm1 public import Mathlib.Algebra.MvPolynomial.Degrees public import Mathlib.Algebra.Polynomial.AlgebraMap public import Mathlib.Algebra.Polynomial.BigOperators @@ -457,122 +458,6 @@ theorem evalInt_parityAmplifier_eq_sum {A : Type*} [CommRing A] (ℓ : ℕ) (y : /-! ### 3. Coefficient and `ℓ₁`-norm bounds (Lemma B.1) -/ -/-- The `ℓ₁` coefficient norm `∑ i ∈ p.support, (p.coeff i).natAbs` of an integer polynomial. -/ -def coeffNorm1 (p : ℤ[X]) : ℕ := - ∑ i ∈ p.support, (p.coeff i).natAbs - -/-- The `ℓ₁` norm of `0` is `0`. -/ -@[simp] -theorem coeffNorm1_zero : coeffNorm1 0 = 0 := by - simp only [coeffNorm1, support_zero, sum_empty] - -/-- Every individual coefficient of `p` has absolute value at most `coeffNorm1 p`. -/ -theorem natAbs_coeff_le_coeffNorm1 (p : ℤ[X]) (k : ℕ) : - (p.coeff k).natAbs ≤ coeffNorm1 p := by - by_cases hk : k ∈ p.support - · exact single_le_sum (f := fun i => (p.coeff i).natAbs) (fun _ _ => Nat.zero_le _) hk - · rw [notMem_support_iff.mp hk, Int.natAbs_zero] - exact Nat.zero_le _ - -/-- The sum of `|p.coeff i|` over any finite set of indices is at most `coeffNorm1 p`. -/ -theorem sum_natAbs_coeff_le_coeffNorm1 (p : ℤ[X]) (s : Finset ℕ) : - ∑ i ∈ s, (p.coeff i).natAbs ≤ coeffNorm1 p := by - have hsub : ∑ i ∈ s, (p.coeff i).natAbs = ∑ i ∈ s ∩ p.support, (p.coeff i).natAbs := by - refine (sum_subset inter_subset_left ?_).symm - intro i hi his - rw [mem_inter, not_and_or, notMem_support_iff] at his - rcases his with hns | hp0 - · exact absurd hi hns - · simp only [hp0, Int.natAbs_zero] - rw [hsub, coeffNorm1] - exact sum_le_sum_of_subset inter_subset_right - -/-- Triangle inequality for `coeffNorm1`. -/ -theorem coeffNorm1_add_le (p q : ℤ[X]) : - coeffNorm1 (p + q) ≤ coeffNorm1 p + coeffNorm1 q := by - have hsub : (p + q).support ⊆ p.support ∪ q.support := support_add - calc - coeffNorm1 (p + q) - ≤ ∑ i ∈ p.support ∪ q.support, ((p + q).coeff i).natAbs := - sum_le_sum_of_subset hsub - _ ≤ ∑ i ∈ p.support ∪ q.support, ((p.coeff i).natAbs + (q.coeff i).natAbs) := by - refine sum_le_sum fun i _ => ?_ - rw [coeff_add] - exact Int.natAbs_add_le _ _ - _ = (∑ i ∈ p.support ∪ q.support, (p.coeff i).natAbs) + - ∑ i ∈ p.support ∪ q.support, (q.coeff i).natAbs := sum_add_distrib - _ ≤ coeffNorm1 p + coeffNorm1 q := - add_le_add (sum_natAbs_coeff_le_coeffNorm1 p _) (sum_natAbs_coeff_le_coeffNorm1 q _) - -/-- Multiplying by `X ^ k` does not increase `coeffNorm1`. -/ -theorem coeffNorm1_mul_X_pow_le (p : ℤ[X]) (k : ℕ) : - coeffNorm1 (p * X ^ k) ≤ coeffNorm1 p := by - rw [coeffNorm1] - have hsub : (p * X ^ k).support ⊆ p.support.map ⟨fun i => i + k, add_left_injective k⟩ := by - intro i hi - rw [mem_support_iff] at hi - rw [mem_map] - by_cases hik : k ≤ i - · refine ⟨i - k, ?_, by simp only [Function.Embedding.coeFn_mk]; omega⟩ - rw [mem_support_iff] - intro h0 - apply hi - have hi_eq : i = i - k + k := (Nat.sub_add_cancel hik).symm - rw [hi_eq, coeff_mul_X_pow, h0] - · exfalso - apply hi - rw [mul_comm, coeff_X_pow_mul'] - simp only [hik, ↓reduceIte] - refine (sum_le_sum_of_subset hsub).trans ?_ - rw [sum_map] - refine le_of_eq (sum_congr rfl fun i _ => ?_) - simp only [Function.Embedding.coeFn_mk, coeff_mul_X_pow] - -/-- The `ℓ₁` norm of a constant polynomial `C a` is `a.natAbs`. -/ -theorem coeffNorm1_C (a : ℤ) : coeffNorm1 (C a) = a.natAbs := by - by_cases ha : a = 0 - · subst ha - simp only [map_zero, coeffNorm1_zero, Int.natAbs_zero] - · rw [coeffNorm1, support_C ha, sum_singleton, coeff_C_zero] - -/-- Scaling by `C a` scales `coeffNorm1` by at most `a.natAbs`. -/ -theorem coeffNorm1_C_mul_le (a : ℤ) (p : ℤ[X]) : - coeffNorm1 (C a * p) ≤ a.natAbs * coeffNorm1 p := by - have hsub : (C a * p).support ⊆ p.support := by - intro i hi - rw [mem_support_iff, coeff_C_mul] at hi - exact mem_support_iff.mpr (right_ne_zero_of_mul hi) - calc - coeffNorm1 (C a * p) ≤ ∑ i ∈ p.support, ((C a * p).coeff i).natAbs := - sum_le_sum_of_subset hsub - _ = a.natAbs * coeffNorm1 p := by - rw [coeffNorm1, mul_sum] - refine sum_congr rfl fun i _ => ?_ - rw [coeff_C_mul, Int.natAbs_mul] - -/-- Multiplying by `1 - X` increases `coeffNorm1` by at most a factor of `2`. -/ -theorem coeffNorm1_one_sub_X_mul_le (p : ℤ[X]) : - coeffNorm1 ((1 - X) * p) ≤ 2 * coeffNorm1 p := by - have hEq : (1 - X) * p = p + C (-1) * (p * X ^ 1) := by - rw [map_neg, map_one] - ring - rw [hEq, two_mul] - refine (coeffNorm1_add_le _ _).trans (add_le_add le_rfl ?_) - have h1 := coeffNorm1_C_mul_le (-1) (p * X ^ 1) - have h2 := coeffNorm1_mul_X_pow_le p 1 - simp only [Int.natAbs_neg, Int.natAbs_one, one_mul] at h1 - exact h1.trans h2 - -/-- Multiplying by `(1 - X) ^ ℓ` increases `coeffNorm1` by at most a factor of `2 ^ ℓ`. -/ -theorem coeffNorm1_one_sub_X_pow_mul_le (ℓ : ℕ) (p : ℤ[X]) : - coeffNorm1 ((1 - X) ^ ℓ * p) ≤ 2 ^ ℓ * coeffNorm1 p := by - induction ℓ with - | zero => simp only [pow_zero, one_mul, le_refl] - | succ ℓ ih => - have hEq : (1 - X) ^ (ℓ + 1) * p = (1 - X) * ((1 - X) ^ ℓ * p) := by ring - rw [hEq, pow_succ', mul_assoc] - exact (coeffNorm1_one_sub_X_mul_le _).trans (Nat.mul_le_mul_left 2 ih) - private theorem sum_range_choose_add (m k : ℕ) : ∑ j ∈ range (k + 1), Nat.choose (m + j) j = Nat.choose (m + k + 1) k := by induction k with diff --git a/ComplexityTests/Foundations/Data/Polynomial/CoeffNorm1.lean b/ComplexityTests/Foundations/Data/Polynomial/CoeffNorm1.lean new file mode 100644 index 0000000000..62c3407e93 --- /dev/null +++ b/ComplexityTests/Foundations/Data/Polynomial/CoeffNorm1.lean @@ -0,0 +1,38 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Foundations.Data.Polynomial.CoeffNorm1 + +/-! +# Tests for `Polynomial.coeffNorm1` + +Smoke tests for the `ℓ₁` coefficient norm `Polynomial.coeffNorm1` on `ℤ[X]`. +-/ + +@[expose] public section + +namespace Polynomial.CoeffNorm1Tests + +example : coeffNorm1 0 = 0 ∧ coeffNorm1 1 = 1 ∧ coeffNorm1 (C (-5)) = 5 := by + refine ⟨coeffNorm1_zero, coeffNorm1_one, ?_⟩ + rw [coeffNorm1_C] + rfl + +example (p q : ℤ[X]) : + coeffNorm1 (p - q) ≤ coeffNorm1 p + coeffNorm1 q ∧ + coeffNorm1 (p * q) ≤ coeffNorm1 p * coeffNorm1 q ∧ + coeffNorm1 (p ^ 3) ≤ coeffNorm1 p ^ 3 ∧ + coeffNorm1 ((1 - X) ^ 3 * p) ≤ 8 * coeffNorm1 p ∧ + (coeffNorm1 (C (-3) * p) : ℤ) ≤ 3 * (coeffNorm1 p : ℤ) := by + refine ⟨coeffNorm1_sub_le p q, coeffNorm1_mul_le p q, coeffNorm1_pow_le p 3, + coeffNorm1_one_sub_X_pow_mul_le 3 p, ?_⟩ + simpa using natCast_coeffNorm1_C_mul_le (-3) p + +end Polynomial.CoeffNorm1Tests From 56ff42b264a5e3ed66ba704a131c74040664a044 Mon Sep 17 00:00:00 2001 From: Samuel Schlesinger Date: Tue, 27 Oct 2026 01:49:08 +0000 Subject: [PATCH 08/20] =?UTF-8?q?refactor(Polynomial,BooleanAnalysis):=20e?= =?UTF-8?q?xtract=20ParityAmplifierDegree=20and=20refine=20=C2=A75.5=20thr?= =?UTF-8?q?esholds=20(#1226)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Complexity.lean | 1 + .../BooleanAnalysis/SparseBranching.lean | 290 ++++-------------- .../Polynomial/ParityAmplifierDegree.lean | 221 +++++++++++++ .../Polynomial/ParityAmplifierDegree.lean | 32 ++ ComplexityTests/SparseBranching.lean | 13 +- 5 files changed, 325 insertions(+), 232 deletions(-) create mode 100644 Complexity/Foundations/Data/Polynomial/ParityAmplifierDegree.lean create mode 100644 ComplexityTests/Foundations/Data/Polynomial/ParityAmplifierDegree.lean diff --git a/Complexity.lean b/Complexity.lean index 6f9b721db3..e1a068b787 100644 --- a/Complexity.lean +++ b/Complexity.lean @@ -1980,6 +1980,7 @@ public import Complexity.Foundations.Data.Polynomial.CoeffList public import Complexity.Foundations.Data.Polynomial.CoeffNorm1 public import Complexity.Foundations.Data.Polynomial.HermiteInterpolation public import Complexity.Foundations.Data.Polynomial.ParityAmplifier +public import Complexity.Foundations.Data.Polynomial.ParityAmplifierDegree public import Complexity.Foundations.Data.Polynomial.SignQueries public import Complexity.Foundations.Data.Rat.Basic public import Complexity.Foundations.Data.Seq.Computation diff --git a/Complexity/Foundations/BooleanAnalysis/SparseBranching.lean b/Complexity/Foundations/BooleanAnalysis/SparseBranching.lean index 6f3b262a4f..85fcaee652 100644 --- a/Complexity/Foundations/BooleanAnalysis/SparseBranching.lean +++ b/Complexity/Foundations/BooleanAnalysis/SparseBranching.lean @@ -9,15 +9,17 @@ module public import Complexity.Init public import Complexity.Foundations.BooleanAnalysis.SparseEquations +public import Complexity.Foundations.Data.Polynomial.ParityAmplifierDegree import Mathlib.Data.Finset.Sum import Mathlib.Data.Fintype.Pi /-! # Univariate parity-product specialization and heavy-variable branch reduction -This module completes the algebraic and combinatorial infrastructure of Sections 5.3, 5.5, and 5.6 -of [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (pp. 37–39), building on -`Complexity.Foundations.BooleanAnalysis.SparseEquations`: +This module completes the algebraic and combinatorial infrastructure of Sections 5.3 and 5.5 +(Proof of Theorem 2.2) of [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] +(pp. 37–39), building on `Complexity.Foundations.BooleanAnalysis.SparseEquations` and +`Complexity.Foundations.Data.Polynomial.ParityAmplifierDegree`: 1. **Univariate $H(T)$ and coordinatewise $H_s(T) = [V^s] H(T)$ specialization (§5.3, eq. 5.5)**: When each variable $v \in \iota$ in equation $i \in I$ is replaced by a univariate polynomial @@ -29,29 +31,36 @@ of [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (pp. 37 `Cslib.BitString.univariateParityCoord` ($s < \ell$) and truncated sum `Cslib.BitString.univariateParityTruncatedSum` have `natDegree` at most `(k * R_deg) * (#I + 2 * (ℓ - 1))` (`Cslib.BitString.natDegree_univariateParityCoord_le`, - `Cslib.BitString.natDegree_univariateParityTruncatedSum_le`) and recover `commonZeroCount I P` - modulo $2^\ell$ at $T = 0$ - (`Cslib.BitString.eval_zero_univariateParityTruncatedSum_modEq_commonZeroCount`, - `Cslib.BitString.emod_eval_zero_univariateParityTruncatedSum_eq_commonZeroCount`). -2. **Free-variable branch relabeling (§5.5–5.6, Proof of Theorem 2.2)**: + `Cslib.BitString.natDegree_univariateParityTruncatedSum_le`). For integer-coefficient + replacements `q : (ι → Bool) → κ → ι → ℤ[X]`, evaluating at $T = 0$ is congruent to + `commonZeroCount I P` modulo $2^\ell$ when `1 ≤ ℓ` + (`Cslib.BitString.eval_zero_univariateParityTruncatedSum_modEq_commonZeroCount`) and recovers + `commonZeroCount I P` via `(· % 2 ^ ℓ)` when `Fintype.card ι < ℓ` + (`Cslib.BitString.emod_eval_zero_univariateParityTruncatedSum_eq_commonZeroCount`). Note that + generic-ring degree and evaluation transport over `R[X]` does not by itself close modular + recovery for rational replacement rows `ℚ[X]`; bridging rational replacement rows with nonzero + cleared denominators to integer modular recovery is a separate follow-up milestone (as in #1248). +2. **Free-variable branch relabeling (§5.5, Proof of Theorem 2.2)**: After branching on a subset $S \subseteq \iota$ of heavy variables, every restricted equation `restrictMonomials S b (P i)` is supported on `univ \ S`. Transporting along an equivalence `e : ↥(univ \ S) ≃ ι'` (such as `Fin n'` with $n' = n - |S|$) via `Cslib.BitString.relabelRestrictedMonomials` preserves degree bounds `#M ≤ k`, never increases monomial counts, bounds every free variable's equation incidence by `b₀` when $S$ is the - heavy-variable set (`Cslib.BitString.varIncidence_relabelRestrictedMonomials_heavyVars_le`), and - decomposes `commonZeroCount I P` additively as the sum of `commonZeroCount` on the relabeled - free-variable cube `ι' → Bool` - (`Cslib.BitString.commonZeroCount_eq_sum_relabelRestrictedMonomials`). -3. **Neutral variable-coverage scopes and Theorem 2.2 threshold bounds (§5.5–5.6)**: + heavy-variable set and `∀ i ∈ I, equationScope (P i) ⊆ V` + (`Cslib.BitString.varIncidence_relabelRestrictedMonomials_heavyVars_le`), and decomposes + `commonZeroCount I P` additively as the sum of `commonZeroCount` on the relabeled free-variable + cube `ι' → Bool` (`Cslib.BitString.commonZeroCount_eq_sum_relabelRestrictedMonomials`). +3. **Neutral variable-coverage scopes and Theorem 2.2 threshold bounds (§5.5)**: Adjoining a singleton neutral scope `{v}` for each declared variable $v \in \iota'$ via `Cslib.BitString.withNeutralFactors` and `Cslib.BitString.withNeutralScope` increments each variable's incidence by `1`, ensuring positive variable incidence (`1 ≤ varIncidence`), total incidence $M' \ge n'$ (`Cslib.BitString.card_le_totalIncidence_withNeutralFactors`), and - light-variable incidence at most $b_0 + 1$. Finally, when $M \cdot s \le b_0 \cdot n$ (as for - $b_0 = \lceil M s / n \rceil$ with $s = \lceil \sqrt{\lambda} \rceil$), the heavy-variable set - has size at most $n / s$, at most $2^{n / s}$ branches, and leaves $n' \ge n - n / s \ge n / 2$ - free variables when $s \ge 2$. + light-variable incidence at most $b_0 + 1$. Finally, when `1 ≤ b₀`, `1 ≤ s`, + `∀ i ∈ F, scope i ⊆ V`, and `totalIncidence F scope * s ≤ b₀ * #V` (which holds both for the + manuscript's threshold `paperHeavyThreshold M n s = ⌈M / n⌉ * s` and for the combined-ceiling + variant `heavyThreshold M n s = ⌈M * s / n⌉` when `1 ≤ n`), the heavy-variable set has size at + most `#V / s`, at most `2 ^ (Fintype.card ι / s)` branches, and leaves + `#(V \ heavyVars V F scope b₀) ≥ #V - #V / s ≥ #V / 2` free variables when `2 ≤ s`. ## Main definitions @@ -64,8 +73,9 @@ of [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (pp. 37 monomial families and restricted branch equations onto a free-variable index type `ι'`. * `Cslib.BitString.withNeutralFactors`, `Cslib.BitString.withNeutralScope`: adjoining neutral singleton scopes `{v}` for every variable $v \in \iota'$. -* `Cslib.BitString.heavyThreshold`: integer ceiling $\lceil M s / n \rceil$ for the heavy-variable - incidence threshold $b_0$. +* `Cslib.BitString.paperHeavyThreshold`, `Cslib.BitString.heavyThreshold`: the manuscript's + heavy-variable threshold $\lceil M / n \rceil s$ and the combined-ceiling variant + $\lceil M s / n \rceil$. * `Cslib.BitString.branchPrecision`: the shared modular precision $\ell = n + 1$ used across the unrestricted system and all free-variable branches. @@ -76,16 +86,18 @@ of [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (pp. 37 $\deg_T \le (k R_{\mathrm{deg}})(m_{\mathrm{test}} + 2(\ell - 1))$. * `Cslib.BitString.eval_zero_univariateParityTruncatedSum_modEq_commonZeroCount` and `Cslib.BitString.emod_eval_zero_univariateParityTruncatedSum_eq_commonZeroCount`: equation (5.5) - congruence and exact recovery of `commonZeroCount` at $T = 0$. + congruence (for `1 ≤ ℓ`) and exact recovery (for `Fintype.card ι < ℓ`) of `commonZeroCount` at + $T = 0$ under integer-coefficient replacements. * `Cslib.BitString.commonZeroCount_eq_sum_relabelRestrictedMonomials`: additive branch decomposition of `commonZeroCount` into `commonZeroCount` over the relabeled free-variable cube `ι' → Bool`. * `Cslib.BitString.varIncidence_relabelRestrictedMonomials_heavyVars_le`: post-branching free-variable incidence bound $\le b_0$ on `ι'`. * `Cslib.BitString.card_le_totalIncidence_withNeutralFactors`: neutral scopes guarantee $M' \ge n'$. * `Cslib.BitString.card_heavyVars_le_card_div` and - `Cslib.BitString.card_sdiff_heavyVars_ge_half`: $|S| \le n / s$ and $n' \ge n / 2$ for $s \ge 2$. + `Cslib.BitString.card_sdiff_heavyVars_ge_half`: $|S| \le n / s$ and $n' \ge n / 2$ for $s \ge 2$, + $b_0 \ge 1$, and scope coverage. * `Cslib.BitString.commonZeroCount_eq_sum_branch_emod_eval_zero` and - `Cslib.BitString.natDegree_univariateParityTruncatedSum_branch_le`: §5.6 shared-precision + `Cslib.BitString.natDegree_univariateParityTruncatedSum_branch_le`: §5.5 shared-precision $\ell = n + 1$ branch recovery and linear degree bound $\deg_T \le (k R_{\mathrm{deg}})((2 c + 4) n')$ when $m_{\mathrm{test}} \le c n$ and $n \le 2 n'$. @@ -93,7 +105,7 @@ of [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (pp. 37 ## References * [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] - (Sections 5.3, 5.5, and 5.6) + (Sections 5.3 and 5.5) -/ @[expose] public noncomputable section @@ -139,18 +151,11 @@ theorem eval_univariateMonomialPoly [CommSemiring R] (q : ι → Polynomial R) ( (univariateMonomialPoly R q M).eval t = ∏ v ∈ M, (q v).eval t := by rw [univariateMonomialPoly, Polynomial.eval_prod] -private theorem eval_sum {α : Type*} [CommSemiring R] (S : Finset α) (f : α → Polynomial R) - (t : R) : - (∑ x ∈ S, f x).eval t = ∑ x ∈ S, (f x).eval t := by - change Polynomial.evalRingHom t (∑ x ∈ S, f x) = _ - rw [map_sum] - rfl - /-- Pointwise evaluation of `univariateMonomialSumPoly R q 𝓜` at `t : R`. -/ theorem eval_univariateMonomialSumPoly [CommSemiring R] (q : ι → Polynomial R) (𝓜 : Finset (Finset ι)) (t : R) : (univariateMonomialSumPoly R q 𝓜).eval t = ∑ M ∈ 𝓜, ∏ v ∈ M, (q v).eval t := by - rw [univariateMonomialSumPoly, eval_sum] + rw [univariateMonomialSumPoly, Polynomial.eval_finsetSum] exact sum_congr rfl fun M _ => eval_univariateMonomialPoly q M t /-- **Restoration at `T = 0`**: if every `q v` (`v ∈ M`) evaluates at `0` to `bitVal R (x v)`, then @@ -188,188 +193,7 @@ theorem natDegree_univariateMonomialSumPoly_le [CommSemiring R] {q : ι → Poly end UnivariateReplacement -/-! ### Section 2: Ring-homomorphism transport and `natDegree` bounds for `parityFactor` -/ - -section UnivariateParityFactor - -/-- Any ring homomorphism `φ : A →+* B` commutes with `Polynomial.evalInt`. -/ -theorem map_evalInt {A B : Type*} [CommRing A] [CommRing B] (φ : A →+* B) (y : A) - (p : Polynomial ℤ) : - φ (Polynomial.evalInt y p) = Polynomial.evalInt (φ y) p := by - induction p using Polynomial.induction_on' with - | add p q ihp ihq => - rw [Polynomial.evalInt, Polynomial.eval₂_add, map_add, ← Polynomial.evalInt, - ← Polynomial.evalInt, ihp, ihq, Polynomial.evalInt, Polynomial.evalInt, - ← Polynomial.eval₂_add] - rfl - | monomial n a => - rw [Polynomial.evalInt, Polynomial.evalInt, Polynomial.eval₂_monomial, - Polynomial.eval₂_monomial, map_mul, map_pow] - congr 1 - rw [eq_intCast, eq_intCast, map_intCast] - -/-- Mapping `parityFactor ℓ y` coefficientwise by `φ : A →+* B` yields `parityFactor ℓ (φ y)`. -/ -theorem map_parityFactor {A B : Type*} [CommRing A] [CommRing B] (φ : A →+* B) (ℓ : ℕ) (y : A) : - (Polynomial.parityFactor ℓ y).map φ = Polynomial.parityFactor ℓ (φ y) := by - ext s - rw [Polynomial.coeff_map, Polynomial.coeff_parityFactor, Polynomial.coeff_parityFactor] - split_ifs with hs - · rw [map_mul, map_pow, map_evalInt, map_evalInt] - · exact map_zero φ - -/-- Any ring homomorphism `φ : A →+* B` commutes with `sumCoeffsBelow`. -/ -theorem map_sumCoeffsBelow {A B : Type*} [Semiring A] [Semiring B] (φ : A →+* B) - (P : Polynomial A) (m : ℕ) : - φ (P.sumCoeffsBelow m) = (P.map φ).sumCoeffsBelow m := by - rw [Polynomial.sumCoeffsBelow, Polynomial.sumCoeffsBelow, map_sum] - refine sum_congr rfl fun j _ => ?_ - rw [Polynomial.coeff_map] - -/-- Evaluating the `s`-th coefficient of `∏ i ∈ I, parityFactor ℓ (L i)` at `t : R` agrees with -the `s`-th coefficient of `∏ i ∈ I, parityFactor ℓ ((L i).eval t)`. -/ -theorem eval_coeff_prod_parityFactor [CommRing R] (I : Finset κ) (ℓ : ℕ) - (L : κ → Polynomial R) (s : ℕ) (t : R) : - ((∏ i ∈ I, Polynomial.parityFactor ℓ (L i)).coeff s).eval t = - (∏ i ∈ I, Polynomial.parityFactor ℓ ((L i).eval t)).coeff s := by - let φ : Polynomial R →+* R := Polynomial.evalRingHom t - change φ ((∏ i ∈ I, Polynomial.parityFactor ℓ (L i)).coeff s) = _ - rw [← Polynomial.coeff_map, Polynomial.map_prod] - refine congrArg (fun Q : Polynomial R => Q.coeff s) (prod_congr rfl fun i _ => ?_) - exact map_parityFactor φ ℓ (L i) - -/-- Evaluating `sumCoeffsBelow m` of `∏ i ∈ I, parityFactor ℓ (L i)` at `t : R` agrees with -`sumCoeffsBelow m` of `∏ i ∈ I, parityFactor ℓ ((L i).eval t)`. -/ -theorem eval_sumCoeffsBelow_prod_parityFactor [CommRing R] (I : Finset κ) (ℓ : ℕ) - (L : κ → Polynomial R) (m : ℕ) (t : R) : - ((∏ i ∈ I, Polynomial.parityFactor ℓ (L i)).sumCoeffsBelow m).eval t = - (∏ i ∈ I, Polynomial.parityFactor ℓ ((L i).eval t)).sumCoeffsBelow m := by - rw [Polynomial.sumCoeffsBelow, eval_sum, Polynomial.sumCoeffsBelow] - exact sum_congr rfl fun s _ => eval_coeff_prod_parityFactor I ℓ L s t - -/-- For `y : Polynomial R` and `p : Polynomial ℤ`, -`(evalInt y p).natDegree ≤ p.natDegree * y.natDegree`. -/ -theorem natDegree_evalInt_le [CommRing R] (y : Polynomial R) (p : Polynomial ℤ) : - (Polynomial.evalInt y p).natDegree ≤ p.natDegree * y.natDegree := by - rw [Polynomial.evalInt, Polynomial.eval₂_eq_sum_range] - refine (Polynomial.natDegree_sum_le _ _).trans ?_ - rw [Finset.fold_max_le] - refine ⟨Nat.zero_le _, fun i hi => ?_⟩ - rw [mem_range, Nat.lt_succ_iff] at hi - dsimp only [Function.comp_apply] - have hcast : (Int.castRingHom (Polynomial R) (p.coeff i)) = Polynomial.C (p.coeff i : R) := by - rw [eq_intCast, ← Polynomial.C_eq_intCast] - rw [hcast] - calc - (Polynomial.C (p.coeff i : R) * y ^ i).natDegree - ≤ (Polynomial.C (p.coeff i : R)).natDegree + (y ^ i).natDegree := - Polynomial.natDegree_mul_le - _ ≤ 0 + i * y.natDegree := by - rw [Polynomial.natDegree_C] - exact add_le_add le_rfl Polynomial.natDegree_pow_le - _ ≤ p.natDegree * y.natDegree := by - rw [zero_add] - exact Nat.mul_le_mul_right _ hi - -/-- `evalInt y (parityBaseDigit ℓ j)` has `natDegree ≤ y.natDegree`. -/ -theorem natDegree_evalInt_parityBaseDigit_le [CommRing R] (ℓ j : ℕ) (y : Polynomial R) : - (Polynomial.evalInt y (Polynomial.parityBaseDigit ℓ j)).natDegree ≤ y.natDegree := by - calc - (Polynomial.evalInt y (Polynomial.parityBaseDigit ℓ j)).natDegree - ≤ (Polynomial.parityBaseDigit ℓ j).natDegree * y.natDegree := - natDegree_evalInt_le y _ - _ ≤ 1 * y.natDegree := - Nat.mul_le_mul_right _ (Polynomial.natDegree_parityBaseDigit_le ℓ j) - _ = y.natDegree := one_mul _ - -/-- `evalInt y hPoly` has `natDegree ≤ 2 * y.natDegree`. -/ -theorem natDegree_evalInt_hPoly_le [CommRing R] (y : Polynomial R) : - (Polynomial.evalInt y Polynomial.hPoly).natDegree ≤ 2 * y.natDegree := by - rw [Polynomial.evalInt_hPoly] - calc - (y ^ 2 - y).natDegree - ≤ max (y ^ 2).natDegree y.natDegree := Polynomial.natDegree_sub_le _ _ - _ ≤ max (2 * y.natDegree) y.natDegree := - max_le_max Polynomial.natDegree_pow_le le_rfl - _ = 2 * y.natDegree := max_eq_left (by omega) - -/-- The `j`-th coefficient of `parityFactor ℓ y` has `natDegree ≤ (1 + 2 * j) * y.natDegree`. -/ -theorem natDegree_coeff_parityFactor_le [CommRing R] (ℓ : ℕ) (y : Polynomial R) (j : ℕ) : - ((Polynomial.parityFactor ℓ y).coeff j).natDegree ≤ (1 + 2 * j) * y.natDegree := by - rw [Polynomial.coeff_parityFactor] - split_ifs with hj - · calc - (Polynomial.evalInt y (Polynomial.parityBaseDigit ℓ j) * - Polynomial.evalInt y Polynomial.hPoly ^ j).natDegree - ≤ (Polynomial.evalInt y (Polynomial.parityBaseDigit ℓ j)).natDegree + - (Polynomial.evalInt y Polynomial.hPoly ^ j).natDegree := - Polynomial.natDegree_mul_le - _ ≤ y.natDegree + j * (Polynomial.evalInt y Polynomial.hPoly).natDegree := - add_le_add (natDegree_evalInt_parityBaseDigit_le ℓ j y) Polynomial.natDegree_pow_le - _ ≤ y.natDegree + j * (2 * y.natDegree) := - add_le_add le_rfl (Nat.mul_le_mul_left j (natDegree_evalInt_hPoly_le y)) - _ = (1 + 2 * j) * y.natDegree := by ring - · simp only [Polynomial.natDegree_zero, zero_le] - -/-- If every `L i` (`i ∈ I`) has `natDegree ≤ d`, then the `V ^ s`-coefficient of -`∏ i ∈ I, parityFactor ℓ (L i)` has `natDegree ≤ d * (#I + 2 * s)`. -/ -theorem natDegree_coeff_prod_parityFactor_le [CommRing R] (I : Finset κ) (ℓ : ℕ) - (L : κ → Polynomial R) {d : ℕ} (hL : ∀ i ∈ I, (L i).natDegree ≤ d) : - ∀ s : ℕ, ((∏ i ∈ I, Polynomial.parityFactor ℓ (L i)).coeff s).natDegree ≤ d * (#I + 2 * s) := by - classical - induction I using Finset.induction_on with - | empty => - intro s - simp only [prod_empty, card_empty, zero_add] - rcases eq_or_ne s 0 with rfl | hs - · simp only [Polynomial.coeff_one_zero, Polynomial.natDegree_one, zero_le] - · rw [Polynomial.coeff_one, ite_eq_right hs, Polynomial.natDegree_zero] - exact Nat.zero_le _ - | insert a I ha ih => - intro s - rw [prod_insert ha, card_insert_of_notMem ha, Polynomial.coeff_mul] - have haL : (L a).natDegree ≤ d := hL a (mem_insert_self a I) - have hIL : ∀ i ∈ I, (L i).natDegree ≤ d := fun i hi => hL i (mem_insert_of_mem hi) - refine (Polynomial.natDegree_sum_le _ _).trans ?_ - rw [Finset.fold_max_le] - refine ⟨Nat.zero_le _, fun p hp => ?_⟩ - rw [mem_antidiagonal] at hp - calc - (((Polynomial.parityFactor ℓ (L a)).coeff p.1) * - ((∏ i ∈ I, Polynomial.parityFactor ℓ (L i)).coeff p.2)).natDegree - ≤ ((Polynomial.parityFactor ℓ (L a)).coeff p.1).natDegree + - ((∏ i ∈ I, Polynomial.parityFactor ℓ (L i)).coeff p.2).natDegree := - Polynomial.natDegree_mul_le - _ ≤ (1 + 2 * p.1) * (L a).natDegree + d * (#I + 2 * p.2) := - add_le_add (natDegree_coeff_parityFactor_le ℓ (L a) p.1) (ih hIL p.2) - _ ≤ (1 + 2 * p.1) * d + d * (#I + 2 * p.2) := - add_le_add (Nat.mul_le_mul_left _ haL) le_rfl - _ = d * (#I + 1 + 2 * (p.1 + p.2)) := by ring - _ = d * (#I + 1 + 2 * s) := by rw [hp] - -/-- For `s < ℓ`, the `V ^ s`-coefficient of `∏ i ∈ I, parityFactor ℓ (L i)` has -`natDegree ≤ d * (#I + 2 * (ℓ - 1))`. -/ -theorem natDegree_coeff_prod_parityFactor_le_of_lt [CommRing R] (I : Finset κ) (ℓ : ℕ) - (L : κ → Polynomial R) {d : ℕ} (hL : ∀ i ∈ I, (L i).natDegree ≤ d) {s : ℕ} (hs : s < ℓ) : - ((∏ i ∈ I, Polynomial.parityFactor ℓ (L i)).coeff s).natDegree ≤ - d * (#I + 2 * (ℓ - 1)) := by - refine (natDegree_coeff_prod_parityFactor_le I ℓ L hL s).trans ?_ - exact Nat.mul_le_mul_left d (by omega) - -/-- The truncated sum `sumCoeffsBelow ℓ (∏ i ∈ I, parityFactor ℓ (L i))` has -`natDegree ≤ d * (#I + 2 * (ℓ - 1))`. -/ -theorem natDegree_sumCoeffsBelow_prod_parityFactor_le [CommRing R] (I : Finset κ) (ℓ : ℕ) - (L : κ → Polynomial R) {d : ℕ} (hL : ∀ i ∈ I, (L i).natDegree ≤ d) : - ((∏ i ∈ I, Polynomial.parityFactor ℓ (L i)).sumCoeffsBelow ℓ).natDegree ≤ - d * (#I + 2 * (ℓ - 1)) := by - rw [Polynomial.sumCoeffsBelow] - refine (Polynomial.natDegree_sum_le _ _).trans ?_ - rw [Finset.fold_max_le] - refine ⟨Nat.zero_le _, fun s hs => ?_⟩ - exact natDegree_coeff_prod_parityFactor_le_of_lt I ℓ L hL (mem_range.mp hs) - -end UnivariateParityFactor - -/-! ### Section 3: Cube-summed univariate polynomial $H(T)$ and equation (5.5) -/ +/-! ### Section 2: Cube-summed univariate polynomial $H(T)$ and equation (5.5) -/ section CubeSummedUnivariate @@ -443,7 +267,7 @@ theorem natDegree_univariateParityCoord_le [Fintype ι] [DecidableEq ι] [CommRi refine (Polynomial.natDegree_sum_le _ _).trans ?_ rw [Finset.fold_max_le] refine ⟨Nat.zero_le _, fun x _ => ?_⟩ - refine natDegree_coeff_prod_parityFactor_le_of_lt I ℓ + refine Polynomial.natDegree_coeff_prod_parityFactor_le_of_lt I ℓ (fun i => univariateMonomialSumPoly R (q x i) (P i)) (fun i hi => ?_) hs exact natDegree_univariateMonomialSumPoly_le (hk i hi) (hq x i hi) @@ -473,9 +297,9 @@ theorem eval_zero_univariateParityTruncatedSum [Fintype ι] [DecidableEq ι] [Co (univariateParityTruncatedSum I P ℓ q).eval 0 = ∑ x : ι → Bool, (∏ i ∈ I, Polynomial.parityFactor ℓ (monomialSum R (P i) x)).sumCoeffsBelow ℓ := by - rw [univariateParityTruncatedSum_eq_sum, eval_sum] + rw [univariateParityTruncatedSum_eq_sum, Polynomial.eval_finsetSum] refine sum_congr rfl fun x _ => ?_ - rw [eval_sumCoeffsBelow_prod_parityFactor] + rw [Polynomial.eval_sumCoeffsBelow_prod_parityFactor] congr 1 refine prod_congr rfl fun i hi => ?_ rw [eval_zero_univariateMonomialSumPoly (hq0 x i hi)] @@ -507,7 +331,7 @@ theorem emod_eval_zero_univariateParityTruncatedSum_eq_commonZeroCount [Fintype end CubeSummedUnivariate -/-! ### Section 4: Free-variable branch relabeling (§5.5–5.6, Proof of Theorem 2.2) -/ +/-! ### Section 3: Free-variable branch relabeling (§5.5, Proof of Theorem 2.2) -/ section BranchRelabeling @@ -735,7 +559,7 @@ theorem varIncidence_relabelRestrictedMonomials_heavyVars_le [Fintype ι] [Decid end BranchRelabeling -/-! ### Section 5: Neutral variable-coverage scopes and Theorem 2.2 threshold bounds (§5.5–5.6) -/ +/-! ### Section 4: Neutral variable-coverage scopes and Theorem 2.2 threshold bounds (§5.5) -/ section NeutralScopesAndThresholds @@ -798,8 +622,12 @@ theorem card_le_totalIncidence_withNeutralFactors [Fintype ι'] (I : Finset κ) rw [totalIncidence_withNeutralFactors] exact Nat.le_add_left _ _ -/-- **§5.5 (heavy-variable threshold $b_0 = \lceil M s / n \rceil$)**: integer ceiling of -`M * s / n`. -/ +/-- **§5.5 (manuscript heavy-variable threshold $b_0 = \lceil M / n \rceil s$, p. 38)**: the +product `((M + n - 1) / n) * s` of the integer ceiling `⌈M / n⌉` and `s`. -/ +def paperHeavyThreshold (M n s : ℕ) : ℕ := + ((M + n - 1) / n) * s + +/-- Combined-ceiling variant `⌈M * s / n⌉ = (M * s + n - 1) / n` of the heavy-variable threshold. -/ def heavyThreshold (M n s : ℕ) : ℕ := (M * s + n - 1) / n @@ -812,6 +640,16 @@ theorem mul_le_heavyThreshold_mul {M n s : ℕ} (hn : 1 ≤ n) : rw [Nat.mul_comm ((M * s + n - 1) / n) n] omega +/-- When `1 ≤ n`, `M * s ≤ paperHeavyThreshold M n s * n`. -/ +theorem mul_le_paperHeavyThreshold_mul {M n s : ℕ} (hn : 1 ≤ n) : + M * s ≤ paperHeavyThreshold M n s * n := by + unfold paperHeavyThreshold + have hceil : M ≤ ((M + n - 1) / n) * n := by + simpa only [heavyThreshold, mul_one] using (mul_le_heavyThreshold_mul (M := M) (s := 1) hn) + calc + M * s ≤ (((M + n - 1) / n) * n) * s := Nat.mul_le_mul_right s hceil + _ = (((M + n - 1) / n) * s) * n := by ring + /-- **§5.5 ($|S| \le n / s$)**: whenever `totalIncidence F scope * s ≤ b₀ * #V`, `1 ≤ b₀`, `1 ≤ s`, and `∀ i ∈ F, scope i ⊆ V`, the heavy-variable set `heavyVars V F scope b₀` has cardinality at most `#V / s`. -/ @@ -867,7 +705,7 @@ theorem card_sdiff_heavyVars_ge_half [DecidableEq ι] (V : Finset ι) (F : Finse have hge := card_sdiff_heavyVars_ge V F scope hb₀ (by omega) hV hM constructor <;> omega -/-- **§5.1 & §5.6 ($\ell = n + 1$)**: the shared modular precision `n + 1` used for both the +/-- **§5.1 & §5.5 ($\ell = n + 1$)**: the shared modular precision `n + 1` used for both the unrestricted system on `n` variables and every free-variable branch. -/ def branchPrecision (n : ℕ) : ℕ := n + 1 @@ -889,7 +727,7 @@ theorem commonZeroCount_lt_two_pow_branchPrecision [Fintype ι] [DecidableEq ι] lt_of_le_of_lt (commonZeroCount_le_two_pow I P) (two_pow_lt_two_pow_branchPrecision (Fintype.card ι)) -/-- **§5.6 (branch count $< 2^\ell$ at original precision $\ell = n + 1$)**: for any subset `S` +/-- **§5.5 (branch count $< 2^\ell$ at original precision $\ell = n + 1$)**: for any subset `S` and branch assignment `b : ι → Bool`, the relabeled branch common-zero count on `ι'` is strictly smaller than `2 ^ branchPrecision (Fintype.card ι)` whenever `e : ↥(univ \ S) ≃ ι'`. -/ theorem commonZeroCount_relabelRestrictedMonomials_lt_two_pow_branchPrecision [Fintype ι] @@ -907,7 +745,7 @@ theorem commonZeroCount_relabelRestrictedMonomials_lt_two_pow_branchPrecision [F _ < 2 ^ branchPrecision (Fintype.card ι) := two_pow_lt_two_pow_branchPrecision (Fintype.card ι) -/-- **§5.6 (exact branch recovery at original precision $\ell = n + 1$)**: on any branch `(S, b)` +/-- **§5.5 (exact branch recovery at original precision $\ell = n + 1$)**: on any branch `(S, b)` relabeled along `e : ↥(univ \ S) ≃ ι'`, evaluating `univariateParityTruncatedSum` at `T = 0` with the original precision `branchPrecision (Fintype.card ι) = n + 1` and taking the remainder modulo `2 ^ branchPrecision (Fintype.card ι)` yields the exact branch common-zero count. -/ @@ -927,7 +765,7 @@ theorem emod_eval_zero_univariateParityTruncatedSum_branch_eq [Fintype ι] [Fint exact emod_eval_zero_univariateParityTruncatedSum_eq_commonZeroCount I (fun i => relabelRestrictedMonomials S e b (P i)) hcard q hq0 -/-- **§5.6 (Theorem 2.2 branch-summed modular recovery)**: summing the per-branch `T = 0` +/-- **§5.5 (Theorem 2.2 branch-summed modular recovery)**: summing the per-branch `T = 0` remainders modulo `2 ^ branchPrecision (Fintype.card ι)` across all `b ∈ branchAssignments S` recovers the exact unrestricted count `(commonZeroCount I P : ℤ)`. -/ theorem commonZeroCount_eq_sum_branch_emod_eval_zero [Fintype ι] [Fintype ι'] @@ -947,7 +785,7 @@ theorem commonZeroCount_eq_sum_branch_emod_eval_zero [Fintype ι] [Fintype ι'] refine sum_congr rfl fun b hb => ?_ exact (emod_eval_zero_univariateParityTruncatedSum_branch_eq S e I P b (q b) (hq0 b hb)).symm -/-- **§5.6 ($m_{\mathrm{test}} + 2(\ell - 1) \le (2c + 4)n'$ when $n \le 2n'$)**: when `m ≤ c * n` +/-- **§5.5 ($m_{\mathrm{test}} + 2(\ell - 1) \le (2c + 4)n'$ when $n \le 2n'$)**: when `m ≤ c * n` and `n ≤ 2 * n'`, the equation-plus-precision factor `m + 2 * (branchPrecision n - 1)` is at most `(2 * c + 4) * n'`. -/ theorem branchEquationBudget_le {m c n n' : ℕ} (hm : m ≤ c * n) (hn : n ≤ 2 * n') : @@ -960,7 +798,7 @@ theorem branchEquationBudget_le {m c n n' : ℕ} (hm : m ≤ c * n) (hn : n ≤ _ ≤ (c + 2) * (2 * n') := Nat.mul_le_mul_left (c + 2) hn _ = (2 * c + 4) * n' := by ring -/-- **§5.6 ($d_H = O_{k, c}(n' R)$ per-branch degree bound)**: on any branch `(S, b)` relabeled +/-- **§5.5 ($d_H = O_{k, c}(n' R)$ per-branch degree bound)**: on any branch `(S, b)` relabeled along `e : ↥(univ \ S) ≃ ι'`, if `#I ≤ c * Fintype.card ι`, `Fintype.card ι ≤ 2 * Fintype.card ι'`, every monomial in the unrestricted system `P` has degree at most `k`, and every branch replacement polynomial `q x i v` has `natDegree ≤ R_deg`, then `univariateParityTruncatedSum` at precision diff --git a/Complexity/Foundations/Data/Polynomial/ParityAmplifierDegree.lean b/Complexity/Foundations/Data/Polynomial/ParityAmplifierDegree.lean new file mode 100644 index 0000000000..3c348a36ee --- /dev/null +++ b/Complexity/Foundations/Data/Polynomial/ParityAmplifierDegree.lean @@ -0,0 +1,221 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Foundations.Data.Polynomial.ParityAmplifier +import Mathlib.Tactic.Linarith +import Mathlib.Tactic.Ring + +/-! +# Ring-homomorphism transport and univariate `natDegree` bounds for parity factors + +This module provides ring-homomorphism transport and univariate `natDegree` bounds for the +parity-amplifying series factors `Polynomial.parityFactor` and truncated coefficient sums +`Polynomial.sumCoeffsBelow` defined in `Complexity.Foundations.Data.Polynomial.ParityAmplifier`. + +When each input $L_i(T) \in R[T]$ is a univariate polynomial of `natDegree` at most $d$, the +$V^s$-coefficient of $\prod_{i \in I} B_i(L_i(T), V)$ in $R[T][V]$ has `natDegree` at most +$d (\#I + 2 s)$ (`Polynomial.natDegree_coeff_prod_parityFactor_le`), so every retained coefficient +for $s < \ell$ and their sum `sumCoeffsBelow ℓ` have `natDegree` at most $d (\#I + 2 (\ell - 1))$ +(`Polynomial.natDegree_coeff_prod_parityFactor_le_of_lt`, +`Polynomial.natDegree_sumCoeffsBelow_prod_parityFactor_le`), matching Lemma 5.2 and equation (5.5) +of [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH]. + +## Main results + +* `Polynomial.map_evalInt`, `Polynomial.map_parityFactor`, `Polynomial.map_sumCoeffsBelow`: + ring-homomorphism transport for `evalInt`, `parityFactor`, and `sumCoeffsBelow`. +* `Polynomial.eval_coeff_prod_parityFactor`, `Polynomial.eval_sumCoeffsBelow_prod_parityFactor`: + pointwise evaluation of coefficients and truncated sums of products of univariate parity factors. +* `Polynomial.natDegree_evalInt_le`, `Polynomial.natDegree_coeff_parityFactor_le`: + univariate `natDegree` bounds for `evalInt` and single parity-factor coefficients. +* `Polynomial.natDegree_coeff_prod_parityFactor_le`, + `Polynomial.natDegree_coeff_prod_parityFactor_le_of_lt`, + `Polynomial.natDegree_sumCoeffsBelow_prod_parityFactor_le`: univariate `natDegree` bounds for + products of parity factors and their truncated coefficient sums. + +## References + +* [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (Lemma 5.2 and Section 5.3) +-/ + +@[expose] public noncomputable section + +namespace Polynomial + +open Finset + +variable {κ R : Type*} + +/-- Any ring homomorphism `φ : A →+* B` commutes with `Polynomial.evalInt`. -/ +theorem map_evalInt {A B : Type*} [CommRing A] [CommRing B] (φ : A →+* B) (y : A) + (p : ℤ[X]) : + φ (evalInt y p) = evalInt (φ y) p := by + induction p using Polynomial.induction_on' with + | add p q ihp ihq => + rw [evalInt, eval₂_add, map_add, ← evalInt, ← evalInt, ihp, ihq, evalInt, evalInt, + ← eval₂_add] + rfl + | monomial n a => + rw [evalInt, evalInt, eval₂_monomial, eval₂_monomial, map_mul, map_pow] + congr 1 + rw [eq_intCast, eq_intCast, map_intCast] + +/-- Mapping `parityFactor ℓ y` coefficientwise by `φ : A →+* B` yields `parityFactor ℓ (φ y)`. -/ +theorem map_parityFactor {A B : Type*} [CommRing A] [CommRing B] (φ : A →+* B) (ℓ : ℕ) (y : A) : + (parityFactor ℓ y).map φ = parityFactor ℓ (φ y) := by + ext s + rw [coeff_map, coeff_parityFactor, coeff_parityFactor] + split_ifs with hs + · rw [map_mul, map_pow, map_evalInt, map_evalInt] + · exact map_zero φ + +/-- Any ring homomorphism `φ : A →+* B` commutes with `sumCoeffsBelow`. -/ +theorem map_sumCoeffsBelow {A B : Type*} [Semiring A] [Semiring B] (φ : A →+* B) + (P : A[X]) (m : ℕ) : + φ (P.sumCoeffsBelow m) = (P.map φ).sumCoeffsBelow m := by + rw [sumCoeffsBelow, sumCoeffsBelow, map_sum] + refine sum_congr rfl fun j _ => ?_ + rw [coeff_map] + +/-- Evaluating the `s`-th coefficient of `∏ i ∈ I, parityFactor ℓ (L i)` at `t : R` agrees with +the `s`-th coefficient of `∏ i ∈ I, parityFactor ℓ ((L i).eval t)`. -/ +theorem eval_coeff_prod_parityFactor [CommRing R] (I : Finset κ) (ℓ : ℕ) + (L : κ → R[X]) (s : ℕ) (t : R) : + ((∏ i ∈ I, parityFactor ℓ (L i)).coeff s).eval t = + (∏ i ∈ I, parityFactor ℓ ((L i).eval t)).coeff s := by + let φ : R[X] →+* R := evalRingHom t + change φ ((∏ i ∈ I, parityFactor ℓ (L i)).coeff s) = _ + rw [← coeff_map, Polynomial.map_prod] + refine congrArg (fun Q : R[X] => Q.coeff s) (prod_congr rfl fun i _ => ?_) + exact map_parityFactor φ ℓ (L i) + +/-- Evaluating `sumCoeffsBelow m` of `∏ i ∈ I, parityFactor ℓ (L i)` at `t : R` agrees with +`sumCoeffsBelow m` of `∏ i ∈ I, parityFactor ℓ ((L i).eval t)`. -/ +theorem eval_sumCoeffsBelow_prod_parityFactor [CommRing R] (I : Finset κ) (ℓ : ℕ) + (L : κ → R[X]) (m : ℕ) (t : R) : + ((∏ i ∈ I, parityFactor ℓ (L i)).sumCoeffsBelow m).eval t = + (∏ i ∈ I, parityFactor ℓ ((L i).eval t)).sumCoeffsBelow m := by + rw [sumCoeffsBelow, eval_finsetSum, sumCoeffsBelow] + exact sum_congr rfl fun s _ => eval_coeff_prod_parityFactor I ℓ L s t + +/-- For `y : R[X]` and `p : ℤ[X]`, `(evalInt y p).natDegree ≤ p.natDegree * y.natDegree`. -/ +theorem natDegree_evalInt_le [CommRing R] (y : R[X]) (p : ℤ[X]) : + (evalInt y p).natDegree ≤ p.natDegree * y.natDegree := by + rw [evalInt, eval₂_eq_sum_range] + refine (natDegree_sum_le _ _).trans ?_ + rw [Finset.fold_max_le] + refine ⟨Nat.zero_le _, fun i hi => ?_⟩ + rw [mem_range, Nat.lt_succ_iff] at hi + dsimp only [Function.comp_apply] + have hcast : (Int.castRingHom R[X] (p.coeff i)) = C (p.coeff i : R) := by + rw [eq_intCast, ← C_eq_intCast] + rw [hcast] + calc + (C (p.coeff i : R) * y ^ i).natDegree + ≤ (C (p.coeff i : R)).natDegree + (y ^ i).natDegree := natDegree_mul_le + _ ≤ 0 + i * y.natDegree := by + rw [natDegree_C] + exact add_le_add le_rfl natDegree_pow_le + _ ≤ p.natDegree * y.natDegree := by + rw [zero_add] + exact Nat.mul_le_mul_right _ hi + +/-- `evalInt y (parityBaseDigit ℓ j)` has `natDegree ≤ y.natDegree`. -/ +theorem natDegree_evalInt_parityBaseDigit_le [CommRing R] (ℓ j : ℕ) (y : R[X]) : + (evalInt y (parityBaseDigit ℓ j)).natDegree ≤ y.natDegree := by + calc + (evalInt y (parityBaseDigit ℓ j)).natDegree + ≤ (parityBaseDigit ℓ j).natDegree * y.natDegree := natDegree_evalInt_le y _ + _ ≤ 1 * y.natDegree := Nat.mul_le_mul_right _ (natDegree_parityBaseDigit_le ℓ j) + _ = y.natDegree := one_mul _ + +/-- `evalInt y hPoly` has `natDegree ≤ 2 * y.natDegree`. -/ +theorem natDegree_evalInt_hPoly_le [CommRing R] (y : R[X]) : + (evalInt y hPoly).natDegree ≤ 2 * y.natDegree := by + rw [evalInt_hPoly] + calc + (y ^ 2 - y).natDegree + ≤ max (y ^ 2).natDegree y.natDegree := natDegree_sub_le _ _ + _ ≤ max (2 * y.natDegree) y.natDegree := max_le_max natDegree_pow_le le_rfl + _ = 2 * y.natDegree := max_eq_left (by omega) + +/-- The `j`-th coefficient of `parityFactor ℓ y` has `natDegree ≤ (1 + 2 * j) * y.natDegree`. -/ +theorem natDegree_coeff_parityFactor_le [CommRing R] (ℓ : ℕ) (y : R[X]) (j : ℕ) : + ((parityFactor ℓ y).coeff j).natDegree ≤ (1 + 2 * j) * y.natDegree := by + rw [coeff_parityFactor] + split_ifs with hj + · calc + (evalInt y (parityBaseDigit ℓ j) * evalInt y hPoly ^ j).natDegree + ≤ (evalInt y (parityBaseDigit ℓ j)).natDegree + + (evalInt y hPoly ^ j).natDegree := natDegree_mul_le + _ ≤ y.natDegree + j * (evalInt y hPoly).natDegree := + add_le_add (natDegree_evalInt_parityBaseDigit_le ℓ j y) natDegree_pow_le + _ ≤ y.natDegree + j * (2 * y.natDegree) := + add_le_add le_rfl (Nat.mul_le_mul_left j (natDegree_evalInt_hPoly_le y)) + _ = (1 + 2 * j) * y.natDegree := by ring + · simp only [natDegree_zero, zero_le] + +/-- If every `L i` (`i ∈ I`) has `natDegree ≤ d`, then the `V ^ s`-coefficient of +`∏ i ∈ I, parityFactor ℓ (L i)` has `natDegree ≤ d * (#I + 2 * s)`. -/ +theorem natDegree_coeff_prod_parityFactor_le [CommRing R] (I : Finset κ) (ℓ : ℕ) + (L : κ → R[X]) {d : ℕ} (hL : ∀ i ∈ I, (L i).natDegree ≤ d) : + ∀ s : ℕ, ((∏ i ∈ I, parityFactor ℓ (L i)).coeff s).natDegree ≤ d * (#I + 2 * s) := by + classical + induction I using Finset.induction_on with + | empty => + intro s + simp only [prod_empty, card_empty, zero_add] + rcases eq_or_ne s 0 with rfl | hs + · simp only [coeff_one_zero, natDegree_one, zero_le] + · rw [coeff_one, ite_eq_right hs, natDegree_zero] + exact Nat.zero_le _ + | insert a I ha ih => + intro s + rw [prod_insert ha, card_insert_of_notMem ha, coeff_mul] + have haL : (L a).natDegree ≤ d := hL a (mem_insert_self a I) + have hIL : ∀ i ∈ I, (L i).natDegree ≤ d := fun i hi => hL i (mem_insert_of_mem hi) + refine (natDegree_sum_le _ _).trans ?_ + rw [Finset.fold_max_le] + refine ⟨Nat.zero_le _, fun p hp => ?_⟩ + rw [mem_antidiagonal] at hp + calc + (((parityFactor ℓ (L a)).coeff p.1) * + ((∏ i ∈ I, parityFactor ℓ (L i)).coeff p.2)).natDegree + ≤ ((parityFactor ℓ (L a)).coeff p.1).natDegree + + ((∏ i ∈ I, parityFactor ℓ (L i)).coeff p.2).natDegree := natDegree_mul_le + _ ≤ (1 + 2 * p.1) * (L a).natDegree + d * (#I + 2 * p.2) := + add_le_add (natDegree_coeff_parityFactor_le ℓ (L a) p.1) (ih hIL p.2) + _ ≤ (1 + 2 * p.1) * d + d * (#I + 2 * p.2) := + add_le_add (Nat.mul_le_mul_left _ haL) le_rfl + _ = d * (#I + 1 + 2 * (p.1 + p.2)) := by ring + _ = d * (#I + 1 + 2 * s) := by rw [hp] + +/-- For `s < ℓ`, the `V ^ s`-coefficient of `∏ i ∈ I, parityFactor ℓ (L i)` has +`natDegree ≤ d * (#I + 2 * (ℓ - 1))`. -/ +theorem natDegree_coeff_prod_parityFactor_le_of_lt [CommRing R] (I : Finset κ) (ℓ : ℕ) + (L : κ → R[X]) {d : ℕ} (hL : ∀ i ∈ I, (L i).natDegree ≤ d) {s : ℕ} (hs : s < ℓ) : + ((∏ i ∈ I, parityFactor ℓ (L i)).coeff s).natDegree ≤ + d * (#I + 2 * (ℓ - 1)) := by + refine (natDegree_coeff_prod_parityFactor_le I ℓ L hL s).trans ?_ + exact Nat.mul_le_mul_left d (by omega) + +/-- The truncated sum `sumCoeffsBelow ℓ (∏ i ∈ I, parityFactor ℓ (L i))` has +`natDegree ≤ d * (#I + 2 * (ℓ - 1))`. -/ +theorem natDegree_sumCoeffsBelow_prod_parityFactor_le [CommRing R] (I : Finset κ) (ℓ : ℕ) + (L : κ → R[X]) {d : ℕ} (hL : ∀ i ∈ I, (L i).natDegree ≤ d) : + ((∏ i ∈ I, parityFactor ℓ (L i)).sumCoeffsBelow ℓ).natDegree ≤ + d * (#I + 2 * (ℓ - 1)) := by + rw [sumCoeffsBelow] + refine (natDegree_sum_le _ _).trans ?_ + rw [Finset.fold_max_le] + refine ⟨Nat.zero_le _, fun s hs => ?_⟩ + exact natDegree_coeff_prod_parityFactor_le_of_lt I ℓ L hL (mem_range.mp hs) + +end Polynomial diff --git a/ComplexityTests/Foundations/Data/Polynomial/ParityAmplifierDegree.lean b/ComplexityTests/Foundations/Data/Polynomial/ParityAmplifierDegree.lean new file mode 100644 index 0000000000..75070910c0 --- /dev/null +++ b/ComplexityTests/Foundations/Data/Polynomial/ParityAmplifierDegree.lean @@ -0,0 +1,32 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Foundations.Data.Polynomial.ParityAmplifierDegree +import Mathlib.Data.Fintype.Fin + +/-! +# Tests for `Complexity.Foundations.Data.Polynomial.ParityAmplifierDegree` + +Concrete degree and evaluation checks for `Polynomial.parityFactor` over `R[X]`. +-/ + +@[expose] public noncomputable section + +namespace Polynomial.ParityAmplifierDegreeTests + +open Finset + +example (L : Fin 2 → ℤ[X]) (hL : ∀ i ∈ (univ : Finset (Fin 2)), (L i).natDegree ≤ 3) : + (((∏ i ∈ (univ : Finset (Fin 2)), parityFactor 2 (L i)).coeff 1).natDegree ≤ 12) ∧ + ((∏ i ∈ (univ : Finset (Fin 2)), parityFactor 2 (L i)).sumCoeffsBelow 2).natDegree ≤ 12 := by + exact ⟨(natDegree_coeff_prod_parityFactor_le_of_lt univ 2 L hL (by decide)).trans (by decide), + (natDegree_sumCoeffsBelow_prod_parityFactor_le univ 2 L hL).trans (by decide)⟩ + +end Polynomial.ParityAmplifierDegreeTests diff --git a/ComplexityTests/SparseBranching.lean b/ComplexityTests/SparseBranching.lean index f69342c3bf..6c36fc2109 100644 --- a/ComplexityTests/SparseBranching.lean +++ b/ComplexityTests/SparseBranching.lean @@ -94,13 +94,14 @@ example (v : Fin 2) : ⟨one_le_varIncidence_withNeutralFactors univ (fun i => equationScope (testSys i)) v, card_le_totalIncidence_withNeutralFactors univ (fun i => equationScope (testSys i))⟩ -/-- Heavy-variable threshold ceiling `heavyThreshold M n s` satisfies `M * s ≤ b₀ * n` and yields -at least `n / 2` free variables when `s ≥ 2`. -/ +/-- Heavy-variable threshold ceiling `heavyThreshold M n s` and the manuscript's separate-ceiling +formula `paperHeavyThreshold M n s = ⌈M / n⌉ * s` both satisfy `M * s ≤ b₀ * n`. -/ example : - 4 * 2 ≤ heavyThreshold 4 20 2 * 20 := - mul_le_heavyThreshold_mul (by decide) + 4 * 2 ≤ heavyThreshold 4 20 2 * 20 ∧ + 4 * 2 ≤ paperHeavyThreshold 4 20 2 * 20 := + ⟨mul_le_heavyThreshold_mul (by decide), mul_le_paperHeavyThreshold_mul (by decide)⟩ -/-- §5.6 shared-precision (`ℓ = n + 1 = 3`) branch-summed modular recovery on `testSys` when +/-- §5.5 shared-precision (`ℓ = n + 1 = 3`) branch-summed modular recovery on `testSys` when branching on `S = {0}`. -/ example : (commonZeroCount (univ : Finset (Fin 2)) testSys : ℤ) = @@ -116,7 +117,7 @@ example : intro _b _hb x _i _hi _M _hM w _hw simp only [Polynomial.eval_add, Polynomial.eval_C, Polynomial.eval_X, add_zero] -/-- §5.6 linear per-branch degree bound `d_H ≤ (k * R_deg) * ((2 * c + 4) * n')` (`k = 2`, +/-- §5.5 linear per-branch degree bound `d_H ≤ (k * R_deg) * ((2 * c + 4) * n')` (`k = 2`, `R_deg = 3`, `c = 1`, `n = 2`, `n' = 1`). -/ example (b : Fin 2 → Bool) (q : (Fin #(univ \ ({0} : Finset (Fin 2))) → Bool) → Fin 2 → From bcf6ea427aaccad2ca268a4a27cccf2d97639323 Mon Sep 17 00:00:00 2001 From: Samuel Schlesinger Date: Tue, 27 Oct 2026 02:03:09 +0000 Subject: [PATCH 09/20] feat(Foundations/BooleanAnalysis): add cleared-denominator specialization and exact division recovery --- Complexity.lean | 2 + .../SparseClearedSpecialization.lean | 857 ++++++++++++++++++ .../Data/Polynomial/BivariateCoeffNorm1.lean | 201 ++++ .../Data/Polynomial/BivariateCoeffNorm1.lean | 41 + .../SparseClearedSpecialization.lean | 136 +++ 5 files changed, 1237 insertions(+) create mode 100644 Complexity/Foundations/BooleanAnalysis/SparseClearedSpecialization.lean create mode 100644 Complexity/Foundations/Data/Polynomial/BivariateCoeffNorm1.lean create mode 100644 ComplexityTests/Foundations/Data/Polynomial/BivariateCoeffNorm1.lean create mode 100644 ComplexityTests/SparseClearedSpecialization.lean diff --git a/Complexity.lean b/Complexity.lean index e1a068b787..52a62375c3 100644 --- a/Complexity.lean +++ b/Complexity.lean @@ -1775,6 +1775,7 @@ public import Complexity.Foundations.BooleanAnalysis.QuadraticForm public import Complexity.Foundations.BooleanAnalysis.RelevantCoordinates public import Complexity.Foundations.BooleanAnalysis.SignApproximation public import Complexity.Foundations.BooleanAnalysis.SparseBranching +public import Complexity.Foundations.BooleanAnalysis.SparseClearedSpecialization public import Complexity.Foundations.BooleanAnalysis.SparseEquations public import Complexity.Foundations.BooleanAnalysis.Symmetrization public import Complexity.Foundations.Combinatorics.AffineDisperser @@ -1976,6 +1977,7 @@ public import Complexity.Foundations.Data.Nat.Radix public import Complexity.Foundations.Data.Option public import Complexity.Foundations.Data.OrderedSet public import Complexity.Foundations.Data.OrderedSet.Spec +public import Complexity.Foundations.Data.Polynomial.BivariateCoeffNorm1 public import Complexity.Foundations.Data.Polynomial.CoeffList public import Complexity.Foundations.Data.Polynomial.CoeffNorm1 public import Complexity.Foundations.Data.Polynomial.HermiteInterpolation diff --git a/Complexity/Foundations/BooleanAnalysis/SparseClearedSpecialization.lean b/Complexity/Foundations/BooleanAnalysis/SparseClearedSpecialization.lean new file mode 100644 index 0000000000..5603285196 --- /dev/null +++ b/Complexity/Foundations/BooleanAnalysis/SparseClearedSpecialization.lean @@ -0,0 +1,857 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Foundations.BooleanAnalysis.SparseBranching +public import Complexity.Foundations.Data.Polynomial.BivariateCoeffNorm1 +import Mathlib.Data.Finset.NatAntidiagonal +import Mathlib.Data.Finset.Sum +import Mathlib.Data.Fintype.Pi + +/-! +# Rational-to-cleared-denominator specialization and exact division recovery + +This module bridges the rational replacement polynomials of Section 5.3–5.4 and the +cleared-denominator integer interpolation pipeline of Section 5.4 and Appendix B.2–B.3 of +[OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (pp. 37–39, 48–50): + +1. **Cleared-denominator evaluation at $T = 0$, ring homogenization, and `natDegree` bounds + (§5.3–5.4 & Appendix B.2)**: + When each variable $v \in \iota$ in equation $i \in I$ has an integer numerator polynomial + $\theta_{x, i, v}(T) \in \mathbb{Z}[T]$ over a common denominator $d_{\mathrm{den}} \in + \mathbb{Z}$ satisfying $\theta_{x, i, v}(0) = d_{\mathrm{den}} \cdot \mathrm{bitVal}_{\mathbb{Z}} + (x_v)$ and $\deg_T \theta_{x, i, v} \le R_{\mathrm{deg}}$, the cleared-denominator equation + polynomial `Cslib.BitString.clearedMonomialSumPoly` has `natDegree ≤ k * R_deg`, evaluates at + $T = 0$ to $d_{\mathrm{den}}^k \cdot \mathrm{monomialSum}_{\mathbb{Z}}(\mathcal{P}_i, x)$, and + maps into any commutative ring $R$ (such as $\mathbb{Q}$) as $d_{\mathrm{den}}^k$ times + `Cslib.BitString.univariateMonomialSumPoly`. +2. **Cube-summed cleared-denominator polynomials $\tilde{H}_s(T) = \Omega [V^s] H(T)$ and exact + integer division recovery (§5.4 & Appendix B.3, eq. B.1)**: + Summing the cleared parity-factor products over $x \in \{0, 1\}^\iota$ yields + `Cslib.BitString.univariateClearedParityProduct`, its $V^s$-coordinates + `Cslib.BitString.univariateClearedParityCoord` ($\tilde{H}_s(T) \in \mathbb{Z}[T]$), and its + truncated sum `Cslib.BitString.univariateClearedParityTruncatedSum`. Over any field $K$ of + characteristic zero (such as $\mathbb{Q}$), $\tilde{H}_s(T)$ equals the common product + denominator $\Omega = (d_{\mathrm{den}}^k)^{(2\ell - 1)\#I}$ + (`Cslib.BitString.clearedProductDenom`) times the rational coordinate polynomial `[V^s] H(T)` + associated to the rational replacement family `Cslib.BitString.divDenomReplacement` + ($r_{x, i, v}(T) = d_{\mathrm{den}}^{-1} \theta_{x, i, v}(T)$). At $T = 0$, $\tilde{H}_s(0)$ is + an exact integer multiple of $\Omega$; when $d_{\mathrm{den}} \neq 0$ and + `Fintype.card ι < ℓ`, dividing each $\tilde{H}_s(0)$ (or Cramer's rule determinant numerator + $N_{H, s} = D_H \tilde{H}_s(0)$ in eq. B.1) by $\Omega$ (or $\Omega D_H$), summing over + $0 \le s < \ell$, and reducing modulo $2^\ell$ recovers `commonZeroCount I P` on the nose, both + on a single problem and summed across all heavy-variable branches at shared precision + $\ell = n + 1$. + +## Main definitions + +* `Cslib.BitString.clearedProductDenom`: the product denominator + $\Omega = ((d_{\mathrm{den}}^k)^{2\ell - 1})^{m_{\mathrm{test}}}$. +* `Cslib.BitString.univariateClearedParityProduct`, + `Cslib.BitString.univariateClearedParityCoord`, + `Cslib.BitString.univariateClearedParityTruncatedSum`: the cube-summed cleared-denominator + bivariate polynomial $\tilde{H}(T, V) \in \mathbb{Z}[T][V]$, its $V^s$-coordinate polynomials + $\tilde{H}_s(T) \in \mathbb{Z}[T]$, and its truncated sum + $S_\ell(\tilde{H}(T)) \in \mathbb{Z}[T]$. +* `Cslib.BitString.divDenomReplacement`: the rational replacement family + $r_{x, i, v}(T) = d_{\mathrm{den}}^{-1} \theta_{x, i, v}(T) \in K[T]$. + +## Main results + +* `Cslib.BitString.eval_zero_clearedMonomialSumPoly`, + `Cslib.BitString.map_clearedMonomialSumPoly`, + `Cslib.BitString.natDegree_clearedMonomialSumPoly_le`: $T = 0$ evaluation, ring homogenization, + and `natDegree` bound for cleared-denominator equation polynomials. +* `Cslib.BitString.natDegree_univariateClearedParityCoord_le`, + `Cslib.BitString.natDegree_univariateClearedParityTruncatedSum_le`: equation (5.5a) `natDegree` + bounds for $\tilde{H}_s(T)$ and $S_\ell(\tilde{H}(T))$. +* `Cslib.BitString.map_univariateClearedParityCoord_divDenomReplacement`, + `Cslib.BitString.map_univariateClearedParityTruncatedSum_divDenomReplacement`: over any field $K$, + $\tilde{H}_s(T) = \Omega [V^s] H(T)$ and $S_\ell(\tilde{H}(T)) = \Omega S_\ell(H(T))$. +* `Cslib.BitString.bivariateCoeffNorm1_parityFactorCleared_le`, + `Cslib.BitString.bivariateCoeffNorm1_prod_parityFactorCleared_le`, + `Cslib.BitString.coeffNorm1_univariateClearedParityCoord_le`: Appendix B.2 bivariate and + coordinate `ℓ₁`-norm bounds for cleared parity factors and $\tilde{H}_s(T)$. +* `Cslib.BitString.eval_zero_univariateClearedParityCoord`, + `Cslib.BitString.ediv_eval_zero_univariateClearedParityCoord`, + `Cslib.BitString.emod_sum_ediv_eval_zero_univariateClearedParityCoord_eq_commonZeroCount`, + `Cslib.BitString.emod_ediv_eval_zero_univariateClearedParityTruncatedSum_eq_commonZeroCount`: + exact integer divisibility by $\Omega$ at $T = 0$ and exact modular recovery of `commonZeroCount`. +* `Cslib.BitString.emod_sum_cramer_ediv_eq_commonZeroCount`: Appendix B.3 (eq. B.1) exact integer + division recovery from Cramer's rule determinant numerators $N_{H, s} = D_H \tilde{H}_s(0)$. +* `Cslib.BitString.commonZeroCount_eq_sum_branch_emod_ediv_cleared`: §5.5 branch-summed exact + recovery from cleared-denominator branch polynomials at shared precision $\ell = n + 1$. + +## References + +* [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (Sections 5.3–5.5 and + Appendix B.2–B.3) +-/ + +@[expose] public noncomputable section + +namespace Cslib.BitString + +open Finset + +variable {ι κ R : Type*} + +/-! ### 1. Ring-homomorphism transport and `natDegree` bounds for cleared parity factors -/ + +/-- Any ring homomorphism `φ : A →+* B` commutes with `parityBaseDigitCleared`. -/ +theorem map_parityBaseDigitCleared {A B : Type*} [CommRing A] [CommRing B] (φ : A →+* B) + (ℓ j : ℕ) (Δ A_i : A) : + φ (parityBaseDigitCleared ℓ j Δ A_i) = + parityBaseDigitCleared ℓ j (φ Δ) (φ A_i) := by + simp only [parityBaseDigitCleared, map_add, map_mul, map_intCast] + +/-- Any ring homomorphism `φ : A →+* B` commutes with `hPolyCleared`. -/ +theorem map_hPolyCleared {A B : Type*} [CommRing A] [CommRing B] (φ : A →+* B) (Δ A_i : A) : + φ (hPolyCleared Δ A_i) = hPolyCleared (φ Δ) (φ A_i) := by + simp only [hPolyCleared, map_mul, map_sub] + +/-- Mapping `parityFactorCleared ℓ Δ A_i` coefficientwise by `φ : A →+* B` yields +`parityFactorCleared ℓ (φ Δ) (φ A_i)`. -/ +theorem map_parityFactorCleared {A B : Type*} [CommRing A] [CommRing B] (φ : A →+* B) + (ℓ : ℕ) (Δ A_i : A) : + (parityFactorCleared ℓ Δ A_i).map φ = parityFactorCleared ℓ (φ Δ) (φ A_i) := by + ext s + rw [Polynomial.coeff_map, coeff_parityFactorCleared, coeff_parityFactorCleared] + split_ifs with hs + · rw [map_mul, map_mul, map_pow, map_pow, map_parityBaseDigitCleared, map_hPolyCleared] + · exact map_zero φ + +/-- Evaluating the `s`-th coefficient of `∏ i ∈ I, parityFactorCleared ℓ Δ (A_i i)` at `t : R` +agrees with the `s`-th coefficient of +`∏ i ∈ I, parityFactorCleared ℓ (Δ.eval t) ((A_i i).eval t)`. -/ +theorem eval_coeff_prod_parityFactorCleared [CommRing R] (I : Finset κ) (ℓ : ℕ) + (Δ : Polynomial R) (A_i : κ → Polynomial R) (s : ℕ) (t : R) : + ((∏ i ∈ I, parityFactorCleared ℓ Δ (A_i i)).coeff s).eval t = + (∏ i ∈ I, parityFactorCleared ℓ (Δ.eval t) ((A_i i).eval t)).coeff s := by + let φ : Polynomial R →+* R := Polynomial.evalRingHom t + change φ ((∏ i ∈ I, parityFactorCleared ℓ Δ (A_i i)).coeff s) = _ + rw [← Polynomial.coeff_map, Polynomial.map_prod] + refine congrArg (fun Q : Polynomial R => Q.coeff s) (prod_congr rfl fun i _ => ?_) + exact map_parityFactorCleared φ ℓ Δ (A_i i) + +/-- Evaluating `sumCoeffsBelow m` of `∏ i ∈ I, parityFactorCleared ℓ Δ (A_i i)` at `t : R` agrees +with `sumCoeffsBelow m` of `∏ i ∈ I, parityFactorCleared ℓ (Δ.eval t) ((A_i i).eval t)`. -/ +theorem eval_sumCoeffsBelow_prod_parityFactorCleared [CommRing R] (I : Finset κ) (ℓ : ℕ) + (Δ : Polynomial R) (A_i : κ → Polynomial R) (m : ℕ) (t : R) : + ((∏ i ∈ I, parityFactorCleared ℓ Δ (A_i i)).sumCoeffsBelow m).eval t = + (∏ i ∈ I, parityFactorCleared ℓ (Δ.eval t) ((A_i i).eval t)).sumCoeffsBelow m := by + rw [Polynomial.sumCoeffsBelow, Polynomial.eval_finsetSum, Polynomial.sumCoeffsBelow] + exact sum_congr rfl fun s _ => eval_coeff_prod_parityFactorCleared I ℓ Δ A_i s t + +/-- When `Δ` has `natDegree = 0` and `A_i` has `natDegree ≤ d`, `parityBaseDigitCleared ℓ j Δ A_i` +has `natDegree ≤ d`. -/ +theorem natDegree_parityBaseDigitCleared_le [CommRing R] (ℓ j : ℕ) (Δ A_i : Polynomial R) + {d : ℕ} (hΔ : Δ.natDegree = 0) (hA : A_i.natDegree ≤ d) : + (parityBaseDigitCleared ℓ j Δ A_i).natDegree ≤ d := by + rw [parityBaseDigitCleared] + have hcast : ∀ c : ℤ, (c : Polynomial R) = Polynomial.C (c : R) := fun c => by + rw [← Polynomial.C_eq_intCast] + rw [hcast, hcast] + refine (Polynomial.natDegree_add_le _ _).trans (max_le ?_ ?_) + · exact (Polynomial.natDegree_C_mul_le _ _).trans (by omega) + · exact (Polynomial.natDegree_C_mul_le _ _).trans hA + +/-- When `Δ` has `natDegree = 0` and `A_i` has `natDegree ≤ d`, `hPolyCleared Δ A_i` has +`natDegree ≤ 2 * d`. -/ +theorem natDegree_hPolyCleared_le [CommRing R] (Δ A_i : Polynomial R) {d : ℕ} + (hΔ : Δ.natDegree = 0) (hA : A_i.natDegree ≤ d) : + (hPolyCleared Δ A_i).natDegree ≤ 2 * d := by + rw [hPolyCleared] + have hsub : (A_i - Δ).natDegree ≤ d := + (Polynomial.natDegree_sub_le _ _).trans (max_le hA (by omega)) + calc + (A_i * (A_i - Δ)).natDegree + ≤ A_i.natDegree + (A_i - Δ).natDegree := Polynomial.natDegree_mul_le + _ ≤ d + d := add_le_add hA hsub + _ = 2 * d := by ring + +/-- When `Δ` has `natDegree = 0` and `A_i` has `natDegree ≤ d`, the `s`-th coefficient of +`parityFactorCleared ℓ Δ A_i` has `natDegree ≤ d * (1 + 2 * s)`. -/ +theorem natDegree_coeff_parityFactorCleared_le [CommRing R] (ℓ : ℕ) (Δ A_i : Polynomial R) + {d : ℕ} (hΔ : Δ.natDegree = 0) (hA : A_i.natDegree ≤ d) (s : ℕ) : + ((parityFactorCleared ℓ Δ A_i).coeff s).natDegree ≤ d * (1 + 2 * s) := by + rw [coeff_parityFactorCleared] + split_ifs with hs + · have hΔpow : (Δ ^ (2 * (ℓ - 1 - s))).natDegree = 0 := by + refine Nat.eq_zero_of_le_zero ((Polynomial.natDegree_pow_le).trans ?_) + simp only [hΔ, mul_zero, le_rfl] + have he : (parityBaseDigitCleared ℓ s Δ A_i).natDegree ≤ d := + natDegree_parityBaseDigitCleared_le ℓ s Δ A_i hΔ hA + have hh : (hPolyCleared Δ A_i ^ s).natDegree ≤ s * (2 * d) := + (Polynomial.natDegree_pow_le).trans + (Nat.mul_le_mul_left s (natDegree_hPolyCleared_le Δ A_i hΔ hA)) + calc + (Δ ^ (2 * (ℓ - 1 - s)) * parityBaseDigitCleared ℓ s Δ A_i * + hPolyCleared Δ A_i ^ s).natDegree + ≤ (Δ ^ (2 * (ℓ - 1 - s)) * parityBaseDigitCleared ℓ s Δ A_i).natDegree + + (hPolyCleared Δ A_i ^ s).natDegree := Polynomial.natDegree_mul_le + _ ≤ ((Δ ^ (2 * (ℓ - 1 - s))).natDegree + + (parityBaseDigitCleared ℓ s Δ A_i).natDegree) + + (hPolyCleared Δ A_i ^ s).natDegree := + add_le_add Polynomial.natDegree_mul_le le_rfl + _ ≤ (0 + d) + s * (2 * d) := add_le_add (add_le_add (le_of_eq hΔpow) he) hh + _ = d * (1 + 2 * s) := by ring + · simp only [Polynomial.natDegree_zero, zero_le] + +/-- **Lemma 5.2 (cleared-denominator univariate `natDegree` bound)**: if `Δ.natDegree = 0` and +every `A_i i` (`i ∈ I`) has `natDegree ≤ d`, then the `s`-th coefficient of +`∏ i ∈ I, parityFactorCleared ℓ Δ (A_i i)` has `natDegree ≤ d * (#I + 2 * s)`. -/ +theorem natDegree_coeff_prod_parityFactorCleared_le [CommRing R] (I : Finset κ) (ℓ : ℕ) + (Δ : Polynomial R) (A_i : κ → Polynomial R) {d : ℕ} (hΔ : Δ.natDegree = 0) + (hA : ∀ i ∈ I, (A_i i).natDegree ≤ d) : + ∀ s : ℕ, + ((∏ i ∈ I, parityFactorCleared ℓ Δ (A_i i)).coeff s).natDegree ≤ d * (#I + 2 * s) := by + classical + induction I using Finset.induction_on with + | empty => + intro s + rcases s with _ | s + · simp only [prod_empty, Polynomial.coeff_one_zero, Polynomial.natDegree_one, zero_le] + · simp only [prod_empty, Polynomial.coeff_one, Nat.succ_ne_zero, ↓reduceIte, + Polynomial.natDegree_zero, zero_le] + | insert a I ha ih => + intro s + have ha_le : (A_i a).natDegree ≤ d := hA a (mem_insert_self a I) + have hI_le : ∀ i ∈ I, (A_i i).natDegree ≤ d := fun i hi => hA i (mem_insert_of_mem hi) + rw [prod_insert ha, card_insert_of_notMem ha, Polynomial.coeff_mul] + refine (Polynomial.natDegree_sum_le _ _).trans ?_ + rw [Finset.fold_max_le] + refine ⟨Nat.zero_le _, fun p hp => ?_⟩ + rw [Finset.mem_antidiagonal] at hp + dsimp only [Function.comp_apply] + have h1 := natDegree_coeff_parityFactorCleared_le ℓ Δ (A_i a) hΔ ha_le p.1 + have h2 := ih hI_le p.2 + calc + ((parityFactorCleared ℓ Δ (A_i a)).coeff p.1 * + (∏ x ∈ I, parityFactorCleared ℓ Δ (A_i x)).coeff p.2).natDegree + ≤ ((parityFactorCleared ℓ Δ (A_i a)).coeff p.1).natDegree + + ((∏ x ∈ I, parityFactorCleared ℓ Δ (A_i x)).coeff p.2).natDegree := + Polynomial.natDegree_mul_le + _ ≤ d * (1 + 2 * p.1) + d * (#I + 2 * p.2) := add_le_add h1 h2 + _ = d * (#I + 1 + 2 * (p.1 + p.2)) := by ring + _ = d * (#I + 1 + 2 * s) := by rw [hp] + +/-- For `s < ℓ`, the `s`-th coefficient of `∏ i ∈ I, parityFactorCleared ℓ Δ (A_i i)` has +`natDegree ≤ d * (#I + 2 * (ℓ - 1))`. -/ +theorem natDegree_coeff_prod_parityFactorCleared_le_of_lt [CommRing R] (I : Finset κ) + {ℓ s d : ℕ} (Δ : Polynomial R) (A_i : κ → Polynomial R) (hΔ : Δ.natDegree = 0) + (hA : ∀ i ∈ I, (A_i i).natDegree ≤ d) (hs : s < ℓ) : + ((∏ i ∈ I, parityFactorCleared ℓ Δ (A_i i)).coeff s).natDegree ≤ + d * (#I + 2 * (ℓ - 1)) := by + refine (natDegree_coeff_prod_parityFactorCleared_le I ℓ Δ A_i hΔ hA s).trans ?_ + exact Nat.mul_le_mul_left d (by omega) + +/-- The truncated sum `sumCoeffsBelow ℓ (∏ i ∈ I, parityFactorCleared ℓ Δ (A_i i))` has +`natDegree ≤ d * (#I + 2 * (ℓ - 1))`. -/ +theorem natDegree_sumCoeffsBelow_prod_parityFactorCleared_le [CommRing R] (I : Finset κ) + (ℓ : ℕ) (Δ : Polynomial R) (A_i : κ → Polynomial R) {d : ℕ} (hΔ : Δ.natDegree = 0) + (hA : ∀ i ∈ I, (A_i i).natDegree ≤ d) : + ((∏ i ∈ I, parityFactorCleared ℓ Δ (A_i i)).sumCoeffsBelow ℓ).natDegree ≤ + d * (#I + 2 * (ℓ - 1)) := by + rw [Polynomial.sumCoeffsBelow] + refine (Polynomial.natDegree_sum_le _ _).trans ?_ + rw [Finset.fold_max_le] + refine ⟨Nat.zero_le _, fun s hs => ?_⟩ + rw [mem_range] at hs + exact natDegree_coeff_prod_parityFactorCleared_le_of_lt I Δ A_i hΔ hA hs + +/-! ### 2. Cleared-denominator monomials and equations: $T = 0$ evaluation, ring homogenization, +and `natDegree` bounds (§5.3–5.4 & Appendix B.2) -/ + +/-- Evaluating `clearedMonomialPoly d_den k θ M` at `t : ℤ` yields +`d_den ^ (k - #M) * ∏ v ∈ M, (θ v).eval t`. -/ +theorem eval_clearedMonomialPoly (d_den : ℤ) (k : ℕ) (θ : ι → Polynomial ℤ) (M : Finset ι) + (t : ℤ) : + (clearedMonomialPoly d_den k θ M).eval t = + d_den ^ (k - #M) * ∏ v ∈ M, (θ v).eval t := by + rw [clearedMonomialPoly, Polynomial.eval_mul, Polynomial.eval_C, Polynomial.eval_prod] + +/-- At `T = 0`, if `#M ≤ k` and every `θ v` (`v ∈ M`) evaluates to `d_den * bitVal ℤ (x v)`, then +`clearedMonomialPoly d_den k θ M` evaluates to `d_den ^ k * monomial ℤ M x`. -/ +theorem eval_zero_clearedMonomialPoly (d_den : ℤ) {k : ℕ} (θ : ι → Polynomial ℤ) + {M : Finset ι} (x : ι → Bool) (hM : #M ≤ k) + (hθ : ∀ v ∈ M, (θ v).eval 0 = d_den * bitVal ℤ (x v)) : + (clearedMonomialPoly d_den k θ M).eval 0 = d_den ^ k * monomial ℤ M x := by + rw [eval_clearedMonomialPoly, monomial] + have hprod : (∏ v ∈ M, (θ v).eval 0) = d_den ^ #M * ∏ v ∈ M, bitVal ℤ (x v) := by + rw [← prod_const, ← prod_mul_distrib] + exact prod_congr rfl fun v hv => hθ v hv + rw [hprod, ← mul_assoc, ← pow_add, Nat.sub_add_cancel hM] + +/-- **§5.3–5.4 ($T = 0$ evaluation of cleared equation polynomial)**: at `T = 0`, if every +`M ∈ 𝓜` has `#M ≤ k` and every `θ v` (`v ∈ M`) evaluates to `d_den * bitVal ℤ (x v)`, then +`clearedMonomialSumPoly d_den k θ 𝓜` evaluates to `d_den ^ k * monomialSum ℤ 𝓜 x`. -/ +theorem eval_zero_clearedMonomialSumPoly (d_den : ℤ) {k : ℕ} (θ : ι → Polynomial ℤ) + {𝓜 : Finset (Finset ι)} (x : ι → Bool) (hk : ∀ M ∈ 𝓜, #M ≤ k) + (hθ : ∀ M ∈ 𝓜, ∀ v ∈ M, (θ v).eval 0 = d_den * bitVal ℤ (x v)) : + (clearedMonomialSumPoly d_den k θ 𝓜).eval 0 = d_den ^ k * monomialSum ℤ 𝓜 x := by + rw [clearedMonomialSumPoly, Polynomial.eval_finsetSum, monomialSum, mul_sum] + exact sum_congr rfl fun M hM => eval_zero_clearedMonomialPoly d_den θ x (hk M hM) (hθ M hM) + +/-- Mapping `clearedMonomialPoly d_den k θ M` into `R[X]` when `#M ≤ k` and +`(θ v).map (Int.castRingHom R) = C (d_den : R) * q v` yields +`C ((d_den : R) ^ k) * univariateMonomialPoly R q M`. -/ +theorem map_clearedMonomialPoly [CommRing R] (d_den : ℤ) {k : ℕ} (θ : ι → Polynomial ℤ) + (q : ι → Polynomial R) {M : Finset ι} (hM : #M ≤ k) + (hq : ∀ v ∈ M, (θ v).map (Int.castRingHom R) = Polynomial.C (d_den : R) * q v) : + (clearedMonomialPoly d_den k θ M).map (Int.castRingHom R) = + Polynomial.C ((d_den : R) ^ k) * univariateMonomialPoly R q M := by + rw [clearedMonomialPoly, Polynomial.map_mul, Polynomial.map_C, eq_intCast, Int.cast_pow, + Polynomial.map_prod] + have hprod : + (∏ v ∈ M, (θ v).map (Int.castRingHom R)) = + Polynomial.C ((d_den : R) ^ #M) * univariateMonomialPoly R q M := by + rw [univariateMonomialPoly, Polynomial.C_pow, ← prod_const, ← prod_mul_distrib] + exact prod_congr rfl fun v hv => hq v hv + rw [hprod, ← mul_assoc, ← Polynomial.C_mul, ← pow_add, Nat.sub_add_cancel hM] + +/-- **§5.4 (ring homogenization of cleared equation polynomial)**: mapping +`clearedMonomialSumPoly d_den k θ 𝓜` into `R[X]` when `∀ M ∈ 𝓜, #M ≤ k` and +`(θ v).map (Int.castRingHom R) = C (d_den : R) * q v` yields +`C ((d_den : R) ^ k) * univariateMonomialSumPoly R q 𝓜`. -/ +theorem map_clearedMonomialSumPoly [CommRing R] (d_den : ℤ) {k : ℕ} (θ : ι → Polynomial ℤ) + (q : ι → Polynomial R) {𝓜 : Finset (Finset ι)} (hk : ∀ M ∈ 𝓜, #M ≤ k) + (hq : ∀ M ∈ 𝓜, ∀ v ∈ M, (θ v).map (Int.castRingHom R) = Polynomial.C (d_den : R) * q v) : + (clearedMonomialSumPoly d_den k θ 𝓜).map (Int.castRingHom R) = + Polynomial.C ((d_den : R) ^ k) * univariateMonomialSumPoly R q 𝓜 := by + rw [clearedMonomialSumPoly, Polynomial.map_sum, univariateMonomialSumPoly, mul_sum] + exact sum_congr rfl fun M hM => map_clearedMonomialPoly d_den θ q (hk M hM) (hq M hM) + +/-- If every `θ v` (`v ∈ M`) has `natDegree ≤ R_deg`, then `clearedMonomialPoly d_den k θ M` has +`natDegree ≤ #M * R_deg`. -/ +theorem natDegree_clearedMonomialPoly_le (d_den : ℤ) (k : ℕ) (θ : ι → Polynomial ℤ) + {M : Finset ι} {R_deg : ℕ} (hθ : ∀ v ∈ M, (θ v).natDegree ≤ R_deg) : + (clearedMonomialPoly d_den k θ M).natDegree ≤ #M * R_deg := by + rw [clearedMonomialPoly] + exact (Polynomial.natDegree_C_mul_le _ _).trans + (natDegree_univariateMonomialPoly_le le_rfl hθ) + +/-- If every `M ∈ 𝓜` has `#M ≤ k` and every `θ v` (`v ∈ M`) has `natDegree ≤ R_deg`, then +`clearedMonomialSumPoly d_den k θ 𝓜` has `natDegree ≤ k * R_deg`. -/ +theorem natDegree_clearedMonomialSumPoly_le (d_den : ℤ) {k R_deg : ℕ} (θ : ι → Polynomial ℤ) + {𝓜 : Finset (Finset ι)} (hk : ∀ M ∈ 𝓜, #M ≤ k) + (hθ : ∀ M ∈ 𝓜, ∀ v ∈ M, (θ v).natDegree ≤ R_deg) : + (clearedMonomialSumPoly d_den k θ 𝓜).natDegree ≤ k * R_deg := by + rw [clearedMonomialSumPoly] + refine (Polynomial.natDegree_sum_le _ _).trans ?_ + rw [Finset.fold_max_le] + refine ⟨Nat.zero_le _, fun M hM => ?_⟩ + exact (natDegree_clearedMonomialPoly_le d_den k θ (hθ M hM)).trans + (Nat.mul_le_mul_right R_deg (hk M hM)) + +/-! ### 3. Cube-summed cleared-denominator polynomials $\tilde{H}_s(T) = \Omega [V^s] H(T)$ and +exact integer division recovery (§5.4 & Appendix B.2–B.3) -/ + +/-- The common product denominator $\Omega = \Gamma^{m_{\mathrm{test}}} = +((d_{\mathrm{den}}^k)^{2\ell - 1})^{m_{\mathrm{test}}}$ of the product of $m_{\mathrm{test}}$ +cleared parity factors (§5.4 and Appendix B.2). -/ +def clearedProductDenom (d_den : ℤ) (k ℓ m_test : ℕ) : ℤ := + ((d_den ^ k) ^ (2 * ℓ - 1)) ^ m_test + +/-- When `d_den ≠ 0`, `clearedProductDenom d_den k ℓ m_test ≠ 0`. -/ +theorem clearedProductDenom_ne_zero {d_den : ℤ} (hd : d_den ≠ 0) (k ℓ m_test : ℕ) : + clearedProductDenom d_den k ℓ m_test ≠ 0 := + pow_ne_zero m_test (pow_ne_zero (2 * ℓ - 1) (pow_ne_zero k hd)) + +/-- The cube-summed cleared-denominator bivariate polynomial +$\tilde{H}(T, V) = \sum_{x \in \{0, 1\}^\iota} \prod_{i \in I} (\Gamma B_i)(T, V)$ in +`Polynomial (Polynomial ℤ)` (`ℤ[T][V]`). -/ +def univariateClearedParityProduct [Fintype ι] [DecidableEq ι] (I : Finset κ) + (P : κ → Finset (Finset ι)) (d_den : ℤ) (k ℓ : ℕ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) : Polynomial (Polynomial ℤ) := + ∑ x : ι → Bool, + ∏ i ∈ I, + parityFactorCleared ℓ (Polynomial.C (d_den ^ k)) + (clearedMonomialSumPoly d_den k (θ x i) (P i)) + +/-- The $V^s$-coordinate polynomial $\tilde{H}_s(T) = [V^s] \tilde{H}(T) \in \mathbb{Z}[T]$. -/ +def univariateClearedParityCoord [Fintype ι] [DecidableEq ι] (I : Finset κ) + (P : κ → Finset (Finset ι)) (d_den : ℤ) (k ℓ : ℕ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) (s : ℕ) : Polynomial ℤ := + (univariateClearedParityProduct I P d_den k ℓ θ).coeff s + +/-- Explicit cube-sum expansion of `univariateClearedParityCoord`. -/ +theorem univariateClearedParityCoord_eq_sum [Fintype ι] [DecidableEq ι] (I : Finset κ) + (P : κ → Finset (Finset ι)) (d_den : ℤ) (k ℓ : ℕ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) (s : ℕ) : + univariateClearedParityCoord I P d_den k ℓ θ s = + ∑ x : ι → Bool, + (∏ i ∈ I, + parityFactorCleared ℓ (Polynomial.C (d_den ^ k)) + (clearedMonomialSumPoly d_den k (θ x i) (P i))).coeff s := by + rw [univariateClearedParityCoord, univariateClearedParityProduct, Polynomial.finsetSum_coeff] + +/-- The truncated coefficient sum $S_\ell(\tilde{H}(T)) = \sum_{s < \ell} \tilde{H}_s(T) \in +\mathbb{Z}[T]$. -/ +def univariateClearedParityTruncatedSum [Fintype ι] [DecidableEq ι] (I : Finset κ) + (P : κ → Finset (Finset ι)) (d_den : ℤ) (k ℓ : ℕ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) : Polynomial ℤ := + (univariateClearedParityProduct I P d_den k ℓ θ).sumCoeffsBelow ℓ + +/-- `univariateClearedParityTruncatedSum` is the sum of `univariateClearedParityCoord` over +`s ∈ range ℓ`. -/ +theorem univariateClearedParityTruncatedSum_eq_sum_coord [Fintype ι] [DecidableEq ι] + (I : Finset κ) (P : κ → Finset (Finset ι)) (d_den : ℤ) (k ℓ : ℕ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) : + univariateClearedParityTruncatedSum I P d_den k ℓ θ = + ∑ s ∈ range ℓ, univariateClearedParityCoord I P d_den k ℓ θ s := + rfl + +/-- Explicit cube-sum expansion of `univariateClearedParityTruncatedSum`. -/ +theorem univariateClearedParityTruncatedSum_eq_sum [Fintype ι] [DecidableEq ι] (I : Finset κ) + (P : κ → Finset (Finset ι)) (d_den : ℤ) (k ℓ : ℕ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) : + univariateClearedParityTruncatedSum I P d_den k ℓ θ = + ∑ x : ι → Bool, + (∏ i ∈ I, + parityFactorCleared ℓ (Polynomial.C (d_den ^ k)) + (clearedMonomialSumPoly d_den k (θ x i) (P i))).sumCoeffsBelow ℓ := by + rw [univariateClearedParityTruncatedSum, univariateClearedParityProduct, sumCoeffsBelow_sum] + +/-- **Equation (5.5a) (cleared-denominator coordinate `natDegree` bound)**: for `s < ℓ`, if every +equation `P i` (`i ∈ I`) has degree at most `k` and every numerator `θ x i v` has +`natDegree ≤ R_deg`, then `univariateClearedParityCoord I P d_den k ℓ θ s` has +`natDegree ≤ (k * R_deg) * (#I + 2 * (ℓ - 1))`. -/ +theorem natDegree_univariateClearedParityCoord_le [Fintype ι] [DecidableEq ι] (I : Finset κ) + (P : κ → Finset (Finset ι)) (d_den : ℤ) (k ℓ : ℕ) {R_deg s : ℕ} + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hθ : ∀ x : ι → Bool, ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, (θ x i v).natDegree ≤ R_deg) + (hs : s < ℓ) : + (univariateClearedParityCoord I P d_den k ℓ θ s).natDegree ≤ + (k * R_deg) * (#I + 2 * (ℓ - 1)) := by + rw [univariateClearedParityCoord_eq_sum] + refine (Polynomial.natDegree_sum_le _ _).trans ?_ + rw [Finset.fold_max_le] + refine ⟨Nat.zero_le _, fun x _ => ?_⟩ + exact natDegree_coeff_prod_parityFactorCleared_le_of_lt I (Polynomial.C (d_den ^ k)) + (fun i => clearedMonomialSumPoly d_den k (θ x i) (P i)) + (Polynomial.natDegree_C (d_den ^ k)) + (fun i hi => natDegree_clearedMonomialSumPoly_le d_den (θ x i) (hk i hi) (hθ x i hi)) hs + +/-- **Equation (5.5a) (cleared-denominator truncated-sum `natDegree` bound)**: under the same +hypotheses, `univariateClearedParityTruncatedSum I P d_den k ℓ θ` has +`natDegree ≤ (k * R_deg) * (#I + 2 * (ℓ - 1))`. -/ +theorem natDegree_univariateClearedParityTruncatedSum_le [Fintype ι] [DecidableEq ι] + (I : Finset κ) (P : κ → Finset (Finset ι)) (d_den : ℤ) (k ℓ : ℕ) {R_deg : ℕ} + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hθ : ∀ x : ι → Bool, ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, (θ x i v).natDegree ≤ R_deg) : + (univariateClearedParityTruncatedSum I P d_den k ℓ θ).natDegree ≤ + (k * R_deg) * (#I + 2 * (ℓ - 1)) := by + rw [univariateClearedParityTruncatedSum_eq_sum_coord] + refine (Polynomial.natDegree_sum_le _ _).trans ?_ + rw [Finset.fold_max_le] + refine ⟨Nat.zero_le _, fun s hs => ?_⟩ + rw [mem_range] at hs + exact natDegree_univariateClearedParityCoord_le I P d_den k ℓ θ hk hθ hs + +/-- **§5.4 & Appendix B.2–B.3 (homogenization of $\tilde{H}_s(T) = \Omega [V^s] H(T)$)**: +for `1 ≤ ℓ`, if `∀ i ∈ I, ∀ M ∈ P i, #M ≤ k` and every numerator `θ x i v` maps into `R[X]` as +`C (d_den : R) * q x i v`, then mapping `univariateClearedParityCoord I P d_den k ℓ θ s` into +`R[X]` gives `C (clearedProductDenom d_den k ℓ #I : R) * univariateParityCoord I P ℓ q s`. -/ +theorem map_univariateClearedParityCoord [Fintype ι] [DecidableEq ι] [CommRing R] (I : Finset κ) + (P : κ → Finset (Finset ι)) (d_den : ℤ) {k ℓ : ℕ} (hℓ : 1 ≤ ℓ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) (q : (ι → Bool) → κ → ι → Polynomial R) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hq : ∀ x : ι → Bool, ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, + (θ x i v).map (Int.castRingHom R) = Polynomial.C (d_den : R) * q x i v) (s : ℕ) : + (univariateClearedParityCoord I P d_den k ℓ θ s).map (Int.castRingHom R) = + Polynomial.C (clearedProductDenom d_den k ℓ #I : R) * univariateParityCoord I P ℓ q s := by + let φ : Polynomial ℤ →+* Polynomial R := Polynomial.mapRingHom (Int.castRingHom R) + change φ (univariateClearedParityCoord I P d_den k ℓ θ s) = _ + rw [univariateClearedParityCoord_eq_sum, univariateParityCoord_eq_sum, map_sum, mul_sum] + refine sum_congr rfl fun x _ => ?_ + rw [← Polynomial.coeff_map, Polynomial.map_prod] + have hprod : + (∏ i ∈ I, + (parityFactorCleared ℓ (Polynomial.C (d_den ^ k)) + (clearedMonomialSumPoly d_den k (θ x i) (P i))).map φ) = + ∏ i ∈ I, + parityFactorCleared ℓ (Polynomial.C ((d_den : R) ^ k)) + (Polynomial.C ((d_den : R) ^ k) * univariateMonomialSumPoly R (q x i) (P i)) := by + refine prod_congr rfl fun i hi => ?_ + rw [map_parityFactorCleared] + congr 1 + · change (Polynomial.C (d_den ^ k)).map (Int.castRingHom R) = _ + rw [Polynomial.map_C, eq_intCast, Int.cast_pow] + · exact map_clearedMonomialSumPoly d_den (θ x i) (q x i) (hk i hi) (hq x i hi) + rw [hprod, prod_parityFactorCleared_mul I hℓ (Polynomial.C ((d_den : R) ^ k)) + (fun i => univariateMonomialSumPoly R (q x i) (P i)), Polynomial.coeff_C_mul] + congr 1 + simp only [clearedProductDenom, Int.cast_pow, Polynomial.C_pow] + +/-- **§5.4 & Appendix B.2–B.3 (homogenization of $S_\ell(\tilde{H}(T)) = \Omega S_\ell(H(T))$ +over `R[X]`)**: under the same hypotheses, mapping +`univariateClearedParityTruncatedSum I P d_den k ℓ θ` into `R[X]` gives +`C (clearedProductDenom d_den k ℓ #I : R) * univariateParityTruncatedSum I P ℓ q`. -/ +theorem map_univariateClearedParityTruncatedSum [Fintype ι] [DecidableEq ι] [CommRing R] + (I : Finset κ) (P : κ → Finset (Finset ι)) (d_den : ℤ) {k ℓ : ℕ} (hℓ : 1 ≤ ℓ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) (q : (ι → Bool) → κ → ι → Polynomial R) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hq : ∀ x : ι → Bool, ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, + (θ x i v).map (Int.castRingHom R) = Polynomial.C (d_den : R) * q x i v) : + (univariateClearedParityTruncatedSum I P d_den k ℓ θ).map (Int.castRingHom R) = + Polynomial.C (clearedProductDenom d_den k ℓ #I : R) * + univariateParityTruncatedSum I P ℓ q := by + rw [univariateClearedParityTruncatedSum_eq_sum_coord, Polynomial.map_sum, + univariateParityTruncatedSum_eq_sum_coord, mul_sum] + exact sum_congr rfl fun s _ => map_univariateClearedParityCoord I P d_den hℓ θ q hk hq s + +/-- The rational replacement family $r_{x, i, v}(T) = d_{\mathrm{den}}^{-1} \theta_{x, i, v}(T) \in +K[T]$ over a field $K$ associated to an integer numerator family $\theta$ with common denominator +$d_{\mathrm{den}}$. -/ +def divDenomReplacement (K : Type*) [Field K] (d_den : ℤ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) (x : ι → Bool) (i : κ) (v : ι) : Polynomial K := + Polynomial.C ((d_den : K)⁻¹) * (θ x i v).map (Int.castRingHom K) + +/-- Multiplying `divDenomReplacement K d_den θ x i v` by `C (d_den : K)` when `(d_den : K) ≠ 0` +recovers `(θ x i v).map (Int.castRingHom K)`. -/ +theorem C_mul_divDenomReplacement {K : Type*} [Field K] {d_den : ℤ} (hd : (d_den : K) ≠ 0) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) (x : ι → Bool) (i : κ) (v : ι) : + (θ x i v).map (Int.castRingHom K) = + Polynomial.C (d_den : K) * divDenomReplacement K d_den θ x i v := by + rw [divDenomReplacement, ← mul_assoc, ← Polynomial.C_mul, mul_inv_cancel₀ hd, Polynomial.C_1, + one_mul] + +/-- At `T = 0`, if `(d_den : K) ≠ 0` and `(θ x i v).eval 0 = d_den * bitVal ℤ (x v)`, then +`divDenomReplacement K d_den θ x i v` restores `bitVal K (x v)`. -/ +theorem eval_zero_divDenomReplacement {K : Type*} [Field K] {d_den : ℤ} (hd : (d_den : K) ≠ 0) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) {x : ι → Bool} {i : κ} {v : ι} + (hθ : (θ x i v).eval 0 = d_den * bitVal ℤ (x v)) : + (divDenomReplacement K d_den θ x i v).eval 0 = bitVal K (x v) := by + rw [divDenomReplacement, Polynomial.eval_mul, Polynomial.eval_C] + have h0 : (0 : K) = Int.castRingHom K 0 := by rw [map_zero] + have hbit : (bitVal ℤ (x v) : K) = bitVal K (x v) := by + cases x v <;> simp only [bitVal_true, bitVal_false, Int.cast_one, Int.cast_zero] + rw [h0, Polynomial.eval_map_apply, eq_intCast, hθ, Int.cast_mul, hbit, ← mul_assoc, + inv_mul_cancel₀ hd, one_mul] + +/-- **§5.4 & Appendix B.3 ($\tilde{H}_s(T) = \Omega [V^s] H(T)$ over a field $K$)**: when +`(d_den : K) ≠ 0`, `1 ≤ ℓ`, and `∀ i ∈ I, ∀ M ∈ P i, #M ≤ k`, mapping +`univariateClearedParityCoord I P d_den k ℓ θ s` into `K[T]` equals +`C (clearedProductDenom d_den k ℓ #I : K)` times `univariateParityCoord` for +`divDenomReplacement K d_den θ`. -/ +theorem map_univariateClearedParityCoord_divDenomReplacement [Fintype ι] [DecidableEq ι] + {K : Type*} [Field K] (I : Finset κ) (P : κ → Finset (Finset ι)) {d_den : ℤ} + (hd : (d_den : K) ≠ 0) {k ℓ : ℕ} (hℓ : 1 ≤ ℓ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) (s : ℕ) : + (univariateClearedParityCoord I P d_den k ℓ θ s).map (Int.castRingHom K) = + Polynomial.C (clearedProductDenom d_den k ℓ #I : K) * + univariateParityCoord I P ℓ (divDenomReplacement K d_den θ) s := + map_univariateClearedParityCoord I P d_den hℓ θ (divDenomReplacement K d_den θ) hk + (fun x i _ _ _ v _ => C_mul_divDenomReplacement hd θ x i v) s + +/-- **§5.4 & Appendix B.3 ($S_\ell(\tilde{H}(T)) = \Omega S_\ell(H(T))$ over a field $K$)**: under +the same hypotheses, mapping `univariateClearedParityTruncatedSum I P d_den k ℓ θ` into `K[T]` +equals `C (clearedProductDenom d_den k ℓ #I : K)` times `univariateParityTruncatedSum` for +`divDenomReplacement K d_den θ`. -/ +theorem map_univariateClearedParityTruncatedSum_divDenomReplacement [Fintype ι] [DecidableEq ι] + {K : Type*} [Field K] (I : Finset κ) (P : κ → Finset (Finset ι)) {d_den : ℤ} + (hd : (d_den : K) ≠ 0) {k ℓ : ℕ} (hℓ : 1 ≤ ℓ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) : + (univariateClearedParityTruncatedSum I P d_den k ℓ θ).map (Int.castRingHom K) = + Polynomial.C (clearedProductDenom d_den k ℓ #I : K) * + univariateParityTruncatedSum I P ℓ (divDenomReplacement K d_den θ) := + map_univariateClearedParityTruncatedSum I P d_den hℓ θ (divDenomReplacement K d_den θ) hk + (fun x i _ _ _ v _ => C_mul_divDenomReplacement hd θ x i v) + +/-- **§5.4 & Appendix B.3 (exact integer factorization of $\tilde{H}_s(0)$ at $T = 0$)**: +for `1 ≤ ℓ`, if `∀ i ∈ I, ∀ M ∈ P i, #M ≤ k` and every `θ x i v` evaluates at `0` to +`d_den * bitVal ℤ (x v)`, then `(univariateClearedParityCoord I P d_den k ℓ θ s).eval 0` equals +`clearedProductDenom d_den k ℓ #I` times the integer value of `[V^s] H(0)`. -/ +theorem eval_zero_univariateClearedParityCoord [Fintype ι] [DecidableEq ι] (I : Finset κ) + (P : κ → Finset (Finset ι)) (d_den : ℤ) {k ℓ : ℕ} (hℓ : 1 ≤ ℓ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hθ : ∀ x : ι → Bool, ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, + (θ x i v).eval 0 = d_den * bitVal ℤ (x v)) (s : ℕ) : + (univariateClearedParityCoord I P d_den k ℓ θ s).eval 0 = + clearedProductDenom d_den k ℓ #I * + ∑ x : ι → Bool, + (∏ i ∈ I, Polynomial.parityFactor ℓ (monomialSum ℤ (P i) x)).coeff s := by + rw [univariateClearedParityCoord_eq_sum, Polynomial.eval_finsetSum, mul_sum] + refine sum_congr rfl fun x _ => ?_ + rw [eval_coeff_prod_parityFactorCleared, Polynomial.eval_C] + have hprod : + (∏ i ∈ I, + parityFactorCleared ℓ (d_den ^ k) + ((clearedMonomialSumPoly d_den k (θ x i) (P i)).eval 0)) = + ∏ i ∈ I, + parityFactorCleared ℓ (d_den ^ k) (d_den ^ k * monomialSum ℤ (P i) x) := by + refine prod_congr rfl fun i hi => ?_ + rw [eval_zero_clearedMonomialSumPoly d_den (θ x i) x (hk i hi) (hθ x i hi)] + rw [hprod, prod_parityFactorCleared_mul I hℓ (d_den ^ k) (fun i => monomialSum ℤ (P i) x), + Polynomial.coeff_C_mul, clearedProductDenom] + +/-- **§5.4 & Appendix B.3 (exact integer factorization of $S_\ell(\tilde{H})(0)$ at $T = 0$)**: +under the same hypotheses, `(univariateClearedParityTruncatedSum I P d_den k ℓ θ).eval 0` equals +`clearedProductDenom d_den k ℓ #I` times the integer value of $S_\ell(H(0))$. -/ +theorem eval_zero_univariateClearedParityTruncatedSum [Fintype ι] [DecidableEq ι] (I : Finset κ) + (P : κ → Finset (Finset ι)) (d_den : ℤ) {k ℓ : ℕ} (hℓ : 1 ≤ ℓ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hθ : ∀ x : ι → Bool, ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, + (θ x i v).eval 0 = d_den * bitVal ℤ (x v)) : + (univariateClearedParityTruncatedSum I P d_den k ℓ θ).eval 0 = + clearedProductDenom d_den k ℓ #I * + ∑ x : ι → Bool, + (∏ i ∈ I, Polynomial.parityFactor ℓ (monomialSum ℤ (P i) x)).sumCoeffsBelow ℓ := by + rw [univariateClearedParityTruncatedSum_eq_sum_coord, Polynomial.eval_finsetSum] + have hsum : + (∑ s ∈ range ℓ, (univariateClearedParityCoord I P d_den k ℓ θ s).eval 0) = + ∑ s ∈ range ℓ, + clearedProductDenom d_den k ℓ #I * + ∑ x : ι → Bool, + (∏ i ∈ I, Polynomial.parityFactor ℓ (monomialSum ℤ (P i) x)).coeff s := + sum_congr rfl fun s _ => eval_zero_univariateClearedParityCoord I P d_den hℓ θ hk hθ s + rw [hsum, ← mul_sum, sum_comm] + rfl + +/-- **Appendix B.3 (exact divisibility of $\tilde{H}_s(0)$ by $\Omega$)**: under the hypotheses of +`eval_zero_univariateClearedParityCoord`, `clearedProductDenom d_den k ℓ #I` divides +`(univariateClearedParityCoord I P d_den k ℓ θ s).eval 0` in `ℤ`. -/ +theorem dvd_eval_zero_univariateClearedParityCoord [Fintype ι] [DecidableEq ι] (I : Finset κ) + (P : κ → Finset (Finset ι)) (d_den : ℤ) {k ℓ : ℕ} (hℓ : 1 ≤ ℓ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hθ : ∀ x : ι → Bool, ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, + (θ x i v).eval 0 = d_den * bitVal ℤ (x v)) (s : ℕ) : + clearedProductDenom d_den k ℓ #I ∣ + (univariateClearedParityCoord I P d_den k ℓ θ s).eval 0 := + ⟨_, eval_zero_univariateClearedParityCoord I P d_den hℓ θ hk hθ s⟩ + +/-- **Appendix B.3 (exact integer quotient $\tilde{H}_s(0) / \Omega = H_s(0)$)**: when in addition +`d_den ≠ 0`, exact integer division of `(univariateClearedParityCoord I P d_den k ℓ θ s).eval 0` +by `clearedProductDenom d_den k ℓ #I` recovers the integer coefficient sum +`∑ x : ι → Bool, (∏ i ∈ I, parityFactor ℓ (monomialSum ℤ (P i) x)).coeff s`. -/ +theorem ediv_eval_zero_univariateClearedParityCoord [Fintype ι] [DecidableEq ι] (I : Finset κ) + (P : κ → Finset (Finset ι)) {d_den : ℤ} (hd : d_den ≠ 0) {k ℓ : ℕ} (hℓ : 1 ≤ ℓ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hθ : ∀ x : ι → Bool, ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, + (θ x i v).eval 0 = d_den * bitVal ℤ (x v)) (s : ℕ) : + (univariateClearedParityCoord I P d_den k ℓ θ s).eval 0 / + clearedProductDenom d_den k ℓ #I = + ∑ x : ι → Bool, + (∏ i ∈ I, Polynomial.parityFactor ℓ (monomialSum ℤ (P i) x)).coeff s := by + rw [eval_zero_univariateClearedParityCoord I P d_den hℓ θ hk hθ s, + Int.mul_ediv_cancel_left _ (clearedProductDenom_ne_zero hd k ℓ #I)] + +/-- **§5.4 & Appendix B.3 (exact modular recovery of `commonZeroCount` from coordinate quotients +$\tilde{H}_s(0) / \Omega$)**: when `Fintype.card ι < ℓ` and `d_den ≠ 0`, summing the exact integer +quotients `(univariateClearedParityCoord I P d_den k ℓ θ s).eval 0 / Ω` over `s ∈ range ℓ` and +reducing modulo `2 ^ ℓ` recovers `commonZeroCount I P`. -/ +theorem emod_sum_ediv_eval_zero_univariateClearedParityCoord_eq_commonZeroCount + [Fintype ι] [DecidableEq ι] (I : Finset κ) (P : κ → Finset (Finset ι)) {d_den : ℤ} + (hd : d_den ≠ 0) {k ℓ : ℕ} (hℓ : Fintype.card ι < ℓ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hθ : ∀ x : ι → Bool, ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, + (θ x i v).eval 0 = d_den * bitVal ℤ (x v)) : + (∑ s ∈ range ℓ, + (univariateClearedParityCoord I P d_den k ℓ θ s).eval 0 / + clearedProductDenom d_den k ℓ #I) % ((2 : ℤ) ^ ℓ) = + commonZeroCount I P := by + have hℓ1 : 1 ≤ ℓ := by omega + have hsum : + (∑ s ∈ range ℓ, + (univariateClearedParityCoord I P d_den k ℓ θ s).eval 0 / + clearedProductDenom d_den k ℓ #I) = + ∑ x : ι → Bool, + (∏ i ∈ I, Polynomial.parityFactor ℓ (monomialSum ℤ (P i) x)).sumCoeffsBelow ℓ := by + calc + (∑ s ∈ range ℓ, + (univariateClearedParityCoord I P d_den k ℓ θ s).eval 0 / + clearedProductDenom d_den k ℓ #I) + = ∑ s ∈ range ℓ, + ∑ x : ι → Bool, + (∏ i ∈ I, Polynomial.parityFactor ℓ (monomialSum ℤ (P i) x)).coeff s := + sum_congr rfl fun s _ => + ediv_eval_zero_univariateClearedParityCoord I P hd hℓ1 θ hk hθ s + _ = ∑ x : ι → Bool, + (∏ i ∈ I, Polynomial.parityFactor ℓ (monomialSum ℤ (P i) x)).sumCoeffsBelow ℓ := by + rw [sum_comm] + rfl + rw [hsum] + exact emod_sum_sumCoeffsBelow_prod_parityFactor_eq_commonZeroCount I P hℓ + +/-- **§5.4 & Appendix B.3 (exact modular recovery of `commonZeroCount` from +$S_\ell(\tilde{H})(0) / \Omega$)**: under the same hypotheses, dividing +`(univariateClearedParityTruncatedSum I P d_den k ℓ θ).eval 0` by `clearedProductDenom d_den k ℓ #I` +and reducing modulo `2 ^ ℓ` recovers `commonZeroCount I P`. -/ +theorem emod_ediv_eval_zero_univariateClearedParityTruncatedSum_eq_commonZeroCount + [Fintype ι] [DecidableEq ι] (I : Finset κ) (P : κ → Finset (Finset ι)) {d_den : ℤ} + (hd : d_den ≠ 0) {k ℓ : ℕ} (hℓ : Fintype.card ι < ℓ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hθ : ∀ x : ι → Bool, ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, + (θ x i v).eval 0 = d_den * bitVal ℤ (x v)) : + ((univariateClearedParityTruncatedSum I P d_den k ℓ θ).eval 0 / + clearedProductDenom d_den k ℓ #I) % ((2 : ℤ) ^ ℓ) = + commonZeroCount I P := by + have hℓ1 : 1 ≤ ℓ := by omega + rw [eval_zero_univariateClearedParityTruncatedSum I P d_den hℓ1 θ hk hθ, + Int.mul_ediv_cancel_left _ (clearedProductDenom_ne_zero hd k ℓ #I)] + exact emod_sum_sumCoeffsBelow_prod_parityFactor_eq_commonZeroCount I P hℓ + +/-- **Appendix B.3 (eq. B.1, Cramer's rule determinant exact division recovery)**: if +`N_H : ℕ → ℤ` and `D_H : ℤ` (`D_H ≠ 0`) satisfy +`N_H s = D_H * (univariateClearedParityCoord I P d_den k ℓ θ s).eval 0` for all `s ∈ range ℓ` +(as in $N_H = \det V^{(0)} = (\det V) \cdot \Omega H_s(0)$), then for `d_den ≠ 0` and +`Fintype.card ι < ℓ`, summing the exact integer quotients +`N_H s / (clearedProductDenom d_den k ℓ #I * D_H)` over `s ∈ range ℓ` and reducing modulo `2 ^ ℓ` +recovers `commonZeroCount I P`. -/ +theorem emod_sum_cramer_ediv_eq_commonZeroCount [Fintype ι] [DecidableEq ι] (I : Finset κ) + (P : κ → Finset (Finset ι)) {d_den D_H : ℤ} (hd : d_den ≠ 0) (hDH : D_H ≠ 0) + {k ℓ : ℕ} (hℓ : Fintype.card ι < ℓ) + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) (N_H : ℕ → ℤ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hθ : ∀ x : ι → Bool, ∀ i ∈ I, ∀ M ∈ P i, ∀ v ∈ M, + (θ x i v).eval 0 = d_den * bitVal ℤ (x v)) + (hcramer : ∀ s ∈ range ℓ, + N_H s = D_H * (univariateClearedParityCoord I P d_den k ℓ θ s).eval 0) : + (∑ s ∈ range ℓ, N_H s / (clearedProductDenom d_den k ℓ #I * D_H)) % ((2 : ℤ) ^ ℓ) = + commonZeroCount I P := by + have hℓ1 : 1 ≤ ℓ := by omega + have hcongr : + (∑ s ∈ range ℓ, N_H s / (clearedProductDenom d_den k ℓ #I * D_H)) = + ∑ s ∈ range ℓ, + (univariateClearedParityCoord I P d_den k ℓ θ s).eval 0 / + clearedProductDenom d_den k ℓ #I := by + refine sum_congr rfl fun s hs => ?_ + rw [hcramer s hs, eval_zero_univariateClearedParityCoord I P d_den hℓ1 θ hk hθ s] + have hmul : + D_H * (clearedProductDenom d_den k ℓ #I * + ∑ x : ι → Bool, + (∏ i ∈ I, Polynomial.parityFactor ℓ (monomialSum ℤ (P i) x)).coeff s) = + (clearedProductDenom d_den k ℓ #I * D_H) * + ∑ x : ι → Bool, + (∏ i ∈ I, Polynomial.parityFactor ℓ (monomialSum ℤ (P i) x)).coeff s := by + ring + rw [hmul, + Int.mul_ediv_cancel_left _ (mul_ne_zero (clearedProductDenom_ne_zero hd k ℓ #I) hDH), + Int.mul_ediv_cancel_left _ (clearedProductDenom_ne_zero hd k ℓ #I)] + rw [hcongr] + exact emod_sum_ediv_eval_zero_univariateClearedParityCoord_eq_commonZeroCount I P hd hℓ θ hk hθ + +/-- **§5.5 & Appendix B.3 (branch-summed exact integer division recovery at shared precision +$\ell = n + 1$)**: summing the branch modular residues of +`((univariateClearedParityTruncatedSum ...).eval 0 / clearedProductDenom ...)` at precision +`branchPrecision (Fintype.card ι)` across all `b ∈ branchAssignments S` recovers +`commonZeroCount I P`. -/ +theorem commonZeroCount_eq_sum_branch_emod_ediv_cleared {ι' : Type*} [Fintype ι] [DecidableEq ι] + [Fintype ι'] [DecidableEq ι'] (S : Finset ι) (e : ↥(univ \ S) ≃ ι') + (I : Finset κ) (P : κ → Finset (Finset ι)) {d_den : ℤ} (hd : d_den ≠ 0) {k : ℕ} + (θ : (ι → Bool) → (ι' → Bool) → κ → ι' → Polynomial ℤ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hθ : ∀ b ∈ branchAssignments S, ∀ x : ι' → Bool, ∀ i ∈ I, + ∀ M ∈ relabelRestrictedMonomials S e b (P i), ∀ v ∈ M, + (θ b x i v).eval 0 = d_den * bitVal ℤ (x v)) : + (commonZeroCount I P : ℤ) = + ∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum I + (fun i => relabelRestrictedMonomials S e b (P i)) + d_den k (branchPrecision (Fintype.card ι)) (θ b)).eval 0 / + clearedProductDenom d_den k (branchPrecision (Fintype.card ι)) #I) % + ((2 : ℤ) ^ branchPrecision (Fintype.card ι)) := by + rw [commonZeroCount_eq_sum_relabelRestrictedMonomials S e I P, Nat.cast_sum] + refine sum_congr rfl fun b hb => ?_ + have hlt : Fintype.card ι' < branchPrecision (Fintype.card ι) := by + have hle : Fintype.card ι' ≤ Fintype.card ι := by + rw [← Fintype.card_congr e, Fintype.card_coe] + exact card_le_univ _ + rw [branchPrecision] + omega + have hk_branch : ∀ i ∈ I, ∀ M ∈ relabelRestrictedMonomials S e b (P i), #M ≤ k := + fun i hi M hM => card_mem_relabelRestrictedMonomials_le (hk i hi) M hM + exact (emod_ediv_eval_zero_univariateClearedParityTruncatedSum_eq_commonZeroCount I + (fun i => relabelRestrictedMonomials S e b (P i)) hd hlt (θ b) hk_branch (hθ b hb)).symm + +/-! ### 4. Bivariate `ℓ₁`-norm bounds for cleared parity products and coordinates +(Appendix B.2) -/ + +/-- **Appendix B.2 (`∥Γ B_i∥₁ ≤ B₁ = ℓ E_ℓ (B + |Δ|)^{2ℓ - 1}`)**: if `A_i.coeffNorm1 ≤ B` and +`∀ s < ℓ, (parityBaseDigit ℓ s).coeffNorm1 ≤ E_ℓ`, then +`(parityFactorCleared ℓ (C Δ) A_i).bivariateCoeffNorm1 ≤ ℓ * E_ℓ * (B + Δ.natAbs) ^ (2 * ℓ - 1)`. -/ +theorem bivariateCoeffNorm1_parityFactorCleared_le (ℓ : ℕ) (Δ : ℤ) + {A_i : Polynomial ℤ} {B E_ℓ : ℕ} (hA : A_i.coeffNorm1 ≤ B) + (hE : ∀ s < ℓ, (Polynomial.parityBaseDigit ℓ s).coeffNorm1 ≤ E_ℓ) : + (parityFactorCleared ℓ (Polynomial.C Δ) A_i).bivariateCoeffNorm1 ≤ + ℓ * E_ℓ * (B + Δ.natAbs) ^ (2 * ℓ - 1) := by + have hsub : (parityFactorCleared ℓ (Polynomial.C Δ) A_i).support ⊆ range ℓ := by + intro s hs + rw [Polynomial.mem_support_iff, coeff_parityFactorCleared] at hs + by_contra hns + rw [mem_range] at hns + exact hs (ite_eq_right hns) + rw [Polynomial.bivariateCoeffNorm1_eq_sum_of_support_subset hsub] + calc + (∑ s ∈ range ℓ, ((parityFactorCleared ℓ (Polynomial.C Δ) A_i).coeff s).coeffNorm1) + ≤ ∑ _s ∈ range ℓ, E_ℓ * (B + Δ.natAbs) ^ (2 * ℓ - 1) := by + refine sum_le_sum fun s hs => ?_ + rw [mem_range] at hs + exact (coeffNorm1_coeff_parityFactorCleared_le ℓ Δ hA s).trans + (Nat.mul_le_mul_right _ (hE s hs)) + _ = ℓ * E_ℓ * (B + Δ.natAbs) ^ (2 * ℓ - 1) := by + rw [sum_const, card_range, smul_eq_mul, ← mul_assoc] + +/-- **Appendix B.2 (`∥Ω ∏_{i ∈ I} B_i∥₁ ≤ B₁ ^ #I`)**: under the same bounds for every `i ∈ I`, +the product of cleared parity factors has `bivariateCoeffNorm1` at most +`(ℓ * E_ℓ * (B + Δ.natAbs) ^ (2 * ℓ - 1)) ^ #I`. -/ +theorem bivariateCoeffNorm1_prod_parityFactorCleared_le (I : Finset κ) (ℓ : ℕ) (Δ : ℤ) + {A_i : κ → Polynomial ℤ} {B E_ℓ : ℕ} + (hA : ∀ i ∈ I, (A_i i).coeffNorm1 ≤ B) + (hE : ∀ s < ℓ, (Polynomial.parityBaseDigit ℓ s).coeffNorm1 ≤ E_ℓ) : + (∏ i ∈ I, parityFactorCleared ℓ (Polynomial.C Δ) (A_i i)).bivariateCoeffNorm1 ≤ + (ℓ * E_ℓ * (B + Δ.natAbs) ^ (2 * ℓ - 1)) ^ #I := by + calc + (∏ i ∈ I, parityFactorCleared ℓ (Polynomial.C Δ) (A_i i)).bivariateCoeffNorm1 + ≤ ∏ i ∈ I, (parityFactorCleared ℓ (Polynomial.C Δ) (A_i i)).bivariateCoeffNorm1 := + Polynomial.bivariateCoeffNorm1_prod_le I _ + _ ≤ ∏ _i ∈ I, (ℓ * E_ℓ * (B + Δ.natAbs) ^ (2 * ℓ - 1)) := + prod_le_prod fun i hi => bivariateCoeffNorm1_parityFactorCleared_le ℓ Δ (hA i hi) hE + _ = (ℓ * E_ℓ * (B + Δ.natAbs) ^ (2 * ℓ - 1)) ^ #I := prod_const _ + +/-- **Appendix B.2 (`∥[V^s] \tilde{H}(T)∥₁ ≤ 2 ^ n * B₁ ^ #I`)**: if every cleared equation +polynomial `clearedMonomialSumPoly d_den k (θ x i) (P i)` has `coeffNorm1 ≤ B` and +`∀ j < ℓ, (parityBaseDigit ℓ j).coeffNorm1 ≤ E_ℓ`, then every coordinate polynomial +`univariateClearedParityCoord I P d_den k ℓ θ s` has `coeffNorm1` at most +`2 ^ Fintype.card ι * (ℓ * E_ℓ * (B + (d_den ^ k).natAbs) ^ (2 * ℓ - 1)) ^ #I`. -/ +theorem coeffNorm1_univariateClearedParityCoord_le [Fintype ι] [DecidableEq ι] (I : Finset κ) + (P : κ → Finset (Finset ι)) (d_den : ℤ) (k ℓ : ℕ) {B E_ℓ : ℕ} + (θ : (ι → Bool) → κ → ι → Polynomial ℤ) + (hA : ∀ x : ι → Bool, ∀ i ∈ I, + (clearedMonomialSumPoly d_den k (θ x i) (P i)).coeffNorm1 ≤ B) + (hE : ∀ j < ℓ, (Polynomial.parityBaseDigit ℓ j).coeffNorm1 ≤ E_ℓ) (s : ℕ) : + (univariateClearedParityCoord I P d_den k ℓ θ s).coeffNorm1 ≤ + 2 ^ Fintype.card ι * (ℓ * E_ℓ * (B + (d_den ^ k).natAbs) ^ (2 * ℓ - 1)) ^ #I := by + calc + (univariateClearedParityCoord I P d_den k ℓ θ s).coeffNorm1 + ≤ (univariateClearedParityProduct I P d_den k ℓ θ).bivariateCoeffNorm1 := + Polynomial.coeffNorm1_coeff_le_bivariateCoeffNorm1 _ s + _ ≤ ∑ x : ι → Bool, + (∏ i ∈ I, + parityFactorCleared ℓ (Polynomial.C (d_den ^ k)) + (clearedMonomialSumPoly d_den k (θ x i) (P i))).bivariateCoeffNorm1 := + Polynomial.bivariateCoeffNorm1_sum_le univ _ + _ ≤ ∑ _x : ι → Bool, (ℓ * E_ℓ * (B + (d_den ^ k).natAbs) ^ (2 * ℓ - 1)) ^ #I := + sum_le_sum fun x _ => + bivariateCoeffNorm1_prod_parityFactorCleared_le I ℓ (d_den ^ k) (hA x) hE + _ = 2 ^ Fintype.card ι * (ℓ * E_ℓ * (B + (d_den ^ k).natAbs) ^ (2 * ℓ - 1)) ^ #I := by + rw [sum_const, card_univ, Fintype.card_fun, Fintype.card_bool, smul_eq_mul] + +end Cslib.BitString diff --git a/Complexity/Foundations/Data/Polynomial/BivariateCoeffNorm1.lean b/Complexity/Foundations/Data/Polynomial/BivariateCoeffNorm1.lean new file mode 100644 index 0000000000..5e1241c67d --- /dev/null +++ b/Complexity/Foundations/Data/Polynomial/BivariateCoeffNorm1.lean @@ -0,0 +1,201 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Foundations.Data.Polynomial.CoeffNorm1 +import Mathlib.Data.Finset.Sum + +/-! +# Total `ℓ₁` Coefficient Norm of Bivariate Integer Polynomials + +This module defines the total bivariate `ℓ₁` coefficient norm `Polynomial.bivariateCoeffNorm1` of a +polynomial `P : Polynomial (Polynomial ℤ)` (representing `P(T, V) ∈ ℤ[T][V]`), defined as the sum +over `s ∈ P.support` of `(P.coeff s).coeffNorm1`, and proves its basic triangle and +submultiplicativity inequalities. These bounds are used in Appendix B.2 of +[OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] to bound the coefficient size +of cleared-denominator parity-amplifier products. + +## Main definitions + +* `Polynomial.bivariateCoeffNorm1`: the total `ℓ₁` norm + `∑ s ∈ P.support, (P.coeff s).coeffNorm1` of `P : Polynomial (Polynomial ℤ)`. + +## Main results + +* `Polynomial.coeffNorm1_coeff_le_bivariateCoeffNorm1`: every `V^s`-coefficient has `coeffNorm1` + at most `P.bivariateCoeffNorm1`. +* `Polynomial.bivariateCoeffNorm1_add_le`, `Polynomial.bivariateCoeffNorm1_sum_le`: triangle + inequalities for `bivariateCoeffNorm1`. +* `Polynomial.bivariateCoeffNorm1_mul_le`, `Polynomial.bivariateCoeffNorm1_prod_le`: + submultiplicativity of `bivariateCoeffNorm1` on `Polynomial (Polynomial ℤ)`. +-/ + +@[expose] public noncomputable section + +namespace Polynomial + +open Finset + +/-- The total bivariate `ℓ₁` coefficient norm `∑ s ∈ P.support, (P.coeff s).coeffNorm1` of a +polynomial `P : Polynomial (Polynomial ℤ)`. -/ +def bivariateCoeffNorm1 (P : Polynomial (Polynomial ℤ)) : ℕ := + ∑ s ∈ P.support, (P.coeff s).coeffNorm1 + +/-- `bivariateCoeffNorm1 0 = 0`. -/ +@[simp] +theorem bivariateCoeffNorm1_zero : bivariateCoeffNorm1 0 = 0 := by + simp only [bivariateCoeffNorm1, support_zero, sum_empty] + +/-- `bivariateCoeffNorm1 (C c) = c.coeffNorm1`. -/ +@[simp] +theorem bivariateCoeffNorm1_C (c : Polynomial ℤ) : + (C c).bivariateCoeffNorm1 = c.coeffNorm1 := by + by_cases hc : c = 0 + · subst hc + simp only [C_0, bivariateCoeffNorm1_zero, coeffNorm1_zero] + · rw [bivariateCoeffNorm1, support_C hc, sum_singleton, coeff_C_zero] + +/-- `bivariateCoeffNorm1 1 = 1`. -/ +@[simp] +theorem bivariateCoeffNorm1_one : (1 : Polynomial (Polynomial ℤ)).bivariateCoeffNorm1 = 1 := by + rw [← C_1, bivariateCoeffNorm1_C, coeffNorm1_one] + +/-- Every `V^s`-coefficient of `P` has `coeffNorm1` at most `P.bivariateCoeffNorm1`. -/ +theorem coeffNorm1_coeff_le_bivariateCoeffNorm1 (P : Polynomial (Polynomial ℤ)) (s : ℕ) : + (P.coeff s).coeffNorm1 ≤ P.bivariateCoeffNorm1 := by + by_cases hs : s ∈ P.support + · exact single_le_sum (f := fun i => (P.coeff i).coeffNorm1) (fun _ _ => Nat.zero_le _) hs + · rw [notMem_support_iff.mp hs, coeffNorm1_zero] + exact Nat.zero_le _ + +/-- If `P.support ⊆ S`, then `P.bivariateCoeffNorm1 = ∑ s ∈ S, (P.coeff s).coeffNorm1`. -/ +theorem bivariateCoeffNorm1_eq_sum_of_support_subset {P : Polynomial (Polynomial ℤ)} + {S : Finset ℕ} (hS : P.support ⊆ S) : + P.bivariateCoeffNorm1 = ∑ s ∈ S, (P.coeff s).coeffNorm1 := by + rw [bivariateCoeffNorm1] + refine sum_subset hS fun s _ hs => ?_ + rw [notMem_support_iff.mp hs, coeffNorm1_zero] + +/-- Triangle inequality for `bivariateCoeffNorm1`. -/ +theorem bivariateCoeffNorm1_add_le (P Q : Polynomial (Polynomial ℤ)) : + (P + Q).bivariateCoeffNorm1 ≤ P.bivariateCoeffNorm1 + Q.bivariateCoeffNorm1 := by + classical + let S := P.support ∪ Q.support + have hPQ : (P + Q).support ⊆ S := support_add + have hP : P.support ⊆ S := subset_union_left + have hQ : Q.support ⊆ S := subset_union_right + rw [bivariateCoeffNorm1_eq_sum_of_support_subset hPQ, + bivariateCoeffNorm1_eq_sum_of_support_subset hP, + bivariateCoeffNorm1_eq_sum_of_support_subset hQ, ← sum_add_distrib] + refine sum_le_sum fun s _ => ?_ + rw [coeff_add] + exact coeffNorm1_add_le _ _ + +/-- Finite-sum triangle inequality for `bivariateCoeffNorm1`. -/ +theorem bivariateCoeffNorm1_sum_le {α : Type*} (s : Finset α) + (f : α → Polynomial (Polynomial ℤ)) : + (∑ a ∈ s, f a).bivariateCoeffNorm1 ≤ ∑ a ∈ s, (f a).bivariateCoeffNorm1 := by + classical + induction s using Finset.induction_on with + | empty => + simp only [sum_empty, bivariateCoeffNorm1_zero, le_rfl] + | insert a s ha ih => + rw [sum_insert ha, sum_insert ha] + exact (bivariateCoeffNorm1_add_le _ _).trans (Nat.add_le_add_left ih _) + +/-- Multiplying by `C c` (`c : Polynomial ℤ`) scales `bivariateCoeffNorm1` by at most +`c.coeffNorm1`. -/ +theorem bivariateCoeffNorm1_C_mul_le (c : Polynomial ℤ) (P : Polynomial (Polynomial ℤ)) : + (C c * P).bivariateCoeffNorm1 ≤ c.coeffNorm1 * P.bivariateCoeffNorm1 := by + have hsub : (C c * P).support ⊆ P.support := by + intro s hs + rw [mem_support_iff, coeff_C_mul] at hs + exact mem_support_iff.mpr (right_ne_zero_of_mul hs) + calc + (C c * P).bivariateCoeffNorm1 + ≤ ∑ s ∈ P.support, ((C c * P).coeff s).coeffNorm1 := + sum_le_sum_of_subset hsub + _ ≤ ∑ s ∈ P.support, c.coeffNorm1 * (P.coeff s).coeffNorm1 := by + refine sum_le_sum fun s _ => ?_ + rw [coeff_C_mul] + exact coeffNorm1_mul_le _ _ + _ = c.coeffNorm1 * P.bivariateCoeffNorm1 := by + rw [bivariateCoeffNorm1, mul_sum] + +/-- Multiplying by `X ^ k` does not increase `bivariateCoeffNorm1`. -/ +theorem bivariateCoeffNorm1_mul_X_pow_le (P : Polynomial (Polynomial ℤ)) (k : ℕ) : + (P * X ^ k).bivariateCoeffNorm1 ≤ P.bivariateCoeffNorm1 := by + rw [bivariateCoeffNorm1] + have hsub : + (P * X ^ k).support ⊆ + P.support.map ⟨fun i => i + k, add_left_injective k⟩ := by + intro i hi + rw [mem_support_iff] at hi + rw [mem_map] + by_cases hik : k ≤ i + · refine ⟨i - k, ?_, by simp only [Function.Embedding.coeFn_mk]; omega⟩ + rw [mem_support_iff] + intro h0 + apply hi + have hi_eq : i = i - k + k := (Nat.sub_add_cancel hik).symm + rw [hi_eq, coeff_mul_X_pow, h0] + · exfalso + apply hi + rw [mul_comm, coeff_X_pow_mul'] + simp only [hik, ↓reduceIte] + refine (sum_le_sum_of_subset hsub).trans ?_ + rw [sum_map] + refine le_of_eq (sum_congr rfl fun i _ => ?_) + simp only [Function.Embedding.coeFn_mk, coeff_mul_X_pow] + +/-- `bivariateCoeffNorm1` is submultiplicative on `Polynomial (Polynomial ℤ)`. -/ +theorem bivariateCoeffNorm1_mul_le (P Q : Polynomial (Polynomial ℤ)) : + (P * Q).bivariateCoeffNorm1 ≤ P.bivariateCoeffNorm1 * Q.bivariateCoeffNorm1 := by + have hdecomp : P * Q = ∑ i ∈ P.support, C (P.coeff i) * (Q * X ^ i) := by + conv_lhs => rw [P.as_sum_support_C_mul_X_pow] + rw [sum_mul] + refine sum_congr rfl fun i _ => ?_ + ring + rw [hdecomp] + calc + (∑ i ∈ P.support, C (P.coeff i) * (Q * X ^ i)).bivariateCoeffNorm1 + ≤ ∑ i ∈ P.support, + (C (P.coeff i) * (Q * X ^ i)).bivariateCoeffNorm1 := + bivariateCoeffNorm1_sum_le _ _ + _ ≤ ∑ i ∈ P.support, (P.coeff i).coeffNorm1 * Q.bivariateCoeffNorm1 := by + refine sum_le_sum fun i _ => ?_ + exact (bivariateCoeffNorm1_C_mul_le (P.coeff i) _).trans + (Nat.mul_le_mul_left _ (bivariateCoeffNorm1_mul_X_pow_le Q i)) + _ = P.bivariateCoeffNorm1 * Q.bivariateCoeffNorm1 := by + rw [← sum_mul, ← bivariateCoeffNorm1] + +/-- `bivariateCoeffNorm1` of a power is at most the power of `bivariateCoeffNorm1`. -/ +theorem bivariateCoeffNorm1_pow_le (P : Polynomial (Polynomial ℤ)) (n : ℕ) : + (P ^ n).bivariateCoeffNorm1 ≤ P.bivariateCoeffNorm1 ^ n := by + induction n with + | zero => + simp only [pow_zero, bivariateCoeffNorm1_one, le_rfl] + | succ n ih => + rw [pow_succ, pow_succ] + exact (bivariateCoeffNorm1_mul_le _ _).trans (Nat.mul_le_mul_right _ ih) + +/-- `bivariateCoeffNorm1` of a finite product is at most the product of the +`bivariateCoeffNorm1`s. -/ +theorem bivariateCoeffNorm1_prod_le {κ : Type*} (I : Finset κ) + (F : κ → Polynomial (Polynomial ℤ)) : + (∏ i ∈ I, F i).bivariateCoeffNorm1 ≤ ∏ i ∈ I, (F i).bivariateCoeffNorm1 := by + classical + induction I using Finset.induction_on with + | empty => + simp only [prod_empty, bivariateCoeffNorm1_one, le_rfl] + | insert a I ha ih => + rw [prod_insert ha, prod_insert ha] + exact (bivariateCoeffNorm1_mul_le _ _).trans (Nat.mul_le_mul_left _ ih) + +end Polynomial diff --git a/ComplexityTests/Foundations/Data/Polynomial/BivariateCoeffNorm1.lean b/ComplexityTests/Foundations/Data/Polynomial/BivariateCoeffNorm1.lean new file mode 100644 index 0000000000..ccae7a2582 --- /dev/null +++ b/ComplexityTests/Foundations/Data/Polynomial/BivariateCoeffNorm1.lean @@ -0,0 +1,41 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Foundations.Data.Polynomial.BivariateCoeffNorm1 + +/-! +# Tests for `Complexity.Foundations.Data.Polynomial.BivariateCoeffNorm1` +-/ + +namespace ComplexityTests.BivariateCoeffNorm1 + +open Polynomial + +/-- Concrete check of `bivariateCoeffNorm1_zero`, `bivariateCoeffNorm1_one`, and +`bivariateCoeffNorm1_C`. -/ +example : + (0 : Polynomial (Polynomial ℤ)).bivariateCoeffNorm1 = 0 ∧ + (1 : Polynomial (Polynomial ℤ)).bivariateCoeffNorm1 = 1 ∧ + (C (C (-3 : ℤ))).bivariateCoeffNorm1 = 3 := by + refine ⟨bivariateCoeffNorm1_zero, bivariateCoeffNorm1_one, ?_⟩ + rw [bivariateCoeffNorm1_C, coeffNorm1_C] + rfl + +/-- Concrete check of `coeffNorm1_coeff_le_bivariateCoeffNorm1`, `bivariateCoeffNorm1_add_le`, and +`bivariateCoeffNorm1_mul_le`. -/ +example (P Q : Polynomial (Polynomial ℤ)) (s : ℕ) : + (P.coeff s).coeffNorm1 ≤ P.bivariateCoeffNorm1 ∧ + (P + Q).bivariateCoeffNorm1 ≤ P.bivariateCoeffNorm1 + Q.bivariateCoeffNorm1 ∧ + (P * Q).bivariateCoeffNorm1 ≤ P.bivariateCoeffNorm1 * Q.bivariateCoeffNorm1 := + ⟨coeffNorm1_coeff_le_bivariateCoeffNorm1 P s, + bivariateCoeffNorm1_add_le P Q, + bivariateCoeffNorm1_mul_le P Q⟩ + +end ComplexityTests.BivariateCoeffNorm1 diff --git a/ComplexityTests/SparseClearedSpecialization.lean b/ComplexityTests/SparseClearedSpecialization.lean new file mode 100644 index 0000000000..bb296230f4 --- /dev/null +++ b/ComplexityTests/SparseClearedSpecialization.lean @@ -0,0 +1,136 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Foundations.BooleanAnalysis.SparseClearedSpecialization +public import ComplexityTests.SparseBranching +public import Mathlib.Data.Rat.Defs + +/-! +# Tests for rational-to-cleared-denominator specialization and exact division recovery + +Concrete non-vacuity checks and edge-case controls for +`Complexity.Foundations.BooleanAnalysis.SparseClearedSpecialization`. +-/ + +@[expose] public noncomputable section + +namespace Cslib.BitString + +open Finset + +/-- Cleared-denominator linear replacement numerator `3 * bitVal ℤ (x v) + T` over common +denominator `d_den = 3`, which evaluates to `3 * bitVal ℤ (x v)` at `T = 0`. -/ +def testClearedLinearNumerator (x : Fin 2 → Bool) (_i : Fin 2) (v : Fin 2) : Polynomial ℤ := + Polynomial.C (3 * bitVal ℤ (x v)) + Polynomial.X + +/-- At `T = 0`, `testClearedLinearNumerator x i v` evaluates to `3 * bitVal ℤ (x v)`. -/ +theorem eval_zero_testClearedLinearNumerator (x : Fin 2 → Bool) (i v : Fin 2) : + (testClearedLinearNumerator x i v).eval 0 = 3 * bitVal ℤ (x v) := by + simp only [testClearedLinearNumerator, Polynomial.eval_add, Polynomial.eval_C, + Polynomial.eval_X, add_zero] + +/-- Equation (5.5a) cleared-denominator `natDegree` bound (`k = 2`, `R_deg = 3`, `#I = 2`, `ℓ = 2`, +`d_den = 3`): both `[V ^ 1] \tilde{H}(T)` and `S_2(\tilde{H}(T))` have `natDegree ≤ 24`. -/ +example (θ : (Fin 2 → Bool) → Fin 2 → Fin 2 → Polynomial ℤ) + (hθ : ∀ x : Fin 2 → Bool, ∀ i ∈ (univ : Finset (Fin 2)), ∀ M ∈ testSys i, ∀ v ∈ M, + (θ x i v).natDegree ≤ 3) : + (univariateClearedParityCoord (univ : Finset (Fin 2)) testSys 3 2 2 θ 1).natDegree ≤ 24 ∧ + (univariateClearedParityTruncatedSum (univ : Finset (Fin 2)) testSys 3 2 2 θ).natDegree ≤ + 24 := by + have hk : ∀ i ∈ (univ : Finset (Fin 2)), ∀ M ∈ testSys i, #M ≤ 2 := by + intro _i _ M _ + exact (card_le_univ M).trans (by decide) + exact ⟨(natDegree_univariateClearedParityCoord_le univ testSys 3 2 2 θ hk hθ (by decide)).trans + (by decide), + (natDegree_univariateClearedParityTruncatedSum_le univ testSys 3 2 2 θ hk hθ).trans + (by decide)⟩ + +/-- §5.4 & Appendix B.3 rational homogenization over `ℚ` (`d_den = 3`, `k = 2`, `ℓ = 3`): +mapping `univariateClearedParityCoord` into `ℚ[T]` equals `C (clearedProductDenom 3 2 3 #univ : ℚ)` +times the rational `univariateParityCoord` for `divDenomReplacement ℚ 3`. -/ +example (s : ℕ) : + (univariateClearedParityCoord (univ : Finset (Fin 2)) testSys 3 2 3 + testClearedLinearNumerator s).map (Int.castRingHom ℚ) = + Polynomial.C (clearedProductDenom 3 2 3 #(univ : Finset (Fin 2)) : ℚ) * + univariateParityCoord (univ : Finset (Fin 2)) testSys 3 + (divDenomReplacement ℚ 3 testClearedLinearNumerator) s := by + have hk : ∀ i ∈ (univ : Finset (Fin 2)), ∀ M ∈ testSys i, #M ≤ 2 := by + intro _i _ M _ + exact (card_le_univ M).trans (by decide) + exact map_univariateClearedParityCoord_divDenomReplacement univ testSys (by decide) (by decide) + testClearedLinearNumerator hk s + +/-- §5.4 & Appendix B.3 exact integer division and modular recovery at `T = 0` (`d_den = 3`, +`k = 2`, `ℓ = 3 > Fintype.card (Fin 2)`): dividing each cleared coordinate value at `0` by +`clearedProductDenom 3 2 3 2`, summing over `s ∈ range 3`, and reducing modulo `2 ^ 3 = 8` +recovers `commonZeroCount univ testSys = 1`. -/ +example : + (∑ s ∈ range 3, + (univariateClearedParityCoord (univ : Finset (Fin 2)) testSys 3 2 3 + testClearedLinearNumerator s).eval 0 / + clearedProductDenom 3 2 3 #(univ : Finset (Fin 2))) % ((2 : ℤ) ^ 3) = + commonZeroCount (univ : Finset (Fin 2)) testSys := by + have hk : ∀ i ∈ (univ : Finset (Fin 2)), ∀ M ∈ testSys i, #M ≤ 2 := by + intro _i _ M _ + exact (card_le_univ M).trans (by decide) + exact emod_sum_ediv_eval_zero_univariateClearedParityCoord_eq_commonZeroCount univ testSys + (by decide) (by decide) testClearedLinearNumerator hk + (fun x i _ _ _ v _ => eval_zero_testClearedLinearNumerator x i v) + +/-- Appendix B.3 (eq. B.1) Cramer's rule determinant recovery with `d_den = 3` and `D_H = 5`. -/ +example : + (∑ s ∈ range 3, + (5 * (univariateClearedParityCoord (univ : Finset (Fin 2)) testSys 3 2 3 + testClearedLinearNumerator s).eval 0) / + (clearedProductDenom 3 2 3 #(univ : Finset (Fin 2)) * 5)) % ((2 : ℤ) ^ 3) = + commonZeroCount (univ : Finset (Fin 2)) testSys := by + have hk : ∀ i ∈ (univ : Finset (Fin 2)), ∀ M ∈ testSys i, #M ≤ 2 := by + intro _i _ M _ + exact (card_le_univ M).trans (by decide) + exact emod_sum_cramer_ediv_eq_commonZeroCount univ testSys (by decide) (by decide) (by decide) + testClearedLinearNumerator + (fun s => + 5 * (univariateClearedParityCoord univ testSys 3 2 3 testClearedLinearNumerator s).eval 0) + hk (fun x i _ _ _ v _ => eval_zero_testClearedLinearNumerator x i v) + (fun _ _ => rfl) + +/-- §5.5 & Appendix B.3 branch-summed exact integer division recovery on `testSys` when branching +on `S = {0}` at shared precision `ℓ = branchPrecision 2 = 3`. -/ +example : + (commonZeroCount (univ : Finset (Fin 2)) testSys : ℤ) = + ∑ b ∈ branchAssignments ({0} : Finset (Fin 2)), + ((univariateClearedParityTruncatedSum (univ : Finset (Fin 2)) + (fun i => relabelRestrictedMonomials ({0} : Finset (Fin 2)) + (equivFin (univ \ ({0} : Finset (Fin 2)))) b (testSys i)) + 3 2 (branchPrecision (Fintype.card (Fin 2))) + (fun x _i w => Polynomial.C (3 * bitVal ℤ (x w)) + Polynomial.X)).eval 0 / + clearedProductDenom 3 2 (branchPrecision (Fintype.card (Fin 2))) + #(univ : Finset (Fin 2))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card (Fin 2))) := by + have hk : ∀ i ∈ (univ : Finset (Fin 2)), ∀ M ∈ testSys i, #M ≤ 2 := by + intro _i _ M _ + exact (card_le_univ M).trans (by decide) + refine commonZeroCount_eq_sum_branch_emod_ediv_cleared {0} + (equivFin (univ \ ({0} : Finset (Fin 2)))) univ testSys (by decide) _ hk ?_ + intro _b _hb x _i _hi _M _hM w _hw + simp only [Polynomial.eval_add, Polynomial.eval_C, Polynomial.eval_X, add_zero] + +/-- Appendix B.2 coordinate `coeffNorm1` bound on `testSys` (`d_den = 3`, `k = 2`, `ℓ = 2`, +`B = 10`, `E_ℓ = 100`, `#I = 2`, `n = 2`). -/ +example (θ : (Fin 2 → Bool) → Fin 2 → Fin 2 → Polynomial ℤ) + (hA : ∀ x : Fin 2 → Bool, ∀ i ∈ (univ : Finset (Fin 2)), + (clearedMonomialSumPoly 3 2 (θ x i) (testSys i)).coeffNorm1 ≤ 10) + (hE : ∀ j < 2, (Polynomial.parityBaseDigit 2 j).coeffNorm1 ≤ 100) (s : ℕ) : + (univariateClearedParityCoord (univ : Finset (Fin 2)) testSys 3 2 2 θ s).coeffNorm1 ≤ + 2 ^ Fintype.card (Fin 2) * + (2 * 100 * (10 + ((3 : ℤ) ^ 2).natAbs) ^ (2 * 2 - 1)) ^ #(univ : Finset (Fin 2)) := + coeffNorm1_univariateClearedParityCoord_le univ testSys 3 2 2 θ hA hE s + +end Cslib.BitString From 8728e1f0ad8cb280bf00cb1760e5626bacbad7c6 Mon Sep 17 00:00:00 2001 From: Samuel Schlesinger Date: Tue, 27 Oct 2026 03:09:37 +0000 Subject: [PATCH 10/20] docs,test(BooleanAnalysis,Polynomial): qualify clearing premises and drop signature mirror (#1273) --- .../SparseClearedSpecialization.lean | 50 +++++++++++-------- .../Data/Polynomial/BivariateCoeffNorm1.lean | 10 ---- 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/Complexity/Foundations/BooleanAnalysis/SparseClearedSpecialization.lean b/Complexity/Foundations/BooleanAnalysis/SparseClearedSpecialization.lean index 5603285196..1abdd4fff2 100644 --- a/Complexity/Foundations/BooleanAnalysis/SparseClearedSpecialization.lean +++ b/Complexity/Foundations/BooleanAnalysis/SparseClearedSpecialization.lean @@ -23,31 +23,35 @@ cleared-denominator integer interpolation pipeline of Section 5.4 and Appendix B 1. **Cleared-denominator evaluation at $T = 0$, ring homogenization, and `natDegree` bounds (§5.3–5.4 & Appendix B.2)**: - When each variable $v \in \iota$ in equation $i \in I$ has an integer numerator polynomial - $\theta_{x, i, v}(T) \in \mathbb{Z}[T]$ over a common denominator $d_{\mathrm{den}} \in - \mathbb{Z}$ satisfying $\theta_{x, i, v}(0) = d_{\mathrm{den}} \cdot \mathrm{bitVal}_{\mathbb{Z}} - (x_v)$ and $\deg_T \theta_{x, i, v} \le R_{\mathrm{deg}}$, the cleared-denominator equation - polynomial `Cslib.BitString.clearedMonomialSumPoly` has `natDegree ≤ k * R_deg`, evaluates at - $T = 0$ to $d_{\mathrm{den}}^k \cdot \mathrm{monomialSum}_{\mathbb{Z}}(\mathcal{P}_i, x)$, and - maps into any commutative ring $R$ (such as $\mathbb{Q}$) as $d_{\mathrm{den}}^k$ times - `Cslib.BitString.univariateMonomialSumPoly`. + When every monomial $M \in \mathcal{P}_i$ has size $\#M \le k$ and each variable $v \in M$ in + equation $i \in I$ has an integer numerator polynomial $\theta_{x, i, v}(T) \in \mathbb{Z}[T]$ + over a common denominator $d_{\mathrm{den}} \in \mathbb{Z}$ satisfying + $\theta_{x, i, v}(0) = d_{\mathrm{den}} \cdot \mathrm{bitVal}_{\mathbb{Z}}(x_v)$ and + $\deg_T \theta_{x, i, v} \le R_{\mathrm{deg}}$, the cleared-denominator equation polynomial + `Cslib.BitString.clearedMonomialSumPoly` has `natDegree ≤ k * R_deg`, evaluates at $T = 0$ to + $d_{\mathrm{den}}^k \cdot \mathrm{monomialSum}_{\mathbb{Z}}(\mathcal{P}_i, x)$, and maps into any + commutative ring $R$ as `C ((d_den : R) ^ k)` times `Cslib.BitString.univariateMonomialSumPoly` + whenever `(θ x i v).map (Int.castRingHom R) = C (d_den : R) * q x i v` for all $M \in + \mathcal{P}_i$ and $v \in M$. 2. **Cube-summed cleared-denominator polynomials $\tilde{H}_s(T) = \Omega [V^s] H(T)$ and exact integer division recovery (§5.4 & Appendix B.3, eq. B.1)**: Summing the cleared parity-factor products over $x \in \{0, 1\}^\iota$ yields `Cslib.BitString.univariateClearedParityProduct`, its $V^s$-coordinates `Cslib.BitString.univariateClearedParityCoord` ($\tilde{H}_s(T) \in \mathbb{Z}[T]$), and its - truncated sum `Cslib.BitString.univariateClearedParityTruncatedSum`. Over any field $K$ of - characteristic zero (such as $\mathbb{Q}$), $\tilde{H}_s(T)$ equals the common product - denominator $\Omega = (d_{\mathrm{den}}^k)^{(2\ell - 1)\#I}$ - (`Cslib.BitString.clearedProductDenom`) times the rational coordinate polynomial `[V^s] H(T)` - associated to the rational replacement family `Cslib.BitString.divDenomReplacement` - ($r_{x, i, v}(T) = d_{\mathrm{den}}^{-1} \theta_{x, i, v}(T)$). At $T = 0$, $\tilde{H}_s(0)$ is - an exact integer multiple of $\Omega$; when $d_{\mathrm{den}} \neq 0$ and - `Fintype.card ι < ℓ`, dividing each $\tilde{H}_s(0)$ (or Cramer's rule determinant numerator - $N_{H, s} = D_H \tilde{H}_s(0)$ in eq. B.1) by $\Omega$ (or $\Omega D_H$), summing over - $0 \le s < \ell$, and reducing modulo $2^\ell$ recovers `commonZeroCount I P` on the nose, both - on a single problem and summed across all heavy-variable branches at shared precision - $\ell = n + 1$. + truncated sum `Cslib.BitString.univariateClearedParityTruncatedSum`. Over any field $K$ with + $(d_{\mathrm{den}} : K) \neq 0$, $1 \le \ell$, and $\forall i \in I, \forall M \in \mathcal{P}_i, + \#M \le k$, $\tilde{H}_s(T)$ maps into $K[T]$ as the common product denominator + $\Omega = (d_{\mathrm{den}}^k)^{(2\ell - 1)\#I}$ (`Cslib.BitString.clearedProductDenom`) times + the rational coordinate polynomial `[V^s] H(T)` associated to the rational replacement family + `Cslib.BitString.divDenomReplacement` ($r_{x, i, v}(T) = d_{\mathrm{den}}^{-1} + \theta_{x, i, v}(T)$). At $T = 0$, when $1 \le \ell$, $\#M \le k$, and + $\theta_{x, i, v}(0) = d_{\mathrm{den}} \cdot \mathrm{bitVal}_{\mathbb{Z}}(x_v)$, + $\tilde{H}_s(0)$ is an exact integer multiple of $\Omega$; when $d_{\mathrm{den}} \neq 0$ and + `Fintype.card ι < ℓ` (and $D_H \neq 0$ for Cramer determinant recovery), dividing each + $\tilde{H}_s(0)$ (or Cramer's rule determinant numerator $N_{H, s} = D_H \tilde{H}_s(0)$ in + eq. B.1) by $\Omega$ (or $\Omega D_H$), summing over $0 \le s < \ell$, and reducing modulo + $2^\ell$ recovers `commonZeroCount I P` on the nose, both on a single problem and summed across + all heavy-variable branches at shared precision $\ell = n + 1$. ## Main definitions @@ -72,7 +76,8 @@ cleared-denominator integer interpolation pipeline of Section 5.4 and Appendix B `Cslib.BitString.natDegree_univariateClearedParityTruncatedSum_le`: equation (5.5a) `natDegree` bounds for $\tilde{H}_s(T)$ and $S_\ell(\tilde{H}(T))$. * `Cslib.BitString.map_univariateClearedParityCoord_divDenomReplacement`, - `Cslib.BitString.map_univariateClearedParityTruncatedSum_divDenomReplacement`: over any field $K$, + `Cslib.BitString.map_univariateClearedParityTruncatedSum_divDenomReplacement`: over any field $K$ + with $(d_{\mathrm{den}} : K) \neq 0$, $1 \le \ell$, and monomial degree at most $k$, $\tilde{H}_s(T) = \Omega [V^s] H(T)$ and $S_\ell(\tilde{H}(T)) = \Omega S_\ell(H(T))$. * `Cslib.BitString.bivariateCoeffNorm1_parityFactorCleared_le`, `Cslib.BitString.bivariateCoeffNorm1_prod_parityFactorCleared_le`, @@ -84,7 +89,8 @@ cleared-denominator integer interpolation pipeline of Section 5.4 and Appendix B `Cslib.BitString.emod_ediv_eval_zero_univariateClearedParityTruncatedSum_eq_commonZeroCount`: exact integer divisibility by $\Omega$ at $T = 0$ and exact modular recovery of `commonZeroCount`. * `Cslib.BitString.emod_sum_cramer_ediv_eq_commonZeroCount`: Appendix B.3 (eq. B.1) exact integer - division recovery from Cramer's rule determinant numerators $N_{H, s} = D_H \tilde{H}_s(0)$. + division recovery from Cramer's rule determinant numerators $N_{H, s} = D_H \tilde{H}_s(0)$ when + $d_{\mathrm{den}} \neq 0$, $D_H \neq 0$, and `Fintype.card ι < ℓ`. * `Cslib.BitString.commonZeroCount_eq_sum_branch_emod_ediv_cleared`: §5.5 branch-summed exact recovery from cleared-denominator branch polynomials at shared precision $\ell = n + 1$. diff --git a/ComplexityTests/Foundations/Data/Polynomial/BivariateCoeffNorm1.lean b/ComplexityTests/Foundations/Data/Polynomial/BivariateCoeffNorm1.lean index ccae7a2582..3c22800545 100644 --- a/ComplexityTests/Foundations/Data/Polynomial/BivariateCoeffNorm1.lean +++ b/ComplexityTests/Foundations/Data/Polynomial/BivariateCoeffNorm1.lean @@ -28,14 +28,4 @@ example : rw [bivariateCoeffNorm1_C, coeffNorm1_C] rfl -/-- Concrete check of `coeffNorm1_coeff_le_bivariateCoeffNorm1`, `bivariateCoeffNorm1_add_le`, and -`bivariateCoeffNorm1_mul_le`. -/ -example (P Q : Polynomial (Polynomial ℤ)) (s : ℕ) : - (P.coeff s).coeffNorm1 ≤ P.bivariateCoeffNorm1 ∧ - (P + Q).bivariateCoeffNorm1 ≤ P.bivariateCoeffNorm1 + Q.bivariateCoeffNorm1 ∧ - (P * Q).bivariateCoeffNorm1 ≤ P.bivariateCoeffNorm1 * Q.bivariateCoeffNorm1 := - ⟨coeffNorm1_coeff_le_bivariateCoeffNorm1 P s, - bivariateCoeffNorm1_add_le P Q, - bivariateCoeffNorm1_mul_le P Q⟩ - end ComplexityTests.BivariateCoeffNorm1 From 5be06c84b058582f6cd27b98bde692f5678a35bc Mon Sep 17 00:00:00 2001 From: Samuel Schlesinger Date: Tue, 27 Oct 2026 03:58:14 +0000 Subject: [PATCH 11/20] feat(Foundations/BooleanAnalysis): instantiate cleared parity specialization with Section 4 replacement designs (#1226) --- Complexity.lean | 1 + .../SparseReplacementDesign.lean | 731 ++++++++++++++++++ ComplexityTests/SparseReplacementDesign.lean | 106 +++ 3 files changed, 838 insertions(+) create mode 100644 Complexity/Foundations/BooleanAnalysis/SparseReplacementDesign.lean create mode 100644 ComplexityTests/SparseReplacementDesign.lean diff --git a/Complexity.lean b/Complexity.lean index fd2a2b5db5..a75d846b14 100644 --- a/Complexity.lean +++ b/Complexity.lean @@ -1782,6 +1782,7 @@ public import Complexity.Foundations.BooleanAnalysis.SignApproximation public import Complexity.Foundations.BooleanAnalysis.SparseBranching public import Complexity.Foundations.BooleanAnalysis.SparseClearedSpecialization public import Complexity.Foundations.BooleanAnalysis.SparseEquations +public import Complexity.Foundations.BooleanAnalysis.SparseReplacementDesign public import Complexity.Foundations.BooleanAnalysis.Symmetrization public import Complexity.Foundations.Combinatorics.AffineDisperser public import Complexity.Foundations.Combinatorics.AffineDisperser.AffineSubspace diff --git a/Complexity/Foundations/BooleanAnalysis/SparseReplacementDesign.lean b/Complexity/Foundations/BooleanAnalysis/SparseReplacementDesign.lean new file mode 100644 index 0000000000..2c091a37cd --- /dev/null +++ b/Complexity/Foundations/BooleanAnalysis/SparseReplacementDesign.lean @@ -0,0 +1,731 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Foundations.BooleanAnalysis.SparseClearedSpecialization +public import Complexity.Foundations.LinearAlgebra.ReplacementDesign + +/-! +# Instantiating cleared parity-polynomial specialization with Section 4 replacement designs + +This module connects the Section 4 algebraic replacement design construction +(`Complexity.Foundations.LinearAlgebra.ReplacementDesign`) directly to the Section 5.3–5.5 and +Appendix B.2–B.3 cleared-denominator parity-polynomial zero-counting pipeline +(`Complexity.Foundations.BooleanAnalysis.SparseClearedSpecialization`) of +[OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (printed pp. 32–34, 37–39, +48–50): + +1. **Neutral singleton scope augmentation (§5.3 & §5.5, pp. 37–38)**: + Given an equation family `P : κ → Finset (Finset (Fin n))`, `augmentedEquationScope P` augments + the equation scopes `equationScope (P i)` (`Sum.inl i`) with one singleton scope `{v}` + (`Sum.inr v`) per variable `v : Fin n`. This ensures that every variable occurs in at least one + factor scope, that the total incidence count is `(∑ i, #(equationScope (P i))) + n ≥ n` + (`sum_card_augmentedEquationScope`, `le_sum_card_augmentedEquationScope`), and that per-variable + factor occurrences increase by exactly `1` (`card_filter_mem_augmentedEquationScope`), so + Lemma 4.7 (`exists_replacementDesign`) applies directly whenever equation occurrences are bounded + by `b₀` and equation scopes by `w ≥ 1` (`exists_replacementDesign_augmentedEquationScope`). + +2. **Univariate polynomial replacement rows from a `ReplacementDesign` (§5.3–5.4, pp. 37–38)**: + For any `D : ReplacementDesign scope Q r A₀ R τ`, incidence `e : ScopeIncidence scope`, and + Boolean assignment `x : Fin n → Bool`, `evalVarReplacementRowPoly D e x : ℚ[X]` and its scaled + integer counterpart `evalVarReplacementRowScaledIntPoly D e x : ℤ[X]` evaluate `D`'s replacement + rows on the `{0, 1}` vector `fun u => bitVal _ (x u)`. Using `D`'s fields from Definition 3.1 + and Lemma 4.6, we prove: + - `(evalVarReplacementRowScaledIntPoly D e x).map (Int.castRingHom ℚ) = + C (commonDenom Q R : ℚ) * evalVarReplacementRowPoly D e x`, + - `(evalVarReplacementRowPoly D e x).eval 0 = bitVal ℚ (x (scopeVarOf scope e))` and + `(evalVarReplacementRowScaledIntPoly D e x).eval 0 = + (commonDenom Q R : ℤ) * bitVal ℤ (x (scopeVarOf scope e))`, + - `natDegree ≤ R - 1` for both polynomials, + - `(evalVarReplacementRowScaledIntPoly D e x).coeffNorm1 ≤ designRowNormBound Q R`, where + `designRowNormBound Q R = commonDenom Q R * (1 + (1 + 2 ^ Q) * R * (4 * Q) ^ (R - 1))`, and + - at each evaluation node `nodePoint t` (`t : Fin Q`), `(evalVarReplacementRowPoly D e x).eval + (nodePoint t)` depends only on `x` restricted to the assigned variable group + `varGroup D.varAssign t (D.factorAssign (scopeFactorOf scope e) t)` and the measurement vector + `(varMeasurementMatrix Q r A₀ R ℚ D.place (scopeVarOf scope)).mulVec + (fun u => bitVal ℚ (x u))`. + +3. **Concrete §5.3–5.5 degree, norm, and exact modular zero-counting theorems**: + Packaging these replacement rows into `designReplacementMap D emb` and + `designReplacementScaledIntMap D emb` (for any factor embedding `emb : κ → F`) discharges all + clearing, degree, $T = 0$ evaluation, and `coeffNorm1` premises of + `SparseClearedSpecialization`, yielding concrete `ReplacementDesign` specializations of: + - the equation (5.5a) degree bound `(k * (R - 1)) * (#I + 2 * (ℓ - 1))` + (`natDegree_univariateClearedParityCoord_design_le`, + `natDegree_univariateClearedParityTruncatedSum_design_le`), + - the rational homogenization identity $\tilde{H}_s(T) = \Omega [V^s] H(T)$ over `ℚ[X]` + (`map_univariateClearedParityCoord_design`, + `map_univariateClearedParityTruncatedSum_design`), + - the Appendix B.2 coordinate `ℓ₁`-norm bound + (`coeffNorm1_univariateClearedParityCoord_design_le`), + - exact integer division and modulo-`2 ^ ℓ` recovery of `commonZeroCount I P` when `n < ℓ` and + `∀ i ∈ I, ∀ M ∈ P i, #M ≤ k`, including Cramer's rule determinant recovery (when `D_H ≠ 0`) + and §5.5 heavy-variable branch summation at shared precision `branchPrecision n = n + 1` + (`emod_sum_ediv_eval_zero_clearedParityCoord_design_eq_commonZeroCount`, + `emod_ediv_eval_zero_clearedParityTruncatedSum_design_eq_commonZeroCount`, + `emod_sum_cramer_ediv_design_eq_commonZeroCount`, + `commonZeroCount_eq_sum_branch_emod_ediv_design`). + +## Main definitions + +* `Cslib.BitString.augmentedEquationScope`: scope family on `κ ⊕ Fin n` combining + `equationScope (P i)` with neutral singleton scopes `{v}`. +* `Cslib.BitString.designRowNormBound`: the Lemma 4.6 row `ℓ₁`-norm bound + `commonDenom Q R * (1 + (1 + 2 ^ Q) * R * (4 * Q) ^ (R - 1))`. +* `Cslib.BitString.evalVarReplacementRowPoly`, + `Cslib.BitString.evalVarReplacementRowScaledIntPoly`: univariate rational and scaled integer + replacement polynomials evaluated on a Boolean assignment `x : Fin n → Bool`. +* `Cslib.BitString.designReplacementMap`, + `Cslib.BitString.designReplacementScaledIntMap`: equation-indexed rational and scaled integer + replacement polynomial families associated to a `ReplacementDesign`. + +## Main results + +* `Cslib.BitString.sum_card_augmentedEquationScope`, + `Cslib.BitString.card_filter_mem_augmentedEquationScope`, + `Cslib.BitString.exists_replacementDesign_augmentedEquationScope`: incidence count, variable + occurrence count, and Lemma 4.7 existence for neutral-singleton augmented equation scopes. +* `Cslib.BitString.map_evalVarReplacementRowScaledIntPoly`, + `Cslib.BitString.eval_zero_evalVarReplacementRowPoly`, + `Cslib.BitString.eval_zero_evalVarReplacementRowScaledIntPoly`, + `Cslib.BitString.natDegree_evalVarReplacementRowScaledIntPoly_le`, + `Cslib.BitString.coeffNorm1_evalVarReplacementRowScaledIntPoly_le`, + `Cslib.BitString.eval_evalVarReplacementRowPoly_nodePoint_eq_of_eq_on_varGroup`: + Definition 3.1 and Lemma 4.6 properties of `evalVarReplacementRowPoly` and + `evalVarReplacementRowScaledIntPoly`. +* `Cslib.BitString.natDegree_univariateClearedParityCoord_design_le`, + `Cslib.BitString.natDegree_univariateClearedParityTruncatedSum_design_le`, + `Cslib.BitString.map_univariateClearedParityCoord_design`, + `Cslib.BitString.coeffNorm1_univariateClearedParityCoord_design_le`: + concrete `ReplacementDesign` degree, homogenization, and `ℓ₁`-norm bounds. +* `Cslib.BitString.emod_sum_ediv_eval_zero_clearedParityCoord_design_eq_commonZeroCount`, + `Cslib.BitString.emod_ediv_eval_zero_clearedParityTruncatedSum_design_eq_commonZeroCount`, + `Cslib.BitString.emod_sum_cramer_ediv_design_eq_commonZeroCount`, + `Cslib.BitString.commonZeroCount_eq_sum_branch_emod_ediv_design`: + exact integer division recovery of `commonZeroCount` from `ReplacementDesign`s on a single system + and summed across heavy-variable branches. + +## References + +* [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (Sections 4.5–4.6, 5.3–5.5, + and Appendix B.2–B.3, pp. 32–34, 37–39, 48–50) +-/ + +@[expose] public noncomputable section + +namespace Cslib.BitString + +open Finset Polynomial +open scoped BigOperators +open Cslib.BalancedSchedules Cslib.LinearAlgebra + +variable {κ : Type*} {n Q r A₀ R : ℕ} {τ : ℚ} + +/-! ### 1. Neutral singleton scope augmentation (§5.3 & §5.5, pp. 37–38) -/ + +/-- The augmented factor scope family on `κ ⊕ Fin n` combining the equation scopes +`equationScope (P i)` (`Sum.inl i`) with one neutral singleton scope `{v}` (`Sum.inr v`) per +variable `v : Fin n` (§5.3 and §5.5, printed pp. 37–38). -/ +def augmentedEquationScope (P : κ → Finset (Finset (Fin n))) : κ ⊕ Fin n → Finset (Fin n) + | Sum.inl i => equationScope (P i) + | Sum.inr v => {v} + +@[simp] +theorem augmentedEquationScope_inl (P : κ → Finset (Finset (Fin n))) (i : κ) : + augmentedEquationScope P (Sum.inl i) = equationScope (P i) := + rfl + +@[simp] +theorem augmentedEquationScope_inr (P : κ → Finset (Finset (Fin n))) (v : Fin n) : + augmentedEquationScope P (Sum.inr v) = {v} := + rfl + +/-- Every variable `v ∈ M` of a monomial `M ∈ P i` belongs to +`augmentedEquationScope P (Sum.inl i)`. -/ +theorem mem_augmentedEquationScope_inl_of_mem {P : κ → Finset (Finset (Fin n))} {i : κ} + {M : Finset (Fin n)} {v : Fin n} (hM : M ∈ P i) (hv : v ∈ M) : + v ∈ augmentedEquationScope P (Sum.inl i) := + mem_biUnion.mpr ⟨M, hM, hv⟩ + +/-- The total incidence count of `augmentedEquationScope P` equals +`(∑ i : κ, #(equationScope (P i))) + n`. -/ +theorem sum_card_augmentedEquationScope [Fintype κ] (P : κ → Finset (Finset (Fin n))) : + (∑ f : κ ⊕ Fin n, #(augmentedEquationScope P f)) = + (∑ i : κ, #(equationScope (P i))) + n := by + simp only [Fintype.sum_sum_type, augmentedEquationScope_inl, augmentedEquationScope_inr, + card_singleton, sum_const, card_univ, Fintype.card_fin, smul_eq_mul, mul_one] + +/-- Neutral singleton factors ensure that the total incidence count of `augmentedEquationScope P` +is at least `n` (§5.5, p. 38: `M' ≥ n'`). -/ +theorem le_sum_card_augmentedEquationScope [Fintype κ] (P : κ → Finset (Finset (Fin n))) : + n ≤ ∑ f : κ ⊕ Fin n, #(augmentedEquationScope P f) := by + rw [sum_card_augmentedEquationScope] + exact Nat.le_add_left n _ + +/-- If `1 ≤ w` and every equation scope `equationScope (P i)` has size at most `w`, then every +scope in `augmentedEquationScope P` has size at most `w`. -/ +theorem card_augmentedEquationScope_le {P : κ → Finset (Finset (Fin n))} {w : ℕ} + (hw1 : 1 ≤ w) (hw : ∀ i : κ, #(equationScope (P i)) ≤ w) (f : κ ⊕ Fin n) : + #(augmentedEquationScope P f) ≤ w := by + cases f with + | inl i => exact hw i + | inr v => simpa only [augmentedEquationScope_inr, card_singleton] using hw1 + +/-- Each variable `v : Fin n` occurs in `#{i : κ | v ∈ equationScope (P i)} + 1` scopes of +`augmentedEquationScope P` (its equation occurrences plus its neutral singleton scope). -/ +theorem card_filter_mem_augmentedEquationScope [Fintype κ] + (P : κ → Finset (Finset (Fin n))) (v : Fin n) : + #{f : κ ⊕ Fin n | v ∈ augmentedEquationScope P f} = + #{i : κ | v ∈ equationScope (P i)} + 1 := by + rw [card_filter, card_filter, Fintype.sum_sum_type] + simp only [augmentedEquationScope_inl, augmentedEquationScope_inr, mem_singleton, sum_ite_eq, + mem_univ, ↓reduceIte] + congr 1 + +/-- If every variable occurs in at most `b₀` equation scopes, then every variable occurs in at most +`b₀ + 1` scopes of `augmentedEquationScope P`. -/ +theorem card_filter_mem_augmentedEquationScope_le [Fintype κ] + {P : κ → Finset (Finset (Fin n))} {b₀ : ℕ} + (hb : ∀ v : Fin n, #{i : κ | v ∈ equationScope (P i)} ≤ b₀) (v : Fin n) : + #{f : κ ⊕ Fin n | v ∈ augmentedEquationScope P f} ≤ b₀ + 1 := by + rw [card_filter_mem_augmentedEquationScope] + exact Nat.add_le_add_right (hb v) 1 + +/-- If every variable occurs in at most `b₀` equation scopes, then the total incidence count of +`augmentedEquationScope P` is at most `(b₀ + 1) * n`. -/ +theorem sum_card_augmentedEquationScope_le [Fintype κ] + {P : κ → Finset (Finset (Fin n))} {b₀ : ℕ} + (hb : ∀ v : Fin n, #{i : κ | v ∈ equationScope (P i)} ≤ b₀) : + (∑ f : κ ⊕ Fin n, #(augmentedEquationScope P f)) ≤ (b₀ + 1) * n := by + classical + have hswap : + (∑ f : κ ⊕ Fin n, #(augmentedEquationScope P f)) = + ∑ v : Fin n, #{f : κ ⊕ Fin n | v ∈ augmentedEquationScope P f} := by + simp only [card_eq_sum_ones, sum_filter] + rw [sum_comm] + refine sum_congr rfl fun f _ => ?_ + simp only [sum_ite_mem, univ_inter] + rw [hswap] + calc + (∑ v : Fin n, #{f : κ ⊕ Fin n | v ∈ augmentedEquationScope P f}) + ≤ ∑ _v : Fin n, (b₀ + 1) := + sum_le_sum fun v _ => card_filter_mem_augmentedEquationScope_le hb v + _ = (b₀ + 1) * n := by + rw [sum_const, card_univ, Fintype.card_fin, smul_eq_mul, mul_comm] + +/-- **Lemma 4.7 for neutral-singleton augmented equation scopes (§5.5, pp. 38–39)**: +when every variable belongs to at most `b₀` equation scopes and every equation scope has size at +most `w` (`1 ≤ w`), the augmented scope family `augmentedEquationScope P` satisfies `1 ≤ b₀ + 1` +and `M ≤ (b₀ + 1) * n` automatically, and admits a Section 4 `ReplacementDesign` under the balance +and binomial-tail conditions for `b = b₀ + 1`. -/ +theorem exists_replacementDesign_augmentedEquationScope [Fintype κ] + (P : κ → Finset (Finset (Fin n))) {b₀ w : ℕ} + (hn : 1 ≤ n) (hw_pos : 1 ≤ w) + (hr : 2 ≤ r) (hR : 1 ≤ R) (hRQ : R < Q) (hτ : 0 ≤ τ) + (hI : ∀ a < R - 1, A₀ + a ≤ Q) + (hb : ∀ v : Fin n, #{i : κ | v ∈ equationScope (P i)} ≤ b₀) + (hw : ∀ i : κ, #(equationScope (P i)) ≤ w) + (hincidenceSize : + 2 * (b₀ + 1 + w) * (r ^ (2 * Q)) ^ 2 ≤ (∑ i : κ, #(equationScope (P i))) + n) + (hgroupSize : 2 * Q * r ^ 2 ≤ n) + (htail : binomTailProb Q r A₀ R ≤ τ / ((r : ℚ) * ((b₀ + 1 : ℕ) : ℚ))) : + Nonempty (ReplacementDesign (augmentedEquationScope P) Q r A₀ R τ) := by + refine exists_replacementDesign (augmentedEquationScope P) hn (Nat.le_add_left 1 b₀) hw_pos hr + hR hRQ hτ hI (card_filter_mem_augmentedEquationScope_le hb) + (card_augmentedEquationScope_le hw_pos hw) (sum_card_augmentedEquationScope_le hb) ?_ hgroupSize + htail + rwa [sum_card_augmentedEquationScope] + +/-! ### 2. Univariate replacement polynomials from a `ReplacementDesign` (§5.3–5.4, pp. 37–38) -/ + +/-- The explicit Lemma 4.6 `ℓ₁` coefficient norm bound +`commonDenom Q R * (1 + (1 + 2 ^ Q) * R * (4 * Q) ^ (R - 1))` for scaled integer replacement rows +(printed p. 33). -/ +def designRowNormBound (Q R : ℕ) : ℕ := + commonDenom Q R * (1 + (1 + 2 ^ Q) * R * (4 * Q) ^ (R - 1)) + +/-- `commonDenom Q R ≤ designRowNormBound Q R`. -/ +theorem commonDenom_le_designRowNormBound (Q R : ℕ) : + commonDenom Q R ≤ designRowNormBound Q R := + Nat.le_mul_of_pos_right (commonDenom Q R) (by omega) + +/-- `0 < designRowNormBound Q R`. -/ +theorem designRowNormBound_pos (Q R : ℕ) : 0 < designRowNormBound Q R := + lt_of_lt_of_le (commonDenom_pos Q R) (commonDenom_le_designRowNormBound Q R) + +/-- `(commonDenom Q R : ℤ) ≠ 0`. -/ +theorem commonDenom_intCast_ne_zero (Q R : ℕ) : (commonDenom Q R : ℤ) ≠ 0 := + Nat.cast_ne_zero.mpr (commonDenom_pos Q R).ne' + +/-- `(commonDenom Q R : ℚ) ≠ 0`. -/ +theorem commonDenom_ratCast_ne_zero (Q R : ℕ) : (commonDenom Q R : ℚ) ≠ 0 := + Nat.cast_ne_zero.mpr (commonDenom_pos Q R).ne' + +/-- The univariate rational replacement polynomial `⟨P⃗_e(T), x⟩ ∈ ℚ[X]` for incidence +`e : ScopeIncidence scope` evaluated on a Boolean assignment `x : Fin n → Bool` (§5.3, p. 37). -/ +noncomputable def evalVarReplacementRowPoly {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) + (e : ScopeIncidence scope) (x : Fin n → Bool) : Polynomial ℚ := + ∑ u : Fin n, + Polynomial.C (bitVal ℚ (x u)) * varReplacementRow Q r A₀ R D.place (scopeVarOf scope) e u + +/-- The scaled integer univariate replacement polynomial `d_den ⟨P⃗_e(T), x⟩ ∈ ℤ[X]` for incidence +`e : ScopeIncidence scope` evaluated on a Boolean assignment `x : Fin n → Bool` +(§5.4 & Lemma 4.6, pp. 33, 37–38). -/ +noncomputable def evalVarReplacementRowScaledIntPoly {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) + (e : ScopeIncidence scope) (x : Fin n → Bool) : Polynomial ℤ := + ∑ u : Fin n, + Polynomial.C (bitVal ℤ (x u)) * + varReplacementRowScaledInt Q r A₀ R D.place (scopeVarOf scope) e u + +/-- Pointwise evaluation of `evalVarReplacementRowPoly D e x` at `t : ℚ` agrees with +`evalVarReplacementRow` on `fun u => bitVal ℚ (x u)`. -/ +theorem eval_evalVarReplacementRowPoly {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) + (e : ScopeIncidence scope) (x : Fin n → Bool) (t : ℚ) : + (evalVarReplacementRowPoly D e x).eval t = + evalVarReplacementRow Q r A₀ R D.place (scopeVarOf scope) e t (fun u => bitVal ℚ (x u)) := by + rw [evalVarReplacementRowPoly, evalVarReplacementRow, Polynomial.eval_finsetSum] + refine sum_congr rfl fun u _ => ?_ + rw [Polynomial.eval_mul, Polynomial.eval_C, mul_comm] + +/-- At `T = 0`, `evalVarReplacementRowPoly D e x` evaluates to `bitVal ℚ (x (scopeVarOf scope e))` +(Definition 3.1 (4), p. 22). -/ +theorem eval_zero_evalVarReplacementRowPoly {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) + (e : ScopeIncidence scope) (x : Fin n → Bool) : + (evalVarReplacementRowPoly D e x).eval 0 = bitVal ℚ (x (scopeVarOf scope e)) := by + rw [eval_evalVarReplacementRowPoly, D.evalReplacementRow_zero] + +/-- Mapping `evalVarReplacementRowScaledIntPoly D e x` into `ℚ[X]` yields +`C (commonDenom Q R : ℚ) * evalVarReplacementRowPoly D e x` (Definition 3.1 (5) & Lemma 4.6). -/ +theorem map_evalVarReplacementRowScaledIntPoly {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) + (e : ScopeIncidence scope) (x : Fin n → Bool) : + (evalVarReplacementRowScaledIntPoly D e x).map (Int.castRingHom ℚ) = + Polynomial.C (commonDenom Q R : ℚ) * evalVarReplacementRowPoly D e x := by + rw [evalVarReplacementRowScaledIntPoly, evalVarReplacementRowPoly, Polynomial.map_sum, mul_sum] + refine sum_congr rfl fun u _ => ?_ + have hbit : (Int.castRingHom ℚ) (bitVal ℤ (x u)) = bitVal ℚ (x u) := by + cases x u <;> rfl + rw [Polynomial.map_mul, Polynomial.map_C, hbit, D.map_replacementRowScaledInt e u, + Algebra.smul_def, algebraMap_eq, mul_left_comm] + +/-- At `T = 0`, `evalVarReplacementRowScaledIntPoly D e x` evaluates to +`(commonDenom Q R : ℤ) * bitVal ℤ (x (scopeVarOf scope e))`. -/ +theorem eval_zero_evalVarReplacementRowScaledIntPoly {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) + (e : ScopeIncidence scope) (x : Fin n → Bool) : + (evalVarReplacementRowScaledIntPoly D e x).eval 0 = + (commonDenom Q R : ℤ) * bitVal ℤ (x (scopeVarOf scope e)) := by + apply Int.cast_injective (α := ℚ) + have hmap := congrArg (fun p : Polynomial ℚ => p.eval 0) + (map_evalVarReplacementRowScaledIntPoly D e x) + rw [Polynomial.eval_mul, Polynomial.eval_C, eval_zero_evalVarReplacementRowPoly] at hmap + have h0 : (0 : ℚ) = Int.castRingHom ℚ 0 := rfl + rw [h0, Polynomial.eval_map_apply, eq_intCast] at hmap + rw [hmap, Int.cast_mul, Int.cast_natCast] + cases x (scopeVarOf scope e) <;> + simp only [bitVal_true, bitVal_false, Int.cast_one, Int.cast_zero] + +/-- `evalVarReplacementRowPoly D e x` has `natDegree ≤ R - 1` (Definition 3.1 (4)). -/ +theorem natDegree_evalVarReplacementRowPoly_le {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) + (e : ScopeIncidence scope) (x : Fin n → Bool) : + (evalVarReplacementRowPoly D e x).natDegree ≤ R - 1 := by + rw [evalVarReplacementRowPoly] + refine (Polynomial.natDegree_sum_le _ _).trans ?_ + rw [Finset.fold_max_le] + refine ⟨Nat.zero_le _, fun u _ => ?_⟩ + exact (Polynomial.natDegree_C_mul_le _ _).trans (D.natDegree_replacementRow_le e u) + +/-- `evalVarReplacementRowScaledIntPoly D e x` has `natDegree ≤ R - 1`. -/ +theorem natDegree_evalVarReplacementRowScaledIntPoly_le {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) + (e : ScopeIncidence scope) (x : Fin n → Bool) : + (evalVarReplacementRowScaledIntPoly D e x).natDegree ≤ R - 1 := by + have hinj : Function.Injective (Int.castRingHom ℚ) := Int.cast_injective + rw [← Polynomial.natDegree_map_eq_of_injective hinj, map_evalVarReplacementRowScaledIntPoly] + exact (Polynomial.natDegree_C_mul_le _ _).trans (natDegree_evalVarReplacementRowPoly_le D e x) + +/-- **Lemma 4.6 row `ℓ₁`-norm bound on Boolean inputs**: +`(evalVarReplacementRowScaledIntPoly D e x).coeffNorm1 ≤ designRowNormBound Q R`. -/ +theorem coeffNorm1_evalVarReplacementRowScaledIntPoly_le {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) + (e : ScopeIncidence scope) (x : Fin n → Bool) : + (evalVarReplacementRowScaledIntPoly D e x).coeffNorm1 ≤ designRowNormBound Q R := by + have hsum : + (evalVarReplacementRowScaledIntPoly D e x).coeffNorm1 ≤ + ∑ u : Fin n, + (varReplacementRowScaledInt Q r A₀ R D.place (scopeVarOf scope) e u).coeffNorm1 := by + rw [evalVarReplacementRowScaledIntPoly] + refine (Polynomial.coeffNorm1_sum_le univ _).trans (sum_le_sum fun u _ => ?_) + cases x u + · simp only [bitVal_false, Polynomial.C_0, zero_mul, Polynomial.coeffNorm1_zero, zero_le] + · simp only [bitVal_true, Polynomial.C_1, one_mul, le_rfl] + have hrow := D.sum_coeffNorm1_replacementRowScaledInt_le e + have hrow_nat : + (∑ u : Fin n, + (varReplacementRowScaledInt Q r A₀ R D.place (scopeVarOf scope) e u).coeffNorm1) ≤ + designRowNormBound Q R := by + rw [designRowNormBound] + exact_mod_cast hrow + exact hsum.trans hrow_nat + +/-- **Definition 3.1 (4) group-and-measurement locality at `nodePoint t`**: +at `t : Fin Q`, `(evalVarReplacementRowPoly D e x).eval (nodePoint t)` depends only on `x` +restricted to `varGroup D.varAssign t (D.factorAssign (scopeFactorOf scope e) t)` and the +measurement vector `(varMeasurementMatrix Q r A₀ R ℚ D.place (scopeVarOf scope)).mulVec +(fun u => bitVal ℚ (x u))`. -/ +theorem eval_evalVarReplacementRowPoly_nodePoint_eq_of_eq_on_varGroup {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) + (e : ScopeIncidence scope) (t : Fin Q) (x x' : Fin n → Bool) + (hgrp : ∀ u ∈ varGroup D.varAssign t (D.factorAssign (scopeFactorOf scope e) t), x u = x' u) + (hmeas : + (varMeasurementMatrix Q r A₀ R ℚ D.place (scopeVarOf scope)).mulVec + (fun u => bitVal ℚ (x u)) = + (varMeasurementMatrix Q r A₀ R ℚ D.place (scopeVarOf scope)).mulVec + (fun u => bitVal ℚ (x' u))) : + (evalVarReplacementRowPoly D e x).eval (nodePoint t) = + (evalVarReplacementRowPoly D e x').eval (nodePoint t) := by + rw [eval_evalVarReplacementRowPoly, eval_evalVarReplacementRowPoly] + exact D.evalReplacementRow_nodePoint_eq_of_eq_on_varGroup e t + (fun u => bitVal ℚ (x u)) (fun u => bitVal ℚ (x' u)) + (fun u hu => congrArg (bitVal ℚ) (hgrp u hu)) hmeas + +/-! ### 3. Factor-indexed replacement families `designReplacementMap` and +`designReplacementScaledIntMap` (§5.3–5.4) -/ + +/-- The equation-indexed rational replacement family `(Fin n → Bool) → κ → Fin n → ℚ[X]` associated +to a `ReplacementDesign` and factor embedding `emb : κ → F`, using +`evalVarReplacementRowPoly D ⟨emb i, ⟨v, hv⟩⟩ x` for `v ∈ scope (emb i)` and the constant Boolean +value `C (bitVal ℚ (x v))` outside `scope (emb i)`. -/ +noncomputable def designReplacementMap {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (x : Fin n → Bool) (i : κ) (v : Fin n) : Polynomial ℚ := + if hv : v ∈ scope (emb i) then + evalVarReplacementRowPoly D ⟨emb i, ⟨v, hv⟩⟩ x + else + Polynomial.C (bitVal ℚ (x v)) + +/-- The equation-indexed scaled integer replacement family `(Fin n → Bool) → κ → Fin n → ℤ[X]` +associated to a `ReplacementDesign` and factor embedding `emb : κ → F`, using +`evalVarReplacementRowScaledIntPoly D ⟨emb i, ⟨v, hv⟩⟩ x` for `v ∈ scope (emb i)` and +`C ((commonDenom Q R : ℤ) * bitVal ℤ (x v))` outside `scope (emb i)`. -/ +noncomputable def designReplacementScaledIntMap {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (x : Fin n → Bool) (i : κ) (v : Fin n) : Polynomial ℤ := + if hv : v ∈ scope (emb i) then + evalVarReplacementRowScaledIntPoly D ⟨emb i, ⟨v, hv⟩⟩ x + else + Polynomial.C ((commonDenom Q R : ℤ) * bitVal ℤ (x v)) + +/-- On `hv : v ∈ scope (emb i)`, `designReplacementMap D emb x i v` is +`evalVarReplacementRowPoly D ⟨emb i, ⟨v, hv⟩⟩ x`. -/ +theorem designReplacementMap_of_mem {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (x : Fin n → Bool) {i : κ} {v : Fin n} (hv : v ∈ scope (emb i)) : + designReplacementMap D emb x i v = evalVarReplacementRowPoly D ⟨emb i, ⟨v, hv⟩⟩ x := by + simp only [designReplacementMap, hv, ↓reduceDIte] + +/-- On `hv : v ∈ scope (emb i)`, `designReplacementScaledIntMap D emb x i v` is +`evalVarReplacementRowScaledIntPoly D ⟨emb i, ⟨v, hv⟩⟩ x`. -/ +theorem designReplacementScaledIntMap_of_mem {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (x : Fin n → Bool) {i : κ} {v : Fin n} (hv : v ∈ scope (emb i)) : + designReplacementScaledIntMap D emb x i v = + evalVarReplacementRowScaledIntPoly D ⟨emb i, ⟨v, hv⟩⟩ x := by + simp only [designReplacementScaledIntMap, hv, ↓reduceDIte] + +/-- Mapping `designReplacementScaledIntMap D emb x i v` into `ℚ[X]` yields +`C (commonDenom Q R : ℚ) * designReplacementMap D emb x i v`. -/ +theorem map_designReplacementScaledIntMap {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (x : Fin n → Bool) (i : κ) (v : Fin n) : + (designReplacementScaledIntMap D emb x i v).map (Int.castRingHom ℚ) = + Polynomial.C (commonDenom Q R : ℚ) * designReplacementMap D emb x i v := by + unfold designReplacementScaledIntMap designReplacementMap + split_ifs with hv + · exact map_evalVarReplacementRowScaledIntPoly D ⟨emb i, ⟨v, hv⟩⟩ x + · rw [Polynomial.map_C, eq_intCast, Int.cast_mul, Int.cast_natCast, Polynomial.C_mul] + cases x v <;> + simp only [bitVal_true, bitVal_false, Int.cast_one, Int.cast_zero, Polynomial.C_1, + Polynomial.C_0, mul_one, mul_zero] + +/-- `divDenomReplacement ℚ (commonDenom Q R : ℤ) (designReplacementScaledIntMap D emb)` agrees +with `designReplacementMap D emb`. -/ +theorem divDenomReplacement_designReplacementScaledIntMap {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (x : Fin n → Bool) (i : κ) (v : Fin n) : + divDenomReplacement ℚ (commonDenom Q R : ℤ) (designReplacementScaledIntMap D emb) x i v = + designReplacementMap D emb x i v := by + rw [divDenomReplacement, map_designReplacementScaledIntMap, ← mul_assoc, ← Polynomial.C_mul, + Int.cast_natCast, inv_mul_cancel₀ (commonDenom_ratCast_ne_zero Q R), Polynomial.C_1, one_mul] + +/-- At `T = 0`, `designReplacementMap D emb x i v` evaluates to `bitVal ℚ (x v)`. -/ +theorem eval_zero_designReplacementMap {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (x : Fin n → Bool) (i : κ) (v : Fin n) : + (designReplacementMap D emb x i v).eval 0 = bitVal ℚ (x v) := by + unfold designReplacementMap + split_ifs with hv + · exact eval_zero_evalVarReplacementRowPoly D ⟨emb i, ⟨v, hv⟩⟩ x + · exact Polynomial.eval_C + +/-- At `T = 0`, `designReplacementScaledIntMap D emb x i v` evaluates to +`(commonDenom Q R : ℤ) * bitVal ℤ (x v)`. -/ +theorem eval_zero_designReplacementScaledIntMap {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (x : Fin n → Bool) (i : κ) (v : Fin n) : + (designReplacementScaledIntMap D emb x i v).eval 0 = + (commonDenom Q R : ℤ) * bitVal ℤ (x v) := by + unfold designReplacementScaledIntMap + split_ifs with hv + · exact eval_zero_evalVarReplacementRowScaledIntPoly D ⟨emb i, ⟨v, hv⟩⟩ x + · exact Polynomial.eval_C + +/-- `designReplacementMap D emb x i v` has `natDegree ≤ R - 1`. -/ +theorem natDegree_designReplacementMap_le {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (x : Fin n → Bool) (i : κ) (v : Fin n) : + (designReplacementMap D emb x i v).natDegree ≤ R - 1 := by + unfold designReplacementMap + split_ifs with hv + · exact natDegree_evalVarReplacementRowPoly_le D ⟨emb i, ⟨v, hv⟩⟩ x + · rw [Polynomial.natDegree_C] + exact Nat.zero_le _ + +/-- `designReplacementScaledIntMap D emb x i v` has `natDegree ≤ R - 1`. -/ +theorem natDegree_designReplacementScaledIntMap_le {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (x : Fin n → Bool) (i : κ) (v : Fin n) : + (designReplacementScaledIntMap D emb x i v).natDegree ≤ R - 1 := by + unfold designReplacementScaledIntMap + split_ifs with hv + · exact natDegree_evalVarReplacementRowScaledIntPoly_le D ⟨emb i, ⟨v, hv⟩⟩ x + · rw [Polynomial.natDegree_C] + exact Nat.zero_le _ + +/-- `(designReplacementScaledIntMap D emb x i v).coeffNorm1 ≤ designRowNormBound Q R`. -/ +theorem coeffNorm1_designReplacementScaledIntMap_le {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (x : Fin n → Bool) (i : κ) (v : Fin n) : + (designReplacementScaledIntMap D emb x i v).coeffNorm1 ≤ designRowNormBound Q R := by + unfold designReplacementScaledIntMap + split_ifs with hv + · exact coeffNorm1_evalVarReplacementRowScaledIntPoly_le D ⟨emb i, ⟨v, hv⟩⟩ x + · rw [Polynomial.coeffNorm1_C] + cases x v + · simp only [bitVal_false, mul_zero, Int.natAbs_zero, zero_le] + · simp only [bitVal_true, mul_one, Int.natAbs_natCast] + exact commonDenom_le_designRowNormBound Q R + +/-- **Appendix B.2 Stage-1 `ℓ₁`-norm bound for `designReplacementScaledIntMap`**: +if every monomial `M ∈ P i` has `#M ≤ k`, then +`clearedMonomialSumPoly (commonDenom Q R : ℤ) k (designReplacementScaledIntMap D emb x i) (P i)` +has `coeffNorm1 ≤ #(P i) * designRowNormBound Q R ^ k`. -/ +theorem coeffNorm1_clearedMonomialSumPoly_designReplacementScaledIntMap_le {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (P : κ → Finset (Finset (Fin n))) (x : Fin n → Bool) {i : κ} {k : ℕ} + (hk : ∀ M ∈ P i, #M ≤ k) : + (clearedMonomialSumPoly (commonDenom Q R : ℤ) k + (designReplacementScaledIntMap D emb x i) (P i)).coeffNorm1 ≤ + #(P i) * designRowNormBound Q R ^ k := by + refine coeffNorm1_clearedMonomialSumPoly_le ?_ hk + (fun _ _ v _ => coeffNorm1_designReplacementScaledIntMap_le D emb x i v) + simpa only [Int.natAbs_natCast] using commonDenom_le_designRowNormBound Q R + +/-! ### 4. Concrete §5.3–5.5 degree, homogenization, `ℓ₁`-norm, and exact division recovery +theorems for `ReplacementDesign` -/ + +/-- **Equation (5.5a) coordinate `natDegree` bound for `ReplacementDesign`**: +for `s < ℓ` and `∀ i ∈ I, ∀ M ∈ P i, #M ≤ k`, the cleared coordinate polynomial +`univariateClearedParityCoord I P (commonDenom Q R : ℤ) k ℓ (designReplacementScaledIntMap D emb) s` +has `natDegree ≤ (k * (R - 1)) * (#I + 2 * (ℓ - 1))`. -/ +theorem natDegree_univariateClearedParityCoord_design_le {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (I : Finset κ) (P : κ → Finset (Finset (Fin n))) {k ℓ s : ℕ} + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) (hs : s < ℓ) : + (univariateClearedParityCoord I P (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb) s).natDegree ≤ + (k * (R - 1)) * (#I + 2 * (ℓ - 1)) := + natDegree_univariateClearedParityCoord_le I P (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb) hk + (fun x i _ _ _ v _ => natDegree_designReplacementScaledIntMap_le D emb x i v) hs + +/-- **Equation (5.5a) truncated-sum `natDegree` bound for `ReplacementDesign`**: +when `∀ i ∈ I, ∀ M ∈ P i, #M ≤ k`, the cleared truncated sum +`univariateClearedParityTruncatedSum I P (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb)` +has `natDegree ≤ (k * (R - 1)) * (#I + 2 * (ℓ - 1))`. -/ +theorem natDegree_univariateClearedParityTruncatedSum_design_le {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (I : Finset κ) (P : κ → Finset (Finset (Fin n))) (k ℓ : ℕ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) : + (univariateClearedParityTruncatedSum I P (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb)).natDegree ≤ + (k * (R - 1)) * (#I + 2 * (ℓ - 1)) := + natDegree_univariateClearedParityTruncatedSum_le I P (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb) hk + (fun x i _ _ _ v _ => natDegree_designReplacementScaledIntMap_le D emb x i v) + +/-- **§5.4 & Appendix B.3 ($\tilde{H}_s(T) = \Omega [V^s] H(T)$ over `ℚ[X]` for +`ReplacementDesign`)**: for `1 ≤ ℓ` and `∀ i ∈ I, ∀ M ∈ P i, #M ≤ k`, mapping +`univariateClearedParityCoord I P (commonDenom Q R : ℤ) k ℓ (designReplacementScaledIntMap D emb) s` +into `ℚ[X]` equals `C (clearedProductDenom (commonDenom Q R : ℤ) k ℓ #I : ℚ)` times +`univariateParityCoord I P ℓ (designReplacementMap D emb) s`. -/ +theorem map_univariateClearedParityCoord_design {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (I : Finset κ) (P : κ → Finset (Finset (Fin n))) {k ℓ : ℕ} (hℓ : 1 ≤ ℓ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) (s : ℕ) : + (univariateClearedParityCoord I P (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb) s).map (Int.castRingHom ℚ) = + Polynomial.C (clearedProductDenom (commonDenom Q R : ℤ) k ℓ #I : ℚ) * + univariateParityCoord I P ℓ (designReplacementMap D emb) s := + map_univariateClearedParityCoord I P (commonDenom Q R : ℤ) hℓ + (designReplacementScaledIntMap D emb) (designReplacementMap D emb) hk + (fun x i _ _ _ v _ => map_designReplacementScaledIntMap D emb x i v) s + +/-- **§5.4 & Appendix B.3 ($S_\ell(\tilde{H}(T)) = \Omega S_\ell(H(T))$ over `ℚ[X]` for +`ReplacementDesign`)**: under the same hypotheses, mapping +`univariateClearedParityTruncatedSum I P (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb)` into `ℚ[X]` equals +`C (clearedProductDenom (commonDenom Q R : ℤ) k ℓ #I : ℚ)` times +`univariateParityTruncatedSum I P ℓ (designReplacementMap D emb)`. -/ +theorem map_univariateClearedParityTruncatedSum_design {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (I : Finset κ) (P : κ → Finset (Finset (Fin n))) {k ℓ : ℕ} (hℓ : 1 ≤ ℓ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) : + (univariateClearedParityTruncatedSum I P (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb)).map (Int.castRingHom ℚ) = + Polynomial.C (clearedProductDenom (commonDenom Q R : ℤ) k ℓ #I : ℚ) * + univariateParityTruncatedSum I P ℓ (designReplacementMap D emb) := + map_univariateClearedParityTruncatedSum I P (commonDenom Q R : ℤ) hℓ + (designReplacementScaledIntMap D emb) (designReplacementMap D emb) hk + (fun x i _ _ _ v _ => map_designReplacementScaledIntMap D emb x i v) + +/-- **Appendix B.2 coordinate `ℓ₁`-norm bound for `ReplacementDesign`**: +if `∀ i ∈ I, ∀ M ∈ P i, #M ≤ k`, `∀ i ∈ I, #(P i) ≤ S_mon`, and +`∀ j < ℓ, (parityBaseDigit ℓ j).coeffNorm1 ≤ E_ℓ`, then every coordinate polynomial +`univariateClearedParityCoord I P (commonDenom Q R : ℤ) k ℓ (designReplacementScaledIntMap D emb) s` +has `coeffNorm1` at most +`2 ^ n * (ℓ * E_ℓ * (S_mon * designRowNormBound Q R ^ k + commonDenom Q R ^ k) ^ (2 * ℓ - 1)) ^ #I`. +-/ +theorem coeffNorm1_univariateClearedParityCoord_design_le {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (I : Finset κ) (P : κ → Finset (Finset (Fin n))) (k ℓ : ℕ) {S_mon E_ℓ : ℕ} + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hS : ∀ i ∈ I, #(P i) ≤ S_mon) + (hE : ∀ j < ℓ, (Polynomial.parityBaseDigit ℓ j).coeffNorm1 ≤ E_ℓ) (s : ℕ) : + (univariateClearedParityCoord I P (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb) s).coeffNorm1 ≤ + 2 ^ n * + (ℓ * E_ℓ * + (S_mon * designRowNormBound Q R ^ k + commonDenom Q R ^ k) ^ (2 * ℓ - 1)) ^ #I := by + have hbound := + coeffNorm1_univariateClearedParityCoord_le I P (commonDenom Q R : ℤ) k ℓ + (B := S_mon * designRowNormBound Q R ^ k) (designReplacementScaledIntMap D emb) + (fun x i hi => + (coeffNorm1_clearedMonomialSumPoly_designReplacementScaledIntMap_le D emb P x + (hk i hi)).trans (Nat.mul_le_mul_right _ (hS i hi))) + hE s + simpa only [Fintype.card_fin, ← Int.natCast_pow, Int.natAbs_natCast] using hbound + +/-- **§5.4 & Appendix B.3 (exact modular recovery of `commonZeroCount` from coordinate quotients +for `ReplacementDesign`)**: when `n < ℓ` and `∀ i ∈ I, ∀ M ∈ P i, #M ≤ k`, summing the exact +integer quotients +`(univariateClearedParityCoord I P (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb) s).eval 0 / + clearedProductDenom (commonDenom Q R : ℤ) k ℓ #I` +over `s ∈ range ℓ` and reducing modulo `2 ^ ℓ` recovers `commonZeroCount I P`. -/ +theorem emod_sum_ediv_eval_zero_clearedParityCoord_design_eq_commonZeroCount + {F : Type*} [Fintype F] {scope : F → Finset (Fin n)} + (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (I : Finset κ) (P : κ → Finset (Finset (Fin n))) {k ℓ : ℕ} (hℓ : n < ℓ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) : + (∑ s ∈ range ℓ, + (univariateClearedParityCoord I P (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb) s).eval 0 / + clearedProductDenom (commonDenom Q R : ℤ) k ℓ #I) % ((2 : ℤ) ^ ℓ) = + commonZeroCount I P := + emod_sum_ediv_eval_zero_univariateClearedParityCoord_eq_commonZeroCount I P + (commonDenom_intCast_ne_zero Q R) (by simpa only [Fintype.card_fin] using hℓ) + (designReplacementScaledIntMap D emb) hk + (fun x i _ _ _ v _ => eval_zero_designReplacementScaledIntMap D emb x i v) + +/-- **§5.4 & Appendix B.3 (exact modular recovery of `commonZeroCount` from +$S_\ell(\tilde{H})(0) / \Omega$ for `ReplacementDesign`)**: under the same hypotheses, dividing +`(univariateClearedParityTruncatedSum I P (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb)).eval 0` by +`clearedProductDenom (commonDenom Q R : ℤ) k ℓ #I` and reducing modulo `2 ^ ℓ` recovers +`commonZeroCount I P`. -/ +theorem emod_ediv_eval_zero_clearedParityTruncatedSum_design_eq_commonZeroCount + {F : Type*} [Fintype F] {scope : F → Finset (Fin n)} + (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (I : Finset κ) (P : κ → Finset (Finset (Fin n))) {k ℓ : ℕ} (hℓ : n < ℓ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) : + ((univariateClearedParityTruncatedSum I P (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb)).eval 0 / + clearedProductDenom (commonDenom Q R : ℤ) k ℓ #I) % ((2 : ℤ) ^ ℓ) = + commonZeroCount I P := + emod_ediv_eval_zero_univariateClearedParityTruncatedSum_eq_commonZeroCount I P + (commonDenom_intCast_ne_zero Q R) (by simpa only [Fintype.card_fin] using hℓ) + (designReplacementScaledIntMap D emb) hk + (fun x i _ _ _ v _ => eval_zero_designReplacementScaledIntMap D emb x i v) + +/-- **Appendix B.3 (eq. B.1, Cramer's rule determinant exact division recovery for +`ReplacementDesign`)**: if `D_H ≠ 0`, `n < ℓ`, `∀ i ∈ I, ∀ M ∈ P i, #M ≤ k`, and +`N_H s = D_H * (univariateClearedParityCoord I P (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb) s).eval 0` for all `s ∈ range ℓ`, then summing the exact +integer quotients `N_H s / (clearedProductDenom (commonDenom Q R : ℤ) k ℓ #I * D_H)` over +`s ∈ range ℓ` and reducing modulo `2 ^ ℓ` recovers `commonZeroCount I P`. -/ +theorem emod_sum_cramer_ediv_design_eq_commonZeroCount {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + (I : Finset κ) (P : κ → Finset (Finset (Fin n))) {D_H : ℤ} (hDH : D_H ≠ 0) + {k ℓ : ℕ} (hℓ : n < ℓ) (N_H : ℕ → ℤ) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) + (hcramer : ∀ s ∈ range ℓ, + N_H s = D_H * (univariateClearedParityCoord I P (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb) s).eval 0) : + (∑ s ∈ range ℓ, + N_H s / (clearedProductDenom (commonDenom Q R : ℤ) k ℓ #I * D_H)) % ((2 : ℤ) ^ ℓ) = + commonZeroCount I P := + emod_sum_cramer_ediv_eq_commonZeroCount I P (commonDenom_intCast_ne_zero Q R) hDH + (by simpa only [Fintype.card_fin] using hℓ) (designReplacementScaledIntMap D emb) N_H hk + (fun x i _ _ _ v _ => eval_zero_designReplacementScaledIntMap D emb x i v) hcramer + +/-- **§5.5 & Appendix B.3 (branch-summed exact integer division recovery from per-branch +`ReplacementDesign`s at shared precision $\ell = n + 1$)**: given a heavy-variable subset +`S : Finset (Fin n)`, a relabeling `e : ↥(univ \ S) ≃ Fin n'` of the free variables, and a +per-branch `ReplacementDesign` family `D : (Fin n → Bool) → ReplacementDesign (scope b) Q r A₀ R τ` +(with factor embeddings `emb b : κ → F`), summing the branch modular residues at shared precision +`branchPrecision n = n + 1` across `b ∈ branchAssignments S` recovers `commonZeroCount I P`. -/ +theorem commonZeroCount_eq_sum_branch_emod_ediv_design {F : Type*} [Fintype F] {n' : ℕ} + (S : Finset (Fin n)) (e : ↥(univ \ S) ≃ Fin n') + (I : Finset κ) (P : κ → Finset (Finset (Fin n))) {k : ℕ} + (scope : (Fin n → Bool) → F → Finset (Fin n')) + (D : (b : Fin n → Bool) → ReplacementDesign (scope b) Q r A₀ R τ) + (emb : (Fin n → Bool) → κ → F) + (hk : ∀ i ∈ I, ∀ M ∈ P i, #M ≤ k) : + (commonZeroCount I P : ℤ) = + ∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum I + (fun i => relabelRestrictedMonomials S e b (P i)) + (commonDenom Q R : ℤ) k (branchPrecision n) + (designReplacementScaledIntMap (D b) (emb b))).eval 0 / + clearedProductDenom (commonDenom Q R : ℤ) k (branchPrecision n) #I) % + ((2 : ℤ) ^ branchPrecision n) := by + simpa only [Fintype.card_fin] using + commonZeroCount_eq_sum_branch_emod_ediv_cleared S e I P + (commonDenom_intCast_ne_zero Q R) + (fun b => designReplacementScaledIntMap (D b) (emb b)) hk + (fun b _ x i _ _ _ v _ => eval_zero_designReplacementScaledIntMap (D b) (emb b) x i v) + +end Cslib.BitString diff --git a/ComplexityTests/SparseReplacementDesign.lean b/ComplexityTests/SparseReplacementDesign.lean new file mode 100644 index 0000000000..ab2b69ea3e --- /dev/null +++ b/ComplexityTests/SparseReplacementDesign.lean @@ -0,0 +1,106 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Foundations.BooleanAnalysis.SparseReplacementDesign +import Mathlib.Tactic.NormNum + +/-! +# Tests for `Complexity.Foundations.BooleanAnalysis.SparseReplacementDesign` + +Concrete checks and nonvacuous witnesses for neutral-singleton augmented equation scopes, +`designRowNormBound`, `exists_replacementDesign_augmentedEquationScope`, and the +`ReplacementDesign` specializations of cleared-denominator zero counting and heavy-variable +branch recovery. +-/ + +@[expose] public noncomputable section + +namespace Cslib.BitString.SparseReplacementDesignTests + +open Finset Polynomial +open scoped BigOperators +open Cslib.BalancedSchedules Cslib.LinearAlgebra + +/-- Concrete equation family on `Fin 3` with two equations: +- equation `0`: `x₀ + x₀ x₁ = 0` (monomials `{0}`, `{0, 1}`; scope `{0, 1}`), +- equation `1`: `x₁ x₂ + 1 = 0` (monomials `{1, 2}`, `∅`; scope `{1, 2}`). -/ +def sampleEqs : Fin 2 → Finset (Finset (Fin 3)) + | ⟨0, _⟩ => {{0}, {0, 1}} + | ⟨1, _⟩ => {{1, 2}, ∅} + +/-- Total incidence of `augmentedEquationScope sampleEqs` is `(2 + 2) + 3 = 7 ≥ 3`. -/ +example : + (∑ f : Fin 2 ⊕ Fin 3, #(augmentedEquationScope sampleEqs f)) = 7 ∧ + 3 ≤ ∑ f : Fin 2 ⊕ Fin 3, #(augmentedEquationScope sampleEqs f) := by + refine ⟨?_, le_sum_card_augmentedEquationScope sampleEqs⟩ + rw [sum_card_augmentedEquationScope] + decide + +/-- Variable `1 : Fin 3` belongs to both equation scopes plus its neutral singleton scope +(`2 + 1 = 3` scopes total), whereas variable `0 : Fin 3` belongs to `1 + 1 = 2` scopes. -/ +example : + #{f : Fin 2 ⊕ Fin 3 | (1 : Fin 3) ∈ augmentedEquationScope sampleEqs f} = 3 ∧ + #{f : Fin 2 ⊕ Fin 3 | (0 : Fin 3) ∈ augmentedEquationScope sampleEqs f} = 2 := by + rw [card_filter_mem_augmentedEquationScope, card_filter_mem_augmentedEquationScope] + decide + +/-- Explicit value of `designRowNormBound 3 2`: +`commonDenom 3 2 = 1! * 3! = 6` and `1 + (1 + 2 ^ 3) * 2 * (4 * 3) ^ 1 = 1 + 9 * 2 * 12 = 217`, +so `designRowNormBound 3 2 = 6 * 217 = 1302`. -/ +example : + commonDenom 3 2 = 6 ∧ + designRowNormBound 3 2 = 1302 ∧ + commonDenom 3 2 ≤ designRowNormBound 3 2 ∧ + 0 < designRowNormBound 3 2 := by + refine ⟨by decide, by decide, commonDenom_le_designRowNormBound 3 2, designRowNormBound_pos 3 2⟩ + +/-- Empty equation family on `n = 16384` variables used to witness +`exists_replacementDesign_augmentedEquationScope` with `b₀ = 0` (`b = 1`), `w = 1`, `Q = 3`, +`r = 2`, `A₀ = 0`, `R = 2`, `τ = 1 / 2`. -/ +def emptyEqs16384 : Fin 0 → Finset (Finset (Fin 16384)) := + Fin.elim0 + +/-- Nonvacuous witness of `exists_replacementDesign_augmentedEquationScope` and exact modular +recovery of `commonZeroCount = 2 ^ 16384` at precision `ℓ = 16385`. -/ +theorem exists_design_and_recover_emptyEqs16384 : + ∃ D : ReplacementDesign (augmentedEquationScope emptyEqs16384) 3 2 0 2 (1 / 2), + ((univariateClearedParityTruncatedSum (univ : Finset (Fin 0)) emptyEqs16384 + (commonDenom 3 2 : ℤ) 3 16385 + (designReplacementScaledIntMap D Sum.inl)).eval 0 / + clearedProductDenom (commonDenom 3 2 : ℤ) 3 16385 #(univ : Finset (Fin 0))) % + ((2 : ℤ) ^ 16385) = + (2 : ℤ) ^ 16384 := by + have hcard : #(measurementIndices 3 2 0 2) = 10 := by + rw [card_measurementIndices_eq] + decide + have htail : binomTailProb 3 2 0 2 ≤ (1 / 2 : ℚ) / ((2 : ℚ) * ((0 + 1 : ℕ) : ℚ)) := by + rw [binomTailProb_eq_div 3 2 0 2 (by decide), hcard] + norm_num + have hne : Nonempty (ReplacementDesign (augmentedEquationScope emptyEqs16384) 3 2 0 2 (1 / 2)) := + exists_replacementDesign_augmentedEquationScope emptyEqs16384 (b₀ := 0) (w := 1) + (by decide) (by decide) (by decide) (by decide) (by decide) (by norm_num) + (by intro a ha; omega) + (fun v => by simp) + (fun i => Fin.elim0 i) + (by decide) + (by decide) + htail + obtain ⟨D⟩ := hne + refine ⟨D, ?_⟩ + have hrec := + emod_ediv_eval_zero_clearedParityTruncatedSum_design_eq_commonZeroCount D Sum.inl + (univ : Finset (Fin 0)) emptyEqs16384 (k := 3) (ℓ := 16385) (by decide) + (fun i => Fin.elim0 i) + have hcount : (commonZeroCount (univ : Finset (Fin 0)) emptyEqs16384 : ℤ) = (2 : ℤ) ^ 16384 := by + have hempty : (univ : Finset (Fin 0)) = ∅ := rfl + rw [hempty, commonZeroCount_empty, Fintype.card_fin, Nat.cast_pow, Nat.cast_ofNat] + exact hrec.trans hcount + +end Cslib.BitString.SparseReplacementDesignTests From 1d6220a81afe423bfa8aea36b34d8211541485ae Mon Sep 17 00:00:00 2001 From: Samuel Schlesinger Date: Tue, 27 Oct 2026 04:14:50 +0000 Subject: [PATCH 12/20] test(BooleanAnalysis): add concrete expected-value and checked branch-recovery clients for SparseReplacementDesign --- ComplexityTests/SparseReplacementDesign.lean | 118 ++++++++++++++++++- 1 file changed, 117 insertions(+), 1 deletion(-) diff --git a/ComplexityTests/SparseReplacementDesign.lean b/ComplexityTests/SparseReplacementDesign.lean index ab2b69ea3e..27e85be521 100644 --- a/ComplexityTests/SparseReplacementDesign.lean +++ b/ComplexityTests/SparseReplacementDesign.lean @@ -30,11 +30,19 @@ open Cslib.BalancedSchedules Cslib.LinearAlgebra /-- Concrete equation family on `Fin 3` with two equations: - equation `0`: `x₀ + x₀ x₁ = 0` (monomials `{0}`, `{0, 1}`; scope `{0, 1}`), -- equation `1`: `x₁ x₂ + 1 = 0` (monomials `{1, 2}`, `∅`; scope `{1, 2}`). -/ +- equation `1`: `x₁ x₂ + 1 = 0` (monomials `{1, 2}`, `∅`; scope `{1, 2}`). +Its satisfying assignments are `(false, true, true)` and `(true, true, true)` (`2` common zeros). -/ def sampleEqs : Fin 2 → Finset (Finset (Fin 3)) | ⟨0, _⟩ => {{0}, {0, 1}} | ⟨1, _⟩ => {{1, 2}, ∅} +/-- Expected-value control: `sampleEqs` has `commonZeroCount = 2`, while the empty equation set has +`commonZeroCount = 8`. -/ +example : + commonZeroCount univ sampleEqs = 2 ∧ + commonZeroCount (∅ : Finset (Fin 2)) sampleEqs = 8 := by + decide + /-- Total incidence of `augmentedEquationScope sampleEqs` is `(2 + 2) + 3 = 7 ≥ 3`. -/ example : (∑ f : Fin 2 ⊕ Fin 3, #(augmentedEquationScope sampleEqs f)) = 7 ∧ @@ -61,6 +69,114 @@ example : 0 < designRowNormBound 3 2 := by refine ⟨by decide, by decide, commonDenom_le_designRowNormBound 3 2, designRowNormBound_pos 3 2⟩ +/-- Canonical `Q = 1, r = 1, A₀ = 0, R = 1, τ = 0` replacement design for any scope family on +`Fin n` (`1 ≤ n`), used to exercise concrete branch-recovery and degree/norm specialization lemmas +on small explicit formulas. -/ +def unitReplacementDesign {F : Type*} [Fintype F] {n : ℕ} + (scope : F → Finset (Fin n)) : ReplacementDesign scope 1 1 0 1 0 := + let h := Fintype.card (ScopeIncidence scope) + let eFin := Fintype.equivFin (ScopeIncidence scope) + let place : ScopeIncidence scope → Fin h × AuxLabel 1 1 := + fun e => (eFin e, (fun _ => 0, fun _ => 0)) + have hinj : Function.Injective place := fun e₁ e₂ hEq => + eFin.injective (congrArg Prod.fst hEq) + { varAssign := fun _ _ => 0 + factorAssign := fun _ _ => 0 + h := h + place := place + card_varGroup_le := fun t g => by + have hsub : #(varGroup (fun (_ : Fin n) (_ : Fin 1) => (0 : Fin 1)) t g) ≤ n := by + simpa only [card_univ, Fintype.card_fin] using + card_le_univ (varGroup (fun (_ : Fin n) (_ : Fin 1) => (0 : Fin 1)) t g) + omega + factorAssign_of_empty := fun _ _ _ => rfl + injective_place := hinj + place_snd := fun _ => rfl + h_mul_D_le := by + change Fintype.card (ScopeIncidence scope) * 1 ^ (2 * 1) ≤ 2 * ∑ f : F, #(scope f) + rw [card_scopeIncidence] + omega + total_measurement_rows_le := by + have hmeas : #(measurementIndices 1 1 0 1) = 0 := by decide + simp [hmeas] + sum_abs_measurement_row_le := + sum_abs_varMeasurementMatrix_le 1 1 0 1 hinj (scopeVarOf scope) + natDegree_replacementRow_le := + natDegree_varReplacementRow_le 1 1 0 1 place (scopeVarOf scope) + eval_replacementRow_zero := + eval_varReplacementRow_zero 1 1 0 1 hinj (scopeVarOf scope) + evalReplacementRow_nodePoint_eq_zero_of_kernel := fun e t g hg ξ hsupp hker => + evalVarReplacementRow_nodePoint_eq_zero_of_kernel 1 1 0 1 place (scopeVarOf scope) + (fun _ _ => 0) (fun _ => rfl) e t g hg ξ hsupp hker + map_replacementRowScaledInt := + map_varReplacementRowScaledInt 1 1 0 1 place (scopeVarOf scope) + sum_coeffNorm1_replacementRowScaledInt_le := + sum_coeffNorm1_varReplacementRowScaledInt_le (by decide) hinj (scopeVarOf scope) + (by intro a ha; omega) } + +/-- Explicit equivalence between the unbranched variables `{0, 2}` (`univ \ {1}` in `Fin 3`) and +`Fin 2`. -/ +def sampleFreeVarEquiv : ↥((univ : Finset (Fin 3)) \ ({1} : Finset (Fin 3))) ≃ Fin 2 where + toFun v := if v.1 = 0 then 0 else 1 + invFun i := if i = 0 then ⟨0, by decide⟩ else ⟨2, by decide⟩ + left_inv := by decide + right_inv := by decide + +/-- Checked client of `commonZeroCount_eq_sum_branch_emod_ediv_design` on `sampleEqs` with partial +branching set `S = {1}` (branching on variable `1 : Fin 3` and leaving `{0, 2} ≃ Fin 2` free): +the branch-summed `ReplacementDesign` recovery equals the exact count `2`. -/ +example : + ∑ b ∈ branchAssignments ({1} : Finset (Fin 3)), + ((univariateClearedParityTruncatedSum (univ : Finset (Fin 2)) + (fun i => relabelRestrictedMonomials ({1} : Finset (Fin 3)) sampleFreeVarEquiv b + (sampleEqs i)) + (commonDenom 1 1 : ℤ) 2 (branchPrecision 3) + (designReplacementScaledIntMap + (unitReplacementDesign + (augmentedEquationScope fun i => + relabelRestrictedMonomials ({1} : Finset (Fin 3)) sampleFreeVarEquiv b + (sampleEqs i))) + Sum.inl)).eval 0 / + clearedProductDenom (commonDenom 1 1 : ℤ) 2 (branchPrecision 3) + #(univ : Finset (Fin 2))) % + ((2 : ℤ) ^ branchPrecision 3) = 2 := by + have hrec := commonZeroCount_eq_sum_branch_emod_ediv_design + ({1} : Finset (Fin 3)) sampleFreeVarEquiv (univ : Finset (Fin 2)) sampleEqs (k := 2) + (fun b => augmentedEquationScope fun i => + relabelRestrictedMonomials ({1} : Finset (Fin 3)) sampleFreeVarEquiv b (sampleEqs i)) + (fun b => unitReplacementDesign + (augmentedEquationScope fun i => + relabelRestrictedMonomials ({1} : Finset (Fin 3)) sampleFreeVarEquiv b (sampleEqs i))) + (fun _ => Sum.inl) + (by decide) + have hcount : commonZeroCount (univ : Finset (Fin 2)) sampleEqs = 2 := by decide + rw [← hrec, hcount] + rfl + +/-- Concrete degree and `coeffNorm1` bounds on `sampleEqs` via `unitReplacementDesign`: at degree +bound `k = 2` and precision `ℓ = 4`, the truncated sum has `natDegree = 0` (`≤ 0`) and every +coordinate polynomial has `coeffNorm1` bounded by +`2 ^ 3 * (4 * E_ℓ * (2 * designRowNormBound 1 1 ^ 2 + commonDenom 1 1 ^ 2) ^ 7) ^ 2`. -/ +example {E_ℓ : ℕ} (hE : ∀ j < 4, (Polynomial.parityBaseDigit 4 j).coeffNorm1 ≤ E_ℓ) (s : ℕ) : + (univariateClearedParityTruncatedSum (univ : Finset (Fin 2)) sampleEqs + (commonDenom 1 1 : ℤ) 2 4 + (designReplacementScaledIntMap + (unitReplacementDesign (augmentedEquationScope sampleEqs)) Sum.inl)).natDegree ≤ 0 ∧ + (univariateClearedParityCoord (univ : Finset (Fin 2)) sampleEqs + (commonDenom 1 1 : ℤ) 2 4 + (designReplacementScaledIntMap + (unitReplacementDesign (augmentedEquationScope sampleEqs)) Sum.inl) s).coeffNorm1 ≤ + 2 ^ 3 * + (4 * E_ℓ * + (2 * designRowNormBound 1 1 ^ 2 + commonDenom 1 1 ^ 2) ^ (2 * 4 - 1)) ^ 2 := by + refine ⟨?_, ?_⟩ + · simpa using natDegree_univariateClearedParityTruncatedSum_design_le + (unitReplacementDesign (augmentedEquationScope sampleEqs)) Sum.inl + (univ : Finset (Fin 2)) sampleEqs 2 4 (by decide) + · simpa using coeffNorm1_univariateClearedParityCoord_design_le + (unitReplacementDesign (augmentedEquationScope sampleEqs)) Sum.inl + (univ : Finset (Fin 2)) sampleEqs 2 4 (S_mon := 2) (by decide) (by decide) hE s + /-- Empty equation family on `n = 16384` variables used to witness `exists_replacementDesign_augmentedEquationScope` with `b₀ = 0` (`b = 1`), `w = 1`, `Q = 3`, `r = 2`, `A₀ = 0`, `R = 2`, `τ = 1 / 2`. -/ From f0bdbb0ab2deb4f74e05cf3507c17a93862b9ede Mon Sep 17 00:00:00 2001 From: Samuel Schlesinger Date: Tue, 27 Oct 2026 04:49:59 +0000 Subject: [PATCH 13/20] fix(BooleanAnalysis/SparseReplacementDesign): address #1294 review items - Replace duplicate augmentedEquationScope with SparseBranching.withNeutralScope and withNeutralFactors - Add scoped locality theorems eval_nodePoint_designReplacementMap_eq_of_eq_on_varGroup and eval_univariateMonomialSumPoly_designReplacementMap_nodePoint_eq - Add nonconstSampleDesign test exercising nonconstant degree-1 replacement rows and factor-level locality - Document eq. (5.5) degree strengthening, exists_replacementDesign_withNeutralScope numerical hypotheses, and emod_sum_cramer_ediv_design_eq_commonZeroCount hcramer premise --- .../SparseReplacementDesign.lean | 295 +++++++++--------- ComplexityTests/SparseReplacementDesign.lean | 217 +++++++++++-- 2 files changed, 343 insertions(+), 169 deletions(-) diff --git a/Complexity/Foundations/BooleanAnalysis/SparseReplacementDesign.lean b/Complexity/Foundations/BooleanAnalysis/SparseReplacementDesign.lean index 2c091a37cd..0cc8c74195 100644 --- a/Complexity/Foundations/BooleanAnalysis/SparseReplacementDesign.lean +++ b/Complexity/Foundations/BooleanAnalysis/SparseReplacementDesign.lean @@ -22,14 +22,19 @@ Appendix B.2–B.3 cleared-denominator parity-polynomial zero-counting pipeline 48–50): 1. **Neutral singleton scope augmentation (§5.3 & §5.5, pp. 37–38)**: - Given an equation family `P : κ → Finset (Finset (Fin n))`, `augmentedEquationScope P` augments - the equation scopes `equationScope (P i)` (`Sum.inl i`) with one singleton scope `{v}` - (`Sum.inr v`) per variable `v : Fin n`. This ensures that every variable occurs in at least one - factor scope, that the total incidence count is `(∑ i, #(equationScope (P i))) + n ≥ n` - (`sum_card_augmentedEquationScope`, `le_sum_card_augmentedEquationScope`), and that per-variable - factor occurrences increase by exactly `1` (`card_filter_mem_augmentedEquationScope`), so - Lemma 4.7 (`exists_replacementDesign`) applies directly whenever equation occurrences are bounded - by `b₀` and equation scopes by `w ≥ 1` (`exists_replacementDesign_augmentedEquationScope`). + Reusing `withNeutralFactors` and `withNeutralScope` from + `Complexity.Foundations.BooleanAnalysis.SparseBranching` on + `scope = fun i => equationScope (P i)` adjoins one singleton scope `{v}` (`Sum.inr v`) per + variable `v : Fin n` to the equation scopes `equationScope (P i)` (`Sum.inl i`). Combined with + `totalIncidence_withNeutralFactors` (`M = (∑ i, #(equationScope (P i))) + n ≥ n`) and + `varIncidence_withNeutralFactors_le` (`varIncidence ≤ b₀ + 1`), we prove + `card_withNeutralScope_le`, `totalIncidence_withNeutralFactors_le`, and + `exists_replacementDesign_withNeutralScope`: Lemma 4.7 (`exists_replacementDesign`) applies to + `withNeutralScope (fun i => equationScope (P i))` whenever equation variable occurrences are + bounded by `b₀`, equation scopes have size at most `w ≥ 1`, and the numerical balance + (`2 * (b₀ + 1 + w) * (r ^ (2 * Q)) ^ 2 ≤ (∑ i, #(equationScope (P i))) + n`, + `2 * Q * r ^ 2 ≤ n`), interval (`∀ a < R - 1, A₀ + a ≤ Q`), and binomial-tail + (`binomTailProb Q r A₀ R ≤ τ / (r * (b₀ + 1))`) hypotheses hold for `b = b₀ + 1`. 2. **Univariate polynomial replacement rows from a `ReplacementDesign` (§5.3–5.4, pp. 37–38)**: For any `D : ReplacementDesign scope Q r A₀ R τ`, incidence `e : ScopeIncidence scope`, and @@ -47,17 +52,22 @@ Appendix B.2–B.3 cleared-denominator parity-polynomial zero-counting pipeline `designRowNormBound Q R = commonDenom Q R * (1 + (1 + 2 ^ Q) * R * (4 * Q) ^ (R - 1))`, and - at each evaluation node `nodePoint t` (`t : Fin Q`), `(evalVarReplacementRowPoly D e x).eval (nodePoint t)` depends only on `x` restricted to the assigned variable group - `varGroup D.varAssign t (D.factorAssign (scopeFactorOf scope e) t)` and the measurement vector - `(varMeasurementMatrix Q r A₀ R ℚ D.place (scopeVarOf scope)).mulVec + `varGroup D.varAssign t (D.factorAssign (scopeFactorOf scope e) t)` and the full measurement + vector `(varMeasurementMatrix Q r A₀ R ℚ D.place (scopeVarOf scope)).mulVec (fun u => bitVal ℚ (x u))`. -3. **Concrete §5.3–5.5 degree, norm, and exact modular zero-counting theorems**: +3. **Concrete §5.3–5.5 degree, locality, norm, and exact modular zero-counting theorems**: Packaging these replacement rows into `designReplacementMap D emb` and - `designReplacementScaledIntMap D emb` (for any factor embedding `emb : κ → F`) discharges all - clearing, degree, $T = 0$ evaluation, and `coeffNorm1` premises of - `SparseClearedSpecialization`, yielding concrete `ReplacementDesign` specializations of: - - the equation (5.5a) degree bound `(k * (R - 1)) * (#I + 2 * (ℓ - 1))` - (`natDegree_univariateClearedParityCoord_design_le`, + `designReplacementScaledIntMap D emb` (for any factor embedding `emb : κ → F`, falling back to + the constant Boolean value outside `scope (emb i)`) discharges all clearing, degree, $T = 0$ + evaluation, and `coeffNorm1` premises of `SparseClearedSpecialization` unconditionally, and + preserves node-point group-and-measurement locality on covered scopes + (`eval_nodePoint_designReplacementMap_eq_of_eq_on_varGroup`, + `eval_univariateMonomialSumPoly_designReplacementMap_nodePoint_eq`). This + yields concrete `ReplacementDesign` specializations of: + - the equation (5.5) degree bound `(k * (R - 1)) * (#I + 2 * (ℓ - 1))` (strengthening the + manuscript's coarser `k * R * (#I + 2 * (ℓ - 1))` display on p. 37 using `natDegree ≤ R - 1` + from Definition 3.1 (4); `natDegree_univariateClearedParityCoord_design_le`, `natDegree_univariateClearedParityTruncatedSum_design_le`), - the rational homogenization identity $\tilde{H}_s(T) = \Omega [V^s] H(T)$ over `ℚ[X]` (`map_univariateClearedParityCoord_design`, @@ -65,8 +75,10 @@ Appendix B.2–B.3 cleared-denominator parity-polynomial zero-counting pipeline - the Appendix B.2 coordinate `ℓ₁`-norm bound (`coeffNorm1_univariateClearedParityCoord_design_le`), - exact integer division and modulo-`2 ^ ℓ` recovery of `commonZeroCount I P` when `n < ℓ` and - `∀ i ∈ I, ∀ M ∈ P i, #M ≤ k`, including Cramer's rule determinant recovery (when `D_H ≠ 0`) - and §5.5 heavy-variable branch summation at shared precision `branchPrecision n = n + 1` + `∀ i ∈ I, ∀ M ∈ P i, #M ≤ k`, including Cramer's rule determinant recovery (under `D_H ≠ 0` + and the Cramer numerator identity `hcramer : ∀ s ∈ range ℓ, N_H s = D_H * + (univariateClearedParityCoord ... s).eval 0`) and §5.5 heavy-variable branch summation at + shared precision `branchPrecision n = n + 1` (`emod_sum_ediv_eval_zero_clearedParityCoord_design_eq_commonZeroCount`, `emod_ediv_eval_zero_clearedParityTruncatedSum_design_eq_commonZeroCount`, `emod_sum_cramer_ediv_design_eq_commonZeroCount`, @@ -74,8 +86,6 @@ Appendix B.2–B.3 cleared-denominator parity-polynomial zero-counting pipeline ## Main definitions -* `Cslib.BitString.augmentedEquationScope`: scope family on `κ ⊕ Fin n` combining - `equationScope (P i)` with neutral singleton scopes `{v}`. * `Cslib.BitString.designRowNormBound`: the Lemma 4.6 row `ℓ₁`-norm bound `commonDenom Q R * (1 + (1 + 2 ^ Q) * R * (4 * Q) ^ (R - 1))`. * `Cslib.BitString.evalVarReplacementRowPoly`, @@ -87,18 +97,20 @@ Appendix B.2–B.3 cleared-denominator parity-polynomial zero-counting pipeline ## Main results -* `Cslib.BitString.sum_card_augmentedEquationScope`, - `Cslib.BitString.card_filter_mem_augmentedEquationScope`, - `Cslib.BitString.exists_replacementDesign_augmentedEquationScope`: incidence count, variable - occurrence count, and Lemma 4.7 existence for neutral-singleton augmented equation scopes. +* `Cslib.BitString.card_withNeutralScope_le`, + `Cslib.BitString.totalIncidence_withNeutralFactors_le`, + `Cslib.BitString.exists_replacementDesign_withNeutralScope`: scope-width bound, total-incidence + upper bound, and Lemma 4.7 existence for `withNeutralScope`. * `Cslib.BitString.map_evalVarReplacementRowScaledIntPoly`, `Cslib.BitString.eval_zero_evalVarReplacementRowPoly`, `Cslib.BitString.eval_zero_evalVarReplacementRowScaledIntPoly`, `Cslib.BitString.natDegree_evalVarReplacementRowScaledIntPoly_le`, `Cslib.BitString.coeffNorm1_evalVarReplacementRowScaledIntPoly_le`, - `Cslib.BitString.eval_evalVarReplacementRowPoly_nodePoint_eq_of_eq_on_varGroup`: - Definition 3.1 and Lemma 4.6 properties of `evalVarReplacementRowPoly` and - `evalVarReplacementRowScaledIntPoly`. + `Cslib.BitString.eval_evalVarReplacementRowPoly_nodePoint_eq_of_eq_on_varGroup`, + `Cslib.BitString.eval_nodePoint_designReplacementMap_eq_of_eq_on_varGroup`, + `Cslib.BitString.eval_univariateMonomialSumPoly_designReplacementMap_nodePoint_eq`: + Definition 3.1 and Lemma 4.6 properties of `evalVarReplacementRowPoly`, + `evalVarReplacementRowScaledIntPoly`, and `designReplacementMap`. * `Cslib.BitString.natDegree_univariateClearedParityCoord_design_le`, `Cslib.BitString.natDegree_univariateClearedParityTruncatedSum_design_le`, `Cslib.BitString.map_univariateClearedParityCoord_design`, @@ -127,120 +139,73 @@ open Cslib.BalancedSchedules Cslib.LinearAlgebra variable {κ : Type*} {n Q r A₀ R : ℕ} {τ : ℚ} -/-! ### 1. Neutral singleton scope augmentation (§5.3 & §5.5, pp. 37–38) -/ - -/-- The augmented factor scope family on `κ ⊕ Fin n` combining the equation scopes -`equationScope (P i)` (`Sum.inl i`) with one neutral singleton scope `{v}` (`Sum.inr v`) per -variable `v : Fin n` (§5.3 and §5.5, printed pp. 37–38). -/ -def augmentedEquationScope (P : κ → Finset (Finset (Fin n))) : κ ⊕ Fin n → Finset (Fin n) - | Sum.inl i => equationScope (P i) - | Sum.inr v => {v} - -@[simp] -theorem augmentedEquationScope_inl (P : κ → Finset (Finset (Fin n))) (i : κ) : - augmentedEquationScope P (Sum.inl i) = equationScope (P i) := - rfl +/-! ### 1. Neutral singleton scope augmentation via `withNeutralScope` (§5.3 & §5.5, pp. 37–38) -/ +/-- `withNeutralFactors (univ : Finset κ)` is `(univ : Finset (κ ⊕ ι'))`. -/ @[simp] -theorem augmentedEquationScope_inr (P : κ → Finset (Finset (Fin n))) (v : Fin n) : - augmentedEquationScope P (Sum.inr v) = {v} := - rfl - -/-- Every variable `v ∈ M` of a monomial `M ∈ P i` belongs to -`augmentedEquationScope P (Sum.inl i)`. -/ -theorem mem_augmentedEquationScope_inl_of_mem {P : κ → Finset (Finset (Fin n))} {i : κ} - {M : Finset (Fin n)} {v : Fin n} (hM : M ∈ P i) (hv : v ∈ M) : - v ∈ augmentedEquationScope P (Sum.inl i) := - mem_biUnion.mpr ⟨M, hM, hv⟩ - -/-- The total incidence count of `augmentedEquationScope P` equals -`(∑ i : κ, #(equationScope (P i))) + n`. -/ -theorem sum_card_augmentedEquationScope [Fintype κ] (P : κ → Finset (Finset (Fin n))) : - (∑ f : κ ⊕ Fin n, #(augmentedEquationScope P f)) = - (∑ i : κ, #(equationScope (P i))) + n := by - simp only [Fintype.sum_sum_type, augmentedEquationScope_inl, augmentedEquationScope_inr, - card_singleton, sum_const, card_univ, Fintype.card_fin, smul_eq_mul, mul_one] - -/-- Neutral singleton factors ensure that the total incidence count of `augmentedEquationScope P` -is at least `n` (§5.5, p. 38: `M' ≥ n'`). -/ -theorem le_sum_card_augmentedEquationScope [Fintype κ] (P : κ → Finset (Finset (Fin n))) : - n ≤ ∑ f : κ ⊕ Fin n, #(augmentedEquationScope P f) := by - rw [sum_card_augmentedEquationScope] - exact Nat.le_add_left n _ - -/-- If `1 ≤ w` and every equation scope `equationScope (P i)` has size at most `w`, then every -scope in `augmentedEquationScope P` has size at most `w`. -/ -theorem card_augmentedEquationScope_le {P : κ → Finset (Finset (Fin n))} {w : ℕ} - (hw1 : 1 ≤ w) (hw : ∀ i : κ, #(equationScope (P i)) ≤ w) (f : κ ⊕ Fin n) : - #(augmentedEquationScope P f) ≤ w := by +theorem withNeutralFactors_univ [Fintype κ] {ι' : Type*} [Fintype ι'] : + withNeutralFactors (univ : Finset κ) = (univ : Finset (κ ⊕ ι')) := by + ext f + cases f <;> simp [withNeutralFactors] + +/-- If `1 ≤ w` and every scope `scope i` has size at most `w`, then every scope in +`withNeutralScope scope` has size at most `w`. -/ +theorem card_withNeutralScope_le {ι' : Type*} {scope : κ → Finset ι'} {w : ℕ} + (hw1 : 1 ≤ w) (hw : ∀ i : κ, #(scope i) ≤ w) (f : κ ⊕ ι') : + #(withNeutralScope scope f) ≤ w := by cases f with | inl i => exact hw i - | inr v => simpa only [augmentedEquationScope_inr, card_singleton] using hw1 - -/-- Each variable `v : Fin n` occurs in `#{i : κ | v ∈ equationScope (P i)} + 1` scopes of -`augmentedEquationScope P` (its equation occurrences plus its neutral singleton scope). -/ -theorem card_filter_mem_augmentedEquationScope [Fintype κ] - (P : κ → Finset (Finset (Fin n))) (v : Fin n) : - #{f : κ ⊕ Fin n | v ∈ augmentedEquationScope P f} = - #{i : κ | v ∈ equationScope (P i)} + 1 := by - rw [card_filter, card_filter, Fintype.sum_sum_type] - simp only [augmentedEquationScope_inl, augmentedEquationScope_inr, mem_singleton, sum_ite_eq, - mem_univ, ↓reduceIte] - congr 1 - -/-- If every variable occurs in at most `b₀` equation scopes, then every variable occurs in at most -`b₀ + 1` scopes of `augmentedEquationScope P`. -/ -theorem card_filter_mem_augmentedEquationScope_le [Fintype κ] - {P : κ → Finset (Finset (Fin n))} {b₀ : ℕ} - (hb : ∀ v : Fin n, #{i : κ | v ∈ equationScope (P i)} ≤ b₀) (v : Fin n) : - #{f : κ ⊕ Fin n | v ∈ augmentedEquationScope P f} ≤ b₀ + 1 := by - rw [card_filter_mem_augmentedEquationScope] - exact Nat.add_le_add_right (hb v) 1 - -/-- If every variable occurs in at most `b₀` equation scopes, then the total incidence count of -`augmentedEquationScope P` is at most `(b₀ + 1) * n`. -/ -theorem sum_card_augmentedEquationScope_le [Fintype κ] - {P : κ → Finset (Finset (Fin n))} {b₀ : ℕ} - (hb : ∀ v : Fin n, #{i : κ | v ∈ equationScope (P i)} ≤ b₀) : - (∑ f : κ ⊕ Fin n, #(augmentedEquationScope P f)) ≤ (b₀ + 1) * n := by - classical - have hswap : - (∑ f : κ ⊕ Fin n, #(augmentedEquationScope P f)) = - ∑ v : Fin n, #{f : κ ⊕ Fin n | v ∈ augmentedEquationScope P f} := by - simp only [card_eq_sum_ones, sum_filter] - rw [sum_comm] - refine sum_congr rfl fun f _ => ?_ - simp only [sum_ite_mem, univ_inter] - rw [hswap] + | inr v => simpa only [withNeutralScope, card_singleton] using hw1 + +/-- If every variable `v : ι'` has `varIncidence I scope v ≤ b₀`, then the total incidence after +adjoining neutral singleton scopes is at most `(b₀ + 1) * Fintype.card ι'`. -/ +theorem totalIncidence_withNeutralFactors_le {ι' : Type*} [Fintype ι'] [DecidableEq ι'] + {I : Finset κ} {scope : κ → Finset ι'} {b₀ : ℕ} + (hb : ∀ v : ι', varIncidence I scope v ≤ b₀) : + totalIncidence (withNeutralFactors I) (withNeutralScope scope) ≤ + (b₀ + 1) * Fintype.card ι' := by + rw [← sum_varIncidence_eq_totalIncidence (univ : Finset ι') (withNeutralFactors I) + (withNeutralScope scope) (fun _ _ => subset_univ _)] calc - (∑ v : Fin n, #{f : κ ⊕ Fin n | v ∈ augmentedEquationScope P f}) - ≤ ∑ _v : Fin n, (b₀ + 1) := - sum_le_sum fun v _ => card_filter_mem_augmentedEquationScope_le hb v - _ = (b₀ + 1) * n := by - rw [sum_const, card_univ, Fintype.card_fin, smul_eq_mul, mul_comm] - -/-- **Lemma 4.7 for neutral-singleton augmented equation scopes (§5.5, pp. 38–39)**: -when every variable belongs to at most `b₀` equation scopes and every equation scope has size at -most `w` (`1 ≤ w`), the augmented scope family `augmentedEquationScope P` satisfies `1 ≤ b₀ + 1` -and `M ≤ (b₀ + 1) * n` automatically, and admits a Section 4 `ReplacementDesign` under the balance -and binomial-tail conditions for `b = b₀ + 1`. -/ -theorem exists_replacementDesign_augmentedEquationScope [Fintype κ] - (P : κ → Finset (Finset (Fin n))) {b₀ w : ℕ} + (∑ v ∈ (univ : Finset ι'), varIncidence (withNeutralFactors I) (withNeutralScope scope) v) + ≤ ∑ _v ∈ (univ : Finset ι'), (b₀ + 1) := + sum_le_sum fun v _ => varIncidence_withNeutralFactors_le (hb v) + _ = (b₀ + 1) * Fintype.card ι' := by + rw [sum_const, card_univ, smul_eq_mul, mul_comm] + +/-- **Lemma 4.7 for neutral-singleton augmented scopes (`withNeutralScope`, §5.5, pp. 38–39)**: +when every variable belongs to at most `b₀` scopes of `scope : κ → Finset (Fin n)` and every +`scope i` has size at most `w` (`1 ≤ w`), the augmented scope family `withNeutralScope scope` +satisfies `1 ≤ b₀ + 1` and `M ≤ (b₀ + 1) * n` automatically, and admits a Section 4 +`ReplacementDesign` under the numerical balance (`2 * (b₀ + 1 + w) * (r ^ (2 * Q)) ^ 2 ≤ +totalIncidence univ scope + n`, `2 * Q * r ^ 2 ≤ n`), interval (`∀ a < R - 1, A₀ + a ≤ Q`), and +binomial-tail (`binomTailProb Q r A₀ R ≤ τ / (r * (b₀ + 1))`) hypotheses for `b = b₀ + 1`. -/ +theorem exists_replacementDesign_withNeutralScope [Fintype κ] + (scope : κ → Finset (Fin n)) {b₀ w : ℕ} (hn : 1 ≤ n) (hw_pos : 1 ≤ w) (hr : 2 ≤ r) (hR : 1 ≤ R) (hRQ : R < Q) (hτ : 0 ≤ τ) (hI : ∀ a < R - 1, A₀ + a ≤ Q) - (hb : ∀ v : Fin n, #{i : κ | v ∈ equationScope (P i)} ≤ b₀) - (hw : ∀ i : κ, #(equationScope (P i)) ≤ w) + (hb : ∀ v : Fin n, varIncidence univ scope v ≤ b₀) + (hw : ∀ i : κ, #(scope i) ≤ w) (hincidenceSize : - 2 * (b₀ + 1 + w) * (r ^ (2 * Q)) ^ 2 ≤ (∑ i : κ, #(equationScope (P i))) + n) + 2 * (b₀ + 1 + w) * (r ^ (2 * Q)) ^ 2 ≤ totalIncidence univ scope + n) (hgroupSize : 2 * Q * r ^ 2 ≤ n) (htail : binomTailProb Q r A₀ R ≤ τ / ((r : ℚ) * ((b₀ + 1 : ℕ) : ℚ))) : - Nonempty (ReplacementDesign (augmentedEquationScope P) Q r A₀ R τ) := by - refine exists_replacementDesign (augmentedEquationScope P) hn (Nat.le_add_left 1 b₀) hw_pos hr - hR hRQ hτ hI (card_filter_mem_augmentedEquationScope_le hb) - (card_augmentedEquationScope_le hw_pos hw) (sum_card_augmentedEquationScope_le hb) ?_ hgroupSize - htail - rwa [sum_card_augmentedEquationScope] + Nonempty (ReplacementDesign (withNeutralScope scope) Q r A₀ R τ) := by + have hvar : ∀ v : Fin n, #{f : κ ⊕ Fin n | v ∈ withNeutralScope scope f} ≤ b₀ + 1 := by + intro v + simpa only [varIncidence, withNeutralFactors_univ] using + varIncidence_withNeutralFactors_le (hb v) + have hM_le : (∑ f : κ ⊕ Fin n, #(withNeutralScope scope f)) ≤ (b₀ + 1) * n := by + simpa only [totalIncidence, withNeutralFactors_univ, Fintype.card_fin] using + totalIncidence_withNeutralFactors_le hb + have hM_eq : + (∑ f : κ ⊕ Fin n, #(withNeutralScope scope f)) = totalIncidence univ scope + n := by + simpa only [totalIncidence, withNeutralFactors_univ, Fintype.card_fin] using + totalIncidence_withNeutralFactors (univ : Finset κ) scope + refine exists_replacementDesign (withNeutralScope scope) hn (Nat.le_add_left 1 b₀) hw_pos hr + hR hRQ hτ hI hvar (card_withNeutralScope_le hw_pos hw) hM_le ?_ hgroupSize htail + rwa [hM_eq] /-! ### 2. Univariate replacement polynomials from a `ReplacementDesign` (§5.3–5.4, pp. 37–38) -/ @@ -268,16 +233,17 @@ theorem commonDenom_ratCast_ne_zero (Q R : ℕ) : (commonDenom Q R : ℚ) ≠ 0 Nat.cast_ne_zero.mpr (commonDenom_pos Q R).ne' /-- The univariate rational replacement polynomial `⟨P⃗_e(T), x⟩ ∈ ℚ[X]` for incidence -`e : ScopeIncidence scope` evaluated on a Boolean assignment `x : Fin n → Bool` (§5.3, p. 37). -/ +`e : ScopeIncidence scope` and Boolean assignment `x : Fin n → Bool` (§5.3, p. 37). -/ noncomputable def evalVarReplacementRowPoly {F : Type*} [Fintype F] {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (e : ScopeIncidence scope) (x : Fin n → Bool) : Polynomial ℚ := ∑ u : Fin n, - Polynomial.C (bitVal ℚ (x u)) * varReplacementRow Q r A₀ R D.place (scopeVarOf scope) e u + Polynomial.C (bitVal ℚ (x u)) * + varReplacementRow Q r A₀ R D.place (scopeVarOf scope) e u -/-- The scaled integer univariate replacement polynomial `d_den ⟨P⃗_e(T), x⟩ ∈ ℤ[X]` for incidence -`e : ScopeIncidence scope` evaluated on a Boolean assignment `x : Fin n → Bool` -(§5.4 & Lemma 4.6, pp. 33, 37–38). -/ +/-- The univariate scaled integer replacement polynomial `d_den · ⟨P⃗_e(T), x⟩ ∈ ℤ[X]` for +incidence `e : ScopeIncidence scope` and Boolean assignment `x : Fin n → Bool` (§5.4 & Lemma 4.6, +pp. 33, 37–38). -/ noncomputable def evalVarReplacementRowScaledIntPoly {F : Type*} [Fintype F] {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (e : ScopeIncidence scope) (x : Fin n → Bool) : Polynomial ℤ := @@ -285,8 +251,8 @@ noncomputable def evalVarReplacementRowScaledIntPoly {F : Type*} [Fintype F] Polynomial.C (bitVal ℤ (x u)) * varReplacementRowScaledInt Q r A₀ R D.place (scopeVarOf scope) e u -/-- Pointwise evaluation of `evalVarReplacementRowPoly D e x` at `t : ℚ` agrees with -`evalVarReplacementRow` on `fun u => bitVal ℚ (x u)`. -/ +/-- Evaluating `evalVarReplacementRowPoly D e x` at `t : ℚ` agrees with +`evalVarReplacementRow Q r A₀ R D.place (scopeVarOf scope) e t (fun u => bitVal ℚ (x u))`. -/ theorem eval_evalVarReplacementRowPoly {F : Type*} [Fintype F] {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (e : ScopeIncidence scope) (x : Fin n → Bool) (t : ℚ) : @@ -444,6 +410,51 @@ theorem designReplacementScaledIntMap_of_mem {F : Type*} [Fintype F] evalVarReplacementRowScaledIntPoly D ⟨emb i, ⟨v, hv⟩⟩ x := by simp only [designReplacementScaledIntMap, hv, ↓reduceDIte] +/-- **Definition 3.1 (4) scoped variable-level locality for `designReplacementMap`**: +when `hv : v ∈ scope (emb i)`, `(designReplacementMap D emb x i v).eval (nodePoint t)` depends +only on `x` restricted to `varGroup D.varAssign t (D.factorAssign (emb i) t)` and the full +measurement vector `(varMeasurementMatrix Q r A₀ R ℚ D.place (scopeVarOf scope)).mulVec +(fun u => bitVal ℚ (x u))`. -/ +theorem eval_nodePoint_designReplacementMap_eq_of_eq_on_varGroup {F : Type*} [Fintype F] + {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) + {i : κ} {v : Fin n} (hv : v ∈ scope (emb i)) (t : Fin Q) (x x' : Fin n → Bool) + (hgrp : ∀ u ∈ varGroup D.varAssign t (D.factorAssign (emb i) t), x u = x' u) + (hmeas : + (varMeasurementMatrix Q r A₀ R ℚ D.place (scopeVarOf scope)).mulVec + (fun u => bitVal ℚ (x u)) = + (varMeasurementMatrix Q r A₀ R ℚ D.place (scopeVarOf scope)).mulVec + (fun u => bitVal ℚ (x' u))) : + (designReplacementMap D emb x i v).eval (nodePoint t) = + (designReplacementMap D emb x' i v).eval (nodePoint t) := by + rw [designReplacementMap_of_mem D emb x hv, designReplacementMap_of_mem D emb x' hv] + exact eval_evalVarReplacementRowPoly_nodePoint_eq_of_eq_on_varGroup D ⟨emb i, ⟨v, hv⟩⟩ t + x x' hgrp hmeas + +/-- **Definition 3.1 (4) & §5.3 factor-level locality for `univariateMonomialSumPoly` under scope +coverage**: when `equationScope (P i) ⊆ scope (emb i)` (for instance when +`scope = withNeutralScope (fun j => equationScope (P j))` and `emb = Sum.inl`), the substituted +equation factor `(univariateMonomialSumPoly ℚ (designReplacementMap D emb x i) (P i)).eval +(nodePoint t)` depends only on `x` restricted to `varGroup D.varAssign t (D.factorAssign (emb i) t)` +and the full measurement vector `(varMeasurementMatrix Q r A₀ R ℚ D.place (scopeVarOf scope)).mulVec +(fun u => bitVal ℚ (x u))`. -/ +theorem eval_univariateMonomialSumPoly_designReplacementMap_nodePoint_eq + {F : Type*} [Fintype F] {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) + (emb : κ → F) (P : κ → Finset (Finset (Fin n))) {i : κ} + (hscope : equationScope (P i) ⊆ scope (emb i)) (t : Fin Q) (x x' : Fin n → Bool) + (hgrp : ∀ u ∈ varGroup D.varAssign t (D.factorAssign (emb i) t), x u = x' u) + (hmeas : + (varMeasurementMatrix Q r A₀ R ℚ D.place (scopeVarOf scope)).mulVec + (fun u => bitVal ℚ (x u)) = + (varMeasurementMatrix Q r A₀ R ℚ D.place (scopeVarOf scope)).mulVec + (fun u => bitVal ℚ (x' u))) : + (univariateMonomialSumPoly ℚ (designReplacementMap D emb x i) (P i)).eval (nodePoint t) = + (univariateMonomialSumPoly ℚ (designReplacementMap D emb x' i) (P i)).eval (nodePoint t) := by + rw [eval_univariateMonomialSumPoly, eval_univariateMonomialSumPoly] + refine sum_congr rfl fun M hM => prod_congr rfl fun v hv => ?_ + have hv_scope : v ∈ scope (emb i) := hscope (mem_biUnion.mpr ⟨M, hM, hv⟩) + exact eval_nodePoint_designReplacementMap_eq_of_eq_on_varGroup D emb hv_scope t x x' + hgrp hmeas + /-- Mapping `designReplacementScaledIntMap D emb x i v` into `ℚ[X]` yields `C (commonDenom Q R : ℚ) * designReplacementMap D emb x i v`. -/ theorem map_designReplacementScaledIntMap {F : Type*} [Fintype F] @@ -545,10 +556,11 @@ theorem coeffNorm1_clearedMonomialSumPoly_designReplacementScaledIntMap_le {F : /-! ### 4. Concrete §5.3–5.5 degree, homogenization, `ℓ₁`-norm, and exact division recovery theorems for `ReplacementDesign` -/ -/-- **Equation (5.5a) coordinate `natDegree` bound for `ReplacementDesign`**: +/-- **Equation (5.5) coordinate `natDegree` bound for `ReplacementDesign` (p. 37)**: for `s < ℓ` and `∀ i ∈ I, ∀ M ∈ P i, #M ≤ k`, the cleared coordinate polynomial `univariateClearedParityCoord I P (commonDenom Q R : ℤ) k ℓ (designReplacementScaledIntMap D emb) s` -has `natDegree ≤ (k * (R - 1)) * (#I + 2 * (ℓ - 1))`. -/ +has `natDegree ≤ (k * (R - 1)) * (#I + 2 * (ℓ - 1))` (strengthening the manuscript's coarser +`k * R * (#I + 2 * (ℓ - 1))` display in (5.5) via `natDegree ≤ R - 1` from Definition 3.1 (4)). -/ theorem natDegree_univariateClearedParityCoord_design_le {F : Type*} [Fintype F] {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) (I : Finset κ) (P : κ → Finset (Finset (Fin n))) {k ℓ s : ℕ} @@ -560,11 +572,12 @@ theorem natDegree_univariateClearedParityCoord_design_le {F : Type*} [Fintype F] (designReplacementScaledIntMap D emb) hk (fun x i _ _ _ v _ => natDegree_designReplacementScaledIntMap_le D emb x i v) hs -/-- **Equation (5.5a) truncated-sum `natDegree` bound for `ReplacementDesign`**: +/-- **Equation (5.5) truncated-sum `natDegree` bound for `ReplacementDesign` (p. 37)**: when `∀ i ∈ I, ∀ M ∈ P i, #M ≤ k`, the cleared truncated sum `univariateClearedParityTruncatedSum I P (commonDenom Q R : ℤ) k ℓ (designReplacementScaledIntMap D emb)` -has `natDegree ≤ (k * (R - 1)) * (#I + 2 * (ℓ - 1))`. -/ +has `natDegree ≤ (k * (R - 1)) * (#I + 2 * (ℓ - 1))` (strengthening the manuscript's coarser +`k * R * (#I + 2 * (ℓ - 1))` display in (5.5) via `natDegree ≤ R - 1` from Definition 3.1 (4)). -/ theorem natDegree_univariateClearedParityTruncatedSum_design_le {F : Type*} [Fintype F] {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) (I : Finset κ) (P : κ → Finset (Finset (Fin n))) (k ℓ : ℕ) diff --git a/ComplexityTests/SparseReplacementDesign.lean b/ComplexityTests/SparseReplacementDesign.lean index 27e85be521..17c89a9e11 100644 --- a/ComplexityTests/SparseReplacementDesign.lean +++ b/ComplexityTests/SparseReplacementDesign.lean @@ -14,8 +14,9 @@ import Mathlib.Tactic.NormNum /-! # Tests for `Complexity.Foundations.BooleanAnalysis.SparseReplacementDesign` -Concrete checks and nonvacuous witnesses for neutral-singleton augmented equation scopes, -`designRowNormBound`, `exists_replacementDesign_augmentedEquationScope`, and the +Concrete checks and nonvacuous witnesses for `withNeutralScope` equation scopes, +`designRowNormBound`, `exists_replacementDesign_withNeutralScope`, nonconstant factor locality +(`eval_univariateMonomialSumPoly_designReplacementMap_nodePoint_eq`), and the `ReplacementDesign` specializations of cleared-denominator zero counting and heavy-variable branch recovery. -/ @@ -36,6 +37,10 @@ def sampleEqs : Fin 2 → Finset (Finset (Fin 3)) | ⟨0, _⟩ => {{0}, {0, 1}} | ⟨1, _⟩ => {{1, 2}, ∅} +/-- Scope family of `sampleEqs`. -/ +def sampleScope (i : Fin 2) : Finset (Fin 3) := + equationScope (sampleEqs i) + /-- Expected-value control: `sampleEqs` has `commonZeroCount = 2`, while the empty equation set has `commonZeroCount = 8`. -/ example : @@ -43,20 +48,22 @@ example : commonZeroCount (∅ : Finset (Fin 2)) sampleEqs = 8 := by decide -/-- Total incidence of `augmentedEquationScope sampleEqs` is `(2 + 2) + 3 = 7 ≥ 3`. -/ +/-- Total incidence of `withNeutralScope sampleScope` is `(2 + 2) + 3 = 7 ≥ 3`. -/ example : - (∑ f : Fin 2 ⊕ Fin 3, #(augmentedEquationScope sampleEqs f)) = 7 ∧ - 3 ≤ ∑ f : Fin 2 ⊕ Fin 3, #(augmentedEquationScope sampleEqs f) := by - refine ⟨?_, le_sum_card_augmentedEquationScope sampleEqs⟩ - rw [sum_card_augmentedEquationScope] + totalIncidence (withNeutralFactors (univ : Finset (Fin 2))) (withNeutralScope sampleScope) = 7 ∧ + 3 ≤ totalIncidence (withNeutralFactors (univ : Finset (Fin 2))) + (withNeutralScope sampleScope) := by + refine ⟨?_, card_le_totalIncidence_withNeutralFactors (univ : Finset (Fin 2)) sampleScope⟩ + rw [totalIncidence_withNeutralFactors] decide /-- Variable `1 : Fin 3` belongs to both equation scopes plus its neutral singleton scope (`2 + 1 = 3` scopes total), whereas variable `0 : Fin 3` belongs to `1 + 1 = 2` scopes. -/ example : - #{f : Fin 2 ⊕ Fin 3 | (1 : Fin 3) ∈ augmentedEquationScope sampleEqs f} = 3 ∧ - #{f : Fin 2 ⊕ Fin 3 | (0 : Fin 3) ∈ augmentedEquationScope sampleEqs f} = 2 := by - rw [card_filter_mem_augmentedEquationScope, card_filter_mem_augmentedEquationScope] + varIncidence (withNeutralFactors (univ : Finset (Fin 2))) (withNeutralScope sampleScope) 1 = 3 ∧ + varIncidence (withNeutralFactors (univ : Finset (Fin 2))) + (withNeutralScope sampleScope) 0 = 2 := by + rw [varIncidence_withNeutralFactors, varIncidence_withNeutralFactors] decide /-- Explicit value of `designRowNormBound 3 2`: @@ -114,6 +121,155 @@ def unitReplacementDesign {F : Type*} [Fintype F] {n : ℕ} sum_coeffNorm1_varReplacementRowScaledInt_le (by decide) hinj (scopeVarOf scope) (by intro a ha; omega) } +/-- Explicit `Q = 1, r = 2, A₀ = 0, R = 2, τ = 0` replacement design on +`withNeutralScope sampleScope` (`n = 3`, `h = 3`): +- variables `0, 1` are in group `0` and variable `2` is in group `1`, +- both equation factors `Sum.inl 0` and `Sum.inl 1` are assigned to group `0`, +- `measurementIndices 1 2 0 2 = ∅`, so measurement vectors vanish unconditionally, +- for variable `2` in equation `1` (`scope = {1, 2}`), the replacement polynomial evaluates to `1` + at `T = 0` and `0` at `T = nodePoint 0 = 1`, hence is nonconstant of exact degree `1`. -/ +def nonconstSampleVarAssign : Fin 3 → Fin 1 → Fin 2 := + fun v _ => if v.1 < 2 then 0 else 1 + +/-- Factor group schedule for `nonconstSampleDesign`. -/ +def nonconstSampleFactorAssign : Fin 2 ⊕ Fin 3 → Fin 1 → Fin 2 + | Sum.inl _, _ => 0 + | Sum.inr _, _ => 1 + +/-- Copy index in `Fin 3` separating the `7` incidences of `withNeutralScope sampleScope` into +distinct `(copy, AuxLabel 1 2)` slots. -/ +def nonconstSampleCopy (e : ScopeIncidence (withNeutralScope sampleScope)) : Fin 3 := + match e.1 with + | Sum.inl 0 => if e.2.1 = 0 then 0 else 1 + | Sum.inl 1 => if e.2.1 = 1 then 2 else 0 + | Sum.inr 0 => 0 + | Sum.inr 1 => 1 + | Sum.inr 2 => 0 + +/-- Injective placement for `nonconstSampleDesign`. -/ +def nonconstSamplePlace (e : ScopeIncidence (withNeutralScope sampleScope)) : + Fin 3 × AuxLabel 1 2 := + (nonconstSampleCopy e, + (nonconstSampleVarAssign (scopeVarOf (withNeutralScope sampleScope) e), + nonconstSampleFactorAssign (scopeFactorOf (withNeutralScope sampleScope) e))) + +theorem injective_nonconstSamplePlace : Function.Injective nonconstSamplePlace := by + decide + +/-- Concrete `Q = 1, r = 2, A₀ = 0, R = 2, τ = 0` replacement design on +`withNeutralScope sampleScope` with nonconstant degree-`1` replacement rows. -/ +def nonconstSampleDesign : + ReplacementDesign (withNeutralScope sampleScope) 1 2 0 2 0 where + varAssign := nonconstSampleVarAssign + factorAssign := nonconstSampleFactorAssign + h := 3 + place := nonconstSamplePlace + card_varGroup_le := by decide + factorAssign_of_empty := by decide + injective_place := injective_nonconstSamplePlace + place_snd := fun _ => rfl + h_mul_D_le := by decide + total_measurement_rows_le := by + have hmeas : #(measurementIndices 1 2 0 2) = 0 := by decide + simp [hmeas] + sum_abs_measurement_row_le := + sum_abs_varMeasurementMatrix_le 1 2 0 2 injective_nonconstSamplePlace + (scopeVarOf (withNeutralScope sampleScope)) + natDegree_replacementRow_le := + natDegree_varReplacementRow_le 1 2 0 2 nonconstSamplePlace + (scopeVarOf (withNeutralScope sampleScope)) + eval_replacementRow_zero := + eval_varReplacementRow_zero 1 2 0 2 injective_nonconstSamplePlace + (scopeVarOf (withNeutralScope sampleScope)) + evalReplacementRow_nodePoint_eq_zero_of_kernel := fun e t g hg ξ hsupp hker => + evalVarReplacementRow_nodePoint_eq_zero_of_kernel 1 2 0 2 nonconstSamplePlace + (scopeVarOf (withNeutralScope sampleScope)) nonconstSampleVarAssign (fun _ => rfl) e t g hg + ξ hsupp hker + map_replacementRowScaledInt := + map_varReplacementRowScaledInt 1 2 0 2 nonconstSamplePlace + (scopeVarOf (withNeutralScope sampleScope)) + sum_coeffNorm1_replacementRowScaledInt_le := + sum_coeffNorm1_varReplacementRowScaledInt_le (by decide) injective_nonconstSamplePlace + (scopeVarOf (withNeutralScope sampleScope)) (by intro a ha; omega) + +/-- Assignment `x₁ = (false, false, true)` placing `true` on variable `2 : Fin 3` in group `1` and +`false` on group `0 = {0, 1}`. -/ +def sampleAssign₁ : Fin 3 → Bool := fun v => decide (v = 2) + +/-- All-false assignment `x₂ = (false, false, false)` agreeing with `sampleAssign₁` on group +`0 = {0, 1}` and differing on variable `2 ∈ equationScope (sampleEqs 1)`. -/ +def sampleAssign₂ : Fin 3 → Bool := fun _ => false + +/-- Nonconstant replacement-row and factor-locality control on `nonconstSampleDesign`: +1. For equation `1` (`x₁ x₂ + 1`, scope `{1, 2}`) and variable `2` on `sampleAssign₁`, the + replacement polynomial + `P(T) = designReplacementMap nonconstSampleDesign Sum.inl sampleAssign₁ 1 2` + evaluates to `1` at `T = 0` and to `0` at `T = nodePoint (0 : Fin 1)` (comparing `sampleAssign₁` + with `sampleAssign₂` on group `0`), so `P.eval 0 ≠ P.eval (nodePoint 0)` and `P` has exact + nonconstant degree `P.natDegree = 1`. +2. Although `sampleAssign₁` and `sampleAssign₂` differ on variable + `2 ∈ equationScope (sampleEqs 1)`, + `eval_univariateMonomialSumPoly_designReplacementMap_nodePoint_eq` proves unconditionally that + their substituted equation-`1` factors at `nodePoint (0 : Fin 1)` coincide. -/ +example : + (designReplacementMap nonconstSampleDesign Sum.inl sampleAssign₁ 1 2).eval 0 = 1 ∧ + (designReplacementMap nonconstSampleDesign Sum.inl sampleAssign₁ 1 2).eval + (nodePoint (0 : Fin 1)) = 0 ∧ + (designReplacementMap nonconstSampleDesign Sum.inl sampleAssign₁ 1 2).natDegree = 1 ∧ + (univariateMonomialSumPoly ℚ (designReplacementMap nonconstSampleDesign Sum.inl sampleAssign₁ 1) + (sampleEqs 1)).eval (nodePoint (0 : Fin 1)) = + (univariateMonomialSumPoly ℚ (designReplacementMap nonconstSampleDesign Sum.inl sampleAssign₂ 1) + (sampleEqs 1)).eval (nodePoint (0 : Fin 1)) := by + have hgrp : ∀ u ∈ varGroup nonconstSampleDesign.varAssign (0 : Fin 1) + (nonconstSampleDesign.factorAssign (Sum.inl 1) (0 : Fin 1)), + sampleAssign₁ u = sampleAssign₂ u := by + decide + have hmeas : + (varMeasurementMatrix 1 2 0 2 ℚ nonconstSampleDesign.place + (scopeVarOf (withNeutralScope sampleScope))).mulVec + (fun u => bitVal ℚ (sampleAssign₁ u)) = + (varMeasurementMatrix 1 2 0 2 ℚ nonconstSampleDesign.place + (scopeVarOf (withNeutralScope sampleScope))).mulVec + (fun u => bitVal ℚ (sampleAssign₂ u)) := by + funext p + exact absurd p.2.2 (by decide +revert) + have heval0 : + (designReplacementMap nonconstSampleDesign Sum.inl sampleAssign₁ 1 2).eval 0 = 1 := by + rw [eval_zero_designReplacementMap] + rfl + have heval1 : + (designReplacementMap nonconstSampleDesign Sum.inl sampleAssign₁ 1 2).eval + (nodePoint (0 : Fin 1)) = 0 := by + have hloc := eval_nodePoint_designReplacementMap_eq_of_eq_on_varGroup + nonconstSampleDesign Sum.inl (i := (1 : Fin 2)) (v := (2 : Fin 3)) (by decide) + (0 : Fin 1) sampleAssign₁ sampleAssign₂ hgrp hmeas + have hzero : + designReplacementMap nonconstSampleDesign Sum.inl sampleAssign₂ 1 2 = 0 := by + simp [sampleAssign₂, designReplacementMap, evalVarReplacementRowPoly] + rw [hloc, hzero, Polynomial.eval_zero] + have hdeg : + (designReplacementMap nonconstSampleDesign Sum.inl sampleAssign₁ 1 2).natDegree = 1 := by + have hle : + (designReplacementMap nonconstSampleDesign Sum.inl sampleAssign₁ 1 2).natDegree ≤ 2 - 1 := + natDegree_designReplacementMap_le nonconstSampleDesign Sum.inl sampleAssign₁ 1 2 + have hne0 : + (designReplacementMap nonconstSampleDesign Sum.inl sampleAssign₁ 1 2).natDegree ≠ 0 := by + intro h0 + have hconst := Polynomial.eq_C_of_natDegree_eq_zero h0 + have h1 : + (designReplacementMap nonconstSampleDesign Sum.inl sampleAssign₁ 1 2).eval 0 = + (designReplacementMap nonconstSampleDesign Sum.inl sampleAssign₁ 1 2).eval + (nodePoint (0 : Fin 1)) := by + conv_lhs => rw [hconst, Polynomial.eval_C] + conv_rhs => rw [hconst, Polynomial.eval_C] + rw [heval0, heval1] at h1 + exact one_ne_zero h1 + omega + refine ⟨heval0, heval1, hdeg, ?_⟩ + exact eval_univariateMonomialSumPoly_designReplacementMap_nodePoint_eq + nonconstSampleDesign Sum.inl sampleEqs (i := (1 : Fin 2)) (by decide) (0 : Fin 1) + sampleAssign₁ sampleAssign₂ hgrp hmeas + /-- Explicit equivalence between the unbranched variables `{0, 2}` (`univ \ {1}` in `Fin 3`) and `Fin 2`. -/ def sampleFreeVarEquiv : ↥((univ : Finset (Fin 3)) \ ({1} : Finset (Fin 3))) ≃ Fin 2 where @@ -133,20 +289,23 @@ example : (commonDenom 1 1 : ℤ) 2 (branchPrecision 3) (designReplacementScaledIntMap (unitReplacementDesign - (augmentedEquationScope fun i => - relabelRestrictedMonomials ({1} : Finset (Fin 3)) sampleFreeVarEquiv b - (sampleEqs i))) + (withNeutralScope fun i => + equationScope + (relabelRestrictedMonomials ({1} : Finset (Fin 3)) sampleFreeVarEquiv b + (sampleEqs i)))) Sum.inl)).eval 0 / clearedProductDenom (commonDenom 1 1 : ℤ) 2 (branchPrecision 3) #(univ : Finset (Fin 2))) % ((2 : ℤ) ^ branchPrecision 3) = 2 := by have hrec := commonZeroCount_eq_sum_branch_emod_ediv_design ({1} : Finset (Fin 3)) sampleFreeVarEquiv (univ : Finset (Fin 2)) sampleEqs (k := 2) - (fun b => augmentedEquationScope fun i => - relabelRestrictedMonomials ({1} : Finset (Fin 3)) sampleFreeVarEquiv b (sampleEqs i)) + (fun b => withNeutralScope fun i => + equationScope + (relabelRestrictedMonomials ({1} : Finset (Fin 3)) sampleFreeVarEquiv b (sampleEqs i))) (fun b => unitReplacementDesign - (augmentedEquationScope fun i => - relabelRestrictedMonomials ({1} : Finset (Fin 3)) sampleFreeVarEquiv b (sampleEqs i))) + (withNeutralScope fun i => + equationScope + (relabelRestrictedMonomials ({1} : Finset (Fin 3)) sampleFreeVarEquiv b (sampleEqs i)))) (fun _ => Sum.inl) (by decide) have hcount : commonZeroCount (univ : Finset (Fin 2)) sampleEqs = 2 := by decide @@ -161,32 +320,33 @@ example {E_ℓ : ℕ} (hE : ∀ j < 4, (Polynomial.parityBaseDigit 4 j).coeffNor (univariateClearedParityTruncatedSum (univ : Finset (Fin 2)) sampleEqs (commonDenom 1 1 : ℤ) 2 4 (designReplacementScaledIntMap - (unitReplacementDesign (augmentedEquationScope sampleEqs)) Sum.inl)).natDegree ≤ 0 ∧ + (unitReplacementDesign (withNeutralScope sampleScope)) Sum.inl)).natDegree ≤ 0 ∧ (univariateClearedParityCoord (univ : Finset (Fin 2)) sampleEqs (commonDenom 1 1 : ℤ) 2 4 (designReplacementScaledIntMap - (unitReplacementDesign (augmentedEquationScope sampleEqs)) Sum.inl) s).coeffNorm1 ≤ + (unitReplacementDesign (withNeutralScope sampleScope)) Sum.inl) s).coeffNorm1 ≤ 2 ^ 3 * (4 * E_ℓ * (2 * designRowNormBound 1 1 ^ 2 + commonDenom 1 1 ^ 2) ^ (2 * 4 - 1)) ^ 2 := by refine ⟨?_, ?_⟩ · simpa using natDegree_univariateClearedParityTruncatedSum_design_le - (unitReplacementDesign (augmentedEquationScope sampleEqs)) Sum.inl + (unitReplacementDesign (withNeutralScope sampleScope)) Sum.inl (univ : Finset (Fin 2)) sampleEqs 2 4 (by decide) · simpa using coeffNorm1_univariateClearedParityCoord_design_le - (unitReplacementDesign (augmentedEquationScope sampleEqs)) Sum.inl + (unitReplacementDesign (withNeutralScope sampleScope)) Sum.inl (univ : Finset (Fin 2)) sampleEqs 2 4 (S_mon := 2) (by decide) (by decide) hE s /-- Empty equation family on `n = 16384` variables used to witness -`exists_replacementDesign_augmentedEquationScope` with `b₀ = 0` (`b = 1`), `w = 1`, `Q = 3`, +`exists_replacementDesign_withNeutralScope` with `b₀ = 0` (`b = 1`), `w = 1`, `Q = 3`, `r = 2`, `A₀ = 0`, `R = 2`, `τ = 1 / 2`. -/ def emptyEqs16384 : Fin 0 → Finset (Finset (Fin 16384)) := Fin.elim0 -/-- Nonvacuous witness of `exists_replacementDesign_augmentedEquationScope` and exact modular +/-- Nonvacuous witness of `exists_replacementDesign_withNeutralScope` and exact modular recovery of `commonZeroCount = 2 ^ 16384` at precision `ℓ = 16385`. -/ theorem exists_design_and_recover_emptyEqs16384 : - ∃ D : ReplacementDesign (augmentedEquationScope emptyEqs16384) 3 2 0 2 (1 / 2), + ∃ D : ReplacementDesign (withNeutralScope fun i => equationScope (emptyEqs16384 i)) + 3 2 0 2 (1 / 2), ((univariateClearedParityTruncatedSum (univ : Finset (Fin 0)) emptyEqs16384 (commonDenom 3 2 : ℤ) 3 16385 (designReplacementScaledIntMap D Sum.inl)).eval 0 / @@ -199,11 +359,12 @@ theorem exists_design_and_recover_emptyEqs16384 : have htail : binomTailProb 3 2 0 2 ≤ (1 / 2 : ℚ) / ((2 : ℚ) * ((0 + 1 : ℕ) : ℚ)) := by rw [binomTailProb_eq_div 3 2 0 2 (by decide), hcard] norm_num - have hne : Nonempty (ReplacementDesign (augmentedEquationScope emptyEqs16384) 3 2 0 2 (1 / 2)) := - exists_replacementDesign_augmentedEquationScope emptyEqs16384 (b₀ := 0) (w := 1) - (by decide) (by decide) (by decide) (by decide) (by decide) (by norm_num) + have hne : Nonempty (ReplacementDesign + (withNeutralScope fun i => equationScope (emptyEqs16384 i)) 3 2 0 2 (1 / 2)) := + exists_replacementDesign_withNeutralScope (fun i => equationScope (emptyEqs16384 i)) + (b₀ := 0) (w := 1) (by decide) (by decide) (by decide) (by decide) (by decide) (by norm_num) (by intro a ha; omega) - (fun v => by simp) + (fun v => by simp [varIncidence]) (fun i => Fin.elim0 i) (by decide) (by decide) From 3dc90252def49185b07dcae52170f4aaa0edb850 Mon Sep 17 00:00:00 2001 From: Samuel Giuseppe Schlesinger Date: Tue, 27 Oct 2026 00:59:35 -0400 Subject: [PATCH 14/20] doc(BooleanAnalysis): correct replacement degree provenance --- .../BooleanAnalysis/SparseReplacementDesign.lean | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Complexity/Foundations/BooleanAnalysis/SparseReplacementDesign.lean b/Complexity/Foundations/BooleanAnalysis/SparseReplacementDesign.lean index 0cc8c74195..708e6284a7 100644 --- a/Complexity/Foundations/BooleanAnalysis/SparseReplacementDesign.lean +++ b/Complexity/Foundations/BooleanAnalysis/SparseReplacementDesign.lean @@ -67,7 +67,8 @@ Appendix B.2–B.3 cleared-denominator parity-polynomial zero-counting pipeline yields concrete `ReplacementDesign` specializations of: - the equation (5.5) degree bound `(k * (R - 1)) * (#I + 2 * (ℓ - 1))` (strengthening the manuscript's coarser `k * R * (#I + 2 * (ℓ - 1))` display on p. 37 using `natDegree ≤ R - 1` - from Definition 3.1 (4); `natDegree_univariateClearedParityCoord_design_le`, + from Lemma 4.3 and its variable-row transfer in §4.5 (4.14); + `natDegree_univariateClearedParityCoord_design_le`, `natDegree_univariateClearedParityTruncatedSum_design_le`), - the rational homogenization identity $\tilde{H}_s(T) = \Omega [V^s] H(T)$ over `ℚ[X]` (`map_univariateClearedParityCoord_design`, @@ -301,7 +302,8 @@ theorem eval_zero_evalVarReplacementRowScaledIntPoly {F : Type*} [Fintype F] cases x (scopeVarOf scope e) <;> simp only [bitVal_true, bitVal_false, Int.cast_one, Int.cast_zero] -/-- `evalVarReplacementRowPoly D e x` has `natDegree ≤ R - 1` (Definition 3.1 (4)). -/ +/-- `evalVarReplacementRowPoly D e x` has `natDegree ≤ R - 1` by Lemma 4.3 and its +variable-row transfer in §4.5 (4.14). -/ theorem natDegree_evalVarReplacementRowPoly_le {F : Type*} [Fintype F] {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (e : ScopeIncidence scope) (x : Fin n → Bool) : @@ -560,7 +562,8 @@ theorems for `ReplacementDesign` -/ for `s < ℓ` and `∀ i ∈ I, ∀ M ∈ P i, #M ≤ k`, the cleared coordinate polynomial `univariateClearedParityCoord I P (commonDenom Q R : ℤ) k ℓ (designReplacementScaledIntMap D emb) s` has `natDegree ≤ (k * (R - 1)) * (#I + 2 * (ℓ - 1))` (strengthening the manuscript's coarser -`k * R * (#I + 2 * (ℓ - 1))` display in (5.5) via `natDegree ≤ R - 1` from Definition 3.1 (4)). -/ +`k * R * (#I + 2 * (ℓ - 1))` display in (5.5) via `natDegree ≤ R - 1` +from Lemma 4.3 and its variable-row transfer in §4.5 (4.14)). -/ theorem natDegree_univariateClearedParityCoord_design_le {F : Type*} [Fintype F] {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) (I : Finset κ) (P : κ → Finset (Finset (Fin n))) {k ℓ s : ℕ} @@ -577,7 +580,8 @@ when `∀ i ∈ I, ∀ M ∈ P i, #M ≤ k`, the cleared truncated sum `univariateClearedParityTruncatedSum I P (commonDenom Q R : ℤ) k ℓ (designReplacementScaledIntMap D emb)` has `natDegree ≤ (k * (R - 1)) * (#I + 2 * (ℓ - 1))` (strengthening the manuscript's coarser -`k * R * (#I + 2 * (ℓ - 1))` display in (5.5) via `natDegree ≤ R - 1` from Definition 3.1 (4)). -/ +`k * R * (#I + 2 * (ℓ - 1))` display in (5.5) via `natDegree ≤ R - 1` +from Lemma 4.3 and its variable-row transfer in §4.5 (4.14)). -/ theorem natDegree_univariateClearedParityTruncatedSum_design_le {F : Type*} [Fintype F] {scope : F → Finset (Fin n)} (D : ReplacementDesign scope Q r A₀ R τ) (emb : κ → F) (I : Finset κ) (P : κ → Finset (Finset (Fin n))) (k ℓ : ℕ) From ffb5db9b97164f88c7e0432ba476c379fb4f9284 Mon Sep 17 00:00:00 2001 From: Samuel Schlesinger Date: Tue, 27 Oct 2026 05:17:08 +0000 Subject: [PATCH 15/20] feat(Logics/Propositional/CNF): bridge sparse replacement design with CNF parity counter (#1226) --- Complexity.lean | 1 + .../CNF/SparseDesignCounter.lean | 602 ++++++++++++++++++ ComplexityTests/SparseDesignCounter.lean | 474 ++++++++++++++ 3 files changed, 1077 insertions(+) create mode 100644 Complexity/Logics/Propositional/CNF/SparseDesignCounter.lean create mode 100644 ComplexityTests/SparseDesignCounter.lean diff --git a/Complexity.lean b/Complexity.lean index 4a2b1eb440..9b64b1ed94 100644 --- a/Complexity.lean +++ b/Complexity.lean @@ -2196,6 +2196,7 @@ public import Complexity.Logics.Propositional.CNF.Planar.PairedCrossover public import Complexity.Logics.Propositional.CNF.Planar.PairedWire public import Complexity.Logics.Propositional.CNF.PolyTime public import Complexity.Logics.Propositional.CNF.PolynomialTests +public import Complexity.Logics.Propositional.CNF.SparseDesignCounter public import Complexity.Logics.Propositional.CNF.SparseParityCounter public import Complexity.Logics.Propositional.CNF.ThreeCNF public import Complexity.Logics.Propositional.CNF.ThreeCNF.Exact diff --git a/Complexity/Logics/Propositional/CNF/SparseDesignCounter.lean b/Complexity/Logics/Propositional/CNF/SparseDesignCounter.lean new file mode 100644 index 0000000000..c84c6d6c7e --- /dev/null +++ b/Complexity/Logics/Propositional/CNF/SparseDesignCounter.lean @@ -0,0 +1,602 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Foundations.BooleanAnalysis.SparseReplacementDesign +public import Complexity.Logics.Propositional.CNF.SparseParityCounter + +/-! +# Replacement-Design Specialization of Sparse Parity Model Counting for CNF Formulas + +This module connects the compiled CNF parity-test equation systems and greedy zero-counting +reduction of Sections 6.1–6.3 (`Complexity.Logics.Propositional.CNF.SparseParityCounter`) directly +with the Section 4 algebraic replacement design specialization of Sections 5.3–5.5 and Appendix B.2 +(`Complexity.Foundations.BooleanAnalysis.SparseReplacementDesign`) of +[OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (printed pp. 37–43, 48–50): + +1. **Branch-restricted CNF parity systems and neutral singleton scopes (§5.5 & §6.2–6.3)**: + Given `φ : CNF V`, parity-check rows `rows : List (Fin φ.length → Bool)`, a heavy-variable subset + `S : Finset V`, a free-variable equivalence `e : ↥(univ \ S) ≃ Fin n'`, and a branch assignment + `b : V → Bool`: + - `CNF.branchParityRowSystem φ rows S e b : Fin rows.length → Finset (Finset (Fin n'))` restricts + each compiled parity equation `φ.parityRowSystem rows j` to `S` under `b` (cancelling duplicate + monomials modulo `2`) and relabels the remaining free variables along `e`. + - `CNF.branchParityRowScope φ rows S e b` is its variable-scope family on `Fin n'`, and + `CNF.branchParityRowNeutralScope φ rows S e b : Fin rows.length ⊕ Fin n' → Finset (Fin n')` + augments those scopes with one neutral singleton scope `{v}` per free variable `v : Fin n'` via + `withNeutralScope`. + - When every clause of `φ` has width at most `k` and every row in `rows` has Hamming weight at + most `W`, each branch equation has degree at most `k`, at most `W * 2 ^ k` monomials, and + scope size at most `k * (W * 2 ^ k)`. On the canonical heavy-variable set + `S = heavyVars univ univ (fun j => equationScope (φ.parityRowSystem rows j)) b₀`, every free + variable `v : Fin n'` belongs to at most `b₀ + 1` scopes of `branchParityRowNeutralScope`, + total branch incidence satisfies `n' ≤ M'_b ≤ (b₀ + 1) * n'`, and Lemma 4.7 supplies a + concrete `ReplacementDesign` (`CNF.exists_replacementDesign_branchParityRowNeutralScope`). + +2. **Per-branch factor locality, polynomial degree, and coordinate `coeffNorm1` bounds (§5.3–5.4 & + Appendix B.2)**: + For any `D : ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) Q r A₀ R τ`, + instantiating `SparseReplacementDesign` with `emb = Sum.inl` automatically discharges the + monomial-degree (`#M ≤ k`), monomial-count (`#(P j) ≤ W * 2 ^ k`), and scope-containment + (`equationScope (P j) ⊆ scope (Sum.inl j)`) premises from `∀ c ∈ φ, c.length ≤ k` and + `∀ r ∈ rows, weight r ≤ W`, yielding: + - node-point factor locality + (`CNF.eval_univariateMonomialSumPoly_branchParityRowSystem_nodePoint_eq`), + - the equation (5.5) degree bound `(k * (R - 1)) * (rows.length + 2 * (ℓ - 1))` + (`CNF.natDegree_univariateClearedParityCoord_branchParityRowSystem_le`, + `CNF.natDegree_univariateClearedParityTruncatedSum_branchParityRowSystem_le`), and + - the Appendix B.2 coordinate `ℓ₁`-norm bound with `S_mon = W * 2 ^ k` + (`CNF.coeffNorm1_univariateClearedParityCoord_branchParityRowSystem_le`). + +3. **Exact branch-summed `ReplacementDesign` recovery of `commonZeroCount`, `numPassing`, and + `φ.modelCountOn Finset.univ` (§5.4–5.5 & §6.2–6.3)**: + Eliminating the abstract replacement-map hypotheses `d_den`, `θ`, and `hθ` of + `SparseParityCounter`, any per-branch family of replacement designs `D b` recovers + `commonZeroCount univ (φ.parityRowSystem rows) = numPassing φ.violations rows` via + branch-summed evaluation at `T = 0` + (`CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design`, + `CNF.numPassing_eq_sum_branch_emod_ediv_design`), and recovers `φ.modelCountOn Finset.univ` on + the nose after `3 * Fintype.card V` greedy rounds + (`CNF.modelCountOn_eq_sum_branch_emod_ediv_design_greedy`, + `CNF.exists_initialTests_modelCountOn_eq_sum_branch_emod_ediv_design_greedy`), with + `max D₀ P` simplified unconditionally to `D₀ = CNF.initialRowWeightBound B φ.length` + (`CNF.max_initialRowWeightBound_greedyRowListLength`). + +## Main definitions + +* `Cslib.Logic.PL.CNF.branchParityRowSystem`: branch-restricted and relabeled `𝔽₂` polynomial system + `fun j => relabelRestrictedMonomials S e b (φ.parityRowSystem rows j)`. +* `Cslib.Logic.PL.CNF.branchParityRowScope`: variable-scope family of `branchParityRowSystem`. +* `Cslib.Logic.PL.CNF.branchParityRowNeutralScope`: neutral-singleton augmented scope family + `withNeutralScope (φ.branchParityRowScope rows S e b)`. + +## Main results + +* `Cslib.Logic.PL.CNF.card_mem_branchParityRowSystem_le`, + `Cslib.Logic.PL.CNF.card_branchParityRowSystem_le`, + `Cslib.Logic.PL.CNF.card_branchParityRowScope_le`, + `Cslib.Logic.PL.CNF.card_branchParityRowNeutralScope_le`: per-branch monomial degree, sparsity, + and scope-width bounds from clause width `≤ k` and row weight `≤ W`. +* `Cslib.Logic.PL.CNF.varIncidence_branchParityRowNeutralScope_heavyVars_le`, + `Cslib.Logic.PL.CNF.totalIncidence_branchParityRowNeutralScope_heavyVars_le`, + `Cslib.Logic.PL.CNF.exists_replacementDesign_branchParityRowNeutralScope`: post-branching + free-variable incidence bounds and Lemma 4.7 `ReplacementDesign` existence on each branch. +* `Cslib.Logic.PL.CNF.eval_univariateMonomialSumPoly_branchParityRowSystem_nodePoint_eq`, + `Cslib.Logic.PL.CNF.natDegree_univariateClearedParityCoord_branchParityRowSystem_le`, + `Cslib.Logic.PL.CNF.natDegree_univariateClearedParityTruncatedSum_branchParityRowSystem_le`, + `Cslib.Logic.PL.CNF.coeffNorm1_univariateClearedParityCoord_branchParityRowSystem_le`: per-branch + locality, degree, and `coeffNorm1` bounds for a `ReplacementDesign`. +* `Cslib.Logic.PL.CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design`, + `Cslib.Logic.PL.CNF.numPassing_eq_sum_branch_emod_ediv_design`, + `Cslib.Logic.PL.CNF.modelCountOn_eq_sum_branch_emod_ediv_design_greedy`, + `Cslib.Logic.PL.CNF.max_initialRowWeightBound_greedyRowListLength`, + `Cslib.Logic.PL.CNF.exists_initialTests_modelCountOn_eq_sum_branch_emod_ediv_design_greedy`: + end-to-end `ReplacementDesign` recovery of `commonZeroCount`, `numPassing`, and + `φ.modelCountOn Finset.univ`. + +## References + +* [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (Sections 5.3–5.5 and 6.1–6.3, + printed pp. 37–43, 48–50) +-/ + +@[expose] public noncomputable section + +namespace Cslib.Logic.PL + +open Finset Polynomial Cslib.BitString Cslib.BalancedSchedules Cslib.LinearAlgebra +open scoped BigOperators + +variable {V : Type*} + +/-! ### 1. Branch-restricted CNF parity systems and neutral singleton scopes -/ + +section BranchParityRowSystem + +variable [Fintype V] [DecidableEq V] {n' : ℕ} + +/-- The `Fin rows.length`-indexed sparse `𝔽₂` polynomial system on `Fin n'` obtained from +`φ.parityRowSystem rows` by fixing `S : Finset V` to `b : V → Bool` (cancelling duplicate +monomials modulo `2`) and relabeling `univ \ S ≃ Fin n'` along `e` +([OpenAI2026ETH], §5.5 & §6.3, pp. 38–39, 43). -/ +def CNF.branchParityRowSystem (φ : CNF V) (rows : List (Fin φ.length → Bool)) + (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') (b : V → Bool) + (j : Fin rows.length) : Finset (Finset (Fin n')) := + relabelRestrictedMonomials S e b (φ.parityRowSystem rows j) + +/-- The variable scope `equationScope (φ.branchParityRowSystem rows S e b j) : Finset (Fin n')` of +restricted parity equation `j` on branch `b`. -/ +def CNF.branchParityRowScope (φ : CNF V) (rows : List (Fin φ.length → Bool)) + (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') (b : V → Bool) + (j : Fin rows.length) : Finset (Fin n') := + equationScope (φ.branchParityRowSystem rows S e b j) + +/-- The neutral-singleton augmented scope family on `Fin rows.length ⊕ Fin n'` associated to +`φ.branchParityRowScope rows S e b` ([OpenAI2026ETH], §5.3 & §5.5, pp. 37–38). -/ +def CNF.branchParityRowNeutralScope (φ : CNF V) (rows : List (Fin φ.length → Bool)) + (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') (b : V → Bool) : + Fin rows.length ⊕ Fin n' → Finset (Fin n') := + withNeutralScope (φ.branchParityRowScope rows S e b) + +/-- Every monomial in `φ.branchParityRowSystem rows S e b j` has degree at most `k` whenever every +clause of `φ` has width at most `k`. -/ +theorem CNF.card_mem_branchParityRowSystem_le {φ : CNF V} {k : ℕ} + (hk : ∀ c ∈ φ, c.length ≤ k) (rows : List (Fin φ.length → Bool)) + (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') (b : V → Bool) + (j : Fin rows.length) {M : Finset (Fin n')} + (hM : M ∈ φ.branchParityRowSystem rows S e b j) : + #M ≤ k := + card_mem_relabelRestrictedMonomials_le + (fun _M₀ hM₀ => CNF.card_mem_parityRowSystem_le hk rows j hM₀) M hM + +/-- Every branch equation `φ.branchParityRowSystem rows S e b j` contains at most `W * 2 ^ k` +monomials whenever every clause of `φ` has width at most `k` and every row in `rows` has Hamming +weight at most `W`. -/ +theorem CNF.card_branchParityRowSystem_le {φ : CNF V} {k W : ℕ} + (hk : ∀ c ∈ φ, c.length ≤ k) {rows : List (Fin φ.length → Bool)} + (hW : ∀ r ∈ rows, weight r ≤ W) (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') + (b : V → Bool) (j : Fin rows.length) : + #(φ.branchParityRowSystem rows S e b j) ≤ W * 2 ^ k := + (card_relabelRestrictedMonomials_le S e b (φ.parityRowSystem rows j)).trans + (CNF.card_parityRowSystem_le hk hW j) + +/-- Every branch equation scope `φ.branchParityRowScope rows S e b j` has size at most +`k * (W * 2 ^ k)` whenever every clause of `φ` has width at most `k` and every row in `rows` has +Hamming weight at most `W`. -/ +theorem CNF.card_branchParityRowScope_le {φ : CNF V} {k W : ℕ} + (hk : ∀ c ∈ φ, c.length ≤ k) {rows : List (Fin φ.length → Bool)} + (hW : ∀ r ∈ rows, weight r ≤ W) (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') + (b : V → Bool) (j : Fin rows.length) : + #(φ.branchParityRowScope rows S e b j) ≤ k * (W * 2 ^ k) := + (card_equationScope_le (fun _ hM => + CNF.card_mem_branchParityRowSystem_le hk rows S e b j hM)).trans + (Nat.mul_le_mul_left k (CNF.card_branchParityRowSystem_le hk hW S e b j)) + +/-- Every factor in `φ.branchParityRowNeutralScope rows S e b` has scope width at most +`max 1 (k * (W * 2 ^ k))` whenever every clause of `φ` has width at most `k` and every row in +`rows` has Hamming weight at most `W`. -/ +theorem CNF.card_branchParityRowNeutralScope_le {φ : CNF V} {k W : ℕ} + (hk : ∀ c ∈ φ, c.length ≤ k) {rows : List (Fin φ.length → Bool)} + (hW : ∀ r ∈ rows, weight r ≤ W) (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') + (b : V → Bool) (f : Fin rows.length ⊕ Fin n') : + #(φ.branchParityRowNeutralScope rows S e b f) ≤ max 1 (k * (W * 2 ^ k)) := + card_withNeutralScope_le (le_max_left 1 _) + (fun j => (CNF.card_branchParityRowScope_le hk hW S e b j).trans (le_max_right 1 _)) f + +/-- Total factor–variable incidence of `φ.branchParityRowNeutralScope rows S e b` equals +`totalIncidence univ (φ.branchParityRowScope rows S e b) + n'`. -/ +theorem CNF.totalIncidence_branchParityRowNeutralScope_eq (φ : CNF V) + (rows : List (Fin φ.length → Bool)) (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') + (b : V → Bool) : + totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n')) + (φ.branchParityRowNeutralScope rows S e b) = + totalIncidence (univ : Finset (Fin rows.length)) + (φ.branchParityRowScope rows S e b) + n' := by + rw [CNF.branchParityRowNeutralScope, ← withNeutralFactors_univ, + totalIncidence_withNeutralFactors, Fintype.card_fin] + +/-- Neutral singleton factors ensure `n' ≤ M'_b` on every branch `b` ([OpenAI2026ETH], §5.5, +p. 38). -/ +theorem CNF.le_totalIncidence_branchParityRowNeutralScope (φ : CNF V) + (rows : List (Fin φ.length → Bool)) (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') + (b : V → Bool) : + n' ≤ totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n')) + (φ.branchParityRowNeutralScope rows S e b) := by + rw [CNF.totalIncidence_branchParityRowNeutralScope_eq] + exact Nat.le_add_left n' _ + +/-- When `S = heavyVars univ univ (fun j => equationScope (φ.parityRowSystem rows j)) b₀`, every +free variable `v : Fin n'` occurs in at most `b₀` restricted equation scopes of +`φ.branchParityRowScope rows S e b`. -/ +theorem CNF.varIncidence_branchParityRowScope_heavyVars_le (φ : CNF V) + (rows : List (Fin φ.length → Bool)) (b₀ : ℕ) + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n') + (b : V → Bool) (v : Fin n') : + varIncidence (univ : Finset (Fin rows.length)) + (φ.branchParityRowScope rows + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) + e b) v ≤ b₀ := + varIncidence_relabelRestrictedMonomials_heavyVars_le univ univ + (φ.parityRowSystem rows) b₀ subset_rfl e b v + +/-- When `S = heavyVars univ univ (fun j => equationScope (φ.parityRowSystem rows j)) b₀`, every +free variable `v : Fin n'` occurs in at most `b₀ + 1` scopes of +`φ.branchParityRowNeutralScope rows S e b`. -/ +theorem CNF.varIncidence_branchParityRowNeutralScope_heavyVars_le (φ : CNF V) + (rows : List (Fin φ.length → Bool)) (b₀ : ℕ) + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n') + (b : V → Bool) (v : Fin n') : + varIncidence (univ : Finset (Fin rows.length ⊕ Fin n')) + (φ.branchParityRowNeutralScope rows + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) + e b) v ≤ b₀ + 1 := by + rw [CNF.branchParityRowNeutralScope, ← withNeutralFactors_univ] + exact varIncidence_withNeutralFactors_le + (CNF.varIncidence_branchParityRowScope_heavyVars_le φ rows b₀ e b v) + +/-- When `S = heavyVars univ univ (fun j => equationScope (φ.parityRowSystem rows j)) b₀`, total +branch incidence of `φ.branchParityRowNeutralScope rows S e b` is at most `(b₀ + 1) * n'`. -/ +theorem CNF.totalIncidence_branchParityRowNeutralScope_heavyVars_le (φ : CNF V) + (rows : List (Fin φ.length → Bool)) (b₀ : ℕ) + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n') + (b : V → Bool) : + totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n')) + (φ.branchParityRowNeutralScope rows + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) + e b) ≤ (b₀ + 1) * n' := by + rw [CNF.branchParityRowNeutralScope, ← withNeutralFactors_univ] + simpa only [Fintype.card_fin] using + totalIncidence_withNeutralFactors_le + (CNF.varIncidence_branchParityRowScope_heavyVars_le φ rows b₀ e b) + +/-- **§5.5 & §6.3 (Lemma 4.7 `ReplacementDesign` existence on each heavy-variable branch of a +compiled CNF parity system)**: if every clause of `φ` has width at most `k` and every row in `rows` +has Hamming weight at most `W`, then on every branch `b : V → Bool` of +`S = heavyVars univ univ (fun j => equationScope (φ.parityRowSystem rows j)) b₀` with free-variable +relabeling `e : ↥(univ \ S) ≃ Fin n'`, the neutral-augmented scope family +`φ.branchParityRowNeutralScope rows S e b` admits a Section 4 +`ReplacementDesign _ Q r A₀ R τ` whenever the numerical balance and binomial-tail hypotheses of +Lemma 4.7 hold for `b_occ = b₀ + 1` and `w_width = max 1 (k * (W * 2 ^ k))`. -/ +theorem CNF.exists_replacementDesign_branchParityRowNeutralScope {φ : CNF V} + {k W b₀ Q r A₀ R : ℕ} {τ : ℚ} (hk : ∀ c ∈ φ, c.length ≤ k) + {rows : List (Fin φ.length → Bool)} (hW : ∀ r_row ∈ rows, weight r_row ≤ W) + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n') + (b : V → Bool) (hn' : 1 ≤ n') (hr : 2 ≤ r) (hR : 1 ≤ R) (hRQ : R < Q) (hτ : 0 ≤ τ) + (hI : ∀ a < R - 1, A₀ + a ≤ Q) + (hbal₁ : + 2 * (b₀ + 1 + max 1 (k * (W * 2 ^ k))) * (r ^ (2 * Q)) ^ 2 ≤ + totalIncidence (univ : Finset (Fin rows.length)) + (φ.branchParityRowScope rows + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) + e b) + n') + (hbal₂ : 2 * Q * r ^ 2 ≤ n') + (htail : binomTailProb Q r A₀ R ≤ τ / ((r : ℚ) * ((b₀ + 1 : ℕ) : ℚ))) : + Nonempty + (ReplacementDesign + (φ.branchParityRowNeutralScope rows + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) + e b) Q r A₀ R τ) := + exists_replacementDesign_withNeutralScope _ hn' (le_max_left 1 _) hr hR hRQ hτ hI + (CNF.varIncidence_branchParityRowScope_heavyVars_le φ rows b₀ e b) + (fun j => (CNF.card_branchParityRowScope_le hk hW _ e b j).trans (le_max_right 1 _)) + hbal₁ hbal₂ htail + +end BranchParityRowSystem + +/-! ### 2. Per-branch locality, degree, and `coeffNorm1` bounds under a `ReplacementDesign` -/ + +section BranchDesignBounds + +variable [Fintype V] [DecidableEq V] {n' Q r A₀ R : ℕ} {τ : ℚ} + +/-- **§5.3 factor-level locality on a branch-restricted CNF parity equation**: for any +`D : ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) Q r A₀ R τ`, the substituted +branch equation factor `(univariateMonomialSumPoly ℚ (designReplacementMap D Sum.inl x j) +(φ.branchParityRowSystem rows S e b j)).eval (nodePoint t)` depends only on `x` restricted to +`varGroup D.varAssign t (D.factorAssign (Sum.inl j) t)` and the measurement vector +`(varMeasurementMatrix Q r A₀ R ℚ D.place +(scopeVarOf (φ.branchParityRowNeutralScope rows S e b))).mulVec (fun u => bitVal ℚ (x u))`. -/ +theorem CNF.eval_univariateMonomialSumPoly_branchParityRowSystem_nodePoint_eq + (φ : CNF V) (rows : List (Fin φ.length → Bool)) + (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') (b : V → Bool) + (D : ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) Q r A₀ R τ) + (j : Fin rows.length) (t : Fin Q) (x x' : Fin n' → Bool) + (hgrp : ∀ u ∈ varGroup D.varAssign t (D.factorAssign (Sum.inl j) t), x u = x' u) + (hmeas : + (varMeasurementMatrix Q r A₀ R ℚ D.place + (scopeVarOf (φ.branchParityRowNeutralScope rows S e b))).mulVec + (fun u => bitVal ℚ (x u)) = + (varMeasurementMatrix Q r A₀ R ℚ D.place + (scopeVarOf (φ.branchParityRowNeutralScope rows S e b))).mulVec + (fun u => bitVal ℚ (x' u))) : + (univariateMonomialSumPoly ℚ (designReplacementMap D Sum.inl x j) + (φ.branchParityRowSystem rows S e b j)).eval (nodePoint t) = + (univariateMonomialSumPoly ℚ (designReplacementMap D Sum.inl x' j) + (φ.branchParityRowSystem rows S e b j)).eval (nodePoint t) := + eval_univariateMonomialSumPoly_designReplacementMap_nodePoint_eq D Sum.inl + (φ.branchParityRowSystem rows S e b) subset_rfl t x x' hgrp hmeas + +/-- **Equation (5.5) degree bound on a branch-restricted CNF parity system**: if every clause of `φ` +has width at most `k`, then for any replacement design `D` on branch `b` (with factor embedding +`emb : Fin rows.length → F`) and `s < ℓ`, the cleared parity coordinate `s` on +`φ.branchParityRowSystem rows S e b` has +`natDegree ≤ (k * (R - 1)) * (rows.length + 2 * (ℓ - 1))` (strengthening the manuscript's coarser +`k * R * (rows.length + 2 * (ℓ - 1))` display in (5.5) via `natDegree ≤ R - 1` from Lemma 4.3 and +§4.5 (4.14)). -/ +theorem CNF.natDegree_univariateClearedParityCoord_branchParityRowSystem_le + {F : Type*} [Fintype F] {scope : F → Finset (Fin n')} {φ : CNF V} {k ℓ s : ℕ} + (hk : ∀ c ∈ φ, c.length ≤ k) (rows : List (Fin φ.length → Bool)) + (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') (b : V → Bool) + (D : ReplacementDesign scope Q r A₀ R τ) (emb : Fin rows.length → F) + (hs : s < ℓ) : + (univariateClearedParityCoord (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb) s).natDegree ≤ + (k * (R - 1)) * (rows.length + 2 * (ℓ - 1)) := by + have hdeg := natDegree_univariateClearedParityCoord_design_le D emb + (univ : Finset (Fin rows.length)) (φ.branchParityRowSystem rows S e b) + (fun j _ _M hM => CNF.card_mem_branchParityRowSystem_le hk rows S e b j hM) hs + simpa only [card_univ, Fintype.card_fin] using hdeg + +/-- **Equation (5.5) degree bound for `univariateClearedParityTruncatedSum` on a branch-restricted +CNF parity system**: under `∀ c ∈ φ, c.length ≤ k`, the truncated sum has +`natDegree ≤ (k * (R - 1)) * (rows.length + 2 * (ℓ - 1))` (strengthening the manuscript's coarser +`k * R * (rows.length + 2 * (ℓ - 1))` display in (5.5) via `natDegree ≤ R - 1` from Lemma 4.3 and +§4.5 (4.14)). -/ +theorem CNF.natDegree_univariateClearedParityTruncatedSum_branchParityRowSystem_le + {F : Type*} [Fintype F] {scope : F → Finset (Fin n')} {φ : CNF V} {k : ℕ} + (hk : ∀ c ∈ φ, c.length ≤ k) (rows : List (Fin φ.length → Bool)) + (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') (b : V → Bool) + (D : ReplacementDesign scope Q r A₀ R τ) (emb : Fin rows.length → F) + (ℓ : ℕ) : + (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb)).natDegree ≤ + (k * (R - 1)) * (rows.length + 2 * (ℓ - 1)) := by + have hdeg := natDegree_univariateClearedParityTruncatedSum_design_le D emb + (univ : Finset (Fin rows.length)) (φ.branchParityRowSystem rows S e b) k ℓ + (fun j _ _M hM => CNF.card_mem_branchParityRowSystem_le hk rows S e b j hM) + simpa only [card_univ, Fintype.card_fin] using hdeg + +/-- **Appendix B.2 coordinate `coeffNorm1` bound on a branch-restricted CNF parity system**: if +every clause of `φ` has width at most `k` and every row in `rows` has Hamming weight at most `W`, +then for any replacement design `D` on branch `b`, every cleared parity coordinate `s` on +`φ.branchParityRowSystem rows S e b` satisfies the Appendix B.2 `ℓ₁`-norm bound with +`S_mon = W * 2 ^ k`. -/ +theorem CNF.coeffNorm1_univariateClearedParityCoord_branchParityRowSystem_le + {F : Type*} [Fintype F] {scope : F → Finset (Fin n')} {φ : CNF V} {k W ℓ E_ℓ : ℕ} + (hk : ∀ c ∈ φ, c.length ≤ k) {rows : List (Fin φ.length → Bool)} + (hW : ∀ r_row ∈ rows, weight r_row ≤ W) (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') + (b : V → Bool) (D : ReplacementDesign scope Q r A₀ R τ) + (emb : Fin rows.length → F) + (hE : ∀ j < ℓ, (Polynomial.parityBaseDigit ℓ j).coeffNorm1 ≤ E_ℓ) (s : ℕ) : + (univariateClearedParityCoord (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb) s).coeffNorm1 ≤ + 2 ^ n' * + (ℓ * E_ℓ * + ((W * 2 ^ k) * designRowNormBound Q R ^ k + commonDenom Q R ^ k) ^ (2 * ℓ - 1)) ^ + rows.length := by + have hnorm := coeffNorm1_univariateClearedParityCoord_design_le D emb + (univ : Finset (Fin rows.length)) (φ.branchParityRowSystem rows S e b) k ℓ + (S_mon := W * 2 ^ k) + (fun j _ _M hM => CNF.card_mem_branchParityRowSystem_le hk rows S e b j hM) + (fun j _ => CNF.card_branchParityRowSystem_le hk hW S e b j) + hE s + simpa only [card_univ, Fintype.card_fin] using hnorm + +end BranchDesignBounds + +/-! ### 3. End-to-end `ReplacementDesign` recovery of `commonZeroCount`, `numPassing`, and `#F` -/ + +section DesignRecovery + +variable [Fintype V] [DecidableEq V] {n' Q r A₀ R : ℕ} {τ : ℚ} + +/-- **§5.4–5.5 single-branch `ReplacementDesign` recovery for `φ.branchParityRowSystem`**: when +`∀ c ∈ φ, c.length ≤ k` and `n' < ℓ`, evaluating `univariateClearedParityTruncatedSum` at `T = 0`, +dividing by `clearedProductDenom`, and reducing modulo `2 ^ ℓ` recovers the branch common-zero count +`commonZeroCount univ (φ.branchParityRowSystem rows S e b)`. -/ +theorem CNF.emod_ediv_eval_zero_branchParityRowSystem_design_eq_commonZeroCount + {F : Type*} [Fintype F] {scope : F → Finset (Fin n')} {φ : CNF V} {k ℓ : ℕ} + (hk : ∀ c ∈ φ, c.length ≤ k) (rows : List (Fin φ.length → Bool)) + (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') (b : V → Bool) + (D : ReplacementDesign scope Q r A₀ R τ) (emb : Fin rows.length → F) + (hℓ : n' < ℓ) : + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) (commonDenom Q R : ℤ) k ℓ + (designReplacementScaledIntMap D emb)).eval 0 / + clearedProductDenom (commonDenom Q R : ℤ) k ℓ + #(univ : Finset (Fin rows.length))) % ((2 : ℤ) ^ ℓ) = + (commonZeroCount (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) : ℤ) := + emod_ediv_eval_zero_clearedParityTruncatedSum_design_eq_commonZeroCount D emb + (univ : Finset (Fin rows.length)) (φ.branchParityRowSystem rows S e b) hℓ + (fun j _ _M hM => CNF.card_mem_branchParityRowSystem_le hk rows S e b j hM) + +/-- **§5.4–5.5 & §6 (branch-summed `ReplacementDesign` recovery of `commonZeroCount` on +`φ.parityRowSystem rows`)**: when every clause of `φ` has width at most `k`, summing the per-branch +`ReplacementDesign` modular residues of `univariateClearedParityTruncatedSum` at shared precision +`branchPrecision (Fintype.card V)` across all `b ∈ branchAssignments S` recovers +`commonZeroCount univ (φ.parityRowSystem rows)`. -/ +theorem CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design + {F : (V → Bool) → Type*} [∀ b, Fintype (F b)] {φ : CNF V} {k : ℕ} + (hk : ∀ c ∈ φ, c.length ≤ k) (rows : List (Fin φ.length → Bool)) + (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') + (scope : (b : V → Bool) → F b → Finset (Fin n')) + (D : (b : V → Bool) → ReplacementDesign (scope b) Q r A₀ R τ) + (emb : (b : V → Bool) → Fin rows.length → F b) : + (commonZeroCount (univ : Finset (Fin rows.length)) (φ.parityRowSystem rows) : ℤ) = + ∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) (commonDenom Q R : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) (emb b))).eval 0 / + clearedProductDenom (commonDenom Q R : ℤ) k + (branchPrecision (Fintype.card V)) #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card V)) := + commonZeroCount_eq_sum_branch_emod_ediv_cleared S e (univ : Finset (Fin rows.length)) + (φ.parityRowSystem rows) (commonDenom_intCast_ne_zero Q R) + (fun b => designReplacementScaledIntMap (D b) (emb b)) + (fun j _ _M hM => CNF.card_mem_parityRowSystem_le hk rows j hM) + (fun b _ x j _ _ _ v _ => eval_zero_designReplacementScaledIntMap (D b) (emb b) x j v) + +/-- **§5.4–5.5 & §6 (branch-summed `ReplacementDesign` recovery of +`numPassing φ.violations rows`)**: when every clause of `φ` has width at most `k`, the +branch-summed `ReplacementDesign` evaluation at `T = 0` equals +`(numPassing φ.violations rows : ℤ)`. -/ +theorem CNF.numPassing_eq_sum_branch_emod_ediv_design + {F : (V → Bool) → Type*} [∀ b, Fintype (F b)] {φ : CNF V} {k : ℕ} + (hk : ∀ c ∈ φ, c.length ≤ k) (rows : List (Fin φ.length → Bool)) + (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') + (scope : (b : V → Bool) → F b → Finset (Fin n')) + (D : (b : V → Bool) → ReplacementDesign (scope b) Q r A₀ R τ) + (emb : (b : V → Bool) → Fin rows.length → F b) : + (numPassing φ.violations rows : ℤ) = + ∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) (commonDenom Q R : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) (emb b))).eval 0 / + clearedProductDenom (commonDenom Q R : ℤ) k + (branchPrecision (Fintype.card V)) #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card V)) := by + rw [← CNF.commonZeroCount_parityRowSystem] + exact CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design hk rows S e scope D emb + +/-- **§5.4–5.5 & §6.2–6.3 (branch-summed `ReplacementDesign` recovery of +`φ.modelCountOn Finset.univ` after `3 * n` greedy rounds)**: under the hypotheses of +`CNF.commonZeroCount_parityRowSystem_greedy`, for any heavy-variable set `S : Finset V`, +free-variable relabeling `e : ↥(univ \ S) ≃ Fin n'`, and per-branch replacement design family +`D b`, summing the branch modular residues of `univariateClearedParityTruncatedSum` at `T = 0` +across `b ∈ branchAssignments S` recovers `(φ.modelCountOn Finset.univ : ℤ)` without any auxiliary +replacement hypotheses. -/ +theorem CNF.modelCountOn_eq_sum_branch_emod_ediv_design_greedy + {F : (V → Bool) → Type*} [∀ b, Fintype (F b)] (φ : CNF V) {k P : ℕ} + (hk : ∀ c ∈ φ, c.length ≤ k) (hn : 1 ≤ Fintype.card V) (hP : 1 ≤ P) + (A : ℕ → List (Fin φ.length → Bool)) + (hinit : ∀ σ, PassesTests φ.violations (A 0) σ → φ.eval σ = false → + φ.length ≤ P * weight (φ.violations σ)) + (γ : ℕ → Fin P → Fin φ.length × Bool) (hA : ∀ i, A (i + 1) = A i ++ [testRow (γ i)]) + (hγ : ∀ i (γ' : Fin P → Fin φ.length × Bool), + commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow (γ i)])) ≤ + commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow γ']))) + (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') + (scope : (b : V → Bool) → F b → Finset (Fin n')) + (D : (b : V → Bool) → ReplacementDesign (scope b) Q r A₀ R τ) + (emb : (b : V → Bool) → Fin (A (3 * Fintype.card V)).length → F b) : + (φ.modelCountOn Finset.univ : ℤ) = + ∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum + (univ : Finset (Fin (A (3 * Fintype.card V)).length)) + (φ.branchParityRowSystem (A (3 * Fintype.card V)) S e b) + (commonDenom Q R : ℤ) k (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) (emb b))).eval 0 / + clearedProductDenom (commonDenom Q R : ℤ) k + (branchPrecision (Fintype.card V)) + #(univ : Finset (Fin (A (3 * Fintype.card V)).length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card V)) := by + rw [← CNF.commonZeroCount_parityRowSystem_greedy φ hn hP A hinit γ hA hγ] + exact CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design hk + (A (3 * Fintype.card V)) S e scope D emb + +/-- For all `B, m : ℕ`, the Lemma 6.2 greedy list length +`P = 20000 * B ^ 2 * (Nat.log 2 m + 1) ^ 2` is at most the Lemma 6.1 initial row weight bound +`D₀ = 320000 * B ^ 2 * (Nat.log 2 m + 1) ^ 3`. -/ +theorem CNF.greedyRowListLength_le_initialRowWeightBound (B m : ℕ) : + CNF.greedyRowListLength B m ≤ CNF.initialRowWeightBound B m := by + unfold CNF.greedyRowListLength CNF.initialRowWeightBound + have h1 : 20000 * B ^ 2 ≤ 320000 * B ^ 2 := + Nat.mul_le_mul_right (B ^ 2) (by decide) + have h2 : (Nat.log 2 m + 1) ^ 2 ≤ (Nat.log 2 m + 1) ^ 3 := + Nat.pow_le_pow_right (Nat.succ_pos _) (by decide) + exact Nat.mul_le_mul h1 h2 + +/-- Consequently `max (CNF.initialRowWeightBound B m) (CNF.greedyRowListLength B m)` simplifies to +`CNF.initialRowWeightBound B m`. -/ +@[simp] +theorem CNF.max_initialRowWeightBound_greedyRowListLength (B m : ℕ) : + max (CNF.initialRowWeightBound B m) (CNF.greedyRowListLength B m) = + CNF.initialRowWeightBound B m := + max_eq_left (CNF.greedyRowListLength_le_initialRowWeightBound B m) + +/-- **Lemmas 6.1–6.2 & §§5.4–5.5, 6.3 (end-to-end initial + greedy parity-test compilation and +branch-summed `ReplacementDesign` recovery of `φ.modelCountOn Finset.univ`)**: for any width-`≤ k` +CNF `φ` on `n = Fintype.card V ≥ 1` variables with `φ.length ≤ B * n` (`B ≥ 1`), there exist +initial parity rows `A_init` (`A_init.length ≤ 3 * n`, each of weight at most +`D₀ = CNF.initialRowWeightBound B φ.length`) such that for any greedy sequence +`A (i + 1) = A i ++ [testRow (γ i)]` with `A 0 = A_init` minimizing +`commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow γ']))` over candidate rows of list length +`P = CNF.greedyRowListLength B φ.length`: +1. At every stage `i ≤ 3 * n`, `(A i).length ≤ 6 * n`, and every compiled equation + `φ.parityRowSystem (A i) j` has degree at most `k`, at most `D₀ * 2 ^ k` monomials, and + variable-scope size `#(equationScope (φ.parityRowSystem (A i) j)) ≤ k * (D₀ * 2 ^ k)`. +2. After `3 * n` rounds, for any heavy-variable set `S : Finset V`, free-variable relabeling + `e : ↥(univ \ S) ≃ Fin n'`, and per-branch replacement design family `D b`, the branch-summed + `ReplacementDesign` evaluation at `T = 0` equals `(φ.modelCountOn Finset.univ : ℤ)`. -/ +theorem CNF.exists_initialTests_modelCountOn_eq_sum_branch_emod_ediv_design_greedy + {F : (V → Bool) → Type*} [∀ b, Fintype (F b)] (φ : CNF V) {k B : ℕ} + (hk : ∀ c ∈ φ, c.length ≤ k) (hn : 1 ≤ Fintype.card V) (hB : 1 ≤ B) + (hm : φ.length ≤ B * Fintype.card V) : + let D₀ := CNF.initialRowWeightBound B φ.length + let P := CNF.greedyRowListLength B φ.length + ∃ A_init : List (Fin φ.length → Bool), A_init.length ≤ 3 * Fintype.card V ∧ + (∀ r_row ∈ A_init, weight r_row ≤ D₀) ∧ + ∀ (A : ℕ → List (Fin φ.length → Bool)) + (γ : ℕ → Fin P → Fin φ.length × Bool), + A 0 = A_init → (∀ i, A (i + 1) = A i ++ [testRow (γ i)]) → + (∀ i (γ' : Fin P → Fin φ.length × Bool), + commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow (γ i)])) ≤ + commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow γ']))) → + (∀ i ≤ 3 * Fintype.card V, + (A i).length ≤ 6 * Fintype.card V ∧ + ∀ j : Fin (A i).length, + (∀ M ∈ φ.parityRowSystem (A i) j, M ⊆ φ.vars.toFinset ∧ #M ≤ k) ∧ + #(φ.parityRowSystem (A i) j) ≤ D₀ * 2 ^ k ∧ + #(equationScope (φ.parityRowSystem (A i) j)) ≤ k * (D₀ * 2 ^ k)) ∧ + ∀ (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') + (scope : (b : V → Bool) → F b → Finset (Fin n')) + (D : (b : V → Bool) → ReplacementDesign (scope b) Q r A₀ R τ) + (emb : (b : V → Bool) → Fin (A (3 * Fintype.card V)).length → F b), + (φ.modelCountOn Finset.univ : ℤ) = + ∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum + (univ : Finset (Fin (A (3 * Fintype.card V)).length)) + (φ.branchParityRowSystem (A (3 * Fintype.card V)) S e b) + (commonDenom Q R : ℤ) k (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) (emb b))).eval 0 / + clearedProductDenom (commonDenom Q R : ℤ) k + (branchPrecision (Fintype.card V)) + #(univ : Finset (Fin (A (3 * Fintype.card V)).length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card V)) := by + obtain ⟨A_init, hlen, hw, hgreedy⟩ := CNF.exists_initialTests_commonZeroCount_greedy φ hk hn hB hm + refine ⟨A_init, hlen, hw, fun A γ h0 hA hγ => ?_⟩ + obtain ⟨hcount, hbounds⟩ := hgreedy A γ h0 hA hγ + refine ⟨fun i hi => ?_, fun S e scope D emb => ?_⟩ + · obtain ⟨hlen_i, hj⟩ := hbounds i hi + refine ⟨hlen_i, fun j => ?_⟩ + obtain ⟨hM, hcard, hscope⟩ := hj j + rw [CNF.max_initialRowWeightBound_greedyRowListLength] at hcard hscope + exact ⟨hM, hcard, hscope⟩ + · rw [← hcount] + exact CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design hk + (A (3 * Fintype.card V)) S e scope D emb + +end DesignRecovery + +end Cslib.Logic.PL diff --git a/ComplexityTests/SparseDesignCounter.lean b/ComplexityTests/SparseDesignCounter.lean new file mode 100644 index 0000000000..3663158a41 --- /dev/null +++ b/ComplexityTests/SparseDesignCounter.lean @@ -0,0 +1,474 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Logics.Propositional.CNF.SparseDesignCounter + +/-! +# Tests for `Complexity.Logics.Propositional.CNF.SparseDesignCounter` +-/ + +@[expose] public noncomputable section + +namespace ComplexityTests.SparseDesignCounter + +open Finset Polynomial Cslib.BitString Cslib.BalancedSchedules Cslib.LinearAlgebra Cslib.Logic.PL + +/-- Concrete 2-variable 2-CNF formula `(x₀ ∨ ¬x₁) ∧ (x₁)` on `Fin 2`, with unique satisfying +assignment `x₀ = true, x₁ = true`. -/ +def testCNF : CNF (Fin 2) := + [[(0, true), (1, false)], [(1, true)]] + +/-- Concrete two-row unit parity check matrix selecting clause `0` and clause `1` of `testCNF`. -/ +def testRows : List (Fin testCNF.length → Bool) := + [Pi.single ⟨0, by decide⟩ true, Pi.single ⟨1, by decide⟩ true] + +/-- Concrete 3-variable 2-CNF formula `(x₀ ∨ ¬x₁) ∧ (x₁ ∨ ¬x₂)` on `Fin 3`, with `4` satisfying +assignments (`(false, false, false)`, `(true, false, false)`, `(true, true, false)`, and +`(true, true, true)`). -/ +def testCNF3 : CNF (Fin 3) := + [[(0, true), (1, false)], [(1, true), (2, false)]] + +/-- Unit parity check rows for `testCNF3`. -/ +def testRows3 : List (Fin testCNF3.length → Bool) := + [Pi.single ⟨0, by decide⟩ true, Pi.single ⟨1, by decide⟩ true] + +/-- Explicit equivalence between the unbranched variables `{1, 2}` (`univ \ {0}` in `Fin 3`) and +`Fin 2`. -/ +def freeVarEquiv3 : ↥((univ : Finset (Fin 3)) \ ({0} : Finset (Fin 3))) ≃ Fin 2 where + toFun v := if v.1 = 1 then 0 else 1 + invFun i := if i = 0 then ⟨1, by decide⟩ else ⟨2, by decide⟩ + left_inv := by decide + right_inv := by decide + +/-- Expected-value and sparsity controls on `testCNF3.branchParityRowSystem`, +`branchParityRowScope`, and `branchParityRowNeutralScope` for branch `b = fun _ => false` on +`S = {0}`: +- Clause `0` (`x₀ ∨ ¬x₁`) has violation monomial `(1 + x₀) x₁ = x₁ + x₀ x₁`, which under + `x₀ = false` restricts to `x₁` (free variable `0 : Fin 2`, scope `{0}`). +- Clause `1` (`x₁ ∨ ¬x₂`) has violation monomial `(1 + x₁) x₂ = x₂ + x₁ x₂`, which restricts to + `{1}, {0, 1}` on `Fin 2` (scope `{0, 1}`). +- Neutral singleton factors add `{0}` and `{1}`, so total neutral-augmented incidence is + `(1 + 2) + 2 = 5 ≥ 2`. -/ +example (j : Fin testRows3.length) (f : Fin testRows3.length ⊕ Fin 2) : + #(testCNF3.branchParityRowSystem testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 + (fun _ => false) j) ≤ 1 * 2 ^ 2 ∧ + #(testCNF3.branchParityRowScope testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 + (fun _ => false) j) ≤ 2 * (1 * 2 ^ 2) ∧ + #(testCNF3.branchParityRowNeutralScope testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 + (fun _ => false) f) ≤ max 1 (2 * (1 * 2 ^ 2)) ∧ + totalIncidence (univ : Finset (Fin testRows3.length ⊕ Fin 2)) + (testCNF3.branchParityRowNeutralScope testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 + (fun _ => false)) = 5 ∧ + 2 ≤ totalIncidence (univ : Finset (Fin testRows3.length ⊕ Fin 2)) + (testCNF3.branchParityRowNeutralScope testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 + (fun _ => false)) := by + refine ⟨?_, ?_, ?_, by decide, ?_⟩ + · exact testCNF3.card_branchParityRowSystem_le (k := 2) (W := 1) (by decide) (by decide) + ({0} : Finset (Fin 3)) freeVarEquiv3 (fun _ => false) j + · exact testCNF3.card_branchParityRowScope_le (k := 2) (W := 1) (by decide) (by decide) + ({0} : Finset (Fin 3)) freeVarEquiv3 (fun _ => false) j + · exact testCNF3.card_branchParityRowNeutralScope_le (k := 2) (W := 1) (by decide) (by decide) + ({0} : Finset (Fin 3)) freeVarEquiv3 (fun _ => false) f + · exact testCNF3.le_totalIncidence_branchParityRowNeutralScope testRows3 + ({0} : Finset (Fin 3)) freeVarEquiv3 (fun _ => false) + +/-- Canonical `Q = 1, r = 1, A₀ = 0, R = 1, τ = 0` replacement design for any scope family on +`Fin n`. -/ +def unitReplacementDesign {F : Type*} [Fintype F] {n : ℕ} + (scope : F → Finset (Fin n)) : ReplacementDesign scope 1 1 0 1 0 := + let h := Fintype.card (ScopeIncidence scope) + let eFin := Fintype.equivFin (ScopeIncidence scope) + let place : ScopeIncidence scope → Fin h × AuxLabel 1 1 := + fun e => (eFin e, (fun _ => 0, fun _ => 0)) + have hinj : Function.Injective place := fun _ _ hEq => + eFin.injective (congrArg Prod.fst hEq) + { varAssign := fun _ _ => 0 + factorAssign := fun _ _ => 0 + h := h + place := place + card_varGroup_le := fun t g => by + have hsub : #(varGroup (fun (_ : Fin n) (_ : Fin 1) => (0 : Fin 1)) t g) ≤ n := by + simpa only [card_univ, Fintype.card_fin] using + card_le_univ (varGroup (fun (_ : Fin n) (_ : Fin 1) => (0 : Fin 1)) t g) + omega + factorAssign_of_empty := fun _ _ _ => rfl + injective_place := hinj + place_snd := fun _ => rfl + h_mul_D_le := by + change Fintype.card (ScopeIncidence scope) * 1 ^ (2 * 1) ≤ 2 * ∑ f : F, #(scope f) + rw [card_scopeIncidence] + omega + total_measurement_rows_le := by + have hmeas : #(measurementIndices 1 1 0 1) = 0 := by decide + simp [hmeas] + sum_abs_measurement_row_le := + sum_abs_varMeasurementMatrix_le 1 1 0 1 hinj (scopeVarOf scope) + natDegree_replacementRow_le := + natDegree_varReplacementRow_le 1 1 0 1 place (scopeVarOf scope) + eval_replacementRow_zero := + eval_varReplacementRow_zero 1 1 0 1 hinj (scopeVarOf scope) + evalReplacementRow_nodePoint_eq_zero_of_kernel := fun e t g hg ξ hsupp hker => + evalVarReplacementRow_nodePoint_eq_zero_of_kernel 1 1 0 1 place (scopeVarOf scope) + (fun _ _ => 0) (fun _ => rfl) e t g hg ξ hsupp hker + map_replacementRowScaledInt := + map_varReplacementRowScaledInt 1 1 0 1 place (scopeVarOf scope) + sum_coeffNorm1_replacementRowScaledInt_le := + sum_coeffNorm1_varReplacementRowScaledInt_le (by decide) hinj (scopeVarOf scope) + (by intro a ha; omega) } + +/-- Scope family on `Fin testRows3.length ⊕ Fin 2` for branch `b = fun _ => false` of `testCNF3`. -/ +abbrev sampleBranchNeutralScope : Fin testRows3.length ⊕ Fin 2 → Finset (Fin 2) := + testCNF3.branchParityRowNeutralScope testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 + (fun _ => false) + +/-- Variable group schedule for `nonconstBranchDesign`: free variable `0` in group `0`, free +variable `1` in group `1`. -/ +def nonconstBranchVarAssign : Fin 2 → Fin 1 → Fin 2 := + fun v _ => v + +/-- Factor group schedule for `nonconstBranchDesign`: equation factors in group `0`, neutral +factors in group `1`. -/ +def nonconstBranchFactorAssign : Fin testRows3.length ⊕ Fin 2 → Fin 1 → Fin 2 + | Sum.inl _, _ => 0 + | Sum.inr _, _ => 1 + +/-- Copy index in `Fin 2` separating the `5` incidences of `sampleBranchNeutralScope`. -/ +def nonconstBranchCopy (e : ScopeIncidence sampleBranchNeutralScope) : Fin 2 := + match e.1 with + | Sum.inl ⟨0, _⟩ => 0 + | Sum.inl ⟨1, _⟩ => if e.2.1 = 0 then 1 else 0 + | Sum.inr _ => 0 + +/-- Injective placement for `nonconstBranchDesign`. -/ +def nonconstBranchPlace (e : ScopeIncidence sampleBranchNeutralScope) : + Fin 2 × AuxLabel 1 2 := + (nonconstBranchCopy e, + (nonconstBranchVarAssign (scopeVarOf sampleBranchNeutralScope e), + nonconstBranchFactorAssign (scopeFactorOf sampleBranchNeutralScope e))) + +theorem injective_nonconstBranchPlace : Function.Injective nonconstBranchPlace := by + decide + +/-- Concrete `Q = 1, r = 2, A₀ = 0, R = 2, τ = 0` replacement design on `sampleBranchNeutralScope` +with nonconstant degree-`1` replacement rows. -/ +def nonconstBranchDesign : + ReplacementDesign sampleBranchNeutralScope 1 2 0 2 0 where + varAssign := nonconstBranchVarAssign + factorAssign := nonconstBranchFactorAssign + h := 2 + place := nonconstBranchPlace + card_varGroup_le := by decide + factorAssign_of_empty := by decide + injective_place := injective_nonconstBranchPlace + place_snd := fun _ => rfl + h_mul_D_le := by decide + total_measurement_rows_le := by + have hmeas : #(measurementIndices 1 2 0 2) = 0 := by decide + simp [hmeas] + sum_abs_measurement_row_le := + sum_abs_varMeasurementMatrix_le 1 2 0 2 injective_nonconstBranchPlace + (scopeVarOf sampleBranchNeutralScope) + natDegree_replacementRow_le := + natDegree_varReplacementRow_le 1 2 0 2 nonconstBranchPlace + (scopeVarOf sampleBranchNeutralScope) + eval_replacementRow_zero := + eval_varReplacementRow_zero 1 2 0 2 injective_nonconstBranchPlace + (scopeVarOf sampleBranchNeutralScope) + evalReplacementRow_nodePoint_eq_zero_of_kernel := fun e t g hg ξ hsupp hker => + evalVarReplacementRow_nodePoint_eq_zero_of_kernel 1 2 0 2 nonconstBranchPlace + (scopeVarOf sampleBranchNeutralScope) nonconstBranchVarAssign (fun _ => rfl) e t g hg ξ + hsupp hker + map_replacementRowScaledInt := + map_varReplacementRowScaledInt 1 2 0 2 nonconstBranchPlace + (scopeVarOf sampleBranchNeutralScope) + sum_coeffNorm1_replacementRowScaledInt_le := + sum_coeffNorm1_varReplacementRowScaledInt_le (by decide) injective_nonconstBranchPlace + (scopeVarOf sampleBranchNeutralScope) (by intro a ha; omega) + +/-- Assignment `x₁ = (false, true)` on `Fin 2` placing `true` on free variable `1 : Fin 2` in +group `1`. -/ +def branchAssign₁ : Fin 2 → Bool := fun v => decide (v = 1) + +/-- All-false assignment `x₂ = (false, false)` on `Fin 2` agreeing with `branchAssign₁` on group +`0 = {0}`. -/ +def branchAssign₂ : Fin 2 → Bool := fun _ => false + +/-- Checked client of `CNF.eval_univariateMonomialSumPoly_branchParityRowSystem_nodePoint_eq`, +`CNF.natDegree_univariateClearedParityCoord_branchParityRowSystem_le`, +`CNF.natDegree_univariateClearedParityTruncatedSum_branchParityRowSystem_le`, and +`CNF.coeffNorm1_univariateClearedParityCoord_branchParityRowSystem_le` on `nonconstBranchDesign`: +1. The replacement polynomial for equation `1` and free variable `1 : Fin 2` on `branchAssign₁` has + exact nonconstant degree `1` (`eval 0 = 1`, `eval (nodePoint 0) = 0`). +2. `CNF.eval_univariateMonomialSumPoly_branchParityRowSystem_nodePoint_eq` proves that the + substituted equation-`1` factors for `branchAssign₁` and `branchAssign₂` coincide at + `nodePoint (0 : Fin 1)`. +3. The cleared coordinate and truncated-sum polynomials at `k = 2, ℓ = 4` have `natDegree ≤ 16` + and satisfy the Appendix B.2 `coeffNorm1` bound. -/ +example {E_ℓ : ℕ} (hE : ∀ j < 4, (Polynomial.parityBaseDigit 4 j).coeffNorm1 ≤ E_ℓ) : + (designReplacementMap nonconstBranchDesign Sum.inl branchAssign₁ ⟨1, by decide⟩ 1).eval 0 = 1 ∧ + (designReplacementMap nonconstBranchDesign Sum.inl branchAssign₁ ⟨1, by decide⟩ 1).eval + (nodePoint (0 : Fin 1)) = 0 ∧ + (univariateMonomialSumPoly ℚ + (designReplacementMap nonconstBranchDesign Sum.inl branchAssign₁ ⟨1, by decide⟩) + (testCNF3.branchParityRowSystem testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 + (fun _ => false) ⟨1, by decide⟩)).eval (nodePoint (0 : Fin 1)) = + (univariateMonomialSumPoly ℚ + (designReplacementMap nonconstBranchDesign Sum.inl branchAssign₂ ⟨1, by decide⟩) + (testCNF3.branchParityRowSystem testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 + (fun _ => false) ⟨1, by decide⟩)).eval (nodePoint (0 : Fin 1)) ∧ + (univariateClearedParityCoord (univ : Finset (Fin testRows3.length)) + (testCNF3.branchParityRowSystem testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 + (fun _ => false)) + (commonDenom 1 2 : ℤ) 2 4 (designReplacementScaledIntMap nonconstBranchDesign Sum.inl) + 0).natDegree ≤ 16 ∧ + (univariateClearedParityTruncatedSum (univ : Finset (Fin testRows3.length)) + (testCNF3.branchParityRowSystem testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 + (fun _ => false)) + (commonDenom 1 2 : ℤ) 2 4 + (designReplacementScaledIntMap nonconstBranchDesign Sum.inl)).natDegree ≤ 16 ∧ + (univariateClearedParityCoord (univ : Finset (Fin testRows3.length)) + (testCNF3.branchParityRowSystem testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 + (fun _ => false)) + (commonDenom 1 2 : ℤ) 2 4 (designReplacementScaledIntMap nonconstBranchDesign Sum.inl) + 0).coeffNorm1 ≤ + 2 ^ 2 * + (4 * E_ℓ * + ((1 * 2 ^ 2) * designRowNormBound 1 2 ^ 2 + commonDenom 1 2 ^ 2) ^ (2 * 4 - 1)) ^ 2 := by + have hgrp : ∀ u ∈ varGroup nonconstBranchDesign.varAssign (0 : Fin 1) + (nonconstBranchDesign.factorAssign (Sum.inl ⟨1, by decide⟩) (0 : Fin 1)), + branchAssign₁ u = branchAssign₂ u := by + decide + have hmeas : + (varMeasurementMatrix 1 2 0 2 ℚ nonconstBranchDesign.place + (scopeVarOf sampleBranchNeutralScope)).mulVec (fun u => bitVal ℚ (branchAssign₁ u)) = + (varMeasurementMatrix 1 2 0 2 ℚ nonconstBranchDesign.place + (scopeVarOf sampleBranchNeutralScope)).mulVec (fun u => bitVal ℚ (branchAssign₂ u)) := by + funext p + exact absurd p.2.2 (by decide +revert) + have heval0 : + (designReplacementMap nonconstBranchDesign Sum.inl branchAssign₁ ⟨1, by decide⟩ 1).eval 0 = + 1 := by + rw [eval_zero_designReplacementMap] + rfl + have heval1 : + (designReplacementMap nonconstBranchDesign Sum.inl branchAssign₁ ⟨1, by decide⟩ 1).eval + (nodePoint (0 : Fin 1)) = 0 := by + have hloc := eval_nodePoint_designReplacementMap_eq_of_eq_on_varGroup + nonconstBranchDesign Sum.inl (i := (⟨1, by decide⟩ : Fin testRows3.length)) + (v := (1 : Fin 2)) (by decide) (0 : Fin 1) branchAssign₁ branchAssign₂ hgrp hmeas + have hzero : + designReplacementMap nonconstBranchDesign Sum.inl branchAssign₂ ⟨1, by decide⟩ 1 = 0 := by + simp [branchAssign₂, designReplacementMap, evalVarReplacementRowPoly] + rw [hloc, hzero, Polynomial.eval_zero] + refine ⟨heval0, heval1, ?_, ?_, ?_, ?_⟩ + · exact testCNF3.eval_univariateMonomialSumPoly_branchParityRowSystem_nodePoint_eq + testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 (fun _ => false) nonconstBranchDesign + ⟨1, by decide⟩ (0 : Fin 1) branchAssign₁ branchAssign₂ hgrp hmeas + · simpa [testRows3] using testCNF3.natDegree_univariateClearedParityCoord_branchParityRowSystem_le + (k := 2) (ℓ := 4) (s := 0) (by decide) testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 + (fun _ => false) nonconstBranchDesign Sum.inl (by decide) + · simpa [testRows3] using + testCNF3.natDegree_univariateClearedParityTruncatedSum_branchParityRowSystem_le + (k := 2) (by decide) testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 + (fun _ => false) nonconstBranchDesign Sum.inl 4 + · simpa [testRows3] using + testCNF3.coeffNorm1_univariateClearedParityCoord_branchParityRowSystem_le + (k := 2) (W := 1) (ℓ := 4) (by decide) (by decide) ({0} : Finset (Fin 3)) freeVarEquiv3 + (fun _ => false) nonconstBranchDesign Sum.inl hE 0 + +/-- Checked client of `CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design` and +`CNF.numPassing_eq_sum_branch_emod_ediv_design` on `testCNF3` and `testRows3` (`S = {0}`): +the branch-summed `ReplacementDesign` recovery equals `4`. -/ +example : + ∑ b ∈ branchAssignments ({0} : Finset (Fin 3)), + ((univariateClearedParityTruncatedSum (univ : Finset (Fin testRows3.length)) + (testCNF3.branchParityRowSystem testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 b) + (commonDenom 1 1 : ℤ) 2 (branchPrecision (Fintype.card (Fin 3))) + (designReplacementScaledIntMap + (unitReplacementDesign + (testCNF3.branchParityRowNeutralScope testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 b)) + Sum.inl)).eval 0 / + clearedProductDenom (commonDenom 1 1 : ℤ) 2 (branchPrecision (Fintype.card (Fin 3))) + #(univ : Finset (Fin testRows3.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card (Fin 3))) = 4 := by + have hrec := testCNF3.numPassing_eq_sum_branch_emod_ediv_design (k := 2) (by decide) testRows3 + ({0} : Finset (Fin 3)) freeVarEquiv3 + (fun b => testCNF3.branchParityRowNeutralScope testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 b) + (fun b => unitReplacementDesign + (testCNF3.branchParityRowNeutralScope testRows3 ({0} : Finset (Fin 3)) freeVarEquiv3 b)) + (fun _ => Sum.inl) + have hpass : numPassing testCNF3.violations testRows3 = 4 := by decide + rw [← hrec, hpass] + rfl + +/-- Explicit equivalence between `{1}` (`univ \ {0}` in `Fin 2`) and `Fin 1`. -/ +def freeVarEquiv2 : ↥((univ : Finset (Fin 2)) \ ({0} : Finset (Fin 2))) ≃ Fin 1 where + toFun _ := 0 + invFun _ := ⟨1, by decide⟩ + left_inv := by decide + right_inv := by decide + +/-- Concrete candidate tuple of length `P = 2` for `testCNF`. -/ +def testCand : Fin 2 → Fin testCNF.length × Bool := + fun _ => (⟨0, by decide⟩, false) + +/-- Concrete `3 * n`-step greedy row sequence starting from `testRows`. -/ +def testGreedySeq : ℕ → List (Fin testCNF.length → Bool) + | 0 => testRows + | i + 1 => testGreedySeq i ++ [testRow testCand] + +private theorem passesTests_testGreedySeq_imp_passesTests_testRows : + ∀ (i : ℕ) (σ : Fin 2 → Bool), + PassesTests testCNF.violations (testGreedySeq i) σ → + PassesTests testCNF.violations testRows σ + | 0, _, h => h + | i + 1, σ, h => + passesTests_testGreedySeq_imp_passesTests_testRows i σ + ((passesTests_append_singleton _ _ _ _).mp h).1 + +private theorem violations_eq_zero_of_passesTests_testRows : + ∀ σ : Fin 2 → Bool, PassesTests testCNF.violations testRows σ → testCNF.violations σ = 0 := by + decide + +private theorem commonZeroCount_testGreedySeq_step_le (i : ℕ) + (γ' : Fin 2 → Fin testCNF.length × Bool) : + commonZeroCount univ (testCNF.parityRowSystem (testGreedySeq i ++ [testRow testCand])) ≤ + commonZeroCount univ (testCNF.parityRowSystem (testGreedySeq i ++ [testRow γ'])) := by + rw [testCNF.commonZeroCount_parityRowSystem, testCNF.commonZeroCount_parityRowSystem] + apply card_le_card + intro σ hσ + rw [mem_filter] at hσ ⊢ + refine ⟨mem_univ σ, ?_⟩ + have hpasses_i := ((passesTests_append_singleton _ _ _ _).mp hσ.2).1 + have hzero := violations_eq_zero_of_passesTests_testRows σ + (passesTests_testGreedySeq_imp_passesTests_testRows i σ hpasses_i) + rw [passesTests_append_singleton] + refine ⟨hpasses_i, ?_⟩ + rw [hzero, dotProduct_zero] + rfl + +/-- Checked client of `CNF.modelCountOn_eq_sum_branch_emod_ediv_design_greedy`: recovers +`testCNF.modelCountOn Finset.univ = 1` via `unitReplacementDesign` without any auxiliary `θ` or +`hθ` hypotheses. -/ +example : + ∑ b ∈ branchAssignments ({0} : Finset (Fin 2)), + ((univariateClearedParityTruncatedSum + (univ : Finset (Fin (testGreedySeq (3 * Fintype.card (Fin 2))).length)) + (testCNF.branchParityRowSystem (testGreedySeq (3 * Fintype.card (Fin 2))) + ({0} : Finset (Fin 2)) freeVarEquiv2 b) + (commonDenom 1 1 : ℤ) 2 (branchPrecision (Fintype.card (Fin 2))) + (designReplacementScaledIntMap + (unitReplacementDesign + (testCNF.branchParityRowNeutralScope (testGreedySeq (3 * Fintype.card (Fin 2))) + ({0} : Finset (Fin 2)) freeVarEquiv2 b)) + Sum.inl)).eval 0 / + clearedProductDenom (commonDenom 1 1 : ℤ) 2 (branchPrecision (Fintype.card (Fin 2))) + #(univ : Finset (Fin (testGreedySeq (3 * Fintype.card (Fin 2))).length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card (Fin 2))) = 1 := by + have hrec := testCNF.modelCountOn_eq_sum_branch_emod_ediv_design_greedy + (k := 2) (P := 2) (by decide) (by decide) (by decide) testGreedySeq (by decide) + (fun _ => testCand) (fun _ => rfl) commonZeroCount_testGreedySeq_step_le + ({0} : Finset (Fin 2)) freeVarEquiv2 + (fun b => testCNF.branchParityRowNeutralScope (testGreedySeq (3 * Fintype.card (Fin 2))) + ({0} : Finset (Fin 2)) freeVarEquiv2 b) + (fun b => unitReplacementDesign + (testCNF.branchParityRowNeutralScope (testGreedySeq (3 * Fintype.card (Fin 2))) + ({0} : Finset (Fin 2)) freeVarEquiv2 b)) + (fun _ => Sum.inl) + have hcount : testCNF.modelCountOn Finset.univ = 1 := by decide + rw [← hrec, hcount] + rfl + +/-- Concrete check of `CNF.max_initialRowWeightBound_greedyRowListLength` at `B = 2, m = 8`. -/ +example : + max (CNF.initialRowWeightBound 2 8) (CNF.greedyRowListLength 2 8) = + 320000 * 2 ^ 2 * (3 + 1) ^ 3 := by + rw [CNF.max_initialRowWeightBound_greedyRowListLength] + decide + +/-- Empty CNF on `Fin 16384` used to witness +`CNF.exists_replacementDesign_branchParityRowNeutralScope` at `b₀ = 0`, `Q = 3`, `r = 2`, +`A₀ = 0`, `R = 2`, `τ = 1 / 2`. -/ +def emptyCNF16384 : CNF (Fin 16384) := [] + +/-- Equivalence between `↥(univ \ heavyVars univ univ ... 0)` and `Fin 16384` for `emptyCNF16384` +with `rows = []`. -/ +def emptyFreeVarEquiv16384 : + ↥((univ : Finset (Fin 16384)) \ + heavyVars univ (univ : Finset (Fin ([] : List (Fin emptyCNF16384.length → Bool)).length)) + (fun j => equationScope (emptyCNF16384.parityRowSystem [] j)) 0) ≃ Fin 16384 where + toFun v := v.1 + invFun v := ⟨v, by + rw [mem_sdiff] + refine ⟨mem_univ v, ?_⟩ + simp [heavyVars, varIncidence]⟩ + left_inv v := by ext; rfl + right_inv _ := rfl + +/-- Nonvacuous witness of `CNF.exists_replacementDesign_branchParityRowNeutralScope` and +single-branch recovery `CNF.emod_ediv_eval_zero_branchParityRowSystem_design_eq_commonZeroCount` on +`emptyCNF16384` (`commonZeroCount = 2 ^ 16384` at `ℓ = 16385`). -/ +theorem exists_design_and_recover_emptyCNF16384 : + ∃ D : ReplacementDesign + (emptyCNF16384.branchParityRowNeutralScope [] + (heavyVars univ (univ : Finset (Fin ([] : List (Fin emptyCNF16384.length → Bool)).length)) + (fun j => equationScope (emptyCNF16384.parityRowSystem [] j)) 0) + emptyFreeVarEquiv16384 (fun _ => false)) 3 2 0 2 (1 / 2), + ((univariateClearedParityTruncatedSum + (univ : Finset (Fin ([] : List (Fin emptyCNF16384.length → Bool)).length)) + (emptyCNF16384.branchParityRowSystem [] + (heavyVars univ + (univ : Finset (Fin ([] : List (Fin emptyCNF16384.length → Bool)).length)) + (fun j => equationScope (emptyCNF16384.parityRowSystem [] j)) 0) + emptyFreeVarEquiv16384 (fun _ => false)) + (commonDenom 3 2 : ℤ) 3 16385 (designReplacementScaledIntMap D Sum.inl)).eval 0 / + clearedProductDenom (commonDenom 3 2 : ℤ) 3 16385 + #(univ : Finset (Fin ([] : List (Fin emptyCNF16384.length → Bool)).length))) % + ((2 : ℤ) ^ 16385) = (2 : ℤ) ^ 16384 := by + have hcard : #(measurementIndices 3 2 0 2) = 10 := by + rw [card_measurementIndices_eq] + decide + have htail : binomTailProb 3 2 0 2 ≤ (1 / 2 : ℚ) / ((2 : ℚ) * ((0 + 1 : ℕ) : ℚ)) := by + rw [binomTailProb_eq_div 3 2 0 2 (by decide), hcard] + norm_num + have hI : ∀ a < 2 - 1, 0 + a ≤ 3 := by decide + have hbal₁_arith : 2 * (0 + 1 + max 1 (3 * (0 * 2 ^ 3))) * (2 ^ (2 * 3)) ^ 2 ≤ 0 + 16384 := by + decide + have hbal₂ : 2 * 3 * 2 ^ 2 ≤ 16384 := by decide + have hne := emptyCNF16384.exists_replacementDesign_branchParityRowNeutralScope + (k := 3) (W := 0) (b₀ := 0) (Q := 3) (r := 2) (A₀ := 0) (R := 2) (τ := 1 / 2) + (rows := []) (fun _ hc => nomatch hc) (fun _ hr => nomatch hr) + emptyFreeVarEquiv16384 (fun _ => false) + (by decide) (by decide) (by decide) (by decide) (by norm_num) + hI hbal₁_arith hbal₂ htail + obtain ⟨D⟩ := hne + refine ⟨D, ?_⟩ + have hrec := emptyCNF16384.emod_ediv_eval_zero_branchParityRowSystem_design_eq_commonZeroCount + (k := 3) (ℓ := 16385) (fun _ hc => nomatch hc) [] + (heavyVars univ (univ : Finset (Fin ([] : List (Fin emptyCNF16384.length → Bool)).length)) + (fun j => equationScope (emptyCNF16384.parityRowSystem [] j)) 0) + emptyFreeVarEquiv16384 (fun _ => false) D Sum.inl (by decide) + have hcount : + (commonZeroCount + (univ : Finset (Fin ([] : List (Fin emptyCNF16384.length → Bool)).length)) + (emptyCNF16384.branchParityRowSystem [] + (heavyVars univ (univ : Finset (Fin ([] : List (Fin emptyCNF16384.length → Bool)).length)) + (fun j => equationScope (emptyCNF16384.parityRowSystem [] j)) 0) + emptyFreeVarEquiv16384 (fun _ => false)) : ℤ) = (2 : ℤ) ^ 16384 := by + change + (commonZeroCount (∅ : Finset (Fin ([] : List (Fin emptyCNF16384.length → Bool)).length)) + (emptyCNF16384.branchParityRowSystem [] + (heavyVars univ (univ : Finset (Fin ([] : List (Fin emptyCNF16384.length → Bool)).length)) + (fun j => equationScope (emptyCNF16384.parityRowSystem [] j)) 0) + emptyFreeVarEquiv16384 (fun _ => false)) : ℤ) = (2 : ℤ) ^ 16384 + rw [commonZeroCount_empty, Fintype.card_fin, Nat.cast_pow, Nat.cast_ofNat] + exact hrec.trans hcount + +end ComplexityTests.SparseDesignCounter From e96809c7a21f24f835b6a6d110f5f08b56c37313 Mon Sep 17 00:00:00 2001 From: Samuel Schlesinger Date: Tue, 27 Oct 2026 05:23:16 +0000 Subject: [PATCH 16/20] feat(FineGrained): add Section 6.3 compiled parity-row schedule feasibility and examination bounds (#1226) --- Complexity.lean | 1 + .../FineGrained/SparseParitySchedule.lean | 778 ++++++++++++++++++ .../FineGrained/SparseParitySchedule.lean | 279 +++++++ 3 files changed, 1058 insertions(+) create mode 100644 Complexity/Computability/Complexity/FineGrained/SparseParitySchedule.lean create mode 100644 ComplexityTests/Computability/Complexity/FineGrained/SparseParitySchedule.lean diff --git a/Complexity.lean b/Complexity.lean index d43d4cf127..3b469a1bdf 100644 --- a/Complexity.lean +++ b/Complexity.lean @@ -774,6 +774,7 @@ public import Complexity.Computability.Complexity.FineGrained.ReplacementParams public import Complexity.Computability.Complexity.FineGrained.ReplacementScheduleDesign public import Complexity.Computability.Complexity.FineGrained.Schoening public import Complexity.Computability.Complexity.FineGrained.SparseBranchSchedule +public import Complexity.Computability.Complexity.FineGrained.SparseParitySchedule public import Complexity.Computability.Complexity.FineGrained.Sparsification public import Complexity.Computability.Complexity.HardnessEncoding.PolyTime public import Complexity.Computability.Complexity.HardnessEncoding.Program diff --git a/Complexity/Computability/Complexity/FineGrained/SparseParitySchedule.lean b/Complexity/Computability/Complexity/FineGrained/SparseParitySchedule.lean new file mode 100644 index 0000000000..c68ba86ce1 --- /dev/null +++ b/Complexity/Computability/Complexity/FineGrained/SparseParitySchedule.lean @@ -0,0 +1,778 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Computability.Complexity.FineGrained.SparseBranchSchedule +public import Complexity.Logics.Propositional.CNF.SparseParityCounter + +/-! +# Section 6.3 compiled CNF parity-row schedule feasibility and domain-examination bounds + +This module connects the compiled CNF parity-row systems and greedy model-counting reduction of +`Complexity.Logics.Propositional.CNF.SparseParityCounter` (Sections 6.1–6.3, Lemmas 6.1–6.2, +printed pp. 39–43 of [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH]) with the +per-branch schedule feasibility, `ReplacementDesign` existence, and domain-examination bounds of +`Complexity.Computability.Complexity.FineGrained.SparseBranchSchedule` (Section 5.5, Proof of +Theorem 2.2, printed pp. 38–39): + +1. **Incidence, free-variable, and scope-width bounds for `CNF.parityRowSystem` (§6.3, p. 43)**: + In Lemma 6.2 and Section 6.3, every candidate parity-row list `rows : List (Fin φ.length → Bool)` + (as well as the final list `A (3 * n)`) has at most `6 * Fintype.card V` equations ($c = 6$ in + Theorem 2.2) and row Hamming weight at most `W` (with `W = max D₀ P`). For any width-`≤ k` CNF + `φ : CNF V`: + - `CNF.totalIncidence_parityRowSystem_le_six_mul`: when `rows.length ≤ 6 * Fintype.card V` and + `∀ r ∈ rows, weight r ≤ W`, total variable-equation incidence across `φ.parityRowSystem rows` + is at most `(6 * (k * (W * 2 ^ k))) * Fintype.card V`. + - `CNF.card_le_two_mul_freeVar_parityRowSystem`: when `1 ≤ b₀`, `2 ≤ s_div`, and + `(6 * (k * (W * 2 ^ k))) * s_div ≤ b₀`, removing the heavy variables + `S = heavyVars univ univ (fun j => equationScope (φ.parityRowSystem rows j)) b₀` leaves + `Fintype.card V ≤ 2 * n'`, `Fintype.card V / 2 ≤ n'`, and at most + `2 ^ (Fintype.card V / s_div)` branches in `branchAssignments S`. + - `CNF.card_branchAugmentedScope_parityRowSystem_le`: every factor in + `branchAugmentedScope S e univ (φ.parityRowSystem rows) b` has scope width at most + `max (k * (W * 2 ^ k)) 1`. +2. **Per-branch and uniform `ReplacementDesign` existence and `(16 * k + 4)` domain-examination + bounds for `CNF.parityRowSystem` (§6.3, p. 43)**: + - `CNF.exists_branch_replacementDesign_parityRowSystem` and + `CNF.exists_branch_schedule_parityRowSystem`: instantiate + `Feasible.exists_branch_replacementDesign` and `exists_branch_schedule_replacementDesign` + directly on `φ.parityRowSystem rows` with scope width bound `w = k * (W * 2 ^ k)`. + - `CNF.branch_domainExaminationBound_parityRowSystem_le` and + `CNF.sum_branch_domainExaminationBound_parityRowSystem_le`: specialize + `Feasible.branch_domainExaminationBound_le` and `sum_branch_domainExaminationBound_le` at the + Lemma 6.2 equation-count ratio `c = 6` (`rows.length ≤ 6 * Fintype.card V`), yielding the + explicit single-branch examination bound + `2 * numNodes n' * numGroups n' * exp (((16 * k + 4) : ℝ) * n' * rowCost β n')` (since + `k * (2 * 6 + 4) + 4 = 16 * k + 4`) and the branch-summed bound + `2 ^ (Fintype.card V / s_div) * (2 * numNodes n' * numGroups n' *` + `exp (((16 * k + 4) : ℝ) * n' * rowCost β n'))`. +3. **End-to-end Lemma 6.1 + Lemma 6.2 + Section 6.3 greedy parity-test schedule theorems**: + - `CNF.exists_greedy_parityRowSystem_branch_schedule`: combines + `CNF.exists_initialTests_commonZeroCount_greedy` with + `CNF.exists_branch_schedule_parityRowSystem`, establishing that at every greedy stage + `i ≤ 3 * Fintype.card V` (with `W = max D₀ P`), `(A i).length ≤ 6 * Fintype.card V`, every + branch of `φ.parityRowSystem (A i)` is `Feasible` and admits a concrete `ReplacementDesign` in + the polylogarithmic regime, and at stage `3 * Fintype.card V`, + `commonZeroCount univ (φ.parityRowSystem (A (3 * Fintype.card V))) =` + `φ.modelCountOn Finset.univ`. + - `CNF.initialRowWeightBound_le_mul_pow_clog`, + `CNF.exists_branch_schedule_parityRowSystem_of_le_clog_pow`, and + `CNF.exists_greedy_parityRowSystem_branch_schedule_of_le_clog_pow`: discharge the free-variable + polylogarithmic schedule hypotheses `n₀ ≤ n'`, `b₀ + 1 ≤ (Nat.clog 2 n') ^ β`, and + `max (k * (W * 2 ^ k)) 1 ≤ (Nat.clog 2 n') ^ β` unconditionally at the canonical Section 5.5 / + Section 6.3 heavy-variable branching schedule `s_div = (Nat.clog 2 n).sqrt`, + `b₀ = CNF.parityBranchThreshold k W n`, and `β = 2 * β_B + 5` whenever + `B ≤ C_B * (Nat.clog 2 n) ^ β_B` and `N₀ ≤ n`. + +## Main definitions + +* `Cslib.Logic.PL.CNF.initialRowWeightCoeff` +* `Cslib.Logic.PL.CNF.parityBranchThreshold` +* `Cslib.Logic.PL.CNF.parityScheduleCoeff` + +## Main results + +* `Cslib.Logic.PL.CNF.totalIncidence_parityRowSystem_le_six_mul` +* `Cslib.Logic.PL.CNF.card_le_two_mul_freeVar_parityRowSystem` +* `Cslib.Logic.PL.CNF.card_branchAugmentedScope_parityRowSystem_le` +* `Cslib.Logic.PL.CNF.exists_branch_replacementDesign_parityRowSystem` +* `Cslib.Logic.PL.CNF.exists_branch_schedule_parityRowSystem` +* `Cslib.Logic.PL.CNF.branch_domainExaminationBound_parityRowSystem_le` +* `Cslib.Logic.PL.CNF.sum_branch_domainExaminationBound_parityRowSystem_le` +* `Cslib.Logic.PL.CNF.exists_greedy_parityRowSystem_branch_schedule` +* `Cslib.Logic.PL.CNF.initialRowWeightBound_le_mul_pow_clog` +* `Cslib.Logic.PL.CNF.exists_branch_schedule_parityRowSystem_of_le_clog_pow` +* `Cslib.Logic.PL.CNF.exists_greedy_parityRowSystem_branch_schedule_of_le_clog_pow` + +## References + +* [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] + (Section 5.5, pp. 38–39; Sections 6.1–6.3, pp. 39–43) +-/ + +public section + +namespace Cslib.Logic.PL + +open Finset +open Cslib.BitString +open Cslib.LinearAlgebra +open Cslib.Complexity.SubexponentialSAT.ReplacementParams + +variable {V : Type*} {n' : ℕ} + +/-! ### 1. Incidence, free-variable, and scope-width bounds for `CNF.parityRowSystem` -/ + +/-- **Section 6.2 & 6.3 ($M \le 6 k W 2^k n$ for candidate parity-row systems):** +when every clause of `φ` has width at most `k`, every row in `rows` has Hamming weight at most `W`, +and `rows.length ≤ 6 * Fintype.card V`, the total variable-equation incidence of +`φ.parityRowSystem rows` is at most `(6 * (k * (W * 2 ^ k))) * Fintype.card V`. -/ +theorem CNF.totalIncidence_parityRowSystem_le_six_mul [Fintype V] [DecidableEq V] + {φ : CNF V} {k W : ℕ} (hk : ∀ c ∈ φ, c.length ≤ k) + {rows : List (Fin φ.length → Bool)} (hW : ∀ r ∈ rows, weight r ≤ W) + (hlen : rows.length ≤ 6 * Fintype.card V) : + totalIncidence (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) ≤ + (6 * (k * (W * 2 ^ k))) * Fintype.card V := by + calc totalIncidence (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) + ≤ (k * (W * 2 ^ k)) * rows.length := CNF.totalIncidence_parityRowSystem_le hk hW + _ ≤ (k * (W * 2 ^ k)) * (6 * Fintype.card V) := Nat.mul_le_mul_left _ hlen + _ = (6 * (k * (W * 2 ^ k))) * Fintype.card V := by ring + +/-- **Section 5.5 & 6.3 ($n \le 2n'$ and branch count $\le 2^{n / s}$ for `CNF.parityRowSystem`):** +when `∀ c ∈ φ, c.length ≤ k`, `∀ r ∈ rows, weight r ≤ W`, `rows.length ≤ 6 * Fintype.card V`, +`1 ≤ b₀`, `2 ≤ s_div`, and `(6 * (k * (W * 2 ^ k))) * s_div ≤ b₀`, removing the heavy variables +`S = heavyVars univ univ (fun j => equationScope (φ.parityRowSystem rows j)) b₀` leaves +`Fintype.card V ≤ 2 * n'`, `Fintype.card V / 2 ≤ n'`, and at most `2 ^ (Fintype.card V / s_div)` +branches in `branchAssignments S`. -/ +theorem CNF.card_le_two_mul_freeVar_parityRowSystem [Fintype V] [DecidableEq V] + {φ : CNF V} {k W b₀ s_div : ℕ} (hk : ∀ c ∈ φ, c.length ≤ k) + {rows : List (Fin φ.length → Bool)} (hW : ∀ r ∈ rows, weight r ≤ W) + (hlen : rows.length ≤ 6 * Fintype.card V) + (hb₀ : 1 ≤ b₀) (hs_div : 2 ≤ s_div) + (h_thresh : (6 * (k * (W * 2 ^ k))) * s_div ≤ b₀) + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n') : + (Fintype.card V ≤ 2 * n' ∧ Fintype.card V / 2 ≤ n') ∧ + #(branchAssignments + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀)) ≤ + 2 ^ (Fintype.card V / s_div) := by + have hM : + totalIncidence (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) * s_div ≤ + b₀ * Fintype.card V := by + calc totalIncidence (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) * s_div + ≤ ((6 * (k * (W * 2 ^ k))) * Fintype.card V) * s_div := + Nat.mul_le_mul_right s_div (CNF.totalIncidence_parityRowSystem_le_six_mul hk hW hlen) + _ = ((6 * (k * (W * 2 ^ k))) * s_div) * Fintype.card V := by ring + _ ≤ b₀ * Fintype.card V := Nat.mul_le_mul_right _ h_thresh + exact ⟨card_le_two_mul_freeVar_of_heavyVars univ + (fun j => equationScope (φ.parityRowSystem rows j)) hb₀ hs_div hM e, + card_branchAssignments_heavyVars_le_two_pow_div univ + (fun j => equationScope (φ.parityRowSystem rows j)) hb₀ (by omega) hM⟩ + +/-- **Section 5.5 & 6.3 (per-factor scope width $\le \max(k W 2^k, 1)$ for `CNF.parityRowSystem`):** +when `∀ c ∈ φ, c.length ≤ k` and `∀ r ∈ rows, weight r ≤ W`, every factor `f` of +`branchAugmentedScope S e univ (φ.parityRowSystem rows) b` has scope cardinality at most +`max (k * (W * 2 ^ k)) 1`. -/ +theorem CNF.card_branchAugmentedScope_parityRowSystem_le [Fintype V] [DecidableEq V] + {φ : CNF V} {k W : ℕ} (hk : ∀ c ∈ φ, c.length ≤ k) + {rows : List (Fin φ.length → Bool)} (hW : ∀ r ∈ rows, weight r ≤ W) + (S : Finset V) (e : ↥(univ \ S) ≃ Fin n') (b : V → Bool) + (f : {j : Fin rows.length // j ∈ (univ : Finset (Fin rows.length))} ⊕ Fin n') : + #(branchAugmentedScope S e univ (φ.parityRowSystem rows) b f) ≤ + max (k * (W * 2 ^ k)) 1 := + card_branchAugmentedScope_le S e univ (φ.parityRowSystem rows) b + (fun j _ => CNF.card_equationScope_parityRowSystem_le hk hW j) f + +/-! ### 2. Per-branch and uniform `ReplacementDesign` and domain-examination bounds -/ + +/-- **Section 6.3 per-branch `ReplacementDesign` existence for `CNF.parityRowSystem`**: +Given a width-`≤ k` CNF `φ : CNF V`, a parity-row list `rows : List (Fin φ.length → Bool)` with +`∀ r ∈ rows, weight r ≤ W`, +`S = heavyVars univ univ (fun j => equationScope (φ.parityRowSystem rows j)) b₀`, +`e : ↥(univ \ S) ≃ Fin n'`, and +`hF : Feasible β n' (b₀ + 1) (max (k * (W * 2 ^ k)) 1)` +`(∑ f, #(branchAugmentedScope S e univ (φ.parityRowSystem rows) b f))`, +there exists a concrete Section 4 `ReplacementDesign` for +`branchAugmentedScope S e univ (φ.parityRowSystem rows) b` at the Lemma 4.8 schedule. -/ +theorem CNF.exists_branch_replacementDesign_parityRowSystem [Fintype V] [DecidableEq V] + {φ : CNF V} {β k W b₀ : ℕ} (hk : ∀ c ∈ φ, c.length ≤ k) + {rows : List (Fin φ.length → Bool)} (hW : ∀ r ∈ rows, weight r ≤ W) + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n') + (b : V → Bool) + (hF : Feasible β n' (b₀ + 1) (max (k * (W * 2 ^ k)) 1) + (∑ f : {j : Fin rows.length // j ∈ (univ : Finset (Fin rows.length))} ⊕ Fin n', + #(branchAugmentedScope + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) + e univ (φ.parityRowSystem rows) b f))) : + Nonempty + (ReplacementDesign + (branchAugmentedScope + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) + e univ (φ.parityRowSystem rows) b) + (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n')) := + hF.exists_branch_replacementDesign univ univ (φ.parityRowSystem rows) (Subset.refl _) e b + (fun j _ => CNF.card_equationScope_parityRowSystem_le hk hW j) + +/-- **Uniform Section 6.3 schedule feasibility and `ReplacementDesign` existence for +`CNF.parityRowSystem`**: +For every `1 ≤ β`, there exists `n₀ ≥ 20` such that for any width-`≤ k` CNF `φ : CNF V` and +parity-row list `rows : List (Fin φ.length → Bool)` with `∀ r ∈ rows, weight r ≤ W`, whenever the +free-variable count `n'` after removing +`S = heavyVars univ univ (fun j => equationScope (φ.parityRowSystem rows j)) b₀` satisfies +`n₀ ≤ n'`, `b₀ + 1 ≤ (Nat.clog 2 n') ^ β`, and `max (k * (W * 2 ^ k)) 1 ≤ (Nat.clog 2 n') ^ β`, +**every** branch assignment `b : V → Bool` simultaneously satisfies `Feasible` and admits a +concrete `ReplacementDesign`. -/ +theorem CNF.exists_branch_schedule_parityRowSystem {β : ℕ} (hβ : 1 ≤ β) : + ∃ n₀ : ℕ, 20 ≤ n₀ ∧ + ∀ {V : Type*} [Fintype V] [DecidableEq V] + {φ : CNF V} ⦃n' k W b₀ : ℕ⦄, + (∀ c ∈ φ, c.length ≤ k) → + ∀ {rows : List (Fin φ.length → Bool)}, + (∀ r ∈ rows, weight r ≤ W) → + ∀ (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n'), + n₀ ≤ n' → + b₀ + 1 ≤ Nat.clog 2 n' ^ β → + max (k * (W * 2 ^ k)) 1 ≤ Nat.clog 2 n' ^ β → + ∀ b : V → Bool, + Feasible β n' (b₀ + 1) (max (k * (W * 2 ^ k)) 1) + (∑ f : {j : Fin rows.length // j ∈ (univ : Finset (Fin rows.length))} ⊕ Fin n', + #(branchAugmentedScope + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) + e univ (φ.parityRowSystem rows) b f)) ∧ + Nonempty + (ReplacementDesign + (branchAugmentedScope + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) + e univ (φ.parityRowSystem rows) b) + (numNodes n') (numGroups n') (intervalStart β n') + (rowBound β n') (tauRat n')) := by + obtain ⟨n₀, hn₀20, hsched⟩ := exists_branch_schedule_replacementDesign hβ + refine ⟨n₀, hn₀20, + fun {V _ _ φ n' k W b₀} hk {rows} hW e hn' hb₀ hw_pow b => ?_⟩ + exact hsched univ univ (φ.parityRowSystem rows) (Subset.refl _) e hn' hb₀ hw_pow + (fun j _ => CNF.card_equationScope_parityRowSystem_le hk hW j) b + +/-- **Section 6.3 single-branch domain-examination bound for `CNF.parityRowSystem` ($c = 6$):** +For any parity-row list `rows : List (Fin φ.length → Bool)` with `rows.length ≤ 6 * Fintype.card V` +and `Fintype.card V ≤ 2 * n'`, and any branch `b` with `hF : Feasible β n' b_occ w_width M'` and +concrete schedule design `D`, at the Section 5.3 / 6.3 degree budget +`d = k * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1))` and canonical truncation order +`q = (d * rowBound β n') / numNodes n'`, the induced Section 3 counting design +`C := hF.toCountingDesign D s` satisfies +`(∑ t : Fin (numNodes n'), (#{p : Finset (Fin n') × Finset (Fin n') | #p.1 ≤ q ∧ p.2 ⊆ p.1} : ℝ) * + (2 * (#(C.measurementBox t) : ℝ) * + ∑ g : Fin (numGroups n'), (Fintype.card (C.LocalCube t g) : ℝ))) + ≤ 2 * numNodes n' * numGroups n' * exp (((16 * k + 4 : ℕ) : ℝ) * n' * rowCost β n')`. -/ +theorem CNF.branch_domainExaminationBound_parityRowSystem_le [Fintype V] + {F_idx : Type*} [Fintype F_idx] {scope : F_idx → Finset (Fin n')} + {φ : CNF V} {β b_occ w_width M' k : ℕ} + (rows : List (Fin φ.length → Bool)) + (hF : Feasible β n' b_occ w_width M') + (D : ReplacementDesign scope (numNodes n') (numGroups n') (intervalStart β n') + (rowBound β n') (tauRat n')) + (s : Finset F_idx) (hlen : rows.length ≤ 6 * Fintype.card V) (hn : Fintype.card V ≤ 2 * n') : + let d := k * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1)) + let q := (d * rowBound β n') / numNodes n' + let C := hF.toCountingDesign D s + (∑ t : Fin (numNodes n'), + (#{p : Finset (Fin n') × Finset (Fin n') | #p.1 ≤ q ∧ p.2 ⊆ p.1} : ℝ) * + (2 * (#(C.measurementBox t) : ℝ) * + ∑ g : Fin (numGroups n'), (Fintype.card (C.LocalCube t g) : ℝ))) ≤ + 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * + Real.exp (((16 * k + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n') ∧ + 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * + Real.exp (((16 * k + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n') ≤ + 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * + Real.exp (((16 * k + 4 : ℕ) : ℝ) * (n' : ℝ) * + (1028 * ((β : ℝ) + 3) * (Nat.clog 2 (Nat.clog 2 n') : ℝ) ^ 2 / + Real.sqrt (Nat.clog 2 n'))) := by + intro d q C + have hcard : #(univ : Finset (Fin rows.length)) ≤ 6 * Fintype.card V := by + simpa only [card_univ, Fintype.card_fin] using hlen + have hbound := hF.branch_domainExaminationBound_le (ι := V) (k := k) (c := 6) + (univ : Finset (Fin rows.length)) D s hcard hn + have h16 : k * (2 * 6 + 4) + 4 = 16 * k + 4 := by ring + simpa only [card_univ, Fintype.card_fin, h16] using hbound + +/-- **Section 6.3 multi-branch domain-examination bound across `branchAssignments` for +`CNF.parityRowSystem`**: +When `∀ c ∈ φ, c.length ≤ k`, `∀ r ∈ rows, weight r ≤ W`, `rows.length ≤ 6 * Fintype.card V`, +`1 ≤ b₀`, `2 ≤ s_div`, `(6 * (k * (W * 2 ^ k))) * s_div ≤ b₀`, and `e : ↥(univ \ S) ≃ Fin n'`, +the free-variable dimension satisfies `Fintype.card V ≤ 2 * n'`, and if each branch +`b ∈ branchAssignments S` has its real examination sum bounded via +`CNF.branch_domainExaminationBound_parityRowSystem_le`, then the sum of those examination bounds +across all `b ∈ branchAssignments S` is at most +`(2 : ℝ) ^ (Fintype.card V / s_div) * (2 * numNodes n' * numGroups n' * + exp (((16 * k + 4 : ℕ) : ℝ) * n' * rowCost β n'))`. -/ +theorem CNF.sum_branch_domainExaminationBound_parityRowSystem_le [Fintype V] [DecidableEq V] + {φ : CNF V} {β k W b₀ s_div : ℕ} (hk : ∀ c ∈ φ, c.length ≤ k) + {rows : List (Fin φ.length → Bool)} (hW : ∀ r ∈ rows, weight r ≤ W) + (hlen : rows.length ≤ 6 * Fintype.card V) + (hb₀ : 1 ≤ b₀) (hs_div : 2 ≤ s_div) + (h_thresh : (6 * (k * (W * 2 ^ k))) * s_div ≤ b₀) + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n') + (examSum : (V → Bool) → ℝ) + (hexam : ∀ b ∈ branchAssignments + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀), + examSum b ≤ + 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * + Real.exp (((16 * k + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n')) : + Fintype.card V ≤ 2 * n' ∧ + (∑ b ∈ branchAssignments + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀), + examSum b) ≤ + (2 : ℝ) ^ (Fintype.card V / s_div) * + (2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * + Real.exp (((16 * k + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n')) := by + have hM : + totalIncidence (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) * s_div ≤ + b₀ * Fintype.card V := by + calc totalIncidence (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) * s_div + ≤ ((6 * (k * (W * 2 ^ k))) * Fintype.card V) * s_div := + Nat.mul_le_mul_right s_div (CNF.totalIncidence_parityRowSystem_le_six_mul hk hW hlen) + _ = ((6 * (k * (W * 2 ^ k))) * s_div) * Fintype.card V := by ring + _ ≤ b₀ * Fintype.card V := Nat.mul_le_mul_right _ h_thresh + have h16 : k * (2 * 6 + 4) + 4 = 16 * k + 4 := by ring + simpa only [h16] using + sum_branch_domainExaminationBound_le (β := β) (k := k) (c := 6) + (univ : Finset (Fin rows.length)) (φ.parityRowSystem rows) hb₀ hs_div hM e examSum + (by simpa only [h16] using hexam) + +/-! ### 3. End-to-end Lemma 6.1 + Lemma 6.2 + Section 6.3 greedy parity-test schedule theorem -/ + +private theorem greedyRowListLength_le_initialRowWeightBound (B m : ℕ) : + CNF.greedyRowListLength B m ≤ CNF.initialRowWeightBound B m := by + unfold CNF.greedyRowListLength CNF.initialRowWeightBound + have h1 : 20000 * B ^ 2 ≤ 320000 * B ^ 2 := Nat.mul_le_mul_right _ (by decide) + have h2 : (Nat.log 2 m + 1) ^ 2 ≤ (Nat.log 2 m + 1) ^ 3 := + Nat.pow_le_pow_right (Nat.succ_pos _) (by decide) + exact Nat.mul_le_mul h1 h2 + +private theorem max_initialRowWeightBound_greedyRowListLength (B m : ℕ) : + max (CNF.initialRowWeightBound B m) (CNF.greedyRowListLength B m) = + CNF.initialRowWeightBound B m := + max_eq_left (greedyRowListLength_le_initialRowWeightBound B m) + +/-- **Lemmas 6.1–6.2 & Section 6.3 (greedy parity-row selection with uniform per-branch +`Feasible` and `ReplacementDesign` guarantees at every stage `i ≤ 3 * n`)**: +For any `1 ≤ β`, there exists `n₀ ≥ 20` such that for any width-`≤ k` CNF `φ : CNF V` on +`n = Fintype.card V ≥ 1` variables with `φ.length ≤ B * n` (`1 ≤ B`), there exist initial parity +rows `A₀` (`A₀.length ≤ 3 * n`, each of weight at most `D₀ = CNF.initialRowWeightBound B φ.length`) +such that for any `3 * n`-step greedy sequence `A (i + 1) = A i ++ [testRow (γ i)]` with `A 0 = A₀` +minimizing `commonZeroCount` over candidate rows of list length +`P = CNF.greedyRowListLength B φ.length`: +1. After `3 * n` rounds, + `commonZeroCount univ (φ.parityRowSystem (A (3 * n))) = φ.modelCountOn Finset.univ`. +2. At every stage `i ≤ 3 * n`, `(A i).length ≤ 6 * n`, and whenever the free-variable count `n'` + after removing + `S_i = heavyVars univ univ (fun j => equationScope (φ.parityRowSystem (A i) j)) b₀` satisfies + `n₀ ≤ n'`, `b₀ + 1 ≤ (Nat.clog 2 n') ^ β`, and + `max (k * (max D₀ P * 2 ^ k)) 1 ≤ (Nat.clog 2 n') ^ β`, every branch `b : V → Bool` of + `φ.parityRowSystem (A i)` satisfies + `Feasible β n' (b₀ + 1) (max (k * (max D₀ P * 2 ^ k)) 1) M'_b` + and admits a concrete `ReplacementDesign`. -/ +theorem CNF.exists_greedy_parityRowSystem_branch_schedule {β : ℕ} (hβ : 1 ≤ β) : + ∃ n₀ : ℕ, 20 ≤ n₀ ∧ + ∀ {V : Type*} [Fintype V] [DecidableEq V] + (φ : CNF V) {k B : ℕ}, + (∀ c ∈ φ, c.length ≤ k) → + 1 ≤ Fintype.card V → + 1 ≤ B → + φ.length ≤ B * Fintype.card V → + let D₀ := CNF.initialRowWeightBound B φ.length + let P := CNF.greedyRowListLength B φ.length + ∃ A₀ : List (Fin φ.length → Bool), A₀.length ≤ 3 * Fintype.card V ∧ + (∀ r ∈ A₀, weight r ≤ D₀) ∧ + ∀ (A : ℕ → List (Fin φ.length → Bool)) + (γ : ℕ → Fin P → Fin φ.length × Bool), + A 0 = A₀ → (∀ i, A (i + 1) = A i ++ [testRow (γ i)]) → + (∀ i (γ' : Fin P → Fin φ.length × Bool), + commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow (γ i)])) ≤ + commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow γ']))) → + commonZeroCount univ (φ.parityRowSystem (A (3 * Fintype.card V))) = + φ.modelCountOn Finset.univ ∧ + ∀ i ≤ 3 * Fintype.card V, + (A i).length ≤ 6 * Fintype.card V ∧ + ∀ ⦃n' b₀ : ℕ⦄ + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) b₀) ≃ Fin n'), + n₀ ≤ n' → + b₀ + 1 ≤ Nat.clog 2 n' ^ β → + max (k * (max D₀ P * 2 ^ k)) 1 ≤ Nat.clog 2 n' ^ β → + ∀ b : V → Bool, + Feasible β n' (b₀ + 1) (max (k * (max D₀ P * 2 ^ k)) 1) + (∑ f : {j : Fin (A i).length // + j ∈ (univ : Finset (Fin (A i).length))} ⊕ Fin n', + #(branchAugmentedScope + (heavyVars univ (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) b₀) + e univ (φ.parityRowSystem (A i)) b f)) ∧ + Nonempty + (ReplacementDesign + (branchAugmentedScope + (heavyVars univ (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) b₀) + e univ (φ.parityRowSystem (A i)) b) + (numNodes n') (numGroups n') (intervalStart β n') + (rowBound β n') (tauRat n')) := by + obtain ⟨n₀, hn₀20, hsched⟩ := exists_branch_schedule_replacementDesign hβ + refine ⟨n₀, hn₀20, fun {V _ _} φ {k B} hk hn hB hm => ?_⟩ + intro D₀ P + obtain ⟨A₀, hlen0, hw0, hgreedy⟩ := φ.exists_initialTests_commonZeroCount_greedy hk hn hB hm + refine ⟨A₀, hlen0, hw0, fun A γ h0 hA hγ => ?_⟩ + obtain ⟨hcount, hstage⟩ := hgreedy A γ h0 hA hγ + refine ⟨hcount, fun i hi => ?_⟩ + obtain ⟨hlen_i, hscope_i⟩ := hstage i hi + refine ⟨hlen_i, fun {n' b₀} e hn' hb₀ hw_pow b => ?_⟩ + exact hsched univ univ (φ.parityRowSystem (A i)) (Subset.refl _) e hn' hb₀ hw_pow + (fun j _ => (hscope_i j).2.2) b + +/-! ### 4. Unconditional polylogarithmic schedule discharge for `B ≤ C_B * (Nat.clog 2 n) ^ β_B` -/ + +private theorem clog_two_le_two_mul_of_le_two_mul {n n' : ℕ} (hn : n ≤ 2 * n') (hn' : 2 ≤ n') : + Nat.clog 2 n ≤ 2 * Nat.clog 2 n' := by + have h1 : 1 ≤ Nat.clog 2 n' := + (Nat.lt_clog_iff_pow_lt one_lt_two).mpr (by omega : 2 ^ 0 < n') + have h2 : n ≤ 2 ^ (Nat.clog 2 n' + 1) := by + calc n ≤ 2 * n' := hn + _ ≤ 2 * 2 ^ Nat.clog 2 n' := Nat.mul_le_mul_left 2 (Nat.le_pow_clog one_lt_two n') + _ = 2 ^ (Nat.clog 2 n' + 1) := (pow_succ' 2 _).symm + have h3 : Nat.clog 2 n ≤ Nat.clog 2 n' + 1 := + (Nat.clog_le_iff_le_pow one_lt_two).mpr h2 + omega + +/-- Coefficient for the polynomial bound on `CNF.initialRowWeightBound B m` when +`B ≤ C_B * (Nat.clog 2 n) ^ β_B` and `m ≤ B * n`. -/ +def CNF.initialRowWeightCoeff (C_B β_B : ℕ) : ℕ := + 320000 * C_B ^ 2 * (C_B + β_B + 2) ^ 3 + +/-- **Section 6.1 & 6.3 ($D_0 \le C \cdot (\lceil \log_2 n \rceil)^{2\beta_B + 3}$):** +when `2 ≤ n`, `m ≤ B * n`, and `B ≤ C_B * (Nat.clog 2 n) ^ β_B`, the initial parity-row weight bound +`CNF.initialRowWeightBound B m` is at most +`CNF.initialRowWeightCoeff C_B β_B * (Nat.clog 2 n) ^ (2 * β_B + 3)`. -/ +theorem CNF.initialRowWeightBound_le_mul_pow_clog {n m B C_B β_B : ℕ} + (hn : 2 ≤ n) (hm : m ≤ B * n) (hB : B ≤ C_B * Nat.clog 2 n ^ β_B) : + CNF.initialRowWeightBound B m ≤ + CNF.initialRowWeightCoeff C_B β_B * Nat.clog 2 n ^ (2 * β_B + 3) := by + set lam := Nat.clog 2 n + have hlam1 : 1 ≤ lam := + (Nat.lt_clog_iff_pow_lt one_lt_two).mpr (by omega : 2 ^ 0 < n) + have hn_pow : n ≤ 2 ^ lam := Nat.le_pow_clog one_lt_two n + have hlam_pow : lam ^ β_B ≤ 2 ^ (lam * β_B) := by + calc lam ^ β_B ≤ (2 ^ lam) ^ β_B := Nat.pow_le_pow_left lam.lt_two_pow_self.le β_B + _ = 2 ^ (lam * β_B) := (pow_mul 2 lam β_B).symm + have hCB_pow : C_B ≤ 2 ^ (C_B * lam) := by + calc C_B ≤ 2 ^ C_B := C_B.lt_two_pow_self.le + _ ≤ 2 ^ (C_B * lam) := Nat.pow_le_pow_right two_pos (Nat.le_mul_of_pos_right C_B hlam1) + have hm_pow : m ≤ 2 ^ ((C_B + β_B + 1) * lam) := by + calc m ≤ B * n := hm + _ ≤ C_B * lam ^ β_B * n := Nat.mul_le_mul_right n hB + _ ≤ 2 ^ (C_B * lam) * 2 ^ (lam * β_B) * 2 ^ lam := + Nat.mul_le_mul (Nat.mul_le_mul hCB_pow hlam_pow) hn_pow + _ = 2 ^ ((C_B + β_B + 1) * lam) := by rw [← pow_add, ← pow_add]; ring_nf + have hlog : Nat.log 2 m + 1 ≤ (C_B + β_B + 2) * lam := by + have hlog_le : Nat.log 2 m ≤ (C_B + β_B + 1) * lam := by + calc Nat.log 2 m ≤ Nat.log 2 (2 ^ ((C_B + β_B + 1) * lam)) := Nat.log_mono_right hm_pow + _ = (C_B + β_B + 1) * lam := Nat.log_pow one_lt_two _ + nlinarith + have hB2 : B ^ 2 ≤ C_B ^ 2 * lam ^ (2 * β_B) := by + calc B ^ 2 ≤ (C_B * lam ^ β_B) ^ 2 := Nat.pow_le_pow_left hB 2 + _ = C_B ^ 2 * lam ^ (2 * β_B) := by rw [mul_pow, ← pow_mul]; ring + have hlog3 : (Nat.log 2 m + 1) ^ 3 ≤ (C_B + β_B + 2) ^ 3 * lam ^ 3 := by + calc (Nat.log 2 m + 1) ^ 3 ≤ ((C_B + β_B + 2) * lam) ^ 3 := Nat.pow_le_pow_left hlog 3 + _ = (C_B + β_B + 2) ^ 3 * lam ^ 3 := mul_pow _ _ 3 + unfold CNF.initialRowWeightBound CNF.initialRowWeightCoeff + calc 320000 * B ^ 2 * (Nat.log 2 m + 1) ^ 3 + ≤ 320000 * (C_B ^ 2 * lam ^ (2 * β_B)) * ((C_B + β_B + 2) ^ 3 * lam ^ 3) := + Nat.mul_le_mul (Nat.mul_le_mul_left 320000 hB2) hlog3 + _ = 320000 * C_B ^ 2 * (C_B + β_B + 2) ^ 3 * lam ^ (2 * β_B + 3) := by + rw [pow_add]; ring + +/-- Canonical Section 5.5 & 6.3 heavy-variable branching threshold +`b₀ = (6 * (k * (W * 2 ^ k))) * (Nat.clog 2 n).sqrt + 1` for a width-`≤ k` CNF with row-weight +bound `W` on `n` variables. -/ +def CNF.parityBranchThreshold (k W n : ℕ) : ℕ := + (6 * (k * (W * 2 ^ k))) * (Nat.clog 2 n).sqrt + 1 + +/-- Schedule coefficient bounding `CNF.parityBranchThreshold k W n + 1` and +`max (k * (W * 2 ^ k)) 1` against `(Nat.clog 2 n') ^ (2 * β_B + 4)` when `n ≤ 2 * n'`. -/ +def CNF.parityScheduleCoeff (k C_B β_B : ℕ) : ℕ := + (6 * k * 2 ^ k * CNF.initialRowWeightCoeff C_B β_B + 2) * 2 ^ (2 * β_B + 4) + +private theorem parityBranchThreshold_succ_and_width_le_clog_pow {n n' m B W k C_B β_B : ℕ} + (hn : 2 ≤ n) (hn_le : n ≤ 2 * n') (hn' : 2 ≤ n') + (hm : m ≤ B * n) (hB : B ≤ C_B * Nat.clog 2 n ^ β_B) + (hW : W ≤ CNF.initialRowWeightBound B m) + (hcoeff : CNF.parityScheduleCoeff k C_B β_B ≤ Nat.clog 2 n') : + CNF.parityBranchThreshold k W n + 1 ≤ Nat.clog 2 n' ^ (2 * β_B + 5) ∧ + max (k * (W * 2 ^ k)) 1 ≤ Nat.clog 2 n' ^ (2 * β_B + 5) := by + set lam := Nat.clog 2 n + set lam' := Nat.clog 2 n' + have hlam1 : 1 ≤ lam := + (Nat.lt_clog_iff_pow_lt one_lt_two).mpr (by omega : 2 ^ 0 < n) + have hsqrt1 : 1 ≤ lam.sqrt := Nat.le_sqrt.mpr (by omega) + have hmax_le : max (k * (W * 2 ^ k)) 1 ≤ CNF.parityBranchThreshold k W n + 1 := by + unfold CNF.parityBranchThreshold + have hmul : k * (W * 2 ^ k) ≤ (6 * (k * (W * 2 ^ k))) * (Nat.clog 2 n).sqrt := by + calc k * (W * 2 ^ k) = (k * (W * 2 ^ k)) * 1 := (mul_one _).symm + _ ≤ (6 * (k * (W * 2 ^ k))) * (Nat.clog 2 n).sqrt := + Nat.mul_le_mul (Nat.le_mul_of_pos_left _ (by decide)) hsqrt1 + omega + have hW_le : W ≤ CNF.initialRowWeightCoeff C_B β_B * lam ^ (2 * β_B + 3) := + hW.trans (CNF.initialRowWeightBound_le_mul_pow_clog hn hm hB) + have hterm : + (6 * (k * (W * 2 ^ k))) * lam.sqrt ≤ + (6 * k * 2 ^ k * CNF.initialRowWeightCoeff C_B β_B) * lam ^ (2 * β_B + 4) := by + calc (6 * (k * (W * 2 ^ k))) * lam.sqrt + = (6 * k * 2 ^ k) * W * lam.sqrt := by ring + _ ≤ (6 * k * 2 ^ k) * (CNF.initialRowWeightCoeff C_B β_B * lam ^ (2 * β_B + 3)) * lam := + Nat.mul_le_mul (Nat.mul_le_mul_left _ hW_le) (Nat.sqrt_le_self lam) + _ = (6 * k * 2 ^ k * CNF.initialRowWeightCoeff C_B β_B) * lam ^ (2 * β_B + 4) := by + rw [pow_succ]; ring + have h1_pow : 1 ≤ lam ^ (2 * β_B + 4) := Nat.one_le_pow _ lam hlam1 + have hthresh_lam : + CNF.parityBranchThreshold k W n + 1 ≤ + (6 * k * 2 ^ k * CNF.initialRowWeightCoeff C_B β_B + 2) * lam ^ (2 * β_B + 4) := by + unfold CNF.parityBranchThreshold + calc (6 * (k * (W * 2 ^ k))) * lam.sqrt + 1 + 1 + ≤ (6 * k * 2 ^ k * CNF.initialRowWeightCoeff C_B β_B) * lam ^ (2 * β_B + 4) + + 2 * lam ^ (2 * β_B + 4) := by linarith + _ = (6 * k * 2 ^ k * CNF.initialRowWeightCoeff C_B β_B + 2) * lam ^ (2 * β_B + 4) := by + ring + have hlam_pow : lam ^ (2 * β_B + 4) ≤ 2 ^ (2 * β_B + 4) * lam' ^ (2 * β_B + 4) := by + calc lam ^ (2 * β_B + 4) ≤ (2 * lam') ^ (2 * β_B + 4) := + Nat.pow_le_pow_left (clog_two_le_two_mul_of_le_two_mul hn_le hn') _ + _ = 2 ^ (2 * β_B + 4) * lam' ^ (2 * β_B + 4) := mul_pow 2 lam' _ + have hthresh_lam' : + CNF.parityBranchThreshold k W n + 1 ≤ Nat.clog 2 n' ^ (2 * β_B + 5) := by + calc CNF.parityBranchThreshold k W n + 1 + ≤ (6 * k * 2 ^ k * CNF.initialRowWeightCoeff C_B β_B + 2) * + (2 ^ (2 * β_B + 4) * lam' ^ (2 * β_B + 4)) := + hthresh_lam.trans (Nat.mul_le_mul_left _ hlam_pow) + _ = CNF.parityScheduleCoeff k C_B β_B * lam' ^ (2 * β_B + 4) := by + unfold CNF.parityScheduleCoeff; ring + _ ≤ lam' * lam' ^ (2 * β_B + 4) := Nat.mul_le_mul_right _ hcoeff + _ = lam' ^ (2 * β_B + 5) := (pow_succ' lam' (2 * β_B + 4)).symm + exact ⟨hthresh_lam', hmax_le.trans hthresh_lam'⟩ + +/-- **Unconditional Section 6.3 branch-schedule feasibility and `ReplacementDesign` existence for +`CNF.parityRowSystem` with `B ≤ C_B * (Nat.clog 2 n) ^ β_B`**: +For any `k C_B β_B : ℕ`, there exists an explicit threshold `N₀ ≥ 20` such that for any width-`≤ k` +CNF `φ : CNF V` with `N₀ ≤ Fintype.card V`, `φ.length ≤ B * Fintype.card V`, and +`B ≤ C_B * (Nat.clog 2 (Fintype.card V)) ^ β_B`, and any parity-row list +`rows : List (Fin φ.length → Bool)` with `rows.length ≤ 6 * Fintype.card V`, +`∀ r ∈ rows, weight r ≤ W`, and `W ≤ CNF.initialRowWeightBound B φ.length`, at the canonical +threshold `b₀ = CNF.parityBranchThreshold k W (Fintype.card V)` and exponent `β = 2 * β_B + 5`: +1. `2 ≤ (Nat.clog 2 (Fintype.card V)).sqrt`, +2. `Fintype.card V ≤ 2 * n'` and `Fintype.card V / 2 ≤ n'`, +3. `#(branchAssignments S) ≤ 2 ^ (Fintype.card V / (Nat.clog 2 (Fintype.card V)).sqrt)`, and +4. **every** branch `b : V → Bool` unconditionally satisfies `Feasible (2 * β_B + 5) n' (b₀ + 1)` + `(max (k * (W * 2 ^ k)) 1) M'_b` and admits a concrete `ReplacementDesign`. -/ +theorem CNF.exists_branch_schedule_parityRowSystem_of_le_clog_pow (k C_B β_B : ℕ) : + ∃ N₀ : ℕ, 20 ≤ N₀ ∧ + ∀ {V : Type*} [Fintype V] [DecidableEq V] + {φ : CNF V} ⦃n' B W : ℕ⦄, + (∀ c ∈ φ, c.length ≤ k) → + N₀ ≤ Fintype.card V → + φ.length ≤ B * Fintype.card V → + B ≤ C_B * Nat.clog 2 (Fintype.card V) ^ β_B → + W ≤ CNF.initialRowWeightBound B φ.length → + ∀ {rows : List (Fin φ.length → Bool)}, + (∀ r ∈ rows, weight r ≤ W) → + rows.length ≤ 6 * Fintype.card V → + let b₀ := CNF.parityBranchThreshold k W (Fintype.card V) + ∀ (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n'), + 2 ≤ (Nat.clog 2 (Fintype.card V)).sqrt ∧ + (Fintype.card V ≤ 2 * n' ∧ Fintype.card V / 2 ≤ n') ∧ + #(branchAssignments + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀)) ≤ + 2 ^ (Fintype.card V / (Nat.clog 2 (Fintype.card V)).sqrt) ∧ + ∀ b : V → Bool, + Feasible (2 * β_B + 5) n' (b₀ + 1) (max (k * (W * 2 ^ k)) 1) + (∑ f : {j : Fin rows.length // j ∈ (univ : Finset (Fin rows.length))} ⊕ Fin n', + #(branchAugmentedScope + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) + e univ (φ.parityRowSystem rows) b f)) ∧ + Nonempty + (ReplacementDesign + (branchAugmentedScope + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) + e univ (φ.parityRowSystem rows) b) + (numNodes n') (numGroups n') (intervalStart (2 * β_B + 5) n') + (rowBound (2 * β_B + 5) n') (tauRat n')) := by + obtain ⟨n₀, hn₀20, hsched⟩ := + CNF.exists_branch_schedule_parityRowSystem (β := 2 * β_B + 5) (by omega) + set C := CNF.parityScheduleCoeff k C_B β_B + refine ⟨max (2 * n₀) (2 ^ (C + 1)), by omega, + fun {V _ _ φ n' B W} hk hN₀ hm hB hW_bound {rows} hW hlen => ?_⟩ + intro b₀ e + have hn20 : 20 ≤ Fintype.card V := by + have : 2 * n₀ ≤ Fintype.card V := (le_max_left _ _).trans hN₀ + omega + have hsqrt : 2 ≤ (Nat.clog 2 (Fintype.card V)).sqrt := by + refine Nat.le_sqrt.mpr ?_ + have h4 : 2 ^ 3 < Fintype.card V := by omega + have hclog : 3 < Nat.clog 2 (Fintype.card V) := (Nat.lt_clog_iff_pow_lt one_lt_two).mpr h4 + omega + have hb₀_pos : 1 ≤ b₀ := Nat.succ_pos _ + have hthresh : (6 * (k * (W * 2 ^ k))) * (Nat.clog 2 (Fintype.card V)).sqrt ≤ b₀ := + Nat.le_succ _ + obtain ⟨⟨hn_le, hn_div⟩, hbranches⟩ := + CNF.card_le_two_mul_freeVar_parityRowSystem hk hW hlen hb₀_pos hsqrt hthresh e + have hn₀_le : n₀ ≤ n' := by + have : 2 * n₀ ≤ Fintype.card V := (le_max_left _ _).trans hN₀ + omega + have hcoeff : C ≤ Nat.clog 2 n' := by + have hpow : 2 ^ (C + 1) ≤ 2 * n' := ((le_max_right _ _).trans hN₀).trans hn_le + have hpow' : 2 ^ C ≤ n' := by rw [pow_succ'] at hpow; omega + exact (Nat.clog_pow 2 C one_lt_two).symm.le.trans (Nat.clog_mono_right 2 hpow') + obtain ⟨hb₀_pow, hw_pow⟩ := + parityBranchThreshold_succ_and_width_le_clog_pow (by omega) hn_le (by omega) hm hB hW_bound + hcoeff + exact ⟨hsqrt, ⟨hn_le, hn_div⟩, hbranches, + fun b => hsched hk hW e hn₀_le hb₀_pow hw_pow b⟩ + +/-- **Unconditional Section 6.3 greedy parity-test schedule theorem for +`B ≤ C_B * (Nat.clog 2 n) ^ β_B`**: +For any `k C_B β_B : ℕ`, there exists `N₀ ≥ 20` such that for any width-`≤ k` CNF `φ : CNF V` with +`N₀ ≤ Fintype.card V`, `1 ≤ B ≤ C_B * (Nat.clog 2 (Fintype.card V)) ^ β_B`, and +`φ.length ≤ B * Fintype.card V`, there exist initial parity rows `A₀` (`A₀.length ≤ 3 * n`, each of +weight at most `D₀ = CNF.initialRowWeightBound B φ.length`) such that for any `3 * n`-step greedy +sequence `A (i + 1) = A i ++ [testRow (γ i)]` with `A 0 = A₀` minimizing `commonZeroCount`: +1. `commonZeroCount univ (φ.parityRowSystem (A (3 * Fintype.card V))) = φ.modelCountOn Finset.univ`. +2. At every stage `i ≤ 3 * Fintype.card V`, `(A i).length ≤ 6 * Fintype.card V`, and at the + canonical threshold `b₀ = CNF.parityBranchThreshold k D₀ (Fintype.card V)`: + - `Fintype.card V ≤ 2 * n'` and `Fintype.card V / 2 ≤ n'`, + - `#(branchAssignments S_i) ≤ 2 ^ (Fintype.card V / (Nat.clog 2 (Fintype.card V)).sqrt)`, and + - **every** branch `b : V → Bool` unconditionally satisfies + `Feasible (2 * β_B + 5) n' (b₀ + 1) (max (k * (D₀ * 2 ^ k)) 1) M'_b` and admits a concrete + `ReplacementDesign`. -/ +theorem CNF.exists_greedy_parityRowSystem_branch_schedule_of_le_clog_pow (k C_B β_B : ℕ) : + ∃ N₀ : ℕ, 20 ≤ N₀ ∧ + ∀ {V : Type*} [Fintype V] [DecidableEq V] + (φ : CNF V) {B : ℕ}, + (∀ c ∈ φ, c.length ≤ k) → + N₀ ≤ Fintype.card V → + 1 ≤ B → + B ≤ C_B * Nat.clog 2 (Fintype.card V) ^ β_B → + φ.length ≤ B * Fintype.card V → + let D₀ := CNF.initialRowWeightBound B φ.length + let P := CNF.greedyRowListLength B φ.length + let b₀ := CNF.parityBranchThreshold k D₀ (Fintype.card V) + ∃ A₀ : List (Fin φ.length → Bool), A₀.length ≤ 3 * Fintype.card V ∧ + (∀ r ∈ A₀, weight r ≤ D₀) ∧ + ∀ (A : ℕ → List (Fin φ.length → Bool)) + (γ : ℕ → Fin P → Fin φ.length × Bool), + A 0 = A₀ → (∀ i, A (i + 1) = A i ++ [testRow (γ i)]) → + (∀ i (γ' : Fin P → Fin φ.length × Bool), + commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow (γ i)])) ≤ + commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow γ']))) → + commonZeroCount univ (φ.parityRowSystem (A (3 * Fintype.card V))) = + φ.modelCountOn Finset.univ ∧ + ∀ i ≤ 3 * Fintype.card V, + (A i).length ≤ 6 * Fintype.card V ∧ + ∀ ⦃n' : ℕ⦄ + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) b₀) ≃ Fin n'), + (Fintype.card V ≤ 2 * n' ∧ Fintype.card V / 2 ≤ n') ∧ + #(branchAssignments + (heavyVars univ (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) b₀)) ≤ + 2 ^ (Fintype.card V / (Nat.clog 2 (Fintype.card V)).sqrt) ∧ + ∀ b : V → Bool, + Feasible (2 * β_B + 5) n' (b₀ + 1) (max (k * (D₀ * 2 ^ k)) 1) + (∑ f : {j : Fin (A i).length // + j ∈ (univ : Finset (Fin (A i).length))} ⊕ Fin n', + #(branchAugmentedScope + (heavyVars univ (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) b₀) + e univ (φ.parityRowSystem (A i)) b f)) ∧ + Nonempty + (ReplacementDesign + (branchAugmentedScope + (heavyVars univ (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) b₀) + e univ (φ.parityRowSystem (A i)) b) + (numNodes n') (numGroups n') (intervalStart (2 * β_B + 5) n') + (rowBound (2 * β_B + 5) n') (tauRat n')) := by + obtain ⟨n₀, hn₀20, hsched⟩ := + exists_branch_schedule_replacementDesign (β := 2 * β_B + 5) (by omega) + set C := CNF.parityScheduleCoeff k C_B β_B + refine ⟨max (2 * n₀) (2 ^ (C + 1)), by omega, + fun {V _ _} φ {B} hk hN₀ hB1 hB_le hm => ?_⟩ + intro D₀ P b₀ + obtain ⟨A₀, hlen0, hw0, hgreedy⟩ := + φ.exists_initialTests_commonZeroCount_greedy hk (by omega) hB1 hm + refine ⟨A₀, hlen0, hw0, fun A γ h0 hA hγ => ?_⟩ + obtain ⟨hcount, hstage⟩ := hgreedy A γ h0 hA hγ + refine ⟨hcount, fun i hi => ?_⟩ + obtain ⟨hlen_i, hscope_i⟩ := hstage i hi + refine ⟨hlen_i, fun {n'} e => ?_⟩ + have hscope_D₀ : ∀ j : Fin (A i).length, + #(equationScope (φ.parityRowSystem (A i) j)) ≤ k * (D₀ * 2 ^ k) := fun j => by + simpa only [D₀, P, max_initialRowWeightBound_greedyRowListLength] using (hscope_i j).2.2 + have hn20 : 20 ≤ Fintype.card V := by + have : 2 * n₀ ≤ Fintype.card V := (le_max_left _ _).trans hN₀ + omega + have hsqrt : 2 ≤ (Nat.clog 2 (Fintype.card V)).sqrt := by + refine Nat.le_sqrt.mpr ?_ + have h4 : 2 ^ 3 < Fintype.card V := by omega + have hclog : 3 < Nat.clog 2 (Fintype.card V) := (Nat.lt_clog_iff_pow_lt one_lt_two).mpr h4 + omega + have hM_le : + totalIncidence (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) * + (Nat.clog 2 (Fintype.card V)).sqrt ≤ + b₀ * Fintype.card V := by + have htot : + totalIncidence (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) ≤ + (6 * (k * (D₀ * 2 ^ k))) * Fintype.card V := by + calc totalIncidence (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) + ≤ ∑ _j ∈ (univ : Finset (Fin (A i).length)), (k * (D₀ * 2 ^ k)) := + sum_le_sum fun j _ => hscope_D₀ j + _ = (A i).length * (k * (D₀ * 2 ^ k)) := by + simp only [sum_const, card_univ, Fintype.card_fin, smul_eq_mul] + _ ≤ (6 * Fintype.card V) * (k * (D₀ * 2 ^ k)) := Nat.mul_le_mul_right _ hlen_i + _ = (6 * (k * (D₀ * 2 ^ k))) * Fintype.card V := by ring + calc totalIncidence (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) * + (Nat.clog 2 (Fintype.card V)).sqrt + ≤ ((6 * (k * (D₀ * 2 ^ k))) * Fintype.card V) * + (Nat.clog 2 (Fintype.card V)).sqrt := Nat.mul_le_mul_right _ htot + _ = ((6 * (k * (D₀ * 2 ^ k))) * (Nat.clog 2 (Fintype.card V)).sqrt) * + Fintype.card V := by ring + _ ≤ b₀ * Fintype.card V := Nat.mul_le_mul_right _ (Nat.le_succ _) + have hb₀_pos : 1 ≤ b₀ := Nat.succ_pos _ + have hcard : Fintype.card V ≤ 2 * n' ∧ Fintype.card V / 2 ≤ n' := + card_le_two_mul_freeVar_of_heavyVars univ + (fun j => equationScope (φ.parityRowSystem (A i) j)) hb₀_pos hsqrt hM_le e + have hbr : + #(branchAssignments + (heavyVars univ (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) b₀)) ≤ + 2 ^ (Fintype.card V / (Nat.clog 2 (Fintype.card V)).sqrt) := + card_branchAssignments_heavyVars_le_two_pow_div univ + (fun j => equationScope (φ.parityRowSystem (A i) j)) hb₀_pos (by omega) hM_le + have hn₀_le : n₀ ≤ n' := by + have : 2 * n₀ ≤ Fintype.card V := (le_max_left _ _).trans hN₀ + omega + have hcoeff : C ≤ Nat.clog 2 n' := by + have hpow : 2 ^ (C + 1) ≤ 2 * n' := ((le_max_right _ _).trans hN₀).trans hcard.1 + have hpow' : 2 ^ C ≤ n' := by rw [pow_succ'] at hpow; omega + exact (Nat.clog_pow 2 C one_lt_two).symm.le.trans (Nat.clog_mono_right 2 hpow') + obtain ⟨hb₀_pow, hw_pow⟩ := + parityBranchThreshold_succ_and_width_le_clog_pow (by omega) hcard.1 (by omega) hm hB_le + le_rfl hcoeff + refine ⟨hcard, hbr, fun b => ?_⟩ + exact hsched univ univ (φ.parityRowSystem (A i)) (Subset.refl _) e hn₀_le hb₀_pow hw_pow + (fun j _ => hscope_D₀ j) b + +end Cslib.Logic.PL diff --git a/ComplexityTests/Computability/Complexity/FineGrained/SparseParitySchedule.lean b/ComplexityTests/Computability/Complexity/FineGrained/SparseParitySchedule.lean new file mode 100644 index 0000000000..382d82aa4c --- /dev/null +++ b/ComplexityTests/Computability/Complexity/FineGrained/SparseParitySchedule.lean @@ -0,0 +1,279 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Computability.Complexity.FineGrained.SparseParitySchedule +import Mathlib.Tactic.NormNum +import Mathlib.Tactic.Positivity + +/-! +# Tests for `Complexity.Computability.Complexity.FineGrained.SparseParitySchedule` + +Concrete expected-value checks on a 2-variable 2-CNF formula `testCNF` (`(x₀ ∨ ¬x₁) ∧ (x₁)`) for +`CNF.totalIncidence_parityRowSystem_le_six_mul`, `CNF.card_le_two_mul_freeVar_parityRowSystem`, +`CNF.card_branchAugmentedScope_parityRowSystem_le`, and +`CNF.sum_branch_domainExaminationBound_parityRowSystem_le`, together with a nonvacuous witness at +`n = 2 ^ (2 ^ 50)` instantiating `CNF.exists_branch_replacementDesign_parityRowSystem` and +`CNF.branch_domainExaminationBound_parityRowSystem_le`. +-/ + +@[expose] public noncomputable section + +namespace Cslib.Complexity.SubexponentialSAT.SparseParityScheduleTests + +open Finset +open scoped BigOperators +open Cslib.BitString Cslib.LinearAlgebra Cslib.ReplacementCounting Cslib.Logic.PL +open Cslib.Complexity.SubexponentialSAT.ReplacementParams + +/-- Concrete 2-variable 2-CNF formula `(x₀ ∨ ¬x₁) ∧ (x₁)` on `Fin 2`. -/ +def testCNF : CNF (Fin 2) := + [[(0, true), (1, false)], [(1, true)]] + +/-- Concrete two-row unit parity check matrix selecting clause `0` and clause `1` of `testCNF`. -/ +def testRows : List (Fin testCNF.length → Bool) := + [Pi.single ⟨0, by decide⟩ true, Pi.single ⟨1, by decide⟩ true] + +/-- Concrete check of `CNF.totalIncidence_parityRowSystem_le_six_mul` on `testCNF` and `testRows` +(`k = 2`, `W = 1`, `Fintype.card (Fin 2) = 2`): +`totalIncidence ≤ (6 * (2 * (1 * 2 ^ 2))) * 2 = 96`. -/ +example : + totalIncidence (univ : Finset (Fin testRows.length)) + (fun j => equationScope (testCNF.parityRowSystem testRows j)) ≤ + (6 * (2 * (1 * 2 ^ 2))) * Fintype.card (Fin 2) := + testCNF.totalIncidence_parityRowSystem_le_six_mul (k := 2) (W := 1) + (by decide) (by decide) (by decide) + +/-- At threshold `b₀ = 96` (`s_div = 2`), `heavyVars` on `testCNF.parityRowSystem testRows` is +empty, so `n' = 2`. -/ +def testEquiv96 : + ↥((univ : Finset (Fin 2)) \ + heavyVars univ (univ : Finset (Fin testRows.length)) + (fun j => equationScope (testCNF.parityRowSystem testRows j)) 96) ≃ Fin 2 where + toFun v := v.1 + invFun v := ⟨v, by decide +revert⟩ + left_inv v := by ext; rfl + right_inv v := rfl + +/-- Concrete check of `CNF.card_le_two_mul_freeVar_parityRowSystem`, +`CNF.card_branchAugmentedScope_parityRowSystem_le`, and +`CNF.sum_branch_domainExaminationBound_parityRowSystem_le` on `testCNF` and `testRows`. -/ +example (b : Fin 2 → Bool) + (f : {j : Fin testRows.length // j ∈ (univ : Finset (Fin testRows.length))} ⊕ Fin 2) : + let S := heavyVars univ (univ : Finset (Fin testRows.length)) + (fun j => equationScope (testCNF.parityRowSystem testRows j)) 96 + (Fintype.card (Fin 2) ≤ 2 * 2 ∧ Fintype.card (Fin 2) / 2 ≤ 2) ∧ + #(branchAssignments S) ≤ 2 ^ (Fintype.card (Fin 2) / 2) ∧ + #(branchAugmentedScope S testEquiv96 univ (testCNF.parityRowSystem testRows) b f) ≤ + max (2 * (1 * 2 ^ 2)) 1 ∧ + (∑ _b ∈ branchAssignments S, (0 : ℝ)) ≤ + (2 : ℝ) ^ (Fintype.card (Fin 2) / 2) * + (2 * (numNodes 2 : ℝ) * (numGroups 2 : ℝ) * + Real.exp (((16 * 2 + 4 : ℕ) : ℝ) * (2 : ℝ) * rowCost 1 2)) := by + intro S + have hfree := testCNF.card_le_two_mul_freeVar_parityRowSystem (k := 2) (W := 1) (b₀ := 96) + (s_div := 2) (by decide) (by decide) (by decide) (by decide) (by decide) (by decide) + testEquiv96 + have hscope := testCNF.card_branchAugmentedScope_parityRowSystem_le (k := 2) (W := 1) + (by decide) (by decide) S testEquiv96 b f + have hsum := testCNF.sum_branch_domainExaminationBound_parityRowSystem_le + (β := 1) (k := 2) (W := 1) (b₀ := 96) (s_div := 2) + (by decide) (by decide) (by decide) (by decide) (by decide) (by decide) + testEquiv96 (fun _ => 0) (fun _ _ => by positivity) + exact ⟨hfree.1, hfree.2, hscope, hsum.2⟩ + +/-- Nonvacuous concrete witness at `n = 2 ^ (2 ^ 50)` for an empty 3-CNF `emptyCNF n : CNF (Fin n)` +and empty parity-row list `[]`, instantiating `CNF.exists_branch_replacementDesign_parityRowSystem` +and `CNF.branch_domainExaminationBound_parityRowSystem_le`. -/ +def emptyCNF (n : ℕ) : CNF (Fin n) := + [] + +theorem heavyVars_emptyCNF_eq_empty (n b₀ : ℕ) : + heavyVars (univ : Finset (Fin n)) (univ : Finset (Fin ([] : List (Fin 0 → Bool)).length)) + (fun j => equationScope ((emptyCNF n).parityRowSystem [] j)) b₀ = ∅ := by + ext v + simp [heavyVars, varIncidence] + +def emptyCNFEquiv (n b₀ : ℕ) : + ↥((univ : Finset (Fin n)) \ + heavyVars (univ : Finset (Fin n)) (univ : Finset (Fin ([] : List (Fin 0 → Bool)).length)) + (fun j => equationScope ((emptyCNF n).parityRowSystem [] j)) b₀) ≃ Fin n where + toFun v := v.1 + invFun v := ⟨v, by rw [heavyVars_emptyCNF_eq_empty]; simp⟩ + left_inv v := by ext; rfl + right_inv v := rfl + +example : + ∃ m n : ℕ, + m = 2 ^ 50 ∧ + n = 2 ^ m ∧ + rowCost 1 n < 1 / 3 ∧ + ∀ b : Fin n → Bool, + ∃ (hF : Feasible 1 n (1 + 1) (max (3 * (0 * 2 ^ 3)) 1) + (∑ f : {j : Fin ([] : List (Fin (emptyCNF n).length → Bool)).length // + j ∈ (univ : Finset (Fin ([] : List (Fin (emptyCNF n).length → Bool)).length))} ⊕ + Fin n, + #(branchAugmentedScope + (heavyVars (univ : Finset (Fin n)) + (univ : Finset (Fin ([] : List (Fin (emptyCNF n).length → Bool)).length)) + (fun j => equationScope ((emptyCNF n).parityRowSystem [] j)) 1) + (emptyCNFEquiv n 1) univ ((emptyCNF n).parityRowSystem []) b f))) + (D : ReplacementDesign + (branchAugmentedScope + (heavyVars (univ : Finset (Fin n)) + (univ : Finset (Fin ([] : List (Fin (emptyCNF n).length → Bool)).length)) + (fun j => equationScope ((emptyCNF n).parityRowSystem [] j)) 1) + (emptyCNFEquiv n 1) univ ((emptyCNF n).parityRowSystem []) b) + (numNodes n) (numGroups n) (intervalStart 1 n) (rowBound 1 n) (tauRat n)), + let d := 3 * (([] : List (Fin (emptyCNF n).length → Bool)).length + + 2 * (branchPrecision (Fintype.card (Fin n)) - 1)) + let q := (d * rowBound 1 n) / numNodes n + let C := hF.toCountingDesign D univ + (∑ t : Fin (numNodes n), + (#{p : Finset (Fin n) × Finset (Fin n) | #p.1 ≤ q ∧ p.2 ⊆ p.1} : ℝ) * + (2 * (#(C.measurementBox t) : ℝ) * + ∑ g : Fin (numGroups n), (Fintype.card (C.LocalCube t g) : ℝ))) ≤ + 2 * (numNodes n : ℝ) * (numGroups n : ℝ) * + Real.exp (((16 * 3 + 4 : ℕ) : ℝ) * (n : ℝ) * rowCost 1 n) := by + obtain ⟨m, hm⟩ : ∃ m : ℕ, m = 2 ^ 50 := ⟨2 ^ 50, rfl⟩ + obtain ⟨n, hn⟩ : ∃ n : ℕ, n = 2 ^ m := ⟨2 ^ m, rfl⟩ + have hcl_n : Nat.clog 2 n = 2 ^ 50 := by + rw [hn, Nat.clog_pow 2 m one_lt_two, hm] + have hcl_cl : Nat.clog 2 (Nat.clog 2 n) = 50 := by + rw [hcl_n] + exact Nat.clog_pow 2 50 one_lt_two + have hr_eq : numGroups n = 13421 := by + unfold numGroups + rw [hcl_cl, hcl_n] + have hsq : (2 ^ 50 : ℕ).sqrt = 2 ^ 25 := + le_antisymm (Nat.lt_succ_iff.mp (Nat.sqrt_lt.mpr (by norm_num))) + (Nat.le_sqrt.mpr (by norm_num)) + rw [hsq] + norm_num + have hQ_eq : numNodes n = 175921860444 := by + unfold numNodes + rw [hcl_cl, hcl_n] + norm_num + have hR_eq : rowBound 1 n = 134217728 := by + unfold rowBound + rw [hcl_n] + have hsq : (2 ^ 50 - 1 : ℕ).sqrt = 2 ^ 25 - 1 := + le_antisymm (Nat.lt_succ_iff.mp (Nat.sqrt_lt.mpr (by norm_num))) + (Nat.le_sqrt.mpr (by norm_num)) + simp only [show (2 ^ 50 : ℕ) ≠ 0 by positivity, ↓reduceIte, hsq] + norm_num + have hr : 2 ≤ numGroups n := by rw [hr_eq]; norm_num + have hR : 32 ≤ rowBound 1 n := by rw [hR_eq]; norm_num + have hRQ : 6 * rowBound 1 n ≤ numNodes n := by rw [hR_eq, hQ_eq]; norm_num + have hsub := interval_subset_range (β := 1) hr (by omega) (by omega) + have hrc := rowCost_le hr hR hRQ + have hrc_lt : rowCost 1 n < 1 / 3 := hrc.trans_lt <| by + rw [hcl_cl, hcl_n, show ((2 ^ 50 : ℕ) : ℝ) = ((2 : ℝ) ^ 25) ^ 2 by norm_num, + Real.sqrt_sq (by positivity)] + norm_num + refine ⟨m, n, hm, hn, hrc_lt, fun b => ?_⟩ + let S := heavyVars (univ : Finset (Fin n)) + (univ : Finset (Fin ([] : List (Fin (emptyCNF n).length → Bool)).length)) + (fun j => equationScope ((emptyCNF n).parityRowSystem [] j)) 1 + have hsum_eq : + (∑ f : {j : Fin ([] : List (Fin (emptyCNF n).length → Bool)).length // + j ∈ (univ : Finset (Fin ([] : List (Fin (emptyCNF n).length → Bool)).length))} ⊕ Fin n, + #(branchAugmentedScope S (emptyCNFEquiv n 1) univ + ((emptyCNF n).parityRowSystem []) b f)) = n := by + rw [sum_card_branchAugmentedScope] + simp [totalIncidence] + have hF : Feasible 1 n (1 + 1) (max (3 * (0 * 2 ^ 3)) 1) + (∑ f : {j : Fin ([] : List (Fin (emptyCNF n).length → Bool)).length // + j ∈ (univ : Finset (Fin ([] : List (Fin (emptyCNF n).length → Bool)).length))} ⊕ Fin n, + #(branchAugmentedScope S (emptyCNFEquiv n 1) univ + ((emptyCNF n).parityRowSystem []) b f)) := by + rw [hsum_eq] + exact { + twenty_le := by + rw [hn] + exact (by norm_num : 20 ≤ 2 ^ 5).trans + (Nat.pow_le_pow_right two_pos (by rw [hm]; norm_num)) + two_le_numGroups := hr + thirtyTwo_le_rowBound := hR + six_mul_rowBound_le_numNodes := hRQ + tau_pos := by unfold tau; rw [hr_eq, hcl_n]; positivity + tau_le_half := by unfold tau; rw [hr_eq, hcl_n]; norm_num + auxDim_le := auxDim_le_two_pow n + aux_balance := + (Nat.mul_le_mul (by norm_num : 2 * (1 + 1 + max (3 * (0 * 2 ^ 3)) 1) ≤ 2 ^ 3) + (Nat.pow_le_pow_left (auxDim_le_two_pow n) 2)).trans <| by + rw [← pow_mul, ← pow_add, hn] + exact Nat.pow_le_pow_right two_pos + (by rw [Nat.clog_pow 2 m one_lt_two, hm]; norm_num) + var_balance := by + rw [hQ_eq, hr_eq, hn] + exact (by norm_num : 2 * 175921860444 * 13421 ^ 2 ≤ 2 ^ 66).trans + (Nat.pow_le_pow_right two_pos (by rw [hm]; norm_num)) + card_interval_eq := card_interval (by omega) + interval_subset := hsub + mem_interval_of_close := fun k hk => + ⟨mem_interval_of_abs_sub_le hr hR (by omega) hk, + Nat.lt_succ_iff.mp + (mem_range.mp (hsub (mem_interval_of_abs_sub_le hr hR (by omega) hk)))⟩ + binomTail_lt := + binomTail_lt_tailBudget le_rfl hr hR hRQ (by norm_num) (by rw [hcl_n]; norm_num) + rowCost_bound := hrc + } + have hk : ∀ c ∈ emptyCNF n, c.length ≤ 3 := by simp [emptyCNF] + have hW : ∀ r ∈ ([] : List (Fin (emptyCNF n).length → Bool)), weight r ≤ 0 := by simp + obtain ⟨D⟩ := (emptyCNF n).exists_branch_replacementDesign_parityRowSystem hk hW + (emptyCNFEquiv n 1) b hF + refine ⟨hF, D, ?_⟩ + have hlen : ([] : List (Fin (emptyCNF n).length → Bool)).length ≤ 6 * Fintype.card (Fin n) := by + simp + have hn_card : Fintype.card (Fin n) ≤ 2 * n := by + rw [Fintype.card_fin] + omega + exact ((emptyCNF n).branch_domainExaminationBound_parityRowSystem_le (k := 3) + ([] : List (Fin (emptyCNF n).length → Bool)) hF D univ hlen hn_card).1 + +-- 6. Concrete check of `CNF.initialRowWeightBound_le_mul_pow_clog` on `testCNF` (`n = 2`, `m = 2`, +-- `B = 1`, `C_B = 1`, `β_B = 0`). +example : + CNF.initialRowWeightBound 1 testCNF.length ≤ + CNF.initialRowWeightCoeff 1 0 * Nat.clog 2 (Fintype.card (Fin 2)) ^ (2 * 0 + 3) := + CNF.initialRowWeightBound_le_mul_pow_clog (by decide) (by decide) (by decide) + +-- 7. Unconditional schedule discharge `CNF.exists_branch_schedule_parityRowSystem_of_le_clog_pow` +-- at `k = 3`, `C_B = 1`, `β_B = 1`. +example : + ∃ N₀ : ℕ, 20 ≤ N₀ ∧ + ∀ n ≥ N₀, + let φ := emptyCNF n + let W := CNF.initialRowWeightBound 1 φ.length + let b₀ := CNF.parityBranchThreshold 3 W (Fintype.card (Fin n)) + ∀ b : Fin n → Bool, + Nonempty + (ReplacementDesign + (branchAugmentedScope + (heavyVars univ (univ : Finset (Fin ([] : List (Fin φ.length → Bool)).length)) + (fun j => equationScope (φ.parityRowSystem [] j)) b₀) + (emptyCNFEquiv n b₀) univ (φ.parityRowSystem []) b) + (numNodes n) (numGroups n) (intervalStart (2 * 1 + 5) n) + (rowBound (2 * 1 + 5) n) (tauRat n)) := by + obtain ⟨N₀, hN₀20, hsched⟩ := CNF.exists_branch_schedule_parityRowSystem_of_le_clog_pow 3 1 1 + refine ⟨N₀, hN₀20, fun n hn => ?_⟩ + intro φ W b₀ b + have hk : ∀ c ∈ φ, c.length ≤ 3 := by simp [φ, emptyCNF] + have hcard : N₀ ≤ Fintype.card (Fin n) := by simpa only [Fintype.card_fin] using hn + have hm : φ.length ≤ 1 * Fintype.card (Fin n) := by simp [φ, emptyCNF] + have hB : 1 ≤ 1 * Nat.clog 2 (Fintype.card (Fin n)) ^ 1 := by + rw [Fintype.card_fin, one_mul, pow_one] + have : 2 ^ 0 < n := by omega + exact (Nat.lt_clog_iff_pow_lt one_lt_two).mpr this + have hW : ∀ r ∈ ([] : List (Fin φ.length → Bool)), weight r ≤ W := by simp + have hlen : ([] : List (Fin φ.length → Bool)).length ≤ 6 * Fintype.card (Fin n) := by simp + exact (hsched hk hcard hm hB le_rfl hW hlen (emptyCNFEquiv n b₀)).2.2.2 b |>.2 + +end Cslib.Complexity.SubexponentialSAT.SparseParityScheduleTests From dcdef39ba9029b5f137c1db0aa6c780ae2bd4c62 Mon Sep 17 00:00:00 2001 From: Samuel Schlesinger Date: Tue, 27 Oct 2026 05:38:31 +0000 Subject: [PATCH 17/20] feat(FineGrained): instantiate Lemma 4.8 schedule for CNF sparse parity-design counter (#1226) --- Complexity.lean | 1 + .../FineGrained/SparseCNFDesignSchedule.lean | 705 ++++++++++++++++++ .../FineGrained/SparseCNFDesignSchedule.lean | 281 +++++++ 3 files changed, 987 insertions(+) create mode 100644 Complexity/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean create mode 100644 ComplexityTests/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean diff --git a/Complexity.lean b/Complexity.lean index b56af09948..37a605fa15 100644 --- a/Complexity.lean +++ b/Complexity.lean @@ -773,6 +773,7 @@ public import Complexity.Computability.Complexity.FineGrained.Reduction public import Complexity.Computability.Complexity.FineGrained.ReplacementParams public import Complexity.Computability.Complexity.FineGrained.ReplacementScheduleDesign public import Complexity.Computability.Complexity.FineGrained.Schoening +public import Complexity.Computability.Complexity.FineGrained.SparseCNFDesignSchedule public import Complexity.Computability.Complexity.FineGrained.Sparsification public import Complexity.Computability.Complexity.HardnessEncoding.PolyTime public import Complexity.Computability.Complexity.HardnessEncoding.Program diff --git a/Complexity/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean b/Complexity/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean new file mode 100644 index 0000000000..6895409ab6 --- /dev/null +++ b/Complexity/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean @@ -0,0 +1,705 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Computability.Complexity.FineGrained.ReplacementScheduleDesign +public import Complexity.Logics.Propositional.CNF.SparseDesignCounter + +/-! +# Section 6.3 Lemma 4.8 schedule instantiation for compiled CNF sparse parity-design counters + +This module bridges the compiled CNF sparse parity-design counter of +`Complexity.Logics.Propositional.CNF.SparseDesignCounter` (Sections 5.4–5.5 and 6.1–6.3 of +[OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH]) with the concrete Lemma 4.7 / +Lemma 4.8 parameter schedule `(numNodes n', numGroups n', intervalStart β n', rowBound β n', +tauRat n')` and Proposition 3.4 domain-examination bounds of +`Complexity.Computability.Complexity.FineGrained.ReplacementScheduleDesign` (Sections 3.5 and +4.6–4.7): + +1. **Per-branch and uniform Lemma 4.7 + Lemma 4.8 `ReplacementDesign` existence on + `CNF.branchParityRowNeutralScope` (§5.5 & §6.3, pp. 38–39, 43):** + - `Feasible.exists_branchParityRow_replacementDesign`: on any heavy-variable branch + `b : V → Bool` of `S = heavyVars univ univ (fun j => equationScope (φ.parityRowSystem rows j)) + b₀` with free-variable relabeling `e : ↥(univ \ S) ≃ Fin n'`, if every clause of `φ` has width + at most `k`, every row in `rows` has Hamming weight at most `W`, and + `hF : Feasible β n' (b₀ + 1) (max 1 (k * (W * 2 ^ k))) M'_b` holds, then there exists a + concrete Section 4 + `ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) (numNodes n') (numGroups n') + (intervalStart β n') (rowBound β n') (tauRat n')`. + - `exists_schedule_branchParityRow_replacementDesign`: uniformly for any `1 ≤ β`, produces + `n₀ ≥ 20` (via `exists_schedule_replacementDesign`) such that whenever `n₀ ≤ n'`, + `b₀ + 1 ≤ (Nat.clog 2 n') ^ β`, `max 1 (k * (W * 2 ^ k)) ≤ (Nat.clog 2 n') ^ β`, + `∀ c ∈ φ, c.length ≤ k`, and `∀ r_row ∈ rows, weight r_row ≤ W`, **every** branch + `b : V → Bool` simultaneously satisfies + `Feasible β n' (b₀ + 1) (max 1 (k * (W * 2 ^ k))) M'_b` and admits a concrete schedule + `ReplacementDesign`, with all per-branch incidence bounds (`n' ≤ M'_b`, + `M'_b ≤ (b₀ + 1) * n'`, per-variable occurrence `≤ b₀ + 1`, and per-factor width + `≤ max 1 (k * (W * 2 ^ k))`) discharged automatically. + +2. **Schedule-instantiated `commonZeroCount`, `numPassing`, and greedy `modelCountOn` recovery + (§§5.4–5.5, 6.1–6.3, pp. 38–43):** + - `exists_schedule_design_commonZeroCount_parityRowSystem_eq` and + `exists_schedule_design_numPassing_eq`: under the uniform polylogarithmic schedule hypotheses, + exhibits a concrete family `D` of Lemma 4.8 schedule `ReplacementDesign`s across all branches + `b : V → Bool` whose branch-summed constant-term evaluation of + `univariateClearedParityTruncatedSum` recovers `commonZeroCount univ (φ.parityRowSystem rows)` + and `numPassing φ.violations rows`, with each branch numerator of degree at most + `(k * (rowBound β n' - 1)) * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1))`. + - `exists_schedule_design_modelCountOn_eq_greedy` and + `exists_initialTests_and_schedule_design_modelCountOn_eq`: combines Lemma 6.1 (initial parity + tests of weight `≤ D₀`), Lemma 6.2 (`3 * n` greedy rounds of list length `P ≤ D₀`), and the + uniform Lemma 4.8 schedule threshold `n₀ ≤ n'` to recover `φ.modelCountOn Finset.univ` from + concrete Lemma 4.8 schedule `ReplacementDesign`s with numerator degree at most + `(k * (rowBound β n' - 1)) * (8 * Fintype.card V)`. + +3. **Section 6.3 (`c = 6`) candidate/final degree budgets and Proposition 3.4 / Lemma 4.8 + domain-examination bounds (§5.5 & §6.3, pp. 38–39, 43):** + - `branchParityRowDegreeBudget_le` and `greedyCandidateDegreeBudget_le`: when + `rows.length ≤ c * Fintype.card V` (in particular `c = 6` for every Lemma 6.2 candidate and + final system) and `Fintype.card V ≤ 2 * n'`, the pre-replacement degree factor + `d = k * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1))` is at most + `(k * (2 * c + 4)) * n'` (and `(16 * k) * n'` when `c = 6`). + - `Feasible.branchParityRow_domainExaminationBound_le`, + `Feasible.greedyCandidate_domainExaminationBound_le`, and + `sum_branchParityRow_domainExaminationBound_le`: bounds the per-branch and branch-summed + Proposition 3.4 local Boolean assignment examination counts on compiled CNF parity systems by + `2 * numNodes n' * numGroups n' * exp (((k * (2 * c + 4) + 4) : ℝ) * n' * rowCost β n')` per + branch and `2 ^ (Fintype.card V / s_div)` times that bound across all `branchAssignments S`. + +## Main results + +* `Feasible.exists_branchParityRow_replacementDesign` +* `exists_schedule_branchParityRow_replacementDesign` +* `exists_schedule_design_commonZeroCount_parityRowSystem_eq` +* `exists_schedule_design_numPassing_eq` +* `exists_schedule_design_modelCountOn_eq_greedy` +* `exists_initialTests_and_schedule_design_modelCountOn_eq` +* `branchParityRowDegreeBudget_le` +* `greedyCandidateDegreeBudget_le` +* `Feasible.branchParityRow_domainExaminationBound_le` +* `Feasible.greedyCandidate_domainExaminationBound_le` +* `sum_branchParityRow_domainExaminationBound_le` + +## References + +* [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (Section 3.5, pp. 25–26; + Section 4.6–4.7, pp. 33–35; Section 5.4–5.5, pp. 38–39; Section 6.1–6.3, pp. 40–43) +-/ + +@[expose] public noncomputable section + +namespace Cslib.Complexity.SubexponentialSAT.ReplacementParams + +open Finset Polynomial Cslib.BitString Cslib.BalancedSchedules Cslib.LinearAlgebra + Cslib.ReplacementCounting Cslib.Logic.PL +open scoped BigOperators + +variable {V : Type*} {n' : ℕ} + +/-! ### 1. Per-branch and uniform Lemma 4.8 schedule `ReplacementDesign` existence -/ + +section BranchScheduleExistence + +variable [Fintype V] [DecidableEq V] + +/-- **§5.5 & §6.3 (per-branch Lemma 4.7 + Lemma 4.8 schedule `ReplacementDesign` existence on +`CNF.branchParityRowNeutralScope`)**: if every clause of `φ` has width at most `k`, every row in +`rows` has Hamming weight at most `W`, and at `S = heavyVars univ univ (fun j => equationScope +(φ.parityRowSystem rows j)) b₀` with free-variable relabeling `e : ↥(univ \ S) ≃ Fin n'` the +schedule parameters satisfy `Feasible β n' (b₀ + 1) (max 1 (k * (W * 2 ^ k))) M'_b`, then branch `b` +admits a concrete Section 4 +`ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) (numNodes n') (numGroups n') +(intervalStart β n') (rowBound β n') (tauRat n')`. -/ +theorem Feasible.exists_branchParityRow_replacementDesign {φ : CNF V} {β k W b₀ : ℕ} + (hk : ∀ c ∈ φ, c.length ≤ k) {rows : List (Fin φ.length → Bool)} + (hW : ∀ r_row ∈ rows, weight r_row ≤ W) + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n') + (b : V → Bool) + (hF : Feasible β n' (b₀ + 1) (max 1 (k * (W * 2 ^ k))) + (totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n')) + (φ.branchParityRowNeutralScope rows + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) + e b))) : + Nonempty + (ReplacementDesign + (φ.branchParityRowNeutralScope rows + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) + e b) + (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n')) := + hF.exists_replacementDesign _ (Nat.succ_pos b₀) (le_max_left 1 _) + (CNF.varIncidence_branchParityRowNeutralScope_heavyVars_le φ rows b₀ e b) + (CNF.card_branchParityRowNeutralScope_le hk hW _ e b) + (CNF.totalIncidence_branchParityRowNeutralScope_heavyVars_le φ rows b₀ e b) + +/-- **§5.5 & §6.3 (uniform Lemma 4.7 + Lemma 4.8 schedule `ReplacementDesign` existence across all +heavy-variable branches of `φ.parityRowSystem rows`)**: for every integer `1 ≤ β`, there exists +`n₀ ≥ 20` such that whenever the free-variable count `n'` satisfies `n₀ ≤ n'`, the heavy-variable +threshold satisfies `b₀ + 1 ≤ (Nat.clog 2 n') ^ β`, the neutral-augmented scope width bound +satisfies `max 1 (k * (W * 2 ^ k)) ≤ (Nat.clog 2 n') ^ β`, every clause of `φ` has width at most +`k`, and every row in `rows` has Hamming weight at most `W`, **every** branch assignment +`b : V → Bool` simultaneously satisfies `Feasible` and admits a concrete Lemma 4.8 schedule +`ReplacementDesign`. -/ +theorem exists_schedule_branchParityRow_replacementDesign {β : ℕ} (hβ : 1 ≤ β) : + ∃ n₀ : ℕ, 20 ≤ n₀ ∧ + ∀ {V : Type*} [Fintype V] [DecidableEq V] {φ : CNF V} {k W b₀ n' : ℕ} + {rows : List (Fin φ.length → Bool)} + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n'), + n₀ ≤ n' → + b₀ + 1 ≤ Nat.clog 2 n' ^ β → + max 1 (k * (W * 2 ^ k)) ≤ Nat.clog 2 n' ^ β → + (∀ c ∈ φ, c.length ≤ k) → + (∀ r_row ∈ rows, weight r_row ≤ W) → + ∀ b : V → Bool, + Feasible β n' (b₀ + 1) (max 1 (k * (W * 2 ^ k))) + (totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n')) + (φ.branchParityRowNeutralScope rows + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) + e b)) ∧ + Nonempty + (ReplacementDesign + (φ.branchParityRowNeutralScope rows + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) + e b) + (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n')) := by + obtain ⟨n₀, hn₀20, hsched⟩ := exists_schedule_replacementDesign hβ + refine ⟨n₀, hn₀20, fun {V _ _ φ k W b₀ n' rows} e hn' hb hw hk hW b => ?_⟩ + exact hsched + (φ.branchParityRowNeutralScope rows + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) + e b) + hn' (Nat.succ_pos b₀) hb (le_max_left 1 _) hw + (CNF.le_totalIncidence_branchParityRowNeutralScope φ rows _ e b) + (CNF.totalIncidence_branchParityRowNeutralScope_heavyVars_le φ rows b₀ e b) + (CNF.varIncidence_branchParityRowNeutralScope_heavyVars_le φ rows b₀ e b) + (CNF.card_branchParityRowNeutralScope_le hk hW _ e b) + +end BranchScheduleExistence + +/-! ### 2. End-to-end Lemma 4.8 schedule `ReplacementDesign` recovery of `numPassing` and `#F` -/ + +section ScheduleDesignRecovery + +variable [Fintype V] [DecidableEq V] + +/-- **§5.4–5.5 & §6.3 (schedule-instantiated `commonZeroCount` recovery on `φ.parityRowSystem`)**: +for every `1 ≤ β`, there exists `n₀ ≥ 20` such that whenever `n₀ ≤ n'`, +`b₀ + 1 ≤ (Nat.clog 2 n') ^ β`, `max 1 (k * (W * 2 ^ k)) ≤ (Nat.clog 2 n') ^ β`, +`∀ c ∈ φ, c.length ≤ k`, and `∀ r_row ∈ rows, weight r_row ≤ W`, there exists a family `D` of +concrete Lemma 4.8 schedule `ReplacementDesign`s across all branches `b : V → Bool` whose +branch-summed constant-term evaluation recovers +`(commonZeroCount univ (φ.parityRowSystem rows) : ℤ)` and whose univariate numerators have degree at +most `(k * (rowBound β n' - 1)) * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1))`. -/ +theorem exists_schedule_design_commonZeroCount_parityRowSystem_eq {β : ℕ} (hβ : 1 ≤ β) : + ∃ n₀ : ℕ, 20 ≤ n₀ ∧ + ∀ {V : Type*} [Fintype V] [DecidableEq V] {φ : CNF V} {k W b₀ n' : ℕ} + {rows : List (Fin φ.length → Bool)} + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n'), + n₀ ≤ n' → + b₀ + 1 ≤ Nat.clog 2 n' ^ β → + max 1 (k * (W * 2 ^ k)) ≤ Nat.clog 2 n' ^ β → + (∀ c ∈ φ, c.length ≤ k) → + (∀ r_row ∈ rows, weight r_row ≤ W) → + let S := heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀ + (∀ b : V → Bool, + Feasible β n' (b₀ + 1) (max 1 (k * (W * 2 ^ k))) + (totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n')) + (φ.branchParityRowNeutralScope rows S e b))) ∧ + ∃ D : (b : V → Bool) → + ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) + (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n'), + (commonZeroCount (univ : Finset (Fin rows.length)) (φ.parityRowSystem rows) : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) Sum.inl)).eval 0 / + clearedProductDenom (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ + ∀ b : V → Bool, + (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) Sum.inl)).natDegree ≤ + (k * (rowBound β n' - 1)) * + (rows.length + 2 * (branchPrecision (Fintype.card V) - 1)) := by + obtain ⟨n₀, hn₀20, hsched⟩ := exists_schedule_branchParityRow_replacementDesign hβ + refine ⟨n₀, hn₀20, fun {V _ _ φ k W b₀ n' rows} e hn' hb hw hk hW => ?_⟩ + intro S + have hbranch := hsched e hn' hb hw hk hW + refine ⟨fun b => (hbranch b).1, ?_⟩ + let D : (b : V → Bool) → + ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) + (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n') := + fun b => Classical.choice (hbranch b).2 + refine ⟨D, ?_, ?_⟩ + · exact CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design hk rows S e + (φ.branchParityRowNeutralScope rows S e) D (fun _ => Sum.inl) + · intro b + exact CNF.natDegree_univariateClearedParityTruncatedSum_branchParityRowSystem_le hk rows S e b + (D b) Sum.inl (branchPrecision (Fintype.card V)) + +/-- **§5.4–5.5 & §6.3 (schedule-instantiated `numPassing` recovery on `φ.violations`)**: under the +same polylogarithmic schedule hypotheses, there exists a family `D` of concrete Lemma 4.8 schedule +`ReplacementDesign`s across all branches `b : V → Bool` whose branch-summed constant-term evaluation +recovers `(numPassing φ.violations rows : ℤ)`. -/ +theorem exists_schedule_design_numPassing_eq {β : ℕ} (hβ : 1 ≤ β) : + ∃ n₀ : ℕ, 20 ≤ n₀ ∧ + ∀ {V : Type*} [Fintype V] [DecidableEq V] {φ : CNF V} {k W b₀ n' : ℕ} + {rows : List (Fin φ.length → Bool)} + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n'), + n₀ ≤ n' → + b₀ + 1 ≤ Nat.clog 2 n' ^ β → + max 1 (k * (W * 2 ^ k)) ≤ Nat.clog 2 n' ^ β → + (∀ c ∈ φ, c.length ≤ k) → + (∀ r_row ∈ rows, weight r_row ≤ W) → + let S := heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀ + (∀ b : V → Bool, + Feasible β n' (b₀ + 1) (max 1 (k * (W * 2 ^ k))) + (totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n')) + (φ.branchParityRowNeutralScope rows S e b))) ∧ + ∃ D : (b : V → Bool) → + ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) + (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n'), + (numPassing φ.violations rows : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) Sum.inl)).eval 0 / + clearedProductDenom (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ + ∀ b : V → Bool, + (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) Sum.inl)).natDegree ≤ + (k * (rowBound β n' - 1)) * + (rows.length + 2 * (branchPrecision (Fintype.card V) - 1)) := by + obtain ⟨n₀, hn₀20, hsched⟩ := exists_schedule_design_commonZeroCount_parityRowSystem_eq hβ + refine ⟨n₀, hn₀20, fun {V _ _ φ k W b₀ n' rows} e hn' hb hw hk hW => ?_⟩ + obtain ⟨hF, D, hcount, hdeg⟩ := hsched e hn' hb hw hk hW + rw [CNF.commonZeroCount_parityRowSystem] at hcount + exact ⟨hF, D, hcount, hdeg⟩ + +/-- If every row in `A 0` has Hamming weight at most `D₀` and each step appends `testRow (γ i)` of +list length `P`, then at every stage `j` every row in `A j` has Hamming weight at most +`max D₀ P`. -/ +theorem weight_le_max_of_append_testRow {m D₀ P : ℕ} + (A : ℕ → List (Fin m → Bool)) (hA₀ : ∀ r_row ∈ A 0, weight r_row ≤ D₀) + (γ : ℕ → Fin P → Fin m × Bool) (hA : ∀ i, A (i + 1) = A i ++ [testRow (γ i)]) : + ∀ (j : ℕ) (r_row : Fin m → Bool), r_row ∈ A j → weight r_row ≤ max D₀ P := by + intro j + induction j with + | zero => + exact fun r_row hr => (hA₀ r_row hr).trans (le_max_left D₀ P) + | succ j ih => + intro r_row hr + rw [hA j] at hr + rcases List.mem_append.mp hr with hr | hr + · exact ih r_row hr + · rw [List.mem_singleton.mp hr] + exact (weight_testRow_le (γ j)).trans (le_max_right D₀ P) + +/-- **§§5.4–5.5 & 6.2–6.3 (schedule-instantiated greedy `modelCountOn` recovery)**: for every +`1 ≤ β`, there exists `n₀ ≥ 20` such that under the hypotheses of +`CNF.commonZeroCount_parityRowSystem_greedy`, if every row of `A 0` has weight at most `D₀` and at +stage `3 * Fintype.card V` the free-variable count `n'` satisfies `n₀ ≤ n'`, +`b₀ + 1 ≤ (Nat.clog 2 n') ^ β`, and `max 1 (k * (max D₀ P * 2 ^ k)) ≤ (Nat.clog 2 n') ^ β`, then +there exists a concrete family `D` of Lemma 4.8 schedule `ReplacementDesign`s across all branches of +`A (3 * Fintype.card V)` whose branch-summed constant-term evaluation recovers +`(φ.modelCountOn Finset.univ : ℤ)`. -/ +theorem exists_schedule_design_modelCountOn_eq_greedy {β : ℕ} (hβ : 1 ≤ β) : + ∃ n₀ : ℕ, 20 ≤ n₀ ∧ + ∀ {V : Type*} [Fintype V] [DecidableEq V] (φ : CNF V) {k D₀ P b₀ n' : ℕ}, + (∀ c ∈ φ, c.length ≤ k) → + 1 ≤ Fintype.card V → + 1 ≤ P → + ∀ (A : ℕ → List (Fin φ.length → Bool)), + (∀ r_row ∈ A 0, weight r_row ≤ D₀) → + (∀ σ, PassesTests φ.violations (A 0) σ → φ.eval σ = false → + φ.length ≤ P * weight (φ.violations σ)) → + ∀ (γ : ℕ → Fin P → Fin φ.length × Bool), + (∀ i, A (i + 1) = A i ++ [testRow (γ i)]) → + (∀ i (γ' : Fin P → Fin φ.length × Bool), + commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow (γ i)])) ≤ + commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow γ']))) → + ∀ (e : ↥(univ \ heavyVars univ (univ : Finset (Fin (A (3 * Fintype.card V)).length)) + (fun j => equationScope (φ.parityRowSystem (A (3 * Fintype.card V)) j)) b₀) ≃ Fin n'), + n₀ ≤ n' → + b₀ + 1 ≤ Nat.clog 2 n' ^ β → + max 1 (k * (max D₀ P * 2 ^ k)) ≤ Nat.clog 2 n' ^ β → + let rows := A (3 * Fintype.card V) + let S := heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀ + (∀ b : V → Bool, + Feasible β n' (b₀ + 1) (max 1 (k * (max D₀ P * 2 ^ k))) + (totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n')) + (φ.branchParityRowNeutralScope rows S e b))) ∧ + ∃ D : (b : V → Bool) → + ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) + (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n'), + (φ.modelCountOn Finset.univ : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) Sum.inl)).eval 0 / + clearedProductDenom (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ + ∀ b : V → Bool, + (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) Sum.inl)).natDegree ≤ + (k * (rowBound β n' - 1)) * + (rows.length + 2 * (branchPrecision (Fintype.card V) - 1)) := by + obtain ⟨n₀, hn₀20, hsched⟩ := exists_schedule_design_commonZeroCount_parityRowSystem_eq hβ + refine ⟨n₀, hn₀20, + fun {V _ _} φ {k D₀ P b₀ n'} hk hn hP A hA₀_wt hinit γ hA hγ e hn' hb hw => ?_⟩ + have hW : ∀ r_row ∈ A (3 * Fintype.card V), weight r_row ≤ max D₀ P := + weight_le_max_of_append_testRow A hA₀_wt γ hA (3 * Fintype.card V) + obtain ⟨hF, D, hcount, hdeg⟩ := hsched e hn' hb hw hk hW + rw [CNF.commonZeroCount_parityRowSystem_greedy φ hn hP A hinit γ hA hγ] at hcount + exact ⟨hF, D, hcount, hdeg⟩ + +/-- **Lemmas 6.1–6.2, Lemma 4.7–4.8, & §§5.4–5.5, 6.3 (end-to-end initial + greedy parity-test +compilation and Lemma 4.8 schedule `ReplacementDesign` recovery of `φ.modelCountOn Finset.univ`)**: +for every `1 ≤ β`, there exists `n₀ ≥ 20` such that for any width-`≤ k` CNF `φ` on +`n = Fintype.card V ≥ 1` variables with `φ.length ≤ B * n` (`B ≥ 1`), there exist initial parity +rows `A_init` (`A_init.length ≤ 3 * n`, each of weight at most +`D₀ = CNF.initialRowWeightBound B φ.length`) such that for any greedy sequence +`A (i + 1) = A i ++ [testRow (γ i)]` with `A 0 = A_init` minimizing +`commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow γ']))` over candidate rows of list length +`P = CNF.greedyRowListLength B φ.length`, whenever at stage `3 * n` the free-variable count `n'` +satisfies `n₀ ≤ n'`, `b₀ + 1 ≤ (Nat.clog 2 n') ^ β`, and +`max 1 (k * (D₀ * 2 ^ k)) ≤ (Nat.clog 2 n') ^ β`: +1. Every branch `b : V → Bool` satisfies + `Feasible β n' (b₀ + 1) (max 1 (k * (D₀ * 2 ^ k))) M'_b`, +2. There exists a family `D` of concrete Lemma 4.8 schedule `ReplacementDesign`s across all + branches whose branch-summed constant-term evaluation recovers + `(φ.modelCountOn Finset.univ : ℤ)`, +3. Every branch numerator has `natDegree ≤ (k * (rowBound β n' - 1)) * (8 * Fintype.card V)`. -/ +theorem exists_initialTests_and_schedule_design_modelCountOn_eq {β : ℕ} (hβ : 1 ≤ β) : + ∃ n₀ : ℕ, 20 ≤ n₀ ∧ + ∀ {V : Type*} [Fintype V] [DecidableEq V] (φ : CNF V) {k B : ℕ}, + (∀ c ∈ φ, c.length ≤ k) → + 1 ≤ Fintype.card V → + 1 ≤ B → + φ.length ≤ B * Fintype.card V → + let D₀ := CNF.initialRowWeightBound B φ.length + let P := CNF.greedyRowListLength B φ.length + ∃ A_init : List (Fin φ.length → Bool), A_init.length ≤ 3 * Fintype.card V ∧ + (∀ r_row ∈ A_init, weight r_row ≤ D₀) ∧ + ∀ (A : ℕ → List (Fin φ.length → Bool)) + (γ : ℕ → Fin P → Fin φ.length × Bool), + A 0 = A_init → (∀ i, A (i + 1) = A i ++ [testRow (γ i)]) → + (∀ i (γ' : Fin P → Fin φ.length × Bool), + commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow (γ i)])) ≤ + commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow γ']))) → + (∀ i ≤ 3 * Fintype.card V, + (A i).length ≤ 6 * Fintype.card V ∧ + ∀ j : Fin (A i).length, + (∀ M ∈ φ.parityRowSystem (A i) j, M ⊆ φ.vars.toFinset ∧ #M ≤ k) ∧ + #(φ.parityRowSystem (A i) j) ≤ D₀ * 2 ^ k ∧ + #(equationScope (φ.parityRowSystem (A i) j)) ≤ k * (D₀ * 2 ^ k)) ∧ + ∀ {b₀ n' : ℕ} + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin (A (3 * Fintype.card V)).length)) + (fun j => equationScope (φ.parityRowSystem (A (3 * Fintype.card V)) j)) b₀) ≃ + Fin n'), + n₀ ≤ n' → + b₀ + 1 ≤ Nat.clog 2 n' ^ β → + max 1 (k * (D₀ * 2 ^ k)) ≤ Nat.clog 2 n' ^ β → + let rows := A (3 * Fintype.card V) + let S := heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀ + (∀ b : V → Bool, + Feasible β n' (b₀ + 1) (max 1 (k * (D₀ * 2 ^ k))) + (totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n')) + (φ.branchParityRowNeutralScope rows S e b))) ∧ + ∃ D : (b : V → Bool) → + ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) + (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n'), + (φ.modelCountOn Finset.univ : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) Sum.inl)).eval 0 / + clearedProductDenom (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ + ∀ b : V → Bool, + (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) Sum.inl)).natDegree ≤ + (k * (rowBound β n' - 1)) * (8 * Fintype.card V) := by + obtain ⟨n₀, hn₀20, hsched⟩ := exists_schedule_branchParityRow_replacementDesign hβ + refine ⟨n₀, hn₀20, fun {V _ _} φ {k B} hk hn hB hm => ?_⟩ + obtain ⟨A_init, hlen, hw, hgreedy⟩ := CNF.exists_initialTests_commonZeroCount_greedy φ hk hn hB hm + refine ⟨A_init, hlen, hw, fun A γ h0 hA hγ => ?_⟩ + obtain ⟨hcount, hbounds⟩ := hgreedy A γ h0 hA hγ + have hstage : + ∀ i ≤ 3 * Fintype.card V, + (A i).length ≤ 6 * Fintype.card V ∧ + ∀ j : Fin (A i).length, + (∀ M ∈ φ.parityRowSystem (A i) j, M ⊆ φ.vars.toFinset ∧ #M ≤ k) ∧ + #(φ.parityRowSystem (A i) j) ≤ CNF.initialRowWeightBound B φ.length * 2 ^ k ∧ + #(equationScope (φ.parityRowSystem (A i) j)) ≤ + k * (CNF.initialRowWeightBound B φ.length * 2 ^ k) := by + intro i hi + obtain ⟨hlen_i, hj⟩ := hbounds i hi + refine ⟨hlen_i, fun j => ?_⟩ + obtain ⟨hM, hcard, hscope⟩ := hj j + rw [CNF.max_initialRowWeightBound_greedyRowListLength] at hcard hscope + exact ⟨hM, hcard, hscope⟩ + refine ⟨hstage, fun {b₀ n'} e hn' hb hw_width => ?_⟩ + intro rows S + have hW_rows : ∀ r_row ∈ rows, weight r_row ≤ CNF.initialRowWeightBound B φ.length := by + intro r_row hr + have hmax := weight_le_max_of_append_testRow A (h0 ▸ hw) γ hA (3 * Fintype.card V) r_row hr + rwa [CNF.max_initialRowWeightBound_greedyRowListLength] at hmax + have hbranch := hsched e hn' hb hw_width hk hW_rows + refine ⟨fun b => (hbranch b).1, ?_⟩ + let D : (b : V → Bool) → + ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) + (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n') := + fun b => Classical.choice (hbranch b).2 + refine ⟨D, ?_, ?_⟩ + · rw [← hcount] + exact CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design hk rows S e + (φ.branchParityRowNeutralScope rows S e) D (fun _ => Sum.inl) + · intro b + have hdeg := CNF.natDegree_univariateClearedParityTruncatedSum_branchParityRowSystem_le hk rows + S e b (D b) Sum.inl (branchPrecision (Fintype.card V)) + have hrows_len : rows.length ≤ 6 * Fintype.card V := (hstage (3 * Fintype.card V) le_rfl).1 + have h8 : rows.length + 2 * (branchPrecision (Fintype.card V) - 1) ≤ 8 * Fintype.card V := by + unfold branchPrecision + omega + exact hdeg.trans (Nat.mul_le_mul_left (k * (rowBound β n' - 1)) h8) + +end ScheduleDesignRecovery + +/-! ### 3. Section 6.3 (`c = 6`) degree budgets and Proposition 3.4 domain-examination bounds -/ + +section DomainExaminationBounds + +/-- **Section 5.5 & Section 6.3 degree budget**: when `rows.length ≤ c * Fintype.card V` and +`Fintype.card V ≤ 2 * n'`, the pre-replacement degree factor +`k * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1))` at original precision +`branchPrecision (Fintype.card V) = Fintype.card V + 1` is at most `(k * (2 * c + 4)) * n'`. -/ +theorem branchParityRowDegreeBudget_le {k c n n' m : ℕ} + (hm : m ≤ c * n) (hn : n ≤ 2 * n') : + k * (m + 2 * (branchPrecision n - 1)) ≤ (k * (2 * c + 4)) * n' := by + unfold branchPrecision + have h1 : m + 2 * (n + 1 - 1) ≤ (2 * c + 4) * n' := by + calc m + 2 * (n + 1 - 1) + = m + 2 * n := by omega + _ ≤ c * n + 2 * n := Nat.add_le_add_right hm (2 * n) + _ = (c + 2) * n := by ring + _ ≤ (c + 2) * (2 * n') := Nat.mul_le_mul_left (c + 2) hn + _ = (2 * c + 4) * n' := by ring + calc k * (m + 2 * (n + 1 - 1)) + ≤ k * ((2 * c + 4) * n') := Nat.mul_le_mul_left k h1 + _ = (k * (2 * c + 4)) * n' := (mul_assoc k (2 * c + 4) n').symm + +/-- **Section 6.3 (`c = 6`) Lemma 6.2 candidate/final degree budget**: for any candidate or final +system with `rows.length ≤ 6 * Fintype.card V` and `Fintype.card V ≤ 2 * n'`, the pre-replacement +degree factor `k * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1))` is at most +`(16 * k) * n'`. -/ +theorem greedyCandidateDegreeBudget_le {k n n' m : ℕ} + (hm : m ≤ 6 * n) (hn : n ≤ 2 * n') : + k * (m + 2 * (branchPrecision n - 1)) ≤ (16 * k) * n' := by + have h := branchParityRowDegreeBudget_le (k := k) hm hn + rwa [show k * (2 * 6 + 4) = 16 * k by ring] at h + +/-- **Section 5.5 (`n ≤ 2 * n'` after branching on `heavyVars` of `φ.parityRowSystem rows`)**: when +`1 ≤ b₀`, `2 ≤ s_div`, `totalIncidence univ (fun j => equationScope (φ.parityRowSystem rows j)) * +s_div ≤ b₀ * Fintype.card V`, and `e : ↥(univ \ heavyVars ...) ≃ Fin n'`, the free-variable count +`n'` satisfies `Fintype.card V ≤ 2 * n'` and `Fintype.card V / 2 ≤ n'`. -/ +theorem card_le_two_mul_freeVar_of_heavyVars_parityRowSystem [Fintype V] [DecidableEq V] + (φ : CNF V) (rows : List (Fin φ.length → Bool)) {b₀ s_div : ℕ} + (hb₀ : 1 ≤ b₀) (hs_div : 2 ≤ s_div) + (hM : + totalIncidence (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) * s_div ≤ + b₀ * Fintype.card V) + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n') : + Fintype.card V ≤ 2 * n' ∧ Fintype.card V / 2 ≤ n' := by + have hhalf := card_sdiff_heavyVars_ge_half (univ : Finset V) + (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) hb₀ hs_div + (fun _ _ => subset_univ _) (by simpa only [card_univ] using hM) + have hcard : #(univ \ heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) = n' := by + simpa only [Fintype.card_coe, Fintype.card_fin] using Fintype.card_congr e + simpa only [card_univ, hcard] using hhalf + +/-- **Section 5.5 & Section 6.3 single-branch Proposition 3.4 / Lemma 4.8 domain-examination bound +for `φ.parityRowSystem rows`**: for any branch with `hF : Feasible β n' b_occ w_width M'` and +concrete schedule design `D` on `Fin n'`, if `rows.length ≤ c * Fintype.card V` and +`Fintype.card V ≤ 2 * n'`, then at +`d = k * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1))` and canonical truncation order +`q = (d * rowBound β n') / numNodes n'`, the induced Section 3 counting design +`C := hF.toCountingDesign D s` examines at most +`2 * numNodes n' * numGroups n' * exp (((k * (2 * c + 4) + 4) : ℝ) * n' * rowCost β n')` local +Boolean assignments. -/ +theorem Feasible.branchParityRow_domainExaminationBound_le [Fintype V] {F_idx : Type*} + [Fintype F_idx] {scope : F_idx → Finset (Fin n')} {β b_occ w_width M' k c : ℕ} + (φ : CNF V) (rows : List (Fin φ.length → Bool)) + (hF : Feasible β n' b_occ w_width M') + (D : ReplacementDesign scope (numNodes n') (numGroups n') (intervalStart β n') + (rowBound β n') (tauRat n')) + (s : Finset F_idx) (hm : rows.length ≤ c * Fintype.card V) (hn : Fintype.card V ≤ 2 * n') : + let d := k * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1)) + let q := (d * rowBound β n') / numNodes n' + let C := hF.toCountingDesign D s + (∑ t : Fin (numNodes n'), + (#{p : Finset (Fin n') × Finset (Fin n') | #p.1 ≤ q ∧ p.2 ⊆ p.1} : ℝ) * + (2 * (#(C.measurementBox t) : ℝ) * + ∑ g : Fin (numGroups n'), (Fintype.card (C.LocalCube t g) : ℝ))) ≤ + 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * + Real.exp (((k * (2 * c + 4) + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n') ∧ + 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * + Real.exp (((k * (2 * c + 4) + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n') ≤ + 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * + Real.exp (((k * (2 * c + 4) + 4 : ℕ) : ℝ) * (n' : ℝ) * + (1028 * ((β : ℝ) + 3) * (Nat.clog 2 (Nat.clog 2 n') : ℝ) ^ 2 / + Real.sqrt (Nat.clog 2 n'))) := by + intro d q C + have hd_le : (d : ℝ) ≤ ((k * (2 * c + 4) : ℕ) : ℝ) * (n' : ℝ) := by + exact_mod_cast branchParityRowDegreeBudget_le (k := k) hm hn + have hq : + (q : ℝ) ≤ ((k * (2 * c + 4) : ℕ) : ℝ) * (n' : ℝ) * + ((rowBound β n' : ℝ) / numNodes n') := by + calc (q : ℝ) + ≤ ((d * rowBound β n' : ℕ) : ℝ) / numNodes n' := Nat.cast_div_le + _ = (d : ℝ) * ((rowBound β n' : ℝ) / numNodes n') := by push_cast; ring + _ ≤ (((k * (2 * c + 4) : ℕ) : ℝ) * (n' : ℝ)) * + ((rowBound β n' : ℝ) / numNodes n') := + mul_le_mul_of_nonneg_right hd_le (div_nonneg (Nat.cast_nonneg _) (Nat.cast_nonneg _)) + have hc_nn : (0 : ℝ) ≤ ((k * (2 * c + 4) : ℕ) : ℝ) := Nat.cast_nonneg _ + have hbound := hF.domainExaminationBound_le_mul_exp_rowCost D s hc_nn hq + have hcast : + (((k * (2 * c + 4) : ℕ) : ℝ) + 4) = ((k * (2 * c + 4) + 4 : ℕ) : ℝ) := by + push_cast + ring + rw [hcast] at hbound + exact hbound + +/-- **Section 6.3 (`c = 6`) single-branch domain-examination bound for any Lemma 6.2 candidate or +final system (`rows.length ≤ 6 * Fintype.card V`)**: specializes +`Feasible.branchParityRow_domainExaminationBound_le` to `c = 6`, giving the exponent multiplier +`16 * k + 4`. -/ +theorem Feasible.greedyCandidate_domainExaminationBound_le [Fintype V] {F_idx : Type*} + [Fintype F_idx] {scope : F_idx → Finset (Fin n')} {β b_occ w_width M' k : ℕ} + (φ : CNF V) (rows : List (Fin φ.length → Bool)) + (hF : Feasible β n' b_occ w_width M') + (D : ReplacementDesign scope (numNodes n') (numGroups n') (intervalStart β n') + (rowBound β n') (tauRat n')) + (s : Finset F_idx) (hm : rows.length ≤ 6 * Fintype.card V) (hn : Fintype.card V ≤ 2 * n') : + let d := k * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1)) + let q := (d * rowBound β n') / numNodes n' + let C := hF.toCountingDesign D s + (∑ t : Fin (numNodes n'), + (#{p : Finset (Fin n') × Finset (Fin n') | #p.1 ≤ q ∧ p.2 ⊆ p.1} : ℝ) * + (2 * (#(C.measurementBox t) : ℝ) * + ∑ g : Fin (numGroups n'), (Fintype.card (C.LocalCube t g) : ℝ))) ≤ + 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * + Real.exp (((16 * k + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n') ∧ + 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * + Real.exp (((16 * k + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n') ≤ + 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * + Real.exp (((16 * k + 4 : ℕ) : ℝ) * (n' : ℝ) * + (1028 * ((β : ℝ) + 3) * (Nat.clog 2 (Nat.clog 2 n') : ℝ) ^ 2 / + Real.sqrt (Nat.clog 2 n'))) := by + have h := hF.branchParityRow_domainExaminationBound_le (k := k) (c := 6) φ rows D s hm hn + rwa [show k * (2 * 6 + 4) + 4 = 16 * k + 4 by ring] at h + +/-- **Section 5.5 & Section 6.3 multi-branch domain-examination bound across all +`branchAssignments S` of `φ.parityRowSystem rows`**: when +`S = heavyVars univ univ (fun j => equationScope (φ.parityRowSystem rows j)) b₀` with `1 ≤ b₀`, +`2 ≤ s_div`, `totalIncidence univ (fun j => equationScope (φ.parityRowSystem rows j)) * s_div ≤ +b₀ * Fintype.card V`, and `e : ↥(univ \ S) ≃ Fin n'`, the free-variable dimension satisfies +`Fintype.card V ≤ 2 * n'`, and if each branch `b ∈ branchAssignments S` has its real examination sum +bounded via `Feasible.branchParityRow_domainExaminationBound_le`, then the sum across all +`b ∈ branchAssignments S` is at most +`(2 : ℝ) ^ (Fintype.card V / s_div) * (2 * numNodes n' * numGroups n' * + exp (((k * (2 * c + 4) + 4 : ℕ) : ℝ) * n' * rowCost β n'))`. -/ +theorem sum_branchParityRow_domainExaminationBound_le [Fintype V] [DecidableEq V] + (φ : CNF V) (rows : List (Fin φ.length → Bool)) {β b₀ s_div k c : ℕ} + (hb₀ : 1 ≤ b₀) (hs_div : 2 ≤ s_div) + (hM : + totalIncidence (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) * s_div ≤ + b₀ * Fintype.card V) + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n') + (examSum : (V → Bool) → ℝ) + (hexam : ∀ b ∈ branchAssignments + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀), + examSum b ≤ + 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * + Real.exp (((k * (2 * c + 4) + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n')) : + Fintype.card V ≤ 2 * n' ∧ + (∑ b ∈ branchAssignments + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀), + examSum b) ≤ + (2 : ℝ) ^ (Fintype.card V / s_div) * + (2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * + Real.exp (((k * (2 * c + 4) + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n')) := by + have hn := + (card_le_two_mul_freeVar_of_heavyVars_parityRowSystem φ rows hb₀ hs_div hM e).1 + refine ⟨hn, ?_⟩ + let S := heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀ + let B := 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * + Real.exp (((k * (2 * c + 4) + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n') + have hB_nn : 0 ≤ B := by positivity + have hcard : (#(branchAssignments S) : ℝ) ≤ (2 : ℝ) ^ (Fintype.card V / s_div) := by + exact_mod_cast card_branchAssignments_heavyVars_le_two_pow_div + (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) hb₀ (by omega) hM + calc ∑ b ∈ branchAssignments S, examSum b + ≤ ∑ _b ∈ branchAssignments S, B := sum_le_sum hexam + _ = (#(branchAssignments S) : ℝ) * B := by rw [sum_const, nsmul_eq_mul] + _ ≤ (2 : ℝ) ^ (Fintype.card V / s_div) * B := mul_le_mul_of_nonneg_right hcard hB_nn + +end DomainExaminationBounds + +end Cslib.Complexity.SubexponentialSAT.ReplacementParams diff --git a/ComplexityTests/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean b/ComplexityTests/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean new file mode 100644 index 0000000000..f591d1590c --- /dev/null +++ b/ComplexityTests/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean @@ -0,0 +1,281 @@ +/- +Copyright (c) 2026 Samuel Schlesinger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Samuel Schlesinger +-/ + +module +-- upstream: candidate + +public import Complexity.Init +public import Complexity.Computability.Complexity.FineGrained.SparseCNFDesignSchedule +import Mathlib.Tactic.Linarith +import Mathlib.Tactic.NormNum +import Mathlib.Tactic.Positivity +import Mathlib.Tactic.Ring + +/-! +# Tests for `Complexity.Computability.Complexity.FineGrained.SparseCNFDesignSchedule` + +Concrete checks for Section 6.3 candidate/final degree budgets (`branchParityRowDegreeBudget_le`, +`greedyCandidateDegreeBudget_le`), greedy row-weight preservation +(`weight_le_max_of_append_testRow`), free-variable dimension lower bounds +(`card_le_two_mul_freeVar_of_heavyVars_parityRowSystem`), a concrete schedule witness at +`n = 2 ^ (2 ^ 50)` instantiating `Feasible.exists_branchParityRow_replacementDesign`, +`Feasible.branchParityRow_domainExaminationBound_le`, +`Feasible.greedyCandidate_domainExaminationBound_le`, and +`sum_branchParityRow_domainExaminationBound_le`, and instantiations of the uniform schedule +recovery theorems (`exists_schedule_branchParityRow_replacementDesign`, +`exists_schedule_design_commonZeroCount_parityRowSystem_eq`, +`exists_schedule_design_numPassing_eq`, `exists_schedule_design_modelCountOn_eq_greedy`, and +`exists_initialTests_and_schedule_design_modelCountOn_eq`). +-/ + +@[expose] public noncomputable section + +namespace Cslib.Complexity.SubexponentialSAT.SparseCNFDesignScheduleTests + +open Finset Polynomial Cslib.BitString Cslib.BalancedSchedules Cslib.LinearAlgebra + Cslib.ReplacementCounting Cslib.Logic.PL +open Cslib.Complexity.SubexponentialSAT.ReplacementParams +open scoped BigOperators + +/-! ### 1. Concrete degree-budget and row-weight checks -/ + +/-- Concrete check of `branchParityRowDegreeBudget_le` and `greedyCandidateDegreeBudget_le` for +`k = 3, c = 6, n = 20, n' = 12, m = 100`. -/ +example : + 3 * (100 + 2 * (branchPrecision 20 - 1)) ≤ (3 * (2 * 6 + 4)) * 12 ∧ + 3 * (100 + 2 * (branchPrecision 20 - 1)) ≤ (16 * 3) * 12 := + ⟨branchParityRowDegreeBudget_le (k := 3) (c := 6) (n := 20) (n' := 12) (m := 100) + (by decide) (by decide), + greedyCandidateDegreeBudget_le (k := 3) (n := 20) (n' := 12) (m := 100) + (by decide) (by decide)⟩ + +/-- Concrete 2-CNF over `Fin 3`: `(x₀ ∨ ¬x₁) ∧ (x₁ ∨ x₂)`. -/ +def sampleCNF3 : CNF (Fin 3) := + [[(0, true), (1, false)], [(1, true), (2, true)]] + +/-- Concrete check of `weight_le_max_of_append_testRow` on a 1-step greedy sequence over +`sampleCNF3`. -/ +example : + let γ₀ : Fin 1 → Fin sampleCNF3.length × Bool := fun _ => (⟨0, by decide⟩, true) + let A : ℕ → List (Fin sampleCNF3.length → Bool) := + fun j => Nat.rec [![true, false]] (fun _ acc => acc ++ [testRow γ₀]) j + ∀ (j : ℕ) (r_row : Fin sampleCNF3.length → Bool), r_row ∈ A j → weight r_row ≤ max 1 1 := by + intro γ₀ A + refine weight_le_max_of_append_testRow A ?_ (fun _ => γ₀) (fun _ => rfl) + intro r_row hr + change r_row ∈ [![true, false]] at hr + rcases List.mem_singleton.mp hr with rfl + decide + +/-- Concrete check of `card_le_two_mul_freeVar_of_heavyVars_parityRowSystem` on `sampleCNF3` with +an empty row list (`b₀ = 1, s_div = 2, n' = 3`). -/ +example : + let rows : List (Fin sampleCNF3.length → Bool) := [] + let S := heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (sampleCNF3.parityRowSystem rows j)) 1 + let _e : ↥(univ \ S) ≃ Fin 3 := + Fintype.equivFinOfCardEq (by decide) + Fintype.card (Fin 3) ≤ 2 * 3 ∧ Fintype.card (Fin 3) / 2 ≤ 3 := by + intro rows S e + exact card_le_two_mul_freeVar_of_heavyVars_parityRowSystem sampleCNF3 rows + (b₀ := 1) (s_div := 2) (by decide) (by decide) (by decide) e + +/-! ### 2. Concrete schedule witness at `n = 2 ^ (2 ^ 50)` -/ + +private def emptyCNF (n : ℕ) : CNF (Fin n) := + [] + +private def emptyRows (n : ℕ) : List (Fin (emptyCNF n).length → Bool) := + [] + +/-- For `emptyCNF n` and `emptyRows n`, `heavyVars` at `b₀` is empty. -/ +private theorem empty_heavyVars_eq_empty (n b₀ : ℕ) : + heavyVars (univ : Finset (Fin n)) (univ : Finset (Fin (emptyRows n).length)) + (fun j => equationScope ((emptyCNF n).parityRowSystem (emptyRows n) j)) b₀ = ∅ := by + ext v + have hzero : + varIncidence (univ : Finset (Fin (emptyRows n).length)) + (fun j => equationScope ((emptyCNF n).parityRowSystem (emptyRows n) j)) v = 0 := by + rfl + simp only [heavyVars, hzero, mem_filter, mem_univ, true_and, notMem_empty, iff_false, not_lt] + exact Nat.zero_le b₀ + +private def emptyFreeEquiv (n b₀ : ℕ) : + ↥((univ : Finset (Fin n)) \ + heavyVars univ (univ : Finset (Fin (emptyRows n).length)) + (fun j => equationScope ((emptyCNF n).parityRowSystem (emptyRows n) j)) b₀) ≃ + Fin n := + { toFun := fun v => v.1 + invFun := fun v => ⟨v, by rw [empty_heavyVars_eq_empty]; simp⟩ + left_inv := fun v => by ext; rfl + right_inv := fun v => rfl } + +private theorem totalIncidence_empty_branchParityRowNeutralScope (n b₀ : ℕ) (b : Fin n → Bool) : + totalIncidence + (univ : Finset (Fin (emptyRows n).length ⊕ Fin n)) + ((emptyCNF n).branchParityRowNeutralScope (emptyRows n) + (heavyVars univ (univ : Finset (Fin (emptyRows n).length)) + (fun j => equationScope ((emptyCNF n).parityRowSystem (emptyRows n) j)) b₀) + (emptyFreeEquiv n b₀) b) = n := by + rw [CNF.totalIncidence_branchParityRowNeutralScope_eq] + have hzero : + totalIncidence + (univ : Finset (Fin (emptyRows n).length)) + ((emptyCNF n).branchParityRowScope (emptyRows n) + (heavyVars univ (univ : Finset (Fin (emptyRows n).length)) + (fun j => equationScope ((emptyCNF n).parityRowSystem (emptyRows n) j)) b₀) + (emptyFreeEquiv n b₀) b) = 0 := rfl + rw [hzero, zero_add] + +/-- Concrete witness at `n = 2 ^ (2 ^ 50)`, `β = 1`, `b₀ = 1`, `W = 0`, `k = 3`: +instantiates `Feasible.exists_branchParityRow_replacementDesign`, +`Feasible.branchParityRow_domainExaminationBound_le`, +`Feasible.greedyCandidate_domainExaminationBound_le`, and +`sum_branchParityRow_domainExaminationBound_le`. -/ +example : + ∃ m n : ℕ, + m = 2 ^ 50 ∧ + n = 2 ^ m ∧ + rowCost 1 n < 1 / 3 ∧ + let φ := emptyCNF n + let rows := emptyRows n + let S := heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) 1 + let e := emptyFreeEquiv n 1 + (∀ b : Fin n → Bool, + ∃ (hF : Feasible 1 n 2 (max 1 (3 * (0 * 2 ^ 3))) + (totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n)) + (φ.branchParityRowNeutralScope rows S e b))) + (D : ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) + (numNodes n) (numGroups n) (intervalStart 1 n) (rowBound 1 n) (tauRat n)), + let d := 3 * (rows.length + 2 * (branchPrecision (Fintype.card (Fin n)) - 1)) + let q := (d * rowBound 1 n) / numNodes n + let C := hF.toCountingDesign D univ + (∑ t : Fin (numNodes n), + (#{p : Finset (Fin n) × Finset (Fin n) | #p.1 ≤ q ∧ p.2 ⊆ p.1} : ℝ) * + (2 * (#(C.measurementBox t) : ℝ) * + ∑ g : Fin (numGroups n), (Fintype.card (C.LocalCube t g) : ℝ))) ≤ + 2 * (numNodes n : ℝ) * (numGroups n : ℝ) * + Real.exp (((16 * 3 + 4 : ℕ) : ℝ) * (n : ℝ) * rowCost 1 n)) ∧ + Fintype.card (Fin n) ≤ 2 * n := by + obtain ⟨m, hm⟩ : ∃ m : ℕ, m = 2 ^ 50 := ⟨2 ^ 50, rfl⟩ + obtain ⟨n, hn⟩ : ∃ n : ℕ, n = 2 ^ m := ⟨2 ^ m, rfl⟩ + have hcl_n : Nat.clog 2 n = 2 ^ 50 := by + rw [hn, Nat.clog_pow 2 m one_lt_two, hm] + have hcl_cl : Nat.clog 2 (Nat.clog 2 n) = 50 := by + rw [hcl_n] + exact Nat.clog_pow 2 50 one_lt_two + have hr_eq : numGroups n = 13421 := by + unfold numGroups + rw [hcl_cl, hcl_n] + have hsq : (2 ^ 50 : ℕ).sqrt = 2 ^ 25 := + le_antisymm (Nat.lt_succ_iff.mp (Nat.sqrt_lt.mpr (by norm_num))) + (Nat.le_sqrt.mpr (by norm_num)) + rw [hsq] + norm_num + have hQ_eq : numNodes n = 175921860444 := by + unfold numNodes + rw [hcl_cl, hcl_n] + norm_num + have hR_eq : rowBound 1 n = 134217728 := by + unfold rowBound + rw [hcl_n] + have hsq : (2 ^ 50 - 1 : ℕ).sqrt = 2 ^ 25 - 1 := + le_antisymm (Nat.lt_succ_iff.mp (Nat.sqrt_lt.mpr (by norm_num))) + (Nat.le_sqrt.mpr (by norm_num)) + simp only [show (2 ^ 50 : ℕ) ≠ 0 by positivity, ↓reduceIte, hsq] + norm_num + have hr : 2 ≤ numGroups n := by rw [hr_eq]; norm_num + have hR : 32 ≤ rowBound 1 n := by rw [hR_eq]; norm_num + have hRQ : 6 * rowBound 1 n ≤ numNodes n := by rw [hR_eq, hQ_eq]; norm_num + have hsub := interval_subset_range (β := 1) hr (by omega) (by omega) + have hrc := rowCost_le hr hR hRQ + have hrc_lt : rowCost 1 n < 1 / 3 := hrc.trans_lt <| by + rw [hcl_cl, hcl_n, show ((2 ^ 50 : ℕ) : ℝ) = ((2 : ℝ) ^ 25) ^ 2 by norm_num, + Real.sqrt_sq (by positivity)] + norm_num + have hF_base : Feasible 1 n 2 1 n := { + twenty_le := by + rw [hn] + exact (by norm_num : 20 ≤ 2 ^ 5).trans + (Nat.pow_le_pow_right two_pos (by rw [hm]; norm_num)) + two_le_numGroups := hr + thirtyTwo_le_rowBound := hR + six_mul_rowBound_le_numNodes := hRQ + tau_pos := by unfold tau; rw [hr_eq, hcl_n]; positivity + tau_le_half := by unfold tau; rw [hr_eq, hcl_n]; norm_num + auxDim_le := auxDim_le_two_pow n + aux_balance := + (Nat.mul_le_mul_left 6 (Nat.pow_le_pow_left (auxDim_le_two_pow n) 2)).trans <| by + have h6 : 6 ≤ 2 ^ 3 := by decide + refine (Nat.mul_le_mul_right _ h6).trans ?_ + rw [← pow_mul, ← pow_add, hn] + exact Nat.pow_le_pow_right two_pos + (by rw [Nat.clog_pow 2 m one_lt_two, hm]; norm_num) + var_balance := by + rw [hQ_eq, hr_eq, hn] + exact (by norm_num : 2 * 175921860444 * 13421 ^ 2 ≤ 2 ^ 66).trans + (Nat.pow_le_pow_right two_pos (by rw [hm]; norm_num)) + card_interval_eq := card_interval (by omega) + interval_subset := hsub + mem_interval_of_close := fun k hk => + ⟨mem_interval_of_abs_sub_le hr hR (by omega) hk, + Nat.lt_succ_iff.mp + (mem_range.mp (hsub (mem_interval_of_abs_sub_le hr hR (by omega) hk)))⟩ + binomTail_lt := + binomTail_lt_tailBudget le_rfl hr hR hRQ (by decide) (by rw [hcl_n]; norm_num) + rowCost_bound := hrc + } + refine ⟨m, n, hm, hn, hrc_lt, ?_⟩ + intro φ rows S e + have hM : + totalIncidence (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) * 2 ≤ + 1 * Fintype.card (Fin n) := by + have hzero : + totalIncidence (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) = 0 := rfl + rw [hzero, zero_mul] + exact Nat.zero_le _ + have hsum := sum_branchParityRow_domainExaminationBound_le φ rows + (β := 1) (b₀ := 1) (s_div := 2) (k := 3) (c := 6) + le_rfl le_rfl hM e (fun _ => 0) (fun _ _ => by positivity) + refine ⟨fun b => ?_, hsum.1⟩ + have hF_b : Feasible 1 n 2 (max 1 (3 * (0 * 2 ^ 3))) + (totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n)) + (φ.branchParityRowNeutralScope rows S e b)) := by + rw [totalIncidence_empty_branchParityRowNeutralScope n 1 b] + exact hF_base + have hk : ∀ c ∈ φ, c.length ≤ 3 := fun _ hc => False.elim (List.not_mem_nil hc) + have hW : ∀ r_row ∈ rows, weight r_row ≤ 0 := fun _ hr_row => False.elim (List.not_mem_nil hr_row) + obtain ⟨D⟩ := hF_b.exists_branchParityRow_replacementDesign hk hW e b + refine ⟨hF_b, D, ?_⟩ + have hm_rows : rows.length ≤ 6 * Fintype.card (Fin n) := Nat.zero_le _ + exact (hF_b.greedyCandidate_domainExaminationBound_le (k := 3) φ rows D univ hm_rows hsum.1).1 + +/-! ### 3. Instantiation of uniform schedule recovery theorems at `β = 1` -/ + +/-- Nonvacuous instantiation of `exists_schedule_branchParityRow_replacementDesign`, +`exists_schedule_design_commonZeroCount_parityRowSystem_eq`, +`exists_schedule_design_numPassing_eq`, +`exists_schedule_design_modelCountOn_eq_greedy`, and +`exists_initialTests_and_schedule_design_modelCountOn_eq` at `β = 1`. -/ +example : + (∃ n₀ : ℕ, 20 ≤ n₀) ∧ + (∃ n₁ : ℕ, 20 ≤ n₁) ∧ + (∃ n₂ : ℕ, 20 ≤ n₂) ∧ + (∃ n₃ : ℕ, 20 ≤ n₃) ∧ + (∃ n₄ : ℕ, 20 ≤ n₄) := by + obtain ⟨n₀, hn₀, _⟩ := exists_schedule_branchParityRow_replacementDesign.{0} (β := 1) le_rfl + obtain ⟨n₁, hn₁, _⟩ := + exists_schedule_design_commonZeroCount_parityRowSystem_eq.{0} (β := 1) le_rfl + obtain ⟨n₂, hn₂, _⟩ := exists_schedule_design_numPassing_eq.{0} (β := 1) le_rfl + obtain ⟨n₃, hn₃, _⟩ := exists_schedule_design_modelCountOn_eq_greedy.{0} (β := 1) le_rfl + obtain ⟨n₄, hn₄, _⟩ := + exists_initialTests_and_schedule_design_modelCountOn_eq.{0} (β := 1) le_rfl + exact ⟨⟨n₀, hn₀⟩, ⟨n₁, hn₁⟩, ⟨n₂, hn₂⟩, ⟨n₃, hn₃⟩, ⟨n₄, hn₄⟩⟩ + +end Cslib.Complexity.SubexponentialSAT.SparseCNFDesignScheduleTests From 0d8c600039a91d92aa3c7974fe3004530c6f46a9 Mon Sep 17 00:00:00 2001 From: Samuel Giuseppe Schlesinger Date: Tue, 27 Oct 2026 01:39:08 -0400 Subject: [PATCH 18/20] doc(FineGrained): distinguish equation ratio from source sparsity parameter --- .../Complexity/FineGrained/SparseParitySchedule.lean | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Complexity/Computability/Complexity/FineGrained/SparseParitySchedule.lean b/Complexity/Computability/Complexity/FineGrained/SparseParitySchedule.lean index c68ba86ce1..95ba9d34b3 100644 --- a/Complexity/Computability/Complexity/FineGrained/SparseParitySchedule.lean +++ b/Complexity/Computability/Complexity/FineGrained/SparseParitySchedule.lean @@ -23,8 +23,10 @@ Theorem 2.2, printed pp. 38–39): 1. **Incidence, free-variable, and scope-width bounds for `CNF.parityRowSystem` (§6.3, p. 43)**: In Lemma 6.2 and Section 6.3, every candidate parity-row list `rows : List (Fin φ.length → Bool)` - (as well as the final list `A (3 * n)`) has at most `6 * Fintype.card V` equations ($c = 6$ in - Theorem 2.2) and row Hamming weight at most `W` (with `W = max D₀ P`). For any width-`≤ k` CNF + (as well as the final list `A (3 * n)`) has at most `6 * Fintype.card V` equations, giving + equation-count ratio `6`, and row Hamming weight at most `W` (with `W = max D₀ P`). Theorem 2.2 + uses a sufficiently large `c = c(k)` to bound both the equation count and monomial sparsity. + For any width-`≤ k` CNF `φ : CNF V`: - `CNF.totalIncidence_parityRowSystem_le_six_mul`: when `rows.length ≤ 6 * Fintype.card V` and `∀ r ∈ rows, weight r ≤ W`, total variable-equation incidence across `φ.parityRowSystem rows` From b0323d24bbd7fd796c03355b6ad63c0e0112564e Mon Sep 17 00:00:00 2001 From: Samuel Schlesinger Date: Tue, 27 Oct 2026 05:55:47 +0000 Subject: [PATCH 19/20] refactor(FineGrained): consume SparseParitySchedule in SparseCNFDesignSchedule (#1226) --- .../FineGrained/SparseCNFDesignSchedule.lean | 1171 ++++++++--------- .../FineGrained/SparseCNFDesignSchedule.lean | 348 ++--- 2 files changed, 632 insertions(+), 887 deletions(-) diff --git a/Complexity/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean b/Complexity/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean index 6895409ab6..8fd3d3c52c 100644 --- a/Complexity/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean +++ b/Complexity/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean @@ -8,698 +8,595 @@ module -- upstream: candidate public import Complexity.Init -public import Complexity.Computability.Complexity.FineGrained.ReplacementScheduleDesign +public import Complexity.Computability.Complexity.FineGrained.SparseParitySchedule public import Complexity.Logics.Propositional.CNF.SparseDesignCounter /-! -# Section 6.3 Lemma 4.8 schedule instantiation for compiled CNF sparse parity-design counters - -This module bridges the compiled CNF sparse parity-design counter of -`Complexity.Logics.Propositional.CNF.SparseDesignCounter` (Sections 5.4–5.5 and 6.1–6.3 of -[OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH]) with the concrete Lemma 4.7 / -Lemma 4.8 parameter schedule `(numNodes n', numGroups n', intervalStart β n', rowBound β n', -tauRat n')` and Proposition 3.4 domain-examination bounds of -`Complexity.Computability.Complexity.FineGrained.ReplacementScheduleDesign` (Sections 3.5 and -4.6–4.7): - -1. **Per-branch and uniform Lemma 4.7 + Lemma 4.8 `ReplacementDesign` existence on - `CNF.branchParityRowNeutralScope` (§5.5 & §6.3, pp. 38–39, 43):** - - `Feasible.exists_branchParityRow_replacementDesign`: on any heavy-variable branch - `b : V → Bool` of `S = heavyVars univ univ (fun j => equationScope (φ.parityRowSystem rows j)) - b₀` with free-variable relabeling `e : ↥(univ \ S) ≃ Fin n'`, if every clause of `φ` has width - at most `k`, every row in `rows` has Hamming weight at most `W`, and - `hF : Feasible β n' (b₀ + 1) (max 1 (k * (W * 2 ^ k))) M'_b` holds, then there exists a - concrete Section 4 - `ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) (numNodes n') (numGroups n') - (intervalStart β n') (rowBound β n') (tauRat n')`. - - `exists_schedule_branchParityRow_replacementDesign`: uniformly for any `1 ≤ β`, produces - `n₀ ≥ 20` (via `exists_schedule_replacementDesign`) such that whenever `n₀ ≤ n'`, - `b₀ + 1 ≤ (Nat.clog 2 n') ^ β`, `max 1 (k * (W * 2 ^ k)) ≤ (Nat.clog 2 n') ^ β`, - `∀ c ∈ φ, c.length ≤ k`, and `∀ r_row ∈ rows, weight r_row ≤ W`, **every** branch - `b : V → Bool` simultaneously satisfies - `Feasible β n' (b₀ + 1) (max 1 (k * (W * 2 ^ k))) M'_b` and admits a concrete schedule - `ReplacementDesign`, with all per-branch incidence bounds (`n' ≤ M'_b`, - `M'_b ≤ (b₀ + 1) * n'`, per-variable occurrence `≤ b₀ + 1`, and per-factor width - `≤ max 1 (k * (W * 2 ^ k))`) discharged automatically. - -2. **Schedule-instantiated `commonZeroCount`, `numPassing`, and greedy `modelCountOn` recovery - (§§5.4–5.5, 6.1–6.3, pp. 38–43):** - - `exists_schedule_design_commonZeroCount_parityRowSystem_eq` and - `exists_schedule_design_numPassing_eq`: under the uniform polylogarithmic schedule hypotheses, - exhibits a concrete family `D` of Lemma 4.8 schedule `ReplacementDesign`s across all branches - `b : V → Bool` whose branch-summed constant-term evaluation of - `univariateClearedParityTruncatedSum` recovers `commonZeroCount univ (φ.parityRowSystem rows)` - and `numPassing φ.violations rows`, with each branch numerator of degree at most - `(k * (rowBound β n' - 1)) * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1))`. - - `exists_schedule_design_modelCountOn_eq_greedy` and - `exists_initialTests_and_schedule_design_modelCountOn_eq`: combines Lemma 6.1 (initial parity - tests of weight `≤ D₀`), Lemma 6.2 (`3 * n` greedy rounds of list length `P ≤ D₀`), and the - uniform Lemma 4.8 schedule threshold `n₀ ≤ n'` to recover `φ.modelCountOn Finset.univ` from - concrete Lemma 4.8 schedule `ReplacementDesign`s with numerator degree at most - `(k * (rowBound β n' - 1)) * (8 * Fintype.card V)`. - -3. **Section 6.3 (`c = 6`) candidate/final degree budgets and Proposition 3.4 / Lemma 4.8 - domain-examination bounds (§5.5 & §6.3, pp. 38–39, 43):** - - `branchParityRowDegreeBudget_le` and `greedyCandidateDegreeBudget_le`: when - `rows.length ≤ c * Fintype.card V` (in particular `c = 6` for every Lemma 6.2 candidate and - final system) and `Fintype.card V ≤ 2 * n'`, the pre-replacement degree factor - `d = k * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1))` is at most - `(k * (2 * c + 4)) * n'` (and `(16 * k) * n'` when `c = 6`). - - `Feasible.branchParityRow_domainExaminationBound_le`, - `Feasible.greedyCandidate_domainExaminationBound_le`, and - `sum_branchParityRow_domainExaminationBound_le`: bounds the per-branch and branch-summed - Proposition 3.4 local Boolean assignment examination counts on compiled CNF parity systems by - `2 * numNodes n' * numGroups n' * exp (((k * (2 * c + 4) + 4) : ℝ) * n' * rowCost β n')` per - branch and `2 ^ (Fintype.card V / s_div)` times that bound across all `branchAssignments S`. +# Schedule-Instantiated Exact Recovery for the CNF Sparse Parity-Design Counter + +This module composes the Section 6.3 compiled parity-row schedule supplier of +`Complexity.Computability.Complexity.FineGrained.SparseParitySchedule` with the `ReplacementDesign` +constant-term recovery and univariate numerator degree bounds of +`Complexity.Logics.Propositional.CNF.SparseDesignCounter`, following Sections 5.4–5.5 and 6.1–6.3 +(printed pp. 38–43) of [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH]: + +1. **Index-equivalence bridge between `Fin m ⊕ Fin n'` and `{j : Fin m // j ∈ univ} ⊕ Fin n'`**: + - `CNF.parityRowAugmentedIndexEquiv`: canonical equivalence + `Fin m ⊕ Fin n' ≃ {j : Fin m // j ∈ (univ : Finset (Fin m))} ⊕ Fin n'`. + - `CNF.parityRowAugmentedInl`: active-equation factor embedding into `{j // j ∈ univ} ⊕ Fin n'`. + - `CNF.branchAugmentedScope_parityRowSystem_comp_equiv_inl` and + `CNF.branchAugmentedScope_parityRowSystem_comp_equiv_inr`: evaluate + `branchAugmentedScope S e univ (φ.parityRowSystem rows) b` along + `CNF.parityRowAugmentedIndexEquiv`. +2. **Schedule-instantiated exact recovery of `commonZeroCount` and `numPassing` (§5.4–5.5 & §6.3)**: + - `CNF.exists_schedule_design_commonZeroCount_parityRowSystem_eq` and + `CNF.exists_schedule_design_numPassing_eq`: combine + `CNF.exists_branch_schedule_parityRowSystem` with + `CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design` and + `CNF.numPassing_eq_sum_branch_emod_ediv_design` under polylogarithmic schedule bounds. + - `CNF.exists_schedule_design_commonZeroCount_parityRowSystem_of_le_clog_pow` and + `CNF.exists_schedule_design_numPassing_of_le_clog_pow`: combine the unconditional + polylogarithmic schedule supplier `CNF.exists_branch_schedule_parityRowSystem_of_le_clog_pow` + (`B ≤ C_B * (Nat.clog 2 n) ^ β_B`, `b₀ = CNF.parityBranchThreshold k W n`, + `β = 2 * β_B + 5`) with exact branch-summed constant-term recovery and numerator degree bounds. +3. **End-to-end greedy `modelCountOn` schedule-design recovery (§6.1–6.3)**: + - `CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_eq`: combines + `CNF.exists_greedy_parityRowSystem_branch_schedule` with exact branch-summed constant-term + recovery of `φ.modelCountOn Finset.univ` and the `(k * (rowBound β n' - 1)) * (8 * n)` + numerator degree bound after `3 * n` greedy rounds. + - `CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_of_le_clog_pow`: combines + `CNF.exists_greedy_parityRowSystem_branch_schedule_of_le_clog_pow` with exact branch-summed + constant-term recovery of `φ.modelCountOn Finset.univ` unconditionally for any width-`≤ k` CNF + with `φ.length ≤ B * n` and `B ≤ C_B * (Nat.clog 2 n) ^ β_B`. + +## Main definitions + +* `Cslib.Logic.PL.CNF.parityRowAugmentedIndexEquiv` +* `Cslib.Logic.PL.CNF.parityRowAugmentedInl` ## Main results -* `Feasible.exists_branchParityRow_replacementDesign` -* `exists_schedule_branchParityRow_replacementDesign` -* `exists_schedule_design_commonZeroCount_parityRowSystem_eq` -* `exists_schedule_design_numPassing_eq` -* `exists_schedule_design_modelCountOn_eq_greedy` -* `exists_initialTests_and_schedule_design_modelCountOn_eq` -* `branchParityRowDegreeBudget_le` -* `greedyCandidateDegreeBudget_le` -* `Feasible.branchParityRow_domainExaminationBound_le` -* `Feasible.greedyCandidate_domainExaminationBound_le` -* `sum_branchParityRow_domainExaminationBound_le` +* `Cslib.Logic.PL.CNF.branchAugmentedScope_parityRowSystem_comp_equiv_inl` +* `Cslib.Logic.PL.CNF.branchAugmentedScope_parityRowSystem_comp_equiv_inr` +* `Cslib.Logic.PL.CNF.exists_schedule_design_commonZeroCount_parityRowSystem_eq` +* `Cslib.Logic.PL.CNF.exists_schedule_design_numPassing_eq` +* `Cslib.Logic.PL.CNF.exists_schedule_design_commonZeroCount_parityRowSystem_of_le_clog_pow` +* `Cslib.Logic.PL.CNF.exists_schedule_design_numPassing_of_le_clog_pow` +* `Cslib.Logic.PL.CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_eq` +* `Cslib.Logic.PL.CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_of_le_clog_pow` ## References -* [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] (Section 3.5, pp. 25–26; - Section 4.6–4.7, pp. 33–35; Section 5.4–5.5, pp. 38–39; Section 6.1–6.3, pp. 40–43) +* [OpenAI, *The Exponential Time Hypothesis is False*][OpenAI2026ETH] + (Sections 5.4–5.5, pp. 38–39; Sections 6.1–6.3, pp. 39–43) -/ -@[expose] public noncomputable section +public section -namespace Cslib.Complexity.SubexponentialSAT.ReplacementParams +namespace Cslib.Logic.PL -open Finset Polynomial Cslib.BitString Cslib.BalancedSchedules Cslib.LinearAlgebra - Cslib.ReplacementCounting Cslib.Logic.PL -open scoped BigOperators +open Finset +open Cslib.BitString +open Cslib.LinearAlgebra +open Cslib.Complexity.SubexponentialSAT.ReplacementParams variable {V : Type*} {n' : ℕ} -/-! ### 1. Per-branch and uniform Lemma 4.8 schedule `ReplacementDesign` existence -/ - -section BranchScheduleExistence - -variable [Fintype V] [DecidableEq V] - -/-- **§5.5 & §6.3 (per-branch Lemma 4.7 + Lemma 4.8 schedule `ReplacementDesign` existence on -`CNF.branchParityRowNeutralScope`)**: if every clause of `φ` has width at most `k`, every row in -`rows` has Hamming weight at most `W`, and at `S = heavyVars univ univ (fun j => equationScope -(φ.parityRowSystem rows j)) b₀` with free-variable relabeling `e : ↥(univ \ S) ≃ Fin n'` the -schedule parameters satisfy `Feasible β n' (b₀ + 1) (max 1 (k * (W * 2 ^ k))) M'_b`, then branch `b` -admits a concrete Section 4 -`ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) (numNodes n') (numGroups n') -(intervalStart β n') (rowBound β n') (tauRat n')`. -/ -theorem Feasible.exists_branchParityRow_replacementDesign {φ : CNF V} {β k W b₀ : ℕ} - (hk : ∀ c ∈ φ, c.length ≤ k) {rows : List (Fin φ.length → Bool)} - (hW : ∀ r_row ∈ rows, weight r_row ≤ W) - (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n') - (b : V → Bool) - (hF : Feasible β n' (b₀ + 1) (max 1 (k * (W * 2 ^ k))) - (totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n')) - (φ.branchParityRowNeutralScope rows - (heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀) - e b))) : - Nonempty - (ReplacementDesign - (φ.branchParityRowNeutralScope rows - (heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀) - e b) - (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n')) := - hF.exists_replacementDesign _ (Nat.succ_pos b₀) (le_max_left 1 _) - (CNF.varIncidence_branchParityRowNeutralScope_heavyVars_le φ rows b₀ e b) - (CNF.card_branchParityRowNeutralScope_le hk hW _ e b) - (CNF.totalIncidence_branchParityRowNeutralScope_heavyVars_le φ rows b₀ e b) - -/-- **§5.5 & §6.3 (uniform Lemma 4.7 + Lemma 4.8 schedule `ReplacementDesign` existence across all -heavy-variable branches of `φ.parityRowSystem rows`)**: for every integer `1 ≤ β`, there exists -`n₀ ≥ 20` such that whenever the free-variable count `n'` satisfies `n₀ ≤ n'`, the heavy-variable -threshold satisfies `b₀ + 1 ≤ (Nat.clog 2 n') ^ β`, the neutral-augmented scope width bound -satisfies `max 1 (k * (W * 2 ^ k)) ≤ (Nat.clog 2 n') ^ β`, every clause of `φ` has width at most -`k`, and every row in `rows` has Hamming weight at most `W`, **every** branch assignment -`b : V → Bool` simultaneously satisfies `Feasible` and admits a concrete Lemma 4.8 schedule -`ReplacementDesign`. -/ -theorem exists_schedule_branchParityRow_replacementDesign {β : ℕ} (hβ : 1 ≤ β) : - ∃ n₀ : ℕ, 20 ≤ n₀ ∧ - ∀ {V : Type*} [Fintype V] [DecidableEq V] {φ : CNF V} {k W b₀ n' : ℕ} - {rows : List (Fin φ.length → Bool)} - (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n'), - n₀ ≤ n' → - b₀ + 1 ≤ Nat.clog 2 n' ^ β → - max 1 (k * (W * 2 ^ k)) ≤ Nat.clog 2 n' ^ β → - (∀ c ∈ φ, c.length ≤ k) → - (∀ r_row ∈ rows, weight r_row ≤ W) → - ∀ b : V → Bool, - Feasible β n' (b₀ + 1) (max 1 (k * (W * 2 ^ k))) - (totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n')) - (φ.branchParityRowNeutralScope rows - (heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀) - e b)) ∧ - Nonempty - (ReplacementDesign - (φ.branchParityRowNeutralScope rows - (heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀) - e b) - (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n')) := by - obtain ⟨n₀, hn₀20, hsched⟩ := exists_schedule_replacementDesign hβ - refine ⟨n₀, hn₀20, fun {V _ _ φ k W b₀ n' rows} e hn' hb hw hk hW b => ?_⟩ - exact hsched - (φ.branchParityRowNeutralScope rows - (heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀) - e b) - hn' (Nat.succ_pos b₀) hb (le_max_left 1 _) hw - (CNF.le_totalIncidence_branchParityRowNeutralScope φ rows _ e b) - (CNF.totalIncidence_branchParityRowNeutralScope_heavyVars_le φ rows b₀ e b) - (CNF.varIncidence_branchParityRowNeutralScope_heavyVars_le φ rows b₀ e b) - (CNF.card_branchParityRowNeutralScope_le hk hW _ e b) - -end BranchScheduleExistence - -/-! ### 2. End-to-end Lemma 4.8 schedule `ReplacementDesign` recovery of `numPassing` and `#F` -/ - -section ScheduleDesignRecovery - -variable [Fintype V] [DecidableEq V] - -/-- **§5.4–5.5 & §6.3 (schedule-instantiated `commonZeroCount` recovery on `φ.parityRowSystem`)**: -for every `1 ≤ β`, there exists `n₀ ≥ 20` such that whenever `n₀ ≤ n'`, -`b₀ + 1 ≤ (Nat.clog 2 n') ^ β`, `max 1 (k * (W * 2 ^ k)) ≤ (Nat.clog 2 n') ^ β`, +/-! ### 1. Index-equivalence bridge between `Fin m ⊕ Fin n'` and `{j // j ∈ univ} ⊕ Fin n'` -/ + +/-- Canonical equivalence between the flat factor index `Fin m ⊕ Fin n'` of +`CNF.branchParityRowNeutralScope` and the active-subtype factor index +`{j : Fin m // j ∈ (univ : Finset (Fin m))} ⊕ Fin n'` of `branchAugmentedScope`. -/ +@[expose] +def CNF.parityRowAugmentedIndexEquiv (m n' : ℕ) : + Fin m ⊕ Fin n' ≃ {j : Fin m // j ∈ (univ : Finset (Fin m))} ⊕ Fin n' := + Equiv.sumCongr (Equiv.subtypeUnivEquiv mem_univ).symm (Equiv.refl (Fin n')) + +/-- Active-equation factor embedding `Fin m → {j : Fin m // j ∈ univ} ⊕ Fin n'` into the left +summand of `branchAugmentedScope`. -/ +@[expose] +def CNF.parityRowAugmentedInl {m n' : ℕ} (j : Fin m) : + {j : Fin m // j ∈ (univ : Finset (Fin m))} ⊕ Fin n' := + Sum.inl ⟨j, mem_univ j⟩ + +@[simp] +theorem CNF.parityRowAugmentedIndexEquiv_inl {m n' : ℕ} (j : Fin m) : + CNF.parityRowAugmentedIndexEquiv m n' (Sum.inl j) = CNF.parityRowAugmentedInl j := + rfl + +@[simp] +theorem CNF.parityRowAugmentedIndexEquiv_inr {m n' : ℕ} (v : Fin n') : + CNF.parityRowAugmentedIndexEquiv m n' (Sum.inr v) = Sum.inr v := + rfl + +/-- Evaluating `branchAugmentedScope S e univ (φ.parityRowSystem rows) b` at +`CNF.parityRowAugmentedInl j` yields `branchEquationScope S e (φ.parityRowSystem rows) b j`. -/ +@[simp] +theorem CNF.branchAugmentedScope_parityRowAugmentedInl [Fintype V] [DecidableEq V] + (φ : CNF V) (rows : List (Fin φ.length → Bool)) (S : Finset V) + (e : ↥(univ \ S) ≃ Fin n') (b : V → Bool) (j : Fin rows.length) : + branchAugmentedScope S e univ (φ.parityRowSystem rows) b (CNF.parityRowAugmentedInl j) = + branchEquationScope S e (φ.parityRowSystem rows) b j := + branchAugmentedScope_inl S e univ (φ.parityRowSystem rows) b ⟨j, mem_univ j⟩ + +/-- Evaluating `branchAugmentedScope S e univ (φ.parityRowSystem rows) b` at +`CNF.parityRowAugmentedIndexEquiv rows.length n' (Sum.inl j)` yields +`branchEquationScope S e (φ.parityRowSystem rows) b j`. -/ +theorem CNF.branchAugmentedScope_parityRowSystem_comp_equiv_inl [Fintype V] [DecidableEq V] + (φ : CNF V) (rows : List (Fin φ.length → Bool)) (S : Finset V) + (e : ↥(univ \ S) ≃ Fin n') (b : V → Bool) (j : Fin rows.length) : + branchAugmentedScope S e univ (φ.parityRowSystem rows) b + (CNF.parityRowAugmentedIndexEquiv rows.length n' (Sum.inl j)) = + branchEquationScope S e (φ.parityRowSystem rows) b j := + branchAugmentedScope_inl S e univ (φ.parityRowSystem rows) b ⟨j, mem_univ j⟩ + +/-- Evaluating `branchAugmentedScope S e univ (φ.parityRowSystem rows) b` at +`CNF.parityRowAugmentedIndexEquiv rows.length n' (Sum.inr v)` yields the neutral singleton scope +`{v}`. -/ +theorem CNF.branchAugmentedScope_parityRowSystem_comp_equiv_inr [Fintype V] [DecidableEq V] + (φ : CNF V) (rows : List (Fin φ.length → Bool)) (S : Finset V) + (e : ↥(univ \ S) ≃ Fin n') (b : V → Bool) (v : Fin n') : + branchAugmentedScope S e univ (φ.parityRowSystem rows) b + (CNF.parityRowAugmentedIndexEquiv rows.length n' (Sum.inr v)) = {v} := + branchAugmentedScope_inr S e univ (φ.parityRowSystem rows) b v + +/-! ### 2. Schedule-instantiated exact recovery of `commonZeroCount` and `numPassing` -/ + +/-- **§5.4–5.5 & §6.3 (schedule-instantiated `ReplacementDesign` recovery of `commonZeroCount` on +`φ.parityRowSystem rows`)**: for every `1 ≤ β`, the threshold `n₀ ≥ 20` of +`CNF.exists_branch_schedule_parityRowSystem` guarantees that whenever `n₀ ≤ n'`, +`b₀ + 1 ≤ (Nat.clog 2 n') ^ β`, `max (k * (W * 2 ^ k)) 1 ≤ (Nat.clog 2 n') ^ β`, `∀ c ∈ φ, c.length ≤ k`, and `∀ r_row ∈ rows, weight r_row ≤ W`, there exists a family `D` of -concrete Lemma 4.8 schedule `ReplacementDesign`s across all branches `b : V → Bool` whose -branch-summed constant-term evaluation recovers -`(commonZeroCount univ (φ.parityRowSystem rows) : ℤ)` and whose univariate numerators have degree at -most `(k * (rowBound β n' - 1)) * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1))`. -/ -theorem exists_schedule_design_commonZeroCount_parityRowSystem_eq {β : ℕ} (hβ : 1 ≤ β) : +concrete Lemma 4.8 schedule `ReplacementDesign`s across all branches `b : V → Bool` (with every +branch satisfying `Feasible`) such that the branch-summed modular evaluation of +`univariateClearedParityTruncatedSum` at `T = 0` equals +`(commonZeroCount univ (φ.parityRowSystem rows) : ℤ)` and every branch numerator has degree at most +`(k * (rowBound β n' - 1)) * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1))`. -/ +theorem CNF.exists_schedule_design_commonZeroCount_parityRowSystem_eq {β : ℕ} (hβ : 1 ≤ β) : ∃ n₀ : ℕ, 20 ≤ n₀ ∧ - ∀ {V : Type*} [Fintype V] [DecidableEq V] {φ : CNF V} {k W b₀ n' : ℕ} - {rows : List (Fin φ.length → Bool)} - (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n'), - n₀ ≤ n' → - b₀ + 1 ≤ Nat.clog 2 n' ^ β → - max 1 (k * (W * 2 ^ k)) ≤ Nat.clog 2 n' ^ β → + ∀ {V : Type*} [Fintype V] [DecidableEq V] + {φ : CNF V} ⦃n' k W b₀ : ℕ⦄, (∀ c ∈ φ, c.length ≤ k) → - (∀ r_row ∈ rows, weight r_row ≤ W) → - let S := heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀ - (∀ b : V → Bool, - Feasible β n' (b₀ + 1) (max 1 (k * (W * 2 ^ k))) - (totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n')) - (φ.branchParityRowNeutralScope rows S e b))) ∧ - ∃ D : (b : V → Bool) → - ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) - (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n'), - (commonZeroCount (univ : Finset (Fin rows.length)) (φ.parityRowSystem rows) : ℤ) = - (∑ b ∈ branchAssignments S, - ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) - (φ.branchParityRowSystem rows S e b) - (commonDenom (numNodes n') (rowBound β n') : ℤ) k - (branchPrecision (Fintype.card V)) - (designReplacementScaledIntMap (D b) Sum.inl)).eval 0 / - clearedProductDenom (commonDenom (numNodes n') (rowBound β n') : ℤ) k + ∀ {rows : List (Fin φ.length → Bool)}, + (∀ r_row ∈ rows, weight r_row ≤ W) → + let S := heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀ + ∀ (e : ↥(univ \ S) ≃ Fin n'), + n₀ ≤ n' → + b₀ + 1 ≤ Nat.clog 2 n' ^ β → + max (k * (W * 2 ^ k)) 1 ≤ Nat.clog 2 n' ^ β → + (∀ b : V → Bool, + Feasible β n' (b₀ + 1) (max (k * (W * 2 ^ k)) 1) + (∑ f : {j : Fin rows.length // j ∈ (univ : Finset (Fin rows.length))} ⊕ Fin n', + #(branchAugmentedScope S e univ (φ.parityRowSystem rows) b f))) ∧ + ∃ D : (b : V → Bool) → + ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) + (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n'), + (commonZeroCount (univ : Finset (Fin rows.length)) (φ.parityRowSystem rows) : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound β n') : ℤ) k (branchPrecision (Fintype.card V)) - #(univ : Finset (Fin rows.length))) % - ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ - ∀ b : V → Bool, - (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) - (φ.branchParityRowSystem rows S e b) - (commonDenom (numNodes n') (rowBound β n') : ℤ) k - (branchPrecision (Fintype.card V)) - (designReplacementScaledIntMap (D b) Sum.inl)).natDegree ≤ + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).eval 0 / + clearedProductDenom (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ + ∀ b : V → Bool, + (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).natDegree ≤ (k * (rowBound β n' - 1)) * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1)) := by - obtain ⟨n₀, hn₀20, hsched⟩ := exists_schedule_branchParityRow_replacementDesign hβ - refine ⟨n₀, hn₀20, fun {V _ _ φ k W b₀ n' rows} e hn' hb hw hk hW => ?_⟩ - intro S - have hbranch := hsched e hn' hb hw hk hW - refine ⟨fun b => (hbranch b).1, ?_⟩ + obtain ⟨n₀, hn₀20, hsched⟩ := CNF.exists_branch_schedule_parityRowSystem hβ + refine ⟨n₀, hn₀20, fun {V _ _ φ n' k W b₀} hk {rows} hW => ?_⟩ + intro S e hn' hb₀ hw + have h_all := hsched hk hW e hn' hb₀ hw let D : (b : V → Bool) → - ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) + ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n') := - fun b => Classical.choice (hbranch b).2 - refine ⟨D, ?_, ?_⟩ + fun b => Classical.choice (h_all b).2 + refine ⟨fun b => (h_all b).1, D, ?_, fun b => ?_⟩ · exact CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design hk rows S e - (φ.branchParityRowNeutralScope rows S e) D (fun _ => Sum.inl) - · intro b - exact CNF.natDegree_univariateClearedParityTruncatedSum_branchParityRowSystem_le hk rows S e b - (D b) Sum.inl (branchPrecision (Fintype.card V)) - -/-- **§5.4–5.5 & §6.3 (schedule-instantiated `numPassing` recovery on `φ.violations`)**: under the -same polylogarithmic schedule hypotheses, there exists a family `D` of concrete Lemma 4.8 schedule -`ReplacementDesign`s across all branches `b : V → Bool` whose branch-summed constant-term evaluation -recovers `(numPassing φ.violations rows : ℤ)`. -/ -theorem exists_schedule_design_numPassing_eq {β : ℕ} (hβ : 1 ≤ β) : + (fun b => branchAugmentedScope S e univ (φ.parityRowSystem rows) b) D + (fun _ => CNF.parityRowAugmentedInl) + · exact CNF.natDegree_univariateClearedParityTruncatedSum_branchParityRowSystem_le hk rows S e b + (D b) CNF.parityRowAugmentedInl (branchPrecision (Fintype.card V)) + +/-- **§5.4–5.5 & §6.3 (schedule-instantiated `ReplacementDesign` recovery of +`numPassing φ.violations rows`)**: under the hypotheses of +`CNF.exists_schedule_design_commonZeroCount_parityRowSystem_eq`, the branch-summed constant-term +evaluation from the schedule `ReplacementDesign` family `D` recovers +`(numPassing φ.violations rows : ℤ)`. -/ +theorem CNF.exists_schedule_design_numPassing_eq {β : ℕ} (hβ : 1 ≤ β) : ∃ n₀ : ℕ, 20 ≤ n₀ ∧ - ∀ {V : Type*} [Fintype V] [DecidableEq V] {φ : CNF V} {k W b₀ n' : ℕ} - {rows : List (Fin φ.length → Bool)} - (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n'), - n₀ ≤ n' → - b₀ + 1 ≤ Nat.clog 2 n' ^ β → - max 1 (k * (W * 2 ^ k)) ≤ Nat.clog 2 n' ^ β → + ∀ {V : Type*} [Fintype V] [DecidableEq V] + {φ : CNF V} ⦃n' k W b₀ : ℕ⦄, (∀ c ∈ φ, c.length ≤ k) → - (∀ r_row ∈ rows, weight r_row ≤ W) → - let S := heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀ - (∀ b : V → Bool, - Feasible β n' (b₀ + 1) (max 1 (k * (W * 2 ^ k))) - (totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n')) - (φ.branchParityRowNeutralScope rows S e b))) ∧ - ∃ D : (b : V → Bool) → - ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) - (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n'), - (numPassing φ.violations rows : ℤ) = - (∑ b ∈ branchAssignments S, - ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) - (φ.branchParityRowSystem rows S e b) - (commonDenom (numNodes n') (rowBound β n') : ℤ) k - (branchPrecision (Fintype.card V)) - (designReplacementScaledIntMap (D b) Sum.inl)).eval 0 / - clearedProductDenom (commonDenom (numNodes n') (rowBound β n') : ℤ) k + ∀ {rows : List (Fin φ.length → Bool)}, + (∀ r_row ∈ rows, weight r_row ≤ W) → + let S := heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀ + ∀ (e : ↥(univ \ S) ≃ Fin n'), + n₀ ≤ n' → + b₀ + 1 ≤ Nat.clog 2 n' ^ β → + max (k * (W * 2 ^ k)) 1 ≤ Nat.clog 2 n' ^ β → + (∀ b : V → Bool, + Feasible β n' (b₀ + 1) (max (k * (W * 2 ^ k)) 1) + (∑ f : {j : Fin rows.length // j ∈ (univ : Finset (Fin rows.length))} ⊕ Fin n', + #(branchAugmentedScope S e univ (φ.parityRowSystem rows) b f))) ∧ + ∃ D : (b : V → Bool) → + ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) + (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n'), + (numPassing φ.violations rows : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound β n') : ℤ) k (branchPrecision (Fintype.card V)) - #(univ : Finset (Fin rows.length))) % - ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ - ∀ b : V → Bool, - (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) - (φ.branchParityRowSystem rows S e b) - (commonDenom (numNodes n') (rowBound β n') : ℤ) k - (branchPrecision (Fintype.card V)) - (designReplacementScaledIntMap (D b) Sum.inl)).natDegree ≤ + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).eval 0 / + clearedProductDenom (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ + ∀ b : V → Bool, + (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).natDegree ≤ (k * (rowBound β n' - 1)) * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1)) := by - obtain ⟨n₀, hn₀20, hsched⟩ := exists_schedule_design_commonZeroCount_parityRowSystem_eq hβ - refine ⟨n₀, hn₀20, fun {V _ _ φ k W b₀ n' rows} e hn' hb hw hk hW => ?_⟩ - obtain ⟨hF, D, hcount, hdeg⟩ := hsched e hn' hb hw hk hW - rw [CNF.commonZeroCount_parityRowSystem] at hcount - exact ⟨hF, D, hcount, hdeg⟩ - -/-- If every row in `A 0` has Hamming weight at most `D₀` and each step appends `testRow (γ i)` of -list length `P`, then at every stage `j` every row in `A j` has Hamming weight at most -`max D₀ P`. -/ -theorem weight_le_max_of_append_testRow {m D₀ P : ℕ} - (A : ℕ → List (Fin m → Bool)) (hA₀ : ∀ r_row ∈ A 0, weight r_row ≤ D₀) - (γ : ℕ → Fin P → Fin m × Bool) (hA : ∀ i, A (i + 1) = A i ++ [testRow (γ i)]) : - ∀ (j : ℕ) (r_row : Fin m → Bool), r_row ∈ A j → weight r_row ≤ max D₀ P := by - intro j - induction j with - | zero => - exact fun r_row hr => (hA₀ r_row hr).trans (le_max_left D₀ P) - | succ j ih => - intro r_row hr - rw [hA j] at hr - rcases List.mem_append.mp hr with hr | hr - · exact ih r_row hr - · rw [List.mem_singleton.mp hr] - exact (weight_testRow_le (γ j)).trans (le_max_right D₀ P) - -/-- **§§5.4–5.5 & 6.2–6.3 (schedule-instantiated greedy `modelCountOn` recovery)**: for every -`1 ≤ β`, there exists `n₀ ≥ 20` such that under the hypotheses of -`CNF.commonZeroCount_parityRowSystem_greedy`, if every row of `A 0` has weight at most `D₀` and at -stage `3 * Fintype.card V` the free-variable count `n'` satisfies `n₀ ≤ n'`, -`b₀ + 1 ≤ (Nat.clog 2 n') ^ β`, and `max 1 (k * (max D₀ P * 2 ^ k)) ≤ (Nat.clog 2 n') ^ β`, then -there exists a concrete family `D` of Lemma 4.8 schedule `ReplacementDesign`s across all branches of -`A (3 * Fintype.card V)` whose branch-summed constant-term evaluation recovers -`(φ.modelCountOn Finset.univ : ℤ)`. -/ -theorem exists_schedule_design_modelCountOn_eq_greedy {β : ℕ} (hβ : 1 ≤ β) : - ∃ n₀ : ℕ, 20 ≤ n₀ ∧ - ∀ {V : Type*} [Fintype V] [DecidableEq V] (φ : CNF V) {k D₀ P b₀ n' : ℕ}, + obtain ⟨n₀, hn₀20, hsched⟩ := CNF.exists_schedule_design_commonZeroCount_parityRowSystem_eq hβ + refine ⟨n₀, hn₀20, fun {V _ _ φ n' k W b₀} hk {rows} hW => ?_⟩ + intro S e hn' hb₀ hw + rw [← CNF.commonZeroCount_parityRowSystem] + exact hsched hk hW e hn' hb₀ hw + +/-- **Unconditional Section 6.3 schedule-design recovery of `commonZeroCount` for +`B ≤ C_B * (Nat.clog 2 n) ^ β_B`**: combines +`CNF.exists_branch_schedule_parityRowSystem_of_le_clog_pow` with +`CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design` and +`CNF.natDegree_univariateClearedParityTruncatedSum_branchParityRowSystem_le`. -/ +theorem CNF.exists_schedule_design_commonZeroCount_parityRowSystem_of_le_clog_pow + (k C_B β_B : ℕ) : + ∃ N₀ : ℕ, 20 ≤ N₀ ∧ + ∀ {V : Type*} [Fintype V] [DecidableEq V] + {φ : CNF V} ⦃n' B W : ℕ⦄, (∀ c ∈ φ, c.length ≤ k) → - 1 ≤ Fintype.card V → - 1 ≤ P → - ∀ (A : ℕ → List (Fin φ.length → Bool)), - (∀ r_row ∈ A 0, weight r_row ≤ D₀) → - (∀ σ, PassesTests φ.violations (A 0) σ → φ.eval σ = false → - φ.length ≤ P * weight (φ.violations σ)) → - ∀ (γ : ℕ → Fin P → Fin φ.length × Bool), - (∀ i, A (i + 1) = A i ++ [testRow (γ i)]) → - (∀ i (γ' : Fin P → Fin φ.length × Bool), - commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow (γ i)])) ≤ - commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow γ']))) → - ∀ (e : ↥(univ \ heavyVars univ (univ : Finset (Fin (A (3 * Fintype.card V)).length)) - (fun j => equationScope (φ.parityRowSystem (A (3 * Fintype.card V)) j)) b₀) ≃ Fin n'), - n₀ ≤ n' → - b₀ + 1 ≤ Nat.clog 2 n' ^ β → - max 1 (k * (max D₀ P * 2 ^ k)) ≤ Nat.clog 2 n' ^ β → - let rows := A (3 * Fintype.card V) - let S := heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀ - (∀ b : V → Bool, - Feasible β n' (b₀ + 1) (max 1 (k * (max D₀ P * 2 ^ k))) - (totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n')) - (φ.branchParityRowNeutralScope rows S e b))) ∧ - ∃ D : (b : V → Bool) → - ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) - (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n'), - (φ.modelCountOn Finset.univ : ℤ) = - (∑ b ∈ branchAssignments S, - ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) - (φ.branchParityRowSystem rows S e b) - (commonDenom (numNodes n') (rowBound β n') : ℤ) k - (branchPrecision (Fintype.card V)) - (designReplacementScaledIntMap (D b) Sum.inl)).eval 0 / - clearedProductDenom (commonDenom (numNodes n') (rowBound β n') : ℤ) k + N₀ ≤ Fintype.card V → + φ.length ≤ B * Fintype.card V → + B ≤ C_B * Nat.clog 2 (Fintype.card V) ^ β_B → + W ≤ CNF.initialRowWeightBound B φ.length → + ∀ {rows : List (Fin φ.length → Bool)}, + (∀ r_row ∈ rows, weight r_row ≤ W) → + rows.length ≤ 6 * Fintype.card V → + let b₀ := CNF.parityBranchThreshold k W (Fintype.card V) + let S := heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀ + ∀ (e : ↥(univ \ S) ≃ Fin n'), + 2 ≤ (Nat.clog 2 (Fintype.card V)).sqrt ∧ + (Fintype.card V ≤ 2 * n' ∧ Fintype.card V / 2 ≤ n') ∧ + #(branchAssignments S) ≤ + 2 ^ (Fintype.card V / (Nat.clog 2 (Fintype.card V)).sqrt) ∧ + (∀ b : V → Bool, + Feasible (2 * β_B + 5) n' (b₀ + 1) (max (k * (W * 2 ^ k)) 1) + (∑ f : {j : Fin rows.length // j ∈ (univ : Finset (Fin rows.length))} ⊕ Fin n', + #(branchAugmentedScope S e univ (φ.parityRowSystem rows) b f))) ∧ + ∃ D : (b : V → Bool) → + ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) + (numNodes n') (numGroups n') (intervalStart (2 * β_B + 5) n') + (rowBound (2 * β_B + 5) n') (tauRat n'), + (commonZeroCount (univ : Finset (Fin rows.length)) (φ.parityRowSystem rows) : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound (2 * β_B + 5) n') : ℤ) k (branchPrecision (Fintype.card V)) - #(univ : Finset (Fin rows.length))) % - ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ - ∀ b : V → Bool, - (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) - (φ.branchParityRowSystem rows S e b) - (commonDenom (numNodes n') (rowBound β n') : ℤ) k - (branchPrecision (Fintype.card V)) - (designReplacementScaledIntMap (D b) Sum.inl)).natDegree ≤ - (k * (rowBound β n' - 1)) * + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).eval 0 / + clearedProductDenom + (commonDenom (numNodes n') (rowBound (2 * β_B + 5) n') : ℤ) k + (branchPrecision (Fintype.card V)) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ + ∀ b : V → Bool, + (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound (2 * β_B + 5) n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).natDegree ≤ + (k * (rowBound (2 * β_B + 5) n' - 1)) * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1)) := by - obtain ⟨n₀, hn₀20, hsched⟩ := exists_schedule_design_commonZeroCount_parityRowSystem_eq hβ - refine ⟨n₀, hn₀20, - fun {V _ _} φ {k D₀ P b₀ n'} hk hn hP A hA₀_wt hinit γ hA hγ e hn' hb hw => ?_⟩ - have hW : ∀ r_row ∈ A (3 * Fintype.card V), weight r_row ≤ max D₀ P := - weight_le_max_of_append_testRow A hA₀_wt γ hA (3 * Fintype.card V) - obtain ⟨hF, D, hcount, hdeg⟩ := hsched e hn' hb hw hk hW - rw [CNF.commonZeroCount_parityRowSystem_greedy φ hn hP A hinit γ hA hγ] at hcount - exact ⟨hF, D, hcount, hdeg⟩ - -/-- **Lemmas 6.1–6.2, Lemma 4.7–4.8, & §§5.4–5.5, 6.3 (end-to-end initial + greedy parity-test -compilation and Lemma 4.8 schedule `ReplacementDesign` recovery of `φ.modelCountOn Finset.univ`)**: -for every `1 ≤ β`, there exists `n₀ ≥ 20` such that for any width-`≤ k` CNF `φ` on -`n = Fintype.card V ≥ 1` variables with `φ.length ≤ B * n` (`B ≥ 1`), there exist initial parity -rows `A_init` (`A_init.length ≤ 3 * n`, each of weight at most -`D₀ = CNF.initialRowWeightBound B φ.length`) such that for any greedy sequence -`A (i + 1) = A i ++ [testRow (γ i)]` with `A 0 = A_init` minimizing -`commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow γ']))` over candidate rows of list length -`P = CNF.greedyRowListLength B φ.length`, whenever at stage `3 * n` the free-variable count `n'` -satisfies `n₀ ≤ n'`, `b₀ + 1 ≤ (Nat.clog 2 n') ^ β`, and -`max 1 (k * (D₀ * 2 ^ k)) ≤ (Nat.clog 2 n') ^ β`: -1. Every branch `b : V → Bool` satisfies - `Feasible β n' (b₀ + 1) (max 1 (k * (D₀ * 2 ^ k))) M'_b`, -2. There exists a family `D` of concrete Lemma 4.8 schedule `ReplacementDesign`s across all - branches whose branch-summed constant-term evaluation recovers - `(φ.modelCountOn Finset.univ : ℤ)`, -3. Every branch numerator has `natDegree ≤ (k * (rowBound β n' - 1)) * (8 * Fintype.card V)`. -/ -theorem exists_initialTests_and_schedule_design_modelCountOn_eq {β : ℕ} (hβ : 1 ≤ β) : + obtain ⟨N₀, hN₀20, hsched⟩ := CNF.exists_branch_schedule_parityRowSystem_of_le_clog_pow k C_B β_B + refine ⟨N₀, hN₀20, fun {V _ _ φ n' B W} hk hN₀ hm hB hW_bound {rows} hW hlen => ?_⟩ + intro b₀ S e + obtain ⟨hsqrt, hcard, hbr, h_all⟩ := hsched hk hN₀ hm hB hW_bound hW hlen e + let D : (b : V → Bool) → + ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) + (numNodes n') (numGroups n') (intervalStart (2 * β_B + 5) n') + (rowBound (2 * β_B + 5) n') (tauRat n') := + fun b => Classical.choice (h_all b).2 + refine ⟨hsqrt, hcard, hbr, fun b => (h_all b).1, D, ?_, fun b => ?_⟩ + · exact CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design hk rows S e + (fun b => branchAugmentedScope S e univ (φ.parityRowSystem rows) b) D + (fun _ => CNF.parityRowAugmentedInl) + · exact CNF.natDegree_univariateClearedParityTruncatedSum_branchParityRowSystem_le hk rows S e b + (D b) CNF.parityRowAugmentedInl (branchPrecision (Fintype.card V)) + +/-- **Unconditional Section 6.3 schedule-design recovery of `numPassing φ.violations rows` for +`B ≤ C_B * (Nat.clog 2 n) ^ β_B`**. -/ +theorem CNF.exists_schedule_design_numPassing_of_le_clog_pow (k C_B β_B : ℕ) : + ∃ N₀ : ℕ, 20 ≤ N₀ ∧ + ∀ {V : Type*} [Fintype V] [DecidableEq V] + {φ : CNF V} ⦃n' B W : ℕ⦄, + (∀ c ∈ φ, c.length ≤ k) → + N₀ ≤ Fintype.card V → + φ.length ≤ B * Fintype.card V → + B ≤ C_B * Nat.clog 2 (Fintype.card V) ^ β_B → + W ≤ CNF.initialRowWeightBound B φ.length → + ∀ {rows : List (Fin φ.length → Bool)}, + (∀ r_row ∈ rows, weight r_row ≤ W) → + rows.length ≤ 6 * Fintype.card V → + let b₀ := CNF.parityBranchThreshold k W (Fintype.card V) + let S := heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀ + ∀ (e : ↥(univ \ S) ≃ Fin n'), + 2 ≤ (Nat.clog 2 (Fintype.card V)).sqrt ∧ + (Fintype.card V ≤ 2 * n' ∧ Fintype.card V / 2 ≤ n') ∧ + #(branchAssignments S) ≤ + 2 ^ (Fintype.card V / (Nat.clog 2 (Fintype.card V)).sqrt) ∧ + (∀ b : V → Bool, + Feasible (2 * β_B + 5) n' (b₀ + 1) (max (k * (W * 2 ^ k)) 1) + (∑ f : {j : Fin rows.length // j ∈ (univ : Finset (Fin rows.length))} ⊕ Fin n', + #(branchAugmentedScope S e univ (φ.parityRowSystem rows) b f))) ∧ + ∃ D : (b : V → Bool) → + ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) + (numNodes n') (numGroups n') (intervalStart (2 * β_B + 5) n') + (rowBound (2 * β_B + 5) n') (tauRat n'), + (numPassing φ.violations rows : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound (2 * β_B + 5) n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).eval 0 / + clearedProductDenom + (commonDenom (numNodes n') (rowBound (2 * β_B + 5) n') : ℤ) k + (branchPrecision (Fintype.card V)) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ + ∀ b : V → Bool, + (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound (2 * β_B + 5) n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).natDegree ≤ + (k * (rowBound (2 * β_B + 5) n' - 1)) * + (rows.length + 2 * (branchPrecision (Fintype.card V) - 1)) := by + obtain ⟨N₀, hN₀20, hsched⟩ := + CNF.exists_schedule_design_commonZeroCount_parityRowSystem_of_le_clog_pow k C_B β_B + refine ⟨N₀, hN₀20, fun {V _ _ φ n' B W} hk hN₀ hm hB hW_bound {rows} hW hlen => ?_⟩ + intro b₀ S e + rw [← CNF.commonZeroCount_parityRowSystem] + exact hsched hk hN₀ hm hB hW_bound hW hlen e + +/-! ### 3. End-to-end greedy `modelCountOn` schedule-design recovery -/ + +/-- **Lemmas 6.1–6.2 & §§5.4–5.5, 6.3 (conditional greedy parity-test schedule-design recovery of +`φ.modelCountOn Finset.univ`)**: combines `CNF.exists_greedy_parityRowSystem_branch_schedule` with +`CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design` so that at every stage +`i ≤ 3 * n`, concrete Lemma 4.8 schedule `ReplacementDesign`s exist across all heavy-variable +branches, and at the final stage `i = 3 * n`, they recover `(φ.modelCountOn Finset.univ : ℤ)` with +univariate numerator degree at most `(k * (rowBound β n' - 1)) * (8 * Fintype.card V)`. -/ +theorem CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_eq {β : ℕ} (hβ : 1 ≤ β) : ∃ n₀ : ℕ, 20 ≤ n₀ ∧ - ∀ {V : Type*} [Fintype V] [DecidableEq V] (φ : CNF V) {k B : ℕ}, + ∀ {V : Type*} [Fintype V] [DecidableEq V] + (φ : CNF V) {k B : ℕ}, (∀ c ∈ φ, c.length ≤ k) → 1 ≤ Fintype.card V → 1 ≤ B → φ.length ≤ B * Fintype.card V → let D₀ := CNF.initialRowWeightBound B φ.length let P := CNF.greedyRowListLength B φ.length - ∃ A_init : List (Fin φ.length → Bool), A_init.length ≤ 3 * Fintype.card V ∧ - (∀ r_row ∈ A_init, weight r_row ≤ D₀) ∧ + ∃ A₀ : List (Fin φ.length → Bool), A₀.length ≤ 3 * Fintype.card V ∧ + (∀ r_row ∈ A₀, weight r_row ≤ D₀) ∧ ∀ (A : ℕ → List (Fin φ.length → Bool)) (γ : ℕ → Fin P → Fin φ.length × Bool), - A 0 = A_init → (∀ i, A (i + 1) = A i ++ [testRow (γ i)]) → + A 0 = A₀ → (∀ i, A (i + 1) = A i ++ [testRow (γ i)]) → (∀ i (γ' : Fin P → Fin φ.length × Bool), commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow (γ i)])) ≤ commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow γ']))) → + commonZeroCount univ (φ.parityRowSystem (A (3 * Fintype.card V))) = + φ.modelCountOn Finset.univ ∧ (∀ i ≤ 3 * Fintype.card V, (A i).length ≤ 6 * Fintype.card V ∧ - ∀ j : Fin (A i).length, - (∀ M ∈ φ.parityRowSystem (A i) j, M ⊆ φ.vars.toFinset ∧ #M ≤ k) ∧ - #(φ.parityRowSystem (A i) j) ≤ D₀ * 2 ^ k ∧ - #(equationScope (φ.parityRowSystem (A i) j)) ≤ k * (D₀ * 2 ^ k)) ∧ - ∀ {b₀ n' : ℕ} - (e : ↥(univ \ heavyVars univ (univ : Finset (Fin (A (3 * Fintype.card V)).length)) - (fun j => equationScope (φ.parityRowSystem (A (3 * Fintype.card V)) j)) b₀) ≃ - Fin n'), - n₀ ≤ n' → - b₀ + 1 ≤ Nat.clog 2 n' ^ β → - max 1 (k * (D₀ * 2 ^ k)) ≤ Nat.clog 2 n' ^ β → + ∀ ⦃n' b₀ : ℕ⦄ + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) b₀) ≃ Fin n'), + n₀ ≤ n' → + b₀ + 1 ≤ Nat.clog 2 n' ^ β → + max (k * (max D₀ P * 2 ^ k)) 1 ≤ Nat.clog 2 n' ^ β → + ∀ b : V → Bool, + Feasible β n' (b₀ + 1) (max (k * (max D₀ P * 2 ^ k)) 1) + (∑ f : {j : Fin (A i).length // + j ∈ (univ : Finset (Fin (A i).length))} ⊕ Fin n', + #(branchAugmentedScope + (heavyVars univ (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) b₀) + e univ (φ.parityRowSystem (A i)) b f)) ∧ + Nonempty + (ReplacementDesign + (branchAugmentedScope + (heavyVars univ (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) b₀) + e univ (φ.parityRowSystem (A i)) b) + (numNodes n') (numGroups n') (intervalStart β n') + (rowBound β n') (tauRat n'))) ∧ + ∀ ⦃n' b₀ : ℕ⦄, let rows := A (3 * Fintype.card V) let S := heavyVars univ (univ : Finset (Fin rows.length)) (fun j => equationScope (φ.parityRowSystem rows j)) b₀ - (∀ b : V → Bool, - Feasible β n' (b₀ + 1) (max 1 (k * (D₀ * 2 ^ k))) - (totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n')) - (φ.branchParityRowNeutralScope rows S e b))) ∧ - ∃ D : (b : V → Bool) → - ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) - (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n'), - (φ.modelCountOn Finset.univ : ℤ) = - (∑ b ∈ branchAssignments S, - ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + ∀ (e : ↥(univ \ S) ≃ Fin n'), + n₀ ≤ n' → + b₀ + 1 ≤ Nat.clog 2 n' ^ β → + max (k * (max D₀ P * 2 ^ k)) 1 ≤ Nat.clog 2 n' ^ β → + ∃ D : (b : V → Bool) → + ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) + (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n'), + (φ.modelCountOn Finset.univ : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).eval 0 / + clearedProductDenom (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ + ∀ b : V → Bool, + (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) (φ.branchParityRowSystem rows S e b) (commonDenom (numNodes n') (rowBound β n') : ℤ) k (branchPrecision (Fintype.card V)) - (designReplacementScaledIntMap (D b) Sum.inl)).eval 0 / - clearedProductDenom (commonDenom (numNodes n') (rowBound β n') : ℤ) k - (branchPrecision (Fintype.card V)) - #(univ : Finset (Fin rows.length))) % - ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ - ∀ b : V → Bool, - (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) - (φ.branchParityRowSystem rows S e b) - (commonDenom (numNodes n') (rowBound β n') : ℤ) k - (branchPrecision (Fintype.card V)) - (designReplacementScaledIntMap (D b) Sum.inl)).natDegree ≤ - (k * (rowBound β n' - 1)) * (8 * Fintype.card V) := by - obtain ⟨n₀, hn₀20, hsched⟩ := exists_schedule_branchParityRow_replacementDesign hβ + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).natDegree ≤ + (k * (rowBound β n' - 1)) * (8 * Fintype.card V) := by + obtain ⟨n₀, hn₀20, hgreedy_sched⟩ := CNF.exists_greedy_parityRowSystem_branch_schedule hβ refine ⟨n₀, hn₀20, fun {V _ _} φ {k B} hk hn hB hm => ?_⟩ - obtain ⟨A_init, hlen, hw, hgreedy⟩ := CNF.exists_initialTests_commonZeroCount_greedy φ hk hn hB hm - refine ⟨A_init, hlen, hw, fun A γ h0 hA hγ => ?_⟩ - obtain ⟨hcount, hbounds⟩ := hgreedy A γ h0 hA hγ - have hstage : - ∀ i ≤ 3 * Fintype.card V, - (A i).length ≤ 6 * Fintype.card V ∧ - ∀ j : Fin (A i).length, - (∀ M ∈ φ.parityRowSystem (A i) j, M ⊆ φ.vars.toFinset ∧ #M ≤ k) ∧ - #(φ.parityRowSystem (A i) j) ≤ CNF.initialRowWeightBound B φ.length * 2 ^ k ∧ - #(equationScope (φ.parityRowSystem (A i) j)) ≤ - k * (CNF.initialRowWeightBound B φ.length * 2 ^ k) := by - intro i hi - obtain ⟨hlen_i, hj⟩ := hbounds i hi - refine ⟨hlen_i, fun j => ?_⟩ - obtain ⟨hM, hcard, hscope⟩ := hj j - rw [CNF.max_initialRowWeightBound_greedyRowListLength] at hcard hscope - exact ⟨hM, hcard, hscope⟩ - refine ⟨hstage, fun {b₀ n'} e hn' hb hw_width => ?_⟩ - intro rows S - have hW_rows : ∀ r_row ∈ rows, weight r_row ≤ CNF.initialRowWeightBound B φ.length := by - intro r_row hr - have hmax := weight_le_max_of_append_testRow A (h0 ▸ hw) γ hA (3 * Fintype.card V) r_row hr - rwa [CNF.max_initialRowWeightBound_greedyRowListLength] at hmax - have hbranch := hsched e hn' hb hw_width hk hW_rows - refine ⟨fun b => (hbranch b).1, ?_⟩ + intro D₀ P + obtain ⟨A₀, hlen0, hw0, hgreedy⟩ := hgreedy_sched φ hk hn hB hm + refine ⟨A₀, hlen0, hw0, fun A γ h0 hA hγ => ?_⟩ + obtain ⟨hcount, hstage⟩ := hgreedy A γ h0 hA hγ + refine ⟨hcount, hstage, fun {n' b₀} => ?_⟩ + intro rows S e hn' hb₀ hw + obtain ⟨hlen_final, h_all⟩ := hstage (3 * Fintype.card V) le_rfl let D : (b : V → Bool) → - ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) + ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n') := - fun b => Classical.choice (hbranch b).2 - refine ⟨D, ?_, ?_⟩ + fun b => Classical.choice (h_all e hn' hb₀ hw b).2 + refine ⟨D, ?_, fun b => ?_⟩ + · rw [← hcount] + exact CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design hk rows S e + (fun b => branchAugmentedScope S e univ (φ.parityRowSystem rows) b) D + (fun _ => CNF.parityRowAugmentedInl) + · have hdeg := + CNF.natDegree_univariateClearedParityTruncatedSum_branchParityRowSystem_le hk rows S e b + (D b) CNF.parityRowAugmentedInl (branchPrecision (Fintype.card V)) + have hrows : rows.length ≤ 6 * Fintype.card V := hlen_final + refine hdeg.trans (Nat.mul_le_mul_left _ ?_) + unfold branchPrecision + omega + +/-- **Unconditional Section 6.3 greedy parity-test schedule-design recovery of +`φ.modelCountOn Finset.univ` for `B ≤ C_B * (Nat.clog 2 n) ^ β_B`**: combines +`CNF.exists_greedy_parityRowSystem_branch_schedule_of_le_clog_pow` with exact branch-summed +constant-term recovery and univariate numerator degree bounds. -/ +theorem CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_of_le_clog_pow + (k C_B β_B : ℕ) : + ∃ N₀ : ℕ, 20 ≤ N₀ ∧ + ∀ {V : Type*} [Fintype V] [DecidableEq V] + (φ : CNF V) {B : ℕ}, + (∀ c ∈ φ, c.length ≤ k) → + N₀ ≤ Fintype.card V → + 1 ≤ B → + B ≤ C_B * Nat.clog 2 (Fintype.card V) ^ β_B → + φ.length ≤ B * Fintype.card V → + let D₀ := CNF.initialRowWeightBound B φ.length + let P := CNF.greedyRowListLength B φ.length + let b₀ := CNF.parityBranchThreshold k D₀ (Fintype.card V) + ∃ A₀ : List (Fin φ.length → Bool), A₀.length ≤ 3 * Fintype.card V ∧ + (∀ r_row ∈ A₀, weight r_row ≤ D₀) ∧ + ∀ (A : ℕ → List (Fin φ.length → Bool)) + (γ : ℕ → Fin P → Fin φ.length × Bool), + A 0 = A₀ → (∀ i, A (i + 1) = A i ++ [testRow (γ i)]) → + (∀ i (γ' : Fin P → Fin φ.length × Bool), + commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow (γ i)])) ≤ + commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow γ']))) → + commonZeroCount univ (φ.parityRowSystem (A (3 * Fintype.card V))) = + φ.modelCountOn Finset.univ ∧ + (∀ i ≤ 3 * Fintype.card V, + (A i).length ≤ 6 * Fintype.card V ∧ + ∀ ⦃n' : ℕ⦄ + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) b₀) ≃ Fin n'), + (Fintype.card V ≤ 2 * n' ∧ Fintype.card V / 2 ≤ n') ∧ + #(branchAssignments + (heavyVars univ (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) b₀)) ≤ + 2 ^ (Fintype.card V / (Nat.clog 2 (Fintype.card V)).sqrt) ∧ + ∀ b : V → Bool, + Feasible (2 * β_B + 5) n' (b₀ + 1) (max (k * (D₀ * 2 ^ k)) 1) + (∑ f : {j : Fin (A i).length // + j ∈ (univ : Finset (Fin (A i).length))} ⊕ Fin n', + #(branchAugmentedScope + (heavyVars univ (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) b₀) + e univ (φ.parityRowSystem (A i)) b f)) ∧ + Nonempty + (ReplacementDesign + (branchAugmentedScope + (heavyVars univ (univ : Finset (Fin (A i).length)) + (fun j => equationScope (φ.parityRowSystem (A i) j)) b₀) + e univ (φ.parityRowSystem (A i)) b) + (numNodes n') (numGroups n') (intervalStart (2 * β_B + 5) n') + (rowBound (2 * β_B + 5) n') (tauRat n'))) ∧ + ∀ ⦃n' : ℕ⦄, + let rows := A (3 * Fintype.card V) + let S := heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀ + ∀ (e : ↥(univ \ S) ≃ Fin n'), + ∃ D : (b : V → Bool) → + ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) + (numNodes n') (numGroups n') (intervalStart (2 * β_B + 5) n') + (rowBound (2 * β_B + 5) n') (tauRat n'), + (φ.modelCountOn Finset.univ : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound (2 * β_B + 5) n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).eval 0 / + clearedProductDenom + (commonDenom (numNodes n') (rowBound (2 * β_B + 5) n') : ℤ) k + (branchPrecision (Fintype.card V)) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ + ∀ b : V → Bool, + (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound (2 * β_B + 5) n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).natDegree ≤ + (k * (rowBound (2 * β_B + 5) n' - 1)) * (8 * Fintype.card V) := by + obtain ⟨N₀, hN₀20, hgreedy_sched⟩ := + CNF.exists_greedy_parityRowSystem_branch_schedule_of_le_clog_pow k C_B β_B + refine ⟨N₀, hN₀20, fun {V _ _} φ {B} hk hN₀ hB1 hB_le hm => ?_⟩ + intro D₀ P b₀ + obtain ⟨A₀, hlen0, hw0, hgreedy⟩ := hgreedy_sched φ hk hN₀ hB1 hB_le hm + refine ⟨A₀, hlen0, hw0, fun A γ h0 hA hγ => ?_⟩ + obtain ⟨hcount, hstage⟩ := hgreedy A γ h0 hA hγ + refine ⟨hcount, hstage, fun {n'} => ?_⟩ + intro rows S e + obtain ⟨hlen_final, h_all⟩ := hstage (3 * Fintype.card V) le_rfl + let D : (b : V → Bool) → + ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) + (numNodes n') (numGroups n') (intervalStart (2 * β_B + 5) n') + (rowBound (2 * β_B + 5) n') (tauRat n') := + fun b => Classical.choice ((h_all e).2.2 b).2 + refine ⟨D, ?_, fun b => ?_⟩ · rw [← hcount] exact CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design hk rows S e - (φ.branchParityRowNeutralScope rows S e) D (fun _ => Sum.inl) - · intro b - have hdeg := CNF.natDegree_univariateClearedParityTruncatedSum_branchParityRowSystem_le hk rows - S e b (D b) Sum.inl (branchPrecision (Fintype.card V)) - have hrows_len : rows.length ≤ 6 * Fintype.card V := (hstage (3 * Fintype.card V) le_rfl).1 - have h8 : rows.length + 2 * (branchPrecision (Fintype.card V) - 1) ≤ 8 * Fintype.card V := by - unfold branchPrecision - omega - exact hdeg.trans (Nat.mul_le_mul_left (k * (rowBound β n' - 1)) h8) - -end ScheduleDesignRecovery - -/-! ### 3. Section 6.3 (`c = 6`) degree budgets and Proposition 3.4 domain-examination bounds -/ - -section DomainExaminationBounds - -/-- **Section 5.5 & Section 6.3 degree budget**: when `rows.length ≤ c * Fintype.card V` and -`Fintype.card V ≤ 2 * n'`, the pre-replacement degree factor -`k * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1))` at original precision -`branchPrecision (Fintype.card V) = Fintype.card V + 1` is at most `(k * (2 * c + 4)) * n'`. -/ -theorem branchParityRowDegreeBudget_le {k c n n' m : ℕ} - (hm : m ≤ c * n) (hn : n ≤ 2 * n') : - k * (m + 2 * (branchPrecision n - 1)) ≤ (k * (2 * c + 4)) * n' := by - unfold branchPrecision - have h1 : m + 2 * (n + 1 - 1) ≤ (2 * c + 4) * n' := by - calc m + 2 * (n + 1 - 1) - = m + 2 * n := by omega - _ ≤ c * n + 2 * n := Nat.add_le_add_right hm (2 * n) - _ = (c + 2) * n := by ring - _ ≤ (c + 2) * (2 * n') := Nat.mul_le_mul_left (c + 2) hn - _ = (2 * c + 4) * n' := by ring - calc k * (m + 2 * (n + 1 - 1)) - ≤ k * ((2 * c + 4) * n') := Nat.mul_le_mul_left k h1 - _ = (k * (2 * c + 4)) * n' := (mul_assoc k (2 * c + 4) n').symm - -/-- **Section 6.3 (`c = 6`) Lemma 6.2 candidate/final degree budget**: for any candidate or final -system with `rows.length ≤ 6 * Fintype.card V` and `Fintype.card V ≤ 2 * n'`, the pre-replacement -degree factor `k * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1))` is at most -`(16 * k) * n'`. -/ -theorem greedyCandidateDegreeBudget_le {k n n' m : ℕ} - (hm : m ≤ 6 * n) (hn : n ≤ 2 * n') : - k * (m + 2 * (branchPrecision n - 1)) ≤ (16 * k) * n' := by - have h := branchParityRowDegreeBudget_le (k := k) hm hn - rwa [show k * (2 * 6 + 4) = 16 * k by ring] at h - -/-- **Section 5.5 (`n ≤ 2 * n'` after branching on `heavyVars` of `φ.parityRowSystem rows`)**: when -`1 ≤ b₀`, `2 ≤ s_div`, `totalIncidence univ (fun j => equationScope (φ.parityRowSystem rows j)) * -s_div ≤ b₀ * Fintype.card V`, and `e : ↥(univ \ heavyVars ...) ≃ Fin n'`, the free-variable count -`n'` satisfies `Fintype.card V ≤ 2 * n'` and `Fintype.card V / 2 ≤ n'`. -/ -theorem card_le_two_mul_freeVar_of_heavyVars_parityRowSystem [Fintype V] [DecidableEq V] - (φ : CNF V) (rows : List (Fin φ.length → Bool)) {b₀ s_div : ℕ} - (hb₀ : 1 ≤ b₀) (hs_div : 2 ≤ s_div) - (hM : - totalIncidence (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) * s_div ≤ - b₀ * Fintype.card V) - (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n') : - Fintype.card V ≤ 2 * n' ∧ Fintype.card V / 2 ≤ n' := by - have hhalf := card_sdiff_heavyVars_ge_half (univ : Finset V) - (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) hb₀ hs_div - (fun _ _ => subset_univ _) (by simpa only [card_univ] using hM) - have hcard : #(univ \ heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀) = n' := by - simpa only [Fintype.card_coe, Fintype.card_fin] using Fintype.card_congr e - simpa only [card_univ, hcard] using hhalf - -/-- **Section 5.5 & Section 6.3 single-branch Proposition 3.4 / Lemma 4.8 domain-examination bound -for `φ.parityRowSystem rows`**: for any branch with `hF : Feasible β n' b_occ w_width M'` and -concrete schedule design `D` on `Fin n'`, if `rows.length ≤ c * Fintype.card V` and -`Fintype.card V ≤ 2 * n'`, then at -`d = k * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1))` and canonical truncation order -`q = (d * rowBound β n') / numNodes n'`, the induced Section 3 counting design -`C := hF.toCountingDesign D s` examines at most -`2 * numNodes n' * numGroups n' * exp (((k * (2 * c + 4) + 4) : ℝ) * n' * rowCost β n')` local -Boolean assignments. -/ -theorem Feasible.branchParityRow_domainExaminationBound_le [Fintype V] {F_idx : Type*} - [Fintype F_idx] {scope : F_idx → Finset (Fin n')} {β b_occ w_width M' k c : ℕ} - (φ : CNF V) (rows : List (Fin φ.length → Bool)) - (hF : Feasible β n' b_occ w_width M') - (D : ReplacementDesign scope (numNodes n') (numGroups n') (intervalStart β n') - (rowBound β n') (tauRat n')) - (s : Finset F_idx) (hm : rows.length ≤ c * Fintype.card V) (hn : Fintype.card V ≤ 2 * n') : - let d := k * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1)) - let q := (d * rowBound β n') / numNodes n' - let C := hF.toCountingDesign D s - (∑ t : Fin (numNodes n'), - (#{p : Finset (Fin n') × Finset (Fin n') | #p.1 ≤ q ∧ p.2 ⊆ p.1} : ℝ) * - (2 * (#(C.measurementBox t) : ℝ) * - ∑ g : Fin (numGroups n'), (Fintype.card (C.LocalCube t g) : ℝ))) ≤ - 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * - Real.exp (((k * (2 * c + 4) + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n') ∧ - 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * - Real.exp (((k * (2 * c + 4) + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n') ≤ - 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * - Real.exp (((k * (2 * c + 4) + 4 : ℕ) : ℝ) * (n' : ℝ) * - (1028 * ((β : ℝ) + 3) * (Nat.clog 2 (Nat.clog 2 n') : ℝ) ^ 2 / - Real.sqrt (Nat.clog 2 n'))) := by - intro d q C - have hd_le : (d : ℝ) ≤ ((k * (2 * c + 4) : ℕ) : ℝ) * (n' : ℝ) := by - exact_mod_cast branchParityRowDegreeBudget_le (k := k) hm hn - have hq : - (q : ℝ) ≤ ((k * (2 * c + 4) : ℕ) : ℝ) * (n' : ℝ) * - ((rowBound β n' : ℝ) / numNodes n') := by - calc (q : ℝ) - ≤ ((d * rowBound β n' : ℕ) : ℝ) / numNodes n' := Nat.cast_div_le - _ = (d : ℝ) * ((rowBound β n' : ℝ) / numNodes n') := by push_cast; ring - _ ≤ (((k * (2 * c + 4) : ℕ) : ℝ) * (n' : ℝ)) * - ((rowBound β n' : ℝ) / numNodes n') := - mul_le_mul_of_nonneg_right hd_le (div_nonneg (Nat.cast_nonneg _) (Nat.cast_nonneg _)) - have hc_nn : (0 : ℝ) ≤ ((k * (2 * c + 4) : ℕ) : ℝ) := Nat.cast_nonneg _ - have hbound := hF.domainExaminationBound_le_mul_exp_rowCost D s hc_nn hq - have hcast : - (((k * (2 * c + 4) : ℕ) : ℝ) + 4) = ((k * (2 * c + 4) + 4 : ℕ) : ℝ) := by - push_cast - ring - rw [hcast] at hbound - exact hbound - -/-- **Section 6.3 (`c = 6`) single-branch domain-examination bound for any Lemma 6.2 candidate or -final system (`rows.length ≤ 6 * Fintype.card V`)**: specializes -`Feasible.branchParityRow_domainExaminationBound_le` to `c = 6`, giving the exponent multiplier -`16 * k + 4`. -/ -theorem Feasible.greedyCandidate_domainExaminationBound_le [Fintype V] {F_idx : Type*} - [Fintype F_idx] {scope : F_idx → Finset (Fin n')} {β b_occ w_width M' k : ℕ} - (φ : CNF V) (rows : List (Fin φ.length → Bool)) - (hF : Feasible β n' b_occ w_width M') - (D : ReplacementDesign scope (numNodes n') (numGroups n') (intervalStart β n') - (rowBound β n') (tauRat n')) - (s : Finset F_idx) (hm : rows.length ≤ 6 * Fintype.card V) (hn : Fintype.card V ≤ 2 * n') : - let d := k * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1)) - let q := (d * rowBound β n') / numNodes n' - let C := hF.toCountingDesign D s - (∑ t : Fin (numNodes n'), - (#{p : Finset (Fin n') × Finset (Fin n') | #p.1 ≤ q ∧ p.2 ⊆ p.1} : ℝ) * - (2 * (#(C.measurementBox t) : ℝ) * - ∑ g : Fin (numGroups n'), (Fintype.card (C.LocalCube t g) : ℝ))) ≤ - 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * - Real.exp (((16 * k + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n') ∧ - 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * - Real.exp (((16 * k + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n') ≤ - 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * - Real.exp (((16 * k + 4 : ℕ) : ℝ) * (n' : ℝ) * - (1028 * ((β : ℝ) + 3) * (Nat.clog 2 (Nat.clog 2 n') : ℝ) ^ 2 / - Real.sqrt (Nat.clog 2 n'))) := by - have h := hF.branchParityRow_domainExaminationBound_le (k := k) (c := 6) φ rows D s hm hn - rwa [show k * (2 * 6 + 4) + 4 = 16 * k + 4 by ring] at h - -/-- **Section 5.5 & Section 6.3 multi-branch domain-examination bound across all -`branchAssignments S` of `φ.parityRowSystem rows`**: when -`S = heavyVars univ univ (fun j => equationScope (φ.parityRowSystem rows j)) b₀` with `1 ≤ b₀`, -`2 ≤ s_div`, `totalIncidence univ (fun j => equationScope (φ.parityRowSystem rows j)) * s_div ≤ -b₀ * Fintype.card V`, and `e : ↥(univ \ S) ≃ Fin n'`, the free-variable dimension satisfies -`Fintype.card V ≤ 2 * n'`, and if each branch `b ∈ branchAssignments S` has its real examination sum -bounded via `Feasible.branchParityRow_domainExaminationBound_le`, then the sum across all -`b ∈ branchAssignments S` is at most -`(2 : ℝ) ^ (Fintype.card V / s_div) * (2 * numNodes n' * numGroups n' * - exp (((k * (2 * c + 4) + 4 : ℕ) : ℝ) * n' * rowCost β n'))`. -/ -theorem sum_branchParityRow_domainExaminationBound_le [Fintype V] [DecidableEq V] - (φ : CNF V) (rows : List (Fin φ.length → Bool)) {β b₀ s_div k c : ℕ} - (hb₀ : 1 ≤ b₀) (hs_div : 2 ≤ s_div) - (hM : - totalIncidence (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) * s_div ≤ - b₀ * Fintype.card V) - (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n') - (examSum : (V → Bool) → ℝ) - (hexam : ∀ b ∈ branchAssignments - (heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀), - examSum b ≤ - 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * - Real.exp (((k * (2 * c + 4) + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n')) : - Fintype.card V ≤ 2 * n' ∧ - (∑ b ∈ branchAssignments - (heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀), - examSum b) ≤ - (2 : ℝ) ^ (Fintype.card V / s_div) * - (2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * - Real.exp (((k * (2 * c + 4) + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n')) := by - have hn := - (card_le_two_mul_freeVar_of_heavyVars_parityRowSystem φ rows hb₀ hs_div hM e).1 - refine ⟨hn, ?_⟩ - let S := heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀ - let B := 2 * (numNodes n' : ℝ) * (numGroups n' : ℝ) * - Real.exp (((k * (2 * c + 4) + 4 : ℕ) : ℝ) * (n' : ℝ) * rowCost β n') - have hB_nn : 0 ≤ B := by positivity - have hcard : (#(branchAssignments S) : ℝ) ≤ (2 : ℝ) ^ (Fintype.card V / s_div) := by - exact_mod_cast card_branchAssignments_heavyVars_le_two_pow_div - (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) hb₀ (by omega) hM - calc ∑ b ∈ branchAssignments S, examSum b - ≤ ∑ _b ∈ branchAssignments S, B := sum_le_sum hexam - _ = (#(branchAssignments S) : ℝ) * B := by rw [sum_const, nsmul_eq_mul] - _ ≤ (2 : ℝ) ^ (Fintype.card V / s_div) * B := mul_le_mul_of_nonneg_right hcard hB_nn - -end DomainExaminationBounds - -end Cslib.Complexity.SubexponentialSAT.ReplacementParams + (fun b => branchAugmentedScope S e univ (φ.parityRowSystem rows) b) D + (fun _ => CNF.parityRowAugmentedInl) + · have hdeg := + CNF.natDegree_univariateClearedParityTruncatedSum_branchParityRowSystem_le hk rows S e b + (D b) CNF.parityRowAugmentedInl (branchPrecision (Fintype.card V)) + have hrows : rows.length ≤ 6 * Fintype.card V := hlen_final + refine hdeg.trans (Nat.mul_le_mul_left _ ?_) + unfold branchPrecision + omega + +end Cslib.Logic.PL diff --git a/ComplexityTests/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean b/ComplexityTests/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean index f591d1590c..3ab96f98fb 100644 --- a/ComplexityTests/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean +++ b/ComplexityTests/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean @@ -9,273 +9,121 @@ module public import Complexity.Init public import Complexity.Computability.Complexity.FineGrained.SparseCNFDesignSchedule -import Mathlib.Tactic.Linarith -import Mathlib.Tactic.NormNum -import Mathlib.Tactic.Positivity -import Mathlib.Tactic.Ring /-! -# Tests for `Complexity.Computability.Complexity.FineGrained.SparseCNFDesignSchedule` +# Tests for `SparseCNFDesignSchedule` -Concrete checks for Section 6.3 candidate/final degree budgets (`branchParityRowDegreeBudget_le`, -`greedyCandidateDegreeBudget_le`), greedy row-weight preservation -(`weight_le_max_of_append_testRow`), free-variable dimension lower bounds -(`card_le_two_mul_freeVar_of_heavyVars_parityRowSystem`), a concrete schedule witness at -`n = 2 ^ (2 ^ 50)` instantiating `Feasible.exists_branchParityRow_replacementDesign`, -`Feasible.branchParityRow_domainExaminationBound_le`, -`Feasible.greedyCandidate_domainExaminationBound_le`, and -`sum_branchParityRow_domainExaminationBound_le`, and instantiations of the uniform schedule -recovery theorems (`exists_schedule_branchParityRow_replacementDesign`, -`exists_schedule_design_commonZeroCount_parityRowSystem_eq`, -`exists_schedule_design_numPassing_eq`, `exists_schedule_design_modelCountOn_eq_greedy`, and -`exists_initialTests_and_schedule_design_modelCountOn_eq`). +Concrete tests and nonvacuity witnesses for the index-equivalence bridge and schedule-instantiated +exact recovery theorems in +`Complexity.Computability.Complexity.FineGrained.SparseCNFDesignSchedule`. -/ -@[expose] public noncomputable section +public section -namespace Cslib.Complexity.SubexponentialSAT.SparseCNFDesignScheduleTests +namespace Cslib.Complexity.SubexponentialSAT.ReplacementParams.SparseCNFDesignScheduleTests -open Finset Polynomial Cslib.BitString Cslib.BalancedSchedules Cslib.LinearAlgebra - Cslib.ReplacementCounting Cslib.Logic.PL +open Finset +open Cslib.BitString +open Cslib.LinearAlgebra +open Cslib.Logic.PL open Cslib.Complexity.SubexponentialSAT.ReplacementParams -open scoped BigOperators -/-! ### 1. Concrete degree-budget and row-weight checks -/ +/-! ### 1. Index-equivalence bridge between `Fin m ⊕ Fin n'` and `{j // j ∈ univ} ⊕ Fin n'` -/ -/-- Concrete check of `branchParityRowDegreeBudget_le` and `greedyCandidateDegreeBudget_le` for -`k = 3, c = 6, n = 20, n' = 12, m = 100`. -/ -example : - 3 * (100 + 2 * (branchPrecision 20 - 1)) ≤ (3 * (2 * 6 + 4)) * 12 ∧ - 3 * (100 + 2 * (branchPrecision 20 - 1)) ≤ (16 * 3) * 12 := - ⟨branchParityRowDegreeBudget_le (k := 3) (c := 6) (n := 20) (n' := 12) (m := 100) - (by decide) (by decide), - greedyCandidateDegreeBudget_le (k := 3) (n := 20) (n' := 12) (m := 100) - (by decide) (by decide)⟩ - -/-- Concrete 2-CNF over `Fin 3`: `(x₀ ∨ ¬x₁) ∧ (x₁ ∨ x₂)`. -/ +/-- A 2-CNF over `Fin 3` with two clauses `(x₀ ∨ ¬x₁) ∧ (x₁ ∨ x₂)` and one single-clause row. -/ def sampleCNF3 : CNF (Fin 3) := - [[(0, true), (1, false)], [(1, true), (2, true)]] + [[⟨0, true⟩, ⟨1, false⟩], [⟨1, true⟩, ⟨2, true⟩]] -/-- Concrete check of `weight_le_max_of_append_testRow` on a 1-step greedy sequence over -`sampleCNF3`. -/ -example : - let γ₀ : Fin 1 → Fin sampleCNF3.length × Bool := fun _ => (⟨0, by decide⟩, true) - let A : ℕ → List (Fin sampleCNF3.length → Bool) := - fun j => Nat.rec [![true, false]] (fun _ acc => acc ++ [testRow γ₀]) j - ∀ (j : ℕ) (r_row : Fin sampleCNF3.length → Bool), r_row ∈ A j → weight r_row ≤ max 1 1 := by - intro γ₀ A - refine weight_le_max_of_append_testRow A ?_ (fun _ => γ₀) (fun _ => rfl) - intro r_row hr - change r_row ∈ [![true, false]] at hr - rcases List.mem_singleton.mp hr with rfl - decide - -/-- Concrete check of `card_le_two_mul_freeVar_of_heavyVars_parityRowSystem` on `sampleCNF3` with -an empty row list (`b₀ = 1, s_div = 2, n' = 3`). -/ -example : - let rows : List (Fin sampleCNF3.length → Bool) := [] - let S := heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (sampleCNF3.parityRowSystem rows j)) 1 - let _e : ↥(univ \ S) ≃ Fin 3 := - Fintype.equivFinOfCardEq (by decide) - Fintype.card (Fin 3) ≤ 2 * 3 ∧ Fintype.card (Fin 3) / 2 ≤ 3 := by - intro rows S e - exact card_le_two_mul_freeVar_of_heavyVars_parityRowSystem sampleCNF3 rows - (b₀ := 1) (s_div := 2) (by decide) (by decide) (by decide) e +def sampleRow3 : Fin sampleCNF3.length → Bool := + fun i => decide (i = ⟨0, by decide⟩) -/-! ### 2. Concrete schedule witness at `n = 2 ^ (2 ^ 50)` -/ +def sampleRows3 : List (Fin sampleCNF3.length → Bool) := [sampleRow3] -private def emptyCNF (n : ℕ) : CNF (Fin n) := - [] +example (j : Fin 1) : + CNF.parityRowAugmentedIndexEquiv 1 3 (Sum.inl j) = CNF.parityRowAugmentedInl j := by + simp only [CNF.parityRowAugmentedIndexEquiv_inl] -private def emptyRows (n : ℕ) : List (Fin (emptyCNF n).length → Bool) := - [] +example (v : Fin 3) : + CNF.parityRowAugmentedIndexEquiv 1 3 (Sum.inr v) = Sum.inr v := by + simp only [CNF.parityRowAugmentedIndexEquiv_inr] -/-- For `emptyCNF n` and `emptyRows n`, `heavyVars` at `b₀` is empty. -/ -private theorem empty_heavyVars_eq_empty (n b₀ : ℕ) : - heavyVars (univ : Finset (Fin n)) (univ : Finset (Fin (emptyRows n).length)) - (fun j => equationScope ((emptyCNF n).parityRowSystem (emptyRows n) j)) b₀ = ∅ := by - ext v - have hzero : - varIncidence (univ : Finset (Fin (emptyRows n).length)) - (fun j => equationScope ((emptyCNF n).parityRowSystem (emptyRows n) j)) v = 0 := by - rfl - simp only [heavyVars, hzero, mem_filter, mem_univ, true_and, notMem_empty, iff_false, not_lt] - exact Nat.zero_le b₀ +example (e : ↥(univ \ (∅ : Finset (Fin 3))) ≃ Fin 3) (b : Fin 3 → Bool) + (j : Fin sampleRows3.length) : + branchAugmentedScope ∅ e univ (sampleCNF3.parityRowSystem sampleRows3) b + (CNF.parityRowAugmentedIndexEquiv sampleRows3.length 3 (Sum.inl j)) = + branchEquationScope ∅ e (sampleCNF3.parityRowSystem sampleRows3) b j := + sampleCNF3.branchAugmentedScope_parityRowSystem_comp_equiv_inl sampleRows3 ∅ e b j -private def emptyFreeEquiv (n b₀ : ℕ) : - ↥((univ : Finset (Fin n)) \ - heavyVars univ (univ : Finset (Fin (emptyRows n).length)) - (fun j => equationScope ((emptyCNF n).parityRowSystem (emptyRows n) j)) b₀) ≃ - Fin n := - { toFun := fun v => v.1 - invFun := fun v => ⟨v, by rw [empty_heavyVars_eq_empty]; simp⟩ - left_inv := fun v => by ext; rfl - right_inv := fun v => rfl } +example (e : ↥(univ \ (∅ : Finset (Fin 3))) ≃ Fin 3) (b : Fin 3 → Bool) (v : Fin 3) : + branchAugmentedScope ∅ e univ (sampleCNF3.parityRowSystem sampleRows3) b + (CNF.parityRowAugmentedIndexEquiv sampleRows3.length 3 (Sum.inr v)) = {v} := + sampleCNF3.branchAugmentedScope_parityRowSystem_comp_equiv_inr sampleRows3 ∅ e b v -private theorem totalIncidence_empty_branchParityRowNeutralScope (n b₀ : ℕ) (b : Fin n → Bool) : - totalIncidence - (univ : Finset (Fin (emptyRows n).length ⊕ Fin n)) - ((emptyCNF n).branchParityRowNeutralScope (emptyRows n) - (heavyVars univ (univ : Finset (Fin (emptyRows n).length)) - (fun j => equationScope ((emptyCNF n).parityRowSystem (emptyRows n) j)) b₀) - (emptyFreeEquiv n b₀) b) = n := by - rw [CNF.totalIncidence_branchParityRowNeutralScope_eq] - have hzero : - totalIncidence - (univ : Finset (Fin (emptyRows n).length)) - ((emptyCNF n).branchParityRowScope (emptyRows n) - (heavyVars univ (univ : Finset (Fin (emptyRows n).length)) - (fun j => equationScope ((emptyCNF n).parityRowSystem (emptyRows n) j)) b₀) - (emptyFreeEquiv n b₀) b) = 0 := rfl - rw [hzero, zero_add] +/-! ### 2. Schedule-instantiated exact recovery of `commonZeroCount`, `numPassing`, and `#F` -/ -/-- Concrete witness at `n = 2 ^ (2 ^ 50)`, `β = 1`, `b₀ = 1`, `W = 0`, `k = 3`: -instantiates `Feasible.exists_branchParityRow_replacementDesign`, -`Feasible.branchParityRow_domainExaminationBound_le`, -`Feasible.greedyCandidate_domainExaminationBound_le`, and -`sum_branchParityRow_domainExaminationBound_le`. -/ example : - ∃ m n : ℕ, - m = 2 ^ 50 ∧ - n = 2 ^ m ∧ - rowCost 1 n < 1 / 3 ∧ - let φ := emptyCNF n - let rows := emptyRows n - let S := heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) 1 - let e := emptyFreeEquiv n 1 - (∀ b : Fin n → Bool, - ∃ (hF : Feasible 1 n 2 (max 1 (3 * (0 * 2 ^ 3))) - (totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n)) - (φ.branchParityRowNeutralScope rows S e b))) - (D : ReplacementDesign (φ.branchParityRowNeutralScope rows S e b) - (numNodes n) (numGroups n) (intervalStart 1 n) (rowBound 1 n) (tauRat n)), - let d := 3 * (rows.length + 2 * (branchPrecision (Fintype.card (Fin n)) - 1)) - let q := (d * rowBound 1 n) / numNodes n - let C := hF.toCountingDesign D univ - (∑ t : Fin (numNodes n), - (#{p : Finset (Fin n) × Finset (Fin n) | #p.1 ≤ q ∧ p.2 ⊆ p.1} : ℝ) * - (2 * (#(C.measurementBox t) : ℝ) * - ∑ g : Fin (numGroups n), (Fintype.card (C.LocalCube t g) : ℝ))) ≤ - 2 * (numNodes n : ℝ) * (numGroups n : ℝ) * - Real.exp (((16 * 3 + 4 : ℕ) : ℝ) * (n : ℝ) * rowCost 1 n)) ∧ - Fintype.card (Fin n) ≤ 2 * n := by - obtain ⟨m, hm⟩ : ∃ m : ℕ, m = 2 ^ 50 := ⟨2 ^ 50, rfl⟩ - obtain ⟨n, hn⟩ : ∃ n : ℕ, n = 2 ^ m := ⟨2 ^ m, rfl⟩ - have hcl_n : Nat.clog 2 n = 2 ^ 50 := by - rw [hn, Nat.clog_pow 2 m one_lt_two, hm] - have hcl_cl : Nat.clog 2 (Nat.clog 2 n) = 50 := by - rw [hcl_n] - exact Nat.clog_pow 2 50 one_lt_two - have hr_eq : numGroups n = 13421 := by - unfold numGroups - rw [hcl_cl, hcl_n] - have hsq : (2 ^ 50 : ℕ).sqrt = 2 ^ 25 := - le_antisymm (Nat.lt_succ_iff.mp (Nat.sqrt_lt.mpr (by norm_num))) - (Nat.le_sqrt.mpr (by norm_num)) - rw [hsq] - norm_num - have hQ_eq : numNodes n = 175921860444 := by - unfold numNodes - rw [hcl_cl, hcl_n] - norm_num - have hR_eq : rowBound 1 n = 134217728 := by - unfold rowBound - rw [hcl_n] - have hsq : (2 ^ 50 - 1 : ℕ).sqrt = 2 ^ 25 - 1 := - le_antisymm (Nat.lt_succ_iff.mp (Nat.sqrt_lt.mpr (by norm_num))) - (Nat.le_sqrt.mpr (by norm_num)) - simp only [show (2 ^ 50 : ℕ) ≠ 0 by positivity, ↓reduceIte, hsq] - norm_num - have hr : 2 ≤ numGroups n := by rw [hr_eq]; norm_num - have hR : 32 ≤ rowBound 1 n := by rw [hR_eq]; norm_num - have hRQ : 6 * rowBound 1 n ≤ numNodes n := by rw [hR_eq, hQ_eq]; norm_num - have hsub := interval_subset_range (β := 1) hr (by omega) (by omega) - have hrc := rowCost_le hr hR hRQ - have hrc_lt : rowCost 1 n < 1 / 3 := hrc.trans_lt <| by - rw [hcl_cl, hcl_n, show ((2 ^ 50 : ℕ) : ℝ) = ((2 : ℝ) ^ 25) ^ 2 by norm_num, - Real.sqrt_sq (by positivity)] - norm_num - have hF_base : Feasible 1 n 2 1 n := { - twenty_le := by - rw [hn] - exact (by norm_num : 20 ≤ 2 ^ 5).trans - (Nat.pow_le_pow_right two_pos (by rw [hm]; norm_num)) - two_le_numGroups := hr - thirtyTwo_le_rowBound := hR - six_mul_rowBound_le_numNodes := hRQ - tau_pos := by unfold tau; rw [hr_eq, hcl_n]; positivity - tau_le_half := by unfold tau; rw [hr_eq, hcl_n]; norm_num - auxDim_le := auxDim_le_two_pow n - aux_balance := - (Nat.mul_le_mul_left 6 (Nat.pow_le_pow_left (auxDim_le_two_pow n) 2)).trans <| by - have h6 : 6 ≤ 2 ^ 3 := by decide - refine (Nat.mul_le_mul_right _ h6).trans ?_ - rw [← pow_mul, ← pow_add, hn] - exact Nat.pow_le_pow_right two_pos - (by rw [Nat.clog_pow 2 m one_lt_two, hm]; norm_num) - var_balance := by - rw [hQ_eq, hr_eq, hn] - exact (by norm_num : 2 * 175921860444 * 13421 ^ 2 ≤ 2 ^ 66).trans - (Nat.pow_le_pow_right two_pos (by rw [hm]; norm_num)) - card_interval_eq := card_interval (by omega) - interval_subset := hsub - mem_interval_of_close := fun k hk => - ⟨mem_interval_of_abs_sub_le hr hR (by omega) hk, - Nat.lt_succ_iff.mp - (mem_range.mp (hsub (mem_interval_of_abs_sub_le hr hR (by omega) hk)))⟩ - binomTail_lt := - binomTail_lt_tailBudget le_rfl hr hR hRQ (by decide) (by rw [hcl_n]; norm_num) - rowCost_bound := hrc - } - refine ⟨m, n, hm, hn, hrc_lt, ?_⟩ - intro φ rows S e - have hM : - totalIncidence (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) * 2 ≤ - 1 * Fintype.card (Fin n) := by - have hzero : - totalIncidence (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) = 0 := rfl - rw [hzero, zero_mul] - exact Nat.zero_le _ - have hsum := sum_branchParityRow_domainExaminationBound_le φ rows - (β := 1) (b₀ := 1) (s_div := 2) (k := 3) (c := 6) - le_rfl le_rfl hM e (fun _ => 0) (fun _ _ => by positivity) - refine ⟨fun b => ?_, hsum.1⟩ - have hF_b : Feasible 1 n 2 (max 1 (3 * (0 * 2 ^ 3))) - (totalIncidence (univ : Finset (Fin rows.length ⊕ Fin n)) - (φ.branchParityRowNeutralScope rows S e b)) := by - rw [totalIncidence_empty_branchParityRowNeutralScope n 1 b] - exact hF_base - have hk : ∀ c ∈ φ, c.length ≤ 3 := fun _ hc => False.elim (List.not_mem_nil hc) - have hW : ∀ r_row ∈ rows, weight r_row ≤ 0 := fun _ hr_row => False.elim (List.not_mem_nil hr_row) - obtain ⟨D⟩ := hF_b.exists_branchParityRow_replacementDesign hk hW e b - refine ⟨hF_b, D, ?_⟩ - have hm_rows : rows.length ≤ 6 * Fintype.card (Fin n) := Nat.zero_le _ - exact (hF_b.greedyCandidate_domainExaminationBound_le (k := 3) φ rows D univ hm_rows hsum.1).1 - -/-! ### 3. Instantiation of uniform schedule recovery theorems at `β = 1` -/ - -/-- Nonvacuous instantiation of `exists_schedule_branchParityRow_replacementDesign`, -`exists_schedule_design_commonZeroCount_parityRowSystem_eq`, -`exists_schedule_design_numPassing_eq`, -`exists_schedule_design_modelCountOn_eq_greedy`, and -`exists_initialTests_and_schedule_design_modelCountOn_eq` at `β = 1`. -/ -example : - (∃ n₀ : ℕ, 20 ≤ n₀) ∧ - (∃ n₁ : ℕ, 20 ≤ n₁) ∧ - (∃ n₂ : ℕ, 20 ≤ n₂) ∧ - (∃ n₃ : ℕ, 20 ≤ n₃) ∧ - (∃ n₄ : ℕ, 20 ≤ n₄) := by - obtain ⟨n₀, hn₀, _⟩ := exists_schedule_branchParityRow_replacementDesign.{0} (β := 1) le_rfl - obtain ⟨n₁, hn₁, _⟩ := - exists_schedule_design_commonZeroCount_parityRowSystem_eq.{0} (β := 1) le_rfl - obtain ⟨n₂, hn₂, _⟩ := exists_schedule_design_numPassing_eq.{0} (β := 1) le_rfl - obtain ⟨n₃, hn₃, _⟩ := exists_schedule_design_modelCountOn_eq_greedy.{0} (β := 1) le_rfl - obtain ⟨n₄, hn₄, _⟩ := - exists_initialTests_and_schedule_design_modelCountOn_eq.{0} (β := 1) le_rfl - exact ⟨⟨n₀, hn₀⟩, ⟨n₁, hn₁⟩, ⟨n₂, hn₂⟩, ⟨n₃, hn₃⟩, ⟨n₄, hn₄⟩⟩ - -end Cslib.Complexity.SubexponentialSAT.SparseCNFDesignScheduleTests + ∃ n₀ : ℕ, 20 ≤ n₀ ∧ + ∀ {V : Type} [Fintype V] [DecidableEq V] + {φ : CNF V} ⦃n' k W b₀ : ℕ⦄, + (∀ c ∈ φ, c.length ≤ k) → + ∀ {rows : List (Fin φ.length → Bool)}, + (∀ r_row ∈ rows, weight r_row ≤ W) → + let S := heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀ + ∀ (e : ↥(univ \ S) ≃ Fin n'), + n₀ ≤ n' → + b₀ + 1 ≤ Nat.clog 2 n' ^ 1 → + max (k * (W * 2 ^ k)) 1 ≤ Nat.clog 2 n' ^ 1 → + (∀ b : V → Bool, + Feasible 1 n' (b₀ + 1) (max (k * (W * 2 ^ k)) 1) + (∑ f : {j : Fin rows.length // j ∈ (univ : Finset (Fin rows.length))} ⊕ Fin n', + #(branchAugmentedScope S e univ (φ.parityRowSystem rows) b f))) ∧ + ∃ D : (b : V → Bool) → + ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) + (numNodes n') (numGroups n') (intervalStart 1 n') (rowBound 1 n') (tauRat n'), + (commonZeroCount (univ : Finset (Fin rows.length)) (φ.parityRowSystem rows) : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound 1 n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).eval 0 / + clearedProductDenom (commonDenom (numNodes n') (rowBound 1 n') : ℤ) k + (branchPrecision (Fintype.card V)) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ + ∀ b : V → Bool, + (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound 1 n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).natDegree ≤ + (k * (rowBound 1 n' - 1)) * + (rows.length + 2 * (branchPrecision (Fintype.card V) - 1)) := + CNF.exists_schedule_design_commonZeroCount_parityRowSystem_eq.{0} le_rfl + +example : ∃ n₀ : ℕ, 20 ≤ n₀ := by + obtain ⟨n₀, hn₀, _⟩ := CNF.exists_schedule_design_numPassing_eq.{0} (β := 1) le_rfl + exact ⟨n₀, hn₀⟩ + +example : ∃ N₀ : ℕ, 20 ≤ N₀ := by + obtain ⟨N₀, hN₀, _⟩ := + CNF.exists_schedule_design_commonZeroCount_parityRowSystem_of_le_clog_pow.{0} 3 2 1 + exact ⟨N₀, hN₀⟩ + +example : ∃ N₀ : ℕ, 20 ≤ N₀ := by + obtain ⟨N₀, hN₀, _⟩ := + CNF.exists_schedule_design_numPassing_of_le_clog_pow.{0} 3 2 1 + exact ⟨N₀, hN₀⟩ + +example : ∃ n₀ : ℕ, 20 ≤ n₀ := by + obtain ⟨n₀, hn₀, _⟩ := + CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_eq.{0} (β := 1) le_rfl + exact ⟨n₀, hn₀⟩ + +example : ∃ N₀ : ℕ, 20 ≤ N₀ := by + obtain ⟨N₀, hN₀, _⟩ := + CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_of_le_clog_pow.{0} 3 2 1 + exact ⟨N₀, hN₀⟩ + +end Cslib.Complexity.SubexponentialSAT.ReplacementParams.SparseCNFDesignScheduleTests From bf7c87a631406ac5f36c95c2d6ad88c688663dd8 Mon Sep 17 00:00:00 2001 From: Samuel Schlesinger Date: Tue, 27 Oct 2026 06:09:37 +0000 Subject: [PATCH 20/20] test(FineGrained): exercise recovery conclusions on nonzero parity row (#1226) --- .../FineGrained/SparseCNFDesignSchedule.lean | 172 ++++++++-- .../FineGrained/SparseCNFDesignSchedule.lean | 318 ++++++++++++++---- 2 files changed, 391 insertions(+), 99 deletions(-) diff --git a/Complexity/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean b/Complexity/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean index 8fd3d3c52c..0a60ac6b77 100644 --- a/Complexity/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean +++ b/Complexity/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean @@ -24,11 +24,18 @@ constant-term recovery and univariate numerator degree bounds of - `CNF.parityRowAugmentedIndexEquiv`: canonical equivalence `Fin m ⊕ Fin n' ≃ {j : Fin m // j ∈ (univ : Finset (Fin m))} ⊕ Fin n'`. - `CNF.parityRowAugmentedInl`: active-equation factor embedding into `{j // j ∈ univ} ⊕ Fin n'`. - - `CNF.branchAugmentedScope_parityRowSystem_comp_equiv_inl` and + - `CNF.branchAugmentedScope_parityRowAugmentedInl`, + `CNF.branchAugmentedScope_parityRowSystem_comp_equiv_inl`, and `CNF.branchAugmentedScope_parityRowSystem_comp_equiv_inr`: evaluate - `branchAugmentedScope S e univ (φ.parityRowSystem rows) b` along - `CNF.parityRowAugmentedIndexEquiv`. + `branchAugmentedScope S e univ (φ.parityRowSystem rows) b` along `CNF.parityRowAugmentedInl` + and `CNF.parityRowAugmentedIndexEquiv`. 2. **Schedule-instantiated exact recovery of `commonZeroCount` and `numPassing` (§5.4–5.5 & §6.3)**: + - `CNF.exists_branch_replacementDesign_commonZeroCount_parityRowSystem_eq`: given per-branch + `Feasible β n' (b₀ + 1) (max (k * (W * 2 ^ k)) 1) M'_b`, consumes + `CNF.exists_branch_replacementDesign_parityRowSystem` and recovers + `commonZeroCount univ (φ.parityRowSystem rows)` and `numPassing φ.violations rows` with + univariate numerator degree at most + `(k * (rowBound β n' - 1)) * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1))`. - `CNF.exists_schedule_design_commonZeroCount_parityRowSystem_eq` and `CNF.exists_schedule_design_numPassing_eq`: combine `CNF.exists_branch_schedule_parityRowSystem` with @@ -40,14 +47,21 @@ constant-term recovery and univariate numerator degree bounds of (`B ≤ C_B * (Nat.clog 2 n) ^ β_B`, `b₀ = CNF.parityBranchThreshold k W n`, `β = 2 * β_B + 5`) with exact branch-summed constant-term recovery and numerator degree bounds. 3. **End-to-end greedy `modelCountOn` schedule-design recovery (§6.1–6.3)**: - - `CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_eq`: combines - `CNF.exists_greedy_parityRowSystem_branch_schedule` with exact branch-summed constant-term - recovery of `φ.modelCountOn Finset.univ` and the `(k * (rowBound β n' - 1)) * (8 * n)` - numerator degree bound after `3 * n` greedy rounds. - - `CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_of_le_clog_pow`: combines + - In Lemma 6.2 and Section 6.3, every candidate and final parity-row system has equation-count + ratio `6` (`rows.length ≤ 6 * Fintype.card V`, giving + `rows.length + 2 * (branchPrecision n - 1) ≤ 8 * n`), whereas Theorem 2.2's parameter + `c = c(k)` bounds both equation count and the monomial-sparsity exponent; our theorems keep the + equation-count bound `rows.length ≤ 6 * Fintype.card V` and the monomial-sparsity bound + `W * 2 ^ k` explicit. + - `CNF.exists_greedy_testRow_trajectory`: finite-minimization existence of a greedy parity-row + trajectory `(A, γ)` whenever `Nonempty (Fin P → Fin φ.length × Bool)`. + - `CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_eq` and + `CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_of_le_clog_pow`: combine + `CNF.exists_greedy_parityRowSystem_branch_schedule` and `CNF.exists_greedy_parityRowSystem_branch_schedule_of_le_clog_pow` with exact branch-summed - constant-term recovery of `φ.modelCountOn Finset.univ` unconditionally for any width-`≤ k` CNF - with `φ.length ≤ B * n` and `B ≤ C_B * (Nat.clog 2 n) ^ β_B`. + constant-term recovery of `φ.modelCountOn Finset.univ` and the + `(k * (rowBound _ n' - 1)) * (8 * Fintype.card V)` numerator degree bound after `3 * n` greedy + rounds. ## Main definitions @@ -56,12 +70,15 @@ constant-term recovery and univariate numerator degree bounds of ## Main results +* `Cslib.Logic.PL.CNF.branchAugmentedScope_parityRowAugmentedInl` * `Cslib.Logic.PL.CNF.branchAugmentedScope_parityRowSystem_comp_equiv_inl` * `Cslib.Logic.PL.CNF.branchAugmentedScope_parityRowSystem_comp_equiv_inr` +* `Cslib.Logic.PL.CNF.exists_branch_replacementDesign_commonZeroCount_parityRowSystem_eq` * `Cslib.Logic.PL.CNF.exists_schedule_design_commonZeroCount_parityRowSystem_eq` * `Cslib.Logic.PL.CNF.exists_schedule_design_numPassing_eq` * `Cslib.Logic.PL.CNF.exists_schedule_design_commonZeroCount_parityRowSystem_of_le_clog_pow` * `Cslib.Logic.PL.CNF.exists_schedule_design_numPassing_of_le_clog_pow` +* `Cslib.Logic.PL.CNF.exists_greedy_testRow_trajectory` * `Cslib.Logic.PL.CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_eq` * `Cslib.Logic.PL.CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_of_le_clog_pow` @@ -142,6 +159,79 @@ theorem CNF.branchAugmentedScope_parityRowSystem_comp_equiv_inr [Fintype V] [Dec /-! ### 2. Schedule-instantiated exact recovery of `commonZeroCount` and `numPassing` -/ +/-- **§5.4–5.5 & §6.3 (`Feasible`-instantiated `ReplacementDesign` recovery of `commonZeroCount` +and `numPassing` on `φ.parityRowSystem rows`)**: given a width-`≤ k` CNF `φ : CNF V`, a parity-row +list `rows : List (Fin φ.length → Bool)` with `∀ r_row ∈ rows, weight r_row ≤ W`, heavy-variable +set `S = heavyVars univ univ (fun j => equationScope (φ.parityRowSystem rows j)) b₀`, free-variable +relabeling `e : ↥(univ \ S) ≃ Fin n'`, and per-branch +`Feasible β n' (b₀ + 1) (max (k * (W * 2 ^ k)) 1) M'_b`, +there exists a family `D` of concrete Lemma 4.8 schedule `ReplacementDesign`s across all branches +`b : V → Bool` recovering `commonZeroCount univ (φ.parityRowSystem rows)` and +`numPassing φ.violations rows` via constant-term evaluation with univariate numerator degree at most +`(k * (rowBound β n' - 1)) * (rows.length + 2 * (branchPrecision (Fintype.card V) - 1))`. -/ +theorem CNF.exists_branch_replacementDesign_commonZeroCount_parityRowSystem_eq + [Fintype V] [DecidableEq V] {φ : CNF V} {β k W b₀ : ℕ} + (hk : ∀ c ∈ φ, c.length ≤ k) + {rows : List (Fin φ.length → Bool)} (hW : ∀ r_row ∈ rows, weight r_row ≤ W) + (e : ↥(univ \ heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) ≃ Fin n') + (hF : ∀ b : V → Bool, + Feasible β n' (b₀ + 1) (max (k * (W * 2 ^ k)) 1) + (∑ f : {j : Fin rows.length // j ∈ (univ : Finset (Fin rows.length))} ⊕ Fin n', + #(branchAugmentedScope + (heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀) + e univ (φ.parityRowSystem rows) b f))) : + let S := heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀ + ∃ D : (b : V → Bool) → + ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) + (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n'), + (commonZeroCount (univ : Finset (Fin rows.length)) (φ.parityRowSystem rows) : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).eval 0 / + clearedProductDenom (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ + (numPassing φ.violations rows : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).eval 0 / + clearedProductDenom (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ + ∀ b : V → Bool, + (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound β n') : ℤ) k + (branchPrecision (Fintype.card V)) + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).natDegree ≤ + (k * (rowBound β n' - 1)) * + (rows.length + 2 * (branchPrecision (Fintype.card V) - 1)) := by + intro S + let D : (b : V → Bool) → + ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) + (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n') := + fun b => Classical.choice + (φ.exists_branch_replacementDesign_parityRowSystem hk hW e b (hF b)) + have hcz := CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design hk rows S e + (fun b => branchAugmentedScope S e univ (φ.parityRowSystem rows) b) D + (fun _ => CNF.parityRowAugmentedInl) + refine ⟨D, hcz, ?_, fun b => ?_⟩ + · rw [← CNF.commonZeroCount_parityRowSystem] + exact hcz + · exact CNF.natDegree_univariateClearedParityTruncatedSum_branchParityRowSystem_le hk rows S e b + (D b) CNF.parityRowAugmentedInl (branchPrecision (Fintype.card V)) + /-- **§5.4–5.5 & §6.3 (schedule-instantiated `ReplacementDesign` recovery of `commonZeroCount` on `φ.parityRowSystem rows`)**: for every `1 ≤ β`, the threshold `n₀ ≥ 20` of `CNF.exists_branch_schedule_parityRowSystem` guarantees that whenever `n₀ ≤ n'`, @@ -195,16 +285,10 @@ theorem CNF.exists_schedule_design_commonZeroCount_parityRowSystem_eq {β : ℕ} refine ⟨n₀, hn₀20, fun {V _ _ φ n' k W b₀} hk {rows} hW => ?_⟩ intro S e hn' hb₀ hw have h_all := hsched hk hW e hn' hb₀ hw - let D : (b : V → Bool) → - ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) - (numNodes n') (numGroups n') (intervalStart β n') (rowBound β n') (tauRat n') := - fun b => Classical.choice (h_all b).2 - refine ⟨fun b => (h_all b).1, D, ?_, fun b => ?_⟩ - · exact CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design hk rows S e - (fun b => branchAugmentedScope S e univ (φ.parityRowSystem rows) b) D - (fun _ => CNF.parityRowAugmentedInl) - · exact CNF.natDegree_univariateClearedParityTruncatedSum_branchParityRowSystem_le hk rows S e b - (D b) CNF.parityRowAugmentedInl (branchPrecision (Fintype.card V)) + obtain ⟨D, hcz, _, hdeg⟩ := + φ.exists_branch_replacementDesign_commonZeroCount_parityRowSystem_eq hk hW e + (fun b => (h_all b).1) + exact ⟨fun b => (h_all b).1, D, hcz, hdeg⟩ /-- **§5.4–5.5 & §6.3 (schedule-instantiated `ReplacementDesign` recovery of `numPassing φ.violations rows`)**: under the hypotheses of @@ -314,17 +398,10 @@ theorem CNF.exists_schedule_design_commonZeroCount_parityRowSystem_of_le_clog_po refine ⟨N₀, hN₀20, fun {V _ _ φ n' B W} hk hN₀ hm hB hW_bound {rows} hW hlen => ?_⟩ intro b₀ S e obtain ⟨hsqrt, hcard, hbr, h_all⟩ := hsched hk hN₀ hm hB hW_bound hW hlen e - let D : (b : V → Bool) → - ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) - (numNodes n') (numGroups n') (intervalStart (2 * β_B + 5) n') - (rowBound (2 * β_B + 5) n') (tauRat n') := - fun b => Classical.choice (h_all b).2 - refine ⟨hsqrt, hcard, hbr, fun b => (h_all b).1, D, ?_, fun b => ?_⟩ - · exact CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design hk rows S e - (fun b => branchAugmentedScope S e univ (φ.parityRowSystem rows) b) D - (fun _ => CNF.parityRowAugmentedInl) - · exact CNF.natDegree_univariateClearedParityTruncatedSum_branchParityRowSystem_le hk rows S e b - (D b) CNF.parityRowAugmentedInl (branchPrecision (Fintype.card V)) + obtain ⟨D, hcz, _, hdeg⟩ := + φ.exists_branch_replacementDesign_commonZeroCount_parityRowSystem_eq hk hW e + (fun b => (h_all b).1) + exact ⟨hsqrt, hcard, hbr, fun b => (h_all b).1, D, hcz, hdeg⟩ /-- **Unconditional Section 6.3 schedule-design recovery of `numPassing φ.violations rows` for `B ≤ C_B * (Nat.clog 2 n) ^ β_B`**. -/ @@ -385,12 +462,41 @@ theorem CNF.exists_schedule_design_numPassing_of_le_clog_pow (k C_B β_B : ℕ) /-! ### 3. End-to-end greedy `modelCountOn` schedule-design recovery -/ +/-- Finite-minimization existence of a greedy parity-row trajectory `(A, γ)` starting from any +initial row list `A₀`, provided the candidate tuple type `Fin P → Fin φ.length × Bool` is nonempty +(for instance whenever `1 ≤ φ.length`). -/ +theorem CNF.exists_greedy_testRow_trajectory [Fintype V] [DecidableEq V] + (φ : CNF V) (P : ℕ) [Nonempty (Fin P → Fin φ.length × Bool)] + (A₀ : List (Fin φ.length → Bool)) : + ∃ (A : ℕ → List (Fin φ.length → Bool)) + (γ : ℕ → Fin P → Fin φ.length × Bool), + A 0 = A₀ ∧ + (∀ i, A (i + 1) = A i ++ [testRow (γ i)]) ∧ + (∀ i (γ' : Fin P → Fin φ.length × Bool), + commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow (γ i)])) ≤ + commonZeroCount univ (φ.parityRowSystem (A i ++ [testRow γ']))) := by + have hmin : ∀ rows : List (Fin φ.length → Bool), + ∃ γ₀ : Fin P → Fin φ.length × Bool, + ∀ γ' : Fin P → Fin φ.length × Bool, + commonZeroCount univ (φ.parityRowSystem (rows ++ [testRow γ₀])) ≤ + commonZeroCount univ (φ.parityRowSystem (rows ++ [testRow γ'])) := fun rows => by + obtain ⟨γ₀, _, hγ₀⟩ := + exists_min_image (univ : Finset (Fin P → Fin φ.length × Bool)) + (fun γ' => commonZeroCount univ (φ.parityRowSystem (rows ++ [testRow γ']))) + univ_nonempty + exact ⟨γ₀, fun γ' => hγ₀ γ' (mem_univ γ')⟩ + choose nextGamma hnextGamma using hmin + let A : ℕ → List (Fin φ.length → Bool) := + fun i => Nat.recOn i A₀ (fun _ rows => rows ++ [testRow (nextGamma rows)]) + refine ⟨A, fun i => nextGamma (A i), rfl, fun _ => rfl, fun i γ' => hnextGamma (A i) γ'⟩ + /-- **Lemmas 6.1–6.2 & §§5.4–5.5, 6.3 (conditional greedy parity-test schedule-design recovery of `φ.modelCountOn Finset.univ`)**: combines `CNF.exists_greedy_parityRowSystem_branch_schedule` with `CNF.commonZeroCount_parityRowSystem_eq_sum_branch_emod_ediv_design` so that at every stage `i ≤ 3 * n`, concrete Lemma 4.8 schedule `ReplacementDesign`s exist across all heavy-variable -branches, and at the final stage `i = 3 * n`, they recover `(φ.modelCountOn Finset.univ : ℤ)` with -univariate numerator degree at most `(k * (rowBound β n' - 1)) * (8 * Fintype.card V)`. -/ +branches (with equation-count bound `(A i).length ≤ 6 * n`), and at the final stage `i = 3 * n`, +they recover `(φ.modelCountOn Finset.univ : ℤ)` with univariate numerator degree at most +`(k * (rowBound β n' - 1)) * (8 * Fintype.card V)`. -/ theorem CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_eq {β : ℕ} (hβ : 1 ≤ β) : ∃ n₀ : ℕ, 20 ≤ n₀ ∧ ∀ {V : Type*} [Fintype V] [DecidableEq V] diff --git a/ComplexityTests/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean b/ComplexityTests/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean index 3ab96f98fb..3a9be73c8f 100644 --- a/ComplexityTests/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean +++ b/ComplexityTests/Computability/Complexity/FineGrained/SparseCNFDesignSchedule.lean @@ -13,12 +13,12 @@ public import Complexity.Computability.Complexity.FineGrained.SparseCNFDesignSch /-! # Tests for `SparseCNFDesignSchedule` -Concrete tests and nonvacuity witnesses for the index-equivalence bridge and schedule-instantiated -exact recovery theorems in +Concrete tests and nonvacuous recovery witnesses on a formula with a nonzero parity row for the +index-equivalence bridge and schedule-instantiated exact recovery theorems in `Complexity.Computability.Complexity.FineGrained.SparseCNFDesignSchedule`. -/ -public section +@[expose] public noncomputable section namespace Cslib.Complexity.SubexponentialSAT.ReplacementParams.SparseCNFDesignScheduleTests @@ -47,6 +47,13 @@ example (v : Fin 3) : CNF.parityRowAugmentedIndexEquiv 1 3 (Sum.inr v) = Sum.inr v := by simp only [CNF.parityRowAugmentedIndexEquiv_inr] +example (e : ↥(univ \ (∅ : Finset (Fin 3))) ≃ Fin 3) (b : Fin 3 → Bool) + (j : Fin sampleRows3.length) : + branchAugmentedScope ∅ e univ (sampleCNF3.parityRowSystem sampleRows3) b + (CNF.parityRowAugmentedInl j) = + branchEquationScope ∅ e (sampleCNF3.parityRowSystem sampleRows3) b j := + sampleCNF3.branchAugmentedScope_parityRowAugmentedInl sampleRows3 ∅ e b j + example (e : ↥(univ \ (∅ : Finset (Fin 3))) ≃ Fin 3) (b : Fin 3 → Bool) (j : Fin sampleRows3.length) : branchAugmentedScope ∅ e univ (sampleCNF3.parityRowSystem sampleRows3) b @@ -59,71 +66,250 @@ example (e : ↥(univ \ (∅ : Finset (Fin 3))) ≃ Fin 3) (b : Fin 3 → Bool) (CNF.parityRowAugmentedIndexEquiv sampleRows3.length 3 (Sum.inr v)) = {v} := sampleCNF3.branchAugmentedScope_parityRowSystem_comp_equiv_inr sampleRows3 ∅ e b v -/-! ### 2. Schedule-instantiated exact recovery of `commonZeroCount`, `numPassing`, and `#F` -/ +/-! ### 2. Nonzero-row CNF fixture and schedule-instantiated exact recovery witnesses -/ + +/-- A 1-clause CNF `(x₀)` over `Fin (n + 1)` of width `1 ≤ 3`. -/ +def unitClauseCNF (n : ℕ) : CNF (Fin (n + 1)) := + [[⟨0, true⟩]] + +/-- Nonzero parity-row list selecting the unique clause of `unitClauseCNF n`. -/ +def unitClauseRows (n : ℕ) : List (Fin (unitClauseCNF n).length → Bool) := + [fun _ => true] + +theorem width_unitClauseCNF_le_three (n : ℕ) : + ∀ c ∈ unitClauseCNF n, c.length ≤ 3 := by + intro c hc + rcases List.mem_singleton.mp hc with rfl + simp +theorem weight_unitClauseRows_le_one (n : ℕ) : + ∀ r_row ∈ unitClauseRows n, weight r_row ≤ 1 := by + intro r_row hr + rcases List.mem_singleton.mp hr with rfl + refine (card_filter_le _ _).trans ?_ + rw [card_univ, Fintype.card_fin] + simp [unitClauseCNF] + +theorem heavyVars_unitClauseCNF_eq_empty (n : ℕ) {b₀ : ℕ} (hb₀ : 1 ≤ b₀) : + heavyVars (univ : Finset (Fin (n + 1))) + (univ : Finset (Fin (unitClauseRows n).length)) + (fun j => equationScope ((unitClauseCNF n).parityRowSystem (unitClauseRows n) j)) b₀ = + ∅ := by + ext v + simp only [heavyVars, varIncidence, mem_filter, mem_univ, true_and, notMem_empty, iff_false, + not_lt] + refine (card_filter_le _ _).trans ?_ + rw [card_univ, Fintype.card_fin] + simpa [unitClauseRows] using hb₀ + +/-- Free-variable equivalence for `unitClauseCNF n` and `unitClauseRows n` at any threshold +`1 ≤ b₀`, since `heavyVars` is empty. -/ +def unitClauseEquiv (n : ℕ) {b₀ : ℕ} (hb₀ : 1 ≤ b₀) : + ↥((univ : Finset (Fin (n + 1))) \ + heavyVars (univ : Finset (Fin (n + 1))) + (univ : Finset (Fin (unitClauseRows n).length)) + (fun j => equationScope ((unitClauseCNF n).parityRowSystem (unitClauseRows n) j)) b₀) ≃ + Fin (n + 1) where + toFun v := v.1 + invFun v := ⟨v, by rw [heavyVars_unitClauseCNF_eq_empty n hb₀]; simp⟩ + left_inv v := by ext; rfl + right_inv v := rfl + +private theorem five_le_clog_succ {n : ℕ} (hn : 20 ≤ n) : 5 ≤ Nat.clog 2 (n + 1) := by + have h16 : 2 ^ 4 < n + 1 := by omega + exact (Nat.lt_clog_iff_pow_lt one_lt_two).mpr h16 + +/-- Nonvacuous recovery check for `CNF.exists_schedule_design_commonZeroCount_parityRowSystem_eq` +and `CNF.exists_schedule_design_numPassing_eq` on `unitClauseCNF n₀` with the nonzero parity row +`unitClauseRows n₀` (`W = 1`, `b₀ = 1`, `k = 3`, `β = 5`). -/ example : ∃ n₀ : ℕ, 20 ≤ n₀ ∧ - ∀ {V : Type} [Fintype V] [DecidableEq V] - {φ : CNF V} ⦃n' k W b₀ : ℕ⦄, - (∀ c ∈ φ, c.length ≤ k) → - ∀ {rows : List (Fin φ.length → Bool)}, - (∀ r_row ∈ rows, weight r_row ≤ W) → - let S := heavyVars univ (univ : Finset (Fin rows.length)) - (fun j => equationScope (φ.parityRowSystem rows j)) b₀ - ∀ (e : ↥(univ \ S) ≃ Fin n'), - n₀ ≤ n' → - b₀ + 1 ≤ Nat.clog 2 n' ^ 1 → - max (k * (W * 2 ^ k)) 1 ≤ Nat.clog 2 n' ^ 1 → - (∀ b : V → Bool, - Feasible 1 n' (b₀ + 1) (max (k * (W * 2 ^ k)) 1) - (∑ f : {j : Fin rows.length // j ∈ (univ : Finset (Fin rows.length))} ⊕ Fin n', - #(branchAugmentedScope S e univ (φ.parityRowSystem rows) b f))) ∧ - ∃ D : (b : V → Bool) → - ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) - (numNodes n') (numGroups n') (intervalStart 1 n') (rowBound 1 n') (tauRat n'), - (commonZeroCount (univ : Finset (Fin rows.length)) (φ.parityRowSystem rows) : ℤ) = - (∑ b ∈ branchAssignments S, - ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) - (φ.branchParityRowSystem rows S e b) - (commonDenom (numNodes n') (rowBound 1 n') : ℤ) k - (branchPrecision (Fintype.card V)) - (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).eval 0 / - clearedProductDenom (commonDenom (numNodes n') (rowBound 1 n') : ℤ) k - (branchPrecision (Fintype.card V)) - #(univ : Finset (Fin rows.length))) % - ((2 : ℤ) ^ branchPrecision (Fintype.card V))) ∧ - ∀ b : V → Bool, - (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) - (φ.branchParityRowSystem rows S e b) - (commonDenom (numNodes n') (rowBound 1 n') : ℤ) k - (branchPrecision (Fintype.card V)) - (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).natDegree ≤ - (k * (rowBound 1 n' - 1)) * - (rows.length + 2 * (branchPrecision (Fintype.card V) - 1)) := - CNF.exists_schedule_design_commonZeroCount_parityRowSystem_eq.{0} le_rfl - -example : ∃ n₀ : ℕ, 20 ≤ n₀ := by - obtain ⟨n₀, hn₀, _⟩ := CNF.exists_schedule_design_numPassing_eq.{0} (β := 1) le_rfl - exact ⟨n₀, hn₀⟩ - -example : ∃ N₀ : ℕ, 20 ≤ N₀ := by - obtain ⟨N₀, hN₀, _⟩ := - CNF.exists_schedule_design_commonZeroCount_parityRowSystem_of_le_clog_pow.{0} 3 2 1 - exact ⟨N₀, hN₀⟩ - -example : ∃ N₀ : ℕ, 20 ≤ N₀ := by - obtain ⟨N₀, hN₀, _⟩ := - CNF.exists_schedule_design_numPassing_of_le_clog_pow.{0} 3 2 1 - exact ⟨N₀, hN₀⟩ - -example : ∃ n₀ : ℕ, 20 ≤ n₀ := by - obtain ⟨n₀, hn₀, _⟩ := - CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_eq.{0} (β := 1) le_rfl - exact ⟨n₀, hn₀⟩ - -example : ∃ N₀ : ℕ, 20 ≤ N₀ := by - obtain ⟨N₀, hN₀, _⟩ := - CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_of_le_clog_pow.{0} 3 2 1 - exact ⟨N₀, hN₀⟩ + let φ := unitClauseCNF n₀ + let rows := unitClauseRows n₀ + let S := heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) 1 + let e := unitClauseEquiv n₀ (b₀ := 1) le_rfl + ∃ (D₁ D₂ : (b : Fin (n₀ + 1) → Bool) → + ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) + (numNodes (n₀ + 1)) (numGroups (n₀ + 1)) (intervalStart 5 (n₀ + 1)) + (rowBound 5 (n₀ + 1)) (tauRat (n₀ + 1))), + (commonZeroCount (univ : Finset (Fin rows.length)) (φ.parityRowSystem rows) : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes (n₀ + 1)) (rowBound 5 (n₀ + 1)) : ℤ) 3 + (branchPrecision (Fintype.card (Fin (n₀ + 1)))) + (designReplacementScaledIntMap (D₁ b) CNF.parityRowAugmentedInl)).eval 0 / + clearedProductDenom + (commonDenom (numNodes (n₀ + 1)) (rowBound 5 (n₀ + 1)) : ℤ) 3 + (branchPrecision (Fintype.card (Fin (n₀ + 1)))) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card (Fin (n₀ + 1))))) ∧ + (numPassing φ.violations rows : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes (n₀ + 1)) (rowBound 5 (n₀ + 1)) : ℤ) 3 + (branchPrecision (Fintype.card (Fin (n₀ + 1)))) + (designReplacementScaledIntMap (D₂ b) CNF.parityRowAugmentedInl)).eval 0 / + clearedProductDenom + (commonDenom (numNodes (n₀ + 1)) (rowBound 5 (n₀ + 1)) : ℤ) 3 + (branchPrecision (Fintype.card (Fin (n₀ + 1)))) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card (Fin (n₀ + 1))))) := by + obtain ⟨n₁, hn₁, hcz⟩ := + CNF.exists_schedule_design_commonZeroCount_parityRowSystem_eq.{0} (β := 5) (by decide) + obtain ⟨n₂, hn₂, hnp⟩ := + CNF.exists_schedule_design_numPassing_eq.{0} (β := 5) (by decide) + let n₀ := max n₁ n₂ + have hn₀ : 20 ≤ n₀ := hn₁.trans (le_max_left n₁ n₂) + refine ⟨n₀, hn₀, ?_⟩ + intro φ rows S e + have h5 : 5 ^ 5 ≤ Nat.clog 2 (n₀ + 1) ^ 5 := + Nat.pow_le_pow_left (five_le_clog_succ hn₀) 5 + have hb₀ : 1 + 1 ≤ Nat.clog 2 (n₀ + 1) ^ 5 := (by decide : 1 + 1 ≤ 5 ^ 5).trans h5 + have hw : max (3 * (1 * 2 ^ 3)) 1 ≤ Nat.clog 2 (n₀ + 1) ^ 5 := + (by decide : max (3 * (1 * 2 ^ 3)) 1 ≤ 5 ^ 5).trans h5 + obtain ⟨_, D₁, hD₁, _⟩ := hcz (width_unitClauseCNF_le_three n₀) (weight_unitClauseRows_le_one n₀) + e ((le_max_left n₁ n₂).trans (Nat.le_succ n₀)) hb₀ hw + obtain ⟨_, D₂, hD₂, _⟩ := hnp (width_unitClauseCNF_le_three n₀) (weight_unitClauseRows_le_one n₀) + e ((le_max_right n₁ n₂).trans (Nat.le_succ n₀)) hb₀ hw + exact ⟨D₁, D₂, hD₁, hD₂⟩ + +/-- Nonvacuous recovery check for +`CNF.exists_schedule_design_commonZeroCount_parityRowSystem_of_le_clog_pow` and +`CNF.exists_schedule_design_numPassing_of_le_clog_pow` on `unitClauseCNF N₀` (`k = 3`, `C_B = 1`, +`β_B = 1`, `B = 1`). -/ +example : + ∃ N₀ : ℕ, 20 ≤ N₀ ∧ + let φ := unitClauseCNF N₀ + let W := CNF.initialRowWeightBound 1 φ.length + let b₀ := CNF.parityBranchThreshold 3 W (Fintype.card (Fin (N₀ + 1))) + ∃ rows : List (Fin φ.length → Bool), + rows.length ≤ 6 * Fintype.card (Fin (N₀ + 1)) ∧ + let S := heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀ + let n' := Fintype.card ↥((univ : Finset (Fin (N₀ + 1))) \ S) + let e := Fintype.equivFin ↥((univ : Finset (Fin (N₀ + 1))) \ S) + ∃ (D₁ D₂ : (b : Fin (N₀ + 1) → Bool) → + ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) + (numNodes n') (numGroups n') (intervalStart 7 n') + (rowBound 7 n') (tauRat n')), + (commonZeroCount (univ : Finset (Fin rows.length)) (φ.parityRowSystem rows) : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound 7 n') : ℤ) 3 + (branchPrecision (Fintype.card (Fin (N₀ + 1)))) + (designReplacementScaledIntMap (D₁ b) CNF.parityRowAugmentedInl)).eval 0 / + clearedProductDenom + (commonDenom (numNodes n') (rowBound 7 n') : ℤ) 3 + (branchPrecision (Fintype.card (Fin (N₀ + 1)))) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card (Fin (N₀ + 1))))) ∧ + (numPassing φ.violations rows : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound 7 n') : ℤ) 3 + (branchPrecision (Fintype.card (Fin (N₀ + 1)))) + (designReplacementScaledIntMap (D₂ b) CNF.parityRowAugmentedInl)).eval 0 / + clearedProductDenom + (commonDenom (numNodes n') (rowBound 7 n') : ℤ) 3 + (branchPrecision (Fintype.card (Fin (N₀ + 1)))) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card (Fin (N₀ + 1))))) := by + obtain ⟨N₁, hN₁, hcz⟩ := + CNF.exists_schedule_design_commonZeroCount_parityRowSystem_of_le_clog_pow.{0} 3 1 1 + obtain ⟨N₂, hN₂, hnp⟩ := + CNF.exists_schedule_design_numPassing_of_le_clog_pow.{0} 3 1 1 + let N₀ := max N₁ N₂ + have hN₀ : 20 ≤ N₀ := hN₁.trans (le_max_left N₁ N₂) + refine ⟨N₀, hN₀, ?_⟩ + intro φ W b₀ + have hcard₁ : N₁ ≤ Fintype.card (Fin (N₀ + 1)) := by + rw [Fintype.card_fin] + exact (le_max_left N₁ N₂).trans (Nat.le_succ N₀) + have hcard₂ : N₂ ≤ Fintype.card (Fin (N₀ + 1)) := by + rw [Fintype.card_fin] + exact (le_max_right N₁ N₂).trans (Nat.le_succ N₀) + have hm : φ.length ≤ 1 * Fintype.card (Fin (N₀ + 1)) := by simp [φ, unitClauseCNF] + have hB : 1 ≤ 1 * Nat.clog 2 (Fintype.card (Fin (N₀ + 1))) ^ 1 := by + rw [Fintype.card_fin, one_mul, pow_one] + exact (by decide : 1 ≤ 5).trans (five_le_clog_succ hN₀) + have hn1 : 1 ≤ Fintype.card (Fin (N₀ + 1)) := by rw [Fintype.card_fin]; omega + obtain ⟨A₀, hlen0, hw0, _⟩ := + φ.exists_initialTests_commonZeroCount_greedy (width_unitClauseCNF_le_three N₀) hn1 le_rfl hm + have hlen : A₀.length ≤ 6 * Fintype.card (Fin (N₀ + 1)) := + hlen0.trans (Nat.mul_le_mul_right _ (by decide)) + refine ⟨A₀, hlen, ?_⟩ + intro S n' e + obtain ⟨_, _, _, _, D₁, hD₁, _⟩ := hcz (width_unitClauseCNF_le_three N₀) hcard₁ hm hB le_rfl + hw0 hlen e + obtain ⟨_, _, _, _, D₂, hD₂, _⟩ := hnp (width_unitClauseCNF_le_three N₀) hcard₂ hm hB le_rfl + hw0 hlen e + exact ⟨D₁, D₂, hD₁, hD₂⟩ + +/-- Nonvacuous end-to-end greedy model-count recovery check for +`CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_of_le_clog_pow` and +`CNF.exists_greedy_testRow_trajectory` on `unitClauseCNF N₀` (`k = 3`, `C_B = 1`, `β_B = 1`, +`B = 1`). -/ +example : + ∃ N₀ : ℕ, 20 ≤ N₀ ∧ + let φ := unitClauseCNF N₀ + let D₀ := CNF.initialRowWeightBound 1 φ.length + let b₀ := CNF.parityBranchThreshold 3 D₀ (Fintype.card (Fin (N₀ + 1))) + ∃ (rows : List (Fin φ.length → Bool)), + rows.length ≤ 6 * Fintype.card (Fin (N₀ + 1)) ∧ + let S := heavyVars univ (univ : Finset (Fin rows.length)) + (fun j => equationScope (φ.parityRowSystem rows j)) b₀ + let n' := Fintype.card ↥((univ : Finset (Fin (N₀ + 1))) \ S) + let e := Fintype.equivFin ↥((univ : Finset (Fin (N₀ + 1))) \ S) + ∃ D : (b : Fin (N₀ + 1) → Bool) → + ReplacementDesign (branchAugmentedScope S e univ (φ.parityRowSystem rows) b) + (numNodes n') (numGroups n') (intervalStart 7 n') (rowBound 7 n') (tauRat n'), + (φ.modelCountOn Finset.univ : ℤ) = + (∑ b ∈ branchAssignments S, + ((univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound 7 n') : ℤ) 3 + (branchPrecision (Fintype.card (Fin (N₀ + 1)))) + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).eval 0 / + clearedProductDenom + (commonDenom (numNodes n') (rowBound 7 n') : ℤ) 3 + (branchPrecision (Fintype.card (Fin (N₀ + 1)))) + #(univ : Finset (Fin rows.length))) % + ((2 : ℤ) ^ branchPrecision (Fintype.card (Fin (N₀ + 1))))) ∧ + ∀ b : Fin (N₀ + 1) → Bool, + (univariateClearedParityTruncatedSum (univ : Finset (Fin rows.length)) + (φ.branchParityRowSystem rows S e b) + (commonDenom (numNodes n') (rowBound 7 n') : ℤ) 3 + (branchPrecision (Fintype.card (Fin (N₀ + 1)))) + (designReplacementScaledIntMap (D b) CNF.parityRowAugmentedInl)).natDegree ≤ + (3 * (rowBound 7 n' - 1)) * (8 * Fintype.card (Fin (N₀ + 1))) := by + obtain ⟨N₀, hN₀, hgreedy_sched⟩ := + CNF.exists_greedy_parityRowSystem_schedule_design_modelCountOn_of_le_clog_pow.{0} 3 1 1 + refine ⟨N₀, hN₀, ?_⟩ + intro φ D₀ b₀ + have hcard : N₀ ≤ Fintype.card (Fin (N₀ + 1)) := by + rw [Fintype.card_fin] + exact Nat.le_succ N₀ + have hB : 1 ≤ 1 * Nat.clog 2 (Fintype.card (Fin (N₀ + 1))) ^ 1 := by + rw [Fintype.card_fin, one_mul, pow_one] + exact (by decide : 1 ≤ 5).trans (five_le_clog_succ hN₀) + have hm : φ.length ≤ 1 * Fintype.card (Fin (N₀ + 1)) := by simp [φ, unitClauseCNF] + obtain ⟨A₀, _, _, hgreedy⟩ := + hgreedy_sched φ (width_unitClauseCNF_le_three N₀) hcard le_rfl hB hm + let P := CNF.greedyRowListLength 1 φ.length + have : Nonempty (Fin P → Fin φ.length × Bool) := + ⟨fun _ => (⟨0, by simp [φ, unitClauseCNF]⟩, false)⟩ + obtain ⟨A, γ, h0, hA, hγ⟩ := φ.exists_greedy_testRow_trajectory P A₀ + obtain ⟨_, hstage, hrec⟩ := hgreedy A γ h0 hA hγ + have hlen : (A (3 * Fintype.card (Fin (N₀ + 1)))).length ≤ + 6 * Fintype.card (Fin (N₀ + 1)) := + (hstage (3 * Fintype.card (Fin (N₀ + 1))) le_rfl).1 + refine ⟨A (3 * Fintype.card (Fin (N₀ + 1))), hlen, ?_⟩ + intro S n' e + exact hrec e end Cslib.Complexity.SubexponentialSAT.ReplacementParams.SparseCNFDesignScheduleTests