carl  24.04
Computer ARithmetic Library
Constraint.h
Go to the documentation of this file.
1 #pragma once
2 
4 #include <carl-common/config.h>
14 
15 #include <cassert>
16 #include <cstring>
17 #include <iostream>
18 #include <sstream>
19 
20 
21 namespace carl {
22 
23 // Forward definition.
24 template<typename Pol>
25 class Constraint;
26 
27 template<typename Poly>
28 using Constraints = std::set<Constraint<Poly>, carl::less<Constraint<Poly>, false>>;
29 
30 template<typename Pol>
32  /// Basic constraint.
34  /// Cache for the factorization.
36  /// A container which includes all variables occurring in the polynomial considered by this constraint.
38  /// A map which stores information about properties of the variables in this constraint.
40  #ifdef THREAD_SAFE
41  /// Mutex for access to variable information map.
42  std::mutex m_var_info_map_mutex;
43  /// Mutex for access to the factorization.
44  std::mutex m_lhs_factorization_mutex;
45  /// Mutex for access to the variables.
46  std::mutex m_variables_mutex;
47  #endif
48 
50  const auto& key() const { return m_constraint; }
51 };
52 
53 template<typename Pol>
55 
56 
57 /**
58  * Represent a polynomial (in)equality against zero. Such an (in)equality
59  * can be seen as an atomic formula/atom for the theory of real arithmetic.
60  */
61 template<typename Pol>
62 class Constraint {
63 
64 private:
66 
67 public:
68  explicit Constraint(bool valid = true) : m_element(BasicConstraint<Pol>(valid)) {}
69 
70  explicit Constraint(carl::Variable::Arg var, Relation rel, const typename Pol::NumberType& bound = constant_zero<typename Pol::NumberType>::get()) : m_element(constraint::create_normalized_bound<Pol>(var,rel,bound)) {}
71 
72  explicit Constraint(const Pol& lhs, Relation rel) : m_element(constraint::create_normalized_constraint(lhs,rel)) {}
73 
74  explicit Constraint(const BasicConstraint<Pol>& constraint) : m_element(constraint::create_normalized_constraint(constraint.lhs(),constraint.relation())) {}
75 
76  Constraint(const Constraint& constraint) : m_element(constraint.m_element) {}
77 
78  Constraint(Constraint&& constraint) noexcept : m_element(std::move(constraint.m_element)) {}
79 
80  Constraint& operator=(const Constraint& constraint) {
81  m_element = constraint.m_element;
82  return *this;
83  }
84 
85  Constraint& operator=(Constraint&& constraint) noexcept {
86  m_element = std::move(constraint.m_element);
87  return *this;
88  }
89 
90  operator const BasicConstraint<Pol>& () const {
91  return m_element->m_constraint;
92  }
93 
94  operator BasicConstraint<Pol> () const {
95  return m_element->m_constraint;
96  }
97 
98  /**
99  * Returns the associated BasicConstraint.
100  */
101  const BasicConstraint<Pol>& constr() const {
102  return m_element->m_constraint;
103  }
104 
105  /**
106  * @return The considered polynomial being the left-hand side of this constraint.
107  * Hence, the right-hand side of any constraint is always 0.
108  */
109  const Pol& lhs() const {
110  return m_element->m_constraint.lhs();
111  }
112 
113  /**
114  * @return The relation symbol of this constraint.
115  */
116  Relation relation() const {
117  return m_element->m_constraint.relation();
118  }
119 
120  /**
121  * @return A hash value for this constraint.
122  */
123  size_t hash() const {
124  return m_element->m_constraint.hash();
125  }
126 
127  /**
128  * @return A container containing all variables occurring in the polynomial of this constraint.
129  */
130  const auto& variables() const {
131  #ifdef THREAD_SAFE
132  m_element->m_variables_mutex.lock();
133  #endif
134  if (m_element->m_variables.empty()) {
135  m_element->m_variables = carl::variables(lhs());
136  }
137  #ifdef THREAD_SAFE
138  m_element->m_variables_mutex.unlock();
139  #endif
140  return m_element->m_variables;
141  }
142 
144  #ifdef THREAD_SAFE
145  m_element->m_lhs_factorization_mutex.lock();
146  #endif
147  if (m_element->m_lhs_factorization.empty()) {
148  m_element->m_lhs_factorization = carl::factorization(lhs());
149  }
150  #ifdef THREAD_SAFE
151  m_element->m_lhs_factorization_mutex.unlock();
152  #endif
153  return m_element->m_lhs_factorization;
154  }
155 
156  /**
157  * @param variable The variable to find variable information for.
158  * @tparam gatherCoeff
159  * @return The whole variable information object.
160  * Note, that if the given variable is not in this constraints, this method fails.
161  * Furthermore, the variable information returned do provide coefficients only, if
162  * the given flag gatherCoeff is set to true.
163  */
164  template<bool gatherCoeff = false>
165  const VarInfo<Pol>& var_info(const Variable variable) const {
166  #ifdef THREAD_SAFE
167  m_element->m_var_info_map_mutex.lock();
168  #endif
169  if (!m_element->m_var_info_map.occurs(variable) || (gatherCoeff && !m_element->m_var_info_map.var(variable).has_coeff())) {
170  m_element->m_var_info_map.data()[variable] = carl::var_info(lhs(),variable,gatherCoeff);
171  assert(m_element->m_var_info_map.occurs(variable));
172  }
173  #ifdef THREAD_SAFE
174  m_element->m_var_info_map_mutex.unlock();
175  #endif
176  return m_element->m_var_info_map.var(variable);
177  }
178 
179  template<bool gatherCoeff = false>
180  const VarsInfo<Pol>& var_info() const {
181  for (const auto& var : variables()) {
182  var_info<gatherCoeff>(var);
183  }
184  return m_element->m_var_info_map;
185  }
186 
187  /**
188  * Checks, whether the constraint is consistent.
189  * It differs between, containing variables, consistent, and inconsistent.
190  * @return 0, if the constraint is not consistent.
191  * 1, if the constraint is consistent.
192  * 2, if the constraint still contains variables.
193  */
194  unsigned is_consistent() const {
195  return m_element->m_constraint.is_consistent();
196  }
197 
199  return Constraint(constr().negation());
200  }
201 
202  /* (legacy) convenience methods */
203 
204  /**
205  * @param _variable The variable for which to determine the maximal degree.
206  * @return The maximal degree of the given variable in this constraint. (Monomial-wise)
207  */
208  uint maxDegree(const Variable& _variable) const {
209  if (!variables().has(_variable)) return 0;
210  else return var_info(_variable).max_degree();
211  }
212 
213  /**
214  * @return The maximal degree of all variables in this constraint. (Monomial-wise)
215  */
216  uint max_degree() const {
217  uint result = 0;
218  for (const auto& var : variables()) {
219  uint deg = maxDegree(var);
220  if (deg > result) result = deg;
221  }
222  return result;
223  }
224 
225  /**
226  * Calculates the coefficient of the given variable with the given degree. Note, that it only
227  * computes the coefficient once and stores the result.
228  * @param _var The variable for which to calculate the coefficient.
229  * @param _degree The according degree of the variable for which to calculate the coefficient.
230  * @return The ith coefficient of the given variable, where i is the given degree.
231  */
232  Pol coefficient(const Variable& _var, uint _degree) const {
233  auto& vi = var_info<true>(_var);
234  auto d = vi.coeffs().find(_degree);
235  return d != vi.coeffs().end() ? d->second : Pol(typename Pol::NumberType(0));
236  }
237 
238  /**
239  * @return true, if it contains only integer valued variables.
240  */
241  bool integer_valued() const {
243  }
244 
245  /**
246  * @return true, if it contains only real valued variables.
247  */
248  bool realValued() const {
250  }
251 
252  /**
253  * Checks if this constraints contains an integer valued variable.
254  * @return true, if it does;
255  * false, otherwise.
256  */
258  return !variables().integer().empty();
259  }
260 
261  /**
262  * Checks if this constraints contains an real valued variable.
263  * @return true, if it does;
264  * false, otherwise.
265  */
266  bool hasRealValuedVariable() const {
267  return !variables().real().empty();
268  }
269 
270  /**
271  * Determines whether the constraint is pseudo-boolean.
272  *
273  * @return True if this constraint is pseudo-boolean. False otherwise.
274  */
275  bool isPseudoBoolean() const {
276  return !variables().boolean().empty();
277  }
278 
279  template<typename P>
280  friend bool operator==(const Constraint<P>& lhs, const Constraint<P>& rhs);
281  template<typename P>
282  friend bool operator<(const Constraint<P>& lhs, const Constraint<P>& rhs);
283  template<typename P>
284  friend std::ostream& operator<<(std::ostream& os, const Constraint<P>& c);
285 };
286 
287 template<typename P>
288 bool operator==(const Constraint<P>& lhs, const Constraint<P>& rhs) {
289  return lhs.m_element.id() == rhs.m_element.id();
290 }
291 
292 template<typename P>
293 bool operator!=(const Constraint<P>& lhs, const Constraint<P>& rhs) {
294  return !(lhs == rhs);
295 }
296 
297 template<typename P>
298 bool operator<(const Constraint<P>& lhs, const Constraint<P>& rhs) {
299  return lhs.m_element.id() < rhs.m_element.id();
300 }
301 
302 template<typename P>
303 bool operator<=(const Constraint<P>& lhs, const Constraint<P>& rhs) {
304  return lhs == rhs || lhs < rhs;
305 }
306 
307 template<typename P>
308 bool operator>(const Constraint<P>& lhs, const Constraint<P>& rhs) {
309  return rhs < lhs;
310 }
311 
312 template<typename P>
313 bool operator>=(const Constraint<P>& lhs, const Constraint<P>& rhs) {
314  return rhs <= lhs;
315 }
316 
317 /**
318  * Prints the given constraint on the given stream.
319  * @param os The stream to print the given constraint on.
320  * @param c The formula to print.
321  * @return The stream after printing the given constraint on it.
322  */
323 template<typename Poly>
324 std::ostream& operator<<(std::ostream& os, const Constraint<Poly>& c) {
325  return os << c.m_element->m_constraint;
326 }
327 
328 template<typename Pol>
329 void variables(const Constraint<Pol>& c, carlVariables& vars) {
330  vars.add(c.variables().begin(), c.variables().end());
331 }
332 
333 template<typename Pol>
334 std::optional<std::pair<Variable, Pol>> get_substitution(const Constraint<Pol>& c, bool _negated = false, Variable _exclude = carl::Variable::NO_VARIABLE) {
335  return get_substitution(c.constr(), _negated, _exclude, std::optional(c.template var_info<true>()));
336 }
337 
338 // implicit conversions do not work for template argument deduction
339 template<typename Pol>
340 auto get_assignment(const Constraint<Pol>& c) { return get_assignment(c.constr()); }
341 template<typename Pol>
342 auto compare(const Constraint<Pol>& c1, const Constraint<Pol>& c2) { return compare(c1.constr(), c2.constr()); }
343 template<typename Pol>
345 template<typename Pol>
346 bool is_bound(const Constraint<Pol>& constr, bool negated = false) {
347  if (negated) {
348  return is_bound(constr.constr().negation());
349  } else {
350  return is_bound(constr.constr());
351  }
352 }
353 template<typename Pol>
354 bool is_lower_bound(const Constraint<Pol>& constr) { return is_lower_bound(constr.constr()); }
355 template<typename Pol>
356 bool is_upper_bound(const Constraint<Pol>& constr) { return is_upper_bound(constr.constr()); }
357 
358 } // namespace carl
359 
360 namespace std {
361 
362 /**
363  * Implements std::hash for constraints.
364  */
365 template<typename Pol>
366 struct hash<carl::Constraint<Pol>> {
367  /**
368  * @param constraint The constraint to get the hash for.
369  * @return The hash of the given constraint.
370  */
371  std::size_t operator()(const carl::Constraint<Pol>& constraint) const {
372  return constraint.hash();
373  }
374 };
375 
376 /**
377  * Implements std::hash for vectors of constraints.
378  */
379 template<typename Pol>
380 struct hash<std::vector<carl::Constraint<Pol>>> {
381  /**
382  * @param arg The vector of constraints to get the hash for.
383  * @return The hash of the given vector of constraints.
384  */
385  std::size_t operator()(const std::vector<carl::Constraint<Pol>>& arg) const {
386  std::size_t seed = arg.size();
387  for(auto& c : arg) {
388  seed ^= std::hash<carl::Constraint<Pol>>()(c) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
389  }
390  return seed;
391  }
392 };
393 } // namespace std
MultivariatePolynomial< Rational > Pol
Definition: HornerTest.cpp:17
carl is the main namespace for the library.
bool operator>(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
std::uint64_t uint
Definition: numbers.h:16
bool operator<(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
std::set< Constraint< Poly >, carl::less< Constraint< Poly >, false > > Constraints
Definition: Constraint.h:28
std::ostream & operator<<(std::ostream &os, const BasicConstraint< Poly > &c)
Prints the given constraint on the given stream.
unsigned satisfied_by(const BasicConstraint< Pol > &c, const Assignment< typename Pol::NumberType > &_assignment)
Checks whether the given assignment satisfies this constraint.
Definition: Evaluation.h:24
signed compare(const BasicConstraint< Pol > &_constraintA, const BasicConstraint< Pol > &_constraintB)
Compares _constraintA with _constraintB.
Definition: Comparison.h:25
bool is_bound(const BasicConstraint< Pol > &constr)
Definition: Bound.h:11
VarInfo< MultivariatePolynomial< Coeff, Ordering, Policies > > var_info(const MultivariatePolynomial< Coeff, Ordering, Policies > &poly, const Variable var, bool collect_coeff=false)
Definition: VarInfo.h:54
bool is_upper_bound(const BasicConstraint< Pol > &constr)
Definition: Bound.h:39
bool operator!=(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
bool operator<=(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
bool operator==(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
bool operator>=(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
std::optional< std::pair< Variable, Pol > > get_substitution(const BasicConstraint< Pol > &c, bool _negated=false, Variable _exclude=carl::Variable::NO_VARIABLE, std::optional< VarsInfo< Pol >> var_info=std::nullopt)
If this constraint represents a substitution (equation, where at least one variable occurs only linea...
Definition: Substitution.h:18
std::optional< std::pair< Variable, typename Pol::NumberType > > get_assignment(const BasicConstraint< Pol > &c)
Definition: Substitution.h:38
std::map< Variable, T > Assignment
Definition: Common.h:13
bool is_lower_bound(const BasicConstraint< Pol > &constr)
Definition: Bound.h:21
std::map< Pol, uint > Factors
Definition: Common.h:21
Relation
Definition: Relation.h:20
void variables(const BasicConstraint< Pol > &c, carlVariables &vars)
Factors< MultivariatePolynomial< C, O, P > > factorization(const MultivariatePolynomial< C, O, P > &p, bool includeConstants=true)
Try to factorize a multivariate polynomial.
Definition: Factorization.h:31
BasicConstraint< Pol > create_normalized_constraint(const Pol &lhs, Relation rel)
BasicConstraint< Pol > create_normalized_bound(Variable var, Relation rel, const typename Pol::NumberType &bound)
Represent a polynomial (in)equality against zero.
A Variable represents an algebraic variable that can be used throughout carl.
Definition: Variable.h:85
static const Variable NO_VARIABLE
Instance of an invalid variable.
Definition: Variable.h:203
static variable_type_filter excluding(std::initializer_list< VariableType > i)
Definition: Variables.h:24
void add(Variable v)
Definition: Variables.h:141
Alternative specialization of std::less for pointer types.
Represent a polynomial (in)equality against zero.
Definition: Constraint.h:62
const VarInfo< Pol > & var_info(const Variable variable) const
Definition: Constraint.h:165
Constraint(const Pol &lhs, Relation rel)
Definition: Constraint.h:72
bool isPseudoBoolean() const
Determines whether the constraint is pseudo-boolean.
Definition: Constraint.h:275
uint max_degree() const
Definition: Constraint.h:216
uint maxDegree(const Variable &_variable) const
Definition: Constraint.h:208
Pol coefficient(const Variable &_var, uint _degree) const
Calculates the coefficient of the given variable with the given degree.
Definition: Constraint.h:232
Constraint & operator=(Constraint &&constraint) noexcept
Definition: Constraint.h:85
friend bool operator<(const Constraint< P > &lhs, const Constraint< P > &rhs)
Definition: Constraint.h:298
const auto & variables() const
Definition: Constraint.h:130
bool hasIntegerValuedVariable() const
Checks if this constraints contains an integer valued variable.
Definition: Constraint.h:257
bool integer_valued() const
Definition: Constraint.h:241
const VarsInfo< Pol > & var_info() const
Definition: Constraint.h:180
friend bool operator==(const Constraint< P > &lhs, const Constraint< P > &rhs)
Definition: Constraint.h:288
const BasicConstraint< Pol > & constr() const
Returns the associated BasicConstraint.
Definition: Constraint.h:101
const Factors< Pol > & lhs_factorization() const
Definition: Constraint.h:143
bool realValued() const
Definition: Constraint.h:248
Constraint(const BasicConstraint< Pol > &constraint)
Definition: Constraint.h:74
unsigned is_consistent() const
Checks, whether the constraint is consistent.
Definition: Constraint.h:194
Constraint & operator=(const Constraint &constraint)
Definition: Constraint.h:80
bool hasRealValuedVariable() const
Checks if this constraints contains an real valued variable.
Definition: Constraint.h:266
pool::PoolElement< CachedConstraintContent< Pol > > m_element
Definition: Constraint.h:65
size_t hash() const
Definition: Constraint.h:123
Constraint negation() const
Definition: Constraint.h:198
Relation relation() const
Definition: Constraint.h:116
Constraint(carl::Variable::Arg var, Relation rel, const typename Pol::NumberType &bound=constant_zero< typename Pol::NumberType >::get())
Definition: Constraint.h:70
friend std::ostream & operator<<(std::ostream &os, const Constraint< P > &c)
const Pol & lhs() const
Definition: Constraint.h:109
Constraint(const Constraint &constraint)
Definition: Constraint.h:76
Constraint(Constraint &&constraint) noexcept
Definition: Constraint.h:78
Constraint(bool valid=true)
Definition: Constraint.h:68
Factors< Pol > m_lhs_factorization
Cache for the factorization.
Definition: Constraint.h:35
VarsInfo< Pol > m_var_info_map
A map which stores information about properties of the variables in this constraint.
Definition: Constraint.h:39
CachedConstraintContent(BasicConstraint< Pol > &&c)
Definition: Constraint.h:49
carlVariables m_variables
A container which includes all variables occurring in the polynomial considered by this constraint.
Definition: Constraint.h:37
BasicConstraint< Pol > m_constraint
Basic constraint.
Definition: Constraint.h:33
const auto & key() const
Definition: Constraint.h:50
std::size_t operator()(const carl::Constraint< Pol > &constraint) const
Definition: Constraint.h:371
std::size_t operator()(const std::vector< carl::Constraint< Pol >> &arg) const
Definition: Constraint.h:385