use crate::engine::Assignments;
use crate::engine::TrailedInteger;
use crate::engine::TrailedValues;
use crate::predicates::Predicate;
#[cfg(doc)]
use crate::propagation::ExplanationContext;
use crate::variables::DomainId;
use crate::variables::IntegerVariable;
use crate::variables::Literal;
#[derive(Debug)]
pub struct Domains<'a> {
pub(crate) assignments: &'a Assignments,
trailed_values: &'a mut TrailedValues,
}
impl<'a> Domains<'a> {
pub(crate) fn new(assignments: &'a Assignments, trailed_values: &'a mut TrailedValues) -> Self {
Domains {
assignments,
trailed_values,
}
}
pub fn reborrow(&mut self) -> Domains<'_> {
Domains::new(self.assignments, self.trailed_values)
}
}
pub(crate) trait HasAssignments {
fn assignments(&self) -> &Assignments;
fn trailed_values(&self) -> &TrailedValues;
fn trailed_values_mut(&mut self) -> &mut TrailedValues;
}
impl HasAssignments for Domains<'_> {
fn assignments(&self) -> &Assignments {
self.assignments
}
fn trailed_values(&self) -> &TrailedValues {
self.trailed_values
}
fn trailed_values_mut(&mut self) -> &mut TrailedValues {
self.trailed_values
}
}
pub trait ReadDomains {
fn evaluate_predicate(&self, predicate: Predicate) -> Option<bool>;
fn evaluate_literal(&self, literal: Literal) -> Option<bool>;
fn get_holes_at_current_checkpoint<Var: IntegerVariable>(
&self,
var: &Var,
) -> impl Iterator<Item = i32>;
fn get_holes<Var: IntegerVariable>(&self, var: &Var) -> impl Iterator<Item = i32>;
fn is_fixed<Var: IntegerVariable>(&self, var: &Var) -> bool;
fn fixed_value<Var: IntegerVariable>(&self, var: &Var) -> Option<i32>;
fn lower_bound<Var: IntegerVariable>(&self, var: &Var) -> i32;
fn lower_bound_at_trail_position<Var: IntegerVariable>(
&self,
var: &Var,
trail_position: usize,
) -> i32;
fn upper_bound<Var: IntegerVariable>(&self, var: &Var) -> i32;
fn upper_bound_at_trail_position<Var: IntegerVariable>(
&self,
var: &Var,
trail_position: usize,
) -> i32;
fn contains<Var: IntegerVariable>(&self, var: &Var, value: i32) -> bool;
fn contains_at_trail_position<Var: IntegerVariable>(
&self,
var: &Var,
value: i32,
trail_position: usize,
) -> bool;
fn iterate_domain<Var: IntegerVariable>(&self, var: &Var) -> impl Iterator<Item = i32>;
fn is_decision_predicate(&self, predicate: Predicate) -> bool;
fn is_initial_bound(&self, predicate: Predicate) -> bool;
fn get_checkpoint_for_predicate(&self, predicate: Predicate) -> Option<usize>;
fn read_trailed_integer(&self, trailed_integer: TrailedInteger) -> i64;
fn new_trailed_integer(&mut self, initial_value: i64) -> TrailedInteger;
fn write_trailed_integer(&mut self, trailed_integer: TrailedInteger, value: i64);
fn get_checkpoint(&self) -> usize;
fn initial_lower_bound(&self, var: DomainId) -> i32;
fn initial_upper_bound(&self, var: DomainId) -> i32;
fn initial_holes(&self, var: DomainId) -> Vec<i32>;
fn number_of_domains(&self) -> u32;
}
impl<T: HasAssignments> ReadDomains for T {
fn evaluate_predicate(&self, predicate: Predicate) -> Option<bool> {
self.assignments().evaluate_predicate(predicate)
}
fn evaluate_literal(&self, literal: Literal) -> Option<bool> {
self.evaluate_predicate(literal.get_true_predicate())
}
fn get_holes_at_current_checkpoint<Var: IntegerVariable>(
&self,
var: &Var,
) -> impl Iterator<Item = i32> {
var.get_holes_at_current_checkpoint(self.assignments())
}
fn get_holes<Var: IntegerVariable>(&self, var: &Var) -> impl Iterator<Item = i32> {
var.get_holes(self.assignments())
}
fn is_fixed<Var: IntegerVariable>(&self, var: &Var) -> bool {
self.lower_bound(var) == self.upper_bound(var)
}
fn fixed_value<Var: IntegerVariable>(&self, var: &Var) -> Option<i32> {
let lower_bound = self.lower_bound(var);
(lower_bound == self.upper_bound(var)).then_some(lower_bound)
}
fn lower_bound<Var: IntegerVariable>(&self, var: &Var) -> i32 {
var.lower_bound(self.assignments())
}
fn lower_bound_at_trail_position<Var: IntegerVariable>(
&self,
var: &Var,
trail_position: usize,
) -> i32 {
var.lower_bound_at_trail_position(self.assignments(), trail_position)
}
fn upper_bound<Var: IntegerVariable>(&self, var: &Var) -> i32 {
var.upper_bound(self.assignments())
}
fn upper_bound_at_trail_position<Var: IntegerVariable>(
&self,
var: &Var,
trail_position: usize,
) -> i32 {
var.upper_bound_at_trail_position(self.assignments(), trail_position)
}
fn contains<Var: IntegerVariable>(&self, var: &Var, value: i32) -> bool {
var.contains(self.assignments(), value)
}
fn contains_at_trail_position<Var: IntegerVariable>(
&self,
var: &Var,
value: i32,
trail_position: usize,
) -> bool {
var.contains_at_trail_position(self.assignments(), value, trail_position)
}
fn iterate_domain<Var: IntegerVariable>(&self, var: &Var) -> impl Iterator<Item = i32> {
var.iterate_domain(self.assignments())
}
fn is_decision_predicate(&self, predicate: Predicate) -> bool {
self.assignments().is_decision_predicate(&predicate)
}
fn is_initial_bound(&self, predicate: Predicate) -> bool {
self.assignments().is_initial_bound(predicate)
}
fn get_checkpoint_for_predicate(&self, predicate: Predicate) -> Option<usize> {
self.assignments().get_checkpoint_for_predicate(&predicate)
}
fn read_trailed_integer(&self, trailed_integer: TrailedInteger) -> i64 {
self.trailed_values().read(trailed_integer)
}
fn new_trailed_integer(&mut self, initial_value: i64) -> TrailedInteger {
self.trailed_values_mut().grow(initial_value)
}
fn write_trailed_integer(&mut self, trailed_integer: TrailedInteger, value: i64) {
self.trailed_values_mut().assign(trailed_integer, value);
}
fn get_checkpoint(&self) -> usize {
self.assignments().get_checkpoint()
}
fn initial_lower_bound(&self, var: DomainId) -> i32 {
self.assignments().get_initial_lower_bound(var)
}
fn initial_upper_bound(&self, var: DomainId) -> i32 {
self.assignments().get_initial_upper_bound(var)
}
fn initial_holes(&self, var: DomainId) -> Vec<i32> {
self.assignments().get_initial_holes(var)
}
fn number_of_domains(&self) -> u32 {
self.assignments().num_domains()
}
}