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, Debug, PartialEq)]
37pub struct FloatDomainSnapshot {
38 pub min: f64,
40 pub max: f64,
42 pub holes: Vec<f64>,
44}
45
46impl FloatDomainSnapshot {
47 #[must_use]
48 pub fn is_empty(&self) -> bool {
49 self.min > self.max
50 || ((self.max - self.min).abs() <= f64::EPSILON
51 && self
52 .holes
53 .iter()
54 .any(|hole| (*hole - self.min).abs() <= f64::EPSILON))
55 }
56
57 #[must_use]
58 pub fn is_fixed(&self) -> bool {
59 !self.is_empty()
60 && (self.max - self.min).abs() < f64::EPSILON
61 && !self
62 .holes
63 .iter()
64 .any(|hole| (*hole - self.min).abs() <= f64::EPSILON)
65 }
66
67 #[must_use]
68 pub fn contains(&self, value: f64) -> bool {
69 !self.is_empty()
70 && value >= self.min
71 && value <= self.max
72 && !self
73 .holes
74 .iter()
75 .any(|hole| (*hole - value).abs() <= f64::EPSILON)
76 }
77}
78
79pub trait ExtendedPropagationContext {
81 fn set_domain(&self, var: VariableId) -> Option<SetDomainSnapshot>;
82 fn float_domain(&self, var: VariableId) -> Option<FloatDomainSnapshot>;
83 fn force_set_in(&mut self, var: VariableId, value: i32) -> bool;
84 fn force_set_out(&mut self, var: VariableId, value: i32) -> bool;
85 fn tighten_set_cardinality(
86 &mut self,
87 var: VariableId,
88 card_min: usize,
89 card_max: usize,
90 ) -> bool;
91 fn tighten_float_below(&mut self, var: VariableId, bound: f64) -> bool;
92 fn tighten_float_above(&mut self, var: VariableId, bound: f64) -> bool;
93 fn exclude_float_point(&mut self, var: VariableId, value: f64) -> bool;
95}