Source: 3-SATISFIABILITY (3SAT)
Target: REGISTER SUFFICIENCY
Motivation: The previous issue body used a simplified "diamond chain" gadget and an unspecified, clause-dependent register bound. That is not the classical reduction cited by Garey–Johnson. This replacement follows Sethi's actual Reduction I / Theorem 3.11.
Reference: Garey & Johnson, Computers and Intractability, A11 PO1; Ravi Sethi, "Complete Register Allocation Problems," SIAM J. Comput. 4(3), 1975, Reduction I and Theorem 3.11.
GJ Source Entry
[PO1] REGISTER SUFFICIENCY
INSTANCE: Directed acyclic graph G = (V, A), positive integer K.
QUESTION: Is there a computation for G that uses K or fewer registers?
Reference: [Sethi, 1975]. Transformation from 3SAT.
Orientation Convention
Use Sethi's orientation: an arc (u, v) means that v is a direct descendant of u, so v must be computed before u.
Reduction Algorithm
Input: a 3-CNF formula
phi = C_1 and ... and C_m
over variables x_1, ..., x_n, where each clause is
C_i = (Y[i,1] or Y[i,2] or Y[i,3])
and each Y[i,j] is either x_k or not x_k.
Define b = max(0, 2*n - m).
Create node families:
A = { a[j] | 1 <= j <= 2*n + 1 }
B = { bnode[j] | 1 <= j <= b }
C = { c[i] | 1 <= i <= m }
F = { f[i,j] | 1 <= i <= m, 1 <= j <= 3 }
M = { initial, d, final }
R = { r[k,j] | 1 <= k <= n, 1 <= j <= 2*n - 2*k + 2 }
S = { s[k,j] | 1 <= k <= n, 1 <= j <= 2*n - 2*k + 1 }
T = { t[k,j] | 1 <= k <= n, 1 <= j <= 2*n - 2*k + 1 }
U = { u[k,1], u[k,2] | 1 <= k <= n }
W = { w[k] | 1 <= k <= n }
X = { x_pos[k], x_neg[k] | 1 <= k <= n }
Z = { z[k] | 1 <= k <= n }
Set
V = A union B union C union F union M union R union S union T union U union W union X union Z.
Add arc families:
-
E1 = { (initial, g) | g in A union B union F union U }
-
E2 = { (g, initial) | g in C union R union S union T union W }
-
E3 = { (final, g) | g in W union X union Z union {initial, d} }
-
For each k = 1..n, add
(x_pos[k], z[k])
(x_neg[k], z[k])
(x_pos[k], u[k,1])
(x_neg[k], u[k,2])
-
For each k = 1..n, add
(w[k], u[k,1])
(w[k], u[k,2])
-
For each k = 1..n:
- for
j = 1..(2*n - 2*k + 1), add
(x_pos[k], s[k,j])
(x_neg[k], t[k,j])
- for
j = 1..(2*n - 2*k + 2), add
-
For each k = 2..n, add
(z[k], w[k-1])
(z[k], z[k-1])
For each clause i = 1..m, add
(c[i], w[n])
(c[i], z[n])
-
For each clause i = 1..m and each j = 1..3, add
-
For each g in B union C, add
-
Literal-to-clause-lock edges:
For each clause i and literal position j, define:
- if
Y[i,j] = x_k, then
lit(i,j) = x_pos[k]
neg_lit(i,j) = x_neg[k]
- if
Y[i,j] = not x_k, then
lit(i,j) = x_neg[k]
neg_lit(i,j) = x_pos[k]
Add:
(lit(i,1), f[i,1])
(lit(i,2), f[i,2])
(lit(i,3), f[i,3])
and for each pair 1 <= j < k <= 3, add
Finally set the register bound to
K = 3*m + 4*n + 1 + b.
Output the RegisterSufficiency instance (D=(V,E), K).
Solution Extraction
Given a computation of D using at most K registers:
- Stop immediately after
w[n] is computed.
- For each variable
x_k, at most one of x_pos[k] and x_neg[k] has been computed by then.
- Set
tau(x_k) = true iff x_pos[k] has already been computed by that time,
tau(x_k) = false otherwise.
Correctness Sketch
- Forward direction: keep the existing 8-step Sethi stone algorithm unchanged.
- Do not invert
E4 and do not flip the orientation convention. The DAG construction itself is correct.
Why w[n] is the correct extraction point
The literal-assignment stage ends when z[n] and w[n] have been computed.
After the move that computes w[n] and before the move that computes d, only clause nodes c[i] are computed.
So the truth assignment read immediately after w[n] is stable throughout the clause phase.
Why the repaired extraction works
Assume, for contradiction, that some clause
C_i = (Y[i,1] or Y[i,2] or Y[i,3])
is false under tau.
For each j in {1,2,3}, the node corresponding to literal Y[i,j] has not been computed by the snapshot time:
- if
Y[i,j] = x_k and tau(x_k) = false, then x_pos[k] is uncomputed;
- if
Y[i,j] = not x_k and tau(x_k) = true, then x_neg[k] is uncomputed.
Hence each f[i,j] still has an uncomputed literal ancestor when c[i] is reached.
During the clause phase there is no free register.
Therefore c[i] cannot be computed without one extra register.
Contradiction.
So the extracted assignment satisfies phi.
Sanity Check
Take phi = (x_1 or x_1 or x_1).
The old rule (stop at z[1], set tau(x_1) = true iff x_neg[1] has been computed) returns false.
The repaired rule (stop at w[1], set tau(x_1) = true iff x_pos[1] has been computed) returns true, which is the intended satisfying assignment.
Size Overhead
Let b = max(0, 2*n - m).
| Target metric (code name) |
Expression |
num_vertices |
3*num_vars^2 + 9*num_vars + 4*num_clauses + b + 4 |
num_arcs |
6*num_vars^2 + 19*num_vars + 16*num_clauses + 2*b + 1 |
bound |
3*num_clauses + 4*num_vars + 1 + b |
So the construction is polynomial and in fact O(n^2 + m).
Implementation Notes
- Please implement the classical Sethi reduction, not the 4-node diamond approximation.
- Do not make
B unconditional; when m >= 2*n, B is empty.
- The Garey–Johnson comment about max out-degree
<= 2 is a stronger variant. This issue should implement the baseline Sethi construction first.
- Change "exactly one" to "at most one" in the extraction rule.
- Change the sign in the assignment rule from
x_neg[k] to x_pos[k].
- Keep
E4 exactly as stated above — do not invert or flip the orientation.
Example
Source (KSatisfiability):
phi = (x_1 or not x_2 or x_3) and (not x_1 or x_2 or not x_3)
Then n = 3, m = 2, b = max(0, 6 - 2) = 4, so
K = 3*2 + 4*3 + 1 + 4 = 23
num_vertices = 70
num_arcs = 152
For clause 1, the E10 edges are:
(x_pos[1], f[1,1])
(x_neg[2], f[1,2])
(x_pos[3], f[1,3])
(x_neg[1], f[1,2])
(x_neg[1], f[1,3])
(x_pos[2], f[1,3])
The rest of the graph is generated mechanically from the formulas above.
Validation Method
- Closed-loop test: reduce KSatisfiability to RegisterSufficiency, solve via RegisterSufficiency → ILP, extract truth assignment from computation ordering prefix at w[n], verify all clauses satisfied
- Test with both satisfiable and unsatisfiable instances
- Add a regression case where the last variable is forced true (e.g.,
phi = (x_1 or x_1 or x_1))
- The extracted assignment must be read at
w[n], not z[n]
- Verify vertex/arc counts match overhead formulas
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 PO1.
Source: 3-SATISFIABILITY (3SAT)
Target: REGISTER SUFFICIENCY
Motivation: The previous issue body used a simplified "diamond chain" gadget and an unspecified, clause-dependent register bound. That is not the classical reduction cited by Garey–Johnson. This replacement follows Sethi's actual Reduction I / Theorem 3.11.
Reference: Garey & Johnson, Computers and Intractability, A11 PO1; Ravi Sethi, "Complete Register Allocation Problems," SIAM J. Comput. 4(3), 1975, Reduction I and Theorem 3.11.
GJ Source Entry
Orientation Convention
Use Sethi's orientation: an arc
(u, v)means thatvis a direct descendant ofu, sovmust be computed beforeu.Reduction Algorithm
Input: a 3-CNF formula
phi = C_1 and ... and C_mover variables
x_1, ..., x_n, where each clause isC_i = (Y[i,1] or Y[i,2] or Y[i,3])and each
Y[i,j]is eitherx_kornot x_k.Define
b = max(0, 2*n - m).Create node families:
A = { a[j] | 1 <= j <= 2*n + 1 }B = { bnode[j] | 1 <= j <= b }C = { c[i] | 1 <= i <= m }F = { f[i,j] | 1 <= i <= m, 1 <= j <= 3 }M = { initial, d, final }R = { r[k,j] | 1 <= k <= n, 1 <= j <= 2*n - 2*k + 2 }S = { s[k,j] | 1 <= k <= n, 1 <= j <= 2*n - 2*k + 1 }T = { t[k,j] | 1 <= k <= n, 1 <= j <= 2*n - 2*k + 1 }U = { u[k,1], u[k,2] | 1 <= k <= n }W = { w[k] | 1 <= k <= n }X = { x_pos[k], x_neg[k] | 1 <= k <= n }Z = { z[k] | 1 <= k <= n }Set
V = A union B union C union F union M union R union S union T union U union W union X union Z.Add arc families:
E1 = { (initial, g) | g in A union B union F union U }E2 = { (g, initial) | g in C union R union S union T union W }E3 = { (final, g) | g in W union X union Z union {initial, d} }For each
k = 1..n, add(x_pos[k], z[k])(x_neg[k], z[k])(x_pos[k], u[k,1])(x_neg[k], u[k,2])For each
k = 1..n, add(w[k], u[k,1])(w[k], u[k,2])For each
k = 1..n:j = 1..(2*n - 2*k + 1), add(x_pos[k], s[k,j])(x_neg[k], t[k,j])j = 1..(2*n - 2*k + 2), add(z[k], r[k,j])For each
k = 2..n, add(z[k], w[k-1])(z[k], z[k-1])For each clause
i = 1..m, add(c[i], w[n])(c[i], z[n])For each clause
i = 1..mand eachj = 1..3, add(c[i], f[i,j])For each
g in B union C, add(d, g)Literal-to-clause-lock edges:
For each clause
iand literal positionj, define:Y[i,j] = x_k, thenlit(i,j) = x_pos[k]neg_lit(i,j) = x_neg[k]Y[i,j] = not x_k, thenlit(i,j) = x_neg[k]neg_lit(i,j) = x_pos[k]Add:
(lit(i,1), f[i,1])(lit(i,2), f[i,2])(lit(i,3), f[i,3])and for each pair
1 <= j < k <= 3, add(neg_lit(i,j), f[i,k])Finally set the register bound to
K = 3*m + 4*n + 1 + b.Output the
RegisterSufficiencyinstance(D=(V,E), K).Solution Extraction
Given a computation of
Dusing at mostKregisters:w[n]is computed.x_k, at most one ofx_pos[k]andx_neg[k]has been computed by then.tau(x_k) = trueiffx_pos[k]has already been computed by that time,tau(x_k) = falseotherwise.Correctness Sketch
E4and do not flip the orientation convention. The DAG construction itself is correct.Why
w[n]is the correct extraction pointThe literal-assignment stage ends when
z[n]andw[n]have been computed.After the move that computes
w[n]and before the move that computesd, only clause nodesc[i]are computed.So the truth assignment read immediately after
w[n]is stable throughout the clause phase.Why the repaired extraction works
Assume, for contradiction, that some clause
C_i = (Y[i,1] or Y[i,2] or Y[i,3])is false under
tau.For each
j in {1,2,3}, the node corresponding to literalY[i,j]has not been computed by the snapshot time:Y[i,j] = x_kandtau(x_k) = false, thenx_pos[k]is uncomputed;Y[i,j] = not x_kandtau(x_k) = true, thenx_neg[k]is uncomputed.Hence each
f[i,j]still has an uncomputed literal ancestor whenc[i]is reached.During the clause phase there is no free register.
Therefore
c[i]cannot be computed without one extra register.Contradiction.
So the extracted assignment satisfies
phi.Sanity Check
Take
phi = (x_1 or x_1 or x_1).The old rule (stop at
z[1], settau(x_1) = trueiffx_neg[1]has been computed) returnsfalse.The repaired rule (stop at
w[1], settau(x_1) = trueiffx_pos[1]has been computed) returnstrue, which is the intended satisfying assignment.Size Overhead
Let
b = max(0, 2*n - m).num_vertices3*num_vars^2 + 9*num_vars + 4*num_clauses + b + 4num_arcs6*num_vars^2 + 19*num_vars + 16*num_clauses + 2*b + 1bound3*num_clauses + 4*num_vars + 1 + bSo the construction is polynomial and in fact O(n^2 + m).
Implementation Notes
Bunconditional; whenm >= 2*n,Bis empty.<= 2is a stronger variant. This issue should implement the baseline Sethi construction first.x_neg[k]tox_pos[k].E4exactly as stated above — do not invert or flip the orientation.Example
Source (KSatisfiability):
phi = (x_1 or not x_2 or x_3) and (not x_1 or x_2 or not x_3)Then
n = 3,m = 2,b = max(0, 6 - 2) = 4, soK = 3*2 + 4*3 + 1 + 4 = 23num_vertices = 70num_arcs = 152For clause 1, the E10 edges are:
(x_pos[1], f[1,1])(x_neg[2], f[1,2])(x_pos[3], f[1,3])(x_neg[1], f[1,2])(x_neg[1], f[1,3])(x_pos[2], f[1,3])The rest of the graph is generated mechanically from the formulas above.
Validation Method
phi = (x_1 or x_1 or x_1))w[n], notz[n]References