use alloc::vec::Vec;
use super::solver::Solver;
use super::{Cnf, Var};
pub struct Models {
solver: Solver,
project: Vec<Var>,
done: bool,
}
impl Iterator for Models {
type Item = Vec<bool>;
fn next(&mut self) -> Option<Vec<bool>> {
if self.done {
return None;
}
if !self.solver.search() {
self.done = true;
return None;
}
let model = self.solver.model();
if !self.solver.block(&self.project, &model) {
self.done = true;
}
Some(model)
}
}
pub fn all_models(cnf: &Cnf, project: Vec<Var>) -> Models {
Models {
solver: Solver::new(cnf),
project,
done: false,
}
}
pub fn models(cnf: &Cnf, project: &[Var], limit: usize) -> Vec<Vec<bool>> {
all_models(cnf, project.to_vec()).take(limit).collect()
}
pub fn models_upto(cnf: &Cnf, project: &[Var], limit: usize) -> usize {
all_models(cnf, project.to_vec()).take(limit).count()
}