diff --git a/.gitignore b/.gitignore index df4e3266d..8e5bd7294 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ crashes/ *.pyo # Ignore callgrind files callgrind.out.* +gmon.out # .hpp files are automatically generated *.hpp .env diff --git a/gmon.out b/gmon.out deleted file mode 100644 index cba10a19b..000000000 Binary files a/gmon.out and /dev/null differ diff --git a/src/ast/rewriter/CMakeLists.txt b/src/ast/rewriter/CMakeLists.txt index 10f7130ec..3c5f6defe 100644 --- a/src/ast/rewriter/CMakeLists.txt +++ b/src/ast/rewriter/CMakeLists.txt @@ -39,6 +39,7 @@ z3_add_component(rewriter rewriter.cpp seq_axioms.cpp seq_eq_solver.cpp + seq_derive.cpp seq_subset.cpp seq_derive.cpp seq_rewriter.cpp diff --git a/src/ast/rewriter/seq_derive.cpp b/src/ast/rewriter/seq_derive.cpp index 4f0233961..8f5831086 100644 --- a/src/ast/rewriter/seq_derive.cpp +++ b/src/ast/rewriter/seq_derive.cpp @@ -615,9 +615,16 @@ namespace seq { } bool derive::pred_implies(expr* a, expr* b) { +<<<<<<< HEAD bool sign_a = m.is_not(a, a); bool sign_b = m.is_not(b, b); return pred_implies(sign_a, a, sign_b, b); +======= + expr* nota = nullptr, * notb = nullptr; + bool sign_a = m.is_not(a, nota); + bool sign_b = m.is_not(b, notb); + return pred_implies(sign_a, sign_a ? nota : a, sign_b, sign_b ? notb : b); +>>>>>>> b5afa9200e22209daec4b6d64831f89b8b1dc822 } expr_ref derive::mk_union(expr* a, expr* b) { @@ -748,11 +755,14 @@ namespace seq { return expr_ref(re().mk_to_re(u().str.mk_concat(s1, s2)), m); // r* · r* → r* + expr* a1 = nullptr, *a2 = nullptr, * b1 = nullptr; + if (re().is_star(a, a1) && re().is_star(b, b1) && a1 == b1) return expr_ref(a, m); // Right-associate: (a · b) · c → a · (b · c) + if (re().is_concat(a, a1, a2)) return mk_concat(a1, mk_concat(a2, b)); @@ -883,6 +893,7 @@ namespace seq { expr* saved_path_expr = m_path_expr; // Push atoms onto path and check for contradiction or implication +<<<<<<< HEAD lbool result = push_path_atoms(c, sign); if (result != l_undef) { m_path.shrink(saved_path_sz); @@ -898,6 +909,31 @@ namespace seq { m_intervals.shrink(saved_intervals_sz); m_intervals_start = saved_intervals_start; return result; +======= + lbool atoms_result = push_path_atoms(c, sign); + if (atoms_result == l_false) { + m_path.shrink(saved_path_sz); + m_intervals.shrink(saved_intervals_sz); + m_intervals_start = saved_intervals_start; + return l_false; + } + + // Update intervals + lbool intervals_result = push_intervals_impl(c, sign); + if (intervals_result == l_false) { + m_path.shrink(saved_path_sz); + m_intervals.shrink(saved_intervals_sz); + m_intervals_start = saved_intervals_start; + return l_false; + } + + // If either determined the atom is implied, no need to actually push + if (atoms_result == l_true || intervals_result == l_true) { + m_path.shrink(saved_path_sz); + m_intervals.shrink(saved_intervals_sz); + m_intervals_start = saved_intervals_start; + return l_true; +>>>>>>> b5afa9200e22209daec4b6d64831f89b8b1dc822 } // Update path expression diff --git a/src/ast/rewriter/seq_rewriter.cpp b/src/ast/rewriter/seq_rewriter.cpp index a4d7816b5..73a5e6417 100644 --- a/src/ast/rewriter/seq_rewriter.cpp +++ b/src/ast/rewriter/seq_rewriter.cpp @@ -2613,8 +2613,7 @@ expr_ref seq_rewriter::is_nullable(expr* r) { return result; } - -/ () +/* Push reverse inwards (whenever possible). */ br_status seq_rewriter::mk_re_reverse(expr* r, expr_ref& result) { @@ -2842,14 +2841,6 @@ expr_ref seq_rewriter::mk_derivative(expr* r) { return result; } -expr_ref seq_rewriter::mk_brz_derivative(expr* r) { - sort* seq_sort = nullptr, * ele_sort = nullptr; - VERIFY(m_util.is_re(r, seq_sort)); - VERIFY(m_util.is_seq(seq_sort, ele_sort)); - expr_ref v(m().mk_var(0, ele_sort), m()); - return mk_derivative_rec(v, r); -} - expr_ref seq_rewriter::mk_derivative(expr* ele, expr* r) { auto result = m_derive(ele, r); TRACE(seq, @@ -3010,6 +3001,7 @@ expr_ref seq_rewriter::merge_regex_sets(expr* r1, expr* r2, expr* unit, return composeresult(ar); } } + /* * calls elim_condition */ @@ -3396,7 +3388,6 @@ expr_ref seq_rewriter::mk_der_cond(expr* cond, expr* ele, sort* seq_sort) { } - /************************************************* ***** End Derivative Code ***** *************************************************/ diff --git a/src/ast/rewriter/seq_rewriter.h b/src/ast/rewriter/seq_rewriter.h index 62f79bd99..7b8058353 100644 --- a/src/ast/rewriter/seq_rewriter.h +++ b/src/ast/rewriter/seq_rewriter.h @@ -139,8 +139,14 @@ class seq_rewriter { // re2automaton m_re2aut; op_cache m_op_cache; expr_ref_vector m_es, m_lhs, m_rhs; +<<<<<<< HEAD bool m_coalesce_chars; bool m_in_bisim { false }; +======= + bool m_coalesce_chars; + unsigned m_re_deriv_depth { 0 }; + static const unsigned m_max_re_deriv_depth = 512; +>>>>>>> b5afa9200e22209daec4b6d64831f89b8b1dc822 enum length_comparison { shorter_c, @@ -332,7 +338,7 @@ class seq_rewriter { public: seq_rewriter(ast_manager & m, params_ref const & p = params_ref()): - m_util(m), m_subset(m_util.re), m_autil(m), m_br(m, p), m_derive(m, *this), // m_re2aut(m), + m_util(m), m_subset(m_util.re), m_autil(m), m_br(m, p), m_derive(m, *this), m_op_cache(m), m_es(m), m_lhs(m), m_rhs(m) { } diff --git a/src/ast/rewriter/seq_subset.cpp b/src/ast/rewriter/seq_subset.cpp index 2fc4d1f71..f12bc32b1 100644 --- a/src/ast/rewriter/seq_subset.cpp +++ b/src/ast/rewriter/seq_subset.cpp @@ -19,7 +19,7 @@ Author: bool seq_subset::is_subset_rec(expr* a, expr* b, unsigned depth) const { while (true) { - + if (a == b) return true; if (m_re.is_empty(a)) @@ -30,7 +30,7 @@ bool seq_subset::is_subset_rec(expr* a, expr* b, unsigned depth) const { return true; if (depth >= m_max_depth) - return false; + return false; expr* a1 = nullptr, * a2 = nullptr, * b1 = nullptr, * b2 = nullptr; unsigned la, ua, lb, ub; @@ -39,16 +39,12 @@ bool seq_subset::is_subset_rec(expr* a, expr* b, unsigned depth) const { if (m_re.is_dot_plus(b) && m_re.get_info(a).nullable == l_false) return true; - // a ⊆ a* - if (m_re.is_star(b, b1) && is_subset_rec(a, b1, depth)) - return true; - // e ⊆ a* if (m_re.is_epsilon(a) && m_re.is_star(b, b1)) return true; - // R ⊆ R* - if (m_re.is_star(b, b1) && is_subset_rec(a, b1, depth + 1)) + // a ⊆ a*: if b = b1* and a ⊆ b1, then a ⊆ b1* + if (m_re.is_star(b, b1) && is_subset_rec(a, b1, depth)) return true; // R1* ⊆ R2* if R1 ⊆ R2