Skip to main content

pumpkin_core/propagators/hypercube_linear/
checker.rs

1use std::fmt::Debug;
2
3use pumpkin_checking::AtomicConstraint;
4use pumpkin_checking::CheckerVariable;
5use pumpkin_checking::InferenceChecker;
6use pumpkin_checking::IntExt;
7use pumpkin_checking::VariableState;
8
9#[derive(Debug, Clone)]
10pub struct HypercubeLinearChecker<Atomic, Var> {
11    pub hypercube: Vec<Atomic>,
12    pub terms: Vec<Var>,
13    pub bound: i32,
14}
15
16impl<Atomic, Var> InferenceChecker<Atomic> for HypercubeLinearChecker<Atomic, Var>
17where
18    Atomic: AtomicConstraint + Clone + Debug,
19    Var: CheckerVariable<Atomic>,
20{
21    fn check(&self, state: VariableState<Atomic>, _: &[Atomic], _: Option<&Atomic>) -> bool {
22        let hypercube_satisfied = self.hypercube.iter().all(|atomic| state.is_true(atomic));
23
24        let term_sum = self
25            .terms
26            .iter()
27            .map(|term| IntExt::<i64>::from(term.induced_lower_bound(&state)))
28            .sum::<IntExt<i64>>();
29
30        let linear_slack = i64::from(self.bound) - term_sum;
31        let linear_conflicting = linear_slack < 0;
32
33        hypercube_satisfied && linear_conflicting
34    }
35}