Skip to main content

conjure_cp_core/ast/domains/
attrs.rs

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        // 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        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)]
158pub enum PartialityAttr {
159    Total,
160    Partial,
161}
162
163impl Display for PartialityAttr {
164    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
165        match self {
166            PartialityAttr::Total => write!(f, "total"),
167            PartialityAttr::Partial => write!(f, ""),
168        }
169    }
170}
171
172#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
173pub enum JectivityAttr {
174    None,
175    Injective,
176    Surjective,
177    Bijective,
178}
179
180impl Display for JectivityAttr {
181    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
182        match self {
183            JectivityAttr::None => write!(f, ""),
184            JectivityAttr::Injective => write!(f, "injective"),
185            JectivityAttr::Surjective => write!(f, "surjective"),
186            JectivityAttr::Bijective => write!(f, "bijective"),
187        }
188    }
189}