use crate::cnf::CnfFormula;
use crate::cnf::Literal;
use crate::preprocess::probe_engine::*;
use crate::tests::common::clause;
use std::collections::HashSet;
use std::time::Duration;
const TEST_BUDGET: Duration = Duration::from_secs(10);
#[test]
fn observe_model_splits_and_tracks_top() {
let mut p = Partition::new();
p.classes = vec![vec![1, 2, 3, 4]];
p.top = 0;
p.observe_model(&[1, -2, 3, -4]);
assert_eq!(p.classes[p.top], vec![1, 3]);
assert!(p.classes.iter().any(|c| c == &vec![2, 4]));
assert_eq!(p.classes.len(), 2);
p.observe_model(&[1, -2, -3, 4]); assert_eq!(p.classes[p.top], vec![1]);
assert!(p.classes.iter().all(|c| c != &vec![3]));
}
#[test]
fn engine_finds_backbone_and_equiv() {
let f = CnfFormula {
num_vars: 5,
clauses: vec![
clause(&[(0, true), (1, true)]),
clause(&[(0, true), (1, false)]),
clause(&[(2, false), (3, true)]),
clause(&[(2, true), (3, false)]),
clause(&[(2, true), (4, true)]),
],
};
let mut e = ProbeEngine::new(&f).expect("the solver allocates");
let bb_eng = e.run_backbone(TEST_BUDGET);
let set_eng: HashSet<(u32, bool)> = bb_eng
.forced
.iter()
.map(|l| (l.var.0, l.positive))
.collect();
assert_eq!(
set_eng,
HashSet::from([(0u32, true)]),
"engine backbone must be exactly {{x0=true}}, got {:?}",
bb_eng.forced,
);
assert_eq!(e.partition.confirmed_backbone.len(), bb_eng.forced.len());
let eq_eng = e.run_equiv(TEST_BUDGET, &None);
let has_23 = |v: &Vec<(Literal, Literal)>| {
v.iter().any(|(a, b)| {
let vars = [a.var.0, b.var.0];
vars.contains(&2) && vars.contains(&3)
})
};
assert!(
has_23(&eq_eng.equivalences),
"engine must find x2 ≡ x3, got {:?}",
eq_eng.equivalences
);
}