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

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

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

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

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

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

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

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

            
45
impl<A: Display> Display for SetAttr<A> {
46
29820
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
47
29820
        match self.size {
48
11556
            Range::Unbounded => Ok(()),
49
18264
            _ => write!(f, "({})", fmt_size("size", &self.size)),
50
        }
51
29820
    }
52
}
53

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

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

            
83
impl<A: Display> Display for MSetAttr<A> {
84
484
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
85
484
        let size_str = fmt_size("size", &self.size);
86

            
87
        // It only makes sense in terms of min and max occurrence for the essence language,
88
        // so for single ranges it is still presented as min and max occurrence.
89
484
        let occ_str = match &self.occurrence {
90
            Range::Single(x) => format!("minOccur({x}), maxOccur({x})"),
91
80
            Range::Bounded(l, r) => format!("minOccur({l}), maxOccur({r})"),
92
204
            Range::UnboundedL(r) => format!("maxOccur({r})"),
93
40
            Range::UnboundedR(l) => format!("minOccur({l})"),
94
160
            Range::Unbounded => "".to_string(),
95
        };
96

            
97
484
        let mut strs = [size_str, occ_str]
98
484
            .iter()
99
968
            .filter(|s| !s.is_empty())
100
484
            .join(", ");
101
484
        if !strs.is_empty() {
102
444
            strs = format!("({})", strs);
103
444
        }
104
484
        write!(f, "{strs}")
105
484
    }
106
}
107

            
108
impl<A> Default for MSetAttr<A> {
109
40
    fn default() -> Self {
110
40
        MSetAttr {
111
40
            size: Range::Unbounded,
112
40
            occurrence: Range::Unbounded,
113
40
        }
114
40
    }
115
}
116

            
117
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, FuncMap, TryFuncMap, Quine)]
118
#[path_prefix(conjure_cp::ast)]
119
pub struct FuncAttr<A = Int> {
120
    pub size: Range<A>,
121
    pub partiality: PartialityAttr,
122
    pub jectivity: JectivityAttr,
123
}
124

            
125
impl<A: Display> Display for FuncAttr<A> {
126
808
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
127
808
        let size_str = fmt_size("size", &self.size);
128
808
        let mut strs = [
129
808
            size_str,
130
808
            self.partiality.to_string(),
131
808
            self.jectivity.to_string(),
132
808
        ]
133
808
        .iter()
134
2424
        .filter(|s| !s.is_empty())
135
808
        .join(", ");
136
808
        if !strs.is_empty() {
137
332
            strs = format!("({})", strs);
138
572
        }
139
808
        write!(f, "{strs}")
140
808
    }
141
}
142

            
143
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, FuncMap, TryFuncMap, Quine)]
144
#[path_prefix(conjure_cp::ast)]
145
pub struct SequenceAttr<A = Int> {
146
    pub size: Range<A>,
147
    pub jectivity: JectivityAttr,
148
}
149

            
150
impl<A> Default for SequenceAttr<A> {
151
120
    fn default() -> Self {
152
120
        SequenceAttr {
153
120
            size: Range::Unbounded,
154
120
            jectivity: JectivityAttr::None,
155
120
        }
156
120
    }
157
}
158

            
159
impl<A: Display> Display for SequenceAttr<A> {
160
320
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
161
320
        let size_str = fmt_size("size", &self.size);
162
320
        let mut strs = [size_str, self.jectivity.to_string()]
163
320
            .iter()
164
640
            .filter(|s| !s.is_empty())
165
320
            .join(", ");
166
320
        if !strs.is_empty() {
167
320
            strs = format!("({})", strs);
168
320
        }
169
320
        write!(f, "{strs}")
170
320
    }
171
}
172

            
173
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, FuncMap, TryFuncMap, Quine)]
174
#[path_prefix(conjure_cp::ast)]
175
pub struct PartitionAttr<A = Int> {
176
    pub num_parts: Range<A>, // i.e. how many parts there are in the partition
177
    pub part_len: Range<A>,  // i.e. the size of each constitutent part
178
    pub is_regular: bool,
179
}
180

            
181
impl<A: Display> Display for PartitionAttr<A> {
182
380
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
183
380
        let num_parts_str = fmt_size("numParts", &self.num_parts);
184
380
        let part_len_str = fmt_size("partSize", &self.part_len);
185

            
186
380
        let regular_str = match &self.is_regular {
187
40
            true => "regular".to_string(),
188
340
            false => String::new(),
189
        };
190

            
191
380
        let mut strs = [num_parts_str, part_len_str, regular_str]
192
380
            .iter()
193
1140
            .filter(|s| !s.is_empty())
194
380
            .join(", ");
195
380
        if !strs.is_empty() {
196
140
            strs = format!("({})", strs);
197
260
        }
198
380
        write!(f, "{strs}")
199
380
    }
