# Solver Notes

## Formula Notes

- Family: `md5-equivalence-checking`, generated by Yosys sequential
  equivalence checking for parallel MD5 circuits.
- The visible training formulas are SAT Yosys-style Tseitin miters with all
  non-unit clauses topologically ordered by their maximum variable.
- Instance size is linear in a repetition/time-step count `N`:
  `vars = 117323*N - 27970`, `clauses = 315656*N - 82683`.
  Visible `N` values: 50, 80, 100, 120, 130, 200, 250, 460, 500.
- Clause templates are mostly binary/ternary gate definitions for AND, OR,
  NOR, and small XOR/XNOR constructions. There are also repeated 32-bit,
  128-bit, and final `N`-input reductions.
- Unit clauses dominate the query surface: all but two are positive in the
  visible instances. Variable `1` is forced true, variable `2` false, and the
  final miter AND is forced false.

## Techniques Used

- Fast DIMACS parser that separates unit clauses from non-units and stores
  non-units in compact contiguous literal/offset arrays.
- Self-contained watched-literal CDCL implementation. No external SAT, SMT,
  PB, MIP, or CP-SAT code is used.
- 1-UIP conflict analysis, simple variable activity, saved phase, and a
  conservative timeout/conflict stop that returns `UNKNOWN`.
- SAT-only output. The solver never claims UNSAT because it does not emit
  VeriPB proofs.
- Full independent model verification over every original unit and non-unit
  clause before printing `s SATISFIABLE`.

## Results So Far

Visible train runs, stdout redirected to `/dev/null`, all returned SAT with
verified models:

| N | File suffix | Time | Max RSS |
|---:|---|---:|---:|
| 50 | `20.normalised.cnf.xz` | 3.77s | 642 MB |
| 80 | `14.normalised.cnf.xz` | 6.09s | 1074 MB |
| 100 | `4.normalised.cnf.xz` | 7.65s | 1318 MB |
| 120 | `16.normalised.cnf.xz` | 9.46s | 1561 MB |
| 130 | `18.normalised.cnf.xz` | 10.22s | 1684 MB |
| 200 | `2.normalised.cnf.xz` | 15.06s | 2601 MB |
| 250 | `1.normalised.cnf.xz` | 20.67s | 3221 MB |
| 460 | `11.normalised.cnf.xz` | 37.45s | 5903 MB |
| 500 | `9.normalised.cnf.xz` | 40.87s | 6413 MB |

Each visible instance solved with two CDCL conflicts; most time is parsing,
watch construction, propagation, verification, and complete model output.

## Remaining Things To Try

- Remove the now-unused structural justification code path if future source
  maintenance matters.
- Add a direct Yosys-gate simulator/model constructor. CDCL is already fast on
  the visible split, but a direct constructor could lower memory substantially.
- Use narrower activity storage or skip activity arrays until the first
  conflict if hidden instances scale past the visible `N=500`.

## Known Limitations

- UNSAT instances return `UNKNOWN`; there is no VeriPB proof path.
- The solver is sound for SAT because it checks the printed model, but the
  CDCL search is intentionally bounded. If the bound or wall clock is reached,
  it returns `UNKNOWN`.
- Memory is linear in clauses and reaches about 6.4 GB on the visible `N=500`
  instance.

## Changelog

- Added `tools/profile_cnf.py` and `tools/classify_defs.py` for streaming
  structure scans.
- Identified the formulas as repeated Yosys MD5 equivalence miters with a
  final AND of per-block indicators.
- Implemented an initial backward justification engine; it was sound but not
  effective enough on early XOR/adder constraints.
- Added a compact watched-literal CDCL implementation with 1-UIP learning and
  full model verification.
- Updated metadata and build notes for broker submission.
