1
use crate::ast::domains::Int;
2
use crate::ast::domains::range::Range;
3
use itertools::Itertools;
4
use polyquine::Quine;
5
use serde::{Deserialize, Serialize};
6
use std::fmt::{Display, Formatter};
7

            
8
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
9
#[path_prefix(conjure_cp::ast)]
10
pub struct SetAttr<A = Int> {
11
    pub size: Range<A>,
12
}
13

            
14
impl<A> SetAttr<A> {
15
196
    pub fn new(size: Range<A>) -> Self {
16
196
        Self { size }
17
196
    }
18

            
19
1
    pub fn new_min_max_size(min: A, max: A) -> Self {
20
1
        Self::new(Range::Bounded(min, max))
21
1
    }
22

            
23
79
    pub fn new_min_size(min: A) -> Self {
24
79
        Self::new(Range::UnboundedR(min))
25
79
    }
26

            
27
3
    pub fn new_max_size(max: A) -> Self {
28
3
        Self::new(Range::UnboundedL(max))
29
3
    }
30

            
31
3
    pub fn new_size(sz: A) -> Self {
32
3
        Self::new(Range::Single(sz))
33
3
    }
34
}
35

            
36
impl<A> Default for SetAttr<A> {
37
8744
    fn default() -> Self {
38
8744
        SetAttr {
39
8744
            size: Range::Unbounded,
40
8744
        }
41
8744
    }
42
}
43

            
44
impl<A: Display> Display for SetAttr<A> {
45
24874
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
46
24874
        match &self.size {
47
66
            Range::Single(x) => write!(f, "(size {x})"),
48
68
            Range::Bounded(l, r) => write!(f, "(minSize {l}, maxSize {r})"),
49
18
            Range::UnboundedL(r) => write!(f, "(maxSize {r})"),
50
18200
            Range::UnboundedR(l) => write!(f, "(minSize {l})"),
51
6522
            Range::Unbounded => write!(f, ""),
52
        }
53
24874
    }
54
}
55

            
56
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
57
#[path_prefix(conjure_cp::ast)]
58
pub struct MSetAttr<A = Int> {
59
    pub size: Range<A>,
60
    pub occurrence: Range<A>,
61
}
62

            
63
impl<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

            
85
impl<A: Display> Display for MSetAttr<A> {
86
482
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
87
482
        let size_str = match &self.size {
88
40
            Range::Single(x) => format!("size {x}"),
89
40
            Range::Bounded(l, r) => format!("minSize {l}, maxSize {r}"),
90
40
            Range::UnboundedL(r) => format!("maxSize {r}"),
91
82
            Range::UnboundedR(l) => format!("minSize {l}"),
92
280
            Range::Unbounded => "".to_string(),
93
        };
94

            
95
        // It only makes sense in terms of min and max occurrence for the essence language,
96
        // so for single ranges it is still presented as min and max occurrence.
97
482
        let occ_str = match &self.occurrence {
98
            Range::Single(x) => format!("minOccur {x}, maxOccur {x}"),
99
80
            Range::Bounded(l, r) => format!("minOccur {l} , maxOccur {r}"),
100
202
            Range::UnboundedL(r) => format!("maxOccur {r}"),
101
40
            Range::UnboundedR(l) => format!("minOccur {l}"),
102
160
            Range::Unbounded => "".to_string(),
103
        };
104

            
105
482
        let mut strs = [size_str, occ_str]
106
482
            .iter()
107
964
            .filter(|s| !s.is_empty())
108
482
            .join(", ");
109
482
        if !strs.is_empty() {
110
442
            strs = format!("({})", strs);
111
442
        }
112
482
        write!(f, "{strs}")
113
482
    }
