use logicaffeine_proof::cdcl::Lit;
use logicaffeine_proof::hypercube::clauses_to_expr;
use logicaffeine_proof::lyapunov::{auto_collapse, AutoCollapse};
use logicaffeine_proof::sat::{prove_unsat, UnsatOutcome};
use logicaffeine_proof::{pigeonhole, pseudo_boolean, xorsat};
#[test]
fn cascade_certifies_irregular_counting_core_via_collapse() {
let p = |v: u32| Lit::new(v, true);
let q = |v: u32| Lit::new(v, false);
let clauses = vec![vec![p(0)], vec![p(1)], vec![p(2)], vec![q(0), q(1), q(2)]];
let e = clauses_to_expr(&clauses).unwrap();
assert!(!pigeonhole::decide_pigeonhole_unsat(&e), "pigeonhole recognizer does not fire");
assert!(!pseudo_boolean::refute_clausal(&e), "cutting-planes recognizer does not fire");
assert!(!xorsat::refute_via_parity(&e), "parity recognizer does not fire");
assert!(
!matches!(auto_collapse(3, &clauses), AutoCollapse::None),
"auto_collapse must certify the counting core"
);
assert_eq!(prove_unsat(&e), UnsatOutcome::Refuted);
}
#[test]
fn collapse_cut_stays_sound_on_satisfiable() {
let p = |v: u32| Lit::new(v, true);
let q = |v: u32| Lit::new(v, false);
let clauses = vec![vec![p(0)], vec![p(1)], vec![q(0), q(1), p(2)]];
let e = clauses_to_expr(&clauses).unwrap();
assert!(
matches!(prove_unsat(&e), UnsatOutcome::Sat(_)),
"a satisfiable formula must never be falsely refuted by the collapse cut"
);
}