1pub 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 XCumulative<'a> {
53 scope: Vec<XVarVal>,
54 map: HashMap<String, &'a XDomainInteger>,
55 set: &'a XVariableSet,
56 lengths: Vec<XVarVal>,
57 heights: Vec<XVarVal>,
58 ends: Option<Vec<XVarVal>>,
59 machines: Option<Vec<XVarVal>>,
60 operator: Operator,
62 operand: Operand,
63 star_index: Option<i32>,
64 }
65
66 impl Display for XCumulative<'_> {
67 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
68 let mut ret = String::default();
69 for e in self.scope.iter() {
70 ret.push('(');
71 ret.push_str(&e.to_string());
72 ret.push_str("), ")
73 }
74 ret.push_str(" lengths = ");
75 for e in self.lengths.iter() {
76 ret.push('(');
77 ret.push_str(&e.to_string());
78 ret.push_str("), ")
79 }
80 ret.push_str(" heights = ");
81 for e in self.heights.iter() {
82 ret.push('(');
83 ret.push_str(&e.to_string());
84 ret.push_str("), ")
85 }
86 if let Some(machines) = &self.machines {
87 ret.push_str(" machines = ");
88 for e in machines.iter() {
89 ret.push('(');
90 ret.push_str(&e.to_string());
91 ret.push_str("), ")
92 }
93 }
94 if let Some(ends) = &self.ends {
95 ret.push_str(" ends = ");
96 for e in ends.iter() {
97 ret.push('(');
98 ret.push_str(&e.to_string());
99 ret.push_str("), ")
100 }
101 }
102 if let Some(n) = &self.star_index {
103 ret.push_str(&format!(" star_index = {}", n));
104 }
105
106 write!(
107 f,
108 "XCumulative: origins = {}, condition = ({:?},{:?}),",
109 ret, self.operator, self.operand,
110 )
111 }
112 }
113
114 impl<'a> XCumulative<'a> {
115 pub fn from_str(
116 origins_str: &str,
117 lengths_str: &str,
118 heights_str: &str,
119 condition_str: &str,
120 ends_str: &str,
121 machines_str: &str,
122 start_index_str: &str,
123 set: &'a XVariableSet,
124 ) -> Result<Self, Xcsp3Error> {
125 let scope = match list_to_vec_var_val(origins_str) {
126 Ok(n) => n,
127 Err(e) => {
128 return Err(e);
129 }
130 };
131 let lengths = match list_to_vec_var_val(lengths_str) {
132 Ok(n) => n,
133 Err(e) => {
134 return Err(e);
135 }
136 };
137 let heights = match list_to_vec_var_val(heights_str) {
138 Ok(n) => n,
139 Err(e) => {
140 return Err(e);
141 }
142 };
143 let binding = condition_str.replace(['(', ')', ','], " ");
144 let spilt: Vec<&str> = binding.split_whitespace().collect();
145 let ope: Operator = match Operator::get_operator_by_str(spilt[0]) {
146 None => {
147 return Err(Xcsp3Error::get_constraint_cumulative_error(
148 "parse cumulative constraint error, ",
149 ))
150 }
151 Some(o) => o,
152 };
153 let rand: Operand = match Operand::get_operand_by_str(&spilt[1..], &ope) {
154 None => {
155 return Err(Xcsp3Error::get_constraint_cumulative_error(
156 "parse cumulative constraint error, ",
157 ))
158 }
159 Some(r) => r,
160 };
161 let ends = if ends_str.is_empty() {
162 None
163 } else {
164 match list_to_vec_var_val(ends_str) {
165 Ok(n) => Some(n),
166 Err(e) => {
167 return Err(e);
168 }
169 }
170 };
171
172 let machines = if machines_str.is_empty() {
173 None
174 } else {
175 match list_to_vec_var_val(machines_str) {
176 Ok(n) => Some(n),
177 Err(e) => {
178 return Err(e);
179 }
180 }
181 };
182 let start_index = if !start_index_str.is_empty() {
183 match start_index_str.parse::<i32>() {
184 Ok(n) => Some(n),
185 Err(_) => {
186 return Err(Xcsp3Error::get_constraint_cumulative_error(
187 "parse cumulative constraint start_index error, ",
188 ));
189 }
190 }
191 } else {
192 None
193 };
194
195 Ok(Self::new(
196 scope,
197 set,
198 lengths,
199 heights,
200 ends,
201 machines,
202 ope,
203 rand,
204 start_index,
205 ))
206 }
207
208 pub fn new(
209 scope: Vec<XVarVal>,
210 set: &'a XVariableSet,
211 lengths: Vec<XVarVal>,
212 heights: Vec<XVarVal>,
213 ends: Option<Vec<XVarVal>>,
214 machines: Option<Vec<XVarVal>>,
215 operator: Operator,
216 operand: Operand,
217 star_index: Option<i32>,
218 ) -> Self {
219 Self {
220 scope,
221 map: Default::default(),
222 set,
223 lengths,
224 heights,
225 ends,
226 machines,
227 operator,
228 operand,
229 star_index,
230 }
231 }
232
233 pub fn lengths(&self) -> &Vec<XVarVal> {
234 &self.lengths
235 }
236 pub fn heights(&self) -> &Vec<XVarVal> {
237 &self.heights
238 }
239 pub fn machines(&self) -> &Option<Vec<XVarVal>> {
240 &self.machines
241 }
242 pub fn ends(&self) -> &Option<Vec<XVarVal>> {
243 &self.ends
244 }
245 pub fn operator(&self) -> &Operator {
246 &self.operator
247 }
248 pub fn operand(&self) -> &Operand {
249 &self.operand
250 }
251 pub fn star_index(&self) -> Option<i32> {
252 self.star_index
253 }
254 }
255 impl XConstraintTrait for XCumulative<'_> {
256 fn get_scope_string(&self) -> &Vec<XVarVal> {
257 &self.scope
258 }
259
260 fn get_scope(&mut self) -> Vec<(&String, &XDomainInteger)> {
261 for e in &self.scope {
262 if let XVarVal::IntVar(s) = e {
263 if !self.map.contains_key(s) {
264 if let Ok(vec) = self.set.construct_scope(&[s]) {
265 for (vs, vv) in vec.into_iter() {
266 self.map.insert(vs, vv);
267 }
268 }
269 }
270 }
271 }
272 let mut scope_vec_var: Vec<(&String, &XDomainInteger)> = vec![];
273 for e in self.map.iter() {
274 scope_vec_var.push((e.0, e.1))
275 }
276 scope_vec_var
277 }
278 }
279}