pub mod xcsp3_core {
use crate::constraints::xconstraint_type::xcsp3_core::XConstraintType;
use crate::data_structs::xint_val_var::xcsp3_core::XVarVal;
use crate::errors::xcsp3error::xcsp3_core::Xcsp3Error;
use crate::utils::utils_functions::xcsp3_utils::list_to_vec_var_val;
use crate::variables::xdomain::xcsp3_core::XDomainInteger;
use crate::variables::xvariable_set::xcsp3_core::XVariableSet;
use std::fmt::{Display, Formatter};
pub struct XGroup<'a> {
args: Vec<Vec<XVarVal>>,
map: Vec<Vec<(String, &'a XDomainInteger)>>,
set: &'a XVariableSet,
template: Box<XConstraintType<'a>>,
}
impl Display for XGroup<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut ret = String::default();
for a in self.args.iter() {
ret.push('[');
for e in a.iter() {
ret.push_str(e.to_string().as_str());
ret.push_str(", ")
}
ret.push(']');
}
write!(
f,
"XGroup: [constraint = {} [ args = {}]]",
&self.template.to_string(),
ret
)
}
}
impl<'a> XGroup<'a> {
pub fn get_scope(&mut self) -> &Vec<Vec<(String, &XDomainInteger)>> {
if self.map.is_empty() {
self.map.reserve(self.args.len());
for arg in self.args.iter() {
for v in arg.iter() {
if let XVarVal::IntVar(s) = v {
let mut ar: Vec<(String, &XDomainInteger)> = vec![];
if let Ok(vec) = self.set.construct_scope(&[s]) {
for (vs, vv) in vec.into_iter() {
ar.push((vs, vv))
}
}
self.map.push(ar);
}
}
}
}
&self.map
}
pub fn get_args(&self) -> &Vec<Vec<XVarVal>> {
&self.args
}
pub fn get_template(&self) -> &XConstraintType<'a> {
&self.template
}
pub fn from_str(
cc: XConstraintType<'a>,
arg_str: &[String],
set: &'a XVariableSet,
) -> Result<Self, Xcsp3Error> {
let mut args: Vec<Vec<XVarVal>> = vec![];
args.reserve(arg_str.len());
for a in arg_str.iter() {
match list_to_vec_var_val(a) {
Ok(scope_vec_str) => {
args.push(scope_vec_str);
}
Err(e) => return Err(e),
}
}
Ok(XGroup::new(args, set, Box::new(cc)))
}
pub fn new(
args: Vec<Vec<XVarVal>>,
set: &'a XVariableSet,
template: Box<XConstraintType<'a>>,
) -> Self {
Self {
args,
map: vec![],
set,
template,
}
}
}
}