diff --git a/src/api/dotnet/Deprecated.cs b/src/api/dotnet/Deprecated.cs
index 7dc524834..aa6dffb45 100644
--- a/src/api/dotnet/Deprecated.cs
+++ b/src/api/dotnet/Deprecated.cs
@@ -65,22 +65,29 @@ namespace Microsoft.Z3
///
/// Checks whether the assertions in the context are consistent or not.
///
- public static Status Check(Context ctx, List core, params Expr[] assumptions)
+ public static Status Check(Context ctx, List core, ref Model model, ref Expr proof, params Expr[] assumptions)
{
Z3_lbool r;
- core = null;
+ model = null;
+ proof = null;
if (assumptions == null || assumptions.Length == 0)
r = (Z3_lbool)Native.Z3_check(ctx.nCtx);
else {
- IntPtr model = IntPtr.Zero, proof = IntPtr.Zero;
+ IntPtr mdl = IntPtr.Zero, prf = IntPtr.Zero;
uint core_size = 0;
IntPtr[] native_core = new IntPtr[assumptions.Length];
r = (Z3_lbool)Native.Z3_check_assumptions(ctx.nCtx,
(uint)assumptions.Length, AST.ArrayToNative(assumptions),
- ref model, ref proof, ref core_size, native_core);
+ ref mdl, ref prf, ref core_size, native_core);
for (uint i = 0; i < core_size; i++)
core.Add((BoolExpr)Expr.Create(ctx, native_core[i]));
+ if (mdl != IntPtr.Zero) {
+ model = new Model(ctx, mdl);
+ }
+ if (prf != IntPtr.Zero) {
+ proof = Expr.Create(ctx, prf);
+ }
}
switch (r)
diff --git a/src/muz/rel/udoc_relation.cpp b/src/muz/rel/udoc_relation.cpp
index 3e01a8ba6..07ca511a6 100644
--- a/src/muz/rel/udoc_relation.cpp
+++ b/src/muz/rel/udoc_relation.cpp
@@ -904,12 +904,17 @@ namespace datalog {
else if (m.is_not(g, e1)) {
udoc sub;
sub.push_back(dm.allocateX());
- apply_guard(e1, sub, equalities, discard_cols);
- TRACE("doc",
- result.display(dm, tout << "result0:") << "\n";
- sub.display(dm, tout << "sub:") << "\n";);
+ // TODO: right now we state that no columns are discarded to avoid
+ // silent column merging. This can be optimized if the set of merged
+ // columns is returned so that here we remove different columns.
+ bit_vector empty;
+ empty.resize(discard_cols.size(), false);
+ apply_guard(e1, sub, equalities, empty);
result.subtract(dm, sub);
result.simplify(dm);
+ TRACE("doc",
+ result.display(dm, tout << "result0:") << "\n";
+ sub.display(dm, tout << "sub:") << "\n";);
sub.reset(dm);
TRACE("doc", result.display(dm, tout << "result:") << "\n";);
}
@@ -1022,7 +1027,7 @@ namespace datalog {
return check_kind(t)?alloc(filter_interpreted_fn, get(t), get_ast_manager(), condition):0;
}
- class udoc_plugin::join_project_fn : convenient_relation_join_project_fn {
+ class udoc_plugin::join_project_fn : public convenient_relation_join_project_fn {
udoc_plugin::join_fn m_joiner;
union_find_default_ctx union_ctx;
bit_vector m_to_delete;
@@ -1114,18 +1119,21 @@ namespace datalog {
utbv& neg = d->neg();
unsigned mid = dm1.num_tbits();
unsigned hi = dm.num_tbits();
- tbm.set(pos,d1.pos(), mid-1, 0);
- tbm.set(pos,d2.pos(), hi-1, mid);
+ tbm.set(pos, d1.pos(), mid-1, 0);
+ tbm.set(pos, d2.pos(), hi-1, mid);
for (unsigned i = 0; i < d1.neg().size(); ++i) {
t = tbm.allocateX();
tbm.set(*t, d1.neg()[i], mid-1, 0);
+ VERIFY(tbm.set_and(*t, pos));
neg.push_back(t.detach());
}
for (unsigned i = 0; i < d2.neg().size(); ++i) {
t = tbm.allocateX();
tbm.set(*t, d2.neg()[i], hi-1, mid);
+ VERIFY(tbm.set_and(*t, pos));
neg.push_back(t.detach());
}
+ SASSERT(dm.well_formed(*d));
return d.detach();
}
@@ -1135,15 +1143,11 @@ namespace datalog {
relation_base const& t1, relation_base const& t2,
unsigned joined_col_cnt, const unsigned * cols1, const unsigned * cols2,
unsigned removed_col_cnt, const unsigned * removed_cols) {
- if (check_kind(t1) && check_kind(t2))
- return 0;
-#if 0
- return alloc(join_project_fn, get(t1), ge(t2),
- joined_col_cnt, cols1, cols2,
- removed_col_cnt, removed_cols);
-#endif
- else
+ if (!check_kind(t1) || !check_kind(t2))
return 0;
+ return alloc(join_project_fn, get(t1), get(t2),
+ joined_col_cnt, cols1, cols2,
+ removed_col_cnt, removed_cols);
}
diff --git a/src/test/udoc_relation.cpp b/src/test/udoc_relation.cpp
index 24ccb34b0..d7f83f0aa 100644
--- a/src/test/udoc_relation.cpp
+++ b/src/test/udoc_relation.cpp
@@ -376,15 +376,31 @@ public:
unsigned_vector remove;
remove.push_back(0);
remove.push_back(2);
+
t1 = mk_full(sig2);
+ apply_filter(*t1, conds[2].get());
+ apply_filter_project(*t1, remove, conds[2].get());
+ apply_filter_project(*t1, remove, conds[3].get());
+ t1->deallocate();
+
+ t1 = mk_full(sig2);
+ apply_filter(*t1, conds[3].get());
+ apply_filter_project(*t1, remove, conds[2].get());
+ apply_filter_project(*t1, remove, conds[3].get());
+ t1->deallocate();
+
for (unsigned i = 0; i < conds.size(); ++i) {
+ t1 = mk_full(sig2);
apply_filter_project(*t1, remove, conds[i].get());
+ t1->deallocate();
}
+
remove[1] = 1;
for (unsigned i = 0; i < conds.size(); ++i) {
+ t1 = mk_full(sig2);
apply_filter_project(*t1, remove, conds[i].get());
+ t1->deallocate();
}
- t1->deallocate();
}
@@ -476,52 +492,13 @@ public:
scoped_ptr rename;
rename = p.mk_rename_fn(*t1, cycle.size(), cycle.c_ptr());
relation_base* t = (*rename)(*t1);
- verify_permutation(*t1,*t, cycle);
+ cr.verify_permutation(*t1,*t, cycle);
t1->display(std::cout); std::cout << "\n";
t->display(std::cout); std::cout << "\n";
t->deallocate();
t1->deallocate();
}
- void verify_permutation(relation_base const& src, relation_base const& dst,
- unsigned_vector const& cycle) {
- unsigned_vector perm;
- relation_signature const& sig1 = src.get_signature();
- relation_signature const& sig2 = dst.get_signature();
- for (unsigned i = 0; i < sig1.size(); ++i) {
- perm.push_back(i);
- }
- for (unsigned i = 0; i < cycle.size(); ++i) {
- unsigned j = (i + 1)%cycle.size();
- unsigned col1 = cycle[i];
- unsigned col2 = cycle[j];
- perm[col2] = col1;
- }
- for (unsigned i = 0; i < perm.size(); ++i) {
- SASSERT(sig2[perm[i]] == sig1[i]);
- }
- expr_ref_vector sub(m);
- for (unsigned i = 0; i < perm.size(); ++i) {
- sub.push_back(m.mk_var(perm[i], sig1[i]));
- }
- var_subst subst(m, false);
- expr_ref fml1(m), fml2(m);
- src.to_formula(fml1);
- dst.to_formula(fml2);
- subst(fml1, sub.size(), sub.c_ptr(), fml1);
- expr_ref_vector vars(m);
- for (unsigned i = 0; i < sig2.size(); ++i) {
- std::stringstream strm;
- strm << "x" << i;
- vars.push_back(m.mk_const(symbol(strm.str().c_str()), sig2[i]));
- }
-
- subst(fml1, vars.size(), vars.c_ptr(), fml1);
- subst(fml2, vars.size(), vars.c_ptr(), fml2);
-
- check_equiv(fml1, fml2);
- }
-
/*
The filter_by_negation postcondition:
filter_by_negation(tgt, neg, columns in tgt: c1,...,cN,
@@ -733,51 +710,9 @@ public:
void apply_filter_project(udoc_relation& t, unsigned_vector const& rm, app* cond) {
scoped_ptr rt;
rt = p.mk_filter_interpreted_and_project_fn(t, cond, rm.size(), rm.c_ptr());
- udoc_relation* full = mk_full(t.get_signature());
- rel_union union_fn = p.mk_union_fn(t, *full, 0);
- (*union_fn)(t, *full, 0);
datalog::relation_base* result = (*rt)(t);
-
- for (unsigned i = 0; i < rm.size(); ++i) {
- std::cout << rm[i] << " ";
- }
- std::cout << mk_pp(cond, m) << "\n";
- t.display(std::cout);
- result->display(std::cout);
+ cr.verify_filter_project(t, *result, cond, rm);
result->deallocate();
- full->deallocate();
- }
-
- void verify_filter_project(udoc_relation const& r, unsigned_vector const& rm, app* cond) {
- expr_ref fml(m), cfml(m);
- r.to_formula(fml);
- cfml = cond;
- relation_signature const& sig = r.get_signature();
- expr_ref_vector vars(m);
- for (unsigned i = 0, j = 0, k = 0; i < sig.size(); ++i) {
- if (j < rm.size() && rm[j] == i) {
- project_var(i, sig[i], cfml);
- ++j;
- }
- else {
- vars.push_back(m.mk_var(k, sig[i]));
- ++k;
- }
- }
-
- check_equiv(fml, cfml);
- }
-
- void check_equiv(expr* fml1, expr* fml2) {
- TRACE("doc", tout << mk_pp(fml1, m) << "\n";
- tout << mk_pp(fml2, m) << "\n";);
- smt_params fp;
- smt::kernel solver(m, fp);
- expr_ref tmp(m);
- tmp = m.mk_not(m.mk_eq(fml1, fml2));
- solver.assert_expr(tmp);
- lbool res = solver.check();
- SASSERT(res == l_false);
}
void project_var(unsigned i, sort* s, expr_ref& fml) {