24 template<
typename Pol>
27 #ifdef CONSTRAINT_BOUND_DEBUG
28 std::cout <<
"add from a " << (_inConjunction ?
"conjunction" :
"disjunction") <<
" to " << &_constraintBounds <<
": " << _constraint << std::endl;
34 typename Pol::NumberType boundValue;
36 const Pol& lhs = constraint.
lhs();
38 bool multipliedByMinusOne = lhs.lterm().coeff() <
typename Pol::NumberType( 0 );
39 if( multipliedByMinusOne )
41 boundValue = constraint.
lhs().constant_part();
43 poly =
Pol( -lhs + boundValue );
47 boundValue = -constraint.
lhs().constant_part();
48 poly =
Pol( lhs + boundValue );
50 typename Pol::NumberType cf( poly.coprime_factor() );
54 #ifdef CONSTRAINT_BOUND_DEBUG
55 std::cout <<
"try to add the bound " << relation << boundValue <<
" for the polynomial " << poly << std::endl;
57 auto resA = _constraintBounds.insert( std::make_pair( std::move(poly), std::move( std::map<
typename Pol::NumberType, std::pair<
Relation,
Formula<Pol>>>() ) ) );
58 auto resB = resA.first->second.insert( std::make_pair( boundValue, std::make_pair( relation, _constraint ) ) );
59 if( resB.second || resB.first->second.first == relation )
60 return resB.first->second.second;
69 resB.first->second.second = _constraint;
70 return resB.first->second.second;
77 switch( resB.first->second.first )
80 return resB.first->second.second;
82 return resB.first->second.second;
86 return resB.first->second.second;
90 return resB.first->second.second;
99 switch( resB.first->second.first )
102 return resB.first->second.second;
106 return resB.first->second.second;
108 return resB.first->second.second;
115 return resB.first->second.second;
120 switch( resB.first->second.first )
124 resB.first->second.second = _constraint;
125 return resB.first->second.second;
130 resB.first->second.second = _constraint;
131 return resB.first->second.second;
142 switch( resB.first->second.first )
145 return resB.first->second.second;
149 return resB.first->second.second;
153 return resB.first->second.second;
158 return resB.first->second.second;
163 switch( resB.first->second.first )
167 resB.first->second.second = _constraint;
168 return resB.first->second.second;
175 resB.first->second.second = _constraint;
185 switch( resB.first->second.first )
191 resB.first->second.second = _constraint;
192 return resB.first->second.second;
200 resB.first->second.second = _constraint;
201 return resB.first->second.second;
206 switch( resB.first->second.first )
211 return resB.first->second.second;
213 return resB.first->second.second;
219 return resB.first->second.second;
222 return resB.first->second.second;
228 switch( resB.first->second.first )
236 resB.first->second.second = _constraint;
237 return resB.first->second.second;
243 resB.first->second.second = _constraint;
244 return resB.first->second.second;
249 switch( resB.first->second.first )
254 return resB.first->second.second;
258 return resB.first->second.second;
262 return resB.first->second.second;
265 return resB.first->second.second;
272 switch( resB.first->second.first )
279 return resB.first->second.second;
283 return resB.first->second.second;
287 return resB.first->second.second;
292 return resB.first->second.second;
297 switch( resB.first->second.first )
306 return resB.first->second.second;
309 return resB.first->second.second;
327 template<
typename Pol>
330 #ifdef CONSTRAINT_BOUND_DEBUG
331 std::cout <<
"swap from " << &_constraintBounds <<
" to a " << (_inConjunction ?
"conjunction" :
"disjunction") << std::endl;
333 while( !_constraintBounds.empty() )
335 #ifdef CONSTRAINT_BOUND_DEBUG
336 std::cout <<
"for the bounds of " << _constraintBounds.begin()->first << std::endl;
338 const std::map<typename Pol::NumberType, std::pair<Relation, Formula<Pol>>>& bounds = _constraintBounds.begin()->second;
339 assert( !bounds.empty() );
340 if( bounds.size() == 1 )
342 _intoFormulas.push_back( bounds.begin()->second.second );
343 #ifdef CONSTRAINT_BOUND_DEBUG
344 std::cout <<
" just add the only bound" << std::endl;
349 auto mostSignificantLowerBound = bounds.end();
350 auto mostSignificantUpperBound = bounds.end();
351 auto moreSignificantCase = bounds.end();
353 auto iter = bounds.begin();
354 for( ; iter != bounds.end(); ++iter )
356 #ifdef CONSTRAINT_BOUND_DEBUG
357 std::cout <<
" bound is " << iter->second.first << iter->first << std::endl;
360 || (!_inConjunction && iter->second.first ==
Relation::EQ) )
362 if( moreSignificantCase == bounds.end() )
364 if( (_inConjunction && mostSignificantUpperBound == bounds.end())
365 || (!_inConjunction && mostSignificantLowerBound == bounds.end()) )
367 if( (_inConjunction && mostSignificantLowerBound != bounds.end())
368 || (!_inConjunction && mostSignificantUpperBound != bounds.end()) )
370 #ifdef CONSTRAINT_BOUND_DEBUG
371 std::cout <<
" case: " << __LINE__ << std::endl;
373 _intoFormulas.push_back( iter->second.second );
377 #ifdef CONSTRAINT_BOUND_DEBUG
378 std::cout <<
" case: " << __LINE__ << std::endl;
380 lessSignificantCases.push_back( iter->second.second );
388 if( (_inConjunction && mostSignificantUpperBound != bounds.end())
389 || (!_inConjunction && mostSignificantLowerBound != bounds.end())
390 || moreSignificantCase != bounds.end() )
392 #ifdef CONSTRAINT_BOUND_DEBUG
393 std::cout <<
" case: " << __LINE__ << std::endl;
399 #ifdef CONSTRAINT_BOUND_DEBUG
400 std::cout <<
" case: " << __LINE__ << std::endl;
403 mostSignificantLowerBound = iter;
405 mostSignificantUpperBound = iter;
406 lessSignificantCases.clear();
409 else if( (_inConjunction && iter->second.first ==
Relation::EQ)
410 || (!_inConjunction && iter->second.first ==
Relation::NEQ) )
414 if( moreSignificantCase != bounds.end() || (_inConjunction ? mostSignificantUpperBound : mostSignificantLowerBound) != bounds.end() )
416 #ifdef CONSTRAINT_BOUND_DEBUG
417 std::cout <<
" case: " << __LINE__ << std::endl;
425 #ifdef CONSTRAINT_BOUND_DEBUG
426 std::cout <<
" case: " << __LINE__ << std::endl;
428 moreSignificantCase = iter;
435 #ifdef CONSTRAINT_BOUND_DEBUG
436 std::cout <<
" case: " << __LINE__ << std::endl;
440 if( _inConjunction && mostSignificantUpperBound == bounds.end() )
442 #ifdef CONSTRAINT_BOUND_DEBUG
443 std::cout <<
" case: " << __LINE__ << std::endl;
445 mostSignificantUpperBound = iter;
447 else if( !_inConjunction && mostSignificantLowerBound == bounds.end() )
449 #ifdef CONSTRAINT_BOUND_DEBUG
450 std::cout <<
" case: " << __LINE__ << std::endl;
452 mostSignificantLowerBound = iter;
456 if( iter != bounds.end() )
458 if( moreSignificantCase != bounds.end() )
460 _intoFormulas.push_back( moreSignificantCase->second.second );
464 #ifdef CONSTRAINT_BOUND_DEBUG
465 if( !(_inConjunction || mostSignificantUpperBound == bounds.end() || mostSignificantLowerBound == bounds.end()
466 || mostSignificantUpperBound->first > mostSignificantLowerBound->first)
467 || !( !_inConjunction || mostSignificantUpperBound == bounds.end() || mostSignificantLowerBound == bounds.end()
468 || mostSignificantLowerBound->first > mostSignificantUpperBound->first ) )
470 std::cout <<
"mostSignificantUpperBound: " << mostSignificantUpperBound->first <<
" [" << mostSignificantUpperBound->second.second <<
"]" << std::endl;
471 std::cout <<
"mostSignificantLowerBound: " << mostSignificantLowerBound->first <<
" [" << mostSignificantLowerBound->second.second <<
"]" << std::endl;
474 assert( !_inConjunction || mostSignificantUpperBound == bounds.end() || mostSignificantLowerBound == bounds.end()
475 || mostSignificantUpperBound->first > mostSignificantLowerBound->first );
476 assert( _inConjunction || mostSignificantUpperBound == bounds.end() || mostSignificantLowerBound == bounds.end()
477 || mostSignificantLowerBound->first > mostSignificantUpperBound->first );
478 if( mostSignificantUpperBound != bounds.end() )
479 _intoFormulas.push_back( mostSignificantUpperBound->second.second );
480 if( mostSignificantLowerBound != bounds.end() )
481 _intoFormulas.push_back( mostSignificantLowerBound->second.second );
482 _intoFormulas.insert(_intoFormulas.end(), lessSignificantCases.begin(), lessSignificantCases.end() );
485 _constraintBounds.erase( _constraintBounds.begin() );
487 if( _constraintBounds.empty() )
489 #ifdef CONSTRAINT_BOUND_DEBUG
490 std::cout << std::endl;
496 _constraintBounds.clear();
497 #ifdef CONSTRAINT_BOUND_DEBUG
498 std::cout <<
"is " << (_inConjunction ?
"invalid" :
"valid") << std::endl << std::endl;
MultivariatePolynomial< Rational > Pol
carl is the main namespace for the library.
bool swapConstraintBounds(ConstraintBounds< Pol > &_constraintBounds, Formulas< Pol > &_intoFormulas, bool _inConjunction)
Stores for every polynomial for which we determined bounds for given constraints a minimal set of con...
Formula< Pol > addConstraintBound(ConstraintBounds< Pol > &_constraintBounds, const Formula< Pol > &_constraint, bool _inConjunction)
Adds the bound to the bounds of the polynomial specified by this constraint.
std::vector< Formula< Poly > > Formulas
Relation inverse(Relation r)
Inverts the given relation symbol.
FastMap< Pol, std::map< typename Pol::NumberType, std::pair< Relation, Formula< Pol > >> > ConstraintBounds
A map from formula pointers to a map of rationals to a pair of a constraint relation and a formula po...
Relation turn_around(Relation r)
Turns around the given relation symbol, in the sense that LESS (LEQ) and GREATER (GEQ) are swapped.
std::unordered_map< T1, T2, std::hash< T1 > > FastMap
Represent a polynomial (in)equality against zero.
unsigned is_consistent() const
Checks, whether the constraint is consistent.
Relation relation() const
Represent an SMT formula, which can be an atom for some background theory or a boolean combination of...
const Formula & subformula() const
const Constraint< Pol > & constraint() const