use super::*;
#[test]
fn a_refuted_instance_is_an_explicit_contradiction_under_the_identity_map() {
let t = Scratch::new("unsat");
let input = t.file("un.cnf", REFUTED_WEIGHTED);
let out = t.out("bundle");
run(&[s(&input), "-o", s(&out)]).exit(0);
let record = json(&out.join(PREPROCESS_RECORD_NAME));
assert_eq!(record["unsat"], true);
let original_num_vars = record["original_num_vars"].as_u64().expect("var count");
let map: Vec<i64> = record["reduced_to_original_dimacs"]
.as_array()
.expect("the map")
.iter()
.map(|v| v.as_i64().expect("a signed id"))
.collect();
assert_eq!(
map,
(1..=original_num_vars as i64).collect::<Vec<_>>(),
"a refutation keeps the original numbering",
);
let cnf = read(&out.join(REDUCED_CNF_NAME));
let clauses: Vec<Vec<i32>> = cnf
.lines()
.filter(|l| !l.starts_with('c') && !l.starts_with('p') && !l.trim().is_empty())
.map(|l| {
l.split_whitespace()
.map(|t| t.parse::<i32>().expect("a literal"))
.take_while(|t| *t != 0)
.collect()
})
.collect();
assert_eq!(clauses.len(), 2, "an explicit contradiction is two clauses");
assert_eq!(clauses[0].len(), 1);
assert_eq!(clauses[1], vec![-clauses[0][0]]);
assert!(
cnf.starts_with(&format!("p cnf {original_num_vars} 2\n")),
"over the original variable count:\n{cnf}",
);
}
#[test]
fn a_refuted_instance_writes_two_files_and_no_vtree() {
let t = Scratch::new("unsatfiles");
let input = t.file("un.cnf", REFUTED_WEIGHTED);
let out = t.out("bundle");
let r = run(&[s(&input), "-o", s(&out)]).exit(0);
assert_eq!(
entries(&out),
set(&[REDUCED_CNF_NAME, PREPROCESS_RECORD_NAME])
);
r.assert_stdout("unsat: preprocessing refuted the instance; count(original) = 0");
r.assert_stdout("vtree: none (the count is already 0)");
}
#[test]
fn a_fully_resolved_instance_writes_two_files_and_no_vtree() {
let t = Scratch::new("resolved");
let input = t.file("fr.cnf", FULLY_RESOLVED);
let out = t.out("bundle");
let r = run(&[s(&input), "-o", s(&out)]).exit(0);
assert_eq!(
entries(&out),
set(&[REDUCED_CNF_NAME, PREPROCESS_RECORD_NAME])
);
assert!(read(&out.join(REDUCED_CNF_NAME)).starts_with("p cnf 0 0\n"));
r.assert_stdout("reduced: 0 vars — fully resolved");
r.assert_stdout("vtree: none (no variables to build one over)");
r.assert_stdout("count(original) = 2^1");
}
#[test]
fn the_picture_flag_on_a_fully_resolved_instance_exits_zero_and_writes_no_picture() {
let t = Scratch::new("resolveddot");
let input = t.file("fr.cnf", FULLY_RESOLVED);
let out = t.out("bundle");
run(&[s(&input), "-o", s(&out), "--dot"]).exit(0);
assert_eq!(
entries(&out),
set(&[REDUCED_CNF_NAME, PREPROCESS_RECORD_NAME]),
"there is no vtree to picture, so asking for one adds no file",
);
}