pumpkin_core/engine/predicates/
predicate_constructor.rs1use super::predicate::Predicate;
2
3pub trait PredicateConstructor {
5 type Value;
7
8 fn lower_bound_predicate(&self, bound: Self::Value) -> Predicate;
10
11 fn upper_bound_predicate(&self, bound: Self::Value) -> Predicate;
13
14 fn equality_predicate(&self, bound: Self::Value) -> Predicate;
16
17 fn disequality_predicate(&self, bound: Self::Value) -> Predicate;
19}
20
21#[macro_export]
48macro_rules! predicate {
49 ($($var:ident).+$([$index:expr])? >= $bound:expr) => {{
50 #[allow(unused, reason = "could be imported at call-site")]
51 use $crate::predicates::PredicateConstructor;
52 $($var).+$([$index])?.lower_bound_predicate($bound)
53 }};
54 ($($var:ident).+$([$index:expr])? <= $bound:expr) => {{
55 #[allow(unused, reason = "could be imported at call-site")]
56 use $crate::predicates::PredicateConstructor;
57 $($var).+$([$index])?.upper_bound_predicate($bound)
58 }};
59 ($($var:ident).+$([$index:expr])? == $value:expr) => {{
60 #[allow(unused, reason = "could be imported at call-site")]
61 use $crate::predicates::PredicateConstructor;
62 $($var).+$([$index])?.equality_predicate($value)
63 }};
64 ($($var:ident).+$([$index:expr])? != $value:expr) => {{
65 #[allow(unused, reason = "could be imported at call-site")]
66 use $crate::predicates::PredicateConstructor;
67 $($var).+$([$index])?.disequality_predicate($value)
68 }};
69}
70
71#[cfg(test)]
72mod tests {
73 use crate::variables::DomainId;
74
75 #[test]
76 fn macro_local_identifiers_are_matched() {
77 let x = DomainId::new(0);
78
79 assert_eq!(x, predicate![x >= 2].get_domain());
80 assert_eq!(x, predicate![x <= 3].get_domain());
81 assert_eq!(x, predicate![x == 5].get_domain());
82 assert_eq!(x, predicate![x != 5].get_domain());
83
84 assert_eq!(2, predicate![x >= 2].get_right_hand_side());
85 assert_eq!(3, predicate![x <= 3].get_right_hand_side());
86 assert_eq!(5, predicate![x == 5].get_right_hand_side());
87 assert_eq!(5, predicate![x != 5].get_right_hand_side());
88
89 assert!(predicate!(x >= 2).is_lower_bound_predicate());
90 assert!(!predicate!(x >= 2).is_upper_bound_predicate());
91 assert!(!predicate!(x >= 2).is_equality_predicate());
92 assert!(!predicate!(x >= 2).is_not_equal_predicate());
93
94 assert!(predicate!(x <= 3).is_upper_bound_predicate());
95 assert!(!predicate!(x <= 3).is_lower_bound_predicate());
96 assert!(!predicate!(x <= 3).is_equality_predicate());
97 assert!(!predicate!(x <= 3).is_not_equal_predicate());
98
99 assert!(predicate!(x == 5).is_equality_predicate());
100 assert!(!predicate!(x == 5).is_lower_bound_predicate());
101 assert!(!predicate!(x == 5).is_upper_bound_predicate());
102 assert!(!predicate!(x == 5).is_not_equal_predicate());
103
104 assert!(predicate!(x != 5).is_not_equal_predicate());
105 assert!(!predicate!(x != 5).is_lower_bound_predicate());
106 assert!(!predicate!(x != 5).is_upper_bound_predicate());
107 assert!(!predicate!(x != 5).is_equality_predicate());
108 }
109
110 #[test]
111 fn macro_nested_identifiers_are_matched() {
112 struct Wrapper {
113 x: DomainId,
114 }
115
116 let wrapper = Wrapper {
117 x: DomainId::new(0),
118 };
119
120 assert_eq!(wrapper.x, predicate![wrapper.x >= 2].get_domain());
121 assert_eq!(wrapper.x, predicate![wrapper.x <= 3].get_domain());
122 assert_eq!(wrapper.x, predicate![wrapper.x == 5].get_domain());
123 assert_eq!(wrapper.x, predicate![wrapper.x != 5].get_domain());
124
125 assert_eq!(2, predicate![wrapper.x >= 2].get_right_hand_side());
126 assert_eq!(3, predicate![wrapper.x <= 3].get_right_hand_side());
127 assert_eq!(5, predicate![wrapper.x == 5].get_right_hand_side());
128 assert_eq!(5, predicate![wrapper.x != 5].get_right_hand_side());
129 }
130
131 #[test]
132 fn macro_index_expressions_are_matched() {
133 let wrapper = [DomainId::new(0)];
134
135 assert_eq!(wrapper[0], predicate![wrapper[0] >= 2].get_domain());
136 assert_eq!(wrapper[0], predicate![wrapper[0] <= 3].get_domain());
137 assert_eq!(wrapper[0], predicate![wrapper[0] == 5].get_domain());
138 assert_eq!(wrapper[0], predicate![wrapper[0] != 5].get_domain());
139
140 assert_eq!(2, predicate![wrapper[0] >= 2].get_right_hand_side());
141 assert_eq!(3, predicate![wrapper[0] <= 3].get_right_hand_side());
142 assert_eq!(5, predicate![wrapper[0] == 5].get_right_hand_side());
143 assert_eq!(5, predicate![wrapper[0] != 5].get_right_hand_side());
144 }
145}