mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 01:25:31 +00:00
Reorganizing the code
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
8b70f0b833
commit
d8cd3fc3ab
36 changed files with 261 additions and 429 deletions
|
@ -20,7 +20,6 @@ Revision History:
|
|||
#include"ast_pp.h"
|
||||
#include"ast_ll_pp.h"
|
||||
#include"var_subst.h"
|
||||
#include"front_end_params.h"
|
||||
#include"array_decl_plugin.h"
|
||||
#include"well_sorted.h"
|
||||
#include"used_symbols.h"
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
model_evaluator_params.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
New parameter setting support for rewriter.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-22
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"model_evaluator_params.h"
|
||||
|
||||
model_evaluator_params::model_evaluator_params() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void model_evaluator_params::reset() {
|
||||
m_model_completion = false;
|
||||
m_cache = true;
|
||||
m_max_steps = UINT_MAX;
|
||||
m_max_memory = UINT_MAX;
|
||||
}
|
||||
|
||||
#define PARAM(name) param_names.push_back(name)
|
||||
|
||||
void model_evaluator_params::get_params(svector<char const *> & param_names) const {
|
||||
PARAM(":model-completion");
|
||||
PARAM(":cache");
|
||||
PARAM(":max-steps");
|
||||
PARAM(":max-memory");
|
||||
}
|
||||
|
||||
#define DESCR(NAME, DR) if (strcmp(name, NAME) == 0) return DR
|
||||
|
||||
char const * model_evaluator_params::get_param_descr(char const * name) const {
|
||||
DESCR(":model-completion", "(default: false) assigns an interpretation to symbols that are not intepreted by the model.");
|
||||
DESCR(":cache", "(default: true) cache intermediate results.");
|
||||
DESCR(":max-steps", "(default: infty) maximum number of steps.");
|
||||
DESCR(":max-memory", "(default: infty) maximum amount of memory in megabytes.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define RBOOL(NAME) if (strcmp(name, NAME) == 0) return CPK_BOOL
|
||||
#define RUINT(NAME) if (strcmp(name, NAME) == 0) return CPK_UINT
|
||||
|
||||
param_kind model_evaluator_params::get_param_kind(char const * name) const {
|
||||
RBOOL(":model-completion");
|
||||
RBOOL(":cache");
|
||||
RUINT(":max-steps");
|
||||
RUINT(":max-memory");
|
||||
return CPK_INVALID;
|
||||
}
|
||||
|
||||
#define SET(NAME, FIELD) if (strcmp(name, NAME) == 0) { FIELD = value; return true; }
|
||||
|
||||
bool model_evaluator_params::set_bool_param(char const * name, bool value) {
|
||||
SET(":model-completion", m_model_completion);
|
||||
SET(":cache", m_cache);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool model_evaluator_params::set_uint_param(char const * name, unsigned value) {
|
||||
SET(":max-steps", m_max_steps);
|
||||
SET(":max-memory", m_max_memory);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1,348 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
model_smt2_pp.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Pretty printer for models using SMT2 format.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo)
|
||||
|
||||
Revision History:
|
||||
|
||||
|
||||
--*/
|
||||
#include"model_smt2_pp.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"func_decl_dependencies.h"
|
||||
#include"pp.h"
|
||||
using namespace format_ns;
|
||||
|
||||
static void pp_indent(std::ostream & out, unsigned indent) {
|
||||
for (unsigned i = 0; i < indent; i++)
|
||||
out << " ";
|
||||
}
|
||||
|
||||
static unsigned pp_symbol(std::ostream & out, symbol const & s) {
|
||||
if (is_smt2_quoted_symbol(s)) {
|
||||
std::string str = mk_smt2_quoted_symbol(s);
|
||||
out << str;
|
||||
return static_cast<unsigned>(str.length());
|
||||
}
|
||||
else if (s.is_numerical()) {
|
||||
std::string str = s.str();
|
||||
out << str;
|
||||
return static_cast<unsigned>(str.length());
|
||||
}
|
||||
else {
|
||||
out << s.bare_str();
|
||||
return static_cast<unsigned>(strlen(s.bare_str()));
|
||||
}
|
||||
}
|
||||
|
||||
#define TAB_SZ 2
|
||||
|
||||
class model_smt2_pp_ctx {
|
||||
public:
|
||||
virtual ast_manager & m() const = 0;
|
||||
virtual void display(std::ostream & out, sort * s, unsigned indent = 0) = 0;
|
||||
virtual void display(std::ostream & out, expr * n, unsigned indent = 0) = 0;
|
||||
virtual void pp(sort * s, format_ns::format_ref & r) = 0;
|
||||
virtual void pp(func_decl * f, format_ns::format_ref & r) = 0;
|
||||
virtual void pp(expr * n, format_ns::format_ref & r) = 0;
|
||||
virtual void pp(expr * n, unsigned num_vars, char const * var_prefix, format_ns::format_ref & r, sbuffer<symbol> & var_names) = 0;
|
||||
};
|
||||
|
||||
class model_smt2_pp_cmd_ctx : public model_smt2_pp_ctx {
|
||||
cmd_context & m_ctx;
|
||||
public:
|
||||
model_smt2_pp_cmd_ctx(cmd_context & ctx):m_ctx(ctx) {}
|
||||
virtual ast_manager & m() const { return m_ctx.m(); }
|
||||
virtual void display(std::ostream & out, sort * s, unsigned indent = 0) { m_ctx.display(out, s, indent); }
|
||||
virtual void display(std::ostream & out, expr * n, unsigned indent = 0) { m_ctx.display(out, n, indent); }
|
||||
virtual void pp(sort * s, format_ns::format_ref & r) { r = m_ctx.pp(s); }
|
||||
virtual void pp(func_decl * f, format_ns::format_ref & r) { return m_ctx.pp(f, r); }
|
||||
virtual void pp(expr * n, format_ns::format_ref & r) { return m_ctx.pp(n, r); }
|
||||
virtual void pp(expr * n, unsigned num_vars, char const * var_prefix, format_ns::format_ref & r, sbuffer<symbol> & var_names) {
|
||||
return m_ctx.pp(n, num_vars, var_prefix, r, var_names);
|
||||
}
|
||||
};
|
||||
|
||||
class model_smt2_pp_simple_ctx : public model_smt2_pp_ctx {
|
||||
ast_manager & m_manager;
|
||||
smt2_pp_environment_dbg m_env;
|
||||
public:
|
||||
model_smt2_pp_simple_ctx(ast_manager & m):m_manager(m), m_env(m) {}
|
||||
virtual ast_manager & m() const { return m_manager; }
|
||||
virtual void display(std::ostream & out, sort * s, unsigned indent = 0) { out << mk_ismt2_pp(s, m(), indent); }
|
||||
virtual void display(std::ostream & out, expr * n, unsigned indent = 0) { out << mk_ismt2_pp(n, m(), indent); }
|
||||
virtual void pp(sort * s, format_ns::format_ref & r) { mk_smt2_format(s, m_env, get_pp_default_params(), r); }
|
||||
virtual void pp(func_decl * f, format_ns::format_ref & r) { mk_smt2_format(f, m_env, get_pp_default_params(), r); }
|
||||
virtual void pp(expr * n, format_ns::format_ref & r) {
|
||||
sbuffer<symbol> buf;
|
||||
mk_smt2_format(n, m_env, get_pp_default_params(), 0, 0, r, buf);
|
||||
}
|
||||
virtual void pp(expr * n, unsigned num_vars, char const * var_prefix, format_ns::format_ref & r, sbuffer<symbol> & var_names) {
|
||||
mk_smt2_format(n, m_env, get_pp_default_params(), num_vars, var_prefix, r, var_names);
|
||||
}
|
||||
};
|
||||
|
||||
static void pp_uninterp_sorts(std::ostream & out, model_smt2_pp_ctx & ctx, model_core const & md, unsigned indent) {
|
||||
ast_manager & m = ctx.m();
|
||||
ptr_buffer<format> f_conds;
|
||||
unsigned num = md.get_num_uninterpreted_sorts();
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
sort * s = md.get_uninterpreted_sort(i);
|
||||
ptr_vector<expr> const & u = md.get_universe(s);
|
||||
std::ostringstream buffer;
|
||||
buffer << "universe for ";
|
||||
ctx.display(buffer, s, 13);
|
||||
buffer << ":\n";
|
||||
pp_indent(buffer, TAB_SZ);
|
||||
ptr_vector<expr>::const_iterator it = u.begin();
|
||||
ptr_vector<expr>::const_iterator end = u.end();
|
||||
for (; it != end; ++it) {
|
||||
SASSERT(is_app(*it));
|
||||
app * c = to_app(*it);
|
||||
pp_symbol(buffer, c->get_decl()->get_name());
|
||||
buffer << " ";
|
||||
}
|
||||
buffer << "\n-----------";
|
||||
std::string buffer_str = buffer.str();
|
||||
unsigned len = static_cast<unsigned>(buffer_str.length());
|
||||
pp_indent(out, indent);
|
||||
out << ";; ";
|
||||
for (unsigned i = 0; i < len; i++) {
|
||||
char c = buffer_str[i];
|
||||
if (c == '\n') {
|
||||
out << "\n";
|
||||
pp_indent(out, indent);
|
||||
out << ";; ";
|
||||
}
|
||||
else {
|
||||
out << c;
|
||||
}
|
||||
}
|
||||
out << "\n";
|
||||
pp_indent(out, indent);
|
||||
out << ";; definitions for universe elements:\n";
|
||||
it = u.begin();
|
||||
for (; it != end; ++it) {
|
||||
app * c = to_app(*it);
|
||||
pp_indent(out, indent);
|
||||
out << "(declare-fun ";
|
||||
unsigned len = pp_symbol(out, c->get_decl()->get_name());
|
||||
out << " () ";
|
||||
ctx.display(out, c->get_decl()->get_range(), indent + len + 16);
|
||||
out << ")\n";
|
||||
}
|
||||
pp_indent(out, indent);
|
||||
out << ";; cardinality constraint:\n";
|
||||
f_conds.reset();
|
||||
format * var = mk_string(m, "x");
|
||||
it = u.begin();
|
||||
for (; it != end; ++it) {
|
||||
app * c = to_app(*it);
|
||||
symbol csym = c->get_decl()->get_name();
|
||||
std::string cname;
|
||||
if (is_smt2_quoted_symbol(csym))
|
||||
cname = mk_smt2_quoted_symbol(csym);
|
||||
else
|
||||
cname = csym.str();
|
||||
format * c_args[2] = { var, mk_string(m, cname.c_str()) };
|
||||
f_conds.push_back(mk_seq1<format**, f2f>(m, c_args, c_args+2, f2f(), "="));
|
||||
}
|
||||
SASSERT(!f_conds.empty());
|
||||
format * f_cond;
|
||||
if (f_conds.size() > 1)
|
||||
f_cond = mk_seq1(m, f_conds.begin(), f_conds.end(), f2f(), "or");
|
||||
else
|
||||
f_cond = f_conds[0];
|
||||
format_ref f_s(fm(m));
|
||||
ctx.pp(s, f_s);
|
||||
format * f_args[2] = { mk_compose(m,
|
||||
mk_string(m, "((x "),
|
||||
mk_indent(m, 4, mk_compose(m, f_s.get(), mk_string(m, "))")))),
|
||||
f_cond };
|
||||
format_ref f_card(fm(m));
|
||||
f_card = mk_indent(m, indent, mk_seq1<format**, f2f>(m, f_args, f_args+2, f2f(), "forall"));
|
||||
pp_indent(out, indent);
|
||||
pp(out, f_card, m, get_pp_default_params());
|
||||
out << "\n";
|
||||
pp_indent(out, indent);
|
||||
out << ";; -----------\n";
|
||||
}
|
||||
}
|
||||
|
||||
static void pp_consts(std::ostream & out, model_smt2_pp_ctx & ctx, model_core const & md, unsigned indent) {
|
||||
unsigned num = md.get_num_constants();
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
func_decl * c = md.get_constant(i);
|
||||
expr * c_i = md.get_const_interp(c);
|
||||
pp_indent(out, indent);
|
||||
out << "(define-fun ";
|
||||
unsigned len = pp_symbol(out, c->get_name());
|
||||
out << " () ";
|
||||
ctx.display(out, c->get_range(), indent + len + 16);
|
||||
out << "\n";
|
||||
pp_indent(out, indent + TAB_SZ);
|
||||
ctx.display(out, c_i);
|
||||
out << ")\n";
|
||||
}
|
||||
}
|
||||
|
||||
void sort_fun_decls(ast_manager & m, model_core const & md, ptr_buffer<func_decl> & result) {
|
||||
func_decl_set visited;
|
||||
ptr_vector<func_decl> todo;
|
||||
unsigned sz = md.get_num_functions();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
func_decl * f = md.get_function(i);
|
||||
if (visited.contains(f))
|
||||
continue;
|
||||
visited.insert(f);
|
||||
todo.push_back(f);
|
||||
while (!todo.empty()) {
|
||||
func_decl * curr = todo.back();
|
||||
func_interp * curr_i = md.get_func_interp(curr);
|
||||
SASSERT(curr_i != 0);
|
||||
if (!curr_i->is_partial()) {
|
||||
func_decl_set deps;
|
||||
bool all_visited = true;
|
||||
collect_func_decls(m, curr_i->get_else(), deps);
|
||||
func_decl_set::iterator it2 = deps.begin();
|
||||
func_decl_set::iterator end2 = deps.end();
|
||||
for (; it2 != end2; ++it2) {
|
||||
func_decl * d = *it2;
|
||||
if (d->get_arity() > 0 && md.has_interpretation(d) && !visited.contains(d)) {
|
||||
todo.push_back(d);
|
||||
visited.insert(d);
|
||||
all_visited = false;
|
||||
}
|
||||
}
|
||||
if (!all_visited)
|
||||
continue;
|
||||
}
|
||||
todo.pop_back();
|
||||
result.push_back(curr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pp_funs(std::ostream & out, model_smt2_pp_ctx & ctx, model_core const & md, unsigned indent) {
|
||||
ast_manager & m = ctx.m();
|
||||
sbuffer<symbol> var_names;
|
||||
ptr_buffer<format> f_var_names;
|
||||
ptr_buffer<format> f_arg_decls;
|
||||
ptr_buffer<format> f_entries;
|
||||
ptr_buffer<format> f_entry_conds;
|
||||
ptr_buffer<func_decl> func_decls;
|
||||
sort_fun_decls(m, md, func_decls);
|
||||
for (unsigned i = 0; i < func_decls.size(); i++) {
|
||||
func_decl * f = func_decls[i];
|
||||
func_interp * f_i = md.get_func_interp(f);
|
||||
SASSERT(f->get_arity() == f_i->get_arity());
|
||||
format_ref body(fm(m));
|
||||
var_names.reset();
|
||||
if (f_i->is_partial()) {
|
||||
body = mk_string(m, "#unspecified");
|
||||
for (unsigned j = 0; j < f->get_arity(); j++) {
|
||||
std::stringstream strm;
|
||||
strm << "x!" << (j+1);
|
||||
var_names.push_back(symbol(strm.str().c_str()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
ctx.pp(f_i->get_else(), f->get_arity(), "x", body, var_names);
|
||||
}
|
||||
TRACE("model_smt2_pp", for (unsigned i = 0; i < var_names.size(); i++) tout << var_names[i] << "\n";);
|
||||
f_var_names.reset();
|
||||
for (unsigned i = 0; i < f->get_arity(); i++)
|
||||
f_var_names.push_back(mk_string(m, var_names[i].bare_str()));
|
||||
f_arg_decls.reset();
|
||||
for (unsigned i = 0; i < f->get_arity(); i++) {
|
||||
format_ref f_domain(fm(m));
|
||||
ctx.pp(f->get_domain(i), f_domain);
|
||||
format * args[2] = { f_var_names[i], f_domain.get() };
|
||||
f_arg_decls.push_back(mk_seq5<format**, f2f>(m, args, args+2, f2f()));
|
||||
}
|
||||
format * f_domain = mk_seq5(m, f_arg_decls.begin(), f_arg_decls.end(), f2f());
|
||||
format_ref f_range(fm(m));
|
||||
ctx.pp(f->get_range(), f_range);
|
||||
if (f_i->num_entries() > 0) {
|
||||
f_entries.reset();
|
||||
for (unsigned i = 0; i < f_i->num_entries(); i++) {
|
||||
func_entry const * e = f_i->get_entry(i);
|
||||
f_entry_conds.reset();
|
||||
for (unsigned j = 0; j < f->get_arity(); j++) {
|
||||
format_ref f_arg(fm(m));
|
||||
ctx.pp(e->get_arg(j), f_arg);
|
||||
format * eq_args[2] = { f_var_names[j], f_arg.get() };
|
||||
f_entry_conds.push_back(mk_seq1<format**, f2f>(m, eq_args, eq_args+2, f2f(), "="));
|
||||
}
|
||||
format * f_entry_cond;
|
||||
SASSERT(!f_entry_conds.empty());
|
||||
if (f_entry_conds.size() > 1)
|
||||
f_entry_cond = mk_seq1(m, f_entry_conds.begin(), f_entry_conds.end(), f2f(), "and");
|
||||
else
|
||||
f_entry_cond = f_entry_conds[0];
|
||||
format_ref f_result(fm(m));
|
||||
ctx.pp(e->get_result(), f_result);
|
||||
if (i > 0)
|
||||
f_entries.push_back(mk_line_break(m));
|
||||
f_entries.push_back(mk_group(m, mk_compose(m,
|
||||
mk_string(m, "(ite "),
|
||||
mk_indent(m, 5, f_entry_cond),
|
||||
mk_indent(m, TAB_SZ, mk_compose(m,
|
||||
mk_line_break(m),
|
||||
f_result.get())))));
|
||||
}
|
||||
f_entries.push_back(mk_indent(m, TAB_SZ, mk_compose(m,
|
||||
mk_line_break(m),
|
||||
body.get())));
|
||||
for (unsigned i = 0; i < f_i->num_entries(); i++)
|
||||
f_entries.push_back(mk_string(m, ")"));
|
||||
body = mk_compose(m, f_entries.size(), f_entries.c_ptr());
|
||||
}
|
||||
format_ref def(fm(m));
|
||||
std::string fname;
|
||||
if (is_smt2_quoted_symbol(f->get_name()))
|
||||
fname = mk_smt2_quoted_symbol(f->get_name());
|
||||
else
|
||||
fname = f->get_name().str();
|
||||
def = mk_indent(m, indent, mk_compose(m,
|
||||
mk_compose(m,
|
||||
mk_string(m, "(define-fun "),
|
||||
mk_string(m, fname.c_str()),
|
||||
mk_string(m, " "),
|
||||
mk_compose(m,
|
||||
f_domain,
|
||||
mk_string(m, " "),
|
||||
f_range)),
|
||||
mk_indent(m, TAB_SZ, mk_compose(m,
|
||||
mk_line_break(m),
|
||||
body.get(),
|
||||
mk_string(m, ")")))));
|
||||
pp_indent(out, indent);
|
||||
pp(out, def.get(), m, get_pp_default_params());
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void model_smt2_pp(std::ostream & out, cmd_context & ctx, model_core const & m, unsigned indent) {
|
||||
model_smt2_pp_cmd_ctx _ctx(ctx);
|
||||
pp_uninterp_sorts(out, _ctx, m, indent);
|
||||
pp_consts(out, _ctx, m, indent);
|
||||
pp_funs(out, _ctx, m, indent);
|
||||
}
|
||||
|
||||
void model_smt2_pp(std::ostream & out, ast_manager & m, model_core const & md, unsigned indent) {
|
||||
model_smt2_pp_simple_ctx _ctx(m);
|
||||
pp_uninterp_sorts(out, _ctx, md, indent);
|
||||
pp_consts(out, _ctx, md, indent);
|
||||
pp_funs(out, _ctx, md, indent);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
model_smt2_pp.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Pretty printer for models using SMT2 format.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo)
|
||||
|
||||
Revision History:
|
||||
|
||||
|
||||
--*/
|
||||
#ifndef _MODEL_SMT2_PP_H_
|
||||
#define _MODEL_SMT2_PP_H_
|
||||
|
||||
#include"cmd_context.h"
|
||||
|
||||
void model_smt2_pp(std::ostream & out, cmd_context & ctx, model_core const & m, unsigned indent);
|
||||
void model_smt2_pp(std::ostream & out, ast_manager & m, model_core const & md, unsigned indent);
|
||||
|
||||
#endif
|
|
@ -20,7 +20,6 @@ Revision History:
|
|||
#include"ast_pp.h"
|
||||
#include"ast_ll_pp.h"
|
||||
#include"var_subst.h"
|
||||
#include"front_end_params.h"
|
||||
#include"array_decl_plugin.h"
|
||||
#include"well_sorted.h"
|
||||
#include"used_symbols.h"
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
value.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2007-08-17.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"value.h"
|
||||
|
||||
void bool_value::display(std::ostream & out) const {
|
||||
out << (m_value ? "true" : "false");
|
||||
}
|
||||
|
||||
unsigned bool_value::hash() const {
|
||||
return m_value ? 1 : 0;
|
||||
}
|
||||
|
||||
bool bool_value::operator==(const value & other) const {
|
||||
const bool_value * o = dynamic_cast<const bool_value*>(&other);
|
||||
return o && m_value == o->m_value;
|
||||
}
|
||||
|
||||
basic_factory::basic_factory(ast_manager & m):
|
||||
value_factory(symbol("basic"), m),
|
||||
m_bool(m) {
|
||||
m_bool = m.mk_type(m.get_basic_family_id(), BOOL_SORT);
|
||||
m_true = alloc(bool_value, true, m_bool.get());
|
||||
m_false = alloc(bool_value, false, m_bool.get());
|
||||
}
|
||||
|
||||
|
|
@ -1,162 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
value.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Abstract class used to represent values in a model.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2007-08-14.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _VALUE_H_
|
||||
#define _VALUE_H_
|
||||
|
||||
#include"core_model.h"
|
||||
#include"ast.h"
|
||||
#include"ref.h"
|
||||
|
||||
class model;
|
||||
|
||||
class value {
|
||||
partition_id m_partition_id;
|
||||
unsigned m_ref_count;
|
||||
type_ast * m_type;
|
||||
|
||||
friend class model;
|
||||
|
||||
void set_partition_id(partition_id id) {
|
||||
m_partition_id = id;
|
||||
}
|
||||
|
||||
public:
|
||||
value(type_ast * ty):
|
||||
m_partition_id(null_partition_id),
|
||||
m_ref_count(0),
|
||||
m_type(ty) {
|
||||
}
|
||||
|
||||
virtual ~value() {}
|
||||
|
||||
void inc_ref() { m_ref_count ++; }
|
||||
|
||||
void dec_ref() {
|
||||
SASSERT(m_ref_count > 0);
|
||||
m_ref_count--;
|
||||
if (m_ref_count == 0) {
|
||||
dealloc(this);
|
||||
}
|
||||
}
|
||||
|
||||
partition_id get_partition_id() { return m_partition_id; }
|
||||
|
||||
type_ast * get_type() const { return m_type; }
|
||||
|
||||
virtual void display(std::ostream & out) const = 0;
|
||||
|
||||
virtual unsigned hash() const = 0;
|
||||
|
||||
virtual bool operator==(const value & other) const = 0;
|
||||
|
||||
virtual void infer_types(ast_vector<type_ast> & result) { /* default: do nothing */ }
|
||||
|
||||
virtual void collect_used_partitions(svector<bool> & result) { /* default: do nothing */ }
|
||||
};
|
||||
|
||||
inline std::ostream & operator<<(std::ostream & target, const value & v) {
|
||||
v.display(target);
|
||||
return target;
|
||||
}
|
||||
|
||||
class value_factory {
|
||||
family_id m_fid;
|
||||
public:
|
||||
value_factory(symbol fname, ast_manager & m):
|
||||
m_fid(m.get_family_id(fname)) {
|
||||
}
|
||||
|
||||
virtual ~value_factory() {}
|
||||
|
||||
// Return some value of the given type
|
||||
virtual value * get_some_value(type_ast * ty) = 0;
|
||||
|
||||
// Return two distinct values of the given type
|
||||
virtual bool get_some_values(type_ast * ty, ref<value> & v1, ref<value> & v2) = 0;
|
||||
|
||||
// Return a fresh value of the given type
|
||||
virtual value * get_fresh_value(type_ast * ty) = 0;
|
||||
|
||||
virtual value * update_value(value * source, const svector<partition_id> & pid2pid) {
|
||||
return source;
|
||||
}
|
||||
|
||||
family_id get_family_id() const { return m_fid; }
|
||||
};
|
||||
|
||||
class bool_value : public value {
|
||||
friend class basic_factory;
|
||||
bool m_value;
|
||||
|
||||
bool_value(bool v, type_ast * ty):
|
||||
value(ty),
|
||||
m_value(v) {
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
bool get_value() const {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
virtual void display(std::ostream & out) const;
|
||||
|
||||
virtual unsigned hash() const;
|
||||
|
||||
virtual bool operator==(const value & other) const;
|
||||
};
|
||||
|
||||
class basic_factory : public value_factory {
|
||||
ast_ref<type_ast> m_bool;
|
||||
ref<bool_value> m_true;
|
||||
ref<bool_value> m_false;
|
||||
public:
|
||||
basic_factory(ast_manager & m);
|
||||
|
||||
virtual ~basic_factory() {}
|
||||
|
||||
bool_value * get_true() const {
|
||||
return m_true.get();
|
||||
}
|
||||
|
||||
bool_value * get_false() const {
|
||||
return m_false.get();
|
||||
}
|
||||
|
||||
// Return some value of the given type
|
||||
virtual value * get_some_value(type_ast * ty) {
|
||||
return get_false();
|
||||
}
|
||||
|
||||
// Return two distinct values of the given type
|
||||
virtual bool get_some_values(type_ast * ty, ref<value> & v1, ref<value> & v2) {
|
||||
v1 = get_false();
|
||||
v2 = get_true();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return a fresh value of the given type
|
||||
virtual value * get_fresh_value(type_ast * ty) {
|
||||
// it is not possible to create new fresh values...
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _VALUE_H_ */
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue