1use crate::ast::domains::Int;
2use crate::ast::domains::range::Range;
3use itertools::Itertools;
4use polyquine::Quine;
5use serde::{Deserialize, Serialize};
6use std::fmt::{Display, Formatter};
7
8#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
9#[path_prefix(conjure_cp::ast)]
10pub struct SetAttr<A = Int> {
11 pub size: Range<A>,
12}
13
14impl<A> SetAttr<A> {
15 pub fn new(size: Range<A>) -> Self {
16 Self { size }
17 }
18
19 pub fn new_min_max_size(min: A, max: A) -> Self {
20 Self::new(Range::Bounded(min, max))
21 }
22
23 pub fn new_min_size(min: A) -> Self {
24 Self::new(Range::UnboundedR(min))
25 }
26
27 pub fn new_max_size(max: A) -> Self {
28 Self::new(Range::UnboundedL(max))
29 }
30
31 pub fn new_size(sz: A) -> Self {
32 Self::new(Range::Single(sz))
33 }
34}
35
36impl<A> Default for SetAttr<A> {
37 fn default() -> Self {
38 SetAttr {
39 size: Range::Unbounded,
40 }
41 }
42}
43
44impl<A: Display> Display for SetAttr<A> {
45 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
46 match &self.size {
47 Range::Single(x) => write!(f, "(size {x})"),
48 Range::Bounded(l, r) => write!(f, "(minSize {l}, maxSize {r})"),
49 Range::UnboundedL(r) => write!(f, "(maxSize {r})"),
50 Range::UnboundedR(l) => write!(f, "(minSize {l})"),
51 Range::Unbounded => write!(f, ""),
52 }
53 }
54}
55
56#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
57#[path_prefix(conjure_cp::ast)]
58pub struct MSetAttr<A = Int> {
59 pub size: Range<A>,
60 pub occurrence: Range<A>,
61}
62
63impl<A> MSetAttr<A> {
64 pub fn new(size: Range<A>, occurrence: Range<A>) -> Self {
65 Self { size, occurrence }
66 }
67
68 pub fn new_min_max_size(min: A, max: A) -> Self {
69 Self::new(Range::Bounded(min, max), Range::Unbounded)
70 }
71
72 pub fn new_min_size(min: A) -> Self {
73 Self::new(Range::UnboundedR(min), Range::Unbounded)
74 }
75
76 pub fn new_max_size(max: A) -> Self {
77 Self::new(Range::UnboundedL(max), Range::Unbounded)
78 }
79
80 pub fn new_size(sz: A) -> Self {
81 Self::new(Range::Single(sz), Range::Unbounded)
82 }
83}
84
85impl<A: Display> Display for MSetAttr<A> {
86 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
87 let size_str = match &self.size {
88 Range::Single(x) => format!("size {x}"),
89 Range::Bounded(l, r) => format!("minSize {l}, maxSize {r}"),
90 Range::UnboundedL(r) => format!("maxSize {r}"),
91 Range::UnboundedR(l) => format!("minSize {l}"),
92 Range::Unbounded => "".to_string(),
93 };
94
95 let occ_str = match &self.occurrence {
98 Range::Single(x) => format!("minOccur {x}, maxOccur {x}"),
99 Range::Bounded(l, r) => format!("minOccur {l} , maxOccur {r}"),
100 Range::UnboundedL(r) => format!("maxOccur {r}"),
101 Range::UnboundedR(l) => format!("minOccur {l}"),
102 Range::Unbounded => "".to_string(),
103 };
104
105 let mut strs = [size_str, occ_str]
106 .iter()
107 .filter(|s| !s.is_empty())
108 .join(", ");
109 if !strs.is_empty() {
110 strs = format!("({})", strs);
111 }
112 write!(f, "{strs}")
113 }
114}
115
116impl<A> Default for MSetAttr<A> {
117 fn default() -> Self {
118 MSetAttr {
119 size: Range::Unbounded,
120 occurrence: Range::Unbounded,
121 }
122 }
123}
124
125#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
126#[path_prefix(conjure_cp::ast)]
127pub struct FuncAttr<A = Int> {
128 pub size: Range<A>,
129 pub partiality: PartialityAttr,
130 pub jectivity: JectivityAttr,
131}
132
133impl<A: Display> Display for FuncAttr<A> {
134 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
135 let size_str = match &self.size {
136 Range::Single(x) => format!("size({x})"),
137 Range::Bounded(l, r) => format!("minSize({l}), maxSize({r})"),
138 Range::UnboundedL(r) => format!("maxSize({r})"),
139 Range::UnboundedR(l) => format!("minSize({l})"),
140 Range::Unbounded => "".to_string(),
141 };
142 let mut strs = [
143 size_str,
144 self.partiality.to_string(),
145 self.jectivity.to_string(),
146 ]
147 .iter()
148 .filter(|s| !s.is_empty())
149 .join(", ");
150 if !strs.is_empty() {
151 strs = format!("({})", strs);
152 }
153 write!(f, "{strs}")
154 }
155}
156
157#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
158#[path_prefix(conjure_cp::ast)]
159pub struct SequenceAttr<A = Int> {
160 pub size: Range<A>,
161 pub jectivity: JectivityAttr,
162}
163
164impl<A> Default for SequenceAttr<A> {
165 fn default() -> Self {
166 SequenceAttr {
167 size: Range::Unbounded,
168 jectivity: JectivityAttr::None,
169 }
170 }
171}
172
173impl<A: Display> Display for SequenceAttr<A> {
174 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
175 let size_str = match &self.size {
176 Range::Single(x) => format!("size {x}"),
177 Range::Bounded(l, r) => format!("minSize {l}, maxSize {r}"),
178 Range::UnboundedL(r) => format!("maxSize {r}"),
179 Range::UnboundedR(l) => format!("minSize {l}"),
180 Range::Unbounded => "".to_string(),
181 };
182 let mut strs = [size_str, self.jectivity.to_string()]
183 .iter()
184 .filter(|s| !s.is_empty())
185 .join(", ");
186 if !strs.is_empty() {
187 strs = format!("({})", strs);
188 }
189 write!(f, "{strs}")
190 }
191}
192
193#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
194#[path_prefix(conjure_cp::ast)]
195pub struct PartitionAttr<A = Int> {
196 pub num_parts: Range<A>, pub part_len: Range<A>, pub is_regular: bool,
199}
200
201impl<A: Display> Display for PartitionAttr<A> {
202 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
203 let num_parts_str = match &self.num_parts {
204 Range::Single(x) => format!("numParts {x}"),
205 Range::Bounded(l, r) => format!("minNumParts {l}, maxNumParts {r}"),
206 Range::UnboundedL(r) => format!("maxNumParts {r}"),
207 Range::UnboundedR(l) => format!("minNumParts {l}"),
208 Range::Unbounded => "".to_string(),
209 };
210
211 let part_len_str = match &self.part_len {
212 Range::Single(x) => format!("partSize {x}"),
213 Range::Bounded(l, r) => format!("minPartSize {l} , maxPartSize {r}"),
214 Range::UnboundedL(r) => format!("maxPartSize {r}"),
215 Range::UnboundedR(l) => format!("minPartSize {l}"),
216 Range::Unbounded => "".to_string(),
217 };
218
219 let regular_str = match &self.is_regular {
220 true => "regular".to_string(),
221 false => String::new(),
222 };
223
224 let mut strs = [num_parts_str, part_len_str, regular_str]
225 .iter()
226 .filter(|s| !s.is_empty())
227 .join(", ");
228 if !strs.is_empty() {
229 strs = format!("({})", strs);
230 }
231 write!(f, "{strs}")
232 }
233}
234
235impl<A> Default for PartitionAttr<A> {
236 fn default() -> Self {
237 PartitionAttr {
238 num_parts: Range::Unbounded,
239 part_len: Range::Unbounded,
240 is_regular: false,
241 }
242 }
243}
244
245#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
246pub enum PartialityAttr {
247 Total,
248 Partial,
249}
250
251impl Display for PartialityAttr {
252 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
253 match self {
254 PartialityAttr::Total => write!(f, "total"),
255 PartialityAttr::Partial => write!(f, ""),
256 }
257 }
258}
259
260#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
261pub enum JectivityAttr {
262 None,
263 Injective,
264 Surjective,
265 Bijective,
266}
267
268impl Display for JectivityAttr {
269 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
270 match self {
271 JectivityAttr::None => write!(f, ""),
272 JectivityAttr::Injective => write!(f, "injective"),
273 JectivityAttr::Surjective => write!(f, "surjective"),
274 JectivityAttr::Bijective => write!(f, "bijective"),
275 }
276 }
277}
278
279#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
280#[path_prefix(conjure_cp::ast)]
281pub struct RelAttr<A = Int> {
282 pub size: Range<A>,
283 pub binary: Vec<BinaryAttr>,
284}
285
286impl<A> Default for RelAttr<A> {
287 fn default() -> Self {
288 RelAttr {
289 size: Range::Unbounded,
290 binary: Vec::new(),
291 }
292 }
293}
294
295impl<A: Display> Display for RelAttr<A> {
296 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
297 let size_str = match &self.size {
298 Range::Single(x) => format!("size {x}"),
299 Range::Bounded(l, r) => format!("minSize {l}, maxSize {r}"),
300 Range::UnboundedL(r) => format!("maxSize {r}"),
301 Range::UnboundedR(l) => format!("minSize {l}"),
302 Range::Unbounded => "".to_string(),
303 };
304 let mut strs = [size_str, self.binary.iter().join(", ")]
305 .iter()
306 .filter(|s| !s.is_empty())
307 .join(", ");
308 if !strs.is_empty() {
309 strs = format!("({})", strs);
310 }
311 write!(f, "{strs}")
312 }
313}
314
315#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
316pub enum BinaryAttr {
317 Reflexive,
318 Irreflexive,
319 Coreflexive,
320 Symmetric,
321 AntiSymmetric,
322 ASymmetric,
323 Transitive,
324 Total,
325 Connex,
326 Euclidean,
327 Serial,
328 Equivalence,
329 PartialOrder,
330}
331
332impl Display for BinaryAttr {
333 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
334 match self {
335 BinaryAttr::Reflexive => write!(f, "reflexive"),
336 BinaryAttr::Irreflexive => write!(f, "irreflexive"),
337 BinaryAttr::Coreflexive => write!(f, "coreflexive"),
338 BinaryAttr::Symmetric => write!(f, "symmetric"),
339 BinaryAttr::AntiSymmetric => write!(f, "antiSymmetric"),
340 BinaryAttr::ASymmetric => write!(f, "aSymmetric"),
341 BinaryAttr::Transitive => write!(f, "transitive"),
342 BinaryAttr::Total => write!(f, "total"),
343 BinaryAttr::Connex => write!(f, "connex"),
344 BinaryAttr::Euclidean => write!(f, "Euclidean"),
345 BinaryAttr::Serial => write!(f, "serial"),
346 BinaryAttr::Equivalence => write!(f, "equivalence"),
347 BinaryAttr::PartialOrder => write!(f, "partialOrder"),
348 }
349 }
350}