mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 01:25:31 +00:00
Integrate new regex solver (#4602)
* std::cout debugging statements * comment out std::cout debugging as this is now a shared fork * convert std::cout to TRACE statements for seq_rewriter and seq_regex * add cases to min_length and max_length for regexes * bug fix * update min_length and max_length functions for REs * initial pass on simplifying derivative normal forms by eliminating redundant predicates locally * add seq_regex_brief trace statements * working on debugging ref count issue * fix ref count bug and convert trace statements to seq_regex_brief * add compact tracing for cache hits/misses * seq_regex fix cache hit/miss tracing and wrapper around is_nullable * minor * label and disable more experimental changes for testing * minor documentation / tracing * a few more @EXP annotations * dead state elimination skeleton code * progress on dead state elimination * more progress on dead state elimination * refactor dead state class to separate self-contained state_graph class * finish factoring state_graph to only work with unsigned values, and implement separate functionality for expr* logic * implement get_all_derivatives, add debug tracing * trace statements for debugging is_nullable loop bug * fix is_nullable loop bug * comment out local nullable change and mark experimental * pretty printing for state_graph * rewrite state graph to remove the fragile assumption that all edges from a state are added at a time * start of general cycle detection check + fix some comments * implement full cycle detection procedure * normalize derivative conditions to form 'ele <= a' * order derivative conditions by character code * fix confusing names m_to and m_from * assign increasing state IDs from 1 instead of using get_id on AST node * remove elim_condition call in get_dall_derivatives * use u_map instead of uint_map to avoid memory leak * remove unnecessary call to is_ground * debugging * small improvements to seq_regex_brief tracing * fix bug on evil2 example * save work * new propagate code * work in progress on using same seq sort for deriv calls * avoid re-computing derivatives: use same head var for every derivative call * use min_length on regexes to prune search * simple implementation of can_be_in_cycle using rank function idea * add a disabled experimental change * minor cleanup comments, etc. * seq_rewriter cleanup for PR * typo noticed by Nikolaj * move state graph to util/state_graph * re-add accidentally removed line * clean up seq_regex code removing obsolete functions and comments * a few more cleanup items * remove experimental functionality for integration * fix compilation * remove some tracing and TODOs * remove old comment * update copyright dates to 2020 * feedback from Nikolaj * use [] for map access * make state_graph methods constant * avoid recursion in mark_dead_recursive and mark_live_recursive * a possible bug fix in propagate_nonempty * write down list of invariants in state_graph * implement partial invariant check and insert CASSERT statements * expand on invariant check and tracing * finish state graph invariant check * minor tweaks * regex propagation: convert first two axioms to propagations * remove obsolete regex solver functionality Co-authored-by: calebstanford-msr <t-casta@microsoft.com>
This commit is contained in:
parent
293b0b8cc2
commit
976e4c91b0
8 changed files with 922 additions and 257 deletions
|
@ -2617,7 +2617,7 @@ expr_ref seq_rewriter::mk_der_compl(expr* r) {
|
|||
Make an re_predicate with an arbitrary condition cond, enforcing
|
||||
derivative normal form on how conditions are written.
|
||||
|
||||
Tries to rewrites everything to (ele <= x) constraints:
|
||||
Tries to rewrite everything to (ele <= x) constraints:
|
||||
(ele = a) => ite(ele <= a-1, none, ite(ele <= a, epsilon, none))
|
||||
(a = ele) => "
|
||||
(a <= ele) => ite(ele <= a-1, none, epsilon)
|
||||
|
|
|
@ -342,6 +342,5 @@ public:
|
|||
// heuristic elimination of element from condition that comes form a derivative.
|
||||
// special case optimization for conjunctions of equalities, disequalities and ranges.
|
||||
void elim_condition(expr* elem, expr_ref& cond);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -1316,22 +1316,21 @@ unsigned seq_util::re::min_length(expr* r) const {
|
|||
unsigned lo = 0, hi = 0;
|
||||
if (is_empty(r))
|
||||
return UINT_MAX;
|
||||
if (is_concat(r, r1, r2))
|
||||
if (is_concat(r, r1, r2))
|
||||
return u.max_plus(min_length(r1), min_length(r2));
|
||||
if (m.is_ite(r, s, r1, r2))
|
||||
if (is_union(r, r1, r2) || m.is_ite(r, s, r1, r2))
|
||||
return std::min(min_length(r1), min_length(r2));
|
||||
if (is_diff(r, r1, r2))
|
||||
return min_length(r1);
|
||||
if (is_union(r, r1, r2))
|
||||
return std::min(min_length(r1), min_length(r2));
|
||||
if (is_intersection(r, r1, r2))
|
||||
if (is_intersection(r, r1, r2))
|
||||
return std::max(min_length(r1), min_length(r2));
|
||||
if (is_loop(r, r1, lo, hi))
|
||||
if (is_diff(r, r1, r2) || is_reverse(r, r1) || is_plus(r, r1))
|
||||
return min_length(r1);
|
||||
if (is_loop(r, r1, lo) || is_loop(r, r1, lo, hi))
|
||||
return u.max_mul(lo, min_length(r1));
|
||||
if (is_range(r))
|
||||
return 1;
|
||||
if (is_to_re(r, s))
|
||||
if (is_to_re(r, s))
|
||||
return u.str.min_length(s);
|
||||
if (is_range(r) || is_of_pred(r) || is_full_char(r))
|
||||
return 1;
|
||||
// Else: star, option, complement, full_seq, derivative
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1341,22 +1340,21 @@ unsigned seq_util::re::max_length(expr* r) const {
|
|||
unsigned lo = 0, hi = 0;
|
||||
if (is_empty(r))
|
||||
return 0;
|
||||
if (is_concat(r, r1, r2))
|
||||
if (is_concat(r, r1, r2))
|
||||
return u.max_plus(max_length(r1), max_length(r2));
|
||||
if (m.is_ite(r, s, r1, r2))
|
||||
if (is_union(r, r1, r2) || m.is_ite(r, s, r1, r2))
|
||||
return std::max(max_length(r1), max_length(r2));
|
||||
if (is_diff(r, r1, r2))
|
||||
return max_length(r1);
|
||||
if (is_union(r, r1, r2))
|
||||
return std::max(max_length(r1), max_length(r2));
|
||||
if (is_intersection(r, r1, r2))
|
||||
if (is_intersection(r, r1, r2))
|
||||
return std::min(max_length(r1), max_length(r2));
|
||||
if (is_diff(r, r1, r2) || is_reverse(r, r1) || is_opt(r, r1))
|
||||
return max_length(r1);
|
||||
if (is_loop(r, r1, lo, hi))
|
||||
return u.max_mul(hi, max_length(r1));
|
||||
if (is_range(r))
|
||||
return 1;
|
||||
if (is_to_re(r, s))
|
||||
if (is_to_re(r, s))
|
||||
return u.str.max_length(s);
|
||||
if (is_range(r) || is_of_pred(r) || is_full_char(r))
|
||||
return 1;
|
||||
// Else: star, plus, complement, full_seq, loop(r,r1,lo), derivative
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue