The reduction from satisfiability to (3,4)-satisfiability
Lax345332.Construction · concepts/Lax345332/Construction.lean · lax-345332
No public endorsements yet.
Loading review…
Sign in with ORCIDNatural Language Statement
Definition
A CNF formula with literal occurrences over variables below is turned into a (3,4) formula in two steps.
Splitting. The occurrence at position is replaced by a fresh variable , where is the variable occurring there. A clause becomes a chain through link variables : the clause becomes , and an empty clause stays empty. For every the implications , taken cyclically over all positions, force the copies of to agree. Clauses now have at most three literals and every variable occurs at most three times.
Padding. Every clause with fewer than three literals is filled with literals , each on a fresh variable that a private copy of Tovey's gadget forces to be true. The gadget has thirteen clauses on and nine further variables; occurs three times in it and every other variable four times.
The reduction on words decodes a formula, applies the two steps and encodes the result; a word that encodes no formula is treated as the formula with one empty clause.
Concept map
Evidence
Lean source view on GitHub
| 1 | import Lax345332.ThreeFourSat |
| 2 | |
| 3 | /-! |
| 4 | --- |
| 5 | title: The reduction from satisfiability to (3,4)-satisfiability |
| 6 | type: definition |
| 7 | --- |
| 8 | A CNF formula with literal occurrences over variables below is turned into a |
| 9 | (3,4) formula in two steps. |
| 10 | |
| 11 | *Splitting.* The occurrence at position is replaced by a fresh variable , |
| 12 | where is the variable occurring there. A clause becomes a chain through link variables |
| 13 | : the clause becomes |
| 14 | , and an |
| 15 | empty clause stays empty. For every the implications , taken |
| 16 | cyclically over all positions, force the copies of to agree. Clauses now have at most |
| 17 | three literals and every variable occurs at most three times. |
| 18 | |
| 19 | *Padding.* Every clause with fewer than three literals is filled with literals , |
| 20 | each on a fresh variable that a private copy of Tovey's gadget forces to be true. The |
| 21 | gadget has thirteen clauses on and nine further variables; occurs three times in |
| 22 | it and every other variable four times. |
| 23 | |
| 24 | The reduction on words decodes a formula, applies the two steps and encodes the result; a |
| 25 | word that encodes no formula is treated as the formula with one empty clause. |
| 26 | |
| 27 | # Formalization notes |
| 28 | |
| 29 | All copies with and are created and tied together, not only those |
| 30 | of pairs that occur. This makes the cyclic successor of a position simply the next |
| 31 | position, at the cost of an output of quadratic size. |
| 32 | -/ |
| 33 | |
| 34 | namespace Lax345332.Construction |
| 35 | |
| 36 | open Lax429075.CNF Lax429075.Encoding Lax434930.PolynomialTime Lax345332.ThreeFourSat |
| 37 | |
| 38 | -- The gadget |
| 39 | |
| 40 | /-- Tovey's thirteen clauses on the variables `g, g+1, …, g+9`; they force `g` to be true. -/ |
| 41 | def gadget (g : ℕ) : Formula := |
| 42 | let y := g |
| 43 | let a (j : ℕ) := g + 1 + 3 * j |
| 44 | let b (j : ℕ) := g + 2 + 3 * j |
| 45 | let d (j : ℕ) := g + 3 + 3 * j |
| 46 | ((List.range 3).map fun j => [⟨y, true⟩, ⟨a j, true⟩, ⟨b j, true⟩]) ++ |
| 47 | ((List.range 3).flatMap fun j => |
| 48 | [[⟨d j, true⟩, ⟨a j, true⟩, ⟨b j, false⟩], [⟨d j, true⟩, ⟨a j, false⟩, ⟨b j, true⟩], |
| 49 | [⟨d j, true⟩, ⟨a j, false⟩, ⟨b j, false⟩]]) ++ |
| 50 | [[⟨d 0, false⟩, ⟨d 1, false⟩, ⟨d 2, false⟩]] |
| 51 | |
| 52 | -- Padding |
| 53 | |
| 54 | /-- The base of the `t`-th gadget of the `k`-th clause, above the variables below `B`. -/ |
| 55 | def ybase (B k t : ℕ) : ℕ := B + 30 * k + 10 * t |
| 56 | |
| 57 | /-- The padding literals of a clause of length `n`. -/ |
| 58 | def pads (B k n : ℕ) : Clause := (List.range (3 - n)).map fun t => ⟨ybase B k t, false⟩ |
| 59 | |
| 60 | /-- The `k`-th clause, padded, with its three gadgets. -/ |
| 61 | def unit (B k : ℕ) (C : Clause) : Formula := |
| 62 | (C ++ pads B k C.length) :: |
| 63 | (gadget (ybase B k 0) ++ gadget (ybase B k 1) ++ gadget (ybase B k 2)) |
| 64 | |
| 65 | /-- The padded formula. -/ |
| 66 | def pad (B : ℕ) (G : Formula) : Formula := |
| 67 | (List.range G.length).flatMap fun k => unit B k (G.getD k []) |
| 68 | |
| 69 | -- Splitting |
| 70 | |
| 71 | /-- The copy of the variable `v` at position `p`. -/ |
| 72 | def wv (V v p : ℕ) : ℕ := v + p * V |
| 73 | |
| 74 | /-- The link variable after position `p`. -/ |
| 75 | def zv (V N p : ℕ) : ℕ := V * N + p |
| 76 | |
| 77 | def dflt : Literal := ⟨0, false⟩ |
| 78 | |
| 79 | /-- The `i`-th clause of the chain of `C`, whose first literal sits at position `o`. -/ |
| 80 | def chainClause (V N o : ℕ) (C : Clause) (i : ℕ) : Clause := |
| 81 | (if i = 0 then [] else [⟨zv V N (o + i - 1), false⟩]) ++ |
| 82 | [⟨wv V (C.getD i dflt).index (o + i), (C.getD i dflt).positive⟩] ++ |
| 83 | (if i + 1 = C.length then [] else [⟨zv V N (o + i), true⟩]) |
| 84 | |
| 85 | def chainClauses (V N o : ℕ) (C : Clause) : Formula := |
| 86 | if C.length = 0 then [[]] else (List.range C.length).map (chainClause V N o C) |
| 87 | |
| 88 | def chains (V N : ℕ) : ℕ → Formula → Formula |
| 89 | | _, [] => [] |
| 90 | | o, C :: F => chainClauses V N o C ++ chains V N (o + C.length) F |
| 91 | |
| 92 | /-- The cyclic successor on positions. -/ |
| 93 | def next (N p : ℕ) : ℕ := if p + 1 < N then p + 1 else 0 |
| 94 | |
| 95 | /-- The implications `w v (next p) → w v p`. -/ |
| 96 | def cycles (V N : ℕ) : Formula := |
| 97 | (List.range (V * N)).map fun k => [⟨k, true⟩, ⟨wv V (k % V) (next N (k / V)), false⟩] |
| 98 | |
| 99 | /-- The number of literal occurrences. -/ |
| 100 | def size (F : Formula) : ℕ := (F.map List.length).sum |
| 101 | |
| 102 | /-- A strict bound on the variables. -/ |
| 103 | def bound : Formula → ℕ |
| 104 | | [] => 1 |
| 105 | | C :: F => max (C.foldr (fun l b => max (l.index + 1) b) 1) (bound F) |
| 106 | |
| 107 | def split (F : Formula) : Formula := |
| 108 | chains (bound F) (size F) 0 F ++ cycles (bound F) (size F) |
| 109 | |
| 110 | -- The reduction |
| 111 | |
| 112 | /-- The reduction on formulas. -/ |
| 113 | def transform (F : Formula) : Formula := pad (bound F * size F + size F) (split F) |
| 114 | |
| 115 | /-- The formula a word stands for. -/ |
| 116 | def parseF (w : Word) : Formula := (decodeCNF w).getD [[]] |
| 117 | |
| 118 | /-- The reduction on words. -/ |
| 119 | def reduce (w : Word) : Word := encodeCNF (transform (parseF w)) |
| 120 | |
| 121 | /-- The image is a (3,4) formula. -/ |
| 122 | axiom transform_isThreeFour (F : Formula) : IsThreeFour (transform F) |
| 123 | |
| 124 | /-- The image is satisfiable exactly when the formula is. -/ |
| 125 | axiom transform_sat (F : Formula) : Satisfiable F ↔ Satisfiable (transform F) |
| 126 | |
| 127 | /-- The reduction on words is correct. -/ |
| 128 | axiom reduce_correct (w : Word) : w ∈ Lax429075.Satisfiability.SAT ↔ reduce w ∈ SAT34 |
| 129 | |
| 130 | /-- The reduction on words is computable in polynomial time. -/ |
| 131 | axiom reduce_polyTime : Nonempty (Turing.TM2ComputableInPolyTime id id reduce) |
| 132 | |
| 133 | end Lax345332.Construction |
| 134 |
Formalization notes
All copies with and are created and tied together, not only those of pairs that occur. This makes the cyclic successor of a position simply the next position, at the cost of an output of quadratic size.
Discussion
Ask a question or add context. Endorsements and structured flags are kept in the review panel above.
0 comments