pumpkin_core/engine/variables/
domain_id.rs1use 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#[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}