1use crate::VariableId;
2
3#[derive(Clone, Debug, PartialEq, Eq)]
5pub struct SetDomainSnapshot {
6 pub glb: Vec<i32>,
8 pub lub: Vec<i32>,
10 pub card_min: usize,
12 pub card_max: usize,
14}
15
16impl SetDomainSnapshot {
17 #[must_use]
18 pub fn is_empty(&self) -> bool {
19 self.card_min > self.card_max
20 || self.glb.len() > self.card_max
21 || self.lub.len() < self.card_min
22 || !self.glb.iter().all(|value| self.lub.contains(value))
23 }
24
25 #[must_use]
26 pub fn undecided(&self) -> Vec<i32> {
27 self.lub
28 .iter()
29 .copied()
30 .filter(|value| !self.glb.contains(value))
31 .collect()
32 }
33}
34
35#[derive(Clone, Copy, Debug, PartialEq)]
37pub struct FloatDomainSnapshot {
38 pub min: f64,
40 pub max: f64,
42}
43
44impl FloatDomainSnapshot {
45 #[must_use]
46 pub fn is_empty(self) -> bool {
47 self.min > self.max
48 }
49
50 #[must_use]
51 pub fn contains(self, value: f64) -> bool {
52 !self.is_empty() && value >= self.min && value <= self.max
53 }
54}
55
56pub trait ExtendedPropagationContext {
58 fn set_domain(&self, var: VariableId) -> Option<SetDomainSnapshot>;
59 fn float_domain(&self, var: VariableId) -> Option<FloatDomainSnapshot>;
60 fn force_set_in(&mut self, var: VariableId, value: i32) -> bool;
61 fn force_set_out(&mut self, var: VariableId, value: i32) -> bool;
62 fn tighten_float_below(&mut self, var: VariableId, bound: f64) -> bool;
63 fn tighten_float_above(&mut self, var: VariableId, bound: f64) -> bool;
64}