pumpkin_core/engine/variables/
literal.rs1use std::ops::Not;
2
3use enumset::EnumSet;
4
5use super::DomainId;
6use super::IntegerVariable;
7use super::TransformableVariable;
8use crate::engine::notifications::DomainEvent;
9use crate::engine::notifications::OpaqueDomainEvent;
10use crate::engine::notifications::Watchers;
11use crate::engine::predicates::predicate::Predicate;
12use crate::engine::predicates::predicate_constructor::PredicateConstructor;
13use crate::engine::variables::AffineView;
14use crate::engine::Assignments;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
17pub struct Literal {
18 integer_variable: AffineView<DomainId>,
19}
20
21impl Literal {
22 pub(crate) fn new(domain_id: DomainId) -> Literal {
23 Literal {
24 integer_variable: domain_id.scaled(1),
25 }
26 }
27
28 #[cfg(test)]
29 pub fn test_new(domain_id: DomainId) -> Literal {
30 Literal {
31 integer_variable: domain_id.scaled(1),
32 }
33 }
34
35 pub fn get_integer_variable(&self) -> AffineView<DomainId> {
36 self.integer_variable
37 }
38
39 pub fn get_true_predicate(&self) -> Predicate {
40 self.lower_bound_predicate(1)
41 }
42
43 pub fn get_false_predicate(&self) -> Predicate {
44 self.upper_bound_predicate(0)
45 }
46}
47
48impl Not for Literal {
49 type Output = Literal;
50
51 fn not(self) -> Self::Output {
52 Literal {
53 integer_variable: self.integer_variable.scaled(-1).offset(1),
54 }
55 }
56}
57
58impl IntegerVariable for Literal {
59 type AffineView = AffineView<Self>;
60
61 fn lower_bound(&self, assignment: &Assignments) -> i32 {
66 self.integer_variable.lower_bound(assignment)
67 }
68
69 fn lower_bound_at_trail_position(
70 &self,
71 assignment: &Assignments,
72 trail_position: usize,
73 ) -> i32 {
74 self.integer_variable
75 .lower_bound_at_trail_position(assignment, trail_position)
76 }
77
78 fn upper_bound(&self, assignment: &Assignments) -> i32 {
83 self.integer_variable.upper_bound(assignment)
84 }
85
86 fn upper_bound_at_trail_position(
87 &self,
88 assignment: &Assignments,
89 trail_position: usize,
90 ) -> i32 {
91 self.integer_variable
92 .upper_bound_at_trail_position(assignment, trail_position)
93 }
94
95 fn contains(&self, assignment: &Assignments, value: i32) -> bool {
101 self.integer_variable.contains(assignment, value)
102 }
103
104 fn contains_at_trail_position(
105 &self,
106 assignment: &Assignments,
107 value: i32,
108 trail_position: usize,
109 ) -> bool {
110 self.integer_variable
111 .contains_at_trail_position(assignment, value, trail_position)
112 }
113
114 fn iterate_domain(&self, assignment: &Assignments) -> impl Iterator<Item = i32> {
115 self.integer_variable.iterate_domain(assignment)
116 }
117
118 fn watch_all(&self, watchers: &mut Watchers<'_>, events: EnumSet<DomainEvent>) {
119 self.integer_variable.watch_all(watchers, events)
120 }
121
122 fn unpack_event(&self, event: OpaqueDomainEvent) -> DomainEvent {
123 self.integer_variable.unpack_event(event)
124 }
125
126 fn watch_all_backtrack(&self, watchers: &mut Watchers<'_>, events: EnumSet<DomainEvent>) {
127 self.integer_variable.watch_all_backtrack(watchers, events)
128 }
129
130 fn get_holes_on_current_decision_level(
131 &self,
132 assignments: &Assignments,
133 ) -> impl Iterator<Item = i32> {
134 self.integer_variable
135 .get_holes_on_current_decision_level(assignments)
136 }
137
138 fn get_holes(&self, assignments: &Assignments) -> impl Iterator<Item = i32> {
139 self.integer_variable.get_holes(assignments)
140 }
141}
142
143impl PredicateConstructor for Literal {
144 type Value = i32;
145
146 fn lower_bound_predicate(&self, bound: Self::Value) -> Predicate {
147 self.integer_variable.lower_bound_predicate(bound)
148 }
149
150 fn upper_bound_predicate(&self, bound: Self::Value) -> Predicate {
151 self.integer_variable.upper_bound_predicate(bound)
152 }
153
154 fn equality_predicate(&self, bound: Self::Value) -> Predicate {
155 self.integer_variable.equality_predicate(bound)
156 }
157
158 fn disequality_predicate(&self, bound: Self::Value) -> Predicate {
159 self.integer_variable.disequality_predicate(bound)
160 }
161}
162
163impl TransformableVariable<AffineView<Literal>> for Literal {
164 fn scaled(&self, scale: i32) -> AffineView<Literal> {
165 AffineView::new(*self, scale, 0)
166 }
167
168 fn offset(&self, offset: i32) -> AffineView<Literal> {
169 AffineView::new(*self, 1, offset)
170 }
171}