pub mod xcsp3_core {
use crate::errors::xcsp3error::xcsp3_core::Xcsp3Error;
use crate::variables::xdomain::xcsp3_core::XDomainInteger;
use crate::variables::xvariable_type::xcsp3_core::XVariableType;
use std::collections::HashMap;
use std::fmt::{Display, Formatter};
use std::slice::Iter;
pub struct XVariableSet {
variables: Vec<XVariableType>,
id_to_index: HashMap<String, usize>, }
impl Default for XVariableSet {
fn default() -> Self {
Self::new()
}
}
impl Display for XVariableSet {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut ret = String::default();
for e in self.variables.iter() {
ret = format!("{} \t{}\n", ret, e);
}
write!(f, "XVariableSet: \n{}", ret)
}
}
impl XVariableSet {
pub fn iter(&self) -> Iter<'_, XVariableType> {
self.variables.iter()
}
pub fn new() -> XVariableSet {
XVariableSet {
variables: vec![],
id_to_index: HashMap::default(),
}
}
pub fn build_variable_int(&mut self, id: &str, domain_string: &str, symbolic: &String) {
if symbolic.eq("symbolic") {
let domain = XDomainInteger::from_symbolic(domain_string);
let var = XVariableType::new_int(id, domain);
self.id_to_index.insert(var.get_id(), self.variables.len());
self.variables.push(var);
} else {
match XDomainInteger::from_string(domain_string) {
Ok(domain) => {
let var = XVariableType::new_int(id, domain);
self.id_to_index.insert(var.get_id(), self.variables.len());
self.variables.push(var);
}
Err(e) => {
self.variables.push(XVariableType::XVariableNone(e));
}
}
}
}
pub fn build_variable_int_as(&mut self, id: &str, as_str: &str) {
match self.find_variable(as_str) {
Ok(v) => {
if let XVariableType::XVariableInt(vv) = v {
let var = XVariableType::new_int(id, vv.domain.clone());
self.id_to_index.insert(var.get_id(), self.variables.len());
self.variables.push(var);
}
}
Err(e) => {
self.variables.push(XVariableType::XVariableNone(e));
}
}
}
pub fn build_variable_array(&mut self, id: &str, sizes: &str, domain_string: &str) {
match XDomainInteger::from_string(domain_string) {
Ok(domain) => {
let array = XVariableType::new_array(id, sizes, domain);
match array {
XVariableType::XVariableArray(_) => {
self.id_to_index
.insert(array.get_id(), self.variables.len());
self.variables.push(array);
}
_ => {
self.variables.push(XVariableType::XVariableNone(
Xcsp3Error::get_variable_size_invalid_error(""),
));
}
}
}
Err(e) => {
self.variables.push(XVariableType::XVariableNone(e));
}
};
}
pub fn build_variable_tree(
&mut self,
id: &str,
sizes: &str,
domain_for: Vec<&String>,
domain_value: Vec<&String>,
) {
let tree = XVariableType::new_tree(id, sizes, domain_for, domain_value);
match tree {
Ok(tree) => {
self.id_to_index.insert(tree.get_id(), self.variables.len());
self.variables.push(tree);
}
Err(e) => {
self.variables.push(XVariableType::XVariableNone(e));
}
}
}
pub fn find_variable(&self, id: &str) -> Result<&XVariableType, Xcsp3Error> {
let name = match id.find('[') {
None => id,
Some(n) => &id[..n],
};
match self.id_to_index.get(name) {
None => Err(Xcsp3Error::get_variable_not_found_error(
&("not find the variable named ".to_owned() + name),
)),
Some(v) => Ok(&self.variables[*v]),
}
}
pub fn construct_scope(
&self,
scope_str: &[&String],
) -> Result<Vec<(String, &XDomainInteger)>, Xcsp3Error> {
let mut ret: Vec<(String, &XDomainInteger)> = vec![];
for e in scope_str.iter() {
{
match self.find_variable(e) {
Ok(var_type) => match var_type {
XVariableType::XVariableArray(a) => match a.find_variable(e) {
Ok(mut vec) => {
for (e1, e2) in vec.iter_mut() {
ret.push((e1.to_string(), e2));
}
}
Err(e) => {
return Err(e);
}
},
XVariableType::XVariableInt(i) => ret.push((i.id.clone(), &i.domain)),
XVariableType::XVariableTree(t) => match t.find_variable(e) {
Ok(mut vec) => {
for (e1, e2) in vec.iter_mut() {
ret.push((e1.to_string(), e2));
}
}
Err(e) => {
return Err(e);
}
},
_ => {}
},
Err(_) => {
return Err(Xcsp3Error::get_variable_not_found_error(
"the scope not found, ",
));
}
}
}
}
Ok(ret)
}
}
}