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 FuncAttr<A = Int> {
59    pub size: Range<A>,
60    pub partiality: PartialityAttr,
61    pub jectivity: JectivityAttr,
62}
63
64impl<A: Display> Display for FuncAttr<A> {
65    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
66        let size_str = match &self.size {
67            Range::Single(x) => format!("size({x})"),
68            Range::Bounded(l, r) => format!("minSize({l}), maxSize({r})"),
69            Range::UnboundedL(r) => format!("maxSize({r})"),
70            Range::UnboundedR(l) => format!("minSize({l})"),
71            Range::Unbounded => "".to_string(),
72        };
73        let mut strs = [
74            size_str,
75            self.partiality.to_string(),
76            self.jectivity.to_string(),
77        ]
78        .iter()
79        .filter(|s| !s.is_empty())
80        .join(", ");
81        if !strs.is_empty() {
82            strs = format!("({})", strs);
83        }
84        write!(f, "{strs}")
85    }
86}
87
88#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
89pub enum PartialityAttr {
90    Total,
91    Partial,
92}
93
94impl Display for PartialityAttr {
95    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
96        match self {
97            PartialityAttr::Total => write!(f, "total"),
98            PartialityAttr::Partial => write!(f, ""),
99        }
100    }
101}
102
103#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
104pub enum JectivityAttr {
105    None,
106    Injective,
107    Surjective,
108    Bijective,
109}
110
111impl Display for JectivityAttr {
112    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
113        match self {
114            JectivityAttr::None => write!(f, ""),
115            JectivityAttr::Injective => write!(f, "injective"),
116            JectivityAttr::Surjective => write!(f, "surjective"),
117            JectivityAttr::Bijective => write!(f, "bijective"),
118        }
119    }
120}