xcsp3_rust/constraints/
xcumulative.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/31 12:42
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::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        // condition
61        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}