200
}
201

            
202
impl<A> Default for PartitionAttr<A> {
203
40
    fn default() -> Self {
204
40
        PartitionAttr {
205
40
            num_parts: Range::Unbounded,
206
40
            part_len: Range::Unbounded,
207
40
            is_regular: false,
208
40
        }
209
40
    }
210
}
211

            
212
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
213
pub enum PartialityAttr {
214
    Total,
215
    Partial,
216
}
217

            
218
impl Display for PartialityAttr {
219
808
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
220
808
        match self {
221
92
            PartialityAttr::Total => write!(f, "total"),
222
716
            PartialityAttr::Partial => write!(f, ""),
223
        }
224
808
    }
225
}
226

            
227
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
228
pub enum JectivityAttr {
229
    None,
230
    Injective,
231
    Surjective,
232
    Bijective,
233
}
234

            
235
impl Display for JectivityAttr {
236
1128
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
237
1128
        match self {
238
600
            JectivityAttr::None => write!(f, ""),
239
328
            JectivityAttr::Injective => write!(f, "injective"),
240
104
            JectivityAttr::Surjective => write!(f, "surjective"),
241
96
            JectivityAttr::Bijective => write!(f, "bijective"),
242
        }
243
1128
    }
244
}
245

            
246
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, FuncMap, TryFuncMap, Quine)]
247
#[path_prefix(conjure_cp::ast)]
248
pub struct RelAttr<A = Int> {
249
    pub size: Range<A>,
250
    pub binary: Vec<BinaryAttr>,
251
}
252

            
253
impl<A> Default for RelAttr<A> {
254
4
    fn default() -> Self {
255
4
        RelAttr {
256
4
            size: Range::Unbounded,
257
4
            binary: Vec::new(),
258
4
        }
259
4
    }
260
}
261

            
262
impl<A: Display> Display for RelAttr<A> {
263
496
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
264
496
        let size_str = fmt_size("size", &self.size);
265
496
        let mut strs = [size_str, self.binary.iter().join(", ")]
266
496
            .iter()
267
992
            .filter(|s| !s.is_empty())
268
496
            .join(", ");
269
496
        if !strs.is_empty() {
270
244
            strs = format!("({})", strs);
271
252
        }
272
496
        write!(f, "{strs}")
273
496
    }
274
}
275

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

            
293
impl Display for BinaryAttr {
294
520
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
295
520
        match self {
296
40
            BinaryAttr::Reflexive => write!(f, "reflexive"),
297
40
            BinaryAttr::Irreflexive => write!(f, "irreflexive"),
298
40
            BinaryAttr::Coreflexive => write!(f, "coreflexive"),
299
40
            BinaryAttr::Symmetric => write!(f, "symmetric"),
300
40
            BinaryAttr::AntiSymmetric => write!(f, "antiSymmetric"),
301
40
            BinaryAttr::ASymmetric => write!(f, "aSymmetric"),
302
40
            BinaryAttr::Transitive => write!(f, "transitive"),
303
40
            BinaryAttr::Total => write!(f, "total"),
304
40
            BinaryAttr::Connex => write!(f, "connex"),
305
40
            BinaryAttr::Euclidean => write!(f, "Euclidean"),
306
40
            BinaryAttr::Serial => write!(f, "serial"),
307
40
            BinaryAttr::Equivalence => write!(f, "equivalence"),
308
40
            BinaryAttr::PartialOrder => write!(f, "partialOrder"),
309
        }
310
520
    }
311
}
312

            
313
/// Format a range as Essence size attribute
314
#[inline]
315
21132
fn fmt_size<A: Display>(suffix: &str, sz: &Range<A>) -> String {
316
21132
    let cap_suffix = capitalize(suffix);
317
21132
    match sz {
318
544
        Range::Single(x) => format!("{suffix}({x})"),
319
408
        Range::Bounded(l, r) => format!("min{cap_suffix}({l}), max{cap_suffix}({r})"),
320
328
        Range::UnboundedL(r) => format!("max{cap_suffix}({r})"),
321
18312
        Range::UnboundedR(l) => format!("min{cap_suffix}({l})"),
322
1540
        Range::Unbounded => "".to_string(),
323
    }
324
21132
}
325

            
326
#[inline]
327
21132
fn capitalize(s: &str) -> String {
328
21132
    let mut c = s.chars();
329
21132
    match c.next() {
330
        None => String::new(),
331
21132
        Some(f) => f.to_uppercase().to_string() + c.as_str(),
332
    }
333
21132
}