xcsp3_rust/constraints/
xcardinality.rs

1/*=============================================================================
2* parser for CSP instances represented in XCSP3 Format
3*
4* Copyright (c) 2023 xcsp.org (contact @ xcsp.org)
5*
6* Permission is hereby granted, free of charge, to any person obtaining a copy
7* of this software and associated documentation files (the "Software"), to deal
8* in the Software without restriction, including without limitation the rights
9* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10* copies of the Software, and to permit persons to whom the Software is
11* furnished to do so, subject to the following conditions:
12*
13* The above copyright notice and this permission notice shall be included in
14* all copies or substantial portions of the Software.
15*
16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22* THE SOFTWARE.
23*=============================================================================
24*/
25
26/*
27 * <p>@project_name: xcsp3-rust
28 * </p>
29 * <p>@author: luhan zhen
30 * </p>
31 * <p>@date:  2023/7/29 16:48
32 * </p>
33 * <p>@email: zhenlh20@mails.jlu.edu.cn
34 * </p>
35 * <p>@version: 1.0
36 * </p>
37 * <p>@description:
38 * </p>
39 */
40pub mod xcsp3_core {
41    use crate::constraints::xconstraint_trait::xcsp3_core::XConstraintTrait;
42    use crate::data_structs::xint_val_var::xcsp3_core::XVarVal;
43    use crate::errors::xcsp3error::xcsp3_core::Xcsp3Error;
44    use crate::utils::utils_functions::xcsp3_utils::list_to_vec_var_val;
45    use crate::variables::xdomain::xcsp3_core::XDomainInteger;
46    use crate::variables::xvariable_set::xcsp3_core::XVariableSet;
47    use std::collections::HashMap;
48    use std::fmt::{Display, Formatter};
49
50    pub struct XCardinality<'a> {
51        scope: Vec<XVarVal>,
52        values: Vec<XVarVal>,
53        occurs: Vec<XVarVal>,
54        map: HashMap<String, &'a XDomainInteger>,
55        set: &'a XVariableSet,
56        closed: Option<bool>,
57    }
58    impl Display for XCardinality<'_> {
59        fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
60            let mut ret = String::default();
61            for e in self.scope.iter() {
62                ret.push('(');
63                ret.push_str(&e.to_string());
64                ret.push_str("), ")
65            }
66            ret.push_str("  values = ");
67            for e in self.values.iter() {
68                ret.push('(');
69                ret.push_str(&e.to_string());
70                ret.push_str("), ")
71            }
72            if let Some(c) = self.closed {
73                ret.push_str(&format!("  closed = {}", c));
74            }
75            ret.push_str("  occurs = ");
76            for e in self.occurs.iter() {
77                ret.push('(');
78                ret.push_str(&e.to_string());
79                ret.push_str("), ")
80            }
81
82            write!(f, "XCardinality: list =  {},  ", ret,)
83        }
84    }
85
86    impl<'a> XCardinality<'a> {
87        pub fn from_str(
88            list: &str,
89            values_str: &str,
90            occurs_str: &str,
91            closed_str: &str,
92            set: &'a XVariableSet,
93        ) -> Result<Self, Xcsp3Error> {
94            let scope = match list_to_vec_var_val(list) {
95                Ok(s) => s,
96                Err(e) => return Err(e),
97            };
98            let value = match list_to_vec_var_val(values_str) {
99                Ok(s) => s,
100                Err(e) => return Err(e),
101            };
102            let occurs = match list_to_vec_var_val(occurs_str) {
103                Ok(s) => s,
104                Err(e) => return Err(e),
105            };
106            let closed = if !closed_str.is_empty() {
107                match closed_str.parse::<bool>() {
108                    Ok(n) => Some(n),
109                    Err(_) => {
110                        return Err(Xcsp3Error::get_constraint_cardinality_error(
111                            "parse cardinality  constraint closed error, ",
112                        ));
113                    }
114                }
115            } else {
116                None
117            };
118            Ok(Self::new(scope, value, occurs, set, closed))
119        }
120
121        pub fn new(
122            scope: Vec<XVarVal>,
123            values: Vec<XVarVal>,
124            occurs: Vec<XVarVal>,
125            set: &'a XVariableSet,
126            closed: Option<bool>,
127        ) -> Self {
128            Self {
129                scope,
130                values,
131                occurs,
132                map: Default::default(),
133                set,
134                closed,
135            }
136        }
137
138        pub fn get_occurs(&self) -> &Vec<XVarVal> {
139            &self.occurs
140        }
141
142        pub fn get_closed(&self) -> &Option<bool> {
143            &self.closed
144        }
145
146        pub fn get_values(&self) -> &Vec<XVarVal> {
147            &self.values
148        }
149    }
150
151    impl XConstraintTrait for XCardinality<'_> {
152        fn get_scope_string(&self) -> &Vec<XVarVal> {
153            &self.scope
154        }
155
156        fn get_scope(&mut self) -> Vec<(&String, &XDomainInteger)> {
157            for e in &self.scope {
158                if let XVarVal::IntVar(s) = e {
159                    if !self.map.contains_key(s) {
160                        if let Ok(vec) = self.set.construct_scope(&[s]) {
161                            for (vs, vv) in vec.into_iter() {
162                                self.map.insert(vs, vv);
163                            }
164                        }
165                    }
166                }
167            }
168            let mut scope_vec_var: Vec<(&String, &XDomainInteger)> = vec![];
169            for e in self.map.iter() {
170                scope_vec_var.push((e.0, e.1))
171            }
172            scope_vec_var
173        }
174    }
175}