1 #include "NewGBPPModule.h"
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>
10 FormulaT replace_groebner(const FormulaT& f) {
11 SMTRAT_LOG_FUNC("smtrat.newgbpp", f);
13 // TODO reduce other subformulas using Groebner basis?
15 if (!f.is_nary()) return f;
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());
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);
34 if (new_complexity <= old_complexity) {
35 for (const auto& eq : basis) {
36 result.emplace_back(ConstraintT(eq, carl::Relation::EQ));
42 for (const auto& sf : f) {
43 if (sf.type() == carl::FormulaType::CONSTRAINT && sf.constraint().relation() == carl::Relation::EQ) {
44 result.emplace_back(sf);
50 for (const auto& sf : f) {
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);
58 return FormulaT(f.type(), std::move(result));
61 template<class Settings>
62 NewGBPPModule<Settings>::NewGBPPModule(const ModuleInput* _formula, Conditionals& _conditionals, Manager* _manager)
63 : PModule(_formula, _conditionals, _manager, Settings::moduleName) {
66 template<class Settings>
67 NewGBPPModule<Settings>::~NewGBPPModule() {}
69 template<class Settings>
70 Answer NewGBPPModule<Settings>::checkCore() {
71 // TODO adapt for incrementality + backtracking + infeasible subsets to allow for inprocessing
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);
78 FormulaT formula = replace_groebner(matrix);
79 if (!prefix.empty()) {
80 formula = carl::to_formula(prefix, formula);
84 if (formula.is_false()) {
87 addSubformulaToPassedFormula(formula);
91 generateTrivialInfeasibleSubset();