xcsp3_rust/constraints/
xconstraint_set.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: luhanzhen
30 * </p>
31 * <p>@date: 2023/7/7
32 * </p>
33 * <p>@time: 18:35
34 * </p>
35 * <p>@this_file_name:xcsp3constraint
36 * </p>
37 */
38
39pub mod xcsp3_core {
40    use crate::constraints::xall_different::xcsp3_core::XAllDifferent;
41    use crate::constraints::xall_different_except::xcsp3_core::XAllDifferentExcept;
42    use crate::constraints::xall_equal::xcsp3_core::XAllEqual;
43    use crate::constraints::xconstraint_type::xcsp3_core::XConstraintType;
44    use crate::constraints::xelement::xcsp3_core::XElement;
45    use crate::constraints::xextension::xcsp3_core::XExtension;
46    use crate::constraints::xgroup::xcsp3_core::XGroup;
47    use crate::constraints::xinstantiation::xcsp3_core::XInstantiation;
48
49    use crate::constraints::xcardinality::xcsp3_core::XCardinality;
50    use crate::constraints::xchannel::xcsp3_core::XChannel;
51    use crate::constraints::xcount::xcsp3_core::XCount;
52    use crate::constraints::xcumulative::xcsp3_core::XCumulative;
53    use crate::constraints::xintension::xcsp3_core::XIntention;
54    use crate::constraints::xmax_min::xcsp3_core::XMaxMin;
55    use crate::constraints::xmdd::xcsp3_core::XMdd;
56    use crate::constraints::xn_values::xcsp3_core::XNValues;
57    use crate::constraints::xno_overlap::xcsp3_core::XNoOverlap;
58    use crate::constraints::xno_overlap_k_dimensional::xcsp3_core::XNoOverlapKDim;
59    use crate::constraints::xordered::xcsp3_core::XOrdered;
60    use crate::constraints::xregular::xcsp3_core::XRegular;
61    use crate::constraints::xslide::xcsp3_core::XSlide;
62    use crate::constraints::xstretch::xcsp3_core::XStretch;
63    use crate::constraints::xsum::xcsp3_core::XSum;
64    use crate::data_structs::xint_val_var::xcsp3_core::XVarVal;
65    use crate::utils::utils_functions::xcsp3_utils::list_to_matrix_ids;
66    use crate::variables::xvariable_set::xcsp3_core::XVariableSet;
67    use std::slice::{Iter, IterMut};
68
69    /**
70    the XConstraintSet is a container that stores all constraints.
71     */
72    pub struct XConstraintSet<'a> {
73        constraints: Vec<XConstraintType<'a>>,
74        set: &'a XVariableSet,
75    }
76
77    impl<'a> XConstraintSet<'a> {
78        pub fn new(set: &'a XVariableSet) -> XConstraintSet<'a> {
79            XConstraintSet {
80                constraints: vec![],
81                set,
82            }
83        }
84
85        pub fn build_no_overlap_k_dim(
86            &mut self,
87            list: &str,
88            lengths_str: &str,
89            zero_ignored_str: &str,
90        ) {
91            match XNoOverlapKDim::from_str(list, lengths_str, zero_ignored_str, self.set) {
92                Ok(c) => {
93                    self.constraints.push(XConstraintType::XNoOverlapKDim(c));
94                }
95                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
96            }
97        }
98
99        pub fn build_no_overlap(&mut self, list: &str, lengths_str: &str, zero_ignored_str: &str) {
100            match XNoOverlap::from_str(list, lengths_str, zero_ignored_str, self.set) {
101                Ok(c) => {
102                    self.constraints.push(XConstraintType::XNoOverlap(c));
103                }
104                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
105            }
106        }
107
108        pub fn build_cumulative(
109            &mut self,
110            origins_str: &str,
111            lengths_str: &str,
112            heights_str: &str,
113            condition_str: &str,
114            ends_str: &str,
115            machines_str: &str,
116            start_index_str: &str,
117        ) {
118            match XCumulative::from_str(
119                origins_str,
120                lengths_str,
121                heights_str,
122                condition_str,
123                ends_str,
124                machines_str,
125                start_index_str,
126                self.set,
127            ) {
128                Ok(c) => {
129                    self.constraints.push(XConstraintType::XCumulative(c));
130                }
131                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
132            }
133        }
134        pub fn build_channel(&mut self, list: &str, start_index_str: &str, value_str: &str) {
135            match XChannel::from_str(list, start_index_str, value_str, self.set) {
136                Ok(c) => {
137                    self.constraints.push(XConstraintType::XChannel(c));
138                }
139                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
140            }
141        }
142        pub fn build_cardinality(
143            &mut self,
144            list: &str,
145            values_str: &str,
146            occurs_str: &str,
147            closed_str: &str,
148        ) {
149            match XCardinality::from_str(list, values_str, occurs_str, closed_str, self.set) {
150                Ok(c) => {
151                    self.constraints.push(XConstraintType::XCardinality(c));
152                }
153                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
154            }
155        }
156
157        pub fn build_stretch(
158            &mut self,
159            list: &str,
160            value_str: &str,
161            widths_str: &str,
162            patterns_str: &str,
163        ) {
164            match XStretch::from_str(list, value_str, widths_str, patterns_str, self.set) {
165                Ok(c) => {
166                    self.constraints.push(XConstraintType::XStretch(c));
167                }
168                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
169            }
170        }
171        pub fn build_element(
172            &mut self,
173            vars: &str,
174            values_str: &str,
175            index_str: &str,
176            start_index_str: &str,
177        ) {
178            match XElement::from_str(vars, values_str, index_str, start_index_str, self.set) {
179                Ok(c) => {
180                    self.constraints.push(XConstraintType::XElement(c));
181                }
182                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
183            }
184        }
185        pub fn build_slide(
186            &mut self,
187            cc: XConstraintType<'a>,
188            vars: &str,
189            offset_str: &str,
190            circular_str: &str,
191        ) {
192            // println!("tttt: {}", cc.to_string())
193            match XSlide::from_str(cc, vars, offset_str, circular_str, self.set) {
194                Ok(c) => {
195                    self.constraints.push(XConstraintType::XSlide(c));
196                }
197                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
198            }
199        }
200        pub fn build_group(&mut self, cc: XConstraintType<'a>, args: &[String]) {
201            // if let XConstraintType::XGroup(_) = &cc {
202            //     // println!("group is in {}",c.to_string());
203            //     self.constraints.push(XConstraintType::XConstraintNone(
204            //         Xcsp3Error::get_constraint_group_error("the group is in group"),
205            //     ))
206            // }
207            match XGroup::from_str(cc, args, self.set) {
208                Ok(c) => {
209                    self.constraints.push(XConstraintType::XGroup(c));
210                }
211                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
212            }
213        }
214
215        /// this function is designed for XGroup, parse the template for XGroup
216        pub fn get_last_constraint(&mut self) -> Option<XConstraintType<'a>> {
217            self.constraints.pop()
218        }
219
220        pub fn iter(&self) -> Iter<'_, XConstraintType> {
221            self.constraints.iter()
222        }
223
224        pub fn iter_mut(&mut self) -> IterMut<'_, XConstraintType<'a>> {
225            self.constraints.iter_mut()
226        }
227
228        pub fn build_minimum(&mut self, vars: &str, condition: &str) {
229            match XMaxMin::from_str(vars, condition, true, self.set) {
230                Ok(c) => {
231                    self.constraints.push(XConstraintType::XMinimum(c));
232                }
233                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
234            }
235        }
236        pub fn build_maximum(&mut self, vars: &str, condition: &str) {
237            match XMaxMin::from_str(vars, condition, false, self.set) {
238                Ok(c) => {
239                    self.constraints.push(XConstraintType::XMaximum(c));
240                }
241                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
242            }
243        }
244
245        pub fn build_count(&mut self, vars: &str, condition: &str, coeffs: &str) {
246            match XCount::from_str(vars, condition, coeffs, self.set) {
247                Ok(c) => {
248                    self.constraints.push(XConstraintType::XCount(c));
249                }
250                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
251            }
252        }
253
254        pub fn build_n_values(&mut self, vars: &str, condition: &str, coeffs: &str) {
255            match XNValues::from_str(vars, condition, coeffs, self.set) {
256                Ok(c) => {
257                    self.constraints.push(XConstraintType::XNValues(c));
258                }
259                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
260            }
261        }
262
263        pub fn build_sum(&mut self, vars: &str, condition: &str, coeffs: &str) {
264            match XSum::from_str(vars, condition, coeffs, self.set) {
265                Ok(c) => {
266                    self.constraints.push(XConstraintType::XSum(c));
267                }
268                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
269            }
270        }
271
272        pub fn build_intention(&mut self, function: &str) {
273            match XIntention::from_str_without_scope(function, self.set) {
274                Ok(c) => {
275                    self.constraints.push(XConstraintType::XIntention(c));
276                }
277                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
278            }
279        }
280
281        pub fn build_regular(
282            &mut self,
283            list: &str,
284            transitions_str: &str,
285            start_str: &str,
286            final_str: &str,
287        ) {
288            match XRegular::from_str(list, transitions_str, start_str, final_str, self.set) {
289                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
290                Ok(c) => {
291                    self.constraints.push(XConstraintType::XRegular(c));
292                }
293            }
294        }
295
296        pub fn build_mdd(&mut self, list: &str, transitions_str: &str) {
297            match XMdd::from_str(list, transitions_str, self.set) {
298                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
299                Ok(c) => {
300                    self.constraints.push(XConstraintType::XMdd(c));
301                }
302            }
303        }
304
305        pub fn build_ordered(&mut self, list: &str, lengths_str: &str, operator: &str) {
306            if lengths_str.is_empty() {
307                match XOrdered::from_str_without_lengths(list, operator, self.set) {
308                    Ok(c) => {
309                        self.constraints.push(XConstraintType::XOrdered(c));
310                    }
311                    Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
312                }
313            } else {
314                match XOrdered::from_str(list, lengths_str, operator, self.set) {
315                    Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
316                    Ok(c) => {
317                        self.constraints.push(XConstraintType::XOrdered(c));
318                    }
319                }
320            }
321        }
322
323        pub fn build_instantiation(&mut self, list: &str, values: &str) {
324            match XInstantiation::from_str(list, values, self.set) {
325                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
326                Ok(c) => {
327                    self.constraints.push(XConstraintType::XInstantiation(c));
328                }
329            }
330        }
331
332        pub fn build_extension(&mut self, list: &str, tuple: &str, is_support: bool) {
333            match XExtension::from_str(list, tuple, is_support, self.set) {
334                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
335                Ok(c) => {
336                    self.constraints.push(XConstraintType::XExtension(c));
337                }
338            }
339        }
340
341        pub fn build_all_equal(&mut self, list: &str) {
342            match XAllEqual::from_str(list, self.set) {
343                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
344                Ok(c) => {
345                    self.constraints.push(XConstraintType::XAllEqual(c));
346                }
347            }
348        }
349
350        pub fn build_all_different(&mut self, list: &str) {
351            match XAllDifferent::from_str(list, self.set) {
352                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
353                Ok(c) => {
354                    self.constraints.push(XConstraintType::XAllDifferent(c));
355                }
356            }
357        }
358
359        pub fn build_all_different_except(&mut self, list: &str, except: &str) {
360            match XAllDifferentExcept::from_str(list, except, self.set) {
361                Err(e) => self.constraints.push(XConstraintType::XConstraintNone(e)),
362                Ok(c) => {
363                    self.constraints
364                        .push(XConstraintType::XAllDifferentExcept(c));
365                }
366            }
367        }
368        pub fn build_all_different_matrix(&mut self, list: &str) {
369            let mat = list_to_matrix_ids(list);
370            for line in mat.iter() {
371                let mut scope: Vec<XVarVal> = vec![];
372                for e in line {
373                    scope.push(XVarVal::IntVar(e.clone()))
374                }
375                self.constraints
376                    .push(XConstraintType::XAllDifferent(XAllDifferent::from_str_vec(
377                        scope, self.set,
378                    )))
379            }
380            for i in 0..mat[0].len() {
381                let mut scope: Vec<XVarVal> = vec![];
382                for m in mat.iter() {
383                    scope.push(XVarVal::IntVar(m[i].clone()))
384                }
385                self.constraints
386                    .push(XConstraintType::XAllDifferent(XAllDifferent::from_str_vec(
387                        scope, self.set,
388                    )))
389            }
390        }
391    }
392}