/*++ Copyright (c) 2010 Microsoft Corporation Module Name: dl_bound_relation.h Abstract: Basic (strict upper) bound relation. Author: Nikolaj Bjorner (nbjorner) 2010-2-11 Revision History: --*/ #pragma once #include "muz/base/dl_context.h" #include "muz/rel/dl_relation_manager.h" #include "muz/rel/dl_base.h" #include "util/uint_set.h" #include "muz/rel/dl_vector_relation.h" #include "muz/rel/dl_interval_relation.h" #include "ast/arith_decl_plugin.h" #include "ast/rewriter/bool_rewriter.h" namespace datalog { class bound_relation; class bound_relation_plugin : public relation_plugin { friend class bound_relation; class join_fn; class project_fn; class rename_fn; class union_fn; class union_fn_i; class filter_equal_fn; class filter_identical_fn; class filter_interpreted_fn; class filter_intersection_fn; arith_util m_arith; bool_rewriter m_bsimp; public: bound_relation_plugin(relation_manager& m); bool can_handle_signature(const relation_signature & s) override; static symbol get_name() { return symbol("bound_relation"); } relation_base * mk_empty(const relation_signature & s) override; relation_base * mk_full(func_decl* p, const relation_signature & s) override; relation_join_fn * mk_join_fn(const relation_base & t1, const relation_base & t2, unsigned col_cnt, const unsigned * cols1, const unsigned * cols2) override; relation_transformer_fn * mk_project_fn(const relation_base & t, unsigned col_cnt, const unsigned * removed_cols) override; relation_transformer_fn * mk_rename_fn(const relation_base & t, unsigned permutation_cycle_len, const unsigned * permutation_cycle) override; relation_union_fn * mk_union_fn(const relation_base & tgt, const relation_base & src, const relation_base * delta) override; relation_union_fn * mk_widen_fn(const relation_base & tgt, const relation_base & src, const relation_base * delta) override; relation_mutator_fn * mk_filter_identical_fn(const relation_base & t, unsigned col_cnt, const unsigned * identical_cols) override; relation_mutator_fn * mk_filter_equal_fn(const relation_base & t, const relation_element & value, unsigned col) override; relation_mutator_fn * mk_filter_interpreted_fn(const relation_base & t, app * condition) override; relation_join_fn * mk_join_project_fn(const relation_base & t1, const relation_base & t2, unsigned joined_col_cnt, const unsigned * cols1, const unsigned * cols2, unsigned removed_col_cnt, const unsigned * removed_cols) override { return nullptr; } #if 0 virtual intersection_filter_fn * mk_filter_by_intersection_fn( const relation_base & t, const relation_base & src, unsigned joined_col_cnt, const unsigned * t_cols, const unsigned * src_cols) { return 0; } #endif static bound_relation* get(relation_base* r); private: static bound_relation& get(relation_base& r); static bound_relation const & get(relation_base const& r); static bool is_interval_relation(relation_base const& r); static interval_relation& get_interval_relation(relation_base& r); static interval_relation const& get_interval_relation(relation_base const& r); }; struct uint_set2 { uint_set lt; uint_set le; bool operator==(const uint_set2& other) const { return other.lt == lt && other.le == le; } bool operator!=(const uint_set2& other) const { return other.lt != lt || other.le != le; } }; inline std::ostream & operator<<(std::ostream & target, const uint_set2 & s) { return target << s.lt << " " << s.le; } class bound_relation_helper { public: static void mk_project_t(uint_set2& t, unsigned_vector const& renaming); }; class bound_relation : public vector_relation { friend class bound_relation_plugin; svector > m_todo; public: bound_relation(bound_relation_plugin& p, relation_signature const& s, bool is_empty); bool empty() const override { return m_empty; } void add_fact(const relation_fact & f) override; bool contains_fact(const relation_fact & f) const override; bound_relation * clone() const override; bound_relation * complement(func_decl* p) const override; void to_formula(expr_ref& fml) const override; bound_relation_plugin& get_plugin() const; void mk_union_i(interval_relation const& src, bound_relation* delta, bool is_widen); void mk_lt(unsigned i, unsigned j); void mk_lt(unsigned i); void mk_le(unsigned i, unsigned j); bool is_lt(unsigned i, unsigned j) const; bool is_precise() const override { return false; } private: typedef uint_set2 T; T mk_intersect(T const& t1, T const& t2, bool& is_empty) const override; T mk_widen(T const& t1, T const& t2) const override; T mk_unite(T const& t1, T const& t2) const override; T mk_eq(union_find<> const& old_eqs, union_find<> const& new_eqs, T const& t) const override; void mk_rename_elem(T& i, unsigned col_cnt, unsigned const* cycle) override; bool is_subset_of(T const& t1, T const& t2) const override; bool is_full(T const& t) const override; bool is_empty(unsigned idx, T const& t) const override; void display_index(unsigned idx, T const& t, std::ostream& out) const override; void normalize(T const& src, T& dst) const; void normalize(uint_set const& src, uint_set& dst) const; }; };