/*++ Copyright (c) 2006 Microsoft Corporation Module Name: order.h Abstract: Abstract class for term orderings. Author: Leonardo de Moura (leonardo) 2008-01-28. Revision History: --*/ #ifndef _ORDER_H_ #define _ORDER_H_ #include"substitution.h" #include"precedence.h" #include"trace.h" class order { protected: ast_manager & m_manager; precedence * m_precedence; substitution * m_subst; typedef std::pair expr_offset_pair; svector m_eq_todo; expr_offset find(expr_offset t) { while (m_subst && is_var(t.get_expr()) && m_subst->find(to_var(t.get_expr()), t.get_offset(), t)) ; return t; } bool f_greater(func_decl * f, func_decl * g) const { bool r = m_precedence->compare(f, g) > 0; TRACE("order", tout << f->get_name() << " greater than " << g->get_name() << " == " << r << "\n";); return r; } public: enum result { UNKNOWN, UNCOMPARABLE, EQUAL, GREATER, LESSER, NOT_GTEQ }; static bool ok(result r) { return r == EQUAL || r == GREATER || r == LESSER; } order(ast_manager & m, precedence * p):m_manager(m), m_precedence(p) { SASSERT(p); } virtual ~order() { dealloc(m_precedence); } virtual void reserve(unsigned num_offsets, unsigned num_vars) {} virtual void reserve_offsets(unsigned num_offsets) {} virtual void reserve_vars(unsigned num_vars) {} ast_manager & get_manager() { return m_manager; } virtual result compare(expr_offset const & t1, expr_offset const & t2, substitution * s) = 0; result compare(expr * t1, expr * t2, unsigned offset, substitution * s) { return compare(expr_offset(t1, offset), expr_offset(t2, offset), s); } result compare(expr * t1, expr * t2) { return compare(expr_offset(t1, 0), expr_offset(t2, 0), 0); } virtual bool greater(expr_offset const & t1, expr_offset const & t2, substitution * s) = 0; bool greater(expr * t1, expr * t2) { return greater(expr_offset(t1,0), expr_offset(t2,0), 0); } bool greater(expr * t1, expr * t2, substitution * s) { return greater(expr_offset(t1,0), expr_offset(t2,0), s); } bool greater(expr * t1, expr * t2, unsigned offset, substitution * s) { return greater(expr_offset(t1, offset), expr_offset(t2, offset), s); } /** \brief Return a value > 0 if t1 is greater than t2, 0 if t1 == t2, and < 0 otherwise (uncomparable, unknown, lesser). */ virtual int compare_ge(expr_offset const & t1, expr_offset const & t2, substitution * s) = 0; /** \brief Return true if the given terms are equal modulo the given substitution */ bool equal(expr_offset const & t1, expr_offset const & t2, substitution * s); bool equal(expr * t1, expr * t2, unsigned offset = 0, substitution * s = 0) { return equal(expr_offset(t1, offset), expr_offset(t2, offset), s); } }; #endif /* _ORDER_H_ */