xcsp3_rust/constraints/
xn_values.rs1pub mod xcsp3_core {
41 use crate::constraints::xconstraint_trait::xcsp3_core::XConstraintTrait;
42 use crate::data_structs::xint_val_var::xcsp3_core::XVarVal;
43 use crate::data_structs::xrelational_operand::xcsp3_core::Operand;
44 use crate::data_structs::xrelational_operator::xcsp3_core::Operator;
45 use crate::errors::xcsp3error::xcsp3_core::Xcsp3Error;
46 use crate::utils::utils_functions::xcsp3_utils::list_to_vec_var_val;
47 use crate::variables::xdomain::xcsp3_core::XDomainInteger;
48 use crate::variables::xvariable_set::xcsp3_core::XVariableSet;
49 use std::collections::HashMap;
50 use std::fmt::{Display, Formatter};
51
52 pub struct XNValues<'a> {
53 scope: Vec<XVarVal>,
54 map: HashMap<String, &'a XDomainInteger>,
55 set: &'a XVariableSet,
56 operator: Operator,
57 operand: Operand,
58 except: Option<Vec<XVarVal>>,
59 }
60 impl Display for XNValues<'_> {
61 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
62 let mut ret = String::default();
63 for e in self.scope.iter() {
64 ret.push('(');
65 ret.push_str(&e.to_string());
66 ret.push_str("), ")
67 }
68 if let Some(except) = &self.except {
69 ret.push_str("except = (");
70 for e in except.iter() {
71 ret.push_str(&e.to_string());
72 ret.push_str(", ")
73 }
74 ret.push_str(") ");
75 }
76
77 write!(
78 f,
79 "XNValues: scope = {}, condition = ({:?}, {:?})",
80 ret, self.operator, self.operand
81 )
82 }
83 }
84 impl XConstraintTrait for XNValues<'_> {
85 fn get_scope_string(&self) -> &Vec<XVarVal> {
86 &self.scope
87 }
88
89 fn get_scope(&mut self) -> Vec<(&String, &XDomainInteger)> {
90 for e in &self.scope {
91 if let XVarVal::IntVar(s) = e {
92 if !self.map.contains_key(s) {
93 if let Ok(vec) = self.set.construct_scope(&[s]) {
94 for (vs, vv) in vec.into_iter() {
95 self.map.insert(vs, vv);
96 }
97 }
98 }
99 }
100 }
101 let mut scope_vec_var: Vec<(&String, &XDomainInteger)> = vec![];
102 for e in self.map.iter() {
103 scope_vec_var.push((e.0, e.1))
104 }
105 scope_vec_var
106 }
107 }
108
109 impl<'a> XNValues<'a> {
110 pub fn from_str(
111 list: &str,
112 condition: &str,
113 except_str: &str,
114 set: &'a XVariableSet,
115 ) -> Result<Self, Xcsp3Error> {
116 match list_to_vec_var_val(list) {
117 Ok(scope_vec_str) => {
118 let except = if except_str.is_empty() {
119 None
120 } else {
121 match list_to_vec_var_val(except_str) {
122 Ok(coe_vec) => Some(coe_vec),
123 Err(e) => return Err(e),
124 }
125 };
126 let condition = condition.replace(['(', ')', ','], " ");
127 let spilt: Vec<&str> = condition.split_whitespace().collect();
128
129 let ope: Operator = match Operator::get_operator_by_str(spilt[0]) {
130 None => {
131 return Err(Xcsp3Error::get_constraint_sum_error(
132 "parse sum constraint Operator error, ",
133 ));
134 }
135 Some(o) => o,
136 };
137
138 let rand: Operand = match Operand::get_operand_by_str(&spilt[1..], &ope) {
139 None => {
140 return Err(Xcsp3Error::get_constraint_sum_error(
141 "parse sum constraint Operand error, ",
142 ));
143 }
144 Some(r) => r,
145 };
146 Ok(Self::new(scope_vec_str, set, ope, rand, except))
147 }
148 Err(e) => Err(e),
149 }
150 }
151
152 pub fn new(
153 scope: Vec<XVarVal>,
154 set: &'a XVariableSet,
155 operator: Operator,
156 operand: Operand,
157 except: Option<Vec<XVarVal>>,
158 ) -> Self {
159 Self {
160 scope,
161 map: Default::default(),
162 set,
163 operator,
164 operand,
165 except,
166 }
167 }
168
169 pub fn get_except(&self) -> &Option<Vec<XVarVal>> {
170 &self.except
171 }
172 pub fn get_operand(&self) -> &Operand {
173 &self.operand
174 }
175
176 pub fn get_operator(&self) -> &Operator {
177 &self.operator
178 }
179 }
180}