SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
Condition.cpp
Go to the documentation of this file.
1 /**
2  * Class to create a condition object.
3  * @author Florian Corzilius
4  * @since 2010-07-26
5  * @version 2011-06-20
6  */
7 
8 #include "Condition.h"
9 
11 
12 namespace smtrat {
13 namespace vs
14 {
15  Condition::Condition( const smtrat::ConstraintT& _cons, size_t _id, size_t _val, bool _flag, const carl::PointerSet<Condition>& _oConds, bool _rAdded ):
16  mFlag( _flag ),
17  mRecentlyAdded( _rAdded ),
18  mValuation( _val ),
19  mId( _id ),
20  mConstraint( _cons ),
21  mpOriginalConditions( new carl::PointerSet<Condition>( _oConds ) )
22  {}
23 
24  Condition::Condition( const Condition& _cond, size_t _id ):
25  mFlag( _cond.flag() ),
26  mRecentlyAdded( false ),
27  mValuation( _cond.valuation() ),
28  mId( _id ),
29  mConstraint( _cond.constraint() ),
30  mpOriginalConditions( new carl::PointerSet<Condition>( _cond.originalConditions() ) )
31  {}
32 
34  {
35  (*mpOriginalConditions).clear();
36  delete mpOriginalConditions;
37  }
38 
40 
41  /**
42  * Valuates the constraint according to a variable (it possibly not contains).
43  *
44  * @param _consideredVariable The variable which is considered in this valuation.
45  * @param _maxNumberOfVars
46  *
47  * @return A valuation of the constraint according to an heuristic.
48  */
49  double Condition::valuate( const carl::Variable& _consideredVariable, size_t _maxNumberOfVars, bool _preferEquation ) const
50  {
51  if( !constraint().variables().has( _consideredVariable ) )
52  return 0;
53  const auto& varInfo = constraint().var_info( _consideredVariable );
54  double maximum = 0;
55  if( _maxNumberOfVars < 4 )
56  maximum = 16;
57  else
58  maximum = (double)_maxNumberOfVars * (double)_maxNumberOfVars;
59  // Check the relation symbol.
60  double relationSymbolWeight = 0;
61  switch( constraint().relation() )
62  {
63  case carl::Relation::EQ:
64  relationSymbolWeight += 1;
65  break;
66  case carl::Relation::GEQ:
67  relationSymbolWeight += 2;
68  break;
69  case carl::Relation::LEQ:
70  relationSymbolWeight += 2;
71  break;
72  case carl::Relation::LESS:
73  relationSymbolWeight += 4;
74  break;
75  case carl::Relation::GREATER:
76  relationSymbolWeight += 4;
77  break;
78  case carl::Relation::NEQ:
79  relationSymbolWeight += 3;
80  break;
81  default:
82  return 0;
83  }
84  //Check the degree of the variable.
85  double degreeWeight = (double)varInfo.max_degree();
86  if( maximum <= degreeWeight )
87  degreeWeight = maximum - 1;
88  //Check the leading coefficient of the given variable.
89  unsigned lCoeffWeight = 0;
90  unsigned lCoeffWeightB = 2;
91  if( degreeWeight <= 1 )
92  {
93  smtrat::Poly coeff = constraint().coefficient( _consideredVariable, varInfo.max_degree() );
94  if( coeff.is_constant() )
95  {
96  if( _consideredVariable.type() == carl::VariableType::VT_INT && (coeff == Poly(1) || coeff == Poly(-1)) )
97  {
98  lCoeffWeightB = 1;
99  }
100  lCoeffWeight = 1;
101  }
102  else
103  lCoeffWeight = 3;
104  }
105  else if( degreeWeight == 2 )
106  {
107  bool hasRationalLeadingCoefficient = constraint().coefficient( _consideredVariable, varInfo.max_degree() ).is_constant();
108  if( hasRationalLeadingCoefficient && constraint().coefficient( _consideredVariable, varInfo.max_degree() - 1 ).is_constant() )
109  lCoeffWeight = 1;
110  else if( hasRationalLeadingCoefficient )
111  lCoeffWeight = 2;
112  else
113  lCoeffWeight = 3;
114  }
115  // Check the number of variables.
116  //double numberOfVariableWeight = (double) constraint().variables().size();
117  // Check how in how many monomials the variable occurs.
118  double numberOfVariableOccurencesWeight = (double)varInfo.num_occurences();
119  if( maximum <= numberOfVariableOccurencesWeight )
120  numberOfVariableOccurencesWeight = maximum - 1;
121  // If variable occurs only in one monomial, give a bonus if all other monomials are either positive or negative.
122  double otherMonomialsPositiveWeight = 2;
123  double finitlyManySolutionsWeight = INFINITLY_MANY_SOLUTIONS_WEIGHT;
124  // TODO: avoid expanding the polynomial somehow
125 #ifdef __VS
126  smtrat::Poly::PolyType polyExpanded = (smtrat::Poly::PolyType)constraint().lhs();
127 #else
128  typename smtrat::Poly::PolyType polyExpanded = (typename smtrat::Poly::PolyType)constraint().lhs();
129 #endif
130  if( numberOfVariableOccurencesWeight == 1 && ( polyExpanded.nr_terms() == 1 || (!carl::is_zero(constraint().lhs().constant_part()) && polyExpanded.nr_terms() > 1) ) )
131  {
132  bool allOtherMonomialsPos = true;
133  bool allOtherMonomialsNeg = true;
134  for( auto term = polyExpanded.begin(); term != polyExpanded.end(); ++term )
135  {
136  if( term->has( _consideredVariable ) )
137  {
138  if( term->num_variables() > 1 )
139  {
140  allOtherMonomialsPos = false;
141  allOtherMonomialsNeg = false;
142  break;
143  }
144  }
145  else
146  {
147  carl::Definiteness defin = carl::definiteness(*term);
148  if( defin == carl::Definiteness::NON )
149  {
150  allOtherMonomialsPos = false;
151  allOtherMonomialsNeg = false;
152  break;
153  }
154  else if( defin > carl::Definiteness::NON )
155  {
156  if( !allOtherMonomialsNeg )
157  allOtherMonomialsNeg = false;
158  if( !allOtherMonomialsPos )
159  break;
160  }
161  else
162  {
163  if( !allOtherMonomialsPos )
164  allOtherMonomialsPos = false;
165  if( !allOtherMonomialsNeg )
166  break;
167  }
168  }
169  }
170  if( allOtherMonomialsPos || allOtherMonomialsNeg )
171  {
172  otherMonomialsPositiveWeight = 1;
173  if( constraint().relation() == carl::Relation::EQ )
174  finitlyManySolutionsWeight = 1;
175  }
176  }
177  double weightFactorTmp = maximum;
178 // std::cout << "valuate " << mConstraint << " for " << _consideredVariable << std::endl;
179 // std::cout << "finitlyManySolutionsWeight = " << finitlyManySolutionsWeight << std::endl;
180 // std::cout << "wtfweight = " << (_preferEquation ? ((constraint().relation() == carl::Relation::EQ || degreeWeight <= 2) ? 1 : 2) : (degreeWeight <= 2 ? 1 : 2)) << std::endl;
181 // std::cout << "relationSymbolWeight = " << relationSymbolWeight << std::endl;
182 // std::cout << "univariateWeight = " << (degreeWeight <= 2 && numberOfVariableWeight == 1 ? 1 : 2) << std::endl;
183 // std::cout << "degreeWeight = " << degreeWeight << std::endl;
184 // std::cout << "lCoeffWeight = " << lCoeffWeight << std::endl;
185 // if( _consideredVariable.type() == carl::VariableType::VT_INT )
186 // {
187 // std::cout << "lCoeffWeightB = " << lCoeffWeightB << std::endl;
188 // }
189 // std::cout << "numberOfVariableWeight = " << numberOfVariableWeight << std::endl;
190 // std::cout << "numberOfVariableOccurencesWeight = " << numberOfVariableOccurencesWeight << std::endl;
191 // std::cout << "otherMonomialsPositiveWeight = " << otherMonomialsPositiveWeight << std::endl;
192  double result = finitlyManySolutionsWeight;
193  if( _preferEquation )
194  result += ((constraint().relation() == carl::Relation::EQ || degreeWeight <= 2) ? 1 : 2)/weightFactorTmp;
195  else
196  result += (degreeWeight <= 2 ? 1 : 2)/weightFactorTmp;
197  weightFactorTmp *= maximum;
198  result += relationSymbolWeight/weightFactorTmp;
199  weightFactorTmp *= maximum;
200  //result += (degreeWeight <= 2 && numberOfVariableWeight == 1 ? 1 : 2) /weightFactorTmp;
201  //weightFactorTmp *= maximum;
202  result += degreeWeight/weightFactorTmp;
203  weightFactorTmp *= maximum;
204  result += lCoeffWeight/weightFactorTmp;
205  weightFactorTmp *= maximum;
206  if( _consideredVariable.type() == carl::VariableType::VT_INT )
207  {
208  result += lCoeffWeightB/weightFactorTmp;
209  weightFactorTmp *= maximum;
210  }
211  //result += numberOfVariableWeight/weightFactorTmp;
212  //weightFactorTmp *= maximum;
213  result += numberOfVariableOccurencesWeight/weightFactorTmp;
214  weightFactorTmp *= maximum;
215  result += otherMonomialsPositiveWeight/weightFactorTmp;
216  return result;
217 
218  }
219 
220  /**
221  * Checks the equality of a given condition (right hand side) with this condition (left hand side).
222  *
223  * @param _condition The condition to compare with (rhs).
224  *
225  * @return true ,if the given condition is equal to this condition;
226  * false ,otherwise.
227  */
228  bool Condition::operator==( const Condition& _condition ) const
229  {
230  return mId == _condition.id();
231  }
232 
233  /**
234  * Checks if the given condition (right hand side) is greater than this condition (left hand side).
235  *
236  * @param _condition The condition to compare with (rhs).
237  *
238  * @return true ,if the given substitution is greater than this substitution;
239  * false ,otherwise.
240  */
241  bool Condition::operator<( const Condition& _condition ) const
242  {
243  return mId < _condition.id();
244  }
245 
246  std::ostream& operator<<( std::ostream& _out, const Condition& _condition )
247  {
248  _condition.print( _out );
249  return _out;
250  }
251 
252  /**
253  * Prints the condition to an output stream.
254  *
255  * @param _out The output stream, where it should print.
256  */
257  void Condition::print( std::ostream& _out ) const
258  {
259  _out << constraint();
260  _out << " [" << mId << "]";
261  _out << " ";
262  if( flag() )
263  _out << "(true, ";
264  else
265  _out << "(false, ";
266  _out << "valuation=" << valuation();
267  if( recentlyAdded() )
268  _out << ", recently added) {";
269  else
270  _out << ") {";
271  if( originalConditions().empty() )
272  _out << "no original condition}";
273  else
274  {
275  for( auto oCond = originalConditions().begin(); oCond != originalConditions().end(); ++oCond )
276  {
277  if( oCond != originalConditions().begin() )
278  _out << ", ";
279  _out << "[" << (*oCond)->id() << "]";
280  }
281  _out << " }";
282  }
283  }
284 } // end namspace vs
285 } // end namespace smtrat
void print(std::ostream &=std::cout) const
Prints the condition to an output stream.
Definition: Condition.cpp:257
const smtrat::ConstraintT & constraint() const
Definition: Condition.h:81
static const double INFINITLY_MANY_SOLUTIONS_WEIGHT
Definition: Condition.h:23
bool recentlyAdded() const
Definition: Condition.h:61
double valuate(const carl::Variable &, size_t, bool) const
Valuates the constraint according to a variable (it possibly not contains).
Definition: Condition.cpp:49
carl::PointerSet< Condition > * mpOriginalConditions
Definition: Condition.h:32
size_t id() const
Definition: Condition.h:76
bool flag() const
Definition: Condition.h:51
size_t valuation() const
Definition: Condition.h:71
const carl::PointerSet< Condition > & originalConditions() const
Definition: Condition.h:91
bool operator<(const Condition &) const
Checks if the given condition (right hand side) is greater than this condition (left hand side).
Definition: Condition.cpp:241
bool operator==(const Condition &) const
Checks the equality of a given condition (right hand side) with this condition (left hand side).
Definition: Condition.cpp:228
Condition(const smtrat::ConstraintT &, size_t _id, size_t=0, bool=false, const carl::PointerSet< Condition > &=carl::PointerSet< Condition >(), bool=false)
Definition: Condition.cpp:15
std::ostream & operator<<(std::ostream &_out, const Condition &_condition)
Definition: Condition.cpp:246
Class to create the formulas for axioms.
carl::MultivariatePolynomial< Rational > Poly
Definition: types.h:25
carl::Constraint< Poly > ConstraintT
Definition: types.h:29