SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
Manager.h
Go to the documentation of this file.
1 /**
2  * @file Manager.h
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 #pragma once
13 
14 #include <vector>
15 
16 #include "StrategyGraph.h"
17 #ifdef SMTRAT_STRAT_PARALLEL_MODE
18 #include "ThreadPool.h"
19 #endif
20 
22 #include "ModuleInput.h"
23 #include "Module.h"
24 
25 namespace smtrat
26 {
27  class Module; // forward declaration
28  //class ModuleFactory; // forward declaration
29 
30  /**
31  * Base class for solvers. This is the interface to the user.
32  **/
33  class Manager
34  {
35  friend class Module;
36  private:
37 
38  /// a vector of flags, which indicate that an answer has been found of an antecessor module of the primary module
40  /// the constraints so far passed to the primary backend
42  /// The propositions of the passed formula.
43  carl::Condition mPropositions;
44  /// Contains the backtrack points, that are iterators to the last formula to be kept when backtracking to the respective point.
45  std::vector<ModuleInput::iterator> mBacktrackPoints;
46  /// all generated instances of modules
47  std::vector<Module*> mGeneratedModules;
48  /// a mapping of each module to its backends
49  std::map<const Module* const, std::vector<Module*> > mBackendsOfModules;
50  /// the primary backends
52  /// a Boolean showing whether the manager has received new constraint after the last consistency check
54  /// primary strategy
56  /// channel to write debug output
57  std::ostream mDebugOutputChannel;
58  /// the logic this solver considers
59  carl::Logic mLogic;
60  /// List of formula which are relevant for certain tasks
61  std::set<FormulaT> mInformationRelevantFormula;
62  /// Level of lemma generation
64  /// objective variable
65  carl::Variable mObjectiveVariable;
66  #ifdef SMTRAT_STRAT_PARALLEL_MODE
67  /// contains all threads to assign jobs to
68  ThreadPool* mpThreadPool;
69  /// the number of branches occurring in the strategy (the same as the number of leaves)
70  size_t mNumberOfBranches;
71  /// the number of cores of the system we run on
72  unsigned mNumberOfCores;
73  /// a flag indicating whether we might run in parallel eventually
74  bool mRunsParallel;
75  /// a mutex for exclusive access of the backends to members of this state
76  mutable std::mutex mBackendsMutex;
77 
78  /**
79  * Initializes some members of the manager, which are only needed for supporting parallel module calls.
80  */
81  void initialize();
82  #endif
83 
84  public:
85  /**
86  * Constructs a manager.
87  */
88  Manager();
89 
90  /**
91  * Destructs a manager.
92  */
93  ~Manager();
94 
95  // Main interfaces
96 
97  /**
98  * Informs the solver about a constraint. Optimally, it should be informed about all constraints,
99  * which it will receive eventually, before any of them is added as part of a formula with the
100  * interface add(..).
101  * @param _constraint The constraint to inform about.
102  * @return false, if it is easy to decide (for any module used of this solver), whether
103  * the constraint itself is inconsistent;
104  * true, otherwise.
105  */
106  bool inform( const FormulaT& _constraint );
107 
108  /**
109  * The inverse of informing about a constraint. All data structures which were kept regarding this
110  * constraint are going to be removed. Note, that this makes only sense if it is not likely enough
111  * that a formula with this constraint must be solved again.
112  * @param _constraint The constraint to remove from internal data structures.
113  */
114  void deinform( const FormulaT& _constraint );
115 
116  /**
117  * Adds the given formula to the conjunction of formulas, which will be considered for the next
118  * satisfiability check.
119  * @param _subformula The formula to add.
120  * @param _containsUnknownConstraints true, if the formula to add contains constraints, about which this solver
121  * was not yet informed.
122  * @return false, if it is easy to decide whether adding this formula creates a conflict;
123  * true, otherwise.
124  */
125  bool add( const FormulaT& _subformula, bool _containsUnknownConstraints = true );
126 
127  /**
128  * Checks the so far added formulas for satisfiability.
129  * @return True, if the conjunction of the so far added formulas is satisfiable;
130  * False, if it not satisfiable;
131  * Unknown, if this solver cannot decide whether it is satisfiable or not.
132  */
133  Answer check( bool _full = true );
134 
135  /**
136  * Pushes a backtrack point to the stack of backtrack points.
137  *
138  * Note, that this interface has not necessarily be used to apply a solver constructed
139  * with SMT-RAT, but is often required by state-of-the-art SMT solvers when embedding
140  * a theory solver constructed with SMT-RAT into them.
141  */
142  void push()
143  {
144  // Pushes iterator to last formula contained in the backtrack point.
145  auto it = mpPassedFormula->end();
146  // If the list is empty use end(), otherwise an iterator to the last element
147  if (!mpPassedFormula->empty()) --it;
148  mBacktrackPoints.emplace_back(it);
149  }
150 
151  /**
152  * Pops a backtrack point from the stack of backtrack points. This provokes, that
153  * all formulas which have been added after that backtrack point are removed.
154  *
155  * Note, that this interface has not necessarily be used to apply a solver constructed
156  * with SMT-RAT, but is often required by state-of-the-art SMT solvers when embedding
157  * a theory solver constructed with SMT-RAT into them.
158  */
159  bool pop();
160 
161  void pop( size_t _levels );
162 
163  void clear()
164  {
165  while( pop() );
166  }
167 
168  void setObjectiveVariable(carl::Variable var) {
170  }
171 
172  const carl::Variable& objectiveVariable() const {
173  return mObjectiveVariable;
174  }
175 
176  void reset();
177 
178  /**
179  * @return All infeasible subsets of the set so far added formulas.
180  *
181  * Note, that the conjunction of the so far added formulas must be inconsistent to
182  * receive an infeasible subset.
183  */
184  const std::vector<FormulaSetT>& infeasibleSubsets() const;
185 
186  /**
187  * Determines variables assigned by the currently found satisfying assignment to an equal value in their domain.
188  * @return A list of vectors of variables, stating that the variables in one vector are assigned to equal values.
189  */
190  std::list<std::vector<carl::Variable>> getModelEqualities() const;
191 
192  /**
193  * @return An assignment of the variables, which occur in the so far added
194  * formulas, to values of their domains, such that it satisfies the
195  * conjunction of these formulas.
196  *
197  * Note, that an assignment is only provided if the conjunction of so far added
198  * formulas is satisfiable. Furthermore, when solving non-linear real arithmetic
199  * formulas the assignment could contain other variables or freshly introduced
200  * variables.
201  */
202  const Model& model() const;
203 
204  /**
205  * @return A list of all assignments, such that they satisfy the conjunction of
206  * the so far added formulas.
207  *
208  * Note, that an assignment is only provided if the conjunction of so far added
209  * formulas is satisfiable. Furthermore, when solving non-linear real arithmetic
210  * formulas the assignment could contain other variables or freshly introduced
211  * variables.
212  */
213  const std::vector<Model>& allModels() const
214  {
216  return mpPrimaryBackend->allModels();
217  }
218 
219  /**
220  * Returns the lemmas/tautologies which were made during the last solving provoked by check(). These lemmas
221  * can be used in the same manner as infeasible subsets are used.
222  * @return The lemmas/tautologies made during solving.
223  */
224  std::vector<FormulaT> lemmas();
225 
226  /**
227  * @return The conjunction of so far added formulas.
228  */
229  const ModuleInput& formula() const
230  {
231  return *mpPassedFormula;
232  }
233 
234  // @todo: we want a const_iterator here, but gcc 4.8 doesn't allow us :( even though it should
236  {
237  return mpPassedFormula->begin();
238  }
240  {
241  return mpPassedFormula->end();
242  }
243 
244  /**
245  * Prints the currently found assignment of variables occurring in the so far
246  * added formulas to values of their domains, if the conjunction of these
247  * formulas is satisfiable.
248  */
249  void printAssignment() const;
250 
251  /**
252  * Prints all assignments of variables occurring in the so far
253  * added formulas to values of their domains, if the conjunction of these
254  * formulas is satisfiable.
255  * @param _out The stream to print on.
256  */
257  void printAllAssignments( std::ostream& _out = std::cout )
258  {
260  }
261 
262  /**
263  * Prints the first found infeasible subset of the set of received formulas.
264  * @param _out The stream to print on.
265  */
266  void printInfeasibleSubset( std::ostream& _out = std::cout ) const;
267 
268  /**
269  * Prints the stack of backtrack points.
270  * @param _out The stream to print on.
271  */
272  void printBackTrackStack( std::ostream& _out = std::cout ) const;
273 
274  /**
275  * Prints the strategy of the solver maintained by this manager.
276  * @param _out The stream to print on.
277  */
278  void printStrategyGraph( std::ostream& _out = std::cout ) const
279  {
280  _out << mStrategyGraph << std::endl;
281  }
282 
283  // Internally used interfaces
284 
285  /**
286  * @return All instantiated modules of the solver belonging to this manager.
287  */
288  const std::vector<Module*>& getAllGeneratedModules() const
289  {
290  return mGeneratedModules;
291  }
292 
293  /**
294  * @return The stream to print the debug information on.
295  */
296  std::ostream& rDebugOutputChannel()
297  {
298  return mDebugOutputChannel;
299  }
300 
301  /**
302  * @return A constant reference to the logic this solver considers.
303  */
304  auto logic() const {
305  return mLogic;
306  }
307 
308  /**
309  * @return A reference to the logic this solver considers.
310  */
311  auto& rLogic() {
312  return mLogic;
313  }
314 
315  /**
316  * Adds formula to InformationRelevantFormula
317  * @param formula Formula to add
318  */
320  {
322  }
323 
324  /**
325  * Deletes all InformationRelevantFormula
326  */
328  {
330  }
331 
332  /**
333  * Sets the current level for lemma generation
334  * @param level Level
335  */
336  inline void setLemmaLevel(LemmaLevel level)
337  {
338  mLemmaLevel = level;
339  }
340 
341  /**
342  * Checks if current lemma level is greater or equal to given level.
343  * @param level Level to check.
344  */
345  inline bool isLemmaLevel(LemmaLevel level)
346  {
347  return level <= mLemmaLevel;
348  }
349 
350  /**
351  * @return A pair of a Boolean and a formula, where the Boolean is true, if the input formula
352  * could be simplified to an equisatisfiable formula. The formula is equisatisfiable to this
353  * solver's input formula, if the Boolean is true.
354  */
355  std::pair<bool,FormulaT> getInputSimplified();
356 
357  /**
358  * Removes the formula at the given position in the conjunction of formulas,
359  * which will be considered for the next satisfiability check.
360  * @param _subformula The position of the formula to remove.
361  * @return An iterator to the formula after the position of the just removed
362  * formula. If the removed formula has been the last element, the
363  * end of the conjunction of formulas, which will be considered for the
364  * next satisfiability check is returned.
365  */
366  ModuleInput::iterator remove( ModuleInput::iterator _subformula ); // @todo: we want a const_iterator here, but gcc 4.8 doesn't allow us :( even though it should
367 
368  /**
369  * Temporarily added: (TODO: Discuss with Gereon)
370  * Removes the given formula in the conjunction of formulas,
371  * which will be considered for the next satisfiability check.
372  * @param _subformula The formula to remove.
373  * @return An iterator to the formula after the position of the just removed
374  * formula. If the removed formula has been the last element, the
375  * end of the conjunction of formulas, which will be considered for the
376  * next satisfiability check is returned.
377  */
378  ModuleInput::iterator remove( const FormulaT& _subformula )
379  {
380  return remove( mpPassedFormula->find( _subformula ) );
381  }
382 
383  protected:
384 
385  void setStrategy(const std::initializer_list<BackendLink>& backends) {
386  std::size_t id = mStrategyGraph.addRoot(backends);
387  std::size_t priority = mpPrimaryBackend->threadPriority().first;
389  SMTRAT_LOG_INFO("smtrat.strategygraph", "Strategygraph:" << std::endl << mStrategyGraph);
390  SMTRAT_LOG_INFO("smtrat.strategygraph", "Branches: " << mStrategyGraph.numberOfBranches());
391  }
392  void setStrategy(const BackendLink& backend) {
393  setStrategy({backend});
394  }
395  template<typename Module>
396  BackendLink addBackend(const std::initializer_list<BackendLink>& backends = {}) {
397  return mStrategyGraph.addBackend<Module>(backends);
398  }
399  template<typename Module>
401  return mStrategyGraph.addBackend<Module>({backend});
402  }
403  BackendLink& addEdge(std::size_t from, std::size_t to) {
404  return mStrategyGraph.addEdge(from, to);
405  }
406  /**
407  * Gets all backends so far instantiated according the strategy and all previous enquiries of the given module.
408  * @param _module The module to get all backends so far instantiated according the strategy and all previous enquiries of this module.
409  * @return All backends so far instantiated according the strategy and all previous enquiries of the given module.
410  */
411  std::vector<Module*> getAllBackends( Module* _module ) const
412  {
413  #ifdef SMTRAT_STRAT_PARALLEL_MODE
414  std::lock_guard<std::mutex> lock( mBackendsMutex );
415  #endif
416  auto iter = mBackendsOfModules.find( _module );
417  assert( iter != mBackendsOfModules.end() );
418  std::vector<Module*> result = iter->second;
419  return result;
420  }
421 
422  #ifdef SMTRAT_STRAT_PARALLEL_MODE
423  /**
424  * @return true, if we might run in parallel eventually;
425  * false, otherwise.
426  */
427  bool runsParallel()
428  {
429  initialize();
430  return mRunsParallel;
431  }
432  #endif
433 
434  /**
435  * Get the backends to call for the given problem instance required by the given module.
436  *
437  * @param _requiredBy The module asking for a backend.
438  * @param _foundAnswer A conditional
439  *
440  * @return A vector of modules, which the module defined by _requiredBy calls in parallel to achieve
441  * an answer to the given instance.
442  */
443  std::vector<Module*> getBackends( Module* _requiredBy, std::atomic_bool* _foundAnswer );
444 
445  #ifdef SMTRAT_STRAT_PARALLEL_MODE
446  /**
447  * Submits an enquiry of a module to solve its passed formula.
448  * @param _module The module which wants its passed formula to be solved.
449  * @param _full false, if this module should avoid too expensive procedures and rather return unknown instead.
450  * @param _objective
451  * @return A future containing the answer, as soon as the enquiry has been processed.
452  */
453  Answer runBackends(const std::vector<Module*>& modules, bool final, bool full, carl::Variable objective);
454  #endif
455 
456  /**
457  * Gets all InformationRelevantFormulas
458  * @return Set of all formulas
459  */
460  inline const std::set<FormulaT>& getInformationRelevantFormulas()
461  {
463  }
464  };
465 } // namespace smtrat
Base class for solvers.
Definition: Manager.h:34
bool mBackendsUptodate
a Boolean showing whether the manager has received new constraint after the last consistency check
Definition: Manager.h:53
void push()
Pushes a backtrack point to the stack of backtrack points.
Definition: Manager.h:142
bool inform(const FormulaT &_constraint)
Informs the solver about a constraint.
Definition: Manager.cpp:76
void printStrategyGraph(std::ostream &_out=std::cout) const
Prints the strategy of the solver maintained by this manager.
Definition: Manager.h:278
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 setObjectiveVariable(carl::Variable var)
Definition: Manager.h:168
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
ModuleInput::iterator remove(const FormulaT &_subformula)
Temporarily added: (TODO: Discuss with Gereon) Removes the given formula in the conjunction of formul...
Definition: Manager.h:378
std::vector< Module * > mGeneratedModules
all generated instances of modules
Definition: Manager.h:47
ModuleInput::iterator formulaBegin()
Definition: Manager.h:235
std::set< FormulaT > mInformationRelevantFormula
List of formula which are relevant for certain tasks.
Definition: Manager.h:61
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
bool isLemmaLevel(LemmaLevel level)
Checks if current lemma level is greater or equal to given level.
Definition: Manager.h:345
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
void addInformationRelevantFormula(const FormulaT &formula)
Adds formula to InformationRelevantFormula.
Definition: Manager.h:319
void clearInformationRelevantFormula()
Deletes all InformationRelevantFormula.
Definition: Manager.h:327
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
void setStrategy(const BackendLink &backend)
Definition: Manager.h:392
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
carl::Variable mObjectiveVariable
objective variable
Definition: Manager.h:65
std::ostream mDebugOutputChannel
channel to write debug output
Definition: Manager.h:57
carl::Condition mPropositions
The propositions of the passed formula.
Definition: Manager.h:43
void setStrategy(const std::initializer_list< BackendLink > &backends)
Definition: Manager.h:385
void printAssignment() const
Prints the currently found assignment of variables occurring in the so far added formulas to values o...
Definition: Manager.cpp:154
LemmaLevel mLemmaLevel
Level of lemma generation.
Definition: Manager.h:63
~Manager()
Destructs a manager.
Definition: Manager.cpp:51
BackendLink addBackend(const BackendLink &backend)
Definition: Manager.h:400
bool pop()
Pops a backtrack point from the stack of backtrack points.
Definition: Manager.cpp:166
const std::vector< Model > & allModels() const
Definition: Manager.h:213
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
void setLemmaLevel(LemmaLevel level)
Sets the current level for lemma generation.
Definition: Manager.h:336
carl::Logic mLogic
the logic this solver considers
Definition: Manager.h:59
const std::vector< Module * > & getAllGeneratedModules() const
Definition: Manager.h:288
std::vector< FormulaT > lemmas()
Returns the lemmas/tautologies which were made during the last solving provoked by check().
Definition: Manager.cpp:138
std::vector< Module * > getAllBackends(Module *_module) const
Gets all backends so far instantiated according the strategy and all previous enquiries of the given ...
Definition: Manager.h:411
std::ostream & rDebugOutputChannel()
Definition: Manager.h:296
auto & rLogic()
Definition: Manager.h:311
BackendLink & addEdge(std::size_t from, std::size_t to)
Definition: Manager.h:403
const ModuleInput & formula() const
Definition: Manager.h:229
void printAllAssignments(std::ostream &_out=std::cout)
Prints all assignments of variables occurring in the so far added formulas to values of their domains...
Definition: Manager.h:257
auto logic() const
Definition: Manager.h:304
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
ModuleInput::iterator formulaEnd()
Definition: Manager.h:239
void clear()
Definition: Manager.h:163
BackendLink addBackend(const std::initializer_list< BackendLink > &backends={})
Definition: Manager.h:396
Manager()
Constructs a manager.
Definition: Manager.cpp:23
const Model & model() const
Definition: Manager.cpp:132
const std::set< FormulaT > & getInformationRelevantFormulas()
Gets all InformationRelevantFormulas.
Definition: Manager.h:460
The input formula a module has to consider for it's satisfiability check.
Definition: ModuleInput.h:131
iterator find(const FormulaT &_formula)
Definition: ModuleInput.cpp:46
bool empty() const
Definition: ModuleInput.h:349
super::iterator iterator
Passing through the list::iterator.
Definition: ModuleInput.h:144
A base class for all kind of theory solving methods.
Definition: Module.h:70
thread_priority threadPriority() const
Definition: Module.h:414
void setThreadPriority(thread_priority _threadPriority)
Sets the priority of this module to get a thread for running its check procedure.
Definition: Module.h:423
virtual void updateAllModels()
Updates all satisfying models, if the solver has detected the consistency of the received formula,...
Definition: Module.cpp:261
void printAllModels(std::ostream &_out=std::cout)
Prints all assignments of this module satisfying its received formula if it satisfiable and this modu...
Definition: Module.cpp:1161
const std::vector< Model > & allModels() const
Definition: Module.h:471
std::size_t numberOfBranches() const
std::size_t addRoot(const std::initializer_list< BackendLink > &backends)
BackendLink & addEdge(std::size_t from, std::size_t to)
BackendLink addBackend(const std::initializer_list< BackendLink > &backends)
int var(Lit p)
Definition: SolverTypes.h:64
Class to create the formulas for axioms.
LemmaLevel
Definition: types.h:53
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
#define SMTRAT_LOG_INFO(channel, msg)
Definition: logging.h:34