SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
UnsatCore_ModelExclusion.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <carl-common/datastructures/Bitset.h>
4 #include <carl-covering/carl-covering.h>
6 
7 namespace smtrat {
8 namespace unsatcore {
9 
10 /**
11  * Implements an easy strategy to obtain an unsatisfiable core.
12  * Essentially it computes a cover that rejects all possible models if we allow the removal of clauses.
13  *
14  * - Allow to disable every formula f_i by encoding (y_i <=> f_i)
15  * - Find a satisfying assignment (which will set some f_i to false)
16  * -
17  */
18 template<typename Solver>
20 private:
21  Solver& mSolver;
22  carl::covering::TypedSetCover<FormulaT> mSetCover;
23  std::map<carl::Variable, FormulaT> mFormulas;
24  std::size_t mAssignments = 0;
25 public:
26  UnsatCoreBackend(Solver& s, const FormulasT& fs) : mSolver(s) {
27  FormulasT phis;
28  std::size_t id = 0;
29  for (const auto& f : fs) {
30  auto it = mFormulas.emplace(carl::fresh_boolean_variable(), f);
31  phis.emplace_back(FormulaT(it.first->first));
32  mSolver.add(FormulaT(carl::FormulaType::IFF, {FormulaT(it.first->first), f}));
33  SMTRAT_LOG_DEBUG("smtrat.unsatcore", it.first->first << " <-> " << f << " with id " << id);
34  id++;
35  }
36  // At least one clause should be active.
37  mSolver.add(FormulaT(carl::FormulaType::OR, std::move(phis)));
38  }
40  const auto& m = mSolver.model();
41  FormulasT subs;
42  SMTRAT_LOG_DEBUG("smtrat.unsatcore", "Got assignment " << m);
43  for (const auto& f: mFormulas) {
44  SMTRAT_LOG_DEBUG("smtrat.unsatcore", "Processing " << f.first);
45  const auto& val = m.evaluated(f.first);
46  assert(val.isBool());
47  if (!val.asBool()) {
48  subs.emplace_back(FormulaT(f.first));
49  mSetCover.set(f.second, mAssignments);
50  }
51  }
52  SMTRAT_LOG_TRACE("smtrat.unsatcore", "Excluding assignment with " << subs);
53  mSolver.add(FormulaT(carl::FormulaType::OR, std::move(subs)));
54  mAssignments++;
55  }
57  while (true) {
58  Answer a = mSolver.check();
59  switch (a) {
60  case Answer::SAT:
61  processAssignment();
62  break;
63  case Answer::UNSAT:
64  SMTRAT_LOG_INFO("smtrat.unsatcore", "Formula became unsat.");
65  return a;
66  case Answer::OPTIMAL:
67  assert(false && "solver should not be in optimization mode");
68  return a;
69  default:
70  SMTRAT_LOG_ERROR("smtrat.unsatcore", "Unexpected answer " << a);
71  return a;
72  }
73  }
74  }
75  std::pair<Answer, FormulasT> run() {
76  Answer a = compute();
77  if (a != Answer::UNSAT) {
78  return std::make_pair(a, FormulasT());
79  } else {
80  auto covering = mSetCover.get_cover([](auto& sc) {
81  carl::Bitset res;
82  res |= carl::covering::heuristic::remove_duplicates(sc);
83  res |= carl::covering::heuristic::select_essential(sc);
84  res |= carl::covering::heuristic::greedy(sc);
85  return res;
86  });
87  SMTRAT_LOG_DEBUG("smtrat.unsatcore", "Greedy: " << covering);
88  return std::make_pair(Answer::UNSAT, covering);
89  }
90  }
91 };
92 
93 }
94 }
Class to create the formulas for axioms.
carl::Formula< Poly > FormulaT
Definition: types.h:37
Answer
An enum with the possible answers a Module can give.
Definition: types.h:57
@ OPTIMAL
Definition: types.h:57
UnsatCoreStrategy
Definition: UnsatCore.h:8
carl::Formulas< Poly > FormulasT
Definition: types.h:39
#define SMTRAT_LOG_TRACE(channel, msg)
Definition: logging.h:36
#define SMTRAT_LOG_INFO(channel, msg)
Definition: logging.h:34
#define SMTRAT_LOG_ERROR(channel, msg)
Definition: logging.h:32
#define SMTRAT_LOG_DEBUG(channel, msg)
Definition: logging.h:35