/*++ Copyright (c) 2015 Microsoft Corporation Module Name: ackr_info.h Abstract: Author: Mikolas Janota Revision History: --*/ #pragma once #include "util/ref.h" #include "util/obj_hashtable.h" #include "ast/ast.h" #include "ast/rewriter/expr_replacer.h" #include "ast/ast_translation.h" /** \brief Information about how a formula is being converted into a formula without uninterpreted function symbols via ackermannization. The intended use is that new terms are added via set_abstr. Once all terms are abstracted, call seal. The function abstract may only be called when sealed. The class enables reference counting. **/ class ackr_info { public: ackr_info(ast_manager& m) : m(m), m_er(mk_default_expr_replacer(m, false)), m_subst(m), m_ref_count(0), m_sealed(false) {} virtual ~ackr_info() { for (auto & kv : m_t2c) { m.dec_ref(kv.m_key); m.dec_ref(kv.m_value); } } inline void set_abstr(app* term, app* c) { SASSERT(!m_sealed); SASSERT(c && term); m_t2c.insert(term,c); m_c2t.insert(c->get_decl(),term); m_subst.insert(term, c); m.inc_ref(term); m.inc_ref(c); } inline expr_ref abstract(expr * e) { expr_ref res(m); SASSERT(m_sealed); (*m_er)(e, res); return res; } inline app* find_term(func_decl* c) const { app * rv = nullptr; m_c2t.find(c,rv); return rv; } inline app* get_abstr(app* term) const { return m_t2c.find(term); } inline void seal() { m_sealed = true; m_er->set_substitution(&m_subst); } virtual ackr_info * translate(ast_translation & translator) { ackr_info * const retv = alloc(ackr_info, translator.to()); for (auto & kv : m_t2c) { retv->set_abstr(translator(kv.m_key), translator(kv.m_value)); } if (m_sealed) retv->seal(); return retv; } // // Reference counting // void inc_ref() { ++m_ref_count; } void dec_ref() { --m_ref_count; if (m_ref_count == 0) { dealloc(this); } } private: typedef obj_map t2ct; typedef obj_map c2tt; ast_manager& m; t2ct m_t2c; // terms to constants c2tt m_c2t; // constants to terms (inversion of m_t2c) // replacer and substitution used to compute abstractions scoped_ptr m_er; expr_substitution m_subst; unsigned m_ref_count; // reference counting bool m_sealed; // debugging }; typedef ref ackr_info_ref;