SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
util.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "../CADCellsStatistics.h"
4 
6 
8  return proj.degree(p1) < proj.degree(p2);
9  //return proj.max_degree(p1) < proj.max_degree(p2);
10 }
11 
13  if (rf.is_root()) {
14  return proj.degree(rf.root().poly);
15  } else {
16  std::size_t deg = 0;
17  for (const auto& p : rf.polys()) {
18  auto d = proj.degree(p);
19  if (deg < d) deg = d;
20  }
21  return deg;
22  }
23 }
24 
26  return max_degree(proj, rf1) < max_degree(proj, rf2);
27 }
28 
29 inline std::optional<datastructures::IndexedRoot> simplest_bound(datastructures::Projections& proj, const std::vector<datastructures::TaggedIndexedRoot>& bounds, datastructures::PolyRef origin_filter) {
30  assert(!bounds.empty());
31  std::optional<datastructures::IndexedRoot> simplest;
32  for (auto iter = bounds.begin(); iter != bounds.end(); iter++) {
33  if (!iter->origin || *iter->origin != origin_filter) continue;
34  if (!simplest || compare_simplest(proj,iter->root.poly,simplest->poly)) {
35  simplest = iter->root;
36  }
37  }
38  return simplest;
39 }
40 
41 inline datastructures::IndexedRoot simplest_bound(datastructures::Projections& proj, const std::vector<datastructures::TaggedIndexedRoot>& bounds, bool enable_weak = false) {
42  assert(!bounds.empty());
43  auto simplest = bounds.begin();
44  for (auto iter = bounds.begin(); iter != bounds.end(); iter++) {
45  if (enable_weak && iter->is_inclusive != simplest->is_inclusive) {
46  if (simplest->is_inclusive) {
47  simplest = iter;
48  }
49  } else if (compare_simplest(proj,iter->root.poly,simplest->root.poly)) {
50  simplest = iter;
51  }
52  }
53  return simplest->root;
54 }
55 
57  if (del.is_section()) {
58  #ifdef SMTRAT_DEVOPTION_Statistics
59  auto max_level = proj.polys().context().variable_ordering().size();
60  auto level = del.lower()->second.at(0).root.poly.level;
61  statistics().section_common_zeros(max_level-level, del.lower()->second.size());
62  #endif
63  SMTRAT_STATISTICS_CALL(statistics().got_bound(datastructures::SymbolicInterval(util::simplest_bound(proj, del.lower()->second))));
64  return datastructures::SymbolicInterval(util::simplest_bound(proj, del.lower()->second));
65  } else {
68  if (!del.lower_unbounded()) {
69  assert(enable_weak || del.lower_strict());
70  if (del.lower_strict()) {
71  lower = datastructures::Bound::strict(util::simplest_bound(proj, del.lower()->second, enable_weak));
72  } else {
73  lower = datastructures::Bound::weak(util::simplest_bound(proj, del.lower()->second, enable_weak));
74  }
75  }
76  if (!del.upper_unbounded()) {
77  assert(enable_weak || del.upper_strict());
78  if (del.upper_strict()) {
79  upper = datastructures::Bound::strict(util::simplest_bound(proj, del.upper()->second, enable_weak));
80  } else {
81  upper = datastructures::Bound::weak(util::simplest_bound(proj, del.upper()->second, enable_weak));
82  }
83  }
84  SMTRAT_STATISTICS_CALL(statistics().got_bound(datastructures::SymbolicInterval(lower, upper)));
85  return datastructures::SymbolicInterval(lower, upper);
86  }
87 }
88 
90  // assumes that interval is the simplest cell
91 
92  if (delin.roots().empty()) return;
93 
94  if (!delin_interval.lower_unbounded()) {
95  auto it = delin_interval.lower();
96  bool at_lower = true;
97  while(true) {
98  for (const auto& ir : it->second) {
99  if (ir.root != interval.lower().value()) {
100  if (enable_weak && (interval.lower().is_strict() || (ir.is_inclusive))) {
101  ordering.add_leq(ir.root, interval.lower().value());
102  } else {
103  if (at_lower) {
104  ordering.add_eq(ir.root, interval.lower().value());
105  } else {
106  ordering.add_less(ir.root, interval.lower().value());
107  }
108  }
109  }
110  }
111  at_lower = false;
112  if (it != delin.roots().begin()) it--;
113  else break;
114  }
115  }
116  if (!delin_interval.upper_unbounded()) {
117  auto it = delin_interval.upper();
118  bool at_upper = true;
119  while(it != delin.roots().end()) {
120  for (const auto& ir : it->second) {
121  if (ir.root != interval.upper().value()) {
122  if (enable_weak && (interval.upper().is_strict() || (ir.is_inclusive))) {
123  ordering.add_leq(interval.upper().value(), ir.root);
124  } else {
125  if (at_upper) {
126  ordering.add_eq(interval.upper().value(), ir.root);
127  } else {
128  ordering.add_less(interval.upper().value(), ir.root);
129  }
130  }
131  }
132  }
133  at_upper = false;
134  it++;
135  }
136  }
137 }
138 
140  assert(!enable_weak); // not supported
141 
142  if (delin.roots().empty()) return ;
143 
144  auto it = delin.roots().begin();
145  auto barrier = simplest_bound(proj, it->second);
146  while(it != delin.roots().end()) {
147  auto simplest = simplest_bound(proj, it->second);
148  if (barrier != simplest) {
149  ordering.add_less(barrier, simplest);
150  }
151  for (const auto& ir : it->second) {
152  if (ir.root != simplest) {
153  ordering.add_eq(simplest, ir.root);
154  }
155  }
156  barrier = simplest;
157  it++;
158  }
159 }
160 
161 inline void simplest_ldb_ordering(datastructures::Projections& proj, const datastructures::Delineation& delin, const datastructures::DelineationInterval& delin_interval, const datastructures::SymbolicInterval& interval, datastructures::IndexedRootOrdering& ordering, boost::container::flat_set<datastructures::PolyRef>& equational, bool enable_weak, bool use_global_cache) {
162  // assumes that interval is the simplest cell
163 
164  auto has_resultant = [&proj,&ordering,&use_global_cache](datastructures::PolyRef p, datastructures::PolyRef q) -> bool {
165  assert(p.level == q.level);
166  if (p.id == q.id) return true;
167  if (use_global_cache && proj.know_res(p,q)) return true;
168  return ordering.has_pair(p,q);
169  };
170 
171  const bool section = delin_interval.is_section();
172  while(section) {
173  auto old_size = equational.size();
174 
175  auto it = delin_interval.lower();
176  while(true) {
177  for (auto ir = it->second.begin(); ir != it->second.end(); ir++) {
178  if (ir->root.poly == interval.section_defining().poly) continue;
179  if (equational.contains(ir->root.poly)) continue;
180  if (!util::compare_simplest(proj,ir->root,interval.section_defining())) {
181  equational.insert(ir->root.poly);
182  }
183  }
184  if (it != delin.roots().begin()) it--;
185  else break;
186  }
187 
188  it = delin_interval.upper();
189  while(it != delin.roots().end()) {
190  for (auto ir = it->second.begin(); ir != it->second.end(); ir++) {
191  if (ir->root.poly == interval.section_defining().poly) continue;
192  if (equational.contains(ir->root.poly)) continue;
193  if (!util::compare_simplest(proj,ir->root,interval.section_defining())) {
194  equational.insert(ir->root.poly);
195  }
196  }
197  it++;
198  }
199 
200  if (old_size == equational.size()) {
201  break;
202  }
203  }
204 
205  if (!delin_interval.lower_unbounded()) {
206  std::vector<datastructures::RootFunction> reached;
207  auto it = delin_interval.lower();
208  auto barrier = interval.lower().value();
209  bool barrier_incl = interval.lower().is_weak();
210  reached.push_back(barrier);
211  while(true) {
212  auto old_barrier = barrier;
213  bool old_barrier_incl = barrier_incl;
214  for (auto ir = it->second.begin(); ir != it->second.end(); ir++) {
215  if (section && equational.contains(ir->root.poly)) continue;
216  if (util::compare_simplest(proj,ir->root,barrier) || barrier == ir->root) {
217  if (barrier == ir->root) {
218  barrier_incl = ir->is_inclusive && barrier_incl;
219  }
220  barrier = ir->root;
221  }
222  }
223  assert(it != delin_interval.lower() || barrier == interval.lower().value());
224  if (barrier != old_barrier) {
225  bool rchd = false;
226  for (const auto& r : reached) {
227  if(barrier.is_root() && r.is_root() && has_resultant(barrier.root().poly,r.root().poly)) {
228  if (enable_weak && interval.upper().is_strict()) {
229  ordering.add_leq(barrier, r);
230  } else {
231  ordering.add_less(barrier, r);
232  }
233  rchd = true;
234  }
235  }
236  if (!rchd) {
237  if (enable_weak && (interval.lower().is_strict() || barrier_incl || !old_barrier_incl)) {
238  ordering.add_leq(barrier, old_barrier);
239  } else {
240  ordering.add_less(barrier, old_barrier);
241  }
242  }
243  reached.push_back(barrier);
244  }
245  for (const auto& ir : it->second) {
246  if (section && equational.contains(ir.root.poly)) continue;
247  if (ir.root != barrier) {
248  bool rchd = false;
249  for (const auto& r : reached) {
250  if(r.is_root() && has_resultant(ir.root.poly,r.root().poly)) {
251  if (enable_weak && interval.upper().is_strict()) {
252  ordering.add_leq(ir.root, r);
253  } else {
254  ordering.add_less(ir.root, r);
255  }
256  rchd = true;
257  }
258  }
259  if (!rchd) {
260  if (enable_weak && (interval.lower().is_strict() || ir.is_inclusive || !barrier_incl)) {
261  ordering.add_leq(ir.root, barrier);
262  } else {
263  ordering.add_less(ir.root, barrier);
264  }
265  }
266  reached.push_back(ir.root);
267  }
268  }
269  if (it != delin.roots().begin()) it--;
270  else break;
271  }
272  }
273 
274  if (!delin_interval.upper_unbounded()) {
275  std::vector<datastructures::RootFunction> reached;
276  auto it = delin_interval.upper();
277  auto barrier = interval.upper().value();
278  bool barrier_incl = interval.upper().is_weak();
279  reached.push_back(barrier);
280  while(it != delin.roots().end()) {
281  auto old_barrier = barrier;
282  bool old_barrier_incl = barrier_incl;
283  for (auto ir = it->second.begin(); ir != it->second.end(); ir++) {
284  if (section && equational.contains(ir->root.poly)) continue;
285  if (util::compare_simplest(proj,ir->root,barrier) || barrier == ir->root) {
286  if (barrier == ir->root) {
287  barrier_incl = ir->is_inclusive && barrier_incl;
288  }
289  barrier = ir->root;
290  }
291  }
292  assert(it != delin_interval.upper() || barrier == interval.upper().value());
293  if (barrier != old_barrier) {
294  bool rchd = false;
295  for (const auto& r : reached) {
296  if(barrier.is_root() && r.is_root() && has_resultant(barrier.root().poly,r.root().poly)) {
297  if (enable_weak && interval.upper().is_strict()) {
298  ordering.add_leq(r, barrier);
299  } else {
300  ordering.add_less(r, barrier);
301  }
302  rchd = true;
303  }
304  }
305  if (!rchd) {
306  if (enable_weak && (interval.upper().is_strict() || barrier_incl || !old_barrier_incl)) {
307  ordering.add_leq(old_barrier, barrier);
308  } else {
309  ordering.add_less(old_barrier, barrier);
310  }
311  }
312  reached.push_back(barrier);
313  }
314  for (const auto& ir : it->second) {
315  if (section && equational.contains(ir.root.poly)) continue;
316  if (ir.root != barrier) {
317  bool rchd = false;
318  for (const auto& r : reached) {
319  if(r.is_root() && has_resultant(ir.root.poly,r.root().poly)) {
320  if (enable_weak && interval.upper().is_strict()) {
321  ordering.add_leq(r, ir.root);
322  } else {
323  ordering.add_less(r, ir.root);
324  }
325  rchd = true;
326  }
327  }
328  if (!rchd) {
329  if (enable_weak && (interval.upper().is_strict() || ir.is_inclusive || !barrier_incl)) {
330  ordering.add_leq(barrier, ir.root);
331  } else {
332  ordering.add_less(barrier, ir.root);
333  }
334  }
335  reached.push_back(ir.root);
336  }
337  }
338  it++;
339  }
340  }
341 }
342 
343 /// Polynomial decomposition
344 
346  boost::container::flat_set<std::size_t> delineated_roots;
347  std::size_t critical_lower_root = 0;
348  std::size_t critical_upper_root = 0;
349 };
350 
352  boost::container::flat_map<datastructures::PolyRef,PolyDelineation> data;
353  inline auto& get(const datastructures::PolyRef& poly) {
354  if (data.find(poly) == data.end()) {
355  data.emplace(poly, PolyDelineation());
356  }
357  return data[poly];
358  }
359 };
360 
361 inline void decompose(datastructures::Delineation& delin, const datastructures::DelineationInterval& delin_interval, PolyDelineations& poly_delins) {
362  if (!delin_interval.lower_unbounded()) {
363  boost::container::flat_set<datastructures::PolyRef> seen;
364  auto it = delin_interval.lower();
365  while(true) {
366  for (const auto& ir : it->second) {
367  assert(!ir.origin && !ir.is_optional);
368  poly_delins.get(ir.root.poly).delineated_roots.insert(ir.root.index);
369  if (!seen.contains(ir.root.poly)) {
370  poly_delins.get(ir.root.poly).critical_lower_root = ir.root.index;
371  seen.insert(ir.root.poly);
372  } else {
373  delin.remove_root(it->first,ir);
374  }
375  }
376  if (it != delin.roots().begin()) it--;
377  else break;
378  }
379  }
380  if (!delin_interval.upper_unbounded()) {
381  boost::container::flat_set<datastructures::PolyRef> seen;
382  auto it = delin_interval.upper();
383  while(it != delin.roots().end()) {
384  for (const auto& ir : it->second) {
385  assert(!ir.origin && !ir.is_optional);
386  poly_delins.get(ir.root.poly).delineated_roots.insert(ir.root.index);
387  if (!seen.contains(ir.root.poly)) {
388  poly_delins.get(ir.root.poly).critical_upper_root = ir.root.index;
389  seen.insert(ir.root.poly);
390  } else {
391  delin.remove_root(it->first,ir);
392  }
393  }
394  it++;
395  }
396  }
397 }
398 
399 inline void chain_ordering(const datastructures::PolyRef poly, const PolyDelineation& poly_delin, datastructures::IndexedRootOrdering& ordering) {
400  //assert(poly_delin.critical_lower_root == 0 && poly_delin.critical_upper_root == 0);
401  for (auto it = poly_delin.delineated_roots.begin(); it != poly_delin.delineated_roots.end() && it != std::prev(poly_delin.delineated_roots.end()); it++) {
402  ordering.add_less(datastructures::IndexedRoot(poly,*it),datastructures::IndexedRoot(poly,*(it+1)));
403  }
404 }
405 
407  if (poly_delin.critical_lower_root != 0) {
408  for (auto it = poly_delin.delineated_roots.begin(); *it != poly_delin.critical_lower_root; it++) {
410  }
411  }
412  if (poly_delin.critical_upper_root != 0) {
413  for (auto it = poly_delin.delineated_roots.rbegin(); *it != poly_delin.critical_upper_root; it++) {
415  }
416  }
417 }
418 
419 /// Local delineability
420 
422  boost::container::flat_set<datastructures::PolyRef> polys;
423  for (auto it = delin.roots().begin(); it != delin.roots().end(); it++) {
424  for (const auto& t_root : it->second) {
425  if (t_root.origin) {
426  polys.insert(*t_root.origin);
427  }
428  }
429  }
430  return polys;
431 }
432 
434  for (auto it = delin.roots().begin(); it != delin.roots().end(); it++) {
435  for (const auto& t_root : it->second) {
436  if (t_root.origin && *t_root.origin == poly) {
437  if (!t_root.is_optional) {
438  return false;
439  }
440  }
441  }
442  }
443  return true;
444 }
445 
447  // Choose l and l' - the range of optional roots that may be inside the cell.
448  // We choose it as large as possible.
449  std::optional<datastructures::RootMap::const_iterator> ri_begin;
450  std::optional<datastructures::RootMap::const_iterator> ri_end;
451  for (auto it = delin.roots().begin(); it != delin.roots().end(); it++) {
452  bool only_optional_roots = true;
453  bool has_root = false;
454  for (const auto& t_root : it->second) {
455  if (t_root.origin && *t_root.origin == poly) {
456  has_root = true;
457  if (!t_root.is_optional) {
458  only_optional_roots = false;
459  break;
460  }
461  }
462  }
463  if (has_root) {
464  if (only_optional_roots) {
465  if (!ri_begin) ri_begin = it;
466  ri_end = std::next(it);
467  } else if (it->first > sample) {
468  break;
469  } else {
470  ri_begin = std::nullopt;
471  ri_end = std::nullopt;
472  }
473 
474  }
475  }
476  assert((bool)ri_begin == (bool)ri_end);
477 
478  // Maybe-inside-roots: Add pairs to the ordering, remove them from the delineation.
481  if (ri_begin && ri_end) {
482  // assert(((*ri_begin) == delin.roots().begin() || std::prev(*ri_begin)->first < sample) && ((*ri_end) == delin.roots().end() || sample < (*ri_end)->first)); // this assertion is faulty
484  for (auto it = *ri_begin; it != *ri_end; it++) {
485  if (it->second.empty()) continue;
486  auto simplest = simplest_bound(proj, it->second, poly);
487  if (simplest) {
488  if (ri_first == datastructures::IndexedRoot()) ri_first = *simplest;
489  ri_last = *simplest;
490  for (const auto& t_root : it->second) {
491  assert(!(t_root.origin && *t_root.origin == poly) || t_root.is_optional);
492  if (*t_root.origin == poly && t_root.root != *simplest) {
493  ordering.add_eq(*simplest, t_root.root);
494  }
495  }
496  if (prev != datastructures::IndexedRoot()) {
497  ordering.add_less(prev, *simplest);
498  }
499  prev = *simplest;
500  delin.remove_roots_with_origin(it->first, poly);
501  }
502  }
503  }
504 
505  // Connect ri_first
506  bool p_at_lower = false;
507  if (ri_first != datastructures::IndexedRoot()) {
508  assert(*ri_begin != *ri_end);
509  bool use_interval_bound = false;
510  if (!interval.lower().is_infty()) {
511  auto lower = proj.evaluate(ass, interval.lower().value()).first;
512  if (lower <= (*ri_begin)->first) {
513  if (!interval.lower().value().is_root()) {
514  use_interval_bound = false;
515  } else { // if there is a root with higher degree below, we take the interval bound
516  auto bound_deg = proj.total_degree(interval.lower().value().root().poly);
517  if (*ri_begin != delin.roots().begin()) {
518  auto it = std::prev(*ri_begin);
519  while (!use_interval_bound) {
520  for (const auto& t_root : it->second) {
521  if (*t_root.origin == poly) {
522  if (proj.total_degree(t_root.root.poly) > bound_deg) {
523  use_interval_bound = true;
524  break;
525  }
526  }
527  }
528  if (it == delin.roots().begin()) break;
529  it--;
530  }
531  }
532  }
533  } else { // some roots are outside, thus we cannot use the interval bound
534  use_interval_bound = false;
535  }
536  }
537  if (!use_interval_bound) { // Connect ri_first with all roots below
538  if (*ri_begin != delin.roots().begin()) {
539  auto it = std::prev(*ri_begin);
540  while (true) {
541  for (const auto& t_root : it->second) {
542  if (*t_root.origin == poly) {
543  ordering.add_less(t_root.root, ri_first);
544  }
545  }
546  if (it == delin.roots().begin()) break;
547  it--;
548  }
549  }
550  } else { // Connect ri_first with interval.lower().value()
551  if ((*ri_begin)->first == proj.evaluate(ass, interval.lower().value()).first) {
552  ordering.add_eq(interval.lower().value(), ri_first);
553  p_at_lower = true;
554  } else {
555  ordering.add_less(interval.lower().value(), ri_first);
556  }
557  }
558  }
559 
560  // Connect for ri_last
561  bool p_at_upper = false;
562  if (ri_last != datastructures::IndexedRoot()) {
563  assert(*ri_begin != *ri_end);
564  bool use_interval_bound = false;
565  if (!interval.upper().is_infty()) {
566  auto upper = proj.evaluate(ass, interval.upper().value()).first;
567  if (upper >= std::prev(*ri_end)->first) {
568  if (!interval.upper().value().is_root()) {
569  use_interval_bound = false;
570  } else { // if there is a root with higher degree below, we take the interval bound
571  auto bound_deg = proj.total_degree(interval.upper().value().root().poly);
572  for (auto it = *ri_end; it != delin.roots().end() && use_interval_bound; it++) {
573  for (const auto& t_root : it->second) {
574  if (*t_root.origin == poly) {
575  if (proj.total_degree(t_root.root.poly) > bound_deg) {
576  use_interval_bound = true;
577  break;
578  }
579  }
580  }
581  }
582  }
583  } else { // some roots are outside, thus we cannot use the interval bound
584  use_interval_bound = false;
585  }
586  }
587  if (!use_interval_bound) { // Connect ri_last with all roots above
588  for (auto it = *ri_end; it != delin.roots().end(); it++) {
589  for (const auto& t_root : it->second) {
590  if (*t_root.origin == poly) {
591  ordering.add_less(ri_last, t_root.root);
592  }
593  }
594  }
595  } else { // Connect ri_first with interval.lower().value()
596  if (std::prev(*ri_end)->first == proj.evaluate(ass, interval.upper().value()).first) {
597  ordering.add_eq(ri_last, interval.lower().value());
598  p_at_upper = true;
599  } else {
600  ordering.add_less(ri_last, interval.lower().value());
601  }
602  }
603  }
604 
605  // Always-outside-roots: We make them non-optional, so they are considered in the further heuristic.
606  for (auto it = delin.roots().begin(); it != delin.roots().end(); it++) {
607  for (auto t_root : it->second) {
608  if (t_root.origin && *t_root.origin == poly) {
609  t_root.origin = std::nullopt;
610  t_root.is_optional = false;
611  t_root.is_inclusive = t_root.is_inclusive && ((!(it->first <= sample) || !p_at_lower) && (!(it->first >= sample) || !p_at_upper));
612  delin.add_root(it->first, t_root);
613  }
614  }
615  delin.remove_roots_with_origin(it->first, poly);
616  }
617 }
618 
620  for (auto it = delin.roots().begin(); it != delin.roots().end(); it++) {
621  for (auto t_root : it->second) {
622  assert(t_root.origin || !t_root.is_optional);
623  if (t_root.origin && *t_root.origin == poly) {
624  t_root.origin = std::nullopt;
625  t_root.is_optional = false;
626  t_root.is_inclusive = false;
627  delin.add_root(it->first, t_root);
628  }
629  }
630  delin.remove_roots_with_origin(it->first, poly);
631  }
632 }
633 
634 }
Bound type of a SymbolicInterval.
Definition: roots.h:205
static Bound strict(RootFunction value)
Definition: roots.h:215
static Bound weak(RootFunction value)
Definition: roots.h:218
Represents the delineation of a set of polynomials (at a sample), that is.
Definition: delineation.h:118
void remove_roots_with_origin(RAN root, PolyRef origin, bool only_optional=false)
Definition: delineation.h:226
void remove_root(RAN root, TaggedIndexedRoot tagged_root)
Definition: delineation.h:220
void add_root(RAN root, TaggedIndexedRoot tagged_root)
Definition: delineation.h:206
const auto & roots() const
Returns the underlying root map, which is a set of real algebraic numbers to indexed root expressions...
Definition: delineation.h:132
Describes an ordering of IndexedRoots.
Definition: roots.h:400
void add_eq(RootFunction first, RootFunction second)
Definition: roots.h:449
void add_leq(RootFunction first, RootFunction second)
Definition: roots.h:420
void add_less(RootFunction first, RootFunction second)
Definition: roots.h:435
bool has_pair(const PolyRef p1, const PolyRef p2) const
Definition: roots.h:578
Encapsulates all computations on polynomials.
Definition: projections.h:46
std::size_t degree(PolyRef p) const
Definition: projections.h:403
RAN evaluate(const Assignment &sample, IndexedRoot r)
Definition: projections.h:429
bool know_res(PolyRef p, PolyRef q) const
Definition: projections.h:192
void polys(boost::container::flat_set< PolyRef > &result) const
Definition: roots.h:126
const IndexedRoot & root() const
Definition: roots.h:117
A symbolic interal whose bounds are defined by indexed root expressions.
Definition: roots.h:250
const auto & lower() const
Return the lower bound.
Definition: roots.h:285
const auto & upper() const
Returns the upper bound.
Definition: roots.h:292
const IndexedRoot & section_defining() const
In case of a section, the defining indexed root is returned.
Definition: roots.h:277
void chain_ordering(const datastructures::PolyRef poly, const PolyDelineation &poly_delin, datastructures::IndexedRootOrdering &ordering)
Definition: util.h:399
void simplest_chain_ordering(datastructures::Projections &proj, const datastructures::Delineation &delin, datastructures::IndexedRootOrdering &ordering, bool enable_weak=false)
Definition: util.h:139
void simplify(const datastructures::PolyRef poly, datastructures::Delineation &delin)
Definition: util.h:619
bool max_degree(datastructures::Projections &proj, datastructures::RootFunction rf)
Definition: util.h:12
bool compare_simplest(datastructures::Projections &proj, datastructures::PolyRef p1, datastructures::PolyRef p2)
Definition: util.h:7
datastructures::SymbolicInterval compute_simplest_cell(datastructures::Projections &proj, const datastructures::DelineationInterval &del, bool enable_weak=false)
Definition: util.h:56
void simplest_biggest_cell_ordering(datastructures::Projections &, const datastructures::Delineation &delin, const datastructures::DelineationInterval &delin_interval, const datastructures::SymbolicInterval &interval, datastructures::IndexedRootOrdering &ordering, bool enable_weak=false)
Definition: util.h:89
void simplest_ldb_ordering(datastructures::Projections &proj, const datastructures::Delineation &delin, const datastructures::DelineationInterval &delin_interval, const datastructures::SymbolicInterval &interval, datastructures::IndexedRootOrdering &ordering, boost::container::flat_set< datastructures::PolyRef > &equational, bool enable_weak, bool use_global_cache)
Definition: util.h:161
auto get_local_del_polys(const datastructures::Delineation &delin)
Local delineability.
Definition: util.h:421
void local_del_ordering(datastructures::Projections &proj, const datastructures::PolyRef poly, const cadcells::Assignment &ass, const cadcells::RAN &sample, datastructures::Delineation &delin, const datastructures::SymbolicInterval &interval, datastructures::IndexedRootOrdering &ordering)
Definition: util.h:446
void biggest_cell_ordering(const datastructures::PolyRef poly, const PolyDelineation &poly_delin, datastructures::IndexedRootOrdering &ordering)
Definition: util.h:406
bool local_del_poly_independent(const datastructures::Delineation &delin, const datastructures::PolyRef &poly)
Definition: util.h:433
std::optional< datastructures::IndexedRoot > simplest_bound(datastructures::Projections &proj, const std::vector< datastructures::TaggedIndexedRoot > &bounds, datastructures::PolyRef origin_filter)
Definition: util.h:29
void decompose(datastructures::Delineation &delin, const datastructures::DelineationInterval &delin_interval, PolyDelineations &poly_delins)
Definition: util.h:361
Polynomial::RootType RAN
Definition: common.h:24
carl::Assignment< RAN > Assignment
Definition: common.h:25
auto max_level(cadcells::datastructures::Projections &, const boost::container::flat_set< cadcells::datastructures::PolyConstraint > &a)
#define SMTRAT_STATISTICS_CALL(function)
Definition: Statistics.h:23
Represents the i-th root of a multivariate polynomial at its main variable (given an appropriate samp...
Definition: roots.h:15
PolyRef poly
A multivariate polynomial.
Definition: roots.h:17
boost::container::flat_set< std::size_t > delineated_roots
Definition: util.h:346
auto & get(const datastructures::PolyRef &poly)
Definition: util.h:353
boost::container::flat_map< datastructures::PolyRef, PolyDelineation > data
Definition: util.h:352