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_predicate_at_trail_position(
64 &self,
65 predicate: Predicate,
66 trail_position: usize,
67 ) -> Option<bool>;
68
69 fn evaluate_literal(&self, literal: Literal) -> Option<bool>;
72
73 fn get_holes_at_current_checkpoint<Var: IntegerVariable>(
75 &self,
76 var: &Var,
77 ) -> impl Iterator<Item = i32>;
78
79 fn get_holes<Var: IntegerVariable>(&self, var: &Var) -> impl Iterator<Item = i32>;
82
83 fn is_fixed<Var: IntegerVariable>(&self, var: &Var) -> bool;
86
87 fn fixed_value<Var: IntegerVariable>(&self, var: &Var) -> Option<i32>;
90
91 fn lower_bound<Var: IntegerVariable>(&self, var: &Var) -> i32;
93
94 fn lower_bound_at_trail_position<Var: IntegerVariable>(
99 &self,
100 var: &Var,
101 trail_position: usize,
102 ) -> i32;
103
104 fn upper_bound<Var: IntegerVariable>(&self, var: &Var) -> i32;
106
107 fn upper_bound_at_trail_position<Var: IntegerVariable>(
112 &self,
113 var: &Var,
114 trail_position: usize,
115 ) -> i32;
116
117 fn contains<Var: IntegerVariable>(&self, var: &Var, value: i32) -> bool;
119
120 fn contains_at_trail_position<Var: IntegerVariable>(
126 &self,
127 var: &Var,
128 value: i32,
129 trail_position: usize,
130 ) -> bool;
131
132 fn iterate_domain<Var: IntegerVariable>(&self, var: &Var) -> impl Iterator<Item = i32>;
135
136 fn is_decision_predicate(&self, predicate: Predicate) -> bool;
139
140 fn is_initial_bound(&self, predicate: Predicate) -> bool;
142
143 fn get_checkpoint_for_predicate(&self, predicate: Predicate) -> Option<usize>;
146
147 fn read_trailed_integer(&self, trailed_integer: TrailedInteger) -> i64;
149
150 fn new_trailed_integer(&mut self, initial_value: i64) -> TrailedInteger;
152
153 fn write_trailed_integer(&mut self, trailed_integer: TrailedInteger, value: i64);
155
156 fn get_checkpoint(&self) -> usize;
158
159 fn initial_lower_bound(&self, var: DomainId) -> i32;
161
162 fn initial_upper_bound(&self, var: DomainId) -> i32;
164
165 fn initial_holes(&self, var: DomainId) -> Vec<i32>;
167
168 fn number_of_domains(&self) -> u32;
170}
171
172impl<T: HasAssignments> ReadDomains for T {
173 fn evaluate_predicate(&self, predicate: Predicate) -> Option<bool> {
174 self.assignments().evaluate_predicate(predicate)
175 }
176
177 fn evaluate_literal(&self, literal: Literal) -> Option<bool> {
178 self.evaluate_predicate(literal.get_true_predicate())
179 }
180
181 fn get_holes_at_current_checkpoint<Var: IntegerVariable>(
182 &self,
183 var: &Var,
184 ) -> impl Iterator<Item = i32> {
185 var.get_holes_at_current_checkpoint(self.assignments())
186 }
187
188 fn get_holes<Var: IntegerVariable>(&self, var: &Var) -> impl Iterator<Item = i32> {
189 var.get_holes(self.assignments())
190 }
191
192 fn is_fixed<Var: IntegerVariable>(&self, var: &Var) -> bool {
193 self.lower_bound(var) == self.upper_bound(var)
194 }
195
196 fn fixed_value<Var: IntegerVariable>(&self, var: &Var) -> Option<i32> {
197 let lower_bound = self.lower_bound(var);
198 (lower_bound == self.upper_bound(var)).then_some(lower_bound)
199 }
200
201 fn lower_bound<Var: IntegerVariable>(&self, var: &Var) -> i32 {
202 var.lower_bound(self.assignments())
203 }
204
205 fn lower_bound_at_trail_position<Var: IntegerVariable>(
206 &self,
207 var: &Var,
208 trail_position: usize,
209 ) -> i32 {
210 var.lower_bound_at_trail_position(self.assignments(), trail_position)
211 }
212
213 fn upper_bound<Var: IntegerVariable>(&self, var: &Var) -> i32 {
214 var.upper_bound(self.assignments())
215 }
216
217 fn upper_bound_at_trail_position<Var: IntegerVariable>(
218 &self,
219 var: &Var,
220 trail_position: usize,
221 ) -> i32 {
222 var.upper_bound_at_trail_position(self.assignments(), trail_position)
223 }
224
225 fn contains<Var: IntegerVariable>(&self, var: &Var, value: i32) -> bool {
226 var.contains(self.assignments(), value)
227 }
228
229 fn contains_at_trail_position<Var: IntegerVariable>(
230 &self,
231 var: &Var,
232 value: i32,
233 trail_position: usize,
234 ) -> bool {
235 var.contains_at_trail_position(self.assignments(), value, trail_position)
236 }
237
238 fn iterate_domain<Var: IntegerVariable>(&self, var: &Var) -> impl Iterator<Item = i32> {
239 var.iterate_domain(self.assignments())
240 }
241
242 fn is_decision_predicate(&self, predicate: Predicate) -> bool {
243 self.assignments().is_decision_predicate(&predicate)
244 }
245
246 fn is_initial_bound(&self, predicate: Predicate) -> bool {
247 self.assignments().is_initial_bound(predicate)
248 }
249
250 fn get_checkpoint_for_predicate(&self, predicate: Predicate) -> Option<usize> {
251 self.assignments().get_checkpoint_for_predicate(&predicate)
252 }
253
254 fn read_trailed_integer(&self, trailed_integer: TrailedInteger) -> i64 {
255 self.trailed_values().read(trailed_integer)
256 }
257
258 fn new_trailed_integer(&mut self, initial_value: i64) -> TrailedInteger {
259 self.trailed_values_mut().grow(initial_value)
260 }
261
262 fn write_trailed_integer(&mut self, trailed_integer: TrailedInteger, value: i64) {
263 self.trailed_values_mut().assign(trailed_integer, value);
264 }
265
266 fn get_checkpoint(&self) -> usize {
267 self.assignments().get_checkpoint()
268 }
269
270 fn initial_lower_bound(&self, var: DomainId) -> i32 {
271 self.assignments().get_initial_lower_bound(var)
272 }
273
274 fn initial_upper_bound(&self, var: DomainId) -> i32 {
275 self.assignments().get_initial_upper_bound(var)
276 }
277
278 fn initial_holes(&self, var: DomainId) -> Vec<i32> {
279 self.assignments().get_initial_holes(var)
280 }
281
282 fn number_of_domains(&self) -> u32 {
283 self.assignments().num_domains()
284 }
285
286 fn evaluate_predicate_at_trail_position(
287 &self,
288 predicate: Predicate,
289 trail_position: usize,
290 ) -> Option<bool> {
291 self.assignments()
292 .evaluate_predicate_at_trail_position(predicate, trail_position)
293 }
294}