mirror of
https://github.com/Z3Prover/z3
synced 2025-10-04 15:03:57 +00:00
merged
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
commit
9ab1210cc2
518 changed files with 21452 additions and 22650 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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_ */
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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); }
|
||||
|
|
9
src/ast/normal_forms/nnf_params.pyg
Normal file
9
src/ast/normal_forms/nnf_params.pyg
Normal 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')))
|
|
@ -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();
|
||||
|
|
|
@ -22,7 +22,6 @@ Notes:
|
|||
|
||||
#include"ast.h"
|
||||
#include"map.h"
|
||||
#include"front_end_params.h"
|
||||
|
||||
class expr_pattern_match {
|
||||
|
||||
|
|
32
src/ast/pattern/pattern_inference_params.cpp
Normal file
32
src/ast/pattern/pattern_inference_params.cpp
Normal 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();
|
||||
}
|
52
src/ast/pattern/pattern_inference_params.h
Normal file
52
src/ast/pattern/pattern_inference_params.h
Normal 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_ */
|
||||
|
12
src/ast/pattern/pattern_inference_params_helper.pyg
Normal file
12
src/ast/pattern/pattern_inference_params_helper.pyg
Normal 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')))
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
10
src/ast/pp.h
10
src/ast/pp.h
|
@ -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_ */
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
18
src/ast/pp_params.pyg
Normal 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')))
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
15
src/ast/rewriter/arith_rewriter_params.pyg
Normal file
15
src/ast/rewriter/arith_rewriter_params.pyg
Normal 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))).")))
|
|
@ -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) {
|
||||
|
|
5
src/ast/rewriter/array_rewriter_params.pyg
Normal file
5
src/ast/rewriter/array_rewriter_params.pyg
Normal 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")))
|
38
src/ast/rewriter/bit_blaster/bit_blaster_params.h
Normal file
38
src/ast/rewriter/bit_blaster/bit_blaster_params.h
Normal 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_ */
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
9
src/ast/rewriter/bool_rewriter_params.pyg
Normal file
9
src/ast/rewriter/bool_rewriter_params.pyg
Normal 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")))
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
10
src/ast/rewriter/bv_rewriter_params.pyg
Normal file
10
src/ast/rewriter/bv_rewriter_params.pyg
Normal 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")))
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
8
src/ast/rewriter/poly_rewriter_params.pyg
Normal file
8
src/ast/rewriter/poly_rewriter_params.pyg
Normal 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")))
|
11
src/ast/rewriter/rewriter_params.pyg
Normal file
11
src/ast/rewriter/rewriter_params.pyg
Normal 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.")))
|
||||
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
26
src/ast/simplifier/arith_simplifier_params.cpp
Normal file
26
src/ast/simplifier/arith_simplifier_params.cpp
Normal 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();
|
||||
}
|
36
src/ast/simplifier/arith_simplifier_params.h
Normal file
36
src/ast/simplifier/arith_simplifier_params.h
Normal 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_ */
|
||||
|
7
src/ast/simplifier/arith_simplifier_params_helper.pyg
Normal file
7
src/ast/simplifier/arith_simplifier_params_helper.pyg
Normal 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')))
|
26
src/ast/simplifier/array_simplifier_params.cpp
Normal file
26
src/ast/simplifier/array_simplifier_params.cpp
Normal 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();
|
||||
}
|
36
src/ast/simplifier/array_simplifier_params.h
Normal file
36
src/ast/simplifier/array_simplifier_params.h
Normal 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_ */
|
||||
|
6
src/ast/simplifier/array_simplifier_params_helper.pyg
Normal file
6
src/ast/simplifier/array_simplifier_params_helper.pyg
Normal 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')))
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
|
|
26
src/ast/simplifier/bv_simplifier_params.cpp
Normal file
26
src/ast/simplifier/bv_simplifier_params.cpp
Normal 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();
|
||||
}
|
36
src/ast/simplifier/bv_simplifier_params.h
Normal file
36
src/ast/simplifier/bv_simplifier_params.h
Normal 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_ */
|
||||
|
6
src/ast/simplifier/bv_simplifier_params_helper.pyg
Normal file
6
src/ast/simplifier/bv_simplifier_params_helper.pyg
Normal 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')))
|
|
@ -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";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue