mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 17:45:32 +00:00
Bugfixes for model verification of unspecified values of fp.min/fp.max
This commit is contained in:
parent
14d2356a32
commit
92152b16ca
6 changed files with 131 additions and 113 deletions
|
@ -45,6 +45,15 @@ void fpa2bv_model_converter::display(std::ostream & out) {
|
|||
unsigned indent = n.size() + 4;
|
||||
out << mk_ismt2_pp(it->m_value, m, indent) << ")";
|
||||
}
|
||||
for (obj_map<func_decl, std::pair<app*, app*> >::iterator it = m_specials.begin();
|
||||
it != m_specials.end();
|
||||
it++) {
|
||||
const symbol & n = it->m_key->get_name();
|
||||
out << "\n (" << n << " ";
|
||||
unsigned indent = n.size() + 4;
|
||||
out << mk_ismt2_pp(it->m_value.first, m, indent) << "; " <<
|
||||
mk_ismt2_pp(it->m_value.second, m, indent) << ")";
|
||||
}
|
||||
out << ")" << std::endl;
|
||||
}
|
||||
|
||||
|
@ -79,12 +88,16 @@ model_converter * fpa2bv_model_converter::translate(ast_translation & translator
|
|||
translator.to().inc_ref(k);
|
||||
translator.to().inc_ref(v);
|
||||
}
|
||||
for (obj_hashtable<func_decl>::iterator it = m_decls_to_hide.begin();
|
||||
it != m_decls_to_hide.end();
|
||||
for (obj_map<func_decl, std::pair<app*, app*> >::iterator it = m_specials.begin();
|
||||
it != m_specials.end();
|
||||
it++) {
|
||||
func_decl * k = translator(*it);
|
||||
res->m_decls_to_hide.insert(k);
|
||||
func_decl * k = translator(it->m_key);
|
||||
app * v1 = translator(it->m_value.first);
|
||||
app * v2 = translator(it->m_value.second);
|
||||
res->m_specials.insert(k, std::pair<app*, app*>(v1, v2));
|
||||
translator.to().inc_ref(k);
|
||||
translator.to().inc_ref(v1);
|
||||
translator.to().inc_ref(v2);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -217,10 +230,29 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) {
|
|||
|
||||
obj_hashtable<func_decl> seen;
|
||||
|
||||
for (obj_hashtable<func_decl>::iterator it = m_decls_to_hide.begin();
|
||||
it != m_decls_to_hide.end();
|
||||
it++)
|
||||
seen.insert(*it);
|
||||
for (obj_map<func_decl, std::pair<app*, app*> >::iterator it = m_specials.begin();
|
||||
it != m_specials.end();
|
||||
it++) {
|
||||
func_decl * f = it->m_key;
|
||||
expr_ref pzero(m), nzero(m);
|
||||
pzero = fu.mk_pzero(f->get_range());
|
||||
nzero = fu.mk_nzero(f->get_range());
|
||||
|
||||
expr_ref pn(m), np(m);
|
||||
bv_mdl->eval(it->m_value.first, pn, true);
|
||||
bv_mdl->eval(it->m_value.second, np, true);
|
||||
seen.insert(it->m_value.first->get_decl());
|
||||
seen.insert(it->m_value.second->get_decl());
|
||||
|
||||
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, (m.is_true(pn) ? nzero : pzero));
|
||||
flt_fi->set_else(m.is_true(np) ? nzero : pzero);
|
||||
|
||||
float_mdl->register_decl(f, flt_fi);
|
||||
TRACE("fpa2bv_mc", tout << "fp.min/fp.max special: " << std::endl <<
|
||||
mk_ismt2_pp(f, m) << " == " << mk_ismt2_pp(flt_fi->get_interp(), m) << std::endl;);
|
||||
}
|
||||
|
||||
for (obj_map<func_decl, expr*>::iterator it = m_const2bv.begin();
|
||||
it != m_const2bv.end();
|
||||
|
@ -362,10 +394,6 @@ void fpa2bv_model_converter::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,
|
||||
obj_map<func_decl, func_decl*> const & uf2bvuf,
|
||||
obj_hashtable<func_decl> const & decls_to_hide) {
|
||||
return alloc(fpa2bv_model_converter, m, const2bv, rm_const2bv, uf2bvuf, decls_to_hide);
|
||||
model_converter * mk_fpa2bv_model_converter(ast_manager & m, fpa2bv_converter const & conv) {
|
||||
return alloc(fpa2bv_model_converter, m, conv);
|
||||
}
|
||||
|
|
|
@ -27,44 +27,41 @@ class fpa2bv_model_converter : public model_converter {
|
|||
obj_map<func_decl, expr*> m_const2bv;
|
||||
obj_map<func_decl, expr*> m_rm_const2bv;
|
||||
obj_map<func_decl, func_decl*> m_uf2bvuf;
|
||||
obj_hashtable<func_decl> m_decls_to_hide;
|
||||
obj_map<func_decl, std::pair<app*, app*> > m_specials;
|
||||
|
||||
public:
|
||||
fpa2bv_model_converter(ast_manager & m, obj_map<func_decl, expr*> const & const2bv,
|
||||
obj_map<func_decl, expr*> const & rm_const2bv,
|
||||
obj_map<func_decl, func_decl*> const & uf2bvuf,
|
||||
obj_hashtable<func_decl> const & decls_to_hide) :
|
||||
m(m) {
|
||||
for (obj_map<func_decl, expr*>::iterator it = const2bv.begin();
|
||||
it != const2bv.end();
|
||||
fpa2bv_model_converter(ast_manager & m, fpa2bv_converter const & conv) : m(m) {
|
||||
for (obj_map<func_decl, expr*>::iterator it = conv.m_const2bv.begin();
|
||||
it != conv.m_const2bv.end();
|
||||
it++)
|
||||
{
|
||||
m_const2bv.insert(it->m_key, it->m_value);
|
||||
m.inc_ref(it->m_key);
|
||||
m.inc_ref(it->m_value);
|
||||
}
|
||||
for (obj_map<func_decl, expr*>::iterator it = rm_const2bv.begin();
|
||||
it != rm_const2bv.end();
|
||||
for (obj_map<func_decl, expr*>::iterator it = conv.m_rm_const2bv.begin();
|
||||
it != conv.m_rm_const2bv.end();
|
||||
it++)
|
||||
{
|
||||
m_rm_const2bv.insert(it->m_key, it->m_value);
|
||||
m.inc_ref(it->m_key);
|
||||
m.inc_ref(it->m_value);
|
||||
}
|
||||
for (obj_map<func_decl, func_decl*>::iterator it = uf2bvuf.begin();
|
||||
it != uf2bvuf.end();
|
||||
for (obj_map<func_decl, func_decl*>::iterator it = conv.m_uf2bvuf.begin();
|
||||
it != conv.m_uf2bvuf.end();
|
||||
it++)
|
||||
{
|
||||
m_uf2bvuf.insert(it->m_key, it->m_value);
|
||||
m.inc_ref(it->m_key);
|
||||
m.inc_ref(it->m_value);
|
||||
}
|
||||
for (obj_hashtable<func_decl>::iterator it = decls_to_hide.begin();
|
||||
it != decls_to_hide.end();
|
||||
it++)
|
||||
{
|
||||
m_decls_to_hide.insert(*it);
|
||||
m.inc_ref(*it);
|
||||
for (obj_map<func_decl, std::pair<app*, app*> >::iterator it = conv.m_specials.begin();
|
||||
it != conv.m_specials.end();
|
||||
it++) {
|
||||
m_specials.insert(it->m_key, it->m_value);
|
||||
m.inc_ref(it->m_key);
|
||||
m.inc_ref(it->m_value.first);
|
||||
m.inc_ref(it->m_value.second);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,7 +69,13 @@ public:
|
|||
dec_ref_map_key_values(m, m_const2bv);
|
||||
dec_ref_map_key_values(m, m_rm_const2bv);
|
||||
dec_ref_map_key_values(m, m_uf2bvuf);
|
||||
dec_ref_collection_values(m, m_decls_to_hide);
|
||||
for (obj_map<func_decl, std::pair<app*, app*> >::iterator it = m_specials.begin();
|
||||
it != m_specials.end();
|
||||
it++) {
|
||||
m.dec_ref(it->m_key);
|
||||
m.dec_ref(it->m_value.first);
|
||||
m.dec_ref(it->m_value.second);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void operator()(model_ref & md, unsigned goal_idx) {
|
||||
|
@ -92,7 +95,7 @@ public:
|
|||
virtual model_converter * translate(ast_translation & translator);
|
||||
|
||||
protected:
|
||||
fpa2bv_model_converter(ast_manager & m) : m(m) { }
|
||||
fpa2bv_model_converter(ast_manager & m) : m(m){ }
|
||||
|
||||
void convert(model * bv_mdl, model * float_mdl);
|
||||
expr_ref convert_bv2fp(sort * s, expr * sgn, expr * exp, expr * sig) const;
|
||||
|
@ -102,10 +105,6 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
model_converter * mk_fpa2bv_model_converter(ast_manager & m,
|
||||
obj_map<func_decl, expr*> const & const2bv,
|
||||
obj_map<func_decl, expr*> const & rm_const2bv,
|
||||
obj_map<func_decl, func_decl*> const & uf2bvuf,
|
||||
obj_hashtable<func_decl> const & decls_to_hide);
|
||||
model_converter * mk_fpa2bv_model_converter(ast_manager & m, fpa2bv_converter const & conv);
|
||||
|
||||
#endif
|
|
@ -43,26 +43,26 @@ class fpa2bv_tactic : public tactic {
|
|||
}
|
||||
|
||||
void updt_params(params_ref const & p) {
|
||||
m_rw.cfg().updt_params(p);
|
||||
m_rw.cfg().updt_params(p);
|
||||
}
|
||||
|
||||
|
||||
void set_cancel(bool f) {
|
||||
m_rw.set_cancel(f);
|
||||
}
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
m_proofs_enabled = g->proofs_enabled();
|
||||
m_produce_models = g->models_enabled();
|
||||
m_produce_unsat_cores = g->unsat_core_enabled();
|
||||
|
||||
|
||||
mc = 0; pc = 0; core = 0; result.reset();
|
||||
tactic_report report("fpa2bv", *g);
|
||||
m_rw.reset();
|
||||
m_rw.reset();
|
||||
|
||||
TRACE("fpa2bv", tout << "BEFORE: " << std::endl; g->display(tout););
|
||||
|
||||
|
@ -70,7 +70,7 @@ class fpa2bv_tactic : public tactic {
|
|||
result.push_back(g.get());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_num_steps = 0;
|
||||
expr_ref new_curr(m);
|
||||
proof_ref new_pr(m);
|
||||
|
@ -91,7 +91,7 @@ class fpa2bv_tactic : public tactic {
|
|||
const app * a = to_app(new_curr.get());
|
||||
if (a->get_family_id() == m_conv.fu().get_family_id() &&
|
||||
a->get_decl_kind() == OP_FPA_IS_NAN) {
|
||||
// Inject auxiliary lemmas that fix e to the one and only NaN value,
|
||||
// Inject auxiliary lemmas that fix e to the one and only NaN value,
|
||||
// that is (= e (fp #b0 #b1...1 #b0...01)), so that the value propagation
|
||||
// has a value to propagate.
|
||||
expr * sgn, *sig, *exp;
|
||||
|
@ -104,8 +104,8 @@ class fpa2bv_tactic : public tactic {
|
|||
}
|
||||
}
|
||||
|
||||
if (g->models_enabled())
|
||||
mc = mk_fpa2bv_model_converter(m, m_conv.const2bv(), m_conv.rm_const2bv(), m_conv.uf2bvuf(), m_conv.decls_to_hide());
|
||||
if (g->models_enabled())
|
||||
mc = mk_fpa2bv_model_converter(m, m_conv);
|
||||
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
|
@ -114,7 +114,7 @@ class fpa2bv_tactic : public tactic {
|
|||
result.back()->assert_expr(m_conv.m_extra_assertions[i].get());
|
||||
|
||||
SASSERT(g->is_well_sorted());
|
||||
TRACE("fpa2bv", tout << "AFTER: " << std::endl; g->display(tout);
|
||||
TRACE("fpa2bv", tout << "AFTER: " << std::endl; g->display(tout);
|
||||
if (mc) mc->display(tout); tout << std::endl; );
|
||||
}
|
||||
};
|
||||
|
@ -141,12 +141,12 @@ public:
|
|||
m_imp->updt_params(p);
|
||||
}
|
||||
|
||||
virtual void collect_param_descrs(param_descrs & r) {
|
||||
virtual void collect_param_descrs(param_descrs & r) {
|
||||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
try {
|
||||
|
@ -156,8 +156,8 @@ public:
|
|||
throw tactic_exception(ex.msg());
|
||||
}
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
|
||||
virtual void cleanup() {
|
||||
imp * d = alloc(imp, m_imp->m, m_params);
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
|
@ -173,6 +173,6 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
tactic * mk_fpa2bv_tactic(ast_manager & m, params_ref const & p) {
|
||||
tactic * mk_fpa2bv_tactic(ast_manager & m, params_ref const & p) {
|
||||
return clean(alloc(fpa2bv_tactic, m, p));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue