-
Notifications
You must be signed in to change notification settings - Fork 3
[Model] AlgebraicEquationsOverGF2 #853
Description
Motivation
ALGEBRAIC EQUATIONS OVER GF[2] (P228) from Garey & Johnson, A7 AN9. A classical NP-complete problem useful for reductions. Fundamental in coding theory, cryptography (Groebner basis attacks on AES), and algebraic complexity theory. Serves as a target for the X3C reduction (R172) established by Fraenkel and Yesha (1979). Remains NP-complete even when restricted to degree-2 polynomials (Valiant, 1979).
Associated rules:
- [Rule] X3C to ALGEBRAIC EQUATIONS OVER GF[2] #859: ExactCoverBy3Sets → AlgebraicEquationsOverGF2 (classical NP-completeness proof)
Definition
Name: AlgebraicEquationsOverGF2
Reference: Garey & Johnson, Computers and Intractability, A7 AN9
Mathematical definition:
INSTANCE: Polynomials P_i(x_1, x_2, . . . , x_n), 1 ≤ i ≤ m, over GF[2], i.e., each polynomial is a sum of terms, where each term is either the integer 1 or a product of distinct x_i.
QUESTION: Do there exist u_1, u_2, . . . , u_n ∈ {0,1} such that, for 1 ≤ i ≤ m, P_i(u_1, u_2, . . . , u_n) = 0, where arithmetic operations are as defined in GF[2], with 1+1 = 0 and 1·1 = 1?
Variables
- Count: n binary variables (x_1, ..., x_n)
- Per-variable domain: {0, 1} (elements of GF(2))
- Meaning: x_j = u_j is the assignment to variable j. Since variables are over GF(2), all polynomials are multilinear (x_j^2 = x_j). The system is satisfiable iff there exists an assignment (u_1, ..., u_n) ∈ {0,1}^n such that every polynomial evaluates to 0 under GF(2) arithmetic.
Schema (data type)
Type name: AlgebraicEquationsOverGF2
Variants: none (polynomials are always multilinear over GF(2); no type parameters)
| Field | Type | Description |
|---|---|---|
num_variables |
usize |
Number of variables n |
equations |
Vec<Vec<Vec<usize>>> |
Each equation is a list of monomials; each monomial is a sorted list of variable indices (empty = constant 1) |
Notes:
- This is a feasibility (decision) problem:
Value = Or. - Key getter methods:
num_variables()(= n),num_equations()(= m). - Each equation represents a polynomial P_i = 0. A monomial is a product of distinct variables identified by index. The empty monomial
[]represents the constant 1. Addition is XOR (mod 2). For example, x_1 * x_2 + x_3 + 1 = 0 is represented as[[0, 1], [2], []].
Complexity
- Decision complexity: NP-complete (Fraenkel and Yesha, 1979; transformation from X3C). Remains NP-complete even when restricted to degree-2 (quadratic) polynomials (Valiant, 1979). Linear systems (degree 1) are solvable in polynomial time via Gaussian elimination over GF(2).
- Best known exact algorithm (degree-2): O*(2^{0.6943n}) via improved parity-counting techniques (Dinur, SODA 2021), building on Bjorklund, Kaski & Williams (ICALP 2019, O*(2^{0.804n})) and Lokshtanov, Paturi, Tamaki, Williams & Yu (SODA 2017, O*(2^{0.876n})).
- General degree-d: O*(2^{(1 - 1/(5d))n}) (Lokshtanov et al., SODA 2017).
- Concrete complexity expression:
"2^(0.6943 * num_variables)"(fordeclare_variants!; degree-2 bound, the most common case) - References:
- A.S. Fraenkel, Y. Yesha (1979). "Complexity of problems in games, graphs and algebraic equations." Discrete Applied Mathematics, 1(1-2):15-30.
- I. Dinur (2021). "Improved Algorithms for Solving Polynomial Systems over GF(2) by Multiple Parity-Counting." SODA 2021.
- A. Bjorklund, P. Kaski, R. Williams (2019). "Solving Systems of Polynomial Equations over GF(2) by a Parity-Counting Self-Reduction." ICALP 2019.
- D. Lokshtanov, R. Paturi, S. Tamaki, R. Williams, H. Yu (2017). "Beating Brute Force for Systems of Polynomial Equations over Finite Fields." SODA 2017.
Extra Remark
Full book text:
INSTANCE: Polynomials P_i(x_1, x_2, . . . , x_n), 1 ≤ i ≤ m, over GF[2], i.e., each polynomial is a sum of terms, where each term is either the integer 1 or a product of distinct x_i.
QUESTION: Do there exist u_1, u_2, . . . , u_n ∈ {0,1} such that, for 1 ≤ i ≤ m, P_i(u_1, u_2, . . . , u_n) = 0, where arithmetic operations are as defined in GF[2], with 1+1 = 0 and 1·1 = 1?
Reference: [Fraenkel and Yesha, 1977]. Transformation from X3C.
Comment: Remains NP-complete even if none of the polynomials has a term involving more than two variables [Valiant, 1977c]. Easily solved in polynomial time if no term involves more than one variable or if there is just one polynomial. Variant in which the u_j are allowed to range over the algebraic closure of GF[2] is NP-hard, even if no term involves more than two variables [Fraenkel and Yesha, 1977].
How to solve
- It can be solved by (existing) bruteforce. (Enumerate all 2^n assignments; check if every polynomial evaluates to 0 mod 2.)
- It can be solved by reducing to integer programming. (Each polynomial equation P_i = 0 over GF(2) can be linearized by introducing auxiliary variables for each product term, then requiring the XOR of all terms to be 0, expressible as a linear constraint modulo 2 embedded in ILP. Companion rule issue to be filed separately.)
- Other: Groebner basis methods; parity-counting algorithms (Lokshtanov et al. 2017, Bjorklund et al. 2019).
Example Instance
Input:
n = 3 variables: x_1, x_2, x_3
m = 3 quadratic equations over GF(2):
- P_1: x_1 · x_2 + x_3 = 0
- P_2: x_2 · x_3 + x_1 + 1 = 0
- P_3: x_1 + x_2 + x_3 + 1 = 0
Represented as:
equations = [
[[0, 1], [2]], // x1*x2 + x3
[[1, 2], [0], []], // x2*x3 + x1 + 1
[[0], [1], [2], []], // x1 + x2 + x3 + 1
]
Feasible assignment: (x_1, x_2, x_3) = (1, 0, 0):
- P_1: 1·0 + 0 = 0 (mod 2) ✓
- P_2: 0·0 + 1 + 1 = 0 (mod 2) ✓
- P_3: 1 + 0 + 0 + 1 = 0 (mod 2) ✓
Answer: YES — this is the unique satisfying assignment (1 out of 8 possible).
Negative example:
Replace P_2 with P_2': x_1 · x_2 + x_3 + 1 = 0. Now P_1 and P_2' are contradictory: P_1 requires x_1·x_2 + x_3 = 0 while P_2' requires x_1·x_2 + x_3 + 1 = 0, which means 0 = 1 in GF(2) — impossible regardless of the variable assignment. Answer: NO.
Python validation script
# Positive example
satisfying = []
for x1 in range(2):
for x2 in range(2):
for x3 in range(2):
p1 = (x1*x2 + x3) % 2
p2 = (x2*x3 + x1 + 1) % 2
p3 = (x1 + x2 + x3 + 1) % 2
if p1 == 0 and p2 == 0 and p3 == 0:
satisfying.append((x1, x2, x3))
assert satisfying == [(1, 0, 0)]
print(f"Positive: {len(satisfying)} satisfying assignment(s): {satisfying}")
# Negative example (P1 and P2' contradict)
satisfying_neg = []
for x1 in range(2):
for x2 in range(2):
for x3 in range(2):
p1 = (x1*x2 + x3) % 2
p2p = (x1*x2 + x3 + 1) % 2 # contradicts P1
p3 = (x1 + x2 + x3 + 1) % 2
if p1 == 0 and p2p == 0 and p3 == 0:
satisfying_neg.append((x1, x2, x3))
assert len(satisfying_neg) == 0
print("Negative: 0 satisfying assignments (correct)")Metadata
Metadata
Assignees
Labels
Type
Projects
Status