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