use super::Domains;
use super::LocalId;
use super::Propagator;
use super::PropagatorId;
use super::PropagatorVarId;
#[cfg(doc)]
use crate::Solver;
use crate::basic_types::PredicateId;
use crate::engine::Assignments;
use crate::engine::State;
use crate::engine::TrailedValues;
use crate::engine::notifications::Watchers;
#[cfg(doc)]
use crate::engine::variables::AffineView;
#[cfg(doc)]
use crate::engine::variables::DomainId;
use crate::predicates::Predicate;
#[cfg(doc)]
use crate::propagation::DomainEvent;
use crate::propagation::DomainEvents;
use crate::propagation::EventsToRegister;
use crate::propagation::RuntimeCheckers;
use crate::variables::IntegerVariable;
pub trait PropagatorConstructor {
type PropagatorImpl: Propagator + Clone;
fn create(self, context: PropagatorConstructorContext) -> PropagatorSpec<Self::PropagatorImpl>;
}
#[derive(Clone, Debug)]
pub struct PropagatorSpec<P> {
pub registration: EventsToRegister,
pub checkers: RuntimeCheckers,
pub propagator: P,
}
#[derive(Debug)]
pub struct PropagatorConstructorContext<'a> {
state: &'a mut State,
pub(crate) propagator_id: PropagatorId,
}
impl PropagatorConstructorContext<'_> {
pub(crate) fn new<'a>(
propagator_id: PropagatorId,
state: &'a mut State,
) -> PropagatorConstructorContext<'a> {
PropagatorConstructorContext {
propagator_id,
state,
}
}
pub fn domains(&mut self) -> Domains<'_> {
Domains::new(&self.state.assignments, &mut self.state.trailed_values)
}
pub fn register_predicate(&mut self, predicate: Predicate) -> PredicateId {
self.state.notification_engine.watch_predicate(
predicate,
self.propagator_id,
&mut self.state.trailed_values,
&self.state.assignments,
)
}
pub fn register_backtrack<Var: IntegerVariable>(
&mut self,
var: Var,
domain_events: DomainEvents,
local_id: LocalId,
) {
let propagator_var = PropagatorVarId {
propagator: self.propagator_id,
variable: local_id,
};
let mut watchers = Watchers::new(propagator_var, &mut self.state.notification_engine);
var.watch_all_backtrack(&mut watchers, domain_events.events());
}
pub fn reborrow(&mut self) -> PropagatorConstructorContext<'_> {
PropagatorConstructorContext {
propagator_id: self.propagator_id,
state: self.state,
}
}
}
mod private {
use super::*;
use crate::propagation::HasAssignments;
impl HasAssignments for PropagatorConstructorContext<'_> {
fn assignments(&self) -> &Assignments {
&self.state.assignments
}
fn trailed_values(&self) -> &TrailedValues {
&self.state.trailed_values
}
fn trailed_values_mut(&mut self) -> &mut TrailedValues {
&mut self.state.trailed_values
}
}
}