mirror of
https://github.com/Z3Prover/z3
synced 2025-06-06 14:13:23 +00:00
testing doc
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
2552c1530b
commit
a50cbef877
10 changed files with 291 additions and 95 deletions
|
@ -154,6 +154,10 @@ namespace datalog {
|
||||||
display_body_impl(ctx, out, indentation);
|
display_body_impl(ctx, out, indentation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void instruction::log_verbose(execution_context& ctx) {
|
||||||
|
IF_VERBOSE(2, display(ctx.get_rel_context(), verbose_stream()););
|
||||||
|
}
|
||||||
|
|
||||||
class instr_io : public instruction {
|
class instr_io : public instruction {
|
||||||
bool m_store;
|
bool m_store;
|
||||||
func_decl_ref m_pred;
|
func_decl_ref m_pred;
|
||||||
|
@ -162,6 +166,7 @@ namespace datalog {
|
||||||
instr_io(bool store, func_decl_ref pred, reg_idx reg)
|
instr_io(bool store, func_decl_ref pred, reg_idx reg)
|
||||||
: m_store(store), m_pred(pred), m_reg(reg) {}
|
: m_store(store), m_pred(pred), m_reg(reg) {}
|
||||||
virtual bool perform(execution_context & ctx) {
|
virtual bool perform(execution_context & ctx) {
|
||||||
|
log_verbose(ctx);
|
||||||
if (m_store) {
|
if (m_store) {
|
||||||
if (ctx.reg(m_reg)) {
|
if (ctx.reg(m_reg)) {
|
||||||
ctx.get_rel_context().store_relation(m_pred, ctx.release_reg(m_reg));
|
ctx.get_rel_context().store_relation(m_pred, ctx.release_reg(m_reg));
|
||||||
|
@ -237,6 +242,7 @@ namespace datalog {
|
||||||
instr_clone_move(bool clone, reg_idx src, reg_idx tgt)
|
instr_clone_move(bool clone, reg_idx src, reg_idx tgt)
|
||||||
: m_clone(clone), m_src(src), m_tgt(tgt) {}
|
: m_clone(clone), m_src(src), m_tgt(tgt) {}
|
||||||
virtual bool perform(execution_context & ctx) {
|
virtual bool perform(execution_context & ctx) {
|
||||||
|
log_verbose(ctx);
|
||||||
ctx.make_empty(m_tgt);
|
ctx.make_empty(m_tgt);
|
||||||
if (m_clone) {
|
if (m_clone) {
|
||||||
ctx.set_reg(m_tgt, ctx.reg(m_src) ? ctx.reg(m_src)->clone() : 0);
|
ctx.set_reg(m_tgt, ctx.reg(m_src) ? ctx.reg(m_src)->clone() : 0);
|
||||||
|
@ -296,6 +302,7 @@ namespace datalog {
|
||||||
dealloc(m_body);
|
dealloc(m_body);
|
||||||
}
|
}
|
||||||
virtual bool perform(execution_context & ctx) {
|
virtual bool perform(execution_context & ctx) {
|
||||||
|
log_verbose(ctx);
|
||||||
TRACE("dl", tout << "loop entered\n";);
|
TRACE("dl", tout << "loop entered\n";);
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
while (!control_is_empty(ctx)) {
|
while (!control_is_empty(ctx)) {
|
||||||
|
@ -339,6 +346,7 @@ namespace datalog {
|
||||||
: m_rel1(rel1), m_rel2(rel2), m_cols1(col_cnt, cols1),
|
: m_rel1(rel1), m_rel2(rel2), m_cols1(col_cnt, cols1),
|
||||||
m_cols2(col_cnt, cols2), m_res(result) {}
|
m_cols2(col_cnt, cols2), m_res(result) {}
|
||||||
virtual bool perform(execution_context & ctx) {
|
virtual bool perform(execution_context & ctx) {
|
||||||
|
log_verbose(ctx);
|
||||||
ctx.make_empty(m_res);
|
ctx.make_empty(m_res);
|
||||||
if (!ctx.reg(m_rel1) || !ctx.reg(m_rel2)) {
|
if (!ctx.reg(m_rel1) || !ctx.reg(m_rel2)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -400,6 +408,7 @@ namespace datalog {
|
||||||
instr_filter_equal(ast_manager & m, reg_idx reg, const relation_element & value, unsigned col)
|
instr_filter_equal(ast_manager & m, reg_idx reg, const relation_element & value, unsigned col)
|
||||||
: m_reg(reg), m_value(value, m), m_col(col) {}
|
: m_reg(reg), m_value(value, m), m_col(col) {}
|
||||||
virtual bool perform(execution_context & ctx) {
|
virtual bool perform(execution_context & ctx) {
|
||||||
|
log_verbose(ctx);
|
||||||
if (!ctx.reg(m_reg)) {
|
if (!ctx.reg(m_reg)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -447,6 +456,7 @@ namespace datalog {
|
||||||
instr_filter_identical(reg_idx reg, unsigned col_cnt, const unsigned * identical_cols)
|
instr_filter_identical(reg_idx reg, unsigned col_cnt, const unsigned * identical_cols)
|
||||||
: m_reg(reg), m_cols(col_cnt, identical_cols) {}
|
: m_reg(reg), m_cols(col_cnt, identical_cols) {}
|
||||||
virtual bool perform(execution_context & ctx) {
|
virtual bool perform(execution_context & ctx) {
|
||||||
|
log_verbose(ctx);
|
||||||
if (!ctx.reg(m_reg)) {
|
if (!ctx.reg(m_reg)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -493,6 +503,7 @@ namespace datalog {
|
||||||
if (!ctx.reg(m_reg)) {
|
if (!ctx.reg(m_reg)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
log_verbose(ctx);
|
||||||
|
|
||||||
relation_mutator_fn * fn;
|
relation_mutator_fn * fn;
|
||||||
relation_base & r = *ctx.reg(m_reg);
|
relation_base & r = *ctx.reg(m_reg);
|
||||||
|
@ -543,6 +554,7 @@ namespace datalog {
|
||||||
m_res(result) {}
|
m_res(result) {}
|
||||||
|
|
||||||
virtual bool perform(execution_context & ctx) {
|
virtual bool perform(execution_context & ctx) {
|
||||||
|
log_verbose(ctx);
|
||||||
if (!ctx.reg(m_src)) {
|
if (!ctx.reg(m_src)) {
|
||||||
ctx.make_empty(m_res);
|
ctx.make_empty(m_res);
|
||||||
return true;
|
return true;
|
||||||
|
@ -601,6 +613,7 @@ namespace datalog {
|
||||||
instr_union(reg_idx src, reg_idx tgt, reg_idx delta, bool widen)
|
instr_union(reg_idx src, reg_idx tgt, reg_idx delta, bool widen)
|
||||||
: m_src(src), m_tgt(tgt), m_delta(delta), m_widen(widen) {}
|
: m_src(src), m_tgt(tgt), m_delta(delta), m_widen(widen) {}
|
||||||
virtual bool perform(execution_context & ctx) {
|
virtual bool perform(execution_context & ctx) {
|
||||||
|
log_verbose(ctx);
|
||||||
TRACE("dl", tout << "union " << m_src << " into " << m_tgt
|
TRACE("dl", tout << "union " << m_src << " into " << m_tgt
|
||||||
<< " " << ctx.reg(m_src) << " " << ctx.reg(m_tgt) << "\n";);
|
<< " " << ctx.reg(m_src) << " " << ctx.reg(m_tgt) << "\n";);
|
||||||
if (!ctx.reg(m_src)) {
|
if (!ctx.reg(m_src)) {
|
||||||
|
@ -713,6 +726,7 @@ namespace datalog {
|
||||||
reg_idx tgt) : m_projection(projection), m_src(src),
|
reg_idx tgt) : m_projection(projection), m_src(src),
|
||||||
m_cols(col_cnt, cols), m_tgt(tgt) {}
|
m_cols(col_cnt, cols), m_tgt(tgt) {}
|
||||||
virtual bool perform(execution_context & ctx) {
|
virtual bool perform(execution_context & ctx) {
|
||||||
|
log_verbose(ctx);
|
||||||
ctx.make_empty(m_tgt);
|
ctx.make_empty(m_tgt);
|
||||||
if (!ctx.reg(m_src)) {
|
if (!ctx.reg(m_src)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -778,6 +792,7 @@ namespace datalog {
|
||||||
m_cols2(joined_col_cnt, cols2), m_removed_cols(removed_col_cnt, removed_cols), m_res(result) {
|
m_cols2(joined_col_cnt, cols2), m_removed_cols(removed_col_cnt, removed_cols), m_res(result) {
|
||||||
}
|
}
|
||||||
virtual bool perform(execution_context & ctx) {
|
virtual bool perform(execution_context & ctx) {
|
||||||
|
log_verbose(ctx);
|
||||||
ctx.make_empty(m_res);
|
ctx.make_empty(m_res);
|
||||||
if (!ctx.reg(m_rel1) || !ctx.reg(m_rel2)) {
|
if (!ctx.reg(m_rel1) || !ctx.reg(m_rel2)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -839,6 +854,7 @@ namespace datalog {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool perform(execution_context & ctx) {
|
virtual bool perform(execution_context & ctx) {
|
||||||
|
log_verbose(ctx);
|
||||||
if (!ctx.reg(m_src)) {
|
if (!ctx.reg(m_src)) {
|
||||||
ctx.make_empty(m_result);
|
ctx.make_empty(m_result);
|
||||||
return true;
|
return true;
|
||||||
|
@ -893,6 +909,7 @@ namespace datalog {
|
||||||
const unsigned * cols2)
|
const unsigned * cols2)
|
||||||
: m_tgt(tgt), m_neg_rel(neg_rel), m_cols1(col_cnt, cols1), m_cols2(col_cnt, cols2) {}
|
: m_tgt(tgt), m_neg_rel(neg_rel), m_cols1(col_cnt, cols1), m_cols2(col_cnt, cols2) {}
|
||||||
virtual bool perform(execution_context & ctx) {
|
virtual bool perform(execution_context & ctx) {
|
||||||
|
log_verbose(ctx);
|
||||||
if (!ctx.reg(m_tgt) || !ctx.reg(m_neg_rel)) {
|
if (!ctx.reg(m_tgt) || !ctx.reg(m_neg_rel)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -948,6 +965,7 @@ namespace datalog {
|
||||||
m_fact.push_back(val);
|
m_fact.push_back(val);
|
||||||
}
|
}
|
||||||
virtual bool perform(execution_context & ctx) {
|
virtual bool perform(execution_context & ctx) {
|
||||||
|
log_verbose(ctx);
|
||||||
ctx.make_empty(m_tgt);
|
ctx.make_empty(m_tgt);
|
||||||
relation_base * rel = ctx.get_rel_context().get_rmanager().mk_empty_relation(m_sig, m_pred);
|
relation_base * rel = ctx.get_rel_context().get_rmanager().mk_empty_relation(m_sig, m_pred);
|
||||||
rel->add_fact(m_fact);
|
rel->add_fact(m_fact);
|
||||||
|
@ -980,6 +998,7 @@ namespace datalog {
|
||||||
public:
|
public:
|
||||||
instr_mk_total(const relation_signature & sig, func_decl* p, reg_idx tgt) : m_sig(sig), m_pred(p), m_tgt(tgt) {}
|
instr_mk_total(const relation_signature & sig, func_decl* p, reg_idx tgt) : m_sig(sig), m_pred(p), m_tgt(tgt) {}
|
||||||
virtual bool perform(execution_context & ctx) {
|
virtual bool perform(execution_context & ctx) {
|
||||||
|
log_verbose(ctx);
|
||||||
ctx.make_empty(m_tgt);
|
ctx.make_empty(m_tgt);
|
||||||
ctx.set_reg(m_tgt, ctx.get_rel_context().get_rmanager().mk_full_relation(m_sig, m_pred));
|
ctx.set_reg(m_tgt, ctx.get_rel_context().get_rmanager().mk_full_relation(m_sig, m_pred));
|
||||||
return true;
|
return true;
|
||||||
|
@ -1006,6 +1025,7 @@ namespace datalog {
|
||||||
instr_mark_saturated(ast_manager & m, func_decl * pred)
|
instr_mark_saturated(ast_manager & m, func_decl * pred)
|
||||||
: m_pred(pred, m) {}
|
: m_pred(pred, m) {}
|
||||||
virtual bool perform(execution_context & ctx) {
|
virtual bool perform(execution_context & ctx) {
|
||||||
|
log_verbose(ctx);
|
||||||
ctx.get_rel_context().get_rmanager().mark_saturated(m_pred);
|
ctx.get_rel_context().get_rmanager().mark_saturated(m_pred);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1027,6 +1047,7 @@ namespace datalog {
|
||||||
instr_assert_signature(const relation_signature & s, reg_idx tgt)
|
instr_assert_signature(const relation_signature & s, reg_idx tgt)
|
||||||
: m_sig(s), m_tgt(tgt) {}
|
: m_sig(s), m_tgt(tgt) {}
|
||||||
virtual bool perform(execution_context & ctx) {
|
virtual bool perform(execution_context & ctx) {
|
||||||
|
log_verbose(ctx);
|
||||||
if (ctx.reg(m_tgt)) {
|
if (ctx.reg(m_tgt)) {
|
||||||
SASSERT(ctx.reg(m_tgt)->get_signature()==m_sig);
|
SASSERT(ctx.reg(m_tgt)->get_signature()==m_sig);
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,6 +222,8 @@ namespace datalog {
|
||||||
Each line must be prepended by \c indentation and ended by a newline character.
|
Each line must be prepended by \c indentation and ended by a newline character.
|
||||||
*/
|
*/
|
||||||
virtual void display_body_impl(rel_context const & ctx, std::ostream & out, std::string indentation) const {}
|
virtual void display_body_impl(rel_context const & ctx, std::ostream & out, std::string indentation) const {}
|
||||||
|
void log_verbose(execution_context& ctx);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef execution_context::reg_type reg_type;
|
typedef execution_context::reg_type reg_type;
|
||||||
typedef execution_context::reg_idx reg_idx;
|
typedef execution_context::reg_idx reg_idx;
|
||||||
|
|
|
@ -50,6 +50,7 @@ doc* doc_manager::allocate(doc const& src) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
doc* doc_manager::allocate(tbv* t) {
|
doc* doc_manager::allocate(tbv* t) {
|
||||||
|
SASSERT(t);
|
||||||
void* mm = m_alloc.allocate(sizeof(doc));
|
void* mm = m_alloc.allocate(sizeof(doc));
|
||||||
return new (mm) doc(t);
|
return new (mm) doc(t);
|
||||||
}
|
}
|
||||||
|
@ -85,9 +86,7 @@ void doc_manager::copy(doc& dst, doc const& src) {
|
||||||
for (unsigned i = 0; i < n; ++i) {
|
for (unsigned i = 0; i < n; ++i) {
|
||||||
m.copy(dst.neg()[i], src.neg()[i]);
|
m.copy(dst.neg()[i], src.neg()[i]);
|
||||||
}
|
}
|
||||||
for (unsigned i = n; i < dst.neg().size(); ++i) {
|
dst.neg().reset(m);
|
||||||
dst.neg().erase(m, dst.neg().size()-1);
|
|
||||||
}
|
|
||||||
for (unsigned i = n; i < src.neg().size(); ++i) {
|
for (unsigned i = n; i < src.neg().size(); ++i) {
|
||||||
dst.neg().push_back(m.allocate(src.neg()[i]));
|
dst.neg().push_back(m.allocate(src.neg()[i]));
|
||||||
}
|
}
|
||||||
|
@ -110,12 +109,7 @@ doc& doc_manager::fillX(doc& src) {
|
||||||
bool doc_manager::set_and(doc& dst, doc const& src) {
|
bool doc_manager::set_and(doc& dst, doc const& src) {
|
||||||
// (A \ B) & (C \ D) = (A & C) \ (B u D)
|
// (A \ B) & (C \ D) = (A & C) \ (B u D)
|
||||||
if (!m.set_and(dst.pos(), src.pos())) return false;
|
if (!m.set_and(dst.pos(), src.pos())) return false;
|
||||||
for (unsigned i = 0; i < dst.neg().size(); ++i) {
|
dst.neg().intersect(m, src.pos());
|
||||||
if (!m.set_and(dst.neg()[i], dst.pos())) {
|
|
||||||
dst.neg().erase(m, i);
|
|
||||||
--i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tbv_ref t(m);
|
tbv_ref t(m);
|
||||||
for (unsigned i = 0; i < src.neg().size(); ++i) {
|
for (unsigned i = 0; i < src.neg().size(); ++i) {
|
||||||
t = m.allocate(src.neg()[i]);
|
t = m.allocate(src.neg()[i]);
|
||||||
|
@ -279,6 +273,7 @@ bool doc_manager::intersect(doc const& A, doc const& B, doc& result) {
|
||||||
doc* doc_manager::project(doc_manager& dstm, unsigned n, bool const* to_delete, doc const& src) {
|
doc* doc_manager::project(doc_manager& dstm, unsigned n, bool const* to_delete, doc const& src) {
|
||||||
tbv_manager& dstt = dstm.m;
|
tbv_manager& dstt = dstm.m;
|
||||||
doc* r = dstm.allocate(dstt.project(n, to_delete, src.pos()));
|
doc* r = dstm.allocate(dstt.project(n, to_delete, src.pos()));
|
||||||
|
SASSERT(r);
|
||||||
|
|
||||||
if (src.neg().is_empty()) {
|
if (src.neg().is_empty()) {
|
||||||
return r;
|
return r;
|
||||||
|
@ -405,13 +400,21 @@ void doc_manager::complement(doc const& src, ptr_vector<doc>& result) {
|
||||||
result.push_back(allocate(src.neg()[i]));
|
result.push_back(allocate(src.neg()[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// (A \ {A1}) \ (B \ {B1})
|
||||||
|
// (A & !A1 & & !B) | (A & B1 & !A1)
|
||||||
|
// A \ {A1 u B} u (A & B1) \ {A1}
|
||||||
void doc_manager::subtract(doc const& A, doc const& B, ptr_vector<doc>& result) {
|
void doc_manager::subtract(doc const& A, doc const& B, ptr_vector<doc>& result) {
|
||||||
doc_ref r(*this), r2(*this);
|
doc_ref r(*this), r2(*this);
|
||||||
|
tbv_ref t(m);
|
||||||
r = allocate(A);
|
r = allocate(A);
|
||||||
if (r->neg().insert(m, m.allocate(B.pos()))) {
|
t = m.allocate(B.pos());
|
||||||
|
if (m.set_and(*t, A.pos()) && r->neg().insert(m, t.detach())) {
|
||||||
result.push_back(r.detach());
|
result.push_back(r.detach());
|
||||||
r = allocate(A);
|
r = allocate(A);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
result.push_back(allocate(A));
|
||||||
|
}
|
||||||
for (unsigned i = 0; i < B.neg().size(); ++i) {
|
for (unsigned i = 0; i < B.neg().size(); ++i) {
|
||||||
r2 = allocate(B.neg()[i]);
|
r2 = allocate(B.neg()[i]);
|
||||||
if (set_and(*r, *r2)) {
|
if (set_and(*r, *r2)) {
|
||||||
|
|
|
@ -111,12 +111,16 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void push_back(T* t) {
|
void push_back(T* t) {
|
||||||
|
SASSERT(t);
|
||||||
m_elems.push_back(t);
|
m_elems.push_back(t);
|
||||||
}
|
}
|
||||||
void erase(M& m, unsigned idx) {
|
void erase(M& m, unsigned idx) {
|
||||||
T* t = m_elems[idx];
|
m.deallocate(m_elems[idx]);
|
||||||
m_elems.erase(t);
|
unsigned sz = m_elems.size();
|
||||||
m.deallocate(t);
|
for (unsigned i = idx+1; i < sz; ++i) {
|
||||||
|
m_elems[i-1] = m_elems[i];
|
||||||
|
}
|
||||||
|
m_elems.resize(sz-1);
|
||||||
}
|
}
|
||||||
void reset(M& m) {
|
void reset(M& m) {
|
||||||
for (unsigned i = 0; i < m_elems.size(); ++i) {
|
for (unsigned i = 0; i < m_elems.size(); ++i) {
|
||||||
|
@ -125,21 +129,20 @@ public:
|
||||||
m_elems.reset();
|
m_elems.reset();
|
||||||
}
|
}
|
||||||
bool insert(M& m, T* t) {
|
bool insert(M& m, T* t) {
|
||||||
|
SASSERT(t);
|
||||||
unsigned sz = size(), j = 0;
|
unsigned sz = size(), j = 0;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (unsigned i = 0; i < sz; ++i, ++j) {
|
for (unsigned i = 0; i < sz; ++i, ++j) {
|
||||||
|
if (m.contains(*m_elems[i], *t)) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
if (!found && m.contains(*t, *m_elems[i])) {
|
if (!found && m.contains(*t, *m_elems[i])) {
|
||||||
m.deallocate(m_elems[i]);
|
m.deallocate(m_elems[i]);
|
||||||
--j;
|
--j;
|
||||||
}
|
}
|
||||||
else {
|
else if (i != j) {
|
||||||
if (m.contains(*m_elems[i], *t)) {
|
m_elems[j] = m_elems[i];
|
||||||
found = true;
|
}
|
||||||
}
|
|
||||||
if (i != j) {
|
|
||||||
m_elems[j] = m_elems[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (j != sz) m_elems.resize(j);
|
if (j != sz) m_elems.resize(j);
|
||||||
if (found) {
|
if (found) {
|
||||||
|
@ -150,7 +153,7 @@ public:
|
||||||
}
|
}
|
||||||
return !found;
|
return !found;
|
||||||
}
|
}
|
||||||
void intersect(M& m, T& t) {
|
void intersect(M& m, T const& t) {
|
||||||
unsigned sz = size();
|
unsigned sz = size();
|
||||||
unsigned j = 0;
|
unsigned j = 0;
|
||||||
for (unsigned i = 0; i < sz; ++i, ++j) {
|
for (unsigned i = 0; i < sz; ++i, ++j) {
|
||||||
|
@ -159,7 +162,7 @@ public:
|
||||||
--j;
|
--j;
|
||||||
}
|
}
|
||||||
else if (i != j) {
|
else if (i != j) {
|
||||||
m_elems[i] = m_elems[j];
|
m_elems[j] = m_elems[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (j != sz) m_elems.resize(j);
|
if (j != sz) m_elems.resize(j);
|
||||||
|
@ -233,13 +236,26 @@ public:
|
||||||
std::swap(*this, result);
|
std::swap(*this, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void merge(M& m, unsigned lo, unsigned length, subset_ints const& equalities, bit_vector const& discard_cols) {
|
bool well_formed(M& m) const {
|
||||||
for (unsigned i = 0; i < size(); ++i) {
|
for (unsigned i = 0; i < size(); ++i) {
|
||||||
|
if (!m.well_formed(*m_elems[i])) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void merge(M& m, unsigned lo, unsigned length, subset_ints const& equalities, bit_vector const& discard_cols) {
|
||||||
|
unsigned j = 0;
|
||||||
|
unsigned sz = size();
|
||||||
|
for (unsigned i = 0; i < sz; ++i, ++j) {
|
||||||
if (!m.merge(*m_elems[i], lo, length, equalities, discard_cols)) {
|
if (!m.merge(*m_elems[i], lo, length, equalities, discard_cols)) {
|
||||||
erase(m, i);
|
--j;
|
||||||
--i;
|
m.deallocate(m_elems[i]);
|
||||||
|
}
|
||||||
|
else if (i != j) {
|
||||||
|
m_elems[j] = m_elems[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (j != sz) m_elems.resize(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
void merge(M& m, unsigned lo1, unsigned lo2, unsigned length, bit_vector const& discard_cols) {
|
void merge(M& m, unsigned lo1, unsigned lo2, unsigned length, bit_vector const& discard_cols) {
|
||||||
|
|
|
@ -92,7 +92,8 @@ tbv* tbv_manager::allocate(uint64 val, unsigned hi, unsigned lo) {
|
||||||
}
|
}
|
||||||
tbv* tbv_manager::allocate(tbv const& bv, unsigned const* permutation) {
|
tbv* tbv_manager::allocate(tbv const& bv, unsigned const* permutation) {
|
||||||
tbv* r = allocate();
|
tbv* r = allocate();
|
||||||
for (unsigned i = 0; i < num_tbits(); ++i) {
|
unsigned sz = num_tbits();
|
||||||
|
for (unsigned i = 0; i < sz; ++i) {
|
||||||
r->set(permutation[i], bv[i]);
|
r->set(permutation[i], bv[i]);
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -373,6 +373,7 @@ namespace datalog {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRACE("doc", result->display(tout << "result:\n"););
|
TRACE("doc", result->display(tout << "result:\n"););
|
||||||
|
SASSERT(r.well_formed(result->get_dm()));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -412,6 +413,7 @@ namespace datalog {
|
||||||
ud2.push_back(d2.detach());
|
ud2.push_back(d2.detach());
|
||||||
}
|
}
|
||||||
TRACE("doc", tout << "final size: " << r->get_size_estimate_rows() << '\n';);
|
TRACE("doc", tout << "final size: " << r->get_size_estimate_rows() << '\n';);
|
||||||
|
SASSERT(ud2.well_formed(dm2));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -431,20 +433,60 @@ namespace datalog {
|
||||||
rename_fn(udoc_relation const& t, unsigned cycle_len, const unsigned * cycle)
|
rename_fn(udoc_relation const& t, unsigned cycle_len, const unsigned * cycle)
|
||||||
: convenient_relation_rename_fn(t.get_signature(), cycle_len, cycle) {
|
: convenient_relation_rename_fn(t.get_signature(), cycle_len, cycle) {
|
||||||
udoc_plugin& p = t.get_plugin();
|
udoc_plugin& p = t.get_plugin();
|
||||||
|
ast_manager& m = p.get_ast_manager();
|
||||||
|
relation_signature const& sig1 = t.get_signature();
|
||||||
|
relation_signature const& sig2 = get_result_signature();
|
||||||
|
unsigned_vector permutation0, column_info;
|
||||||
for (unsigned i = 0; i < t.get_num_bits(); ++i) {
|
for (unsigned i = 0; i < t.get_num_bits(); ++i) {
|
||||||
m_permutation.push_back(i);
|
m_permutation.push_back(i);
|
||||||
}
|
}
|
||||||
unsigned len = t.column_num_bits(cycle[0]);
|
for (unsigned i = 0; i < sig1.size(); ++i) {
|
||||||
|
permutation0.push_back(i);
|
||||||
|
}
|
||||||
for (unsigned i = 0; i < cycle_len; ++i) {
|
for (unsigned i = 0; i < cycle_len; ++i) {
|
||||||
unsigned j = (i + 1)%cycle_len;
|
unsigned j = (i + 1)%cycle_len;
|
||||||
unsigned col1 = cycle[i];
|
unsigned col1 = cycle[i];
|
||||||
unsigned col2 = cycle[j];
|
unsigned col2 = cycle[j];
|
||||||
unsigned lo1 = t.column_idx(col1);
|
permutation0[col2] = col1;
|
||||||
unsigned lo2 = t.column_idx(col2);
|
}
|
||||||
|
unsigned column = 0;
|
||||||
|
for (unsigned i = 0; i < sig2.size(); ++i) {
|
||||||
|
column_info.push_back(column);
|
||||||
|
column += p.num_sort_bits(sig2[i]);
|
||||||
|
}
|
||||||
|
column_info.push_back(column);
|
||||||
|
SASSERT(column == t.get_num_bits());
|
||||||
|
|
||||||
|
TRACE("doc",
|
||||||
|
sig1.output(m, tout << "sig1: "); tout << "\n";
|
||||||
|
sig2.output(m, tout << "sig2: "); tout << "\n";
|
||||||
|
tout << "permute: ";
|
||||||
|
for (unsigned i = 0; i < permutation0.size(); ++i) {
|
||||||
|
tout << permutation0[i] << " ";
|
||||||
|
}
|
||||||
|
tout << "\n";
|
||||||
|
tout << "cycle: ";
|
||||||
|
for (unsigned i = 0; i < cycle_len; ++i) {
|
||||||
|
tout << cycle[i] << " ";
|
||||||
|
}
|
||||||
|
tout << "\n";
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// 0 -> 2
|
||||||
|
// [3:2:1] -> [1:2:3]
|
||||||
|
// [3,4,5,1,2,0]
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < sig1.size(); ++i) {
|
||||||
|
unsigned len = t.column_num_bits(i);
|
||||||
|
unsigned lo1 = t.column_idx(i);
|
||||||
|
unsigned col2 = permutation0[i];
|
||||||
|
unsigned lo2 = column_info[col2];
|
||||||
|
SASSERT(lo2 + len <= t.get_num_bits());
|
||||||
|
SASSERT(lo1 + len <= t.get_num_bits());
|
||||||
for (unsigned k = 0; k < len; ++k) {
|
for (unsigned k = 0; k < len; ++k) {
|
||||||
m_permutation[k + lo1] = k + lo2;
|
m_permutation[k + lo1] = k + lo2;
|
||||||
}
|
}
|
||||||
SASSERT(t.column_num_bits(col1) == t.column_num_bits(col2));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,10 +499,12 @@ namespace datalog {
|
||||||
udoc const& src = r.get_udoc();
|
udoc const& src = r.get_udoc();
|
||||||
udoc& dst = result->get_udoc();
|
udoc& dst = result->get_udoc();
|
||||||
doc_manager& dm = r.get_dm();
|
doc_manager& dm = r.get_dm();
|
||||||
|
SASSERT(&result->get_dm() == &dm);
|
||||||
for (unsigned i = 0; i < src.size(); ++i) {
|
for (unsigned i = 0; i < src.size(); ++i) {
|
||||||
dst.push_back(dm.allocate(src[i], m_permutation.c_ptr()));
|
dst.push_back(dm.allocate(src[i], m_permutation.c_ptr()));
|
||||||
}
|
}
|
||||||
TRACE("doc", result->display(tout << "result:\n"););
|
TRACE("doc", result->display(tout << "result:\n"););
|
||||||
|
SASSERT(dst.well_formed(dm));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -488,6 +532,8 @@ namespace datalog {
|
||||||
if (d) d1 = &d->get_udoc();
|
if (d) d1 = &d->get_udoc();
|
||||||
if (d1) d1->reset(dm);
|
if (d1) d1->reset(dm);
|
||||||
r.get_plugin().mk_union(dm, r.get_udoc(), src.get_udoc(), d1);
|
r.get_plugin().mk_union(dm, r.get_udoc(), src.get_udoc(), d1);
|
||||||
|
SASSERT(r.get_udoc().well_formed(dm));
|
||||||
|
SASSERT(!d1 || d1->well_formed(dm));
|
||||||
TRACE("doc", _r.display(tout << "dst':\n"); );
|
TRACE("doc", _r.display(tout << "dst':\n"); );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -547,6 +593,7 @@ namespace datalog {
|
||||||
udoc& d = r.get_udoc();
|
udoc& d = r.get_udoc();
|
||||||
doc_manager& dm = r.get_dm();
|
doc_manager& dm = r.get_dm();
|
||||||
d.merge(dm, m_cols[0], m_size, m_equalities, m_empty_bv);
|
d.merge(dm, m_cols[0], m_size, m_equalities, m_empty_bv);
|
||||||
|
SASSERT(d.well_formed(dm));
|
||||||
TRACE("doc", tout << "final size: " << r.get_size_estimate_rows() << '\n';);
|
TRACE("doc", tout << "final size: " << r.get_size_estimate_rows() << '\n';);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -575,6 +622,7 @@ namespace datalog {
|
||||||
virtual void operator()(relation_base & tb) {
|
virtual void operator()(relation_base & tb) {
|
||||||
udoc_relation & t = get(tb);
|
udoc_relation & t = get(tb);
|
||||||
t.get_udoc().intersect(dm, *m_filter);
|
t.get_udoc().intersect(dm, *m_filter);
|
||||||
|
SASSERT(t.get_udoc().well_formed(t.get_dm()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
relation_mutator_fn * udoc_plugin::mk_filter_equal_fn(
|
relation_mutator_fn * udoc_plugin::mk_filter_equal_fn(
|
||||||
|
@ -826,11 +874,15 @@ namespace datalog {
|
||||||
virtual void operator()(relation_base & tb) {
|
virtual void operator()(relation_base & tb) {
|
||||||
udoc_relation & t = get(tb);
|
udoc_relation & t = get(tb);
|
||||||
udoc& u = t.get_udoc();
|
udoc& u = t.get_udoc();
|
||||||
|
SASSERT(u.well_formed(dm));
|
||||||
u.intersect(dm, m_udoc);
|
u.intersect(dm, m_udoc);
|
||||||
|
SASSERT(u.well_formed(dm));
|
||||||
if (m_condition && !u.is_empty()) {
|
if (m_condition && !u.is_empty()) {
|
||||||
t.apply_guard(m_condition, u, m_equalities, m_empty_bv);
|
t.apply_guard(m_condition, u, m_equalities, m_empty_bv);
|
||||||
|
SASSERT(u.well_formed(dm));
|
||||||
}
|
}
|
||||||
u.simplify(dm);
|
u.simplify(dm);
|
||||||
|
SASSERT(u.well_formed(dm));
|
||||||
TRACE("doc", tout << "final size: " << t.get_size_estimate_rows() << '\n';);
|
TRACE("doc", tout << "final size: " << t.get_size_estimate_rows() << '\n';);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -896,7 +948,12 @@ namespace datalog {
|
||||||
}
|
}
|
||||||
renamed_neg.push_back(newD.detach());
|
renamed_neg.push_back(newD.detach());
|
||||||
}
|
}
|
||||||
dst.subtract(t.get_dm(), renamed_neg);
|
TRACE("doc", dst.display(dm, tout) << "\n";
|
||||||
|
renamed_neg.display(dm, tout) << "\n";
|
||||||
|
);
|
||||||
|
dst.subtract(dm, renamed_neg);
|
||||||
|
TRACE("doc", dst.display(dm, tout) << "\n";);
|
||||||
|
SASSERT(dst.well_formed(dm));
|
||||||
renamed_neg.reset(t.get_dm());
|
renamed_neg.reset(t.get_dm());
|
||||||
}
|
}
|
||||||
void copy_column(
|
void copy_column(
|
||||||
|
@ -971,17 +1028,23 @@ namespace datalog {
|
||||||
udoc const& u1 = t.get_udoc();
|
udoc const& u1 = t.get_udoc();
|
||||||
doc_manager& dm = t.get_dm();
|
doc_manager& dm = t.get_dm();
|
||||||
udoc u2;
|
udoc u2;
|
||||||
|
SASSERT(u1.well_formed(dm));
|
||||||
u2.copy(dm, u1);
|
u2.copy(dm, u1);
|
||||||
|
SASSERT(u2.well_formed(dm));
|
||||||
u2.intersect(dm, m_udoc);
|
u2.intersect(dm, m_udoc);
|
||||||
u2.merge(dm, m_roots, m_equalities, m_col_list);
|
SASSERT(u2.well_formed(dm));
|
||||||
|
u2.merge(dm, m_roots, m_equalities, m_col_list);
|
||||||
|
SASSERT(u2.well_formed(dm));
|
||||||
if (m_condition && !u2.is_empty()) {
|
if (m_condition && !u2.is_empty()) {
|
||||||
t.apply_guard(m_condition, u2, m_equalities, m_col_list);
|
t.apply_guard(m_condition, u2, m_equalities, m_col_list);
|
||||||
|
SASSERT(u2.well_formed(dm));
|
||||||
}
|
}
|
||||||
udoc_relation* r = get(t.get_plugin().mk_empty(get_result_signature()));
|
udoc_relation* r = get(t.get_plugin().mk_empty(get_result_signature()));
|
||||||
doc_manager& dm2 = r->get_dm();
|
doc_manager& dm2 = r->get_dm();
|
||||||
for (unsigned i = 0; i < u2.size(); ++i) {
|
for (unsigned i = 0; i < u2.size(); ++i) {
|
||||||
doc* d = dm.project(dm2, m_to_delete.size(), m_to_delete.c_ptr(), u2[i]);
|
doc* d = dm.project(dm2, m_to_delete.size(), m_to_delete.c_ptr(), u2[i]);
|
||||||
r->get_udoc().insert(dm2, d);
|
r->get_udoc().insert(dm2, d);
|
||||||
|
SASSERT(r->get_udoc().well_formed(dm2));
|
||||||
}
|
}
|
||||||
u2.reset(dm);
|
u2.reset(dm);
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -40,7 +40,22 @@ static void tst1(unsigned num_bits) {
|
||||||
m.deallocate(bN);
|
m.deallocate(bN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tst0() {
|
||||||
|
tbv_manager m(0);
|
||||||
|
|
||||||
|
tbv_ref t1(m), t2(m), t3(m);
|
||||||
|
t1 = m.allocate1();
|
||||||
|
t2 = m.allocate0();
|
||||||
|
t3 = m.allocateX();
|
||||||
|
m.display(std::cout, *t1) << "\n";
|
||||||
|
m.display(std::cout, *t2) << "\n";
|
||||||
|
m.display(std::cout, *t3) << "\n";
|
||||||
|
SASSERT(m.equals(*t1, *t2));
|
||||||
|
SASSERT(m.equals(*t1, *t3));
|
||||||
|
}
|
||||||
|
|
||||||
void tst_tbv() {
|
void tst_tbv() {
|
||||||
|
tst0();
|
||||||
tst1(31);
|
tst1(31);
|
||||||
tst1(11);
|
tst1(11);
|
||||||
tst1(15);
|
tst1(15);
|
||||||
|
|
|
@ -88,8 +88,10 @@ public:
|
||||||
udoc_relation* t1, *t2, *t3;
|
udoc_relation* t1, *t2, *t3;
|
||||||
expr_ref fml(m);
|
expr_ref fml(m);
|
||||||
|
|
||||||
|
test_rename();
|
||||||
test_filter_neg();
|
test_filter_neg();
|
||||||
|
|
||||||
|
|
||||||
// empty
|
// empty
|
||||||
{
|
{
|
||||||
std::cout << "empty\n";
|
std::cout << "empty\n";
|
||||||
|
@ -168,26 +170,6 @@ public:
|
||||||
t1->deallocate();
|
t1->deallocate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// rename
|
|
||||||
{
|
|
||||||
t1 = mk_empty(sig);
|
|
||||||
unsigned_vector cycle;
|
|
||||||
cycle.push_back(0);
|
|
||||||
cycle.push_back(2);
|
|
||||||
datalog::relation_transformer_fn* rename = p.mk_rename_fn(*t1, cycle.size(), cycle.c_ptr());
|
|
||||||
|
|
||||||
t1->add_fact(fact1);
|
|
||||||
t1->add_fact(fact2);
|
|
||||||
t1->add_fact(fact3);
|
|
||||||
t = (*rename)(*t1);
|
|
||||||
t1->display(std::cout); std::cout << "\n";
|
|
||||||
t->display(std::cout); std::cout << "\n";
|
|
||||||
t->deallocate();
|
|
||||||
|
|
||||||
dealloc(rename);
|
|
||||||
t1->deallocate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// union
|
// union
|
||||||
{
|
{
|
||||||
t1 = mk_empty(sig);
|
t1 = mk_empty(sig);
|
||||||
|
@ -342,6 +324,98 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_rename() {
|
||||||
|
udoc_relation* t1;
|
||||||
|
// rename
|
||||||
|
datalog::relation_signature sig;
|
||||||
|
sig.push_back(bv.mk_sort(12));
|
||||||
|
sig.push_back(bv.mk_sort(6));
|
||||||
|
sig.push_back(bv.mk_sort(2));
|
||||||
|
datalog::relation_fact fact1(m);
|
||||||
|
fact1.push_back(bv.mk_numeral(rational(1), 12));
|
||||||
|
fact1.push_back(bv.mk_numeral(rational(6), 6));
|
||||||
|
fact1.push_back(bv.mk_numeral(rational(3), 2));
|
||||||
|
t1 = mk_empty(sig);
|
||||||
|
t1->add_fact(fact1);
|
||||||
|
unsigned_vector cycle;
|
||||||
|
cycle.push_back(0);
|
||||||
|
cycle.push_back(2);
|
||||||
|
check_permutation(t1, cycle);
|
||||||
|
|
||||||
|
sig.reset();
|
||||||
|
sig.push_back(bv.mk_sort(2));
|
||||||
|
sig.push_back(bv.mk_sort(6));
|
||||||
|
sig.push_back(bv.mk_sort(12));
|
||||||
|
fact1.reset();
|
||||||
|
fact1.push_back(bv.mk_numeral(rational(3), 2));
|
||||||
|
fact1.push_back(bv.mk_numeral(rational(6), 6));
|
||||||
|
fact1.push_back(bv.mk_numeral(rational(1), 12));
|
||||||
|
t1 = mk_empty(sig);
|
||||||
|
t1->add_fact(fact1);
|
||||||
|
cycle.reset();
|
||||||
|
cycle.push_back(0);
|
||||||
|
cycle.push_back(2);
|
||||||
|
check_permutation(t1, cycle);
|
||||||
|
|
||||||
|
t1 = mk_empty(sig);
|
||||||
|
t1->add_fact(fact1);
|
||||||
|
cycle.reset();
|
||||||
|
cycle.push_back(0);
|
||||||
|
cycle.push_back(1);
|
||||||
|
cycle.push_back(2);
|
||||||
|
check_permutation(t1, cycle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_permutation(relation_base* t1, unsigned_vector const& cycle) {
|
||||||
|
scoped_ptr<datalog::relation_transformer_fn> rename;
|
||||||
|
rename = p.mk_rename_fn(*t1, cycle.size(), cycle.c_ptr());
|
||||||
|
relation_base* t = (*rename)(*t1);
|
||||||
|
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:
|
The filter_by_negation postcondition:
|
||||||
filter_by_negation(tgt, neg, columns in tgt: c1,...,cN,
|
filter_by_negation(tgt, neg, columns in tgt: c1,...,cN,
|
||||||
|
@ -499,7 +573,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
check_equiv(fml, cfml);
|
check_equiv(fml, cfml);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ fixed_bit_vector_manager::fixed_bit_vector_manager(unsigned num_bits):
|
||||||
|
|
||||||
|
|
||||||
fixed_bit_vector* fixed_bit_vector_manager::allocate() {
|
fixed_bit_vector* fixed_bit_vector_manager::allocate() {
|
||||||
|
if (m_num_bytes == 0) return &m_0;
|
||||||
return static_cast<fixed_bit_vector*>(m_alloc.allocate(m_num_bytes));
|
return static_cast<fixed_bit_vector*>(m_alloc.allocate(m_num_bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +60,7 @@ fixed_bit_vector* fixed_bit_vector_manager::allocate(fixed_bit_vector const& bv)
|
||||||
}
|
}
|
||||||
|
|
||||||
void fixed_bit_vector_manager::deallocate(fixed_bit_vector* bv) {
|
void fixed_bit_vector_manager::deallocate(fixed_bit_vector* bv) {
|
||||||
m_alloc.deallocate(m_num_bytes, bv);
|
if (m_num_bytes > 0) m_alloc.deallocate(m_num_bytes, bv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,46 +25,6 @@ Revision History:
|
||||||
#include"debug.h"
|
#include"debug.h"
|
||||||
#include"small_object_allocator.h"
|
#include"small_object_allocator.h"
|
||||||
|
|
||||||
class fixed_bit_vector;
|
|
||||||
class fixed_bit_vector_manager {
|
|
||||||
friend class fixed_bit_vector;
|
|
||||||
small_object_allocator m_alloc;
|
|
||||||
unsigned m_num_bits;
|
|
||||||
unsigned m_num_bytes;
|
|
||||||
unsigned m_num_words;
|
|
||||||
unsigned m_mask;
|
|
||||||
|
|
||||||
static unsigned num_words(unsigned num_bits) {
|
|
||||||
return (num_bits + 31) / 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
fixed_bit_vector_manager(unsigned num_bits);
|
|
||||||
|
|
||||||
void reset() { m_alloc.reset(); }
|
|
||||||
fixed_bit_vector* allocate();
|
|
||||||
fixed_bit_vector* allocate1();
|
|
||||||
fixed_bit_vector* allocate0();
|
|
||||||
fixed_bit_vector* allocate(fixed_bit_vector const& bv);
|
|
||||||
void deallocate(fixed_bit_vector* bv);
|
|
||||||
|
|
||||||
void copy(fixed_bit_vector& dst, fixed_bit_vector const& src) const;
|
|
||||||
unsigned num_words() const { return m_num_words; }
|
|
||||||
unsigned num_bytes() const { return m_num_bytes; }
|
|
||||||
unsigned num_bits() const { return m_num_bits; }
|
|
||||||
fixed_bit_vector& reset(fixed_bit_vector& bv) const { return fill0(bv); }
|
|
||||||
fixed_bit_vector& fill0(fixed_bit_vector& bv) const;
|
|
||||||
fixed_bit_vector& fill1(fixed_bit_vector& bv) const;
|
|
||||||
fixed_bit_vector& set_and(fixed_bit_vector& dst, fixed_bit_vector const& src) const;
|
|
||||||
fixed_bit_vector& set_or(fixed_bit_vector& dst, fixed_bit_vector const& src) const;
|
|
||||||
fixed_bit_vector& set_neg(fixed_bit_vector& dst) const;
|
|
||||||
unsigned last_word(fixed_bit_vector const& bv) const;
|
|
||||||
bool equals(fixed_bit_vector const& a, fixed_bit_vector const& b) const;
|
|
||||||
unsigned hash(fixed_bit_vector const& src) const;
|
|
||||||
bool contains(fixed_bit_vector const& a, fixed_bit_vector const& b) const;
|
|
||||||
std::ostream& display(std::ostream& out, fixed_bit_vector const& b) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class fixed_bit_vector {
|
class fixed_bit_vector {
|
||||||
friend class fixed_bit_vector_manager;
|
friend class fixed_bit_vector_manager;
|
||||||
friend class tbv_manager;
|
friend class tbv_manager;
|
||||||
|
@ -114,6 +74,47 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class fixed_bit_vector_manager {
|
||||||
|
friend class fixed_bit_vector;
|
||||||
|
small_object_allocator m_alloc;
|
||||||
|
unsigned m_num_bits;
|
||||||
|
unsigned m_num_bytes;
|
||||||
|
unsigned m_num_words;
|
||||||
|
unsigned m_mask;
|
||||||
|
fixed_bit_vector m_0;
|
||||||
|
|
||||||
|
static unsigned num_words(unsigned num_bits) {
|
||||||
|
return (num_bits + 31) / 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
fixed_bit_vector_manager(unsigned num_bits);
|
||||||
|
|
||||||
|
void reset() { m_alloc.reset(); }
|
||||||
|
fixed_bit_vector* allocate();
|
||||||
|
fixed_bit_vector* allocate1();
|
||||||
|
fixed_bit_vector* allocate0();
|
||||||
|
fixed_bit_vector* allocate(fixed_bit_vector const& bv);
|
||||||
|
void deallocate(fixed_bit_vector* bv);
|
||||||
|
|
||||||
|
void copy(fixed_bit_vector& dst, fixed_bit_vector const& src) const;
|
||||||
|
unsigned num_words() const { return m_num_words; }
|
||||||
|
unsigned num_bytes() const { return m_num_bytes; }
|
||||||
|
unsigned num_bits() const { return m_num_bits; }
|
||||||
|
fixed_bit_vector& reset(fixed_bit_vector& bv) const { return fill0(bv); }
|
||||||
|
fixed_bit_vector& fill0(fixed_bit_vector& bv) const;
|
||||||
|
fixed_bit_vector& fill1(fixed_bit_vector& bv) const;
|
||||||
|
fixed_bit_vector& set_and(fixed_bit_vector& dst, fixed_bit_vector const& src) const;
|
||||||
|
fixed_bit_vector& set_or(fixed_bit_vector& dst, fixed_bit_vector const& src) const;
|
||||||
|
fixed_bit_vector& set_neg(fixed_bit_vector& dst) const;
|
||||||
|
unsigned last_word(fixed_bit_vector const& bv) const;
|
||||||
|
bool equals(fixed_bit_vector const& a, fixed_bit_vector const& b) const;
|
||||||
|
unsigned hash(fixed_bit_vector const& src) const;
|
||||||
|
bool contains(fixed_bit_vector const& a, fixed_bit_vector const& b) const;
|
||||||
|
std::ostream& display(std::ostream& out, fixed_bit_vector const& b) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _FIXED_BIT_VECTOR_H_ */
|
#endif /* _FIXED_BIT_VECTOR_H_ */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue