3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 13:28:47 +00:00

FPA bug and leak fixes (thanks to Gabriele Paganelli)

Signed-off-by: Christoph M. Wintersteiger <cwinter@microsoft.com>
This commit is contained in:
Christoph M. Wintersteiger 2013-02-28 18:46:29 +00:00
parent 75eca46d93
commit 6f3850bfbc
5 changed files with 397 additions and 295 deletions

View file

@ -151,6 +151,10 @@ sort * float_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, paramete
if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) {
m_manager->raise_exception("expecting two integer parameters to floating point sort");
}
if (parameters[0].get_int() <= 1 || parameters[1].get_int() <= 1)
m_manager->raise_exception("floating point sorts need parameters > 1");
if (parameters[0].get_int() > parameters[1].get_int())
m_manager->raise_exception("floating point sorts with ebits > sbits are currently not supported");
return mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
case ROUNDING_MODE_SORT:
return mk_rm_sort();
@ -349,14 +353,14 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters,
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));
}
}
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)
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("invalid number of arguments to asFloat operator");
if (!is_rm_sort(domain[0]) || domain[1] != m_real_sort)
m_manager->raise_exception("sort mismatch");
if (arity == 2) {
sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());

File diff suppressed because it is too large Load diff

View file

@ -35,13 +35,13 @@ class fpa2bv_converter {
ast_manager & m;
basic_simplifier_plugin m_simp;
float_util m_util;
mpf_manager & m_mpf_manager;
unsynch_mpz_manager & m_mpz_manager;
mpf_manager & m_mpf_manager;
unsynch_mpz_manager & m_mpz_manager;
bv_util m_bv_util;
float_decl_plugin * m_plugin;
obj_map<func_decl, expr*> m_const2bv;
obj_map<func_decl, expr*> m_rm_const2bv;
obj_map<func_decl, expr*> m_rm_const2bv;
public:
fpa2bv_converter(ast_manager & m);
@ -52,22 +52,22 @@ public:
bool is_float(sort * s) { return m_util.is_float(s); }
bool is_float(expr * e) { return is_app(e) && m_util.is_float(to_app(e)->get_decl()->get_range()); }
bool is_float_family(func_decl * f) { return f->get_family_id() == m_util.get_family_id(); }
bool is_rm_sort(sort * s) { return m_util.is_rm(s); }
bool is_rm_sort(sort * s) { return m_util.is_rm(s); }
void mk_triple(expr * sign, expr * significand, expr * exponent, expr_ref & result) {
SASSERT(m_bv_util.is_bv(sign) && m_bv_util.get_bv_size(sign) == 1);
SASSERT(m_bv_util.is_bv(significand));
SASSERT(m_bv_util.is_bv(exponent));
SASSERT(m_bv_util.is_bv(sign) && m_bv_util.get_bv_size(sign) == 1);
SASSERT(m_bv_util.is_bv(significand));
SASSERT(m_bv_util.is_bv(exponent));
result = m.mk_app(m_util.get_family_id(), OP_TO_FLOAT, sign, significand, exponent);
}
void mk_eq(expr * a, expr * b, expr_ref & result);
void mk_ite(expr * c, expr * t, expr * f, expr_ref & result);
void mk_rounding_mode(func_decl * f, expr_ref & result);
void mk_rounding_mode(func_decl * f, expr_ref & result);
void mk_value(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
void mk_const(func_decl * f, expr_ref & result);
void mk_rm_const(func_decl * f, expr_ref & result);
void mk_rm_const(func_decl * f, expr_ref & result);
void mk_plus_inf(func_decl * f, expr_ref & result);
void mk_minus_inf(func_decl * f, expr_ref & result);
@ -102,7 +102,8 @@ public:
void mk_to_float(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
void mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
fpa2bv_model_converter * mk_model_converter();
obj_map<func_decl, expr*> const & const2bv() const { return m_const2bv; }
obj_map<func_decl, expr*> const & rm_const2bv() const { return m_rm_const2bv; }
void dbg_decouple(const char * prefix, expr_ref & e);
expr_ref_vector extra_assertions;
@ -122,11 +123,11 @@ protected:
void mk_is_denormal(expr * e, expr_ref & result);
void mk_is_normal(expr * e, expr_ref & result);
void mk_is_rm(expr * e, BV_RM_VAL rm, expr_ref & result);
void mk_is_rm(expr * e, BV_RM_VAL rm, expr_ref & result);
void mk_top_exp(unsigned sz, expr_ref & result);
void mk_bot_exp(unsigned sz, expr_ref & result);
void mk_min_exp(unsigned ebits, expr_ref & result);
void mk_min_exp(unsigned ebits, expr_ref & result);
void mk_max_exp(unsigned ebits, expr_ref & result);
void mk_leading_zeros(expr * e, unsigned max_bits, expr_ref & result);
@ -135,7 +136,7 @@ protected:
void mk_unbias(expr * e, expr_ref & result);
void unpack(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref & exp, bool normalize);
void round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & sig, expr_ref & exp, expr_ref & result);
void round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & sig, expr_ref & exp, expr_ref & result);
void add_core(unsigned sbits, unsigned ebits, expr_ref & rm,
expr_ref & c_sgn, expr_ref & c_sig, expr_ref & c_exp, expr_ref & d_sgn, expr_ref & d_sig, expr_ref & d_exp,
@ -146,11 +147,11 @@ protected:
class fpa2bv_model_converter : public model_converter {
ast_manager & m;
obj_map<func_decl, expr*> m_const2bv;
obj_map<func_decl, expr*> m_rm_const2bv;
obj_map<func_decl, expr*> m_rm_const2bv;
public:
fpa2bv_model_converter(ast_manager & m, obj_map<func_decl, expr*> & const2bv,
obj_map<func_decl, expr*> & rm_const2bv) :
fpa2bv_model_converter(ast_manager & m, obj_map<func_decl, expr*> const & const2bv,
obj_map<func_decl, expr*> const & rm_const2bv) :
m(m) {
// Just create a copy?
for (obj_map<func_decl, expr*>::iterator it = const2bv.begin();
@ -161,7 +162,7 @@ public:
m.inc_ref(it->m_key);
m.inc_ref(it->m_value);
}
for (obj_map<func_decl, expr*>::iterator it = rm_const2bv.begin();
for (obj_map<func_decl, expr*>::iterator it = rm_const2bv.begin();
it != rm_const2bv.end();
it++)
{
@ -173,7 +174,7 @@ public:
virtual ~fpa2bv_model_converter() {
dec_ref_map_key_values(m, m_const2bv);
dec_ref_map_key_values(m, m_rm_const2bv);
dec_ref_map_key_values(m, m_rm_const2bv);
}
virtual void operator()(model_ref & md, unsigned goal_idx) {
@ -198,4 +199,9 @@ protected:
void convert(model * bv_mdl, model * float_mdl);
};
model_converter * mk_fpa2bv_model_converter(ast_manager & m,
obj_map<func_decl, expr*> const & const2bv,
obj_map<func_decl, expr*> const & rm_const2bv);
#endif

View file

@ -73,7 +73,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg {
return BR_DONE;
}
if (num == 0 && f->get_family_id() == null_family_id && m_conv.is_rm_sort(f->get_range())) {
if (num == 0 && f->get_family_id() == null_family_id && m_conv.is_rm_sort(f->get_range())) {
m_conv.mk_rm_const(f, result);
return BR_DONE;
}
@ -102,7 +102,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg {
case OP_RM_NEAREST_TIES_TO_EVEN:
case OP_RM_TOWARD_NEGATIVE:
case OP_RM_TOWARD_POSITIVE:
case OP_RM_TOWARD_ZERO: m_conv.mk_rounding_mode(f, result); return BR_DONE;
case OP_RM_TOWARD_ZERO: m_conv.mk_rounding_mode(f, result); return BR_DONE;
case OP_FLOAT_VALUE: m_conv.mk_value(f, num, args, result); return BR_DONE;
case OP_FLOAT_PLUS_INF: m_conv.mk_plus_inf(f, result); return BR_DONE;
case OP_FLOAT_MINUS_INF: m_conv.mk_minus_inf(f, result); return BR_DONE;

View file

@ -90,7 +90,7 @@ class fpa2bv_tactic : public tactic {
}
if (g->models_enabled())
mc = m_conv.mk_model_converter();
mc = mk_fpa2bv_model_converter(m, m_conv.const2bv(), m_conv.rm_const2bv());
g->inc_depth();
result.push_back(g.get());