mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 09:35:32 +00:00
Merge branch 'unstable' of https://git01.codeplex.com/z3 into fpa-api
Conflicts: scripts/mk_project.py src/api/z3.h src/ast/float_decl_plugin.cpp src/ast/float_decl_plugin.h src/ast/fpa/fpa2bv_converter.cpp src/ast/fpa/fpa2bv_rewriter.h src/ast/rewriter/float_rewriter.cpp src/ast/rewriter/float_rewriter.h Signed-off-by: Christoph M. Wintersteiger <cwinter@microsoft.com>
This commit is contained in:
commit
8d3ef92383
240 changed files with 4848 additions and 2395 deletions
|
@ -41,7 +41,7 @@ void float_decl_plugin::set_manager(ast_manager * m, family_id id) {
|
|||
m_manager->inc_ref(m_int_sort);
|
||||
|
||||
// BV is not optional anymore.
|
||||
SASSERT(m_manager->has_plugin(symbol("bv")));
|
||||
SASSERT(m_manager->has_plugin(symbol("bv")));
|
||||
m_bv_fid = m_manager->mk_family_id("bv");
|
||||
m_bv_plugin = static_cast<bv_decl_plugin*>(m_manager->get_plugin(m_bv_fid));
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ func_decl * float_decl_plugin::mk_bin_rel_decl(decl_kind k, unsigned num_paramet
|
|||
if (arity != 2)
|
||||
m_manager->raise_exception("invalid number of arguments to floating point relation");
|
||||
if (domain[0] != domain[1] || !is_float_sort(domain[0]))
|
||||
m_manager->raise_exception("sort mismatch");
|
||||
m_manager->raise_exception("sort mismatch, expected equal FloatingPoint sorts as arguments");
|
||||
symbol name;
|
||||
switch (k) {
|
||||
case OP_FLOAT_EQ: name = "fp.eq"; break;
|
||||
|
@ -290,7 +290,7 @@ func_decl * float_decl_plugin::mk_unary_rel_decl(decl_kind k, unsigned num_param
|
|||
if (arity != 1)
|
||||
m_manager->raise_exception("invalid number of arguments to floating point relation");
|
||||
if (!is_float_sort(domain[0]))
|
||||
m_manager->raise_exception("sort mismatch");
|
||||
m_manager->raise_exception("sort mismatch, expected argument of FloatingPoint sort");
|
||||
symbol name;
|
||||
switch (k) {
|
||||
case OP_FLOAT_IS_ZERO: name = "fp.isZero"; break;
|
||||
|
@ -314,11 +314,11 @@ func_decl * float_decl_plugin::mk_unary_decl(decl_kind k, unsigned num_parameter
|
|||
if (arity != 1)
|
||||
m_manager->raise_exception("invalid number of arguments to floating point operator");
|
||||
if (!is_float_sort(domain[0]))
|
||||
m_manager->raise_exception("sort mismatch");
|
||||
m_manager->raise_exception("sort mismatch, expected argument of FloatingPoint sort");
|
||||
symbol name;
|
||||
switch (k) {
|
||||
case OP_FLOAT_ABS: name = "fp.abs"; break;
|
||||
case OP_FLOAT_NEG: name = "fp.neg"; break;
|
||||
case OP_FLOAT_ABS: name = "fp.abs"; break;
|
||||
case OP_FLOAT_NEG: name = "fp.neg"; break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
@ -331,12 +331,12 @@ func_decl * float_decl_plugin::mk_binary_decl(decl_kind k, unsigned num_paramete
|
|||
if (arity != 2)
|
||||
m_manager->raise_exception("invalid number of arguments to floating point operator");
|
||||
if (domain[0] != domain[1] || !is_float_sort(domain[0]))
|
||||
m_manager->raise_exception("sort mismatch");
|
||||
m_manager->raise_exception("sort mismatch, expected arguments of equal FloatingPoint sorts");
|
||||
symbol name;
|
||||
switch (k) {
|
||||
case OP_FLOAT_REM: name = "fp.rem"; break;
|
||||
case OP_FLOAT_MIN: name = "fp.min"; break;
|
||||
case OP_FLOAT_MAX: name = "fp.max"; break;
|
||||
case OP_FLOAT_REM: name = "fp.rem"; break;
|
||||
case OP_FLOAT_MIN: name = "fp.min"; break;
|
||||
case OP_FLOAT_MAX: name = "fp.max"; break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
@ -348,8 +348,10 @@ func_decl * float_decl_plugin::mk_rm_binary_decl(decl_kind k, unsigned num_param
|
|||
unsigned arity, sort * const * domain, sort * range) {
|
||||
if (arity != 3)
|
||||
m_manager->raise_exception("invalid number of arguments to floating point operator");
|
||||
if (!is_rm_sort(domain[0]) || domain[1] != domain[2] || !is_float_sort(domain[1]))
|
||||
m_manager->raise_exception("sort mismatch");
|
||||
if (!is_rm_sort(domain[0]))
|
||||
m_manager->raise_exception("sort mismatch, expected first argument of RoundingMode sort");
|
||||
if (domain[1] != domain[2] || !is_float_sort(domain[1]))
|
||||
m_manager->raise_exception("sort mismatch, expected arguments 1 and 2 of equal FloatingPoint sorts");
|
||||
symbol name;
|
||||
switch (k) {
|
||||
case OP_FLOAT_ADD: name = "fp.add"; break;
|
||||
|
@ -367,8 +369,10 @@ func_decl * float_decl_plugin::mk_rm_unary_decl(decl_kind k, unsigned num_parame
|
|||
unsigned arity, sort * const * domain, sort * range) {
|
||||
if (arity != 2)
|
||||
m_manager->raise_exception("invalid number of arguments to floating point operator");
|
||||
if (!is_rm_sort(domain[0]) || !is_float_sort(domain[1]))
|
||||
m_manager->raise_exception("sort mismatch");
|
||||
if (!is_rm_sort(domain[0]))
|
||||
m_manager->raise_exception("sort mismatch, expected RoundingMode as first argument");
|
||||
if (!is_float_sort(domain[1]))
|
||||
m_manager->raise_exception("sort mismatch, expected FloatingPoint as second argument");
|
||||
symbol name;
|
||||
switch (k) {
|
||||
case OP_FLOAT_SQRT: name = "fp.sqrt"; break;
|
||||
|
@ -384,8 +388,10 @@ func_decl * float_decl_plugin::mk_fma(decl_kind k, unsigned num_parameters, para
|
|||
unsigned arity, sort * const * domain, sort * range) {
|
||||
if (arity != 4)
|
||||
m_manager->raise_exception("invalid number of arguments to fused_ma operator");
|
||||
if (!is_rm_sort(domain[0]) || domain[1] != domain[2] || domain[1] != domain[3] || !is_float_sort(domain[1]))
|
||||
m_manager->raise_exception("sort mismatch");
|
||||
if (!is_rm_sort(domain[0]))
|
||||
m_manager->raise_exception("sort mismatch, expected RoundingMode as first argument");
|
||||
if (domain[1] != domain[2] || domain[1] != domain[3] || !is_float_sort(domain[1]))
|
||||
m_manager->raise_exception("sort mismatch, expected arguments 1,2,3 of equal FloatingPoint sort");
|
||||
symbol name("fp.fma");
|
||||
return m_manager->mk_func_decl(name, arity, domain, domain[1], func_decl_info(m_family_id, k));
|
||||
}
|
||||
|
@ -429,6 +435,25 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters,
|
|||
symbol name("to_fp");
|
||||
return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
|
||||
}
|
||||
else if (arity == 2 &&
|
||||
is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT) &&
|
||||
is_sort_of(domain[1], m_family_id, FLOAT_SORT)) {
|
||||
// Rounding + 1 FP -> 1 FP
|
||||
if (num_parameters != 2)
|
||||
m_manager->raise_exception("invalid number of parameters to to_fp");
|
||||
if (!parameters[0].is_int() || !parameters[1].is_int())
|
||||
m_manager->raise_exception("invalid parameter type to to_fp");
|
||||
int ebits = parameters[0].get_int();
|
||||
int sbits = parameters[1].get_int();
|
||||
if (!is_rm_sort(domain[0]))
|
||||
m_manager->raise_exception("sort mismatch, expected first argument of RoundingMode sort");
|
||||
if (!is_sort_of(domain[1], m_family_id, FLOAT_SORT))
|
||||
m_manager->raise_exception("sort mismatch, expected second argument of FloatingPoint sort");
|
||||
|
||||
sort * fp = mk_float_sort(ebits, sbits);
|
||||
symbol name("to_fp");
|
||||
return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
|
||||
}
|
||||
else if (arity == 2 &&
|
||||
is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT) &&
|
||||
is_sort_of(domain[1], m_family_id, FLOAT_SORT)) {
|
||||
|
@ -450,9 +475,9 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters,
|
|||
if (arity != 2 && arity != 3)
|
||||
m_manager->raise_exception("invalid number of arguments to to_fp operator");
|
||||
if (arity == 3 && domain[2] != m_int_sort)
|
||||
m_manager->raise_exception("sort mismatch");
|
||||
m_manager->raise_exception("sort mismatch, expected second argument of Int sort");
|
||||
if (domain[1] != m_real_sort)
|
||||
m_manager->raise_exception("sort mismatch");
|
||||
m_manager->raise_exception("sort mismatch, expected second argument of Real sort");
|
||||
|
||||
sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
|
||||
symbol name("to_fp");
|
||||
|
@ -462,14 +487,11 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters,
|
|||
|
||||
func_decl * float_decl_plugin::mk_float_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters,
|
||||
unsigned arity, sort * const * domain, sort * range) {
|
||||
if (!m_bv_plugin)
|
||||
m_manager->raise_exception("asIEEEBV unsupported; use a logic with BV support");
|
||||
if (arity != 1)
|
||||
m_manager->raise_exception("invalid number of arguments to asIEEEBV");
|
||||
if (!is_float_sort(domain[0]))
|
||||
m_manager->raise_exception("sort mismatch");
|
||||
|
||||
// When the bv_decl_plugin is installed, then we know how to convert a float to an IEEE bit-vector.
|
||||
m_manager->raise_exception("sort mismatch, expected argument of FloatingPoint sort");
|
||||
|
||||
unsigned float_sz = domain[0]->get_parameter(0).get_int() + domain[0]->get_parameter(1).get_int();
|
||||
parameter ps[] = { parameter(float_sz) };
|
||||
sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, ps);
|
||||
|
@ -479,14 +501,12 @@ func_decl * float_decl_plugin::mk_float_to_ieee_bv(decl_kind k, unsigned num_par
|
|||
|
||||
func_decl * float_decl_plugin::mk_from3bv(decl_kind k, unsigned num_parameters, parameter const * parameters,
|
||||
unsigned arity, sort * const * domain, sort * range) {
|
||||
if (!m_bv_plugin)
|
||||
m_manager->raise_exception("fp unsupported; use a logic with BV support");
|
||||
if (arity != 3)
|
||||
m_manager->raise_exception("invalid number of arguments to fp");
|
||||
if (!is_sort_of(domain[0], m_bv_fid, BV_SORT) ||
|
||||
!is_sort_of(domain[1], m_bv_fid, BV_SORT) ||
|
||||
!is_sort_of(domain[2], m_bv_fid, BV_SORT))
|
||||
m_manager->raise_exception("sort mismtach");
|
||||
m_manager->raise_exception("sort mismatch");
|
||||
|
||||
sort * fp = mk_float_sort(domain[1]->get_parameter(0).get_int(), domain[2]->get_parameter(0).get_int() + 1);
|
||||
symbol name("fp");
|
||||
|
@ -500,9 +520,9 @@ func_decl * float_decl_plugin::mk_to_ubv(decl_kind k, unsigned num_parameters, p
|
|||
if (arity != 2)
|
||||
m_manager->raise_exception("invalid number of arguments to to_fp_unsigned");
|
||||
if (is_rm_sort(domain[0]))
|
||||
m_manager->raise_exception("sort mismtach");
|
||||
m_manager->raise_exception("sort mismatch, expected first argument of RoundingMode sort");
|
||||
if (!is_sort_of(domain[1], m_bv_fid, BV_SORT))
|
||||
m_manager->raise_exception("sort mismtach");
|
||||
m_manager->raise_exception("sort mismatch, expected second argument of BV sort");
|
||||
|
||||
sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
|
||||
symbol name("fp.t_ubv");
|
||||
|
@ -631,18 +651,16 @@ void float_decl_plugin::get_op_names(svector<builtin_name> & op_names, symbol co
|
|||
op_names.push_back(builtin_name("fp.isInfinite", OP_FLOAT_IS_INF));
|
||||
op_names.push_back(builtin_name("fp.isNaN", OP_FLOAT_IS_NAN));
|
||||
op_names.push_back(builtin_name("fp.isNegative", OP_FLOAT_IS_NEGATIVE));
|
||||
op_names.push_back(builtin_name("fp.isPositive", OP_FLOAT_IS_POSITIVE));
|
||||
|
||||
op_names.push_back(builtin_name("to_fp", OP_FLOAT_FP));
|
||||
op_names.push_back(builtin_name("fp.isPositive", OP_FLOAT_IS_POSITIVE));
|
||||
|
||||
op_names.push_back(builtin_name("fp", OP_FLOAT_FP));
|
||||
op_names.push_back(builtin_name("fp", OP_FLOAT_FP));
|
||||
op_names.push_back(builtin_name("fp.to_ubv", OP_FLOAT_TO_UBV));
|
||||
op_names.push_back(builtin_name("fp.to_sbv", OP_FLOAT_TO_SBV));
|
||||
|
||||
|
||||
op_names.push_back(builtin_name("to_fp", OP_TO_FLOAT));
|
||||
}
|
||||
|
||||
void float_decl_plugin::get_sort_names(svector<builtin_name> & sort_names, symbol const & logic) {
|
||||
void float_decl_plugin::get_sort_names(svector<builtin_name> & sort_names, symbol const & logic) {
|
||||
sort_names.push_back(builtin_name("FloatingPoint", FLOAT_SORT));
|
||||
sort_names.push_back(builtin_name("RoundingMode", ROUNDING_MODE_SORT));
|
||||
|
||||
|
|
|
@ -247,14 +247,14 @@ public:
|
|||
app * mk_mul(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_MUL, arg1, arg2, arg3); }
|
||||
app * mk_sub(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_SUB, arg1, arg2, arg3); }
|
||||
app * mk_div(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_DIV, arg1, arg2, arg3); }
|
||||
app * mk_uminus(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_NEG, arg1); }
|
||||
app * mk_neg(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_NEG, arg1); }
|
||||
app * mk_rem(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_REM, arg1, arg2); }
|
||||
app * mk_max(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_MAX, arg1, arg2); }
|
||||
app * mk_min(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_MIN, arg1, arg2); }
|
||||
app * mk_abs(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_ABS, arg1); }
|
||||
app * mk_sqrt(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_SQRT, arg1, arg2); }
|
||||
app * mk_round(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_ROUND_TO_INTEGRAL, arg1, arg2); }
|
||||
app * mk_fused_ma(expr * arg1, expr * arg2, expr * arg3, expr * arg4) {
|
||||
app * mk_fma(expr * arg1, expr * arg2, expr * arg3, expr * arg4) {
|
||||
expr * args[4] = { arg1, arg2, arg3, arg4 };
|
||||
return m().mk_app(m_fid, OP_FLOAT_FMA, 4, args);
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ public:
|
|||
app * mk_is_positive(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_POSITIVE, arg1); }
|
||||
app * mk_is_negative(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_NEGATIVE, arg1); }
|
||||
|
||||
bool is_uminus(expr * a) { return is_app_of(a, m_fid, OP_FLOAT_NEG); }
|
||||
bool is_neg(expr * a) { return is_app_of(a, m_fid, OP_FLOAT_NEG); }
|
||||
|
||||
app * mk_float_to_ieee_bv(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_TO_IEEE_BV, arg1); }
|
||||
};
|
||||
|
|
|
@ -604,12 +604,12 @@ void fpa2bv_converter::mk_add(func_decl * f, unsigned num, expr * const * args,
|
|||
void fpa2bv_converter::mk_sub(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||
SASSERT(num == 3);
|
||||
expr_ref t(m);
|
||||
mk_uminus(f, 1, &args[2], t);
|
||||
mk_neg(f, 1, &args[2], t);
|
||||
expr * nargs[3] = { args[0], args[1], t };
|
||||
mk_add(f, 3, nargs, result);
|
||||
}
|
||||
|
||||
void fpa2bv_converter::mk_uminus(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||
void fpa2bv_converter::mk_neg(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||
SASSERT(num == 1);
|
||||
expr * sgn, * s, * e;
|
||||
split(args[0], sgn, s, e);
|
||||
|
@ -915,7 +915,7 @@ void fpa2bv_converter::mk_div(func_decl * f, unsigned num, expr * const * args,
|
|||
TRACE("fpa2bv_div", tout << "DIV = " << mk_ismt2_pp(result, m) << std::endl; );
|
||||
}
|
||||
|
||||
void fpa2bv_converter::mk_remainder(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||
void fpa2bv_converter::mk_rem(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||
SASSERT(num == 2);
|
||||
|
||||
// Remainder is always exact, so there is no rounding mode.
|
||||
|
@ -1123,7 +1123,7 @@ void fpa2bv_converter::mk_max(func_decl * f, unsigned num, expr * const * args,
|
|||
mk_triple(r_sgn, r_sig, r_exp, result);
|
||||
}
|
||||
|
||||
void fpa2bv_converter::mk_fusedma(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||
void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||
SASSERT(num == 4);
|
||||
|
||||
// fusedma means (x * y) + z
|
||||
|
@ -1847,6 +1847,15 @@ void fpa2bv_converter::mk_is_subnormal(func_decl * f, unsigned num, expr * const
|
|||
void fpa2bv_converter::mk_is_negative(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||
SASSERT(num == 1);
|
||||
mk_is_neg(args[0], result);
|
||||
TRACE("fpa2bv_is_negative", tout << "result = " << mk_ismt2_pp(result, m) << std::endl;);
|
||||
}
|
||||
|
||||
void fpa2bv_converter::mk_is_positive(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||
SASSERT(num == 1);
|
||||
expr_ref t1(m), t2(m);
|
||||
mk_is_nan(args[0], t1);
|
||||
mk_is_pos(args[0], t2);
|
||||
result = m.mk_and(m.mk_not(t1), t2);
|
||||
}
|
||||
|
||||
void fpa2bv_converter::mk_is_positive(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||
|
@ -2140,7 +2149,7 @@ void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * a
|
|||
void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||
SASSERT(num == 1);
|
||||
expr * sgn, * s, * e;
|
||||
split(args[0], sgn, s, e);
|
||||
split(args[0], sgn, s, e);
|
||||
result = m_bv_util.mk_concat(m_bv_util.mk_concat(sgn, e), s);
|
||||
}
|
||||
|
||||
|
@ -2150,14 +2159,54 @@ void fpa2bv_converter::mk_fp(func_decl * f, unsigned num, expr * const * args, e
|
|||
}
|
||||
|
||||
void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||
SASSERT(num == 2);
|
||||
SASSERT(f->get_num_parameters() == 1);
|
||||
SASSERT(f->get_parameter(0).is_int());
|
||||
|
||||
//unsigned ebits = m_util.get_ebits(f->get_range());
|
||||
//unsigned sbits = m_util.get_sbits(f->get_range());
|
||||
//int width = f->get_parameter(0).get_int();
|
||||
|
||||
//expr * rm = args[0];
|
||||
//expr * x = args[1];
|
||||
|
||||
//expr * sgn, *s, *e;
|
||||
//split(x, sgn, s, e);
|
||||
|
||||
NOT_IMPLEMENTED_YET();
|
||||
}
|
||||
|
||||
void fpa2bv_converter::mk_to_sbv(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||
SASSERT(num == 2);
|
||||
SASSERT(f->get_num_parameters() == 1);
|
||||
SASSERT(f->get_parameter(0).is_int());
|
||||
|
||||
//unsigned ebits = m_util.get_ebits(f->get_range());
|
||||
//unsigned sbits = m_util.get_sbits(f->get_range());
|
||||
//int width = f->get_parameter(0).get_int();
|
||||
|
||||
//expr * rm = args[0];
|
||||
//expr * x = args[1];
|
||||
|
||||
//expr * sgn, *s, *e;
|
||||
//split(x, sgn, s, e);
|
||||
|
||||
NOT_IMPLEMENTED_YET();
|
||||
}
|
||||
|
||||
void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||
SASSERT(num == 1);
|
||||
|
||||
//unsigned ebits = m_util.get_ebits(f->get_range());
|
||||
//unsigned sbits = m_util.get_sbits(f->get_range());
|
||||
//int width = f->get_parameter(0).get_int();
|
||||
|
||||
//expr * rm = args[0];
|
||||
//expr * x = args[1];
|
||||
|
||||
//expr * sgn, *s, *e;
|
||||
//split(x, sgn, s, e);
|
||||
|
||||
NOT_IMPLEMENTED_YET();
|
||||
}
|
||||
|
||||
|
|
|
@ -94,14 +94,14 @@ public:
|
|||
|
||||
void mk_add(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
|
||||
void mk_sub(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
|
||||
void mk_uminus(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
|
||||
void mk_neg(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
|
||||
void mk_mul(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
|
||||
void mk_div(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
|
||||
void mk_remainder(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
|
||||
void mk_rem(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
|
||||
void mk_abs(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
|
||||
void mk_min(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
|
||||
void mk_max(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
|
||||
void mk_fusedma(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
|
||||
void mk_fma(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
|
||||
void mk_sqrt(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
|
||||
void mk_round_to_integral(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg {
|
|||
}
|
||||
|
||||
bool max_steps_exceeded(unsigned num_steps) const {
|
||||
cooperate("fpa2bv");
|
||||
cooperate("fpa2bv");
|
||||
return num_steps > m_max_steps;
|
||||
}
|
||||
|
||||
|
@ -120,14 +120,14 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg {
|
|||
case OP_FLOAT_NAN: m_conv.mk_nan(f, result); return BR_DONE;
|
||||
case OP_FLOAT_ADD: m_conv.mk_add(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_SUB: m_conv.mk_sub(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_NEG: m_conv.mk_uminus(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_NEG: m_conv.mk_neg(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_MUL: m_conv.mk_mul(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_DIV: m_conv.mk_div(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_REM: m_conv.mk_remainder(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_REM: m_conv.mk_rem(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_ABS: m_conv.mk_abs(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_MIN: m_conv.mk_min(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_MAX: m_conv.mk_max(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_FMA: m_conv.mk_fusedma(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_FMA: m_conv.mk_fma(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_SQRT: m_conv.mk_sqrt(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_ROUND_TO_INTEGRAL: m_conv.mk_round_to_integral(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_EQ: m_conv.mk_float_eq(f, num, args, result); return BR_DONE;
|
||||
|
@ -146,7 +146,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg {
|
|||
case OP_FLOAT_IS_NEGATIVE: m_conv.mk_is_negative(f, num, args, result); return BR_DONE;
|
||||
case OP_TO_FLOAT: m_conv.mk_to_float(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_FP: m_conv.mk_fp(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_FP: m_conv.mk_fp(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_TO_UBV: m_conv.mk_to_ubv(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_TO_SBV: m_conv.mk_to_sbv(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_TO_REAL: m_conv.mk_to_real(f, num, args, result); return BR_DONE;
|
||||
|
|
|
@ -911,18 +911,34 @@ void bit_blaster_tpl<Cfg>::mk_shl(unsigned sz, expr * const * a_bits, expr * con
|
|||
out_bits.push_back(a_bits[i]);
|
||||
}
|
||||
else {
|
||||
expr_ref_vector eqs(m());
|
||||
mk_eqs(sz, b_bits, eqs);
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
out_bits.append(sz, a_bits);
|
||||
|
||||
unsigned i = 0;
|
||||
expr_ref_vector new_out_bits(m());
|
||||
for (; i < sz; ++i) {
|
||||
checkpoint();
|
||||
expr_ref out(m());
|
||||
mk_ite(eqs.get(i), a_bits[0], m().mk_false(), out);
|
||||
for (unsigned j = 1; j <= i; j++) {
|
||||
unsigned shift_i = 1 << i;
|
||||
if (shift_i >= sz) break;
|
||||
for (unsigned j = 0; j < sz; ++j) {
|
||||
expr_ref new_out(m());
|
||||
mk_ite(eqs.get(i - j), a_bits[j], out, new_out);
|
||||
out = new_out;
|
||||
expr* a_j = m().mk_false();
|
||||
if (shift_i <= j) a_j = out_bits[j-shift_i].get();
|
||||
mk_ite(b_bits[i], a_j, out_bits[j].get(), new_out);
|
||||
new_out_bits.push_back(new_out);
|
||||
}
|
||||
out_bits.push_back(out);
|
||||
out_bits.reset();
|
||||
out_bits.append(new_out_bits);
|
||||
new_out_bits.reset();
|
||||
}
|
||||
expr_ref is_large(m());
|
||||
is_large = m().mk_false();
|
||||
for (; i < sz; ++i) {
|
||||
mk_or(is_large, b_bits[i], is_large);
|
||||
}
|
||||
for (unsigned j = 0; j < sz; ++j) {
|
||||
expr_ref new_out(m());
|
||||
mk_ite(is_large, m().mk_false(), out_bits[j].get(), new_out);
|
||||
out_bits[j] = new_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -939,19 +955,32 @@ void bit_blaster_tpl<Cfg>::mk_lshr(unsigned sz, expr * const * a_bits, expr * co
|
|||
out_bits.push_back(m().mk_false());
|
||||
}
|
||||
else {
|
||||
expr_ref_vector eqs(m());
|
||||
mk_eqs(sz, b_bits, eqs);
|
||||
out_bits.resize(sz);
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
out_bits.append(sz, a_bits);
|
||||
unsigned i = 0;
|
||||
for (; i < sz; ++i) {
|
||||
checkpoint();
|
||||
expr_ref out(m());
|
||||
mk_ite(eqs.get(i), a_bits[sz-1], m().mk_false(), out);
|
||||
for (unsigned j = 1; j <= i; j++) {
|
||||
expr_ref_vector new_out_bits(m());
|
||||
unsigned shift_i = 1 << i;
|
||||
if (shift_i >= sz) break;
|
||||
for (unsigned j = 0; j < sz; ++j) {
|
||||
expr_ref new_out(m());
|
||||
mk_ite(eqs.get(i - j), a_bits[sz - j - 1], out, new_out);
|
||||
out = new_out;
|
||||
expr* a_j = m().mk_false();
|
||||
if (shift_i + j < sz) a_j = out_bits[j+shift_i].get();
|
||||
mk_ite(b_bits[i], a_j, out_bits[j].get(), new_out);
|
||||
new_out_bits.push_back(new_out);
|
||||
}
|
||||
out_bits.set(sz - i - 1, out);
|
||||
out_bits.reset();
|
||||
out_bits.append(new_out_bits);
|
||||
}
|
||||
expr_ref is_large(m());
|
||||
is_large = m().mk_false();
|
||||
for (; i < sz; ++i) {
|
||||
mk_or(is_large, b_bits[i], is_large);
|
||||
}
|
||||
for (unsigned j = 0; j < sz; ++j) {
|
||||
expr_ref new_out(m());
|
||||
mk_ite(is_large, m().mk_false(), out_bits[j].get(), new_out);
|
||||
out_bits[j] = new_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -968,20 +997,32 @@ void bit_blaster_tpl<Cfg>::mk_ashr(unsigned sz, expr * const * a_bits, expr * co
|
|||
out_bits.push_back(a_bits[sz-1]);
|
||||
}
|
||||
else {
|
||||
expr_ref_vector eqs(m());
|
||||
mk_eqs(sz, b_bits, eqs);
|
||||
out_bits.resize(sz);
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
out_bits.append(sz, a_bits);
|
||||
unsigned i = 0;
|
||||
for (; i < sz; ++i) {
|
||||
checkpoint();
|
||||
expr_ref out(m());
|
||||
out = a_bits[sz-1];
|
||||
for (unsigned j = 1; j <= i; j++) {
|
||||
expr_ref_vector new_out_bits(m());
|
||||
unsigned shift_i = 1 << i;
|
||||
if (shift_i >= sz) break;
|
||||
for (unsigned j = 0; j < sz; ++j) {
|
||||
expr_ref new_out(m());
|
||||
mk_ite(eqs.get(i - j), a_bits[sz - j - 1], out, new_out);
|
||||
out = new_out;
|
||||
expr* a_j = a_bits[sz-1];
|
||||
if (shift_i + j < sz) a_j = out_bits[j+shift_i].get();
|
||||
mk_ite(b_bits[i], a_j, out_bits[j].get(), new_out);
|
||||
new_out_bits.push_back(new_out);
|
||||
}
|
||||
TRACE("bit_blaster", tout << (sz - i - 1) << " :\n" << mk_pp(out, m()) << "\n";);
|
||||
out_bits.set(sz - i - 1, out);
|
||||
out_bits.reset();
|
||||
out_bits.append(new_out_bits);
|
||||
}
|
||||
expr_ref is_large(m());
|
||||
is_large = m().mk_false();
|
||||
for (; i < sz; ++i) {
|
||||
mk_or(is_large, b_bits[i], is_large);
|
||||
}
|
||||
for (unsigned j = 0; j < sz; ++j) {
|
||||
expr_ref new_out(m());
|
||||
mk_ite(is_large, a_bits[sz-1], out_bits[j].get(), new_out);
|
||||
out_bits[j] = new_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ br_status float_rewriter::mk_add(expr * arg1, expr * arg2, expr * arg3, expr_ref
|
|||
|
||||
br_status float_rewriter::mk_sub(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) {
|
||||
// a - b = a + (-b)
|
||||
result = m_util.mk_add(arg1, arg2, m_util.mk_uminus(arg3));
|
||||
result = m_util.mk_add(arg1, arg2, m_util.mk_neg(arg3));
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
|
||||
|
@ -204,7 +204,7 @@ br_status float_rewriter::mk_neg(expr * arg1, expr_ref & result) {
|
|||
result = m_util.mk_plus_inf(m().get_sort(arg1));
|
||||
return BR_DONE;
|
||||
}
|
||||
if (m_util.is_uminus(arg1)) {
|
||||
if (m_util.is_neg(arg1)) {
|
||||
// - - a --> a
|
||||
result = to_app(arg1)->get_arg(0);
|
||||
return BR_DONE;
|
||||
|
@ -239,7 +239,7 @@ br_status float_rewriter::mk_abs(expr * arg1, expr_ref & result) {
|
|||
return BR_DONE;
|
||||
}
|
||||
result = m().mk_ite(m_util.mk_is_sign_minus(arg1),
|
||||
m_util.mk_uminus(arg1),
|
||||
m_util.mk_neg(arg1),
|
||||
arg1);
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
|
||||
br_status mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result);
|
||||
br_status mk_eq_core(expr * arg1, expr * arg2, expr_ref & result);
|
||||
|
||||
|
||||
br_status mk_add(expr * arg1, expr * arg2, expr * arg3, expr_ref & result);
|
||||
br_status mk_sub(expr * arg1, expr * arg2, expr * arg3, expr_ref & result);
|
||||
br_status mk_mul(expr * arg1, expr * arg2, expr * arg3, expr_ref & result);
|
||||
|
|
|
@ -73,6 +73,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
|
|||
m_a_rw.updt_params(p);
|
||||
m_bv_rw.updt_params(p);
|
||||
m_ar_rw.updt_params(p);
|
||||
m_f_rw.updt_params(p);
|
||||
updt_local_params(p);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue