3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 09:05:31 +00:00

Merge branch 'master' of http://github.com/z3prover/z3 into polysat

This commit is contained in:
Nikolaj Bjorner 2021-09-20 17:39:04 -07:00
commit 959f150e4a
104 changed files with 1666 additions and 1040 deletions

View file

@ -80,6 +80,9 @@ class ll_printer {
display_child_ref(n);
}
break;
case AST_FUNC_DECL:
m_out << to_func_decl(n)->get_name();
break;
default:
display_child_ref(n);
}

View file

@ -379,7 +379,7 @@ bool has_uninterpreted(ast_manager& m, expr* _e) {
expr_ref e(_e, m);
arith_util au(m);
func_decl_ref f_out(m);
for (expr* arg : subterms(e)) {
for (expr* arg : subterms::all(e)) {
if (!is_app(arg))
continue;
app* a = to_app(arg);

View file

@ -22,7 +22,6 @@ Author:
char_decl_plugin::char_decl_plugin():
m_charc_sym("Char") {
m_unicode = gparams::get_value("unicode") != "false";
}
char_decl_plugin::~char_decl_plugin() {
@ -49,7 +48,7 @@ func_decl* char_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters,
if (num_parameters != 1)
msg << "incorrect number of parameters passed. Expected 1, received " << num_parameters;
else if (arity != 0)
msg << "incorrect number of arguments passed. Expected 1, received " << arity;
msg << "incorrect number of arguments passed. Expected 0, received " << arity;
else if (!parameters[0].is_int())
msg << "integer parameter expected";
else if (parameters[0].get_int() < 0)
@ -69,6 +68,32 @@ func_decl* char_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters,
return m.mk_func_decl(symbol("char.to_int"), arity, domain, a.mk_int(), func_decl_info(m_family_id, k, 0, nullptr));
}
m.raise_exception(msg.str());
case OP_CHAR_TO_BV:
if (num_parameters != 0)
msg << "incorrect number of parameters passed. Expected 0, received " << num_parameters;
else if (arity != 1)
msg << "incorrect number of arguments passed. Expected one character, received " << arity;
else if (m_char != domain[0])
msg << "expected character sort argument";
else {
bv_util b(m);
unsigned sz = num_bits();
return m.mk_func_decl(symbol("char.to_bv"), arity, domain, b.mk_sort(sz), func_decl_info(m_family_id, k, 0, nullptr));
}
m.raise_exception(msg.str());
case OP_CHAR_FROM_BV: {
bv_util b(m);
if (num_parameters != 0)
msg << "incorrect number of parameters passed. Expected 0, received " << num_parameters;
else if (arity != 1)
msg << "incorrect number of arguments passed. Expected one character, received " << arity;
else if (!b.is_bv_sort(domain[0]) || b.get_bv_size(domain[0]) != num_bits())
msg << "expected bit-vector sort argument with " << num_bits();
else {
return m.mk_func_decl(symbol("char.from_bv"), arity, domain, m_char, func_decl_info(m_family_id, k, 0, nullptr));
}
m.raise_exception(msg.str());
}
case OP_CHAR_IS_DIGIT:
if (num_parameters != 0)
msg << "incorrect number of parameters passed. Expected 0, received " << num_parameters;
@ -78,6 +103,7 @@ func_decl* char_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters,
return m.mk_func_decl(symbol("char.is_digit"), arity, domain, m.mk_bool_sort(), func_decl_info(m_family_id, k, 0, nullptr));
}
m.raise_exception(msg.str());
default:
UNREACHABLE();
}
@ -95,6 +121,8 @@ void char_decl_plugin::get_op_names(svector<builtin_name>& op_names, symbol cons
op_names.push_back(builtin_name("Char", OP_CHAR_CONST));
op_names.push_back(builtin_name("char.to_int", OP_CHAR_TO_INT));
op_names.push_back(builtin_name("char.is_digit", OP_CHAR_IS_DIGIT));
op_names.push_back(builtin_name("char.to_bv", OP_CHAR_TO_BV));
op_names.push_back(builtin_name("char.from_bv", OP_CHAR_FROM_BV));
}
void char_decl_plugin::get_sort_names(svector<builtin_name>& sort_names, symbol const& logic) {

View file

@ -34,13 +34,14 @@ enum char_op_kind {
OP_CHAR_CONST,
OP_CHAR_LE,
OP_CHAR_TO_INT,
OP_CHAR_TO_BV,
OP_CHAR_FROM_BV,
OP_CHAR_IS_DIGIT
};
class char_decl_plugin : public decl_plugin {
sort* m_char { nullptr };
symbol m_charc_sym;
bool m_unicode { true };
void set_manager(ast_manager * m, family_id id) override;
@ -92,12 +93,17 @@ public:
bool is_is_digit(expr const* e) const { return is_app_of(e, m_family_id, OP_CHAR_IS_DIGIT); }
bool is_char2bv(expr const* e) const { return is_app_of(e, m_family_id, OP_CHAR_TO_BV); }
bool is_bv2char(expr const* e) const { return is_app_of(e, m_family_id, OP_CHAR_FROM_BV); }
MATCH_UNARY(is_is_digit);
MATCH_UNARY(is_to_int);
MATCH_UNARY(is_char2bv);
MATCH_UNARY(is_bv2char);
MATCH_BINARY(is_le);
bool unicode() const { return m_unicode; }
unsigned max_char() const { return m_unicode ? zstring::unicode_max_char() : zstring::ascii_max_char(); }
unsigned num_bits() const { return m_unicode ? zstring::unicode_num_bits() : zstring::ascii_num_bits(); }
static unsigned max_char() { return zstring::max_char(); }
static unsigned num_bits() { return zstring::num_bits(); }
};

View file

@ -422,6 +422,11 @@ namespace euf {
set_conflict(n1, n2, j);
return;
}
if (r1->value() != r2->value() && r1->value() != l_undef && r2->value() != l_undef) {
SASSERT(m.is_bool(r1->get_expr()));
set_conflict(n1, n2, j);
return;
}
if (!r2->interpreted() &&
(r1->class_size() > r2->class_size() || r1->interpreted() || r1->value() != l_undef)) {
std::swap(r1, r2);

View file

@ -72,7 +72,7 @@ namespace euf {
void * etable::mk_table_for(unsigned arity, func_decl * d) {
void * r;
SASSERT(d->get_arity() >= 1);
SASSERT(arity >= d->get_arity() || d->is_associative());
SASSERT(arity >= d->get_arity() || d->is_associative() || d->is_left_associative());
switch (arity) {
case 1:
r = TAG(void*, alloc(unary_table), UNARY);

View file

@ -64,11 +64,11 @@ bool has_skolem_functions(expr * n) {
return false;
}
subterms::subterms(expr_ref_vector const& es): m_es(es) {}
subterms::subterms(expr_ref const& e) : m_es(e.m()) { m_es.push_back(e); }
subterms::subterms(expr_ref_vector const& es, bool include_bound): m_include_bound(include_bound), m_es(es) {}
subterms::subterms(expr_ref const& e, bool include_bound) : m_include_bound(include_bound), m_es(e.m()) { m_es.push_back(e); }
subterms::iterator subterms::begin() { return iterator(*this, true); }
subterms::iterator subterms::end() { return iterator(*this, false); }
subterms::iterator::iterator(subterms& f, bool start): m_es(f.m_es) {
subterms::iterator::iterator(subterms& f, bool start): m_include_bound(f.m_include_bound), m_es(f.m_es) {
if (!start) m_es.reset();
}
expr* subterms::iterator::operator*() {
@ -82,14 +82,15 @@ subterms::iterator subterms::iterator::operator++(int) {
subterms::iterator& subterms::iterator::operator++() {
expr* e = m_es.back();
m_visited.mark(e, true);
if (is_app(e)) {
for (expr* arg : *to_app(e)) {
m_es.push_back(arg);
}
}
while (!m_es.empty() && m_visited.is_marked(m_es.back())) {
if (is_app(e))
for (expr* arg : *to_app(e))
m_es.push_back(arg);
else if (is_quantifier(e) && m_include_bound)
m_es.push_back(to_quantifier(e)->get_expr());
while (!m_es.empty() && m_visited.is_marked(m_es.back()))
m_es.pop_back();
}
return *this;
}

View file

@ -168,9 +168,13 @@ bool has_skolem_functions(expr * n);
// pre-order traversal of subterms
class subterms {
bool m_include_bound = false;
expr_ref_vector m_es;
subterms(expr_ref const& e, bool include_bound);
subterms(expr_ref_vector const& es, bool include_bound);
public:
class iterator {
bool m_include_bound = false;
expr_ref_vector m_es;
expr_mark m_visited;
public:
@ -181,8 +185,12 @@ public:
bool operator==(iterator const& other) const;
bool operator!=(iterator const& other) const;
};
subterms(expr_ref_vector const& es);
subterms(expr_ref const& e);
static subterms all(expr_ref const& e) { return subterms(e, true); }
static subterms ground(expr_ref const& e) { return subterms(e, false); }
static subterms all(expr_ref_vector const& e) { return subterms(e, true); }
static subterms ground(expr_ref_vector const& e) { return subterms(e, false); }
iterator begin();
iterator end();
};

View file

@ -19,6 +19,7 @@ Notes:
#include<math.h>
#include "ast/ast_smt2_pp.h"
#include "ast/ast_pp.h"
#include "ast/well_sorted.h"
#include "ast/rewriter/th_rewriter.h"
#include "ast/rewriter/fpa_rewriter.h"
@ -311,10 +312,19 @@ func_interp * bv2fpa_converter::convert_func_interp(model_core * mc, func_decl *
}
}
expr_ref bv_els(m);
bv_els = bv_fi->get_else();
if (bv_els) {
expr_ref ft_els = rebuild_floats(mc, rng, bv_els);
if (m_fpa_util.is_to_sbv(f) || m_fpa_util.is_to_ubv(f)) {
auto fid = m_fpa_util.get_family_id();
auto k = m_fpa_util.is_to_sbv(f) ? OP_FPA_TO_SBV_I : OP_FPA_TO_UBV_I;
expr_ref_vector dom(m);
for (unsigned i = 0; i < f->get_arity(); ++i)
dom.push_back(m.mk_var(i, f->get_domain(i)));
parameter param = f->get_parameter(0);
func_decl_ref to_bv_i(m.mk_func_decl(fid, k, 1, &param, dom.size(), dom.data()), m);
expr_ref else_value(m.mk_app(to_bv_i, dom.size(), dom.data()), m);
result->set_else(else_value);
}
else if (bv_fi->get_else()) {
expr_ref ft_els = rebuild_floats(mc, rng, bv_fi->get_else());
m_th_rw(ft_els);
TRACE("bv2fpa", tout << "else=" << mk_ismt2_pp(ft_els, m) << std::endl;);
result->set_else(ft_els);
@ -412,24 +422,32 @@ void bv2fpa_converter::convert_min_max_specials(model_core * mc, model_core * ta
app * np_cnst = kv.m_value.second;
expr_ref pzero(m), nzero(m);
pzero = m_fpa_util.mk_pzero(f->get_range());
nzero = m_fpa_util.mk_nzero(f->get_range());
sort* srt = f->get_range();
pzero = m_fpa_util.mk_pzero(srt);
nzero = m_fpa_util.mk_nzero(srt);
expr_ref pn(m), np(m);
if (!mc->eval(pn_cnst->get_decl(), pn)) pn = pzero;
if (!mc->eval(np_cnst->get_decl(), np)) np = pzero;
if (!mc->eval(pn_cnst->get_decl(), pn)) pn = m_bv_util.mk_numeral(0, 1);
if (!mc->eval(np_cnst->get_decl(), np)) np = m_bv_util.mk_numeral(0, 1);
seen.insert(pn_cnst->get_decl());
seen.insert(np_cnst->get_decl());
rational pn_num, np_num;
unsigned bv_sz;
m_bv_util.is_numeral(pn, pn_num, bv_sz);
m_bv_util.is_numeral(np, np_num, bv_sz);
VERIFY(m_bv_util.is_numeral(pn, pn_num, bv_sz));
VERIFY(m_bv_util.is_numeral(np, np_num, bv_sz));
func_interp * flt_fi = alloc(func_interp, m, f->get_arity());
expr * pn_args[2] = { pzero, nzero };
if (pn != np) flt_fi->insert_new_entry(pn_args, (pn_num.is_one() ? nzero : pzero));
flt_fi->set_else(np_num.is_one() ? nzero : pzero);
expr * np_args[2] = { nzero, pzero };
flt_fi->insert_new_entry(pn_args, (pn_num.is_one() ? nzero : pzero));
flt_fi->insert_new_entry(np_args, (np_num.is_one() ? nzero : pzero));
auto fid = m_fpa_util.get_family_id();
auto k = is_decl_of(f, fid, OP_FPA_MIN) ? OP_FPA_MIN_I : OP_FPA_MAX_I;
func_decl_ref min_max_i(m.mk_func_decl(fid, k, 0, nullptr, 2, pn_args), m);
expr_ref else_value(m.mk_app(min_max_i, m.mk_var(0, srt), m.mk_var(1, srt)), m);
flt_fi->set_else(else_value);
target_model->register_decl(f, flt_fi);
TRACE("bv2fpa", tout << "fp.min/fp.max special: " << std::endl <<

View file

@ -1267,6 +1267,16 @@ void fpa2bv_converter::mk_abs(sort * s, expr_ref & x, expr_ref & result) {
result = m_util.mk_fp(m_bv_util.mk_numeral(0, 1), exp, sig);
}
void fpa2bv_converter::mk_min_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
func_decl_ref fu(m.mk_func_decl(f->get_family_id(), OP_FPA_MIN, 0, nullptr, num, args), m);
mk_min(fu, num, args, result);
}
void fpa2bv_converter::mk_max_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
func_decl_ref fu(m.mk_func_decl(f->get_family_id(), OP_FPA_MAX, 0, nullptr, num, args), m);
mk_max(fu, num, args, result);
}
void fpa2bv_converter::mk_min(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
SASSERT(num == 2);
@ -3419,6 +3429,16 @@ void fpa2bv_converter::mk_to_sbv(func_decl * f, unsigned num, expr * const * arg
mk_to_bv(f, num, args, true, result);
}
void fpa2bv_converter::mk_to_ubv_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
func_decl_ref fu(m.mk_func_decl(f->get_family_id(), OP_FPA_TO_UBV, 0, nullptr, num, args), m);
mk_to_bv(f, num, args, false, result);
}
void fpa2bv_converter::mk_to_sbv_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
func_decl_ref fu(m.mk_func_decl(f->get_family_id(), OP_FPA_TO_SBV, 0, nullptr, num, args), m);
mk_to_bv(f, num, args, true, result);
}
expr_ref fpa2bv_converter::nan_wrap(expr * n) {
expr_ref n_bv(m), arg_is_nan(m), nan(m), nan_bv(m), res(m);
mk_is_nan(n, arg_is_nan);

View file

@ -141,6 +141,8 @@ public:
void mk_to_ubv(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
void mk_to_sbv(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
void mk_to_ubv_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
void mk_to_sbv_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
void mk_to_bv_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
void mk_to_real(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
void mk_to_real_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
@ -149,6 +151,8 @@ public:
void mk_min(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
void mk_max(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
void mk_min_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
void mk_max_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
expr_ref mk_min_max_unspecified(func_decl * f, expr * x, expr * y);
void reset();

View file

@ -124,6 +124,8 @@ br_status fpa2bv_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr * co
case OP_FPA_ABS: m_conv.mk_abs(f, num, args, result); return BR_DONE;
case OP_FPA_MIN: m_conv.mk_min(f, num, args, result); return BR_DONE;
case OP_FPA_MAX: m_conv.mk_max(f, num, args, result); return BR_DONE;
case OP_FPA_MIN_I: m_conv.mk_min_i(f, num, args, result); return BR_DONE;
case OP_FPA_MAX_I: m_conv.mk_max_i(f, num, args, result); return BR_DONE;
case OP_FPA_FMA: m_conv.mk_fma(f, num, args, result); return BR_DONE;
case OP_FPA_SQRT: m_conv.mk_sqrt(f, num, args, result); return BR_DONE;
case OP_FPA_ROUND_TO_INTEGRAL: m_conv.mk_round_to_integral(f, num, args, result); return BR_DONE;
@ -144,6 +146,8 @@ br_status fpa2bv_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr * co
case OP_FPA_FP: m_conv.mk_fp(f, num, args, result); return BR_DONE;
case OP_FPA_TO_UBV: m_conv.mk_to_ubv(f, num, args, result); return BR_DONE;
case OP_FPA_TO_SBV: m_conv.mk_to_sbv(f, num, args, result); return BR_DONE;
case OP_FPA_TO_UBV_I: m_conv.mk_to_ubv_i(f, num, args, result); return BR_DONE;
case OP_FPA_TO_SBV_I: m_conv.mk_to_sbv_i(f, num, args, result); return BR_DONE;
case OP_FPA_TO_REAL: m_conv.mk_to_real(f, num, args, result); return BR_DONE;
case OP_FPA_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE;

View file

@ -375,6 +375,8 @@ func_decl * fpa_decl_plugin::mk_binary_decl(decl_kind k, unsigned num_parameters
case OP_FPA_REM: name = "fp.rem"; break;
case OP_FPA_MIN: name = "fp.min"; break;
case OP_FPA_MAX: name = "fp.max"; break;
case OP_FPA_MIN_I: name = "fp.min_i"; break;
case OP_FPA_MAX_I: name = "fp.max_i"; break;
default:
UNREACHABLE();
break;
@ -756,6 +758,8 @@ func_decl * fpa_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters,
case OP_FPA_REM:
case OP_FPA_MIN:
case OP_FPA_MAX:
case OP_FPA_MIN_I:
case OP_FPA_MAX_I:
return mk_binary_decl(k, num_parameters, parameters, arity, domain, range);
case OP_FPA_ADD:
case OP_FPA_MUL:
@ -774,8 +778,10 @@ func_decl * fpa_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters,
case OP_FPA_FP:
return mk_fp(k, num_parameters, parameters, arity, domain, range);
case OP_FPA_TO_UBV:
case OP_FPA_TO_UBV_I:
return mk_to_ubv(k, num_parameters, parameters, arity, domain, range);
case OP_FPA_TO_SBV:
case OP_FPA_TO_SBV_I:
return mk_to_sbv(k, num_parameters, parameters, arity, domain, range);
case OP_FPA_TO_REAL:
return mk_to_real(k, num_parameters, parameters, arity, domain, range);
@ -829,6 +835,8 @@ void fpa_decl_plugin::get_op_names(svector<builtin_name> & op_names, symbol cons
op_names.push_back(builtin_name("fp.roundToIntegral", OP_FPA_ROUND_TO_INTEGRAL));
op_names.push_back(builtin_name("fp.min", OP_FPA_MIN));
op_names.push_back(builtin_name("fp.max", OP_FPA_MAX));
op_names.push_back(builtin_name("fp.min_i", OP_FPA_MIN_I));
op_names.push_back(builtin_name("fp.max_i", OP_FPA_MAX_I));
op_names.push_back(builtin_name("fp.leq", OP_FPA_LE));
op_names.push_back(builtin_name("fp.lt", OP_FPA_LT));
op_names.push_back(builtin_name("fp.geq", OP_FPA_GE));
@ -846,6 +854,8 @@ void fpa_decl_plugin::get_op_names(svector<builtin_name> & op_names, symbol cons
op_names.push_back(builtin_name("fp", OP_FPA_FP));
op_names.push_back(builtin_name("fp.to_ubv", OP_FPA_TO_UBV));
op_names.push_back(builtin_name("fp.to_sbv", OP_FPA_TO_SBV));
op_names.push_back(builtin_name("fp.to_ubv_I", OP_FPA_TO_UBV_I));
op_names.push_back(builtin_name("fp.to_sbv_I", OP_FPA_TO_SBV_I));
op_names.push_back(builtin_name("fp.to_real", OP_FPA_TO_REAL));
op_names.push_back(builtin_name("to_fp", OP_FPA_TO_FP));
@ -927,9 +937,8 @@ bool fpa_decl_plugin::is_unique_value(app* e) const {
case OP_FPA_NUM: /* see NaN */
return false;
case OP_FPA_FP:
return m_manager->is_unique_value(e->get_arg(0)) &&
m_manager->is_unique_value(e->get_arg(1)) &&
m_manager->is_unique_value(e->get_arg(2));
return false; /*No; generally not because of clashes with +oo, -oo, +zero, -zero, NaN */
// a refinement would require to return true only if there is no clash with these cases.
default:
return false;
}
@ -1065,10 +1074,12 @@ bool fpa_util::is_considered_uninterpreted(func_decl * f, unsigned n, expr* cons
return is_nan(x);
}
else if (is_decl_of(f, ffid, OP_FPA_TO_SBV) ||
is_decl_of(f, ffid, OP_FPA_TO_UBV)) {
is_decl_of(f, ffid, OP_FPA_TO_UBV) ||
is_decl_of(f, ffid, OP_FPA_TO_SBV_I) ||
is_decl_of(f, ffid, OP_FPA_TO_UBV_I)) {
SASSERT(n == 2);
SASSERT(f->get_num_parameters() == 1);
bool is_signed = f->get_decl_kind() == OP_FPA_TO_SBV;
bool is_signed = f->get_decl_kind() == OP_FPA_TO_SBV || f->get_decl_kind() == OP_FPA_TO_SBV_I;
expr* rm = args[0];
expr* x = args[1];
unsigned bv_sz = f->get_parameter(0).get_int();

View file

@ -58,6 +58,8 @@ enum fpa_op_kind {
OP_FPA_ABS,
OP_FPA_MIN,
OP_FPA_MAX,
OP_FPA_MIN_I,
OP_FPA_MAX_I,
OP_FPA_FMA, // x*y + z
OP_FPA_SQRT,
OP_FPA_ROUND_TO_INTEGRAL,
@ -82,6 +84,9 @@ enum fpa_op_kind {
OP_FPA_TO_SBV,
OP_FPA_TO_REAL,
OP_FPA_TO_SBV_I,
OP_FPA_TO_UBV_I,
/* Extensions */
OP_FPA_TO_IEEE_BV,

View file

@ -114,6 +114,8 @@ app * defined_names::impl::gen_name(expr * e, sort_ref_buffer & var_sorts, buffe
var_sorts.push_back(s);
}
else {
domain.push_back(m.mk_bool_sort());
new_args.push_back(m.mk_true());
var_sorts.push_back(m.mk_bool_sort()); // could be any sort.
}
var_names.push_back(symbol(i));

View file

@ -466,7 +466,7 @@ namespace recfun {
obj_map<expr, ptr_vector<expr>> parents;
expr_ref tmp(e, m());
parents.insert(e, ptr_vector<expr>());
for (expr* t : subterms(tmp)) {
for (expr* t : subterms::ground(tmp)) {
if (is_app(t)) {
for (expr* arg : *to_app(t)) {
parents.insert_if_not_there(arg, ptr_vector<expr>()).push_back(t);

View file

@ -31,7 +31,7 @@ void array_rewriter::updt_params(params_ref const & _p) {
m_expand_store_eq = p.expand_store_eq();
m_expand_nested_stores = p.expand_nested_stores();
m_blast_select_store = p.blast_select_store();
m_expand_select_ite = false;
m_expand_select_ite = p.expand_select_ite();
}
void array_rewriter::get_param_descrs(param_descrs & r) {
@ -226,8 +226,7 @@ br_status array_rewriter::mk_select_core(unsigned num_args, expr * const * args,
result = subst(q->get_expr(), _args.size(), _args.data());
inv_var_shifter invsh(m());
invsh(result, _args.size(), result);
return BR_REWRITE_FULL;
return BR_REWRITE_FULL;
}
if (m_util.is_map(args[0])) {
@ -248,7 +247,6 @@ br_status array_rewriter::mk_select_core(unsigned num_args, expr * const * args,
// select(as-array[f], I) --> f(I)
func_decl * f = m_util.get_as_array_func_decl(to_app(args[0]));
result = m().mk_app(f, num_args - 1, args + 1);
TRACE("array", tout << mk_pp(args[0], m()) << " " << result << "\n";);
return BR_REWRITE1;
}
@ -695,12 +693,6 @@ br_status array_rewriter::mk_eq_core(expr * lhs, expr * rhs, expr_ref & result)
if (m_util.is_const(rhs) && m_util.is_store(lhs)) {
std::swap(lhs, rhs);
}
if (m_util.is_const(lhs, v) && m_util.is_store(rhs)) {
unsigned n = to_app(rhs)->get_num_args();
result = m().mk_and(m().mk_eq(lhs, to_app(rhs)->get_arg(0)),
m().mk_eq(v, to_app(rhs)->get_arg(n - 1)));
return BR_REWRITE2;
}
if (m_util.is_const(lhs, v) && m_util.is_const(rhs, w)) {
result = m().mk_eq(v, w);
return BR_REWRITE1;

View file

@ -66,6 +66,8 @@ br_status fpa_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con
case OP_FPA_ABS: SASSERT(num_args == 1); st = mk_abs(args[0], result); break;
case OP_FPA_MIN: SASSERT(num_args == 2); st = mk_min(args[0], args[1], result); break;
case OP_FPA_MAX: SASSERT(num_args == 2); st = mk_max(args[0], args[1], result); break;
case OP_FPA_MIN_I: SASSERT(num_args == 2); st = mk_min(args[0], args[1], result); break;
case OP_FPA_MAX_I: SASSERT(num_args == 2); st = mk_max(args[0], args[1], result); break;
case OP_FPA_FMA: SASSERT(num_args == 4); st = mk_fma(args[0], args[1], args[2], args[3], result); break;
case OP_FPA_SQRT: SASSERT(num_args == 2); st = mk_sqrt(args[0], args[1], result); break;
case OP_FPA_ROUND_TO_INTEGRAL: SASSERT(num_args == 2); st = mk_round_to_integral(args[0], args[1], result); break;
@ -86,8 +88,10 @@ br_status fpa_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con
case OP_FPA_FP: SASSERT(num_args == 3); st = mk_fp(args[0], args[1], args[2], result); break;
case OP_FPA_TO_FP: st = mk_to_fp(f, num_args, args, result); break;
case OP_FPA_TO_FP_UNSIGNED: SASSERT(num_args == 2); st = mk_to_fp_unsigned(f, args[0], args[1], result); break;
case OP_FPA_TO_UBV: SASSERT(num_args == 2); st = mk_to_ubv(f, args[0], args[1], result); break;
case OP_FPA_TO_SBV: SASSERT(num_args == 2); st = mk_to_sbv(f, args[0], args[1], result); break;
case OP_FPA_TO_UBV: SASSERT(num_args == 2); st = mk_to_ubv(f, args[0], args[1], result); break;
case OP_FPA_TO_SBV: SASSERT(num_args == 2); st = mk_to_sbv(f, args[0], args[1], result); break;
case OP_FPA_TO_UBV_I: SASSERT(num_args == 2); st = mk_to_ubv(f, args[0], args[1], result); break;
case OP_FPA_TO_SBV_I: SASSERT(num_args == 2); st = mk_to_sbv(f, args[0], args[1], result); break;
case OP_FPA_TO_IEEE_BV: SASSERT(num_args == 1); st = mk_to_ieee_bv(f, args[0], result); break;
case OP_FPA_TO_REAL: SASSERT(num_args == 1); st = mk_to_real(args[0], result); break;

View file

@ -21,6 +21,7 @@ Notes:
#include "ast/ast.h"
#include "ast/rewriter/rewriter_types.h"
#include "ast/act_cache.h"
#include "util/obj_hashtable.h"
/**
\brief Common infrastructure for AST rewriters.
@ -60,6 +61,7 @@ protected:
proof_ref_vector m_result_pr_stack;
// --------------------------
obj_hashtable<expr> m_blocked;
expr * m_root;
unsigned m_num_qvars;
struct scope {
@ -112,6 +114,8 @@ protected:
void set_new_child_flag(expr * old_t, expr * new_t) { if (old_t != new_t) set_new_child_flag(old_t); }
void elim_reflex_prs(unsigned spos);
void block(expr* t) { m_blocked.insert(t); }
bool is_blocked(expr* t) const { return m_blocked.contains(t); }
public:
rewriter_core(ast_manager & m, bool proof_gen);
virtual ~rewriter_core();

View file

@ -192,10 +192,21 @@ bool rewriter_tpl<Config>::visit(expr * t, unsigned max_depth) {
switch (t->get_kind()) {
case AST_APP:
if (to_app(t)->get_num_args() == 0) {
if (process_const<ProofGen>(to_app(t)))
return true;
TRACE("rewriter", tout << "process const: " << mk_bounded_pp(t, m()) << " -> " << mk_bounded_pp(m_r,m()) << "\n";);
t = m_r;
if (process_const<ProofGen>(to_app(t)))
return true;
TRACE("rewriter_const", tout << "process const: " << mk_bounded_pp(t, m()) << " -> " << mk_bounded_pp(m_r, m()) << "\n";);
if (!is_blocked(t)) {
rewriter_tpl rw(m(), false, m_cfg);
for (auto* s : m_blocked)
rw.block(s);
rw.block(t);
expr_ref result(m());
rw(m_r, result, m_pr);
m_r = result;
}
set_new_child_flag(t, m_r);
result_stack().push_back(m_r);
return true;
}
if (max_depth != RW_UNBOUNDED_DEPTH)
max_depth--;

View file

@ -124,14 +124,14 @@ void value_sweep::init(expr_ref_vector const& terms) {
m_vars.reset();
m_qhead = 0;
m_vhead = 0;
for (expr* t : subterms(terms)) {
for (expr* t : subterms::ground(terms)) {
m_parents.reserve(t->get_id() + 1);
if (get_value(t))
m_queue.push_back(t);
else if (!is_reducible(t))
m_vars.push_back(t);
}
for (expr* t : subterms(terms)) {
for (expr* t : subterms::ground(terms)) {
if (!is_app(t))
continue;
for (expr* arg : *to_app(t)) {

View file

@ -798,6 +798,15 @@ bool seq_util::is_char2int(expr const* e) const {
return ch.is_to_int(e);
}
bool seq_util::is_bv2char(expr const* e) const {
return ch.is_bv2char(e);
}
bool seq_util::is_char2bv(expr const* e) const {
return ch.is_char2bv(e);
}
app* seq_util::mk_char(unsigned ch) const {
return seq.mk_char(ch);
}

View file

@ -166,8 +166,6 @@ public:
void finalize() override;
bool unicode() const { return get_char_plugin().unicode(); }
decl_plugin * mk_fresh() override { return alloc(seq_decl_plugin); }
sort * mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) override;
@ -241,6 +239,8 @@ public:
bool is_char_is_digit(expr const* e, expr*& d) const { return ch.is_is_digit(e, d); }
bool is_char_is_digit(expr const* e) const { return ch.is_is_digit(e); }
bool is_char2int(expr const* e) const;
bool is_bv2char(expr const* e) const;
bool is_char2bv(expr const* e) const;
app* mk_char_bit(expr* e, unsigned i);
app* mk_char(unsigned ch) const;
app* mk_char_is_digit(expr* e) { return ch.mk_is_digit(e); }
@ -255,6 +255,8 @@ public:
MATCH_BINARY(is_char_le);
MATCH_UNARY(is_char2int);
MATCH_UNARY(is_char2bv);
MATCH_UNARY(is_bv2char);
bool has_re() const { return seq.has_re(); }
bool has_seq() const { return seq.has_seq(); }

View file

@ -406,7 +406,7 @@ void static_features::process(expr * e, bool form_ctx, bool or_and_ctx, bool ite
}
if (stack_depth > m_max_stack_depth) {
for (expr* arg : subterms(expr_ref(e, m)))
for (expr* arg : subterms::ground(expr_ref(e, m)))
if (get_depth(arg) <= 3 || is_quantifier(arg))
process(arg, form_ctx, or_and_ctx, ite_ctx, stack_depth - 10);
return;