mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 01:25:31 +00:00
Improved UF suppport in fpa2bv_converter.
This commit is contained in:
parent
2744d80642
commit
076e680433
7 changed files with 303 additions and 223 deletions
|
@ -207,90 +207,76 @@ void fpa2bv_converter::mk_var(unsigned base_inx, sort * srt, expr_ref & result)
|
|||
mk_fp(sgn, e, s, result);
|
||||
}
|
||||
|
||||
void fpa2bv_converter::mk_uninterpreted_output(sort * rng, func_decl * fbv, expr_ref_buffer & new_args, expr_ref & result) {
|
||||
if (m_util.is_float(rng)) {
|
||||
unsigned ebits = m_util.get_ebits(rng);
|
||||
unsigned sbits = m_util.get_sbits(rng);
|
||||
unsigned bv_sz = ebits + sbits;
|
||||
|
||||
app_ref na(m);
|
||||
na = m.mk_app(fbv, new_args.size(), new_args.c_ptr());
|
||||
mk_fp(m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, na),
|
||||
m_bv_util.mk_extract(bv_sz - 2, sbits - 1, na),
|
||||
m_bv_util.mk_extract(sbits - 2, 0, na),
|
||||
result);
|
||||
}
|
||||
else
|
||||
result = m.mk_app(fbv, new_args.size(), new_args.c_ptr());
|
||||
}
|
||||
|
||||
void fpa2bv_converter::mk_uninterpreted_function(func_decl * f, unsigned num, expr * const * args, expr_ref & result)
|
||||
{
|
||||
TRACE("fpa2bv_dbg", tout << "UF: " << mk_ismt2_pp(f, m) << std::endl; );
|
||||
TRACE("fpa2bv", tout << "UF: " << mk_ismt2_pp(f, m) << std::endl; );
|
||||
SASSERT(f->get_arity() == num);
|
||||
|
||||
expr_ref_buffer new_args(m);
|
||||
|
||||
for (unsigned i = 0; i < num ; i ++)
|
||||
if (is_float(args[i]))
|
||||
{
|
||||
expr * sgn, * sig, * exp;
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
if (is_float(args[i])) {
|
||||
expr * sgn, *exp, *sig;
|
||||
split_fp(args[i], sgn, exp, sig);
|
||||
new_args.push_back(sgn);
|
||||
new_args.push_back(sig);
|
||||
new_args.push_back(exp);
|
||||
expr * args[3] = { sgn, exp, sig };
|
||||
new_args.push_back(m_bv_util.mk_concat(3, args));
|
||||
}
|
||||
else
|
||||
new_args.push_back(args[i]);
|
||||
}
|
||||
|
||||
func_decl * fd;
|
||||
func_decl_triple fd3;
|
||||
if (m_uf2bvuf.find(f, fd)) {
|
||||
result = m.mk_app(fd, new_args.size(), new_args.c_ptr());
|
||||
}
|
||||
else if (m_uf23bvuf.find(f, fd3))
|
||||
{
|
||||
expr_ref a_sgn(m), a_sig(m), a_exp(m);
|
||||
a_sgn = m.mk_app(fd3.f_sgn, new_args.size(), new_args.c_ptr());
|
||||
a_sig = m.mk_app(fd3.f_sig, new_args.size(), new_args.c_ptr());
|
||||
a_exp = m.mk_app(fd3.f_exp, new_args.size(), new_args.c_ptr());
|
||||
mk_fp(a_sgn, a_exp, a_sig, result);
|
||||
}
|
||||
if (m_uf2bvuf.find(f, fd))
|
||||
mk_uninterpreted_output(f->get_range(), fd, new_args, result);
|
||||
else {
|
||||
sort_ref_buffer new_domain(m);
|
||||
|
||||
for (unsigned i = 0; i < f->get_arity() ; i ++)
|
||||
if (is_float(f->get_domain()[i]))
|
||||
{
|
||||
new_domain.push_back(m_bv_util.mk_sort(1));
|
||||
new_domain.push_back(m_bv_util.mk_sort(m_util.get_sbits(f->get_domain()[i])-1));
|
||||
new_domain.push_back(m_bv_util.mk_sort(m_util.get_ebits(f->get_domain()[i])));
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < f->get_arity(); i++) {
|
||||
sort * di = f->get_domain()[i];
|
||||
if (is_float(di))
|
||||
new_domain.push_back(m_bv_util.mk_sort(m_util.get_sbits(di) + m_util.get_ebits(di)));
|
||||
else if (is_rm(di))
|
||||
new_domain.push_back(m_bv_util.mk_sort(3));
|
||||
else
|
||||
new_domain.push_back(f->get_domain()[i]);
|
||||
|
||||
if (!is_float(f->get_range()))
|
||||
{
|
||||
func_decl_ref fbv(m);
|
||||
fbv = (f->get_info()) ? m.mk_func_decl(f->get_name(), new_domain.size(), new_domain.c_ptr(), f->get_range(), *f->get_info()) :
|
||||
m.mk_func_decl(f->get_name(), new_domain.size(), new_domain.c_ptr(), f->get_range());
|
||||
TRACE("fpa2bv_dbg", tout << "New UF func_decl : " << mk_ismt2_pp(fbv, m) << std::endl; );
|
||||
m_uf2bvuf.insert(f, fbv);
|
||||
m.inc_ref(f);
|
||||
m.inc_ref(fbv);
|
||||
result = m.mk_app(fbv, new_args.size(), new_args.c_ptr());
|
||||
new_domain.push_back(di);
|
||||
}
|
||||
else
|
||||
{
|
||||
string_buffer<> name_buffer;
|
||||
name_buffer.reset(); name_buffer << f->get_name() << ".sgn";
|
||||
func_decl * f_sgn = m.mk_func_decl(symbol(name_buffer.c_str()), new_domain.size(), new_domain.c_ptr(), m_bv_util.mk_sort(1));
|
||||
name_buffer.reset(); name_buffer << f->get_name() << ".sig";
|
||||
func_decl * f_sig = m.mk_func_decl(symbol(name_buffer.c_str()), new_domain.size(), new_domain.c_ptr(), m_bv_util.mk_sort(m_util.get_sbits(f->get_range())-1));
|
||||
name_buffer.reset(); name_buffer << f->get_name() << ".exp";
|
||||
func_decl * f_exp = m.mk_func_decl(symbol(name_buffer.c_str()), new_domain.size(), new_domain.c_ptr(), m_bv_util.mk_sort(m_util.get_ebits(f->get_range())));
|
||||
|
||||
expr_ref a_sgn(m), a_sig(m), a_exp(m);
|
||||
a_sgn = m.mk_app(f_sgn, new_args.size(), new_args.c_ptr());
|
||||
a_sig = m.mk_app(f_sig, new_args.size(), new_args.c_ptr());
|
||||
a_exp = m.mk_app(f_exp, new_args.size(), new_args.c_ptr());
|
||||
TRACE("fpa2bv_dbg", tout << "New UF func_decls : " << std::endl;
|
||||
tout << mk_ismt2_pp(f_sgn, m) << std::endl;
|
||||
tout << mk_ismt2_pp(f_sig, m) << std::endl;
|
||||
tout << mk_ismt2_pp(f_exp, m) << std::endl; );
|
||||
m_uf23bvuf.insert(f, func_decl_triple(f_sgn, f_sig, f_exp));
|
||||
m.inc_ref(f);
|
||||
m.inc_ref(f_sgn);
|
||||
m.inc_ref(f_sig);
|
||||
m.inc_ref(f_exp);
|
||||
mk_fp(a_sgn, a_exp, a_sig, result);
|
||||
}
|
||||
}
|
||||
sort * orig_rng = f->get_range();
|
||||
sort_ref rng(orig_rng, m);
|
||||
if (m_util.is_float(orig_rng))
|
||||
rng = m_bv_util.mk_sort(m_util.get_ebits(orig_rng) + m_util.get_sbits(orig_rng));
|
||||
else if (m_util.is_rm(orig_rng))
|
||||
rng = m_bv_util.mk_sort(3);
|
||||
|
||||
TRACE("fpa2bv_dbg", tout << "UF result: " << mk_ismt2_pp(result, m) << std::endl; );
|
||||
func_decl_ref fbv(m);
|
||||
fbv = m.mk_fresh_func_decl(new_domain.size(), new_domain.c_ptr(), rng);
|
||||
TRACE("fpa2bv", tout << "New UF func_decl : " << mk_ismt2_pp(fbv, m) << std::endl;);
|
||||
|
||||
m_uf2bvuf.insert(f, fbv);
|
||||
m.inc_ref(f);
|
||||
m.inc_ref(fbv);
|
||||
|
||||
mk_uninterpreted_output(f->get_range(), fbv, new_args, result);
|
||||
}
|
||||
|
||||
TRACE("fpa2bv", tout << "UF result: " << mk_ismt2_pp(result, m) << std::endl; );
|
||||
|
||||
SASSERT(is_well_sorted(m, result));
|
||||
}
|
||||
|
@ -3709,15 +3695,5 @@ void fpa2bv_converter::reset(void) {
|
|||
dec_ref_map_key_values(m, m_rm_const2bv);
|
||||
dec_ref_map_key_values(m, m_uf2bvuf);
|
||||
|
||||
obj_map<func_decl, func_decl_triple>::iterator it = m_uf23bvuf.begin();
|
||||
obj_map<func_decl, func_decl_triple>::iterator end = m_uf23bvuf.end();
|
||||
for (; it != end; ++it) {
|
||||
m.dec_ref(it->m_key);
|
||||
m.dec_ref(it->m_value.f_sgn);
|
||||
m.dec_ref(it->m_value.f_sig);
|
||||
m.dec_ref(it->m_value.f_exp);
|
||||
}
|
||||
m_uf23bvuf.reset();
|
||||
|
||||
m_extra_assertions.reset();
|
||||
}
|
||||
|
|
|
@ -55,8 +55,7 @@ protected:
|
|||
|
||||
obj_map<func_decl, expr*> m_const2bv;
|
||||
obj_map<func_decl, expr*> m_rm_const2bv;
|
||||
obj_map<func_decl, func_decl*> m_uf2bvuf;
|
||||
obj_map<func_decl, func_decl_triple> m_uf23bvuf;
|
||||
obj_map<func_decl, func_decl*> m_uf2bvuf;
|
||||
|
||||
public:
|
||||
fpa2bv_converter(ast_manager & m);
|
||||
|
@ -143,8 +142,7 @@ public:
|
|||
|
||||
obj_map<func_decl, expr*> const & const2bv() const { return m_const2bv; }
|
||||
obj_map<func_decl, expr*> const & rm_const2bv() const { return m_rm_const2bv; }
|
||||
obj_map<func_decl, func_decl*> const & uf2bvuf() const { return m_uf2bvuf; }
|
||||
obj_map<func_decl, func_decl_triple> const & uf23bvuf() const { return m_uf23bvuf; }
|
||||
obj_map<func_decl, func_decl*> const & uf2bvuf() const { return m_uf2bvuf; }
|
||||
|
||||
void reset(void);
|
||||
|
||||
|
@ -189,6 +187,8 @@ protected:
|
|||
app * mk_fresh_const(char const * prefix, unsigned sz);
|
||||
|
||||
void mk_to_bv(func_decl * f, unsigned num, expr * const * args, bool is_signed, expr_ref & result);
|
||||
|
||||
void mk_uninterpreted_output(sort * rng, func_decl * fbv, expr_ref_buffer & new_args, expr_ref & result);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -91,7 +91,9 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg {
|
|||
|
||||
if (m().is_eq(f)) {
|
||||
SASSERT(num == 2);
|
||||
SASSERT(m().get_sort(args[0]) == m().get_sort(args[1]));
|
||||
TRACE("fpa2bv_rw", tout << "(= " << mk_ismt2_pp(args[0], m()) << " " <<
|
||||
mk_ismt2_pp(args[1], m()) << ")" << std::endl;);
|
||||
SASSERT(m().get_sort(args[0]) == m().get_sort(args[1]));
|
||||
sort * ds = f->get_domain()[0];
|
||||
if (m_conv.is_float(ds)) {
|
||||
m_conv.mk_eq(args[0], args[1], result);
|
||||
|
@ -178,13 +180,10 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg {
|
|||
|
||||
if (f->get_family_id() != 0 && f->get_family_id() != m_conv.fu().get_family_id())
|
||||
{
|
||||
bool is_float_uf = m_conv.is_float(f->get_range());
|
||||
unsigned i = 0;
|
||||
while (!is_float_uf && i < num)
|
||||
{
|
||||
is_float_uf = m_conv.is_float(f->get_domain()[i]);
|
||||
i++;
|
||||
}
|
||||
bool is_float_uf = m_conv.is_float(f->get_range()) || m_conv.is_rm(f->get_range());
|
||||
|
||||
for (unsigned i = 0; i < num; i++)
|
||||
is_float_uf |= m_conv.is_float(f->get_domain()[i]) || m_conv.is_rm(f->get_domain()[i]);
|
||||
|
||||
if (is_float_uf)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue