carl  24.04
Computer ARithmetic Library
ThomEncoding.h
Go to the documentation of this file.
1 /*
2  * File: ThomEncoding.h
3  * Author: tobias
4  *
5  * Created on 19. August 2016, 10:22
6  */
7 
8 #pragma once
9 
11 #include "ThomRootFinder.h"
13 
14 // some settings
15 #define INITIAL_OFFSET (Number(1)/10)
16 
17 
18 namespace carl {
19 
20 template<typename Number>
21 class ThomEncoding {
22 
24 
25  mutable SignCondition mSc; // this can grow when comparing
28 
29  std::shared_ptr<ThomEncoding<Number>> mPoint;
30  mutable std::shared_ptr<SignDetermination<Number>> mSd;
31 
33 
34 public:
35 
37  SignCondition sc,
38  const Polynomial& p,
39  Variable mainVar,
40  std::shared_ptr<ThomEncoding<Number>> point,
41  std::shared_ptr<SignDetermination<Number>> sd,
43  ):
44  mSc(std::move(sc)),
45  mP(p),
46  mMainVar(mainVar),
47  mPoint(std::move(point)),
48  mSd(std::move(sd)),
50  {}
51 
53  const Number& n,
54  Variable mainVar,
55  std::shared_ptr<ThomEncoding<Number>> point = nullptr
56  ):
57  mMainVar(mainVar), mPoint(std::move(point))
58  {
59  Polynomial p = Polynomial(mainVar) - n;
60  std::list<ThomEncoding<Number>> roots = realRootsThom(p, mainVar, point);
61  CARL_LOG_ASSERT("carl.thom", roots.size() == 1, "");
62  mSc = roots.front().mSc;
63  mP = roots.front().mP;
64  mSd = roots.front().mSd;
65  mRelevant = roots.front().mRelevant;
66  }
67 
69  const ThomEncoding<Number>& te,
70  std::shared_ptr<ThomEncoding<Number>> point
71  )
72  {
73  CARL_LOG_ASSERT("carl.thom", te.mP.is_univariate(), "");
74  CARL_LOG_ASSERT("carl.thom", te.mPoint == nullptr, "");
75  CARL_LOG_ASSERT("carl.thom", point != nullptr, "");
76  std::list<ThomEncoding<Number>> roots = realRootsThom(te.mP, te.mMainVar, point);
77  for(const auto& r : roots) {
78  if(te.relevantSignCondition() == r.mSc) {
79  mSc = r.mSc;
80  mP = r.mP;
81  mMainVar = r.mMainVar;
82  mPoint = r.mPoint;
83  mSd = r.mSd;
84  mRelevant = r.mRelevant;
85  return;
86  }
87  }
88  CARL_LOG_ASSERT("carl.thom", false, "should never get here");
89  }
90 
91  bool is_number() const {
92  return false;
93  }
94 
95  const auto& get_number() const {
97  }
98 
99  bool containedIn(const Interval<Number>& i) const {
101  if(i.lower_bound_type() == BoundType::STRICT && *this <= i.lower()) return false;
102  if(i.lower_bound_type() == BoundType::WEAK && *this < i.lower()) return false;
103  }
105  if(i.upper_bound_type() == BoundType::STRICT && *this >= i.upper()) return false;
106  if(i.upper_bound_type() == BoundType::WEAK && *this > i.upper()) return false;
107  }
108  return true;
109  }
110 
111  inline SignCondition signCondition() const { return mSc; }
113  inline Variable::Arg main_var() const { return mMainVar; }
114  inline const Polynomial& polynomial() const { return mP; }
115  inline const ThomEncoding<Number>& point() const {assert(mPoint); return *mPoint; }
116  inline SignDetermination<Number> sd() const {assert(mSd); return *mSd; }
117 
118  std::list<Polynomial> relevantDerivatives() const {
119  std::list<Polynomial> derivatives = der(mP, mMainVar, 0, mP.degree(mMainVar));
120  std::reverse(derivatives.begin(), derivatives.end());
121  derivatives.resize(mRelevant);
122  std::reverse(derivatives.begin(), derivatives.end());
123  assert(derivatives.size() == mRelevant);
124  return derivatives;
125  }
126 
128  if(mPoint == nullptr) return ThomEncoding<Number>(*this);
129  return mPoint->lowestInChain();
130  }
131 
132  uint dimension() const {
133  if(mPoint == nullptr) return 1;
134  return 1 + point().dimension();
135  }
136 
137  std::list<Polynomial> accumulatePolynomials() const {
138  if(mPoint == nullptr) return {polynomial()};
139  std::list<Polynomial> res = point().accumulatePolynomials();
140  res.push_front(polynomial());
141  return res;
142  }
143 
144  std::list<Variable> accumulateVariables() const {
145  if(mPoint == nullptr) return {main_var()};
146  std::list<Variable> res = point().accumulateVariables();
147  res.push_front(main_var());
148  return res;
149  }
150 
152  if(mPoint == nullptr) return signCondition();
153  SignCondition res = point().accumulateSigns();
154  res.insert(res.begin(), mSc.begin(), mSc.end());
155  return res;
156  }
157 
159  if(mPoint == nullptr) return this->relevantSignCondition();
160  SignCondition res = point().accumulateRelevantSigns();
161  SignCondition mScRel = this->relevantSignCondition();
162  res.insert(res.begin(), mScRel.begin(), mScRel.end());
163  return res;
164  }
165 
166  Sign signOnPolynomial(const Polynomial& p) const {
167  CARL_LOG_ASSERT("carl.thom", carl::variables(p).size() <= this->dimension(), "\np = " << p << "\nthis = " << *this);
168  if(carl::is_zero(p)) return Sign(0);
169  if(p.is_constant()) return Sign(carl::sgn(p.lcoeff()));
170  std::list<SignCondition> signs = mSd->getSigns(p);
172  for(const auto& sigma : signs) {
173  if(relevant.isSuffixOf(sigma)) return sigma.front();
174  }
175  CARL_LOG_ASSERT("carl.thom", false, "we should never get here");
176  std::exit(42);
177  return Sign(0);
178  }
179 
180  bool makesPolynomialZero(const Polynomial& pol, Variable::Arg pol_mainVar) const {
181  assert(!carl::is_zero(pol));
182  assert(mMainVar != pol_mainVar);
184  // maybe check first if pol_univ has some constant coefficient...
185  for(const auto& t : pol_univ.coefficients()) {
186  assert(this->dimension() >= carl::variables(t).size());
187  if(this->signOnPolynomial(t) != Sign::ZERO) return false;
188  }
189  return true;
190  }
191 
192 
193  void extendSignCondition() const {
194  CARL_LOG_ASSERT("carl.thom", signCondition().size() < polynomial().degree(mMainVar) + 1, "cannot extend sign condition any more");
195  if(mSc.size() == mP.degree(mMainVar)) {
196  mSc.push_front(Sign::ZERO);
197  return;
198  }
199  Polynomial derivative = der(mP, mMainVar, 1, mP.degree(mMainVar) - mSc.size()).back();
200  mSc.push_front(this->signOnPolynomial(derivative));
201  }
202 
204  return sgn(Polynomial(p));
205  }
206  Sign sgn(const Polynomial& p) const {
207  return signOnPolynomial(p);
208  }
209  Sign sgn() const {
211  }
212 
213  bool is_integral() const {
214  return false;
215  }
216  Number integer_below() const {
218  }
219 
220  //[[deprecated("Use sgn() instead.")]]
221  Sign sgnReprNum() const {
223  }
224 
225  bool is_zero() const {
226  return sgnReprNum() == Sign::ZERO;
227  }
228 
230  CARL_LOG_TRACE("carl.thom", "concating: \n" << *this << "\nwith\n" << other);
231  ThomEncoding<Number> result = other;
232 
233  std::list<ThomEncoding<Number>> thisEncodings;
234  thisEncodings.push_back(ThomEncoding<Number>(*this));
235  std::shared_ptr<ThomEncoding<Number>> curr = mPoint;
236  while(curr != nullptr) {
237  thisEncodings.push_back(ThomEncoding<Number>(*curr));
238  curr = thisEncodings.back().mPoint;
239  }
240  assert(thisEncodings.size() == this->dimension());
241  CARL_LOG_TRACE("carl.thom", "thisEncodings = " << thisEncodings);
242 
243  SignCondition thisSignCondition = this->accumulateRelevantSigns();
245  signCondition.insert(signCondition.begin(), thisSignCondition.begin(), thisSignCondition.end());
246 
247  for(auto itEncoding = thisEncodings.rbegin(); itEncoding != thisEncodings.rend(); itEncoding++) {
248  std::list<Variable> vars = result.accumulateVariables();
249  if(std::find(vars.begin(), vars.end(), itEncoding->main_var()) != vars.end()) {
250  continue;
251  }
252  std::shared_ptr<ThomEncoding<Number>> result_ptr = std::make_shared<ThomEncoding<Number>>(result);
253  std::list<ThomEncoding<Number>> roots = realRootsThom(itEncoding->polynomial(), itEncoding->main_var(), result_ptr);
254  bool succes = false;
255  for(const auto& r : roots) {
256  if(r.accumulateRelevantSigns().isSuffixOf(signCondition)) {
257  result = r;
258  succes = true;
259  break;
260  }
261  }
262  CARL_LOG_ASSERT("carl.thom", succes, "");
263  }
264  CARL_LOG_TRACE("carl.thom", "result of concat: " << result);
265  return result;
266 
267 // std::list<Polynomial> thisPolynomials = this->accumulatePolynomials();
268 // std::list<Variable> thisVars = this->accumulateVariables();
269 // assert(thisPolynomials.size() == thisVars.size());
270 //
271 // SignCondition thisSignCondition = this->accumulateRelevantSigns();
272 // SignCondition signCondition = other.accumulateRelevantSigns();
273 // signCondition.insert(signCondition.begin(), thisSignCondition.begin(), thisSignCondition.end());
274 //
275 // auto itVars = thisVars.rbegin();
276 // for(auto itPoly = thisPolynomials.rbegin(); itPoly != thisPolynomials.rend(); itPoly++) {
277 // std::shared_ptr<ThomEncoding<Number>> result_ptr = std::make_shared<ThomEncoding<Number>>(result);
278 // std::list<ThomEncoding<Number>> roots = realRootsThom(*itPoly, *itVars, result_ptr);
279 // bool succes = false;
280 // for(const auto& r : roots) {
281 // if(r.accumulateRelevantSigns().isSuffixOf(signCondition)) {
282 // result = r;
283 // succes = true;
284 // break;
285 // }
286 // }
287 // CARL_LOG_ASSERT("carl.thom", succes, "");
288 // itVars++;
289 // }
290 //
291 // CARL_LOG_TRACE("carl.thom", "result of concat: " << result);
292 
293  }
294 
296  CARL_LOG_ASSERT("carl.thom", !m.empty(), "called analyzeTEMap with empty map");
297 
298  // collect variables
299  // the thom ecodings can additionally contain other variables than these!!
300  std::list<Variable> vars;
301  for(const auto& entry : m) {
302  CARL_LOG_ASSERT("carl.thom", std::find(vars.begin(), vars.end(), entry.first) == vars.end(), "variable appears twice in map");
303  vars.push_back(entry.first);
304  }
305  std::list<Variable> originalVars = vars;
306 
307  // collect thom encodings
308  std::list<ThomEncoding<Number>> encodings;
309  for(const auto& entry : m) {
310  encodings.push_back(entry.second);
311  }
312 
313  // sort thom encodings in descending dimension
314  encodings.sort(
315  [](const ThomEncoding<Number>& lhs, const ThomEncoding<Number>& rhs) {
316  return lhs.dimension() > rhs.dimension();
317  }
318  );
319 
320  CARL_LOG_TRACE("carl.thom", "encodings = " << encodings);
321 
322  ThomEncoding<Number> result = encodings.front();
323  for(const auto& v : encodings.front().accumulateVariables()) {
324  auto it = std::find(vars.begin(), vars.end(), v);
325  if(it != vars.end()) vars.erase(it);
326  }
327  encodings.erase(encodings.begin());
328 
329  while(!vars.empty()) {
330  CARL_LOG_ASSERT("carl.thom", !encodings.empty(), "");
331  bool takeit = false;
332  for(const auto& v : encodings.front().accumulateVariables()) {
333  if(std::find(originalVars.begin(), originalVars.end(), v) == originalVars.end()) {
334  continue;
335  }
336  auto it = std::find(vars.begin(), vars.end(), v);
337  if(it != vars.end()) {
338  takeit = true;
339  break;
340  }
341  }
342  if(takeit) {
343  result = result.concat(encodings.front());
344  for(const auto& v : encodings.front().accumulateVariables()) {
345  auto it = std::find(vars.begin(), vars.end(), v);
346  if(it != vars.end()) vars.erase(it);
347  }
348  }
349  encodings.erase(encodings.begin());
350  }
351 
352  CARL_LOG_TRACE("carl.thom", "result = " << result);
353 
354  return result;
355 
356  }
357 
358  //*******************//
359  // COMPARISON //
360  //*******************//
361 
363  CARL_LOG_INFO("carl.thom.compare", "lhs = " << lhs << ", rhs = " << rhs);
364 
365  // 1. Encodings from different levels
366  if(!areComparable(lhs, rhs)) {
367  CARL_LOG_TRACE("carl.thom.compare", "encodings are not comparable");
368  // in this case it is not necessary to compare them by the numbers they actually represent
369  return compareDifferentLevels(lhs, rhs);
370  }
371  CARL_LOG_ASSERT("carl.thom.compare", lhs.main_var() == rhs.main_var(), "");
372 
373  // 2. same underlying polynomial
374  if(lhs.polynomial() == rhs.polynomial()) {
375  CARL_LOG_TRACE("carl.thom.compare", "comparing encodings with same underlying polynomials");
377  }
378 
379  // 3. different underlying polynomial
380  // both are nullptr or both are not nullptr
381  if( !(lhs.mPoint == nullptr && rhs.mPoint != nullptr) && !(lhs.mPoint != nullptr && rhs.mPoint == nullptr)) {
382  CARL_LOG_TRACE("carl.thom.compare", "comparing encodings with different underlying polynomials, !!hopefully with same defining point!!");
383  return compareDifferentPoly(lhs, rhs);
384  }
385 
386  // 4. one of the encodings is "new" on this level and therefore has no underlying point
387  CARL_LOG_ASSERT("carl.thom.compare", lhs.mPoint == nullptr || rhs.mPoint == nullptr, "");
388  CARL_LOG_ASSERT("carl.thom.compare", lhs.mPoint != nullptr || rhs.mPoint != nullptr, "");
389  CARL_LOG_TRACE("carl.thom.compare", "one of the encodings is new on this level");
390  if(lhs.mPoint == nullptr) {
391  return compare(ThomEncoding<Number>(lhs, rhs.mPoint), rhs);
392  }
393  if(rhs.mPoint == nullptr) {
394  return compare(lhs, ThomEncoding<Number>(rhs, lhs.mPoint));
395  }
396 
397  CARL_LOG_ASSERT("carl.thom.compare", false, "we should never get here ... inputs where lhs = " << lhs << ", rhs = " << rhs);
398  return EQUAL;
399  }
400 private:
401 
402  /*
403  * This is not the case if
404  * 1. lhs and rhs do not have the same main variable
405  * 2. they both have a different underlying point which is not nullptr
406  */
407  static bool areComparable(const ThomEncoding<Number>& lhs, const ThomEncoding<Number>& rhs) {
408  if(lhs.main_var() != rhs.main_var()) {
409  return false;
410  }
411  // they have the same main var
412  if(lhs.mPoint != nullptr && rhs.mPoint != nullptr) {
413  CARL_LOG_TRACE("carl.thom.compare", "\nlhs = " << lhs << "\nrhs = " << rhs << "\nlhs.mPoint = " << lhs.mPoint << "\nrhs.mPoint = " << rhs.mPoint);
414  if(!lhs.point().equals(rhs.point())) {
415  CARL_LOG_TRACE("carl.thom.compare", "underlying points are unequal");
416  return false;
417  }
418  CARL_LOG_TRACE("carl.thom.compare", "underlying points are equal");
419  }
420  return true;
421  }
422 
424  if(lhs.polynomial() < rhs.polynomial()) return LESS;
425  if(lhs.polynomial() > rhs.polynomial()) return GREATER;
426  if(lhs.mPoint == nullptr && rhs.mPoint != nullptr) return LESS;
427  if(lhs.mPoint != nullptr && rhs.mPoint == nullptr) return GREATER;
428  if(lhs.mPoint != nullptr && rhs.mPoint != nullptr) return compareDifferentLevels(lhs.point(), rhs.point());
429  // same polynomials, mPoint both nullptr
430  CARL_LOG_ASSERT("carl.thom.compare", lhs.mPoint == nullptr && rhs.mPoint == nullptr, "i think this should not happen");
432 
433  }
434 public:
435  static ThomComparisonResult compareRational(const ThomEncoding<Number>& lhs, const Number& rhs) {
436  ThomEncoding<Number> rhs_te(rhs, lhs.main_var(), lhs.mPoint);
437  return compare(lhs, rhs_te);
438  }
439 
441 
442  // checks if the thom encodings are "literally" the same (this is not the same as operator =)
443  bool equals(const ThomEncoding<Number>& other) const {
444  if(this->polynomial() != other.polynomial()) return false;
445  if(this->relevantSignCondition() != other.relevantSignCondition()) return false;
446  if(this->dimension() != other.dimension()) return false;
447  if(this->mPoint != nullptr && other.mPoint != nullptr) {
448  return this->point().equals(other.point());
449  }
450  return true;
451  }
452 
453 
454 public:
455 
456  /* Addition */
457 
458  ThomEncoding<Number> operator+(const Number& rhs) const {
459  Polynomial subs = Polynomial(mMainVar) - rhs;
461  std::list<ThomEncoding<Number>> roots = realRootsThom(p, mMainVar, mPoint);
462  for(const auto& r: roots) {
463  if (relevantSignCondition() == r.mSc) return r;
464  }
465  CARL_LOG_ASSERT("carl.thom.samples", false, "we should never get here");
466  std::exit(42);
467  return *this;
468  }
469 
470  /*
471  * returns a thom encoding representing a number in the interval (lhs, rhs)
472  */
474  CARL_LOG_INFO("carl.thom.samples", lhs << ", " << rhs);
475  CARL_LOG_ASSERT("carl.thom.samples", lhs.mMainVar == rhs.mMainVar, "no intermediate point between encodings on different levels!");
476  CARL_LOG_ASSERT("carl.thom.samples", lhs < rhs, "lhs >= rhs !!!");
477  Number epsilon(INITIAL_OFFSET);
478  std::cout << "epsilon = " << epsilon << std::endl;
479  // pick the polynomial with smaller degree here (or lhs, if equal degree)
480  if(lhs.mP.degree(lhs.mMainVar) <= rhs.mP.degree(rhs.mMainVar)) {
481  ThomEncoding<Number> res = lhs + epsilon;
482  while(res >= rhs) {
483  epsilon /= 2;
484  res = lhs + epsilon;
485  }
486  CARL_LOG_TRACE("carl.thom.samples", "result: " << res);
487  return res;
488  }
489  else {
490  epsilon = -epsilon;
491  ThomEncoding<Number> res = rhs + epsilon;
492  std::cout << "res = " << res << std::endl;
493  while(lhs >= res) {
494  epsilon /= 2;
495  res = rhs + epsilon;
496  }
497  CARL_LOG_TRACE("carl.thom.samples", "result: " << res);
498  return res;
499  }
500 
501  }
502 
503  /*
504  * finds an intermediate point between the thom encoding and the rational
505  * always returns a rational
506  */
507  static Number intermediatePoint(const ThomEncoding<Number>& lhs, const Number& rhs) {
508  CARL_LOG_INFO("carl.thom.samples", lhs << ", " << rhs);
509  CARL_LOG_ASSERT("carl.thom.samples", lhs < rhs, "intermediatePoint with wrong order or equal arguments called");
510  Number res;
511  Number epsilon(INITIAL_OFFSET);
512  res = rhs - epsilon;
513  while(lhs >= res) {
514  epsilon /= 2;
515  res = rhs - epsilon;
516  }
517  CARL_LOG_TRACE("carl.thom.samples", "result: " << res);
518  return res;
519  }
520 
521  static Number intermediatePoint(const Number& lhs, const ThomEncoding<Number>& rhs) {
522  CARL_LOG_INFO("carl.thom.samples", lhs << ", " << rhs);
523  CARL_LOG_ASSERT("carl.thom.samples", lhs < rhs, "intermediatePoint with wrong order order in arguments called");
524  Number res;
525  Number epsilon(INITIAL_OFFSET);
526  res = lhs + epsilon;
527  while(res >= rhs) {
528  epsilon /= 2;
529  res = lhs + epsilon;
530  }
531  CARL_LOG_TRACE("carl.thom.samples", "result: " << res);
532  return res;
533  }
534 
535 
536  /* Output */
537 
538  void print(std::ostream& os) const {
539  os << "\n---------------------------------------------------" << std::endl;
540  os << "Thom encoding" << std::endl;
541  os << "---------------------------------------------------" << std::endl;
542  os << "sign condition:\t\t\t" << mSc << std::endl;
543  os << "relevant:\t\t\t" << mRelevant << std::endl;
544  os << "polynomial:\t\t\t" << mP << std::endl;
545  os << "main variable: \t\t\t" << mMainVar << std::endl;
546  os << "point below:\t\t\t" << mPoint << std::endl;
547  os << "sign determination obejct:\t" << mSd << std::endl;
548  os << "dimension:\t\t\t" << dimension() << std::endl;
549  os << "---------------------------------------------------" << std::endl;
550  }
551 
552 }; // class ThomEncoding
553 
554 
555 
556 
557 // compare thom encodings with thom encodings
558 template<typename N>
559 bool operator<(const ThomEncoding<N>& lhs, const ThomEncoding<N>& rhs) { return ThomEncoding<N>::compare(lhs, rhs) == LESS; }
560 template<typename N>
561 bool operator<=(const ThomEncoding<N>& lhs, const ThomEncoding<N>& rhs) { return ThomEncoding<N>::compare(lhs, rhs) != GREATER; }
562 template<typename N>
563 bool operator>(const ThomEncoding<N>& lhs, const ThomEncoding<N>& rhs) { return ThomEncoding<N>::compare(lhs, rhs) == GREATER; }
564 template<typename N>
565 bool operator>=(const ThomEncoding<N>& lhs, const ThomEncoding<N>& rhs) { return ThomEncoding<N>::compare(lhs, rhs) != LESS; }
566 template<typename N>
567 bool operator==(const ThomEncoding<N>& lhs, const ThomEncoding<N>& rhs) { return ThomEncoding<N>::compare(lhs, rhs) == EQUAL; }
568 template<typename N>
569 bool operator!=(const ThomEncoding<N>& lhs, const ThomEncoding<N>& rhs) { return ThomEncoding<N>::compare(lhs, rhs) != EQUAL; }
570 
571 // comparing with rational numbers
572 template<typename N>
573 bool operator<(const ThomEncoding<N>& lhs, const N& rhs) { return ThomEncoding<N>::compareRational(lhs, rhs) == LESS; }
574 template<typename N>
575 bool operator<=(const ThomEncoding<N>& lhs, const N& rhs) { return ThomEncoding<N>::compareRational(lhs, rhs) != GREATER; }
576 template<typename N>
577 bool operator>(const ThomEncoding<N>& lhs, const N& rhs) { return ThomEncoding<N>::compareRational(lhs, rhs) == GREATER; }
578 template<typename N>
579 bool operator>=(const ThomEncoding<N>& lhs, const N& rhs) { return ThomEncoding<N>::compareRational(lhs, rhs) != LESS; }
580 template<typename N>
581 bool operator==(const ThomEncoding<N>& lhs, const N& rhs) { return ThomEncoding<N>::compareRational(lhs, rhs) == EQUAL; }
582 template<typename N>
583 bool operator!=(const ThomEncoding<N>& lhs, const N& rhs) { return ThomEncoding<N>::compareRational(lhs, rhs) != EQUAL; }
584 
585 template<typename N>
586 bool operator<(const N& lhs, const ThomEncoding<N>& rhs) { return rhs > lhs; }
587 template<typename N>
588 bool operator<=(const N& lhs, const ThomEncoding<N>& rhs) { return rhs >= lhs; }
589 template<typename N>
590 bool operator>(const N& lhs, const ThomEncoding<N>& rhs) { return rhs < lhs; }
591 template<typename N>
592 bool operator>=(const N& lhs, const ThomEncoding<N>& rhs) { return rhs <= lhs; }
593 template<typename N>
594 bool operator==(const N& lhs, const ThomEncoding<N>& rhs) { return rhs == lhs; }
595 template<typename N>
596 bool operator!=(const N& lhs, const ThomEncoding<N>& rhs) { return rhs != lhs; }
597 
598 template<typename N>
599 ThomEncoding<N> operator+(const N& lhs, const ThomEncoding<N>& rhs) { return rhs + lhs; }
600 
601 template<typename N>
602 std::ostream& operator<<(std::ostream& os, const ThomEncoding<N>& rhs) {
603  os << "TE " << rhs.polynomial() << " in " << rhs.main_var() << ", " << rhs.signCondition();
604  if(rhs.dimension() > 1) {
605  os << " OVER " << rhs.point();
606  }
607  return os;
608 }
609 
610 } // namespace carl
611 
612 #include "ThomEncoding.tpp"
#define CARL_LOG_TRACE(channel, msg)
Definition: carl-logging.h:44
#define CARL_LOG_ASSERT(channel, condition, msg)
Definition: carl-logging.h:47
#define CARL_LOG_INFO(channel, msg)
Definition: carl-logging.h:42
int main(int argc, char **argv)
carl is the main namespace for the library.
UnivariatePolynomial< C > to_univariate_polynomial(const MultivariatePolynomial< C, O, P > &p)
Convert a univariate polynomial that is currently (mis)represented by a 'MultivariatePolynomial' into...
const T & derivative(const T &t, Variable, std::size_t n=1)
Computes the n'th derivative of a number, which is either the number itself (for n = 0) or zero.
Definition: Derivative.h:23
std::uint64_t uint
Definition: numbers.h:16
Sign
This class represents the sign of a number .
Definition: Sign.h:20
@ ZERO
Indicates that .
bool is_zero(const Interval< Number > &i)
Check if this interval is a point-interval containing 0.
Definition: Interval.h:1453
std::list< MultivariatePolynomial< Number > > der(const MultivariatePolynomial< Number > &p, Variable::Arg var, uint from, uint upto)
Definition: ThomUtil.h:17
Sign sgn(const Number &n)
Obtain the sign of the given number.
Definition: Sign.h:54
std::list< ThomEncoding< Number > > realRootsThom(const MultivariatePolynomial< Number > &p, Variable::Arg mainVar, std::shared_ptr< ThomEncoding< Number >> point_ptr, const Interval< Number > &interval=Interval< Number >::unbounded_interval())
Coeff substitute(const Monomial &m, const std::map< Variable, Coeff > &substitutions)
Applies the given substitutions to a monomial.
Definition: Substitution.h:19
ThomComparisonResult
Definition: SignCondition.h:15
@ GREATER
Definition: SignCondition.h:15
@ WEAK
the given bound is compared by a weak ordering relation
@ STRICT
the given bound is compared by a strict ordering relation
@ INFTY
the given bound is interpreted as minus or plus infinity depending on whether it is the left or the r...
void variables(const BasicConstraint< Pol > &c, carlVariables &vars)
UnivariatePolynomial< Coefficient > reverse(UnivariatePolynomial< Coefficient > &&p)
Reverses the order of the coefficients of this polynomial.
A Variable represents an algebraic variable that can be used throughout carl.
Definition: Variable.h:85
The class which contains the interval arithmetic including trigonometric functions.
Definition: Interval.h:134
BoundType lower_bound_type() const
The getter for the lower bound type of the interval.
Definition: Interval.h:883
const Number & upper() const
The getter for the upper boundary of the interval.
Definition: Interval.h:849
const Number & lower() const
The getter for the lower boundary of the interval.
Definition: Interval.h:840
BoundType upper_bound_type() const
The getter for the upper bound type of the interval.
Definition: Interval.h:892
static const T & get()
Definition: constants.h:42
This class represents a univariate polynomial with coefficients of an arbitrary type.
const std::vector< Coefficient > & coefficients() const &
Retrieves the coefficients defining this polynomial.
bool is_constant() const
Check if the polynomial is constant.
std::size_t degree(Variable::Arg var) const
Calculates the degree of this polynomial with respect to the given variable.
bool is_univariate() const
Checks whether only one variable occurs.
const Coeff & lcoeff() const
Returns the coefficient of the leading term.
bool isSuffixOf(const SignCondition &other) const
Definition: SignCondition.h:25
static ThomComparisonResult compare(const SignCondition &lhs, const SignCondition &rhs)
Definition: SignCondition.h:48
SignCondition trailingPart(uint count) const
Definition: SignCondition.h:37
Sign sgn(const Polynomial &p) const
Definition: ThomEncoding.h:206
ThomEncoding< Number > operator+(const Number &rhs) const
Definition: ThomEncoding.h:458
bool is_integral() const
Definition: ThomEncoding.h:213
bool containedIn(const Interval< Number > &i) const
Definition: ThomEncoding.h:99
Sign sgn() const
Definition: ThomEncoding.h:209
std::list< Polynomial > relevantDerivatives() const
Definition: ThomEncoding.h:118
std::list< Polynomial > accumulatePolynomials() const
Definition: ThomEncoding.h:137
std::list< Variable > accumulateVariables() const
Definition: ThomEncoding.h:144
uint dimension() const
Definition: ThomEncoding.h:132
ThomEncoding< Number > concat(const ThomEncoding< Number > &other) const
Definition: ThomEncoding.h:229
static ThomComparisonResult compareDifferentPoly(const ThomEncoding< Number > &lhs, const ThomEncoding< Number > &rhs)
static ThomComparisonResult compareRational(const ThomEncoding< Number > &lhs, const Number &rhs)
Definition: ThomEncoding.h:435
Sign signOnPolynomial(const Polynomial &p) const
Definition: ThomEncoding.h:166
bool is_number() const
Definition: ThomEncoding.h:91
ThomEncoding< Number > lowestInChain() const
Definition: ThomEncoding.h:127
SignCondition accumulateRelevantSigns() const
Definition: ThomEncoding.h:158
SignCondition accumulateSigns() const
Definition: ThomEncoding.h:151
SignCondition mSc
Definition: ThomEncoding.h:25
std::shared_ptr< SignDetermination< Number > > mSd
Definition: ThomEncoding.h:30
SignDetermination< Number > sd() const
Definition: ThomEncoding.h:116
SignCondition relevantSignCondition() const
Definition: ThomEncoding.h:112
std::shared_ptr< ThomEncoding< Number > > mPoint
Definition: ThomEncoding.h:29
const Polynomial & polynomial() const
Definition: ThomEncoding.h:114
MultivariatePolynomial< Number > Polynomial
Definition: ThomEncoding.h:23
static ThomComparisonResult compare(const ThomEncoding< Number > &lhs, const ThomEncoding< Number > &rhs)
Definition: ThomEncoding.h:362
bool makesPolynomialZero(const Polynomial &pol, Variable::Arg pol_mainVar) const
Definition: ThomEncoding.h:180
SignCondition signCondition() const
Definition: ThomEncoding.h:111
ThomEncoding(SignCondition sc, const Polynomial &p, Variable mainVar, std::shared_ptr< ThomEncoding< Number >> point, std::shared_ptr< SignDetermination< Number >> sd, uint mRelevant)
Definition: ThomEncoding.h:36
Sign sgn(const UnivariatePolynomial< Number > &p) const
Definition: ThomEncoding.h:203
Number integer_below() const
Definition: ThomEncoding.h:216
static ThomEncoding< Number > intermediatePoint(const ThomEncoding< Number > &lhs, const ThomEncoding< Number > &rhs)
Definition: ThomEncoding.h:473
static bool areComparable(const ThomEncoding< Number > &lhs, const ThomEncoding< Number > &rhs)
Definition: ThomEncoding.h:407
bool is_zero() const
Definition: ThomEncoding.h:225
Sign sgnReprNum() const
Definition: ThomEncoding.h:221
static ThomComparisonResult compareDifferentLevels(const ThomEncoding< Number > &lhs, const ThomEncoding< Number > &rhs)
Definition: ThomEncoding.h:423
const ThomEncoding< Number > & point() const
Definition: ThomEncoding.h:115
ThomEncoding(const ThomEncoding< Number > &te, std::shared_ptr< ThomEncoding< Number >> point)
Definition: ThomEncoding.h:68
static ThomEncoding< Number > analyzeTEMap(const std::map< Variable, ThomEncoding< Number >> &m)
Definition: ThomEncoding.h:295
const auto & get_number() const
Definition: ThomEncoding.h:95
void extendSignCondition() const
Definition: ThomEncoding.h:193
bool equals(const ThomEncoding< Number > &other) const
Definition: ThomEncoding.h:443
ThomEncoding(const Number &n, Variable mainVar, std::shared_ptr< ThomEncoding< Number >> point=nullptr)
Definition: ThomEncoding.h:52
Variable::Arg main_var() const
Definition: ThomEncoding.h:113