SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
CAD.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vector>
4 
5 #include <carl-covering/carl-covering.h>
6 
7 #include "common.h"
9 #include "lifting/LiftingTree.h"
10 #include "utils/CADConstraints.h"
11 #include "utils/CADCore.h"
12 #include "utils/ConflictGraph.h"
13 #include "utils/MISGeneration.h"
15 
16 namespace smtrat {
17 namespace cad {
18 
19  template<typename Settings>
20  class CAD {
21  public:
22  template<CoreHeuristic CH>
23  friend struct CADCore;
25  private:
26  std::vector<carl::Variable> mVariables;
30 
31  // ID scheme for variables x,y,z:
32  // Projection: x=1,y=2,z=3
33  // Lifting: x=3,y=2,z=1,anonymous=0
34  std::size_t idPL(std::size_t level) const {
35  assert(level > 0 && level <= dim());
36  return dim() - level + 1;
37  }
38  std::size_t idLP(std::size_t level) const {
39  assert(level > 0 && level <= dim());
40  return dim() - level + 1;
41  }
42  public:
44  CAD():
46  [&](const UPoly& p, std::size_t cid, bool isBound){ mProjection.addPolynomial(projection::normalize(p), cid, isBound); },
47  [&](const UPoly& p, std::size_t cid, bool isBound){ mProjection.addEqConstraint(projection::normalize(p), cid, isBound); },
48  [&](const UPoly& p, std::size_t cid, bool isBound){ mProjection.removePolynomial(projection::normalize(p), cid, isBound); }
49  ),
52  {
53  mProjection.setRemoveCallback([&](std::size_t level, const SampleLiftedWith& mask){
54  mLifting.removedPolynomialsFromLevel(idPL(level), mask);
55  });
56 
57  if (Settings::debugStepsToTikz) {
58  thp.configure<debug::TikzTreePrinter>("Lifting");
59  thp.configure<debug::TikzDAGPrinter>("Projection");
60  }
61  }
62  ~CAD() {
63  if (Settings::debugStepsToTikz) {
64  thp.layout();
65  thp.writeTo("cad_debug.tex");
66  }
67  }
68  std::size_t dim() const {
69  return mVariables.size();
70  }
71  const auto& getVariables() const {
72  return mVariables;
73  }
74  const auto& getProjection() const {
75  return mProjection;
76  }
77  const auto& getLifting() const {
78  return mLifting;
79  }
80  const auto& getConstraints() const {
81  return mConstraints.indexed();
82  }
83  const auto& getConstraintMap() const {
84  return mConstraints.ordered();
85  }
86  bool isIdValid(std::size_t id) const {
87  return mConstraints.valid(id);
88  }
89  const auto& getBounds() const {
90  return mConstraints.bounds();
91  }
92  void reset(const std::vector<carl::Variable>& vars) {
93  mVariables = vars;
95  mProjection.reset();
96  mLifting.reset(std::vector<carl::Variable>(vars.rbegin(), vars.rend()));
97  }
98  void addConstraint(const ConstraintT& c) {
99  SMTRAT_LOG_DEBUG("smtrat.cad", "Adding " << c);
100  mConstraints.add(c);
101  SMTRAT_LOG_DEBUG("smtrat.cad", "Current projection:" << std::endl << mProjection);
102  SMTRAT_LOG_DEBUG("smtrat.cad", "Current sampletree:" << std::endl << mLifting.getTree());
103  }
104  void removeConstraint(const ConstraintT& c) {
105  SMTRAT_LOG_DEBUG("smtrat.cad", "Removing " << c);
106  auto mask = mConstraints.remove(c);
107  mLifting.removedConstraint(mask);
108  SMTRAT_LOG_DEBUG("smtrat.cad", "Current projection:" << std::endl << mProjection);
109  SMTRAT_LOG_DEBUG("smtrat.cad", "Current sampletree:" << std::endl << mLifting.getTree());
110  }
111 
112  template<typename ConstraintIt>
113  bool evaluateSample(Sample& sample, const ConstraintIt& constraint, Assignment& assignment) const {
114  std::size_t cid = constraint.second;
115  SMTRAT_LOG_TRACE("smtrat.cad.lifting", "Evaluating " << cid << " / " << constraint.first << " on " << assignment);
116  SMTRAT_LOG_TRACE("smtrat.cad.lifting", "Sample was evaluated: " << sample.evaluatedWith() << " / " << sample.evaluationResult());
117  if (sample.evaluatedWith().test(cid)) {
118  return sample.evaluationResult().test(cid);
119  }
120  auto evalResult = carl::evaluate(constraint.first.constr(), assignment);
121  assert(!indeterminate(evalResult));
122  SMTRAT_LOG_TRACE("smtrat.cad.lifting", "Evaluating " << constraint.first << " on " << assignment << " -> " << (bool)evalResult);
123  sample.evaluatedWith().set(cid, true);
124  sample.evaluationResult().set(cid, (bool)evalResult);
125  return (bool)evalResult;
126  }
127 
128  std::vector<Assignment> enumerateSolutions() {
129  std::vector<Assignment> res;
130  SMTRAT_LOG_TRACE("smtrat.cad", "Enumerating satisfying samples...");
131  while (mLifting.hasFullSamples()) {
132  auto it = mLifting.getNextFullSample();
133  auto m = mLifting.extractSampleMap(it);
134  SMTRAT_LOG_TRACE("smtrat.cad", "Checking full sample " << m);
135  assert(m.size() == it.depth());
136  bool sat = true;
137  for (const auto& c: mConstraints.ordered()) {
138  Assignment a = m;
139  sat = sat && evaluateSample(*it, c, a);
140  if (!sat) break;
141  }
142  if (sat) {
143  SMTRAT_LOG_DEBUG("smtrat.cad", "Found satisfying sample " << m);
144  res.emplace_back(m);
145  }
146  }
147  return res;
148  }
149 
151  if (!mLifting.hasFullSamples()) return Answer::UNSAT;
152  SMTRAT_LOG_TRACE("smtrat.cad", "Checking for full satisfying samples...");
153  SMTRAT_LOG_TRACE("smtrat.cad", "Full sample queue:" << std::endl << mLifting.printFullSamples());
154  while (mLifting.hasFullSamples()) {
155  auto it = mLifting.getNextFullSample();
156  auto m = mLifting.extractSampleMap(it);
157  SMTRAT_LOG_TRACE("smtrat.cad", "Checking full sample " << m);
158  assert(m.size() == it.depth());
159  bool sat = true;
160  for (const auto& c: mConstraints.ordered()) {
161  Assignment a = m;
162  sat = sat && evaluateSample(*it, c, a);
163  if (!sat) break;
164  }
165  if (sat) {
166  SMTRAT_LOG_DEBUG("smtrat.cad", "Found satisfying sample " << m);
167  assignment = m;
168  return Answer::SAT;
169  }
170  }
171  SMTRAT_LOG_TRACE("smtrat.cad", "No full satisfying sample found.");
172  return Answer::UNSAT;
173  }
174 
175  template<typename Iterator>
176  Answer checkPartialSample(Iterator& it, std::size_t level) {
177  SMTRAT_LOG_DEBUG("smtrat.cad.lifting", "Checking partial sample " << *it << " against level " << level);
178  Answer answer = Answer::SAT;
179  if (it->hasConflictWithConstraint()) {
180  SMTRAT_LOG_DEBUG("smtrat.cad.lifting", "\tAlready has conflict...");
181  answer = Answer::UNSAT;
182  }
183  for (const auto& c: mConstraints.ordered()) {
184  if (mConstraints.level(c.second) != level) continue;
185  auto a = mLifting.extractSampleMap(it);
186  if (!evaluateSample(*it, c, a)) {
187  SMTRAT_LOG_DEBUG("smtrat.cad.lifting", "\tConflicts with " << c.first);
188  answer = Answer::UNSAT;
189  }
190  }
191  return answer;
192  }
193 
194  Answer check(Assignment& assignment, std::vector<FormulaSetT>& mis) {
195  SMTRAT_LOG_DEBUG("smtrat.cad", "Checking constraints:" << std::endl << mConstraints);
197  return Answer::UNSAT;
198  }
199  SMTRAT_LOG_INFO("smtrat.cad", "Current projection:" << std::endl << mProjection);
201  auto res = cad(assignment, *this, Settings::projectionOperator == ProjectionType::Collins);
202  SMTRAT_LOG_DEBUG("smtrat.cad", "Result: " << res);
203  SMTRAT_LOG_DEBUG("smtrat.cad", "Current projection:" << std::endl << mProjection);
204  SMTRAT_LOG_DEBUG("smtrat.cad", "Current sampletree:" << std::endl << mLifting.getTree());
205  if (res == Answer::UNSAT) {
207  generator(*this, mis);
208  }
209  return res;
210  }
211 
214  for (auto it = mLifting.getTree().begin_preorder(); it != mLifting.getTree().end_preorder();) {
215  if (it->hasConflictWithConstraint()) {
216  // Skip subtrees of already conflicting samples
217  SMTRAT_LOG_TRACE("smtrat.cad.mis", "Adding sample " << *it);
218  cg.addSample(*it);
219  it.skipChildren();
220  } else {
221  it++;
222  }
223  for (std::size_t id = 0; id < mConstraints.size(); id++) {
224  if (!mConstraints.valid(id)) {
225  SMTRAT_LOG_TRACE("smtrat.cad.mis", "Invalid constraint: " << id << ", cur graph:" << std::endl << cg);
226  }
227  assert(mConstraints.valid(id) || cg.coveredSamples(id) == 0);
228  }
229  }
230  SMTRAT_LOG_DEBUG("smtrat.cad.mis", "Resulting conflict graph " << cg);
231  return cg;
232  }
233 
234  auto generateCovering() const {
235  carl::covering::TypedSetCover<ConstraintT> cover;
236  SMTRAT_LOG_DEBUG("smtrat.cad.mis", "Current lifting tree: " << std::endl << mLifting.getTree());
237  carl::IDPool idpool;
238  for (auto it = mLifting.getTree().begin_preorder(); it != mLifting.getTree().end_preorder();) {
239  auto constraints = it->getConflictingConstraints();
240  if (constraints.any()) {
241  auto sid = idpool.get();
242  for (auto cid: constraints) {
243  SMTRAT_LOG_DEBUG("smtrat.cad.mis", sid << " " << *it << " vs. " << cid);
244  cover.set(mConstraints[cid], sid);
245  }
246  it.skipChildren();
247  } else {
248  it++;
249  }
250  }
251  SMTRAT_LOG_DEBUG("smtrat.cad.mis", "Resulting covering " << cover);
252  return cover;
253  }
254  };
255 }
256 }
std::size_t add(const ConstraintT &c)
bool valid(std::size_t id) const
const auto & indexed() const
const auto & ordered() const
carl::Bitset remove(const ConstraintT &c)
Removes a constraint.
void reset(const std::vector< carl::Variable > &vars)
const auto & bounds() const
bool checkForTrivialConflict(std::vector< FormulaSetT > &mis) const
std::size_t size() const
std::size_t level(std::size_t id) const
ConflictGraph generateConflictGraph() const
Definition: CAD.h:212
void reset(const std::vector< carl::Variable > &vars)
Definition: CAD.h:92
CADConstraints< Settings::backtracking > mConstraints
Definition: CAD.h:27
const auto & getConstraintMap() const
Definition: CAD.h:83
std::size_t dim() const
Definition: CAD.h:68
LiftingTree< Settings > mLifting
Definition: CAD.h:29
bool isIdValid(std::size_t id) const
Definition: CAD.h:86
bool evaluateSample(Sample &sample, const ConstraintIt &constraint, Assignment &assignment) const
Definition: CAD.h:113
const auto & getVariables() const
Definition: CAD.h:71
void addConstraint(const ConstraintT &c)
Definition: CAD.h:98
auto generateCovering() const
Definition: CAD.h:234
const auto & getBounds() const
Definition: CAD.h:89
Answer check(Assignment &assignment, std::vector< FormulaSetT > &mis)
Definition: CAD.h:194
const auto & getProjection() const
Definition: CAD.h:74
void removeConstraint(const ConstraintT &c)
Definition: CAD.h:104
std::size_t idPL(std::size_t level) const
Definition: CAD.h:34
Answer checkFullSamples(Assignment &assignment)
Definition: CAD.h:150
const auto & getConstraints() const
Definition: CAD.h:80
std::vector< Assignment > enumerateSolutions()
Definition: CAD.h:128
ProjectionT< Settings > mProjection
Definition: CAD.h:28
const auto & getLifting() const
Definition: CAD.h:77
debug::TikzHistoryPrinter thp
Definition: CAD.h:43
Settings SettingsT
Definition: CAD.h:24
Answer checkPartialSample(Iterator &it, std::size_t level)
Definition: CAD.h:176
std::vector< carl::Variable > mVariables
Definition: CAD.h:26
std::size_t idLP(std::size_t level) const
Definition: CAD.h:38
Representation of a bipartite graph (C+S, E) of vertices C and S, representing the constraints and sa...
Definition: ConflictGraph.h:23
void addSample(const Sample &sample)
std::size_t coveredSamples(std::size_t id) const
Definition: ConflictGraph.h:32
const carl::Bitset & evaluatedWith() const
Definition: Sample.h:53
const carl::Bitset & evaluationResult() const
Definition: Sample.h:59
void configure(const std::string &name)
void writeTo(const std::string &filename) const
Poly normalize(const Poly &p)
Normalizes the given Poly by removing constant and duplicate factors.
Definition: utils.h:32
carl::UnivariatePolynomial< Poly > UPoly
Definition: common.h:17
std::map< carl::Variable, RAN > Assignment
Definition: common.h:14
carl::Bitset SampleLiftedWith
Definition: common.h:15
Rational evaluate(carl::Variable v, const Poly &p, const Rational &r)
Definition: utils.h:11
PositionIteratorType Iterator
Definition: Common.h:49
std::vector< carl::Variable > vars(const std::pair< QuantifierType, std::vector< carl::Variable >> &p)
Definition: QEQuery.h:43
Class to create the formulas for axioms.
const settings::Settings & Settings()
Definition: Settings.h:96
Answer
An enum with the possible answers a Module can give.
Definition: types.h:57
carl::Constraint< Poly > ConstraintT
Definition: types.h:29
#define SMTRAT_LOG_TRACE(channel, msg)
Definition: logging.h:36
#define SMTRAT_LOG_INFO(channel, msg)
Definition: logging.h:34
#define SMTRAT_LOG_DEBUG(channel, msg)
Definition: logging.h:35