From f84d6bf5bb2c031478dfa72c10bcbb957995dc7f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" <cwinter@microsoft.com> Date: Fri, 12 Jun 2015 12:58:07 +0100 Subject: [PATCH 1/2] Bugfix for QF_FP tactic --- src/tactic/fpa/qffp_tactic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tactic/fpa/qffp_tactic.cpp b/src/tactic/fpa/qffp_tactic.cpp index fbce1668e..485e837ee 100644 --- a/src/tactic/fpa/qffp_tactic.cpp +++ b/src/tactic/fpa/qffp_tactic.cpp @@ -53,7 +53,7 @@ struct has_fp_to_real_predicate { class has_fp_to_real_probe : public probe { public: virtual result operator()(goal const & g) { - return !test<has_fp_to_real_predicate>(g); + return test<has_fp_to_real_predicate>(g); } virtual ~has_fp_to_real_probe() {} From 6980fb3035c08905d1de7cada591843cd4dd5448 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" <cwinter@microsoft.com> Date: Fri, 12 Jun 2015 12:58:19 +0100 Subject: [PATCH 2/2] Bugfix for distinct of floats. --- src/ast/fpa/fpa2bv_converter.cpp | 14 ++++++++++++++ src/ast/fpa/fpa2bv_converter.h | 1 + src/ast/fpa/fpa2bv_rewriter.h | 11 +++++++++-- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 4c199ebc6..baba7b701 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -93,6 +93,20 @@ void fpa2bv_converter::mk_ite(expr * c, expr * t, expr * f, expr_ref & result) { mk_fp(sgn, e, s, result); } +void fpa2bv_converter::mk_distinct(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + // Note: in SMT there is only one NaN, so multiple of them are considered + // equal, thus (distinct NaN NaN) is false, even if the two NaNs have + // different bitwise representations (see also mk_eq). + result = m.mk_true(); + for (unsigned i = 0; i < num; i++) { + for (unsigned j = i+1; j < num; j++) { + expr_ref eq(m); + mk_eq(args[i], args[j], eq); + m_simp.mk_and(result, m.mk_not(eq), result); + } + } +} + void fpa2bv_converter::mk_numeral(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 0); SASSERT(f->get_num_parameters() == 1); diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index 4b3c1a6ca..b0881a364 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -80,6 +80,7 @@ public: void mk_eq(expr * a, expr * b, expr_ref & result); void mk_ite(expr * c, expr * t, expr * f, expr_ref & result); + void mk_distinct(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_rounding_mode(func_decl * f, expr_ref & result); void mk_numeral(func_decl * f, unsigned num, expr * const * args, expr_ref & result); diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index ed885a4cc..fa88c227c 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -103,8 +103,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { } return BR_FAILED; } - - if (m().is_ite(f)) { + else if (m().is_ite(f)) { SASSERT(num == 3); if (m_conv.is_float(args[1])) { m_conv.mk_ite(args[0], args[1], args[2], result); @@ -112,6 +111,14 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { } return BR_FAILED; } + else if (m().is_distinct(f)) { + sort * ds = f->get_domain()[0]; + if (m_conv.is_float(ds) || m_conv.is_rm(ds)) { + m_conv.mk_distinct(f, num, args, result); + return BR_DONE; + } + return BR_FAILED; + } if (m_conv.is_float_family(f)) { switch (f->get_decl_kind()) {