xcsp3_rust/utils/utils_functions.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/6/30
32 * </p>
33 * <p>@time: 13:55
34 * </p>
35 * <p>@this_file_name:xcsp3domain
36 * </p>
37 */
38
39pub mod xcsp3_utils {
40 use crate::data_structs::xint_val_var::xcsp3_core::XVarVal;
41 use crate::errors::xcsp3error::xcsp3_core::Xcsp3Error;
42 // use std::str::FromStr;
43
44 pub fn list_to_vec_var_val(list: &str) -> Result<Vec<XVarVal>, Xcsp3Error> {
45 let mut ret: Vec<XVarVal> = vec![];
46 let lists: Vec<&str> = list.split_whitespace().collect();
47 for e in lists.iter() {
48 match XVarVal::from_string(e) {
49 None => {
50 return Err(Xcsp3Error::get_constraint_list_of_values_error(
51 "parse the list of values error. ",
52 ))
53 }
54 Some(vv) => {
55 ret.push(vv);
56 }
57 }
58 }
59 Ok(ret)
60 }
61
62 // pub fn list_to_vec_var(list: &str) -> Vec<XVarVal> {
63 // let mut ret: Vec<XVarVal> = vec![];
64 // let lists: Vec<&str> = list.split_whitespace().collect();
65 // for e in lists.into_iter() {
66 // ret.push(XVarVal::IntVar(e.to_owned()));
67 //
68 // }
69 // ret
70 // }
71
72 pub fn size_to_string(id: &str, size: &[usize]) -> String {
73 let mut ret = id.to_string();
74
75 for e in size.iter() {
76 ret.push_str(&format!("[{}]", e))
77 }
78 ret
79 }
80
81 ///([2,3,4],[2,4,8]) -> [[2,3,4],[2,3,5],[2,3,6],[2,3,7],[2,3,8],[2,4,4],[2,4,5],[2,4,6],[2,4,7],[2,4,8]]
82 pub fn get_all_variables_between_lower_and_upper(
83 lower: Vec<usize>,
84 upper: Vec<usize>,
85 ) -> Vec<Vec<usize>> {
86 let mut ret: Vec<Vec<usize>> = vec![];
87 let mut tmp: Vec<Vec<usize>> = vec![];
88 // println!("{:?},{:?}", lower, upper);
89
90 // recursion_for_get_all_variables(0,&lower,&upper,&ret);
91 for i in lower[0]..upper[0] + 1 {
92 tmp.push(vec![i]);
93 }
94 for deep in 1..lower.len() {
95 for i in lower[deep]..upper[deep] + 1 {
96 for e in tmp.iter() {
97 let mut ee = e.clone();
98 ee.push(i);
99 ret.push(ee)
100 }
101 }
102 tmp = ret.clone();
103 ret.clear();
104 }
105 // println!("ret = {:?}\n", ret);
106 // println!("tmp = {:?}\n", tmp);
107 tmp
108 }
109
110 /// return the nth of the [] in id(str)
111 /// eg x[2][5][] -> 2, y[] -> 0, z[3][] ->1, zzz[4][][4] ->1
112 pub fn get_nth_square_of_name(id: &str) -> usize {
113 match id.find("[]") {
114 None => 0,
115 Some(v) => {
116 let mut cnt: usize = 0;
117 for (_, c) in id[..v].chars().enumerate() {
118 if c == '[' {
119 cnt += 1
120 }
121 }
122 cnt
123 }
124 }
125 }
126
127 /// return the list of scopes,
128 /// eg str"x[1] x[3] x[5]" - > vec[x[1], x[3], x[5]]
129 pub fn list_to_scope_ids(list: &str) -> Vec<String> {
130 let mut ret: Vec<String> = Vec::new();
131 let lists: Vec<&str> = list.split_whitespace().collect();
132 for e in lists.iter() {
133 ret.push(e.to_string());
134 }
135 ret
136 }
137
138 /// return the transitions,
139 /// eg "(a,0,a)(a,1,b)(b,1,c)(c,0,d)(d,0,d)(d,1,e)(e,0,e)" -> vec[ (a,0,a),(a,1,b),(b,1,c),(c,0,d),(d,0,d),(d,1,e),(e,0,e)]
140 pub fn list_to_transitions(list: &str) -> Result<Vec<(String, i32, String)>, Xcsp3Error> {
141 let mut ret: Vec<(String, i32, String)> = Vec::new();
142 let chars = list.chars();
143 if let Some(left) = list.find('(') {
144 if let Some(right) = list.find(')') {
145 ret.reserve(list.len() / (right - left));
146 // n = (right - left - 1) / 2;
147 }
148 }
149 let mut last = usize::MAX;
150 let mut last_comma1 = usize::MAX;
151 let mut last_comma2 = usize::MAX;
152 for (i, x) in chars.enumerate() {
153 if x == '(' {
154 last = i;
155 } else if x == ')' {
156 // println!("{}",&tuple_str[last+1..i]);
157 match list[last_comma1 + 1..last_comma2].parse::<i32>() {
158 Ok(num) => ret.push((
159 list[last + 1..last_comma1].to_string(),
160 num,
161 list[last_comma2 + 1..i].to_string(),
162 )),
163 Err(_) => {
164 return Err(Xcsp3Error::get_constraint_regular_transitions_error(
165 "parse the transitions error, ",
166 ));
167 }
168 }
169 last_comma1 = usize::MAX;
170 } else if x == ',' {
171 if last_comma1 == usize::MAX {
172 last_comma1 = i;
173 } else {
174 last_comma2 = i;
175 }
176 }
177 }
178 Ok(ret)
179 }
180
181 /// return the matrix,
182 /// eg str"(x1,x2,x3,x4,x5)(y1,y2,y3,y4,y5)(z1,z2,z3,z4,z5)" - > vec[[x1,x2,x3,x4,x5][y1,y2,y3,y4,y5][z1,z2,z3,z4,z5]]
183 pub fn list_to_matrix_ids(list: &str) -> Vec<Vec<String>> {
184 let mut ret: Vec<Vec<String>> = Vec::new();
185 let list = list
186 .to_string()
187 .replace(')', "@")
188 .replace('\n', "")
189 .replace('(', " ");
190 let lists: Vec<&str> = list.split('@').collect();
191 for e in lists.iter() {
192 if !e.is_empty() {
193 let ss = e.replace(',', " ");
194 ret.push(list_to_scope_ids(&ss));
195 }
196 }
197 ret
198 }
199
200 /// return the list of values,
201 /// eg str"1 3 5 76" -> vec[1,3,5,76],
202 pub fn list_to_values(list: &str) -> Result<Vec<i32>, Xcsp3Error> {
203 let mut ret: Vec<i32> = Vec::new();
204 let lists: Vec<&str> = list.split_whitespace().collect();
205 for l in lists.iter() {
206 match l.parse::<i32>() {
207 Ok(n) => ret.push(n),
208 Err(_) => {
209 return Err(Xcsp3Error::get_constraint_list_of_values_error(
210 "parse the list of values error. ",
211 ));
212 }
213 }
214 }
215 Ok(ret)
216 }
217
218 /// return the list of values,
219 /// eg str"(1, 3, 5, 76)" -> vec[1,3,5,76],
220 pub fn list_with_bracket_comma_to_values(list: &str) -> Result<Vec<XVarVal>, Xcsp3Error> {
221 let mut ret: Vec<XVarVal> = Vec::new();
222 let list = list.to_string().replace(['(', ')', ','], " ");
223 let lists: Vec<&str> = list.split_whitespace().collect();
224 for e in lists.iter() {
225 match e.parse::<i32>() {
226 Ok(n) => ret.push(XVarVal::IntArgument(n)),
227 Err(_) => {
228 return Err(Xcsp3Error::get_constraint_list_of_values_error(
229 "parse the list of values error. ",
230 ));
231 }
232 }
233 }
234 Ok(ret)
235 }
236
237 // fn string_to_i32(s: &str) -> Option<i32> {
238 // let char = s.chars().rev();
239 // let mut n: i32 = 0;
240 // for (i, c) in char.enumerate() {
241 // if !c.is_numeric() {
242 // return None;
243 // } else {
244 // n += 10i32.pow((i as i32).try_into().unwrap()) * c as i32
245 // }
246 // }
247 // Some(n)
248 // }
249 // fn str_to_2vec(string: &str) -> Vec<Vec<i32>> {
250 // use serde::Deserialize;
251 // #[derive(Debug, Deserialize)]
252 // struct Tuples {
253 // tuples: Vec<Vec<i32>>,
254 // }
255 // let s: Tuples = serde_json::from_str(string).unwrap();
256 // s.tuples
257 // }
258 // pub fn tuple_to_vector1(tuple_str: &str, is_unary: bool) -> Result<Vec<Vec<i32>>, Xcsp3Error> {
259 // let err = Xcsp3Error::get_constraint_extension_error("parse the tuple of extension error");
260 // if is_unary {
261 // let mut ret: Vec<Vec<i32>> = Vec::new();
262 // let tuples: Vec<&str> = tuple_str.split_whitespace().collect();
263 // for tuple in tuples.iter() {
264 // if tuple.contains("..") {
265 // let interval: Vec<&str> = tuple.split("..").collect();
266 // if interval.len() == 2 {
267 // let left = interval[0].parse::<i32>();
268 // let right = interval[1].parse::<i32>();
269 // match left {
270 // Ok(l) => match right {
271 // Ok(r) => {
272 // if l <= r {
273 // for i in l..r + 1 {
274 // ret.push(vec![i])
275 // }
276 // } else {
277 // return Err(err);
278 // }
279 // }
280 // Err(_) => {
281 // return Err(err);
282 // }
283 // },
284 // Err(_) => {
285 // return Err(err);
286 // }
287 // }
288 // }
289 // } else {
290 // match tuple.parse::<i32>() {
291 // Ok(v) => ret.push(vec![v]),
292 // Err(_) => {
293 // return Err(err);
294 // }
295 // }
296 // }
297 // }
298 // Ok(ret)
299 // } else {
300 // let mut tuple_str = tuple_str
301 // .replace(")(", "],[")
302 // .replace('(', "[")
303 // .replace(')', "]")
304 // .replace("*", &i32::MAX.to_string());
305 // tuple_str = "{\"tuples\":[".to_owned() + &tuple_str + "]}";
306 // // println!("{}",tuple_str);
307 // Ok(str_to_2vec(&tuple_str))
308 // // println!("{:?}",ret);
309 // }
310 // // println!("parse Extension {:?}",ti.get());
311 // }
312 ///return the tuples by given string,
313 /// eg (0,0,1)(0,1,0)(1,0,0)(1,1,1) -> [[0,0,1],[0,1,0],[1,0,0],[1,1,1]]
314 pub fn tuple_to_vector(tuple_str: &str, is_unary: bool) -> Result<Vec<Vec<i32>>, Xcsp3Error> {
315 // let ti = TimeInterval::new();
316 let mut ret: Vec<Vec<i32>> = Vec::new();
317 let err = Xcsp3Error::get_constraint_extension_error("parse the tuple of extension error");
318 if is_unary {
319 let tuples: Vec<&str> = tuple_str.split_whitespace().collect();
320 for tuple in tuples.iter() {
321 if tuple.contains("..") {
322 let interval: Vec<&str> = tuple.split("..").collect();
323 if interval.len() == 2 {
324 let left = interval[0].parse::<i32>();
325 let right = interval[1].parse::<i32>();
326 match left {
327 Ok(l) => match right {
328 Ok(r) => {
329 if l <= r {
330 for i in l..r + 1 {
331 ret.push(vec![i])
332 }
333 } else {
334 return Err(err);
335 }
336 }
337 Err(_) => {
338 return Err(err);
339 }
340 },
341 Err(_) => {
342 return Err(err);
343 }
344 }
345 }
346 } else {
347 match tuple.parse::<i32>() {
348 Ok(v) => ret.push(vec![v]),
349 Err(_) => {
350 return Err(err);
351 }
352 }
353 }
354 }
355 } else {
356 let chars = tuple_str.chars();
357 let mut last = 0;
358 let mut tt: Vec<i32> = vec![];
359 let mut n: usize = 0;
360 if let Some(left) = tuple_str.find('(') {
361 if let Some(right) = tuple_str.find(')') {
362 ret.reserve(tuple_str.len() / (right - left));
363 n = (right - left - 1) / 2;
364 }
365 }
366 for (i, x) in chars.enumerate() {
367 if x == '(' {
368 tt.clear();
369 tt.reserve(n);
370 last = i;
371 } else if x == ')' {
372 // println!("{}",&tuple_str[last+1..i]);
373 match tuple_str[last + 1..i].parse::<i32>() {
374 Ok(num) => {
375 tt.push(num);
376 }
377 Err(_) => {
378 if &tuple_str[last + 1..i] == "*" {
379 tt.push(i32::MAX);
380 } else {
381 return Err(err);
382 }
383 }
384 }
385 ret.push(tt.clone())
386 } else if x == ',' {
387 // println!("{}",&tuple_str[last+1..i]);
388 match tuple_str[last + 1..i].parse::<i32>() {
389 Ok(num) => {
390 tt.push(num);
391 }
392 Err(_) => {
393 if &tuple_str[last + 1..i] == "*" {
394 tt.push(i32::MAX);
395 } else {
396 return Err(err);
397 }
398 }
399 }
400 last = i;
401 }
402 }
403 }
404 // println!("parse Extension {:?}",ti.get());
405 Ok(ret)
406 }
407
408 /// transform the string size to vector sizes
409 /// eg: [2][3..4][4..8] -> ([2,3,4],[2,4,8])
410 pub fn sizes_to_double_vec(sizes: &str) -> Result<(Vec<usize>, Vec<usize>), Xcsp3Error> {
411 let mut lower: Vec<usize> = vec![];
412 let mut upper: Vec<usize> = vec![];
413 let sizes = sizes.replace("[]", "[*]").replace(['[', ']'], " ");
414 let nums: Vec<&str> = sizes.split_whitespace().collect();
415 for n in nums.iter() {
416 if n.find('*').is_some() {
417 lower.push(usize::MAX);
418 upper.push(usize::MAX);
419 } else if n.contains("..") {
420 let interval: Vec<&str> = n.split("..").collect();
421 if interval.len() == 2 {
422 let low = interval[0].parse::<usize>();
423 let up = interval[1].parse::<usize>();
424
425 match low {
426 Ok(l) => match up {
427 Ok(u) => {
428 lower.push(l);
429 upper.push(u);
430 }
431 Err(_) => {
432 return Err(Xcsp3Error::get_domain_for_error(
433 "parse the domain for error",
434 ));
435 }
436 },
437 Err(_) => {
438 return Err(Xcsp3Error::get_domain_for_error(
439 "parse the domain for error",
440 ));
441 }
442 }
443 }
444 } else {
445 match n.parse::<usize>() {
446 Ok(v) => {
447 lower.push(v);
448 upper.push(v);
449 }
450 Err(_) => {
451 return Err(Xcsp3Error::get_domain_for_error("parse the domain error"));
452 }
453 };
454 }
455 }
456 Ok((lower, upper))
457 }
458
459 /// transform the string size to vector sizes
460 /// eg: [2][3][4] -> ([2,3,4], 24)
461 pub fn sizes_to_vec(sizes: &str) -> Result<(Vec<usize>, usize), Xcsp3Error> {
462 let mut ret: Vec<usize> = vec![];
463 let mut sz: usize = 1;
464 let mut sizes = sizes.replace('[', " ");
465 sizes = sizes.replace(']', " ");
466 let nums: Vec<&str> = sizes.split_whitespace().collect();
467 for n in nums.iter() {
468 match n.parse::<usize>() {
469 Ok(v) => {
470 ret.push(v);
471 sz *= v;
472 }
473 Err(_) => {
474 return Err(Xcsp3Error::get_variable_size_invalid_error(
475 "parse the size of variable error",
476 ));
477 }
478 };
479 }
480
481 Ok((ret, sz))
482 }
483}
484
485// #[allow(dead_code)]
486// pub mod xcsp3_core {
487//
488// pub fn split_with_elems(s: &str, delim: &char, elems: &mut Vec<String>) {
489// let de = format!("{}", delim);
490// let result: Vec<&str> = s.split(de.as_str()).collect();
491// for elem in result {
492// elems.push(String::from(elem));
493// }
494// }
495//
496// // pub fn parser_domain(domain: &String) -> XDomainInteger
497// // {
498// // let mut ret:XDomainInteger = XDomainInteger::new();
499// // let domains :Vec<&str>= domain.split_whitespace().collect();
500// //
501// // for d in domains.iter()
502// // {
503// // if d.find("..").is_some()
504// // {
505// // let interval: Vec<&str> = d.split("..").collect();
506// // if interval.len() == 2 {
507// // let left = i32::from_str(interval[0]);
508// // let right = i32::from_str(interval[1]);
509// // match left {
510// // Ok(l) => {
511// // match right {
512// // Ok(r) => {
513// // ret.add_interval(l,r);
514// // }
515// // Err(_) => {}
516// // }
517// // }
518// // Err(_) => {}
519// // }
520// // }
521// //
522// //
523// // }else {
524// // match i32::from_str(d){
525// // Ok(v) => {
526// // ret.add_value(v)
527// // }
528// // Err(_) => { }
529// // } ;
530// // }
531// // }
532// //
533// // ret
534// // }
535//
536// pub fn split(s: &str, delim: &char) -> Vec<String> {
537// let mut elems: Vec<String> = vec![];
538// split_with_elems(s, delim, &mut elems);
539// elems
540// }
541//
542// pub fn replace_string_in_place(subject: &mut str, search: &str, replace: &str) {
543// let _ = subject.replace(search, replace);
544// }
545//
546// pub fn remove_char(s: &mut str, c: char) {
547// let _ = s.replace(c, "");
548// }
549// }