SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
Executor.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 
5 #include "../parser/InstructionHandler.h"
6 #include "config.h"
7 #include "ExecutionState.h"
8 
9 #include <carl-io/DIMACSExporter.h>
10 #include <carl-io/SMTLIBStream.h>
15 
16 
17 namespace smtrat {
18 
19 template<typename Strategy>
22  Strategy& solver;
26  int exitCode;
27 public:
30  settings::Settings::getInstance().get<settings::ModuleSettings>("module").set_callbacks([this](const std::string& key){
31  return this->options.find(key) != this->options.end();
32  }, [this](const std::string& key){
33  return this->options.template get<std::string>(key);
34  });
35 
36  state.set_add_assertion_handler([this](const FormulaT& f) {
37  this->solver.add(f);
38  });
40  this->solver.remove(f);
41  });
42  state.set_add_soft_assertion_handler([this](const FormulaT& f, Rational weight, const std::string& id) {
43  this->solver.inform(f);
44  this->maxsmt.add_soft_formula(f, weight, id);
45  });
46  state.set_add_annotated_name_handler([this](const FormulaT& f, const std::string& name) {
47  this->unsatcore.add_annotated_name(f, name);
48  });
50  this->solver.deinform(f);
51  this->maxsmt.remove_soft_formula(f);
52  });
53  state.set_add_objective_handler([this](const Poly& f, bool minimize) {
54  this->optimization.add_objective(f, minimize);
55  });
56  state.set_remove_objective_handler([this](const Poly& f) {
57  this->optimization.remove_objective(f);
58  });
60  this->unsatcore.remove_annotated_name(f);
61  });
62  }
64  }
65  void add(const smtrat::FormulaT& f) {
66  if (state.is_mode(execution::Mode::START)) setLogic(carl::Logic::UNDEFINED);
67 
68  SMTRAT_LOG_DEBUG("smtrat", "Asserting " << f);
69  if (state.has_assertion(f)) {
70  // error() << "assertion already exists";
71  } else if (state.has_soft_assertion(f)) {
72  // error() << "soft assertion already exists";
73  } else {
75  }
76  }
77 
78  void addSoft(const smtrat::FormulaT& f, smtrat::Rational weight, const std::string& id) {
79  if (state.is_mode(execution::Mode::START)) setLogic(carl::Logic::UNDEFINED);
80 
81  if (state.has_assertion(f)) {
82  // error() << "assertion already exists";
83  } else if (state.has_soft_assertion(f)) {
84  // error() << "soft assertion already exists";
85  } else {
86  state.add_soft_assertion(f, weight, id);
87  }
88  }
89 
90  void annotateName(const smtrat::FormulaT& f, const std::string& name) {
91  // TODO incompatible with SMTLIB: also sub-terms can be annotated
92  if (state.is_mode(execution::Mode::START)) setLogic(carl::Logic::UNDEFINED);
93 
94  SMTRAT_LOG_DEBUG("smtrat", "Naming " << name << ": " << f);
95  if (state.has_annotated_name(name)) {
96  error() << "annotated name already taken";
97  } else if (state.has_annotated_name_formula(f)) {
98  error() << "formula has already a name";
99  } else {
100  state.annotate_name(name, f);
101  }
102  }
103  void check() {
105  warn() << "no logic has been set.";
106  if (state.is_mode(execution::Mode::START)) setLogic(carl::Logic::UNDEFINED);
107  }
108  smtrat::resource::Limiter::getInstance().resetTimeout();
110  Model m;
111  ObjectiveValues ov;
112  if (maxsmt.active()) {
113  auto res = maxsmt.compute();
114  this->lastAnswer = std::get<0>(res);
115  m = std::get<1>(res);
116  ov = std::get<2>(res);
117  } else if (optimization.active()) {
118  auto res = optimization.compute();
119  this->lastAnswer = std::get<0>(res);
120  m = std::get<1>(res);
121  ov = std::get<2>(res);
122  if (lastAnswer == Answer::SAT ) {
123  warn() << "the result might not optimal as the strategy contained a module not supporting optimization";
124  }
125  } else {
126  this->lastAnswer = this->solver.check();
127  m = solver.model();
128  }
129 
130  switch (this->lastAnswer) {
131  case smtrat::Answer::SAT:
133  if (this->infos.template has<std::string>("status") && this->infos.template get<std::string>("status") == "unsat") {
134  error() << "expected unsat, but returned sat";
135  this->exitCode = SMTRAT_EXIT_WRONG_ANSWER;
136  } else {
137  regular() << "sat" << std::endl;
138  state.enter_sat(m, ov);
139  this->exitCode = SMTRAT_EXIT_SAT;
140  }
141  break;
142  }
143  case smtrat::Answer::UNSAT: {
144  if (this->infos.template has<std::string>("status") && this->infos.template get<std::string>("status") == "sat") {
145  error() << "expected sat, but returned unsat";
146  this->exitCode = SMTRAT_EXIT_WRONG_ANSWER;
147  } else {
148  regular() << "unsat" << std::endl;
149  state.enter_unsat();
150  this->exitCode = SMTRAT_EXIT_UNSAT;
151  }
152  break;
153  }
155  regular() << "unknown" << std::endl;
156  this->exitCode = SMTRAT_EXIT_UNKNOWN;
157  break;
158  }
160  regular() << "aborted" << std::endl;
161  this->exitCode = SMTRAT_EXIT_UNKNOWN;
162  break;
163  }
164  default: {
165  error() << "unexpected output!";
166  this->exitCode = SMTRAT_EXIT_UNEXPECTED_ANSWER;
167  break;
168  }
169  }
170  }
171  void declareFun(const carl::Variable&) {
172  //if (smtrat::parser::TypeOfTerm::get(var.type()) == smtrat::parser::ExpressionType::THEORY) {
173  // this->solver.quantifierManager().addUnquantifiedVariable(var);
174  //}
175  }
176  void declareSort(const std::string&, const unsigned&) {
177  //error() << "(declare-sort <name> <arity>) is not implemented.";
178  }
179  void defineSort(const std::string&, const std::vector<std::string>&, const carl::Sort&) {
180  //error() << "(define-sort <name> <sort>) is not implemented.";
181  }
182 
183  void qe(){
184  #ifdef CLI_ENABLE_QUANTIFIER_ELIMINATION
185  FormulaT receivedFormula(this->solver.formula());
186  auto res = smtrat::qe::qe(receivedFormula);
187  if (res) {
188  carl::io::SMTLIBStream sls;
189  sls << *res;
190  regular() << sls << std::endl;
191  if (res->type() != carl::FormulaType::FALSE) {
192  this->exitCode = SMTRAT_EXIT_SAT;
193  } else {
194  this->exitCode = SMTRAT_EXIT_UNSAT;
195  }
196  } else {
197  regular() << "unknown" << std::endl;
198  this->exitCode = SMTRAT_EXIT_UNKNOWN;
199  }
200  #else
201  error() << "SMT-RAT has been built without support for quantifier elimination!";
202  #endif
203  }
204 
205  void exit() {
206  }
207  void getAssertions() {
209  regular() << "(";
210  for (const auto& assertion : state.assertions()) {
211  regular() << assertion.formula << " ";
212  }
213  regular() << ")" << std::endl;
214  } else {
215  error() << "nothing is asserted";
216  }
217  }
218  void getAllModels() { // non-standard
220  for (const auto& m: this->solver.allModels()) {
221  regular() << carl::io::asSMTLIB(m) << std::endl;
222  }
223  } else {
224  error() << "Can only be called after a call that returned sat.";
225  }
226  }
227  void getAssignment() {
228  // TODO incompatible with SMTLIB
230  this->solver.printAssignment();
231  }
232  }
233  void getModel() {
235  regular() << carl::io::asSMTLIB(state.model()) << std::endl;
236  } else {
237  error() << "Can only be called after a call that returned sat.";
238  }
239  }
240  void getProof() {
241  error() << "(get-proof) is not implemented.";
242  }
243  void getObjectives() {
245  error() << "Can only be called after a call that returned sat.";
246  } else if (!state.objectiveValues().empty()) {
247  regular() << "(objectives" << std::endl;
248  for (const auto& obj : state.objectiveValues()) {
249  const auto mv = obj.second;
250  if (mv.isMinusInfinity() || mv.isPlusInfinity()) {
251  regular() << " (" << obj.first << " " << mv.asInfinity() << ")" << std::endl;
252  } else {
253  assert(mv.isRational());
254  regular() << " (" << obj.first << " " << mv.asRational() << ")" << std::endl;
255  }
256  }
257  regular() << ")" << std::endl;
258  } else {
259  info() << "no objectives available";
260  }
261  }
262  void getUnsatCore() {
263  // this->solver.printInfeasibleSubset(std::cout);
265  auto res = unsatcore.compute();
266  if (res.first == Answer::UNSAT) {
267  regular() << "(";
268  for (const auto& f: res.second) regular() << f << " ";
269  regular() << ")" << std::endl;
270  } else {
271  error() << "got unexpected answer " << res.first;
272  }
273  } else {
274  error() << "(get-unsat-core) can only be called after (check-sat) returned unsat";
275  }
276  }
277  // TODO add (non-standard) method to access infeasible subsets
278  void getValue(const std::vector<carl::Variable>&) {
279  // TODO implement get-value (t_1 ... t_n)
280  error() << "(get-value (<variables>)) is not implemented.";
281  }
282  // TODO implement check-sat-assuming and get-unsat-assumptions
284  if (state.is_mode(execution::Mode::START)) setLogic(carl::Logic::UNDEFINED);
285 
286  if (!state.has_objective(p)) {
288  } else {
289  error() << "objective function already set";
290  }
291  }
292  void pop(std::size_t n) {
294  warn() << "no logic has been set.";
295  if (state.is_mode(execution::Mode::START)) setLogic(carl::Logic::UNDEFINED);
296  }
297 
298  state.pop(n);
299  }
300  void push(std::size_t n) {
302  warn() << "no logic has been set.";
303  if (state.is_mode(execution::Mode::START)) setLogic(carl::Logic::UNDEFINED);
304  }
305 
306  state.push(n);
307  }
308  void reset() {
309  InstructionHandler::reset();
310  smtrat::resource::Limiter::getInstance().reset();
311  state.reset();
312  solver.reset();
314  maxsmt.reset();
315  unsatcore.reset();
316  }
319  }
320  void setLogic(const carl::Logic& logic) {
322  error() << "The logic has already been set!";
323  } else {
324  state.set_logic(logic);
325  solver.rLogic() = logic;
326  }
327  }
328  int getExitCode() const {
329  return this->exitCode;
330  }
331 };
332 
333 }
constexpr int SMTRAT_EXIT_UNEXPECTED_ANSWER
Definition: ExitCodes.h:18
constexpr int SMTRAT_EXIT_UNKNOWN
Definition: ExitCodes.h:15
constexpr int SMTRAT_EXIT_WRONG_ANSWER
Definition: ExitCodes.h:16
constexpr int SMTRAT_EXIT_SAT
Definition: ExitCodes.h:13
constexpr int SMTRAT_EXIT_UNSAT
Definition: ExitCodes.h:14
void declareFun(const carl::Variable &)
Definition: Executor.h:171
void addObjective(const smtrat::Poly &p, smtrat::parser::OptimizationType ot)
Definition: Executor.h:283
Optimization< Strategy > optimization
Definition: Executor.h:24
Strategy & solver
Definition: Executor.h:22
void addSoft(const smtrat::FormulaT &f, smtrat::Rational weight, const std::string &id)
Definition: Executor.h:78
int getExitCode() const
Definition: Executor.h:328
MaxSMT< Strategy, MaxSMTStrategy::LINEAR_SEARCH > maxsmt
Definition: Executor.h:23
Executor(Strategy &solver)
Definition: Executor.h:29
void declareSort(const std::string &, const unsigned &)
Definition: Executor.h:176
execution::ExecutionState state
Definition: Executor.h:21
void defineSort(const std::string &, const std::vector< std::string > &, const carl::Sort &)
Definition: Executor.h:179
void pop(std::size_t n)
Definition: Executor.h:292
void getObjectives()
Definition: Executor.h:243
void annotateName(const smtrat::FormulaT &f, const std::string &name)
Definition: Executor.h:90
void getUnsatCore()
Definition: Executor.h:262
void getValue(const std::vector< carl::Variable > &)
Definition: Executor.h:278
smtrat::Answer lastAnswer
Definition: Executor.h:28
UnsatCore< Strategy, UnsatCoreStrategy::ModelExclusion > unsatcore
Definition: Executor.h:25
void getProof()
Definition: Executor.h:240
void getAllModels()
Definition: Executor.h:218
void getModel()
Definition: Executor.h:233
void resetAssertions()
Definition: Executor.h:317
void getAssignment()
Definition: Executor.h:227
void add(const smtrat::FormulaT &f)
Definition: Executor.h:65
void getAssertions()
Definition: Executor.h:207
void push(std::size_t n)
Definition: Executor.h:300
void setLogic(const carl::Logic &logic)
Definition: Executor.h:320
void add_soft_formula(const FormulaT &formula, Rational weight, const std::string &id)
Definition: MaxSMT.h:41
void remove_soft_formula(const FormulaT &formula)
Definition: MaxSMT.h:50
void reset()
Definition: MaxSMT.h:55
bool active() const
Definition: MaxSMT.h:59
std::tuple< Answer, Model, ObjectiveValues > compute()
Definition: MaxSMT.h:63
void add_objective(const Poly &objective, bool minimize=true)
Definition: Optimization.h:38
void remove_objective(const Poly &objective)
Definition: Optimization.h:42
std::tuple< Answer, Model, ObjectiveValues > compute(bool full=true)
Definition: Optimization.h:58
bool active() const
Definition: Optimization.h:54
std::pair< Answer, std::vector< std::string > > compute()
Definition: UnsatCore.h:79
void add_annotated_name(const FormulaT &formula, const std::string &name)
Definition: UnsatCore.h:35
void remove_annotated_name(const FormulaT &formula)
Definition: UnsatCore.h:40
void add_assertion(const FormulaT &formula)
void set_add_soft_assertion_handler(std::function< void(const FormulaT &, Rational, const std::string &)> f)
bool has_objective(const Poly &function)
const auto & assertions() const
void set_remove_objective_handler(std::function< void(const Poly &)> f)
void set_add_assertion_handler(std::function< void(const FormulaT &)> f)
void set_remove_annotated_name_handler(std::function< void(const FormulaT &)> f)
bool has_soft_assertion(const FormulaT &formula) const
bool has_assertion(const FormulaT &formula) const
bool has_annotated_name_formula(const smtrat::FormulaT &f)
const smtrat::Model & model() const
void set_add_objective_handler(std::function< void(const Poly &, bool)> f)
bool has_annotated_name(const std::string &n)
void add_soft_assertion(const FormulaT &formula, Rational weight, const std::string &id)
void annotate_name(const std::string &name, const smtrat::FormulaT &f)
bool is_mode(Mode mode) const
void set_logic(carl::Logic logic)
void enter_sat(const smtrat::Model &model, const ObjectiveValues &objectiveValues)
void set_add_annotated_name_handler(std::function< void(const FormulaT &, const std::string &)> f)
void add_objective(const Poly &function, bool minimize)
const smtrat::ObjectiveValues & objectiveValues() const
void set_remove_soft_assertion_handler(std::function< void(const FormulaT &)> f)
void set_remove_assertion_handler(std::function< void(const FormulaT &)> f)
VariantMap< std::string, Value > options
VariantMap< std::string, Value > infos
std::optional< FormulaT > qe(const FormulaT &formula)
Definition: smtrat-qe.cpp:10
Class to create the formulas for axioms.
carl::Formula< Poly > FormulaT
Definition: types.h:37
std::vector< std::pair< std::variant< Poly, std::string >, Model::mapped_type > > ObjectiveValues
Definition: model.h:32
carl::Model< Rational, Poly > Model
Definition: model.h:13
carl::MultivariatePolynomial< Rational > Poly
Definition: types.h:25
Answer
An enum with the possible answers a Module can give.
Definition: types.h:57
@ OPTIMAL
Definition: types.h:57
@ UNKNOWN
Definition: types.h:57
@ ABORTED
Definition: types.h:57
mpq_class Rational
Definition: types.h:19
#define SMTRAT_LOG_DEBUG(channel, msg)
Definition: logging.h:35