carl  24.04
Computer ARithmetic Library
Substitution.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "BasicConstraint.h"
4 
5 #include <optional>
6 
7 namespace carl {
8 
9 /**
10  * If this constraint represents a substitution (equation, where at least one variable occurs only linearly),
11  * this method detects a (there could be various possibilities) corresponding substitution variable and term.
12  * @param _substitutionVariable Is set to the substitution variable, if this constraint represents a substitution.
13  * @param _substitutionTerm Is set to the substitution term, if this constraint represents a substitution.
14  * @return true, if this constraints represents a substitution;
15  * false, otherwise.
16  */
17 template<typename Pol>
18 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) {
19  if (var_info == std::nullopt) {
20  var_info = carl::vars_info(c.lhs(), true);
21  }
22  if ((!_negated && c.relation() != Relation::EQ) || (_negated && c.relation() != Relation::NEQ))
23  return std::nullopt;
24  for (const auto& e : *var_info) {
25  if (e.first == _exclude) continue;
26  if (e.second.max_degree() == 1) {
27  auto d = e.second.coeffs().find(1);
28  assert(d != e.second.coeffs().end());
29  if (d->second.is_constant() && (e.first.type() != carl::VariableType::VT_INT || carl::is_one(carl::abs(d->second.constant_part())))) {
30  return std::make_pair(e.first, (Pol(e.first) * d->second - c.lhs()) / d->second.constant_part());
31  }
32  }
33  }
34  return std::nullopt;
35 }
36 
37 template<typename Pol>
38 std::optional<std::pair<Variable, typename Pol::NumberType>> get_assignment(const BasicConstraint<Pol>& c) {
39  if (c.relation() != Relation::EQ) return std::nullopt;
40  if (c.lhs().nr_terms() > 2) return std::nullopt;
41  if (c.lhs().nr_terms() == 0) return std::nullopt;
42  if (!c.lhs().lterm().is_single_variable()) return std::nullopt;
43  if (c.lhs().nr_terms() == 1) {
44  return std::make_pair(c.lhs().lterm().single_variable(),0);
45  }
46  assert(c.lhs().nr_terms() == 2);
47  if (!c.lhs().trailingTerm().is_constant()) return std::nullopt;
48  return std::make_pair(c.lhs().lterm().single_variable(), -c.lhs().trailingTerm().coeff() / c.lhs().lterm().coeff());
49 }
50 
51 }
MultivariatePolynomial< Rational > Pol
Definition: HornerTest.cpp:17
carl is the main namespace for the library.
Interval< Number > abs(const Interval< Number > &_in)
Method which returns the absolute value of the passed number.
Definition: Interval.h:1511
VarInfo< MultivariatePolynomial< Coeff, Ordering, Policies > > var_info(const MultivariatePolynomial< Coeff, Ordering, Policies > &poly, const Variable var, bool collect_coeff=false)
Definition: VarInfo.h:54
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
VarsInfo< MultivariatePolynomial< Coeff, Ordering, Policies > > vars_info(const MultivariatePolynomial< Coeff, Ordering, Policies > &poly, bool collect_coeff=false)
Definition: VarInfo.h:63
bool is_one(const Interval< Number > &i)
Check if this interval is a point-interval containing 1.
Definition: Interval.h:1462
Represent a polynomial (in)equality against zero.
const Pol & lhs() const
Relation relation() const
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