SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
Sampling.h
Go to the documentation of this file.
1 #pragma once
2 
3 namespace smtrat::covering_ng {
4 
5 
6 enum class SamplingAlgorithm {
8 };
9 
10 /*
11  * @brief Sampling algorithm checking if a the given set of derivations ref is fully covering
12  * @param derivations Vector of sampled derivations, assumed as being sorted by lower bounds
13  * @note redundancies of the first kind are not removed
14  * @return std::nullopt if the vector of derivations is covering, a real algebraic number if the vector of derivations is not covering
15  */
16 template<SamplingAlgorithm S>
17 struct sampling {
18  template<typename FE, typename PropertiesSet>
19  static std::optional<cadcells::RAN> sample_outside(const IntervalSet<PropertiesSet>& derivations, const FE& f);
20 };
21 
22 /// First checks lower bound and then upper bound, then checks between the cells if they are covered.
23 template<>
25  template<typename FE, typename PropertiesSet>
26  static std::optional<cadcells::RAN> sample_outside(const IntervalSet<PropertiesSet>& intervals, const FE&) {
27  // remove redundancies of the first kind
28  // the derivations are already sorted by lower bound
29  std::vector<Interval<PropertiesSet>> derivs;
30  auto iter = intervals.begin();
31  while (iter != intervals.end()) {
32  derivs.push_back(*iter);
33  auto& last_cell = (*iter)->cell();
34  iter++;
35  while (iter != intervals.end() && !cadcells::datastructures::upper_lt_upper(last_cell, (*iter)->cell()))
36  iter++;
37  }
38 
39  if (derivs.empty()) {
40  // There are no cells, just take trivially 0
41  return cadcells::RAN(0);
42  } else if (!derivs.front()->cell().lower_unbounded()) {
43  // Lower bound is finite, just take a sufficiently large negative number
44  return carl::sample_below(derivs.front()->cell().lower()->first);
45  } else if (!derivs.back()->cell().upper_unbounded()) {
46  // Upper bound is finite, just take a sufficiently large positive number
47  return carl::sample_above(derivs.back()->cell().upper()->first);
48  } else {
49  // Search for adjacent disjoint cells and sample between
50  for (size_t i = 0; i + 1 < derivs.size(); i++) {
51  // We know that the cells are ordered by lower bound - so for checking disjointness the following suffices
52  if (!derivs[i]->cell().upper_unbounded() && !derivs[i + 1]->cell().lower_unbounded() && cadcells::datastructures::upper_lt_lower(derivs[i]->cell(), derivs[i + 1]->cell())) {
53  if (derivs[i]->cell().upper()->first == derivs[i + 1]->cell().lower()->first) {
54  return derivs[i]->cell().upper()->first;
55  } else {
56  return carl::sample_between(derivs[i]->cell().upper()->first, derivs[i + 1]->cell().lower()->first);
57  }
58  }
59  }
60  // The cells cover the number line -> There is no sample to be found
61  return std::nullopt;
62  }
63  }
64 };
65 
66 /// First checks lower bound and then upper bound, then checks between the cells if they are covered (defers choosing interval endpoints as much as possible).
67 template<>
69  template<typename FE, typename PropertiesSet>
70  static std::optional<cadcells::RAN> sample_outside(const IntervalSet<PropertiesSet>& intervals, const FE&) {
71  std::vector<Interval<PropertiesSet>> derivs;
72  auto iter = intervals.begin();
73  while (iter != intervals.end()) {
74  derivs.push_back(*iter);
75  auto& last_cell = (*iter)->cell();
76  iter++;
77  while (iter != intervals.end() && !cadcells::datastructures::upper_lt_upper(last_cell, (*iter)->cell()))
78  iter++;
79  }
80 
81  if (derivs.empty()) {
82  return cadcells::RAN(0);
83  } else if (!derivs.front()->cell().lower_unbounded()) {
84  return carl::sample_below(derivs.front()->cell().lower()->first);
85  } else if (!derivs.back()->cell().upper_unbounded()) {
86  return carl::sample_above(derivs.back()->cell().upper()->first);
87  } else {
88  for (size_t i = 0; i + 1 < derivs.size(); i++) {
89  if (!derivs[i]->cell().upper_unbounded() && !derivs[i + 1]->cell().lower_unbounded() && cadcells::datastructures::upper_lt_lower(derivs[i]->cell(), derivs[i + 1]->cell())) {
90  if (derivs[i]->cell().upper()->first != derivs[i + 1]->cell().lower()->first) {
91  return carl::sample_between(derivs[i]->cell().upper()->first, derivs[i + 1]->cell().lower()->first);
92  }
93  }
94  }
95  for (size_t i = 0; i + 1 < derivs.size(); i++) {
96  if (!derivs[i]->cell().upper_unbounded() && !derivs[i + 1]->cell().lower_unbounded() && cadcells::datastructures::upper_lt_lower(derivs[i]->cell(), derivs[i + 1]->cell())) {
97  assert (derivs[i]->cell().upper()->first == derivs[i + 1]->cell().lower()->first);
98  return derivs[i]->cell().upper()->first;
99  }
100  }
101  return std::nullopt;
102  }
103  }
104 };
105 
106 }; // namespace smtrat
bool upper_lt_upper(const DelineationInterval &del1, const DelineationInterval &del2)
Compares the upper bounds of two DelineationIntervals.
Definition: delineation.h:286
bool upper_lt_lower(const DelineationInterval &del1, const DelineationInterval &del2)
Compares an upper bound with a lower bound of DelineationIntervals.
Definition: delineation.h:296
Polynomial::RootType RAN
Definition: common.h:24
std::set< Interval< PropertiesSet >, IntervalCompare< PropertiesSet > > IntervalSet
Definition: types.h:32
@ LOWER_UPPER_BETWEEN_SAMPLING
Definition: Sampling.h:18
static std::optional< cadcells::RAN > sample_outside(const IntervalSet< PropertiesSet > &intervals, const FE &)
Definition: Sampling.h:26
static std::optional< cadcells::RAN > sample_outside(const IntervalSet< PropertiesSet > &intervals, const FE &)
Definition: Sampling.h:70
static std::optional< cadcells::RAN > sample_outside(const IntervalSet< PropertiesSet > &derivations, const FE &f)