114
}
115

            
116
impl<A> Default for MSetAttr<A> {
117
40
    fn default() -> Self {
118
40
        MSetAttr {
119
40
            size: Range::Unbounded,
120
40
            occurrence: Range::Unbounded,
121
40
        }
122
40
    }
123
}
124

            
125
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
126
#[path_prefix(conjure_cp::ast)]
127
pub struct FuncAttr<A = Int> {
128
    pub size: Range<A>,
129
    pub partiality: PartialityAttr,
130
    pub jectivity: JectivityAttr,
131
}
132

            
133
impl<A: Display> Display for FuncAttr<A> {
134
724
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
135
724
        let size_str = match &self.size {
136
52
            Range::Single(x) => format!("size({x})"),
137
54
            Range::Bounded(l, r) => format!("minSize({l}), maxSize({r})"),
138
44
            Range::UnboundedL(r) => format!("maxSize({r})"),
139
92
            Range::UnboundedR(l) => format!("minSize({l})"),
140
482
            Range::Unbounded => "".to_string(),
141
        };
142
724
        let mut strs = [
143
724
            size_str,
144
724
            self.partiality.to_string(),
145
724
            self.jectivity.to_string(),
146
724
        ]
147
724
        .iter()
148
2172
        .filter(|s| !s.is_empty())
149
724
        .join(", ");
150
724
        if !strs.is_empty() {
151
266
            strs = format!("({})", strs);
152
506
        }
153
724
        write!(f, "{strs}")
154
724
    }
155
}
156

            
157
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
158
#[path_prefix(conjure_cp::ast)]
159
pub struct SequenceAttr<A = Int> {
160
    pub size: Range<A>,
161
    pub jectivity: JectivityAttr,
162
}
163

            
164
impl<A> Default for SequenceAttr<A> {
165
120
    fn default() -> Self {
166
120
        SequenceAttr {
167
120
            size: Range::Unbounded,
168
120
            jectivity: JectivityAttr::None,
169
120
        }
170
120
    }
171
}
172

            
173
impl<A: Display> Display for SequenceAttr<A> {
174
320
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
175
320
        let size_str = match &self.size {
176
200
            Range::Single(x) => format!("size {x}"),
177
40
            Range::Bounded(l, r) => format!("minSize {l}, maxSize {r}"),
178
80
            Range::UnboundedL(r) => format!("maxSize {r}"),
179
            Range::UnboundedR(l) => format!("minSize {l}"),
180
            Range::Unbounded => "".to_string(),
181
        };
182
320
        let mut strs = [size_str, self.jectivity.to_string()]
183
320
            .iter()
184
640
            .filter(|s| !s.is_empty())
185
320
            .join(", ");
186
320
        if !strs.is_empty() {
187
320
            strs = format!("({})", strs);
188
320
        }
189
320
        write!(f, "{strs}")
190
320
    }
191
}
192

            
193
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
194
#[path_prefix(conjure_cp::ast)]
195
pub struct PartitionAttr<A = Int> {
196
    pub num_parts: Range<A>, // i.e. how many parts there are in the partition
197
    pub part_len: Range<A>,  // i.e. the size of each constitutent part
198
    pub is_regular: bool,
199
}
200

            
201
impl<A: Display> Display for PartitionAttr<A> {
202
370
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
203
370
        let num_parts_str = match &self.num_parts {
204
46
            Range::Single(x) => format!("numParts {x}"),
205
40
            Range::Bounded(l, r) => format!("minNumParts {l}, maxNumParts {r}"),
206
40
            Range::UnboundedL(r) => format!("maxNumParts {r}"),
207
2
            Range::UnboundedR(l) => format!("minNumParts {l}"),
208
242
            Range::Unbounded => "".to_string(),
209
        };
210

            
211
370
        let part_len_str = match &self.part_len {
212
46
            Range::Single(x) => format!("partSize {x}"),
213
42
            Range::Bounded(l, r) => format!("minPartSize {l} , maxPartSize {r}"),
214
2
            Range::UnboundedL(r) => format!("maxPartSize {r}"),
215
40
            Range::UnboundedR(l) => format!("minPartSize {l}"),
216
240
            Range::Unbounded => "".to_string(),
217
        };
218

            
219
370
        let regular_str = match &self.is_regular {
220
40
            true => "regular".to_string(),
221
330
            false => String::new(),
222
        };
223

            
224
370
        let mut strs = [num_parts_str, part_len_str, regular_str]
225
370
            .iter()
226
1110
            .filter(|s| !s.is_empty())
227
370
            .join(", ");
228
370
        if !strs.is_empty() {
229
130
            strs = format!("({})", strs);
230
250
        }
231
370
        write!(f, "{strs}")
232
370
    }
