pumpkin_solver/api/outputs/
solution_iterator.rsuse super::SatisfactionResult::Satisfiable;
use super::SatisfactionResult::Unknown;
use super::SatisfactionResult::Unsatisfiable;
use crate::branching::Brancher;
use crate::engine::propagation::propagation_context::HasAssignments;
use crate::results::Solution;
use crate::termination::TerminationCondition;
use crate::variables::Literal;
use crate::Solver;
#[derive(Debug)]
pub struct SolutionIterator<'solver, 'brancher, 'termination, B: Brancher, T> {
solver: &'solver mut Solver,
brancher: &'brancher mut B,
termination: &'termination mut T,
next_blocking_clause: Option<Vec<Literal>>,
has_solution: bool,
}
impl<'solver, 'brancher, 'termination, B: Brancher, T: TerminationCondition>
SolutionIterator<'solver, 'brancher, 'termination, B, T>
{
pub(crate) fn new(
solver: &'solver mut Solver,
brancher: &'brancher mut B,
termination: &'termination mut T,
) -> Self {
SolutionIterator {
solver,
brancher,
termination,
next_blocking_clause: None,
has_solution: false,
}
}
pub fn next_solution(&mut self) -> IteratedSolution {
if let Some(blocking_clause) = self.next_blocking_clause.take() {
self.solver
.get_satisfaction_solver_mut()
.restore_state_at_root(self.brancher);
if self.solver.add_clause(blocking_clause).is_err() {
return IteratedSolution::Finished;
}
}
match self.solver.satisfy(self.brancher, self.termination) {
Satisfiable(solution) => {
self.has_solution = true;
self.next_blocking_clause = Some(get_blocking_clause(&solution));
IteratedSolution::Solution(solution)
}
Unsatisfiable => {
if self.has_solution {
IteratedSolution::Finished
} else {
IteratedSolution::Unsatisfiable
}
}
Unknown => IteratedSolution::Unknown,
}
}
}
fn get_blocking_clause(solution: &Solution) -> Vec<Literal> {
solution
.assignments_propositional()
.get_propositional_variables()
.filter(|propositional_variable| {
solution
.assignments_propositional()
.is_variable_assigned(*propositional_variable)
})
.map(|propositional_variable| {
!Literal::new(
propositional_variable,
solution
.assignments_propositional()
.is_variable_assigned_true(propositional_variable),
)
})
.collect::<Vec<_>>()
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug)]
pub enum IteratedSolution {
Solution(Solution),
Finished,
Unknown,
Unsatisfiable,
}