mirror of
https://github.com/Z3Prover/z3
synced 2026-03-07 05:44:51 +00:00
Apply ZIPT improvements: fix loop nullable, drop bounds check, symmetric star merging
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
This commit is contained in:
parent
593e22ba4e
commit
a0b359212e
2 changed files with 19 additions and 5 deletions
|
|
@ -212,11 +212,16 @@ namespace euf {
|
|||
if (same_star_body(a, b))
|
||||
push_merge(n, a);
|
||||
|
||||
// Rule 1 extended: concat(v*, concat(v*, c)) = concat(v*, c)
|
||||
// Rule 1 extended (right): concat(v*, concat(v*, c)) = concat(v*, c)
|
||||
enode* b1, *b2;
|
||||
if (is_concat(b, b1, b2) && same_star_body(a, b1))
|
||||
push_merge(n, b);
|
||||
|
||||
// Rule 1 extended (left): concat(concat(c, v*), v*) = concat(c, v*)
|
||||
enode* a1, *a2;
|
||||
if (is_concat(a, a1, a2) && same_star_body(a2, b))
|
||||
push_merge(n, a);
|
||||
|
||||
// Rule 2: Nullable absorption by .*
|
||||
// concat(.*, v) = .* when v is nullable
|
||||
if (is_full_seq(a) && is_nullable(b))
|
||||
|
|
|
|||
|
|
@ -200,13 +200,18 @@ namespace euf {
|
|||
n->m_length = 1;
|
||||
break;
|
||||
|
||||
case snode_kind::s_loop:
|
||||
case snode_kind::s_loop: {
|
||||
bool body_nullable = n->num_args() > 0 && n->arg(0)->is_nullable();
|
||||
unsigned lo = 0, hi = 0;
|
||||
expr* body = nullptr;
|
||||
bool lo_zero = n->get_expr() && m_seq.re.is_loop(n->get_expr(), body, lo, hi) && lo == 0;
|
||||
n->m_ground = n->num_args() > 0 ? n->arg(0)->is_ground() : true;
|
||||
n->m_regex_free = false;
|
||||
n->m_nullable = false; // depends on lower bound
|
||||
n->m_nullable = lo_zero || body_nullable;
|
||||
n->m_level = 1;
|
||||
n->m_length = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case snode_kind::s_union:
|
||||
SASSERT(n->num_args() == 2);
|
||||
|
|
@ -461,13 +466,17 @@ namespace euf {
|
|||
}
|
||||
|
||||
snode* sgraph::drop_left(snode* n, unsigned count) {
|
||||
for (unsigned i = 0; i < count && !n->is_empty(); ++i)
|
||||
if (count == 0 || n->is_empty()) return n;
|
||||
if (count >= n->length()) return mk_empty();
|
||||
for (unsigned i = 0; i < count; ++i)
|
||||
n = drop_first(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
snode* sgraph::drop_right(snode* n, unsigned count) {
|
||||
for (unsigned i = 0; i < count && !n->is_empty(); ++i)
|
||||
if (count == 0 || n->is_empty()) return n;
|
||||
if (count >= n->length()) return mk_empty();
|
||||
for (unsigned i = 0; i < count; ++i)
|
||||
n = drop_last(n);
|
||||
return n;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue