SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
NewGBPPModule.tpp
Go to the documentation of this file.
1 #include "NewGBPPModule.h"
2 
3 #include <carl-arith/poly/umvpoly/functions/Complexity.h>
4 #include <carl-arith/poly/umvpoly/functions/Groebner.h>
5 #include <carl-formula/formula/functions/PNF.h>
6 #include <boost/container/flat_set.hpp>
7 
8 namespace smtrat {
9 
10 FormulaT replace_groebner(const FormulaT& f) {
11  SMTRAT_LOG_FUNC("smtrat.newgbpp", f);
12 
13  // TODO reduce other subformulas using Groebner basis?
14 
15  if (!f.is_nary()) return f;
16 
17  FormulasT result;
18 
19  if (f.type() == carl::FormulaType::AND) {
20  boost::container::flat_set<Poly> equalities;
21  std::size_t old_complexity = 0;
22  for (const auto& sf : f) {
23  if (sf.type() == carl::FormulaType::CONSTRAINT && sf.constraint().relation() == carl::Relation::EQ) {
24  equalities.insert(sf.constraint().lhs().normalize());
25  old_complexity += carl::complexity(sf.constraint().lhs());
26  }
27  }
28  if (equalities.size()>1) {
29  auto basis = carl::groebner_basis(std::vector<Poly>(equalities.begin(), equalities.end()));
30  std::size_t new_complexity = 0;
31  for (const auto& eq : basis) {
32  new_complexity += carl::complexity(eq);
33  }
34  if (new_complexity <= old_complexity) {
35  for (const auto& eq : basis) {
36  result.emplace_back(ConstraintT(eq, carl::Relation::EQ));
37  }
38  }
39  }
40 
41  if (result.empty()) {
42  for (const auto& sf : f) {
43  if (sf.type() == carl::FormulaType::CONSTRAINT && sf.constraint().relation() == carl::Relation::EQ) {
44  result.emplace_back(sf);
45  }
46  }
47  }
48  }
49 
50  for (const auto& sf : f) {
51  if (sf.is_nary()) {
52  result.emplace_back(replace_groebner(sf));
53  } else if (sf.type() != carl::FormulaType::CONSTRAINT || sf.constraint().relation() != carl::Relation::EQ || f.type() != carl::FormulaType::AND) {
54  result.emplace_back(sf);
55  }
56  }
57 
58  return FormulaT(f.type(), std::move(result));
59 }
60 
61 template<class Settings>
62 NewGBPPModule<Settings>::NewGBPPModule(const ModuleInput* _formula, Conditionals& _conditionals, Manager* _manager)
63  : PModule(_formula, _conditionals, _manager, Settings::moduleName) {
64 }
65 
66 template<class Settings>
67 NewGBPPModule<Settings>::~NewGBPPModule() {}
68 
69 template<class Settings>
70 Answer NewGBPPModule<Settings>::checkCore() {
71  // TODO adapt for incrementality + backtracking + infeasible subsets to allow for inprocessing
72 
73  FormulaT matrix(rReceivedFormula());
74  carl::QuantifierPrefix prefix;
75  if ((carl::PROP_CONTAINS_QUANTIFIER_EXISTS <= matrix.properties()) || (carl::PROP_CONTAINS_QUANTIFIER_FORALL <= matrix.properties())) {
76  std::tie(prefix, matrix) = carl::to_pnf(matrix);
77  }
78  FormulaT formula = replace_groebner(matrix);
79  if (!prefix.empty()) {
80  formula = carl::to_formula(prefix, formula);
81  }
82 
83  Answer ans = SAT;
84  if (formula.is_false()) {
85  ans = UNSAT;
86  } else {
87  addSubformulaToPassedFormula(formula);
88  ans = runBackends();
89  }
90  if (ans == UNSAT) {
91  generateTrivialInfeasibleSubset();
92  }
93  return ans;
94 }
95 
96 } // namespace smtrat