SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
Manager.cpp
Go to the documentation of this file.
1 /**
2  * @file Manager.cpp
3  *
4  * @author Florian Corzilius
5  * @author Ulrich Loup
6  * @author Sebastian Junges
7  * @author Henrik Schmitz
8  * @since 2012-01-18
9  * @version 2013-01-11
10  */
11 
12 #include "Manager.h"
13 #include "StrategyGraph.h"
14 #include <functional>
15 
16 #include <typeinfo>
17 
18 namespace smtrat
19 {
20 
21  // Constructor.
22 
24  mPrimaryBackendFoundAnswer(smtrat::Conditionals(1, new std::atomic_bool(false))),
25  mpPassedFormula(new ModuleInput()),
26  mBacktrackPoints(),
27  mGeneratedModules(),
28  mBackendsOfModules(),
29  mpPrimaryBackend( new Module( mpPassedFormula, mPrimaryBackendFoundAnswer, this ) ),
30  mStrategyGraph(),
31  mDebugOutputChannel( std::cout.rdbuf() ),
32  mLogic( carl::Logic::UNDEFINED ),
33  mInformationRelevantFormula(),
34  mLemmaLevel(LemmaLevel::NONE)
35  #ifdef SMTRAT_STRAT_PARALLEL_MODE
36  ,
37  mpThreadPool( nullptr ),
38  mNumberOfBranches( 0 ),
39  mNumberOfCores( 0 ),
40  mRunsParallel( false )
41  #endif
42  {
44  // inform it about all constraints
45  auto f = [] ( Module* _module, const FormulaT& _constraint ) { _module->inform( _constraint ); };
46  carl::FormulaPool<Poly>::getInstance().forallDo<Module>( f, mpPrimaryBackend );
47  }
48 
49  // Destructor.
50 
52  {
53  #ifdef SMTRAT_STRAT_PARALLEL_MODE
54  if( mpThreadPool != nullptr )
55  delete mpThreadPool;
56  #endif
57  #ifndef SMTRAT_STRAT_PARALLEL_MODE
58  // TODO: Parallel solving causes for some reason segfaults in the modules' destructors
59  // after the specific module's destructor and before entering ~Module()
60  while( !mGeneratedModules.empty() )
61  {
62  Module* ptsmodule = mGeneratedModules.back();
63  mGeneratedModules.pop_back();
64  delete ptsmodule;
65  }
66  while( !mPrimaryBackendFoundAnswer.empty() )
67  {
68  std::atomic_bool* toDelete = mPrimaryBackendFoundAnswer.back();
69  mPrimaryBackendFoundAnswer.pop_back();
70  delete toDelete;
71  }
72  delete mpPassedFormula;
73  #endif
74  }
75 
76  bool Manager::inform( const FormulaT& _constraint )
77  {
78  return mpPrimaryBackend->inform( _constraint );
79  }
80 
81  void Manager::deinform( const FormulaT& _constraint )
82  {
83  mpPrimaryBackend->deinform( _constraint );
84  }
85 
86  bool Manager::add( const FormulaT& _subformula, bool _containsUnknownConstraints )
87  {
88  if( _containsUnknownConstraints )
89  {
90  carl::visit(_subformula, [this](const FormulaT& f){
91  switch (f.type()) {
92  case carl::FormulaType::CONSTRAINT:
93  case carl::FormulaType::VARCOMPARE:
94  case carl::FormulaType::BITVECTOR:
95  case carl::FormulaType::UEQ:
96  mpPrimaryBackend->inform(f);
97  break;
98  default:
99  break;
100  }
101  });
102  }
103  auto res = mpPassedFormula->add( _subformula );
104  if( res.second )
105  {
106  bool r = true;
107  for (auto it = res.first; it != mpPassedFormula->end(); it++) {
108  r = r && mpPrimaryBackend->add( it );
109  }
110  return r;
111  }
112  return true;
113  }
114 
115  Answer Manager::check( bool _full )
116  {
117  *mPrimaryBackendFoundAnswer.back() = false;
119  return mpPrimaryBackend->check( true, _full, objectiveVariable() );
120  }
121 
122  const std::vector<FormulaSetT>& Manager::infeasibleSubsets() const
123  {
125  }
126 
127  std::list<std::vector<carl::Variable>> Manager::getModelEqualities() const
128  {
130  }
131 
132  const Model& Manager::model() const
133  {
135  return mpPrimaryBackend->model();
136  }
137 
138  std::vector<FormulaT> Manager::lemmas()
139  {
140  std::vector<FormulaT> result;
142  for( const auto& lem : mpPrimaryBackend->lemmas() )
143  {
144  result.push_back( lem.mLemma );
145  }
146  return result;
147  }
148 
149  std::pair<bool,FormulaT> Manager::getInputSimplified()
150  {
152  }
153 
155  {
157  }
158 
160  {
161  assert( _subformula != mpPassedFormula->end() );
162  mpPrimaryBackend->remove( _subformula );
163  return mpPassedFormula->erase( _subformula );
164  }
165 
167  {
168  if (mBacktrackPoints.empty()) return false;
169  while (!mpPassedFormula->empty()) {
170  // Remove until the list is either empty or the backtrack point is hit.
171  auto it = mpPassedFormula->end();
172  --it;
173  if (it == mBacktrackPoints.back()) break;
174  remove(it);
175  }
176  mBacktrackPoints.pop_back();
177  return true;
178  }
179 
180  void Manager::pop( size_t _levels )
181  {
182  for( ; _levels > 0; --_levels )
183  if( !pop() ) return;
184  }
185 
187  {
188  while( pop() );
189  while(!mpPassedFormula->empty()) {
190  auto it = mpPassedFormula->end();
191  it--;
192  remove(it);
193  }
194  assert( mpPassedFormula->empty() );
195  assert(mBacktrackPoints.empty());
196  mBackendsOfModules.clear();
197  while( !mGeneratedModules.empty() )
198  {
199  Module* ptsmodule = mGeneratedModules.back();
200  mGeneratedModules.pop_back();
201  delete ptsmodule;
202  }
203  while( mPrimaryBackendFoundAnswer.size() > 1 )
204  {
205  std::atomic_bool* toDelete = mPrimaryBackendFoundAnswer.back();
206  mPrimaryBackendFoundAnswer.pop_back();
207  delete toDelete;
208  }
209  mLogic = carl::Logic::UNDEFINED;
212  mGeneratedModules.push_back( mpPrimaryBackend );
213  }
214 
215  // Methods.
216 
217  #ifdef SMTRAT_STRAT_PARALLEL_MODE
218  void Manager::initialize()
219  {
220  if (mNumberOfCores != 0) return;
221  mNumberOfBranches = mStrategyGraph.numberOfBranches();
222  if( mNumberOfBranches > 1 )
223  {
224  mNumberOfCores = std::thread::hardware_concurrency();
225  if( mNumberOfCores > 1 )
226  {
227  //mStrategyGraph.setThreadAndBranchIds();
228 // mStrategyGraph.tmpPrint();
229 // std::this_thread::sleep_for(std::chrono::seconds(29));
230  mRunsParallel = true;
231  mpThreadPool = new ThreadPool(mNumberOfCores);
232  }
233  }
234  }
235  #endif
236 
237  void Manager::printInfeasibleSubset( std::ostream& _out ) const
238  {
239  _out << "(";
240  if( !mpPrimaryBackend->infeasibleSubsets().empty() )
241  {
242  const FormulaSetT& infSubSet = *mpPrimaryBackend->infeasibleSubsets().begin();
243  if( infSubSet.size() == 1 )
244  {
245  _out << *infSubSet.begin();
246  }
247  else
248  {
249  for( auto subFormula = infSubSet.begin(); subFormula != infSubSet.end(); ++subFormula )
250  {
251  _out << *subFormula << std::endl;
252  }
253  }
254  }
255  _out << ")" << std::endl;
256  }
257 
258  void Manager::printBackTrackStack( std::ostream& _out ) const
259  {
260  auto btlIter = mBacktrackPoints.begin();
261  std::size_t btlCounter = 0;
262  while (btlIter != mBacktrackPoints.end() && *btlIter == mpPassedFormula->end()) {
263  _out << "btl_" << btlCounter << ": (and ) skip" << std::endl;
264  btlCounter++;
265  btlIter++;
266  }
267  _out << "btl_" << btlCounter << ": (and";
268  for (auto it = mpPassedFormula->begin(); it != mpPassedFormula->end(); it++) {
269  _out << " " << it->formula();
270  if (btlIter != mBacktrackPoints.end() && *btlIter == it) {
271  btlCounter++;
272  btlIter++;
273  _out << " )" << std::endl << "btl_" << btlCounter << ": (and";
274  }
275  }
276  _out << " )" << std::endl << std::endl;;
277  }
278 
279  std::vector<Module*> Manager::getBackends( Module* _requiredBy, std::atomic_bool* _foundAnswer )
280  {
281  #ifdef SMTRAT_STRAT_PARALLEL_MODE
282  std::lock_guard<std::mutex> lock(mBackendsMutex);
283  #endif
284  std::vector<Module*> backends;
285  std::vector<Module*>& allBackends = mBackendsOfModules[_requiredBy];
286  _requiredBy->mpPassedFormula->updateProperties();
287  // Obtain list of backends in the strategy
288  auto factories = mStrategyGraph.getBackends(_requiredBy->threadPriority().second, _requiredBy->pPassedFormula()->properties());
289  for (const auto& iter: factories) {
290  // Check if the respective module has already been created
291  bool moduleExists = false;
292  for (const auto& candidate: allBackends) {
293  if (candidate->threadPriority() == iter.first) {
294  backends.emplace_back(candidate);
295  moduleExists = true;
296  break;
297  }
298  }
299  // Create a new module with the given factory
300  if (!moduleExists) {
301  auto factory = iter.second;
302  assert(factory != nullptr);
303  smtrat::Conditionals foundAnswers = smtrat::Conditionals( _requiredBy->answerFound() );
304  foundAnswers.emplace_back(_foundAnswer);
305  Module* newBackend = factory->create(_requiredBy->pPassedFormula(), foundAnswers, this);
306  newBackend->setId(mGeneratedModules.size());
307  newBackend->setThreadPriority(iter.first);
308  mGeneratedModules.emplace_back(newBackend);
309  allBackends.emplace_back(newBackend);
310  backends.emplace_back(newBackend);
311  for(const auto& cons: _requiredBy->informedConstraints()) {
312  newBackend->inform(cons);
313  }
314  for(auto form = _requiredBy->rPassedFormula().begin(); form != _requiredBy->firstSubformulaToPass(); form++) {
315  newBackend->add(form);
316  }
317  }
318  }
319  return backends;
320  }
321 
322  #ifdef SMTRAT_STRAT_PARALLEL_MODE
323  Answer Manager::runBackends(const std::vector<Module*>& _modules, bool _final, bool _full, carl::Variable _objective) {
324  return mpThreadPool->runBackends(_modules, _final, _full, _objective);
325  }
326  #endif
327 } // namespace smtrat
bool inform(const FormulaT &_constraint)
Informs the solver about a constraint.
Definition: Manager.cpp:76
const std::vector< FormulaSetT > & infeasibleSubsets() const
Definition: Manager.cpp:122
ModuleInput * mpPassedFormula
the constraints so far passed to the primary backend
Definition: Manager.h:41
void deinform(const FormulaT &_constraint)
The inverse of informing about a constraint.
Definition: Manager.cpp:81
friend class Module
Definition: Manager.h:35
smtrat::Conditionals mPrimaryBackendFoundAnswer
a vector of flags, which indicate that an answer has been found of an antecessor module of the primar...
Definition: Manager.h:39
Module * mpPrimaryBackend
the primary backends
Definition: Manager.h:51
std::vector< Module * > mGeneratedModules
all generated instances of modules
Definition: Manager.h:47
ModuleInput::iterator remove(ModuleInput::iterator _subformula)
Removes the formula at the given position in the conjunction of formulas, which will be considered fo...
Definition: Manager.cpp:159
std::vector< Module * > getBackends(Module *_requiredBy, std::atomic_bool *_foundAnswer)
Get the backends to call for the given problem instance required by the given module.
Definition: Manager.cpp:279
void printInfeasibleSubset(std::ostream &_out=std::cout) const
Prints the first found infeasible subset of the set of received formulas.
Definition: Manager.cpp:237
StrategyGraph mStrategyGraph
primary strategy
Definition: Manager.h:55
const carl::Variable & objectiveVariable() const
Definition: Manager.h:172
std::map< const Module *const, std::vector< Module * > > mBackendsOfModules
a mapping of each module to its backends
Definition: Manager.h:49
std::list< std::vector< carl::Variable > > getModelEqualities() const
Determines variables assigned by the currently found satisfying assignment to an equal value in their...
Definition: Manager.cpp:127
std::vector< ModuleInput::iterator > mBacktrackPoints
Contains the backtrack points, that are iterators to the last formula to be kept when backtracking to...
Definition: Manager.h:45
void printAssignment() const
Prints the currently found assignment of variables occurring in the so far added formulas to values o...
Definition: Manager.cpp:154
~Manager()
Destructs a manager.
Definition: Manager.cpp:51
bool pop()
Pops a backtrack point from the stack of backtrack points.
Definition: Manager.cpp:166
bool add(const FormulaT &_subformula, bool _containsUnknownConstraints=true)
Adds the given formula to the conjunction of formulas, which will be considered for the next satisfia...
Definition: Manager.cpp:86
carl::Logic mLogic
the logic this solver considers
Definition: Manager.h:59
std::vector< FormulaT > lemmas()
Returns the lemmas/tautologies which were made during the last solving provoked by check().
Definition: Manager.cpp:138
void printBackTrackStack(std::ostream &_out=std::cout) const
Prints the stack of backtrack points.
Definition: Manager.cpp:258
std::pair< bool, FormulaT > getInputSimplified()
Definition: Manager.cpp:149
Answer check(bool _full=true)
Checks the so far added formulas for satisfiability.
Definition: Manager.cpp:115
Manager()
Constructs a manager.
Definition: Manager.cpp:23
const Model & model() const
Definition: Manager.cpp:132
The input formula a module has to consider for it's satisfiability check.
Definition: ModuleInput.h:131
void updateProperties()
Updates all properties of the formula underlying this module input.
carl::Condition properties() const
Definition: ModuleInput.h:175
iterator erase(iterator _formula)
Definition: ModuleInput.cpp:98
bool empty() const
Definition: ModuleInput.h:349
super::iterator iterator
Passing through the list::iterator.
Definition: ModuleInput.h:144
std::pair< iterator, bool > add(const FormulaT &_formula, bool _mightBeConjunction=true)
Definition: ModuleInput.h:430
A base class for all kind of theory solving methods.
Definition: Module.h:70
const std::vector< FormulaSetT > & infeasibleSubsets() const
Definition: Module.h:480
thread_priority threadPriority() const
Definition: Module.h:414
const ModuleInput * pPassedFormula() const
Definition: Module.h:447
virtual void updateModel() const
Updates the model, if the solver has detected the consistency of the received formula,...
Definition: Module.cpp:250
virtual std::list< std::vector< carl::Variable > > getModelEqualities() const
Partition the variables from the current model into equivalence classes according to their assigned v...
Definition: Module.cpp:308
void deinform(const FormulaT &_constraint)
The inverse of informing about a constraint.
Definition: Module.cpp:124
ModuleInput::const_iterator firstSubformulaToPass() const
Definition: Module.h:581
virtual std::pair< bool, FormulaT > getReceivedFormulaSimplified()
Definition: Module.cpp:945
void setThreadPriority(thread_priority _threadPriority)
Sets the priority of this module to get a thread for running its check procedure.
Definition: Module.h:423
bool inform(const FormulaT &_constraint)
Informs the module about the given constraint.
Definition: Module.cpp:117
const std::vector< Lemma > & lemmas() const
Definition: Module.h:565
void setId(std::size_t _id)
Sets this modules unique ID to identify itself.
Definition: Module.h:405
const Model & model() const
Definition: Module.h:463
void updateLemmas()
Stores all lemmas of any backend of this module in its own lemma vector.
Definition: Module.cpp:919
const smtrat::Conditionals & answerFound() const
Definition: Module.h:597
virtual Answer check(bool _final=false, bool _full=true, carl::Variable _objective=carl::Variable::NO_VARIABLE)
Checks the received formula for consistency.
Definition: Module.cpp:86
virtual void remove(ModuleInput::const_iterator _subformula)
Removes everything related to the given sub-formula of the received formula.
Definition: Module.cpp:159
const ModuleInput & rPassedFormula() const
Definition: Module.h:455
void printModel(std::ostream &_out=std::cout) const
Prints the assignment of this module satisfying its received formula if it satisfiable and this modul...
Definition: Module.cpp:1151
const carl::FastSet< FormulaT > & informedConstraints() const
Definition: Module.h:504
bool add(ModuleInput::const_iterator _subformula)
The module has to take the given sub-formula of the received formula into account.
Definition: Module.cpp:138
ModuleInput * mpPassedFormula
The formula passed to the backends of this module.
Definition: Module.h:190
std::set< std::pair< thread_priority, AbstractModuleFactory * > > getBackends(std::size_t vertex, const carl::Condition &condition) const
std::size_t numberOfBranches() const
std::size_t getRoot() const
projection_compare::Candidate< Poly > candidate(const Poly &p, const Poly &q, std::size_t level)
Class to create the formulas for axioms.
LemmaLevel
Definition: types.h:53
@ NONE
Definition: types.h:53
carl::FormulaSet< Poly > FormulaSetT
Definition: types.h:41
carl::Formula< Poly > FormulaT
Definition: types.h:37
carl::Model< Rational, Poly > Model
Definition: model.h:13
Answer
An enum with the possible answers a Module can give.
Definition: types.h:57
std::vector< std::atomic_bool * > Conditionals
A vector of atomic bool pointers.
Definition: types.h:17
std::pair< std::size_t, std::size_t > thread_priority
Definition: types.h:50