SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
unsat_intervals.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vector>
4 
6 
7 template <typename op>
8 std::vector<datastructures::SampledDerivationRef<typename op::PropertiesSet>> get_unsat_intervals(const Constraint& c, datastructures::Projections& proj, const Assignment& sample) {
9  SMTRAT_LOG_FUNC("smtrat.cadcells.algorithms.onecell", c << ", " << sample);
10 
11  auto vars = proj.polys().var_order();
12  auto current_var = vars[sample.size()];
13  auto tmp_sample = sample;
14 
15  assert(carl::level_of(c.lhs()) == sample.size()+1);
16 
17  auto poly_ref = proj.polys()(c.lhs());
18  auto underlying_deriv = datastructures::make_derivation<typename op::PropertiesSet>(proj, sample, sample.size()).sampled_ref();
19 
20  boost::container::flat_set<RAN> roots;
21  for (const auto& factor : proj.factors_nonconst(poly_ref)) {
22  if (factor.level == poly_ref.level && !proj.is_nullified(sample, factor)) {
23  roots.insert(proj.real_roots(sample, factor).begin(), proj.real_roots(sample, factor).end());
24  } else if ((factor.level < poly_ref.level && proj.is_zero(sample, factor)) || (factor.level == poly_ref.level && proj.is_nullified(sample, factor))) {
25  roots.clear();
26  break;
27  }
28  }
29  SMTRAT_LOG_TRACE("smtrat.cadcells.algorithms.onecell", "Got roots " << roots);
30 
31  std::vector<datastructures::SampledDerivationRef<typename op::PropertiesSet>> results;
32 
33  auto add_deriv_from = [&](const RAN& sample) {
34  results.emplace_back(datastructures::make_sampled_derivation<typename op::PropertiesSet>(underlying_deriv, sample));
35  if (carl::is_strict(c.relation())) {
36  results.back()->insert(operators::properties::poly_semi_sgn_inv{ poly_ref });
37  } else {
38  results.back()->insert(operators::properties::poly_sgn_inv{ poly_ref });
39  }
40  if (!op::project_basic_properties(*results.back())) assert(false);
41  op::delineate_properties(*results.back());
42  results.back()->delineate_cell();
43 
44  SMTRAT_LOG_TRACE("smtrat.cadcells.algorithms.onecell", "Got interval " << results.back()->cell() << " wrt " << results.back()->delin());
45  };
46 
47  if (roots.empty()) {
48  tmp_sample.insert_or_assign(current_var, RAN(0));
49  if (!carl::evaluate(c, tmp_sample)) {
50  add_deriv_from(RAN(0));
51  assert(results.back()->cell().lower_unbounded());
52  assert(results.back()->cell().upper_unbounded());
53  }
54  } else {
55  if (carl::is_strict(c.relation())) {
56  /* This block is needed if
57  * the operator does not support weak_sgn_inv
58  * a strict constraint is only violated at a single point
59  */
60  for (auto root = roots.begin(); root != roots.end(); root++) {
61  add_deriv_from(*root);
62  assert(results.back()->cell().is_section());
63  }
64  }
65 
66  {
67  auto current_sample = RAN(carl::sample_below(*roots.begin()));
68  tmp_sample.insert_or_assign(current_var, current_sample);
69  if (c.relation() == carl::Relation::EQ || (c.relation() != carl::Relation::NEQ && !carl::evaluate(c, tmp_sample))) {
70  add_deriv_from(current_sample);
71  assert(results.back()->cell().is_sector());
72  assert(results.back()->cell().lower_unbounded());
73  }
74  }
75 
76  for (auto root = roots.begin(); root != std::prev(roots.end()); root++) {
77  auto current_sample = carl::sample_between(*root, *std::next(root));
78  tmp_sample.insert_or_assign(current_var, current_sample);
79  if (c.relation() == carl::Relation::EQ || (c.relation() != carl::Relation::NEQ && !carl::evaluate(c, tmp_sample))) {
80  add_deriv_from(current_sample);
81  assert(results.back()->cell().is_sector());
82  assert(!results.back()->cell().lower_unbounded());
83  assert(!results.back()->cell().upper_unbounded());
84  }
85  }
86 
87  {
88  auto current_sample = RAN(carl::sample_above(*(--roots.end())));
89  tmp_sample.insert_or_assign(current_var, current_sample);
90  if (c.relation() == carl::Relation::EQ || (c.relation() != carl::Relation::NEQ && !carl::evaluate(c, tmp_sample))) {
91  add_deriv_from(current_sample);
92  assert(results.back()->cell().is_sector());
93  assert(results.back()->cell().upper_unbounded());
94  }
95  }
96  }
97  return results;
98 }
99 
100 template <typename op>
101 std::vector<datastructures::SampledDerivationRef<typename op::PropertiesSet>> get_unsat_intervals(const VariableComparison& c, datastructures::Projections& proj, const Assignment& sample) {
102  SMTRAT_LOG_FUNC("smtrat.cadcells.algorithms.onecell", c << ", " << sample);
103 
104  auto vars = proj.polys().var_order();
105  auto current_var = vars[sample.size()];
106  auto tmp_sample = sample;
107 
108  assert(c.var() == current_var);
109  assert(std::holds_alternative<RAN>(c.value()) || carl::level_of(std::get<MultivariateRoot>(c.value()).poly()) == sample.size() + 1);
110 
111  auto deriv = datastructures::make_derivation<typename op::PropertiesSet>(proj, sample, sample.size() + 1).delineated_ref();
112 
113  auto value_result = [&]() -> std::variant<std::pair<datastructures::IndexedRoot, RAN>, datastructures::PolyRef> {
114  if (std::holds_alternative<RAN>(c.value())) {
115  assert(false);
116  RAN root = std::get<RAN>(c.value());
117  auto p = carl::defining_polynomial(c);
118  auto poly = proj.polys()(p);
119  auto poly_roots = proj.real_roots(sample, poly);
120  size_t index = (size_t)std::distance(poly_roots.begin(), std::find(poly_roots.begin(), poly_roots.end(), root)) + 1;
121  datastructures::IndexedRoot iroot(poly, index);
122  return std::make_pair(iroot, root);
123  } else {
124  auto eval_res = carl::evaluate(std::get<MultivariateRoot>(c.value()), sample);
125  if (!eval_res) {
126  auto p = carl::defining_polynomial(c);
127  return proj.polys()(p);
128  } else {
129  RAN root = *eval_res;
130  auto p = carl::defining_polynomial(c);
131  datastructures::IndexedRoot iroot(proj.polys()(p), std::get<MultivariateRoot>(c.value()).k());
132  return std::make_pair(iroot, root);
133  }
134  }
135  }();
136 
137  std::vector<datastructures::SampledDerivationRef<typename op::PropertiesSet>> results;
138 
139  if (std::holds_alternative<std::pair<datastructures::IndexedRoot, RAN>>(value_result)) {
140  datastructures::IndexedRoot& iroot = std::get<std::pair<datastructures::IndexedRoot, RAN>>(value_result).first;
141  RAN& root = std::get<std::pair<datastructures::IndexedRoot, RAN>>(value_result).second;
142 
143  auto relation = c.negated() ? carl::inverse(c.relation()) : c.relation();
144  bool point = relation == carl::Relation::GREATER || relation == carl::Relation::LESS || relation == carl::Relation::NEQ;
145  bool below = relation == carl::Relation::GREATER || relation == carl::Relation::GEQ || relation == carl::Relation::EQ;
146  bool above = relation == carl::Relation::LESS || relation == carl::Relation::LEQ || relation == carl::Relation::EQ;
147 
148  deriv->insert(operators::properties::poly_del{ iroot.poly });
149  deriv->delin().add_root(root, datastructures::TaggedIndexedRoot{iroot, (op::filter) && carl::is_strict(relation)});
150 
151  if (point) {
152  results.emplace_back(datastructures::make_sampled_derivation(deriv, root));
153  SMTRAT_LOG_TRACE("smtrat.cadcells.algorithms.onecell", "Got interval " << results.back()->cell() << " wrt " << results.back()->delin());
154  }
155  if (below) {
156  results.emplace_back(datastructures::make_sampled_derivation(deriv, RAN(carl::sample_below(root))));
157  SMTRAT_LOG_TRACE("smtrat.cadcells.algorithms.onecell", "Got interval " << results.back()->cell() << " wrt " << results.back()->delin());
158  }
159  if (above) {
160  results.emplace_back(datastructures::make_sampled_derivation(deriv, RAN(carl::sample_above(root))));
161  SMTRAT_LOG_TRACE("smtrat.cadcells.algorithms.onecell", "Got interval " << results.back()->cell() << " wrt " << results.back()->delin());
162  }
163  } else {
164  datastructures::PolyRef& poly = std::get<datastructures::PolyRef>(value_result);
165  if (proj.is_nullified(sample, poly)) {
167  deriv->delin().add_poly_nullified(poly);
168  } else if (proj.num_roots(sample, poly) == 0) {
170  deriv->delin().add_poly_nonzero(poly);
171  } else {
172  assert(proj.num_roots(sample, poly) > 0 && proj.num_roots(sample, poly) < std::get<MultivariateRoot>(c.value()).k());
173  deriv->insert(operators::properties::poly_del{ poly });
174  }
175  results.emplace_back(datastructures::make_sampled_derivation(deriv, RAN(0)));
176  SMTRAT_LOG_TRACE("smtrat.cadcells.algorithms.onecell", "Got interval " << results.back()->cell() << " wrt " << results.back()->delin());
177  }
178  return results;
179 }
180 
181 /**
182  * Returns the unsat intervals of the given atom w.r.t. an underlying sample.
183  *
184  * @param c A constraint or a variable comparison.
185  * @param sample A sample point such that the highest variable in @ref c w.r.t. the variable odering in @ref proj is the only unassigned variable.
186  * @return A list of sampled derivations with the same delineated derivations. The samples for the unassigned variables are sampled from the respective interval.
187  */
188 template <typename op>
189 std::vector<datastructures::SampledDerivationRef<typename op::PropertiesSet>> get_unsat_intervals(const Atom& c, datastructures::Projections& proj, const Assignment& sample) {
190  SMTRAT_LOG_FUNC("smtrat.cadcells.algorithms.onecell", c << ", " << sample);
191  if (std::holds_alternative<Constraint>(c)) {
192  return get_unsat_intervals<op>(std::get<Constraint>(c), proj, sample);
193  } else if (std::holds_alternative<VariableComparison>(c)) {
194  return get_unsat_intervals<op>(std::get<VariableComparison>(c), proj, sample);
195  } else {
196  assert(false);
197  return std::vector<datastructures::SampledDerivationRef<typename op::PropertiesSet>>();
198  }
199 }
200 
201 }
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
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
static bool find(V &ts, const T &t)
Definition: Alg.h:47
Various algorithms as well as helper functions for developing new algorithms.
Definition: interval.h:5
std::vector< datastructures::SampledDerivationRef< typename op::PropertiesSet > > get_unsat_intervals(const Constraint &c, datastructures::Projections &proj, const Assignment &sample)
SampledDerivationRef< Properties > make_sampled_derivation(DelineatedDerivationRef< Properties > delineated, const RAN &main_sample)
Initializes a sampled derivation w.r.t.
Definition: derivation.h:385
Polynomial::RootType RAN
Definition: common.h:24
carl::Assignment< RAN > Assignment
Definition: common.h:25
carl::VariableComparison< Polynomial > VariableComparison
Definition: common.h:20
std::variant< Constraint, VariableComparison > Atom
Definition: common.h:21
carl::BasicConstraint< Polynomial > Constraint
Definition: common.h:18
static size_t level_of(const VariableOrdering &order, const Pol &poly)
Definition: Backend.h:25
Rational evaluate(carl::Variable v, const Poly &p, const Rational &r)
Definition: utils.h:11
std::vector< carl::Variable > vars(const std::pair< QuantifierType, std::vector< carl::Variable >> &p)
Definition: QEQuery.h:43
#define SMTRAT_LOG_TRACE(channel, msg)
Definition: logging.h:36
#define SMTRAT_LOG_FUNC(channel, args)
Definition: logging.h:38
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