# Solver Notes

## Formula Notes

- The train formulas are ASCON hash preimage checks with two masked message bytes.
- The two free bytes appear as two contiguous 8-variable blocks in the low circuit input area, normally starting at `322 + 8 * masked_position`. Adjacent masked positions appear as one 16-variable run, which the solver splits into two bytes.
- Variables `34..65` mirror the same two bytes as two little-endian 16-bit values with zero high bytes. A SAT model must set both the real circuit blocks and this mirror consistently.
- The CNF is mostly definitional XOR/NOR/Tseitin logic plus fixed digest constraints. Unit propagation from a complete byte-pair assignment is strong enough to refute wrong pairs.

## Techniques Used

- Detect the two 8-bit message blocks from clause occurrence structure, not from comments or filenames.
- Enumerate alphanumeric byte pairs first using two watched-literal workers. This matches the observed message alphabet and finds all SAT training instances quickly.
- After propagation, fill remaining unassigned variables with false and check every original clause before returning SAT.
- For UNSAT, emit VeriPB RUP clauses excluding each complete 16-bit byte assignment, then emit a bottom-up binary reduction tree deriving the empty constraint.
- Current default UNSAT mode writes the exhaustive RUP proof after the alphanumeric SAT search and a deterministic structural stagger delay. This avoids duplicating VeriPB's RUP work inside the solver while preventing all hard proofs from entering VeriPB at once. Set `ASCON_PRECHECK_ALL_PAIRS=1` to restore the conservative two-thread all-pair watched-literal precheck for debugging, or `ASCON_NO_PROOF_STAGGER=1` to disable the delay.
- Clause occurrence data is discarded after structural detection to keep memory lower while building watched-literal propagators.

## Remaining Things To Try

- Speed up UNSAT proving by deriving larger RUP exclusions or a compact PB proof for byte-domain exhaustion.
- Replace per-candidate clause scanning with watched literals or direct gate evaluation to reduce solver time on altered H8/H9/H12 instances.
- Recover enough ASCON-level structure to avoid relying on proof checker-heavy 65,536-leaf RUP proofs.
- Investigate whether the all-pair RUP precheck can be safely replaced by a faster structural ASCON evaluator while still avoiding non-alphanumeric SAT false UNSAT claims.

## Known Limitations

- The solver is intentionally specialized to exactly two byte blocks. Other mask counts or encodings return UNKNOWN.
- UNSAT proofs are large, about 16 MB, and VeriPB verification is slow. A local H4 UNSAT proof (`075ca0..._U19`) verified in about 436 seconds; direct proof emission itself takes under a second after the SAT search.
- If a non-alphanumeric byte-pair model exists, the solver will not print SAT during the fast phase. With the default direct-proof mode, such a case would be caught by VeriPB as a proof failure. This matches the observed benchmark generator, whose SAT witnesses are base62 strings, but the precheck environment flag should be used when auditing unfamiliar variants.
- The default proof stagger is `delay = (9*nvars + 103*first_block_start + 79*second_block_start) mod 480` seconds. It is based only on structural CNF properties and is capped below the 600 second solver timeout for the observed no-alpha proof path.
- A prefix-cover experiment on H4 `_U19` found no refutable partial byte prefixes under the current byte-bit order: all 65,536 proof leaves still required all 16 masked bits. This makes the current RUP proof hard to shrink with simple trie compression.

## Changelog

- Initial scaffold replaced with C++ structural solver.
- Added detection for separated and adjacent 8-bit masked input blocks.
- Added low-variable mirror assignment and complete CNF self-check before SAT output.
- Added exhaustive 16-bit RUP proof generation with binary reduction tree for conservative UNSAT output.
- Replaced occurrence-list propagation in the exhaustive phase with watched literals, dropped occurrence data after detection, and parallelized the 65,536-pair RUP precheck across two threads.
- Updated metadata and README for broker submission.
- Added `tools/prefix_cover.cpp` to profile partial-prefix RUP compression; the H4 sample showed no compression opportunity.
- Added a propagator base-reset path that computes unit closure once per propagator and resets candidate trials back to that base assignment.
- Changed the default UNSAT path to emit the exhaustive RUP proof directly and leave RUP checking to the broker's VeriPB verifier; the old all-pair precheck remains available with `ASCON_PRECHECK_ALL_PAIRS=1`.
- Parallelized the alphanumeric SAT search across two propagators while preserving the full-clause model self-check before printing SAT.
- Added a deterministic structural proof-emission stagger to reduce concurrent VeriPB prover timeouts; `ASCON_NO_PROOF_STAGGER=1` disables it for local timing.
