SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
derivation.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "../common.h"
4 
5 #include "delineation.h"
6 #include "polynomials.h"
7 #include "projections.h"
8 #include "properties.h"
9 
11 
12 template<typename Properties>
13 class BaseDerivation;
14 template<typename Properties>
15 class DelineatedDerivation;
16 template<typename Properties>
17 class SampledDerivation;
18 
19 template<typename Properties>
20 using BaseDerivationRef = std::shared_ptr<BaseDerivation<Properties>>;
21 template<typename Properties>
22 using DelineatedDerivationRef = std::shared_ptr<DelineatedDerivation<Properties>>;
23 
24 template<typename Properties>
25 using SampledDerivationRef = std::shared_ptr<SampledDerivation<Properties>>;
26 
27 /**
28  * A reference to a derivation, which is either
29  * - a @ref BaseDerivation (a set of properties for each level)
30  * - a @ref DelineatedDerivation (a @ref BaseDerivation with an underlying @ref SampledDerivation on which the properties can be delineated)
31  * - a @ref SampledDerivation (a @ref DelineatedDerivation with an underlying @ref SampledDerivation plus a sample on the current level such that a delineated interval can be computed)
32  *
33  * ## Memory management
34  *
35  * Memory management is based on std::shared_ptr. A SampledDerivation holds a shared pointer to a DelineatedDerivation, which in turn holds a shared pointer to BaseDerivation. The BaseDerivation holds a @ref DerivationRef to the underlying derivation. Note that not all combinations are legal; i.e. the underlying derivation of a delineated derivation must be a sampled derivation.
36  */
37 template<typename Properties>
39  std::variant<BaseDerivationRef<Properties>, DelineatedDerivationRef<Properties>, SampledDerivationRef<Properties>> m_data;
40 
41 public:
43  : m_data(data) {}
45  : m_data(data) {}
47  : m_data(data) {}
48 
49  bool is_null() const {
50  if (std::holds_alternative<BaseDerivationRef<Properties>>(m_data)) {
51  return std::get<BaseDerivationRef<Properties>>(m_data) == nullptr;
52  } else if (std::holds_alternative<DelineatedDerivationRef<Properties>>(m_data)) {
53  return std::get<DelineatedDerivationRef<Properties>>(m_data) == nullptr;
54  } else {
55  return std::get<SampledDerivationRef<Properties>>(m_data) == nullptr;
56  }
57  }
58  bool is_sampled() const {
59  return std::holds_alternative<SampledDerivationRef<Properties>>(m_data);
60  }
61 
62  auto& base_ref() {
63  if (std::holds_alternative<BaseDerivationRef<Properties>>(m_data)) {
64  return std::get<BaseDerivationRef<Properties>>(m_data);
65  } else if (std::holds_alternative<DelineatedDerivationRef<Properties>>(m_data)) {
66  return std::get<DelineatedDerivationRef<Properties>>(m_data)->base();
67  } else {
68  assert(is_sampled());
69  return std::get<SampledDerivationRef<Properties>>(m_data)->base();
70  }
71  }
72  auto& delineated_ref() {
73  if (std::holds_alternative<DelineatedDerivationRef<Properties>>(m_data)) {
74  return std::get<DelineatedDerivationRef<Properties>>(m_data);
75  } else {
76  assert(is_sampled());
77  return std::get<SampledDerivationRef<Properties>>(m_data)->delineated();
78  }
79  }
80  auto& sampled_ref() {
81  assert(is_sampled());
82  return std::get<SampledDerivationRef<Properties>>(m_data);
83  }
84 
85  const auto& base_ref() const {
86  if (std::holds_alternative<BaseDerivationRef<Properties>>(m_data)) {
87  return std::get<BaseDerivationRef<Properties>>(m_data);
88  } else if (std::holds_alternative<DelineatedDerivationRef<Properties>>(m_data)) {
89  return std::get<DelineatedDerivationRef<Properties>>(m_data)->base();
90  } else {
91  assert(is_sampled());
92  return std::get<SampledDerivationRef<Properties>>(m_data)->base();
93  }
94  }
95  const auto& delineated_ref() const {
96  if (std::holds_alternative<DelineatedDerivationRef<Properties>>(m_data)) {
97  return std::get<DelineatedDerivationRef<Properties>>(m_data);
98  } else {
99  assert(is_sampled());
100  return std::get<SampledDerivationRef<Properties>>(m_data)->delineated();
101  }
102  }
103  const auto& sampled_ref() const {
104  assert(is_sampled());
105  return std::get<SampledDerivationRef<Properties>>(m_data);
106  }
107 
108  auto& base() {
109  return *base_ref();
110  }
111  auto& delineated() {
112  return *delineated_ref();
113  }
114  auto& sampled() {
115  return *sampled_ref();
116  }
117  const auto& base() const {
118  return *base_ref();
119  }
120  const auto& delineated() const {
121  return *delineated_ref();
122  }
123  const auto& sampled() const {
124  return *sampled_ref();
125  }
126 
127  template<typename P>
128  friend bool operator==(const DerivationRef<P>& lhs, const DerivationRef<P>& rhs);
129  template<typename P>
130  friend bool operator<(const DerivationRef<P>& lhs, const DerivationRef<P>& rhs);
131 };
132 template<typename P>
133 bool operator==(const DerivationRef<P>& lhs, const DerivationRef<P>& rhs) {
134  return lhs.m_data == rhs.m_data;
135 }
136 template<typename P>
137 bool operator<(const DerivationRef<P>& lhs, const DerivationRef<P>& rhs) {
138  return lhs.m_data < rhs.m_data;
139 }
140 
141 /**
142  * A BaseDerivation has a level and a set of properties of this level, and an underlying derivation representing the lower levels.
143  *
144  * @tparam Properties Set of properties (from the operator)
145  */
146 template<typename Properties>
148  template<typename P>
149  friend void merge_underlying(std::vector<SampledDerivationRef<P>>& derivations);
150 
153 
154  size_t m_level;
155  Properties m_properties;
156 
157 public:
158  // should be private, but does not work with make_shared:
160  assert((level == 0 && m_underlying.is_null()) || (level > 0 && !m_underlying.is_null()));
161  }
163 
166 
169  carl::Variable main_var() const {
170  if (m_level == 0) return carl::Variable::NO_VARIABLE;
171  else return m_projections.polys().var_order()[m_level-1];
172  }
173  size_t level() const { return m_level; }
174 
175  template<typename P>
176  void insert(P property) {
177  SMTRAT_LOG_FUNC("smtrat.cadcells.derivation", property);
178  assert(property.level() <= m_level && property.level() >= 0);
179 
180  if (property.level() == m_level) {
181  prop_insert<P>(m_properties, property);
182  } else {
183  assert(!m_underlying.is_null());
184  m_underlying.base().insert(property);
185  }
186  }
187 
188  template<typename P>
189  bool contains(const P& property) const {
190  assert(property.level() <= m_level && property.level() >= 0);
191 
192  if (property.level() == m_level) {
193  return prop_has<P>(m_properties, property);
194  } else {
195  assert(!m_underlying.is_null());
196  return m_underlying.base().contains(property);
197  }
198  }
199  template<typename P>
200  const PropertiesTSet<P>& properties() const {
201  return prop_get<P>(m_properties);
202  }
203 
205  assert(other.m_level == m_level && &other.m_projections == &m_projections);
207  if (m_level > 0) {
208  m_underlying.base().merge_with(other.m_underlying.base());
209  }
210  }
211 };
212 
213 /**
214  * A DelineatedDerivation is a BaseDerivation with a Delineation and an underlying SampledDerivation.
215  *
216  * @tparam Properties Set of properties
217  */
218 template<typename Properties>
222 
223 public:
224  // should be private, but does not work with make_shared:
226  : m_base(base) {
227  assert(base->level() == 0 || base->underlying().is_sampled());
228  }
230  : m_base(base), m_delineation(delineation) {
231  assert(base->level() == 0 || base->underlying().is_sampled());
232  }
233 
235  return m_base;
236  };
238  return m_base;
239  };
240 
242  return m_delineation;
243  };
244  const Assignment& underlying_sample() const {
245  if (m_base->level() <= 1) {
246  return empty_assignment;
247  } else {
248  return underlying().sampled().sample();
249  }
250  }
251 
253  return m_base->underlying();
254  };
256  return m_base->underlying();
257  };
259  return m_base->polys();
260  };
262  return m_base->proj();
263  };
264  carl::Variable main_var() const {
265  return m_base->main_var();
266  };
267  size_t level() const {
268  return m_base->level();
269  };
270  template<typename P>
271  void insert(P property) {
272  m_base->insert(property);
273  };
274  template<typename P>
275  bool contains(const P& property) const {
276  return m_base->contains(property);
277  };
278  template<typename P>
279  const PropertiesTSet<P>& properties() const {
280  return m_base->template properties<P>();
281  };
282 
284  m_base->merge_with(*other.m_base);
285  if (!m_delineation.empty() && !other.m_delineation.empty()) {
287  } else {
288  assert(m_delineation.empty() && other.m_delineation.empty());
289  }
290  };
291 };
292 
293 /**
294  * A SampledDerivation is a DelineatedDerivation with a sample and an DelineationInterval w.r.t. to this sample.
295  *
296  * @tparam Properties Set of properties
297  */
298 template<typename Properties>
301  std::optional<DelineationInterval> m_cell;
303 
304 public:
305 
306  // should be private, but does not work with make_shared
308  m_sample = m_delineated->underlying_sample();
309  if (m_delineated->level() > 0) {
310  m_sample.emplace(m_delineated->main_var(), main_sample);
311  }
312  }
313 
316 
317  const DelineationInterval& cell() const { return *m_cell; }
318  /**
319  * Determines the cell w.r.t. the delineation.
320  *
321  */
322  void delineate_cell() {
323  if (m_delineated->level() > 0) {
324  m_cell = m_delineated->delin().delineate_cell(main_var_sample());
325  }
326  }
327 
328  const Assignment& sample() const { return m_sample; };
329  const RAN& main_var_sample() const { return m_sample.at(m_delineated->main_var()); };
330 
332  const BaseDerivationRef<Properties>& base() const { return m_delineated->base(); };
333  Delineation& delin() { return m_delineated->delin(); };
334  const Assignment& underlying_sample() const { return m_delineated->underlying_sample(); }
335  DerivationRef<Properties>& underlying() { return m_delineated->underlying(); };
336  PolyPool& polys() { return m_delineated->polys(); };
337  Projections& proj() { return m_delineated->proj(); };
338  carl::Variable main_var() const { return m_delineated->main_var(); };
339  size_t level() const { return m_delineated->level(); };
340  template<typename P>
341  void insert(P property) { m_delineated->insert(property); };
342  template<typename P>
343  bool contains(const P& property) const { return m_delineated->contains(property); };
344  template<typename P>
345  const PropertiesTSet<P>& properties() const { return m_delineated->template properties<P>(); };
346 
348  m_delineated->merge_with(*other.delineated());
349  if (m_cell && other.m_cell) {
350  delineate_cell();
351  } else {
352  assert(!m_cell && !other.m_cell);
353  }
354  };
355 };
356 
357 /**
358  * Initializes a derivation according the the given assignment and level.
359  */
360 template<typename Properties>
361 DerivationRef<Properties> make_derivation(Projections& proj, const Assignment& assignment, size_t level) {
362  const auto& vars = proj.polys().var_order();
363 
364  auto zero_base = std::make_shared<BaseDerivation<Properties>>(proj, BaseDerivationRef<Properties>(nullptr), 0);
365  auto zero_delineated = std::make_shared<DelineatedDerivation<Properties>>(zero_base);
366  DerivationRef<Properties> current = std::make_shared<SampledDerivation<Properties>>(zero_delineated, RAN(0));
367 
368  for (size_t i = 1; i <= level; i++) {
369  auto base = std::make_shared<BaseDerivation<Properties>>(proj, current, i);
370  auto delineated = std::make_shared<DelineatedDerivation<Properties>>(base);
371  if (assignment.find(vars[i - 1]) != assignment.end()) {
372  current = std::make_shared<SampledDerivation<Properties>>(delineated, assignment.at(vars[i - 1]));
373  } else {
374  current = delineated;
375  }
376  }
377 
378  return current;
379 }
380 
381 /**
382  * Initializes a sampled derivation w.r.t. the delineated derivation and sample.
383  */
384 template<typename Properties>
386  auto base_ref = std::make_shared<BaseDerivation<Properties>>(*delineated->base());
387  auto delineated_ref = std::make_shared<DelineatedDerivation<Properties>>(base_ref, delineated->delin());
388  auto sampled_ref = std::make_shared<SampledDerivation<Properties>>(delineated_ref, main_sample);
389  sampled_ref->delineate_cell();
390  return sampled_ref;
391 }
392 
393 /**
394  * Initializes a sampled derivation w.r.t. the delineated derivation and sample.
395  */
396 template<typename Properties>
398  auto base_ref = std::make_shared<BaseDerivation<Properties>>(underlying->proj(), underlying, underlying->level()+1);
399  auto delineated_ref = std::make_shared<DelineatedDerivation<Properties>>(base_ref);
400  auto sampled_ref = std::make_shared<SampledDerivation<Properties>>(delineated_ref, main_sample);
401  return sampled_ref;
402 }
403 
404 /**
405  * Merges the underlying derivations of a set of sampled derivations. After the operation, all sampled derivations point to the same underlying derivation.
406  */
407 template<typename Properties>
408 void merge_underlying(std::vector<SampledDerivationRef<Properties>>& derivations) {
409  std::set<DerivationRef<Properties>> underlying;
410  for (auto& deriv : derivations) {
411  underlying.insert(deriv->underlying());
412  }
413  assert(!underlying.empty());
414  auto first_underlying = *underlying.begin();
415  for (auto iter = std::next(underlying.begin()); iter != underlying.end(); iter++) {
416  first_underlying.base().merge_with(iter->base());
417  }
418  for (auto& deriv : derivations) {
419  deriv->base()->m_underlying = first_underlying;
420  }
421 }
422 
423 /**
424  * Merges a set of sampled derivations. After the operation, all sampled derivations point to the same underlying derivation.
425  */
426 template<typename Properties>
428  auto first = *derivations.begin();
429  for (auto iter = std::next(derivations.begin()); iter != derivations.end(); iter++) {
430  first->base()->merge_with(*((*iter)->base()));
431  }
432  return first;
433 }
434 
435 
436 } // namespace smtrat::cadcells::datastructures
A BaseDerivation has a level and a set of properties of this level, and an underlying derivation repr...
Definition: derivation.h:147
friend void merge_underlying(std::vector< SampledDerivationRef< P >> &derivations)
const PropertiesTSet< P > & properties() const
Definition: derivation.h:200
BaseDerivation(Projections &projections, DerivationRef< Properties > underlying, size_t level)
Definition: derivation.h:159
DerivationRef< Properties > m_underlying
Definition: derivation.h:151
BaseDerivation(const BaseDerivation &other)
Definition: derivation.h:162
void merge_with(const BaseDerivation< Properties > &other)
Definition: derivation.h:204
bool contains(const P &property) const
Definition: derivation.h:189
DerivationRef< Properties > & underlying()
Definition: derivation.h:164
const DerivationRef< Properties > & underlying() const
Definition: derivation.h:165
A DelineatedDerivation is a BaseDerivation with a Delineation and an underlying SampledDerivation.
Definition: derivation.h:219
DelineatedDerivation(BaseDerivationRef< Properties > base)
Definition: derivation.h:225
void merge_with(const DelineatedDerivation< Properties > &other)
Definition: derivation.h:283
DelineatedDerivation(BaseDerivationRef< Properties > base, const Delineation &delineation)
Definition: derivation.h:229
const BaseDerivationRef< Properties > & base() const
Definition: derivation.h:237
BaseDerivationRef< Properties > & base()
Definition: derivation.h:234
const PropertiesTSet< P > & properties() const
Definition: derivation.h:279
const DerivationRef< Properties > & underlying() const
Definition: derivation.h:255
Represents the delineation of a set of polynomials (at a sample), that is.
Definition: delineation.h:118
void merge_with(const Delineation &other)
Definition: delineation.h:242
A reference to a derivation, which is either.
Definition: derivation.h:38
DerivationRef(const DelineatedDerivationRef< Properties > &data)
Definition: derivation.h:44
friend bool operator==(const DerivationRef< P > &lhs, const DerivationRef< P > &rhs)
Definition: derivation.h:133
friend bool operator<(const DerivationRef< P > &lhs, const DerivationRef< P > &rhs)
Definition: derivation.h:137
DerivationRef(const BaseDerivationRef< Properties > &data)
Definition: derivation.h:42
std::variant< BaseDerivationRef< Properties >, DelineatedDerivationRef< Properties >, SampledDerivationRef< Properties > > m_data
Definition: derivation.h:39
DerivationRef(const SampledDerivationRef< Properties > &data)
Definition: derivation.h:46
Encapsulates all computations on polynomials.
Definition: projections.h:46
A SampledDerivation is a DelineatedDerivation with a sample and an DelineationInterval w....
Definition: derivation.h:299
DelineatedDerivationRef< Properties > m_delineated
Definition: derivation.h:300
std::optional< DelineationInterval > m_cell
Definition: derivation.h:301
void delineate_cell()
Determines the cell w.r.t.
Definition: derivation.h:322
BaseDerivationRef< Properties > & base()
Definition: derivation.h:331
void merge_with(const SampledDerivation< Properties > &other)
Definition: derivation.h:347
DerivationRef< Properties > & underlying()
Definition: derivation.h:335
DelineatedDerivationRef< Properties > & delineated()
Definition: derivation.h:314
const PropertiesTSet< P > & properties() const
Definition: derivation.h:345
SampledDerivation(DelineatedDerivationRef< Properties > base, RAN main_sample)
Definition: derivation.h:307
const BaseDerivationRef< Properties > & base() const
Definition: derivation.h:332
const DelineatedDerivationRef< Properties > & delineated() const
Definition: derivation.h:315
const DelineationInterval & cell() const
Definition: derivation.h:317
Main datastructures.
Definition: delineation.h:9
bool operator==(const TaggedIndexedRoot &lhs, const TaggedIndexedRoot &rhs)
Definition: delineation.h:24
std::shared_ptr< DelineatedDerivation< Properties > > DelineatedDerivationRef
Definition: derivation.h:22
SampledDerivationRef< Properties > make_sampled_derivation(DelineatedDerivationRef< Properties > delineated, const RAN &main_sample)
Initializes a sampled derivation w.r.t.
Definition: derivation.h:385
void merge_underlying(std::vector< SampledDerivationRef< Properties >> &derivations)
Merges the underlying derivations of a set of sampled derivations.
Definition: derivation.h:408
DerivationRef< Properties > make_derivation(Projections &proj, const Assignment &assignment, size_t level)
Initializes a derivation according the the given assignment and level.
Definition: derivation.h:361
bool operator<(const TaggedIndexedRoot &lhs, const TaggedIndexedRoot &rhs)
Definition: delineation.h:27
std::shared_ptr< BaseDerivation< Properties > > BaseDerivationRef
Definition: derivation.h:20
std::shared_ptr< SampledDerivation< Properties > > SampledDerivationRef
Definition: derivation.h:25
SampledDerivationRef< Properties > merge(std::vector< SampledDerivationRef< Properties >> &derivations)
Merges a set of sampled derivations.
Definition: derivation.h:427
boost::container::flat_set< T > PropertiesTSet
Definition: properties.h:19
Polynomial::RootType RAN
Definition: common.h:24
carl::Assignment< RAN > Assignment
Definition: common.h:25
static const Assignment empty_assignment
Definition: common.h:27
std::vector< carl::Variable > vars(const std::pair< QuantifierType, std::vector< carl::Variable >> &p)
Definition: QEQuery.h:43
#define SMTRAT_LOG_FUNC(channel, args)
Definition: logging.h:38