SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
LRAModule.h
Go to the documentation of this file.
1 /**
2  * @file LRAModule.h
3  * @author Florian Corzilius <corzilius@cs.rwth-aachen.de>
4  * @since 2012-04-05
5  * @version 2014-10-01
6  *
7  * Supports optimization.
8  *
9  */
10 
11 #pragma once
12 
13 
14 #include <smtrat-solver/Module.h>
16 #include "tableau/Tableau.h"
17 #include "LRAModuleStatistics.h"
18 #include "LRASettings.h"
19 #include <stdio.h>
20 
21 namespace smtrat
22 {
23 
24  /**
25  * A module which performs the Simplex method on the linear part of it's received formula.
26  */
27  template<class Settings>
28  class LRAModule:
29  public Module
30  {
31  public:
32  /// Number type of the underlying value of a bound of a variable within the LRAModule.
33  typedef typename Settings::BoundType LRABoundType;
34  /// Type of an entry within the tableau.
35  typedef typename Settings::EntryType LRAEntryType;
36  /// Type of a bound of a variable within the LRAModule.
38  /// A variable of the LRAModule, being either a original variable or a slack variable representing a linear polynomial.
40  /// The type of the assignment of a variable maintained by the LRAModule. It consists of a tuple of two value of the bound type.
43  std::string moduleName() const
44  {
45  return SettingsType::moduleName;
46  }
47  /**
48  * Stores a formula, being part of the received formula of this module, and the position of
49  * this formula in the passed formula.
50  * TODO: Maybe it is enough to store a mapping of the formula to the position.
51  */
52  struct Context
53  {
54  /// The formula in the received formula.
56  /// The position of this formula in the passed formula.
58 
59  Context( const FormulaT& _origin, ModuleInput::iterator _pos ):
60  origin( _origin ),
61  position( _pos )
62  {}
63  };
64  /// Maps an original variable to it's corresponding LRAModule variable.
65  typedef carl::FastMap<carl::Variable, LRAVariable*> VarVariableMap;
66  /// Maps a linear polynomial to it's corresponding LRAModule variable.
67  typedef carl::FastPointerMap<typename Poly::PolyType, LRAVariable*> ExVariableMap;
68  /// Maps constraint to the bounds it represents (e.g., equations represent two bounds)
69  typedef carl::FastMap<FormulaT, std::vector<const LRABound*>*> ConstraintBoundsMap;
70  /// Stores the position of a received formula in the passed formula.
71  typedef carl::FastMap<FormulaT, Context> ConstraintContextMap;
72  /// The tableau which is the main data structure maintained by the LRAModule responsible for the pivoting steps.
74 
75  private:
76 
77  /**
78  * A flag, which is true if this module has already set all bounds corresponding to
79  * the constraint, of which this module has been informed.
80  */
82  /// A flag which is true, if the non-linear constraints fulfill the current assignment.
84  /// A flag which is set, if a supremum or infimum of a LRAModule variable has been changed.
86  ///
88  ///
89  mutable bool mRationalModelComputed;
90  ///
92  /**
93  * Contains the main data structures of this module. It maintains for each LRAModule variable a row
94  * or a column. On this tableau pivoting can be performed as the well known Simplex method performs.
95  */
97  /// Stores all linear constraints of which this module has been once informed.
98  carl::FastSet<FormulaT> mLinearConstraints;
99  /// Stores all non-linear constraints which are currently added (by assertSubformula) to this module.
100  carl::FastSet<FormulaT> mNonlinearConstraints;
101  /**
102  * Those constraints p!=0, which are added to this module (part of the received formula), which
103  * are resolved by a constraints as p<0, p<=0, p>=0 or p>0.
104  */
106  /**
107  * Those constraints p!=0, which are added to this module (part of the received formula), which
108  * are not yet resolved by a constraints as p<0, p<=0, p>=0 or p>0.
109  */
111  /**
112  * The delta value, which influencing the assignment such that it also fulfills all strict
113  * inequalities (cf. Integrating Simplex with DPLL(T ) by B. Dutertre and L. de Moura).
114  */
115  carl::Variable mDelta;
116  /// Stores the bounds, which would influence a backend call because of recent changes.
117  std::vector<const LRABound* > mBoundCandidatesToPass;
118  ///
120  #ifdef SMTRAT_DEVOPTION_Statistics
121  /// Stores the yet collected statistics of this LRAModule.
122  LRAModuleStatistics& mStatistics = statistics_get<LRAModuleStatistics>(moduleName() + "_" + std::to_string(id()));
123  #endif
124 
125  public:
126 
127  /**
128  * Constructs a LRAModule.
129  * @param _type The type of this module being LRAModule.
130  * @param _formula The formula passed to this module, called received formula.
131  * @param _settings [Not yet used.]
132  * @param _conditionals Vector of Booleans: If any of them is true, we have to terminate a running check procedure.
133  * @param _manager A reference to the manager of the solver using this module.
134  */
135  LRAModule( const ModuleInput* _formula, Conditionals& _conditionals, Manager* _manager = NULL );
136 
137  /**
138  * Destructs this LRAModule.
139  */
140  virtual ~LRAModule();
141 
142  // Interfaces.
143 
144  /**
145  * Informs this module about the existence of the given constraint, which means
146  * that it could be added in future.
147  * @param _constraint The constraint to inform about.
148  * @return false, if the it can be determined that the constraint itself is conflicting;
149  * true, otherwise.
150  */
151  bool informCore( const FormulaT& _constraint );
152 
153  /**
154  * The inverse of informing about a constraint. All data structures which were kept regarding this
155  * constraint are going to be removed. Note, that this makes only sense if it is not likely enough
156  * that a formula with this constraint must be solved again.
157  * @param _constraint The constraint to remove from internal data structures.
158  */
159  void deinformCore( const FormulaT& _constraint );
160 
161  /**
162  * Initializes the tableau according to all linear constraints, of which this module has been informed.
163  */
164  void init();
165 
166  /**
167  * The module has to take the given sub-formula of the received formula into account.
168  * @param _subformula The sub-formula to take additionally into account.
169  * @return false, if it can be easily decided that this sub-formula causes a conflict with
170  * the already considered sub-formulas;
171  * true, otherwise.
172  */
174 
175  /**
176  * Removes everything related to the given sub-formula of the received formula.
177  * @param _subformula The sub formula of the received formula to remove.
178  */
180 
181  /**
182  * Checks the received formula for consistency.
183  * @return SAT, if the received formula is satisfiable;
184  * UNSAT, if the received formula is not satisfiable;
185  * Unknown, otherwise.
186  */
188 
189  /*
190  * Added Functions for infeasibility
191  */
193 
195 
196  /**
197  * Updates the model, if the solver has detected the consistency of the received formula, beforehand.
198  */
199  void updateModel() const;
200 
201  /**
202  * @return 0, if the given formula is conflicted by the current model;
203  * 1, if the given formula is satisfied by the current model;
204  * 2, otherwise
205  */
206  unsigned currentlySatisfied( const FormulaT& ) const;
207 
208  /**
209  * Gives a rational model if the received formula is satisfiable. Note, that it
210  * is calculated from scratch every time you call this method.
211  * @return The rational model.
212  */
214 
215  Answer optimize( Answer _result );
216 
218 
220 
221  void createInfeasibleSubsets( lra::EntryID _tableauEntry );
222 
223  /**
224  * Returns the bounds of the variables as intervals.
225  * @return The bounds of the variables as intervals.
226  */
228 
229  /**
230  * Prints all linear constraints.
231  * @param _out The output stream to print on.
232  * @param _init The beginning of each line to print.
233  */
234  void printLinearConstraints( std::ostream& _out = std::cout, const std::string _init = "" ) const;
235 
236  /**
237  * Prints all non-linear constraints.
238  * @param _out The output stream to print on.
239  * @param _init The beginning of each line to print.
240  */
241  void printNonlinearConstraints( std::ostream& _out = std::cout, const std::string _init = "" ) const;
242 
243  /**
244  * Prints the mapping of constraints to their corresponding bounds.
245  * @param _out The output stream to print on.
246  * @param _init The beginning of each line to print.
247  */
248  void printConstraintToBound( std::ostream& _out = std::cout, const std::string _init = "" ) const;
249 
250  /**
251  * Prints the strictest bounds, which have to be passed the backend in case.
252  * @param _out The output stream to print on.
253  * @param _init The beginning of each line to print.
254  */
255  void printBoundCandidatesToPass( std::ostream& _out = std::cout, const std::string _init = "" ) const;
256 
257  /**
258  * Prints the current rational assignment.
259  * @param _out The output stream to print on.
260  * @param _init The beginning of each line to print.
261  */
262  void printRationalModel( std::ostream& _out = std::cout, const std::string _init = "" ) const;
263 
264  /**
265  * Prints the current tableau.
266  * @param _out The output stream to print on.
267  * @param _init The beginning of each line to print.
268  */
269  void printTableau( std::ostream& _out = std::cout, const std::string _init = "" ) const;
270 
271  /**
272  * Prints all lra variables and their assignments.
273  * @param _out The output stream to print on.
274  * @param _init The beginning of each line to print.
275  */
276  void printVariables( std::ostream& _out = std::cout, const std::string _init = "" ) const;
277 
278  /**
279  * @return A constant reference to the original variables.
280  */
282  {
283  return mTableau.originalVars();
284  }
285 
286  /**
287  * @return A constant reference to the slack variables.
288  */
290  {
291  return mTableau.slackVars();
292  }
293 
294  /**
295  * @param _constraint The constraint to get the slack variable for.
296  * @return The slack variable constructed for the linear polynomial without the constant part in the given constraint.
297  */
298  const LRAVariable* getSlackVariable( const FormulaT& _constraint ) const
299  {
300  typename ConstraintBoundsMap::const_iterator iter = mTableau.constraintToBound().find( _constraint );
301  assert( iter != mTableau.constraintToBound().end() );
302  return (*iter->second->begin())->pVariable();
303  }
304 
305  private:
306  // Methods.
307 
308  /**
309  * Adds the refinements learned during pivoting to the deductions.
310  */
312 
313  void learnRefinement( const typename LRATableau::LearnedBound& _learnedBound, bool _upperBound );
314 
315  FormulasT createPremise( const std::vector< const LRABound*>& _premiseBounds, bool& _premiseOnlyEqualities ) const;
316 
317  /**
318  * Adapt the passed formula, such that it consists of the finite infimums and supremums
319  * of all variables and the non linear constraints.
320  */
322 
323  /**
324  * Checks whether the current assignment of the linear constraints fulfills the non linear constraints.
325  * @return true, if the current assignment of the linear constraints fulfills the non linear constraints;
326  * false, otherwise.
327  */
329 
330  /**
331  * Activate the given bound and update the supremum, the infimum and the assignment of
332  * variable to which the bound belongs.
333  * @param _bound The bound to activate.
334  * @param _formula The constraints which form this bound.
335  */
336  void activateBound( const LRABound* _bound, const FormulaT& _formula );
337 
338  /**
339  * Activates a strict bound as a result of the two constraints p!=0 and p<=0 resp. p>=0.
340  * @param _neqOrigin The constraint with != as relation symbol.
341  * @param _weakBound The bound corresponding to either a constraint with <= resp. >= as relation symbol.
342  * @param _strictBound The bound to activate corresponding to either a constraint with < or > as relation symbol.
343  */
344  void activateStrictBound( const FormulaT& _neqOrigin, const LRABound& _weakBound, const LRABound* _strictBound );
345 
346  /**
347  * Creates a bound corresponding to the given constraint.
348  * @param _constraint The constraint corresponding to the bound to create.
349  */
350  void setBound( const FormulaT& _constraint );
351 
352  /**
353  * Adds simple deduction being lemmas of the form (=> c_1 c_2) with, e.g. c_1 being p>=1 and c_2 being p>0.
354  */
356  void simpleTheoryPropagation( const LRABound* _bound );
357  void propagate( const LRABound* _premise, const FormulaT& _conclusion );
358  void propagateLowerBound( const LRABound* _bound );
359  void propagateUpperBound( const LRABound* _bound );
360  void propagateEqualBound( const LRABound* _bound );
361 
362  /**
363  * @return true, if a branching occurred.
364  * false, otherwise.
365  */
366  bool gomoryCut();
367 
368  /**
369  * @param _varsToExclude The variable on which we do not want to branch.
370  * @return true, if the solution is not in the domain,
371  * false, otherwise.
372  */
373  bool mostInfeasibleVar( bool _tryGomoryCut, carl::Variables& _varsToExclude );
374 
375  /**
376  * Creates a branch and bound lemma.
377  * @return true, if the solution is not in the domain,
378  * false, otherwise.
379  */
381 
382  /**
383  * Checks whether the found assignment is consistent with the tableau, hence replacing the original
384  * variables in the expressions represented by the slack variables equals their assignment.
385  * @param _assignment The assignment of the original variables.
386  * @param _delta The calculated delta for the given assignment.
387  * @return true, if the found assignment is consistent with the tableau;
388  * false, otherwise.
389  */
390  bool assignmentConsistentWithTableau( const RationalAssignment& _assignment, const LRABoundType& _delta ) const;
391 
392  /**
393  * @return true, if the encountered satisfying assignment for the received formula indeed satisfies it;
394  * false, otherwise.
395  */
396  bool assignmentCorrect() const;
397  };
398 
399 } // namespace smtrat
Class to create a settings object for the LRAModule.
A module which performs the Simplex method on the linear part of it's received formula.
Definition: LRAModule.h:30
void printNonlinearConstraints(std::ostream &_out=std::cout, const std::string _init="") const
Prints all non-linear constraints.
bool mAssignmentFullfilsNonlinearConstraints
A flag which is true, if the non-linear constraints fulfill the current assignment.
Definition: LRAModule.h:83
lra::Tableau< typename Settings::Tableau_settings, LRABoundType, LRAEntryType > LRATableau
The tableau which is the main data structure maintained by the LRAModule responsible for the pivoting...
Definition: LRAModule.h:73
bool informCore(const FormulaT &_constraint)
Informs this module about the existence of the given constraint, which means that it could be added i...
const RationalAssignment & getRationalModel() const
Gives a rational model if the received formula is satisfiable.
carl::FastMap< carl::Variable, LRAVariable * > VarVariableMap
Maps an original variable to it's corresponding LRAModule variable.
Definition: LRAModule.h:65
void adaptPassedFormula()
Adapt the passed formula, such that it consists of the finite infimums and supremums of all variables...
bool mOptimumComputed
Definition: LRAModule.h:87
const LRAVariable * getSlackVariable(const FormulaT &_constraint) const
Definition: LRAModule.h:298
void removeCore(ModuleInput::const_iterator _subformula)
Removes everything related to the given sub-formula of the received formula.
void processLearnedBounds()
const ExVariableMap & slackVariables() const
Definition: LRAModule.h:289
Answer checkNotEqualConstraints(Answer _result)
bool mRationalModelComputed
Definition: LRAModule.h:89
const VarVariableMap & originalVariables() const
Definition: LRAModule.h:281
void init()
Initializes the tableau according to all linear constraints, of which this module has been informed.
carl::Variable mDelta
The delta value, which influencing the assignment such that it also fulfills all strict inequalities ...
Definition: LRAModule.h:115
RationalAssignment mRationalAssignment
Definition: LRAModule.h:119
void printBoundCandidatesToPass(std::ostream &_out=std::cout, const std::string _init="") const
Prints the strictest bounds, which have to be passed the backend in case.
Answer checkCore()
Checks the received formula for consistency.
void learnRefinements()
Adds the refinements learned during pivoting to the deductions.
lra::Value< LRABoundType > LRAValue
The type of the assignment of a variable maintained by the LRAModule. It consists of a tuple of two v...
Definition: LRAModule.h:41
void learnRefinement(const typename LRATableau::LearnedBound &_learnedBound, bool _upperBound)
EvalRationalIntervalMap getVariableBounds() const
Returns the bounds of the variables as intervals.
lra::Bound< LRABoundType, LRAEntryType > LRABound
Type of a bound of a variable within the LRAModule.
Definition: LRAModule.h:37
void setBound(const FormulaT &_constraint)
Creates a bound corresponding to the given constraint.
carl::FastSet< FormulaT > mLinearConstraints
Stores all linear constraints of which this module has been once informed.
Definition: LRAModule.h:98
Answer processResult(Answer _result)
void propagateLowerBound(const LRABound *_bound)
void simpleTheoryPropagation(const LRABound *_bound)
ConstraintContextMap mActiveUnresolvedNEQConstraints
Those constraints p!=0, which are added to this module (part of the received formula),...
Definition: LRAModule.h:110
void simpleTheoryPropagation()
Adds simple deduction being lemmas of the form (=> c_1 c_2) with, e.g.
ConstraintContextMap mActiveResolvedNEQConstraints
Those constraints p!=0, which are added to this module (part of the received formula),...
Definition: LRAModule.h:105
bool branch_and_bound()
Creates a branch and bound lemma.
FormulasT createPremise(const std::vector< const LRABound * > &_premiseBounds, bool &_premiseOnlyEqualities) const
void printRationalModel(std::ostream &_out=std::cout, const std::string _init="") const
Prints the current rational assignment.
std::string moduleName() const
Definition: LRAModule.h:43
bool assignmentCorrect() const
bool mCheckedWithBackends
Definition: LRAModule.h:91
void activateBound(const LRABound *_bound, const FormulaT &_formula)
Activate the given bound and update the supremum, the infimum and the assignment of variable to which...
lra::Variable< LRABoundType, LRAEntryType > LRAVariable
A variable of the LRAModule, being either a original variable or a slack variable representing a line...
Definition: LRAModule.h:39
Answer checkCore_old()
bool mostInfeasibleVar(bool _tryGomoryCut, carl::Variables &_varsToExclude)
virtual ~LRAModule()
Destructs this LRAModule.
Settings::BoundType LRABoundType
Number type of the underlying value of a bound of a variable within the LRAModule.
Definition: LRAModule.h:33
bool mStrongestBoundsRemoved
A flag which is set, if a supremum or infimum of a LRAModule variable has been changed.
Definition: LRAModule.h:85
void propagateUpperBound(const LRABound *_bound)
void propagateEqualBound(const LRABound *_bound)
bool checkAssignmentForNonlinearConstraint()
Checks whether the current assignment of the linear constraints fulfills the non linear constraints.
void printConstraintToBound(std::ostream &_out=std::cout, const std::string _init="") const
Prints the mapping of constraints to their corresponding bounds.
Settings SettingsType
Definition: LRAModule.h:42
carl::FastMap< FormulaT, Context > ConstraintContextMap
Stores the position of a received formula in the passed formula.
Definition: LRAModule.h:71
void createInfeasibleSubsets(lra::EntryID _tableauEntry)
void deinformCore(const FormulaT &_constraint)
The inverse of informing about a constraint.
unsigned currentlySatisfied(const FormulaT &) const
void propagate(const LRABound *_premise, const FormulaT &_conclusion)
Answer optimize(Answer _result)
std::vector< const LRABound * > mBoundCandidatesToPass
Stores the bounds, which would influence a backend call because of recent changes.
Definition: LRAModule.h:117
void updateModel() const
Updates the model, if the solver has detected the consistency of the received formula,...
Settings::EntryType LRAEntryType
Type of an entry within the tableau.
Definition: LRAModule.h:35
void printTableau(std::ostream &_out=std::cout, const std::string _init="") const
Prints the current tableau.
void printVariables(std::ostream &_out=std::cout, const std::string _init="") const
Prints all lra variables and their assignments.
LRAModule(const ModuleInput *_formula, Conditionals &_conditionals, Manager *_manager=NULL)
Constructs a LRAModule.
bool assignmentConsistentWithTableau(const RationalAssignment &_assignment, const LRABoundType &_delta) const
Checks whether the found assignment is consistent with the tableau, hence replacing the original vari...
bool addCore(ModuleInput::const_iterator _subformula)
The module has to take the given sub-formula of the received formula into account.
carl::FastMap< FormulaT, std::vector< const LRABound * > * > ConstraintBoundsMap
Maps constraint to the bounds it represents (e.g., equations represent two bounds)
Definition: LRAModule.h:69
void printLinearConstraints(std::ostream &_out=std::cout, const std::string _init="") const
Prints all linear constraints.
LRATableau mTableau
Contains the main data structures of this module.
Definition: LRAModule.h:96
bool mInitialized
A flag, which is true if this module has already set all bounds corresponding to the constraint,...
Definition: LRAModule.h:81
void activateStrictBound(const FormulaT &_neqOrigin, const LRABound &_weakBound, const LRABound *_strictBound)
Activates a strict bound as a result of the two constraints p!=0 and p<=0 resp.
carl::FastSet< FormulaT > mNonlinearConstraints
Stores all non-linear constraints which are currently added (by assertSubformula) to this module.
Definition: LRAModule.h:100
carl::FastPointerMap< typename Poly::PolyType, LRAVariable * > ExVariableMap
Maps a linear polynomial to it's corresponding LRAModule variable.
Definition: LRAModule.h:67
Base class for solvers.
Definition: Manager.h:34
The input formula a module has to consider for it's satisfiability check.
Definition: ModuleInput.h:131
super::const_iterator const_iterator
Passing through the list::const_iterator.
Definition: ModuleInput.h:146
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
ModuleStatistics & mStatistics
Definition: Module.h:192
Stores a bound, which could be an upper "<= b" or a lower bound ">= b" for a bound value b.
Definition: Bound.h:33
const carl::FastMap< FormulaT, std::vector< const Bound< T1, T2 > * > * > & constraintToBound() const
Definition: Tableau.h:494
const carl::FastPointerMap< typename Poly::PolyType, Variable< T1, T2 > * > & slackVars() const
Definition: Tableau.h:481
const carl::FastMap< carl::Variable, Variable< T1, T2 > * > & originalVars() const
Definition: Tableau.h:473
size_t EntryID
Definition: Variable.h:23
Class to create the formulas for axioms.
carl::Formula< Poly > FormulaT
Definition: types.h:37
carl::Assignment< Rational > RationalAssignment
Definition: types.h:45
const settings::Settings & Settings()
Definition: Settings.h:96
std::map< carl::Variable, RationalInterval > EvalRationalIntervalMap
Definition: model.h:30
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
carl::Formulas< Poly > FormulasT
Definition: types.h:39
Stores a formula, being part of the received formula of this module, and the position of this formula...
Definition: LRAModule.h:53
Context(const FormulaT &_origin, ModuleInput::iterator _pos)
Definition: LRAModule.h:59
FormulaT origin
The formula in the received formula.
Definition: LRAModule.h:55
ModuleInput::iterator position
The position of this formula in the passed formula.
Definition: LRAModule.h:57