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:
commit
959f150e4a
104 changed files with 1666 additions and 1040 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(); }
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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, ¶m, 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 <<
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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--;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue