-
Notifications
You must be signed in to change notification settings - Fork 3
[Rule] 3-SATISFIABILITY to FEASIBLE REGISTER ASSIGNMENT #905
Description
Source: 3-SATISFIABILITY (3SAT)
Target: FEASIBLE REGISTER ASSIGNMENT
Motivation: Establishes NP-completeness of determining whether a given register assignment is feasible for a DAG computation. Even when the number of registers is sufficient, a specific assignment of registers to vertices may not admit any valid evaluation order — and checking this is as hard as 3SAT. This result by Sethi (1975) separates the feasibility question from the sufficiency question.
Reference: Garey & Johnson, Computers and Intractability, A11 PO2; Sethi, R. (1975). "Complete Register Allocation Problems." SIAM Journal on Computing, 4(3), pp. 226–248.
GJ Source Entry
[PO2] FEASIBLE REGISTER ASSIGNMENT
INSTANCE: Directed acyclic graph G = (V, A), positive integer K, register assignment f: V → {R₁, R₂, ..., Rₖ}.
QUESTION: Is there a computation for G that respects the register assignment f?Reference: [Sethi, 1975]. Transformation from 3-SATISFIABILITY.
Comment: NP-complete even with maximum out-degree 2.
Reduction Algorithm
Given a KSatisfiability<K3> instance with n variables and m clauses, construct a FeasibleRegisterAssignment instance (G, K, f) as follows:
Variable gadgets
For each variable x_i (i = 0, ..., n−1), create two source vertices (no incoming arcs):
pos_i: represents the positive literal x_i, assigned to register R_ineg_i: represents the negative literal ¬x_i, assigned to register R_i
Since pos_i and neg_i share register R_i, one must have all its dependents computed before the other can be placed in that register. The vertex computed first encodes the "chosen" truth value.
Clause chain gadgets
For each clause C_j = (l_0 ∨ l_1 ∨ l_2) (j = 0, ..., m−1), create a chain of 5 vertices using two fresh registers R_{n+2j} and R_{n+2j+1}:
lit_{j,0} : depends on src(l_0), register = R_{n+2j}
mid_{j,0} : depends on lit_{j,0}, register = R_{n+2j+1}
lit_{j,1} : depends on src(l_1) and mid_{j,0}, register = R_{n+2j}
mid_{j,1} : depends on lit_{j,1}, register = R_{n+2j+1}
lit_{j,2} : depends on src(l_2) and mid_{j,1}, register = R_{n+2j}
where src(l) is pos_i if l = x_i (positive) or neg_i if l = ¬x_i (negative).
The chain structure enables register reuse: lit_{j,0} dies when mid_{j,0} is computed, freeing R_{n+2j} for lit_{j,1}, and so on.
Solution extraction
From a feasible evaluation ordering σ, read the truth assignment:
- τ(x_i) = 1 if pos_i is computed before neg_i in σ, else τ(x_i) = 0.
Correctness
- (⇒) If the formula is satisfiable, compute chosen literal sources first, then process clause chains. Each satisfied clause has at least one "chosen" source available, so the chain can proceed without register conflicts.
- (⇐) If a feasible ordering exists, the chain structure forces sequential evaluation. If all three literal sources in a clause were "unchosen" (second in their variable pair), a scheduling deadlock occurs — the unchosen source needs its register freed, but freeing requires its partner's dependents (including chain nodes) to complete. Hence at least one literal per clause must be chosen = true.
Size Overhead
| Target metric (code name) | Expression |
|---|---|
num_vertices |
2 * num_vars + 5 * num_clauses |
num_arcs |
7 * num_clauses |
num_registers |
num_vars + 2 * num_clauses |
Derivation: 2 source vertices per variable + 5 chain vertices per clause. Each clause contributes 3 literal dependency arcs + 4 chain dependency arcs = 7 arcs. Each variable uses 1 register; each clause uses 2 fresh registers.
Implementation Note
FeasibleRegisterAssignment currently has 0 outgoing reductions (no ILP solver). A FeasibleRegisterAssignment → ILP rule should be implemented alongside this rule:
- Binary assignment matrix: x[v][t] ∈ {0,1} (vertex v at position t)
- Permutation constraints: each row/col sums to 1
- Topological: for arc (u,v), position(u) < position(v)
- Register conflict: for v,w sharing a register, ordering indicator b[v][w] + big-M constraints ensuring all dependents of the first-computed vertex complete before the second uses the register
- Feasibility objective (Value = Or)
Example
Source (KSatisfiability):
n = 4 variables (x_1, x_2, x_3, x_4), m = 3 clauses:
- C_1 = (x_1 ∨ ¬x_2 ∨ x_3)
- C_2 = (¬x_1 ∨ x_4 ∨ ¬x_3)
- C_3 = (x_2 ∨ ¬x_4 ∨ x_3)
Each variable appears 2–3 times across clauses with mixed polarity. Variables x_1 and x_3 each appear in all 3 clauses with opposite signs.
Target (FeasibleRegisterAssignment):
- 2·4 + 5·3 = 23 vertices, 7·3 = 21 arcs, 4 + 2·3 = 10 registers
- Variable gadget vertices (8): pos_0, neg_0, pos_1, neg_1, pos_2, neg_2, pos_3, neg_3
- Register assignments: R_0 for {pos_0, neg_0}, R_1 for {pos_1, neg_1}, R_2 for {pos_2, neg_2}, R_3 for {pos_3, neg_3}
- Clause 1 chain (5 vertices): lit_{0,0}, mid_{0,0}, lit_{0,1}, mid_{0,1}, lit_{0,2}
- Registers: R_4, R_5, R_4, R_5, R_4
- Literal sources: src(x_1)=pos_0, src(¬x_2)=neg_1, src(x_3)=pos_2
- Arcs: (pos_0, lit_{0,0}), (lit_{0,0}, mid_{0,0}), (neg_1, lit_{0,1}), (mid_{0,0}, lit_{0,1}), (lit_{0,1}, mid_{0,1}), (pos_2, lit_{0,2}), (mid_{0,1}, lit_{0,2})
- Clause 2 chain (5 vertices): lit_{1,0}, mid_{1,0}, lit_{1,1}, mid_{1,1}, lit_{1,2}
- Registers: R_6, R_7, R_6, R_7, R_6
- Literal sources: src(¬x_1)=neg_0, src(x_4)=pos_3, src(¬x_3)=neg_2
- Clause 3 chain (5 vertices): lit_{2,0}, mid_{2,0}, lit_{2,1}, mid_{2,1}, lit_{2,2}
- Registers: R_8, R_9, R_8, R_9, R_8
- Literal sources: src(x_2)=pos_1, src(¬x_4)=neg_3, src(x_3)=pos_2
Satisfying assignment: x_1=1, x_2=0, x_3=1, x_4=1
- C_1: x_1=T ✓
- C_2: x_4=T ✓
- C_3: x_3=T ✓
- Evaluation order: compute pos_0, neg_1, pos_2, pos_3 first (chosen literals), then process clause chains in order. The clause chains proceed without register conflicts because each clause has at least one chosen literal source ready.
Non-satisfying assignment: x_1=0, x_2=1, x_3=0, x_4=0
- C_1: (F ∨ F ∨ F) = F ✗
- All three literal sources for C_1 are "unchosen": pos_0 (x_1 chosen=neg), neg_1 (x_2 chosen=pos), pos_2 (x_3 chosen=neg). This creates the scheduling deadlock in C_1's chain — none of the literal sources can be computed without first completing dependents that include the very chain nodes waiting to start.
Validation Method
- Closed-loop test: reduce KSatisfiability to FeasibleRegisterAssignment, solve target via ILP (FeasibleRegisterAssignment → ILP), extract truth assignment from evaluation ordering, verify all clauses satisfied
- Test with both satisfiable and unsatisfiable instances
- Verified by PR docs: batch verify-reduction — 34 implementable reductions verified #992 with 11K automated checks (constructor + adversary scripts)
References
- Sethi, R. (1975). "Complete Register Allocation Problems." SIAM Journal on Computing, 4(3), pp. 226–248.
- Garey, M. R., & Johnson, D. S. (1979). Computers and Intractability, A11 PO2.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status