3
0
Fork 0
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:
Leonardo de Moura 2012-10-20 19:54:08 -07:00
parent 8b70f0b833
commit d8cd3fc3ab
36 changed files with 261 additions and 429 deletions

View file

@ -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"

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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

View file

@ -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"

View file

@ -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());
}

View file

@ -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_ */