carl  24.04
Computer ARithmetic Library
Ran.h
Go to the documentation of this file.
1 #pragma once
2 
11 
15 
16 #include "../common/Operations.h"
17 #include "../common/NumberOperations.h"
18 
19 #include <list>
20 #include <boost/logic/tribool.hpp>
21 
22 namespace carl {
23 
24 template<typename Number>
26  static const Variable auxVariable;
27 
28  template<typename Num>
30 
31  template<typename Num>
32  friend bool compare(const IntRepRealAlgebraicNumber<Num>&, const Num&, const Relation);
33 
34  template<typename Num, typename Poly>
35  friend boost::tribool evaluate(const BasicConstraint<Poly>&, const Assignment<IntRepRealAlgebraicNumber<Num>>&, bool, bool);
36 
37  template<typename Num>
38  friend std::optional<IntRepRealAlgebraicNumber<Num>> evaluate(MultivariatePolynomial<Num>, const Assignment<IntRepRealAlgebraicNumber<Num>>&, bool);
39 
40  template<typename Num>
42 
43  template<typename Num>
45 
46  template<typename Num>
48 
49  template<typename Num>
51 
52  template<typename Num>
53  friend Num sample_between(const IntRepRealAlgebraicNumber<Num>& lower, const Num& upper);
54 
55  template<typename Num>
56  friend Num sample_between(const Num& lower, const IntRepRealAlgebraicNumber<Num>& upper);
57 
58  template<typename Num>
59  friend Num floor(const IntRepRealAlgebraicNumber<Num>& n);
60 
61  template<typename Num>
62  friend Num ceil(const IntRepRealAlgebraicNumber<Num>& n);
63 
64  template<typename Num>
66 
67 private:
68  struct content {
69  std::optional<UnivariatePolynomial<Number>> polynomial;
71  /// Sign of polynomial at interval.lower()
73 
75  : polynomial(std::nullopt), interval(i), lower_sign(Sign::ZERO) {}
77  : polynomial(std::move(p)), interval(i), lower_sign(Sign::ZERO) {}
79  : polynomial(p), interval(i), lower_sign(Sign::ZERO) {}
81  assert(interval.is_point_interval());
82  polynomial = std::nullopt;
84  }
85  };
86 
87  mutable std::shared_ptr<content> m_content;
88 
91  }
92 
93  bool is_consistent() const {
94  if (interval_int().is_point_interval()) {
95  return !m_content->polynomial && m_content->lower_sign == Sign::ZERO;
96  } else {
97  if (interval_int().contains(0) || interval_int().contains_integer()) {
98  CARL_LOG_DEBUG("carl.ran.interval", "Interval contains 0 or integer");
99  return false;
100  }
101  if (polynomial_int().normalized() != carl::squareFreePart(polynomial_int()).normalized()) {
102  CARL_LOG_DEBUG("carl.ran.interval", "Poly is not square free: " << polynomial_int());
103  return false;
104  }
105  auto lsgn = carl::sgn(carl::evaluate(polynomial_int(), interval_int().lower()));
106  auto usgn = carl::sgn(carl::evaluate(polynomial_int(), interval_int().upper()));
107  if (lsgn == Sign::ZERO || usgn == Sign::ZERO || lsgn == usgn) {
108  CARL_LOG_DEBUG("carl.ran.interval", "Interval does not define a zero");
109  return false;
110  }
111  if (m_content->lower_sign != lsgn) {
112  CARL_LOG_DEBUG("carl.ran.interval", "Lower sign does not match");
113  return false;
114  }
115  return true;
116  }
117  }
118 
119  void set_polynomial(const UnivariatePolynomial<Number>& p, Sign lower_sign) const {
120  assert(!interval_int().is_point_interval());
122  m_content->lower_sign = lower_sign;
123  assert(is_consistent());
124  }
125 
126  /**
127  * Returns the sign of "interval_int() - pivot":
128  * Returns ZERO if pivot is equal to RAN.
129  * Returns POSITIVE if pivot is less than RAN resp. the new lower bound.
130  * Returns NEGATIVE if pivot is greater than RAN resp. the new upper bound.
131  */
132  Sign refine_internal(const Number& pivot) const {
133  // assert(is_consistent());
134  assert(interval_int().contains(pivot));
135  assert(!interval_int().is_point_interval());
136  auto psgn = carl::sgn(carl::evaluate(polynomial_int(), pivot));
137  if (psgn == Sign::ZERO) {
138  interval_int() = Interval<Number>(pivot, pivot);
139  m_content->simplify_to_point();
140  return Sign::ZERO;
141  }
142  if (psgn == m_content->lower_sign) {
143  interval_int().set_lower(pivot);
144  assert(interval_int().is_consistent());
145  return Sign::POSITIVE;
146  } else {
147  interval_int().set_upper(pivot);
148  assert(interval_int().is_consistent());
149  return Sign::NEGATIVE;
150  }
151  }
152 
153 public:
154  void refine() const {
155  if (is_numeric()) return;
156  Number pivot = carl::sample(interval_int());
157  refine_internal(pivot);
158  }
159 
160  std::optional<Sign> refine_using(const Number& pivot) const {
161  if (interval_int().contains(pivot)) {
162  if (is_numeric()) return Sign::ZERO;
163  else return refine_internal(pivot);
164  }
165  return std::nullopt;
166  }
167 
168 private:
169  /// Refines until the number is either numeric or the interval does not contain any integer.
170  void refine_to_integrality() const {
171  while (!interval_int().is_point_interval() && interval_int().contains_integer()) {
172  refine();
173  }
174  }
175 
176 public:
178  : m_content(std::make_shared<content>(Interval<Number>(0))) {}
179 
180  IntRepRealAlgebraicNumber(const Number& n)
181  : m_content(std::make_shared<content>(Interval<Number>(n))) {}
182 
184  : m_content(std::make_shared<content>(replace_variable(p), i)) {
185  CARL_LOG_DEBUG("carl.ran.interval", "Creating (" << p << "," << i << ")");
186  assert(!carl::is_zero(polynomial_int()) && polynomial_int().degree() > 0);
187  assert(interval_int().is_open_interval() || interval_int().is_point_interval());
188  // assert(interval_int().is_point_interval() || count_real_roots(sturm_sequence(), interval_int()) == 1);
189  if (interval_int().is_point_interval()) {
190  m_content->simplify_to_point();
191  } else if (polynomial_int().degree() == 1) {
192  Number a = polynomial_int().coefficients()[1];
193  Number b = polynomial_int().coefficients()[0];
194  interval_int() = Interval<Number>(Number(-b / a));
195  m_content->simplify_to_point();
196  } else {
197  m_content->lower_sign = carl::sgn(carl::evaluate(polynomial_int(), interval_int().lower()));
198  if (interval_int().contains(0)) refine_using(0);
200  }
201  assert(is_consistent());
202  }
203 
206 
209 
212  }
213 
214  bool is_numeric() const {
215  return interval_int().is_point_interval();
216  }
217 
218  const auto& polynomial() const {
219  assert(!is_numeric());
220  return *(m_content->polynomial);
221  }
222  const auto& interval() const {
223  assert(!is_numeric());
224  return m_content->interval;
225  }
226 
227  const auto& value() const {
228  assert(is_numeric());
229  return interval_int().lower();
230  }
231 
232  auto& polynomial_int() const {
233  return *(m_content->polynomial);
234  }
235  auto& interval_int() const {
236  return m_content->interval;
237  }
238 };
239 
240 template<typename Number>
242  return carl::sample(n.interval_int());
243 }
244 
245 template<typename Number>
247  return carl::floor(n.interval_int().upper()) + 1;
248 }
249 template<typename Number>
251  return carl::ceil(n.interval_int().lower()) - 1;
252 }
253 template<typename Number>
255  lower.refine_using(upper.interval_int().lower());
256  upper.refine_using(lower.interval_int().upper());
257  assert(lower.interval_int().upper() <= upper.interval_int().lower());
258  if (lower.is_numeric()) {
259  return sample_between(lower.value(), upper);
260  } else if (upper.is_numeric()) {
261  return sample_between(lower, upper.value());
262  } else {
263  return sample(Interval<Number>(lower.interval_int().upper(), upper.interval_int().lower()), true);
264  }
265 }
266 template<typename Number>
267 Number sample_between(const IntRepRealAlgebraicNumber<Number>& lower, const Number& upper) {
268  lower.refine_using(upper);
269  assert(lower.interval_int().upper() <= upper);
270  assert(lower < upper);
271  while (lower.interval_int().upper() == upper)
272  lower.refine();
273  if (lower.is_numeric()) {
274  return sample_between(lower.value(), upper);
275  } else {
276  return sample(Interval<Number>(lower.interval_int().upper(), BoundType::WEAK, upper, BoundType::STRICT), false);
277  }
278 }
279 template<typename Number>
280 Number sample_between(const Number& lower, const IntRepRealAlgebraicNumber<Number>& upper) {
281  upper.refine_using(lower);
282  assert(lower <= upper.interval_int().lower());
283  assert(lower < upper);
284  while (lower == upper.interval_int().lower())
285  upper.refine();
286  if (upper.is_numeric()) {
287  return sample_between(lower, upper.value());
288  } else {
289  return sample(Interval<Number>(lower, BoundType::STRICT, upper.interval_int().lower(), BoundType::WEAK), false);
290  }
291 }
292 template<typename Number>
294  return carl::floor(n.interval_int().lower());
295 }
296 template<typename Number>
298  return carl::ceil(n.interval_int().upper());
299 }
300 
301 template<typename Number>
303  return carl::is_zero(n.interval_int());
304 }
305 
306 template<typename Number>
308  return n.interval_int().is_point_interval() && carl::is_integer(n.interval_int().lower());
309 }
310 
311 template<typename Number>
313  return carl::floor(n.interval_int().lower());
314 }
315 
316 template<typename Number>
318  assert(!n.interval_int().contains(constant_zero<Number>::get()) || n.interval_int().is_point_interval());
319  if (n.interval_int().is_semi_positive()) {
320  return n;
321  }
322  else {
323  if (n.is_numeric()) {
325  } else {
326  return IntRepRealAlgebraicNumber<Number>(n.polynomial_int().negate_variable(), abs(n.interval_int()));
327  }
328  }
329 }
330 
331 template<typename Number>
333  if (n.is_numeric()) {
334  return carl::bitsize(n.interval_int().lower()) + carl::bitsize(n.interval_int().upper());
335  } else {
336  return carl::bitsize(n.interval_int().lower()) + carl::bitsize(n.interval_int().upper()) + n.polynomial_int().degree();
337  }
338 }
339 
340 template<typename Number>
342  if (n.interval_int().is_point_interval()) return carl::sgn(n.interval_int().lower());
343  assert(!n.interval_int().contains(constant_zero<Number>::get()));
344  if (n.interval_int().is_semi_positive())
345  return Sign::POSITIVE;
346  else {
347  assert(n.interval_int().is_semi_negative());
348  return Sign::NEGATIVE;
349  }
350 }
351 
352 template<typename Number>
355  if (n.polynomial_int() == tmp) return Sign::ZERO;
356  auto seq = carl::sturm_sequence(n.polynomial_int(), derivative(n.polynomial_int()) * tmp);
357  int variations = carl::count_real_roots(seq, n.interval_int());
358  assert((variations == -1) || (variations == 0) || (variations == 1));
359  switch (variations) {
360  case -1:
361  return Sign::NEGATIVE;
362  case 0:
363  return Sign::ZERO;
364  case 1:
365  return Sign::POSITIVE;
366  default:
367  CARL_LOG_ERROR("carl.ran.interval", "Unexpected number of variations, should be -1, 0, 1 but was " << variations);
368  return Sign::ZERO;
369  }
370 }
371 
372 template<typename Number>
374  if (!n.is_numeric() && n.interval_int().contains(i.lower())) {
375  n.refine_internal(i.lower());
376  }
377  if (!n.is_numeric() && n.interval_int().contains(i.upper())) {
378  n.refine_internal(i.upper());
379  }
380  return i.contains(n.interval_int());
381 }
382 
383 template<typename Number>
385  CARL_LOG_DEBUG("carl.ran.interval", "Compare " << lhs << " " << relation << " " << rhs);
386 
387  if (lhs.m_content.get() == rhs.m_content.get()) {
388  CARL_LOG_TRACE("carl.ran.interval", "Contents are equal");
389  return evaluate(Sign::ZERO, relation);
390  }
391 
392  if (lhs.interval_int().is_point_interval() && rhs.interval_int().is_point_interval()) {
393  CARL_LOG_TRACE("carl.ran.interval", "Point interval comparison");
394  return evaluate(lhs.interval_int().lower(), relation, rhs.interval_int().lower());
395  }
396 
398  CARL_LOG_TRACE("carl.ran.interval", "Intervals " << lhs.interval_int() << " and " << rhs.interval_int() << " do intersect");
399  auto intersection = carl::set_intersection(lhs.interval_int(), rhs.interval_int());
400  assert(!intersection.is_empty());
401  lhs.refine_using(intersection.lower());
402  rhs.refine_using(intersection.lower());
403  if (!intersection.is_point_interval()) {
404  lhs.refine_using(intersection.upper());
405  rhs.refine_using(intersection.upper());
406  }
407  }
408  // now: intervals are either equal or disjoint
409  assert(!carl::set_have_intersection(lhs.interval_int(), rhs.interval_int()) || lhs.interval_int() == rhs.interval_int());
410  if (lhs.interval_int() == rhs.interval_int()) {
411  CARL_LOG_TRACE("carl.ran.interval", "Intervals " << lhs.interval_int() << " and " << rhs.interval_int() << " are equal");
412  if (lhs.is_numeric()) {
413  CARL_LOG_TRACE("carl.ran.interval", "Interval " << lhs.interval_int() << " is a point interval");
414  return evaluate(Sign::ZERO, relation);
415  }
416  if (lhs.polynomial_int() == rhs.polynomial_int()) {
417  CARL_LOG_TRACE("carl.ran.interval", "Polynomials " << lhs.polynomial_int() << " and " << rhs.polynomial_int() << " are equal");
418  return evaluate(Sign::ZERO, relation);
419  }
420  auto g = carl::gcd(lhs.polynomial_int(), rhs.polynomial_int());
421  auto lsgn = carl::sgn(carl::evaluate(g, lhs.interval_int().lower()));
422  auto usgn = carl::sgn(carl::evaluate(g, lhs.interval_int().upper()));
423  if (lsgn != usgn) {
424  CARL_LOG_TRACE("carl.ran.interval", "gcd(lhs,rhs) has a zero in the common interval");
425  lhs.set_polynomial(g, lsgn);
426  rhs.set_polynomial(g, lsgn);
427  return evaluate(Sign::ZERO, relation);
428  } else {
429  CARL_LOG_TRACE("carl.ran.interval", "gcd(lhs,rhs) has no zero in the common interval");
430  if (relation == Relation::EQ) return false;
431  if (relation == Relation::NEQ) return true;
432  CARL_LOG_TRACE("carl.ran.interval", "Refine until intervals become disjoint");
433  while (lhs.interval_int() == rhs.interval_int()) {
434  lhs.refine();
435  rhs.refine();
436  }
437  }
438  }
439  // now: intervals are disjoint
440  CARL_LOG_TRACE("carl.ran.interval", "Intervals " << lhs.interval_int() << " and " << rhs.interval_int() << " are disjoint");
442  if (lhs.interval_int().upper() <= rhs.interval_int().lower()) {
443  return relation == Relation::LESS || relation == Relation::LEQ;
444  }
445  if (lhs.interval_int().lower() >= rhs.interval_int().upper()) {
446  return relation == Relation::GREATER || relation == Relation::GEQ;
447  }
448 
449  assert(false);
450  return false;
451 }
452 
453 template<typename Number>
454 bool compare(const IntRepRealAlgebraicNumber<Number>& lhs, const Number& rhs, const Relation relation) {
455  auto res = lhs.refine_using(rhs);
456  if (res) {
457  return evaluate(*res, relation);
458  } else {
459  if (relation == Relation::EQ)
460  return false;
461  else if (relation == Relation::NEQ)
462  return true;
463  else if (relation == Relation::LESS || relation == Relation::LEQ)
464  return lhs.interval_int().upper() <= rhs;
465  else if (relation == Relation::GREATER || relation == Relation::GEQ)
466  return lhs.interval_int().lower() >= rhs;
467  }
468  assert(false);
469  return false;
470 }
471 
472 
473 
474 template<typename Num>
475 std::ostream& operator<<(std::ostream& os, const IntRepRealAlgebraicNumber<Num>& ran) {
476  if (!ran.is_numeric()) {
477  return os << "(IR " << ran.interval() << ", " << ran.polynomial() << ")";
478  } else {
479  return os << "(NR " << ran.value() << ")";
480  }
481 }
482 
483 template<typename Number>
485 
486 template<typename Number>
487 struct is_ran_type<IntRepRealAlgebraicNumber<Number>>: std::true_type {};
488 }
489 
490 namespace std {
491 template<typename Number>
492 struct hash<carl::IntRepRealAlgebraicNumber<Number>> {
494  return carl::hash_all(integer_below(n));
495  }
496 };
497 }
#define CARL_LOG_ERROR(channel, msg)
Definition: carl-logging.h:40
#define CARL_LOG_TRACE(channel, msg)
Definition: carl-logging.h:44
#define CARL_LOG_DEBUG(channel, msg)
Definition: carl-logging.h:43
carl is the main namespace for the library.
MultivariatePolynomial< C, O, P > squareFreePart(const MultivariatePolynomial< C, O, P > &polynomial)
std::vector< UnivariatePolynomial< Coeff > > sturm_sequence(const UnivariatePolynomial< Coeff > &p, const UnivariatePolynomial< Coeff > &q)
Computes the sturm sequence of two polynomials.
Definition: SturmSequence.h:16
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
Interval< Number > ceil(const Interval< Number > &_in)
Method which returns the next larger integer of the passed number or the number itself,...
Definition: Interval.h:1535
Number sample(const Interval< Number > &i, bool includingBounds=true)
Searches for some point in this interval, preferably near the midpoint and with a small representatio...
Definition: Sampling.h:30
Interval< Number > abs(const Interval< Number > &_in)
Method which returns the absolute value of the passed number.
Definition: Interval.h:1511
Interval< Number > floor(const Interval< Number > &_in)
Method which returns the next smaller integer of this number or the number itself,...
Definition: Interval.h:1523
int count_real_roots(const std::vector< UnivariatePolynomial< Coefficient >> &seq, const Interval< Coefficient > &i)
Calculate the number of real roots of a polynomial within a given interval based on a sturm sequence ...
Definition: RootCounting.h:19
const Number & branching_point(const Number &n)
Number sample_above(const Number &n)
std::ostream & operator<<(std::ostream &os, const BasicConstraint< Poly > &c)
Prints the given constraint on the given stream.
cln::cl_I gcd(const cln::cl_I &a, const cln::cl_I &b)
Calculate the greatest common divisor of two integers.
Definition: operations.h:310
signed compare(const BasicConstraint< Pol > &_constraintA, const BasicConstraint< Pol > &_constraintB)
Compares _constraintA with _constraintB.
Definition: Comparison.h:25
Sign
This class represents the sign of a number .
Definition: Sign.h:20
@ NEGATIVE
Indicates that .
@ ZERO
Indicates that .
@ POSITIVE
Indicates that .
bool is_zero(const Interval< Number > &i)
Check if this interval is a point-interval containing 0.
Definition: Interval.h:1453
bool evaluate(const BasicConstraint< Poly > &c, const Assignment< Number > &m)
Definition: Evaluation.h:10
UnivariatePolynomial< Coeff > replace_main_variable(const UnivariatePolynomial< Coeff > &p, Variable newVar)
Replaces the main variable in a polynomial.
Number integer_below(const IntRepRealAlgebraicNumber< Number > &n)
Definition: Ran.h:312
Sign sgn(const Number &n)
Obtain the sign of the given number.
Definition: Sign.h:54
Interval< Number > set_intersection(const Interval< Number > &lhs, const Interval< Number > &rhs)
Intersects two intervals in a set-theoretic manner.
Definition: SetTheory.h:99
Variable fresh_real_variable() noexcept
Definition: VariablePool.h:198
bool contained_in(const IntRepRealAlgebraicNumber< Number > &n, const Interval< Number > &i)
Definition: Ran.h:373
bool set_have_intersection(const Interval< Number > &lhs, const Interval< Number > &rhs)
Definition: SetTheory.h:118
bool is_integer(const Interval< Number > &n)
Definition: Interval.h:1445
@ 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
std::map< Variable, T > Assignment
Definition: Common.h:13
std::size_t hash_all(Args &&... args)
Hashes an arbitrary number of values.
Definition: hash.h:71
Number sample_below(const Number &n)
std::size_t bitsize(const cln::cl_I &n)
Get the bit size of the representation of a integer.
Definition: operations.h:96
Relation
Definition: Relation.h:20
Number sample_between(const Number &lower, const Number &upper)
Represent a polynomial (in)equality against zero.
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
const Number & upper() const
The getter for the upper boundary of the interval.
Definition: Interval.h:849
bool contains(const Number &val) const
Checks if the interval contains the given value.
const Number & lower() const
The getter for the lower boundary of the interval.
Definition: Interval.h:840
This class represents a univariate polynomial with coefficients of an arbitrary type.
The general-purpose multivariate polynomial class.
IntRepRealAlgebraicNumber(const UnivariatePolynomial< Number > &p, const Interval< Number > &i)
Definition: Ran.h:183
auto & interval_int() const
Definition: Ran.h:235
const auto & value() const
Definition: Ran.h:227
std::optional< Sign > refine_using(const Number &pivot) const
Definition: Ran.h:160
void refine_to_integrality() const
Refines until the number is either numeric or the interval does not contain any integer.
Definition: Ran.h:170
friend Num sample_between(const IntRepRealAlgebraicNumber< Num > &lower, const Num &upper)
static const Variable auxVariable
Definition: Ran.h:26
std::shared_ptr< content > m_content
Definition: Ran.h:87
IntRepRealAlgebraicNumber & operator=(const IntRepRealAlgebraicNumber &n)=default
const auto & interval() const
Definition: Ran.h:222
const auto & polynomial() const
Definition: Ran.h:218
friend Num floor(const IntRepRealAlgebraicNumber< Num > &n)
friend bool compare(const IntRepRealAlgebraicNumber< Num > &, const IntRepRealAlgebraicNumber< Num > &, const Relation)
void set_polynomial(const UnivariatePolynomial< Number > &p, Sign lower_sign) const
Definition: Ran.h:119
friend boost::tribool evaluate(const BasicConstraint< Poly > &, const Assignment< IntRepRealAlgebraicNumber< Num >> &, bool, bool)
friend bool compare(const IntRepRealAlgebraicNumber< Num > &, const Num &, const Relation)
friend std::optional< IntRepRealAlgebraicNumber< Num > > evaluate(MultivariatePolynomial< Num >, const Assignment< IntRepRealAlgebraicNumber< Num >> &, bool)
IntRepRealAlgebraicNumber(const IntRepRealAlgebraicNumber &ran)=default
friend Num sample_above(const IntRepRealAlgebraicNumber< Num > &n)
IntRepRealAlgebraicNumber(IntRepRealAlgebraicNumber &&ran)=default
auto & polynomial_int() const
Definition: Ran.h:232
friend Num sample_between(const Num &lower, const IntRepRealAlgebraicNumber< Num > &upper)
friend Num sample_between(const IntRepRealAlgebraicNumber< Num > &lower, const IntRepRealAlgebraicNumber< Num > &upper)
friend Num branching_point(const IntRepRealAlgebraicNumber< Num > &n)
friend Sign sgn(const IntRepRealAlgebraicNumber< Num > &n, const UnivariatePolynomial< Num > &p)
friend Num ceil(const IntRepRealAlgebraicNumber< Num > &n)
IntRepRealAlgebraicNumber & operator=(IntRepRealAlgebraicNumber &&n)=default
bool is_numeric() const
Definition: Ran.h:214
Sign refine_internal(const Number &pivot) const
Returns the sign of "interval_int() - pivot": Returns ZERO if pivot is equal to RAN.
Definition: Ran.h:132
friend Num sample_below(const IntRepRealAlgebraicNumber< Num > &n)
static IntRepRealAlgebraicNumber< Number > create_safe(const UnivariatePolynomial< Number > &p, const Interval< Number > &i)
Definition: Ran.h:210
static UnivariatePolynomial< Number > replace_variable(const UnivariatePolynomial< Number > &p)
Definition: Ran.h:89
bool is_consistent() const
Definition: Ran.h:93
IntRepRealAlgebraicNumber(const Number &n)
Definition: Ran.h:180
Sign lower_sign
Sign of polynomial at interval.lower()
Definition: Ran.h:72
content(UnivariatePolynomial< Number > &&p, const Interval< Number > &i)
Definition: Ran.h:76
Interval< Number > interval
Definition: Ran.h:70
content(const Interval< Number > &i)
Definition: Ran.h:74
content(const UnivariatePolynomial< Number > &p, const Interval< Number > &i)
Definition: Ran.h:78
std::optional< UnivariatePolynomial< Number > > polynomial
Definition: Ran.h:69
std::size_t operator()(const carl::IntRepRealAlgebraicNumber< Number > &n) const
Definition: Ran.h:493