xcsp3_rust/constraints/
xcount.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::data_structs::xrelational_operand::xcsp3_core::Operand;
44 use crate::data_structs::xrelational_operator::xcsp3_core::Operator;
45 use crate::errors::xcsp3error::xcsp3_core::Xcsp3Error;
46 use crate::utils::utils_functions::xcsp3_utils::list_to_vec_var_val;
47 use crate::variables::xdomain::xcsp3_core::XDomainInteger;
48 use crate::variables::xvariable_set::xcsp3_core::XVariableSet;
49 use std::collections::HashMap;
50 use std::fmt::{Display, Formatter};
51
52 pub struct XCount<'a> {
53 scope: Vec<XVarVal>,
54 map: HashMap<String, &'a XDomainInteger>,
55 set: &'a XVariableSet,
56 operator: Operator,
57 operand: Operand,
58 values: Vec<XVarVal>,
59 }
60
61 impl Display for XCount<'_> {
62 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
63 let mut ret = String::default();
64 for e in self.scope.iter() {
65 ret.push('(');
66 ret.push_str(&e.to_string());
67 ret.push_str("), ")
68 }
69 ret.push_str("values = (");
70 for e in self.values.iter() {
71 ret.push_str(&e.to_string());
72 ret.push_str(", ")
73 }
74 ret.push_str("), ");
75 write!(
76 f,
77 "XCount: list = {}, condition = ({:?},{:?})",
78 ret, self.operator, self.operand
79 )
80 }
81 }
82
83 impl XConstraintTrait for XCount<'_> {
84 fn get_scope_string(&self) -> &Vec<XVarVal> {
85 &self.scope
86 }
87
88 fn get_scope(&mut self) -> Vec<(&String, &XDomainInteger)> {
89 for e in &self.scope {
90 if let XVarVal::IntVar(s) = e {
91 if !self.map.contains_key(s) {
92 if let Ok(vec) = self.set.construct_scope(&[s]) {
93 for (vs, vv) in vec.into_iter() {
94 self.map.insert(vs, vv);
95 }
96 }
97 }
98 }
99 }
100 let mut scope_vec_var: Vec<(&String, &XDomainInteger)> = vec![];
101 for e in self.map.iter() {
102 scope_vec_var.push((e.0, e.1))
103 }
104 scope_vec_var
105 }
106 }
107
108 impl<'a> XCount<'a> {
109 pub fn from_str(
110 list: &str,
111 condition: &str,
112 value_str: &str,
113 set: &'a XVariableSet,
114 ) -> Result<Self, Xcsp3Error> {
115 match list_to_vec_var_val(list) {
116 Ok(scope_vec_str) => {
117 let values = match list_to_vec_var_val(value_str) {
118 Ok(coe_vec) => coe_vec,
119 Err(e) => return Err(e),
120 };
121
122 let condition = condition.replace(['(', ')', ','], " ");
123 let spilt: Vec<&str> = condition.split_whitespace().collect();
124
125 let ope: Operator = match Operator::get_operator_by_str(spilt[0]) {
126 None => {
127 return Err(Xcsp3Error::get_constraint_sum_error(
128 "parse count constraint Operator error, ",
129 ));
130 }
131 Some(o) => o,
132 };
133
134 let rand: Operand = match Operand::get_operand_by_str(&spilt[1..], &ope) {
135 None => {
136 return Err(Xcsp3Error::get_constraint_sum_error(
137 "parse count constraint Operand error, ",
138 ));
139 }
140 Some(r) => r,
141 };
142 Ok(Self::new(scope_vec_str, set, ope, rand, values))
143 }
144 Err(e) => Err(e),
145 }
146 }
147
148 pub fn new(
149 scope: Vec<XVarVal>,
150 set: &'a XVariableSet,
151 operator: Operator,
152 operand: Operand,
153 values: Vec<XVarVal>,
154 ) -> Self {
155 Self {
156 scope,
157 map: Default::default(),
158 set,
159 operator,
160 operand,
161 values,
162 }
163 }
164
165 pub fn get_values(&self) -> &Vec<XVarVal> {
166 &self.values
167 }
168 pub fn get_operand(&self) -> &Operand {
169 &self.operand
170 }
171
172 pub fn get_operator(&self) -> &Operator {
173 &self.operator
174 }
175 }
176}