/*++ 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: --*/ #ifndef _DL_BOUND_RELATION_H_ #define _DL_BOUND_RELATION_H_ #include "dl_context.h" #include "uint_set.h" #include "dl_vector_relation.h" #include "dl_interval_relation.h" #include "arith_decl_plugin.h" #include "basic_simplifier_plugin.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; basic_simplifier_plugin m_bsimp; public: bound_relation_plugin(relation_manager& m); virtual bool can_handle_signature(const relation_signature & s); static symbol get_name() { return symbol("bound_relation"); } virtual relation_base * mk_empty(const relation_signature & s); virtual relation_base * mk_full(func_decl* p, const relation_signature & s); virtual relation_join_fn * mk_join_fn(const relation_base & t1, const relation_base & t2, unsigned col_cnt, const unsigned * cols1, const unsigned * cols2); virtual relation_transformer_fn * mk_project_fn(const relation_base & t, unsigned col_cnt, const unsigned * removed_cols); virtual relation_transformer_fn * mk_rename_fn(const relation_base & t, unsigned permutation_cycle_len, const unsigned * permutation_cycle); virtual relation_union_fn * mk_union_fn(const relation_base & tgt, const relation_base & src, const relation_base * delta); virtual relation_union_fn * mk_widen_fn(const relation_base & tgt, const relation_base & src, const relation_base * delta); virtual relation_mutator_fn * mk_filter_identical_fn(const relation_base & t, unsigned col_cnt, const unsigned * identical_cols); virtual relation_mutator_fn * mk_filter_equal_fn(const relation_base & t, const relation_element & value, unsigned col); virtual relation_mutator_fn * mk_filter_interpreted_fn(const relation_base & t, app * condition); virtual 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) { return 0; } #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; uint_set2(uint_set2 const& other):lt(other.lt), le(other.le) {} uint_set2() {} 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); bound_relation& operator=(bound_relation const& other); virtual bool empty() const { return m_empty; } virtual void add_fact(const relation_fact & f); virtual bool contains_fact(const relation_fact & f) const; virtual bound_relation * clone() const; virtual bound_relation * complement(func_decl* p) const; virtual void to_formula(expr_ref& fml) const; 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; private: typedef uint_set2 T; virtual T mk_intersect(T const& t1, T const& t2, bool& is_empty) const; virtual T mk_widen(T const& t1, T const& t2) const; virtual T mk_unite(T const& t1, T const& t2) const; virtual T mk_eq(union_find<> const& old_eqs, union_find<> const& new_eqs, T const& t) const; virtual void mk_rename_elem(T& i, unsigned col_cnt, unsigned const* cycle); virtual bool is_subset_of(T const& t1, T const& t2) const; virtual bool is_full(T const& t) const; virtual bool is_empty(unsigned idx, T const& t) const; virtual void display_index(unsigned idx, T const& t, std::ostream& out) const; void normalize(T const& src, T& dst) const; void normalize(uint_set const& src, uint_set& dst) const; }; }; #endif