pumpkin_core/propagation/
domains.rs1use crate::engine::Assignments;
2use crate::engine::TrailedInteger;
3use crate::engine::TrailedValues;
4use crate::predicates::Predicate;
5#[cfg(doc)]
6use crate::propagation::ExplanationContext;
7use crate::variables::DomainId;
8use crate::variables::IntegerVariable;
9use crate::variables::Literal;
10
11#[derive(Debug)]
16pub struct Domains<'a> {
17 pub(crate) assignments: &'a Assignments,
18 trailed_values: &'a mut TrailedValues,
19}
20
21impl<'a> Domains<'a> {
22 pub(crate) fn new(assignments: &'a Assignments, trailed_values: &'a mut TrailedValues) -> Self {
23 Domains {
24 assignments,
25 trailed_values,
26 }
27 }
28
29 pub fn reborrow(&mut self) -> Domains<'_> {
30 Domains::new(self.assignments, self.trailed_values)
31 }
32}
33
34pub(crate) trait HasAssignments {
36 fn assignments(&self) -> &Assignments;
37 fn trailed_values(&self) -> &TrailedValues;
38 fn trailed_values_mut(&mut self) -> &mut TrailedValues;
39}
40
41impl HasAssignments for Domains<'_> {
42 fn assignments(&self) -> &Assignments {
43 self.assignments
44 }
45
46 fn trailed_values(&self) -> &TrailedValues {
47 self.trailed_values
48 }
49
50 fn trailed_values_mut(&mut self) -> &mut TrailedValues {
51 self.trailed_values
52 }
53}
54
55pub trait ReadDomains {
57 fn evaluate_predicate(&self, predicate: Predicate) -> Option<bool>;
60
61 fn evaluate_literal(&self, literal: Literal) -> Option<bool>;
64
65 fn get_holes_at_current_checkpoint<Var: IntegerVariable>(
67 &self,
68 var: &Var,
69 ) -> impl Iterator<Item = i32>;
70
71 fn get_holes<Var: IntegerVariable>(&self, var: &Var) -> impl Iterator<Item = i32>;
74
75 fn is_fixed<Var: IntegerVariable>(&self, var: &Var) -> bool;
78
79 fn lower_bound<Var: IntegerVariable>(&self, var: &Var) -> i32;
81
82 fn lower_bound_at_trail_position<Var: IntegerVariable>(
87 &self,
88 var: &Var,
89 trail_position: usize,
90 ) -> i32;
91
92 fn upper_bound<Var: IntegerVariable>(&self, var: &Var) -> i32;
94
95 fn upper_bound_at_trail_position<Var: IntegerVariable>(
100 &self,
101 var: &Var,
102 trail_position: usize,
103 ) -> i32;
104
105 fn contains<Var: IntegerVariable>(&self, var: &Var, value: i32) -> bool;
107
108 fn contains_at_trail_position<Var: IntegerVariable>(
114 &self,
115 var: &Var,
116 value: i32,
117 trail_position: usize,
118 ) -> bool;
119
120 fn iterate_domain<Var: IntegerVariable>(&self, var: &Var) -> impl Iterator<Item = i32>;
123
124 fn is_decision_predicate(&self, predicate: Predicate) -> bool;
127
128 fn is_initial_bound(&self, predicate: Predicate) -> bool;
130
131 fn get_checkpoint_for_predicate(&self, predicate: Predicate) -> Option<usize>;
134
135 fn read_trailed_integer(&self, trailed_integer: TrailedInteger) -> i64;
137
138 fn new_trailed_integer(&mut self, initial_value: i64) -> TrailedInteger;
140
141 fn write_trailed_integer(&mut self, trailed_integer: TrailedInteger, value: i64);
143
144 fn get_checkpoint(&self) -> usize;
146
147 fn initial_lower_bound(&self, var: DomainId) -> i32;
149
150 fn initial_upper_bound(&self, var: DomainId) -> i32;
152
153 fn initial_holes(&self, var: DomainId) -> Vec<i32>;
155
156 fn number_of_domains(&self) -> u32;
158}
159
160impl<T: HasAssignments> ReadDomains for T {
161 fn evaluate_predicate(&self, predicate: Predicate) -> Option<bool> {
162 self.assignments().evaluate_predicate(predicate)
163 }
164
165 fn evaluate_literal(&self, literal: Literal) -> Option<bool> {
166 self.evaluate_predicate(literal.get_true_predicate())
167 }
168
169 fn get_holes_at_current_checkpoint<Var: IntegerVariable>(
170 &self,
171 var: &Var,
172 ) -> impl Iterator<Item = i32> {
173 var.get_holes_at_current_checkpoint(self.assignments())
174 }
175
176 fn get_holes<Var: IntegerVariable>(&self, var: &Var) -> impl Iterator<Item = i32> {
177 var.get_holes(self.assignments())
178 }
179
180 fn is_fixed<Var: IntegerVariable>(&self, var: &Var) -> bool {
181 self.lower_bound(var) == self.upper_bound(var)
182 }
183
184 fn lower_bound<Var: IntegerVariable>(&self, var: &Var) -> i32 {
185 var.lower_bound(self.assignments())
186 }
187
188 fn lower_bound_at_trail_position<Var: IntegerVariable>(
189 &self,
190 var: &Var,
191 trail_position: usize,
192 ) -> i32 {
193 var.lower_bound_at_trail_position(self.assignments(), trail_position)
194 }
195
196 fn upper_bound<Var: IntegerVariable>(&self, var: &Var) -> i32 {
197 var.upper_bound(self.assignments())
198 }
199
200 fn upper_bound_at_trail_position<Var: IntegerVariable>(
201 &self,
202 var: &Var,
203 trail_position: usize,
204 ) -> i32 {
205 var.upper_bound_at_trail_position(self.assignments(), trail_position)
206 }
207
208 fn contains<Var: IntegerVariable>(&self, var: &Var, value: i32) -> bool {
209 var.contains(self.assignments(), value)
210 }
211
212 fn contains_at_trail_position<Var: IntegerVariable>(
213 &self,
214 var: &Var,
215 value: i32,
216 trail_position: usize,
217 ) -> bool {
218 var.contains_at_trail_position(self.assignments(), value, trail_position)
219 }
220
221 fn iterate_domain<Var: IntegerVariable>(&self, var: &Var) -> impl Iterator<Item = i32> {
222 var.iterate_domain(self.assignments())
223 }
224
225 fn is_decision_predicate(&self, predicate: Predicate) -> bool {
226 self.assignments().is_decision_predicate(&predicate)
227 }
228
229 fn is_initial_bound(&self, predicate: Predicate) -> bool {
230 self.assignments().is_initial_bound(predicate)
231 }
232
233 fn get_checkpoint_for_predicate(&self, predicate: Predicate) -> Option<usize> {
234 self.assignments().get_checkpoint_for_predicate(&predicate)
235 }
236
237 fn read_trailed_integer(&self, trailed_integer: TrailedInteger) -> i64 {
238 self.trailed_values().read(trailed_integer)
239 }
240
241 fn new_trailed_integer(&mut self, initial_value: i64) -> TrailedInteger {
242 self.trailed_values_mut().grow(initial_value)
243 }
244
245 fn write_trailed_integer(&mut self, trailed_integer: TrailedInteger, value: i64) {
246 self.trailed_values_mut().assign(trailed_integer, value);
247 }
248
249 fn get_checkpoint(&self) -> usize {
250 self.assignments().get_checkpoint()
251 }
252
253 fn initial_lower_bound(&self, var: DomainId) -> i32 {
254 self.assignments().get_initial_lower_bound(var)
255 }
256
257 fn initial_upper_bound(&self, var: DomainId) -> i32 {
258 self.assignments().get_initial_upper_bound(var)
259 }
260
261 fn initial_holes(&self, var: DomainId) -> Vec<i32> {
262 self.assignments().get_initial_holes(var)
263 }
264
265 fn number_of_domains(&self) -> u32 {
266 self.assignments().num_domains()
267 }
268}