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 fixed_value<Var: IntegerVariable>(&self, var: &Var) -> Option<i32>;
82
83 fn lower_bound<Var: IntegerVariable>(&self, var: &Var) -> i32;
85
86 fn lower_bound_at_trail_position<Var: IntegerVariable>(
91 &self,
92 var: &Var,
93 trail_position: usize,
94 ) -> i32;
95
96 fn upper_bound<Var: IntegerVariable>(&self, var: &Var) -> i32;
98
99 fn upper_bound_at_trail_position<Var: IntegerVariable>(
104 &self,
105 var: &Var,
106 trail_position: usize,
107 ) -> i32;
108
109 fn contains<Var: IntegerVariable>(&self, var: &Var, value: i32) -> bool;
111
112 fn contains_at_trail_position<Var: IntegerVariable>(
118 &self,
119 var: &Var,
120 value: i32,
121 trail_position: usize,
122 ) -> bool;
123
124 fn iterate_domain<Var: IntegerVariable>(&self, var: &Var) -> impl Iterator<Item = i32>;
127
128 fn is_decision_predicate(&self, predicate: Predicate) -> bool;
131
132 fn is_initial_bound(&self, predicate: Predicate) -> bool;
134
135 fn get_checkpoint_for_predicate(&self, predicate: Predicate) -> Option<usize>;
138
139 fn read_trailed_integer(&self, trailed_integer: TrailedInteger) -> i64;
141
142 fn new_trailed_integer(&mut self, initial_value: i64) -> TrailedInteger;
144
145 fn write_trailed_integer(&mut self, trailed_integer: TrailedInteger, value: i64);
147
148 fn get_checkpoint(&self) -> usize;
150
151 fn initial_lower_bound(&self, var: DomainId) -> i32;
153
154 fn initial_upper_bound(&self, var: DomainId) -> i32;
156
157 fn initial_holes(&self, var: DomainId) -> Vec<i32>;
159
160 fn number_of_domains(&self) -> u32;
162}
163
164impl<T: HasAssignments> ReadDomains for T {
165 fn evaluate_predicate(&self, predicate: Predicate) -> Option<bool> {
166 self.assignments().evaluate_predicate(predicate)
167 }
168
169 fn evaluate_literal(&self, literal: Literal) -> Option<bool> {
170 self.evaluate_predicate(literal.get_true_predicate())
171 }
172
173 fn get_holes_at_current_checkpoint<Var: IntegerVariable>(
174 &self,
175 var: &Var,
176 ) -> impl Iterator<Item = i32> {
177 var.get_holes_at_current_checkpoint(self.assignments())
178 }
179
180 fn get_holes<Var: IntegerVariable>(&self, var: &Var) -> impl Iterator<Item = i32> {
181 var.get_holes(self.assignments())
182 }
183
184 fn is_fixed<Var: IntegerVariable>(&self, var: &Var) -> bool {
185 self.lower_bound(var) == self.upper_bound(var)
186 }
187
188 fn fixed_value<Var: IntegerVariable>(&self, var: &Var) -> Option<i32> {
189 let lower_bound = self.lower_bound(var);
190 (lower_bound == self.upper_bound(var)).then_some(lower_bound)
191 }
192
193 fn lower_bound<Var: IntegerVariable>(&self, var: &Var) -> i32 {
194 var.lower_bound(self.assignments())
195 }
196
197 fn lower_bound_at_trail_position<Var: IntegerVariable>(
198 &self,
199 var: &Var,
200 trail_position: usize,
201 ) -> i32 {
202 var.lower_bound_at_trail_position(self.assignments(), trail_position)
203 }
204
205 fn upper_bound<Var: IntegerVariable>(&self, var: &Var) -> i32 {
206 var.upper_bound(self.assignments())
207 }
208
209 fn upper_bound_at_trail_position<Var: IntegerVariable>(
210 &self,
211 var: &Var,
212 trail_position: usize,
213 ) -> i32 {
214 var.upper_bound_at_trail_position(self.assignments(), trail_position)
215 }
216
217 fn contains<Var: IntegerVariable>(&self, var: &Var, value: i32) -> bool {
218 var.contains(self.assignments(), value)
219 }
220
221 fn contains_at_trail_position<Var: IntegerVariable>(
222 &self,
223 var: &Var,
224 value: i32,
225 trail_position: usize,
226 ) -> bool {
227 var.contains_at_trail_position(self.assignments(), value, trail_position)
228 }
229
230 fn iterate_domain<Var: IntegerVariable>(&self, var: &Var) -> impl Iterator<Item = i32> {
231 var.iterate_domain(self.assignments())
232 }
233
234 fn is_decision_predicate(&self, predicate: Predicate) -> bool {
235 self.assignments().is_decision_predicate(&predicate)
236 }
237
238 fn is_initial_bound(&self, predicate: Predicate) -> bool {
239 self.assignments().is_initial_bound(predicate)
240 }
241
242 fn get_checkpoint_for_predicate(&self, predicate: Predicate) -> Option<usize> {
243 self.assignments().get_checkpoint_for_predicate(&predicate)
244 }
245
246 fn read_trailed_integer(&self, trailed_integer: TrailedInteger) -> i64 {
247 self.trailed_values().read(trailed_integer)
248 }
249
250 fn new_trailed_integer(&mut self, initial_value: i64) -> TrailedInteger {
251 self.trailed_values_mut().grow(initial_value)
252 }
253
254 fn write_trailed_integer(&mut self, trailed_integer: TrailedInteger, value: i64) {
255 self.trailed_values_mut().assign(trailed_integer, value);
256 }
257
258 fn get_checkpoint(&self) -> usize {
259 self.assignments().get_checkpoint()
260 }
261
262 fn initial_lower_bound(&self, var: DomainId) -> i32 {
263 self.assignments().get_initial_lower_bound(var)
264 }
265
266 fn initial_upper_bound(&self, var: DomainId) -> i32 {
267 self.assignments().get_initial_upper_bound(var)
268 }
269
270 fn initial_holes(&self, var: DomainId) -> Vec<i32> {
271 self.assignments().get_initial_holes(var)
272 }
273
274 fn number_of_domains(&self) -> u32 {
275 self.assignments().num_domains()
276 }
277}