pumpkin_core/engine/
conflict.rs1use crate::engine::reason::ReasonRef;
2use crate::predicates::Predicate;
3use crate::predicates::PropositionalConjunction;
4use crate::proof::InferenceCode;
5use crate::propagation::ExplanationContext;
6use crate::state::CurrentNogood;
7use crate::state::State;
8use crate::variables::DomainId;
9
10pub type PropagationStatusCP = Result<(), Conflict>;
14
15pub fn propagator_conflict(
17 conjunction: PropositionalConjunction,
18 inference_code: &InferenceCode,
19) -> PropagationStatusCP {
20 Err(Conflict::Propagator(PropagatorConflict {
21 conjunction,
22 inference_code: inference_code.clone(),
23 }))
24}
25
26#[derive(Debug, Clone, PartialEq, Eq)]
32pub enum Conflict {
33 Propagator(PropagatorConflict),
35 EmptyDomain(EmptyDomainConflict),
37}
38
39impl From<EmptyDomainConflict> for Conflict {
40 fn from(value: EmptyDomainConflict) -> Self {
41 Conflict::EmptyDomain(value)
42 }
43}
44
45impl From<PropagatorConflict> for Conflict {
46 fn from(value: PropagatorConflict) -> Self {
47 Conflict::Propagator(value)
48 }
49}
50
51#[derive(Clone, Copy, Debug, PartialEq, Eq)]
53pub struct EmptyDomainConflict {
54 pub trigger_predicate: Predicate,
56 pub(crate) trigger_reason: Option<ReasonRef>,
60}
61
62impl EmptyDomainConflict {
63 pub fn domain(&self) -> DomainId {
65 self.trigger_predicate.get_domain()
66 }
67
68 pub fn get_reason(
71 &self,
72 state: &mut State,
73 reason_buffer: &mut (impl Extend<Predicate> + AsRef<[Predicate]>),
74 current_nogood: CurrentNogood,
75 ) -> Option<InferenceCode> {
76 self.trigger_reason.map(|reason_ref| {
77 state.reason_store.get_or_compute(
78 reason_ref,
79 ExplanationContext::new(
80 &state.assignments,
81 current_nogood,
82 state.trail_len(),
83 &mut state.notification_engine,
84 ),
85 &mut state.propagators,
86 reason_buffer,
87 )
88 })
89 }
90}
91
92#[derive(Clone, Debug, PartialEq, Eq)]
95pub struct PropagatorConflict {
96 pub conjunction: PropositionalConjunction,
98 pub inference_code: InferenceCode,
100}