mirror of
https://github.com/Z3Prover/z3
synced 2025-06-30 09:58:46 +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:
parent
75eca46d93
commit
6f3850bfbc
5 changed files with 397 additions and 295 deletions
|
@ -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())) {
|
if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) {
|
||||||
m_manager->raise_exception("expecting two integer parameters to floating point sort");
|
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());
|
return mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
|
||||||
case ROUNDING_MODE_SORT:
|
case ROUNDING_MODE_SORT:
|
||||||
return mk_rm_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);
|
sort * fp = mk_float_sort(domain[2]->get_parameter(0).get_int(), domain[1]->get_parameter(0).get_int()+1);
|
||||||
symbol name("asFloat");
|
symbol name("asFloat");
|
||||||
return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
|
return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// .. Otherwise we only know how to convert rationals/reals.
|
// .. Otherwise we only know how to convert rationals/reals.
|
||||||
if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int()))
|
if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int()))
|
||||||
m_manager->raise_exception("expecting two integer parameters to asFloat");
|
m_manager->raise_exception("expecting two integer parameters to asFloat");
|
||||||
if (arity != 2 && arity != 3)
|
if (arity != 2 && arity != 3)
|
||||||
m_manager->raise_exception("invalid number of arguments to asFloat operator");
|
m_manager->raise_exception("invalid number of arguments to asFloat operator");
|
||||||
if (!is_rm_sort(domain[0]) || domain[1] != m_real_sort)
|
if (!is_rm_sort(domain[0]) || domain[1] != m_real_sort)
|
||||||
m_manager->raise_exception("sort mismatch");
|
m_manager->raise_exception("sort mismatch");
|
||||||
if (arity == 2) {
|
if (arity == 2) {
|
||||||
sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
|
sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -35,13 +35,13 @@ class fpa2bv_converter {
|
||||||
ast_manager & m;
|
ast_manager & m;
|
||||||
basic_simplifier_plugin m_simp;
|
basic_simplifier_plugin m_simp;
|
||||||
float_util m_util;
|
float_util m_util;
|
||||||
mpf_manager & m_mpf_manager;
|
mpf_manager & m_mpf_manager;
|
||||||
unsynch_mpz_manager & m_mpz_manager;
|
unsynch_mpz_manager & m_mpz_manager;
|
||||||
bv_util m_bv_util;
|
bv_util m_bv_util;
|
||||||
float_decl_plugin * m_plugin;
|
float_decl_plugin * m_plugin;
|
||||||
|
|
||||||
obj_map<func_decl, expr*> m_const2bv;
|
obj_map<func_decl, expr*> m_const2bv;
|
||||||
obj_map<func_decl, expr*> m_rm_const2bv;
|
obj_map<func_decl, expr*> m_rm_const2bv;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
fpa2bv_converter(ast_manager & m);
|
fpa2bv_converter(ast_manager & m);
|
||||||
|
@ -52,22 +52,22 @@ public:
|
||||||
bool is_float(sort * s) { return m_util.is_float(s); }
|
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(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_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) {
|
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(sign) && m_bv_util.get_bv_size(sign) == 1);
|
||||||
SASSERT(m_bv_util.is_bv(significand));
|
SASSERT(m_bv_util.is_bv(significand));
|
||||||
SASSERT(m_bv_util.is_bv(exponent));
|
SASSERT(m_bv_util.is_bv(exponent));
|
||||||
result = m.mk_app(m_util.get_family_id(), OP_TO_FLOAT, sign, significand, 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_eq(expr * a, expr * b, expr_ref & result);
|
||||||
void mk_ite(expr * c, expr * t, expr * f, 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_value(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
|
||||||
void mk_const(func_decl * f, 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_plus_inf(func_decl * f, expr_ref & result);
|
||||||
void mk_minus_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_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);
|
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);
|
void dbg_decouple(const char * prefix, expr_ref & e);
|
||||||
expr_ref_vector extra_assertions;
|
expr_ref_vector extra_assertions;
|
||||||
|
@ -122,11 +123,11 @@ protected:
|
||||||
void mk_is_denormal(expr * e, expr_ref & result);
|
void mk_is_denormal(expr * e, expr_ref & result);
|
||||||
void mk_is_normal(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_top_exp(unsigned sz, expr_ref & result);
|
||||||
void mk_bot_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_max_exp(unsigned ebits, expr_ref & result);
|
||||||
|
|
||||||
void mk_leading_zeros(expr * e, unsigned max_bits, expr_ref & result);
|
void mk_leading_zeros(expr * e, unsigned max_bits, expr_ref & result);
|
||||||
|
@ -146,11 +147,11 @@ protected:
|
||||||
class fpa2bv_model_converter : public model_converter {
|
class fpa2bv_model_converter : public model_converter {
|
||||||
ast_manager & m;
|
ast_manager & m;
|
||||||
obj_map<func_decl, expr*> m_const2bv;
|
obj_map<func_decl, expr*> m_const2bv;
|
||||||
obj_map<func_decl, expr*> m_rm_const2bv;
|
obj_map<func_decl, expr*> m_rm_const2bv;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
fpa2bv_model_converter(ast_manager & m, obj_map<func_decl, expr*> & const2bv,
|
fpa2bv_model_converter(ast_manager & m, obj_map<func_decl, expr*> const & const2bv,
|
||||||
obj_map<func_decl, expr*> & rm_const2bv) :
|
obj_map<func_decl, expr*> const & rm_const2bv) :
|
||||||
m(m) {
|
m(m) {
|
||||||
// Just create a copy?
|
// Just create a copy?
|
||||||
for (obj_map<func_decl, expr*>::iterator it = const2bv.begin();
|
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_key);
|
||||||
m.inc_ref(it->m_value);
|
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 != rm_const2bv.end();
|
||||||
it++)
|
it++)
|
||||||
{
|
{
|
||||||
|
@ -173,7 +174,7 @@ public:
|
||||||
|
|
||||||
virtual ~fpa2bv_model_converter() {
|
virtual ~fpa2bv_model_converter() {
|
||||||
dec_ref_map_key_values(m, m_const2bv);
|
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) {
|
virtual void operator()(model_ref & md, unsigned goal_idx) {
|
||||||
|
@ -198,4 +199,9 @@ protected:
|
||||||
void convert(model * bv_mdl, model * float_mdl);
|
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
|
#endif
|
||||||
|
|
|
@ -73,7 +73,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg {
|
||||||
return BR_DONE;
|
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);
|
m_conv.mk_rm_const(f, result);
|
||||||
return BR_DONE;
|
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_NEAREST_TIES_TO_EVEN:
|
||||||
case OP_RM_TOWARD_NEGATIVE:
|
case OP_RM_TOWARD_NEGATIVE:
|
||||||
case OP_RM_TOWARD_POSITIVE:
|
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_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_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;
|
case OP_FLOAT_MINUS_INF: m_conv.mk_minus_inf(f, result); return BR_DONE;
|
||||||
|
|
|
@ -90,7 +90,7 @@ class fpa2bv_tactic : public tactic {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g->models_enabled())
|
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();
|
g->inc_depth();
|
||||||
result.push_back(g.get());
|
result.push_back(g.get());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue