7 auto py_smt = m.def_submodule(
"SMT", R
"(
11 py::enum_<SMT::SolverType> py_smt_solver_type(py_smt, "SolverType", R
"(
12 Identifier for the SMT solver type.
21 py::enum_<SMT::SolverCall> py_smt_solver_call(py_smt, "SolverCall", R
"(
22 Identifier for how the SMT solver is invoked.
29 py::class_<SMT::QueryConfig> py_smt_query_config(py_smt, "QueryConfig", R
"(
30 Represents the data structure to configure an SMT query.
33 py_smt_query_config.def(py::init<>(), R"(
34 Constructs a new query configuration.
38 The SMT solver identifier.
40 :type: hal_py.SMT.SolverType
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.
50 Controls whether the SMT solver should generate a model in case formula is satisfiable.
56 The timeout after which the SMT solver is killed in seconds.
62 Sets the solver type to the desired SMT solver.
64 :param hal_py.SMT.SolverType solver: The solver type identifier.
65 :returns: The updated SMT query configuration.
66 :rtype: hal_py.SMT.QueryConfig
70 Sets the call type to the desired target.
72 :param hal_py.SMT.SolverCall call: The solver call.
73 :returns: The updated SMT query configuration.
74 :rtype: hal_py.SMT.QueryConfig
78 Activates local SMT solver execution.
80 :returns: The updated SMT query configuration.
81 :rtype: hal_py.SMT.QueryConfig
85 Indicates that the SMT solver runs on a remote machine.
87 :returns: The updated SMT query configuration.
88 :rtype: hal_py.SMT.QueryConfig
92 Indicates that the SMT solver should generate a model in case the formula is satisfiable.
94 :returns: The updated SMT query configuration.
95 :rtype: hal_py.SMT.QueryConfig
99 Indicates that the SMT solver should not generate a model.
101 :returns: The updated SMT query configuration.
102 :rtype: hal_py.SMT.QueryConfig
106 Sets a timeout in seconds that terminates an SMT query after the specified time has passed.
108 :param int seconds: The timeout in seconds.
109 :returns: The updated SMT query configuration.
110 :rtype: hal_py.SMT.QueryConfig
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.
119 A constraint that is either an assignment of two Boolean functions or a single Boolean function, e.g., an equality check or similar.
121 :type: hal_py.BooleanFunction or tuple(hal_py.BooleanFunction, hal_py.BooleanFunction)
125 Constructs a new constraint from one Boolean function that evaluates to a single bit.
127 :param hal_py.BooleanFunction constraint: The constraint function.
131 Constructs a new equality constraint from two Boolean functions.
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.
138 Checks whether the constraint is an assignment constraint.
140 :returns: ``True`` if the constraint is an assignment, ``False`` otherwise.
144 py_smt_constraint.def(
146 [](
const SMT::Constraint&
self) -> std::optional<std::pair<BooleanFunction, BooleanFunction>> {
147 auto res =
self.get_assignment();
154 log_error(
"python_context",
"{}", res.get_error().get());
159 Returns the assignment constraint as a pair of Boolean functions.
161 :returns: The assignment constraint on success, ``None`` otherwise.
162 :rtype: tuple(hal_py.BooleanFunction,hal_py.BooleanFunction) or None
165 py_smt_constraint.def(
167 [](
const SMT::Constraint&
self) -> std::optional<const BooleanFunction*> {
168 auto res =
self.get_function();
175 log_error(
"python_context",
"{}", res.get_error().get());
180 Returns the function constraint.
182 :returns: The function constraint on success, ``None`` otherwise.
183 :rtype: hal_py.BooleanFunction or None
186 py::enum_<SMT::SolverResultType> py_smt_result_type(py_smt, "SolverResultType", R
"(
187 Result type of an SMT solver query.
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.
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.
202 :param dict[str,tuple(int,int)] model: A dict from variable name to value and bit-size.
205 py_smt_model.def(py::self == py::self, R"(
206 Checks whether two SMT models are equal.
208 :returns: ``True`` if both models are equal, ``False`` otherwise.
212 py_smt_model.def(py::self != py::self, R"(
213 Checks whether two SMT models are unequal.
215 :returns: ``True`` if both models are unequal, ``False`` otherwise.
220 A dict from variable identifiers to a (1) value and (2) its bit-size.
222 :type: dict(str,tuple(int,int))
225 py_smt_model.def_static(
227 [](
const std::string& model_str,
const SMT::SolverType& solver) -> std::optional<SMT::Model> {
235 log_error(
"python_context",
"{}", res.get_error().get());
239 py::arg(
"model_str"),
242 Parses an SMT-Lib model from a string output by a solver of the given type.
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
253 auto res =
self.evaluate(bf);
260 log_error(
"python_context",
"{}", res.get_error().get());
266 Evaluates the given Boolean function by replacing all variables contained in the model with their corresponding value and simplifying the result.
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
273 py::class_<SMT::SolverResult> py_smt_result(py_smt, "SolverResult", R
"(
274 Represents the result of an SMT query.
278 Result type of the SMT query.
280 :type: hal_py.SMT.ResultType
284 The (optional) model that is only available if type == SMT.ResultType.Sat and model generation is enabled.
286 :type: hal_py.SMT.Model
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.
292 :param hal_py.SMT.Model model: Optional model for satisfiable formula.
293 :returns: The result.
294 :rtype: hal_py.SMT.SolverResult
298 Creates an unsatisfiable result.
300 :returns: The result.
301 :rtype: hal_py.SMT.SolverResult
305 Creates an unknown result.
307 :returns: The result.
308 :rtype: hal_py.SMT.SolverResult
312 Checks whether the result is of a specific type.
314 :param hal_py.SMT.ResultType type: The type to check.
315 :returns: ``True`` in case result matches the given type, ``False`` otherwise.
320 Checks whether the result is satisfiable.
322 :returns: ``True`` in case result is satisfiable, ``False`` otherwise.
327 Checks whether the result is unsatisfiable.
329 :returns: ``True`` in case result is unsatisfiable, ``False`` otherwise.
334 Checks whether the result is unknown.
336 :returns: ``True`` in case result is unknown, ``False`` otherwise.
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.
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.
347 :param list[hal_py.SMT.Constraint] constraints: The (optional) list of constraints.
351 The list of constraints.
353 :type: list[hal_py.SMT.Constraint]
357 Returns the list of constraints.
359 :returns: The list of constraints.
360 :rtype: list[hal_py.SMT.Constraint]
364 Adds a constraint to the SMT solver.
366 :param hal_py.SMT.Constraint constraint: The constraint.
367 :returns: The updated SMT solver.
368 :rtype: hal_py.SMT.Solver
372 Adds a list of constraints to the SMT solver.
374 :param list[hal_py.SMT.Constraint] constraints: The constraints.
375 :returns: The updated SMT solver.
376 :rtype: hal_py.SMT.Solver
380 Checks whether a SMT solver of the given type is available on the local machine.
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.
391 auto res =
self.query(config);
398 log_error(
"python_context",
"{}", res.get_error().get());
404 Queries an SMT solver with the specified query configuration.
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
414 auto res =
self.query_local(config);
421 log_error(
"python_context",
"{}", res.get_error().get());
427 Queries a local SMT solver with the specified query configuration.
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
437 auto res =
self.to_smt2(config);
442 log_error(
"python_context",
"{}", res.get_error().get());
447 Translate the constraints of the solver into an smt2 representation of the query.
449 :param hal_py.SMT.QueryConfig config: The SMT solver query configuration.
450 :returns: The smt2 representation on success, ``None`` otherwise.
454 py_smt_solver.def_static(
455 "query_local_with_smt2",
456 [](
const SMT::QueryConfig& config,
const std::string& smt2) -> std::optional<SMT::SolverResult> {
464 log_error(
"python_context",
"{}", res.get_error().get());
471 Queries a local SMT solver with the specified query configuration and the provided smt2 representation of the query.
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
480 Queries a remote SMT solver with the specified query configuration.
482 WARNING: This function is not yet implemented.
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
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).
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.
496 :param list[hal_py.BooleanFunction] variables: The (optional) list of variables.
500 Looks up a Boolean function in the symbolic state.
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
508 Sets a Boolean function equivalent in the symbolic state.
510 :param hal_py.BooleanFunction key: The Boolean function.
511 :param hal_py.BooleanFunction value: The equivalent Boolean function.
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.
519 The current symbolic state.
521 :type: hal_py.SMT.SymbolicState
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.
527 :param list[hal_py.BooleanFunction] variables: The (optional) list of variables.
530 py_smt_symbolic_execution.def(
533 auto res =
self.evaluate(
function);
538 log_error(
"python_context",
"{}", res.get_error().get());
543 Evaluates a Boolean function within the symbolic state of the symbolic execution.
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
550 py_smt_symbolic_execution.def(
553 auto res =
self.evaluate(constraint);
558 log_error(
"python_context",
"{}", res.get_error().get());
561 py::arg(
"constraint"),
563 Evaluates an equality constraint and applies it to the symbolic state of the symbolic execution.
565 :param hal_py.SMT.Constraint constraint: The equality constraint to evaluate.
566 :returns: ``True`` on success, ``False`` otherwise.
static bool has_local_solver_for(SolverType type, SolverCall call)
Solver & with_constraints(const std::vector< Constraint > &constraints)
const std::vector< Constraint > & get_constraints() const
static Result< SolverResult > query_local_with_smt2(const QueryConfig &config, const std::string &smt2)
Result< SolverResult > query_remote(const QueryConfig &config) const
Solver & with_constraint(const Constraint &constraint)
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)
#define log_error(channel,...)
const Module * module(const Gate *g, const NodeBoxes &boxes)
bool is_assignment() const
std::variant< BooleanFunction, std::pair< BooleanFunction, BooleanFunction > > constraint
A constraint that is either an assignment of two Boolean functions or a single Boolean function,...
static Result< Model > parse(const std::string &model_str, const SolverType &solver)
std::map< std::string, std::tuple< u64, u16 > > model
maps variable identifiers to a (1) value and (2) its bit-size.
bool generate_model
Controls whether the SMT solver should generate a model in case formula is satisfiable.
QueryConfig & with_remote_solver()
SolverType solver
The SMT solver identifier.
u64 timeout_in_seconds
The timeout after which the SMT solver is killed in seconds.
QueryConfig & without_model_generation()
QueryConfig & with_model_generation()
QueryConfig & with_local_solver()
QueryConfig & with_timeout(u64 seconds)
QueryConfig & with_solver(SolverType solver)
QueryConfig & with_call(SolverCall call)
static SolverResult Unknown()
std::optional< Model > model
The (optional) model that is only available if type == SMT::ResultType::Sat and model generation is e...
static SolverResult Sat(const std::optional< Model > &model={})
bool is(const SolverResultType &type) const
static SolverResult UnSat()
SolverResultType type
Result type of the SMT query.