3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-11 03:33:35 +00:00
z3/test/dl_smt_relation.cpp
Leonardo de Moura 68269c43a6 other components
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
2012-10-02 11:48:48 -07:00

234 lines
8.8 KiB
C++

#include "dl_smt_relation.h"
#include "arith_decl_plugin.h"
#include "dl_context.h"
#include "z3.h"
#include "z3_private.h"
namespace datalog {
void test_smt_relation_unit() {
ast_manager m;
m.register_decl_plugins();
arith_util a(m);
sort* int_sort = a.mk_int();
sort* real_sort = a.mk_real();
front_end_params params;
context ctx(m, params);
relation_manager & rm = ctx.get_rmanager();
relation_signature sig1;
sig1.push_back(int_sort);
sig1.push_back(int_sort);
sig1.push_back(real_sort);
smt_relation_plugin plugin(rm);
scoped_rel<relation_base> r1 = plugin.mk_empty(sig1);
// add_fact
relation_fact fact1(m);
fact1.push_back(a.mk_numeral(rational(1), true));
fact1.push_back(a.mk_numeral(rational(2), true));
fact1.push_back(a.mk_numeral(rational(3), false));
relation_fact fact2(m);
fact2.push_back(a.mk_numeral(rational(2), true));
fact2.push_back(a.mk_numeral(rational(2), true));
fact2.push_back(a.mk_numeral(rational(3), false));
r1->add_fact(fact1);
r1->display(std::cout << "r1: ");
// contains_fact
SASSERT(r1->contains_fact(fact1));
SASSERT(!r1->contains_fact(fact2));
// empty
scoped_rel<relation_base> r2 = plugin.mk_empty(sig1);
SASSERT(!r1->empty());
SASSERT(r2->empty());
// clone
scoped_rel<relation_base> r3 = r1->clone();
// complement?
r2->add_fact(fact2);
scoped_rel<relation_base> r4 = dynamic_cast<smt_relation&>(*r2).complement(0);
r4->display(std::cout << "complement r4: " );
// join
unsigned col_cnt = 2;
unsigned cols1[2] = {1, 2};
unsigned cols2[2] = {0, 2};
scoped_ptr<relation_join_fn> joinfn = plugin.mk_join_fn(*r1, *r4, col_cnt, cols1, cols2);
scoped_rel<relation_base> r5 = (*joinfn)(*r1, *r4);
r5->display(std::cout<< "join r5: ");
relation_fact fact3(m);
fact3.push_back(a.mk_numeral(rational(1), true));
fact3.push_back(a.mk_numeral(rational(2), true));
fact3.push_back(a.mk_numeral(rational(3), false));
fact3.push_back(a.mk_numeral(rational(2), true));
fact3.push_back(a.mk_numeral(rational(2), true));
fact3.push_back(a.mk_numeral(rational(3), false));
SASSERT(!r5->contains_fact(fact3));
fact3[5] = a.mk_numeral(rational(4), false);
SASSERT(!r5->contains_fact(fact3));
fact3[5] = a.mk_numeral(rational(3), false);
fact3[4] = a.mk_numeral(rational(3), true);
SASSERT(r5->contains_fact(fact3));
// project
unsigned removed_cols[2] = { 1, 4 };
scoped_ptr<relation_transformer_fn> projfn = plugin.mk_project_fn(*r5, col_cnt, removed_cols);
scoped_rel<relation_base> r6 = (*projfn)(*r5);
r6->display(std::cout<< "project r6: ");
// rename
unsigned cycle[3] = { 0, 2, 4 };
unsigned cycle_len = 3;
scoped_rel<relation_transformer_fn> renamefn = plugin.mk_rename_fn(*r5, cycle_len, cycle);
scoped_rel<relation_base> r7 = (*renamefn)(*r5);
r7->display(std::cout << "rename r7: ");
// union
// widen
relation_base* delta = 0;
scoped_ptr<relation_union_fn> widenfn = plugin.mk_widen_fn(*r1, *r2, delta);
scoped_ptr<relation_union_fn> unionfn = plugin.mk_union_fn(*r1, *r2, delta);
scoped_rel<relation_base> r8 = r1->clone();
(*unionfn)(*r8,*r2,0);
r8->display(std::cout << "union r8: ");
// filter_identical
unsigned identical_cols[2] = { 1, 3 };
scoped_ptr<relation_mutator_fn> filti = plugin.mk_filter_identical_fn(*r5, col_cnt, identical_cols);
scoped_rel<relation_base> r9 = r1->clone();
(*filti)(*r9);
r9->display(std::cout << "filter identical r9: ");
// filter_equal
app_ref value(m);
value = m.mk_const(symbol("x"), int_sort);
scoped_rel<relation_mutator_fn> eqn = plugin.mk_filter_equal_fn(*r5, value.get(), 3);
scoped_rel<relation_base> r10 = r1->clone();
(*eqn)(*r10);
r10->display(std::cout << "filter equal r10: ");
// filter_interpreted
app_ref cond(m);
cond = a.mk_lt(m.mk_var(3, int_sort), m.mk_var(4, int_sort));
scoped_rel<relation_mutator_fn> filtint = plugin.mk_filter_interpreted_fn(*r5, cond);
scoped_rel<relation_base> r11 = r5->clone();
(*filtint)(*r11);
r11->display(std::cout << "filter interpreted r11: ");
}
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 != l_undef) {
std::cout << Z3_ast_to_string(ctx, Z3_fixedpoint_get_answer(ctx, dl)) << "\n";
}
Z3_del_context(ctx);
}
};
void tst_dl_smt_relation() {
datalog::test_smt_relation_api();
datalog::test_smt_relation_unit();
}