xcsp3_rust/variables/xvariable_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/6/30
32 * </p>
33 * <p>@time: 13:47
34 * </p>
35 * <p>@this_file_name:XCSP3Variable
36 * </p>
37 */
38
39pub mod xcsp3_core {
40 use crate::errors::xcsp3error::xcsp3_core::Xcsp3Error;
41 use crate::variables::xdomain::xcsp3_core::XDomainInteger;
42 use crate::variables::xvariable_type::xcsp3_core::XVariableType;
43 use std::collections::HashMap;
44 use std::fmt::{Display, Formatter};
45
46 // use regex::Regex;
47 use std::slice::Iter;
48 /**
49 the XVariableSet is a container that store all variables.
50 */
51 pub struct XVariableSet {
52 variables: Vec<XVariableType>,
53 id_to_index: HashMap<String, usize>, //store the id and the index of the variable
54 // empty_domain: XDomainInteger,
55 }
56
57 impl Default for XVariableSet {
58 fn default() -> Self {
59 Self::new()
60 }
61 }
62
63 impl Display for XVariableSet {
64 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
65 let mut ret = String::default();
66 for e in self.variables.iter() {
67 ret = format!("{} \t{}\n", ret, e);
68 }
69 write!(f, "XVariableSet: \n{}", ret)
70 }
71 }
72
73 impl XVariableSet {
74 pub fn iter(&self) -> Iter<'_, XVariableType> {
75 self.variables.iter()
76 }
77
78 // pub fn to_string(&self) -> String {
79 // let mut ret = String::from("XVariableSet: \n");
80 // for e in self.variables.iter() {
81 // ret = format!("{} \t{}\n", ret, e);
82 // }
83 // ret
84 // }
85 pub fn new() -> XVariableSet {
86 XVariableSet {
87 variables: vec![],
88 id_to_index: HashMap::default(),
89 // empty_domain: XDomainInteger::new(),
90 }
91 }
92
93 pub fn build_variable_int(&mut self, id: &str, domain_string: &str, symbolic: &String) {
94 if symbolic.eq("symbolic") {
95 let domain = XDomainInteger::from_symbolic(domain_string);
96 let var = XVariableType::new_int(id, domain);
97 self.id_to_index.insert(var.get_id(), self.variables.len());
98 self.variables.push(var);
99 } else {
100 match XDomainInteger::from_string(domain_string) {
101 Ok(domain) => {
102 let var = XVariableType::new_int(id, domain);
103 self.id_to_index.insert(var.get_id(), self.variables.len());
104 self.variables.push(var);
105 }
106 Err(e) => {
107 // eprintln!("{}", e.to_string());
108 self.variables.push(XVariableType::XVariableNone(e));
109 }
110 }
111 }
112 }
113
114 pub fn build_variable_int_as(&mut self, id: &str, as_str: &str) {
115 match self.find_variable(as_str) {
116 Ok(v) => {
117 if let XVariableType::XVariableInt(vv) = v {
118 let var = XVariableType::new_int(id, vv.domain.clone());
119 self.id_to_index.insert(var.get_id(), self.variables.len());
120 self.variables.push(var);
121 }
122 }
123 Err(e) => {
124 // eprintln!("{}", e.to_string());
125 self.variables.push(XVariableType::XVariableNone(e));
126 }
127 }
128 }
129
130 pub fn build_variable_array(&mut self, id: &str, sizes: &str, domain_string: &str) {
131 match XDomainInteger::from_string(domain_string) {
132 Ok(domain) => {
133 let array = XVariableType::new_array(id, sizes, domain);
134 match array {
135 XVariableType::XVariableArray(_) => {
136 self.id_to_index
137 .insert(array.get_id(), self.variables.len());
138 self.variables.push(array);
139 }
140 _ => {
141 self.variables.push(XVariableType::XVariableNone(
142 Xcsp3Error::get_variable_size_invalid_error(""),
143 ));
144 }
145 }
146 }
147 Err(e) => {
148 self.variables.push(XVariableType::XVariableNone(e));
149 }
150 };
151 }
152
153 pub fn build_variable_tree(
154 &mut self,
155 id: &str,
156 sizes: &str,
157 domain_for: Vec<&String>,
158 domain_value: Vec<&String>,
159 ) {
160 let tree = XVariableType::new_tree(id, sizes, domain_for, domain_value);
161 match tree {
162 Ok(tree) => {
163 self.id_to_index.insert(tree.get_id(), self.variables.len());
164 self.variables.push(tree);
165 }
166 Err(e) => {
167 self.variables.push(XVariableType::XVariableNone(e));
168 }
169 }
170 }
171
172 pub fn find_variable(&self, id: &str) -> Result<&XVariableType, Xcsp3Error> {
173 let name = match id.find('[') {
174 None => id,
175 Some(n) => &id[..n],
176 };
177 match self.id_to_index.get(name) {
178 None => Err(Xcsp3Error::get_variable_not_found_error(
179 &("not find the variable named ".to_owned() + name),
180 )),
181 Some(v) => Ok(&self.variables[*v]),
182 }
183 }
184
185 ///construct the scope from XVariableSet, when scope is equal to %x, where x is an i32 number, return empty tuple
186 pub fn construct_scope(
187 &self,
188 scope_str: &[&String],
189 ) -> Result<Vec<(String, &XDomainInteger)>, Xcsp3Error> {
190 let mut ret: Vec<(String, &XDomainInteger)> = vec![];
191 for e in scope_str.iter() {
192 {
193 match self.find_variable(e) {
194 Ok(var_type) => match var_type {
195 XVariableType::XVariableArray(a) => match a.find_variable(e) {
196 Ok(mut vec) => {
197 for (e1, e2) in vec.iter_mut() {
198 ret.push((e1.to_string(), e2));
199 }
200 }
201 Err(e) => {
202 return Err(e);
203 }
204 },
205 XVariableType::XVariableInt(i) => ret.push((i.id.clone(), &i.domain)),
206 XVariableType::XVariableTree(t) => match t.find_variable(e) {
207 Ok(mut vec) => {
208 for (e1, e2) in vec.iter_mut() {
209 ret.push((e1.to_string(), e2));
210 }
211 }
212 Err(e) => {
213 return Err(e);
214 }
215 },
216 _ => {}
217 },
218 Err(_) => {
219 return Err(Xcsp3Error::get_variable_not_found_error(
220 "the scope not found, ",
221 ));
222 }
223 }
224 }
225 }
226 Ok(ret)
227 }
228 }
229}