Skip to content

[Rule] 3SAT to REGISTER SUFFICIENCY #872

@isPANN

Description

@isPANN

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:

  1. E1 = { (initial, g) | g in A union B union F union U }

  2. E2 = { (g, initial) | g in C union R union S union T union W }

  3. E3 = { (final, g) | g in W union X union Z union {initial, d} }

  4. 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])
  5. For each k = 1..n, add

    • (w[k], u[k,1])
    • (w[k], u[k,2])
  6. 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
      • (z[k], r[k,j])
  7. 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])
  8. For each clause i = 1..m and each j = 1..3, add

    • (c[i], f[i,j])
  9. For each g in B union C, add

    • (d, g)
  10. 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

    • (neg_lit(i,j), f[i,k])

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:

  1. Stop immediately after w[n] is computed.
  2. For each variable x_k, at most one of x_pos[k] and x_neg[k] has been computed by then.
  3. 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

  1. Please implement the classical Sethi reduction, not the 4-node diamond approximation.
  2. Do not make B unconditional; when m >= 2*n, B is empty.
  3. The Garey–Johnson comment about max out-degree <= 2 is a stronger variant. This issue should implement the baseline Sethi construction first.
  4. Change "exactly one" to "at most one" in the extraction rule.
  5. Change the sign in the assignment rule from x_neg[k] to x_pos[k].
  6. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GoodAn issue passed all checks.ruleA new reduction rule to be added.

    Type

    No type

    Projects

    Status

    Ready

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions