mirror of
https://github.com/Z3Prover/z3
synced 2025-06-03 21:01:22 +00:00
update re simplification
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
a295dd48dc
commit
150c5c283d
4 changed files with 95 additions and 4 deletions
|
@ -222,7 +222,8 @@ br_status seq_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con
|
||||||
case OP_RE_RANGE:
|
case OP_RE_RANGE:
|
||||||
return BR_FAILED;
|
return BR_FAILED;
|
||||||
case OP_RE_INTERSECT:
|
case OP_RE_INTERSECT:
|
||||||
return BR_FAILED;
|
SASSERT(num_args == 2);
|
||||||
|
return mk_re_inter(args[0], args[1], result);
|
||||||
case OP_RE_LOOP:
|
case OP_RE_LOOP:
|
||||||
return mk_re_loop(num_args, args, result);
|
return mk_re_loop(num_args, args, result);
|
||||||
case OP_RE_EMPTY_SET:
|
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) {
|
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;
|
scoped_ptr<eautomaton> aut;
|
||||||
expr_ref_vector seq(m());
|
expr_ref_vector seq(m());
|
||||||
if (!(aut = m_re2aut(b))) {
|
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) {
|
br_status seq_rewriter::mk_re_loop(unsigned num_args, expr* const* args, expr_ref& result) {
|
||||||
rational n1, n2;
|
rational n1, n2;
|
||||||
switch (num_args) {
|
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 + 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) {
|
br_status seq_rewriter::mk_re_star(expr* a, expr_ref& result) {
|
||||||
expr* b, *c, *b1, *c1;
|
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;
|
result = a;
|
||||||
return BR_DONE;
|
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_union(a, b, c)) {
|
||||||
if (m_util.re.is_star(b, b1)) {
|
if (m_util.re.is_star(b, b1)) {
|
||||||
result = m_util.re.mk_star(m_util.re.mk_union(b1, c));
|
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));
|
result = m_util.re.mk_star(m_util.re.mk_union(b, c1));
|
||||||
return BR_REWRITE2;
|
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) &&
|
if (m_util.re.is_concat(a, b, c) &&
|
||||||
m_util.re.is_star(b, b1) && m_util.re.is_star(c, c1)) {
|
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*
|
a+ = aa*
|
||||||
*/
|
*/
|
||||||
br_status seq_rewriter::mk_re_plus(expr* a, expr_ref& result) {
|
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;
|
return BR_FAILED;
|
||||||
// result = m_util.re.mk_concat(a, m_util.re.mk_star(a));
|
// result = m_util.re.mk_concat(a, m_util.re.mk_star(a));
|
||||||
// return BR_REWRITE2;
|
// return BR_REWRITE2;
|
||||||
|
|
|
@ -95,6 +95,7 @@ class seq_rewriter {
|
||||||
br_status mk_str_to_regexp(expr* a, expr_ref& result);
|
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_concat(expr* a, expr* b, expr_ref& result);
|
||||||
br_status mk_re_union(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_star(expr* a, expr_ref& result);
|
||||||
br_status mk_re_plus(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);
|
br_status mk_re_opt(expr* a, expr_ref& result);
|
||||||
|
|
|
@ -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));
|
func_decl_info(m_family_id, OP_STRING_CONST, num_parameters, parameters));
|
||||||
|
|
||||||
case OP_RE_UNION:
|
case OP_RE_UNION:
|
||||||
return mk_assoc_fun(k, arity, domain, range, k, k);
|
|
||||||
|
|
||||||
case OP_RE_CONCAT:
|
case OP_RE_CONCAT:
|
||||||
|
case OP_RE_INTERSECT:
|
||||||
return mk_assoc_fun(k, arity, domain, range, k, k);
|
return mk_assoc_fun(k, arity, domain, range, k, k);
|
||||||
|
|
||||||
case OP_SEQ_CONCAT:
|
case OP_SEQ_CONCAT:
|
||||||
|
|
|
@ -105,6 +105,8 @@ public:
|
||||||
// create an automaton from initial state, final states, and moves
|
// create an automaton from initial state, final states, and moves
|
||||||
automaton(M& m, unsigned init, unsigned_vector const& final, moves const& mvs): m(m) {
|
automaton(M& m, unsigned init, unsigned_vector const& final, moves const& mvs): m(m) {
|
||||||
m_init = init;
|
m_init = init;
|
||||||
|
m_delta.push_back(moves());
|
||||||
|
m_delta_inv.push_back(moves());
|
||||||
for (unsigned i = 0; i < final.size(); ++i) {
|
for (unsigned i = 0; i < final.size(); ++i) {
|
||||||
add_to_final_states(final[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,
|
// Src - ET -> dst - e -> dst1 => Src - ET -> dst1 if out_degree(dst) = 1,
|
||||||
//
|
//
|
||||||
void compress() {
|
void compress() {
|
||||||
|
SASSERT(!m_delta.empty());
|
||||||
for (unsigned i = 0; i < m_delta.size(); ++i) {
|
for (unsigned i = 0; i < m_delta.size(); ++i) {
|
||||||
for (unsigned j = 0; j < m_delta[i].size(); ++j) {
|
for (unsigned j = 0; j < m_delta[i].size(); ++j) {
|
||||||
move const& mv = m_delta[i][j];
|
move const& mv = m_delta[i][j];
|
||||||
|
@ -419,6 +422,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SASSERT(!m_delta.empty());
|
||||||
while (true) {
|
while (true) {
|
||||||
SASSERT(!m_delta.empty());
|
SASSERT(!m_delta.empty());
|
||||||
unsigned src = m_delta.size() - 1;
|
unsigned src = m_delta.size() - 1;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue