From 6c4c9a10e4be2ae1baf646580f635a831f319b02 Mon Sep 17 00:00:00 2001 From: Murphy Berzish Date: Tue, 16 Jan 2018 13:16:31 -0500 Subject: [PATCH] regex length linearity check WIP --- src/smt/theory_str.cpp | 34 ++++++++++++++++++++++++++++++++++ src/smt/theory_str.h | 2 ++ 2 files changed, 36 insertions(+) diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 4c36b0f45..c19b17aec 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -6604,6 +6604,40 @@ namespace smt { return 1; } } + + // Check whether a regex translates well to a linear set of length constraints. + bool theory_str::check_regex_length_linearity(expr * re) { + return check_regex_length_linearity_helper(re, false); + } + + bool theory_str::check_regex_length_linearity_helper(expr * re, bool already_star) { + expr * sub1; + expr * sub2; + if (u.re.is_to_re(re)) { + return true; + } else if (u.re.is_concat(re, sub1, sub2)) { + return check_regex_length_linearity_helper(sub1, already_star) && check_regex_length_linearity_helper(sub2, already_star); + } else if (u.re.is_union(re, sub1, sub2)) { + return check_regex_length_linearity_helper(sub1, already_star) && check_regex_length_linearity_helper(sub2, already_star); + } else if (u.re.is_star(re, sub1) || u.re.is_plus(re, sub1)) { + if (already_star) { + return false; + } else { + return check_regex_length_linearity_helper(sub1, true); + } + } else if (u.re.is_range(re)) { + return true; + } else if (u.re.is_full(re)) { + return true; + } else if (u.re.is_complement(re)) { + // TODO can we do better? + return false; + } else { + TRACE("str", tout << "WARNING: unknown regex term " << mk_pp(re, get_manager()) << std::endl;); + UNREACHABLE(); return false; + } + } + /* * Infer all length constraints implied by the given regular expression `re` * in order to constrain `lenVar` (which must be of sort Int). diff --git a/src/smt/theory_str.h b/src/smt/theory_str.h index acab8e019..26a6acf8d 100644 --- a/src/smt/theory_str.h +++ b/src/smt/theory_str.h @@ -544,6 +544,8 @@ protected: // regex automata and length-aware regex unsigned estimate_regex_complexity(expr * re); unsigned estimate_regex_complexity_under_complement(expr * re); + bool check_regex_length_linearity(expr * re); + bool check_regex_length_linearity_helper(expr * re, bool already_star); expr_ref infer_all_regex_lengths(expr * lenVar, expr * re, expr_ref_vector & freeVariables); bool refine_automaton_lower_bound(eautomaton * aut, rational current_lower_bound, rational & refined_lower_bound); bool refine_automaton_upper_bound(eautomaton * aut, rational current_upper_bound, rational & refined_upper_bound);