use cadical_sys::{CaDiCal, ClauseIterator, Status};
use rand::Rng;
fn get_random_cnf<R: Rng>(rng: &mut R) -> Vec<Vec<i32>> {
let n = rng.gen_range(1..10);
let mut cnf = Vec::new();
for _ in 0..n {
let mut clause = Vec::new();
let m = rng.gen_range(1..10);
for _ in 0..m {
let lit = rng.gen_range(1..10);
if rng.gen_bool(0.5) {
clause.push(lit);
} else {
clause.push(-lit);
}
}
cnf.push(clause);
}
cnf
}
#[test]
fn random_test() {
const ITERATIONS: usize = 10000;
struct CI {
v: Vec<Vec<i32>>,
}
impl ClauseIterator for CI {
fn clause(&mut self, clause: &[i32]) -> bool {
self.v.push(clause.to_vec());
true
}
}
let mut rng = rand::thread_rng();
for i in 0..ITERATIONS {
let seed: u64 = rng.gen();
println!("i = {i}\tseed = {seed}");
let cnf = get_random_cnf(&mut rng);
let mut solver = CaDiCal::new();
for clause in &cnf {
solver.clause6(clause);
}
let mut i1 = CI { v: Vec::new() };
solver.traverse_clauses(&mut i1);
solver.simplify(3);
let mut i2 = CI { v: Vec::new() };
solver.traverse_clauses(&mut i2);
}
}
#[test]
fn basic_sat_solving() {
let mut solver = CaDiCal::new();
solver.clause2(1, 2); solver.clause2(-1, 3); solver.clause2(-2, -3);
let status = solver.solve();
match status {
Status::SATISFIABLE => {
println!("x1: {}", solver.val(1));
println!("x2: {}", solver.val(2));
println!("x3: {}", solver.val(3));
}
Status::UNSATISFIABLE => println!("No solution exists"),
Status::UNKNOWN => println!("Solution status unknown"),
}
}
#[test]
fn advanced_sat_solving() {
let mut solver = CaDiCal::new();
solver.configure("plain".to_string());
solver.set("verbose".to_string(), 1);
solver.clause3(1, 2, 3); solver.clause3(-1, -2, -3);
solver.assume(1);
let status = solver.solve();
if status == Status::SATISFIABLE {
let num_vars = solver.vars();
for var in 1..=num_vars {
println!("Variable {}: {}", var, solver.val(var));
}
}
}
#[test]
fn dimacs_solving() {
let mut solver = CaDiCal::new();
let mut var_count = 0;
let result = solver.read_dimacs1(
"./tests/problem.cnf".to_string(),
"my_problem".to_string(),
&mut var_count,
0,
);
println!("Read DIMACS result: {result:?}");
let status = solver.solve();
if status == Status::SATISFIABLE {
solver.write_extension("/tmp/solution.ext".to_string());
}
}
#[test]
fn solver_management() {
let mut solver = CaDiCal::new();
solver.reserve(1000);
solver.add_observed_var(42);
let _ = solver.simplify(2);
solver.statistics();
solver.resources();
}