mirror of
https://github.com/Z3Prover/z3
synced 2025-04-08 02:15:19 +00:00
266 lines
8.3 KiB
C++
266 lines
8.3 KiB
C++
/*++
|
|
Copyright (c) 2006 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dl_table.h
|
|
|
|
Abstract:
|
|
|
|
<abstract>
|
|
|
|
Author:
|
|
|
|
Krystof Hoder (t-khoder) 2010-09-01.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
#ifndef _DL_TABLE_H_
|
|
#define _DL_TABLE_H_
|
|
|
|
#include<iostream>
|
|
#include<list>
|
|
#include<utility>
|
|
|
|
#include "ast.h"
|
|
#include "bit_vector.h"
|
|
#include "buffer.h"
|
|
#include "hashtable.h"
|
|
#include "map.h"
|
|
#include "ref_vector.h"
|
|
#include "vector.h"
|
|
#include "union_find.h"
|
|
#include "dl_base.h"
|
|
#include "dl_util.h"
|
|
#include "bit_vector.h"
|
|
|
|
|
|
namespace datalog {
|
|
|
|
class context;
|
|
class variable_intersection;
|
|
|
|
|
|
|
|
// -----------------------------------
|
|
//
|
|
// hashtable_table
|
|
//
|
|
// -----------------------------------
|
|
|
|
class hashtable_table;
|
|
|
|
class hashtable_table_plugin : public table_plugin {
|
|
friend class hashtable_table;
|
|
protected:
|
|
class join_fn;
|
|
public:
|
|
typedef hashtable_table table;
|
|
|
|
hashtable_table_plugin(relation_manager & manager)
|
|
: table_plugin(symbol("hashtable"), manager) {}
|
|
|
|
virtual table_base * mk_empty(const table_signature & s);
|
|
|
|
virtual table_join_fn * mk_join_fn(const table_base & t1, const table_base & t2,
|
|
unsigned col_cnt, const unsigned * cols1, const unsigned * cols2);
|
|
};
|
|
|
|
class hashtable_table : public table_base {
|
|
friend class hashtable_table_plugin;
|
|
friend class hashtable_table_plugin::join_fn;
|
|
|
|
class our_iterator_core;
|
|
|
|
typedef hashtable<table_fact, int_vector_hash_proc<table_fact>,
|
|
vector_eq_proc<table_fact> > storage;
|
|
|
|
storage m_data;
|
|
|
|
hashtable_table(hashtable_table_plugin & plugin, const table_signature & sig)
|
|
: table_base(plugin, sig) {}
|
|
public:
|
|
hashtable_table_plugin & get_plugin() const
|
|
{ return static_cast<hashtable_table_plugin &>(table_base::get_plugin()); }
|
|
|
|
virtual void add_fact(const table_fact & f) {
|
|
m_data.insert(f);
|
|
}
|
|
virtual void remove_fact(const table_element* fact) {
|
|
table_fact f(get_signature().size(), fact);
|
|
m_data.remove(f);
|
|
}
|
|
virtual bool contains_fact(const table_fact & f) const {
|
|
return m_data.contains(f);
|
|
}
|
|
|
|
virtual iterator begin() const;
|
|
virtual iterator end() const;
|
|
|
|
virtual unsigned get_size_estimate_rows() const { return m_data.size(); }
|
|
virtual unsigned get_size_estimate_bytes() const { return m_data.size()*get_signature().size()*8; }
|
|
virtual bool knows_exact_size() const { return true; }
|
|
};
|
|
|
|
// -----------------------------------
|
|
//
|
|
// bitvector_table
|
|
//
|
|
// -----------------------------------
|
|
|
|
class bitvector_table;
|
|
|
|
class bitvector_table_plugin : public table_plugin {
|
|
public:
|
|
typedef bitvector_table table;
|
|
|
|
bitvector_table_plugin(relation_manager & manager)
|
|
: table_plugin(symbol("bitvector"), manager) {}
|
|
|
|
virtual bool can_handle_signature(const table_signature & s);
|
|
|
|
virtual table_base * mk_empty(const table_signature & s);
|
|
};
|
|
|
|
class bitvector_table : public table_base {
|
|
friend class bitvector_table_plugin;
|
|
|
|
class bv_iterator;
|
|
bit_vector m_bv;
|
|
unsigned m_num_cols;
|
|
unsigned_vector m_shift;
|
|
unsigned_vector m_mask;
|
|
|
|
unsigned fact2offset(const table_element* f) const;
|
|
void offset2fact(unsigned offset, table_fact& f) const;
|
|
|
|
bitvector_table(bitvector_table_plugin & plugin, const table_signature & sig);
|
|
public:
|
|
virtual void add_fact(const table_fact & f);
|
|
virtual void remove_fact(const table_element* fact);
|
|
virtual bool contains_fact(const table_fact & f) const;
|
|
virtual iterator begin() const;
|
|
virtual iterator end() const;
|
|
};
|
|
|
|
// -------------------------------------------
|
|
// Equivalence table.
|
|
// Really: partial equivalence relation table.
|
|
// -------------------------------------------
|
|
|
|
class equivalence_table;
|
|
|
|
class equivalence_table_plugin : public table_plugin {
|
|
class union_fn;
|
|
class select_equal_and_project_fn;
|
|
class join_project_fn;
|
|
|
|
bool is_equivalence_table(table_base const& tbl) const;
|
|
|
|
public:
|
|
typedef equivalence_table table;
|
|
|
|
equivalence_table_plugin(relation_manager & manager)
|
|
: table_plugin(symbol("equivalence"), manager) {}
|
|
|
|
virtual bool can_handle_signature(const table_signature & s);
|
|
|
|
virtual table_base * mk_empty(const table_signature & s);
|
|
|
|
protected:
|
|
virtual table_union_fn * mk_union_fn(const table_base & tgt, const table_base & src,
|
|
const table_base * delta);
|
|
virtual table_transformer_fn * mk_select_equal_and_project_fn(
|
|
const table_base & t,
|
|
const table_element & value, unsigned col);
|
|
virtual table_join_fn * mk_join_project_fn(const table_base & t1, const table_base & t2,
|
|
unsigned col_cnt, const unsigned * cols1, const unsigned * cols2, unsigned removed_col_cnt,
|
|
const unsigned * removed_cols);
|
|
|
|
|
|
#if 0
|
|
virtual table_join_fn * mk_join_fn(const table_base & t1, const table_base & t2,
|
|
unsigned col_cnt, const unsigned * cols1, const unsigned * cols2);
|
|
virtual table_transformer_fn * mk_project_fn(const table_base & t, unsigned col_cnt,
|
|
const unsigned * removed_cols);
|
|
virtual table_transformer_fn * mk_rename_fn(const table_base & t, unsigned permutation_cycle_len,
|
|
const unsigned * permutation_cycle);
|
|
const table_element & value, unsigned col);
|
|
virtual table_intersection_filter_fn * mk_filter_by_negation_fn(const table_base & t,
|
|
const table_base & negated_obj, unsigned joined_col_cnt,
|
|
const unsigned * t_cols, const unsigned * negated_cols);
|
|
#endif
|
|
};
|
|
|
|
class equivalence_table : public table_base {
|
|
friend class equivalence_table_plugin;
|
|
|
|
class eq_iterator;
|
|
union_find_default_ctx m_ctx;
|
|
bit_vector m_valid;
|
|
union_find<> m_uf;
|
|
table_base* m_sparse;
|
|
|
|
equivalence_table(equivalence_table_plugin & plugin, const table_signature & sig);
|
|
virtual ~equivalence_table();
|
|
|
|
unsigned first(table_fact const& f) const { return static_cast<unsigned>(f[0]); }
|
|
unsigned second(table_fact const& f) const { return static_cast<unsigned>(f[1]); }
|
|
|
|
bool is_valid(unsigned entry) const { return entry < m_valid.size() && m_valid.get(entry); }
|
|
bool is_sparse() const { return m_sparse != 0; }
|
|
|
|
// iterator over equivalence class of 'n'.
|
|
class class_iterator {
|
|
equivalence_table const& m_parent;
|
|
unsigned m_current;
|
|
unsigned m_last;
|
|
bool m_end;
|
|
public:
|
|
class_iterator(equivalence_table const& s, unsigned n, bool end):
|
|
m_parent(s), m_current(n), m_last(n), m_end(end) {}
|
|
|
|
unsigned operator*() { return m_current; }
|
|
|
|
class_iterator& operator++() {
|
|
m_current = m_parent.m_uf.next(m_current);
|
|
m_end = (m_current == m_last);
|
|
return *this;
|
|
}
|
|
|
|
bool operator==(const class_iterator & it) const {
|
|
return
|
|
(m_end && it.m_end) ||
|
|
(!m_end && !it.m_end && m_current == it.m_current);
|
|
}
|
|
bool operator!=(const class_iterator & it) const { return !operator==(it); }
|
|
|
|
};
|
|
class_iterator class_begin(table_element const& e) const;
|
|
class_iterator class_end(table_element const& e) const;
|
|
|
|
void add_fact_sparse(table_fact const& f);
|
|
void mk_sparse();
|
|
|
|
|
|
public:
|
|
virtual void add_fact(const table_fact & f);
|
|
virtual void remove_fact(const table_element* fact);
|
|
virtual bool contains_fact(const table_fact & f) const;
|
|
virtual table_base* clone() const;
|
|
virtual iterator begin() const;
|
|
virtual iterator end() const;
|
|
virtual unsigned get_size_estimate_rows() const;
|
|
virtual unsigned get_size_estimate_bytes() const;
|
|
virtual bool knows_exact_size() const;
|
|
virtual void display(std::ostream & out) const;
|
|
|
|
};
|
|
|
|
|
|
};
|
|
|
|
#endif /* _DL_TABLE_H_ */
|
|
|