xcsp3_rust/constraints/
xcardinality.rs1pub 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}