use downcast_rs::Downcast;
use downcast_rs::impl_downcast;
use dyn_clone::DynClone;
use dyn_clone::clone_trait_object;
use super::Domains;
use super::ExplanationContext;
use super::PropagationContext;
use super::contexts::NotificationContext;
use crate::basic_types::PredicateId;
#[cfg(doc)]
use crate::create_statistics_struct;
#[cfg(doc)]
use crate::engine::ConstraintSatisfactionSolver;
use crate::engine::PropagationStatusCP;
use crate::engine::PropagatorConflict;
use crate::engine::notifications::OpaqueDomainEvent;
use crate::predicates::Predicate;
use crate::proof::InferenceCode;
#[cfg(doc)]
use crate::propagation::DomainEvent;
#[cfg(doc)]
use crate::propagation::PropagatorConstructor;
#[cfg(doc)]
use crate::propagation::PropagatorConstructorContext;
#[cfg(doc)]
use crate::propagation::ReadDomains;
use crate::propagation::local_id::LocalId;
#[cfg(doc)]
use crate::pumpkin_asserts::PUMPKIN_ASSERT_ADVANCED;
#[cfg(doc)]
use crate::pumpkin_asserts::PUMPKIN_ASSERT_EXTREME;
#[cfg(doc)]
use crate::state::Conflict;
use crate::statistics::statistic_logger::StatisticLogger;
#[derive(Clone, Debug)]
pub struct LazyExplanation<'a> {
pub predicates: &'a [Predicate],
pub inference_code: InferenceCode,
}
impl_downcast!(Propagator);
clone_trait_object!(Propagator);
pub trait Propagator: Downcast + DynClone {
fn name(&self) -> &str;
fn propagate_from_scratch(&self, context: PropagationContext) -> PropagationStatusCP;
fn propagate(&mut self, context: PropagationContext) -> PropagationStatusCP {
self.propagate_from_scratch(context)
}
fn notify(
&mut self,
_context: NotificationContext,
_local_id: LocalId,
_event: OpaqueDomainEvent,
) -> EnqueueDecision {
EnqueueDecision::Enqueue
}
fn notify_backtrack(
&mut self,
_context: Domains,
_local_id: LocalId,
_event: OpaqueDomainEvent,
) {
}
fn notify_predicate_id_satisfied(
&mut self,
_context: NotificationContext,
_predicate_id: PredicateId,
) -> EnqueueDecision {
EnqueueDecision::Enqueue
}
fn synchronise(&mut self, _context: NotificationContext<'_>) {}
fn priority(&self) -> Priority {
Priority::VeryLow
}
fn detect_inconsistency(&self, _domains: Domains) -> Option<PropagatorConflict> {
None
}
fn lazy_explanation(
&mut self,
_code: u64,
_context: ExplanationContext,
) -> LazyExplanation<'_> {
panic!(
"{}",
format!(
"Propagator {} does not support lazy explanations.",
self.name()
)
);
}
fn log_statistics(&self, _statistic_logger: StatisticLogger) {}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum EnqueueDecision {
Enqueue,
Skip,
}
#[derive(Default, Debug, Clone, Copy, Hash, PartialEq, Eq)]
#[repr(u8)]
pub enum Priority {
High = 0,
Medium = 1,
Low = 2,
#[default]
VeryLow = 3,
}
impl PartialOrd for Priority {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
((*self) as u8).partial_cmp(&((*other) as u8))
}
}