示例#1
0
Z3Model::Z3Model(Z3Ctx Ctx, Z3_model Model, Z3TheoremProver* TPPtr)
    : Z3Object(Ctx), Model(Model), TPPtr(TPPtr)
{
    if (Ctx != Z3Ctx::NullPtr && Model != nullptr) {
        Z3_model_inc_ref(*Ctx, Model);
    }
}
示例#2
0
Z3Model::Z3Model(const Z3Model& Other)
    : Z3Object(Other), Model(Other.Model), TPPtr(Other.TPPtr)
{
    if (Ctx != Z3Ctx::NullPtr && Model != nullptr) {
        Z3_model_inc_ref(*Ctx, Model);
    }
}
示例#3
0
 Z3Model::Z3Model(const Z3Model& Other)
     : Z3Object(Other.Ctx), Model(Other.Model)
 {
     if(Model != nullptr && Ctx != nullptr) {
         Z3_model_inc_ref(Ctx, Model);
     }
 }
示例#4
0
 Z3Model::Z3Model(Z3_context Ctx, Z3_model Model)
     : Z3Object(Ctx), Model(Model)
 {
     if (Ctx == nullptr || Model == nullptr) {
         throw InternalError((string)"Error: Z3Model::Z3Model(Z3_context, Z3_model) called with " + 
                             "one or more nullptrs");
     }
     Z3_model_inc_ref(Ctx, Model);
 }
示例#5
0
/**
   \brief Small test for the at-most-one constraint.
*/
void tst_at_most_one() 
{
    Z3_context ctx = mk_context();
    Z3_solver s    = mk_solver(ctx);
    Z3_ast k1      = mk_bool_var(ctx, "k1");
    Z3_ast k2      = mk_bool_var(ctx, "k2");
    Z3_ast k3      = mk_bool_var(ctx, "k3");
    Z3_ast k4      = mk_bool_var(ctx, "k4");
    Z3_ast k5      = mk_bool_var(ctx, "k5");
    Z3_ast k6      = mk_bool_var(ctx, "k6");
    Z3_ast args1[5] = { k1, k2, k3, k4, k5 };
    Z3_ast args2[3] = { k4, k5, k6 };
    Z3_model m      = 0;
    Z3_lbool result;
    printf("testing at-most-one constraint\n");
    assert_at_most_one(ctx, s, 5, args1);
    assert_at_most_one(ctx, s, 3, args2);
    printf("it must be sat...\n");
    result = Z3_solver_check(ctx, s);
    if (result != Z3_L_TRUE)
        error("BUG");
    m = Z3_solver_get_model(ctx, s);
    Z3_model_inc_ref(ctx, m);
    printf("model:\n%s\n", Z3_model_to_string(ctx, m));
    Z3_model_dec_ref(ctx, m);
    Z3_solver_assert(ctx, s, mk_binary_or(ctx, k2, k3));
    Z3_solver_assert(ctx, s, mk_binary_or(ctx, k1, k6));
    printf("it must be sat...\n");
    result = Z3_solver_check(ctx, s);
    if (result != Z3_L_TRUE)
        error("BUG");
    m = Z3_solver_get_model(ctx, s);
    Z3_model_inc_ref(ctx, m);
    printf("model:\n%s\n", Z3_model_to_string(ctx, m));
    Z3_solver_assert(ctx, s, mk_binary_or(ctx, k4, k5));
    printf("it must be unsat...\n");
    result = Z3_solver_check(ctx, s);
    if (result != Z3_L_FALSE)
        error("BUG");
    Z3_model_dec_ref(ctx, m);
    Z3_solver_dec_ref(ctx, s);
    Z3_del_context(ctx);
}
示例#6
0
/**
   \brief Naive maxsat procedure based on linear search and at-most-k
   constraint.  Return the number of soft-constraints that can be
   satisfied.  Return -1 if the hard-constraints cannot be
   satisfied. That is, the formula cannot be satisfied even if all
   soft-constraints are ignored.

   Exercise: use binary search to implement MaxSAT.
   Hint: you will need to use an answer literal to retract the at-most-k constraint.
*/
int naive_maxsat(Z3_context ctx, Z3_solver s, unsigned num_hard_cnstrs, Z3_ast * hard_cnstrs, unsigned num_soft_cnstrs, Z3_ast * soft_cnstrs) 
{
    Z3_ast * aux_vars;
    Z3_lbool is_sat;
    unsigned r, k;
    assert_hard_constraints(ctx, s, num_hard_cnstrs, hard_cnstrs);
    printf("checking whether hard constraints are satisfiable...\n");
    is_sat = Z3_solver_check(ctx, s);
    if (is_sat == Z3_L_FALSE) {
        // It is not possible to make the formula satisfiable even when ignoring all soft constraints.
        return -1; 
    }
    if (num_soft_cnstrs == 0)
        return 0; // nothing to be done...
    aux_vars = assert_soft_constraints(ctx, s, num_soft_cnstrs, soft_cnstrs);
    // Perform linear search.
    r = 0;
    k = num_soft_cnstrs - 1;
    for (;;) {
        Z3_model m;
        unsigned num_disabled;
        // at most k soft-constraints can be ignored.
        printf("checking whether at-most %d soft-constraints can be ignored.\n", k);
        assert_at_most_k(ctx, s, num_soft_cnstrs, aux_vars, k);
        is_sat = Z3_solver_check(ctx, s);
        if (is_sat == Z3_L_FALSE) {
            printf("unsat\n");
            return num_soft_cnstrs - k - 1;
        }
    m = Z3_solver_get_model(ctx, s);
        Z3_model_inc_ref(ctx, m);
        num_disabled = get_num_disabled_soft_constraints(ctx, m, num_soft_cnstrs, aux_vars);
        Z3_model_dec_ref(ctx, m);
        if (num_disabled > k) {
            error("BUG");
        }
        printf("sat\n");
        k = num_disabled;
        if (k == 0) {
            // it was possible to satisfy all soft-constraints.
            return num_soft_cnstrs; 
        }
        k--;
    }
}
示例#7
0
    Z3Model& Z3Model::operator = (const Z3Model& Other)
    {
        if(&Other == this) {
            return *this;
        }

        // Do the destructor
        if(Model != nullptr && Ctx != nullptr) {
            Z3_model_dec_ref(Ctx, Model);
        }

        // Assign
        Ctx = Other.Ctx;
        Model = Other.Model;

        if(Model != nullptr && Ctx != nullptr) {
            Z3_model_inc_ref(Ctx, Model);
        }
        return *this;
    }
