# Solver Notes

## Formula Notes

- The visible, unshuffled instances are circuit-minimization encodings of a set-cover style problem.
- Primary variables are choice literals. All-positive clauses over those primaries are coverage constraints.
- The low-level circuit before the coverage block is a ripple/tree population-count circuit built from XOR, AND, and full-adder motifs.
- Final unit clauses on high-numbered variables encode the requested exact cardinality in binary. Examples: `li-exam-61` has popcount bits equal to 61, and `li-test4-96` has bits equal to 96.
- Training thresholds appear to be below the cover sizes found by greedy/local search: exam instances need around 69 choices by greedy, and test4 around 119. No UNSAT proof is emitted yet.
- Some shuffled exam instances still expose 608 large coverage clauses whose literals have a consistent sign per choice variable. These can be solved by treating signed literals as the primary choices and verifying the full CNF assignment.

## Techniques Used

- Parse DIMACS without using comments or filenames.
- Detect the positive set-cover form by requiring 609 or 1461 all-positive non-unit coverage clauses.
- Detect the signed shuffled exam-64 form by requiring 608 large clauses, 4694 consistently signed choice literals, and 609 total signed coverage clauses; this branch conservatively tries cardinality 64 only.
- Read the cardinality value from sorted final unit variables above the primary range.
- Use greedy and weighted stochastic local search to find a cover of size `k`.
- If a cover is found, assign primary variables, run CNF unit propagation to fill the adder/auxiliary variables, then verify every original clause before printing a complete SAT model.

## Remaining Things To Try

- Recover signed choice literals in shuffled instances by matching cardinality gate leaves under polarity flips.
- Produce VeriPB proofs for UNSAT cases by deriving the population-count bound and combining it with a certified set-cover lower bound.
- Replace the current local-search cover finder with an exact branch-and-bound cover solver that can also emit proof artifacts.

## Known Limitations

- UNSAT cases return `UNKNOWN`; this is deliberate until a checkable VeriPB strategy is implemented.
- Shuffled/polarity-scrambled forms outside the signed exam-64 detector return `UNKNOWN`.
- The SAT path is sound but currently useful only for structurally matching positive unshuffled formulas with a cover at or below the encoded cardinality.

## Changelog

- Initial scaffold: trivial UNKNOWN solver.
- Added structural notes and analysis tools under `tools/` for cover extraction, greedy/local cover probing, and disjoint packing experiments.
- Implemented C++ SAT-side solver: positive coverage detection, cardinality extraction, stochastic set-cover search, unit propagation, and full model verification.
- Increased the local-search budget from 20 seconds to 60 seconds after the broker missed the `li-exam-64` SAT cover that appears locally just under the original cutoff.
- Added a signed-literal cover branch for shuffled/renamed exam-64 instances; local tests solve the raw `li-exam-64` and two `sat04-302` shuffled variants with full CNF verification.
