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
6
    pub fn new(size: Range<A>) -> Self {
16
6
        Self { size }
17
6
    }
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
1
    pub fn new_min_size(min: A) -> Self {
24
1
        Self::new(Range::UnboundedR(min))
25
1
    }
26

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

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

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

            
44
impl<A: Display> Display for SetAttr<A> {
45
320
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
46
320
        match &self.size {
47
40
            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
200
            Range::UnboundedR(l) => write!(f, "(minSize({l}))"),
51
80
            Range::Unbounded => write!(f, ""),
52
        }
53
320
    }
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
360
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
87
360
        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
80
            Range::UnboundedR(l) => format!("minSize {l}"),
92
160
            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
360
        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
80
            Range::UnboundedL(r) => format!("maxOccur {r}"),
101
40
            Range::UnboundedR(l) => format!("minOccur {l}"),
102
160
            Range::Unbounded => "".to_string(),
103
        };
104

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

            
116
impl<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)]
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
520
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
135
520
        let size_str = match &self.size {
136
40
            Range::Single(x) => format!("size({x})"),
137
40
            Range::Bounded(l, r) => format!("minSize({l}), maxSize({r})"),
138
40
            Range::UnboundedL(r) => format!("maxSize({r})"),
139
80
            Range::UnboundedR(l) => format!("minSize({l})"),
140
320
            Range::Unbounded => "".to_string(),
141
        };
142
520
        let mut strs = [
143
520
            size_str,
144
520
            self.partiality.to_string(),
145
520
            self.jectivity.to_string(),
146
520
        ]
147
520
        .iter()
148
1560
        .filter(|s| !s.is_empty())
149
520
        .join(", ");
150
520
        if !strs.is_empty() {
151
200
            strs = format!("({})", strs);
152
320
        }
153
520
        write!(f, "{strs}")
154
520
    }
155
}
156

            
157
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
158
pub enum PartialityAttr {
159
    Total,
160
    Partial,
161
}
162

            
163
impl Display for PartialityAttr {
164
520
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
165
520
        match self {
166
80
            PartialityAttr::Total => write!(f, "total"),
167
440
            PartialityAttr::Partial => write!(f, ""),
168
        }
169
520
    }
170
}
171

            
172
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
173
pub enum JectivityAttr {
174
    None,
175
    Injective,
176
    Surjective,
177
    Bijective,
178
}
179

            
180
impl Display for JectivityAttr {
181
520
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
182
520
        match self {
183
360
            JectivityAttr::None => write!(f, ""),
184
80
            JectivityAttr::Injective => write!(f, "injective"),
185
40
            JectivityAttr::Surjective => write!(f, "surjective"),
186
40
            JectivityAttr::Bijective => write!(f, "bijective"),
187
        }
188
520
    }
189
}