# RRLS: lift, learn, loop, and decode

Research extension to the RRLS P versus NP proof audit. 5 September 2026.

This release implements an exact complementary-coordinate lift, a conflict-driven SAT solver, independently checked learned clauses, resumable proof prefixes, and proof slicing. It does not establish P = NP or P ≠ NP. The mathematical arguments below establish the stated transformations and certificate rules. They are not a formal verification of the Python implementation.

The implementation applies established conflict-driven clause learning (CDCL), first-UIP conflict analysis, and reverse unit propagation (RUP). These are not discoveries of this project. [Heule's CDCL presentation](https://www.cs.cmu.edu/~mheule/15816-f22/slides/CDCL.pdf), [Wetzler, Heule, and Hunt, DRAT-trim](https://www.cs.cmu.edu/~mheule/publications/drat-trim.pdf).

## 1. The precise target

For an explicitly encoded CNF formula F, find an assignment satisfying every clause, or establish that no such assignment exists. A finite execution solves its particular input. Proving P = NP would additionally require a uniform deterministic algorithm with polynomial total bit cost for every input length, including compilation, learned representations, search, arithmetic, and decoding. [Cook's official problem statement](https://www.claymath.org/wp-content/uploads/2022/06/pvsnp.pdf).

The sixteen captured cores used here were already decided by the previous engine using branching. Their truth values were not new unknowns. The target of this extension is reusable reasoning and independently checkable evidence on those cores, followed by fixed fresh cases.

## 2. An exact lift with a decoder

For each occurring variable x_i, introduce two coordinates a_i and b_i and require

\[
a_i\lor b_i,\qquad \neg a_i\lor\neg b_i.
\]

For Boolean values these constraints are equivalent to b_i = 1-a_i. Replace positive x_i in every original clause by a_i, and negative x_i by b_i. Call the resulting CNF E(F). All original clause bodies now use positive coordinates; the complementary-pair constraints preserve the original consistency problem.

Define

\[
\ell(x)=(x_1,1-x_1,\ldots,x_n,1-x_n),
\qquad d(a,b)=(a_1,\ldots,a_n).
\]

**Theorem 1.** The maps restrict to inverse bijections between the satisfying assignments of F on its occurring variables and those of E(F):

\[
F(x)=1\iff E(F)(\ell(x))=1,
\qquad d\circ\ell=\operatorname{id},
\qquad \ell\circ d=\operatorname{id}\text{ on models of }E(F).
\]

**Proof.** Each complementary pair has exactly the two assignments (0,1) and (1,0). Every lifted literal therefore has the same value as its corresponding original literal. Each clause, and hence the conjunction, has the same value under the lift. Conversely, every lifted model determines exactly one original assignment by selecting its a-coordinates. The pair constraints force all b-coordinates to be their complements. This proves both implications and the inverse identities. ∎

For n occurring variables and m original clauses this adds n variables, 2n clauses, and 4n literal occurrences. The implementation first names the actually occurring variables densely, so an identifier such as 2^200 does not allocate an array with 2^200 entries. Identifier processing still costs its actual bit length. Variables declared but absent from every clause can be assigned arbitrarily and need not be enumerated.

For exact 3-CNF the relation vocabulary is OR3 plus NEQ2, as in the previous paper. A bijective lift does not make shared constraints independent. It preserves every solution and every obstruction to a solution; it need not improve runtime.

`verify_complement_lift` independently reconstructs the entire expected lifted formula, checks the solver's evidence against that formula, and directly evaluates any decoded SAT model on the original input. For UNSAT, the exact lift equivalence transfers the checked compiled refutation to the original formula.

## 3. Turn an error into an entailed constraint

Let F_i be the input plus previously accepted lemmas. A candidate learned clause C_i is accepted only if assigning all of its literals false makes unit propagation derive a contradiction:

\[
\operatorname{UP}(F_i\land\neg C_i)=\bot.
\]

Here the negation of a disjunction is a conjunction of unit assumptions. An unknown value is never silently interpreted as false.

**Theorem 2: sound learning.** The RUP condition implies F_i entails C_i, and therefore

\[
\operatorname{Models}(F_i\land C_i)=\operatorname{Models}(F_i).
\]

**Proof.** A unit propagation step assigns the sole remaining literal of a clause true. Every satisfying extension of the current partial assignment must make that assignment. By induction, a satisfying extension must obey all propagated units. A completely false clause is incompatible with such an extension. Thus there is no model of F_i that falsifies all literals of C_i, which is precisely entailment. Adding an entailed clause removes no model. ∎

Induction over the proof sequence gives F entails every accepted lemma. The sequence therefore preserves the original solution set, even though it changes the ease with which consequences are found.

A small exact example is

\[
F=(\neg a\lor b)\land(\neg a\lor\neg b)\land(a\lor c).
\]

Trying a=1 forces both b=1 and b=0. Resolution gives the learned unit

\[
\frac{\neg a\lor b\qquad\neg a\lor\neg b}{\neg a}.
\]

The engine can keep a=0 permanently; the third clause then forces c=1. The failed trial has become a consequence of the formula. Calling it a new coordinate does not change what must be proved: that the consequence is entailed.

## 4. The executable loop

`conflict_loop.py` uses dense variable names, two watched literals per non-unit clause, explicit implication reasons, decision levels, phase saving, and deterministic integer activity scores.

1. Propagate unit clauses until a fixed point or conflict.
2. At a conflict, resolve implication reasons backward until the conflict clause has exactly one literal at the current decision level: the first unique implication point, or first UIP.
3. Backtrack to the largest decision level of the other learned literals. The learned clause is now unit, so assert its remaining literal.
4. Retain the learned clause and repeat. If propagation is complete but variables remain unassigned, make and count another decision.
5. Return SAT with a complete model on occurring variables, or UNSAT with a RUP sequence ending in the empty clause. A resource cap returns UNRESOLVED with only its checked proof prefix.

Every resolution step is sound: from A∨v and B∨¬v, any model must satisfy A∨B. Implication reasons are clauses already in the database. The final independent checker does not use the solver's watched-literal code, conflict analysis, activity scores, or claimed status to infer truth.

The independent checker is a separate, scan-based implementation in `verify_conflict_loop.py`. It checks every learned clause in order, including clauses in SAT and unfinished runs. SAT also requires direct evaluation on the original input. UNSAT requires a checked final empty clause. The checker has its own resource limits and may refuse to finish a check; this is not acceptance.

**Theorem 3: accepted decisions.** If the specified checker rules accept SAT, the formula has the supplied satisfying assignment. If they accept UNSAT, the formula has no satisfying assignment.

**Proof.** The SAT condition is the definition of a model. For UNSAT, Theorem 2 inductively implies the final empty clause from F. An empty disjunction is false under every assignment. Hence F has no model. ∎

These proofs establish the abstract rules. Source review, finite tests, and independent execution provide evidence about their implementation; none is a proof-assistant verification of the program or runtime.

## 5. Checked memory and restarting

`resume_until_decided` runs a bounded number of conflicts, saves the learned prefix, and starts a fresh search with that prefix. Before loading it, the checker verifies its exact input fingerprint and rechecks every lemma against that input in sequence. There is no external `trusted` flag, and a lemma from an unrelated problem is not imported merely because it worked elsewhere.

By Theorem 2, this restart preserves the solution set. Restarting can change search order and total work. It is not automatically faster: input processing, rediscovered propagation, and rechecking the accumulated prefix are counted again. A round that learns nothing before exhausting its work budget triggers a stop instead of an unproductive endless loop.

A completed refutation can yield zero new search decisions when reloaded. That is proof reuse, not a new polynomial-time solution of the original problem: the initial search and subsequent proof checks remain real costs.

## 6. Compress a proof without changing its meaning

During RUP replay the checker records the reason clauses used to reach a conflict. Start from the final empty clause, retain the earlier learned clauses needed by those dependencies, and remove the unused learned clauses. Preserve their order and recheck the resulting proof from the original input.

The second check is decisive. A sliced proof is accepted only if every retained lemma still has RUP in its reduced context and the final empty clause remains valid. Dependency extraction and both checks cost time. Report the cost of producing the slice separately from the cost of checking it again later.

This implementation removes unused lemmas. It does not guarantee a shortest proof, and it does not modify the original solver source or optimize an arbitrary program over itself.

## 7. What looping does and does not bound

With n Boolean variables there are 3^n distinct non-tautological clauses when each variable is absent, positive, or negative. That finite count is exponential, not polynomial. Retaining new clauses can ensure finite progress in an unbounded ideal learning procedure without supplying the bound required by P = NP.

Let K be the number of learned clauses and S their total literal count. A naive RUP check of one clause takes at most n+1 scans that assign a new variable or terminate. Ignoring identifier bit costs, total replay work has the coarse bound

\[
O\bigl(K(n+1)(L+S+K)\bigr),
\]

where L includes the input clauses and their literals. Including K counts visits to empty clauses. Thus checking is polynomial in the input **and the supplied proof**, not necessarily in the input alone. K and S can be large. Searching for that proof is a separate cost.

The runtime ledger records decisions, conflicts, propagation queue pops, watched-clause visits, replacement literal tests, resolution steps, selected analysis operations, variable-score visits, and unassignments. It also records stored and proof literals, proof-check work, and elapsed time. These counters describe selected operations; they are not an exhaustive Turing-machine bit-operation count. Sorting, hashing, allocation, parsing, and Python overhead are reflected in elapsed time but not all expanded in the work proxy.

## 8. A known limitation of the present proof language

The following concerns the new native clause-learning/RUP route on unchanged input formulas. It is not a lower bound against every RRLS primitive or every possible compiler.

For n+1 pigeons and n holes, let P_n contain the clauses

\[
\bigvee_{j=1}^{n}p_{i,j}\quad(1\le i\le n+1),
\]

and

\[
\neg p_{i,j}\lor\neg p_{k,j}\quad(i<k,\ 1\le j\le n).
\]

This is the standard pigeonhole CNF: each pigeon uses a hole and two pigeons cannot use the same hole. Its length is polynomial in n. Haken's resolution lower bound shows that this family requires exponential-length resolution refutations. The exact encoding and this bound are stated in [Buss and Pitassi, Resolution and the Weak Pigeonhole Principle](https://www.cs.umd.edu/users/gasarch/TOPICS/resolution/busspit.pdf); Haken's original paper is [The Intractability of Resolution](https://www.sciencedirect.com/science/article/pii/0304397585901446).

A RUP lemma has a polynomial-size resolution derivation, allowing weakening: reverse its unit-reason derivation from the conflicting clause to obtain a subclause of the proposed lemma, then weaken if needed. Reverse processing terminates because each reason depends on earlier assignments. Substituting these derivations for successive RUP steps gives a resolution refutation polynomial in the RUP proof and input size. Weakening can be removed without increasing the refutation size by propagating stronger subclauses.

Consequently, a native RUP-only route cannot always emit polynomial-size refutations on this family. Improving its branching heuristic or looping longer does not remove that limitation. This does **not** imply P ≠ NP. The earlier matching primitive can recognize pigeonhole structure and give a short counting argument in a stronger certificate language. The benchmark generator also includes within-pigeon at-most-one clauses; the theorem in this paragraph concerns the explicitly written standard encoding, not an inference from benchmark timings.

More expressive proof systems and structural certificates can avoid particular resolution lower bounds. That still does not show a polynomial-time compiler can always find the right representation or a short proof for arbitrary SAT. Extended resolution, DRAT, and stronger practical formats have carefully studied relationships; changing their names does not provide a universal time bound. [Kiesl, Rebola-Pardo, and Heule, Simulating Strong Practical Proof Systems with Extended Resolution](https://www.cs.cmu.edu/~mheule/publications/pr_extres.pdf).

## 9. Reproducible evidence

The fixed experiment, its raw results, and the final summary are in `learning-results/`. `learning_experiment.py` specifies the selected inputs, seeds, budgets, timing protocol, and comparisons. The results section is generated from those recorded files when packaging this release.

Previous v0.13 source, previous refinement results, and the prior composition proof remain in the package. This extension adds a new solver route; it does not replace the specialized Horn, matching, or GF(2) dispatches.

### Recorded results

All 40 selected inputs received independently checked decisions: 16 captured cores and 24 fresh or specified-family inputs. The new decisions agreed with the previous refinement on every case. The 16 cores comprise two satisfiable and fourteen unsatisfiable formulas.

Each case and solver had one excluded warm-up and three measured runs, with alternating method order. The following values are sums of the individual case medians within each family, in milliseconds. They are not medians of a combined run. The previous refinement column measures solving only; the final column includes both new solving and independent checking. Imports and file I/O are excluded.

| Family | Cases | Previous refinement, solve only | New route, solve only | New route, solve + check |
|---|---:|---:|---:|---:|
| Captured cores | 16 | 342.762 | 11.761 | 21.411 |
| Fresh random 3-SAT | 12 | 20,066.448 | 214.440 | 1,294.684 |
| Graph 3-coloring CNF | 4 | 415.584 | 6.281 | 15.112 |
| Pigeonhole | 2 | 1.643 | 62.681 | 275.977 |
| XOR | 4 | 9.072 | 52.205 | 299.034 |
| Renamed Horn | 2 | 25.212 | 8.290 | 10.317 |

For `fresh-random3-96-0`, the previous refinement took 14.656 seconds, while the new solver plus checker took 1.081 seconds. The new solver still made 740 decisions and encountered 601 non-root conflicts, producing 602 proof clauses including the empty clause. Its proof required 6,929,551 checker work units. This is a faster finite execution, not an elimination of search.

This comparison changes propagation, preprocessing, branching policy, data structures, and proof production together. It does not isolate the contribution of clause learning or establish that dimensional lifting caused the speed difference. The specialized matching and GF(2) dispatches remain substantially better on their measured families.

**Resuming.** All sixteen cores completed with a two-conflict limit per round and a 100-round outer cap. The most rounds used by a core were seven. For `core-42a31137baa1`, the native seven-round sequence made 26 total decisions and used 80,378 proof-check work units across prefix rechecks and round checks. The single-pass run used 15 decisions and 14,869 proof-check work units. Restarting was sound and persistent, but was more work here.

The executable combination `lift_loop.py ... --lift` was then applied to that same core. It lifted 24 occurring variables to 48 coordinates, completed in seven rounds, and proved UNSAT. It used 32 total decisions, 4,593 search-work units, and 190,296 proof-check work units in the resume sequence; final lift verification is an additional check. The one measured complete command took about 42.7 ms. This application is not part of the three-repeat comparison above.

**Lifting and decoding.** Six fresh 3-SAT cases were lifted and independently checked. Five were satisfiable and their decoded assignments passed the original clauses; one was unsatisfiable and transferred a checked refutation through the exact lift. Search decisions changed as follows:

| Input | Native decisions | Lifted decisions |
|---|---:|---:|
| 24 variables, case 0 | 15 | 15 |
| 24 variables, case 1 | 5 | 13 |
| 24 variables, case 2 | 14 | 12 |
| 40 variables, case 0 | 11 | 24 |
| 40 variables, case 1 | 21 | 11 |
| 40 variables, case 2 | 28 | 15 |

The lift improved this counter on three inputs, worsened it on two, and left it equal on one. A node or decision counter is not total cost; this does not identify a universally best representation.

**Proof slicing.** The 24 checked UNSAT outputs contained 1,058 learned clauses in total. Dependency slicing retained 1,014. Their subsequent replay work fell from 8,770,666 to 8,165,574 units, about 6.9%. Producing these slices required 25,706,906 total check-work units and about 3.44 seconds, including the checks performed by the optimizer. That one-time cost is not free and need not pay off for a single use.

**Completed-proof reuse.** Reloading the 15-clause refutation for `core-42a31137baa1` needed no new search decisions. It still checked the proof before loading and checked the output again, each costing 14,869 work units. The one measured solve-and-check call took approximately 5.05 ms. No claim of a free solve follows from its zero decision count.

### Verification and limits

The 19 passing test groups include the previous twelve regression groups and seven new groups. New checks cover 300 deterministic small random formulas against exhaustive truth assignments, every learned lemma against all models of those small formulas, all 256 subsets of a three-variable forbidden-assignment cube, sparse identifiers, empty and tautological formulas, budget refusal and resume, corrupted proofs and assignments, lift corruption, and rechecked proof slicing.

The saved evidence can be replayed by `python3 -I verify_learning_archive.py`, without importing the solver implementation. A separate command rechecks the applied lift-and-loop artifact. The checker itself is ordinary Python and has not been formally verified. Tests do not prove correctness for all executions or all environments.

The fixed case selection and deterministic seeds are in `learning-results/protocol.json`. Captured cores are related residuals from earlier searches, not sixteen independent random draws. No asymptotic scaling fit or generalization probability is inferred. Timings are from this Linux/Python environment and were not separately measured on Windows. No solver comparison with an optimized industrial SAT solver was performed.

`learning-results/source-at-benchmark/lift_loop.py` preserves the exact timed source before the executable command-line interface was appended. The learning algorithm and measured policy were not tuned after this experiment.

## 10. What remains open

The delivered target is now executable: exact lift, proof-producing learning, checked continuation, and decoding. The open target is substantially stronger:

\[
\exists\text{ one uniform deterministic }A,\ \exists k,\ \forall F,
\quad A(F)\text{ correctly decides SAT within }O(|F|^k)\text{ bit operations}.
\]

This release does not supply that algorithm or proof. Its finite certificates solve the recorded instances. Its transformation theorems justify the lift and learned constraints. Its resolution limitation explains why unbounded repetition of this particular proof rule cannot by itself furnish a polynomial certificate route for all unsatisfiable inputs. Future structural primitives would need their own soundness, coverage, recognition, representation-size, and total-cost arguments.
