mirror of
https://github.com/Z3Prover/z3
synced 2026-08-03 04:33:28 +00:00
catalogue propagation cases for membership
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
1e507cd11e
commit
a8542f5612
2 changed files with 87 additions and 23 deletions
|
|
@ -201,40 +201,96 @@ namespace smt {
|
|||
STRACE(seq_regex_brief, tout << "PIR(" << mk_pp(s, m) << ","
|
||||
<< state_str(r) << ") ";);
|
||||
|
||||
// convert negative negative membership literals to positive
|
||||
// ~(s in R) => s in C(R)
|
||||
if (lit.sign()) {
|
||||
expr_ref fml(re().mk_in_re(s, re().mk_complement(r)), m);
|
||||
rewrite(fml);
|
||||
literal nlit = th.mk_literal(fml);
|
||||
if (lit == nlit) {
|
||||
// is-nullable doesn't simplify for regexes with uninterpreted subterms
|
||||
th.add_unhandled_expr(fml);
|
||||
}
|
||||
th.propagate_lit(nullptr, 1, &lit, nlit);
|
||||
if (unfold_complement(lit, s, r))
|
||||
return;
|
||||
}
|
||||
|
||||
if (coallesce_in_re(lit)) {
|
||||
TRACE(seq_regex, tout
|
||||
<< "simplified conjunctions to an intersection" << std::endl;);
|
||||
STRACE(seq_regex_brief, tout << "coallesce_in_re ";);
|
||||
if (unfold_prefix(lit, s, r))
|
||||
return;
|
||||
|
||||
if (factor_ite(lit, s, r))
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_string_equality(lit)) {
|
||||
TRACE(seq_regex, tout
|
||||
<< "simplified regex using string equality" << std::endl;);
|
||||
STRACE(seq_regex_brief, tout << "string_eq ";);
|
||||
if (coallesce_in_re(lit))
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (is_string_equality(lit))
|
||||
return;
|
||||
|
||||
if (th.use_monadic_regex())
|
||||
add_monadic_membership(lit, s, r);
|
||||
else
|
||||
propagate_accept_legacy(lit, s, r);
|
||||
}
|
||||
|
||||
bool seq_regex::unfold_complement(literal lit, expr *s, expr *r) {
|
||||
if (!lit.sign())
|
||||
return false;
|
||||
// convert negative negative membership literals to positive
|
||||
// ~(s in R) => s in C(R)
|
||||
expr_ref fml(re().mk_in_re(s, re().mk_complement(r)), m);
|
||||
rewrite(fml);
|
||||
literal nlit = th.mk_literal(fml);
|
||||
if (lit == nlit) {
|
||||
// is-nullable doesn't simplify for regexes with uninterpreted subterms
|
||||
th.add_unhandled_expr(fml);
|
||||
}
|
||||
th.propagate_lit(nullptr, 1, &lit, nlit);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool seq_regex::unfold_prefix(literal lit, expr *s, expr *r) {
|
||||
expr_ref_vector prefix(m);
|
||||
expr *hd, *v, *tl = s, *tl1;
|
||||
while (str().is_concat(tl, hd, tl1) && str().is_unit(hd, v))
|
||||
prefix.push_back(v), tl = tl1;
|
||||
|
||||
if (prefix.empty())
|
||||
return false;
|
||||
|
||||
expr_ref q(r, m);
|
||||
for (expr *v : prefix) {
|
||||
q = seq_rw().mk_derivative(v, q);
|
||||
if (re().is_empty(q)) {
|
||||
enode_pair_vector eqs;
|
||||
literal_vector lits;
|
||||
lits.push_back(lit);
|
||||
th.set_conflict(eqs, lits);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
expr_ref fml(re().mk_in_re(tl, q), m);
|
||||
rewrite(fml);
|
||||
literal nlit = th.mk_literal(fml);
|
||||
th.propagate_lit(nullptr, 1, &lit, nlit);
|
||||
TRACE(seq_regex, tout << "unfolded prefix\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool seq_regex::factor_ite(literal lit, expr *s, expr *r) {
|
||||
bool_rewriter br(m);
|
||||
expr_ref c(m), t(m), e(m);
|
||||
if (!br.decompose_ite(r, c, t, e))
|
||||
return false;
|
||||
auto c_lit = th.mk_literal(c);
|
||||
switch (ctx.get_assignment(c_lit)) {
|
||||
case l_true: {
|
||||
literal lits[2] = {lit, c_lit};
|
||||
th.propagate_lit(nullptr, 2, lits, th.mk_literal(re().mk_in_re(s, t)));
|
||||
break;
|
||||
}
|
||||
case l_false: {
|
||||
literal lits[2] = {lit, ~c_lit};
|
||||
th.propagate_lit(nullptr, 2, lits, th.mk_literal(re().mk_in_re(s, e)));
|
||||
break;
|
||||
}
|
||||
case l_undef: {
|
||||
ctx.mark_as_relevant(c_lit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an overapproximating regex s_approx for the input string expression s.
|
||||
* such that for any valuation v(s) of s, v(s) in L(s_approx).
|
||||
|
|
|
|||
|
|
@ -174,6 +174,14 @@ namespace smt {
|
|||
|
||||
bool block_unfolding(literal lit, unsigned i);
|
||||
|
||||
bool unfold_prefix(literal lit, expr *s, expr *r);
|
||||
|
||||
bool unfold_complement(literal lit, expr *s, expr *r);
|
||||
|
||||
bool factor_membership(literal lit, expr *s, expr *r);
|
||||
|
||||
bool factor_ite(literal lit, expr *s, expr *r);
|
||||
|
||||
expr_ref mk_first(expr* r, expr* n);
|
||||
|
||||
bool is_member(expr* r, expr* u);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue