mirror of
https://github.com/Z3Prover/z3
synced 2025-04-13 12:28:44 +00:00
121 lines
2.9 KiB
C++
121 lines
2.9 KiB
C++
/*++
|
|
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<app, app*> t2ct;
|
|
typedef obj_map<func_decl, app*> 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<expr_replacer> m_er;
|
|
expr_substitution m_subst;
|
|
|
|
unsigned m_ref_count; // reference counting
|
|
bool m_sealed; // debugging
|
|
};
|
|
|
|
typedef ref<ackr_info> ackr_info_ref;
|
|
|