HAL  v4.5.0-124-g47ab54673
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
smt.cpp
Go to the documentation of this file.
2 
3 namespace hal
4 {
6  {
7  auto py_smt = m.def_submodule("SMT", R"(
8  SMT solver functions.
9  )");
10 
11  py::enum_<SMT::SolverType> py_smt_solver_type(py_smt, "SolverType", R"(
12  Identifier for the SMT solver type.
13  )");
14 
15  py_smt_solver_type.value("Z3", SMT::SolverType::Z3, R"(Z3 SMT solver.)")
16  .value("Boolector", SMT::SolverType::Boolector, R"(Boolector SMT solver.)")
17  .value("Bitwuzla", SMT::SolverType::Bitwuzla, R"(Bitwuzla SMT solver.)")
18  .value("Unknown", SMT::SolverType::Unknown, R"(Unknown (unsupported) SMT solver.)")
19  .export_values();
20 
21  py::enum_<SMT::SolverCall> py_smt_solver_call(py_smt, "SolverCall", R"(
22  Identifier for how the SMT solver is invoked.
23  )");
24 
25  py_smt_solver_call.value("Binary", SMT::SolverCall::Binary, R"(Call the solver binary in a subprocess.)")
26  .value("Library", SMT::SolverCall::Library, R"(Call the solver through the library linked into HAL.)")
27  .export_values();
28 
29  py::class_<SMT::QueryConfig> py_smt_query_config(py_smt, "QueryConfig", R"(
30  Represents the data structure to configure an SMT query.
31  )");
32 
33  py_smt_query_config.def(py::init<>(), R"(
34  Constructs a new query configuration.
35  )");
36 
37  py_smt_query_config.def_readwrite("solver", &SMT::QueryConfig::solver, R"(
38  The SMT solver identifier.
39 
40  :type: hal_py.SMT.SolverType
41  )");
42 
43  py_smt_query_config.def_readwrite("local", &SMT::QueryConfig::local, R"(
44  Controls whether the SMT query is performed on a local or a remote machine.
45 
46  :type: bool
47  )");
48 
49  py_smt_query_config.def_readwrite("generate_model", &SMT::QueryConfig::generate_model, R"(
50  Controls whether the SMT solver should generate a model in case formula is satisfiable.
51 
52  :type: bool
53  )");
54 
55  py_smt_query_config.def_readwrite("timeout_in_seconds", &SMT::QueryConfig::timeout_in_seconds, R"(
56  The timeout after which the SMT solver is killed in seconds.
57 
58  :type: int
59  )");
60 
61  py_smt_query_config.def("with_solver", &SMT::QueryConfig::with_solver, py::arg("solver"), R"(
62  Sets the solver type to the desired SMT solver.
63 
64  :param hal_py.SMT.SolverType solver: The solver type identifier.
65  :returns: The updated SMT query configuration.
66  :rtype: hal_py.SMT.QueryConfig
67  )");
68 
69  py_smt_query_config.def("with_call", &SMT::QueryConfig::with_call, py::arg("call"), R"(
70  Sets the call type to the desired target.
71 
72  :param hal_py.SMT.SolverCall call: The solver call.
73  :returns: The updated SMT query configuration.
74  :rtype: hal_py.SMT.QueryConfig
75  )");
76 
77  py_smt_query_config.def("with_local_solver", &SMT::QueryConfig::with_local_solver, R"(
78  Activates local SMT solver execution.
79 
80  :returns: The updated SMT query configuration.
81  :rtype: hal_py.SMT.QueryConfig
82  )");
83 
84  py_smt_query_config.def("with_remote_solver", &SMT::QueryConfig::with_remote_solver, R"(
85  Indicates that the SMT solver runs on a remote machine.
86 
87  :returns: The updated SMT query configuration.
88  :rtype: hal_py.SMT.QueryConfig
89  )");
90 
91  py_smt_query_config.def("with_model_generation", &SMT::QueryConfig::with_model_generation, R"(
92  Indicates that the SMT solver should generate a model in case the formula is satisfiable.
93 
94  :returns: The updated SMT query configuration.
95  :rtype: hal_py.SMT.QueryConfig
96  )");
97 
98  py_smt_query_config.def("without_model_generation", &SMT::QueryConfig::without_model_generation, R"(
99  Indicates that the SMT solver should not generate a model.
100 
101  :returns: The updated SMT query configuration.
102  :rtype: hal_py.SMT.QueryConfig
103  )");
104 
105  py_smt_query_config.def("with_timeout", &SMT::QueryConfig::with_timeout, py::arg("seconds"), R"(
106  Sets a timeout in seconds that terminates an SMT query after the specified time has passed.
107 
108  :param int seconds: The timeout in seconds.
109  :returns: The updated SMT query configuration.
110  :rtype: hal_py.SMT.QueryConfig
111  )");
112 
113  py::class_<SMT::Constraint> py_smt_constraint(py_smt, "Constraint", R"(
114  Represents a constraint to the SMT query.
115  A constraint is either an assignment of two Boolean functions or a single Boolean function, e.g., an equality check or similar.
116  )");
117 
118  py_smt_constraint.def_readwrite("constraint", &SMT::Constraint::constraint, R"(
119  A constraint that is either an assignment of two Boolean functions or a single Boolean function, e.g., an equality check or similar.
120 
121  :type: hal_py.BooleanFunction or tuple(hal_py.BooleanFunction, hal_py.BooleanFunction)
122  )");
123 
124  py_smt_constraint.def(py::init([](BooleanFunction constraint) { return new SMT::Constraint(std::move(constraint)); }), py::arg("constraint"), R"(
125  Constructs a new constraint from one Boolean function that evaluates to a single bit.
126 
127  :param hal_py.BooleanFunction constraint: The constraint function.
128  )");
129 
130  py_smt_constraint.def(py::init([](BooleanFunction lhs, BooleanFunction rhs) { return new SMT::Constraint(std::move(lhs), std::move(rhs)); }), py::arg("lhs"), py::arg("rhs"), R"(
131  Constructs a new equality constraint from two Boolean functions.
132 
133  :param hal_py.BooleanFunction lhs: The left-hand side of the equality constraint.
134  :param hal_py.BooleanFunction rhs: The right-hand side of the equality constraint.
135  )");
136 
137  py_smt_constraint.def("is_assignment", &SMT::Constraint::is_assignment, R"(
138  Checks whether the constraint is an assignment constraint.
139 
140  :returns: ``True`` if the constraint is an assignment, ``False`` otherwise.
141  :rtype: bool
142  )");
143 
144  py_smt_constraint.def(
145  "get_assignment",
146  [](const SMT::Constraint& self) -> std::optional<std::pair<BooleanFunction, BooleanFunction>> {
147  auto res = self.get_assignment();
148  if (res.is_ok())
149  {
150  return *res.get();
151  }
152  else
153  {
154  log_error("python_context", "{}", res.get_error().get());
155  return std::nullopt;
156  }
157  },
158  R"(
159  Returns the assignment constraint as a pair of Boolean functions.
160 
161  :returns: The assignment constraint on success, ``None`` otherwise.
162  :rtype: tuple(hal_py.BooleanFunction,hal_py.BooleanFunction) or None
163  )");
164 
165  py_smt_constraint.def(
166  "get_function",
167  [](const SMT::Constraint& self) -> std::optional<const BooleanFunction*> {
168  auto res = self.get_function();
169  if (res.is_ok())
170  {
171  return res.get();
172  }
173  else
174  {
175  log_error("python_context", "{}", res.get_error().get());
176  return std::nullopt;
177  }
178  },
179  R"(
180  Returns the function constraint.
181 
182  :returns: The function constraint on success, ``None`` otherwise.
183  :rtype: hal_py.BooleanFunction or None
184  )");
185 
186  py::enum_<SMT::SolverResultType> py_smt_result_type(py_smt, "SolverResultType", R"(
187  Result type of an SMT solver query.
188  )");
189 
190  py_smt_result_type.value("Sat", SMT::SolverResultType::Sat, R"(The list of constraints is satisfiable.)")
191  .value("UnSat", SMT::SolverResultType::UnSat, R"(The list of constraints is not satisfiable.)")
192  .value("Unknown", SMT::SolverResultType::Unknown, R"(A result could not be obtained, e.g., due to a time-out.)")
193  .export_values();
194 
195  py::class_<SMT::Model> py_smt_model(py_smt, "Model", R"(
196  Represents a list of assignments for variable nodes that yield a satisfiable assignment for a given list of constraints.
197  )");
198 
199  py_smt_model.def(py::init<const std::map<std::string, std::tuple<u64, u16>>&>(), py::arg("model") = std::map<std::string, std::tuple<u64, u16>>(), R"(
200  Constructs a new model from a map of variable names to value and bit-size.
201 
202  :param dict[str,tuple(int,int)] model: A dict from variable name to value and bit-size.
203  )");
204 
205  py_smt_model.def(py::self == py::self, R"(
206  Checks whether two SMT models are equal.
207 
208  :returns: ``True`` if both models are equal, ``False`` otherwise.
209  :rtype: bool
210  )");
211 
212  py_smt_model.def(py::self != py::self, R"(
213  Checks whether two SMT models are unequal.
214 
215  :returns: ``True`` if both models are unequal, ``False`` otherwise.
216  :rtype: bool
217  )");
218 
219  py_smt_model.def_readwrite("model", &SMT::Model::model, R"(
220  A dict from variable identifiers to a (1) value and (2) its bit-size.
221 
222  :type: dict(str,tuple(int,int))
223  )");
224 
225  py_smt_model.def_static(
226  "parse",
227  [](const std::string& model_str, const SMT::SolverType& solver) -> std::optional<SMT::Model> {
228  auto res = SMT::Model::parse(model_str, solver);
229  if (res.is_ok())
230  {
231  return res.get();
232  }
233  else
234  {
235  log_error("python_context", "{}", res.get_error().get());
236  return std::nullopt;
237  }
238  },
239  py::arg("model_str"),
240  py::arg("solver"),
241  R"(
242  Parses an SMT-Lib model from a string output by a solver of the given type.
243 
244  :param str model_str: The SMT-Lib model string.
245  :param hal_py.SMT.SolverType solver: The solver that computed the model.
246  :returns: The model on success, ``None`` otherwise.
247  :rtype: hal_py.SMT.Model or None
248  )");
249 
250  py_smt_model.def(
251  "evaluate",
252  [](const SMT::Model& self, const BooleanFunction& bf) -> std::optional<BooleanFunction> {
253  auto res = self.evaluate(bf);
254  if (res.is_ok())
255  {
256  return res.get();
257  }
258  else
259  {
260  log_error("python_context", "{}", res.get_error().get());
261  return std::nullopt;
262  }
263  },
264  py::arg("bf"),
265  R"(
266  Evaluates the given Boolean function by replacing all variables contained in the model with their corresponding value and simplifying the result.
267 
268  :param hal_py.BooleanFunction bf: The Boolean function to evaluate.
269  :returns: The evaluated function on success, ``None`` otherwise.
270  :rtype: hal_py.BooleanFunction or None
271  )");
272 
273  py::class_<SMT::SolverResult> py_smt_result(py_smt, "SolverResult", R"(
274  Represents the result of an SMT query.
275  )");
276 
277  py_smt_result.def_readwrite("type", &SMT::SolverResult::type, R"(
278  Result type of the SMT query.
279 
280  :type: hal_py.SMT.ResultType
281  )");
282 
283  py_smt_result.def_readwrite("model", &SMT::SolverResult::model, R"(
284  The (optional) model that is only available if type == SMT.ResultType.Sat and model generation is enabled.
285 
286  :type: hal_py.SMT.Model
287  )");
288 
289  py_smt_result.def_static("Sat", &SMT::SolverResult::Sat, py::arg("model") = std::optional<SMT::Model>(), R"(
290  Creates a satisfiable result with an optional model.
291 
292  :param hal_py.SMT.Model model: Optional model for satisfiable formula.
293  :returns: The result.
294  :rtype: hal_py.SMT.SolverResult
295  )");
296 
297  py_smt_result.def_static("UnSat", &SMT::SolverResult::UnSat, R"(
298  Creates an unsatisfiable result.
299 
300  :returns: The result.
301  :rtype: hal_py.SMT.SolverResult
302  )");
303 
304  py_smt_result.def_static("Unknown", &SMT::SolverResult::Unknown, R"(
305  Creates an unknown result.
306 
307  :returns: The result.
308  :rtype: hal_py.SMT.SolverResult
309  )");
310 
311  py_smt_result.def("is", &SMT::SolverResult::is, py::arg("type"), R"(
312  Checks whether the result is of a specific type.
313 
314  :param hal_py.SMT.ResultType type: The type to check.
315  :returns: ``True`` in case result matches the given type, ``False`` otherwise.
316  :rtype: bool
317  )");
318 
319  py_smt_result.def("is_sat", &SMT::SolverResult::is_sat, R"(
320  Checks whether the result is satisfiable.
321 
322  :returns: ``True`` in case result is satisfiable, ``False`` otherwise.
323  :rtype: bool
324  )");
325 
326  py_smt_result.def("is_unsat", &SMT::SolverResult::is_unsat, R"(
327  Checks whether the result is unsatisfiable.
328 
329  :returns: ``True`` in case result is unsatisfiable, ``False`` otherwise.
330  :rtype: bool
331  )");
332 
333  py_smt_result.def("is_unknown", &SMT::SolverResult::is_unknown, R"(
334  Checks whether the result is unknown.
335 
336  :returns: ``True`` in case result is unknown, ``False`` otherwise.
337  :rtype: bool
338  )");
339 
340  py::class_<SMT::Solver> py_smt_solver(py_smt, "Solver", R"(
341  Provides an interface to query SMT solvers for a list of constraints, i.e. statements that have to be equal. To this end, we translate constraints to a SMT-LIB v2 string representation and query solvers with a defined configuration, i.e., chosen solver, model generation etc.
342  )");
343 
344  py_smt_solver.def(py::init<std::vector<SMT::Constraint>>(), py::arg("constraints") = std::vector<SMT::Constraint>(), R"(
345  Constructs an solver with an optional list of constraints.
346 
347  :param list[hal_py.SMT.Constraint] constraints: The (optional) list of constraints.
348  )");
349 
350  py_smt_solver.def_property_readonly("constraints", &SMT::Solver::get_constraints, R"(
351  The list of constraints.
352 
353  :type: list[hal_py.SMT.Constraint]
354  )");
355 
356  py_smt_solver.def("get_constraints", &SMT::Solver::get_constraints, R"(
357  Returns the list of constraints.
358 
359  :returns: The list of constraints.
360  :rtype: list[hal_py.SMT.Constraint]
361  )");
362 
363  py_smt_solver.def("with_constraint", &SMT::Solver::with_constraint, py::arg("constraint"), R"(
364  Adds a constraint to the SMT solver.
365 
366  :param hal_py.SMT.Constraint constraint: The constraint.
367  :returns: The updated SMT solver.
368  :rtype: hal_py.SMT.Solver
369  )");
370 
371  py_smt_solver.def("with_constraints", &SMT::Solver::with_constraints, py::arg("constraints"), R"(
372  Adds a list of constraints to the SMT solver.
373 
374  :param list[hal_py.SMT.Constraint] constraints: The constraints.
375  :returns: The updated SMT solver.
376  :rtype: hal_py.SMT.Solver
377  )");
378 
379  py_smt_solver.def_static("has_local_solver_for", &SMT::Solver::has_local_solver_for, py::arg("type"), py::arg("call"), R"(
380  Checks whether a SMT solver of the given type is available on the local machine.
381 
382  :param hal_py.SMT.SolverType type: The SMT solver type.
383  :param hal_py.SMT.SolverCall call: The solver call.
384  :returns: ``True`` if an SMT solver of the requested type is available, ``False`` otherwise.
385  :rtype: bool
386  )");
387 
388  py_smt_solver.def(
389  "query",
390  [](const SMT::Solver& self, const SMT::QueryConfig& config = SMT::QueryConfig()) -> std::optional<SMT::SolverResult> {
391  auto res = self.query(config);
392  if (res.is_ok())
393  {
394  return res.get();
395  }
396  else
397  {
398  log_error("python_context", "{}", res.get_error().get());
399  return std::nullopt;
400  }
401  },
402  py::arg("config") = SMT::QueryConfig(),
403  R"(
404  Queries an SMT solver with the specified query configuration.
405 
406  :param hal_py.SMT.QueryConfig config: The SMT solver query configuration.
407  :returns: The result on success, a string error message otherwise.
408  :rtype: hal_py.SMT.Result or str
409  )");
410 
411  py_smt_solver.def(
412  "query_local",
413  [](const SMT::Solver& self, const SMT::QueryConfig& config) -> std::optional<SMT::SolverResult> {
414  auto res = self.query_local(config);
415  if (res.is_ok())
416  {
417  return res.get();
418  }
419  else
420  {
421  log_error("python_context", "{}", res.get_error().get());
422  return std::nullopt;
423  }
424  },
425  py::arg("config"),
426  R"(
427  Queries a local SMT solver with the specified query configuration.
428 
429  :param hal_py.SMT.QueryConfig config: The SMT solver query configuration.
430  :returns: The result on success, a string error message otherwise.
431  :rtype: hal_py.SMT.Result or str
432  )");
433 
434  py_smt_solver.def(
435  "to_smt2",
436  [](const SMT::Solver& self, const SMT::QueryConfig& config) -> std::optional<std::string> {
437  auto res = self.to_smt2(config);
438  if (res.is_ok())
439  {
440  return res.get();
441  }
442  log_error("python_context", "{}", res.get_error().get());
443  return std::nullopt;
444  },
445  py::arg("config"),
446  R"(
447  Translate the constraints of the solver into an smt2 representation of the query.
448 
449  :param hal_py.SMT.QueryConfig config: The SMT solver query configuration.
450  :returns: The smt2 representation on success, ``None`` otherwise.
451  :rtype: str or None
452  )");
453 
454  py_smt_solver.def_static(
455  "query_local_with_smt2",
456  [](const SMT::QueryConfig& config, const std::string& smt2) -> std::optional<SMT::SolverResult> {
457  auto res = SMT::Solver::query_local_with_smt2(config, smt2);
458  if (res.is_ok())
459  {
460  return res.get();
461  }
462  else
463  {
464  log_error("python_context", "{}", res.get_error().get());
465  return std::nullopt;
466  }
467  },
468  py::arg("config"),
469  py::arg("smt2"),
470  R"(
471  Queries a local SMT solver with the specified query configuration and the provided smt2 representation of the query.
472 
473  :param hal_py.SMT.QueryConfig config: The SMT solver query configuration.
474  :param str smt2: The SMT solver query as smt2 string.
475  :returns: The result on success, a string error message otherwise.
476  :rtype: hal_py.SMT.Result or str
477  )");
478 
479  py_smt_solver.def("query_remote", &SMT::Solver::query_remote, py::arg("config"), R"(
480  Queries a remote SMT solver with the specified query configuration.
481 
482  WARNING: This function is not yet implemented.
483 
484  :param hal_py.SMT.QueryConfig config: The SMT solver query configuration.
485  :returns: The result on success, a string error message otherwise.
486  :rtype: hal_py.SMT.Result or str
487  )");
488 
489  py::class_<SMT::SymbolicState> py_smt_symbolic_state(py_smt, "SymbolicState", R"(
490  Represents the data structure that keeps track of symbolic variable values (e.g., required for symbolic simplification).
491  )");
492 
493  py_smt_symbolic_state.def(py::init<const std::vector<BooleanFunction>&>(), py::arg("variables") = std::vector<BooleanFunction>(), R"(
494  Constructs a symbolic state and (optionally) initializes the variables.
495 
496  :param list[hal_py.BooleanFunction] variables: The (optional) list of variables.
497  )");
498 
499  py_smt_symbolic_state.def("get", &SMT::SymbolicState::get, py::arg("key"), R"(
500  Looks up a Boolean function in the symbolic state.
501 
502  :param hal_py.BooleanFunction key: The Boolean function to look up.
503  :returns: The Boolean function from the symbolic state or the key itself if it is not contained in the symbolic state.
504  :rtype: hal_py.BooleanFunction
505  )");
506 
507  py_smt_symbolic_state.def("set", &SMT::SymbolicState::set, py::arg("key"), py::arg("value"), R"(
508  Sets a Boolean function equivalent in the symbolic state.
509 
510  :param hal_py.BooleanFunction key: The Boolean function.
511  :param hal_py.BooleanFunction value: The equivalent Boolean function.
512  )");
513 
514  py::class_<SMT::SymbolicExecution> py_smt_symbolic_execution(py_smt, "SymbolicExecution", R"(
515  Represents the symbolic execution engine that handles the evaluation and simplification of Boolean function abstract syntax trees.
516  )");
517 
518  py_smt_symbolic_execution.def_readwrite("state", &SMT::SymbolicExecution::state, R"(
519  The current symbolic state.
520 
521  :type: hal_py.SMT.SymbolicState
522  )");
523 
524  py_smt_symbolic_execution.def(py::init<const std::vector<BooleanFunction>&>(), py::arg("variables") = std::vector<BooleanFunction>(), R"(
525  Creates a symbolic execution engine and (optionally) initializes the variables.
526 
527  :param list[hal_py.BooleanFunction] variables: The (optional) list of variables.
528  )");
529 
530  py_smt_symbolic_execution.def(
531  "evaluate",
532  [](const SMT::SymbolicExecution& self, const BooleanFunction& function) -> std::optional<BooleanFunction> {
533  auto res = self.evaluate(function);
534  if (res.is_ok())
535  {
536  return res.get();
537  }
538  log_error("python_context", "{}", res.get_error().get());
539  return std::nullopt;
540  },
541  py::arg("function"),
542  R"(
543  Evaluates a Boolean function within the symbolic state of the symbolic execution.
544 
545  :param hal_py.BooleanFunction function: The Boolean function to evaluate.
546  :returns: The evaluated Boolean function on success, ``None`` otherwise.
547  :rtype: hal_py.BooleanFunction or None
548  )");
549 
550  py_smt_symbolic_execution.def(
551  "evaluate",
552  [](SMT::SymbolicExecution& self, const SMT::Constraint& constraint) -> bool {
553  auto res = self.evaluate(constraint);
554  if (res.is_ok())
555  {
556  return true;
557  }
558  log_error("python_context", "{}", res.get_error().get());
559  return false;
560  },
561  py::arg("constraint"),
562  R"(
563  Evaluates an equality constraint and applies it to the symbolic state of the symbolic execution.
564 
565  :param hal_py.SMT.Constraint constraint: The equality constraint to evaluate.
566  :returns: ``True`` on success, ``False`` otherwise.
567  :rtype: bool
568  )");
569  }
570 } // namespace hal
static bool has_local_solver_for(SolverType type, SolverCall call)
Definition: solver.cpp:375
Solver & with_constraints(const std::vector< Constraint > &constraints)
Definition: solver.cpp:361
const std::vector< Constraint > & get_constraints() const
Definition: solver.cpp:370
static Result< SolverResult > query_local_with_smt2(const QueryConfig &config, const std::string &smt2)
Definition: solver.cpp:429
Result< SolverResult > query_remote(const QueryConfig &config) const
Definition: solver.cpp:440
Solver & with_constraint(const Constraint &constraint)
Definition: solver.cpp:355
SymbolicState state
The current symbolic state.
const BooleanFunction & get(const BooleanFunction &key) const
void set(const BooleanFunction &key, const BooleanFunction &value)
void smt_init(py::module &m)
Definition: smt.cpp:5
#define log_error(channel,...)
Definition: log.h:78
SolverType
Definition: types.h:47
const Module * module(const Gate *g, const NodeBoxes &boxes)
Definition: defines.h:45
bool is_assignment() const
Definition: types.cpp:173
std::variant< BooleanFunction, std::pair< BooleanFunction, BooleanFunction > > constraint
A constraint that is either an assignment of two Boolean functions or a single Boolean function,...
Definition: types.h:157
static Result< Model > parse(const std::string &model_str, const SolverType &solver)
Definition: types.cpp:220
std::map< std::string, std::tuple< u64, u16 > > model
maps variable identifiers to a (1) value and (2) its bit-size.
Definition: types.h:236
bool generate_model
Controls whether the SMT solver should generate a model in case formula is satisfiable.
Definition: types.h:76
QueryConfig & with_remote_solver()
Definition: types.cpp:107
SolverType solver
The SMT solver identifier.
Definition: types.h:70
u64 timeout_in_seconds
The timeout after which the SMT solver is killed in seconds.
Definition: types.h:78
QueryConfig & without_model_generation()
Definition: types.cpp:119
QueryConfig & with_model_generation()
Definition: types.cpp:113
QueryConfig & with_local_solver()
Definition: types.cpp:101
QueryConfig & with_timeout(u64 seconds)
Definition: types.cpp:125
QueryConfig & with_solver(SolverType solver)
Definition: types.cpp:89
QueryConfig & with_call(SolverCall call)
Definition: types.cpp:95
static SolverResult Unknown()
Definition: types.cpp:309
std::optional< Model > model
The (optional) model that is only available if type == SMT::ResultType::Sat and model generation is e...
Definition: types.h:308
static SolverResult Sat(const std::optional< Model > &model={})
Definition: types.cpp:299
bool is_sat() const
Definition: types.cpp:319
bool is(const SolverResultType &type) const
Definition: types.cpp:314
bool is_unsat() const
Definition: types.cpp:324
static SolverResult UnSat()
Definition: types.cpp:304
SolverResultType type
Result type of the SMT query.
Definition: types.h:306
bool is_unknown() const
Definition: types.cpp:329