SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
Projection_NO.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <iostream>
4 #include <map>
5 #include <vector>
6 
7 #include "../common.h"
8 #include "BaseProjection.h"
9 
10 namespace smtrat {
11 namespace cad {
12 
13  /**
14  * This class implements a projection that supports no incrementality and expects backtracking to be in order.
15  *
16  * It is based on the following data structures:
17  * - mPolynomialIDs: maps polynomials to a (per level) unique id
18  * - mPolynomials: stores polynomials as a list (per level) with their origin
19  *
20  * The origin of a polynomial in level zero is the id of the corresponding constraint.
21  * For all other levels, it is the id of some polynomial from level zero such that the polynomial must be removed if the origin is removed.
22  * For a single projection operation, the resulting origin is the largest of the participating polynomials.
23  * If a polynomial is derived from multiple projection operations, the origin is the earliest and thus smallest, at least for this non-incremental setting.
24  */
25  template<typename Settings>
27  private:
29  using typename Super::Constraints;
30  using Super::mLiftingQueues;
31  using Super::mOperator;
32  using Super::callRemoveCallback;
33  using Super::var;
34  public:
35  using Super::dim;
36  using Super::size;
37  private:
38 
39  template<typename S>
40  friend std::ostream& operator<<(std::ostream& os, const Projection<Incrementality::NONE, Backtracking::ORDERED, S>& p);
41  /// Maps polynomials to a (per level) unique ID.
42  std::vector<std::map<UPoly,std::size_t>> mPolynomialIDs;
43  /// Stores polynomials with their origin constraint ids.
44  std::vector<std::vector<std::pair<UPoly,std::size_t>>> mPolynomials;
45 
46  auto& polyIDs(std::size_t level) {
47  assert(level > 0 && level <= dim());
48  return mPolynomialIDs[level - 1];
49  }
50  const auto& polyIDs(std::size_t level) const {
51  assert(level > 0 && level <= dim());
52  return mPolynomialIDs[level - 1];
53  }
54  auto& polys(std::size_t level) {
55  assert(level > 0 && level <= dim());
56  return mPolynomials[level - 1];
57  }
58  const auto& polys(std::size_t level) const {
59  assert(level > 0 && level <= dim());
60  return mPolynomials[level - 1];
61  }
62 
63  /// Inserts a polynomial with the given origin into the given level.
64  void insertPolynomial(std::size_t level, const UPoly& p, std::size_t origin) {
65  assert(level > 0 && level <= dim());
66  assert(polyIDs(level).find(p) == polyIDs(level).end());
67  std::size_t id = polys(level).size();
68  polys(level).emplace_back(p, origin);
69  polyIDs(level).emplace(p, id);
70  mLiftingQueues[level - 1].insert(id);
71  }
72  /// Removed the last polynomial from the given level.
73  void removePolynomial(std::size_t level) {
74  assert(level > 0 && level <= dim());
75  auto it = polyIDs(level).find(polys(level).back().first);
76  assert(it != polyIDs(level).end());
77  mLiftingQueues[level - 1].erase(it->second);
78  polyIDs(level).erase(it);
79  polys(level).pop_back();
80  }
81 
82  /// Adds a new polynomial to the given level and perform the projection recursively.
83  carl::Bitset addToProjection(std::size_t level, const UPoly& p, std::size_t origin) {
84  assert(level > 0 && level <= dim());
85  SMTRAT_LOG_DEBUG("smtrat.cad.projection", "Adding " << p << " to projection level " << level);
86  if (projection::canBeRemoved(p)) return carl::Bitset();
87  if (level < dim() && projection::canBeForwarded(level, p)) {
88  return addToProjection(level + 1, carl::switch_main_variable(p, var(level+1)), origin);
89  }
90  assert(p.main_var() == var(level));
91  auto it = polyIDs(level).find(p);
92  if (it != polyIDs(level).end()) {
93  // We already have this polynomial.
94  if (level > 0) {
95  assert(polys(level)[it->second].second <= origin);
96  }
97  return carl::Bitset();
98  }
99  carl::Bitset res;
100  if (level < dim()) {
101  mOperator(Settings::projectionOperator, p, var(level + 1),
102  [&](const UPoly& np){ res |= addToProjection(level + 1, np, origin); }
103  );
104  for (const auto& it: polys(level)) {
105  std::size_t newOrigin = std::max(origin, it.second);
106  mOperator(Settings::projectionOperator, p, it.first, var(level + 1),
107  [&](const UPoly& np){ res |= addToProjection(level + 1, np, newOrigin); }
108  );
109  }
110  }
111  // Actually insert afterwards to avoid pairwise projection with itself.
112  insertPolynomial(level, p, origin);
113  res.set(level);
114  return res;
115  }
116  public:
117  Projection(const Constraints& c): Super(c) {}
118  /**
119  * Resets all datastructures, use the given variables from now on.
120  */
121  void reset() {
122  Super::reset();
123  mPolynomials.clear();
124  mPolynomials.resize(dim());
125  mPolynomialIDs.clear();
126  mPolynomialIDs.resize(dim());
127  }
128  /**
129  * Adds the given polynomial to the projection with the given constraint id as origin.
130  * Asserts that the main variable of the polynomial is the first variable.
131  */
132  carl::Bitset addPolynomial(const UPoly& p, std::size_t cid, bool) override {
133  SMTRAT_LOG_DEBUG("smtrat.cad.projection", "Adding " << p << " from constraint " << cid);
134  assert(p.main_var() == var(1));
135  return addToProjection(1, p, cid);
136  }
137  /**
138  * Removed the given polynomial from the projection.
139  * Asserts that this polynomial was the one added last and has the given constraint id as origin.
140  * Calls the callback function for every level with a mask designating the polynomials removed from this level.
141  */
142  void removePolynomial(const UPoly& p, std::size_t cid, bool) override {
143  SMTRAT_LOG_DEBUG("smtrat.cad.projection", "Removing " << p << " from constraint " << cid);
144  // Remove all polynomials from all levels that have the removed constraint as origin.
145  for (std::size_t level = 1; level <= dim(); level++) {
146  carl::Bitset removed;
147  if (polys(level).empty()) continue;
148  while (polys(level).back().second == cid) {
149  std::size_t id = polys(level).size() - 1;
150  mLiftingQueues[level - 1].erase(id);
151  removePolynomial(level);
152  removed.set(id);
153  }
154  assert(polys(level).empty() || polys(level).back().second < cid);
155  callRemoveCallback(level, removed);
156  }
157  }
158 
159  /// Returns the number of polynomials in this level.
160  std::size_t size(std::size_t level) const override {
161  return polys(level).size();
162  }
163  /// Returns whether the number of polynomials in this level is zero.
164  bool empty(std::size_t level) const override {
165  return polys(level).empty();
166  }
167 
168  /// Returns false, as the projection is not incremental.
169  carl::Bitset projectNewPolynomial(const ConstraintSelection& = carl::Bitset(true)) {
170  return carl::Bitset();
171  }
172  bool hasPolynomialById(std::size_t level, std::size_t id) const override {
173  assert(level > 0 && level <= dim());
174  return id < polys(level).size();
175  }
176  /// Get the polynomial from this level with the given id.
177  const UPoly& getPolynomialById(std::size_t level, std::size_t id) const override {
178  assert(level > 0 && level <= dim());
179  assert(id < polys(level).size());
180  return polys(level)[id].first;
181  }
182  };
183 
184  template<typename S>
185  std::ostream& operator<<(std::ostream& os, const Projection<Incrementality::NONE, Backtracking::ORDERED, S>& p) {
186  for (std::size_t level = 1; level <= p.dim(); level++) {
187  os << level << " / " << p.var(level) << ":" << std::endl;
188  for (const auto& it: p.polys(level)) {
189  os << "\t" << it.first << " [" << it.second << "]" << std::endl;
190  }
191  }
192  return os;
193  }
194 }
195 }
void removePolynomial(const Poly &p, std::size_t cid, bool isBound)
Removes the given polynomial from the projection. Converts to a UPoly and calls the appropriate overl...
ProjectionOperator mOperator
The projection operator.
std::size_t dim() const
Returns the dimension of the projection.
std::size_t size() const
std::vector< PolynomialLiftingQueue< BaseProjection > > mLiftingQueues
List of lifting queues that can be used for incremental projection.
carl::Variable var(std::size_t level) const
Returns the variable that corresponds to the given level, that is the variable eliminated in this lev...
void callRemoveCallback(std::size_t level, const SampleLiftedWith &slw) const
void insertPolynomial(std::size_t level, const UPoly &p, std::size_t origin)
Inserts a polynomial with the given origin into the given level.
Definition: Projection_NO.h:64
bool hasPolynomialById(std::size_t level, std::size_t id) const override
std::size_t size(std::size_t level) const override
Returns the number of polynomials in this level.
std::vector< std::map< UPoly, std::size_t > > mPolynomialIDs
Maps polynomials to a (per level) unique ID.
Definition: Projection_NO.h:42
bool empty(std::size_t level) const override
Returns whether the number of polynomials in this level is zero.
std::vector< std::vector< std::pair< UPoly, std::size_t > > > mPolynomials
Stores polynomials with their origin constraint ids.
Definition: Projection_NO.h:44
void removePolynomial(const UPoly &p, std::size_t cid, bool) override
Removed the given polynomial from the projection.
void reset()
Resets all datastructures, use the given variables from now on.
void removePolynomial(std::size_t level)
Removed the last polynomial from the given level.
Definition: Projection_NO.h:73
carl::Bitset addPolynomial(const UPoly &p, std::size_t cid, bool) override
Adds the given polynomial to the projection with the given constraint id as origin.
const UPoly & getPolynomialById(std::size_t level, std::size_t id) const override
Get the polynomial from this level with the given id.
carl::Bitset projectNewPolynomial(const ConstraintSelection &=carl::Bitset(true))
Returns false, as the projection is not incremental.
carl::Bitset addToProjection(std::size_t level, const UPoly &p, std::size_t origin)
Adds a new polynomial to the given level and perform the projection recursively.
Definition: Projection_NO.h:83
int var(Lit p)
Definition: SolverTypes.h:64
static bool find(V &ts, const T &t)
Definition: Alg.h:47
bool canBeRemoved(const UPoly &p)
Checks whether a polynomial can safely be ignored.
bool canBeForwarded(std::size_t, const UPoly &p)
Checks whether a polynomial can safely be forwarded to the next level.
std::ostream & operator<<(std::ostream &os, const SampleIteratorQueue< I, C > &siq)
carl::UnivariatePolynomial< Poly > UPoly
Definition: common.h:17
Incrementality
Definition: Settings.h:7
carl::Bitset ConstraintSelection
Definition: common.h:12
Class to create the formulas for axioms.
@ NONE
Definition: types.h:53
const settings::Settings & Settings()
Definition: Settings.h:96
#define SMTRAT_LOG_DEBUG(channel, msg)
Definition: logging.h:35