SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
BEModule.tpp
Go to the documentation of this file.
1 /**
2  * @file BEModule.tpp
3  * @author Florian Corzilius <corzilius@cs.rwth-aachen.de>
4  *
5  * @version 2015-09-09
6  * Created on 2015-09-09.
7  */
8 
9 #include "BEModule.h"
10 
11 #include <carl-formula/formula/functions/Substitution.h>
12 
13 namespace smtrat
14 {
15  template<class Settings>
16  BEModule<Settings>::BEModule( const ModuleInput* _formula, Conditionals& _conditionals, Manager* _manager ):
17  PModule( _formula, _conditionals, _manager )
18  {
19  extractBoundsFunction = std::bind(&BEModule<Settings>::extractBounds, this, std::placeholders::_1);
20  }
21 
22  template<class Settings>
23  BEModule<Settings>::~BEModule()
24  {}
25 
26  template<class Settings>
27  Answer BEModule<Settings>::checkCore()
28  {
29  if (is_minimizing()) { // TODO optimization possible?
30  SMTRAT_LOG_ERROR("smtrat.be", "Optimization not supported");
31  assert(false);
32  }
33 
34  auto receivedFormula = firstUncheckedReceivedSubformula();
35  while( receivedFormula != rReceivedFormula().end() )
36  {
37  FormulaT formula = carl::visit_result( receivedFormula->formula(), extractBoundsFunction );
38  if( formula.is_false() )
39  {
40  receivedFormulasAsInfeasibleSubset( receivedFormula );
41  return UNSAT;
42  }
43  if( !formula.is_true() )
44  addSubformulaToPassedFormula( formula, receivedFormula->formula() );
45  ++receivedFormula;
46  }
47  Answer ans = runBackends();
48  if( ans == UNSAT )
49  generateTrivialInfeasibleSubset(); // TODO: compute a better infeasible subset
50  return ans;
51  }
52 
53  template<typename Settings>
54  FormulaT BEModule<Settings>::extractBounds(const FormulaT& formula)
55  {
56  if (formula.type() != carl::FormulaType::OR && formula.type() != carl::FormulaType::AND) return formula;
57  bool conjunction = formula.type() == carl::FormulaType::AND;
58 
59  carl::ConstraintBounds<Poly> cb;
60  collectBounds(cb, formula, conjunction);
61  if (cb.empty()) return formula;
62 
63  SMTRAT_LOG_DEBUG("smtrat.be", "Extracted bounds " << cb);
64  if (conjunction) {
65  FormulasT f;
66  swapConstraintBounds(cb, f, conjunction);
67  f.push_back(formula);
68  return FormulaT(carl::FormulaType::AND, std::move(f));
69  } else {
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);
76  }
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());
82  }
83  }
84  }
85  }
86  return formula;
87  }
88 
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);
94  }
95  }
96  }
97 
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);
105 
106  variables.push_back(v);
107  repl.emplace(form, FormulaT(r.second));
108  }
109  FormulaT res = carl::substitute(f, repl);
110  carl::carlVariables remainingVars;
111  carl::variables(res,remainingVars);
112  FormulasT impl;
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}));
119  }
120  }
121  }
122  if (impl.empty()) return res;
123  impl.push_back(res);
124  return FormulaT(carl::FormulaType::AND, std::move(impl));
125  }
126 }
127 
128