3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-08 18:31:49 +00:00

more fun with docs

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2014-09-16 21:46:39 -07:00
parent 44e8833369
commit e32448d7ea
7 changed files with 244 additions and 103 deletions

View file

@ -2066,13 +2066,6 @@ expr* ast_manager::mk_or_reduced(unsigned n, expr* const* args) {
}
}
expr* ast_manager::mk_and_reduced(unsigned n, expr* const* args) {
switch (n) {
case 0: return mk_true();
case 1: return args[0];
default: return mk_and(n, args);
}
}
func_decl * ast_manager::mk_fresh_func_decl(symbol const & prefix, symbol const & suffix, unsigned arity,
sort * const * domain, sort * range) {

View file

@ -2005,7 +2005,6 @@ public:
app * mk_false() { return m_false; }
app * mk_interp(expr * arg) { return mk_app(m_basic_family_id, OP_INTERP, arg); }
expr * mk_or_reduced(unsigned num_args, expr * const * args);
expr * mk_and_reduced(unsigned num_args, expr * const * args);
func_decl* mk_and_decl() {

View file

@ -73,6 +73,9 @@ void doc_manager::subtract(doc const& A, doc const& B, ptr_vector<doc>& result)
bool doc_manager::equals(doc const& a, doc const& b) const {
return false;
}
bool doc_manager::is_full(doc const& src) const {
return false;
}
unsigned doc_manager::hash(doc const& src) const {
return 0;
}

View file

@ -51,7 +51,9 @@ public:
doc& fill0(doc& src) const;
doc& fill1(doc& src) const;
doc& fillX(doc& src) const;
bool is_full(doc const& src) const;
bool set_and(doc& dst, doc const& src) const;
bool intersect(doc const& A, doc const& B, doc& result) const;
void complement(doc const& src, ptr_vector<doc>& result);
void subtract(doc const& A, doc const& B, ptr_vector<doc>& result);
bool equals(doc const& a, doc const& b) const;
@ -61,6 +63,8 @@ public:
unsigned num_tbits() const { return m.num_tbits(); }
};
typedef union_find<> subset_ints;
// union of tbv*, union of doc*
template<typename M, typename T>
class union_bvec {
@ -72,12 +76,12 @@ class union_bvec {
e_fixed
};
typedef union_find<> subset_ints;
public:
unsigned size() const { return m_elems.size(); }
T& operator[](unsigned idx) const { return *m_elems[idx]; }
bool empty() const { return m_elems.empty(); }
bool is_full(M& m) const { return size() == 1 && m.is_full(*m_elems[0]); }
bool contains(M& m, T& t) const {
for (unsigned i = 0; i < m_elems.size(); ++i) {
if (m.contains(*m_elems[i], t)) return true;
@ -143,7 +147,7 @@ public:
T* inter = m.allocate();
for (unsigned i = 0; i < sz1; ++i) {
for (unsigned j = 0; j < sz2; ++j) {
if (m.intesect(*m_elems[i], other[j], *inter)) {
if (m.intersect(*m_elems[i], other[j], *inter)) {
result.push_back(inter);
inter = m.allocate();
}
@ -151,7 +155,7 @@ public:
}
m.deallocate(inter);
std::swap(result, *this);
result.reset();
result.reset(m);
}
void complement(M& m, union_bvec& result) {
union_bvec negated;

View file

@ -118,8 +118,10 @@ public:
tbv_ref& operator=(tbv* d2) {
if (d) mgr.deallocate(d);
d = d2;
return *this;
}
tbv& operator*() { return *d; }
tbv* get() { return d; }
};

View file

@ -1,5 +1,7 @@
#include "udoc_relation.h"
#include "dl_relation_manager.h"
#include "qe_util.h"
#include "ast_util.h"
namespace datalog {
@ -387,110 +389,171 @@ namespace datalog {
return 0;
return alloc(filter_equal_fn, *this, get(t), value, col);
}
bool udoc_relation::is_guard(unsigned n, expr* const* gs) const {
for (unsigned i = 0; i < n; ++i) {
if (!is_guard(gs[i])) return false;
}
return true;
}
bool udoc_relation::is_guard(expr* g) const {
ast_manager& m = get_plugin().get_ast_manager();
expr* e1, *e2;
if (m.is_and(g) || m.is_or(g) || m.is_not(g) || m.is_true(g) || m.is_false(g)) {
return is_guard(to_app(g)->get_num_args(), to_app(g)->get_args());
}
if (m.is_eq(g, e1, e2)) {
if (is_var(e1) && is_var(e2)) return false;
NOT_IMPLEMENTED_YET();
// TBD
}
if (is_var(g)) {
return true;
}
return false;
}
void udoc_relation::extract_guard(expr* cond, expr_ref& guard, expr_ref& rest) const {
rest.reset();
ast_manager& m = get_plugin().get_ast_manager();
expr_ref_vector conds(m), guards(m), rests(m);
conds.push_back(cond);
qe::flatten_and(conds);
for (unsigned i = 0; i < conds.size(); ++i) {
expr* g = conds[i].get();
if (is_guard(g)) {
guards.push_back(g);
}
else {
rests.push_back(g);
}
}
guard = mk_and(m, guards.size(), guards.c_ptr());
rest = mk_and(m, rests.size(), rests.c_ptr());
}
void udoc_relation::compile_guard(expr* g, udoc& d) const {
NOT_IMPLEMENTED_YET();
}
void udoc_relation::apply_guard(expr* g, udoc& result, bit_vector const& discard_cols) {
// datastructure to store equalities with columns that will be projected out
union_find_default_ctx union_ctx;
subset_ints equalities(union_ctx);
for (unsigned i = 0, e = discard_cols.size(); i < e; ++i) {
equalities.mk_var();
}
apply_guard(g, result, equalities, discard_cols);
}
void udoc_relation::apply_guard(
expr* g, udoc& result, subset_ints& equalities,
bit_vector const& discard_cols) {
ast_manager& m = get_plugin().get_ast_manager();
expr* e1, *e2;
if (result.empty()) {
}
else if (m.is_and(g)) {
for (unsigned i = 0; !result.empty() && i < to_app(g)->get_num_args(); ++i) {
apply_guard(to_app(g)->get_arg(i), result, equalities, discard_cols);
}
}
else if (m.is_not(g, e1)) {
udoc sub;
sub.push_back(dm.allocateX());
apply_guard(e1, sub, equalities, discard_cols);
// TBD: result.subtract(dm, sub);
}
else if (m.is_or(g)) {
udoc sub;
sub.push_back(dm.allocateX());
for (unsigned i = 0; !sub.empty() && i < to_app(g)->get_num_args(); ++i) {
expr_ref arg(m);
arg = to_app(g)->get_arg(i);
if (m.is_not(arg, e1)) {
arg = e1;
}
else {
arg = m.mk_not(arg);
}
apply_guard(arg, result, equalities, discard_cols);
}
// TBD: result.subtract(dm, sub);
}
else if (m.is_true(g)) {
}
else if (m.is_false(g)) {
result.reset(dm);
}
else if (is_var(g)) {
SASSERT(m.is_bool(g));
unsigned v = to_var(g)->get_idx();
unsigned idx = column_idx(v);
doc_manager& dm1 = get_plugin().dm(1);
tbv_ref bit1(dm1.tbv());
bit1 = dm1.tbv().allocate1();
result.fix_eq_bits(idx, bit1.get(), 0, 1, equalities, discard_cols);
}
else if (m.is_eq(g, e1, e2)) {
#if 0
static bool cond_is_guard(const expr *e, const table_information& t) {
switch (e->get_kind()) {
case AST_APP: {
const app *app = to_app(e);
switch (app->get_decl_kind()) {
case OP_AND:
case OP_OR:
case OP_NOT:
for (unsigned i = 0; i < app->get_num_args(); ++i) {
if (!cond_is_guard(app->get_arg(i), t))
return false;
}
return true;
case OP_EQ: {
const expr *a = app->get_arg(0), *b = app->get_arg(1);
// column equality is not succinctly representable with TBVs
if (is_var(a) && is_var(b))
return false;
// (= var (concat var foo))
if (t.get_bv_util().is_concat(b))
return false;
return true;}
case OP_FALSE:
case OP_TRUE:
return true;
default:
return false;
}
break;}
case AST_VAR:
return true;
default:
break;
}
return false;
}
static void split_cond_guard(app *cond, expr_ref& guard, expr_ref& leftover, const table_information& t) {
expr_ref_vector guards(guard.m());
expr_ref_vector leftovers(leftover.m());
if (is_app(cond) && to_app(cond)->get_decl_kind() == OP_AND) {
app *a = to_app(cond);
for (unsigned i = 0; i < a->get_num_args(); ++i) {
expr *arg = a->get_arg(i);
if (cond_is_guard(arg, t)) {
guards.push_back(arg);
} else {
leftovers.push_back(arg);
}
}
} else if (cond_is_guard(cond, t)) {
guard = cond;
return;
const var *v;
unsigned vidx = 0;
unsigned length;
unsigned low, high;
expr *e2;
if (is_var(e1)) {
v = to_var(e1);
length = column_num_bits(v->get_idx());
} else if (bv.is_extract(e1, low, high, e11)) {
vidx = bv.get_bv_size(e11) - high - 1;
length = high - low + 1;
SASSERT(is_var(e11));
v = to_var(e11);
} else {
leftover = cond;
return;
NOT_IMPLEMENTED_YET();
}
if (guards.size() > 1) {
guard = guard.m().mk_and(guards.size(), guards.c_ptr());
} else if (guards.size() == 1) {
guard = guards.get(0);
}
if (leftovers.size() > 1) {
leftover = leftover.m().mk_and(leftovers.size(), leftovers.c_ptr());
} else if (leftovers.size() == 1) {
leftover = leftovers.get(0);
}
}
vidx += t.column_idx(v->get_idx());
unsigned final_idx = fix_eq_bits(vidx, e2, 0, length, t, equalities, discard_cols);
SASSERT(final_idx == vidx + length);
(void)final_idx;
#endif
}
else {
// std::ostringstream strm;
// strm << "Guard expression is not handled" << mk_pp(g, m);
// throw default_exception(strm.str());
throw 0;
}
}
class udoc_plugin::filter_interpreted_fn : public relation_mutator_fn {
expr_ref m_condition;
//typename T::bitset_t m_filter;
//bit_vector m_empty_bv;
doc_manager& dm;
expr_ref m_condition;
udoc m_udoc;
bit_vector m_empty_bv;
public:
filter_interpreted_fn(const udoc_relation & t, ast_manager& m, app *condition) :
dm(t.get_dm()),
m_condition(m) {
NOT_IMPLEMENTED_YET();
//m_filter(t.get_num_bits(), true);
//m_empty_bv.resize(t.get_num_bits(), false);
//expr_ref guard(m);
//split_cond_guard(condition, guard, m_condition, t);
//if (guard)
// m_filter.filter(guard, m_empty_bv, t);
m_empty_bv.resize(t.get_num_bits(), false);
expr_ref guard(m), rest(m);
t.extract_guard(condition, guard, m_condition);
t.compile_guard(guard, m_udoc);
if (m.is_true(m_condition)) {
m_condition = 0;
}
}
virtual ~filter_interpreted_fn() {
m_udoc.reset(dm);
}
virtual void operator()(relation_base & tb) {
udoc_relation & t = get(tb);
// first apply guard and then run the interpreter on the leftover
//t.m_bitsets = m_filter.band(t.m_bitsets);
//if (m_condition)
// t.m_bitsets.filter(m_condition, m_empty_bv, t);
udoc& u = t.get_udoc();
u.intersect(dm, m_udoc);
if (m_condition && !u.empty()) {
t.apply_guard(m_condition, u, m_empty_bv);
}
TRACE("dl", tout << "final size: " << t.get_size_estimate_rows() << '\n';);
}
};
@ -531,5 +594,76 @@ namespace datalog {
return alloc(negation_filter_fn, get(t), get(neg), joined_col_cnt, t_cols, negated_cols);
}
#if 0
/// make bits of table [idx,idx+max_length] equal to e sliced starting at idx2
unsigned fix_eq_bits(unsigned idx, expr *e, unsigned idx2, unsigned max_length,
const table_information& t, subset_ints& equalities,
const bit_vector & discard_cols) {
const bv_util& bvu = t.get_bv_util();
const dl_decl_util& dutil = t.get_decl_util();
rational n;
unsigned bv_size;
if (bvu.is_numeral(e, n, bv_size)) {
SASSERT(idx2 < bv_size);
max_length = std::min(max_length, bv_size - idx2);
T num(n, max_length);
fix_eq_bits(idx, &num, idx2, max_length, equalities, discard_cols);
return idx + max_length;
}
uint64 num;
if (dutil.is_numeral(e, num)) {
T num_bv(rational(num,rational::ui64()), max_length);
fix_eq_bits(idx, &num_bv, idx2, max_length, equalities, discard_cols);
return idx + max_length;
}
if (bvu.is_concat(e)) {
const app *a = to_app(e);
// skip the first elements of the concat if e.g. we have a top level extract
unsigned i = 0;
for (; i < a->get_num_args(); ++i) {
unsigned arg_size = bvu.get_bv_size(a->get_arg(i));
if (idx2 < arg_size)
break;
idx2 -= arg_size;
}
SASSERT(i < a->get_num_args());
for (; max_length > 0 && i < a->get_num_args(); ++i) {
unsigned idx0 = idx;
idx = fix_eq_bits(idx, a->get_arg(i), idx2, max_length, t, equalities, discard_cols);
idx2 = 0;
SASSERT((idx - idx0) <= max_length);
max_length = max_length - (idx - idx0);
}
return idx;
}
unsigned low, high;
expr *e2;
if (bvu.is_extract(e, low, high, e2)) {
SASSERT(low <= high);
unsigned size = bvu.get_bv_size(e2);
unsigned offset = size - (high+1) + idx2;
SASSERT(idx2 < (high-low+1));
max_length = std::min(max_length, high - low + 1 - idx2);
return fix_eq_bits(idx, e2, offset, max_length, t, equalities, discard_cols);
}
if (e->get_kind() == AST_VAR) {
unsigned idx_var = idx2 + t.column_idx(to_var(e)->get_idx());
SASSERT(idx2 < t.column_num_bits(to_var(e)->get_idx()));
max_length = std::min(max_length, t.column_num_bits(to_var(e)->get_idx()) - idx2);
fix_eq_bits(idx, 0, idx_var, max_length, equalities, discard_cols);
return idx + max_length;
}
NOT_IMPLEMENTED_YET();
return 0;
}
#endif
}

View file

@ -60,6 +60,12 @@ namespace datalog {
unsigned column_idx(unsigned col) const { return m_column_info[col]; }
unsigned column_num_bits(unsigned col) const { return m_column_info[col+1] - m_column_info[col]; }
void expand_column_vector(unsigned_vector& v, udoc_relation* other = 0) const;
void extract_guard(expr* condition, expr_ref& guard, expr_ref& rest) const;
bool is_guard(expr* g) const;
bool is_guard(unsigned n, expr* const *g) const;
void compile_guard(expr* g, udoc& d) const;
void apply_guard(expr* g, udoc& result, bit_vector const& discard_cols);
void apply_guard(expr* g, udoc& result, subset_ints& equalities, bit_vector const& discard_cols);
};
class udoc_plugin : public relation_plugin {