SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
ProjectionInformation.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "../common.h"
4 #include "../utils/Origin.h"
5 
6 #include <optional>
7 #include <vector>
8 
9 namespace smtrat::cad {
10 
12 public:
13  struct ECData {
14  std::size_t level = 0;
15  carl::Bitset polynomials;
16  };
17  using ECMap = std::map<Origin::BaseType, ECData>;
18 
20  std::vector<ECMap::const_iterator> mUsedEC;
21  // Inactive polynomials in level 0
22  carl::Bitset mInactive;
23 
24  void reset(std::size_t dim) {
25  mECs.clear();
26  mUsedEC.assign(dim, mECs.end());
27  }
28 
29  void createEC(const Origin::BaseType& origin) {
30  assert(mECs.find(origin) == mECs.end());
31  mECs.emplace(origin, ECData());
32  }
33 
34  bool isEC(const Origin::BaseType& origin) const {
35  return mECs.find(origin) != mECs.end();
36  }
37 
38  void addToEC(const Origin::BaseType& origin, std::size_t level, std::size_t pid) {
39  auto it = mECs.find(origin);
40  if (it == mECs.end()) return;
41  if (it->second.level == 0 || it->second.level == level) {
42  SMTRAT_LOG_DEBUG("smtrat.cad.projection", "Adding " << level << "/" << pid << " to EC " << origin);
43  it->second.polynomials.set(pid);
44  } else {
45  SMTRAT_LOG_DEBUG("smtrat.cad.projection", "EC " << origin << " is primitive due to " << level << "/" << pid);
46  }
47  }
48 
49  void removeEC(const Origin::BaseType& origin) {
50  mECs.erase(origin);
51  }
52 };
53 
55 private:
57  /// Which polynomials belong to this specific equational constraint.
58  carl::Bitset polynomials;
59  /// Whether this equational constraint can be used.
60  /// An equational can not be used, if some factor is primitive.
61  bool suitable = true;
62  };
63 
65  private:
66  /// A list of all ECs in this level, identified by their origin.
67  std::vector<EquationalConstraint> mData;
68  public:
69  /// Add a poly to the respective origin.
70  std::size_t addEC() {
71  mData.emplace_back();
72  return mData.size() - 1;
73  }
74 
75  void addPolyToEC(std::size_t id, std::size_t pid) {
76  mData[id].polynomials.set(pid);
77  }
78 
79  bool hasEC() const {
80  return !mData.empty();
81  }
82  std::size_t count() const {
83  return mData.size();
84  }
85  const auto& getEC(std::size_t ecid) const {
86  return mData[ecid];
87  }
88  auto& getEC(std::size_t ecid) {
89  return mData[ecid];
90  }
91  };
92 public:
93  struct LevelInfo {
94  /// Which polynomials are bounds.
95  carl::Bitset bounds;
96  /// Which polynomials have been evaluated w.r.t. purging.
97  carl::Bitset evaluated;
98  /// Which polynomials are purged from the projection. (usually due to bounds)
99  carl::Bitset purged;
100 
101  /// Equational constraints.
103 
104  bool isBound(std::size_t pid) const {
105  return bounds.test(pid);
106  }
107  void setBound(std::size_t pid, bool isBound) {
108  bounds.set(pid, isBound);
109  }
110 
111  bool isEvaluated(std::size_t pid) const {
112  return evaluated.test(pid);
113  }
114  void setEvaluated(std::size_t pid, bool isEvaluated) {
115  evaluated.set(pid, isEvaluated);
116  }
117 
118  bool isPurged(std::size_t pid) const {
119  return purged.test(pid);
120  }
121  void setPurged(std::size_t pid, bool isPurged) {
122  purged.set(pid, isPurged);
123  }
124 
126  evaluated -= purged;
127  }
129  evaluated &= purged;
130  }
131  };
132 private:
133  std::vector<LevelInfo> mLevelData;
134 
135 public:
136  bool hasInfo(std::size_t level) const {
137  return level < mLevelData.size();
138  }
139 
140  void emplace(std::size_t level) {
141  while (mLevelData.size() <= level) mLevelData.emplace_back();
142  }
143  const auto& operator()(std::size_t level) const {
144  assert(hasInfo(level));
145  return mLevelData[level];
146  }
147  auto& operator()(std::size_t level) {
148  assert(hasInfo(level));
149  return mLevelData[level];
150  }
151 
152  void reset(std::size_t dim) {
153  mLevelData.clear();
154  emplace(dim);
155  }
156 };
157 
159 public:
160  struct PolyInfo {
161  /// Origins of this polynomial.
163  };
164 private:
165  std::vector<std::vector<std::optional<PolyInfo>>> mPolyData;
166 
167 public:
168  bool hasInfo(std::size_t level, std::size_t pid) const {
169  assert(level < mPolyData.size());
170  if (mPolyData[level].size() <= pid) return false;
171  return mPolyData[level][pid].has_value();
172  }
173  void emplace(std::size_t level, std::size_t pid) {
174  while (mPolyData.size() <= level) mPolyData.emplace_back();
175  while (mPolyData[level].size() <= pid) mPolyData[level].emplace_back();
176  mPolyData[level][pid] = PolyInfo();
177  }
178  const auto& operator()(std::size_t level, std::size_t pid) const {
179  assert(hasInfo(level, pid));
180  return *mPolyData[level][pid];
181  }
182  auto& operator()(std::size_t level, std::size_t pid) {
183  assert(hasInfo(level, pid));
184  return *mPolyData[level][pid];
185  }
186  void clear(std::size_t level, std::size_t pid) {
187  mPolyData[level][pid] = std::nullopt;
188  }
189  void reset(std::size_t) {
190  mPolyData.clear();
191  }
192 };
193 
195 private:
199 public:
200  const auto& operator()() const {
201  return mGlobal;
202  }
203  auto& operator()() {
204  return mGlobal;
205  }
206 
207  const auto& operator()(std::size_t level) const {
208  return mLevel(level);
209  }
210  auto& operator()(std::size_t level) {
211  return mLevel(level);
212  }
213  bool hasInfo(std::size_t level) const {
214  return mLevel.hasInfo(level);
215  }
216 
217  const auto& operator()(std::size_t level, std::size_t pid) const {
218  return mPoly(level, pid);
219  }
220  auto& operator()(std::size_t level, std::size_t pid) {
221  return mPoly(level, pid);
222  }
223  void clear(std::size_t level, std::size_t pid) {
224  mPoly.clear(level, pid);
225  }
226  void emplace(std::size_t level, std::size_t pid) {
227  mPoly.emplace(level, pid);
228  }
229  bool hasInfo(std::size_t level, std::size_t pid) const {
230  return mPoly.hasInfo(level, pid);
231  }
232 
233  bool isActive(std::size_t level, std::size_t id) const {
234  if (level == 0) {
235  if ((*this)().mInactive.test(id)) {
236  SMTRAT_LOG_DEBUG("smtrat.cad.projection", level << "/" << id << " is inactive on level 0.");
237  return false;
238  }
239  if ((*this)(level).isEvaluated(id) && (*this)(level).isPurged(id)) {
240  SMTRAT_LOG_DEBUG("smtrat.cad.projection", level << "/" << id << " is inactive as being purged.");
241  return false;
242  }
243  SMTRAT_LOG_DEBUG("smtrat.cad.projection", level << "/" << id << " is active on level 0.");
244  return true;
245  }
246  if ((*this)(level).isBound(id)) {
247  SMTRAT_LOG_DEBUG("smtrat.cad.projection", level << "/" << id << " is active as a bound polynomial.");
248  return true;
249  }
250  if (!(*this)(level, id).origin.isActive()) {
251  SMTRAT_LOG_DEBUG("smtrat.cad.projection", level << "/" << id << " is inactive without active origins.");
252  return false;
253  }
254  if ((*this)(level).isEvaluated(id) && (*this)(level).isPurged(id)) {
255  SMTRAT_LOG_DEBUG("smtrat.cad.projection", level << "/" << id << " is inactive as being purged.");
256  return false;
257  }
258  SMTRAT_LOG_DEBUG("smtrat.cad.projection", level << "/" << id << " is active.");
259  return true;
260  }
261 
262  void reset(std::size_t dim) {
263  mGlobal.reset(dim);
264  mLevel.reset(dim);
265  mPoly.reset(dim);
266  }
267 
268  void addECConstraint(std::size_t pid) {
269  SMTRAT_LOG_DEBUG("smtrat.cad.projection", "Add EC " << pid);
270  std::size_t ecid = (*this)(0).ecs.addEC();
271  (*this)(0).ecs.addPolyToEC(ecid, pid);
272  }
273 
274  void removeECConstraint(std::size_t) {
275 
276  }
277 
278  bool hasEC(std::size_t level) const {
279  return (*this)(level).ecs.hasEC();
280  }
281  bool usingEC(std::size_t level) const {
282  return (*this)().mUsedEC[level] != (*this)().mECs.end();
283  }
284  const carl::Bitset& getUsedEC(std::size_t level) const {
285  assert(hasEC(level));
286  assert((*this)().mUsedEC[level]->second.level == level);
287  return (*this)().mUsedEC[level]->second.polynomials;
288  }
289  bool selectEC(std::size_t level) {
290  assert(hasEC(level));
291  assert(!usingEC(level));
292  for (std::size_t ecid = 0; ecid < (*this)(level).ecs.count(); ++ecid) {
293  if (!(*this)(level).ecs.getEC(ecid).suitable) continue;
294  const auto& polys = (*this)(level).ecs.getEC(ecid).polynomials;
295  bool ec_active = true;
296  for (auto pid: polys) {
297  if (!isActive(level, pid)) {
298  ec_active = false;
299  break;
300  }
301  }
302  if (!ec_active) continue;
303 
304  const auto& ecs = (*this)().mECs;
305  for (auto it = ecs.begin(); it != ecs.end(); ++it) {
306  //if (it->second == std::make_pair(level, ecid)) {
307  (*this)().mUsedEC[level] = it;
308  return true;
309  //}
310  }
311  }
312  return false;
313  }
314  void unselectEC(std::size_t level) {
315  (*this)().mUsedEC[level] = (*this)().mECs.end();
316  }
317 };
318 
319 inline std::ostream& operator<<(std::ostream& os, const ProjectionGlobalInformation& gi) {
320  for (const auto& ec: gi.mECs) {
321  os << "\t" << ec.first << " -> " << ec.second.level << "/" << ec.second.polynomials << std::endl;
322  }
323  return os;
324 }
325 inline std::ostream& operator<<(std::ostream& os, const ProjectionLevelInformation::LevelInfo& li) {
326  os << "bounds " << li.bounds << ", purged: " << li.purged << " / " << li.evaluated;
327  return os;
328 }
329 inline std::ostream& operator<<(std::ostream& os, const ProjectionPolynomialInformation::PolyInfo& pi) {
330  os << "origin: " << pi.origin;
331  return os;
332 }
333 
334 }
This class represents one or more origins of some object.
Definition: Origin.h:21
bool isEC(const Origin::BaseType &origin) const
void createEC(const Origin::BaseType &origin)
std::vector< ECMap::const_iterator > mUsedEC
void addToEC(const Origin::BaseType &origin, std::size_t level, std::size_t pid)
void removeEC(const Origin::BaseType &origin)
std::map< Origin::BaseType, ECData > ECMap
bool usingEC(std::size_t level) const
void emplace(std::size_t level, std::size_t pid)
ProjectionGlobalInformation mGlobal
bool isActive(std::size_t level, std::size_t id) const
auto & operator()(std::size_t level, std::size_t pid)
const carl::Bitset & getUsedEC(std::size_t level) const
void clear(std::size_t level, std::size_t pid)
bool hasEC(std::size_t level) const
ProjectionPolynomialInformation mPoly
const auto & operator()(std::size_t level) const
bool hasInfo(std::size_t level, std::size_t pid) const
const auto & operator()(std::size_t level, std::size_t pid) const
bool hasInfo(std::size_t level) const
const auto & operator()(std::size_t level) const
const auto & operator()(std::size_t level, std::size_t pid) const
void clear(std::size_t level, std::size_t pid)
std::vector< std::vector< std::optional< PolyInfo > > > mPolyData
auto & operator()(std::size_t level, std::size_t pid)
void emplace(std::size_t level, std::size_t pid)
bool hasInfo(std::size_t level, std::size_t pid) const
std::ostream & operator<<(std::ostream &os, const SampleIteratorQueue< I, C > &siq)
#define SMTRAT_LOG_DEBUG(channel, msg)
Definition: logging.h:35
bool suitable
Whether this equational constraint can be used.
carl::Bitset polynomials
Which polynomials belong to this specific equational constraint.
std::vector< EquationalConstraint > mData
A list of all ECs in this level, identified by their origin.
std::size_t addEC()
Add a poly to the respective origin.
carl::Bitset bounds
Which polynomials are bounds.
carl::Bitset purged
Which polynomials are purged from the projection. (usually due to bounds)
carl::Bitset evaluated
Which polynomials have been evaluated w.r.t. purging.
void setEvaluated(std::size_t pid, bool isEvaluated)
EquationalConstraints ecs
Equational constraints.