pumpkin_solver/engine/variables/integer_variable.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
use enumset::EnumSet;
use super::TransformableVariable;
use crate::engine::opaque_domain_event::OpaqueDomainEvent;
use crate::engine::predicates::predicate::Predicate;
use crate::engine::predicates::predicate_constructor::PredicateConstructor;
use crate::engine::reason::ReasonRef;
use crate::engine::AssignmentsInteger;
use crate::engine::EmptyDomain;
use crate::engine::IntDomainEvent;
use crate::engine::Watchers;
/// A trait specifying the required behaviour of an integer variable such as retrieving a
/// lower-bound ([`IntegerVariable::lower_bound`]) or adjusting the bounds
/// ([`IntegerVariable::set_lower_bound`]).
pub trait IntegerVariable:
Clone + PredicateConstructor<Value = i32> + TransformableVariable<Self::AffineView>
{
type AffineView: IntegerVariable;
/// Get the lower bound of the variable.
fn lower_bound(&self, assignment: &AssignmentsInteger) -> i32;
/// Get the upper bound of the variable.
fn upper_bound(&self, assignment: &AssignmentsInteger) -> i32;
/// Determine whether the value is in the domain of this variable.
fn contains(&self, assignment: &AssignmentsInteger, value: i32) -> bool;
/// Get a predicate description (bounds + holes) of the domain of this variable.
/// N.B. can be very expensive with large domains, and very large with holey domains
///
/// This should not be used to explicitly check for holes in the domain, but only to build
/// explanations. If views change the observed domain, they will not change this description,
/// because it should be a description of the domain in the solver.
fn describe_domain(&self, assignment: &AssignmentsInteger) -> Vec<Predicate>;
/// Remove a value from the domain of this variable.
fn remove(
&self,
assignment: &mut AssignmentsInteger,
value: i32,
reason: Option<ReasonRef>,
) -> Result<(), EmptyDomain>;
/// Tighten the lower bound of the domain of this variable.
fn set_lower_bound(
&self,
assignment: &mut AssignmentsInteger,
value: i32,
reason: Option<ReasonRef>,
) -> Result<(), EmptyDomain>;
/// Tighten the upper bound of the domain of this variable.
fn set_upper_bound(
&self,
assignment: &mut AssignmentsInteger,
value: i32,
reason: Option<ReasonRef>,
) -> Result<(), EmptyDomain>;
/// Register a watch for this variable on the given domain events.
fn watch_all(&self, watchers: &mut Watchers<'_>, events: EnumSet<IntDomainEvent>);
fn watch_all_backtrack(&self, watchers: &mut Watchers<'_>, events: EnumSet<IntDomainEvent>);
/// Decode a domain event for this variable.
fn unpack_event(&self, event: OpaqueDomainEvent) -> IntDomainEvent;
}