3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-18 02:16:40 +00:00
@veanes
mk_bool_app_helper has a bug:
When it simplifies a disjunction or conjunction of regex membership constraints of the form (and (str.in_re "" R) (str.in_re x Q))
then the first term (str.in_re "" R) is omitted in the result.
You have a test here
3da9d91866/src/ast/rewriter/seq_rewriter.cpp (L438)
that means a regex membership with empty first argument is not put in the two buffers with membership/non-membership.
It isn't put into new_args either because the test bypasses these
3da9d91866/src/ast/rewriter/seq_rewriter.cpp (L485)
This commit is contained in:
Nikolaj Bjorner 2021-06-06 20:30:09 -07:00
parent 3da9d91866
commit 92ec81d108
2 changed files with 21 additions and 9 deletions

View file

@ -432,6 +432,7 @@ br_status seq_rewriter::mk_bool_app_helper(bool is_and, unsigned n, expr* const*
obj_map<expr, expr*> in_re, not_in_re;
bool found_pair = false;
ptr_buffer<expr> new_args;
for (unsigned i = 0; i < n; ++i) {
expr* args_i = args[i];
expr* x = nullptr, *y = nullptr, *z = nullptr;
@ -455,13 +456,15 @@ br_status seq_rewriter::mk_bool_app_helper(bool is_and, unsigned n, expr* const*
found_pair |= in_re.contains(x);
}
}
else
new_args.push_back(args_i);
}
if (!found_pair) {
return BR_FAILED;
}
ptr_buffer<expr> new_args;
for (auto const & kv : in_re) {
expr* x = kv.m_key;
expr* y = kv.m_value;
@ -482,12 +485,6 @@ br_status seq_rewriter::mk_bool_app_helper(bool is_and, unsigned n, expr* const*
new_args.push_back(re().mk_in_re(x, re().mk_complement(y)));
}
}
for (unsigned i = 0; i < n; ++i) {
expr* arg = args[i], * x;
if (!str().is_in_re(arg) && !(m().is_not(arg, x) && str().is_in_re(x))) {
new_args.push_back(arg);
}
}
result = is_and ? m().mk_and(new_args) : m().mk_or(new_args);
return BR_REWRITE_FULL;
@ -2500,7 +2497,7 @@ expr_ref seq_rewriter::is_nullable(expr* r) {
m_op_cache.insert(_OP_RE_IS_NULLABLE, r, nullptr, result);
}
STRACE("seq_verbose", tout << "is_nullable result: "
<< mk_pp(result, m()) << std::endl;);
<< result << std::endl;);
return result;
}