SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
CADCore.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "../common.h"
4 #include "../Settings.h"
5 
7 
8 #include <fstream>
9 
10 namespace smtrat {
11 namespace cad {
12 
13 template<CoreHeuristic CH>
14 struct CADCore {};
15 
16 template<>
18  template<typename CAD>
19  Answer operator()(Assignment& assignment, CAD& cad, bool ignore_nullifications) {
20  cad.mLifting.resetFullSamples();
21  cad.mLifting.restoreRemovedSamples();
22  while (true) {
23  SMTRAT_LOG_DEBUG("smtrat.cad", "Current sample tree:" << std::endl << cad.mLifting.getTree());
24  SMTRAT_LOG_DEBUG("smtrat.cad", "Current sample queue:" << std::endl << cad.mLifting.getLiftingQueue());
25  Answer res = cad.checkFullSamples(assignment);
26  if (res == Answer::SAT) return Answer::SAT;
27 
28  if (!cad.mLifting.hasNextSample()) {
29  SMTRAT_LOG_DEBUG("smtrat.cad", "There is no sample to be lifted.");
30  break;
31  }
32  auto it = cad.mLifting.getNextSample();
33  Sample& s = *it;
34  SMTRAT_LOG_DEBUG("smtrat.cad", "Sample " << s << " at depth " << it.depth());
35  SMTRAT_LOG_DEBUG("smtrat.cad", "Current sample: " << cad.mLifting.printSample(it));
36  assert(0 <= it.depth() && it.depth() < cad.dim());
37  if (s.hasConflictWithConstraint()) {
38  SMTRAT_LOG_DEBUG("smtrat.cad", "Sample " << s << " already has a conflict.");
39  cad.mLifting.removeNextSample();
40  continue;
41  }
42  auto polyID = cad.mProjection.getPolyForLifting(cad.idLP(it.depth() + 1), s.liftedWith());
43  if (polyID) {
44  const auto& poly = cad.mProjection.getPolynomialById(cad.idLP(it.depth() + 1), *polyID);
45  SMTRAT_LOG_DEBUG("smtrat.cad", "Lifting " << s << " with " << poly);
46  if (!cad.mLifting.liftSample(it, poly, *polyID, ignore_nullifications)) return Answer::UNKNOWN;
47  } else {
48  cad.mLifting.removeNextSample();
49  if (!cad.mLifting.hasNextSample()) {
50  SMTRAT_LOG_DEBUG("smtrat.cad", "Got nothing to lift anymore, projecting into level " << idLP(it.depth() + 1) << " ...");
51  carl::Bitset gotNewPolys = cad.mProjection.projectNewPolynomial();
52  if (gotNewPolys.any()) {
53  SMTRAT_LOG_TRACE("smtrat.cad", "Current projection:" << std::endl << cad.mProjection);
54  cad.mLifting.restoreRemovedSamples();
55  }
56  }
57  }
58  }
59  return Answer::UNSAT;
60  }
61 };
62 
63 template<>
65  template<typename CAD>
66  Answer operator()(Assignment& assignment, CAD& cad, bool ignore_nullifications) {
67  cad.mLifting.resetFullSamples();
68  cad.mLifting.restoreRemovedSamples();
69  while (true) {
70  Answer res = cad.checkFullSamples(assignment);
71  if (res == Answer::SAT) return Answer::SAT;
72 
73  if (!cad.mLifting.hasNextSample()) {
74  SMTRAT_LOG_DEBUG("smtrat.cad", "There is no sample to be lifted.");
75  return Answer::UNSAT;
76  }
77 
78  auto it = cad.mLifting.getNextSample();
79  Sample& s = *it;
80  assert(0 <= it.depth() && it.depth() < cad.dim());
81  if (s.hasConflictWithConstraint()) {
82  cad.mLifting.removeNextSample();
83  continue;
84  }
85 
86  auto polyID = cad.mProjection.getPolyForLifting(cad.idLP(it.depth() + 1), s.liftedWith());
87  if (polyID) {
88  const auto& poly = cad.mProjection.getPolynomialById(cad.idLP(it.depth() + 1), *polyID);
89  SMTRAT_LOG_DEBUG("smtrat.cad", "Lifting " << s << " with " << poly);
90  if (!cad.mLifting.liftSample(it, poly, *polyID, ignore_nullifications)) return Answer::UNKNOWN;
91  } else {
92  SMTRAT_LOG_DEBUG("smtrat.cad", "Got no polynomial for " << s << ", projecting into level " << cad.idLP(it.depth() + 1) << " ...");
93  SMTRAT_LOG_DEBUG("smtrat.cad", "Current projection:" << std::endl << cad.mProjection);
94  auto gotNewPolys = cad.mProjection.projectNewPolynomial();
95  SMTRAT_LOG_DEBUG("smtrat.cad", "Tried to project polynomials into level " << cad.idLP(it.depth() + 1) << ", result = " << gotNewPolys);
96  if (gotNewPolys.any()) {
97  cad.mLifting.restoreRemovedSamples();
98  } else if (cad.mProjection.empty(cad.idLP(it.depth() + 1))) {
99  if (!cad.mLifting.addTrivialSample(it)) {
100  cad.mLifting.removeNextSample();
101  }
102  } else {
103  cad.mLifting.removeNextSample();
104  }
105  }
106  }
107  }
108 };
109 
110 template<>
112  template<typename CAD>
113  Answer operator()(Assignment& assignment, CAD& cad, bool ignore_nullifications) {
114  cad.mLifting.resetFullSamples();
115  while (true) {
116  cad.mLifting.restoreRemovedSamples();
117  while (cad.mLifting.hasNextSample() || cad.mLifting.hasFullSamples()) {
118  //SMTRAT_LOG_INFO("smtrat.cad", "Current Projection:" << std::endl << cad.mProjection);
119  //SMTRAT_LOG_INFO("smtrat.cad", "Current lifting" << std::endl << cad.mLifting.getTree());
120  Answer res = cad.checkFullSamples(assignment);
121  if (res == Answer::SAT) return Answer::SAT;
122  if (!cad.mLifting.hasNextSample()) break;
123 
124  auto it = cad.mLifting.getNextSample();
125  SMTRAT_LOG_TRACE("smtrat.cad", "Queue" << std::endl << cad.mLifting.getLiftingQueue());
126  Sample& s = *it;
127  assert(0 <= it.depth() && it.depth() < cad.dim());
128  SMTRAT_LOG_DEBUG("smtrat.cad", "Processing " << cad.mLifting.extractSampleMap(it));
129  if (it.depth() > 0 && cad.checkPartialSample(it, cad.idLP(it.depth())) == Answer::UNSAT) {
130  cad.mLifting.removeNextSample();
131  continue;
132  }
133  auto polyID = cad.mProjection.getPolyForLifting(cad.idLP(it.depth() + 1), s.liftedWith());
134  if (polyID) {
135  const auto& poly = cad.mProjection.getPolynomialById(cad.idLP(it.depth() + 1), *polyID);
136  SMTRAT_LOG_DEBUG("smtrat.cad", "Lifting " << cad.mLifting.extractSampleMap(it) << " with " << poly);
137  if (!cad.mLifting.liftSample(it, poly, *polyID, ignore_nullifications)) return Answer::UNKNOWN;
138  } else {
139  SMTRAT_LOG_DEBUG("smtrat.cad", "Current lifting" << std::endl << cad.mLifting.getTree());
140  SMTRAT_LOG_TRACE("smtrat.cad", "Queue" << std::endl << cad.mLifting.getLiftingQueue());
141  cad.mLifting.removeNextSample();
142  cad.mLifting.addTrivialSample(it);
143  }
144  if (CAD::SettingsT::debugStepsToTikz) {
145  cad.thp.addLifting(cad.mLifting);
146  cad.thp.addProjection(cad.mProjection);
147  cad.thp.step();
148  }
149  }
150  if (CAD::SettingsT::debugProjection) {
151  static std::size_t counter = 0;
152  counter++;
153  std::ofstream out("projection_" + std::to_string(counter) + ".dot");
154  out << "digraph G {" << std::endl;
155  cad.mProjection.exportAsDot(out);
156  out << "}" << std::endl;
157  out.close();
158  }
159  auto r = cad.mProjection.projectNewPolynomial();
160  if (r.none()) {
161  SMTRAT_LOG_INFO("smtrat.cad", "Projection has finished, returning UNSAT");
162  return Answer::UNSAT;
163  }
164  SMTRAT_LOG_INFO("smtrat.cad", "Projected into " << r << ", new projection is" << std::endl << cad.mProjection);
165  }
166  }
167 };
168 
169 template<>
171  template<typename It>
172  bool preferLifting(const It& it) {
173  return it->value().is_numeric();
174  }
175  template<typename CAD>
176  bool doProjection(CAD& cad) {
177  auto r = cad.mProjection.projectNewPolynomial();
178  if (r.none()) {
179  SMTRAT_LOG_INFO("smtrat.cad", "Projection has finished.");
180  return false;
181  }
182  SMTRAT_LOG_INFO("smtrat.cad", "Projected into " << r << ", new projection is" << std::endl << cad.mProjection);
183  return true;
184  }
185  template<typename CAD>
186  bool doLifting(CAD& cad, bool ignore_nullifications) {
187  if (!cad.mLifting.hasNextSample()) return false;
188  auto it = cad.mLifting.getNextSample();
189  SMTRAT_LOG_TRACE("smtrat.cad", "Queue" << std::endl << cad.mLifting.getLiftingQueue());
190  Sample& s = *it;
191  assert(0 <= it.depth() && it.depth() < cad.dim());
192  SMTRAT_LOG_DEBUG("smtrat.cad", "Processing " << cad.mLifting.extractSampleMap(it));
193  if (it.depth() > 0 && cad.checkPartialSample(it, cad.idLP(it.depth())) == Answer::UNSAT) {
194  cad.mLifting.removeNextSample();
195  return false;
196  }
197  auto polyID = cad.mProjection.getPolyForLifting(cad.idLP(it.depth() + 1), s.liftedWith());
198  if (polyID) {
199  const auto& poly = cad.mProjection.getPolynomialById(cad.idLP(it.depth() + 1), *polyID);
200  SMTRAT_LOG_DEBUG("smtrat.cad", "Lifting " << cad.mLifting.extractSampleMap(it) << " with " << poly);
201  if (!cad.mLifting.liftSample(it, poly, *polyID, ignore_nullifications)) return Answer::UNKNOWN;
202  } else {
203  SMTRAT_LOG_DEBUG("smtrat.cad", "Current lifting" << std::endl << cad.mLifting.getTree());
204  SMTRAT_LOG_TRACE("smtrat.cad", "Queue" << std::endl << cad.mLifting.getLiftingQueue());
205  cad.mLifting.removeNextSample();
206  cad.mLifting.addTrivialSample(it);
207  }
208  return true;
209  }
210  template<typename CAD>
211  Answer operator()(Assignment& assignment, CAD& cad, bool ignore_nullifications) {
212  cad.mLifting.restoreRemovedSamples();
213  cad.mLifting.resetFullSamples();
214  while (true) {
215  Answer res = cad.checkFullSamples(assignment);
216  if (res == Answer::SAT) return Answer::SAT;
217  if (!cad.mLifting.hasNextSample()) {
218  if (!doProjection(cad)) return Answer::UNSAT;
219  cad.mLifting.restoreRemovedSamples();
220  }
221  if (preferLifting(cad.mLifting.getNextSample())) {
222  doLifting(cad, ignore_nullifications);
223  } else {
224  doProjection(cad);
225  cad.mLifting.restoreRemovedSamples();
226  }
227  }
228  }
229 };
230 
231 template<>
233  template<typename CAD>
234  Answer operator()(Assignment& assignment, CAD& cad, bool ignore_nullifications) {
235  cad.mLifting.resetFullSamples();
236  cad.mLifting.restoreRemovedSamples();
237  while (true) {
238  carl::Bitset gotNewPolys = cad.mProjection.projectNewPolynomial();
239  if (gotNewPolys.none()) break;
240  }
241  while (cad.mLifting.hasNextSample()) {
242  auto it = cad.mLifting.getNextSample();
243  Sample& s = *it;
244  SMTRAT_LOG_DEBUG("smtrat.cad", "Sample " << s << " at depth " << it.depth());
245  SMTRAT_LOG_DEBUG("smtrat.cad", "Current sample: " << cad.mLifting.printSample(it));
246  assert(0 <= it.depth() && it.depth() < cad.dim());
247  if (s.hasConflictWithConstraint()) {
248  SMTRAT_LOG_DEBUG("smtrat.cad", "Sample " << s << " already has a conflict.");
249  cad.mLifting.removeNextSample();
250  continue;
251  }
252  auto polyID = cad.mProjection.getPolyForLifting(cad.idLP(it.depth() + 1), s.liftedWith());
253  if (polyID) {
254  const auto& poly = cad.mProjection.getPolynomialById(cad.idLP(it.depth() + 1), *polyID);
255  SMTRAT_LOG_DEBUG("smtrat.cad", "Lifting " << s << " with " << poly);
256  if (!cad.mLifting.liftSample(it, poly, *polyID, ignore_nullifications)) return Answer::UNKNOWN;
257  } else {
258  cad.mLifting.removeNextSample();
259  cad.mLifting.addTrivialSample(it);
260  }
261  }
262  std::size_t number_of_cells = 0;
263  const auto& tree = cad.mLifting.getTree();
264  for (auto it = tree.begin_leaf(); it != tree.end_leaf(); ++it) {
265  ++number_of_cells;
266  }
267  SMTRAT_LOG_WARN("smtrat.cad", "Got " << number_of_cells << " cells");
268 
269  auto assignments = cad.enumerateSolutions();
270 #ifdef LOGGING
271  for (const auto& a: assignments) {
272  SMTRAT_LOG_WARN("smtrat.cad", "Solution: " << a);
273  }
274 #endif
275 
276  if (assignments.empty()) return Answer::UNSAT;
277  assignment = assignments.front();
278  return Answer::SAT;
279  }
280 };
281 
282 }
283 }
std::size_t dim() const
Definition: CAD.h:68
LiftingTree< Settings > mLifting
Definition: CAD.h:29
Answer checkFullSamples(Assignment &assignment)
Definition: CAD.h:150
std::vector< Assignment > enumerateSolutions()
Definition: CAD.h:128
ProjectionT< Settings > mProjection
Definition: CAD.h:28
debug::TikzHistoryPrinter thp
Definition: CAD.h:43
Answer checkPartialSample(Iterator &it, std::size_t level)
Definition: CAD.h:176
std::size_t idLP(std::size_t level) const
Definition: CAD.h:38
const SampleLiftedWith & liftedWith() const
Definition: Sample.h:39
bool hasConflictWithConstraint() const
Definition: Sample.h:68
std::map< carl::Variable, RAN > Assignment
Definition: common.h:14
Class to create the formulas for axioms.
Answer
An enum with the possible answers a Module can give.
Definition: types.h:57
@ UNKNOWN
Definition: types.h:57
#define SMTRAT_LOG_TRACE(channel, msg)
Definition: logging.h:36
#define SMTRAT_LOG_WARN(channel, msg)
Definition: logging.h:33
#define SMTRAT_LOG_INFO(channel, msg)
Definition: logging.h:34
#define SMTRAT_LOG_DEBUG(channel, msg)
Definition: logging.h:35
Answer operator()(Assignment &assignment, CAD &cad, bool ignore_nullifications)
Definition: CADCore.h:19
Answer operator()(Assignment &assignment, CAD &cad, bool ignore_nullifications)
Definition: CADCore.h:234
bool doLifting(CAD &cad, bool ignore_nullifications)
Definition: CADCore.h:186
Answer operator()(Assignment &assignment, CAD &cad, bool ignore_nullifications)
Definition: CADCore.h:211
Answer operator()(Assignment &assignment, CAD &cad, bool ignore_nullifications)
Definition: CADCore.h:66
Answer operator()(Assignment &assignment, CAD &cad, bool ignore_nullifications)
Definition: CADCore.h:113