/*++ Copyright (c) 2006 Microsoft Corporation Module Name: substitution_tree.h Abstract: Substitution Trees Author: Leonardo de Moura (leonardo) 2008-02-03. Revision History: --*/ #ifndef _SUBSTITUTION_TREE_H_ #define _SUBSTITUTION_TREE_H_ #include"ast.h" #include"substitution.h" /** \brief Substitution tree visitor. */ class st_visitor { protected: substitution & m_subst; public: st_visitor(substitution & s):m_subst(s) {} virtual ~st_visitor() {} substitution & get_substitution() { return m_subst; } virtual bool operator()(expr * e) { return true; } }; /** \brief Substitution tree term index. */ class substitution_tree { typedef std::pair subst; struct node { bool m_leaf; svector m_subst; node * m_next_sibling; union { node * m_first_child; expr * m_expr; }; node(bool leaf):m_leaf(leaf), m_next_sibling(0), m_first_child(0) {} }; ast_manager & m_manager; ptr_vector m_roots; unsigned m_max_reg; ptr_vector m_registers; unsigned m_size; ptr_vector m_vars; // mapping from decl_id to var_ref_vector // Compilation time fields unsigned m_next_reg; bit_vector m_used_regs; unsigned_vector m_todo; svector m_compatible; svector m_incompatible; // Execution time fields substitution * m_subst; ptr_vector m_bstack; unsigned m_in_offset; unsigned m_st_offset; unsigned m_reg_offset; typedef std::pair entry; svector m_visit_todo; unsigned next_reg(); void push(svector & sv, subst const & s); expr * get_reg_value(unsigned ridx); void set_reg_value(unsigned ridx, expr * e); void erase_reg_from_todo(unsigned ridx); void linearize(svector & result); void process_args(app * in, app * out); void reset_registers(unsigned old_size); unsigned get_compatibility_measure(svector const & sv); node * find_best_child(node * r); void reset_compiler(); node * mk_node_for(expr * new_expr); void mark_used_reg(unsigned ridx); void mark_used_regs(svector const & sv); bool is_fully_compatible(svector const & sv); bool find_fully_compatible_child(node * r, node * & prev, node * & child); static bool at_least_3_children(node * r); void delete_node(node * n); void display(std::ostream & out, subst const & s) const; void display(std::ostream & out, svector const & sv) const; void display(std::ostream & out, node * n, unsigned delta) const; enum st_visit_mode { STV_UNIF, STV_INST, STV_GEN }; expr_offset find(expr_offset p); bool backtrack(); template bool bind_var(var * v, unsigned offset, expr_offset const & p); template bool unify_match(expr_offset p1, expr_offset p2); template bool visit_vars(expr * e, st_visitor & st); template bool visit(svector const & s); template bool visit(expr * e, st_visitor & st, node * r); template void visit(expr * e, st_visitor & st, unsigned in_offset, unsigned st_offset, unsigned reg_offset); public: substitution_tree(ast_manager & m); ~substitution_tree(); void insert(app * n); void insert(expr * n); void erase(app * n); void erase(expr * n); void reset(); bool empty() const { return m_size == 0; } void unify(expr * e, st_visitor & v, unsigned in_offset = 0, unsigned st_offset = 1, unsigned reg_offset = 2); void inst(expr * e, st_visitor & v, unsigned in_offset = 0, unsigned st_offset = 1, unsigned reg_offset = 2); void gen(expr * e, st_visitor & v, unsigned in_offset = 0, unsigned st_offset = 1, unsigned reg_offset = 2); unsigned get_approx_num_regs() const { return m_max_reg + 1; } void display(std::ostream & out) const; }; #endif /* _SUBSTITUTION_TREE_H_ */