SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
EqualitySubstitution.h
Go to the documentation of this file.
1 #pragma once
2 
4 
5 namespace smtrat::qe::util {
6 
8 private:
10  std::vector<carl::Variable> m_variables;
11 
12 public:
13  EquationSubstitution(const FormulasT& cs, const std::vector<carl::Variable>& vs)
14  : m_constraints(cs), m_variables(vs) {}
15 
16  EquationSubstitution(FormulasT&& cs, std::vector<carl::Variable>&& vs)
17  : m_constraints(std::move(cs)), m_variables(std::move(vs)) {}
18 
19  bool apply() {
20  SMTRAT_LOG_DEBUG("smtrat.qe","begin");
21 
22  for (auto it = m_constraints.begin(); it != m_constraints.end(); ++it) {
23  if (it->constraint().relation() != carl::Relation::LEQ) continue;
24  for (auto it_other = std::next(it); it_other != m_constraints.end(); ++it_other) {
25  if (it_other->constraint().relation() != carl::Relation::LEQ) continue;
26  if (it_other->constraint().lhs() + it->constraint().lhs() == Poly(0)) {
27  *it = FormulaT(it->constraint().lhs(), carl::Relation::EQ);
28  m_constraints.erase(it_other);
29  break;
30  }
31  }
32  }
33 
34  auto first_ineq = std::partition(
35  m_constraints.begin(),
36  m_constraints.end(),
37  [](const auto& c) { return c.constraint().relation() == carl::Relation::EQ; }
38  );
39 
40  FormulasT done;
41  for (auto eq_it = m_constraints.begin(); eq_it != first_ineq; ++eq_it) {
42  Poly lhs = eq_it->constraint().lhs();
43  assert(lhs.is_linear());
44  std::optional<TermT> subst_term = std::nullopt;
45  for (const auto& term: lhs) {
46  if (term.is_constant()) continue;
47  auto it = std::find(m_variables.begin(), m_variables.end(), term.single_variable());
48  if (it != m_variables.end()) {
49  subst_term = term;
50  m_variables.erase(it);
51  break;
52  }
53  }
54  if (!subst_term) {
55  done.push_back(*eq_it);
56  continue;
57  }
58  // replace in all remaining equations and other constraints
59  Poly subst = (Poly(*subst_term) - lhs)/(subst_term->coeff());
60  std::for_each(std::next(eq_it), m_constraints.end(), [&subst_term, &subst](auto& c){
61  Poly other_lhs = c.constraint().lhs();
62  carl::substitute_inplace(other_lhs, subst_term->single_variable(), subst);
63  c = FormulaT(other_lhs, c.constraint().relation());
64  });
65  }
66  done.insert(done.end(), first_ineq, m_constraints.end());
67  for (const auto& c : done) {
68  if (c.constraint().is_consistent() == 0) {
69  m_constraints.clear();
70  m_variables.clear();
71  SMTRAT_LOG_DEBUG("smtrat.qe","end false");
72  return false;
73  }
74  }
75 
76  m_constraints = done;
77  SMTRAT_LOG_DEBUG("smtrat.qe","end true");
78  return true;
79  }
80 
81  std::vector<carl::Variable> remaining_variables() {
82  return m_variables;
83  }
84 
86  return m_constraints;
87  }
88 
89 };
90 
91 }
EquationSubstitution(FormulasT &&cs, std::vector< carl::Variable > &&vs)
std::vector< carl::Variable > m_variables
EquationSubstitution(const FormulasT &cs, const std::vector< carl::Variable > &vs)
std::vector< carl::Variable > remaining_variables()
static bool find(V &ts, const T &t)
Definition: Alg.h:47
carl::Formula< Poly > FormulaT
Definition: types.h:37
carl::MultivariatePolynomial< Rational > Poly
Definition: types.h:25
carl::Formulas< Poly > FormulasT
Definition: types.h:39
#define SMTRAT_LOG_DEBUG(channel, msg)
Definition: logging.h:35