SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
Variable.tpp
Go to the documentation of this file.
1 /**
2  * @file Variable.tpp
3  * @author Florian Corzilius <corzilius@cs.rwth-aachen.de>
4  * @since 2012-04-05
5  * @version 2014-10-01
6  */
7 
8 #pragma once
9 
10 #include "Variable.h"
11 
12 namespace smtrat
13 {
14  namespace lra
15  {
16  template<typename T1, typename T2>
17  Variable<T1, T2>::Variable( size_t _position, const typename Poly::PolyType* _expression, ModuleInput::iterator _defaultBoundPosition, bool _isInteger, size_t _id ):
18  mBasic( false ),
19  mOriginal( true ),
20  mInteger( _isInteger ),
21  mStartEntry( LAST_ENTRY_ID ),
22  mSize( 0 ),
23  mConflictActivity( 0 ),
24  mPosition( _position ),
25  mId( _id ),
26  mUpperbounds(),
27  mLowerbounds(),
28  mExpression( _expression),
29  mAssignment( T1( 0 ) ),
30  mLastConsistentAssignment( mAssignment )
31  #ifdef LRA_NO_DIVISION
32  ,
33  mFactor( 1 )
34  #endif
35  {
36  mpSupremum = addUpperBound( NULL, _defaultBoundPosition, FormulaT( carl::FormulaType::TRUE ) ).first;
37  mpInfimum = addLowerBound( NULL, _defaultBoundPosition, FormulaT( carl::FormulaType::TRUE ) ).first;
38  }
39 
40  template<typename T1, typename T2>
41  Variable<T1, T2>::Variable( typename std::list<std::list<std::pair<Variable<T1,T2>*,T2>>>::iterator _positionInNonActives, const typename Poly::PolyType* _expression, ModuleInput::iterator _defaultBoundPosition, bool _isInteger, size_t _id ):
42  mBasic( true ),
43  mOriginal( false ),
44  mInteger( _isInteger ),
45  mStartEntry( LAST_ENTRY_ID ),
46  mSize( 0 ),
47  mConflictActivity( 0 ),
48  mPositionInNonActives( _positionInNonActives ),
49  mId( _id ),
50  mUpperbounds(),
51  mLowerbounds(),
52  mExpression( _expression),
53  mAssignment( T1( 0 ) ),
54  mLastConsistentAssignment( mAssignment )
55  #ifdef LRA_NO_DIVISION
56  ,
57  mFactor( 1 )
58  #endif
59  {
60  mpSupremum = addUpperBound( NULL, _defaultBoundPosition, FormulaT( carl::FormulaType::TRUE ) ).first;
61  mpInfimum = addLowerBound( NULL, _defaultBoundPosition, FormulaT( carl::FormulaType::TRUE ) ).first;
62  }
63 
64  template<typename T1, typename T2>
65  Variable<T1, T2>::~Variable()
66  {
67  while( !mLowerbounds.empty() )
68  {
69  const Bound<T1, T2>* b = *mLowerbounds.begin();
70  mLowerbounds.erase( mLowerbounds.begin() );
71  if( b->type() != Bound<T1, T2>::EQUAL ) delete b;
72  }
73  while( !mUpperbounds.empty() )
74  {
75  const Bound<T1, T2>* b = *mUpperbounds.begin();
76  mUpperbounds.erase( mUpperbounds.begin() );
77  delete b;
78  }
79  delete mExpression;
80  }
81 
82  template<typename T1, typename T2>
83  std::pair<const Bound<T1, T2>*, bool> Variable<T1, T2>::addUpperBound( Value<T1>* const _val, ModuleInput::iterator _position, const FormulaT& _constraint, bool _deduced )
84  {
85  struct Bound<T1, T2>::Info* boundInfo = new struct Bound<T1, T2>::Info( _position );
86  Bound<T1, T2>* newBound = new Bound<T1, T2>( _val, this, Bound<T1, T2>::UPPER, _constraint, boundInfo, _deduced );
87  std::pair<typename Bound<T1, T2>::BoundSet::iterator, bool> result = mUpperbounds.insert( newBound );
88  if( !result.second )
89  {
90  delete newBound;
91  }
92  return std::pair<const Bound<T1, T2>*, bool>( *result.first, result.second );
93  }
94 
95  template<typename T1, typename T2>
96  std::pair<const Bound<T1, T2>*, bool> Variable<T1, T2>::addLowerBound( Value<T1>* const _val, ModuleInput::iterator _position, const FormulaT& _constraint, bool _deduced )
97  {
98  struct Bound<T1, T2>::Info* boundInfo = new struct Bound<T1, T2>::Info( _position );
99  Bound<T1, T2>* newBound = new Bound<T1, T2>( _val, this, Bound<T1, T2>::LOWER, _constraint, boundInfo, _deduced );
100  std::pair<typename Bound<T1, T2>::BoundSet::iterator, bool> result = mLowerbounds.insert( newBound );
101  if( !result.second )
102  {
103  delete newBound;
104  }
105  return std::pair<const Bound<T1, T2>*, bool>( *result.first, result.second );
106  }
107 
108  template<typename T1, typename T2>
109  std::pair<const Bound<T1, T2>*, bool> Variable<T1, T2>::addEqualBound( Value<T1>* const _val, ModuleInput::iterator _position, const FormulaT& _constraint )
110  {
111  struct Bound<T1, T2>::Info* boundInfo = new struct Bound<T1, T2>::Info( _position );
112  Bound<T1, T2>* newBound = new Bound<T1, T2>( _val, this, Bound<T1, T2>::EQUAL, _constraint, boundInfo );
113  std::pair<typename Bound<T1, T2>::BoundSet::iterator, bool> result = mLowerbounds.insert( newBound );
114  if( !result.second )
115  {
116  delete newBound;
117  return std::pair<const Bound<T1, T2>*, bool>( *result.first, false );
118  }
119  else
120  {
121  std::pair<typename Bound<T1, T2>::BoundSet::iterator, bool> resultB = mUpperbounds.insert( newBound );
122  assert( resultB.second );
123  return std::pair<const Bound<T1, T2>*, bool>( *result.first, true );
124  }
125  }
126 
127  template<typename T1, typename T2>
128  void Variable<T1, T2>::removeBound( const Bound<T1, T2>* _bound )
129  {
130  assert( _bound != mpInfimum );
131  assert( _bound != mpSupremum );
132  switch( _bound->type() )
133  {
134  case Bound<T1, T2>::LOWER:
135  mLowerbounds.erase( _bound );
136  break;
137  case Bound<T1, T2>::UPPER:
138  mUpperbounds.erase( _bound );
139  break;
140  default:
141  mLowerbounds.erase( _bound );
142  mUpperbounds.erase( _bound );
143  break;
144  }
145  }
146 
147  template<typename T1, typename T2>
148  bool Variable<T1, T2>::deactivateBound( const Bound<T1, T2>* bound, ModuleInput::iterator _position )
149  {
150  assert( !bound->isInfinite() );
151  assert( !bound->isActive() );
152  bound->pInfo()->updated = 0;
153  bound->pInfo()->position = _position;
154  bool variableBoundsChanged = false;
155  if( bound->isUpperBound() )
156  {
157  //check if it is the supremum
158  if( mpSupremum == bound )
159  {
160  //find the supremum
161  typename Bound<T1, T2>::BoundSet::iterator newBound = mUpperbounds.begin();
162  while( newBound != --mUpperbounds.end() )
163  {
164  if( (*newBound)->isActive() )
165  {
166  ++(*newBound)->pInfo()->updated;
167  break;
168  }
169  ++newBound;
170  }
171  mpSupremum = *newBound;
172  variableBoundsChanged = true;
173  }
174  }
175  if( bound->isLowerBound() )
176  {
177  //check if it is the infimum
178  if( mpInfimum == bound )
179  {
180  //find the infimum
181  typename Bound<T1, T2>::BoundSet::reverse_iterator newBound = mLowerbounds.rbegin();
182  while( newBound != --mLowerbounds.rend() )
183  {
184  if( (*newBound)->isActive() )
185  {
186  ++(*newBound)->pInfo()->updated;
187  break;
188  }
189  ++newBound;
190  }
191  mpInfimum = *newBound;
192  variableBoundsChanged = true;
193  }
194  }
195  return variableBoundsChanged;
196  }
197 
198  template<typename T1, typename T2>
199  RationalInterval Variable<T1, T2>::getVariableBounds() const
200  {
201  carl::BoundType lowerBoundType;
202  Rational lowerBoundValue;
203  carl::BoundType upperBoundType;
204  Rational upperBoundValue;
205  if( infimum().isInfinite() )
206  {
207  lowerBoundType = carl::BoundType::INFTY;
208  lowerBoundValue = Rational(0);
209  }
210  else
211  {
212  lowerBoundType = infimum().isWeak() ? carl::BoundType::WEAK : carl::BoundType::STRICT;
213  lowerBoundValue = Rational(infimum().limit().mainPart());
214  }
215  if( supremum().isInfinite() )
216  {
217  upperBoundType = carl::BoundType::INFTY;
218  upperBoundValue = Rational(0);
219  }
220  else
221  {
222  upperBoundType = supremum().isWeak() ? carl::BoundType::WEAK : carl::BoundType::STRICT;
223  upperBoundValue = Rational(supremum().limit().mainPart());
224  }
225  RationalInterval result = RationalInterval( lowerBoundValue, lowerBoundType, upperBoundValue, upperBoundType );
226  return result;
227  }
228 
229  template<typename T1, typename T2>
230  FormulasT Variable<T1, T2>::getDefiningOrigins() const
231  {
232  FormulasT result;
233  if( !infimum().isInfinite() )
234  {
235  result.push_back( infimum().origins().front() );
236  }
237  if( !supremum().isInfinite() )
238  {
239  result.push_back( supremum().origins().front() );
240  }
241  return result;
242  }
243 
244  template<typename T1, typename T2>
245  void Variable<T1, T2>::print( std::ostream& _out ) const
246  {
247  std::stringstream out;
248  out << *mExpression;
249  _out << std::setw( 15 ) << out.str();
250  _out << std::setw( 6 ) << " -> ";
251  _out << std::setw( 35 ) << mAssignment;
252  _out << std::setw( 6 ) << " in [";
253  _out << std::setw( 12 ) << mpInfimum;
254  _out << std::setw( 2 ) << ", ";
255  _out << std::setw( 12 ) << mpSupremum;
256  _out << std::setw( 1 ) << "]";
257  }
258 
259  template<typename T1, typename T2>
260  void Variable<T1, T2>::printAllBounds( std::ostream& _out, const std::string _init ) const
261  {
262  _out << _init << " Upper bounds: " << std::endl;
263  for( typename Bound<T1, T2>::BoundSet::const_iterator bIter = mUpperbounds.begin(); bIter != mUpperbounds.end(); ++bIter )
264  {
265  _out << _init << " ";
266  (*bIter)->print( true, _out, true );
267  _out << " [" << (*bIter)->pInfo()->updated << "]" << std::endl;
268  }
269  _out << _init << " Lower bounds: " << std::endl;
270  for( typename Bound<T1, T2>::BoundSet::const_reverse_iterator bIter = mLowerbounds.rbegin(); bIter != mLowerbounds.rend(); ++bIter )
271  {
272  _out << _init << " ";
273  (*bIter)->print( true, _out, true );
274  _out << " [" << (*bIter)->pInfo()->updated << "]" << std::endl;
275  }
276  }
277  } // end namspace lra
278 } // end namespace smtrat