3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-18 02:16:40 +00:00

disable unsound simplification of root objects, and incorrect evaluation of negative even roots

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2015-12-09 08:41:59 -08:00
parent 8949790c16
commit 035f2bb0da
4 changed files with 31 additions and 17 deletions

View file

@ -264,9 +264,10 @@ bool arith_rewriter::is_reduce_power_target(expr * arg, bool is_eq) {
}
for (unsigned i = 0; i < sz; i++) {
expr * arg = args[i];
if (m_util.is_power(arg)) {
expr* arg0, *arg1;
if (m_util.is_power(arg, arg0, arg1)) {
rational k;
if (m_util.is_numeral(to_app(arg)->get_arg(1), k) && k.is_int() && ((is_eq && k > rational(1)) || (!is_eq && k > rational(2))))
if (m_util.is_numeral(arg1, k) && k.is_int() && ((is_eq && k > rational(1)) || (!is_eq && k > rational(2))))
return true;
}
}
@ -290,11 +291,15 @@ expr * arith_rewriter::reduce_power(expr * arg, bool is_eq) {
rational k;
for (unsigned i = 0; i < sz; i++) {
expr * arg = args[i];
if (m_util.is_power(arg) && m_util.is_numeral(to_app(arg)->get_arg(1), k) && k.is_int() && ((is_eq && k > rational(1)) || (!is_eq && k > rational(2)))) {
if (is_eq || !k.is_even())
new_args.push_back(to_app(arg)->get_arg(0));
else
new_args.push_back(m_util.mk_power(to_app(arg)->get_arg(0), m_util.mk_numeral(rational(2), m_util.is_int(arg))));
expr * arg0, *arg1;
if (m_util.is_power(arg, arg0, arg1) && m_util.is_numeral(arg1, k) && k.is_int() &&
((is_eq && k > rational(1)) || (!is_eq && k > rational(2)))) {
if (is_eq || !k.is_even()) {
new_args.push_back(arg0);
}
else {
new_args.push_back(m_util.mk_power(arg0, m_util.mk_numeral(rational(2), m_util.is_int(arg))));
}
}
else {
new_args.push_back(arg);
@ -788,6 +793,7 @@ br_status arith_rewriter::mk_power_core(expr * arg1, expr * arg2, expr_ref & res
bool is_num_y = m_util.is_numeral(arg2, y);
bool is_int_sort = m_util.is_int(arg1);
TRACE("arith", tout << mk_pp(arg1, m()) << " " << mk_pp(arg2, m()) << "\n";);
if ((is_num_x && x.is_one()) ||
(is_num_y && y.is_one())) {
result = arg1;
@ -821,11 +827,12 @@ br_status arith_rewriter::mk_power_core(expr * arg1, expr * arg2, expr_ref & res
}
}
if (m_util.is_power(arg1) && is_num_y && y.is_int() && !y.is_zero()) {
expr* arg10, *arg11;
if (m_util.is_power(arg1, arg10, arg11) && is_num_y && y.is_int() && !y.is_zero()) {
// (^ (^ t y2) y) --> (^ t (* y2 y)) If y2 > 0 && y != 0 && y and y2 are integers
rational y2;
if (m_util.is_numeral(to_app(arg1)->get_arg(1), y2) && y2.is_int() && y2.is_pos()) {
result = m_util.mk_power(to_app(arg1)->get_arg(0), m_util.mk_numeral(y*y2, is_int_sort));
if (m_util.is_numeral(arg11, y2) && y2.is_int() && y2.is_pos()) {
result = m_util.mk_power(arg10, m_util.mk_numeral(y*y2, is_int_sort));
return BR_REWRITE1;
}
}
@ -888,6 +895,9 @@ br_status arith_rewriter::mk_power_core(expr * arg1, expr * arg2, expr_ref & res
if (is_num_x) {
rational xk, r;
xk = power(x, u_num_y);
if (xk.is_neg() && u_den_y % 2 == 0) {
return BR_FAILED;
}
if (xk.root(u_den_y, r)) {
if (is_neg_y)
r = rational(1)/r;