# Solver Notes

## Formula Notes

The formulas encode the non-adaptive odd-ball balance-scale problem. The first
block is `W * N * N` variables `B[w,left,right]`; a true variable places one
ball on the left pan and one on the right pan for a weighing. The next block is
`2 * N * ((3^W - 1) / 2)` truth-table/signature variables. A top-half ternary
truth-table row, plus an orientation bit, gives the heavy-ball outcome vector
for a ball.

`tto_zp` instances are satisfiable symmetry-broken ordered-row instances. The
solver chooses `N` top-half rows and orientations whose coordinate sums are
zero, then assigns balls in sorted row order. `ttf` instances force ball `b` to
truth-table row `b + 1`; the small UNSAT cases have an odd number of nonzero
entries in at least one weighing coordinate, while the large `ttf` cases have a
zero-sum orientation assignment.

## Techniques Used

- Structural detector from the diagonal `B[w,i,i]` units and the import-block
  sizes; no filename or comment data is used.
- Direct high-level construction over ternary signatures, using deterministic
  local search for the small zero-sum orientation problem.
- CNF model completion by assigning all primary variables, running unit
  propagation through the generated Tseitin/cardinality auxiliaries, then
  checking every original clause before printing SAT.
- Conservative fallback: unsupported structures, failed construction, failed
  propagation, and current UNSAT parity cases return `UNKNOWN`.

## Remaining Things To Try

- Turn the `ttf` odd-parity detector into a VeriPB proof. The high-level reason
  is that an odd number of forced-on-scale balls cannot be covered by pair
  variables that always place balls in left/right pairs.
- Investigate the generated totalizer variables for the per-ball at-most-one
  constraints; they may provide a compact CP derivation of the parity
  contradiction.
- If UNSAT proof work stalls, add a tree-like RUP proof for the smallest `ttf`
  cases as a fallback, but avoid exponential matching enumeration for large
  odd sets.

## Known Limitations

- The solver currently only commits SAT models. It intentionally returns
  `UNKNOWN` for `ttf` parity UNSAT cases because no checked VeriPB proof is
  emitted yet.
- The high-level search is tuned for the observed `W=4` and `W=5` family. The
  detector rejects shapes outside the recovered encoding.

## Changelog

- Replaced the scaffold with a C++ structural solver for oddball-weighing CNFs.
- Added direct SAT construction for ordered/zero-plus and forced-row variants.
- Added unit-propagation model completion and full original-clause validation
  before exit code 10.
- Added a fast parity detector so forced-row UNSAT cases return `UNKNOWN`
  immediately instead of spending time in sign search.
