Beispiel #1
0
Z3Solver::Z3Solver(Z3Ctx Ctx, Z3_solver Solver)
    : Z3Object(Ctx), Solver(Solver)
{
    if (Ctx != Z3Ctx::NullPtr && Solver != nullptr) {
        Z3_solver_inc_ref(*Ctx, Solver);
    }
}
Beispiel #2
0
Z3Solver::Z3Solver(const Z3Solver& Other)
    : Z3Object(Other), Solver(Other.Solver)
{
    if (Ctx != Z3Ctx::NullPtr && Solver != nullptr) {
        Z3_solver_inc_ref(*Ctx, Solver);
    }
}
Beispiel #3
0
bool Z3SolverImpl::internalRunSolver(
    const Query &query, const std::vector<const Array *> *objects,
    std::vector<std::vector<unsigned char> > *values, bool &hasSolution) {
  TimerStatIncrementer t(stats::queryTime);
  // TODO: Does making a new solver for each query have a performance
  // impact vs making one global solver and using push and pop?
  // TODO: is the "simple_solver" the right solver to use for
  // best performance?
  Z3_solver theSolver = Z3_mk_simple_solver(builder->ctx);
  Z3_solver_inc_ref(builder->ctx, theSolver);
  Z3_solver_set_params(builder->ctx, theSolver, solverParameters);

  runStatusCode = SOLVER_RUN_STATUS_FAILURE;

  for (ConstraintManager::const_iterator it = query.constraints.begin(),
                                         ie = query.constraints.end();
       it != ie; ++it) {
    Z3_solver_assert(builder->ctx, theSolver, builder->construct(*it));
  }
  ++stats::queries;
  if (objects)
    ++stats::queryCounterexamples;

  Z3ASTHandle z3QueryExpr =
      Z3ASTHandle(builder->construct(query.expr), builder->ctx);

  // KLEE Queries are validity queries i.e.
  // ∀ X Constraints(X) → query(X)
  // but Z3 works in terms of satisfiability so instead we ask the
  // negation of the equivalent i.e.
  // ∃ X Constraints(X) ∧ ¬ query(X)
  Z3_solver_assert(
      builder->ctx, theSolver,
      Z3ASTHandle(Z3_mk_not(builder->ctx, z3QueryExpr), builder->ctx));

  ::Z3_lbool satisfiable = Z3_solver_check(builder->ctx, theSolver);
  runStatusCode = handleSolverResponse(theSolver, satisfiable, objects, values,
                                       hasSolution);

  Z3_solver_dec_ref(builder->ctx, theSolver);
  // Clear the builder's cache to prevent memory usage exploding.
  // By using ``autoClearConstructCache=false`` and clearning now
  // we allow Z3_ast expressions to be shared from an entire
  // ``Query`` rather than only sharing within a single call to
  // ``builder->construct()``.
  builder->clearConstructCache();

  if (runStatusCode == SolverImpl::SOLVER_RUN_STATUS_SUCCESS_SOLVABLE ||
      runStatusCode == SolverImpl::SOLVER_RUN_STATUS_SUCCESS_UNSOLVABLE) {
    if (hasSolution) {
      ++stats::queriesInvalid;
    } else {
      ++stats::queriesValid;
    }
    return true; // success
  }
  return false; // failed
}
Beispiel #4
0
int main(){
	Z3_context context;
	Z3_solver solver;
	Z3_sort bvsort1;
	Z3_sort bvsort4;
	Z3_sort memsort;
	Z3_ast x_ast,y_ast,z_ast,u_ast,v_ast,w_ast,test_ast;
	Z3_model model;

	Z3_config config = Z3_mk_config();
	Z3_set_param_value(config,"model","true");
	context = Z3_mk_context_rc(config);
	Z3_set_error_handler(context,error_handler);

	solver = Z3_mk_solver(context);
	Z3_solver_inc_ref(context,solver);

	bvsort1 = Z3_mk_bv_sort(context,8);
	bvsort4 = Z3_mk_bv_sort(context,32);

	memsort = Z3_mk_array_sort(context,bvsort4,bvsort1);
	y_ast = Z3_mk_const(context,Z3_mk_string_symbol(context,"mem"),memsort);
	Z3_inc_ref(context,y_ast);

	u_ast = Z3_mk_unsigned_int64(context,13,bvsort4);
	Z3_inc_ref(context,u_ast);
	v_ast = Z3_mk_select(context,y_ast,u_ast);
	Z3_inc_ref(context,v_ast);

	z_ast = Z3_mk_unsigned_int64(context,7,bvsort1);
	Z3_inc_ref(context,z_ast);
	test_ast = Z3_mk_eq(context,v_ast,z_ast);
	Z3_inc_ref(context,test_ast);
	Z3_solver_assert(context,solver,test_ast);

	w_ast = Z3_mk_const(context,Z3_mk_string_symbol(context,"w"),bvsort1);
	y_ast = Z3_mk_store(context,y_ast,u_ast,w_ast);
	Z3_inc_ref(context,y_ast);

	v_ast = Z3_mk_select(context,y_ast,u_ast);
	Z3_inc_ref(context,v_ast);

	z_ast = Z3_mk_unsigned_int64(context,2,bvsort1);
	Z3_inc_ref(context,z_ast);
	test_ast = Z3_mk_eq(context,v_ast,z_ast);
	Z3_inc_ref(context,test_ast);
	Z3_solver_assert(context,solver,test_ast);

	Z3_solver_check(context,solver);
	model = Z3_solver_get_model(context,solver);
	fprintf(stderr,"%s\n",Z3_model_to_string(context,model));

	fprintf(stderr,"%s\n",Z3_simplify_get_help(context));

	return 0;
}
static void tst_get_implied_equalities1() {
    Z3_config cfg = Z3_mk_config();
    Z3_context ctx = Z3_mk_context(cfg);
    Z3_del_config(cfg);
    Z3_sort int_ty = Z3_mk_int_sort(ctx);
    Z3_ast a = mk_int_var(ctx,"a");
    Z3_ast b = mk_int_var(ctx,"b");
    Z3_ast c = mk_int_var(ctx,"c");
    Z3_ast d = mk_int_var(ctx,"d");
    Z3_func_decl f = Z3_mk_func_decl(ctx, Z3_mk_string_symbol(ctx,"f"), 1, &int_ty, int_ty);
    Z3_ast fa = Z3_mk_app(ctx, f, 1, &a);
    Z3_ast fb = Z3_mk_app(ctx, f, 1, &b);
    Z3_ast fc = Z3_mk_app(ctx, f, 1, &c);
    unsigned const num_terms = 7;
    unsigned i;
    Z3_ast terms[7] = { a, b, c, d, fa, fb, fc };
    unsigned class_ids[7] = { 0, 0, 0, 0, 0, 0, 0 };
    Z3_solver solver = Z3_mk_simple_solver(ctx);
    Z3_solver_inc_ref(ctx, solver);
        
    Z3_solver_assert(ctx, solver, Z3_mk_eq(ctx, a, b));
    Z3_solver_assert(ctx, solver, Z3_mk_eq(ctx, b, d));
    Z3_solver_assert(ctx, solver, Z3_mk_le(ctx, fa, fc));
    Z3_solver_assert(ctx, solver, Z3_mk_le(ctx, fc, d));
    
    Z3_get_implied_equalities(ctx, solver, num_terms, terms, class_ids);
    for (i = 0; i < num_terms; ++i) {
        printf("Class %s |-> %d\n", Z3_ast_to_string(ctx, terms[i]), class_ids[i]);
    }
    SASSERT(class_ids[1] == class_ids[0]);
    SASSERT(class_ids[2] != class_ids[0]);
    SASSERT(class_ids[3] == class_ids[0]);
    SASSERT(class_ids[4] != class_ids[0]);
    SASSERT(class_ids[5] != class_ids[0]);
    SASSERT(class_ids[6] != class_ids[0]);
    SASSERT(class_ids[4] == class_ids[5]);

    printf("asserting b <= f(a)\n");
    Z3_solver_assert(ctx, solver, Z3_mk_le(ctx, b, fa));
    Z3_get_implied_equalities(ctx, solver, num_terms, terms, class_ids);
    for (i = 0; i < num_terms; ++i) {
        printf("Class %s |-> %d\n", Z3_ast_to_string(ctx, terms[i]), class_ids[i]);
    }
    SASSERT(class_ids[1] == class_ids[0]);
    SASSERT(class_ids[2] != class_ids[0]);
    SASSERT(class_ids[3] == class_ids[0]);
    SASSERT(class_ids[4] == class_ids[0]);
    SASSERT(class_ids[5] == class_ids[0]);
    SASSERT(class_ids[6] == class_ids[0]);

    
    Z3_solver_dec_ref(ctx, solver);
    /* delete logical context */
    Z3_del_context(ctx);    
}
Beispiel #6
0
Z3Solver::Z3Solver(Z3Ctx Ctx)
    : Z3Object(Ctx)
{
    if (Ctx != Z3Ctx::NullPtr) {
        Solver = Z3_mk_solver(*Ctx);
    } else {
        Solver = nullptr;
    }
    if (Ctx != Z3Ctx::NullPtr && Solver != nullptr) {
        Z3_solver_inc_ref(*Ctx, Solver);
    }
}
void z3_wrapper_init(z3_wrapper *z3) {
  /* init ctx */
  Z3_config cfg = Z3_mk_config();
  Z3_set_param_value(cfg, "model", "true");
  z3->ctx = Z3_mk_context(cfg);

  /* init error handling */
  Z3_set_error_handler(z3->ctx, z3_error_handler);

  /* init solver */
  z3->solver = Z3_mk_solver(z3->ctx);
  Z3_solver_inc_ref(z3->ctx, z3->solver);

  Z3_del_config(cfg);

  z3->Ek_consts = NULL;
}
static void tst_get_implied_equalities2() {
    enable_trace("after_search");
    enable_trace("get_implied_equalities");
    enable_trace("implied_equalities");
    Z3_config cfg = Z3_mk_config();
    Z3_context ctx = Z3_mk_context(cfg);
    Z3_del_config(cfg);
    Z3_solver solver = Z3_mk_simple_solver(ctx);
    Z3_solver_inc_ref(ctx, solver);
    Z3_sort int_ty = Z3_mk_int_sort(ctx);
    Z3_ast a = mk_int_var(ctx,"a");
    Z3_ast b = mk_int_var(ctx,"b");
    Z3_ast one = Z3_mk_numeral(ctx, "1", int_ty);
    Z3_ast two = Z3_mk_numeral(ctx, "2", int_ty);
    Z3_ast x = Z3_mk_const_array(ctx, int_ty, one);
    Z3_ast y = Z3_mk_store(ctx, x, one, a);
    Z3_ast z = Z3_mk_store(ctx, y, two , b);
    Z3_ast u = Z3_mk_store(ctx, x, two , b);
    Z3_ast v = Z3_mk_store(ctx, u, one , a);
    unsigned const num_terms = 5;
    unsigned i;
    Z3_ast terms[5] = { x, y, z, u, v};
    unsigned class_ids[5] = { 0, 0, 0, 0, 0};
    
    Z3_get_implied_equalities(ctx, solver, num_terms, terms, class_ids);
    for (i = 0; i < num_terms; ++i) {
        printf("Class %s |-> %d\n", Z3_ast_to_string(ctx, terms[i]), class_ids[i]);
    }

    SASSERT(class_ids[1] != class_ids[0]);
    SASSERT(class_ids[2] != class_ids[0]);
    SASSERT(class_ids[3] != class_ids[0]);
    SASSERT(class_ids[4] != class_ids[0]);
    SASSERT(class_ids[4] == class_ids[2]);
    SASSERT(class_ids[2] != class_ids[1]);
    SASSERT(class_ids[3] != class_ids[1]);
    SASSERT(class_ids[4] != class_ids[1]);  
    SASSERT(class_ids[3] != class_ids[2]);

    /* delete logical context */
    Z3_solver_dec_ref(ctx, solver);
    Z3_del_context(ctx);    
}
Beispiel #9
0
Z3_solver mk_solver(Z3_context ctx)
{
    Z3_solver r = Z3_mk_solver(ctx);
    Z3_solver_inc_ref(ctx, r);
    return r;
}
Beispiel #10
0
bool Z3SolverImpl::internalRunSolver(
    const Query &query, const std::vector<const Array *> *objects,
    std::vector<std::vector<unsigned char> > *values, bool &hasSolution) {

  TimerStatIncrementer t(stats::queryTime);
  // NOTE: Z3 will switch to using a slower solver internally if push/pop are
  // used so for now it is likely that creating a new solver each time is the
  // right way to go until Z3 changes its behaviour.
  //
  // TODO: Investigate using a custom tactic as described in
  // https://github.com/klee/klee/issues/653
  Z3_solver theSolver = Z3_mk_solver(builder->ctx);
  Z3_solver_inc_ref(builder->ctx, theSolver);
  Z3_solver_set_params(builder->ctx, theSolver, solverParameters);

  runStatusCode = SOLVER_RUN_STATUS_FAILURE;

  for (ConstraintManager::const_iterator it = query.constraints.begin(),
                                         ie = query.constraints.end();
       it != ie; ++it) {
    Z3_solver_assert(builder->ctx, theSolver, builder->construct(*it));
  }
  ++stats::queries;
  if (objects)
    ++stats::queryCounterexamples;

  Z3ASTHandle z3QueryExpr =
      Z3ASTHandle(builder->construct(query.expr), builder->ctx);

  // KLEE Queries are validity queries i.e.
  // ∀ X Constraints(X) → query(X)
  // but Z3 works in terms of satisfiability so instead we ask the
  // negation of the equivalent i.e.
  // ∃ X Constraints(X) ∧ ¬ query(X)
  Z3_solver_assert(
      builder->ctx, theSolver,
      Z3ASTHandle(Z3_mk_not(builder->ctx, z3QueryExpr), builder->ctx));

  if (dumpedQueriesFile) {
    *dumpedQueriesFile << "; start Z3 query\n";
    *dumpedQueriesFile << Z3_solver_to_string(builder->ctx, theSolver);
    *dumpedQueriesFile << "(check-sat)\n";
    *dumpedQueriesFile << "(reset)\n";
    *dumpedQueriesFile << "; end Z3 query\n\n";
    dumpedQueriesFile->flush();
  }

  ::Z3_lbool satisfiable = Z3_solver_check(builder->ctx, theSolver);
  runStatusCode = handleSolverResponse(theSolver, satisfiable, objects, values,
                                       hasSolution);

  Z3_solver_dec_ref(builder->ctx, theSolver);
  // Clear the builder's cache to prevent memory usage exploding.
  // By using ``autoClearConstructCache=false`` and clearning now
  // we allow Z3_ast expressions to be shared from an entire
  // ``Query`` rather than only sharing within a single call to
  // ``builder->construct()``.
  builder->clearConstructCache();

  if (runStatusCode == SolverImpl::SOLVER_RUN_STATUS_SUCCESS_SOLVABLE ||
      runStatusCode == SolverImpl::SOLVER_RUN_STATUS_SUCCESS_UNSOLVABLE) {
    if (hasSolution) {
      ++stats::queriesInvalid;
    } else {
      ++stats::queriesValid;
    }
    return true; // success
  }
  return false; // failed
}