3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-10-04 15:03:57 +00:00
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2012-12-06 11:05:49 -08:00
commit 9ab1210cc2
518 changed files with 21452 additions and 22650 deletions

View file

@ -144,7 +144,21 @@ public:
bool is_map(expr* n) const { return is_app_of(n, m_fid, OP_ARRAY_MAP); }
bool is_as_array(expr * n) const { return is_app_of(n, m_fid, OP_AS_ARRAY); }
bool is_as_array_tree(expr * n);
bool is_select(func_decl* f) const { return is_decl_of(f, m_fid, OP_SELECT); }
bool is_store(func_decl* f) const { return is_decl_of(f, m_fid, OP_STORE); }
bool is_const(func_decl* f) const { return is_decl_of(f, m_fid, OP_CONST_ARRAY); }
bool is_map(func_decl* f) const { return is_decl_of(f, m_fid, OP_ARRAY_MAP); }
bool is_as_array(func_decl* f) const { return is_decl_of(f, m_fid, OP_AS_ARRAY); }
func_decl * get_as_array_func_decl(app * n) const { SASSERT(is_as_array(n)); return to_func_decl(n->get_decl()->get_parameter(0).get_ast()); }
app * mk_store(unsigned num_args, expr * const * args) {
return m_manager.mk_app(m_fid, OP_STORE, 0, 0, num_args, args);
}
app * mk_select(unsigned num_args, expr * const * args) {
return m_manager.mk_app(m_fid, OP_SELECT, 0, 0, num_args, args);
}
app * mk_map(func_decl * f, unsigned num_args, expr * const * args) {
parameter p(f);
return m_manager.mk_app(m_fid, OP_ARRAY_MAP, 1, &p, num_args, args);

View file

@ -1196,13 +1196,36 @@ decl_plugin * user_sort_plugin::mk_fresh() {
//
// -----------------------------------
ast_manager::ast_manager(proof_gen_mode m, std::ostream *trace_stream, bool is_format_manager):
ast_manager::ast_manager(proof_gen_mode m, char const * trace_file, bool is_format_manager):
m_alloc("ast_manager"),
m_expr_array_manager(*this, m_alloc),
m_expr_dependency_manager(*this, m_alloc),
m_expr_dependency_array_manager(*this, m_alloc),
m_proof_mode(m),
m_trace_stream(trace_stream) {
m_trace_stream(0),
m_trace_stream_owner(false) {
if (trace_file) {
m_trace_stream = alloc(std::fstream, trace_file, std::ios_base::out);
m_trace_stream_owner = true;
}
if (!is_format_manager)
m_format_manager = alloc(ast_manager, PGM_DISABLED, m_trace_stream, true);
else
m_format_manager = 0;
init();
}
ast_manager::ast_manager(proof_gen_mode m, std::fstream * trace_stream, bool is_format_manager):
m_alloc("ast_manager"),
m_expr_array_manager(*this, m_alloc),
m_expr_dependency_manager(*this, m_alloc),
m_expr_dependency_array_manager(*this, m_alloc),
m_proof_mode(m),
m_trace_stream(trace_stream),
m_trace_stream_owner(false) {
if (!is_format_manager)
m_format_manager = alloc(ast_manager, PGM_DISABLED, trace_stream, true);
else
@ -1216,9 +1239,10 @@ ast_manager::ast_manager(ast_manager const & src, bool disable_proofs):
m_expr_dependency_manager(*this, m_alloc),
m_expr_dependency_array_manager(*this, m_alloc),
m_proof_mode(disable_proofs ? PGM_DISABLED : src.m_proof_mode),
m_trace_stream(src.m_trace_stream) {
m_trace_stream(src.m_trace_stream),
m_trace_stream_owner(false) {
SASSERT(!src.is_format_manager());
m_format_manager = 0;
m_format_manager = alloc(ast_manager, PGM_DISABLED, m_trace_stream, true);
init();
copy_families_plugins(src);
}
@ -1256,6 +1280,7 @@ void ast_manager::init() {
ast_manager::~ast_manager() {
SASSERT(is_format_manager() || !m_family_manager.has_family(symbol("format")));
dec_ref(m_bool_sort);
dec_ref(m_proof_sort);
dec_ref(m_true);
@ -1294,6 +1319,13 @@ ast_manager::~ast_manager() {
#endif
if (m_format_manager != 0)
dealloc(m_format_manager);
if (m_trace_stream_owner) {
std::fstream & tmp = * m_trace_stream;
tmp << "[eof]\n";
tmp.close();
dealloc(m_trace_stream);
m_trace_stream = 0;
}
}
void ast_manager::compact_memory() {
@ -1873,8 +1905,8 @@ app * ast_manager::mk_app_core(func_decl * decl, unsigned num_args, expr * const
new_node = new (mem) app(decl, num_args, args);
r = register_node(new_node);
}
#ifndef SMTCOMP
if (m_trace_stream != NULL && r == new_node) {
if (m_trace_stream && r == new_node) {
*m_trace_stream << "[mk-app] #" << r->get_id() << " ";
if (r->get_num_args() == 0 && r->get_decl()->get_name() == "int") {
ast_ll_pp(*m_trace_stream, *this, r);
@ -1887,7 +1919,7 @@ app * ast_manager::mk_app_core(func_decl * decl, unsigned num_args, expr * const
*m_trace_stream << "\n";
}
}
#endif
return r;
}
@ -2064,8 +2096,7 @@ quantifier * ast_manager::mk_quantifier(bool forall, unsigned num_decls, sort *
num_no_patterns, no_patterns);
quantifier * r = register_node(new_node);
#ifndef SMTCOMP
if (m_trace_stream != NULL && r == new_node) {
if (m_trace_stream && r == new_node) {
*m_trace_stream << "[mk-quant] #" << r->get_id() << " " << qid;
for (unsigned i = 0; i < num_patterns; ++i) {
*m_trace_stream << " #" << patterns[i]->get_id();
@ -2073,7 +2104,7 @@ quantifier * ast_manager::mk_quantifier(bool forall, unsigned num_decls, sort *
*m_trace_stream << " #" << body->get_id() << "\n";
}
#endif
return r;
}
@ -2637,12 +2668,13 @@ proof * ast_manager::mk_unit_resolution(unsigned num_proofs, proof * const * pro
ptr_buffer<expr> args;
args.append(num_proofs, (expr**) proofs);
expr * fact;
expr const * f1 = get_fact(proofs[0]);
expr const * f2 = get_fact(proofs[1]);
expr * f1 = get_fact(proofs[0]);
expr * f2 = get_fact(proofs[1]);
if (num_proofs == 2 && is_complement(f1, f2)) {
fact = mk_false();
}
else {
CTRACE("mk_unit_resolution_bug", !is_or(f1), tout << mk_pp(f1, *this) << " " << mk_pp(f2, *this) << "\n";);
SASSERT(is_or(f1));
ptr_buffer<expr> new_lits;
app const * cls = to_app(f1);

View file

@ -1350,7 +1350,8 @@ protected:
unsigned m_fresh_id;
bool m_debug_ref_count;
u_map<unsigned> m_debug_free_indices;
std::ostream* m_trace_stream;
std::fstream* m_trace_stream;
bool m_trace_stream_owner;
#ifdef Z3DEBUG
bool slow_not_contains(ast const * n);
#endif
@ -1361,10 +1362,14 @@ protected:
bool coercion_needed(func_decl * decl, unsigned num_args, expr * const * args);
public:
ast_manager(proof_gen_mode = PGM_DISABLED, std::ostream * trace_stream = NULL, bool is_format_manager = false);
ast_manager(proof_gen_mode = PGM_DISABLED, char const * trace_file = 0, bool is_format_manager = false);
ast_manager(proof_gen_mode, std::fstream * trace_stream, bool is_format_manager = false);
ast_manager(ast_manager const & src, bool disable_proofs = false);
~ast_manager();
bool has_trace_stream() const { return m_trace_stream != 0; }
std::ostream & trace_stream() { SASSERT(has_trace_stream()); return *m_trace_stream; }
void enable_int_real_coercions(bool f) { m_int_real_coercions = f; }
bool int_real_coercions() const { return m_int_real_coercions; }

View file

@ -24,7 +24,7 @@ Revision History:
#include"ast_smt2_pp.h"
struct mk_pp : public mk_ismt2_pp {
mk_pp(ast * t, ast_manager & m, pp_params const & p, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0):
mk_pp(ast * t, ast_manager & m, params_ref const & p, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0):
mk_ismt2_pp(t, m, p, indent, num_vars, var_prefix) {
}
mk_pp(ast * t, ast_manager & m, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0):

View file

@ -33,14 +33,14 @@ public:
virtual void display(std::ostream & out, func_decl * f, unsigned indent = 0) const {
out << f->get_name();
}
virtual void pp(sort * s, format_ns::format_ref & r) const { mk_smt2_format(s, env(), get_pp_default_params(), r); }
virtual void pp(func_decl * f, format_ns::format_ref & r) const { mk_smt2_format(f, env(), get_pp_default_params(), r); }
virtual void pp(sort * s, format_ns::format_ref & r) const { mk_smt2_format(s, env(), params_ref(), r); }
virtual void pp(func_decl * f, format_ns::format_ref & r) const { mk_smt2_format(f, env(), params_ref(), r); }
virtual void pp(expr * n, format_ns::format_ref & r) const {
sbuffer<symbol> buf;
mk_smt2_format(n, env(), get_pp_default_params(), 0, 0, r, buf);
mk_smt2_format(n, env(), params_ref(), 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) const {
mk_smt2_format(n, env(), get_pp_default_params(), num_vars, var_prefix, r, var_names);
mk_smt2_format(n, env(), params_ref(), num_vars, var_prefix, r, var_names);
}
virtual void display(std::ostream & out, expr * n, unsigned indent, unsigned num_vars, char const * var_prefix, sbuffer<symbol> & var_names) const {
NOT_IMPLEMENTED_YET();

View file

@ -24,6 +24,7 @@ Revision History:
#include"ast_ll_pp.h"
#include"ast_pp.h"
#include"algebraic_numbers.h"
#include"pp_params.hpp"
using namespace format_ns;
#define ALIAS_PREFIX "a"
@ -376,7 +377,6 @@ typedef app_ref_vector format_ref_vector;
class smt2_printer {
ast_manager & m_manager;
pp_params const & m_params;
smt2_pp_environment & m_env;
shared_occs m_soccs;
@ -421,6 +421,16 @@ class smt2_printer {
string_buffer<> m_next_name_buffer;
// Config
bool m_pp_decimal;
unsigned m_pp_decimal_precision;
bool m_pp_bv_lits;
bool m_pp_bv_neg;
unsigned m_pp_max_depth;
unsigned m_pp_min_alias_size;
bool m_pp_flat_assoc;
symbol next_name(char const * prefix, unsigned & idx) {
while (true) {
m_next_name_buffer.reset();
@ -508,10 +518,10 @@ class smt2_printer {
void pp_const(app * c) {
format * f;
if (m_env.get_autil().is_numeral(c) || m_env.get_autil().is_irrational_algebraic_numeral(c)) {
f = m_env.pp_arith_literal(c, m_params.m_pp_decimal, m_params.m_pp_decimal_precision);
f = m_env.pp_arith_literal(c, m_pp_decimal, m_pp_decimal_precision);
}
else if (m_env.get_bvutil().is_numeral(c)) {
f = m_env.pp_bv_literal(c, m_params.m_pp_bv_lits, m_params.m_pp_bv_neg);
f = m_env.pp_bv_literal(c, m_pp_bv_lits, m_pp_bv_neg);
}
else if (m_env.get_futil().is_value(c)) {
f = m_env.pp_float_literal(c);
@ -584,8 +594,8 @@ class smt2_printer {
m_format_stack.shrink(fr.m_spos);
m_info_stack.shrink(fr.m_spos);
if (fr.m_use_alias && m_root != t &&
((f_info.m_depth >= m_params.m_pp_max_depth) ||
((f_info.m_weight >= m_params.m_pp_min_alias_size || is_quantifier(t)) && m_soccs.is_shared(t)))) {
((f_info.m_depth >= m_pp_max_depth) ||
((f_info.m_weight >= m_pp_min_alias_size || is_quantifier(t)) && m_soccs.is_shared(t)))) {
symbol a = next_alias();
TRACE("smt2_pp", tout << "a: " << a << " depth: " << f_info.m_depth << ", weight: " << f_info.m_weight
<< ", lvl: " << f_info.m_lvl << " t: #" << t->get_id() << "\n" << mk_ll_pp(t, m())
@ -602,7 +612,7 @@ class smt2_printer {
}
bool flat_assoc(app * t, frame const & fr) {
if (!m_params.m_pp_flat_assoc)
if (!m_pp_flat_assoc)
return false;
func_decl * f = t->get_decl();
if (f->is_associative() && m_frame_stack.size() >= 2 && !m_soccs.is_shared(t)) {
@ -943,9 +953,8 @@ class smt2_printer {
}
public:
smt2_printer(smt2_pp_environment & env, pp_params const & params):
smt2_printer(smt2_pp_environment & env, params_ref const & params):
m_manager(env.get_manager()),
m_params(params),
m_env(env),
m_soccs(m_manager),
m_root(0),
@ -953,6 +962,15 @@ public:
m_next_alias_idx(1),
m_format_stack(fm()) {
init_expr2alias_stack();
pp_params p(params);
m_pp_decimal = p.decimal();
m_pp_decimal_precision = p.decimal_precision();
m_pp_bv_lits = p.bv_literals();
m_pp_bv_neg = p.bv_neg();
m_pp_max_depth = p.max_depth();
m_pp_min_alias_size = p.min_alias_size();
m_pp_flat_assoc = p.flat_assoc();
}
~smt2_printer() {
@ -1003,24 +1021,24 @@ public:
};
void mk_smt2_format(expr * n, smt2_pp_environment & env, pp_params const & p,
void mk_smt2_format(expr * n, smt2_pp_environment & env, params_ref const & p,
unsigned num_vars, char const * var_prefix,
format_ref & r, sbuffer<symbol> & var_names) {
smt2_printer pr(env, p);
pr(n, num_vars, var_prefix, r, var_names);
}
void mk_smt2_format(sort * s, smt2_pp_environment & env, pp_params const & p, format_ref & r) {
void mk_smt2_format(sort * s, smt2_pp_environment & env, params_ref const & p, format_ref & r) {
smt2_printer pr(env, p);
pr(s, r);
}
void mk_smt2_format(func_decl * f, smt2_pp_environment & env, pp_params const & p, format_ref & r) {
void mk_smt2_format(func_decl * f, smt2_pp_environment & env, params_ref const & p, format_ref & r) {
smt2_printer pr(env, p);
pr(f, r);
}
std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & env, pp_params const & p, unsigned indent,
std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & env, params_ref const & p, unsigned indent,
unsigned num_vars, char const * var_prefix) {
ast_manager & m = env.get_manager();
format_ref r(fm(m));
@ -1032,7 +1050,7 @@ std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & e
return out;
}
std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & env, pp_params const & p, unsigned indent) {
std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & env, params_ref const & p, unsigned indent) {
ast_manager & m = env.get_manager();
format_ref r(fm(m));
sbuffer<symbol> var_names;
@ -1043,7 +1061,7 @@ std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & e
return out;
}
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, pp_params const & p, unsigned indent) {
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, params_ref const & p, unsigned indent) {
ast_manager & m = env.get_manager();
format_ref r(fm(m));
sbuffer<symbol> var_names;
@ -1054,7 +1072,7 @@ std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environmen
return out;
}
mk_ismt2_pp::mk_ismt2_pp(ast * t, ast_manager & m, pp_params const & p, unsigned indent, unsigned num_vars, char const * var_prefix):
mk_ismt2_pp::mk_ismt2_pp(ast * t, ast_manager & m, params_ref const & p, unsigned indent, unsigned num_vars, char const * var_prefix):
m_ast(t),
m_manager(m),
m_params(p),
@ -1066,7 +1084,7 @@ mk_ismt2_pp::mk_ismt2_pp(ast * t, ast_manager & m, pp_params const & p, unsigned
mk_ismt2_pp::mk_ismt2_pp(ast * t, ast_manager & m, unsigned indent, unsigned num_vars, char const * var_prefix):
m_ast(t),
m_manager(m),
m_params(get_pp_default_params()),
m_params(m_empty),
m_indent(indent),
m_num_vars(num_vars),
m_var_prefix(var_prefix) {

View file

@ -23,7 +23,7 @@ Revision History:
#define _AST_SMT2_PP_H_
#include"format.h"
#include"pp_params.h"
#include"params.h"
#include"arith_decl_plugin.h"
#include"bv_decl_plugin.h"
#include"array_decl_plugin.h"
@ -82,28 +82,29 @@ public:
virtual bool uses(symbol const & s) const { return false; }
};
void mk_smt2_format(expr * n, smt2_pp_environment & env, pp_params const & p,
void mk_smt2_format(expr * n, smt2_pp_environment & env, params_ref const & p,
unsigned num_vars, char const * var_prefix,
format_ns::format_ref & r, sbuffer<symbol> & var_names);
void mk_smt2_format(sort * s, smt2_pp_environment & env, pp_params const & p, format_ns::format_ref & r);
void mk_smt2_format(func_decl * f, smt2_pp_environment & env, pp_params const & p, format_ns::format_ref & r);
void mk_smt2_format(sort * s, smt2_pp_environment & env, params_ref const & p, format_ns::format_ref & r);
void mk_smt2_format(func_decl * f, smt2_pp_environment & env, params_ref const & p, format_ns::format_ref & r);
std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & env, pp_params const & p, unsigned indent = 0,
std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0,
unsigned num_vars = 0, char const * var_prefix = 0);
std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & env, pp_params const & p, unsigned indent = 0);
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, pp_params const & p, unsigned indent = 0);
std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0);
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0);
/**
\brief Internal wrapper (for debugging purposes only)
*/
struct mk_ismt2_pp {
ast * m_ast;
ast_manager & m_manager;
pp_params const & m_params;
unsigned m_indent;
unsigned m_num_vars;
char const * m_var_prefix;
mk_ismt2_pp(ast * t, ast_manager & m, pp_params const & p, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0);
ast * m_ast;
ast_manager & m_manager;
params_ref m_empty;
params_ref const & m_params;
unsigned m_indent;
unsigned m_num_vars;
char const * m_var_prefix;
mk_ismt2_pp(ast * t, ast_manager & m, params_ref const & p, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0);
mk_ismt2_pp(ast * t, ast_manager & m, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0);
};

View file

@ -67,8 +67,13 @@ symbol smt_renaming::fix_symbol(symbol s, int k) {
buffer << s << k;
return symbol(buffer.str().c_str());
}
buffer << mk_smt2_quoted_symbol(s);
if (is_smt2_quoted_symbol(s)) {
buffer << mk_smt2_quoted_symbol(s);
}
else {
buffer << s;
}
if (k > 0) {
buffer << k;
}
@ -949,6 +954,10 @@ public:
mark.mark(s, true);
}
void operator()(sort* s) {
ast_mark mark;
pp_sort_decl(mark, s);
}
void operator()(func_decl* d) {
if (m_is_smt2) {
@ -962,7 +971,6 @@ public:
m_out << ") ";
visit_sort(d->get_range());
m_out << ")";
newline();
}
else {
m_out << "(";
@ -1021,6 +1029,22 @@ void ast_smt_pp::display_expr_smt2(std::ostream& strm, expr* n, unsigned indent,
p(n);
}
void ast_smt_pp::display_ast_smt2(std::ostream& strm, ast* a, unsigned indent, unsigned num_var_names, char const* const* var_names) {
ptr_vector<quantifier> ql;
smt_renaming rn;
smt_printer p(strm, m_manager, ql, rn, m_logic, false, true, m_simplify_implies, indent, num_var_names, var_names);
if (is_expr(a)) {
p(to_expr(a));
}
else if (is_func_decl(a)) {
p(to_func_decl(a));
}
else {
SASSERT(is_sort(a));
p(to_sort(a));
}
}
void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) {
ptr_vector<quantifier> ql;
@ -1071,6 +1095,7 @@ void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) {
if (!(*m_is_declared)(d)) {
smt_printer p(strm, m_manager, ql, rn, m_logic, true, true, m_simplify_implies, 0);
p(d);
strm << "\n";
}
}
@ -1079,6 +1104,7 @@ void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) {
if (!(*m_is_declared)(d)) {
smt_printer p(strm, m_manager, ql, rn, m_logic, true, true, m_simplify_implies, 0);
p(d);
strm << "\n";
}
}

View file

@ -79,22 +79,23 @@ public:
void display_smt2(std::ostream& strm, expr* n);
void display_expr(std::ostream& strm, expr* n);
void display_expr_smt2(std::ostream& strm, expr* n, unsigned indent = 0, unsigned num_var_names = 0, char const* const* var_names = 0);
void display_ast_smt2(std::ostream& strm, ast* n, unsigned indent = 0, unsigned num_var_names = 0, char const* const* var_names = 0);
};
struct mk_smt_pp {
expr * m_expr;
ast* m_ast;
ast_manager& m_manager;
unsigned m_indent;
unsigned m_num_var_names;
char const* const* m_var_names;
mk_smt_pp(expr* e, ast_manager & m, unsigned indent = 0, unsigned num_var_names = 0, char const* const* var_names = 0) :
m_expr(e), m_manager(m), m_indent(indent), m_num_var_names(num_var_names), m_var_names(var_names) {}
mk_smt_pp(ast* e, ast_manager & m, unsigned indent = 0, unsigned num_var_names = 0, char const* const* var_names = 0) :
m_ast(e), m_manager(m), m_indent(indent), m_num_var_names(num_var_names), m_var_names(var_names) {}
};
inline std::ostream& operator<<(std::ostream& out, const mk_smt_pp & p) {
ast_smt_pp pp(p.m_manager);
pp.display_expr_smt2(out, p.m_expr, p.m_indent, p.m_num_var_names, p.m_var_names);
pp.display_ast_smt2(out, p.m_ast, p.m_indent, p.m_num_var_names, p.m_var_names);
return out;
}

View file

@ -44,8 +44,7 @@ namespace datalog {
m_num_sym("N"),
m_lt_sym("<"),
m_le_sym("<="),
m_rule_sym("R"),
m_hyper_resolve_sym("hyper-res")
m_rule_sym("R")
{
}

View file

@ -69,7 +69,6 @@ namespace datalog {
symbol m_lt_sym;
symbol m_le_sym;
symbol m_rule_sym;
symbol m_hyper_resolve_sym;
bool check_bounds(char const* msg, unsigned low, unsigned up, unsigned val) const;
bool check_domain(unsigned low, unsigned up, unsigned val) const;
@ -93,7 +92,6 @@ namespace datalog {
func_decl * mk_compare(decl_kind k, symbol const& sym, sort*const* domain);
func_decl * mk_clone(sort* r);
func_decl * mk_rule(unsigned arity);
func_decl * mk_hyper_res(unsigned num_params, parameter const* params, unsigned arity, sort *const* domain);
sort * mk_finite_sort(unsigned num_params, parameter const* params);
sort * mk_relation_sort(unsigned num_params, parameter const* params);

View file

@ -348,13 +348,13 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters,
// When the bv_decl_plugin is installed, then we know how to convert 3 bit-vectors into a float!
sort * fp = mk_float_sort(domain[2]->get_parameter(0).get_int(), domain[1]->get_parameter(0).get_int()+1);
symbol name("asFloat");
return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
}
return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
}
else {
// .. Otherwise we only know how to convert rationals/reals.
if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int()))
m_manager->raise_exception("expecting two integer parameters to asFloat");
if (arity != 2 && arity != 3)
if (arity != 2 && arity != 3)
m_manager->raise_exception("invalid number of arguments to asFloat operator");
if (!is_rm_sort(domain[0]) || domain[1] != m_real_sort)
m_manager->raise_exception("sort mismatch");
@ -373,6 +373,23 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters,
}
}
func_decl * float_decl_plugin::mk_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain, sort * range) {
if (!m_bv_plugin)
m_manager->raise_exception("asIEEEBV unsupported; use a logic with BV support");
if (arity != 1)
m_manager->raise_exception("invalid number of arguments to asIEEEBV");
if (!is_float_sort(domain[0]))
m_manager->raise_exception("sort mismatch");
// When the bv_decl_plugin is installed, then we know how to convert a float to an IEEE bit-vector.
unsigned float_sz = domain[0]->get_parameter(0).get_int() + domain[0]->get_parameter(1).get_int();
parameter ps[] = { parameter(float_sz) };
sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, ps);
symbol name("asIEEEBV");
return m_manager->mk_func_decl(name, 1, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters));
}
func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain, sort * range) {
switch (k) {
@ -420,6 +437,8 @@ func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters
return mk_rm_unary_decl(k, num_parameters, parameters, arity, domain, range);
case OP_FLOAT_FUSED_MA:
return mk_fused_ma(k, num_parameters, parameters, arity, domain, range);
case OP_TO_IEEE_BV:
return mk_to_ieee_bv(k, num_parameters, parameters, arity, domain, range);
default:
m_manager->raise_exception("unsupported floating point operator");
return 0;
@ -462,7 +481,10 @@ void float_decl_plugin::get_op_names(svector<builtin_name> & op_names, symbol co
op_names.push_back(builtin_name("min", OP_FLOAT_MIN));
op_names.push_back(builtin_name("max", OP_FLOAT_MAX));
op_names.push_back(builtin_name("asFloat", OP_TO_FLOAT));
op_names.push_back(builtin_name("asFloat", OP_TO_FLOAT));
if (m_bv_plugin)
op_names.push_back(builtin_name("asIEEEBV", OP_TO_IEEE_BV));
}
void float_decl_plugin::get_sort_names(svector<builtin_name> & sort_names, symbol const & logic) {

View file

@ -67,6 +67,7 @@ enum float_op_kind {
OP_FLOAT_IS_SIGN_MINUS,
OP_TO_FLOAT,
OP_TO_IEEE_BV,
LAST_FLOAT_OP
};
@ -118,6 +119,8 @@ class float_decl_plugin : public decl_plugin {
unsigned arity, sort * const * domain, sort * range);
func_decl * mk_to_float(decl_kind k, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain, sort * range);
func_decl * mk_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain, sort * range);
virtual void set_manager(ast_manager * m, family_id id);
unsigned mk_id(mpf const & v);
@ -159,7 +162,7 @@ class float_util {
ast_manager & m_manager;
float_decl_plugin * m_plugin;
family_id m_fid;
arith_util m_a_util;
arith_util m_a_util;
public:
float_util(ast_manager & m);
~float_util();
@ -209,7 +212,7 @@ public:
bool is_to_float(expr * n) { return is_app_of(n, m_fid, OP_TO_FLOAT); }
app * mk_to_float(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_TO_FLOAT, arg1, arg2); }
app * mk_to_float(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_TO_FLOAT, arg1, arg2); }
app * mk_add(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_ADD, arg1, arg2, arg3); }
app * mk_mul(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_MUL, arg1, arg2, arg3); }
app * mk_sub(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_SUB, arg1, arg2, arg3); }
@ -238,6 +241,8 @@ public:
app * mk_is_sign_minus(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_SIGN_MINUS, arg1); }
bool is_uminus(expr * a) { return is_app_of(a, m_fid, OP_FLOAT_UMINUS); }
app * mk_to_ieee_bv(expr * arg1) { return m().mk_app(m_fid, OP_TO_IEEE_BV, arg1); }
};
#endif

View file

@ -1,524 +0,0 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
cnf.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2008-01-23.
Revision History:
--*/
#include"cnf.h"
#include"var_subst.h"
#include"ast_util.h"
#include"ast_pp.h"
#include"ast_ll_pp.h"
unsigned cnf_entry::hash() const {
unsigned a = m_node->get_id();
unsigned b = m_polarity;
unsigned c = m_in_q;
mix(a,b,c);
return c;
}
bool cnf_entry::operator==(cnf_entry const & k) const {
return m_node == k.m_node && m_polarity == k.m_polarity && m_in_q == k.m_in_q;
}
cnf_cache::cnf_cache(ast_manager & m):
m_manager(m) {
}
void cnf_cache::insert(cnf_entry const & k, expr * r, proof * pr) {
SASSERT(!m_cache.contains(k));
m_manager.inc_ref(r);
m_manager.inc_ref(pr);
m_cache.insert(k, expr_proof_pair(r, pr));
}
void cnf_cache::reset() {
cache::iterator it = m_cache.begin();
cache::iterator end = m_cache.end();
for (; it != end; ++it) {
expr_proof_pair & pair = (*it).m_value;
m_manager.dec_ref(pair.first);
m_manager.dec_ref(pair.second);
}
m_cache.reset();
}
void cnf::cache_result(expr * e, bool in_q, expr * r, proof * pr) {
SASSERT(r);
TRACE("cnf", tout << "caching result for: " << e->get_id() << " " << r->get_id() << "\n";);
m_cache.insert(cnf_entry(e, true, in_q), r, pr);
}
void cnf::visit(expr * n, bool in_q, bool & visited) {
if (!is_cached(n, in_q)) {
m_todo.push_back(std::make_pair(n, in_q));
visited = false;
}
}
bool cnf::visit_children(expr * n, bool in_q) {
bool visited = true;
switch(n->get_kind()) {
case AST_APP:
if (m_manager.is_or(n) || m_manager.is_and(n) || m_manager.is_label(n)) {
unsigned j = to_app(n)->get_num_args();
while (j > 0) {
--j;
visit(to_app(n)->get_arg(j), in_q, visited);
}
}
break;
case AST_QUANTIFIER:
visit(to_quantifier(n)->get_expr(), true, visited);
break;
default:
break;
}
return visited;
}
void cnf::reduce1(expr * n, bool in_q) {
switch(n->get_kind()) {
case AST_APP:
if (m_manager.is_or(n))
reduce1_or(to_app(n), in_q);
else if (m_manager.is_and(n))
reduce1_and(to_app(n), in_q);
else if (m_manager.is_label(n))
reduce1_label(to_app(n), in_q);
else
cache_result(n, in_q, n, 0);
break;
case AST_QUANTIFIER:
reduce1_quantifier(to_quantifier(n), in_q);
break;
default:
cache_result(n, in_q, n, 0);
break;
}
}
void cnf::get_args(app * n, bool in_q, ptr_buffer<expr> & new_args, ptr_buffer<proof> & new_arg_prs) {
unsigned num = n->get_num_args();
for (unsigned i = 0; i < num; i++) {
expr * new_arg = 0;
proof * new_arg_pr = 0;
get_cached(n->get_arg(i), in_q, new_arg, new_arg_pr);
SASSERT(new_arg);
new_args.push_back(new_arg);
if (new_arg_pr)
new_arg_prs.push_back(new_arg_pr);
}
}
void cnf::flat_args(func_decl * d, ptr_buffer<expr> const & args, ptr_buffer<expr> & flat_args) {
ptr_buffer<expr>::const_iterator it = args.begin();
ptr_buffer<expr>::const_iterator end = args.end();
for (; it != end; ++it) {
expr * arg = *it;
if (is_app_of(arg, d))
flat_args.append(to_app(arg)->get_num_args(), to_app(arg)->get_args());
else
flat_args.push_back(arg);
}
}
/**
\brief Return the approximated size of distributing OR over AND on
(OR args[0] .... args[sz-1])
*/
approx_nat cnf::approx_result_size_for_disj(ptr_buffer<expr> const & args) {
approx_nat r(1);
ptr_buffer<expr>::const_iterator it = args.begin();
ptr_buffer<expr>::const_iterator end = args.end();
for (; it != end; ++it) {
expr * arg = *it;
if (m_manager.is_and(arg))
r *= to_app(arg)->get_num_args();
}
return r;
}
/**
\brief Return true if it is too expensive to process the disjunction of args
*/
inline bool cnf::is_too_expensive(approx_nat approx_result_size, ptr_buffer<expr> const & args) {
// (OR A (AND B C)) is always considered cheap.
if (args.size() == 2 && (!m_manager.is_and(args[0]) || !m_manager.is_and(args[1])))
return false;
return !(approx_result_size < m_params.m_cnf_factor);
}
/**
\brief Create a (positive) name for the expressions of the form (AND ...) in args.
Store the result in new_args.
*/
void cnf::name_args(ptr_buffer<expr> const & args, expr_ref_buffer & new_args, proof_ref_buffer & new_arg_prs) {
ptr_buffer<expr>::const_iterator it = args.begin();
ptr_buffer<expr>::const_iterator end = args.end();
for (; it != end; ++it) {
expr * arg = *it;
if (m_manager.is_and(arg)) {
expr_ref new_def(m_manager);
proof_ref new_def_pr(m_manager);
app_ref new_arg(m_manager);
proof_ref new_arg_pr(m_manager);
if (m_defined_names.mk_pos_name(to_app(arg), new_def, new_def_pr, new_arg, new_arg_pr)) {
m_todo_defs.push_back(new_def);
if (m_manager.proofs_enabled())
m_todo_proofs.push_back(new_def_pr);
}
new_args.push_back(new_arg);
if (m_manager.fine_grain_proofs())
new_arg_prs.push_back(new_arg_pr);
else
m_coarse_proofs.push_back(new_arg_pr);
}
else
new_args.push_back(arg);
}
}
void cnf::distribute(app * n, app * & r, proof * & pr) {
SASSERT(m_manager.is_or(n));
buffer<unsigned> sz;
buffer<unsigned> it;
ptr_buffer<expr> new_args;
unsigned num = n->get_num_args();
for (unsigned i = 0; i < num; i++) {
expr * arg = n->get_arg(i);
it.push_back(0);
if (m_manager.is_and(arg))
sz.push_back(to_app(arg)->get_num_args());
else
sz.push_back(1);
}
do {
ptr_buffer<expr> lits;
for (unsigned i = 0; i < num; i++) {
expr * arg = n->get_arg(i);
if (m_manager.is_and(arg)) {
SASSERT(it[i] < to_app(arg)->get_num_args());
lits.push_back(to_app(arg)->get_arg(it[i]));
}
else {
SASSERT(it[i] == 0);
lits.push_back(arg);
}
}
app * n = m_manager.mk_or(lits.size(), lits.c_ptr());
new_args.push_back(n);
}
while (product_iterator_next(sz.size(), sz.c_ptr(), it.c_ptr()));
SASSERT(!new_args.empty());
if (new_args.size() == 1)
r = to_app(new_args[0]);
else
r = m_manager.mk_and(new_args.size(), new_args.c_ptr());
pr = 0;
if (m_manager.fine_grain_proofs() && r != n)
pr = m_manager.mk_iff_oeq(m_manager.mk_distributivity(n, r));
}
void cnf::push_quant(quantifier * q, expr * & r, proof * & pr) {
SASSERT(is_forall(q));
expr * e = q->get_expr();
pr = 0;
if (m_manager.is_and(e)) {
expr_ref_buffer new_args(m_manager);
unsigned num = to_app(e)->get_num_args();
for (unsigned i = 0; i < num; i++) {
quantifier_ref aux(m_manager);
aux = m_manager.update_quantifier(q, 0, 0, 0, 0, to_app(e)->get_arg(i));
expr_ref new_arg(m_manager);
elim_unused_vars(m_manager, aux, new_arg);
new_args.push_back(new_arg);
}
r = m_manager.mk_and(new_args.size(), new_args.c_ptr());
if (m_manager.fine_grain_proofs())
pr = m_manager.mk_iff_oeq(m_manager.mk_push_quant(q, r));
}
else {
r = q;
}
}
void cnf::reduce1_or(app * n, bool in_q) {
ptr_buffer<expr> new_args;
ptr_buffer<proof> new_arg_prs;
get_args(n, in_q, new_args, new_arg_prs);
expr * r;
proof * pr = 0;
if (in_q || m_params.m_cnf_mode == CNF_OPPORTUNISTIC || m_params.m_cnf_mode == CNF_FULL) {
ptr_buffer<expr> f_args;
flat_args(n->get_decl(), new_args, f_args);
TRACE("cnf_or", for (unsigned i = 0; i < f_args.size(); i++) tout << mk_pp(f_args[i], m_manager) << "\n";);
approx_nat result_size = approx_result_size_for_disj(f_args);
TRACE("cnf_or", tout << mk_pp(n, m_manager) << "\napprox. result: " << result_size << "\n";);
if (m_params.m_cnf_mode != CNF_OPPORTUNISTIC || result_size < m_params.m_cnf_factor) {
expr_ref_buffer cheap_args(m_manager);
proof_ref_buffer cheap_args_pr(m_manager);
if (is_too_expensive(result_size, f_args)) {
name_args(f_args, cheap_args, cheap_args_pr);
}
else {
cheap_args.append(f_args.size(), f_args.c_ptr());
}
app_ref r1(m_manager);
r1 = m_manager.mk_or(cheap_args.size(), cheap_args.c_ptr());
// Proof gen support ---------------------------
// r1 is (OR cheap_args) it is only built if proofs are enabled.
// p1 is a proof for (= n r1)
proof * p1 = 0;
if (m_manager.fine_grain_proofs()) {
proof * prs[3];
app * r[2];
r[0] = m_manager.mk_or(new_args.size(), new_args.c_ptr());
prs[0] = n == r[0] ? 0 : m_manager.mk_oeq_congruence(n, r[0], new_arg_prs.size(), new_arg_prs.c_ptr());
r[1] = m_manager.mk_or(f_args.size(), f_args.c_ptr());
prs[1] = r[0] == r[1] ? 0 : m_manager.mk_iff_oeq(m_manager.mk_rewrite(r[0], r[1]));
prs[2] = r[1] == r1 ? 0 : m_manager.mk_oeq_congruence(r[1], r1, cheap_args_pr.size(), cheap_args_pr.c_ptr());
p1 = m_manager.mk_transitivity(3, prs);
}
// --------------------------------------------
expr_ref r2(m_manager);
proof_ref p2(m_manager);
m_pull.pull_quant2(r1, r2, p2);
if (is_quantifier(r2)) {
expr * e = to_quantifier(r2)->get_expr();
SASSERT(m_manager.is_or(e));
app * d_r;
proof * d_pr;
distribute(to_app(e), d_r, d_pr);
quantifier_ref r3(m_manager);
r3 = m_manager.update_quantifier(to_quantifier(r2), d_r);
proof * push_pr;
push_quant(r3, r, push_pr);
if (m_manager.fine_grain_proofs()) {
// p1 is a proof of n == r1
// p2 is a proof of r1 == r2
p2 = p2 == 0 ? 0 : m_manager.mk_iff_oeq(p2);
proof * p3 = r2 == r3 ? 0 : m_manager.mk_oeq_quant_intro(to_quantifier(r2), r3, d_pr);
CTRACE("cnf_or", p1, tout << "p1:\n" << mk_pp(m_manager.get_fact(p1), m_manager) << "\n";);
CTRACE("cnf_or", p2, tout << "p2:\n" << mk_pp(m_manager.get_fact(p2), m_manager) << "\n";);
CTRACE("cnf_or", p3, tout << "p3:\n" << mk_pp(m_manager.get_fact(p3), m_manager) << "\n";);
TRACE("cnf_or", tout << "r2 == r3: " << (r2 == r3) << "\n"
<< mk_pp(r2, m_manager) << "\n" << mk_pp(r3, m_manager) << "\n";);
pr = m_manager.mk_transitivity(p1, p2, p3, push_pr);
}
cache_result(n, in_q, r, pr);
}
else {
SASSERT(p2 == 0);
SASSERT(r1 == r2);
SASSERT(m_manager.is_or(r2));
app * r3;
distribute(to_app(r2), r3, pr);
r = r3;
pr = m_manager.mk_transitivity(p1, pr);
cache_result(n, in_q, r, pr);
}
return;
}
}
r = m_manager.mk_or(new_args.size(), new_args.c_ptr());
if (m_manager.fine_grain_proofs() && n != r)
pr = m_manager.mk_oeq_congruence(n, to_app(r), new_arg_prs.size(), new_arg_prs.c_ptr());
cache_result(n, in_q, r, pr);
}
void cnf::reduce1_and(app * n, bool in_q) {
ptr_buffer<expr> new_args;
ptr_buffer<proof> new_arg_prs;
get_args(n, in_q, new_args, new_arg_prs);
app * r;
proof * pr = 0;
if (in_q || m_params.m_cnf_mode == CNF_OPPORTUNISTIC || m_params.m_cnf_mode == CNF_FULL) {
ptr_buffer<expr> f_args;
flat_args(n->get_decl(), new_args, f_args);
r = m_manager.mk_and(f_args.size(), f_args.c_ptr());
if (m_manager.fine_grain_proofs() && n != r) {
app * r0 = m_manager.mk_and(new_args.size(), new_args.c_ptr());
proof * p0 = r0 == n ? 0 : m_manager.mk_oeq_congruence(n, r0, new_arg_prs.size(), new_arg_prs.c_ptr());
proof * p1 = r0 == r ? 0 : m_manager.mk_iff_oeq(m_manager.mk_rewrite(r0, r));
pr = m_manager.mk_transitivity(p0, p1);
}
}
else {
r = m_manager.mk_and(new_args.size(), new_args.c_ptr());
if (m_manager.fine_grain_proofs() && n != r)
pr = m_manager.mk_oeq_congruence(n, r, new_arg_prs.size(), new_arg_prs.c_ptr());
}
cache_result(n, in_q, r, pr);
}
void cnf::reduce1_label(app * n, bool in_q) {
expr * r;
proof * pr = 0;
expr * new_arg;
proof * new_arg_pr;
get_cached(n->get_arg(0), true, new_arg, new_arg_pr);
if (in_q || m_params.m_cnf_mode == CNF_FULL) {
// TODO: in the current implementation, labels are removed during CNF translation.
// This is satisfactory for Boogie, since it does not use labels inside quantifiers,
// and we only need CNF_QUANT for Superposition Calculus.
r = new_arg;
if (m_manager.fine_grain_proofs()) {
proof * p0 = m_manager.mk_iff_oeq(m_manager.mk_rewrite(n, n->get_arg(0)));
pr = m_manager.mk_transitivity(p0, new_arg_pr);
}
}
else {
r = m_manager.mk_app(n->get_decl(), new_arg);
if (m_manager.fine_grain_proofs() && n != r)
pr = m_manager.mk_oeq_congruence(n, to_app(r), 1, &new_arg_pr);
}
cache_result(n, in_q, r, pr);
}
void cnf::reduce1_quantifier(quantifier * q, bool in_q) {
expr * new_expr;
proof * new_expr_pr;
get_cached(q->get_expr(), true, new_expr, new_expr_pr);
expr_ref r(m_manager);
proof_ref pr(m_manager);
if (m_manager.is_and(new_expr) && q->is_forall()) {
quantifier_ref q1(m_manager);
q1 = m_manager.update_quantifier(q, new_expr);
expr_ref q2(m_manager);
proof_ref p2(m_manager);
m_pull.pull_quant2(q1, q2, p2);
expr * q3;
proof * p3;
push_quant(to_quantifier(q2), q3, p3);
r = q3;
if (m_manager.fine_grain_proofs()) {
proof * p1 = q == q1 ? 0 : m_manager.mk_oeq_quant_intro(q, q1, new_expr_pr);
p2 = p2 == 0 ? 0 : m_manager.mk_iff_oeq(p2);
pr = m_manager.mk_transitivity(p1, p2, p3);
}
}
else if ((m_manager.is_or(new_expr) || is_forall(new_expr)) && q->is_forall()) {
quantifier_ref q1(m_manager);
q1 = m_manager.update_quantifier(q, new_expr);
m_pull.pull_quant2(q1, r, pr);
if (m_manager.fine_grain_proofs()) {
pr = pr == 0 ? 0 : m_manager.mk_iff_oeq(pr);
proof * p1 = q == q1 ? 0 : m_manager.mk_oeq_quant_intro(q, q1, new_expr_pr);
pr = m_manager.mk_transitivity(p1, pr);
}
}
else {
r = m_manager.update_quantifier(q, new_expr);
if (m_manager.fine_grain_proofs() && r != q)
pr = q == r ? 0 : m_manager.mk_oeq_quant_intro(q, to_quantifier(r), new_expr_pr);
}
cache_result(q, in_q, r, pr);
TRACE("cnf_quant", tout << mk_pp(q, m_manager) << "\n" << mk_pp(r, m_manager) << "\n";);
}
cnf::cnf(ast_manager & m, defined_names & n, cnf_params & params):
m_params(params),
m_manager(m),
m_defined_names(n),
m_pull(m),
m_cache(m),
m_todo_defs(m),
m_todo_proofs(m),
m_coarse_proofs(m) {
}
cnf::~cnf() {
}
void cnf::reduce(expr * n, expr_ref & r, proof_ref & pr) {
m_coarse_proofs.reset();
m_todo.reset();
m_todo.push_back(expr_bool_pair(n, false));
while (!m_todo.empty()) {
expr_bool_pair pair = m_todo.back();
expr * n = pair.first;
bool in_q = pair.second;
if (is_cached(n, in_q)) {
m_todo.pop_back();
}
else if (visit_children(n, in_q)) {
m_todo.pop_back();
reduce1(n, in_q);
}
}
expr * r2;
proof * pr2;
get_cached(n, false, r2, pr2);
r = r2;
switch (m_manager.proof_mode()) {
case PGM_DISABLED:
pr = m_manager.mk_undef_proof();
break;
case PGM_COARSE:
remove_duplicates(m_coarse_proofs);
pr = n == r2 ? m_manager.mk_reflexivity(n) : m_manager.mk_cnf_star(n, r2, m_coarse_proofs.size(), m_coarse_proofs.c_ptr());
break;
case PGM_FINE:
pr = pr2 == 0 ? m_manager.mk_reflexivity(n) : pr2;
break;
}
}
void cnf::operator()(expr * n, expr_ref_vector & new_defs, proof_ref_vector & new_def_proofs, expr_ref & r, proof_ref & pr) {
if (m_params.m_cnf_mode == CNF_DISABLED) {
r = n;
pr = m_manager.mk_reflexivity(n);
return;
}
reset();
reduce(n, r, pr);
for (unsigned i = 0; i < m_todo_defs.size(); i++) {
expr_ref dr(m_manager);
proof_ref dpr(m_manager);
reduce(m_todo_defs.get(i), dr, dpr);
m_result_defs.push_back(dr);
if (m_manager.proofs_enabled()) {
proof * new_pr = m_manager.mk_modus_ponens(m_todo_proofs.get(i), dpr);
m_result_def_proofs.push_back(new_pr);
}
else
m_result_def_proofs.push_back(m_manager.mk_undef_proof());
}
std::reverse(m_result_defs.begin(), m_result_defs.end());
new_defs.append(m_result_defs.size(), m_result_defs.c_ptr());
std::reverse(m_result_def_proofs.begin(), m_result_def_proofs.end());
new_def_proofs.append(m_result_def_proofs.size(), m_result_def_proofs.c_ptr());
}
void cnf::reset() {
m_cache.reset();
m_todo.reset();
m_todo_defs.reset();
m_todo_proofs.reset();
m_result_defs.reset();
m_result_def_proofs.reset();
}

View file

@ -1,121 +0,0 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
cnf.h
Abstract:
CNF translation
Author:
Leonardo de Moura (leonardo) 2008-01-17.
Revision History:
--*/
#ifndef _CNF_H_
#define _CNF_H_
#include"cnf_params.h"
#include"pull_quant.h"
#include"nnf.h"
#include"approx_nat.h"
/**
\brief Entry into the todo list of the CNF translator. It is also used as the key in the CNF cache.
*/
struct cnf_entry {
expr * m_node;
bool m_polarity:1;
bool m_in_q:1;
cnf_entry():m_node(0), m_polarity(false), m_in_q(false) {}
cnf_entry(expr * n, bool p, bool in_q):m_node(n), m_polarity(p), m_in_q(in_q) {}
unsigned hash() const;
bool operator==(cnf_entry const & k) const;
};
/**
\brief Cache for CNF transformation. It is a mapping from (expr, polarity, in_q) -> (expr, proof)
*/
class cnf_cache {
public:
typedef std::pair<expr *, proof *> expr_proof_pair;
typedef map<cnf_entry, expr_proof_pair, obj_hash<cnf_entry>, default_eq<cnf_entry> > cache;
ast_manager & m_manager;
cache m_cache;
public:
cnf_cache(ast_manager & m);
~cnf_cache() { reset(); }
void insert(cnf_entry const & k, expr * r, proof * pr);
bool contains(cnf_entry const & k) const { return m_cache.contains(k); }
void get(cnf_entry const & k, expr * & r, proof * & pr) const { expr_proof_pair tmp; m_cache.find(k, tmp); r = tmp.first; pr = tmp.second; }
void reset();
};
/**
\brief Functor for converting expressions into CNF. The functor can
optionally process subformulas nested in quantifiers. New names may be
introduced for subformulas that are too expensive to be put into CNF.
NNF translation must be applied before converting to CNF.
- To use CNF_QUANT, we must use at least NNF_QUANT
- To use CNF_OPPORTUNISTIC, we must use at least NNF_QUANT
- To use CNF_FULL, we must use NNF_FULL
*/
class cnf {
typedef std::pair<expr *, bool> expr_bool_pair;
cnf_params & m_params;
ast_manager & m_manager;
defined_names & m_defined_names;
pull_quant m_pull;
cnf_cache m_cache;
svector<expr_bool_pair> m_todo;
expr_ref_vector m_todo_defs;
proof_ref_vector m_todo_proofs;
ptr_vector<expr> m_result_defs;
ptr_vector<proof> m_result_def_proofs;
proof_ref_vector m_coarse_proofs;
void cache_result(expr * e, bool in_q, expr * r, proof * pr);
void get_cached(expr * n, bool in_q, expr * & r, proof * & pr) const { m_cache.get(cnf_entry(n, true, in_q), r, pr); }
bool is_cached(expr * n, bool in_q) const { return m_cache.contains(cnf_entry(n, true, in_q)); }
void visit(expr * n, bool in_q, bool & visited);
bool visit_children(expr * n, bool in_q);
void get_args(app * n, bool in_q, ptr_buffer<expr> & new_args, ptr_buffer<proof> & new_arg_prs);
void flat_args(func_decl * d, ptr_buffer<expr> const & args, ptr_buffer<expr> & flat_args);
approx_nat approx_result_size_for_disj(ptr_buffer<expr> const & args);
bool is_too_expensive(approx_nat approx_result_size, ptr_buffer<expr> const & args);
void name_args(ptr_buffer<expr> const & args, expr_ref_buffer & new_args, proof_ref_buffer & new_arg_prs);
void distribute(app * arg, app * & r, proof * & pr);
void push_quant(quantifier * q, expr * & r, proof * & pr);
void reduce1(expr * n, bool in_q);
void reduce1_or(app * n, bool in_q);
void reduce1_and(app * n, bool in_q);
void reduce1_label(app * n, bool in_q);
void reduce1_quantifier(quantifier * q, bool in_q);
void reduce(expr * n, expr_ref & r, proof_ref & pr);
public:
cnf(ast_manager & m, defined_names & n, cnf_params & params);
~cnf();
void operator()(expr * n, // [IN] expression that should be put into CNF
expr_ref_vector & new_defs, // [OUT] new definitions
proof_ref_vector & new_def_proofs, // [OUT] proofs of the new definitions
expr_ref & r, // [OUT] resultant expression
proof_ref & p // [OUT] proof for (~ n r)
);
void reset();
};
#endif /* _CNF_H_ */

View file

@ -18,6 +18,7 @@ Notes:
--*/
#include"nnf.h"
#include"nnf_params.hpp"
#include"warning.h"
#include"used_vars.h"
#include"well_sorted.h"
@ -29,6 +30,40 @@ Notes:
#include"ast_smt2_pp.h"
/**
\brief NNF translation mode. The cheapest mode is NNF_SKOLEM, and
the most expensive is NNF_FULL.
*/
enum nnf_mode {
NNF_SKOLEM, /* A subformula is put into NNF only if it contains
quantifiers or labels. The result of the
transformation will be in skolem normal form.
If a formula is too expensive to be put into NNF,
then nested quantifiers and labels are renamed.
This mode is sufficient when using E-matching.
*/
NNF_QUANT, /* A subformula is put into NNF if it contains
quantifiers, labels, or is in the scope of a
quantifier. The result of the transformation will be
in skolem normal form, and the body of quantifiers
will be in NNF. If a ground formula is too expensive to
be put into NNF, then nested quantifiers and labels
are renamed.
This mode is sufficient when using Superposition
Calculus.
Remark: If the problem does not contain quantifiers,
then NNF_QUANT is identical to NNF_SKOLEM.
*/
NNF_OPPORTUNISTIC, /* Similar to NNF_QUANT, but a subformula is
also put into NNF, if it is
cheap. Otherwise, the nested quantifiers and
labels are renamed. */
NNF_FULL /* Everything is put into NNF. */
};
class skolemizer {
typedef act_cache cache;
@ -112,20 +147,16 @@ class skolemizer {
}
public:
skolemizer(ast_manager & m, params_ref const & p):
skolemizer(ast_manager & m):
m_manager(m),
m_sk_hack("sk_hack"),
m_sk_hack_enabled(false),
m_cache(m),
m_cache_pr(m) {
updt_params(p);
}
void updt_params(params_ref const & p) {
m_sk_hack_enabled = p.get_bool(":nnf-sk-hack", false);
}
static void get_param_descrs(param_descrs & r) {
r.insert(":nnf-sk-hack", CPK_BOOL, "(default: false) hack for VCC");
void set_sk_hack(bool f) {
m_sk_hack_enabled = f;
}
ast_manager & m() const { return m_manager; }
@ -219,8 +250,6 @@ struct nnf::imp {
name_exprs * m_name_nested_formulas;
name_exprs * m_name_quant;
symbol m_skolem;
volatile bool m_cancel;
unsigned long long m_max_memory; // in bytes
@ -230,10 +259,9 @@ struct nnf::imp {
m_todo_defs(m),
m_todo_proofs(m),
m_result_pr_stack(m),
m_skolemizer(m, p),
m_skolem("skolem"),
m_skolemizer(m),
m_cancel(false) {
updt_local_params(p);
updt_params(p);
for (unsigned i = 0; i < 4; i++) {
m_cache[i] = alloc(act_cache, m);
if (m.proofs_enabled())
@ -257,14 +285,10 @@ struct nnf::imp {
del_name_exprs(m_name_quant);
}
void updt_params(params_ref const & p) {
updt_local_params(p);
m_skolemizer.updt_params(p);
}
void updt_local_params(params_ref const & p) {
symbol mode_sym = p.get_sym(":nnf-mode", m_skolem);
if (mode_sym == m_skolem)
void updt_params(params_ref const & _p) {
nnf_params p(_p);
symbol mode_sym = p.mode();
if (mode_sym == "skolem")
m_mode = NNF_SKOLEM;
else if (mode_sym == "full")
m_mode = NNF_FULL;
@ -272,23 +296,17 @@ struct nnf::imp {
m_mode = NNF_QUANT;
else
throw nnf_params_exception("invalid NNF mode");
TRACE("nnf", tout << "nnf-mode: " << m_mode << " " << mode_sym << "\n" << _p << "\n";);
TRACE("nnf", tout << "nnf-mode: " << m_mode << " " << mode_sym << "\n" << p << "\n";);
m_ignore_labels = p.get_bool(":nnf-ignore-labels", false);
m_skolemize = p.get_bool(":skolemize", true);
m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX));
m_ignore_labels = p.ignore_labels();
m_skolemize = p.skolemize();
m_max_memory = megabytes_to_bytes(p.max_memory());
m_skolemizer.set_sk_hack(p.sk_hack());
}
static void get_param_descrs(param_descrs & r) {
insert_max_memory(r);
r.insert(":nnf-mode", CPK_SYMBOL,
"(default: skolem) NNF translation mode: skolem (skolem normal form), quantifiers (skolem normal form + quantifiers in NNF), full");
r.insert(":nnf-ignore-labels", CPK_BOOL,
"(default: false) remove/ignore labels in the input formula, this option is ignored if proofs are enabled");
r.insert(":skolemize", CPK_BOOL,
"(default: true) skolemize (existential force) quantifiers");
skolemizer::get_param_descrs(r);
nnf_params::collect_param_descrs(r);
}
void reset() {
@ -880,21 +898,6 @@ nnf::nnf(ast_manager & m, defined_names & n, params_ref const & p) {
m_imp = alloc(imp, m, n, p);
}
nnf::nnf(ast_manager & m, defined_names & n, nnf_params & np) {
params_ref p;
if (np.m_nnf_mode == NNF_FULL)
p.set_sym(":nnf-mode", symbol("full"));
else if (np.m_nnf_mode == NNF_QUANT)
p.set_sym(":nnf-mode", symbol("quantifiers"));
if (np.m_nnf_ignore_labels)
p.set_bool(":nnf-ignore-labels", true);
if (np.m_nnf_sk_hack)
p.set_bool(":nnf-sk-hack", true);
m_imp = alloc(imp, m, n, p);
}
nnf::~nnf() {
dealloc(m_imp);
}

View file

@ -21,7 +21,6 @@ Notes:
#define _NNF_H_
#include"ast.h"
#include"nnf_params.h"
#include"params.h"
#include"defined_names.h"
@ -30,7 +29,6 @@ class nnf {
imp * m_imp;
public:
nnf(ast_manager & m, defined_names & n, params_ref const & p = params_ref());
nnf(ast_manager & m, defined_names & n, nnf_params & params); // for backward compatibility
~nnf();
void operator()(expr * n, // [IN] expression that should be put into NNF
@ -41,6 +39,9 @@ public:
);
void updt_params(params_ref const & p);
/*
REG_MODULE_PARAMS('nnf', 'nnf::get_param_descrs')
*/
static void get_param_descrs(param_descrs & r);
void cancel() { set_cancel(true); }

View file

@ -0,0 +1,9 @@
def_module_params('nnf',
description='negation normal form',
export=True,
params=(max_memory_param(),
('sk_hack', BOOL, False, 'hack for VCC'),
('mode', SYMBOL, 'skolem',
'NNF translation mode: skolem (skolem normal form), quantifiers (skolem normal form + quantifiers in NNF), full'),
('ignore_labels', BOOL, False, 'remove/ignore labels in the input formula, this option is ignored if proofs are enabled'),
('skolemize', BOOL, True, 'skolemize (existential force) quantifiers')))

View file

@ -36,7 +36,6 @@ Notes:
#include"ast_pp.h"
#include"cmd_context.h"
#include"smt2parser.h"
#include"front_end_params.h"
expr_pattern_match::expr_pattern_match(ast_manager & manager):
m_manager(manager), m_precompiled(manager) {
@ -388,8 +387,7 @@ expr_pattern_match::initialize(char const * spec_string) {
m_instrs.push_back(instr(BACKTRACK));
std::istringstream is(spec_string);
front_end_params p;
cmd_context ctx(&p, true, &m_manager);
cmd_context ctx(true, &m_manager);
VERIFY(parse_smt2_commands(ctx, is));
ptr_vector<expr>::const_iterator it = ctx.begin_assertions();

View file

@ -22,7 +22,6 @@ Notes:
#include"ast.h"
#include"map.h"
#include"front_end_params.h"
class expr_pattern_match {

View file

@ -0,0 +1,32 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
pattern_inference_params.h
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2012-12-02.
Revision History:
--*/
#include"pattern_inference_params.h"
#include"pattern_inference_params_helper.hpp"
void pattern_inference_params::updt_params(params_ref const & _p) {
pattern_inference_params_helper p(_p);
m_pi_max_multi_patterns = p.max_multi_patterns();
m_pi_block_loop_patterns = p.block_loop_patterns();
m_pi_arith = static_cast<arith_pattern_inference_kind>(p.arith());
m_pi_use_database = p.use_database();
m_pi_arith_weight = p.arith_weight();
m_pi_non_nested_arith_weight = p.non_nested_arith_weight();
m_pi_pull_quantifiers = p.pull_quantifiers();
m_pi_warnings = p.warnings();
}

View file

@ -0,0 +1,52 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
pattern_inference_params.h
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2008-03-24.
Revision History:
--*/
#ifndef _PATTERN_INFERENCE_PARAMS_H_
#define _PATTERN_INFERENCE_PARAMS_H_
#include"params.h"
enum arith_pattern_inference_kind {
AP_NO, // do not infer patterns with arithmetic terms
AP_CONSERVATIVE, // only infer patterns with arithmetic terms if there is no other option
AP_FULL // always use patterns with arithmetic terms
};
struct pattern_inference_params {
unsigned m_pi_max_multi_patterns;
bool m_pi_block_loop_patterns;
arith_pattern_inference_kind m_pi_arith;
bool m_pi_use_database;
unsigned m_pi_arith_weight;
unsigned m_pi_non_nested_arith_weight;
bool m_pi_pull_quantifiers;
int m_pi_nopat_weight;
bool m_pi_avoid_skolems;
bool m_pi_warnings;
pattern_inference_params(params_ref const & p = params_ref()):
m_pi_nopat_weight(-1),
m_pi_avoid_skolems(true) {
updt_params(p);
}
void updt_params(params_ref const & _p);
};
#endif /* _PATTERN_INFERENCE_PARAMS_H_ */

View file

@ -0,0 +1,12 @@
def_module_params(class_name='pattern_inference_params_helper',
module_name='pi',
description='pattern inference (heuristics) for universal formulas (without annotation)',
export=True,
params=(('max_multi_patterns', UINT, 0, 'when patterns are not provided, the prover uses a heuristic to infer them, this option sets the threshold on the number of extra multi-patterns that can be created; by default, the prover creates at most one multi-pattern when there is no unary pattern'),
('block_loop_patterns', BOOL, True, 'block looping patterns during pattern inference'),
('arith', UINT, 1, '0 - do not infer patterns with arithmetic terms, 1 - use patterns with arithmetic terms if there is no other pattern, 2 - always use patterns with arithmetic terms'),
('use_database', BOOL, True, 'use pattern database'),
('arith_weight', UINT, 5, 'default weight for quantifiers where the only available pattern has nested arithmetic terms'),
('non_nested_arith_weight', UINT, 10, 'default weight for quantifiers where the only available pattern has non nested arithmetic terms'),
('pull_quantifiers', BOOL, True, 'pull nested quantifiers, if no pattern was found'),
('warnings', BOOL, False, 'enable/disable warning messages in the pattern inference module')))

View file

@ -17,22 +17,9 @@ Revision History:
--*/
#include"pp.h"
#include"pp_params.hpp"
using namespace format_ns;
pp_params g_pp_params;
void set_pp_default_params(pp_params const & p) {
g_pp_params = p;
}
void register_pp_params(ini_params & p) {
g_pp_params.register_params(p);
}
pp_params const & get_pp_default_params() {
return g_pp_params;
}
static std::pair<unsigned, bool> space_upto_line_break(ast_manager & m, format * f) {
unsigned r;
SASSERT(f->get_family_id() == fm(m).get_family_id("format"));
@ -69,7 +56,15 @@ inline bool fits(ast_manager & m, format * f, unsigned space_left) {
return s <= space_left;
}
void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) {
void pp(std::ostream & out, format * f, ast_manager & m, params_ref const & _p) {
pp_params p(_p);
unsigned max_width = p.max_width();
unsigned max_ribbon = p.max_ribbon();
unsigned max_num_lines = p.max_num_lines();
unsigned max_indent = p.max_indent();
bool bounded = p.bounded();
bool single_line = p.single_line();
unsigned pos = 0;
unsigned ribbon_pos = 0;
unsigned line = 0;
@ -80,7 +75,7 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) {
todo.push_back(std::make_pair(f, 0));
app_ref space(mk_string(m, " "), fm(m));
while (!todo.empty()) {
if (line >= p.m_pp_max_num_lines)
if (line >= max_num_lines)
return;
std::pair<format *, unsigned> pair = todo.back();
format * f = pair.first;
@ -89,10 +84,10 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) {
SASSERT(f->get_family_id() == fm(m).get_family_id("format"));
switch (f->get_decl_kind()) {
case OP_STRING:
if (p.m_pp_bounded && pos > p.m_pp_max_width)
if (bounded && pos > max_width)
break;
len = static_cast<unsigned>(strlen(f->get_decl()->get_parameter(0).get_symbol().bare_str()));
if (p.m_pp_bounded && pos + len > p.m_pp_max_width) {
if (bounded && pos + len > max_width) {
out << "...";
break;
}
@ -103,7 +98,7 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) {
case OP_INDENT:
todo.push_back(std::make_pair(to_app(f->get_arg(0)),
std::min(indent + f->get_decl()->get_parameter(0).get_int(),
p.m_pp_max_indent)));
max_indent)));
break;
case OP_COMPOSE:
i = f->get_num_args();
@ -113,7 +108,7 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) {
}
break;
case OP_CHOICE:
space_left = std::min(p.m_pp_max_width - pos, p.m_pp_max_ribbon - pos);
space_left = std::min(max_width - pos, max_ribbon - pos);
if (space_left > 0 && fits(m, to_app(f->get_arg(0)), space_left))
todo.push_back(std::make_pair(to_app(f->get_arg(0)), indent));
else
@ -121,14 +116,14 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) {
break;
case OP_LINE_BREAK:
case OP_LINE_BREAK_EXT:
if (p.m_pp_single_line) {
if (single_line) {
todo.push_back(std::make_pair(space, indent));
break;
}
pos = indent;
ribbon_pos = 0;
line++;
if (line < p.m_pp_max_num_lines) {
if (line < max_num_lines) {
out << "\n";
for (unsigned i = 0; i < indent; i++)
out << " ";
@ -142,7 +137,3 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) {
}
}
void pp(std::ostream & out, format_ns::format * f, ast_manager & m) {
pp(out, f, m, g_pp_params);
}

View file

@ -20,15 +20,9 @@ Revision History:
#define _PP_H_
#include"format.h"
#include"pp_params.h"
#include"params.h"
void set_pp_default_params(pp_params const & p);
void register_pp_params(ini_params & p);
pp_params const & get_pp_default_params();
void pp(std::ostream & out, format_ns::format * f, ast_manager & m, pp_params const & p);
void pp(std::ostream & out, format_ns::format * f, ast_manager & m);
void pp(std::ostream & out, format_ns::format * f, ast_manager & m, params_ref const & p = params_ref());
#endif /* _PP_H_ */

View file

@ -1,57 +0,0 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
pp_params.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2008-01-20.
Revision History:
--*/
#include"pp_params.h"
pp_params::pp_params():
m_pp_max_indent(UINT_MAX),
m_pp_max_num_lines(UINT_MAX),
m_pp_max_width(80),
m_pp_max_ribbon(80),
m_pp_max_depth(5),
m_pp_min_alias_size(10),
m_pp_decimal(false),
m_pp_decimal_precision(10),
m_pp_bv_lits(true),
m_pp_bv_neg(false),
m_pp_flat_assoc(true),
m_pp_fixed_indent(false),
m_pp_single_line(false),
m_pp_bounded(false),
m_pp_simplify_implies(false) {
}
void pp_params::register_params(ini_params & p) {
p.register_unsigned_param("PP_MAX_INDENT", m_pp_max_indent, "max. indentation in pretty printer", true);
p.register_unsigned_param("PP_MAX_NUM_LINES", m_pp_max_num_lines, "max. number of lines to be displayed in pretty printer", true);
p.register_unsigned_param("PP_MAX_WIDTH", m_pp_max_width, "max. width in pretty printer", true);
p.register_unsigned_param("PP_MAX_RIBBON", m_pp_max_ribbon, "max. ribbon (width - indentation) in pretty printer", true);
p.register_unsigned_param("PP_MAX_DEPTH", m_pp_max_depth, "max. term depth (when pretty printing SMT2 terms/formulas)", true);
p.register_unsigned_param("PP_MIN_ALIAS_SIZE", m_pp_min_alias_size, "min. size for creating an alias for a shared term (when pretty printing SMT2 terms/formulas)", true);
p.register_bool_param("PP_DECIMAL", m_pp_decimal, "pretty print real numbers using decimal notation (the output may be truncated). Z3 adds a '?' if the value is not precise", true);
p.register_unsigned_param("PP_DECIMAL_PRECISION", m_pp_decimal_precision, "maximum number of decimal places to be used when PP_DECIMAL=true", true);
p.register_bool_param("PP_BV_LITERALS", m_pp_bv_lits, "use Bit-Vector literals (e.g, #x0F and #b0101) during pretty printing", true);
p.register_bool_param("PP_BV_NEG", m_pp_bv_neg, "use bvneg when displaying Bit-Vector literals where the most significant bit is 1", true);
p.register_bool_param("PP_FLAT_ASSOC", m_pp_flat_assoc, "flat associative operators (when pretty printing SMT2 terms/formulas)", true);
p.register_bool_param("PP_FIXED_INDENT", m_pp_fixed_indent, "use a fixed indentation for applications", true);
p.register_bool_param("PP_SINGLE_LINE", m_pp_single_line, "ignore line breaks when true", true);
p.register_bool_param("PP_BOUNDED", m_pp_bounded, "ignore characters exceeding max widht", true);
p.register_bool_param("PP_SIMPLIFY_IMPLIES", m_pp_simplify_implies, "simplify nested implications for pretty printing", true);
}

View file

@ -1,46 +0,0 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
pp_params.h
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2008-01-20.
Revision History:
--*/
#ifndef _PP_PARAMS_H_
#define _PP_PARAMS_H_
#include"ini_file.h"
struct pp_params {
unsigned m_pp_max_indent; // max. indentation
unsigned m_pp_max_num_lines; // max. num. lines
unsigned m_pp_max_width; // max. width
unsigned m_pp_max_ribbon; // max. ribbon: width - indentation
unsigned m_pp_max_depth;
unsigned m_pp_min_alias_size;
bool m_pp_decimal; // display reals using decimals
unsigned m_pp_decimal_precision; // max. number of decimal places
bool m_pp_bv_lits;
bool m_pp_bv_neg; // use bvneg to display bit-vector literals which the most significant bit is 1
bool m_pp_flat_assoc;
bool m_pp_fixed_indent;
bool m_pp_single_line; // ignore line breaks if true
bool m_pp_bounded; // ignore characters exceeding max width.
bool m_pp_simplify_implies; // simplify nested implications during pretty printing
pp_params();
void register_params(ini_params & p);
};
#endif /* _PP_PARAMS_H_ */

18
src/ast/pp_params.pyg Normal file
View file

@ -0,0 +1,18 @@
def_module_params('pp',
export=True,
description='pretty printer',
params=(('max_indent', UINT, UINT_MAX, 'max. indentation in pretty printer'),
('max_num_lines', UINT, UINT_MAX, 'max. number of lines to be displayed in pretty printer'),
('max_width', UINT, 80, 'max. width in pretty printer'),
('max_ribbon', UINT, 80, 'max. ribbon (width - indentation) in pretty printer'),
('max_depth', UINT, 5, 'max. term depth (when pretty printing SMT2 terms/formulas)'),
('min_alias_size', UINT, 10, 'min. size for creating an alias for a shared term (when pretty printing SMT2 terms/formulas)'),
('decimal', BOOL, False, 'pretty print real numbers using decimal notation (the output may be truncated). Z3 adds a ? if the value is not precise'),
('decimal_precision', UINT, 10, 'maximum number of decimal places to be used when pp.decimal=true'),
('bv_literals', BOOL, True, 'use Bit-Vector literals (e.g, #x0F and #b0101) during pretty printing'),
('bv_neg', BOOL, False, 'use bvneg when displaying Bit-Vector literals where the most significant bit is 1'),
('flat_assoc', BOOL, True, 'flat associative operators (when pretty printing SMT2 terms/formulas)'),
('fixed_indent', BOOL, False, 'use a fixed indentation for applications'),
('single_line', BOOL, False, 'ignore line breaks when true'),
('bounded', BOOL, False, 'ignore characters exceeding max widht'),
('simplify_implies', BOOL, True, 'simplify nested implications for pretty printing')))

View file

@ -4,7 +4,6 @@
// include "spc_decl_plugin.h"
#include "ast_smt_pp.h"
#include "arith_decl_plugin.h"
#include "front_end_params.h"
#include "th_rewriter.h"
#include "var_subst.h"

View file

@ -17,23 +17,25 @@ Notes:
--*/
#include"arith_rewriter.h"
#include"arith_rewriter_params.hpp"
#include"poly_rewriter_def.h"
#include"algebraic_numbers.h"
#include"ast_pp.h"
void arith_rewriter::updt_local_params(params_ref const & p) {
m_arith_lhs = p.get_bool(":arith-lhs", false);
m_gcd_rounding = p.get_bool(":gcd-rounding", false);
m_eq2ineq = p.get_bool(":eq2ineq", false);
m_elim_to_real = p.get_bool(":elim-to-real", false);
m_push_to_real = p.get_bool(":push-to-real", true);
m_anum_simp = p.get_bool(":algebraic-number-evaluator", true);
m_max_degree = p.get_uint(":max-degree", 64);
m_expand_power = p.get_bool(":expand-power", false);
m_mul2power = p.get_bool(":mul-to-power", false);
m_elim_rem = p.get_bool(":elim-rem", false);
m_expand_tan = p.get_bool(":expand-tan", false);
set_sort_sums(p.get_bool(":sort-sums", false)); // set here to avoid collision with bvadd
void arith_rewriter::updt_local_params(params_ref const & _p) {
arith_rewriter_params p(_p);
m_arith_lhs = p.arith_lhs();
m_gcd_rounding = p.gcd_rounding();
m_eq2ineq = p.eq2ineq();
m_elim_to_real = p.elim_to_real();
m_push_to_real = p.push_to_real();
m_anum_simp = p.algebraic_number_evaluator();
m_max_degree = p.max_degree();
m_expand_power = p.expand_power();
m_mul2power = p.mul_to_power();
m_elim_rem = p.elim_rem();
m_expand_tan = p.expand_tan();
set_sort_sums(p.sort_sums());
}
void arith_rewriter::updt_params(params_ref const & p) {
@ -43,18 +45,7 @@ void arith_rewriter::updt_params(params_ref const & p) {
void arith_rewriter::get_param_descrs(param_descrs & r) {
poly_rewriter<arith_rewriter_core>::get_param_descrs(r);
r.insert(":algebraic-number-evaluator", CPK_BOOL, "(default: true) simplify/evaluate expressions containing (algebraic) irrational numbers.");
r.insert(":mul-to-power", CPK_BOOL, "(default: false) collpase (* t ... t) into (^ t k), it is ignored if :expand-power is true.");
r.insert(":expand-power", CPK_BOOL, "(default: false) expand (^ t k) into (* t ... t) if 1 < k <= :max-degree.");
r.insert(":expand-tan", CPK_BOOL, "(default: false) replace (tan x) with (/ (sin x) (cos x)).");
r.insert(":max-degree", CPK_UINT, "(default: 64) max degree of algebraic numbers (and power operators) processed by simplifier.");
r.insert(":eq2ineq", CPK_BOOL, "(default: false) split arithmetic equalities into two inequalities.");
r.insert(":sort-sums", CPK_BOOL, "(default: false) sort the arguments of + application.");
r.insert(":gcd-rounding", CPK_BOOL, "(default: false) use gcd rounding on integer arithmetic atoms.");
r.insert(":arith-lhs", CPK_BOOL, "(default: false) all monomials are moved to the left-hand-side, and the right-hand-side is just a constant.");
r.insert(":elim-to-real", CPK_BOOL, "(default: false) eliminate to_real from arithmetic predicates that contain only integers.");
r.insert(":push-to-real", CPK_BOOL, "(default: true) distribute to_real over * and +.");
r.insert(":elim-rem", CPK_BOOL, "(default: false) replace (rem x y) with (ite (>= y 0) (mod x y) (- (mod x y))).");
arith_rewriter_params::collect_param_descrs(r);
}
br_status arith_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) {

View file

@ -0,0 +1,15 @@
def_module_params(module_name='rewriter',
class_name='arith_rewriter_params',
export=True,
params=(("algebraic_number_evaluator", BOOL, True, "simplify/evaluate expressions containing (algebraic) irrational numbers."),
("mul_to_power", BOOL, False, "collpase (* t ... t) into (^ t k), it is ignored if expand_power is true."),
("expand_power", BOOL, False, "expand (^ t k) into (* t ... t) if 1 < k <= max_degree."),
("expand_tan", BOOL, False, "replace (tan x) with (/ (sin x) (cos x))."),
("max_degree", UINT, 64, "max degree of algebraic numbers (and power operators) processed by simplifier."),
("eq2ineq", BOOL, False, "split arithmetic equalities into two inequalities."),
("sort_sums", BOOL, False, "sort the arguments of + application."),
("gcd_rounding", BOOL, False, "use gcd rounding on integer arithmetic atoms."),
("arith_lhs", BOOL, False, "all monomials are moved to the left-hand-side, and the right-hand-side is just a constant."),
("elim_to_real", BOOL, False, "eliminate to_real from arithmetic predicates that contain only integers."),
("push_to_real", BOOL, True, "distribute to_real over * and +."),
("elim_rem", BOOL, False, "replace (rem x y) with (ite (>= y 0) (mod x y) (- (mod x y))).")))

View file

@ -17,17 +17,18 @@ Notes:
--*/
#include"array_rewriter.h"
#include"array_rewriter_params.hpp"
#include"ast_lt.h"
#include"ast_pp.h"
void array_rewriter::updt_params(params_ref const & p) {
m_sort_store = p.get_bool(":sort-store", false);
m_expand_select_store = p.get_bool(":expand-select-store", false);
void array_rewriter::updt_params(params_ref const & _p) {
array_rewriter_params p(_p);
m_sort_store = p.sort_store();
m_expand_select_store = p.expand_select_store();
}
void array_rewriter::get_param_descrs(param_descrs & r) {
r.insert(":expand-select-store", CPK_BOOL, "(default: false) replace a (select (store ...) ...) term by an if-then-else term.");
r.insert(":sort-store", CPK_BOOL, "(default: false) sort nested stores when the indices are known to be different.");
array_rewriter_params::collect_param_descrs(r);
}
br_status array_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) {

View file

@ -0,0 +1,5 @@
def_module_params(module_name='rewriter',
class_name='array_rewriter_params',
export=True,
params=(("expand_select_store", BOOL, False, "replace a (select (store ...) ...) term by an if-then-else term"),
("sort_store", BOOL, False, "sort nested stores when the indices are known to be different")))

View file

@ -0,0 +1,38 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
bit_blaster_params.h
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2008-10-02.
Revision History:
--*/
#ifndef _BIT_BLASTER_PARAMS_H_
#define _BIT_BLASTER_PARAMS_H_
struct bit_blaster_params {
bool m_bb_ext_gates;
bool m_bb_quantifiers;
bit_blaster_params():
m_bb_ext_gates(false),
m_bb_quantifiers(false) {
}
#if 0
void register_params(ini_params & p) {
p.register_bool_param("bb_ext_gates", m_bb_ext_gates, "use extended gates during bit-blasting");
p.register_bool_param("bb_quantifiers", m_bb_quantifiers, "convert bit-vectors to Booleans in quantifiers");
}
#endif
};
#endif /* _BIT_BLASTER_PARAMS_H_ */

View file

@ -125,12 +125,12 @@ struct blaster_rewriter_cfg : public default_rewriter_cfg {
}
void updt_params(params_ref const & p) {
m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX));
m_max_steps = p.get_uint(":max-steps", UINT_MAX);
m_blast_add = p.get_bool(":blast-add", true);
m_blast_mul = p.get_bool(":blast-mul", true);
m_blast_full = p.get_bool(":blast-full", false);
m_blast_quant = p.get_bool(":blast-quant", false);
m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX));
m_max_steps = p.get_uint("max_steps", UINT_MAX);
m_blast_add = p.get_bool("blast_add", true);
m_blast_mul = p.get_bool("blast_mul", true);
m_blast_full = p.get_bool("blast_full", false);
m_blast_quant = p.get_bool("blast_quant", false);
m_blaster.set_max_memory(m_max_memory);
}

View file

@ -17,24 +17,21 @@ Notes:
--*/
#include"bool_rewriter.h"
#include"bool_rewriter_params.hpp"
#include"rewriter_def.h"
void bool_rewriter::updt_params(params_ref const & p) {
m_flat = p.get_bool(":flat", true);
m_elim_and = p.get_bool(":elim-and", false);
m_local_ctx = p.get_bool(":local-ctx", false);
m_local_ctx_limit = p.get_uint(":local-ctx-limit", UINT_MAX);
m_blast_distinct = p.get_bool(":blast-distinct", false);
m_ite_extra_rules = p.get_bool(":ite-extra-rules", false);
void bool_rewriter::updt_params(params_ref const & _p) {
bool_rewriter_params p(_p);
m_flat = p.flat();
m_elim_and = p.elim_and();
m_local_ctx = p.local_ctx();
m_local_ctx_limit = p.local_ctx_limit();
m_blast_distinct = p.blast_distinct();
m_ite_extra_rules = p.ite_extra_rules();
}
void bool_rewriter::get_param_descrs(param_descrs & r) {
r.insert(":ite-extra-rules", CPK_BOOL, "(default: false) extra ite simplifications, these additional simplifications may reduce size locally but increase globally.");
r.insert(":flat", CPK_BOOL, "(default: true) create nary applications for and,or,+,*,bvadd,bvmul,bvand,bvor,bvxor.");
r.insert(":elim-and", CPK_BOOL, "(default: false) conjunctions are rewritten using negation and disjunctions.");
r.insert(":local-ctx", CPK_BOOL, "(default: false) perform local (i.e., cheap) context simplifications.");
r.insert(":local-ctx-limit", CPK_UINT, "(default: inf) limit for applying local context simplifier.");
r.insert(":blast-distinct", CPK_BOOL, "(default: false) expand a distinct predicate into a quadratic number of disequalities.");
bool_rewriter_params::collect_param_descrs(r);
}
br_status bool_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) {

View file

@ -0,0 +1,9 @@
def_module_params(module_name='rewriter',
class_name='bool_rewriter_params',
export=True,
params=(("ite_extra_rules", BOOL, False, "extra ite simplifications, these additional simplifications may reduce size locally but increase globally"),
("flat", BOOL, True, "create nary applications for and,or,+,*,bvadd,bvmul,bvand,bvor,bvxor"),
("elim_and", BOOL, False, "conjunctions are rewritten using negation and disjunctions"),
("local_ctx", BOOL, False, "perform local (i.e., cheap) context simplifications"),
("local_ctx_limit", UINT, UINT_MAX, "limit for applying local context simplifier"),
("blast_distinct", BOOL, False, "expand a distinct predicate into a quadratic number of disequalities")))

View file

@ -17,6 +17,7 @@ Notes:
--*/
#include"bv_rewriter.h"
#include"bv_rewriter_params.hpp"
#include"poly_rewriter_def.h"
#include"ast_smt2_pp.h"
@ -53,15 +54,16 @@ app * mk_extract_proc::operator()(unsigned high, unsigned low, expr * arg) {
return r;
}
void bv_rewriter::updt_local_params(params_ref const & p) {
m_hi_div0 = p.get_bool(":hi-div0", true);
m_elim_sign_ext = p.get_bool(":elim-sign-ext", true);
m_mul2concat = p.get_bool(":mul2concat", false);
m_bit2bool = p.get_bool(":bit2bool", true);
m_blast_eq_value = p.get_bool(":blast-eq-value", false);
m_mkbv2num = p.get_bool(":mkbv2num", false);
m_split_concat_eq = p.get_bool(":split-concat-eq", false);
m_udiv2mul = p.get_bool(":udiv2mul", false);
void bv_rewriter::updt_local_params(params_ref const & _p) {
bv_rewriter_params p(_p);
m_hi_div0 = p.hi_div0();
m_elim_sign_ext = p.elim_sign_ext();
m_mul2concat = p.mul2concat();
m_bit2bool = p.bit2bool();
m_blast_eq_value = p.blast_eq_value();
m_split_concat_eq = p.split_concat_eq();
m_udiv2mul = p.udiv2mul();
m_mkbv2num = _p.get_bool("mkbv2num", false);
}
void bv_rewriter::updt_params(params_ref const & p) {
@ -71,15 +73,9 @@ void bv_rewriter::updt_params(params_ref const & p) {
void bv_rewriter::get_param_descrs(param_descrs & r) {
poly_rewriter<bv_rewriter_core>::get_param_descrs(r);
r.insert(":udiv2mul", CPK_BOOL, "(default: false) convert constant udiv to mul.");
r.insert(":split-concat-eq", CPK_BOOL, "(default: false) split equalities of the form (= (concat t1 t2) t3).");
r.insert(":bit2bool", CPK_BOOL, "(default: true) try to convert bit-vector terms of size 1 into Boolean terms.");
r.insert(":blast-eq-value", CPK_BOOL, "(default: false) blast (some) Bit-vector equalities into bits.");
r.insert(":elim-sign-ext", CPK_BOOL, "(default: true) expand sign-ext operator using concat and extract.");
r.insert(":hi-div0", CPK_BOOL, "(default: true) use the 'hardware interpretation' for division by zero (for bit-vector terms).");
r.insert(":mul2concat", CPK_BOOL, "(default: false) replace multiplication by a power of two into a concatenation.");
bv_rewriter_params::collect_param_descrs(r);
#ifndef _EXTERNAL_RELEASE
r.insert(":mkbv2num", CPK_BOOL, "(default: false) convert (mkbv [true/false]*) into a numeral");
r.insert("mkbv2num", CPK_BOOL, "(default: false) convert (mkbv [true/false]*) into a numeral");
#endif
}

View file

@ -0,0 +1,10 @@
def_module_params(module_name='rewriter',
class_name='bv_rewriter_params',
export=True,
params=(("udiv2mul", BOOL, False, "convert constant udiv to mul"),
("split_concat_eq", BOOL, False, "split equalities of the form (= (concat t1 t2) t3)"),
("bit2bool", BOOL, True, "try to convert bit-vector terms of size 1 into Boolean terms"),
("blast_eq_value", BOOL, False, "blast (some) Bit-vector equalities into bits"),
("elim_sign_ext", BOOL, True, "expand sign-ext operator using concat and extract"),
("hi_div0", BOOL, True, "use the 'hardware interpretation' for division by zero (for bit-vector terms)"),
("mul2concat", BOOL, False, "replace multiplication by a power of two into a concatenation")))

View file

@ -59,6 +59,7 @@ br_status float_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * c
case OP_FLOAT_IS_NZERO: SASSERT(num_args == 1); st = mk_is_nzero(args[0], result); break;
case OP_FLOAT_IS_PZERO: SASSERT(num_args == 1); st = mk_is_pzero(args[0], result); break;
case OP_FLOAT_IS_SIGN_MINUS: SASSERT(num_args == 1); st = mk_is_sign_minus(args[0], result); break;
case OP_TO_IEEE_BV: SASSERT(num_args == 1); st = mk_to_ieee_bv(args[0], result); break;
}
return st;
}
@ -439,3 +440,7 @@ br_status float_rewriter::mk_eq_core(expr * arg1, expr * arg2, expr_ref & result
return BR_FAILED;
}
br_status float_rewriter::mk_to_ieee_bv(expr * arg1, expr_ref & result) {
return BR_FAILED;
}

View file

@ -67,6 +67,8 @@ public:
br_status mk_is_nzero(expr * arg1, expr_ref & result);
br_status mk_is_pzero(expr * arg1, expr_ref & result);
br_status mk_is_sign_minus(expr * arg1, expr_ref & result);
br_status mk_to_ieee_bv(expr * arg1, expr_ref & result);
};
#endif

View file

@ -17,6 +17,7 @@ Notes:
--*/
#include"poly_rewriter.h"
#include"poly_rewriter_params.hpp"
#include"ast_lt.h"
#include"ast_ll_pp.h"
#include"ast_smt2_pp.h"
@ -26,20 +27,18 @@ char const * poly_rewriter<Config>::g_ste_blowup_msg = "sum of monomials blowup"
template<typename Config>
void poly_rewriter<Config>::updt_params(params_ref const & p) {
m_flat = p.get_bool(":flat", true);
m_som = p.get_bool(":som", false);
m_hoist_mul = p.get_bool(":hoist-mul", false);
m_hoist_cmul = p.get_bool(":hoist-cmul", false);
m_som_blowup = p.get_uint(":som-blowup", UINT_MAX);
void poly_rewriter<Config>::updt_params(params_ref const & _p) {
poly_rewriter_params p(_p);
m_flat = p.flat();
m_som = p.som();
m_hoist_mul = p.hoist_mul();
m_hoist_cmul = p.hoist_cmul();
m_som_blowup = p.som_blowup();
}
template<typename Config>
void poly_rewriter<Config>::get_param_descrs(param_descrs & r) {
r.insert(":som", CPK_BOOL, "(default: false) put polynomials in som-of-monomials form.");
r.insert(":som-blowup", CPK_UINT, "(default: infty) maximum number of monomials generated when putting a polynomial in sum-of-monomials normal form");
r.insert(":hoist-mul", CPK_BOOL, "(default: false) hoist multiplication over summation to minimize number of multiplications");
r.insert(":hoist-cmul", CPK_BOOL, "(default: false) hoist constant multiplication over summation to minimize number of multiplications");
poly_rewriter_params::collect_param_descrs(r);
}
template<typename Config>

View file

@ -0,0 +1,8 @@
def_module_params(module_name='rewriter',
class_name='poly_rewriter_params',
export=True,
params=(("som", BOOL, False, "put polynomials in som-of-monomials form"),
("som_blowup", UINT, UINT_MAX, "maximum number of monomials generated when putting a polynomial in sum-of-monomials normal form"),
("hoist_mul", BOOL, False, "hoist multiplication over summation to minimize number of multiplications"),
("hoist_cmul", BOOL, False, "hoist constant multiplication over summation to minimize number of multiplications"),
("flat", BOOL, True, "create nary applications for and,or,+,*,bvadd,bvmul,bvand,bvor,bvxor")))

View file

@ -0,0 +1,11 @@
def_module_params('rewriter',
description='new formula simplification module used in the tactic framework, and new solvers',
export=True,
params=(max_memory_param(),
max_steps_param(),
("flat", BOOL, True, "create nary applications for and,or,+,*,bvadd,bvmul,bvand,bvor,bvxor"),
("push_ite_arith", BOOL, False, "push if-then-else over arithmetic terms."),
("push_ite_bv", BOOL, False, "push if-then-else over bit-vector terms."),
("pull_cheap_ite", BOOL, False, "pull if-then-else terms when cheap."),
("cache_all", BOOL, False, "cache all intermediate results.")))

View file

@ -17,6 +17,7 @@ Notes:
--*/
#include"th_rewriter.h"
#include"rewriter_params.hpp"
#include"bool_rewriter.h"
#include"arith_rewriter.h"
#include"bv_rewriter.h"
@ -56,14 +57,15 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
ast_manager & m() const { return m_b_rw.m(); }
void updt_local_params(params_ref const & p) {
m_flat = p.get_bool(":flat", true);
m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX));
m_max_steps = p.get_uint(":max-steps", UINT_MAX);
m_pull_cheap_ite = p.get_bool(":pull-cheap-ite", false);
m_cache_all = p.get_bool(":cache-all", false);
m_push_ite_arith = p.get_bool(":push-ite-arith", false);
m_push_ite_bv = p.get_bool(":push-ite-bv", false);
void updt_local_params(params_ref const & _p) {
rewriter_params p(_p);
m_flat = p.flat();
m_max_memory = megabytes_to_bytes(p.max_memory());
m_max_steps = p.max_steps();
m_pull_cheap_ite = p.pull_cheap_ite();
m_cache_all = p.cache_all();
m_push_ite_arith = p.push_ite_arith();
m_push_ite_bv = p.push_ite_bv();
}
void updt_params(params_ref const & p) {
@ -481,10 +483,13 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
f = to_app(t1)->get_decl();
return unify_core(to_app(t1), t2, new_t1, new_t2, c, first);
}
else {
else if (is_arith_bv_app(t2)) {
f = to_app(t2)->get_decl();
return unify_core(to_app(t2), t1, new_t2, new_t1, c, first);
}
else {
return false;
}
}
// Apply transformations of the form
@ -693,12 +698,7 @@ void th_rewriter::get_param_descrs(param_descrs & r) {
arith_rewriter::get_param_descrs(r);
bv_rewriter::get_param_descrs(r);
array_rewriter::get_param_descrs(r);
insert_max_memory(r);
insert_max_steps(r);
r.insert(":push-ite-arith", CPK_BOOL, "(default: false) push if-then-else over arithmetic terms.");
r.insert(":push-ite-bv", CPK_BOOL, "(default: false) push if-then-else over bit-vector terms.");
r.insert(":pull-cheap-ite", CPK_BOOL, "(default: false) pull if-then-else terms when cheap.");
r.insert(":cache-all", CPK_BOOL, "(default: false) cache all intermediate results.");
rewriter_params::collect_param_descrs(r);
}
th_rewriter::~th_rewriter() {

View file

@ -37,7 +37,6 @@ public:
void updt_params(params_ref const & p);
static void get_param_descrs(param_descrs & r);
unsigned get_cache_size() const;
unsigned get_num_steps() const;

View file

@ -0,0 +1,26 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
arith_simplifier_params.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2012-12-02.
Revision History:
--*/
#include"arith_simplifier_params.h"
#include"arith_simplifier_params_helper.hpp"
void arith_simplifier_params::updt_params(params_ref const & _p) {
arith_simplifier_params_helper p(_p);
m_arith_expand_eqs = p.arith_expand_eqs();
m_arith_process_all_eqs = p.arith_process_all_eqs();
}

View file

@ -0,0 +1,36 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
arith_simplifier_params.h
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2008-05-09.
Revision History:
--*/
#ifndef _ARITH_SIMPLIFIER_PARAMS_H_
#define _ARITH_SIMPLIFIER_PARAMS_H_
#include"params.h"
struct arith_simplifier_params {
bool m_arith_expand_eqs;
bool m_arith_process_all_eqs;
arith_simplifier_params(params_ref const & p = params_ref()) {
updt_params(p);
}
void updt_params(params_ref const & _p);
};
#endif /* _ARITH_SIMPLIFIER_PARAMS_H_ */

View file

@ -0,0 +1,7 @@
def_module_params(class_name='arith_simplifier_params_helper',
module_name="old_simplify", # Parameters will be in the old_simplify module
description="old simplification (stack) still used in the smt module",
export=True,
params=(
('arith.expand_eqs', BOOL, False, 'expand equalities into two inequalities'),
('arith.process_all_eqs', BOOL, False, 'put all equations in the form (= t c), where c is a numeral')))

View file

@ -0,0 +1,26 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
array_simplifier_params.cpp
Abstract:
This file was created during code reorg.
Author:
Leonardo de Moura (leonardo) 2012-12-02.
Revision History:
--*/
#include"array_simplifier_params.h"
#include"array_simplifier_params_helper.hpp"
void array_simplifier_params::updt_params(params_ref const & _p) {
array_simplifier_params_helper p(_p);
m_array_canonize_simplify = p.array_canonize();
m_array_simplify = p.array_simplify();
}

View file

@ -0,0 +1,36 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
array_simplifier_params.h
Abstract:
This file was created during code reorg.
Author:
Leonardo de Moura (leonardo) 2012-12-02.
Revision History:
--*/
#ifndef _ARRAY_SIMPLIFIER_PARAMS_H_
#define _ARRAY_SIMPLIFIER_PARAMS_H_
#include"params.h"
struct array_simplifier_params {
bool m_array_canonize_simplify;
bool m_array_simplify; // temporary hack for disabling array simplifier plugin.
array_simplifier_params(params_ref const & p = params_ref()) {
updt_params(p);
}
void updt_params(params_ref const & _p);
};
#endif /* _ARITH_SIMPLIFIER_PARAMS_H_ */

View file

@ -0,0 +1,6 @@
def_module_params(class_name='array_simplifier_params_helper',
module_name="old_simplify", # Parameters will be in the old_simplify module
export=True,
params=(
('array.canonize', BOOL, False, 'normalize array terms into normal form during simplification'),
('array.simplify', BOOL, True, 'enable/disable array simplifications')))

View file

@ -33,7 +33,7 @@ array_simplifier_plugin::array_simplifier_plugin(
ast_manager & m,
basic_simplifier_plugin& s,
simplifier& simp,
theory_array_params const& p) :
array_simplifier_params const& p) :
simplifier_plugin(symbol("array"),m),
m_util(m),
m_simp(s),

View file

@ -24,7 +24,7 @@ Revision History:
#include"array_decl_plugin.h"
#include"simplifier_plugin.h"
#include"basic_simplifier_plugin.h"
#include"theory_array_params.h"
#include"array_simplifier_params.h"
#include"simplifier.h"
#include"obj_hashtable.h"
#include"lbool.h"
@ -71,7 +71,7 @@ class array_simplifier_plugin : public simplifier_plugin {
array_util m_util;
basic_simplifier_plugin& m_simp;
simplifier& m_simplifier;
theory_array_params const& m_params;
array_simplifier_params const& m_params;
select_cache m_select_cache;
ptr_vector<expr> m_tmp;
ptr_vector<expr> m_tmp2;
@ -100,7 +100,7 @@ class array_simplifier_plugin : public simplifier_plugin {
public:
array_simplifier_plugin(ast_manager & m, basic_simplifier_plugin& s, simplifier& simp, theory_array_params const& p);
array_simplifier_plugin(ast_manager & m, basic_simplifier_plugin& s, simplifier& simp, array_simplifier_params const& p);
virtual ~array_simplifier_plugin();
virtual bool reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result);

View file

@ -0,0 +1,26 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
bv_simplifier_params.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2012-12-02.
Revision History:
--*/
#include"bv_simplifier_params.h"
#include"bv_simplifier_params_helper.hpp"
void bv_simplifier_params::updt_params(params_ref const & _p) {
bv_simplifier_params_helper p(_p);
m_hi_div0 = p.bv_hi_div0();
m_bv2int_distribute = p.bv_bv2int_distribute();
}

View file

@ -0,0 +1,36 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
bv_simplifier_params.h
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2008-10-10.
Revision History:
--*/
#ifndef _BV_SIMPLIFIER_PARAMS_H_
#define _BV_SIMPLIFIER_PARAMS_H_
#include"params.h"
struct bv_simplifier_params {
bool m_hi_div0; //!< if true, uses the hardware interpretation for div0, mod0, ... if false, div0, mod0, ... are considered uninterpreted.
bool m_bv2int_distribute; //!< if true allows downward propagation of bv2int.
bv_simplifier_params(params_ref const & p = params_ref()) {
updt_params(p);
}
void updt_params(params_ref const & _p);
};
#endif /* _BV_SIMPLIFIER_PARAMS_H_ */

View file

@ -0,0 +1,6 @@
def_module_params(class_name='bv_simplifier_params_helper',
module_name="old_simplify", # Parameters will be in the old_simplify module
export=True,
params=(
('bv.hi_div0', BOOL, True, 'if true, then Z3 uses the usual hardware interpretation for division (rem, mod) by zero; otherwise, these operations are considered uninterpreted'),
('bv.bv2int_distribute', BOOL, True, 'if true, then int2bv is distributed over arithmetical operators')))

View file

@ -607,8 +607,8 @@ void substitution_tree::display(std::ostream & out, node * n, unsigned delta) co
out << " ";
display(out, n->m_subst);
if (n->m_leaf) {
pp_params p;
p.m_pp_single_line = true;
params_ref p;
p.set_bool("single_line", true);
out << " ==> ";
out << mk_pp(n->m_expr, m_manager, p);
out << "\n";