SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
Projection.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 <smtrat-cad/common.h>
11 
12 namespace smtrat::qe::cad {
13 
15  using smtrat::cad::Origin;
16  using smtrat::cad::UPoly;
17 
18  template<typename Settings>
19  class Projection: public BaseProjection<Settings> {
20  private:
22  using typename Super::Constraints;
24  using Super::mOperator;
26  using Super::getID;
27  using Super::freeID;
28  using Super::var;
29  public:
30  using Super::dim;
31  using Super::size;
32 
33  private:
34  template<typename S>
35  friend std::ostream& operator<<(std::ostream& os, const Projection<S>& p);
36 
37  std::vector<std::map<UPoly,std::size_t>> mPolynomialIDs;
38  std::vector<std::vector<std::optional<std::pair<UPoly,Origin>>>> mPolynomials;
39 
40  auto& polyIDs(std::size_t level) {
41  assert(level > 0 && level <= dim());
42  return mPolynomialIDs[level - 1];
43  }
44  const auto& polyIDs(std::size_t level) const {
45  assert(level > 0 && level <= dim());
46  return mPolynomialIDs[level - 1];
47  }
48  auto& polys(std::size_t level) {
49  assert(level > 0 && level <= dim());
50  return mPolynomials[level - 1];
51  }
52  const auto& polys(std::size_t level) const {
53  assert(level > 0 && level <= dim());
54  return mPolynomials[level - 1];
55  }
56 
57  carl::Bitset addToProjection(std::size_t level, const UPoly& p, const Origin::BaseType& origin) {
58  assert(level > 0 && level <= dim());
59  if (smtrat::cad::projection::canBeRemoved(p)) return carl::Bitset();
60  SMTRAT_LOG_DEBUG("smtrat.cad.projection", "Adding " << p << " to projection level " << level);
61  assert(p.main_var() == var(level));
62  auto it = polyIDs(level).find(p);
63  if (it != polyIDs(level).end()) {
64  assert(polys(level)[it->second]);
65  polys(level)[it->second]->second += origin;
66  return carl::Bitset();
67  }
68  std::size_t newID = getID(level);;
69  carl::Bitset res;
70  if (level < dim()) {
71  mOperator(Settings::projectionOperator, p, var(level + 1),
72  [&](const UPoly& np){ res |= addToProjection(level + 1, np, Origin::BaseType(level, newID)); }
73  );
74  for (const auto& it: polyIDs(level)) {
75  assert(polys(level)[it.second]);
76  auto newOrigin = Origin::BaseType(level, newID, it.second);
77  mOperator(Settings::projectionOperator, p, it.first, var(level + 1),
78  [&](const UPoly& np){ res |= addToProjection(level + 1, np, newOrigin); }
79  );
80  }
81  }
82  if (newID >= polys(level).size()) {
83  polys(level).resize(newID + 1);
84  }
85  polys(level)[newID] = std::make_pair(p, Origin(origin));
86  polyIDs(level).emplace(p, newID);
87  mLiftingQueues[level - 1].insert(newID);
88  res.set(level);
89  return res;
90  }
91 
92  public:
93  Projection(const Constraints& c): Super(c) {}
94 
95  void reset() {
96  Super::reset();
97  mPolynomials.clear();
98  mPolynomials.resize(dim());
99  mPolynomialIDs.clear();
100  mPolynomialIDs.resize(dim());
101  }
102 
103  carl::Bitset addPolynomial(const UPoly& p, std::size_t cid, bool) override {
104  assert(p.main_var() == var(1));
105  return addToProjection(1, p, Origin::BaseType(0, cid));
106  }
107  void removePolynomial(const UPoly&, std::size_t cid, bool) override {
108  SMTRAT_LOG_DEBUG("smtrat.cad.projection", "Removing " << cid);
109  carl::Bitset filter = carl::Bitset().set(cid);
110  for (std::size_t level = 1; level <= dim(); level++) {
111  for (std::size_t lvl = level; lvl <= dim(); lvl++) {
112  for (auto it = polyIDs(level).begin(); it != polyIDs(level).end(); it++) {
113  assert(polys(level)[it->second]);
114  polys(level)[it->second]->second.erase(level, filter);
115  }
116  }
117  carl::Bitset removed;
118  for (auto it = polyIDs(level).begin(); it != polyIDs(level).end();) {
119  std::size_t id = it->second;
120  assert(polys(level)[id]);
121  if (polys(level)[id]->second.empty()) {
122  freeID(level, id);
123  mLiftingQueues[level - 1].erase(id);
124  removed.set(id);
125  polys(level)[id] = std::nullopt;
126  it = polyIDs(level).erase(it);
127  } else {
128  it++;
129  }
130  }
131  SMTRAT_LOG_TRACE("smtrat.cad.projection", "Calling callback for level " << level << ", removed [" << removed << "]");
132  callRemoveCallback(level, removed);
133  filter = removed;
134  }
135  }
136 
137  bool testProjectionFactor(std::size_t level, std::size_t id) const {
138  for(auto it = polys(level)[id]->second.begin(); it != polys(level)[id]->second.end(); it++) {
139  if(hasPolynomialById(it->level, it->first) && hasPolynomialById(it->level, it->second)) {
140  return true;
141  }
142  }
143  return false;
144  }
145  void removeProjectionFactor(std::size_t level, std::size_t id) {
146  auto p = polys(level)[id];
147  auto it = polyIDs(level).find(p->first);
148 
149  polyIDs(level).erase(it);
150  polys(level)[id] = std::nullopt;
151  freeID(level, id);
152 
153  carl::Bitset removed;
154  removed.set(id);
155  callRemoveCallback(level, removed);
156  }
157 
158  std::size_t size(std::size_t level) const override {
159  return polys(level).size();
160  }
161  bool empty(std::size_t level) const override {
162  return polyIDs(level).empty();
163  }
164 
165  bool hasPolynomialById(std::size_t level, std::size_t id) const override {
166  assert(level > 0 && level <= dim());
167  assert(id < polys(level).size());
168  return bool(polys(level)[id]);
169  }
170  const UPoly& getPolynomialById(std::size_t level, std::size_t id) const override {
171  assert(level > 0 && level <= dim());
172  assert(id < polys(level).size());
173  assert(polys(level)[id]);
174  return polys(level)[id]->first;
175  }
176  };
177 
178  template<typename S>
179  std::ostream& operator<<(std::ostream& os, const Projection<S>& p) {
180  for (std::size_t level = 1; level <= p.dim(); level++) {
181  os << level << " " << p.var(level) << ":" << std::endl;
182  for (const auto& it: p.polyIDs(level)) {
183  assert(p.polys(level)[it.second]);
184  os << "\t" << it.second << ": " << p.polys(level)[it.second]->first << " " << p.polys(level)[it.second]->second << std::endl;
185  }
186  }
187  return os;
188  }
189 }
void reset()
Resets all datastructures, use the given variables from now on.
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
CADConstraints< Settings::backtracking > Constraints
This class represents one or more origins of some object.
Definition: Origin.h:21
carl::Bitset addToProjection(std::size_t level, const UPoly &p, const Origin::BaseType &origin)
Definition: Projection.h:57
ProjectionOperator mOperator
The projection operator.
bool hasPolynomialById(std::size_t level, std::size_t id) const override
Definition: Projection.h:165
bool empty(std::size_t level) const override
Definition: Projection.h:161
virtual std::size_t size(std::size_t level) const=0
auto & polyIDs(std::size_t level)
Definition: Projection.h:40
std::size_t dim() const
Returns the dimension of the projection.
std::size_t size(std::size_t level) const override
Definition: Projection.h:158
void freeID(std::size_t level, std::size_t id)
Frees a currently used polynomial id for the given level.
std::vector< std::map< UPoly, std::size_t > > mPolynomialIDs
Definition: Projection.h:37
std::size_t getID(std::size_t level)
Returns a fresh polynomial id for the given level.
bool testProjectionFactor(std::size_t level, std::size_t id) const
Definition: Projection.h:137
const auto & polys(std::size_t level) const
Definition: Projection.h:52
friend std::ostream & operator<<(std::ostream &os, const Projection< S > &p)
Definition: Projection.h:179
const UPoly & getPolynomialById(std::size_t level, std::size_t id) const override
Retrieves a polynomial from its id.
Definition: Projection.h:170
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...
const auto & polyIDs(std::size_t level) const
Definition: Projection.h:44
Projection(const Constraints &c)
Definition: Projection.h:93
carl::Bitset addPolynomial(const UPoly &p, std::size_t cid, bool) override
Definition: Projection.h:103
void removePolynomial(const UPoly &, std::size_t cid, bool) override
Definition: Projection.h:107
auto & polys(std::size_t level)
Definition: Projection.h:48
std::vector< std::vector< std::optional< std::pair< UPoly, Origin > > > > mPolynomials
Definition: Projection.h:38
void callRemoveCallback(std::size_t level, const SampleLiftedWith &slw) const
void removeProjectionFactor(std::size_t level, std::size_t id)
Definition: Projection.h:145
bool canBeRemoved(const UPoly &p)
Checks whether a polynomial can safely be ignored.
carl::UnivariatePolynomial< Poly > UPoly
Definition: common.h:17
std::ostream & operator<<(std::ostream &os, const Projection< S > &p)
Definition: Projection.h:179
#define SMTRAT_LOG_TRACE(channel, msg)
Definition: logging.h:36
#define SMTRAT_LOG_DEBUG(channel, msg)
Definition: logging.h:35