3 * @author Florian Corzilius <corzilius@cs.rwth-aachen.de>
6 * Created on 2015-09-09.
11 #include <carl-formula/formula/functions/Substitution.h>
15 template<class Settings>
16 BEModule<Settings>::BEModule( const ModuleInput* _formula, Conditionals& _conditionals, Manager* _manager ):
17 PModule( _formula, _conditionals, _manager )
19 extractBoundsFunction = std::bind(&BEModule<Settings>::extractBounds, this, std::placeholders::_1);
22 template<class Settings>
23 BEModule<Settings>::~BEModule()
26 template<class Settings>
27 Answer BEModule<Settings>::checkCore()
29 if (is_minimizing()) { // TODO optimization possible?
30 SMTRAT_LOG_ERROR("smtrat.be", "Optimization not supported");
34 auto receivedFormula = firstUncheckedReceivedSubformula();
35 while( receivedFormula != rReceivedFormula().end() )
37 FormulaT formula = carl::visit_result( receivedFormula->formula(), extractBoundsFunction );
38 if( formula.is_false() )
40 receivedFormulasAsInfeasibleSubset( receivedFormula );
43 if( !formula.is_true() )
44 addSubformulaToPassedFormula( formula, receivedFormula->formula() );
47 Answer ans = runBackends();
49 generateTrivialInfeasibleSubset(); // TODO: compute a better infeasible subset
53 template<typename Settings>
54 FormulaT BEModule<Settings>::extractBounds(const FormulaT& formula)
56 if (formula.type() != carl::FormulaType::OR && formula.type() != carl::FormulaType::AND) return formula;
57 bool conjunction = formula.type() == carl::FormulaType::AND;
59 carl::ConstraintBounds<Poly> cb;
60 collectBounds(cb, formula, conjunction);
61 if (cb.empty()) return formula;
63 SMTRAT_LOG_DEBUG("smtrat.be", "Extracted bounds " << cb);
66 swapConstraintBounds(cb, f, conjunction);
68 return FormulaT(carl::FormulaType::AND, std::move(f));
70 for (const auto& poly: cb) {
71 if (!poly.first.is_variable()) continue;
72 std::vector<Choice> choices;
73 for (const auto& entry: poly.second) {
74 if (entry.second.first != carl::Relation::EQ) break;
75 choices.emplace_back(poly.first.single_variable(), entry.second.second);
77 if (choices.size() != poly.second.size()) continue;
78 for (const auto& c: choices) {
79 auto it = mReplacements.find(c);
80 if (it == mReplacements.end()) {
81 mReplacements.emplace(c, carl::fresh_boolean_variable());
89 template<typename Settings>
90 void BEModule<Settings>::collectBounds(carl::ConstraintBounds<Poly>& cb, const FormulaT& formula, bool conjunction) const {
91 for (const auto& f: formula.subformulas()) {
92 if (f.type() == carl::FormulaType::CONSTRAINT || (f.type() == carl::FormulaType::NOT && f.subformula().type() == carl::FormulaType::CONSTRAINT)) {
93 addConstraintBound(cb, f, conjunction);
98 template<typename Settings>
99 FormulaT BEModule<Settings>::applyReplacements(const FormulaT& f) const {
100 std::vector<carl::Variable> variables;
101 std::map<FormulaT, FormulaT> repl;
102 for (const auto& r: mReplacements) {
103 carl::Variable v = std::get<0>(r.first);
104 FormulaT form = std::get<1>(r.first);
106 variables.push_back(v);
107 repl.emplace(form, FormulaT(r.second));
109 FormulaT res = carl::substitute(f, repl);
110 carl::carlVariables remainingVars;
111 carl::variables(res,remainingVars);
113 for (const auto& v: variables) {
114 if (remainingVars.has(v)) {
115 for (const auto& r: mReplacements) {
116 if (v != std::get<0>(r.first)) continue;
117 FormulaT form = std::get<1>(r.first);
118 impl.push_back(FormulaT(carl::FormulaType::IMPLIES, {FormulaT(r.second), form}));
122 if (impl.empty()) return res;
124 return FormulaT(carl::FormulaType::AND, std::move(impl));