3 #include "../CADCellsStatistics.h"
17 for (
const auto& p : rf.
polys()) {
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;
35 simplest = iter->root;
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) {
53 return simplest->root;
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());
92 if (delin.
roots().empty())
return;
95 auto it = delin_interval.
lower();
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))) {
104 ordering.
add_eq(ir.root, interval.
lower().value());
112 if (it != delin.
roots().begin()) it--;
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))) {
126 ordering.
add_eq(interval.
upper().value(), ir.root);
140 assert(!enable_weak);
142 if (delin.
roots().empty()) return ;
144 auto it = delin.
roots().begin();
146 while(it != delin.
roots().end()) {
148 if (barrier != simplest) {
149 ordering.
add_less(barrier, simplest);
151 for (
const auto& ir : it->second) {
152 if (ir.root != simplest) {
153 ordering.
add_eq(simplest, ir.root);
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;
171 const bool section = delin_interval.
is_section();
173 auto old_size = equational.size();
175 auto it = delin_interval.
lower();
177 for (
auto ir = it->second.begin(); ir != it->second.end(); ir++) {
179 if (equational.contains(ir->root.poly))
continue;
181 equational.insert(ir->root.poly);
184 if (it != delin.
roots().begin()) it--;
188 it = delin_interval.
upper();
189 while(it != delin.
roots().end()) {
190 for (
auto ir = it->second.begin(); ir != it->second.end(); ir++) {
192 if (equational.contains(ir->root.poly))
continue;
194 equational.insert(ir->root.poly);
200 if (old_size == equational.size()) {
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);
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;
217 if (barrier == ir->root) {
218 barrier_incl = ir->is_inclusive && barrier_incl;
223 assert(it != delin_interval.
lower() || barrier == interval.
lower().value());
224 if (barrier != old_barrier) {
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()) {
237 if (enable_weak && (interval.
lower().is_strict() || barrier_incl || !old_barrier_incl)) {
238 ordering.
add_leq(barrier, old_barrier);
240 ordering.
add_less(barrier, old_barrier);
243 reached.push_back(barrier);
245 for (
const auto& ir : it->second) {
246 if (section && equational.contains(ir.root.poly))
continue;
247 if (ir.root != barrier) {
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()) {
260 if (enable_weak && (interval.
lower().is_strict() || ir.is_inclusive || !barrier_incl)) {
261 ordering.
add_leq(ir.root, barrier);
263 ordering.
add_less(ir.root, barrier);
266 reached.push_back(ir.root);
269 if (it != delin.
roots().begin()) it--;
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;
286 if (barrier == ir->root) {
287 barrier_incl = ir->is_inclusive && barrier_incl;
292 assert(it != delin_interval.
upper() || barrier == interval.
upper().value());
293 if (barrier != old_barrier) {
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()) {
306 if (enable_weak && (interval.
upper().is_strict() || barrier_incl || !old_barrier_incl)) {
307 ordering.
add_leq(old_barrier, barrier);
309 ordering.
add_less(old_barrier, barrier);
312 reached.push_back(barrier);
314 for (
const auto& ir : it->second) {
315 if (section && equational.contains(ir.root.poly))
continue;
316 if (ir.root != barrier) {
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()) {
329 if (enable_weak && (interval.
upper().is_strict() || ir.is_inclusive || !barrier_incl)) {
330 ordering.
add_leq(barrier, ir.root);
332 ordering.
add_less(barrier, ir.root);
335 reached.push_back(ir.root);
352 boost::container::flat_map<datastructures::PolyRef,PolyDelineation>
data;
354 if (
data.find(poly) ==
data.end()) {
363 boost::container::flat_set<datastructures::PolyRef> seen;
364 auto it = delin_interval.
lower();
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);
376 if (it != delin.
roots().begin()) it--;
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);
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) {
426 polys.insert(*t_root.origin);
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) {
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) {
457 if (!t_root.is_optional) {
458 only_optional_roots =
false;
464 if (only_optional_roots) {
465 if (!ri_begin) ri_begin = it;
466 ri_end = std::next(it);
467 }
else if (it->first > sample) {
470 ri_begin = std::nullopt;
471 ri_end = std::nullopt;
476 assert((
bool)ri_begin == (
bool)ri_end);
481 if (ri_begin && ri_end) {
484 for (
auto it = *ri_begin; it != *ri_end; it++) {
485 if (it->second.empty())
continue;
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);
506 bool p_at_lower =
false;
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;
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) {
523 use_interval_bound =
true;
528 if (it == delin.
roots().begin())
break;
534 use_interval_bound =
false;
537 if (!use_interval_bound) {
538 if (*ri_begin != delin.
roots().begin()) {
539 auto it = std::prev(*ri_begin);
541 for (
const auto& t_root : it->second) {
542 if (*t_root.origin == poly) {
543 ordering.
add_less(t_root.root, ri_first);
546 if (it == delin.
roots().begin())
break;
551 if ((*ri_begin)->first == proj.
evaluate(ass, interval.
lower().value()).first) {
552 ordering.
add_eq(interval.
lower().value(), ri_first);
561 bool p_at_upper =
false;
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;
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) {
576 use_interval_bound =
true;
584 use_interval_bound =
false;
587 if (!use_interval_bound) {
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);
596 if (std::prev(*ri_end)->first == proj.
evaluate(ass, interval.
upper().value()).first) {
597 ordering.
add_eq(ri_last, interval.
lower().value());
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));
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;
Bound type of a SymbolicInterval.
static Bound strict(RootFunction value)
static Bound weak(RootFunction value)
An interval of a delineation.
bool upper_strict() const
bool lower_unbounded() const
bool lower_strict() const
bool upper_unbounded() const
const auto & upper() const
const auto & lower() const
Represents the delineation of a set of polynomials (at a sample), that is.
void remove_roots_with_origin(RAN root, PolyRef origin, bool only_optional=false)
void remove_root(RAN root, TaggedIndexedRoot tagged_root)
void add_root(RAN root, TaggedIndexedRoot tagged_root)
const auto & roots() const
Returns the underlying root map, which is a set of real algebraic numbers to indexed root expressions...
Describes an ordering of IndexedRoots.
void add_eq(RootFunction first, RootFunction second)
void add_leq(RootFunction first, RootFunction second)
void add_less(RootFunction first, RootFunction second)
bool has_pair(const PolyRef p1, const PolyRef p2) const
Encapsulates all computations on polynomials.
std::size_t degree(PolyRef p) const
RAN evaluate(const Assignment &sample, IndexedRoot r)
bool know_res(PolyRef p, PolyRef q) const
std::size_t total_degree(PolyRef p)
void polys(boost::container::flat_set< PolyRef > &result) const
const IndexedRoot & root() const
A symbolic interal whose bounds are defined by indexed root expressions.
const auto & lower() const
Return the lower bound.
const auto & upper() const
Returns the upper bound.
const IndexedRoot & section_defining() const
In case of a section, the defining indexed root is returned.
void chain_ordering(const datastructures::PolyRef poly, const PolyDelineation &poly_delin, datastructures::IndexedRootOrdering &ordering)
void simplest_chain_ordering(datastructures::Projections &proj, const datastructures::Delineation &delin, datastructures::IndexedRootOrdering &ordering, bool enable_weak=false)
void simplify(const datastructures::PolyRef poly, datastructures::Delineation &delin)
bool max_degree(datastructures::Projections &proj, datastructures::RootFunction rf)
bool compare_simplest(datastructures::Projections &proj, datastructures::PolyRef p1, datastructures::PolyRef p2)
datastructures::SymbolicInterval compute_simplest_cell(datastructures::Projections &proj, const datastructures::DelineationInterval &del, bool enable_weak=false)
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)
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)
auto get_local_del_polys(const datastructures::Delineation &delin)
Local delineability.
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)
void biggest_cell_ordering(const datastructures::PolyRef poly, const PolyDelineation &poly_delin, datastructures::IndexedRootOrdering &ordering)
bool local_del_poly_independent(const datastructures::Delineation &delin, const datastructures::PolyRef &poly)
std::optional< datastructures::IndexedRoot > simplest_bound(datastructures::Projections &proj, const std::vector< datastructures::TaggedIndexedRoot > &bounds, datastructures::PolyRef origin_filter)
void decompose(datastructures::Delineation &delin, const datastructures::DelineationInterval &delin_interval, PolyDelineations &poly_delins)
carl::Assignment< RAN > Assignment
#define SMTRAT_STATISTICS_CALL(function)
Represents the i-th root of a multivariate polynomial at its main variable (given an appropriate samp...
PolyRef poly
A multivariate polynomial.
Polynomial decomposition.
boost::container::flat_set< std::size_t > delineated_roots
std::size_t critical_upper_root
std::size_t critical_lower_root
auto & get(const datastructures::PolyRef &poly)
boost::container::flat_map< datastructures::PolyRef, PolyDelineation > data