pumpkin_core/engine/variables/
domain_id.rs

1use enumset::EnumSet;
2
3use super::TransformableVariable;
4use crate::containers::StorageKey;
5use crate::engine::notifications::DomainEvent;
6use crate::engine::notifications::OpaqueDomainEvent;
7use crate::engine::notifications::Watchers;
8use crate::engine::variables::AffineView;
9use crate::engine::variables::IntegerVariable;
10use crate::engine::Assignments;
11use crate::pumpkin_assert_simple;
12
13/// A structure which represents the most basic [`IntegerVariable`]; it is simply the id which links
14/// to a domain (hence the name).
15#[derive(Clone, PartialEq, Eq, Copy, Hash)]
16pub struct DomainId {
17    id: u32,
18}
19
20impl DomainId {
21    pub fn new(id: u32) -> Self {
22        pumpkin_assert_simple!(id >> 30 == 0, "The first two bits are used as flags");
23        DomainId { id }
24    }
25
26    pub fn id(&self) -> u32 {
27        self.id
28    }
29}
30
31impl IntegerVariable for DomainId {
32    type AffineView = AffineView<Self>;
33
34    fn lower_bound(&self, assignment: &Assignments) -> i32 {
35        assignment.get_lower_bound(*self)
36    }
37
38    fn lower_bound_at_trail_position(
39        &self,
40        assignment: &Assignments,
41        trail_position: usize,
42    ) -> i32 {
43        assignment.get_lower_bound_at_trail_position(*self, trail_position)
44    }
45
46    fn upper_bound(&self, assignment: &Assignments) -> i32 {
47        assignment.get_upper_bound(*self)
48    }
49
50    fn upper_bound_at_trail_position(
51        &self,
52        assignment: &Assignments,
53        trail_position: usize,
54    ) -> i32 {
55        assignment.get_upper_bound_at_trail_position(*self, trail_position)
56    }
57
58    fn contains(&self, assignment: &Assignments, value: i32) -> bool {
59        assignment.is_value_in_domain(*self, value)
60    }
61
62    fn contains_at_trail_position(
63        &self,
64        assignment: &Assignments,
65        value: i32,
66        trail_position: usize,
67    ) -> bool {
68        assignment.is_value_in_domain_at_trail_position(*self, value, trail_position)
69    }
70
71    fn iterate_domain(&self, assignment: &Assignments) -> impl Iterator<Item = i32> {
72        assignment.get_domain_iterator(*self)
73    }
74
75    fn watch_all(&self, watchers: &mut Watchers<'_>, events: EnumSet<DomainEvent>) {
76        watchers.watch_all(*self, events);
77    }
78
79    fn watch_all_backtrack(&self, watchers: &mut Watchers<'_>, events: EnumSet<DomainEvent>) {
80        watchers.watch_all_backtrack(*self, events);
81    }
82
83    fn unpack_event(&self, event: OpaqueDomainEvent) -> DomainEvent {
84        event.unwrap()
85    }
86
87    fn get_holes_on_current_decision_level(
88        &self,
89        assignments: &Assignments,
90    ) -> impl Iterator<Item = i32> {
91        assignments.get_holes_on_current_decision_level(*self)
92    }
93
94    fn get_holes(&self, assignments: &Assignments) -> impl Iterator<Item = i32> {
95        assignments.get_holes(*self)
96    }
97}
98
99impl TransformableVariable<AffineView<DomainId>> for DomainId {
100    fn scaled(&self, scale: i32) -> AffineView<DomainId> {
101        AffineView::new(*self, scale, 0)
102    }
103
104    fn offset(&self, offset: i32) -> AffineView<DomainId> {
105        AffineView::new(*self, 1, offset)
106    }
107}
108
109impl StorageKey for DomainId {
110    fn index(&self) -> usize {
111        self.id as usize
112    }
113
114    fn create_from_index(index: usize) -> Self {
115        DomainId { id: index as u32 }
116    }
117}
118
119impl std::fmt::Display for DomainId {
120    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121        write!(f, "x{}", self.id)
122    }
123}
124
125impl std::fmt::Debug for DomainId {
126    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127        write!(f, "x{}", self.id)
128    }
129}