3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-08 18:31:49 +00:00

update re simplification

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2016-01-15 10:11:39 +05:30
parent a295dd48dc
commit 150c5c283d
4 changed files with 95 additions and 4 deletions

View file

@ -222,7 +222,8 @@ br_status seq_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con
case OP_RE_RANGE:
return BR_FAILED;
case OP_RE_INTERSECT:
return BR_FAILED;
SASSERT(num_args == 2);
return mk_re_inter(args[0], args[1], result);
case OP_RE_LOOP:
return mk_re_loop(num_args, args, result);
case OP_RE_EMPTY_SET:
@ -788,6 +789,14 @@ bool seq_rewriter::is_sequence(expr* e, expr_ref_vector& seq) {
}
br_status seq_rewriter::mk_str_in_regexp(expr* a, expr* b, expr_ref& result) {
if (m_util.re.is_empty(b)) {
result = m().mk_false();
return BR_DONE;
}
if (m_util.re.is_full(b)) {
result = m().mk_true();
return BR_DONE;
}
scoped_ptr<eautomaton> aut;
expr_ref_vector seq(m());
if (!(aut = m_re2aut(b))) {
@ -935,6 +944,38 @@ br_status seq_rewriter::mk_re_union(expr* a, expr* b, expr_ref& result) {
}
/**
(emp n r) = emp
(r n emp) = emp
(all n r) = r
(r n all) = r
(r n r) = r
*/
br_status seq_rewriter::mk_re_inter(expr* a, expr* b, expr_ref& result) {
if (a == b) {
result = a;
return BR_DONE;
}
if (m_util.re.is_empty(a)) {
result = a;
return BR_DONE;
}
if (m_util.re.is_empty(b)) {
result = b;
return BR_DONE;
}
if (m_util.re.is_full(a)) {
result = b;
return BR_DONE;
}
if (m_util.re.is_full(b)) {
result = a;
return BR_DONE;
}
return BR_FAILED;
}
br_status seq_rewriter::mk_re_loop(unsigned num_args, expr* const* args, expr_ref& result) {
rational n1, n2;
switch (num_args) {
@ -964,13 +1005,26 @@ br_status seq_rewriter::mk_re_loop(unsigned num_args, expr* const* args, expr_re
(a* + b)* = (a + b)*
(a + b*)* = (a + b)*
(a*b*)* = (a + b)*
a+* = a*
emp* = ""
all* = all
*/
br_status seq_rewriter::mk_re_star(expr* a, expr_ref& result) {
expr* b, *c, *b1, *c1;
if (m_util.re.is_star(a) || m_util.re.is_empty(a) || m_util.re.is_full(a)) {
if (m_util.re.is_star(a) || m_util.re.is_full(a)) {
result = a;
return BR_DONE;
}
if (m_util.re.is_empty(a)) {
sort* seq_sort = 0;
VERIFY(m_util.is_re(a, seq_sort));
result = m_util.re.mk_to_re(m_util.str.mk_empty(seq_sort));
return BR_DONE;
}
if (m_util.re.is_plus(a, b)) {
result = m_util.re.mk_star(b);
return BR_DONE;
}
if (m_util.re.is_union(a, b, c)) {
if (m_util.re.is_star(b, b1)) {
result = m_util.re.mk_star(m_util.re.mk_union(b1, c));
@ -980,6 +1034,14 @@ br_status seq_rewriter::mk_re_star(expr* a, expr_ref& result) {
result = m_util.re.mk_star(m_util.re.mk_union(b, c1));
return BR_REWRITE2;
}
if (is_epsilon(b)) {
result = m_util.re.mk_star(c);
return BR_REWRITE2;
}
if (is_epsilon(c)) {
result = m_util.re.mk_star(b);
return BR_REWRITE2;
}
}
if (m_util.re.is_concat(a, b, c) &&
m_util.re.is_star(b, b1) && m_util.re.is_star(c, c1)) {
@ -991,9 +1053,34 @@ br_status seq_rewriter::mk_re_star(expr* a, expr_ref& result) {
}
/*
emp+ = emp
all+ = all
a*+ = a*
a++ = a+
a+ = aa*
*/
br_status seq_rewriter::mk_re_plus(expr* a, expr_ref& result) {
if (m_util.re.is_empty(a)) {
result = a;
return BR_DONE;
}
if (m_util.re.is_full(a)) {
result = a;
return BR_DONE;
}
if (is_epsilon(a)) {
result = a;
return BR_DONE;
}
if (m_util.re.is_plus(a)) {
result = a;
return BR_DONE;
}
if (m_util.re.is_star(a)) {
result = a;
return BR_DONE;
}
return BR_FAILED;
// result = m_util.re.mk_concat(a, m_util.re.mk_star(a));
// return BR_REWRITE2;

View file

@ -95,6 +95,7 @@ class seq_rewriter {
br_status mk_str_to_regexp(expr* a, expr_ref& result);
br_status mk_re_concat(expr* a, expr* b, expr_ref& result);
br_status mk_re_union(expr* a, expr* b, expr_ref& result);
br_status mk_re_inter(expr* a, expr* b, expr_ref& result);
br_status mk_re_star(expr* a, expr_ref& result);
br_status mk_re_plus(expr* a, expr_ref& result);
br_status mk_re_opt(expr* a, expr_ref& result);

View file

@ -612,9 +612,8 @@ func_decl * seq_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters,
func_decl_info(m_family_id, OP_STRING_CONST, num_parameters, parameters));
case OP_RE_UNION:
return mk_assoc_fun(k, arity, domain, range, k, k);
case OP_RE_CONCAT:
case OP_RE_INTERSECT:
return mk_assoc_fun(k, arity, domain, range, k, k);
case OP_SEQ_CONCAT:

View file

@ -105,6 +105,8 @@ public:
// create an automaton from initial state, final states, and moves
automaton(M& m, unsigned init, unsigned_vector const& final, moves const& mvs): m(m) {
m_init = init;
m_delta.push_back(moves());
m_delta_inv.push_back(moves());
for (unsigned i = 0; i < final.size(); ++i) {
add_to_final_states(final[i]);
}
@ -331,6 +333,7 @@ public:
// Src - ET -> dst - e -> dst1 => Src - ET -> dst1 if out_degree(dst) = 1,
//
void compress() {
SASSERT(!m_delta.empty());
for (unsigned i = 0; i < m_delta.size(); ++i) {
for (unsigned j = 0; j < m_delta[i].size(); ++j) {
move const& mv = m_delta[i][j];
@ -419,6 +422,7 @@ public:
}
}
}
SASSERT(!m_delta.empty());
while (true) {
SASSERT(!m_delta.empty());
unsigned src = m_delta.size() - 1;