26 z3::expr Z3Solver::mk_or(z3::expr_vector args) {
27 std::vector<Z3_ast> array;
30 array.push_back(args[i]);
32 return to_expr(args.ctx(), Z3_mk_or(args.ctx(),
static_cast<triton::uint32>(array.size()), &(array[0])));
38 this->memoryLimit = 0;
43 std::vector<std::unordered_map<triton::usize, SolverModel>> ret;
53 onode = node->getChildren()[0];
55 if (onode->isLogical() ==
false)
58 z3::expr expr = z3Ast.convert(onode);
59 z3::context& ctx = expr.ctx();
60 z3::solver solver(ctx);
69 p.set(
":timeout", timeout);
71 else if (this->timeout) {
72 p.set(
":timeout", this->timeout);
76 if (this->memoryLimit) {
77 p.set(
":max_memory", this->memoryLimit);
83 auto start = std::chrono::system_clock::now();
86 z3::check_result res = solver.check();
89 this->writeBackStatus(solver, res, status);
92 while (res == z3::sat && limit >= 1) {
94 z3::model m = solver.get_model();
97 std::unordered_map<triton::usize, SolverModel> smodel;
98 z3::expr_vector args(ctx);
102 z3::func_decl z3Variable = m[i];
105 std::string varName = z3Variable.name().str();
108 z3::expr exp = m.get_const_interp(z3Variable);
114 std::string svalue = Z3_get_numeral_string(ctx, exp);
123 smodel[trionModel.
getId()] = trionModel;
126 if (exp.get_sort().is_bv())
127 args.push_back(ctx.bv_const(varName.c_str(), bvSize) != ctx.bv_val(svalue.c_str(), bvSize));
135 ret.push_back(smodel);
140 solver.add(this->mk_or(args));
144 res = solver.check();
149 auto end = std::chrono::system_clock::now();
152 *solvingTime = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
154 catch (
const z3::exception& e) {
155 if (!strcmp(e.msg(),
"max. memory exceeded")) {
174 if (node->isLogical() ==
false)
178 z3::expr expr = z3Ast.convert(node);
179 z3::context& ctx = expr.ctx();
180 z3::solver solver(ctx);
189 p.set(
":timeout", timeout);
191 else if (this->timeout) {
192 p.set(
":timeout", this->timeout);
196 if (this->memoryLimit) {
197 p.set(
":max_memory", this->memoryLimit);
203 auto start = std::chrono::system_clock::now();
205 z3::check_result res = solver.check();
208 auto end = std::chrono::system_clock::now();
211 *solvingTime = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
213 this->writeBackStatus(solver, res, status);
214 return res == z3::sat;
216 catch (
const z3::exception& e) {
217 if (!strcmp(e.msg(),
"max. memory exceeded")) {
229 std::unordered_map<triton::usize, SolverModel> ret;
230 std::vector<std::unordered_map<triton::usize, SolverModel>> allModels;
232 allModels = this->
getModels(node, 1, status, timeout, solvingTime);
233 if (allModels.size() > 0)
234 ret = allModels.front();
249 z3::expr expr = z3Ast.
convert(node);
252 auto snode = tritonAst.convert(expr.simplify());
256 catch (
const z3::exception& e) {
270 z3::expr expr = z3ast.
convert(node);
273 expr = expr.simplify();
276 if (expr.get_sort().is_bool())
277 res = Z3_get_bool_value(expr.ctx(), expr) == Z3_L_TRUE ? true :
false;
283 catch (
const z3::exception& e) {
290 if (status !=
nullptr) {
301 if (solver.reason_unknown() ==
"timeout") {
304 else if (solver.reason_unknown() ==
"max. memory exceeded") {
327 this->memoryLimit = limit;
Converts a Triton's AST to Z3's AST.
TRITON_EXPORT z3::expr convert(const triton::ast::SharedAbstractNode &node)
Converts to Z3's AST.
Converts a Z3's AST to a Triton's AST.
TRITON_EXPORT triton::ast::SharedAbstractNode convert(const z3::expr &expr)
Converts to Triton's AST.
This class is used to represent a constraint model solved.
TRITON_EXPORT triton::usize getId(void) const
Returns the id of the variable.
TRITON_EXPORT std::unordered_map< triton::usize, SolverModel > getModel(const triton::ast::SharedAbstractNode &node, triton::engines::solver::status_e *status=nullptr, triton::uint32 timeout=0, triton::uint32 *solvingTime=nullptr) const
Computes and returns a model from a symbolic constraint. State is returned in the status pointer as w...
TRITON_EXPORT Z3Solver()
Constructor.
TRITON_EXPORT triton::uint512 evaluate(const triton::ast::SharedAbstractNode &node) const
Evaluates a Triton's AST via Z3 and returns a concrete value.
TRITON_EXPORT bool isSat(const triton::ast::SharedAbstractNode &node, triton::engines::solver::status_e *status=nullptr, triton::uint32 timeout=0, triton::uint32 *solvingTime=nullptr) const
Returns true if an expression is satisfiable.
TRITON_EXPORT std::string getName(void) const
Returns the name of this solver.
TRITON_EXPORT void setTimeout(triton::uint32 ms)
Defines a solver timeout (in milliseconds).
TRITON_EXPORT triton::ast::SharedAbstractNode simplify(const triton::ast::SharedAbstractNode &node) const
Converts a Triton's AST to a Z3's AST, perform a Z3 simplification and returns a Triton's AST.
TRITON_EXPORT void setMemoryLimit(triton::uint32 mem)
Defines a solver memory consumption limit (in megabytes).
TRITON_EXPORT std::vector< std::unordered_map< triton::usize, SolverModel > > getModels(const triton::ast::SharedAbstractNode &node, triton::uint32 limit, triton::engines::solver::status_e *status=nullptr, triton::uint32 timeout=0, triton::uint32 *solvingTime=nullptr) const
Computes and returns several models from a symbolic constraint. The limit is the number of models ret...
The exception class used by all AST lifting (e.g z3 <-> triton).
The exception class used by the solver engine.
std::shared_ptr< triton::ast::AbstractNode > SharedAbstractNode
Shared Abstract Node.
math::wide_integer::uint512_t uint512
unsigned 512-bits
std::uint32_t uint32
unisgned 32-bits