pumpkin_core/branching/
selection_context.rs1use std::fmt::Debug;
2
3use crate::basic_types::Random;
4#[cfg(doc)]
5use crate::branching::Brancher;
6#[cfg(test)]
7use crate::engine::notifications::NotificationEngine;
8use crate::engine::predicates::predicate::Predicate;
9#[cfg(doc)]
10use crate::engine::propagation::PropagationContext;
11use crate::engine::variables::DomainGeneratorIterator;
12#[cfg(doc)]
13use crate::engine::variables::DomainId;
14use crate::engine::variables::IntegerVariable;
15use crate::engine::Assignments;
16
17#[derive(Debug)]
21pub struct SelectionContext<'a> {
22 assignments: &'a Assignments,
23 random_generator: &'a mut dyn Random,
24}
25
26impl<'a> SelectionContext<'a> {
27 pub fn new(assignments: &'a Assignments, rng: &'a mut dyn Random) -> Self {
28 SelectionContext {
29 assignments,
30 random_generator: rng,
31 }
32 }
33
34 pub fn are_all_variables_assigned(&self) -> bool {
35 self.assignments
36 .get_domains()
37 .all(|domain_id| self.assignments.is_domain_assigned(&domain_id))
38 }
39
40 pub fn random(&mut self) -> &mut dyn Random {
43 self.random_generator
44 }
45
46 pub fn get_size_of_domain<Var: IntegerVariable>(&self, var: Var) -> i32 {
50 var.upper_bound(self.assignments) - var.lower_bound(self.assignments)
51 }
52
53 pub fn lower_bound<Var: IntegerVariable>(&self, var: Var) -> i32 {
55 var.lower_bound(self.assignments)
56 }
57
58 pub fn upper_bound<Var: IntegerVariable>(&self, var: Var) -> i32 {
60 var.upper_bound(self.assignments)
61 }
62
63 pub fn contains<Var: IntegerVariable>(&self, var: Var, value: i32) -> bool {
65 var.contains(self.assignments, value)
66 }
67
68 pub fn is_integer_fixed<Var: IntegerVariable>(&self, var: Var) -> bool {
71 self.lower_bound(var.clone()) == self.upper_bound(var)
72 }
73
74 pub fn is_predicate_assigned(&self, predicate: Predicate) -> bool {
75 self.assignments.evaluate_predicate(predicate).is_some()
76 }
77
78 pub fn get_domains(&self) -> DomainGeneratorIterator {
80 self.assignments.get_domains()
81 }
82
83 #[cfg(test)]
84 pub(crate) fn create_for_testing(
86 domains: Vec<(i32, i32)>,
87 ) -> (Assignments, NotificationEngine) {
88 let mut assignments = Assignments::default();
89 let mut notification_engine = NotificationEngine::default();
90
91 for (lower_bound, upper_bound) in domains {
92 _ = assignments.grow(lower_bound, upper_bound);
93 notification_engine.grow();
94 }
95
96 (assignments, notification_engine)
97 }
98}