Skip to main content

pumpkin_core/propagation/
domains.rs

1use 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/// Provides access to domain information to propagators.
12///
13/// Implements [`ReadDomains`] to expose information about the current variable domains such as the
14/// lower-bound of a particular variable.
15#[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
34/// A helper-trait for implementing [`ReadDomains`], which exposes the assignment.
35pub(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
55/// A trait defining functions for retrieving information about the current domains.
56pub trait ReadDomains {
57    /// Returns whether the provided [`Predicate`] is assigned (either true or false) or is
58    /// currently unassigned.
59    fn evaluate_predicate(&self, predicate: Predicate) -> Option<bool>;
60
61    /// Returns whether the provided [`Literal`] is assigned (either true or false) or is
62    /// currently unassigned.
63    fn evaluate_literal(&self, literal: Literal) -> Option<bool>;
64
65    /// Returns the holes in the domain which were created on the current checkpoint.
66    fn get_holes_at_current_checkpoint<Var: IntegerVariable>(
67        &self,
68        var: &Var,
69    ) -> impl Iterator<Item = i32>;
70
71    /// Returns all of the holes (currently) in the domain of `var` (including ones which were
72    /// created at previous decision levels).
73    fn get_holes<Var: IntegerVariable>(&self, var: &Var) -> impl Iterator<Item = i32>;
74
75    /// Returns `true` if the domain of the given variable is singleton (i.e., the variable is
76    /// fixed).
77    fn is_fixed<Var: IntegerVariable>(&self, var: &Var) -> bool;
78
79    /// Returns the lowest value in the domain of `var`.
80    fn lower_bound<Var: IntegerVariable>(&self, var: &Var) -> i32;
81
82    /// Returns the lowest value in the domain of `var` at the given `trail_position`.
83    ///
84    /// The trail position can be retrieved when generating lazy explanations using
85    /// [`ExplanationContext::get_trail_position`].
86    fn lower_bound_at_trail_position<Var: IntegerVariable>(
87        &self,
88        var: &Var,
89        trail_position: usize,
90    ) -> i32;
91
92    /// Returns the highest value in the domain of `var`.
93    fn upper_bound<Var: IntegerVariable>(&self, var: &Var) -> i32;
94
95    /// Returns the highest value in the domain of `var` at the given `trail_position`.
96    ///
97    /// The trail position can be retrieved when generating lazy explanations using
98    /// [`ExplanationContext::get_trail_position`].
99    fn upper_bound_at_trail_position<Var: IntegerVariable>(
100        &self,
101        var: &Var,
102        trail_position: usize,
103    ) -> i32;
104
105    /// Returns whether the provided `value` is in the domain of `var`.
106    fn contains<Var: IntegerVariable>(&self, var: &Var, value: i32) -> bool;
107
108    /// Returns whether the provided `value` is in the domain of `var` at the given
109    /// `trail_position`.
110    ///
111    /// The trail position can be retrieved when generating lazy explanations using
112    /// [`ExplanationContext::get_trail_position`].
113    fn contains_at_trail_position<Var: IntegerVariable>(
114        &self,
115        var: &Var,
116        value: i32,
117        trail_position: usize,
118    ) -> bool;
119
120    /// Returns an [`Iterator`] over the values in the domain of the provided `var` (including the
121    /// lower-bound and upper-bound values).
122    fn iterate_domain<Var: IntegerVariable>(&self, var: &Var) -> impl Iterator<Item = i32>;
123
124    /// Returns whether the provided [`Predicate`] was posted as a decision (i.e., it was posted as
125    /// a [`Predicate`] without a reason).
126    fn is_decision_predicate(&self, predicate: Predicate) -> bool;
127
128    /// Returns whether the provided [`Predicate`] is an initial bound of its domain.
129    fn is_initial_bound(&self, predicate: Predicate) -> bool;
130
131    /// If the provided [`Predicate`] is true, then this method returns the checkpoint at which it
132    /// first become true; otherwise, it returns [`None`].
133    fn get_checkpoint_for_predicate(&self, predicate: Predicate) -> Option<usize>;
134
135    /// Returns the current value of the provided [`TrailedInteger`].
136    fn read_trailed_integer(&self, trailed_integer: TrailedInteger) -> i64;
137
138    /// Creates a new [`TrailedInteger`] assigned to the provided `initial_value`.
139    fn new_trailed_integer(&mut self, initial_value: i64) -> TrailedInteger;
140
141    /// Assigns the provided [`TrailedInteger`] to the provided `value`.
142    fn write_trailed_integer(&mut self, trailed_integer: TrailedInteger, value: i64);
143
144    /// Returns the current checkpoint.
145    fn get_checkpoint(&self) -> usize;
146
147    /// Returns the lowest value in the domain of `var` at the time of its creation.
148    fn initial_lower_bound(&self, var: DomainId) -> i32;
149
150    /// Returns the highest value in the domain of `var` at the time of its creation.
151    fn initial_upper_bound(&self, var: DomainId) -> i32;
152
153    /// Returns all of the holes present at the time of thecreation of `var`.
154    fn initial_holes(&self, var: DomainId) -> Vec<i32>;
155
156    /// Returns the number of currently defined domains.
157    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}