From b1d167de5bd0aea754ecf881ad8cb85329d03e6c Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 14 Dec 2021 10:12:38 -0800 Subject: [PATCH] fix co-factoring' Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/seq_skolem.cpp | 1 + src/ast/rewriter/seq_skolem.h | 6 ++++++ src/smt/seq_regex.cpp | 7 ++++--- src/smt/seq_regex.h | 4 ++-- src/smt/theory_seq.cpp | 4 ++++ 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/ast/rewriter/seq_skolem.cpp b/src/ast/rewriter/seq_skolem.cpp index ff67ff0bd12..c2e94821685 100644 --- a/src/ast/rewriter/seq_skolem.cpp +++ b/src/ast/rewriter/seq_skolem.cpp @@ -38,6 +38,7 @@ skolem::skolem(ast_manager& m, th_rewriter& rw): m_max_unfolding = "seq.max_unfolding"; m_length_limit = "seq.length_limit"; m_is_empty = "re.is_empty"; + m_is_non_empty = "re.is_non_empty"; } expr_ref skolem::mk(symbol const& s, expr* e1, expr* e2, expr* e3, expr* e4, sort* range, bool rw) { diff --git a/src/ast/rewriter/seq_skolem.h b/src/ast/rewriter/seq_skolem.h index 799b5ca074e..088a00eeb0b 100644 --- a/src/ast/rewriter/seq_skolem.h +++ b/src/ast/rewriter/seq_skolem.h @@ -37,6 +37,7 @@ namespace seq { symbol m_aut_step; // regex unfolding state symbol m_accept; // regex symbol m_is_empty; // regex emptiness check + symbol m_is_non_empty; symbol m_pre, m_post; // inverse of at: (pre s i) + (at s i) + (post s i) = s if 0 <= i < (len s) symbol m_postp; symbol m_eq; // equality atom @@ -74,6 +75,7 @@ namespace seq { expr_ref mk_accept(expr_ref_vector const& args) { return expr_ref(seq.mk_skolem(m_accept, args.size(), args.data(), m.mk_bool_sort()), m); } expr_ref mk_accept(expr* s, expr* i, expr* r) { return mk(m_accept, s, i, r, nullptr, m.mk_bool_sort()); } expr_ref mk_is_empty(expr* r, expr* u, expr* n) { return mk(m_is_empty, r, u, n, m.mk_bool_sort(), false); } + expr_ref mk_is_non_empty(expr* r, expr* u, expr* n) { return mk(m_is_non_empty, r, u, n, m.mk_bool_sort(), false); } expr_ref mk_indexof_left(expr* t, expr* s, expr* offset = nullptr) { return mk(m_indexof_left, t, s, offset); } expr_ref mk_indexof_right(expr* t, expr* s, expr* offset = nullptr) { return mk(m_indexof_right, t, s, offset); } @@ -155,6 +157,10 @@ namespace seq { bool is_is_empty(expr* e, expr*& r, expr*& u, expr*& n) const { return is_skolem(m_is_empty, e) && (r = to_app(e)->get_arg(0), u = to_app(e)->get_arg(1), n = to_app(e)->get_arg(2), true); } + bool is_is_non_empty(expr* e) const { return is_skolem(m_is_non_empty, e); } + bool is_is_non_empty(expr* e, expr*& r, expr*& u, expr*& n) const { + return is_skolem(m_is_non_empty, e) && (r = to_app(e)->get_arg(0), u = to_app(e)->get_arg(1), n = to_app(e)->get_arg(2), true); + } void decompose(expr* e, expr_ref& head, expr_ref& tail); diff --git a/src/smt/seq_regex.cpp b/src/smt/seq_regex.cpp index 8ac66ec9718..fe716c20d83 100644 --- a/src/smt/seq_regex.cpp +++ b/src/smt/seq_regex.cpp @@ -524,9 +524,10 @@ namespace smt { sort* seq_sort = nullptr; VERIFY(u().is_re(r1, seq_sort)); expr_ref r = symmetric_diff(r1, r2); - expr_ref s(m.mk_fresh_const("re.member", seq_sort), m); - expr_ref is_member(re().mk_in_re(s, r), m); - th.add_axiom(th.mk_eq(r1, r2, false), th.mk_literal(is_member)); + expr_ref emp(re().mk_empty(r->get_sort()), m); + expr_ref n(m.mk_fresh_const("re.char", seq_sort), m); + expr_ref is_non_empty = sk().mk_is_non_empty(r, r, n); + th.add_axiom(th.mk_eq(r1, r2, false), th.mk_literal(is_non_empty)); } bool seq_regex::is_member(expr* r, expr* u) { diff --git a/src/smt/seq_regex.h b/src/smt/seq_regex.h index 201369d2cb7..5c3fddd252e 100644 --- a/src/smt/seq_regex.h +++ b/src/smt/seq_regex.h @@ -184,8 +184,6 @@ namespace smt { bool block_if_empty(expr* r, literal lit); - void propagate_is_non_empty(literal lit); - public: seq_regex(theory_seq& th); @@ -206,6 +204,8 @@ namespace smt { void propagate_ne(expr* r1, expr* r2); void propagate_is_empty(literal lit); + + void propagate_is_non_empty(literal lit); }; diff --git a/src/smt/theory_seq.cpp b/src/smt/theory_seq.cpp index 842798bab74..369adccc1b5 100644 --- a/src/smt/theory_seq.cpp +++ b/src/smt/theory_seq.cpp @@ -3033,6 +3033,10 @@ void theory_seq::assign_eh(bool_var v, bool is_true) { propagate_length_limit(e); } } + else if (m_sk.is_is_non_empty(e)) { + if (is_true) + m_regex.propagate_is_non_empty(lit); + } else if (m_util.str.is_lt(e) || m_util.str.is_le(e)) { m_lts.push_back(e); }