SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
rules_filter_util.h
Go to the documentation of this file.
1 #pragma once
2 
4 
5 inline std::optional<carl::Interval<RAN>> delineable_interval(datastructures::Projections& proj, const Assignment& sample, const boost::container::flat_set<datastructures::PolyRef>& polys) {
7 
8  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "delineable_interval start");
9  auto subderiv = datastructures::make_derivation<PropertiesSet>(proj, sample, sample.size()).sampled_ref();
10  for (const auto& poly : polys) {
11  subderiv->insert(properties::poly_del{ poly });
12  assert(properties::poly_del{ poly }.level() <= subderiv->level());
13  }
14  for(const auto& prop : subderiv->template properties<properties::poly_del>()) {
15  if (!rules::poly_del(*subderiv, prop.poly)) return std::nullopt;
16  }
17  for(const auto& prop : subderiv->template properties<properties::poly_ord_inv>()) {
18  rules::poly_ord_inv(*subderiv, prop.poly);
19  }
20  for(const auto& prop : subderiv->template properties<properties::poly_sgn_inv>()) {
21  rules::poly_sgn_inv(*subderiv, prop.poly);
22  }
23  for(const auto& prop : subderiv->template properties<properties::poly_irreducible_sgn_inv>()) {
24  rules::delineate(*subderiv->delineated(), prop);
25  }
26  subderiv->delineate_cell();
27  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "delineable_interval end; got " << subderiv->cell());
28 
29  if (subderiv->cell().is_section()) {
30  return carl::Interval<RAN>(subderiv->cell().lower()->first);
31  } else {
32  return carl::Interval<RAN>(subderiv->cell().lower_unbounded() ? RAN(0) : subderiv->cell().lower()->first, subderiv->cell().lower_unbounded() ? carl::BoundType::INFTY : carl::BoundType::STRICT, subderiv->cell().upper_unbounded() ? RAN(0) : subderiv->cell().upper()->first, subderiv->cell().upper_unbounded() ? carl::BoundType::INFTY : carl::BoundType::STRICT);
33  }
34 }
35 
36 template<typename P>
37 inline void delineable_interval_roots(datastructures::SampledDerivation<P>& deriv, const boost::container::flat_set<datastructures::PolyRef>& polys, const datastructures::PolyRef resultant) {
38  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "delineable_interval_roots start");
39  auto subderiv = datastructures::make_derivation<P>(deriv.proj(), deriv.sample(), deriv.level()).sampled_ref();
40  for (const auto& poly : polys) {
41  subderiv->insert(properties::poly_del{ poly });
42  assert(properties::poly_del{ poly }.level() <= subderiv->level());
43  }
44  for(const auto& prop : subderiv->template properties<properties::poly_del>()) {
45  if (!rules::poly_del(*subderiv, prop.poly)) {
46  assert(false);
47  return;
48  }
49  }
50  for(const auto& prop : subderiv->template properties<properties::poly_ord_inv>()) {
51  rules::poly_ord_inv(*subderiv, prop.poly);
52  }
53  for(const auto& prop : subderiv->template properties<properties::poly_sgn_inv>()) {
54  rules::poly_sgn_inv(*subderiv, prop.poly);
55  }
56  for(const auto& prop : subderiv->template properties<properties::poly_irreducible_sgn_inv>()) {
57  rules::delineate(*subderiv->delineated(), prop);
58  }
59  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "delineable_interval_roots end; got " << subderiv->delin());
60 
61  for (const auto& [k,v] : subderiv->delin().roots()) {
62  for (auto ir : v) {
63  assert(!ir.is_optional);
64  assert(!ir.is_inclusive);
65  assert(!ir.origin);
66  ir.origin = resultant;
67  deriv.delin().add_root(k, ir);
68  }
69  }
70 }
71 
72 enum class result {
74 };
75 
76 template<typename P>
77 inline void filter_roots(datastructures::DelineatedDerivation<P>& deriv, const datastructures::PolyRef poly, std::function<result(const RAN&)> filter_condition) {
78  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "filter_roots " << poly);
80  if (deriv.proj().is_const(poly)) return;
81  for (const auto& factor : deriv.proj().factors_nonconst(poly)) {
82  if (factor.level == deriv.level()) {
83  if (deriv.proj().is_nullified(deriv.underlying_sample(), factor)) {
84  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "-> nullified: " << factor);
85  deriv.delin().add_poly_nullified(factor);
86  } else {
87  auto roots = deriv.proj().real_roots(deriv.underlying_sample(), factor);
88  if (roots.empty()) {
89  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "-> nonzero: " << factor);
90  deriv.delin().add_poly_nonzero(factor);
91  } else {
92  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "-> got roots: " << roots);
93  for (size_t idx = 0; idx < roots.size(); idx++) {
94  root_map.try_emplace(roots[idx]).first->second.push_back(datastructures::IndexedRoot(factor, idx+1));
95  }
96  }
97  }
98  }
99  }
100  SMTRAT_STATISTICS_CALL(statistics().filter_roots_start(poly.level, deriv.proj().factors_nonconst(poly).size(), root_map.size(), deriv.underlying_sample()));
101  for (const auto& entry : root_map) {
102  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "considering root " << entry);
103  SMTRAT_STATISTICS_CALL(statistics().filter_roots_filter_start(entry.first));
104  switch (filter_condition(entry.first)) {
105  case result::NORMAL:
106  for (const auto& ir : entry.second) {
107  deriv.delin().add_root(entry.first, datastructures::TaggedIndexedRoot { ir, false, false, poly });
108  SMTRAT_STATISTICS_CALL(statistics().filter_roots_got_normal(entry.first));
109  }
110  break;
111  case result::INCLUSIVE:
112  for (const auto& ir : entry.second) {
113  deriv.delin().add_root(entry.first, datastructures::TaggedIndexedRoot { ir, true, false, poly });
114  SMTRAT_STATISTICS_CALL(statistics().filter_roots_got_inclusive(entry.first));
115  }
116  break;
118  for (const auto& ir : entry.second) {
119  deriv.delin().add_root(entry.first, datastructures::TaggedIndexedRoot { ir, false, true, poly });
120  SMTRAT_STATISTICS_CALL(statistics().filter_roots_got_optional(entry.first));
121  }
122  break;
124  for (const auto& ir : entry.second) {
125  deriv.delin().add_root(entry.first, datastructures::TaggedIndexedRoot { ir, true, true, poly });
126  SMTRAT_STATISTICS_CALL(statistics().filter_roots_got_inclusive_optional(entry.first));
127  }
128  break;
129  case result::OMIT:
130  break;
131  default:
132  assert(false);
133  }
134  SMTRAT_STATISTICS_CALL(statistics().filter_roots_filter_end());
135  }
136  SMTRAT_STATISTICS_CALL(statistics().filter_roots_end());
137  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "filter_roots end");
138 }
139 
140 template<typename P>
141 inline auto projection_root(const datastructures::DelineatedDerivation<P>& deriv, const RAN& root) {
142  Assignment ass = deriv.underlying_sample();
143  ass.emplace(deriv.main_var(), root);
144  return ass;
145 }
146 
147 inline bool has_intersection(const RAN& root1, const RAN& root2) {
148  SMTRAT_LOG_FUNC("smtrat.cadcells.operators.rules", root1 << ", " << root2);
149 
150  if (root1.is_numeric() && root1 == root2) return true;
151  auto intersection = carl::set_intersection(root1.interval(), root2.interval());
152  if (intersection.is_empty()) return false;
153  if (root1 < intersection.lower() || root1 > intersection.upper()) return false;
154  if (root1.is_numeric() && root1 == root2) return true;
155  intersection = carl::set_intersection(root1.interval(), root2.interval());
156  if (intersection.is_empty()) return false;
157  if (root2 < intersection.lower() || root2 > intersection.upper()) return false;
158  if (root1.is_numeric() && root1 == root2) return true;
159  intersection = carl::set_intersection(root1.interval(), root2.interval());
160  if (intersection.is_empty()) return false;
161  return true;
162 
163  // We do not have access to libpoly's refine_using:
164 
165  // root1.refine_using(root2.interval().lower());
166  // root1.refine_using(root2.interval().upper());
167  // root2.refine_using(root1.interval().lower());
168  // root2.refine_using(root1.interval().upper());
169 
170  // auto interval1 = root1.interval();
171  // auto interval2 = root2.interval();
172  // SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "Got intervals " << interval1 << ", " << interval2);
173 
174  // if (interval1.is_point_interval() != interval2.is_point_interval()) return false;
175  // else if (interval1.is_point_interval()) return interval1 == interval2;
176  // else return carl::set_have_intersection(interval1, interval2);
177 }
178 
180  if (proj.is_nullified(ass,poly1) || proj.is_nullified(ass,poly2)) return true;
181  auto roots1 = proj.real_roots(ass,poly1);
182  auto roots2 = proj.real_roots(ass,poly2);
183  // auto common_zero = std::find_if(roots1.begin(), roots1.end(), [&roots2](const auto& root1) { return std::find(roots2.begin(), roots2.end(), root1) != roots2.end(); });
184  auto common_zero = std::find_if(roots1.begin(), roots1.end(), [&roots2](const auto& root1) { return std::find_if(roots2.begin(), roots2.end(), [&root1](const auto& root2) { return has_intersection(root1, root2); } ) != roots2.end(); });
185  return common_zero != roots1.end();
186 }
187 
188 }
A DelineatedDerivation is a BaseDerivation with a Delineation and an underlying SampledDerivation.
Definition: derivation.h:219
void add_root(RAN root, TaggedIndexedRoot tagged_root)
Definition: delineation.h:206
Encapsulates all computations on polynomials.
Definition: projections.h:46
const std::vector< PolyRef > & factors_nonconst(PolyRef p)
Definition: projections.h:238
bool is_nullified(const Assignment &sample, PolyRef p)
Definition: projections.h:309
const std::vector< RAN > & real_roots(const Assignment &sample, PolyRef p)
Definition: projections.h:277
A SampledDerivation is a DelineatedDerivation with a sample and an DelineationInterval w....
Definition: derivation.h:299
Poly resultant(carl::Variable variable, const Poly &p, const Poly &q)
Computes the resultant of two polynomials.
Definition: utils.h:48
boost::container::flat_map< RAN, std::vector< IndexedRoot > > RootMapPlain
Definition: delineation.h:32
void delineable_interval_roots(datastructures::SampledDerivation< P > &deriv, const boost::container::flat_set< datastructures::PolyRef > &polys, const datastructures::PolyRef resultant)
bool has_intersection(const RAN &root1, const RAN &root2)
bool has_common_real_root(datastructures::Projections &proj, Assignment ass, const datastructures::PolyRef &poly1, const datastructures::PolyRef &poly2)
void filter_roots(datastructures::DelineatedDerivation< P > &deriv, const datastructures::PolyRef poly, std::function< result(const RAN &)> filter_condition)
auto projection_root(const datastructures::DelineatedDerivation< P > &deriv, const RAN &root)
std::optional< carl::Interval< RAN > > delineable_interval(datastructures::Projections &proj, const Assignment &sample, const boost::container::flat_set< datastructures::PolyRef > &polys)
void poly_ord_inv(datastructures::SampledDerivation< P > &deriv, datastructures::PolyRef poly)
Definition: rules.h:71
void poly_sgn_inv(datastructures::SampledDerivation< P > &deriv, datastructures::PolyRef poly, bool skip_if_ord_inv=true)
Definition: rules.h:85
bool poly_del(datastructures::SampledDerivation< P > &deriv, datastructures::PolyRef poly)
Definition: rules.h:43
void delineate(datastructures::DelineatedDerivation< P > &deriv, const properties::poly_irreducible_sgn_inv &prop)
Definition: rules.h:126
Polynomial::RootType RAN
Definition: common.h:24
carl::Assignment< RAN > Assignment
Definition: common.h:25
#define SMTRAT_LOG_TRACE(channel, msg)
Definition: logging.h:36
#define SMTRAT_LOG_FUNC(channel, args)
Definition: logging.h:38
#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
level_t level
The level of the polynomial.
Definition: polynomials.h:18