use crate::engine::reason::ReasonRef;
use crate::predicates::Predicate;
use crate::predicates::PropositionalConjunction;
use crate::proof::InferenceCode;
use crate::propagation::ExplanationContext;
use crate::state::CurrentNogood;
use crate::state::State;
use crate::variables::DomainId;
pub type PropagationStatusCP = Result<(), Conflict>;
pub fn propagator_conflict(
conjunction: PropositionalConjunction,
inference_code: &InferenceCode,
) -> PropagationStatusCP {
Err(Conflict::Propagator(PropagatorConflict {
conjunction,
inference_code: inference_code.clone(),
}))
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Conflict {
Propagator(PropagatorConflict),
EmptyDomain(EmptyDomainConflict),
}
impl From<EmptyDomainConflict> for Conflict {
fn from(value: EmptyDomainConflict) -> Self {
Conflict::EmptyDomain(value)
}
}
impl From<PropagatorConflict> for Conflict {
fn from(value: PropagatorConflict) -> Self {
Conflict::Propagator(value)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct EmptyDomainConflict {
pub trigger_predicate: Predicate,
pub(crate) trigger_reason: Option<ReasonRef>,
}
impl EmptyDomainConflict {
pub fn domain(&self) -> DomainId {
self.trigger_predicate.get_domain()
}
pub fn get_reason(
&self,
state: &mut State,
reason_buffer: &mut (impl Extend<Predicate> + AsRef<[Predicate]>),
current_nogood: CurrentNogood,
) -> Option<InferenceCode> {
self.trigger_reason.map(|reason_ref| {
state.reason_store.get_or_compute(
reason_ref,
ExplanationContext::new(
&state.assignments,
current_nogood,
state.trail_len(),
&mut state.notification_engine,
),
&mut state.propagators,
reason_buffer,
)
})
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PropagatorConflict {
pub conjunction: PropositionalConjunction,
pub inference_code: InferenceCode,
}