3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-06-19 07:06:28 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2026-06-10 15:31:01 -07:00
commit c9cd5147be
7 changed files with 51 additions and 20 deletions

1
.gitignore vendored
View file

@ -6,6 +6,7 @@ crashes/
*.pyo
# Ignore callgrind files
callgrind.out.*
gmon.out
# .hpp files are automatically generated
*.hpp
.env

BIN
gmon.out

Binary file not shown.

View file

@ -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

View file

@ -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

View file

@ -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 *****
*************************************************/

View file

@ -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) {
}

View file

@ -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