4 * @author Sebastian Junges
9 #include <smtrat-common/smtrat-common.h>
12 #include "GBModuleStatistics.h"
13 #include "UsingDeclarations.h"
15 #include <reallynull/lib/GroebnerToSDP/GroebnerToSDP.h>
18 //#define CHECK_SMALLER_MUSES
19 //#define SEARCH_FOR_RADICALMEMBERS
20 //#define GB_OUTPUT_METHODS
30 template<class Settings>
31 GBModule<Settings>::GBModule( const ModuleInput* const _formula, Conditionals& _conditionals, Manager* const _manager ):
32 Module( _formula, _conditionals, _manager ),
34 mInequalities( this ),
37 #ifdef SMTRAT_DEVOPTION_Statistics
39 mStats(GBModuleStats::getInstance(Settings::identifier)),
40 mGBStats(GBCalculationStats::getInstance(Settings::identifier))
43 pushBacktrackPoint( rReceivedFormula().end( ) );
46 template<class Settings>
47 GBModule<Settings>::~GBModule( )
51 * Adds the constraint to the known constraints of the module.
52 * This includes scanning variables as well as transforming inequalities, if this is enabled.
53 * @param _formula A REALCONSTRAINT which should be regarded by the next theory call.
56 template<class Settings>
57 bool GBModule<Settings>::addCore( ModuleInput::const_iterator _formula )
59 if( _formula->formula().type() != carl::FormulaType::CONSTRAINT )
63 assert(!_formula->formula().constraint().lhs().is_constant());
65 #ifdef SMTRAT_DEVOPTION_Statistics
66 const ConstraintT& constraint = _formula->formula().constraint( );
67 mStats.constraintAdded(constraint.relation());
70 processNewConstraint(_formula);
71 //only equalities should be added to the gb
76 template<class Settings>
77 bool GBModule<Settings>::constraintByGB(carl::Relation cr)
79 return ((cr == carl::Relation::EQ) ||
80 (Settings::transformIntoEqualities == ALL_INEQUALITIES) ||
81 (Settings::transformIntoEqualities == ONLY_NONSTRICT && (cr == carl::Relation::GEQ || cr == carl::Relation::LEQ) ));
85 * Method which updates internal data structures to reflect the added formula.
88 template<class Settings>
89 void GBModule<Settings>::processNewConstraint(ModuleInput::const_iterator _formula)
91 const ConstraintT& constraint = _formula->formula().constraint( );
92 bool toGb = constraintByGB(constraint.relation());
96 handleConstraintToGBQueue(_formula);
100 handleConstraintNotToGB(_formula);
105 * Method which adds constraint to the GB-process.
108 template<class Settings>
109 void GBModule<Settings>::handleConstraintToGBQueue(ModuleInput::const_iterator _formula)
111 pushBacktrackPoint( _formula );
112 // Equalities do not need to be transformed, so we add them directly.
114 if(_formula->formula().constraint( ).relation() == carl::Relation::EQ)
116 newPol = GBPolynomial ((typename Poly::PolyType)_formula->formula().constraint().lhs());
120 newPol = transformIntoEquality( _formula );
123 newPol.setReasons(carl::BitVector(unsigned(mBacktrackPoints.size() - 1)));
124 mBasis.addPolynomial( newPol );
127 if( !Settings::passGB )
129 addReceivedSubformulaToPassedFormula( _formula );
135 * Method which adds constraints to our internal datastructures without adding them to the GB. E.g. inequalities are added to the inequalitiestable.
138 template<class Settings>
139 void GBModule<Settings>::handleConstraintNotToGB(ModuleInput::const_iterator _formula)
141 if( Settings::checkInequalities == NEVER )
143 addReceivedSubformulaToPassedFormula( _formula );
145 else if( Settings::checkInequalities == ALWAYS )
147 mNewInequalities.push_back( mInequalities.InsertReceivedFormula( _formula ) );
148 // assert((mNewInequalities.back()->first)->formula()->constraint().relation() != carl::Relation::EQ); TODO: ???
152 assert( Settings::checkInequalities == AFTER_NEW_GB);
153 mInequalities.InsertReceivedFormula( _formula );
159 * A theory call to the GBModule. The exact working of this module depends on the settings in GBSettings.
160 * @return (TRUE,FALSE,UNKNOWN) dependent on the asserted constraints.
162 template<class Settings>
163 Answer GBModule<Settings>::checkCore()
166 std::cout << "GB Called" << std::endl;
168 // We can only handle conjunctions of constraints.
169 if(!rReceivedFormula().is_constraint_conjunction())
173 // This check asserts that all the conflicts are handled by the SAT solver. (workaround)
174 if( !mInfeasibleSubsets.empty() )
179 #ifdef SMTRAT_DEVOPTION_Statistics
183 assert( mInfeasibleSubsets.empty( ) );
185 // New elements queued for adding to the gb have to be handled.
186 if( !mBasis.inputEmpty( ) )
189 std::cout << "Scheduled: " << std::endl;
190 mBasis.printScheduledPolynomials();
192 if(Settings::iterativeVariableRewriting)
194 if(mRewriteRules.size() > 0)
196 std::list<std::pair<carl::BitVector, carl::BitVector> > deductions;
198 //deductions = mBasis.applyVariableRewriteRulesToInput(mRewriteRules);
199 knownConstraintDeduction(deductions);
203 std::cout << "-------->" << std::endl;
204 mBasis.printScheduledPolynomials();
205 std::cout << "--------|" << std::endl;
207 //first, we interreduce the input!
210 if( !mBasis.inputEmpty( ) )
212 std::list<std::pair<carl::BitVector, carl::BitVector> > deduced = mBasis.reduceInput( );
213 //analyze for deductions
214 knownConstraintDeduction(deduced);
217 //If the GB needs to be updated, we do so. Otherwise we skip.
218 // Notice that we might to update the gb after backtracking (mRecalculateGB flag).
219 if( !mBasis.inputEmpty( ) || (mRecalculateGB && mBacktrackPoints.size() > 1 ) )
221 //now, we calculate the groebner basis
223 std::cout << "basis calculate call" << std::endl;
227 std::cout << "basis calculated" << std::endl;
228 mBasis.getIdeal().print();
230 mRecalculateGB = false;
231 if( Settings::iterativeVariableRewriting && !mBasis.basisis_constant( ) )
233 iterativeVariableRewriting();
235 GBPolynomial witness;
237 // If the system is constant, we already have a witness for unsatisfiability.
238 // On linear systems, all solutions lie in Q. So we do not have to check for a solution.
239 if( Settings::applyNSS && !mBasis.is_constant( ) && !mBasis.getGbIdeal( ).is_linear( ) )
241 witness = callGroebnerToSDP(mBasis.getGbIdeal());
243 // We have found an infeasible subset. Generate it.
245 if( mBasis.basisis_constant( ) || (Settings::applyNSS && !carl::is_zero(witness)) )
248 if( mBasis.basisis_constant( ) )
250 #ifdef SMTRAT_DEVOPTION_Statistics
253 assert(mBasis.getIdeal().nrGenerators() == 1);
254 witness = mBasis.getIdeal( ).getGenerators().front();
259 typename Settings::Reductor red( mBasis.getGbIdeal( ), witness );
260 witness = red.fullReduce( );
261 std::cout << witness << std::endl;
262 assert( carl::is_zero(witness) );
265 mInfeasibleSubsets.emplace_back();
266 // The equalities we used for the basis-computation are the infeasible subset
268 assert(!Settings::getReasonsForInfeasibility || !witness.getReasons().empty());
269 carl::BitVector::const_iterator origIt = witness.getReasons().begin( );
270 origIt++; // As the first bit shows to the first entry in the backtrack points, which is the end of the received formula
272 auto it = mBacktrackPoints.begin( );
273 for( ++it; it != mBacktrackPoints.end( ); ++it )
275 assert(it != mBacktrackPoints.end());
276 assert( (*it)->formula().type() == carl::FormulaType::CONSTRAINT );
277 assert( Settings::transformIntoEqualities != NO_INEQUALITIES || (*it)->formula().constraint( ).relation( ) == carl::Relation::EQ );
279 if( Settings::getReasonsForInfeasibility )
284 mInfeasibleSubsets.back( ).insert( (*it)->formula() );
290 mInfeasibleSubsets.back( ).insert( (*it)->formula() );
294 #ifdef SMTRAT_DEVOPTION_Statistics
295 mStats.EffectivenessOfConflicts( (double)mInfeasibleSubsets.back().size()/(double)rReceivedFormula().size());
297 #ifdef CHECK_SMALLER_MUSES
298 Module::checkInfSubsetForMinimality( mInfeasibleSubsets->begin() );
300 assert(!mInfeasibleSubsets.empty());
301 assert(!mInfeasibleSubsets.front().empty());
307 if( Settings::checkInequalities != NEVER )
309 Answer ans = UNKNOWN;
310 ans = mInequalities.reduceWRTGroebnerBasis( mBasis.getIdeal( ), mRewriteRules );
317 assert( mInfeasibleSubsets.empty( ) );
319 // When passing a gb, first remove last and then pass current gb.
320 if( Settings::passGB )
322 // TODO: Do not use rPassedFormulaBegin, which should be disabled
323 for( ModuleInput::iterator i = passedFormulaBegin( ); i != rPassedFormula().end( ); )
325 // assert( i->formula().type() == carl::FormulaType::CONSTRAINT ); // TODO: Assure, not to add TRUE to the passed formula.
326 if( std::count(mGbEqualities.begin(), mGbEqualities.end(), i->formula()) == 1 )
328 i = super::eraseSubformulaFromPassedFormula( i, true );
335 mGbEqualities.clear();
339 // If we always want to check inequalities, we also have to do so when there is no new groebner basis
340 else if( Settings::checkInequalities == ALWAYS )
342 Answer ans = UNKNOWN;
343 // We only check those inequalities which are new, as the others are unchanged and have already been reduced wrt the latest GB
344 ans = mInequalities.reduceWRTGroebnerBasis( mNewInequalities, mBasis.getIdeal( ), mRewriteRules );
345 // New inequalities are handled now, no need to longer save them as new.
346 mNewInequalities.clear( );
347 // If we managed to get an answer, we can return that.
353 assert( mInfeasibleSubsets.empty( ) );
357 mInequalities.print();
358 std::cout << "Basis" << std::endl;
359 mBasis.getIdeal().print();
363 // call other modules as the groebner module cannot decide satisfiability.
364 Answer ans = runBackends();
367 #ifdef SMTRAT_DEVOPTION_Statistics
368 mStats.backendFalse();
370 // use the infeasible subsets from our backends.
371 getInfeasibleSubsets( );
373 assert( !mInfeasibleSubsets.empty( ) );
380 * With the new groebner basis, we search for radical-members which then can be added to the GB.
384 template<class Settings>
385 bool GBModule<Settings>::iterativeVariableRewriting()
387 std::list<GBPolynomial> polynomials = mBasis.listBasisPolynomials();
388 bool newRuleFound = true;
389 bool gbUpdate = false;
391 // The parameters of the new rule.
392 carl::Variable ruleVar = carl::Variable::NO_VARIABLE;
394 carl::BitVector ruleReasons;
396 std::map<carl::Variable, std::pair<TermT, carl::BitVector> >& rewrites = mRewriteRules;
397 typename Settings::Groebner basis;
401 newRuleFound = false;
403 std::cout << "current gb" << std::endl;
404 for(typename std::list<GBPolynomial>::const_iterator it = polynomials.begin(); it != polynomials.end(); ++it )
407 it->getReasons().print();
408 std::cout << std::endl;
410 std::cout << "----" << std::endl;
413 for(typename std::list<GBPolynomial>::iterator it = polynomials.begin(); it != polynomials.end();)
415 if( it->nr_terms() == 1 && it->lterm().tdeg()==1 )
417 //TODO optimization, this variable does not appear in the gb.
418 ruleVar = it->lterm().single_variable();
419 ruleTerm = TermT(Rational(0));
420 ruleReasons = it->getReasons();
423 else if( it->nr_terms() == 2 )
425 if(it->lterm().tdeg() == 1 )
427 ruleVar = it->lterm().single_variable();
428 if( it->trailingTerm().has(ruleVar) )
430 // TODO deduce a factorisation.
435 ruleTerm = -(it->trailingTerm());
436 ruleReasons = it->getReasons();
440 else if(it->trailingTerm().tdeg() == 1 )
442 ruleVar = it->trailingTerm().single_variable();
443 if( it->lterm().has(ruleVar) )
445 // TODO deduce a factorisation
450 it->lterm().divide(-it->trailingTerm().coeff(), ruleTerm);
451 ruleReasons = it->getReasons();
458 it = polynomials.erase(it);
470 rewrites.insert(std::pair<carl::Variable, std::pair<TermT, carl::BitVector> >(ruleVar, std::pair<TermT, BitVector>(ruleTerm, ruleReasons ) ) );
472 std::list<GBPolynomial> resultingGb;
474 for(typename std::list<GBPolynomial>::const_iterator it = polynomials.begin(); it != polynomials.end(); ++it )
476 resultingGb.push_back(rewriteVariable(*it,ruleVar, ruleTerm, ruleReasons));
477 basis.addPolynomial(resultingGb.back());
479 std::cout << *it << " ---- > ";
481 std::cout << resultingGb.back() << std::endl;
485 if( !basis.inputEmpty( ) )
489 polynomials = basis.listBasisPolynomials();
492 for( std::map<carl::Variable, std::pair<TermT, BitVector> >::iterator it = rewrites.begin(); it != rewrites.end(); ++it )
495 //std::pair<Term, bool> reducedRule = it->second.first.rewriteVariables(ruleVar, ruleTerm);
496 //if(reducedRule.second)
498 // it->second.first = reducedRule.first;
499 // it->second.second |= ruleReasons;
515 #ifdef SEARCH_FOR_RADICALMEMBERS
516 std::set<unsigned> variableNumbers(mBasis.getGbIdeal().gatherVariables());
518 // find variable rewrite rules
519 // apply the rules RRI-* from the Thesis from G.O. Passmore
520 // Iterate over all variables in the GB
521 for(std::set<unsigned>::const_iterator it = variableNumbers.begin(); it != variableNumbers.end(); ++it) {
522 // We search until a given (static) maximal exponent
523 for(unsigned exponent = 3; exponent <= 17; ++(++exponent) )
526 TermT t(Rational(1), *it, exponent);
527 GBPolynomial reduce(t);
530 typename Settings::Reductor reduction( mBasis.getGbIdeal( ), reduce );
531 reduce = reduction.fullReduce( );
533 if( reduce.is_constant() )
535 // TODO handle 0 and 1.
536 // TODO handle other cases
537 // calculate q-root(reduce);
538 #ifdef SMTRAT_DEVOPTION_Statistics
539 mStats.FoundEqualities();
541 std::cout << t << " -> " << reduce << std::endl;
546 else if( reduce.isReducedIdentity(*it, exponent))
548 #ifdef SMTRAT_DEVOPTION_Statistics
549 mStats.FoundIdentities();
551 std::cout << t << " -> " << reduce << std::endl;
565 * A method which looks for polynomials which have trivial factors.
568 template<class Settings>
569 bool GBModule<Settings>::findTrivialFactorisations()
574 template<class Settings>
575 void GBModule<Settings>::knownConstraintDeduction(const std::list<std::pair<carl::BitVector,carl::BitVector> >& deductions)
577 for(auto it = deductions.rbegin(); it != deductions.rend(); ++it)
579 // if the bitvector is not empty, there is a theory deduction
580 if( Settings::addTheoryDeductions == ALL_CONSTRAINTS && !it->second.empty() )
582 FormulasT subformulas;
583 FormulasT deduced( generateReasons( it->first ));
584 // When this kind of deduction is greater than one, we would have to determine wich of them is really the deduced one.
585 if( deduced.size() > 1 ) continue;
586 FormulasT originals( generateReasons( it->second ));
587 FormulasT originalsWithoutDeduced;
589 std::set_difference(originals.begin(), originals.end(), deduced.begin(), deduced.end(), std::inserter(originalsWithoutDeduced, originalsWithoutDeduced.end()));
592 for( auto jt = originalsWithoutDeduced.begin(); jt != originalsWithoutDeduced.end(); ++jt )
594 subformulas.push_back( FormulaT( carl::FormulaType::NOT, *jt ) );
597 for( auto jt = deduced.begin(); jt != deduced.end(); ++jt )
599 subformulas.push_back( *jt );
602 addLemma( FormulaT( carl::FormulaType::OR, subformulas ) );
603 //deduction->print();
604 #ifdef SMTRAT_DEVOPTION_Statistics
605 mStats.DeducedEquality();
611 template<class Settings>
612 void GBModule<Settings>::newConstraintDeduction( )
619 * Removes the constraint from the GBModule.
620 * Notice: Whenever a constraint is removed which was not asserted before, this leads to an unwanted error.
621 * A general approach for this has to be found.
622 * @param _formula the constraint which should be removed.
624 template<class Settings>
625 void GBModule<Settings>::removeCore( ModuleInput::const_iterator _formula )
627 if(_formula->formula().type() != carl::FormulaType::CONSTRAINT) {
630 #ifdef SMTRAT_DEVOPTION_Statistics
631 mStats.constraintRemoved(_formula->formula().constraint().relation());
633 if( constraintByGB(_formula->formula().constraint().relation()))
635 popBacktrackPoint( _formula );
639 if( Settings::checkInequalities != NEVER )
641 if (Settings::checkInequalities == ALWAYS)
643 removeReceivedFormulaFromNewInequalities( _formula );
645 mInequalities.removeInequality( _formula );
651 * Removes a received formula from the list of new inequalities. It assumes that there is only one such element in the list.
654 template<class Settings>
655 void GBModule<Settings>::removeReceivedFormulaFromNewInequalities( ModuleInput::const_iterator _formula )
657 for(auto it = mNewInequalities.begin(); it != mNewInequalities.end(); ++it )
659 if((*it)->first == _formula)
661 mNewInequalities.erase(it);
668 * To implement backtrackability, we save the current state after each equality we add.
669 * @param btpoint The equality we have removed
671 template<class Settings>
672 void GBModule<Settings>::pushBacktrackPoint( ModuleInput::const_iterator btpoint )
674 assert( mBacktrackPoints.empty( ) || btpoint->formula().type() == carl::FormulaType::CONSTRAINT );
675 assert( mBacktrackPoints.size( ) == mStateHistory.size( ) );
677 // We save the current level
678 if( !mBacktrackPoints.empty( ) )
683 if( mStateHistory.empty() )
685 // there are no variable rewrite rules, so we can only push our current basis and empty rewrites
686 mStateHistory.emplace_back( mBasis, std::map<carl::Variable, std::pair<TermT, carl::BitVector> >() );
690 // we save the current basis and the rewrite rules
691 mStateHistory.push_back( GBModuleState<Settings>( mBasis, mRewriteRules ) );
694 mBacktrackPoints.push_back( btpoint );
695 assert( mBacktrackPoints.size( ) == mStateHistory.size( ) );
697 // If we also handle inequalities in the inequalitiestable, we have to notify it about the extra pushbacktrack point
698 if( Settings::checkInequalities != NEVER )
700 mInequalities.pushBacktrackPoint( );
706 * Pops all states from the stack until the state which we had before the constraint was added.
707 * Then, we make new states with all equalities which were added afterwards.
708 * @param a pointer in the received formula to the constraint which will be removed.
710 template<class Settings>
711 void GBModule<Settings>::popBacktrackPoint( ModuleInput::const_iterator btpoint )
713 //assert( validityCheck( ) );
714 assert( mBacktrackPoints.size( ) == mStateHistory.size( ) );
715 assert( !mBacktrackPoints.empty( ) );
717 //We first count how far we have to backtrack.
718 //Because the polynomials have to be added again afterwards, we save them in a list.
719 unsigned nrOfBacktracks = 1;
720 std::list<ModuleInput::const_iterator> rescheduled;
722 while( !mBacktrackPoints.empty( ) )
724 if( mBacktrackPoints.back( ) == btpoint )
726 mBacktrackPoints.pop_back( );
732 rescheduled.push_front(mBacktrackPoints.back());
733 mBacktrackPoints.pop_back( );
737 #ifdef SMTRAT_DEVOPTION_Statistics
738 mStats.PopLevel(nrOfBacktracks);
741 for( unsigned i = 0; i < nrOfBacktracks; ++i )
743 assert( !mStateHistory.empty( ) );
744 mStateHistory.pop_back( );
746 assert( mBacktrackPoints.size( ) == mStateHistory.size( ) );
747 assert( !mStateHistory.empty( ) );
749 // Load the state to be restored;
750 mBasis = mStateHistory.back( ).getBasis( );
751 mRewriteRules = mStateHistory.back().getRewriteRules();
752 //assert( mBasis.nrOriginalConstraints( ) == mBacktrackPoints.size( ) - 1 );
754 if( Settings::checkInequalities != NEVER )
756 mInequalities.popBacktrackPoint( nrOfBacktracks );
759 mRecalculateGB = true;
761 for( auto it = rescheduled.begin(); it != rescheduled.end(); ++it )
763 processNewConstraint(*it);
765 //assert( mBasis.nrOriginalConstraints( ) == mBacktrackPoints.size( ) - 1 );
771 * @param gb The current Groebner basis.
772 * @return A witness which is zero in case we had no success.
774 template<class Settings>
775 typename Settings::Polynomial GBModule<Settings>::callGroebnerToSDP( const Ideal& gb )
777 using namespace reallynull;
779 std::cout << "NSS..?" << std::flush;
781 std::set<unsigned> variables;
782 std::set<unsigned> allVars = gb.gatherVariables( );
783 std::set<unsigned> superfluous = gb.getSuperfluousVariables( );
784 std::set_difference( allVars.begin( ), allVars.end( ),
785 superfluous.begin( ), superfluous.end( ),
786 std::inserter( variables, variables.end( ) ) );
788 unsigned vars = variables.size( );
789 // We currently only try with a low nr of variables.
790 if( vars < Settings::SDPupperBoundNrVariables )
792 std::cout << " Run SDP.." << std::flush;
794 GroebnerToSDP<typename Settings::Order> sdp( gb, MonomialIterator( variables, Settings::maxSDPdegree ) );
795 witness = sdp.findWitness( );
797 std::cout << std::endl;
798 if( !carl::is_zero(witness) ) std::cout << "Found witness: " << witness << std::endl;
804 * Transforms a given inequality to a polynomial such that p = 0 is equivalent to the given constraint.
805 * This is done by inserting an additional variable which has an index which is given by the id of the given inequality.
806 * @param constraint a pointer to the inequality
807 * @return The polynomial which represents the equality.
809 template<class Settings>
810 typename GBModule<Settings>::GBPolynomial GBModule<Settings>::transformIntoEquality( ModuleInput::const_iterator constraint )
812 GBPolynomial result( (typename Poly::PolyType)constraint->formula().constraint( ).lhs( ) );
813 const auto& constr = constraint->formula().constraint( );
814 std::map<ConstraintT, carl::Variable>::const_iterator mapentry = mAdditionalVarMap.find( constr );
815 carl::Variable var = carl::Variable::NO_VARIABLE;
816 if( mapentry == mAdditionalVarMap.end( ) )
818 std::stringstream stream;
819 stream << "AddVarGB" << constr;
821 var = carl::fresh_real_variable( stream.str() );
822 mAdditionalVarMap.insert(std::pair<ConstraintT, carl::Variable>(constr, var));
826 var = mapentry->second;
829 // Modify to reflect inequalities.
830 switch( constraint->formula().constraint( ).relation( ) )
832 case carl::Relation::GEQ:
833 result = result + TermT( -1, var, 2 );
835 case carl::Relation::LEQ:
836 result = result + TermT( 1, var, 2 );
838 case carl::Relation::GREATER:
839 result = result * TermT( 1, var, 2 );
840 result = result + TermT( -1 );
842 case carl::Relation::LESS:
843 result = result * TermT( 1, var, 2 );
844 result = result + TermT( 1 );
846 case carl::Relation::NEQ:
847 result = result * TermT( 1, var, 1);
848 result = result + TermT( 1 );
860 template<class Settings>
861 bool GBModule<Settings>::saveState( )
863 assert( mStateHistory.size( ) == mBacktrackPoints.size( ) );
865 // TODO fix this copy.
866 mStateHistory.pop_back( );
867 mStateHistory.push_back( GBModuleState<Settings>( mBasis, mRewriteRules ) );
873 * Add the equalities from the Groebner basis to the passed formula. Adds the reason vector.
875 template<class Settings>
876 void GBModule<Settings>::passGB( )
878 // This method should only be called if the GB should be passed.
879 assert( Settings::passGB );
881 // Declare a set of reason sets.
884 if( !Settings::passWithMinimalReasons )
886 // In the case we do not want to pass the GB with a minimal reason set,
887 // we calculate the reason set here for all polynomials.
888 for( ModuleInput::const_iterator it = rReceivedFormula().begin( ); it != rReceivedFormula().end( ); ++it )
890 // Add the constraint if it is of a type that it was handled by the gb.
891 if( constraintByGB(it->formula().constraint( ).relation( )) )
893 originals.push_back( it->formula() );
896 assert(!originals.empty());
899 // We extract the current polynomials from the Groebner Basis.
900 const std::vector<GBPolynomial>& simplified = mBasis.getBasisPolynomials();
901 // For each polynomial in this Groebner basis,
902 for( typename std::vector<GBPolynomial>::const_iterator simplIt = simplified.begin( ); simplIt != simplified.end( ); ++simplIt )
904 if( Settings::passWithMinimalReasons )
906 assert(!simplIt->getReasons().empty( ));
907 // We calculate the reason set for this polynomial in the GB.
908 originals = generateReasons( simplIt->getReasons() );
910 // The reason set may never be empty.
911 assert(!originals.empty());
912 // We now add polynomial = 0 as a constraint to the passed formula.
913 // We use the originals set calculated before as reason set.
914 assert(!simplIt->is_constant());
915 auto res = addSubformulaToPassedFormula( FormulaT( Poly(typename smtrat::Poly::PolyType((*simplIt))), carl::Relation::EQ ), FormulaT( carl::FormulaType::AND, originals ) );
917 mGbEqualities.push_back(res.first->formula());
922 * Generate reason sets from reason vectors
923 * @param reasons The reasons vector.
924 * @return The reason set.
926 template<class Settings>
927 FormulasT GBModule<Settings>::generateReasons( const carl::BitVector& reasons )
934 carl::BitVector::const_iterator origIt = reasons.begin( );
938 auto it = mBacktrackPoints.begin( );
939 for( ++it; it != mBacktrackPoints.end( ); ++it )
941 assert( (*it)->formula().type() == carl::FormulaType::CONSTRAINT );
942 assert( Settings::transformIntoEqualities != NO_INEQUALITIES || (*it)->formula().constraint( ).relation( ) == carl::Relation::EQ );
943 // If the corresponding entry in the reason vector is set,
944 // we add the polynomial.
947 origins.push_back( (*it)->formula() );
956 * Generate reason sets from reason vectors
957 * @param reasons The reasons vector.
958 * @return The reason set.
960 template<class Settings>
961 FormulaSetT GBModule<Settings>::generateReasonSet( const carl::BitVector& reasons )
965 return FormulaSetT();
968 carl::BitVector::const_iterator origIt = reasons.begin( );
972 auto it = mBacktrackPoints.begin( );
973 for( ++it; it != mBacktrackPoints.end( ); ++it )
975 assert( (*it)->formula().type() == carl::FormulaType::CONSTRAINT );
976 assert( Settings::transformIntoEqualities != NO_INEQUALITIES || (*it)->formula().constraint( ).relation( ) == carl::Relation::EQ );
977 // If the corresponding entry in the reason vector is set,
978 // we add the polynomial.
981 origins.insert( (*it)->formula() );
990 * A validity check of the data structures which can be used to assert valid behaviour.
991 * @return true, iff the backtrackpoints are valid.
993 template<class Settings>
994 bool GBModule<Settings>::validityCheck( )
996 auto btp = mBacktrackPoints.begin( );
998 for( auto it = rReceivedFormula().begin( ); it != rReceivedFormula().end( ); ++it )
1000 bool isInGb = constraintByGB(it->formula().constraint( ).relation( ));
1007 // printStateHistory( );
1008 // std::cout << *it << " (Element in received formula) != " << **btp << "(Backtrackpoint)" << std::endl;
1018 * This function is overwritten such that it is visible to the InequalitiesTable.
1019 * For more details take a look at Module::eraseSubformulaFromPassedFormula(..)
1022 template<class Settings>
1023 void GBModule<Settings>::removeSubformulaFromPassedFormula( ModuleInput::iterator _formula )
1025 super::eraseSubformulaFromPassedFormula( _formula, true );
1028 #ifdef GB_OUTPUT_METHODS
1031 * Prints the state history.
1033 template<class Settings>
1034 void GBModule<Settings>::printStateHistory( )
1037 auto btp = mBacktrackPoints.begin( );
1038 for( auto it = mStateHistory.begin( ); it != mStateHistory.end( ); ++it )
1040 std::cout << (*btp)->formula() << ": ";
1041 it->getBasis( ).getIdeal( ).print( );
1042 std::cout << "," << std::endl;
1045 std::cout << "]" << std::endl;
1049 * Prints the rewrite rules.
1051 template<class Settings>
1052 void GBModule<Settings>::printRewriteRules( )
1054 for(auto it = mRewriteRules.begin(); it != mRewriteRules.end(); ++it)
1056 std::cout << it->first << " -> " << it->second.first << " [";
1057 it->second.second.print();
1058 std::cout << "]" << std::endl;
1063 } // namespace smtrat