SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
Module.cpp
Go to the documentation of this file.
1 /**
2  * @file Module.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 #include "Module.h"
12 
13 #include <smtrat-solver/Manager.h>
14 
15 #include <boost/range/adaptor/reversed.hpp>
16 
17 #include <fstream>
18 #include <iostream>
19 #include <iomanip>
20 #include <limits.h>
21 #include <cmath>
22 
23 using namespace carl;
24 
25 namespace smtrat
26 {
27 
28  std::size_t Module::mNumOfBranchVarsToStore = 5;
29 #ifdef __VS
30  std::vector<Branching> Module::mLastBranches = std::vector<Branching>( mNumOfBranchVarsToStore, Branching(Poly::PolyType(), 0) );
31 #else
32  std::vector<Branching> Module::mLastBranches = std::vector<Branching>(mNumOfBranchVarsToStore, Branching(typename Poly::PolyType(), 0));
33 #endif
34  std::size_t Module::mFirstPosInLastBranches = 0;
35  std::vector<FormulaT> Module::mOldSplittingVariables;
36 #ifdef SMTRAT_STRAT_PARALLEL_MODE
37  std::mutex Module::mOldSplittingVarMutex;
38 #endif
39 
40  // Constructor.
41 
42  Module::Module( const ModuleInput* _formula, Conditionals& _foundAnswer, Manager* _manager, std::string module_name ):
43  mId( 0 ),
44  mThreadPriority( thread_priority( 0 , 0 ) ),
45  mpReceivedFormula( _formula ),
46  mpPassedFormula( new ModuleInput() ),
47  mModuleName(std::move(module_name)),
48  mInfeasibleSubsets(),
49  mpManager( _manager ),
50  mModel(),
51  mAllModels(),
52  mModelComputed( false ),
53  mFinalCheck( true ),
54  mFullCheck( true ),
55  mObjectiveVariable( carl::Variable::NO_VARIABLE ),
56  mSolverState( UNKNOWN ),
57 #ifdef __VS
58  mBackendsFoundAnswer(new std::atomic<bool>(false)),
59 #else
60  mBackendsFoundAnswer(new std::atomic_bool(false)),
61 #endif
62  mFoundAnswer( _foundAnswer ),
63  mUsedBackends(),
64  mAllBackends(),
65  mLemmas(),
66  mFirstSubformulaToPass( mpPassedFormula->end() ),
67  mConstraintsToInform(),
68  mInformedConstraints(),
69  mFirstUncheckedReceivedSubformula( mpReceivedFormula->end() ),
70  mSmallerMusesCheckCounter( 0 ),
71  mVariableCounters()
72  {}
73 
74  // Destructor.
75 
77  {
78  mLemmas.clear();
79  clearModel();
80  mConstraintsToInform.clear();
81  mInformedConstraints.clear();
82  delete mpPassedFormula;
83  delete mBackendsFoundAnswer;
84  }
85 
86  Answer Module::check( bool _final, bool _full, carl::Variable _objective )
87  {
89  SMTRAT_LOG_INFO("smtrat.module", __func__ << (_final ? " final" : " partial") << (_full ? " full" : " lazy" ) << " with module " << moduleName() << " (" << mId << ")");
90  print("\t");
91  mFinalCheck = _final;
92  mFullCheck = _full;
93  mObjectiveVariable = _objective;
94  #ifdef SMTRAT_DEVOPTION_Statistics
95  ++mStatistics.check_count;
96  #endif
97  clearLemmas();
98  if( rReceivedFormula().empty() )
99  {
101  return foundAnswer( SAT );
102  }
103  Answer result = checkCore();
104 // assert(result == UNKNOWN || result == UNSAT || result == SAT);
105  SMTRAT_LOG_DEBUG("smtrat.module", "Status: " << result);
106  assert( result != UNSAT || hasValidInfeasibleSubset() );
107  if( result != UNKNOWN && !mpReceivedFormula->empty() )
108  {
109  SMTRAT_VALIDATION_ADD("smtrat.module.theory_call",moduleName(),(FormulaT)*mpReceivedFormula,result==SAT);
110  }
111 
114  return foundAnswer( result );
115  }
116 
117  bool Module::inform( const FormulaT& _constraint )
118  {
119  SMTRAT_LOG_DEBUG("smtrat.module", __func__ << " " << moduleName() << " (" << mId << ") about: " << _constraint);
120  addConstraintToInform( _constraint );
121  return informCore( _constraint );
122  }
123 
124  void Module::deinform( const FormulaT& _constraint )
125  {
126  SMTRAT_LOG_DEBUG("smtrat.module", __func__ << " " << moduleName() << " (" << mId << ") about: " << _constraint);
127  if( mpManager != nullptr )
128  {
129  for( auto module = mAllBackends.begin(); module != mAllBackends.end(); ++module )
130  {
131  (*module)->deinform( _constraint );
132  }
133  }
134  mConstraintsToInform.erase( _constraint );
135  deinformCore( _constraint );
136  }
137 
138  bool Module::add( ModuleInput::const_iterator _receivedSubformula )
139  {
141  SMTRAT_LOG_DEBUG("smtrat.module", __func__ << " to " << moduleName() << " (" << mId << "):");
142  SMTRAT_LOG_DEBUG("smtrat.module", "\t" << _receivedSubformula->formula());
144  mFirstUncheckedReceivedSubformula = _receivedSubformula;
145  const carl::Variables& vars = _receivedSubformula->formula().variables();
146  for( carl::Variable::Arg var : vars )
147  {
148  if( var.id() >= mVariableCounters.size() )
149  mVariableCounters.resize( var.id()+1, 0 );
150  ++mVariableCounters[var.id()];
151  }
152  bool result = addCore( _receivedSubformula );
153  if( !result )
154  foundAnswer( UNSAT );
156  return result;
157  }
158 
159  void Module::remove( ModuleInput::const_iterator _receivedSubformula )
160  {
162  SMTRAT_LOG_DEBUG("smtrat.module", __func__ << " from " << moduleName() << " (" << mId << "):");
163  SMTRAT_LOG_DEBUG("smtrat.module", "\t" << _receivedSubformula->formula());
164  removeCore( _receivedSubformula );
165  if( mFirstUncheckedReceivedSubformula == _receivedSubformula )
167  const carl::Variables& vars = _receivedSubformula->formula().variables();
168  for( carl::Variable::Arg var : vars )
169  {
170  assert( mVariableCounters[var.id()] > 0 );
171  --mVariableCounters[var.id()];
172  }
173  // Check if the constraint to delete is an original constraint of constraints in the vector
174  // of passed constraints.
175  ModuleInput::iterator passedSubformula = mpPassedFormula->begin();
176  while( passedSubformula != mpPassedFormula->end() )
177  {
178  // Remove the received formula from the set of origins.
179  if( mpPassedFormula->removeOrigin( passedSubformula, _receivedSubformula->formula() ) )
180  {
181  passedSubformula = this->eraseSubformulaFromPassedFormula( passedSubformula );
182  }
183  else
184  {
185  ++passedSubformula;
186  }
187  }
188  // Delete all infeasible subsets in which the constraint to delete occurs.
189  for( size_t pos = 0; pos < mInfeasibleSubsets.size(); )
190  {
191  auto& infsubset = mInfeasibleSubsets[pos];
192  if( infsubset.find( _receivedSubformula->formula() ) != infsubset.end() )
193  {
194  infsubset = std::move(mInfeasibleSubsets.back());
195  mInfeasibleSubsets.pop_back();
196  }
197  else
198  {
199  ++pos;
200  }
201  }
202  if( mInfeasibleSubsets.empty() )
203  mSolverState.store(UNKNOWN);
205  }
206 
208  {
209  if ( !mInfeasibleSubsets.empty() )
210  return UNSAT;
211 
212  assert( mInfeasibleSubsets.empty() );
213 
214  // Copy the received formula to the passed formula.
215  auto subformula = mpReceivedFormula->begin();
216  for( auto passedSubformula = mpPassedFormula->begin(); passedSubformula != mpPassedFormula->end(); ++passedSubformula )
217  {
218  assert( subformula != mpReceivedFormula->end() );
219  ++subformula;
220  }
221  while( subformula != mpReceivedFormula->end() )
222  {
223  addReceivedSubformulaToPassedFormula( subformula++ );
224  }
225  // Run the backends on the passed formula and return its answer.
226  Answer a = runBackends();
227  if( a == UNSAT )
228  {
230  }
231  return a;
232  }
233 
235  {
236  if( mpManager == nullptr || mConstraintsToInform.empty() ) return;
237  // Get the backends to be considered from the manager.
240  for( Module* backend : mAllBackends )
241  {
242  for( auto iter = mConstraintsToInform.begin(); iter != mConstraintsToInform.end(); ++iter )
243  backend->inform( *iter );
244  backend->init();
245  }
247  mConstraintsToInform.clear();
248  }
249 
250  void Module::updateModel() const
251  {
252  if( !mModelComputed )
253  {
254  clearModel();
257  mModelComputed = true;
258  }
259  }
260 
262  {
263  clearModel();
264  if( solverState() == SAT )
265  {
266  //TODO Matthias: set all models
268  /*carl::Variables receivedVariables;
269  mpReceivedFormula->arithmeticVars( receivedVariables );
270  mpReceivedFormula->booleanVars( receivedVariables );
271  // TODO: Do the same for bv and uninterpreted variables and functions
272  auto iterRV = receivedVariables.begin();
273  if( iterRV != receivedVariables.end() )
274  {
275  for( std::map<ModelVariable,ModelValue>::const_iterator iter = mModel.begin(); iter != mModel.end(); )
276  {
277  if( iter->first.is_variable() )
278  {
279  auto tmp = std::find( iterRV, receivedVariables.end(), iter->first.asVariable() );
280  if( tmp == receivedVariables.end() )
281  {
282  iter = mModel.erase( iter );
283  continue;
284  }
285  else
286  {
287  iterRV = tmp;
288  }
289  }
290  ++iter;
291  }
292  }*/
293  }
294  }
295 
296  unsigned Module::currentlySatisfiedByBackend( const FormulaT& _formula ) const
297  {
298  unsigned result = 3;
299  for( const Module* module : mUsedBackends )
300  {
301  result = module->currentlySatisfied( _formula );
302  if( result == 0 || result == 1 )
303  return result;
304  }
305  return result;
306  }
307 
308  std::list<std::vector<carl::Variable>> Module::getModelEqualities() const
309  {
310  std::list<std::vector<carl::Variable>> res;
311  for( auto& it : this->mModel )
312  {
313  if( it.first.is_variable() )
314  {
315  carl::Variable v = it.first.asVariable();
316  ModelValue a = it.second;
317  bool added = false;
318  for( auto& cls: res )
319  {
320  // There should be no empty classes in the result.
321  assert(cls.size() > 0);
322  // Check if the current assignment fits into this class.
323  if( a == this->mModel.at(cls.front()) )
324  {
325  // insert it and continue with the next assignment.
326  cls.push_back( v );
327  added = true;
328  break;
329  }
330  }
331  if( !added )
332  {
333  // The assignment did not fit in any existing class, hence we create a new one.
334  res.emplace_back(std::vector<carl::Variable>( {v} ));
335  }
336  }
337  }
338  return res;
339  }
340 
341  std::pair<ModuleInput::iterator,bool> Module::addSubformulaToPassedFormula( const FormulaT& _formula, bool _hasSingleOrigin, const FormulaT& _origin, const std::shared_ptr<std::vector<FormulaT>>& _origins, bool _mightBeConjunction )
342  {
343  std::pair<ModuleInput::iterator,bool> res = mpPassedFormula->add( _formula, _hasSingleOrigin, _origin, _origins, _mightBeConjunction );
344  if( res.second )
345  {
347  mFirstSubformulaToPass = res.first;
348  }
349  return res;
350  }
351 
352  bool Module::originInReceivedFormula( const FormulaT& _origin ) const
353  {
354  if( mpReceivedFormula->contains( _origin ) )
355  return true;
356  if( _origin.type() == carl::FormulaType::AND )
357  {
358  FormulasT subFormulasInRF;
359  for( auto fwo = mpReceivedFormula->begin(); fwo != mpReceivedFormula->end(); ++fwo )
360  {
361  const FormulaT& subform = fwo->formula();
362  if( subform.type() == carl::FormulaType::AND )
363  subFormulasInRF.insert(subFormulasInRF.end(), subform.subformulas().begin(), subform.subformulas().end() );
364  else
365  subFormulasInRF.push_back( subform );
366  }
367  for( auto& f : _origin.subformulas() )
368  {
369  if( std::find(subFormulasInRF.begin(), subFormulasInRF.end(), f ) == subFormulasInRF.end() )
370  return false;
371  }
372  return true;
373  }
374  return false;
375  }
376 
377  std::vector<FormulaT> Module::merge( const std::vector<FormulaT>& _vecSetA, const std::vector<FormulaT>& _vecSetB ) const
378  {
379  std::vector<FormulaT> result;
380  std::vector<FormulaT>::const_iterator originSetA = _vecSetA.begin();
381  while( originSetA != _vecSetA.end() )
382  {
383  std::vector<FormulaT>::const_iterator originSetB = _vecSetB.begin();
384  while( originSetB != _vecSetB.end() )
385  {
386  FormulasT subformulas;
387  if( originSetA->type() == carl::FormulaType::AND )
388  subformulas = originSetA->subformulas();
389  else
390  subformulas.push_back( *originSetA );
391  if( originSetB->type() == carl::FormulaType::AND )
392  subformulas.insert(subformulas.end(), originSetB->begin(), originSetB->end() );
393  else
394  subformulas.push_back( *originSetB );
395  result.push_back( FormulaT( carl::FormulaType::AND, std::move( subformulas ) ) );
396  ++originSetB;
397  }
398  ++originSetA;
399  }
400  return result;
401  }
402 
403  size_t Module::determine_smallest_origin( const std::vector<FormulaT>& origins) const
404  {
405  assert( !origins.empty() );
406  auto iter = origins.begin();
407  size_t size_min = (*iter).size();
408  ++iter;
409  size_t index_min = 0, i = 0;
410  while( iter != origins.end() )
411  {
412  if( (*iter).size() < size_min )
413  {
414  size_min = (*iter).size();
415  index_min = i;
416  }
417  ++i;
418  ++iter;
419  }
420  return index_min;
421  }
422 
423 #ifdef __VS
424  bool Module::probablyLooping( const Poly::PolyType& _branchingPolynomial, const Rational& _branchingValue ) const
425 #else
426  bool Module::probablyLooping( const typename Poly::PolyType& _branchingPolynomial, const Rational& _branchingValue ) const
427 #endif
428  {
429  if( mpManager == nullptr ) return false;
430  assert( _branchingPolynomial.constant_part() == 0 );
431  auto iter = mLastBranches.begin();
432  for( ; iter != mLastBranches.end(); ++iter )
433  {
434  if( iter->mPolynomial == _branchingPolynomial )
435  {
436  if( iter->mIncreasing > 0 )
437  {
438  if( _branchingValue >= iter->mValue )
439  {
440  ++(iter->mRepetitions);
441  }
442  else if( _branchingValue <= iter->mValue )
443  {
444  iter->mIncreasing = -1;
445  iter->mRepetitions = 1;
446  }
447  }
448  else if( iter->mIncreasing < 0 )
449  {
450  if( _branchingValue <= iter->mValue )
451  {
452  ++(iter->mRepetitions);
453  }
454  else if( _branchingValue >= iter->mValue )
455  {
456  iter->mIncreasing = 1;
457  iter->mRepetitions = 1;
458  }
459  }
460  else if( _branchingValue != iter->mValue )
461  {
462  iter->mRepetitions = 1;
463  iter->mIncreasing = _branchingValue >= iter->mValue ? 1 : -1;
464  }
465  iter->mValue = _branchingValue;
466  if( iter->mRepetitions > 10 ) return true;
467  break;
468  }
469  }
470  if( iter == mLastBranches.end() )
471  {
472  mLastBranches[mFirstPosInLastBranches] = Branching( _branchingPolynomial, _branchingValue );
473  if( ++mFirstPosInLastBranches == mNumOfBranchVarsToStore ) mFirstPosInLastBranches = 0;
474  }
475  return false;
476  }
477 
478  bool Module::branchAt( const Poly& _polynomial, bool _integral, const Rational& _value, std::vector<FormulaT>&& _premise, bool _leftCaseWeak, bool _preferLeftCase, bool _useReceivedFormulaAsPremise )
479  {
480  assert( !_useReceivedFormulaAsPremise || _premise.empty() );
481  assert( !_polynomial.has_constant_term() );
482  ConstraintT constraintA;
483  ConstraintT constraintB;
484  if( _integral )
485  {
486  Rational bound = carl::floor( _value );
487  Rational boundp = bound;
488  if( _leftCaseWeak )
489  {
490  constraintA = ConstraintT( std::move(_polynomial - bound), Relation::LEQ );
491  constraintB = ConstraintT( std::move(_polynomial - (++bound)), Relation::GEQ );
492  }
493  else
494  {
495  constraintB = ConstraintT( std::move(_polynomial - bound), Relation::GEQ );
496  constraintA = ConstraintT( std::move(_polynomial - (--bound)), Relation::LEQ );
497  }
498  SMTRAT_LOG_INFO("smtrat.module", __func__ << " from " << moduleName() << " (" << mId << ") at " << constraintA << " and " << constraintB);
499  SMTRAT_LOG_INFO("smtrat.module", "\tPremise is: " << _premise);
500  }
501  else
502  {
503  Poly constraintLhs = _polynomial - _value;
504  if( _leftCaseWeak )
505  {
506  constraintA = ConstraintT( constraintLhs, Relation::LEQ );
507  constraintB = ConstraintT( std::move(constraintLhs), Relation::GREATER );
508  }
509  else
510  {
511  constraintA = ConstraintT( constraintLhs, Relation::LESS );
512  constraintB = ConstraintT( std::move(constraintLhs), Relation::GEQ );
513  }
514  }
515  if( constraintA.is_consistent() == 2 )
516  {
517  // Create splitting variables
518  FormulaT s1, s2;
520  if( mOldSplittingVariables.empty() )
521  s1 = FormulaT( carl::fresh_boolean_variable() );
522  else
523  {
524  s1 = mOldSplittingVariables.back();
525  mOldSplittingVariables.pop_back();
526  }
527  if( mOldSplittingVariables.empty() )
528  s2 = FormulaT( carl::fresh_boolean_variable() );
529  else
530  {
531  s2 = mOldSplittingVariables.back();
532  mOldSplittingVariables.pop_back();
533  }
535  // Create _premise -> (s1 or s2)
536  FormulasT subformulas;
537  if( _useReceivedFormulaAsPremise )
538  {
539  for( const auto& fwo : rReceivedFormula() )
540  subformulas.push_back( fwo.formula().negated() );
541  }
542  else
543  {
544  for( const FormulaT& premForm : _premise )
545  {
546  assert( rReceivedFormula().contains( premForm ) );
547  subformulas.push_back( premForm.negated() );
548  }
549  }
550  subformulas.push_back( s1 );
551  subformulas.push_back( s2 );
552  mLemmas.emplace_back( FormulaT( carl::FormulaType::OR, std::move(subformulas) ), LemmaType::NORMAL, _preferLeftCase ? s1 : s2 );
553  // Create (not s1 or not s2)
554  mLemmas.emplace_back( FormulaT( carl::FormulaType::OR, s1.negated(), s2.negated() ), LemmaType::NORMAL, FormulaT( carl::FormulaType::TRUE ) );
555  // Create (s1 -> constraintA)
556  mLemmas.emplace_back( FormulaT( carl::FormulaType::OR, s1.negated(), FormulaT( constraintA ) ), LemmaType::NORMAL, FormulaT( carl::FormulaType::TRUE ) );
557  // Create (s2 -> constraintB)
558  mLemmas.emplace_back( FormulaT( carl::FormulaType::OR, s2.negated(), FormulaT( constraintB ) ), LemmaType::NORMAL, FormulaT( carl::FormulaType::TRUE ) );
559  return true;
560  }
561  assert( constraintB.is_consistent() != 2 );
562  return false;
563  }
564 
565  void Module::splitUnequalConstraint( const FormulaT& _unequalConstraint )
566  {
567  assert( _unequalConstraint.type() == CONSTRAINT );
568  assert( _unequalConstraint.constraint().relation() == Relation::NEQ );
569  const Poly& lhs = _unequalConstraint.constraint().lhs();
570  FormulaT lessConstraint = FormulaT( lhs, Relation::LESS );
571  FormulaT notLessConstraint = FormulaT( FormulaType::NOT, lessConstraint );
572  FormulaT greaterConstraint = FormulaT( lhs, Relation::GREATER );
573  FormulaT notGreaterConstraint = FormulaT( FormulaType::NOT, greaterConstraint );
574  // (not p!=0 or p<0 or p>0)
575  FormulasT subformulas;
576  subformulas.push_back( FormulaT( FormulaType::NOT, _unequalConstraint ) );
577  subformulas.push_back( lessConstraint );
578  subformulas.push_back( greaterConstraint );
579  mLemmas.emplace_back( FormulaT( FormulaType::OR, std::move( subformulas ) ), LemmaType::PERMANENT, FormulaT( carl::FormulaType::TRUE ) );
580  // (not p<0 or p!=0)
581  mLemmas.emplace_back( FormulaT( FormulaType::OR, {notLessConstraint, _unequalConstraint} ), LemmaType::PERMANENT, FormulaT( carl::FormulaType::TRUE ) );
582  // (not p>0 or p!=0)
583  mLemmas.emplace_back( FormulaT( FormulaType::OR, {notGreaterConstraint, _unequalConstraint} ), LemmaType::PERMANENT, FormulaT( carl::FormulaType::TRUE ) );
584  // (not p>0 or not p<0)
585  mLemmas.emplace_back( FormulaT( FormulaType::OR, {notGreaterConstraint, notLessConstraint} ), LemmaType::PERMANENT, FormulaT( carl::FormulaType::TRUE ) );
586  }
587 
588  unsigned Module::checkModel() const
589  {
590  this->updateModel();
591  SMTRAT_LOG_INFO("smtrat.module", "Model: " << mModel);
592  SMTRAT_LOG_INFO("smtrat.module", "Formula: " << FormulaT(*mpReceivedFormula));
594  }
595 
597  {
598  auto backend = mUsedBackends.begin();
599  while( backend != mUsedBackends.end() )
600  {
601  if( (*backend)->solverState() == UNSAT )
602  {
603  std::vector<FormulaSetT> infsubsets = getInfeasibleSubsets( **backend );
604  mInfeasibleSubsets.insert( mInfeasibleSubsets.end(), infsubsets.begin(), infsubsets.end() );
605  // return;
606  }
607  ++backend;
608  }
609  }
610 
611  bool Module::modelsDisjoint( const Model& _modelA, const Model& _modelB )
612  {
613  auto assignment = _modelA.begin();
614  while( assignment != _modelA.end() )
615  {
616  if( _modelB.find( assignment->first ) != _modelB.end() )
617  return false;
618  ++assignment;
619  }
620  assignment = _modelB.begin();
621  while( assignment != _modelB.end() )
622  {
623  if( _modelA.find( assignment->first ) != _modelA.end() )
624  return false;
625  ++assignment;
626  }
627  return true;
628  }
629 
631  {
632  auto module = mUsedBackends.begin();
633  while( module != mUsedBackends.end() )
634  {
635  if( (*module)->solverState() == SAT )
636  {
637  //@todo models should be disjoint, but this breaks CAD on certain inputs.
638  //assert( modelsDisjoint( mModel, (*module)->model() ) );
639  (*module)->updateModel();
640  return (*module)->model();
641  }
642  ++module;
643  }
644  if( !mUsedBackends.empty() )
645  {
646  (*mUsedBackends.begin())->updateModel();
647  return (*mUsedBackends.begin())->model();
648  }
649  return EMPTY_MODEL;
650  }
651 
653  {
654  auto module = mUsedBackends.begin();
655  while( module != mUsedBackends.end() )
656  {
657  if ((*module)->solverState() != ABORTED)
658  {
659  //@todo models should be disjoint, but this breaks CAD on certain inputs.
660  //assert( modelsDisjoint( mModel, (*module)->model() ) );
661  (*module)->updateModel();
662  mModel.update((*module)->model(), false);
663  break;
664  }
665  ++module;
666  }
667  }
668 
670  {
671  auto module = mUsedBackends.begin();
672  while( module != mUsedBackends.end() )
673  {
674  assert( (*module)->solverState() != UNSAT );
675  if( (*module)->solverState() == SAT )
676  {
677  //@todo modules should be disjoint, but this breaks CAD on certain inputs.
678  //assert( modelsDisjoint( mModel, (*module)->model() ) );
679  (*module)->updateAllModels();
680  //TODO Matthias: correct way?
681  for (Model model: (*module)->allModels())
682  {
683  mAllModels.push_back( model );
684  }
685  break;
686  }
687  ++module;
688  }
689  }
690 
691  std::vector<FormulaT>::const_iterator Module::findBestOrigin( const std::vector<FormulaT>& _origins ) const
692  {
693  // TODO: implement other heuristics for finding the best origin, e.g., activity or age based
694  // Find the smallest set of origins.
695  auto smallestOrigin = _origins.begin();
696  auto origin = _origins.begin();
697  while( origin != _origins.end() )
698  {
699  if( origin->size() == 1 )
700  return origin;
701  else if( origin->size() < smallestOrigin->size() )
702  smallestOrigin = origin;
703  ++origin;
704  }
705  assert( smallestOrigin != _origins.end() );
706  return smallestOrigin;
707  }
708 
709  std::vector<FormulaSetT> Module::getInfeasibleSubsets( const Module& _backend ) const
710  {
711  std::vector<FormulaSetT> result;
712  const std::vector<FormulaSetT>& backendsInfsubsets = _backend.infeasibleSubsets();
713  assert( !backendsInfsubsets.empty() );
714  for( std::vector<FormulaSetT>::const_iterator infSubSet = backendsInfsubsets.begin(); infSubSet != backendsInfsubsets.end(); ++infSubSet )
715  {
716  assert( !infSubSet->empty() );
717  #ifdef SMTRAT_DEVOPTION_Validation
718  SMTRAT_VALIDATION_ADD("smtrat.module.infeasible_subsets",moduleName()+ "_infeasible_subset",*infSubSet,false);
719  #endif
720  result.emplace_back();
721  for( const auto& cons : *infSubSet )
722  getOrigins( cons, result.back() );
723  }
724  return result;
725  }
726 
727  Answer Module::runBackends( bool _final, bool _full, carl::Variable _objective )
728  {
729  if( mpManager == nullptr ) return UNKNOWN;
730  *mBackendsFoundAnswer = false;
732  // Update the propositions of the passed formula
734  // Get the backends to be considered from the manager.
737  std::size_t numberOfUsedBackends = mUsedBackends.size();
738  if( numberOfUsedBackends > 0 )
739  {
740  // Update the backends.
742  {
743  bool assertionFailed = false;
744  for( auto module = mAllBackends.begin(); module != mAllBackends.end(); ++module )
745  {
746  (*module)->mLemmas.clear(); // TODO: this might be removed, as it is now done in check as well
747  if( !(*module)->mInfeasibleSubsets.empty() )
748  {
749  assertionFailed = true;
750  }
751  for( auto iter = mConstraintsToInform.begin(); iter != mConstraintsToInform.end(); ++iter )
752  (*module)->inform( *iter );
753  for( auto subformula = mFirstSubformulaToPass; subformula != mpPassedFormula->end(); ++subformula )
754  {
755  if( !(*module)->add( subformula ) )
756  {
757  assertionFailed = true;
758  }
759  }
760  }
763  mConstraintsToInform.clear();
764  if( assertionFailed )
765  {
766  return UNSAT;
767  }
768  }
769  else
770  {
771  // TODO: this might be removed, as it is now done in check as well
772  for( auto module = mAllBackends.begin(); module != mAllBackends.end(); ++module )
773  {
774  (*module)->mLemmas.clear();
775  }
776  }
777 
778  #ifdef SMTRAT_STRAT_PARALLEL_MODE
779  if( mpManager->runsParallel() )
780  {
781  // Run the backend solver parallel until the first answers true or false.
782  if( anAnswerFound() )
783  return ABORTED;
784  Answer res = mpManager->runBackends(mUsedBackends, _final, _full, _objective);
785  return res;
786  }
787  else
788  {
789  #endif
790  // Run the backend solver sequentially until the first answers true or false.
791  auto module = mUsedBackends.begin();
792  while( module != mUsedBackends.end() && result == UNKNOWN )
793  {
795  result = (*module)->check( _final, _full, _objective );
797  (*module)->receivedFormulaChecked();
798  ++module;
799  }
800  #ifdef SMTRAT_STRAT_PARALLEL_MODE
801  }
802  #endif
803  }
804  return result;
805  }
806 
808  {
809  if( _ignoreOrigins )
810  {
811  mpPassedFormula->clearOrigins( _subformula );
812  }
813  assert( !_subformula->hasOrigins() );
814  // Check whether the passed sub-formula has already been part of a consistency check of the backends.
815  bool subformulaChecked = true;
816  if( _subformula == mFirstSubformulaToPass )
817  {
819  subformulaChecked = false;
820  }
821  else
822  {
823  auto iter = mFirstSubformulaToPass;
824  while( iter != mpPassedFormula->end() )
825  {
826  if( iter == _subformula )
827  {
828  subformulaChecked = false;
829  break;
830  }
831  ++iter;
832  }
833  }
834  // Remove the sub-formula from the backends, if it was considered in their consistency checks.
835  if( subformulaChecked )
836  {
837  if( mpManager != nullptr )
838  {
840  for( auto module = mAllBackends.begin(); module != mAllBackends.end(); ++module )
841  {
842  (*module)->remove( _subformula );
843  }
844  }
845  }
846  // Delete the sub formula from the passed formula.
847  return mpPassedFormula->erase( _subformula );
848  }
849 
851  {
852  while( !mpPassedFormula->empty() )
854  }
855 
857  {
858  mSolverState.store(_answer);
859  // If we are in the SMT environment:
860  assert( _answer != ABORTED || anAnswerFound() );
861  if( mpManager != nullptr && _answer != UNKNOWN && _answer != ABORTED )
862  {
863  if( !anAnswerFound() )
864  mFoundAnswer.back()->store( true );
865  }
866  SMTRAT_LOG_INFO("smtrat.module", __func__ << " of " << moduleName() << " (" << mId << ") is " << _answer);
867  if( is_sat(_answer) || _answer == UNKNOWN )
868  {
869  mModelComputed = false;
870  }
871  #ifdef SMTRAT_DEVOPTION_Expensive
872  assert( !is_sat(_answer) || checkModel() != 0 );
873  #endif
874  return _answer;
875  }
876 
877  void Module::addConstraintToInform( const FormulaT& constraint )
878  {
879  // We can give the hint that this constraint will probably be inserted in the end of this container,
880  // as it is compared by an id which gets incremented every time a new constraint is constructed.
881  mConstraintsToInform.insert( constraint );
882  }
883 
885  {
886  if (mModel.empty()) return;
887  mModel.clean();
888  // Collect all variables
889  carl::carlVariables variables;
890  std::set<carl::UninterpretedFunction> functions;
891  for (const auto& f: *mpReceivedFormula) {
892  carl::variables(f.formula(),variables);
893  carl::uninterpreted_functions(f.formula(),functions);
894  }
895  // Filter model
896  for (auto it = mModel.begin(); it != mModel.end(); ) {
897  bool remove = false;
898  if (it->first.isFunction()) {
899  if (functions.find(it->first.asFunction()) == functions.end()) {
900  remove = true;
901  }
902  } else {
903  carl::Variable v;
904  if (it->first.is_variable()) v = it->first.asVariable();
905  else if (it->first.isBVVariable()) v = it->first.asBVVariable().variable();
906  else if (it->first.isUVariable()) v = it->first.asUVariable().variable();
907  if (!variables.has(v)) {
908  remove = true;
909  }
910  }
911  if (remove) {
912  it = mModel.erase(it);
913  } else {
914  ++it;
915  }
916  }
917  }
918 
920  {
921  for( auto module = mUsedBackends.begin(); module != mUsedBackends.end(); ++module )
922  {
923  (*module)->updateLemmas();
924  mLemmas.insert( mLemmas.end(), (*module)->mLemmas.begin(), (*module)->mLemmas.end() );
925  }
926  }
927 
929  {
930  for( auto module = mUsedBackends.begin(); module != mUsedBackends.end(); ++module )
931  {
932  (*module)->collectTheoryPropagations();
933  #ifdef SMTRAT_DEVOPTION_Validation
934  for( const auto& tp : (*module)->mTheoryPropagations )
935  {
936  FormulaT theoryPropagation( FormulaType::IMPLIES, FormulaT( FormulaType::AND, tp.mPremise ), tp.mConclusion );
937  SMTRAT_VALIDATION_ADD("smtrat.module.theory_propagation",(*module)->moduleName() + "_theory_propagation",FormulaT( FormulaType::NOT, theoryPropagation ),false);
938  }
939  #endif
940  std::move( (*module)->mTheoryPropagations.begin(), (*module)->mTheoryPropagations.end(), std::back_inserter( mTheoryPropagations ) );
941  (*module)->mTheoryPropagations.clear();
942  }
943  }
944 
945  std::pair<bool,FormulaT> Module::getReceivedFormulaSimplified()
946  {
947  if( solverState() == UNSAT )
948  return std::make_pair( true, FormulaT( carl::FormulaType::FALSE ) );
949  for( const auto& backend : usedBackends() )
950  {
951  std::pair<bool,FormulaT> simplifiedPassedFormula = backend->getReceivedFormulaSimplified();
952  if( simplifiedPassedFormula.first )
953  {
954  return simplifiedPassedFormula;
955  }
956  }
957  return std::make_pair( false, FormulaT( carl::FormulaType::TRUE ) );
958  }
959 
960  void Module::collectOrigins( const FormulaT& _formula, FormulasT& _origins ) const
961  {
962  if( mpReceivedFormula->contains( _formula ) )
963  {
964  _origins.push_back( _formula );
965  }
966  else
967  {
968  if(_formula.type() != carl::FormulaType::AND ){
969  SMTRAT_LOG_ERROR("smtrat", "Formula " << _formula << " has type: " << _formula.type() << ", not AND-Type");
970  }
971  assert( _formula.type() == carl::FormulaType::AND );
972  for( auto& subformula : _formula.subformulas() )
973  {
974  assert( mpReceivedFormula->contains( subformula ) );
975  _origins.push_back( subformula );
976  }
977  }
978  }
979 
980  void Module::collectOrigins( const FormulaT& _formula, FormulaSetT& _origins ) const
981  {
982  if( mpReceivedFormula->contains( _formula ) )
983  {
984  _origins.insert( _formula );
985  }
986  else
987  {
988  if(_formula.type() != carl::FormulaType::AND ){
989  SMTRAT_LOG_ERROR("smtrat", "Formula " << _formula << " has type: " << _formula.type() << ", not AND-Type");
990  }
991  assert( _formula.type() == carl::FormulaType::AND );
992  for( auto& subformula : _formula.subformulas() )
993  {
994  assert( mpReceivedFormula->contains( subformula ) );
995  _origins.insert( subformula );
996  }
997  }
998  }
999 
1001  {
1002  SMTRAT_LOG_DEBUG("smtrat.module", "InfSubsets: " << mInfeasibleSubsets);
1003  if( mInfeasibleSubsets.empty() ) return false;
1004  for( const auto& infSubset : mInfeasibleSubsets )
1005  {
1006  for( const auto& subFormula : infSubset )
1007  {
1008  if( !mpReceivedFormula->contains( subFormula ) )
1009  {
1010  SMTRAT_LOG_DEBUG("smtrat.module", "Subset " << infSubset << " has " << subFormula << " that we don't know.");
1011  return false;
1012  }
1013  }
1014  }
1015  return true;
1016  }
1017 
1018  void Module::checkInfSubsetForMinimality( std::vector<FormulaSetT>::const_iterator _infsubset, const std::string& _filename, unsigned _maxSizeDifference ) const
1019  {
1020  carl::carlVariables vars(carl::variable_type_filter::arithmetic());
1021  for( auto it = _infsubset->begin(); it != _infsubset->end(); ++it ) {
1022  carl::variables(*it, vars);
1023  }
1024  std::stringstream filename;
1025  filename << _filename << "_" << moduleName() << "_" << mSmallerMusesCheckCounter << ".smt2";
1026  std::ofstream smtlibFile;
1027  smtlibFile.open( filename.str() );
1028  for( size_t size = _infsubset->size() - _maxSizeDifference; size < _infsubset->size(); ++size )
1029  {
1030  // 000000....000011111 (size-many ones)
1031  size_t bitvector = (1 << size) - 1;
1032  // 000000....100000000
1033  size_t limit = (1 << _infsubset->size());
1034  size_t nextbitvector;
1035  while( bitvector < limit )
1036  {
1037  // Compute lexicographical successor of the bit vector.
1038  size_t tmp = (bitvector | (bitvector - 1)) + 1;
1039  nextbitvector = tmp | ((((tmp & -tmp) / (bitvector & -bitvector)) >> 1) - 1);
1040  // For each assumption add a new solver-call by resetting the search state.
1041  smtlibFile << "(reset)\n";
1042  smtlibFile << "(set-logic " << mpManager->logic() << ")\n";
1043  smtlibFile << "(set-option :interactive-mode true)\n";
1044  smtlibFile << "(set-info :smt-lib-version 2.0)\n";
1045  // Add all arithmetic variables.
1046  for (auto v: vars) {
1047  smtlibFile << "(declare-fun " << v << " () " << v.type() << ")\n";
1048  }
1049  smtlibFile << "(set-info :status sat)\n";
1050  smtlibFile << "(assert (and ";
1051  for( auto it = _infsubset->begin(); it != _infsubset->end(); ++it )
1052  {
1053  if( bitvector & 1 )
1054  smtlibFile << " " << *it;
1055  bitvector >>= 1;
1056  }
1057  smtlibFile << "))\n";
1058  smtlibFile << "(get-assertions)\n";
1059  smtlibFile << "(check-sat)\n";
1060  bitvector = nextbitvector;
1062  }
1063  }
1064  smtlibFile << "(exit)";
1065  smtlibFile.close();
1066  }
1067 
1069  {
1070  if (mpManager == nullptr) return;
1072  }
1073 
1074  const std::set<FormulaT>& Module::getInformationRelevantFormulas()
1075  {
1077  }
1078 
1080  {
1081  if (mpManager == nullptr) return true;
1082  return mpManager->isLemmaLevel(level);
1083  }
1084 
1085  void Module::print( const std::string&
1086 #ifdef SMTRAT_LOGGING_ENABLED
1087  _initiation
1088 #endif
1089  ) const
1090  {
1091 #ifdef SMTRAT_LOGGING_ENABLED
1092  SMTRAT_LOG_INFO("smtrat.module", _initiation << "********************************************************************************");
1093  SMTRAT_LOG_INFO("smtrat.module", _initiation << " Solver " << moduleName() << " (" << mId << ")");
1094  SMTRAT_LOG_INFO("smtrat.module", _initiation);
1095  printReceivedFormula( _initiation + "\t" );
1096  SMTRAT_LOG_INFO("smtrat.module", _initiation);
1097  printPassedFormula( _initiation + "\t" );
1098  SMTRAT_LOG_INFO("smtrat.module", _initiation);
1099  printInfeasibleSubsets( _initiation + "\t" );
1100  SMTRAT_LOG_INFO("smtrat.module", _initiation);
1101  SMTRAT_LOG_INFO("smtrat.module", _initiation << "********************************************************************************");
1102 #endif
1103  }
1104 
1105  void Module::printReceivedFormula( const std::string& _initiation ) const
1106  {
1107  SMTRAT_LOG_INFO("smtrat.module", _initiation << "Received formula:");
1108  for( auto form = mpReceivedFormula->begin(); form != mpReceivedFormula->end(); ++form )
1109  {
1110  std::stringstream ss;
1111  ss << _initiation;
1112  ss << std::setw( 45 ) << form->formula();
1113  if( form->deducted() ) ss << " deducted";
1114  SMTRAT_LOG_INFO("smtrat.module", ss.str());
1115  }
1116  }
1117 
1118  void Module::printPassedFormula( const std::string& _initiation ) const
1119  {
1120  SMTRAT_LOG_INFO("smtrat.module", _initiation << "Passed formula:");
1121  for( auto form = mpPassedFormula->begin(); form != mpPassedFormula->end(); ++form )
1122  {
1123  std::stringstream ss;
1124  ss << _initiation;
1125  ss << std::setw( 45 ) << form->formula();
1126  if( form->hasOrigins() )
1127  {
1128  for (const auto& oSubformulas: form->origins()) {
1129  ss << " {" << oSubformulas << " }";
1130  }
1131  }
1132  SMTRAT_LOG_INFO("smtrat.module", ss.str());
1133  }
1134  }
1135 
1136  void Module::printInfeasibleSubsets( const std::string& _initiation ) const
1137  {
1138  SMTRAT_LOG_INFO("smtrat.module", _initiation << "Infeasible subsets:");
1139  for( auto infSubSet = mInfeasibleSubsets.begin(); infSubSet != mInfeasibleSubsets.end(); ++infSubSet )
1140  {
1141  std::stringstream ss;
1142  ss << _initiation;
1143  ss << " {";
1144  for (const auto& infSubFormula: *infSubSet)
1145  ss << " " << infSubFormula << std::endl;
1146  ss << " }";
1147  SMTRAT_LOG_INFO("smtrat.module", "\t" << ss.str());
1148  }
1149  }
1150 
1151  void Module::printModel( std::ostream& _out ) const
1152  {
1153  this->updateModel();
1154  mModel.clean();
1155  if( !mModel.empty() )
1156  {
1157  _out << mModel;
1158  }
1159  }
1160 
1161  void Module::printAllModels( std::ostream& _out )
1162  {
1163  this->updateAllModels();
1164  for( const auto& m : mAllModels )
1165  {
1166  _out << m << std::endl;
1167  }
1168  }
1169 } // namespace smtrat
#define OLD_SPLITTING_VARS_UNLOCK
Definition: Module.h:253
#define OLD_SPLITTING_VARS_LOCK
Definition: Module.h:252
#define SMTRAT_VALIDATION_ADD(channel, name, formula, consistent)
Definition: Validation.h:26
Base class for solvers.
Definition: Manager.h:34
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 addInformationRelevantFormula(const FormulaT &formula)
Adds formula to InformationRelevantFormula.
Definition: Manager.h:319
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
auto logic() const
Definition: Manager.h:304
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
super::const_iterator const_iterator
Passing through the list::const_iterator.
Definition: ModuleInput.h:146
void updateProperties()
Updates all properties of the formula underlying this module input.
bool contains(const FormulaT &_subformula) const
Definition: ModuleInput.h:372
void clearOrigins(iterator _formula)
Definition: ModuleInput.h:417
unsigned satisfiedBy(const Model &_assignment) const
Definition: ModuleInput.cpp:33
iterator erase(iterator _formula)
Definition: ModuleInput.cpp:98
bool removeOrigin(iterator _formula, const FormulaT &_origin)
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
void clearModel() const
Clears the assignment, if any was found.
Definition: Module.h:749
const std::vector< FormulaSetT > & infeasibleSubsets() const
Definition: Module.h:480
std::pair< ModuleInput::iterator, bool > addReceivedSubformulaToPassedFormula(ModuleInput::const_iterator _subformula)
Copies the given sub-formula of the received formula to the passed formula.
Definition: Module.h:857
virtual void init()
Informs all backends about the so far encountered constraints, which have not yet been communicated.
Definition: Module.cpp:234
std::vector< FormulaSetT > mInfeasibleSubsets
Stores the infeasible subsets.
Definition: Module.h:195
void printReceivedFormula(const std::string &_initiation="***") const
Prints the vector of the received formula.
Definition: Module.cpp:1105
void splitUnequalConstraint(const FormulaT &)
Adds the following lemmas for the given constraint p!=0.
Definition: Module.cpp:565
void addInformationRelevantFormula(const FormulaT &formula)
Adds a formula to the InformationRelevantFormula.
Definition: Module.cpp:1068
std::vector< Model > mAllModels
Stores all satisfying assignments.
Definition: Module.h:201
const std::vector< Module * > & usedBackends() const
Definition: Module.h:488
bool anAnswerFound() const
Checks for all antecedent modules and those which run in parallel with the same antecedent modules,...
Definition: Module.h:737
std::vector< Module * > mAllBackends
The backends of this module which have been used.
Definition: Module.h:227
virtual bool addCore([[maybe_unused]] ModuleInput::const_iterator formula)
The module has to take the given sub-formula of the received formula into account.
Definition: Module.h:706
carl::FastSet< FormulaT > mConstraintsToInform
Stores the constraints which the backends must be informed about.
Definition: Module.h:233
virtual std::string moduleName() const
Definition: Module.h:615
ModuleInput::iterator mFirstSubformulaToPass
Stores the position of the first sub-formula in the passed formula, which has not yet been considered...
Definition: Module.h:231
const std::set< FormulaT > & getInformationRelevantFormulas()
Gets all InformationRelevantFormulas.
Definition: Module.cpp:1074
const Model & backendsModel() const
Stores the model of a backend which determined satisfiability of the passed formula in the model of t...
Definition: Module.cpp:630
Conditionals mFoundAnswer
Vector of Booleans: If any of them is true, we have to terminate a running check procedure.
Definition: Module.h:223
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
std::vector< std::size_t > mVariableCounters
Maps variables to the number of their occurrences.
Definition: Module.h:241
void deinform(const FormulaT &_constraint)
The inverse of informing about a constraint.
Definition: Module.cpp:124
bool originInReceivedFormula(const FormulaT &_origin) const
Definition: Module.cpp:352
unsigned currentlySatisfiedByBackend(const FormulaT &_formula) const
Definition: Module.cpp:296
virtual Answer runBackends()
Definition: Module.h:1012
std::pair< ModuleInput::iterator, bool > addSubformulaToPassedFormula(const FormulaT &_formula)
Adds the given formula to the passed formula with no origin.
Definition: Module.h:873
Answer foundAnswer(Answer _answer)
Sets the solver state to the given answer value.
Definition: Module.cpp:856
bool probablyLooping(const typename Poly::PolyType &_branchingPolynomial, const Rational &_branchingValue) const
Checks whether given the current branching value and branching variable/polynomial it is (highly) pro...
Definition: Module.cpp:426
virtual ~Module()
Destructs a module.
Definition: Module.cpp:76
virtual std::pair< bool, FormulaT > getReceivedFormulaSimplified()
Definition: Module.cpp:945
bool mFullCheck
false, if this module should avoid too expensive procedures and rather return unknown instead.
Definition: Module.h:207
unsigned mSmallerMusesCheckCounter
Counter used for the generation of the smt2 files to check for smaller muses.
Definition: Module.h:239
Manager *const mpManager
A reference to the manager.
Definition: Module.h:197
bool inform(const FormulaT &_constraint)
Informs the module about the given constraint.
Definition: Module.cpp:117
ModuleStatistics & mStatistics
Definition: Module.h:192
void printInfeasibleSubsets(const std::string &_initiation="***") const
Prints the infeasible subsets.
Definition: Module.cpp:1136
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
void clearPassedFormula()
Definition: Module.cpp:850
std::vector< Lemma > mLemmas
Stores the lemmas being valid formulas this module or its backends made.
Definition: Module.h:229
const Model & model() const
Definition: Module.h:463
void checkInfSubsetForMinimality(std::vector< FormulaSetT >::const_iterator _infsubset, const std::string &_filename="smaller_muses", unsigned _maxSizeDifference=1) const
Checks the given infeasible subset for minimality by storing all subsets of it, which have a smaller ...
Definition: Module.cpp:1018
bool isLemmaLevel(LemmaLevel level)
Checks if current lemma level is greater or equal to given level.
Definition: Module.cpp:1079
void updateLemmas()
Stores all lemmas of any backend of this module in its own lemma vector.
Definition: Module.cpp:919
Model mModel
Stores the assignment of the current satisfiable result, if existent.
Definition: Module.h:199
std::vector< FormulaT >::const_iterator findBestOrigin(const std::vector< FormulaT > &_origins) const
Definition: Module.cpp:691
Answer solverState() const
Definition: Module.h:388
virtual void removeCore([[maybe_unused]] ModuleInput::const_iterator formula)
Removes everything related to the given sub-formula of the received formula.
Definition: Module.h:729
const FormulaT & getOrigins(ModuleInput::const_iterator _formula) const
Gets the origins of the passed formula at the given position.
Definition: Module.h:808
void excludeNotReceivedVariablesFromModel() const
Excludes all variables from the current model, which do not occur in the received formula.
Definition: Module.cpp:884
virtual void addConstraintToInform(const FormulaT &_constraint)
Adds a constraint to the collection of constraints of this module, which are informed to a freshly ge...
Definition: Module.cpp:877
virtual bool informCore([[maybe_unused]] const FormulaT &_constraint)
Informs the module about the given constraint.
Definition: Module.h:684
std::atomic< Answer > mSolverState
States whether the received formula is known to be satisfiable or unsatisfiable otherwise it is set t...
Definition: Module.h:215
void collectOrigins(const FormulaT &_formula, FormulasT &_origins) const
Collects the formulas in the given formula, which are part of the received formula.
Definition: Module.cpp:960
carl::FastSet< FormulaT > mInformedConstraints
Stores the position of the first constraint of which no backend has been informed about.
Definition: Module.h:235
bool hasValidInfeasibleSubset() const
Definition: Module.cpp:1000
virtual ModuleInput::iterator eraseSubformulaFromPassedFormula(ModuleInput::iterator _subformula, bool _ignoreOrigins=false)
Removes everything related to the sub-formula to remove from the passed formula in the backends of th...
Definition: Module.cpp:807
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
unsigned checkModel() const
Definition: Module.cpp:588
carl::Variable mObjectiveVariable
Objective variable to be minimized. If set to NO_VARIABLE, a normal sat check should be performed.
Definition: Module.h:209
const ModuleInput & rReceivedFormula() const
Definition: Module.h:439
size_t determine_smallest_origin(const std::vector< FormulaT > &origins) const
Definition: Module.cpp:403
std::vector< TheoryPropagation > mTheoryPropagations
Definition: Module.h:211
virtual Answer checkCore()
Checks the received formula for consistency.
Definition: Module.cpp:207
void print(const std::string &_initiation="***") const
Prints everything relevant of the solver.
Definition: Module.cpp:1085
void receivedFormulaChecked()
Notifies that the received formulas has been checked.
Definition: Module.h:589
void getBackendsModel() const
Definition: Module.cpp:652
void collectTheoryPropagations()
Definition: Module.cpp:928
std::atomic_bool * mBackendsFoundAnswer
This flag is passed to any backend and if it determines an answer to a prior check call,...
Definition: Module.h:220
virtual void remove(ModuleInput::const_iterator _subformula)
Removes everything related to the given sub-formula of the received formula.
Definition: Module.cpp:159
std::vector< Module * > mUsedBackends
The backends of this module which are currently used (conditions to use this module are fulfilled for...
Definition: Module.h:225
std::size_t mId
A unique ID to identify this module instance. (Could be useful but currently nowhere used)
Definition: Module.h:184
bool branchAt(const Poly &_polynomial, bool _integral, const Rational &_value, std::vector< FormulaT > &&_premise, bool _leftCaseWeak=true, bool _preferLeftCase=true, bool _useReceivedFormulaAsPremise=false)
Adds a lemmas which provoke a branching for the given variable at the given value,...
Definition: Module.cpp:478
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
bool mModelComputed
True, if the model has already been computed.
Definition: Module.h:203
std::vector< FormulaT > merge(const std::vector< FormulaT > &, const std::vector< FormulaT > &) const
Merges the two vectors of sets into the first one.
Definition: Module.cpp:377
void clearLemmas()
Deletes all yet found lemmas.
Definition: Module.h:550
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
const ModuleInput * mpReceivedFormula
The formula passed to this module.
Definition: Module.h:188
static std::vector< FormulaT > mOldSplittingVariables
Reusable splitting variables.
Definition: Module.h:277
void getBackendsAllModels() const
Stores all models of a backend in the list of all models of this module.
Definition: Module.cpp:669
void getInfeasibleSubsets()
Copies the infeasible subsets of the passed formula.
Definition: Module.cpp:596
ModuleInput * mpPassedFormula
The formula passed to the backends of this module.
Definition: Module.h:190
virtual void deinformCore([[maybe_unused]] const FormulaT &_constraint)
The inverse of informing about a constraint.
Definition: Module.h:695
bool mFinalCheck
true, if the check procedure should perform a final check which especially means not to postpone spli...
Definition: Module.h:205
static bool modelsDisjoint(const Model &_modelA, const Model &_modelB)
Checks whether there is no variable assigned by both models.
Definition: Module.cpp:611
void printPassedFormula(const std::string &_initiation="***") const
Prints the vector of passed formula.
Definition: Module.cpp:1118
ModuleInput::const_iterator mFirstUncheckedReceivedSubformula
Stores the position of the first (by this module) unchecked sub-formula of the received formula.
Definition: Module.h:237
int var(Lit p)
Definition: SolverTypes.h:64
static bool find(V &ts, const T &t)
Definition: Alg.h:47
bool contains(const std::vector< TagPoly > &polys, const Poly &poly)
Definition: utils.h:314
std::vector< carl::Variable > vars(const std::pair< QuantifierType, std::vector< carl::Variable >> &p)
Definition: QEQuery.h:43
Class to create the formulas for axioms.
LemmaLevel
Definition: types.h:53
carl::ModelValue< Rational, Poly > ModelValue
Definition: model.h:12
carl::FormulaSet< Poly > FormulaSetT
Definition: types.h:41
bool is_sat(Answer a)
Definition: types.h:58
carl::Formula< Poly > FormulaT
Definition: types.h:37
static const Model EMPTY_MODEL
Definition: model.h:15
carl::Model< Rational, Poly > Model
Definition: model.h:13
carl::MultivariatePolynomial< Rational > Poly
Definition: types.h:25
Answer
An enum with the possible answers a Module can give.
Definition: types.h:57
@ SAT
Definition: types.h:57
@ UNSAT
Definition: types.h:57
@ UNKNOWN
Definition: types.h:57
@ ABORTED
Definition: types.h:57
std::vector< std::atomic_bool * > Conditionals
A vector of atomic bool pointers.
Definition: types.h:17
carl::Constraint< Poly > ConstraintT
Definition: types.h:29
carl::Formulas< Poly > FormulasT
Definition: types.h:39
mpq_class Rational
Definition: types.h:19
std::pair< std::size_t, std::size_t > thread_priority
Definition: types.h:50
#define SMTRAT_LOG_INFO(channel, msg)
Definition: logging.h:34
#define SMTRAT_LOG_ERROR(channel, msg)
Definition: logging.h:32
#define SMTRAT_LOG_DEBUG(channel, msg)
Definition: logging.h:35
Stores all necessary information of an branch, which can be used to detect probable infinite loop of ...
Definition: Module.h:32