SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
rules.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "properties.h"
4 #include "properties_util.h"
5 #include "../datastructures/derivation.h"
6 
7 /**
8  * Implementation of derivation rules.
9  *
10  * Each rule is realized by a function which works on a derivation object. The parameters of the respective properties are passed as function parameter. The function realizing a derivation rule might either call other derivation rules or add properties to the given derivation.
11  *
12  */
14 
15 template<typename P>
17  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "non_null(" << poly << ")");
18  if(deriv.proj().is_nullified(deriv.sample(), poly)) {
19  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "non_null(" << poly << ") <= false");
20  return false;
21  } else if (deriv.proj().has_const_coeff(poly)) {
22  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "non_null(" << poly << ") <= " << poly << " has const coeff");
23  } else if (!deriv.proj().is_ldcf_zero(deriv.sample(), poly) && deriv.contains(properties::poly_sgn_inv{ deriv.proj().ldcf(poly) } )) {
24  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "non_null(" << poly << ") <= ldcf(" << poly << ")(" << deriv.sample() << ")!=0 && sgn_inv(ldcf(" << poly << ") [" << deriv.proj().ldcf(poly) << "])");
25  } else if (
26  /* deriv.proj().know_disc(poly) && */ deriv.proj().degree(poly) > 1 && !deriv.proj().is_disc_zero(deriv.sample(), poly) &&
27  (deriv.contains(properties::poly_sgn_inv{ deriv.proj().disc(poly) }) || deriv.contains(properties::poly_ord_inv{ deriv.proj().disc(poly) }))
28  ) {
29  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "non_null(" << poly << ") <= disc(" << poly << ")(" << deriv.sample() << ")!=0 && sgn_inv(disc(" << poly << ") [" << deriv.proj().disc(poly) << "])");
30  } else {
31  auto coeff = deriv.proj().simplest_nonzero_coeff(deriv.sample(), poly, [&](const Polynomial& a, const Polynomial& b) {
32  if (deriv.proj().known(a) && deriv.contains( properties::poly_sgn_inv { deriv.proj().polys()(a)} )) return true;
33  if (deriv.proj().known(b) && deriv.contains( properties::poly_sgn_inv { deriv.proj().polys()(b)} )) return true;
34  return carl::level_of(a) < carl::level_of(b) || (carl::level_of(a) == carl::level_of(b) && a.total_degree() < b.total_degree());
35  });
36  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "non_null(" << poly << ") <= sgn_inv(" << coeff << ") && " << coeff << " in coeff(" << poly << ")");
37  deriv.insert(properties::poly_sgn_inv{ coeff });
38  }
39  return true;
40 }
41 
42 template<typename P>
44  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "del(" << poly << ")");
45  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "-> del(" << poly << ") <= non_null(" << poly << ") && ord_inv(disc(" << poly << ") [" << deriv.proj().disc(poly) << "]) && sgn_inv(ldcf(" << poly << ") [" << deriv.proj().ldcf(poly) << "]) && cell_connected(" << (poly.base_level) << ")");
46  deriv.insert(properties::poly_ord_inv{ deriv.proj().disc(poly) });
47  deriv.insert(properties::poly_sgn_inv{ deriv.proj().ldcf(poly) });
49  if (!poly_non_null(deriv, poly)) return false;
50  return true;
51 }
52 
53 template<typename P>
55  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "ord_inv(" << poly << "), " << poly << " irreducible");
56  if (deriv.proj().is_const(poly)) {
57  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "-> ord_inv(" << poly << ") <= " << poly << " const");
58  } else {
59  if (deriv.proj().is_zero(deriv.sample(), poly)) {
60  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "-> ord_inv(" << poly << ") <= del(" << poly << ") && sgn_inv(" << poly << ") && cell_connected(" << poly.level << ")");
61  deriv.insert(properties::poly_del{ poly });
63  } else {
64  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "-> ord_inv(" << poly << ") <= " << poly << "(" << deriv.sample() << ") != 0 && sgn_inv(" << poly << ")");
65  }
67  }
68 }
69 
70 template<typename P>
72  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "ord_inv(" << poly << ")");
73  if (deriv.proj().is_const(poly)) {
74  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "-> ord_inv(" << poly << ") <= " << poly << " const");
75  } else {
76  auto factors = deriv.proj().factors_nonconst(poly);
77  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "-> ord_inv(" << poly << ") <= ord_inv(factors(" << poly << ")) <=> ord_inv(" << factors << ")");
78  for (const auto& factor : factors) {
79  poly_irreducible_ord_inv(deriv, factor);
80  }
81  }
82 }
83 
84 template<typename P>
85 void poly_sgn_inv(datastructures::SampledDerivation<P>& deriv, datastructures::PolyRef poly, bool skip_if_ord_inv = true) {
86  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "sgn_inv(" << poly << ")");
87  if (deriv.proj().is_const(poly)) {
88  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "-> sgn_inv(" << poly << ") <= " << poly << " const");
89  } else if (skip_if_ord_inv && deriv.contains(properties::poly_ord_inv{ poly })) {
90  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "-> sgn_inv(" << poly << ") <= ord_inv(" << poly << ")");
91  } else {
92  std::optional<datastructures::PolyRef> lowest_zero_factor;
93  for (const auto& factor : deriv.proj().factors_nonconst(poly)) {
94  if (deriv.proj().is_zero(deriv.sample(), factor)) {
95  if (lowest_zero_factor == std::nullopt ||
96  factor.level < lowest_zero_factor->level ||
97  (factor.level == lowest_zero_factor->level && (factor.level == poly.level && deriv.proj().is_nullified(deriv.underlying_sample(), factor) && !deriv.proj().is_nullified(deriv.underlying_sample(), *lowest_zero_factor))) ||
98  (factor.level == lowest_zero_factor->level && (factor.level != poly.level || (deriv.proj().is_nullified(deriv.underlying_sample(), factor) && deriv.proj().is_nullified(deriv.underlying_sample(), *lowest_zero_factor))) && deriv.proj().total_degree(factor) < deriv.proj().total_degree(*lowest_zero_factor))
99  ) {
100  lowest_zero_factor = factor;
101  }
102  }
103  }
104 
105  if (lowest_zero_factor) {
106  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "-> sgn_inv(" << poly << ") <= sgn_inv(" << *lowest_zero_factor << ") && " << *lowest_zero_factor << "("<< deriv.sample() <<")=0");
107  deriv.insert(properties::poly_irreducible_sgn_inv{ *lowest_zero_factor });
108  } else {
109  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "-> sgn_inv(" << poly << ") <= sgn_inv(factors(" << poly << ")) <=> sgn_inv(" << deriv.proj().factors_nonconst(poly) << ")");
110  for (const auto& factor : deriv.proj().factors_nonconst(poly)) {
112  }
113  }
114  }
115 }
116 
117 template<typename P>
119  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "sgn_inv(" << poly << "), " << poly << " irreducible and non-zero");
120  assert(deriv.proj().num_roots(deriv.underlying_sample(), poly) == 0);
121  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "-> sgn_inv(" << poly << ") <= del(" << poly << ")");
122  deriv.insert(properties::poly_del{ poly });
123 }
124 
125 template<typename P>
127  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "delineate(" << prop << ")");
128  if (deriv.proj().is_nullified(deriv.underlying_sample(), prop.poly)) {
129  deriv.delin().add_poly_nullified(prop.poly);
130  } else {
131  auto roots = deriv.proj().real_roots(deriv.underlying_sample(), prop.poly);
132  if (roots.empty()) {
133  deriv.delin().add_poly_nonzero(prop.poly);
134  } else {
135  for (size_t idx = 0; idx < roots.size(); idx++) {
137  }
138  }
139  }
140 }
141 
142 template<typename P>
144  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "delineate(" << prop << ")");
145  if (deriv.proj().is_nullified(deriv.underlying_sample(), prop.poly)) {
146  deriv.delin().add_poly_nullified(prop.poly);
147  } else {
148  auto roots = deriv.proj().real_roots(deriv.underlying_sample(), prop.poly);
149  if (roots.empty()) {
150  deriv.delin().add_poly_nonzero(prop.poly);
151  } else {
152  for (size_t idx = 0; idx < roots.size(); idx++) {
153  deriv.delin().add_root(roots[idx], datastructures::TaggedIndexedRoot{datastructures::IndexedRoot(prop.poly, idx+1), true });
154  }
155  }
156  }
157 }
158 
159 template<typename P>
161  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "connected(" << deriv.level() << ")");
162  if (!cell.is_section() && !cell.lower().is_infty() && !cell.upper().is_infty()) {
163  assert(ordering.is_projective() || ordering.holds_transitive(cell.lower().value(),cell.upper().value(), false));
164  }
165  deriv.insert(properties::cell_connected{ deriv.level()-1 });
166 }
167 
168 template<typename P>
170  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "an_sub(" << deriv.level() << ")");
171 }
172 
173 template<typename P>
175  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "sgn_inv(" << poly << "), using EC");
176  assert(cell.is_section());
177  assert(deriv.contains(properties::poly_del{ cell.section_defining().poly }));
179  if (cell.section_defining().poly != poly) {
180  deriv.insert(properties::poly_ord_inv{ deriv.proj().res(cell.section_defining().poly, poly) });
181  }
182 }
183 
184 template<typename P>
186  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "semi_sgn_inv(" << poly << "), using EC");
187  poly_irreducible_sgn_inv_ec(deriv, cell, poly);
188 }
189 
190 template<typename P>
192  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "repr(" << cell << ")");
193  if (!cell.is_section()) {
194  if (!cell.lower().is_infty()) {
195  if (cell.lower().value().is_root()) {
196  deriv.insert(properties::poly_del{ cell.lower().value().root().poly });
197  } else {
198  for (const auto& roots : cell.lower().value().roots()) {
199  for (const auto& root : roots) {
200  deriv.insert(properties::poly_del{ root.poly });
201  }
202  }
203  }
204  }
205  if (!cell.upper().is_infty()) {
206  if (cell.upper().value().is_root()) {
207  deriv.insert(properties::poly_del{ cell.upper().value().root().poly });
208  } else {
209  for (const auto& roots : cell.upper().value().roots()) {
210  for (const auto& root : roots) {
211  deriv.insert(properties::poly_del{ root.poly });
212  }
213  }
214  }
215  }
216  } else {
217  deriv.insert(properties::poly_del{ cell.section_defining().poly });
218  }
219 }
220 
221 template<typename P>
223  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "ir_ord(" << ordering << ", " << deriv.sample() << ")");
224  deriv.insert(properties::cell_connected{ deriv.level() });
225  for (const auto& rel : ordering.data()) {
226  assert(rel.first.is_root() && rel.second.is_root());
227  auto& first = rel.first.root();
228  auto& second = rel.second.root();
229  if (first.poly != second.poly) {
230  assert(rel.is_strict || (ordering.holds_transitive(first,second,false) && ordering.holds_transitive(second,first,false))); // not supported
231  assert(deriv.contains(properties::poly_del{ first.poly }));
232  assert(deriv.contains(properties::poly_del{ second.poly }));
233  deriv.insert(properties::poly_ord_inv{ deriv.proj().res(first.poly, second.poly) });
234  }
235  }
236 }
237 
238 template<typename P>
240  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "sgn_inv(" << poly << "), " << poly << " irreducible");
241 }
242 
243 template<typename P>
245  SMTRAT_LOG_TRACE("smtrat.cadcells.operators.rules", "sgn_inv(" << poly << "), " << poly << " irreducible and nullified");
246  assert(deriv.proj().is_nullified(deriv.underlying_sample(), poly));
247 
248  for (const auto coeff : deriv.proj().coeffs(poly)) {
249  assert(deriv.proj().is_zero(deriv.sample(), coeff));
250  deriv.insert(properties::poly_sgn_inv{ coeff });
251  }
252 }
253 
254 }
255 
256 #include "rules_filter.h"
257 #include "rules_covering.h"
258 #include "rules_null.h"
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
Describes an ordering of IndexedRoots.
Definition: roots.h:400
bool holds_transitive(RootFunction first, RootFunction second, bool strict) const
Definition: roots.h:468
const std::vector< PolyRef > & factors_nonconst(PolyRef p)
Definition: projections.h:238
bool known(const Polynomial &p) const
Definition: projections.h:200
std::size_t degree(PolyRef p) const
Definition: projections.h:403
bool is_ldcf_zero(const Assignment &sample, PolyRef p)
Definition: projections.h:325
bool is_disc_zero(const Assignment &sample, PolyRef p)
Definition: projections.h:329
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
PolyRef simplest_nonzero_coeff(const Assignment &sample, PolyRef p, std::function< bool(const Polynomial &, const Polynomial &)> compare)
Definition: projections.h:359
size_t num_roots(const Assignment &sample, PolyRef p)
Definition: projections.h:262
bool is_zero(const Assignment &sample, PolyRef p)
Definition: projections.h:250
std::vector< PolyRef > coeffs(PolyRef p)
Definition: projections.h:341
A SampledDerivation is a DelineatedDerivation with a sample and an DelineationInterval w....
Definition: derivation.h:299
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
Implementation of derivation rules.
Definition: rules.h:13
void poly_irreducible_ord_inv(datastructures::SampledDerivation< P > &deriv, datastructures::PolyRef poly)
Definition: rules.h:54
void root_ordering_holds(datastructures::SampledDerivation< P > &deriv, const datastructures::IndexedRootOrdering &ordering)
Definition: rules.h:222
void cell_analytic_submanifold([[maybe_unused]] datastructures::SampledDerivation< P > &deriv, const datastructures::SymbolicInterval &)
Definition: rules.h:169
void poly_irreducible_null_sgn_inv(datastructures::SampledDerivation< P > &deriv, datastructures::PolyRef poly)
Definition: rules.h:244
void poly_ord_inv(datastructures::SampledDerivation< P > &deriv, datastructures::PolyRef poly)
Definition: rules.h:71
void poly_irreducible_sgn_inv_ec(datastructures::SampledDerivation< P > &deriv, const datastructures::SymbolicInterval &cell, datastructures::PolyRef poly)
Definition: rules.h:174
void poly_irreducible_nonzero_sgn_inv(datastructures::DelineatedDerivation< P > &deriv, datastructures::PolyRef poly)
Definition: rules.h:118
void cell_connected(datastructures::SampledDerivation< P > &deriv, const datastructures::SymbolicInterval &cell, const datastructures::IndexedRootOrdering &ordering)
Definition: rules.h:160
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 poly_irreducible_sgn_inv(datastructures::SampledDerivation< P > &, const datastructures::SymbolicInterval &, const datastructures::IndexedRootOrdering &, [[maybe_unused]] datastructures::PolyRef poly)
Definition: rules.h:239
void delineate(datastructures::DelineatedDerivation< P > &deriv, const properties::poly_irreducible_semi_sgn_inv &prop)
Definition: rules.h:143
void poly_irreducible_semi_sgn_inv_ec(datastructures::SampledDerivation< P > &deriv, const datastructures::SymbolicInterval &cell, datastructures::PolyRef poly)
Definition: rules.h:185
bool poly_non_null(datastructures::SampledDerivation< P > &deriv, datastructures::PolyRef poly)
Definition: rules.h:16
void cell_represents(datastructures::SampledDerivation< P > &deriv, const datastructures::SymbolicInterval &cell)
Definition: rules.h:191
carl::ContextPolynomial< Rational > Polynomial
Definition: common.h:16
static size_t level_of(const VariableOrdering &order, const Pol &poly)
Definition: Backend.h:25
#define SMTRAT_LOG_TRACE(channel, msg)
Definition: logging.h:36
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
level_t level
The level of the polynomial.
Definition: polynomials.h:18
level_t base_level
The base level of the polynomial.
Definition: polynomials.h:22