3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-23 06:13:40 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-11-22 15:28:33 -08:00
parent 7bc3b4e381
commit f591e0948a
8 changed files with 209 additions and 210 deletions

View file

@ -738,7 +738,6 @@ br_status seq_rewriter::mk_seq_contains(expr* a, expr* b, expr_ref& result) {
return BR_REWRITE2;
}
std::function<bool(expr*)> is_unit = [&](expr *e) { return m_util.str.is_unit(e); };
if (bs.forall(is_unit) && as.forall(is_unit)) {
@ -754,6 +753,16 @@ br_status seq_rewriter::mk_seq_contains(expr* a, expr* b, expr_ref& result) {
return BR_REWRITE_FULL;
}
if (bs.size() == 1 && bs.forall(is_unit) && as.size() > 1) {
expr_ref_vector ors(m());
for (expr* ai : as) {
ors.push_back(m_util.str.mk_contains(ai, bs.get(0)));
}
result = ::mk_or(ors);
return BR_REWRITE_FULL;
}
return BR_FAILED;
}
@ -1575,6 +1584,34 @@ br_status seq_rewriter::mk_eq_core(expr * l, expr * r, expr_ref & result) {
return BR_REWRITE3;
}
/**
* t = (concat (unit (nth t 0)) (unit (nth t 1)) (unit (nth t 2)) .. (unit (nth t k-1)))
* ->
* (length t) = k
*/
bool seq_rewriter::reduce_nth_eq(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_vector& lhs, expr_ref_vector& rhs) {
if (ls.size() == 1 && !rs.empty()) {
expr* l = ls.get(0);
for (unsigned i = 0; i < rs.size(); ++i) {
unsigned k = 0;
expr* ru = nullptr, *r = nullptr;
if (m_util.str.is_unit(rs.get(i), ru) && m_util.str.is_nth(ru, r, k) && k == i && r == l) {
continue;
}
return false;
}
arith_util a(m());
lhs.push_back(m_util.str.mk_length(l));
rhs.push_back(a.mk_int(rs.size()));
ls.reset();
rs.reset();
return true;
}
else if (rs.size() == 1 && !ls.empty()) {
return reduce_nth_eq(rs, ls, rhs, lhs);
}
return false;
}
bool seq_rewriter::reduce_eq(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_vector& lhs, expr_ref_vector& rhs, bool& change) {
expr* a, *b;
@ -1582,6 +1619,10 @@ bool seq_rewriter::reduce_eq(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_
bool lchange = false;
SASSERT(lhs.empty());
TRACE("seq", tout << ls << "\n"; tout << rs << "\n";);
if (reduce_nth_eq(ls, rs, lhs, rhs)) {
change = true;
return true;
}
// solve from back
while (true) {
while (!rs.empty() && m_util.str.is_empty(rs.back())) {

View file

@ -170,6 +170,8 @@ public:
bool reduce_contains(expr* a, expr* b, expr_ref_vector& disj);
bool reduce_nth_eq(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_vector& lhs, expr_ref_vector& rhs);
void add_seqs(expr_ref_vector const& ls, expr_ref_vector const& rs, expr_ref_vector& lhs, expr_ref_vector& rhs);