use crate::branching::Brancher;
use crate::branching::BrancherEvent;
use crate::branching::SelectionContext;
use crate::predicate;
use crate::predicates::Predicate;
use crate::pumpkin_assert_eq_simple;
use crate::results::SolutionReference;
use crate::variables::IntegerVariable;
#[derive(Debug)]
pub struct WarmStart<Var> {
variables: Vec<Var>,
values: Vec<i32>,
has_found_solution: bool,
index: usize,
}
impl<Var: Clone> WarmStart<Var> {
pub fn new(variables: &[Var], values: &[i32]) -> Self {
pumpkin_assert_eq_simple!(variables.len(), values.len());
Self {
variables: variables.iter().rev().cloned().collect(),
values: values.iter().rev().cloned().collect(),
has_found_solution: false,
index: 0,
}
}
}
impl<Var: IntegerVariable> Brancher for WarmStart<Var> {
fn next_decision(&mut self, context: &mut SelectionContext) -> Option<Predicate> {
if self.has_found_solution {
return None;
}
while self.index < self.variables.len() {
let variable = &self.variables[self.index];
let value = self.values[self.index];
let predicate = predicate!(variable == value);
self.index += 1;
if context.assignments.evaluate_predicate(predicate).is_none() {
return Some(predicate);
}
}
None
}
fn synchronise(&mut self, _context: &mut SelectionContext) {
self.index = 0
}
fn on_solution(&mut self, _solution: SolutionReference) {
self.has_found_solution = true;
}
fn subscribe_to_events(&self) -> Vec<BrancherEvent> {
vec![BrancherEvent::Solution, BrancherEvent::Synchronise]
}
}