use std::fmt::Debug;
use crate::basic_types::Random;
#[cfg(doc)]
use crate::branching::Brancher;
use crate::engine::Assignments;
#[cfg(test)]
use crate::engine::notifications::NotificationEngine;
use crate::engine::predicates::predicate::Predicate;
use crate::engine::variables::DomainGeneratorIterator;
#[cfg(doc)]
use crate::engine::variables::DomainId;
use crate::engine::variables::IntegerVariable;
#[cfg(doc)]
use crate::propagation::Domains;
#[derive(Debug)]
pub struct SelectionContext<'a> {
pub(crate) assignments: &'a Assignments,
random_generator: &'a mut dyn Random,
}
impl<'a> SelectionContext<'a> {
pub fn new(assignments: &'a Assignments, rng: &'a mut dyn Random) -> Self {
SelectionContext {
assignments,
random_generator: rng,
}
}
pub fn are_all_variables_assigned(&self) -> bool {
self.assignments
.get_domains()
.all(|domain_id| self.assignments.is_domain_assigned(&domain_id))
}
pub fn random(&mut self) -> &mut dyn Random {
self.random_generator
}
pub fn get_size_of_domain<Var: IntegerVariable>(&self, var: Var) -> i32 {
var.upper_bound(self.assignments) - var.lower_bound(self.assignments)
}
pub fn lower_bound<Var: IntegerVariable>(&self, var: Var) -> i32 {
var.lower_bound(self.assignments)
}
pub fn upper_bound<Var: IntegerVariable>(&self, var: Var) -> i32 {
var.upper_bound(self.assignments)
}
pub fn contains<Var: IntegerVariable>(&self, var: Var, value: i32) -> bool {
var.contains(self.assignments, value)
}
pub fn is_integer_fixed<Var: IntegerVariable>(&self, var: Var) -> bool {
self.lower_bound(var.clone()) == self.upper_bound(var)
}
pub fn is_predicate_assigned(&self, predicate: Predicate) -> bool {
self.assignments.evaluate_predicate(predicate).is_some()
}
pub fn get_domains(&self) -> DomainGeneratorIterator {
self.assignments.get_domains()
}
#[cfg(test)]
pub(crate) fn create_for_testing(
domains: Vec<(i32, i32)>,
) -> (Assignments, NotificationEngine) {
let mut assignments = Assignments::default();
let mut notification_engine = NotificationEngine::default();
for (lower_bound, upper_bound) in domains {
_ = assignments.grow(lower_bound, upper_bound);
notification_engine.grow();
}
(assignments, notification_engine)
}
}