# Solver Notes

## Formula Notes

- The training split is a shuffled grid theorem-proving family. The names show
  sizes such as 5x5 through 20x20, but the solver does not use filenames or
  comments. The solver now reports a count-based grid-shape detection comment.
- Raw structure observed from clauses: `nvars = 2*r*c - 2` for grid dimensions,
  no unit clauses, exactly 5 binary clauses, `2*(r+c)-4` ternary clauses, and
  the remaining clauses are 4-clauses. Variable degrees are small, usually in
  the 3 to 8 range, and polarity is almost balanced.
- The clauses form a local square/boundary refutation pattern. The implemented
  direct prover uses this normalization before falling back to search. A more precise
  normalization pairs variables into `RC-1` two-literal grid objects. With a
  signed object predicate `Y_v := p_v0 AND p_v1`, local blocks normalize to
  `Y_v -> (Y_a OR Y_b)` in the interior, `Y_v -> Y_a` on boundaries, a target
  clause `Y_a OR Y_b`, and an origin prohibition `NOT Y_o`. This is a finite
  descent / backward reachability contradiction on the grid DAG.

## Techniques Used

- Standalone C++20 solver written from scratch; no SAT, SMT, PB, MIP, or CP
  solver libraries or binaries are used.
- Primary path: recover signed two-literal grid objects from clause
  co-occurrence, identify the target/origin binary block, normalize local
  boundary/interior rules, and emit a direct RUP descent proof from the origin
  prohibition to the target contradiction.
- Two-watched-literal Boolean propagation, first-UIP conflict analysis,
  variable activity bumping, phase saving, and short deterministic Luby
  restarts remain as a fallback if structural recovery fails.
- Direct proof clauses and fallback learned clauses are emitted as VeriPB `rup`
  constraints. The final empty contradiction is emitted as `rup >= 1 ;`,
  followed by a standard UNSAT conclusion.
- If a SAT assignment is ever found, the solver independently checks every
  original clause before printing `SATISFIABLE`.

## Remaining Things To Try

- Consider a PB arithmetic proof using object inequalities and path-count
  multipliers. The current RUP proof is already small, but the arithmetic proof
  could be even shorter for very large grids.
- Add proof deletion lines only if hidden instances are much larger and VeriPB
  memory becomes relevant.
- Investigate proof deletion lines if hidden instances are much larger and
  VeriPB memory becomes relevant.

## Known Limitations

- The direct path assumes the recovered grid induction encoding: signed object
  pairs, four binary target clauses plus one origin clause, two ternary boundary
  clauses per boundary object, and four 4-clauses per interior object. If that
  exact recovery fails, the solver uses the checked conflict-proof fallback.
- The solver intentionally does not shell out to `veripb`; proof checking is
  left to the broker.

## Local Results

- Final direct-proof local sweep on `/data/train/*.cnf.xz`: 7/7 returned UNSAT
  and all seven `.pbp` proofs verified with `veripb --cnf`.
- Solver runtimes in the final local sweep were below the visible 0.01s timer
  precision, with proof sizes from 60 to 1,125 lines.

## Changelog

- Initial scaffold: placeholder `UNKNOWN` solver.
- Added a C++ proof-producing conflict-resolution solver with watched literals,
  first-UIP learning, and VeriPB RUP proof output.
- Fixed learned-clause insertion to preserve the asserting literal instead of
  sorting learned clauses, eliminating runaway proof generation.
- Added variable activity, phase saving, and deterministic Luby restarts.
- Tuned the restart base to 5 conflicts after local timing comparisons.
- Added count-based grid dimension reporting and recorded the recovered object
  implication structure.
- Added a direct structural RUP proof generator that recovers signed object
  pairs, boundary/interior predecessor rules, target clauses, and origin
  contradiction. The previous conflict prover remains as fallback.
- Updated metadata and this notebook before broker submission.