void get_function(z3_wrapper *z3, Z3_func_decl fun, uint32_t fun_arity, struct fun *kfun) {
  Z3_model m = Z3_solver_get_model(z3->ctx, z3->solver);
  assert(m);
  
  /* printf("------\n%s\n------\n", Z3_model_to_string(z3->ctx, m)); */
  
  Z3_model_inc_ref(z3->ctx, m);
  
  fun_init(kfun, fun_arity);
  for(size_t xs = 0; xs < int_pow(K, fun_arity); ++xs) {
    /* represent `xs` in the K-ary form,
     * with digits[0] being the highest digit. */
    uint32_t digits[fun_arity];
    get_K_digits(digits, fun_arity, xs);
    Z3_ast args[fun_arity];
    for(size_t i = 0; i < fun_arity; ++i) {
      args[i] = z3->Ek_consts[digits[i]];
    }
    
    /* eval func on given args */
    Z3_ast t = Z3_mk_app(z3->ctx, fun, fun_arity, args);
    Z3_ast res;
 
    assert(Z3_model_eval(z3->ctx, m, t, 1, &res) == Z3_TRUE);


    /* printf("%s == %s\n", Z3_ast_to_string(z3->ctx, t), Z3_ast_to_string(z3->ctx, res)); */
    
    /* interpret the result of function application */
    uint64_t y;
    sscanf(Z3_ast_to_string(z3->ctx, res), "V%lu", &y);
    fun_set_val(kfun, xs, y);
  }
  
  Z3_model_dec_ref(z3->ctx, m);
}
示例#9
0
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");
  }
}