z3-z3-4.13.0.src.muz.rel.dl_table.cpp Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
dl_table.cpp
Abstract:
Author:
Krystof Hoder (t-khoder) 2010-09-01.
Revision History:
--*/
#include "muz/base/dl_context.h"
#include "muz/base/dl_util.h"
#include "muz/rel/dl_table.h"
#include "muz/rel/dl_relation_manager.h"
namespace datalog {
// -----------------------------------
//
// hashtable_table
//
// -----------------------------------
table_base * hashtable_table_plugin::mk_empty(const table_signature & s) {
SASSERT(can_handle_signature(s));
return alloc(hashtable_table, *this, s);
}
class hashtable_table_plugin::join_fn : public convenient_table_join_fn {
unsigned m_joined_col_cnt;
public:
join_fn(const table_signature & t1_sig, const table_signature & t2_sig, unsigned col_cnt, const unsigned * cols1, const unsigned * cols2)
: convenient_table_join_fn(t1_sig, t2_sig, col_cnt, cols1, cols2),
m_joined_col_cnt(col_cnt) {}
table_base * operator()(const table_base & t1, const table_base & t2) override {
const hashtable_table & ht1 = static_cast(t1);
const hashtable_table & ht2 = static_cast(t2);
hashtable_table_plugin & plugin = ht1.get_plugin();
hashtable_table * res = static_cast(plugin.mk_empty(get_result_signature()));
hashtable_table::storage::iterator els1it = ht1.m_data.begin();
hashtable_table::storage::iterator els1end = ht1.m_data.end();
hashtable_table::storage::iterator els2end = ht2.m_data.end();
table_fact acc;
for(; els1it!=els1end; ++els1it) {
const table_fact & row1 = *els1it;
hashtable_table::storage::iterator els2it = ht2.m_data.begin();
for(; els2it!=els2end; ++els2it) {
const table_fact & row2 = *els2it;
bool match=true;
for(unsigned i=0; im_data.insert(acc);
}
}
return res;
}
};
table_join_fn * hashtable_table_plugin::mk_join_fn(const table_base & t1, const table_base & t2,
unsigned col_cnt, const unsigned * cols1, const unsigned * cols2) {
if(t1.get_kind()!=get_kind() || t2.get_kind()!=get_kind()) {
return nullptr;
}
return alloc(join_fn, t1.get_signature(), t2.get_signature(), col_cnt, cols1, cols2);
}
class hashtable_table::our_iterator_core : public iterator_core {
const hashtable_table & m_parent;
storage::iterator m_inner;
storage::iterator m_end;
class our_row : public row_interface {
const our_iterator_core & m_parent;
public:
our_row(const our_iterator_core & parent) : row_interface(parent.m_parent), m_parent(parent) {}
void get_fact(table_fact & result) const override {
result = *m_parent.m_inner;
}
table_element operator[](unsigned col) const override {
return (*m_parent.m_inner)[col];
}
};
our_row m_row_obj;
public:
our_iterator_core(const hashtable_table & t, bool finished) :
m_parent(t), m_inner(finished ? t.m_data.end() : t.m_data.begin()),
m_end(t.m_data.end()), m_row_obj(*this) {}
bool is_finished() const override {
return m_inner==m_end;
}
row_interface & operator*() override {
SASSERT(!is_finished());
return m_row_obj;
}
void operator++() override {
SASSERT(!is_finished());
++m_inner;
}
};
table_base::iterator hashtable_table::begin() const {
return mk_iterator(alloc(our_iterator_core, *this, false));
}
table_base::iterator hashtable_table::end() const {
return mk_iterator(alloc(our_iterator_core, *this, true));
}
// -----------------------------------
//
// bitvector_table
//
// -----------------------------------
bool bitvector_table_plugin::can_handle_signature(const table_signature & sig) {
if(sig.functional_columns()!=0) {
return false;
}
unsigned cols = sig.size();
unsigned shift = 0;
for (unsigned i = 0; i < cols; ++i) {
unsigned s = static_cast(sig[i]);
if (s != sig[i] || !is_power_of_two(s)) {
return false;
}
unsigned num_bits = 0;
unsigned bit_pos = 1;
for (num_bits = 1; num_bits < 32; ++num_bits) {
if (bit_pos & s) {
break;
}
bit_pos <<= 1;
}
shift += num_bits;
if (shift >= 32) {
return false;
}
}
return true;
}
table_base * bitvector_table_plugin::mk_empty(const table_signature & s) {
SASSERT(can_handle_signature(s));
return alloc(bitvector_table, *this, s);
}
class bitvector_table::bv_iterator : public iterator_core {
bitvector_table const& m_bv;
unsigned m_offset;
class our_row : public caching_row_interface {
const bv_iterator& m_parent;
public:
our_row(const bv_iterator & p) : caching_row_interface(p.m_bv), m_parent(p) {}
void get_fact(table_fact& result) const override {
if (result.size() < size()) {
result.resize(size(), 0);
}
m_parent.m_bv.offset2fact(m_parent.m_offset, result);
}
};
our_row m_row_obj;
public:
bv_iterator(const bitvector_table& bv, bool end):
m_bv(bv), m_offset(end?m_bv.m_bv.size():0), m_row_obj(*this)
{
if (!is_finished() && !m_bv.m_bv.get(m_offset)) {
++(*this);
}
}
bool is_finished() const override {
return m_offset == m_bv.m_bv.size();
}
row_interface & operator*() override {
SASSERT(!is_finished());
return m_row_obj;
}
void operator++() override {
SASSERT(!is_finished());
++m_offset;
while (!is_finished() && !m_bv.m_bv.get(m_offset)) {
++m_offset;
}
m_row_obj.reset();
}
};
bitvector_table::bitvector_table(bitvector_table_plugin & plugin, const table_signature & sig)
: table_base(plugin, sig){
SASSERT(plugin.can_handle_signature(sig));
m_num_cols = sig.size();
unsigned shift = 0;
for (unsigned i = 0; i < m_num_cols; ++i) {
unsigned s = static_cast(sig[i]);
if (s != sig[i] || !is_power_of_two(s)) {
throw default_exception("bit-vector table is specialized to small domains that are powers of two");
}
m_shift.push_back(shift);
m_mask.push_back(s - 1);
unsigned num_bits = 0;
unsigned bit_pos = 1;
for (num_bits = 1; num_bits < 32; ++num_bits) {
if (bit_pos & s) {
break;
}
bit_pos <<= 1;
}
shift += num_bits;
if (shift >= 32) {
throw default_exception("bit-vector table is specialized to small domains that are powers of two");
}
}
m_bv.reserve(1 << shift);
}
unsigned bitvector_table::fact2offset(const table_element* f) const {
unsigned result = 0;
for (unsigned i = 0; i < m_num_cols; ++i) {
SASSERT(f[i] < get_signature()[i]);
result += ((unsigned)f[i]) << m_shift[i];
}
return result;
}
void bitvector_table::offset2fact(unsigned offset, table_fact& f) const {
SASSERT(m_num_cols == f.size());
for (unsigned i = 0; i < m_num_cols; ++i) {
f[i] = m_mask[i] & (offset >> m_shift[i]);
}
}
void bitvector_table::add_fact(const table_fact & f) {
m_bv.set(fact2offset(f.data()));
}
void bitvector_table::remove_fact(const table_element* fact) {
m_bv.unset(fact2offset(fact));
}
bool bitvector_table::contains_fact(const table_fact & f) const {
return m_bv.get(fact2offset(f.data()));
}
table_base::iterator bitvector_table::begin() const {
return mk_iterator(alloc(bv_iterator, *this, false));
}
table_base::iterator bitvector_table::end() const {
return mk_iterator(alloc(bv_iterator, *this, true));
}
};