12 #include <carl-arith/poly/umvpoly/functions/Derivative.h>
13 #include <carl-arith/poly/umvpoly/functions/SoSDecomposition.h>
14 #include <carl-arith/constraint/IntervalEvaluation.h>
15 #include <carl-arith/vs/Substitution.h>
27 bool containsEmptyDisjunction =
false;
28 auto conj = _toSimplify.begin();
29 while( conj != _toSimplify.end() )
31 bool conjInconsistent =
false;
32 auto cons = (*conj).begin();
33 while( cons != (*conj).end() )
37 conjInconsistent =
true;
41 cons = (*conj).erase( cons );
45 bool conjEmpty = (*conj).empty();
46 if( conjInconsistent || (containsEmptyDisjunction && conjEmpty) )
50 conj = _toSimplify.erase( conj );
54 if( !containsEmptyDisjunction && conjEmpty )
55 containsEmptyDisjunction =
true;
61 bool containsEmptyDisjunction =
false;
62 auto conj = _toSimplify.begin();
63 while( conj != _toSimplify.end() )
65 bool conjInconsistent =
false;
66 auto cons = (*conj).begin();
67 while( cons != (*conj).end() )
71 conjInconsistent =
true;
75 cons = (*conj).erase( cons );
78 unsigned conflictingWithSolutionSpace = consistent_with(cons->constr(), _solutionSpace );
87 if( conflictingWithSolutionSpace == 0 )
89 auto vars = carl::variables(*cons);
90 _conflictingVars.insert(
vars.begin(),
vars.end() );
91 conjInconsistent =
true;
94 else if( conflictingWithSolutionSpace == 1 )
95 cons = (*conj).erase( cons );
100 bool conjEmpty = (*conj).empty();
101 if( conjInconsistent || (containsEmptyDisjunction && conjEmpty) )
105 conj = _toSimplify.erase( conj );
109 if( !containsEmptyDisjunction && conjEmpty )
110 containsEmptyDisjunction =
true;
117 size_t toSimpSize = _toSimplify.size();
118 for(
size_t pos = 0; pos < toSimpSize; )
120 if( !_toSimplify.begin()->empty() )
125 _toSimplify.erase( _toSimplify.begin() );
126 _toSimplify.insert( _toSimplify.end(), temp.begin(), temp.end() );
137 std::vector<DisjunctionOfConstraintConjunctions> toCombine;
138 for(
auto constraint = _toSimplify.begin(); constraint != _toSimplify.end(); ++constraint )
140 auto& factorization = (*constraint).lhs_factorization();
141 if( !carl::is_trivial(factorization) )
143 switch( constraint->relation() )
149 toCombine.emplace_back();
150 for(
auto factor = factorization.begin(); factor != factorization.end(); ++factor )
152 toCombine.back().emplace_back();
159 toCombine.emplace_back();
160 toCombine.back().emplace_back();
161 toCombine.back().back().push_back( *constraint );
167 toCombine.emplace_back();
168 toCombine.back().emplace_back();
169 for(
auto factor = factorization.begin(); factor != factorization.end(); ++factor )
183 toCombine.emplace_back();
184 toCombine.back().emplace_back();
185 toCombine.back().back().push_back( *constraint );
192 toCombine.emplace_back();
193 toCombine.back().emplace_back();
194 toCombine.back().back().push_back( *constraint );
198 if( !
combine( toCombine, _result ) )
207 auto& factorization = _constraint.lhs_factorization();
208 if( !carl::is_trivial(factorization) )
210 switch( _constraint.relation() )
216 for(
auto factor = factorization.begin(); factor != factorization.end(); ++factor )
225 result.back().push_back( _constraint );
233 for(
auto factor = factorization.begin(); factor != factorization.end(); ++factor )
248 result.back().push_back( _constraint );
257 result.back().push_back( _constraint );
275 for(
size_t i = 0; i < _toSimplify.size(); )
277 auto& cc = _toSimplify[i];
278 bool foundNoInvalidConstraint =
true;
280 while( foundNoInvalidConstraint && pos < cc.size() )
283 std::vector<std::pair<smtrat::Rational,smtrat::Poly>> sosDec;
284 bool lcoeffNeg = carl::is_negative(constraint.lhs().lcoeff());
286 sosDec = carl::sos_decomposition(-constraint.lhs());
288 sosDec = carl::sos_decomposition(constraint.lhs());
289 if( sosDec.size() > 1 )
292 bool addSquares =
true;
293 bool constraintValid =
false;
294 switch( constraint.relation() )
298 if( constraint.lhs().has_constant_term() )
300 foundNoInvalidConstraint =
false;
305 case carl::Relation::NEQ:
308 if( constraint.lhs().has_constant_term() )
310 constraintValid =
true;
314 case carl::Relation::LEQ:
319 constraintValid =
true;
321 else if( constraint.lhs().has_constant_term() )
324 foundNoInvalidConstraint =
false;
328 case carl::Relation::LESS:
333 if( constraint.lhs().has_constant_term() )
334 constraintValid =
true;
337 foundNoInvalidConstraint =
false;
340 case carl::Relation::GEQ:
345 constraintValid =
true;
347 else if( constraint.lhs().has_constant_term() )
350 foundNoInvalidConstraint =
false;
356 assert( constraint.relation() == carl::Relation::GREATER );
359 foundNoInvalidConstraint =
false;
362 if( constraint.lhs().has_constant_term() )
363 constraintValid =
true;
367 assert( !(!foundNoInvalidConstraint && constraintValid) );
368 assert( !(!foundNoInvalidConstraint && addSquares) );
369 if( constraintValid || addSquares )
378 for(
auto it = sosDec.begin(); it != sosDec.end(); ++it )
387 if( foundNoInvalidConstraint )
391 cc = _toSimplify.back();
392 _toSimplify.pop_back();
400 auto& factorization = _constraint.lhs_factorization();
403 assert( _constraint.relation() == Relation::GREATER || _constraint.relation() == Relation::LESS
404 || _constraint.relation() == Relation::GEQ || _constraint.relation() == Relation::LEQ );
405 Relation relPos = Relation::GREATER;
406 Relation relNeg = Relation::LESS;
407 if( _constraint.relation() == Relation::GEQ || _constraint.relation() == Relation::LEQ )
409 relPos = Relation::GEQ;
410 relNeg = Relation::LEQ;
412 bool positive = (_constraint.relation() == Relation::GEQ || _constraint.relation() == Relation::GREATER);
417 unsigned numOfAlwaysNegatives = 0;
418 for(
auto factor = factorization.begin(); factor != factorization.end(); ++factor )
421 unsigned posConsistent = consPos.is_consistent();
422 if( posConsistent != 0 )
423 positives.push_back( consPos );
425 unsigned negConsistent = consNeg.is_consistent();
426 if( negConsistent == 0 )
428 if( posConsistent == 0 )
430 combinations.emplace_back();
431 combinations.back().push_back( consNeg );
434 if( posConsistent != 1 )
435 alwayspositives.push_back( positives.back() );
436 positives.pop_back();
440 if( posConsistent == 0 )
442 ++numOfAlwaysNegatives;
443 if( negConsistent != 1 )
444 alwaysnegatives.push_back( consNeg );
446 else negatives.push_back( consNeg );
449 assert( positives.size() == negatives.size() );
450 if( positives.size() > 0 )
452 std::vector< std::bitset<MAX_PRODUCT_SPLIT_NUMBER> > combSelector = std::vector< std::bitset<MAX_PRODUCT_SPLIT_NUMBER> >();
453 if( fmod( numOfAlwaysNegatives, 2.0 ) != 0.0 )
467 for(
auto comb = combSelector.begin(); comb != combSelector.end(); ++comb )
469 combinations.emplace_back( alwaysnegatives );
470 combinations.back().insert( combinations.back().end(), alwayspositives.begin(), alwayspositives.end() );
471 for(
unsigned pos = 0; pos < positives.size(); ++pos )
474 combinations.back().push_back( negatives[pos] );
476 combinations.back().push_back( positives[pos] );
482 combinations.emplace_back( alwaysnegatives );
483 combinations.back().insert( combinations.back().end(), alwayspositives.begin(), alwayspositives.end() );
488 combinations.emplace_back();
489 combinations.back().push_back( _constraint );
494 void getOddBitStrings( std::size_t _length, std::vector< std::bitset<MAX_PRODUCT_SPLIT_NUMBER> >& _strings )
496 assert( _length > 0 );
497 if( _length == 1 ) _strings.push_back( std::bitset<MAX_PRODUCT_SPLIT_NUMBER>( 1 ) );
500 std::size_t pos = _strings.size();
502 for( ; pos < _strings.size(); ++pos )
505 _strings[pos].flip(0);
508 for( ; pos < _strings.size(); ++pos ) _strings[pos] <<= 1;
512 void getEvenBitStrings( std::size_t _length, std::vector< std::bitset<MAX_PRODUCT_SPLIT_NUMBER> >& _strings )
514 assert( _length > 0 );
515 if( _length == 1 ) _strings.push_back( std::bitset<MAX_PRODUCT_SPLIT_NUMBER>( 0 ) );
518 std::size_t pos = _strings.size();
520 for( ; pos < _strings.size(); ++pos ) _strings[pos] <<= 1;
522 for( ; pos < _strings.size(); ++pos )
525 _strings[pos].flip(0);
532 auto conj = _substitutionResults.begin();
533 while( conj != _substitutionResults.end() )
535 if( conj != _substitutionResults.begin() )
536 std::cout <<
" or (";
539 auto cons = (*conj).begin();
540 while( cons != (*conj).end() )
542 if( cons != (*conj).begin() )
543 std::cout <<
" and ";
547 std::cout <<
")" << std::endl;
550 std::cout << std::endl;
556 bool _accordingPaper,
557 Variables& _conflictingVariables,
560 #ifdef VS_DEBUG_SUBSTITUTION
561 std::cout <<
"substitute: ( " << _cons <<
" )" << _subs << std::endl;
565 switch( _subs.
type() )
569 result =
substituteNormal( _cons, _subs, _result, _accordingPaper, _conflictingVariables, _solutionSpace );
572 case Substitution::PLUS_EPSILON:
577 case Substitution::MINUS_INFINITY:
579 substituteInf( _cons, _subs, _result, _conflictingVariables, _solutionSpace );
582 case Substitution::PLUS_INFINITY:
584 substituteInf( _cons, _subs, _result, _conflictingVariables, _solutionSpace );
589 std::cout <<
"Error in substitute: unexpected type of substitution." << std::endl;
592 #ifdef VS_DEBUG_SUBSTITUTION
595 bool factorization =
true;
602 #ifdef VS_DEBUG_SUBSTITUTION
611 bool _accordingPaper,
612 Variables& _conflictingVariables,
617 if( _cons.variables().has( _subs.
variable() ) )
625 #ifdef VS_DEBUG_SUBSTITUTION
626 std::cout <<
"Result of common substitution:" << sub << std::endl;
629 if( !sub.has_sqrt() )
632 if( _cons.relation() ==
Relation::EQ || _cons.relation() == Relation::NEQ )
635 _result.emplace_back();
640 if( !_subs.
term().denominator().is_constant() )
643 _result.emplace_back();
647 Relation inverseRelation;
648 switch( _cons.relation() )
651 inverseRelation = Relation::GREATER;
653 case Relation::GREATER:
654 inverseRelation = Relation::LESS;
657 inverseRelation = Relation::GEQ;
660 inverseRelation = Relation::LEQ;
666 _result.emplace_back();
673 _result.emplace_back();
682 if( !_subs.
term().denominator().is_constant() )
683 s = sub.denominator();
684 switch( _cons.relation() )
701 case Relation::GREATER:
717 std::cout <<
"Error in substituteNormal: Unexpected relation symbol" << std::endl;
724 _result.emplace_back();
725 _result.back().push_back( _cons );
727 simplify( _result, _conflictingVariables, _solutionSpace );
735 bool _accordingPaper )
739 smtrat::Poly lhs = carl::pow(_q, 2) - carl::pow(_r, 2) * _radicand;
740 if( _accordingPaper )
744 _result.emplace_back();
751 _result.emplace_back();
755 _result.emplace_back();
759 _result.emplace_back();
764 _result.emplace_back();
776 bool _accordingPaper )
780 smtrat::Poly lhs = carl::pow(_q, 2) - carl::pow(_r, 2) * _radicand;
781 if( _accordingPaper )
785 _result.emplace_back();
792 _result.emplace_back();
796 _result.emplace_back();
800 _result.emplace_back();
811 bool _accordingPaper )
815 smtrat::Poly lhs = carl::pow(_q, 2) - carl::pow(_r, 2) * _radicand;
816 if( _accordingPaper )
821 _result.emplace_back();
825 _result.emplace_back();
829 _result.emplace_back();
836 _result.emplace_back();
841 _result.emplace_back();
846 _result.emplace_back();
851 _result.emplace_back();
856 _result.emplace_back();
861 _result.emplace_back();
874 bool _accordingPaper )
878 smtrat::Poly lhs = carl::pow(_q, 2) - carl::pow(_r, 2) * _radicand;
879 if( _accordingPaper )
884 _result.emplace_back();
888 _result.emplace_back();
895 _result.emplace_back();
900 _result.emplace_back();
905 _result.emplace_back();
910 _result.emplace_back();
915 _result.emplace_back();
919 _result.emplace_back();
929 bool _accordingPaper,
930 Variables& _conflictingVariables,
934 if( !_cons.variables().empty() )
936 if( _cons.variables().has( _subs.
variable() ) )
938 switch( _cons.relation() )
955 case Relation::GREATER:
975 simplify( _result, _conflictingVariables, _solutionSpace );
979 _result.emplace_back();
980 _result.back().push_back( _cons );
986 std::cerr <<
"Warning in substitutePlusEps: The chosen constraint has no variable" << std::endl;
993 const Relation _relation,
995 bool _accordingPaper,
996 Variables& _conflictingVariables,
999 assert( _cons.variables().has( _subs.
variable() ) );
1004 if( !
substituteNormal( firstCaseInequality, substitution, _result, _accordingPaper, _conflictingVariables, _solutionSpace ) )
1007 std::vector<DisjunctionOfConstraintConjunctions> substitutionResultsVector;
1017 while( deriv.has( _subs.
variable() ) )
1022 deriv = carl::derivative(deriv, _subs.
variable(), 1);
1026 substitutionResultsVector.emplace_back();
1027 if( !
substituteNormal( equation, substitution, substitutionResultsVector.back(), _accordingPaper, _conflictingVariables, _solutionSpace ) )
1029 substitutionResultsVector.emplace_back();
1030 if( !
substituteNormal( inequality, substitution, substitutionResultsVector.back(), _accordingPaper, _conflictingVariables, _solutionSpace ) )
1032 if( !
combine( substitutionResultsVector, _result ) )
1034 simplify( _result, _conflictingVariables, _solutionSpace );
1036 substitutionResultsVector.pop_back();
1043 if( !_cons.variables().empty() )
1045 if( _cons.variables().has( _subs.
variable() ) )
1049 else if( _cons.relation() == Relation::NEQ )
1054 simplify( _result, _conflictingVariables, _solutionSpace );
1058 _result.emplace_back();
1059 _result.back().push_back( _cons );
1063 std::cout <<
"Warning in substituteInf: The chosen constraint has no variable" << std::endl;
1069 assert( _cons.relation() != Relation::NEQ );
1071 Relation oddRelationType = Relation::GREATER;
1072 Relation evenRelationType = Relation::LESS;
1073 if( _subs.
type() == Substitution::MINUS_INFINITY )
1075 if( _cons.relation() == Relation::GREATER || _cons.relation() == Relation::GEQ )
1077 oddRelationType = Relation::LESS;
1078 evenRelationType = Relation::GREATER;
1083 assert( _subs.
type() == Substitution::PLUS_INFINITY );
1084 if( _cons.relation() == Relation::LESS || _cons.relation() == Relation::LEQ )
1086 oddRelationType = Relation::LESS;
1087 evenRelationType = Relation::GREATER;
1091 carl::uint varDegree = _cons.maxDegree( _subs.
variable() );
1092 assert( varDegree > 0 );
1093 for( carl::uint i = varDegree + 1; i > 0; --i )
1096 _result.emplace_back();
1097 for( carl::uint j = varDegree; j > i - 1; --j )
1101 if( fmod( i - 1, 2.0 ) != 0.0 )
1113 assert( _cons.relation() ==
Relation::EQ || _cons.relation() == Relation::LEQ || _cons.relation() == Relation::GEQ );
1114 carl::uint varDegree = _cons.maxDegree( _subs.
variable() );
1116 _result.emplace_back();
1117 for( carl::uint i = 0; i <= varDegree; ++i )
1123 assert( _cons.relation() == Relation::NEQ );
1124 carl::uint varDegree = _cons.maxDegree( _subs.
variable() );
1125 for( carl::uint i = 0; i <= varDegree; ++i )
1128 _result.emplace_back();
const unsigned MAX_NUM_OF_TERMS
Class containing a method applying a virtual substitution.
const unsigned MAX_PRODUCT_SPLIT_NUMBER
Class containing a method applying a virtual substitution.
const smtrat::SqrtEx & term() const
const carl::Variable & variable() const
const carl::PointerSet< Condition > & originalConditions() const
const Type & type() const
std::vector< carl::Variable > vars(const std::pair< QuantifierType, std::vector< carl::Variable >> &p)
bool substituteNormalSqrtNeq(const smtrat::Poly &_radicand, const smtrat::Poly &_q, const smtrat::Poly &_r, DisjunctionOfConstraintConjunctions &_result, bool _accordingPaper)
Sub-method of substituteNormalSqrt, where applying the substitution led to a term containing a square...
bool combine(const std::vector< std::vector< std::vector< combineType > > > &_toCombine, std::vector< std::vector< combineType > > &_combination)
Combines vectors.
void substituteInfLessGreater(const smtrat::ConstraintT &_cons, const Substitution &_subs, DisjunctionOfConstraintConjunctions &_result)
Applies the given substitution to the given constraint, where the substitution is of the form [x -> +...
bool substituteNormal(const smtrat::ConstraintT &_cons, const Substitution &_subs, DisjunctionOfConstraintConjunctions &_result, bool _accordingPaper, Variables &_conflictingVariables, const smtrat::EvalDoubleIntervalMap &_solutionSpace)
bool substituteNormalSqrtLeq(const smtrat::Poly &_radicand, const smtrat::Poly &_q, const smtrat::Poly &_r, const smtrat::Poly &_s, DisjunctionOfConstraintConjunctions &_result, bool _accordingPaper)
Sub-method of substituteNormalSqrt, where applying the substitution led to a term containing a square...
bool substituteEpsGradients(const smtrat::ConstraintT &_cons, const Substitution &_subs, const Relation _relation, DisjunctionOfConstraintConjunctions &_result, bool _accordingPaper, Variables &_conflictingVariables, const smtrat::EvalDoubleIntervalMap &_solutionSpace)
void getEvenBitStrings(std::size_t _length, std::vector< std::bitset< MAX_PRODUCT_SPLIT_NUMBER > > &_strings)
bool substituteNormalSqrtLess(const smtrat::Poly &_radicand, const smtrat::Poly &_q, const smtrat::Poly &_r, const smtrat::Poly &_s, DisjunctionOfConstraintConjunctions &_result, bool _accordingPaper)
Sub-method of substituteNormalSqrt, where applying the substitution led to a term containing a square...
DisjunctionOfConstraintConjunctions splitProducts(const smtrat::ConstraintT &_constraint, bool _onlyNeq)
Splits the given constraint into a set of constraints which compare the factors of the factorization ...
void substituteInf(const smtrat::ConstraintT &_cons, const Substitution &_subs, DisjunctionOfConstraintConjunctions &_result, Variables &_conflictingVariables, const smtrat::EvalDoubleIntervalMap &_solutionSpace)
void substituteNotTrivialCase(const smtrat::ConstraintT &_cons, const Substitution &_subs, DisjunctionOfConstraintConjunctions &_result)
Deals with the case, that the left hand side of the constraint to substitute is not a trivial polynom...
std::vector< ConstraintVector > DisjunctionOfConstraintConjunctions
a vector of vectors of constraints
void splitSosDecompositions(DisjunctionOfConstraintConjunctions &_toSimplify)
void simplify(DisjunctionOfConstraintConjunctions &_toSimplify, Variables &_conflictingVars, const smtrat::EvalDoubleIntervalMap &_solutionSpace)
std::vector< smtrat::ConstraintT > ConstraintVector
a vector of constraints
bool substitutePlusEps(const smtrat::ConstraintT &_cons, const Substitution &_subs, DisjunctionOfConstraintConjunctions &_result, bool _accordingPaper, Variables &_conflictingVariables, const smtrat::EvalDoubleIntervalMap &_solutionSpace)
bool substitute(const smtrat::ConstraintT &_cons, const Substitution &_subs, DisjunctionOfConstraintConjunctions &_result, bool _accordingPaper, Variables &_conflictingVariables, const smtrat::EvalDoubleIntervalMap &_solutionSpace)
DisjunctionOfConstraintConjunctions getSignCombinations(const smtrat::ConstraintT &_constraint)
For a given constraint f_1*...*f_n ~ 0 this method computes all combinations of constraints f_1 ~_1 0...
bool substituteNormalSqrtEq(const smtrat::Poly &_radicand, const smtrat::Poly &_q, const smtrat::Poly &_r, DisjunctionOfConstraintConjunctions &_result, bool _accordingPaper)
Sub-method of substituteNormalSqrt, where applying the substitution led to a term containing a square...
void substituteTrivialCase(const smtrat::ConstraintT &_cons, const Substitution &_subs, DisjunctionOfConstraintConjunctions &_result)
Deals with the case, that the left hand side of the constraint to substitute is a trivial polynomial ...
void print(DisjunctionOfConstraintConjunctions &_substitutionResults)
Prints the given disjunction of conjunction of constraints.
void getOddBitStrings(std::size_t _length, std::vector< std::bitset< MAX_PRODUCT_SPLIT_NUMBER > > &_strings)
Class to create the formulas for axioms.
carl::SqrtEx< Poly > SqrtEx
carl::MultivariatePolynomial< Rational > Poly
carl::Constraint< Poly > ConstraintT
std::map< carl::Variable, DoubleInterval > EvalDoubleIntervalMap