# Solver Notes

## Formula Notes

The training instances are a compact modular "battleship" encoding.  Ignoring
comments and filenames, the detector recovers:

- `vars = n*m`, interpreted as physical columns `x = 0..m-1` and residues
  `y = 0..n-1`, with variable `x*n + y + 1`.
- The long positive clauses are exactly the `n^2` modular lines
  `y = a*x + b (mod n)`, one clause for each slope/intercept pair.
- Binary clauses are negative and enforce column-style exclusions.  The current
  SAT construction normally selects at most one cell per physical column.  Some
  instances deliberately omit one binary pair; the solver detects this from the
  clauses and can try that pair as two fixed selected cells in the same column.

The high-level SAT problem is therefore to choose cells so every modular line is
hit.  Selecting one cell in every physical column is always safe for the binary
clauses and turns the problem into covering every `(a,b)` residue pair with the
values `chosen_y[x] - a*x`.

## Techniques Used

- Structural detector based only on the DIMACS clauses, not comments or names.
- Greedy initialization that chooses column values with maximum new line
  coverage.
- Deterministic min-conflicts repair on the uncovered modular lines.
- Complete DIMACS assignment reconstruction followed by an independent check of
  every original clause before printing `SATISFIABLE`.
- Missing binary-pair relaxation for formulas where the sanitized CNF permits a
  specific two-cell column selection.
- For square full-binary instances (`m = n`), a compact cutting-planes VeriPB
  proof: derive column AMOs, derive the global lower/upper selected-cell
  equality, derive line AMOs, then use adjacent columns to force a contradiction.
- For full-binary low-column instances with `n <= 5`, a specialized recursive
  line-hitting proof search emits tree-like RUP clauses in VeriPB format.

## Remaining Things To Try

- Add a sound VeriPB proof path for non-square blocking-set UNSAT instances.
  The local `n=7,m=12` full-binary case appears to be the `2n-1` affine-plane
  blocking-set lower bound; a compact proof of that theorem would close the
  last local miss.
- Improve constructive formulas for composite `n` so fewer instances depend on
  stochastic repair.
- Cluster broker timeouts by `(n,m)` and tune search budgets if hidden SAT cases
  are larger than the local training examples.

## Known Limitations

- The solver claims UNSAT for square full-binary instances and for the small
  proof-search regime.  Larger non-square low-column instances still return
  `UNKNOWN` because the modular blocking-set lower-bound proof has not been
  encoded.
- Square instances with omitted binary exclusions are also returned as
  `UNKNOWN` immediately.  The broker has one `n=14,m=14` example in this shape;
  local search did not find a cover, but the full-binary square proof does not
  apply once a column may contain two selected cells.
- Search is deterministic but incomplete.  It is reliable on the observed SAT
  training cases after enough budget, but not a mathematical decision procedure.
- No behavior keys on hashes, filenames, or comments; all structure is recovered
  from sanitized clauses.
- The disabled experimental CDCL/RUP fallback is left in the source behind
  `#if 0`; it was too slow on `n=7,m=12` and should not be enabled without a
  watched-literal rewrite and proof validation.

## Changelog

- Replaced the scaffold with a C++ structural detector and high-level SAT
  cover solver.
- Added model reconstruction and full original-clause verification before
  returning exit code 10.
- Added detection of omitted binary exclusions and a fixed-pair cover search,
  which solves the satisfiable low-column cases that are not one-per-column
  covers.
- Added a proof-producing DFS for small (`n <= 5`) full-binary UNSAT instances.
  It logs RUP clauses for each exhausted line-hitting branch and terminates in
  a VeriPB-checked empty clause.
- Added immediate `UNKNOWN` handling for square full-binary instances outside
  the proof regime to avoid spending search time where the solver cannot
  soundly emit UNSAT.
- Updated metadata to describe the recovered modular line-cover encoding and
  conservative UNSAT behavior.
- Added a square full-binary UNSAT proof generator.  Local verification now
  solves all five square UNSAT training instances (`n=10,11,12,13,16`) with
  VeriPB-checked cutting-planes proofs; local train result is 29/30 solved, with
  only the non-square `n=7,m=12` blocking-set instance returning `UNKNOWN`.
- Added `tools/square_proof.py`, the Python prototype used to validate the
  square proof before porting it to C++.
- Added an immediate `UNKNOWN` path for square instances with missing binary
  exclusions, avoiding two fruitless 30s cover-search attempts on the hidden
  `n=14,m=14` training instance.
