void display_solver_term(SOLVER_CONTEXT ctx, FILE * out, SOLVER_TERM term){ Z3_context c = (Z3_context) ctx; Z3_ast v = (Z3_ast) term; switch (Z3_get_ast_kind(c, v)) { case Z3_NUMERAL_AST: { Z3_sort t; fprintf(out, "%s", Z3_get_numeral_string(c, v)); t = Z3_get_sort(c, v); fprintf(out, ":"); display_sort(c, out, t); break; } case Z3_APP_AST: { unsigned i; Z3_app app = Z3_to_app(c, v); unsigned num_fields = Z3_get_app_num_args(c, app); Z3_func_decl d = Z3_get_app_decl(c, app); fprintf(out, "%s", Z3_func_decl_to_string(c, d)); if (num_fields > 0) { fprintf(out, "["); for (i = 0; i < num_fields; i++) { if (i > 0) { fprintf(out, ", "); } display_solver_term((SOLVER_CONTEXT) c, out, (SOLVER_TERM) Z3_get_app_arg(c, app, i)); } fprintf(out, "]"); } break; } case Z3_QUANTIFIER_AST: { fprintf(out, "quantifier"); ; } default: fprintf(out, "#unknown"); } }
std::string Z3Result::getStringValue() const { z3::expr sExpr = this->expr.simplify(); return Z3_get_numeral_string(this->context, sExpr); }
std::list<std::map<triton::uint32, SolverModel>> SolverEngine::getModels(triton::ast::AbstractNode* node, triton::uint32 limit) const { std::list<std::map<triton::uint32, SolverModel>> ret; std::ostringstream formula; z3::context ctx; z3::solver solver(ctx); triton::uint32 representationMode = triton::ast::representations::astRepresentation.getMode(); if (node == nullptr) throw triton::exceptions::SolverEngine("SolverEngine::getModels(): node cannot be null."); /* Switch into the SMT mode */ triton::ast::representations::astRepresentation.setMode(triton::ast::representations::SMT_REPRESENTATION); /* First, set the QF_AUFBV flag */ formula << "(set-logic QF_BV)"; /* Then, delcare all symbolic variables */ formula << this->symbolicEngine->getVariablesDeclaration(); /* And concat the user expression */ formula << this->symbolicEngine->getFullAst(node); /* Create the context and AST */ Z3_ast ast = Z3_parse_smtlib2_string(ctx, formula.str().c_str(), 0, 0, 0, 0, 0, 0); z3::expr eq(ctx, ast); /* Create a solver and add the expression */ solver.add(eq); /* Check if it is sat */ while (solver.check() == z3::sat && limit >= 1) { /* Get model */ z3::model m = solver.get_model(); /* Traversing the model */ std::map<triton::uint32, SolverModel> smodel; z3::expr_vector args(ctx); for (triton::uint32 i = 0; i < m.size(); i++) { /* Get the z3 variable */ z3::func_decl z3Variable = m[i]; /* Get the name as std::string from a z3 variable */ std::string varName = z3Variable.name().str(); /* Get z3 expr */ z3::expr exp = m.get_const_interp(z3Variable); /* Get the size of a z3 expr */ triton::uint32 bvSize = exp.get_sort().bv_size(); /* Get the value of a z3 expr */ std::string svalue = Z3_get_numeral_string(ctx, exp); /* Convert a string value to a integer value */ triton::uint512 value = triton::uint512(svalue); /* Create a triton model */ SolverModel trionModel = SolverModel(varName, value); /* Map the result */ smodel[trionModel.getId()] = trionModel; /* Uniq result */ if (exp.get_sort().is_bv()) args.push_back(ctx.bv_const(varName.c_str(), bvSize) != ctx.bv_val(svalue.c_str(), bvSize)); } /* Escape last models */ solver.add(triton::engines::solver::mk_or(args)); /* If there is model available */ if (smodel.size() > 0) ret.push_back(smodel); /* Decrement the limit */ limit--; } /* Restore the representation mode */ triton::ast::representations::astRepresentation.setMode(representationMode); return ret; }