z3-z3-4.13.0.src.muz.rel.dl_lazy_table.h Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
dl_lazy_table.h
Abstract:
Structure for delaying table operations.
Author:
Nikolaj Bjorner (nbjorner) 2013-09-04
Revision History:
--*/
#pragma once
#include "muz/rel/dl_base.h"
#include "util/ref.h"
namespace datalog {
class lazy_table;
class lazy_table_plugin : public table_plugin {
friend class lazy_table;
class join_fn;
class project_fn;
class union_fn;
class rename_fn;
class filter_equal_fn;
class filter_identical_fn;
class filter_interpreted_fn;
class filter_by_negation_fn;
table_plugin& m_plugin;
static symbol mk_name(table_plugin& p);
public:
lazy_table_plugin(table_plugin& p):
table_plugin(mk_name(p), p.get_manager()),
m_plugin(p) {}
bool can_handle_signature(const table_signature & s) override {
return m_plugin.can_handle_signature(s);
}
table_base * mk_empty(const table_signature & s) override;
static table_plugin* mk_sparse(relation_manager& rm);
protected:
table_join_fn * mk_join_fn(
const table_base & t1, const table_base & t2,
unsigned col_cnt, const unsigned * cols1, const unsigned * cols2) override;
table_union_fn * mk_union_fn(
const table_base & tgt, const table_base & src,
const table_base * delta) override;
table_transformer_fn * mk_project_fn(
const table_base & t, unsigned col_cnt,
const unsigned * removed_cols) override;
table_transformer_fn * mk_rename_fn(
const table_base & t, unsigned permutation_cycle_len,
const unsigned * permutation_cycle) override;
table_mutator_fn * mk_filter_identical_fn(
const table_base & t, unsigned col_cnt, const unsigned * identical_cols) override;
table_mutator_fn * mk_filter_equal_fn(
const table_base & t, const table_element & value, unsigned col) override;
table_mutator_fn * mk_filter_interpreted_fn(
const table_base & t, app * condition) override;
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) override;
static lazy_table const& get(table_base const& tb);
static lazy_table& get(table_base& tb);
static lazy_table const* get(table_base const* tb);
static lazy_table* get(table_base* tb);
};
enum lazy_table_kind {
LAZY_TABLE_BASE,
LAZY_TABLE_JOIN,
LAZY_TABLE_PROJECT,
LAZY_TABLE_RENAME,
LAZY_TABLE_FILTER_IDENTICAL,
LAZY_TABLE_FILTER_EQUAL,
LAZY_TABLE_FILTER_INTERPRETED,
LAZY_TABLE_FILTER_BY_NEGATION
};
class lazy_table_ref {
protected:
lazy_table_plugin& m_plugin;
table_signature m_signature;
unsigned m_ref;
scoped_rel m_table;
relation_manager& rm() { return m_plugin.get_manager(); }
virtual table_base* force() = 0;
public:
lazy_table_ref(lazy_table_plugin& p, table_signature const& sig):
m_plugin(p), m_signature(sig), m_ref(0) {}
virtual ~lazy_table_ref() = default;
void inc_ref() { ++m_ref; }
void dec_ref() { --m_ref; if (0 == m_ref) dealloc(this); }
void release_table() { m_table.release(); }
virtual lazy_table_kind kind() const = 0;
table_signature const& get_signature() const { return m_signature; }
lazy_table_plugin & get_lplugin() const { return m_plugin; }
table_base* eval() { if (!m_table) { m_table = force(); } SASSERT(m_table); return m_table.get(); }
};
class lazy_table : public table_base {
protected:
mutable ref m_ref;
public:
lazy_table(lazy_table_ref* t):
table_base(t->get_lplugin(), t->get_signature()),
m_ref(t)
{}
lazy_table_plugin& get_lplugin() const {
return dynamic_cast(table_base::get_plugin());
}
table_base * clone() const override;
table_base * complement(func_decl* p, const table_element * func_columns = nullptr) const override;
bool empty() const override;
bool contains_fact(const table_fact & f) const override;
void remove_fact(table_element const* fact) override;
void remove_facts(unsigned fact_cnt, const table_fact * facts) override;
void remove_facts(unsigned fact_cnt, const table_element * facts) override;
void reset() override;
void add_fact(table_fact const& f) override;
unsigned get_size_estimate_rows() const override { return 1; }
unsigned get_size_estimate_bytes() const override { return 1; }
bool knows_exact_size() const override { return false; }
table_base* eval() const;
table_base::iterator begin() const override;
table_base::iterator end() const override;
lazy_table_ref* get_ref() const { return m_ref.get(); }
void set(lazy_table_ref* r) { m_ref = r; }
};
class lazy_table_base : public lazy_table_ref {
public:
lazy_table_base(lazy_table_plugin & p, table_base* table)
: lazy_table_ref(p, table->get_signature()) {
m_table = table;
// SASSERT(&p.m_plugin == &table->get_lplugin());
}
lazy_table_kind kind() const override { return LAZY_TABLE_BASE; }
table_base* force() override { return m_table.get(); }
};
class lazy_table_join : public lazy_table_ref {
unsigned_vector m_cols1;
unsigned_vector m_cols2;
ref m_t1;
ref m_t2;
public:
lazy_table_join(unsigned col_cnt,
const unsigned * cols1, const unsigned * cols2,
lazy_table const& t1, lazy_table const& t2, table_signature const& sig)
: lazy_table_ref(t1.get_lplugin(), sig),
m_cols1(col_cnt, cols1),
m_cols2(col_cnt, cols2),
m_t1(t1.get_ref()),
m_t2(t2.get_ref()) { }
lazy_table_kind kind() const override { return LAZY_TABLE_JOIN; }
unsigned_vector const& cols1() const { return m_cols1; }
unsigned_vector const& cols2() const { return m_cols2; }
lazy_table_ref* t1() const { return m_t1.get(); }
lazy_table_ref* t2() const { return m_t2.get(); }
table_base* force() override;
};
class lazy_table_project : public lazy_table_ref {
unsigned_vector m_cols;
ref m_src;
public:
lazy_table_project(unsigned col_cnt, const unsigned * cols, lazy_table const& src, table_signature const& sig)
: lazy_table_ref(src.get_lplugin(), sig),
m_cols(col_cnt, cols),
m_src(src.get_ref()) {}
lazy_table_kind kind() const override { return LAZY_TABLE_PROJECT; }
unsigned_vector const& cols() const { return m_cols; }
lazy_table_ref* src() const { return m_src.get(); }
table_base* force() override;
};
class lazy_table_rename : public lazy_table_ref {
unsigned_vector m_cols;
ref m_src;
public:
lazy_table_rename(unsigned col_cnt, const unsigned * cols, lazy_table const& src, table_signature const& sig)
: lazy_table_ref(src.get_lplugin(), sig),
m_cols(col_cnt, cols),
m_src(src.get_ref()) {}
lazy_table_kind kind() const override { return LAZY_TABLE_RENAME; }
unsigned_vector const& cols() const { return m_cols; }
lazy_table_ref* src() const { return m_src.get(); }
table_base* force() override;
};
class lazy_table_filter_identical : public lazy_table_ref {
unsigned_vector m_cols;
ref m_src;
public:
lazy_table_filter_identical(unsigned col_cnt, const unsigned * cols, lazy_table const& src)
: lazy_table_ref(src.get_lplugin(), src.get_signature()), m_cols(col_cnt, cols), m_src(src.get_ref()) {}
lazy_table_kind kind() const override { return LAZY_TABLE_FILTER_IDENTICAL; }
unsigned_vector const& cols() const { return m_cols; }
lazy_table_ref* src() const { return m_src.get(); }
table_base* force() override;
};
class lazy_table_filter_equal : public lazy_table_ref {
unsigned m_col;
table_element m_value;
ref m_src;
public:
lazy_table_filter_equal(unsigned col, table_element value, lazy_table const& src)
: lazy_table_ref(src.get_lplugin(), src.get_signature()),
m_col(col),
m_value(value),
m_src(src.get_ref()) {}
lazy_table_kind kind() const override { return LAZY_TABLE_FILTER_EQUAL; }
unsigned col() const { return m_col; }
table_element value() const { return m_value; }
lazy_table_ref* src() const { return m_src.get(); }
table_base* force() override;
};
class lazy_table_filter_interpreted : public lazy_table_ref {
app_ref m_condition;
ref m_src;
public:
lazy_table_filter_interpreted(lazy_table const& src, app* condition)
: lazy_table_ref(src.get_lplugin(), src.get_signature()),
m_condition(condition, src.get_lplugin().get_ast_manager()), m_src(src.get_ref()) {}
lazy_table_kind kind() const override { return LAZY_TABLE_FILTER_INTERPRETED; }
app* condition() const { return m_condition; }
lazy_table_ref* src() const { return m_src.get(); }
table_base* force() override;
};
class lazy_table_filter_by_negation : public lazy_table_ref {
ref m_tgt;
ref m_src;
unsigned_vector m_cols1;
unsigned_vector m_cols2;
public:
lazy_table_filter_by_negation(lazy_table const& tgt, lazy_table const& src,
unsigned_vector const& c1, unsigned_vector const& c2)
: lazy_table_ref(tgt.get_lplugin(), tgt.get_signature()),
m_tgt(tgt.get_ref()),
m_src(src.get_ref()),
m_cols1(c1),
m_cols2(c2) {}
lazy_table_kind kind() const override { return LAZY_TABLE_FILTER_BY_NEGATION; }
lazy_table_ref* tgt() const { return m_tgt.get(); }
lazy_table_ref* src() const { return m_src.get(); }
unsigned_vector const& cols1() const { return m_cols1; }
unsigned_vector const& cols2() const { return m_cols2; }
table_base* force() override;
};
}