From d36c3faf7622bd7344a4965b2e612aaabfe9b6cc Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 17 Sep 2021 14:23:14 +0100 Subject: [PATCH] #4880 add interpreted versions of to_bv functions for MBQI quantifier models --- src/ast/fpa/bv2fpa_converter.cpp | 17 +++++++++++++---- src/ast/fpa/fpa2bv_converter.cpp | 10 ++++++++++ src/ast/fpa/fpa2bv_converter.h | 2 ++ src/ast/fpa/fpa2bv_rewriter.cpp | 2 ++ src/ast/fpa_decl_plugin.cpp | 10 ++++++++-- src/ast/fpa_decl_plugin.h | 3 +++ src/ast/rewriter/fpa_rewriter.cpp | 6 ++++-- 7 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/ast/fpa/bv2fpa_converter.cpp b/src/ast/fpa/bv2fpa_converter.cpp index 0d796004f1e..49f9abacdc2 100644 --- a/src/ast/fpa/bv2fpa_converter.cpp +++ b/src/ast/fpa/bv2fpa_converter.cpp @@ -312,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); diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 8a58cfcd1c1..de0b699466f 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -3429,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); diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index 3e49889fb2c..3a1f2ec50f9 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -141,6 +141,8 @@ class fpa2bv_converter { 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); diff --git a/src/ast/fpa/fpa2bv_rewriter.cpp b/src/ast/fpa/fpa2bv_rewriter.cpp index 80b578c07e1..68a5cd784c6 100644 --- a/src/ast/fpa/fpa2bv_rewriter.cpp +++ b/src/ast/fpa/fpa2bv_rewriter.cpp @@ -146,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; diff --git a/src/ast/fpa_decl_plugin.cpp b/src/ast/fpa_decl_plugin.cpp index 7c9c8deba1d..2dca61a3928 100644 --- a/src/ast/fpa_decl_plugin.cpp +++ b/src/ast/fpa_decl_plugin.cpp @@ -778,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); @@ -852,6 +854,8 @@ void fpa_decl_plugin::get_op_names(svector & 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)); @@ -1070,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(); diff --git a/src/ast/fpa_decl_plugin.h b/src/ast/fpa_decl_plugin.h index 2d7edca8ad2..ef0a1882ce5 100644 --- a/src/ast/fpa_decl_plugin.h +++ b/src/ast/fpa_decl_plugin.h @@ -84,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, diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index ae5710b361a..e135268d690 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -88,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;