/* (declare-fun p_name (E3 E3 ...) Bool) */ Z3_func_decl gen_pred(z3_wrapper *z3, const char *name, const pred *pred) { Z3_symbol symb = Z3_mk_string_symbol(z3->ctx, name); Z3_sort domain[pred->arity]; for(size_t i = 0; i < pred->arity; ++i) { domain[i] = z3->Ek_sort; } Z3_sort range = Z3_mk_bool_sort(z3->ctx); Z3_func_decl p = Z3_mk_func_decl(z3->ctx, symb, pred->arity, domain, range); /* create assertions */ for(size_t xs = 0; xs < int_pow(K, pred->arity); ++xs) { /* represent `xs` in the K-ary form, * with digits[0] being the highest digit. */ uint32_t digits[pred->arity]; get_K_digits(digits, pred->arity, xs); Z3_ast args[pred->arity]; for(size_t i = 0; i < pred->arity; ++i) { args[i] = z3->Ek_consts[digits[i]]; } Z3_ast phi = Z3_mk_app(z3->ctx, p, pred->arity, args); /* if the predicate equals to false on `xs` */ if(!pred_compute(pred, xs)) { phi = Z3_mk_not(z3->ctx, phi); } /* printf("\n%s\n", Z3_ast_to_string(z3->ctx, phi)); */ Z3_solver_assert(z3->ctx, z3->solver, phi); } return p; }
/* (declare-fun f (E3 E3 E3 ...) E3) */ Z3_func_decl gen_fun(z3_wrapper *z3, const char *name, uint32_t arity) { Z3_symbol symb = Z3_mk_string_symbol(z3->ctx, name); Z3_sort domain[arity]; for(size_t i = 0; i < arity; ++i) { domain[i] = z3->Ek_sort; } Z3_sort range = z3->Ek_sort; return Z3_mk_func_decl(z3->ctx, symb, arity, domain, range); }
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); }
void test_apps() { Z3_config cfg = Z3_mk_config(); Z3_set_param_value(cfg,"MODEL","true"); Z3_context ctx = Z3_mk_context(cfg); Z3_symbol A = Z3_mk_string_symbol(ctx, "A"); Z3_symbol F = Z3_mk_string_symbol(ctx, "f"); Z3_sort SA = Z3_mk_uninterpreted_sort(ctx, A); Z3_func_decl f = Z3_mk_func_decl(ctx, F, 1, &SA, SA); Z3_symbol X = Z3_mk_string_symbol(ctx, "x"); Z3_ast x = Z3_mk_const(ctx, X, SA); Z3_ast fx = Z3_mk_app(ctx, f, 1, &x); Z3_ast ffx = Z3_mk_app(ctx, f, 1, &fx); Z3_ast fffx = Z3_mk_app(ctx, f, 1, &ffx); Z3_ast ffffx = Z3_mk_app(ctx, f, 1, &fffx); Z3_ast fffffx = Z3_mk_app(ctx, f, 1, &ffffx); Z3_ast fml = Z3_mk_not(ctx, Z3_mk_eq(ctx, x, fffffx)); Z3_assert_cnstr(ctx, fml); Z3_lbool r = Z3_check(ctx); std::cout << r << "\n"; Z3_del_config(cfg); Z3_del_context(ctx); }
void test_smt_relation_api() { enable_trace("smt_relation"); enable_trace("smt_relation2"); enable_trace("quant_elim"); Z3_config cfg = Z3_mk_config(); Z3_set_param_value(cfg, "DL_DEFAULT_RELATION", "smt_relation2"); Z3_context ctx = Z3_mk_context(cfg); Z3_fixedpoint dl = Z3_mk_fixedpoint(ctx); Z3_fixedpoint_inc_ref(ctx,dl); Z3_del_config(cfg); Z3_sort int_sort = Z3_mk_int_sort(ctx); Z3_sort bool_sort = Z3_mk_bool_sort(ctx); Z3_func_decl nil_decl, is_nil_decl; Z3_func_decl cons_decl, is_cons_decl, head_decl, tail_decl; Z3_sort list = Z3_mk_list_sort( ctx, Z3_mk_string_symbol(ctx, "list"), int_sort, &nil_decl, &is_nil_decl, &cons_decl, &is_cons_decl, &head_decl, &tail_decl); Z3_sort listint[2] = { list, int_sort }; Z3_symbol p_sym = Z3_mk_string_symbol(ctx, "p"); Z3_symbol q_sym = Z3_mk_string_symbol(ctx, "q"); Z3_func_decl p = Z3_mk_func_decl(ctx, p_sym, 2, listint, bool_sort); Z3_func_decl q = Z3_mk_func_decl(ctx, q_sym, 2, listint, bool_sort); Z3_fixedpoint_register_relation(ctx, dl, p); Z3_fixedpoint_register_relation(ctx, dl, q); Z3_ast zero = Z3_mk_numeral(ctx, "0", int_sort); Z3_ast one = Z3_mk_numeral(ctx, "1", int_sort); Z3_ast two = Z3_mk_numeral(ctx, "2", int_sort); Z3_ast x = Z3_mk_bound(ctx, 0, list); Z3_ast y = Z3_mk_bound(ctx, 1, int_sort); Z3_ast z = Z3_mk_bound(ctx, 2, list); Z3_ast zero_x[2] = { zero, x }; Z3_ast fx = Z3_mk_app(ctx, cons_decl, 2, zero_x); Z3_ast zero_fx[2] = { zero, fx }; Z3_ast ffx = Z3_mk_app(ctx, cons_decl, 2, zero_fx); Z3_ast xy[2] = { x, y }; Z3_ast zy[2] = { z, y }; // Z3_ast ffxy[2] = { ffx, y }; // Z3_ast fxy[2] = { fx, y }; Z3_ast zero_nil[2] = { zero, Z3_mk_app(ctx, nil_decl, 0, 0) }; Z3_ast f0 = Z3_mk_app(ctx, cons_decl, 2, zero_nil); Z3_ast zero_f0[2] = { zero, f0 }; Z3_ast f1 = Z3_mk_app(ctx, cons_decl, 2, zero_f0); Z3_ast zero_f1[2] = { zero, f1 }; Z3_ast f2 = Z3_mk_app(ctx, cons_decl, 2, zero_f1); Z3_ast zero_f2[2] = { zero, f2 }; Z3_ast f3 = Z3_mk_app(ctx, cons_decl, 2, zero_f2); Z3_ast zero_f3[2] = { zero, f3 }; Z3_ast f4 = Z3_mk_app(ctx, cons_decl, 2, zero_f3); Z3_ast zero_f4[2] = { zero, f4 }; Z3_ast f5 = Z3_mk_app(ctx, cons_decl, 2, zero_f4); Z3_ast zero_z[2] = { zero, z }; Z3_ast fz = Z3_mk_app(ctx, cons_decl, 2, zero_z); Z3_ast pxy = Z3_mk_app(ctx, p, 2, xy); Z3_ast pzy = Z3_mk_app(ctx, p, 2, zy); Z3_ast qxy = Z3_mk_app(ctx, q, 2, xy); Z3_ast qzy = Z3_mk_app(ctx, q, 2, zy); Z3_ast even_y = Z3_mk_eq(ctx, zero, Z3_mk_mod(ctx, y, two)); Z3_ast odd_y = Z3_mk_eq(ctx, one, Z3_mk_mod(ctx, y, two)); // p(x, y) :- odd(y), p(z,y), f(z) = x . // dead rule. // q(x, y) :- p(f(f(x)), y). // p(x, y) :- q(f(x), y) // x decreases // p(x, y) :- even y, x = f^5(0) // initial condition. Z3_ast body1[3] = { pzy, Z3_mk_eq(ctx, fz, x), odd_y }; Z3_ast body2[2] = { pzy, Z3_mk_eq(ctx, ffx, z) }; Z3_ast body3[2] = { qzy, Z3_mk_eq(ctx, fx, z) }; Z3_ast body4[2] = { even_y, Z3_mk_eq(ctx, x, f5) }; Z3_fixedpoint_add_rule(ctx, dl, Z3_mk_implies(ctx, Z3_mk_and(ctx, 3, body1), pxy), 0); Z3_fixedpoint_add_rule(ctx, dl, Z3_mk_implies(ctx, Z3_mk_and(ctx, 2, body2), qxy), 0); Z3_fixedpoint_add_rule(ctx, dl, Z3_mk_implies(ctx, Z3_mk_and(ctx, 2, body3), pxy), 0); Z3_fixedpoint_add_rule(ctx, dl, Z3_mk_implies(ctx, Z3_mk_and(ctx, 2, body4), pxy), 0); Z3_lbool r = Z3_fixedpoint_query(ctx, dl, pxy); if (r != Z3_L_UNDEF) { std::cout << Z3_ast_to_string(ctx, Z3_fixedpoint_get_answer(ctx, dl)) << "\n"; } Z3_del_context(ctx); }