3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-05-17 07:29:28 +00:00

tentative solution: use existing nullability check (we might want to check in the future which guards of the ITE are actually true)

This commit is contained in:
CEisenhofer 2026-04-14 18:07:03 +02:00
parent f09f6d5097
commit 82df1afeaf
9 changed files with 33 additions and 85 deletions

View file

@ -111,7 +111,6 @@ namespace euf {
case snode_kind::s_empty:
n->m_ground = true;
n->m_regex_free = true;
n->m_nullable = true;
n->m_level = 0;
n->m_length = 0;
break;
@ -119,7 +118,6 @@ namespace euf {
case snode_kind::s_char:
n->m_ground = true;
n->m_regex_free = true;
n->m_nullable = false;
n->m_level = 1;
n->m_length = 1;
break;
@ -128,7 +126,6 @@ namespace euf {
// NSB review: a variable node can be a "value". Should it be ground then?
n->m_ground = false;
n->m_regex_free = true;
n->m_nullable = false;
n->m_level = 1;
n->m_length = 1;
n->m_is_classical = false;
@ -138,7 +135,6 @@ namespace euf {
// NSB review: SASSERT(n->num_args() == 1); and simplify code
n->m_ground = n->num_args() > 0 ? n->arg(0)->is_ground() : true;
n->m_regex_free = true;
n->m_nullable = false;
n->m_level = 1;
n->m_length = 1;
break;
@ -149,7 +145,6 @@ namespace euf {
snode* r = n->arg(1);
n->m_ground = l->is_ground() && r->is_ground();
n->m_regex_free = l->is_regex_free() && r->is_regex_free();
n->m_nullable = l->is_nullable() && r->is_nullable();
n->m_is_classical = l->is_classical() && r->is_classical();
n->m_level = std::max(l->level(), r->level()) + 1;
n->m_length = l->length() + r->length();
@ -166,7 +161,6 @@ namespace euf {
snode* base = n->arg(0);
n->m_ground = base->is_ground();
n->m_regex_free = base->is_regex_free();
n->m_nullable = base->is_nullable();
n->m_is_classical = base->is_classical();
n->m_level = 1;
n->m_length = 1;
@ -178,7 +172,6 @@ namespace euf {
SASSERT(n->num_args() == 1);
n->m_ground = n->arg(0)->is_ground();
n->m_regex_free = false;
n->m_nullable = true;
n->m_is_classical = n->arg(0)->is_classical();
n->m_level = 1;
n->m_length = 1;
@ -196,7 +189,6 @@ namespace euf {
if (n->get_expr() &&
!m_seq.re.is_loop(n->get_expr(), loop_body, lo, hi))
m_seq.re.is_loop(n->get_expr(), loop_body, lo);
n->m_nullable = (lo == 0);
n->m_level = 1;
n->m_length = 1;
break;
@ -206,7 +198,6 @@ namespace euf {
SASSERT(n->num_args() == 2);
n->m_ground = n->arg(0)->is_ground() && n->arg(1)->is_ground();
n->m_regex_free = false;
n->m_nullable = n->arg(0)->is_nullable() || n->arg(1)->is_nullable();
n->m_is_classical = n->arg(0)->is_classical() && n->arg(1)->is_classical();
n->m_level = 1;
n->m_length = 1;
@ -216,7 +207,6 @@ namespace euf {
SASSERT(n->num_args() == 2);
n->m_ground = n->arg(0)->is_ground() && n->arg(1)->is_ground();
n->m_regex_free = false;
n->m_nullable = n->arg(0)->is_nullable() && n->arg(1)->is_nullable();
n->m_is_classical = false;
n->m_level = 1;
n->m_length = 1;
@ -226,7 +216,6 @@ namespace euf {
SASSERT(n->num_args() == 1);
n->m_ground = n->arg(0)->is_ground();
n->m_regex_free = false;
n->m_nullable = !n->arg(0)->is_nullable();
n->m_is_classical = false;
n->m_level = 1;
n->m_length = 1;
@ -235,7 +224,6 @@ namespace euf {
case snode_kind::s_fail:
n->m_ground = true;
n->m_regex_free = false;
n->m_nullable = false;
n->m_is_classical = false;
n->m_level = 1;
n->m_length = 1;
@ -244,7 +232,6 @@ namespace euf {
case snode_kind::s_full_char:
n->m_ground = true;
n->m_regex_free = false;
n->m_nullable = false;
n->m_level = 1;
n->m_length = 1;
break;
@ -252,7 +239,6 @@ namespace euf {
case snode_kind::s_full_seq:
n->m_ground = true;
n->m_regex_free = false;
n->m_nullable = true;
n->m_level = 1;
n->m_length = 1;
break;
@ -261,7 +247,6 @@ namespace euf {
SASSERT(n->num_args() == 2);
n->m_ground = n->arg(0)->is_ground() && n->arg(1)->is_ground();
n->m_regex_free = false;
n->m_nullable = false;
n->m_level = 1;
n->m_length = 1;
break;
@ -270,7 +255,6 @@ namespace euf {
SASSERT(n->num_args() == 1);
n->m_ground = n->arg(0)->is_ground();
n->m_regex_free = false;
n->m_nullable = n->arg(0)->is_nullable();
n->m_level = 1;
n->m_length = 1;
break;
@ -279,7 +263,6 @@ namespace euf {
SASSERT(n->num_args() == 2);
n->m_ground = n->arg(0)->is_ground() && n->arg(1)->is_ground();
n->m_regex_free = false;
n->m_nullable = false;
n->m_level = 1;
n->m_length = 1;
break;
@ -289,7 +272,6 @@ namespace euf {
// Is this UNREACHABLE()?
n->m_ground = true;
n->m_regex_free = true;
n->m_nullable = false;
n->m_level = 1;
n->m_length = 1;
break;
@ -773,8 +755,7 @@ namespace euf {
<< " level=" << n->level()
<< " len=" << n->length()
<< " ground=" << n->is_ground()
<< " rfree=" << n->is_regex_free()
<< " nullable=" << n->is_nullable();
<< " rfree=" << n->is_regex_free();
if (n->num_args() > 0) {
out << " args=(";
for (unsigned i = 0; i < n->num_args(); ++i) {

View file

@ -66,7 +66,6 @@ namespace euf {
// metadata flags, analogous to ZIPT's Str/StrToken properties
bool m_ground = true; // no uninterpreted string variables
bool m_regex_free = true; // no regex constructs
bool m_nullable = false; // accepts the empty string
bool m_is_classical = true; // classical regular expression
unsigned m_level = 0; // tree depth/level (0 for empty, 1 for singletons)
unsigned m_length = 0; // token count, number of leaf tokens in the tree
@ -121,9 +120,6 @@ namespace euf {
bool is_regex_free() const {
return m_regex_free;
}
bool is_nullable() const {
return m_nullable;
}
bool is_classical() const {
return m_is_classical;
}

View file

@ -1613,15 +1613,13 @@ bool seq_util::rex::has_valid_info(expr* r) const {
seq_util::rex::info seq_util::rex::get_cached_info(expr* e) const {
if (has_valid_info(e))
return m_infos[e->get_id()];
else
return invalid_info;
return invalid_info;
}
/*
Get the information value associated with the regular expression e
*/
seq_util::rex::info seq_util::rex::get_info(expr* e) const
{
seq_util::rex::info seq_util::rex::get_info(expr* e) const {
SASSERT(u.is_re(e));
auto result = get_cached_info(e);
if (result.is_valid())