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