SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
Projection_NU.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <iostream>
4 #include <map>
5 #include <vector>
6 
7 #include <optional>
8 
9 #include "../common.h"
10 #include "BaseProjection.h"
11 
12 namespace smtrat {
13 namespace cad {
14 
15  /**
16  * This class implements a projection that supports no incrementality and allows backtracking to be out of order.
17  */
18  template<typename Settings>
20  private:
22  using typename Super::Constraints;
23  using Super::mLiftingQueues;
24  using Super::mOperator;
25  using Super::callRemoveCallback;
26  using Super::getID;
27  using Super::freeID;
28  using Super::var;
29  public:
30  using Super::dim;
31  using Super::size;
32  private:
33 
34  template<typename S>
35  friend std::ostream& operator<<(std::ostream& os, const Projection<Incrementality::NONE, Backtracking::UNORDERED, S>& p);
36  // Maps polynomials to a (per level) unique ID.
37  std::vector<std::map<UPoly,std::size_t>> mPolynomialIDs;
38  // Stores polynomials with their origins, being pairs of polynomials from the level above.
39  std::vector<std::vector<std::optional<std::pair<UPoly,Origin>>>> mPolynomials;
40 
41  auto& polyIDs(std::size_t level) {
42  assert(level > 0 && level <= dim());
43  return mPolynomialIDs[level - 1];
44  }
45  const auto& polyIDs(std::size_t level) const {
46  assert(level > 0 && level <= dim());
47  return mPolynomialIDs[level - 1];
48  }
49  auto& polys(std::size_t level) {
50  assert(level > 0 && level <= dim());
51  return mPolynomials[level - 1];
52  }
53  const auto& polys(std::size_t level) const {
54  assert(level > 0 && level <= dim());
55  return mPolynomials[level - 1];
56  }
57 
58  carl::Bitset addToProjection(std::size_t level, const UPoly& p, const Origin::BaseType& origin) {
59  assert(level > 0 && level <= dim());
60  if (projection::canBeRemoved(p)) return carl::Bitset();
61  SMTRAT_LOG_DEBUG("smtrat.cad.projection", "Adding " << p << " to projection level " << level);
62  assert(p.main_var() == var(level));
63  auto it = polyIDs(level).find(p);
64  if (it != polyIDs(level).end()) {
65  assert(polys(level)[it->second]);
66  polys(level)[it->second]->second += origin;
67  return carl::Bitset();
68  }
69  std::size_t newID = getID(level);;
70  carl::Bitset res;
71  if (level < dim()) {
72  mOperator(Settings::projectionOperator, p, var(level + 1),
73  [&](const UPoly& np){ res |= addToProjection(level + 1, np, Origin::BaseType(level, newID)); }
74  );
75  for (const auto& it: polyIDs(level)) {
76  assert(polys(level)[it.second]);
77  auto newOrigin = Origin::BaseType(level, newID, it.second);
78  mOperator(Settings::projectionOperator, p, it.first, var(level + 1),
79  [&](const UPoly& np){ res |= addToProjection(level + 1, np, newOrigin); }
80  );
81  }
82  }
83  if (newID >= polys(level).size()) {
84  polys(level).resize(newID + 1);
85  }
86  polys(level)[newID] = std::make_pair(p, Origin(origin));
87  polyIDs(level).emplace(p, newID);
88  mLiftingQueues[level - 1].insert(newID);
89  res.set(level);
90  return res;
91  }
92  public:
93  Projection(const Constraints& c): Super(c) {}
94  void reset() {
95  Super::reset();
96  mPolynomials.clear();
97  mPolynomials.resize(dim());
98  mPolynomialIDs.clear();
99  mPolynomialIDs.resize(dim());
100  }
101  carl::Bitset addPolynomial(const UPoly& p, std::size_t cid, bool) override {
102  assert(p.main_var() == var(1));
103  return addToProjection(1, p, Origin::BaseType(0, cid));
104  }
105  void removePolynomial(const UPoly&, std::size_t cid, bool) override {
106  SMTRAT_LOG_DEBUG("smtrat.cad.projection", "Removing " << cid);
107  carl::Bitset filter = carl::Bitset().set(cid);
108  for (std::size_t level = 1; level <= dim(); level++) {
109  for (std::size_t lvl = level; lvl <= dim(); lvl++) {
110  for (auto it = polyIDs(level).begin(); it != polyIDs(level).end(); it++) {
111  assert(polys(level)[it->second]);
112  polys(level)[it->second]->second.erase(level, filter);
113  }
114  }
115  carl::Bitset removed;
116  for (auto it = polyIDs(level).begin(); it != polyIDs(level).end();) {
117  std::size_t id = it->second;
118  assert(polys(level)[id]);
119  if (polys(level)[id]->second.empty()) {
120  freeID(level, id);
121  mLiftingQueues[level - 1].erase(id);
122  removed.set(id);
123  polys(level)[id] = std::nullopt;
124  it = polyIDs(level).erase(it);
125  } else {
126  it++;
127  }
128  }
129  SMTRAT_LOG_TRACE("smtrat.cad.projection", "Calling callback for level " << level << ", removed [" << removed << "]");
130  callRemoveCallback(level, removed);
131  filter = removed;
132  }
133  }
134 
135  std::size_t size(std::size_t level) const override {
136  return polyIDs(level).size();
137  }
138  bool empty(std::size_t level) const override {
139  return polyIDs(level).empty();
140  }
141 
142  carl::Bitset projectNewPolynomial(const ConstraintSelection& = carl::Bitset(true)) {
143  return carl::Bitset();
144  }
145 
146 
147  bool hasPolynomialById(std::size_t level, std::size_t id) const override {
148  assert(level > 0 && level <= dim());
149  assert(id < polys(level).size());
150  return bool(polys(level)[id]);
151  }
152  const UPoly& getPolynomialById(std::size_t level, std::size_t id) const override {
153  assert(level > 0 && level <= dim());
154  assert(id < polys(level).size());
155  assert(polys(level)[id]);
156  return polys(level)[id]->first;
157  }
158  };
159 
160  template<typename S>
162  for (std::size_t level = 1; level <= p.dim(); level++) {
163  os << level << " " << p.var(level) << ":" << std::endl;
164  for (const auto& it: p.polyIDs(level)) {
165  assert(p.polys(level)[it.second]);
166  os << "\t" << it.second << ": " << p.polys(level)[it.second]->first << " " << p.polys(level)[it.second]->second << std::endl;
167  }
168  }
169  return os;
170  }
171 }
172 }
ProjectionOperator mOperator
The projection operator.
std::size_t dim() const
Returns the dimension of the projection.
std::size_t size() const
void freeID(std::size_t level, std::size_t id)
Frees a currently used polynomial id for the given level.
std::size_t getID(std::size_t level)
Returns a fresh polynomial id for the given level.
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
This class represents one or more origins of some object.
Definition: Origin.h:21
void removePolynomial(const UPoly &, std::size_t cid, bool) override
Removes the given polynomial from the projection.
carl::Bitset addToProjection(std::size_t level, const UPoly &p, const Origin::BaseType &origin)
Definition: Projection_NU.h:58
carl::Bitset addPolynomial(const UPoly &p, std::size_t cid, bool) override
Adds the given polynomial to the projection.
std::vector< std::vector< std::optional< std::pair< UPoly, Origin > > > > mPolynomials
Definition: Projection_NU.h:39
const UPoly & getPolynomialById(std::size_t level, std::size_t id) const override
Retrieves a polynomial from its id.
carl::Bitset projectNewPolynomial(const ConstraintSelection &=carl::Bitset(true))
bool hasPolynomialById(std::size_t level, std::size_t id) const override
int var(Lit p)
Definition: SolverTypes.h:64
bool canBeRemoved(const UPoly &p)
Checks whether a polynomial can safely be ignored.
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_TRACE(channel, msg)
Definition: logging.h:36
#define SMTRAT_LOG_DEBUG(channel, msg)
Definition: logging.h:35