mirror of
https://github.com/Z3Prover/z3
synced 2025-04-16 05:48:44 +00:00
fix crash in poly normalizer exposed by qe. Issue #775
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
856cf7d4f9
commit
152321bce6
|
@ -43,8 +43,7 @@ bool arith_simplifier_plugin::is_neg_poly(expr * t) const {
|
||||||
if (m_util.is_mul(t)) {
|
if (m_util.is_mul(t)) {
|
||||||
t = to_app(t)->get_arg(0);
|
t = to_app(t)->get_arg(0);
|
||||||
rational r;
|
rational r;
|
||||||
bool is_int;
|
if (is_numeral(t, r))
|
||||||
if (m_util.is_numeral(t, r, is_int))
|
|
||||||
return r.is_neg();
|
return r.is_neg();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -607,12 +607,25 @@ void poly_simplifier_plugin::append_to_monomial(expr * n, numeral & k, ptr_buffe
|
||||||
k *= val;
|
k *= val;
|
||||||
n = get_monomial_body(n);
|
n = get_monomial_body(n);
|
||||||
|
|
||||||
if (is_mul(n)) {
|
unsigned hd = result.size();
|
||||||
for (unsigned i = 0; i < to_app(n)->get_num_args(); i++)
|
result.push_back(n);
|
||||||
result.push_back(to_app(n)->get_arg(i));
|
while (hd < result.size()) {
|
||||||
}
|
n = result[hd];
|
||||||
else {
|
if (is_mul(n)) {
|
||||||
result.push_back(n);
|
result[hd] = result.back();
|
||||||
|
result.pop_back();
|
||||||
|
for (unsigned i = 0; i < to_app(n)->get_num_args(); i++) {
|
||||||
|
result.push_back(to_app(n)->get_arg(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (is_numeral(n, val)) {
|
||||||
|
k *= val;
|
||||||
|
result[hd] = result.back();
|
||||||
|
result.pop_back();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
++hd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1815,7 +1815,10 @@ bool theory_seq::solve_ne(unsigned idx) {
|
||||||
for (unsigned i = 0; i < n.lits().size(); ++i) {
|
for (unsigned i = 0; i < n.lits().size(); ++i) {
|
||||||
switch (ctx.get_assignment(n.lits(i))) {
|
switch (ctx.get_assignment(n.lits(i))) {
|
||||||
case l_false:
|
case l_false:
|
||||||
TRACE("seq", display_disequation(tout << "has false literal\n", n););
|
TRACE("seq", display_disequation(tout << "has false literal\n", n);
|
||||||
|
ctx.display_literal_verbose(tout, n.lits(i));
|
||||||
|
tout << "\n" << n.lits(i) << " " << ctx.is_relevant(n.lits(i)) << "\n";
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
case l_true:
|
case l_true:
|
||||||
break;
|
break;
|
||||||
|
@ -1841,7 +1844,10 @@ bool theory_seq::solve_ne(unsigned idx) {
|
||||||
change = canonize(n.rs(i), rs, deps) || change;
|
change = canonize(n.rs(i), rs, deps) || change;
|
||||||
|
|
||||||
if (!m_seq_rewrite.reduce_eq(ls, rs, lhs, rhs, change)) {
|
if (!m_seq_rewrite.reduce_eq(ls, rs, lhs, rhs, change)) {
|
||||||
TRACE("seq", display_disequation(tout << "reduces to false: ", n););
|
TRACE("seq", display_disequation(tout << "reduces to false: ", n);
|
||||||
|
tout << n.ls(i) << " -> " << ls << "\n";
|
||||||
|
tout << n.rs(i) << " -> " << rs << "\n";);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (!change) {
|
else if (!change) {
|
||||||
|
@ -3720,30 +3726,29 @@ void theory_seq::new_diseq_eh(theory_var v1, theory_var v2) {
|
||||||
expr_ref e2(n2->get_owner(), m);
|
expr_ref e2(n2->get_owner(), m);
|
||||||
m_exclude.update(e1, e2);
|
m_exclude.update(e1, e2);
|
||||||
expr_ref eq(m.mk_eq(e1, e2), m);
|
expr_ref eq(m.mk_eq(e1, e2), m);
|
||||||
|
TRACE("seq", tout << "new disequality " << get_context().get_scope_level() << ": " << eq << "\n";);
|
||||||
m_rewrite(eq);
|
m_rewrite(eq);
|
||||||
if (!m.is_false(eq)) {
|
if (!m.is_false(eq)) {
|
||||||
TRACE("seq", tout << "new disequality " << get_context().get_scope_level() << ": " << eq << "\n";);
|
|
||||||
|
|
||||||
literal lit = mk_eq(e1, e2, false);
|
literal lit = mk_eq(e1, e2, false);
|
||||||
|
|
||||||
// propagate x != "" into x = (++ (unit (nth x 0) (tail x 0)))
|
|
||||||
if (m_util.str.is_empty(e2)) {
|
if (m_util.str.is_empty(e2)) {
|
||||||
std::swap(e1, e2);
|
std::swap(e1, e2);
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
if (false && m_util.str.is_empty(e1)) {
|
if (false && m_util.str.is_empty(e1)) {
|
||||||
expr_ref head(m), tail(m), conc(m);
|
expr_ref head(m), tail(m), conc(m);
|
||||||
mk_decompose(e2, head, tail);
|
mk_decompose(e2, head, tail);
|
||||||
conc = mk_concat(head, tail);
|
conc = mk_concat(head, tail);
|
||||||
propagate_eq(~lit, e2, conc, true);
|
propagate_eq(~lit, e2, conc, true);
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
// (e1 = "" & e2 = xdz) or (e2 = "" & e1 = xcy) or (e1 = xcy & e2 = xdz & c != d) or (e1 = x & e2 = xdz) or (e2 = x & e1 = xcy)
|
// (e1 = "" & e2 = xdz) or (e2 = "" & e1 = xcy) or (e1 = xcy & e2 = xdz & c != d) or (e1 = x & e2 = xdz) or (e2 = x & e1 = xcy)
|
||||||
// e1 = "" or e1 = xcy or e1 = x
|
// e1 = "" or e1 = xcy or e1 = x
|
||||||
// e2 = "" or e2 = xdz or e2 = x
|
// e2 = "" or e2 = xdz or e2 = x
|
||||||
// e1 = xcy or e2 = xdz
|
// e1 = xcy or e2 = xdz
|
||||||
// c != d
|
// c != d
|
||||||
|
|
||||||
literal lit = mk_seq_eq(e1, e2);
|
|
||||||
sort* char_sort = 0;
|
sort* char_sort = 0;
|
||||||
expr_ref emp(m);
|
expr_ref emp(m);
|
||||||
VERIFY(m_util.is_seq(m.get_sort(e1), char_sort));
|
VERIFY(m_util.is_seq(m.get_sort(e1), char_sort));
|
||||||
|
|
Loading…
Reference in a new issue