Z3Sort::~Z3Sort() { if (Ctx != Z3Ctx::NullPtr && Sort != nullptr) { Z3_dec_ref(*Ctx, Z3_sort_to_ast(*Ctx, Sort)); } for (auto const& FuncDecl : FuncDecls) { Z3_dec_ref(*Ctx, Z3_func_decl_to_ast(*Ctx, FuncDecl.second)); } FuncDecls.clear(); }
void Z3Sort::AddFuncDecl(Z3_func_decl Decl) const { Z3_inc_ref(*Ctx, Z3_func_decl_to_ast(*Ctx, Decl)); string Name(Z3_get_symbol_string(*Ctx, Z3_get_decl_name(*Ctx, Decl))); auto it = FuncDecls.find(Name); if (it != FuncDecls.end()) { Z3_dec_ref(*Ctx, Z3_func_decl_to_ast(*Ctx, it->second)); } FuncDecls[Name] = Decl; }
int main(void) { z3::context context; const int N = 700; Z3_ast x_args[N]; for (unsigned i = 0; i < N; i++) { x_args[i] = context.constant(context.int_symbol(i), context.int_sort()); Z3_inc_ref(context, x_args[i]); } const z3::expr x_distinct_expr(context, Z3_mk_distinct(context, N, x_args)); for (unsigned i = 0; i < N; i++) { Z3_dec_ref(context, x_args[i]); } Z3_ast y_args[N]; for (unsigned i = 0; i < N; i++) { y_args[i] = context.constant(context.int_symbol(N + i), context.int_sort()); Z3_inc_ref(context, y_args[i]); } const z3::expr y_distinct_expr(context, Z3_mk_distinct(context, N, y_args)); for (unsigned i = 0; i < N; i++) { Z3_dec_ref(context, y_args[i]); } z3::solver solver(context); solver.add(x_distinct_expr); solver.add(y_distinct_expr); const z3::expr x(context.constant(context.int_symbol(7), context.int_sort())); const z3::expr y(context.constant(context.int_symbol(N + 42), context.int_sort())); solver.add(x == y); return z3::unsat == solver.check(); }
Z3Sort& Z3Sort::operator = (const Z3Sort& Other) { if(&Other == this) { return *this; } if (Ctx != nullptr && Sort != nullptr) { Z3_dec_ref(Ctx, Z3_sort_to_ast(Ctx, Sort)); } Ctx = Other.Ctx; Sort = Other.Sort; if (Ctx != nullptr && Sort != nullptr) { Z3_inc_ref(Ctx, Z3_sort_to_ast(Ctx, Sort)); } return *this; }
Z3Expr& Z3Expr::operator = (const Z3Expr& Other) { if(&Other == this) { return *this; } // Do the destructor if(AST != nullptr && Ctx != nullptr) { Z3_dec_ref(Ctx, AST); } // Assign Ctx = Other.Ctx; AST = Other.AST; if(AST != nullptr && Ctx != nullptr) { Z3_inc_ref(Ctx, AST); } return *this; }
SolverImpl::SolverRunStatus Z3SolverImpl::handleSolverResponse( ::Z3_solver theSolver, ::Z3_lbool satisfiable, const std::vector<const Array *> *objects, std::vector<std::vector<unsigned char> > *values, bool &hasSolution) { switch (satisfiable) { case Z3_L_TRUE: { hasSolution = true; if (!objects) { // No assignment is needed assert(values == NULL); return SolverImpl::SOLVER_RUN_STATUS_SUCCESS_SOLVABLE; } assert(values && "values cannot be nullptr"); ::Z3_model theModel = Z3_solver_get_model(builder->ctx, theSolver); assert(theModel && "Failed to retrieve model"); Z3_model_inc_ref(builder->ctx, theModel); values->reserve(objects->size()); for (std::vector<const Array *>::const_iterator it = objects->begin(), ie = objects->end(); it != ie; ++it) { const Array *array = *it; std::vector<unsigned char> data; data.reserve(array->size); for (unsigned offset = 0; offset < array->size; offset++) { // We can't use Z3ASTHandle here so have to do ref counting manually ::Z3_ast arrayElementExpr; Z3ASTHandle initial_read = builder->getInitialRead(array, offset); bool successfulEval = Z3_model_eval(builder->ctx, theModel, initial_read, /*model_completion=*/Z3_TRUE, &arrayElementExpr); assert(successfulEval && "Failed to evaluate model"); Z3_inc_ref(builder->ctx, arrayElementExpr); assert(Z3_get_ast_kind(builder->ctx, arrayElementExpr) == Z3_NUMERAL_AST && "Evaluated expression has wrong sort"); int arrayElementValue = 0; bool successGet = Z3_get_numeral_int(builder->ctx, arrayElementExpr, &arrayElementValue); assert(successGet && "failed to get value back"); assert(arrayElementValue >= 0 && arrayElementValue <= 255 && "Integer from model is out of range"); data.push_back(arrayElementValue); Z3_dec_ref(builder->ctx, arrayElementExpr); } values->push_back(data); } Z3_model_dec_ref(builder->ctx, theModel); return SolverImpl::SOLVER_RUN_STATUS_SUCCESS_SOLVABLE; } case Z3_L_FALSE: hasSolution = false; return SolverImpl::SOLVER_RUN_STATUS_SUCCESS_UNSOLVABLE; case Z3_L_UNDEF: { ::Z3_string reason = ::Z3_solver_get_reason_unknown(builder->ctx, theSolver); if (strcmp(reason, "timeout") == 0 || strcmp(reason, "canceled") == 0) { return SolverImpl::SOLVER_RUN_STATUS_TIMEOUT; } if (strcmp(reason, "unknown") == 0) { return SolverImpl::SOLVER_RUN_STATUS_FAILURE; } llvm::errs() << "Unexpected solver failure. Reason is \"" << reason << "\"\n"; abort(); } default: llvm_unreachable("unhandled Z3 result"); } }
Z3Expr::~Z3Expr() { if(AST != nullptr && Ctx != nullptr) { Z3_dec_ref(Ctx, AST); } }
Z3Sort::~Z3Sort() { if (Ctx != nullptr && Sort != nullptr) { Z3_dec_ref(Ctx, Z3_sort_to_ast(Ctx, Sort)); } }