# Diagnosis SAT Solver

## Family Structure
Model-Based Diagnosis (MBD) SAT instances. Two structural types:
- **Multi-step** (ACG/UCG/UR/UTI): 10-20 components × N time steps, ~600 vars/step, EO groups of 6
- **Flat** (total/dated/partial): All components in one block

## Encoding
- EO (Exactly-One) groups of 6 variables per component per time step
- ALO as 6-literal clause, AMO as binary clauses (¬xi ∨ ¬xj)
- Signal variables connect components through implications
- Health variables determine component modes

## Solver Architecture (v19)
1. **Parse + Initial UP**: Fix unit propagations from original clauses
2. **Phase 1 CDCL** (2000 conflicts): Quick learning before preprocessing
3. **Failed Literal Probing** (two 10s preprocessing rounds plus short inprocessing probes): 
   - Probe both polarities of each variable
   - Failed literals → derive unit clauses
   - Common implications → derive unit clauses (with supporting binary clauses for proof)
   - Hyper-binary learning: v→m → learn (¬v ∨ m), up to 10K per round
4. **Bounded Variable Elimination**: Cost ≤ 10, up to 5 rounds
5. **Full CDCL with inprocessing**: Re-probe every 50K conflicts
6. **Polarity policy**: Initial decisions default to negative, matching the strong negative bias from EO AMO, observation exclusion, and cardinality constraints; phase saving takes over after search starts.
7. **Flat EO-aware branching**: Variables in positive 6-literal EO ALO clauses get an initial VSIDS boost only when their span identifies a flat Anbulagan-style encoding, so flat search branches on diagnosis state variables before high-degree cardinality auxiliaries without disturbing multi-step ordering.

## Key Techniques
- Two-Watched-Literal (2WL) propagation with binary clause optimization
- VSIDS variable ordering with occurrence-based initialization
- Phase saving with negative default
- Glucose-style LBD restart (EMA fast/slow factor 1.2) + Luby base 128
- Clause reduction: keep LBD ≤ 3, delete worst 50%
- BVE model reconstruction in reverse elimination order
- VeriPB v2.0 proof output with RUP rules

## Changelog

### v19 (2026-05-09)
- Increased the internal solver cutoff from 580s to 595s. Several v18 unknowns stopped at the internal cutoff or at the inprocessing safety margin around 550s; this spends more of the broker's 600s budget on borderline SAT searches.
- The risk is that a small number of hard instances may be killed by the broker instead of returning `UNKNOWN`, but both are unsolved for scoring and the extra window can recover near-timeout SAT models.

### v18 (2026-05-09)
- Restricted the +100 EO activity boost to flat encodings using a comment-free detector: the largest variable appearing in positive six-literal EO clauses must be less than one quarter of the full variable count.
- Rationale: v17 improved flat SAT instances but was mixed on multi-step ACG/UCG/UR/UTI. Flat encodings put state variables in a compact low-numbered region while multi-step encodings spread state groups across most of the variable range.
- Local smoke tests kept the flat wins (`total-10-15-s` ~26s, `partial-5-13-s` ~67s) and restored faster multi-step behavior (`UCG-20-5p1` solved locally in ~205s, `UR-15-5p1` ~54s, `UTI-15-5p1` ~55s).

### v17 (2026-05-09)
- Added comment-free structural detection for positive six-literal exactly-one ALO clauses during parsing and marked their variables as diagnosis state variables.
- Boosted marked EO variables by +100 in initial activity. This steers the CDCL search away from cardinality-network auxiliaries in flat Anbulagan instances.
- Local smoke-test impact versus v16: `total-10-15-s` improved from ~37s to ~27s, `partial-5-13-s` from ~99s broker / ~47s local with the new build, `partial-5-15-s` from ~184s broker to ~62s local, and `total-10-11-u` from ~46s local to ~34s local. The small UR smoke tests remained comparable.

### v16 (2026-05-09)
- Changed initial decision polarity from positive to negative. The inherited README claimed a negative default, but the code initialized `phase_arr` to zero, which means positive decisions. Local checks showed this improved a representative `total-10-15-s` SAT run from about 54s to about 37s and kept a small UNSAT proof verifiable.
- Added a local-only `DIAG_NO_PROOF=1` switch for timing proof logging overhead. Broker behavior is unchanged because proofs remain enabled by default and UNSAT is only printed when proof mode is active.
- Added `tools/profile_cnf.py` and `tools/run_local.py` for structure profiling and repeatable local smoke tests.
- Encoding notes from this run: the flat Anbulagan instances order 20 components component-major, with six state variables per time point followed by local transition/event variables. The SAT/UNSAT cardinality query changes the auxiliary cardinality network size; in flat instances the maximum auxiliary occurrence count is typically two higher for the satisfiable bound than for the unsatisfiable bound with the same observation length.

### v14 (2026-05-08)
- **CRITICAL FIX**: Backward binary clause storage in hyper-binary learning was wrong
  - `bins[litneg(m)].push_back(poslit)` → `bins[m].push_back(neglit)` (same for neg probe)
  - Old code stored the wrong implication, causing incorrect propagation
- **CRITICAL FIX**: Common implication units now log supporting binary clauses to proof
  - Before logging unit m (from probing v), log (¬v ∨ m) and (v ∨ m) as RUP steps
  - Without these, the unit clause was not RUP-derivable by VeriPB
- Hyper-binary learning limit reduced from 100K to 10K per probe round
- TIME_LIMIT increased from 555s to 580s

### v13 (2026-05-08) [baseline submission]
- Added BVE with proof support
- Added hyper-binary learning (with backward clause bug)
- Added level-0 conflict proof logging
- 26 SAT + 13 UNSAT = 39 solved (4 prover-timeout, 2 OOM)

## Known Limitations
- CDCL ~5000 conflicts/s vs kissat ~100K/s
- UNSAT on harder instances (>10K remaining vars) often times out
- Proof size can cause VeriPB timeout on some instances
- 2 instances cause OOM (partial-5-17-s, ACG-15-10p1)

## Next Steps
- Add subsumption/vivification to reduce clause sizes
- Better restart strategy
- Memory compaction for clause arena
- Detect EO groups for more efficient reasoning