233
}
234

            
235
impl<A> Default for PartitionAttr<A> {
236
40
    fn default() -> Self {
237
40
        PartitionAttr {
238
40
            num_parts: Range::Unbounded,
239
40
            part_len: Range::Unbounded,
240
40
            is_regular: false,
241
40
        }
242
40
    }
243
}
244

            
245
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
246
pub enum PartialityAttr {
247
    Total,
248
    Partial,
249
}
250

            
251
impl Display for PartialityAttr {
252
724
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
253
724
        match self {
254
86
            PartialityAttr::Total => write!(f, "total"),
255
638
            PartialityAttr::Partial => write!(f, ""),
256
        }
257
724
    }
258
}
259

            
260
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
261
pub enum JectivityAttr {
262
    None,
263
    Injective,
264
    Surjective,
265
    Bijective,
266
}
267

            
268
impl Display for JectivityAttr {
269
1044
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
270
1044
        match self {
271
560
            JectivityAttr::None => write!(f, ""),
272
304
            JectivityAttr::Injective => write!(f, "injective"),
273
92
            JectivityAttr::Surjective => write!(f, "surjective"),
274
88
            JectivityAttr::Bijective => write!(f, "bijective"),
275
        }
276
1044
    }
277
}
278

            
279
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
280
#[path_prefix(conjure_cp::ast)]
281
pub struct RelAttr<A = Int> {
282
    pub size: Range<A>,
283
    pub binary: Vec<BinaryAttr>,
284
}
285

            
286
impl<A> Default for RelAttr<A> {
287
2
    fn default() -> Self {
288
2
        RelAttr {
289
2
            size: Range::Unbounded,
290
2
            binary: Vec::new(),
291
2
        }
292
2
    }
293
}
294

            
295
impl<A: Display> Display for RelAttr<A> {
296
488
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
297
488
        let size_str = match &self.size {
298
42
            Range::Single(x) => format!("size {x}"),
299
40
            Range::Bounded(l, r) => format!("minSize {l}, maxSize {r}"),
300
80
            Range::UnboundedL(r) => format!("maxSize {r}"),
301
80
            Range::UnboundedR(l) => format!("minSize {l}"),
302
246
            Range::Unbounded => "".to_string(),
303
        };
304
488
        let mut strs = [size_str, self.binary.iter().join(", ")]
305
488
            .iter()
306
976
            .filter(|s| !s.is_empty())
307
488
            .join(", ");
308
488
        if !strs.is_empty() {
309
242
            strs = format!("({})", strs);
310
246
        }
311
488
        write!(f, "{strs}")
312
488
    }
313
}
314

            
315
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
316
pub 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

            
332
impl Display for BinaryAttr {
333
520
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
334
520
        match self {
335
40
            BinaryAttr::Reflexive => write!(f, "reflexive"),
336
40
            BinaryAttr::Irreflexive => write!(f, "irreflexive"),
337
40
            BinaryAttr::Coreflexive => write!(f, "coreflexive"),
338
40
            BinaryAttr::Symmetric => write!(f, "symmetric"),
339
40
            BinaryAttr::AntiSymmetric => write!(f, "antiSymmetric"),
340
40
            BinaryAttr::ASymmetric => write!(f, "aSymmetric"),
341
40
            BinaryAttr::Transitive => write!(f, "transitive"),
342
40
            BinaryAttr::Total => write!(f, "total"),
343
40
            BinaryAttr::Connex => write!(f, "connex"),
344
40
            BinaryAttr::Euclidean => write!(f, "Euclidean"),
345
40
            BinaryAttr::Serial => write!(f, "serial"),
346
40
            BinaryAttr::Equivalence => write!(f, "equivalence"),
347
40
            BinaryAttr::PartialOrder => write!(f, "partialOrder"),
348
        }
349
520
    }
350
}