3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-20 11:22:04 +00:00

State graph dgml update and fixes in condition simplifier (#5721)

* improved generated dgml graph

* fixed simplification of negated ranges and did some code cleanup

* do not make loops with lower=upper=0, this is epsilon

* do not add loops with lower=upper=1

* bug fix in normalization: forgotten eps case
This commit is contained in:
Margus Veanes 2021-12-19 11:09:55 -08:00 committed by GitHub
parent bee742111a
commit a7b1db611c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 168 additions and 220 deletions

View file

@ -831,6 +831,39 @@ app* seq_util::mk_lt(expr* ch1, expr* ch2) const {
return m.mk_not(mk_le(ch2, ch1));
}
bool seq_util::is_char_const_range(expr const* x, expr* e, unsigned& l, unsigned& u, bool& negated) const {
expr* a, * b, * e1, * e2, * lb, * ub;
e1 = e;
negated = (m.is_not(e, e1)) ? true : false;
if (m.is_eq(e1, a, b) && (a == x && is_const_char(b, l))) {
u = l;
return true;
}
if (is_char_le(e1, a, b) && a == x && is_const_char(b, u)) {
// (x <= u)
l = 0;
return true;
}
if (is_char_le(e1, a, b) && b == x && is_const_char(a, l)) {
// (l <= x)
u = max_char();
return true;
}
if (m.is_and(e1, e1, e2) && is_char_le(e1, lb, a) && a == x && is_const_char(lb, l) &&
is_char_le(e2, b, ub) && b == x && is_const_char(ub, u))
// (l <= x) & (x <= u)
return true;
if (m.is_eq(e1, a, b) && b == x && is_const_char(a, l)) {
u = l;
return true;
}
if (m.is_and(e1, e2, e1) && is_char_le(e1, lb, a) && a == x && is_const_char(lb, l) &&
is_char_le(e2, b, ub) && b == x && is_const_char(ub, u))
// (x <= u) & (l <= x)
return true;
return false;
}
bool seq_util::str::is_string(func_decl const* f, zstring& s) const {
if (is_string(f)) {
s = f->get_parameter(0).get_zstring();
@ -1030,6 +1063,23 @@ app* seq_util::rex::mk_loop(expr* r, unsigned lo, unsigned hi) {
return m.mk_app(m_fid, OP_RE_LOOP, 2, params, 1, &r);
}
expr* seq_util::rex::mk_loop_proper(expr* r, unsigned lo, unsigned hi)
{
if (lo == 0 && hi == 0) {
sort* seq_sort = nullptr;
VERIFY(u.is_re(r, seq_sort));
// avoid creating a loop with both bounds 0
// such an expression is invalid as a loop
// it is BY DEFINITION = epsilon
return mk_epsilon(seq_sort);
}
if (lo == 1 && hi == 1)
// do not create a loop unless it actually is a loop
return r;
parameter params[2] = { parameter(lo), parameter(hi) };
return m.mk_app(m_fid, OP_RE_LOOP, 2, params, 1, &r);
}
app* seq_util::rex::mk_loop(expr* r, expr* lo) {
expr* rs[2] = { r, lo };
return m.mk_app(m_fid, OP_RE_LOOP, 0, nullptr, 2, rs);