Skip to content

Commit 99ec42c

Browse files
additional simplifications to seq
1 parent c1719e9 commit 99ec42c

File tree

2 files changed

+72
-7
lines changed

2 files changed

+72
-7
lines changed

src/ast/rewriter/seq_rewriter.cpp

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,10 +1265,23 @@ br_status seq_rewriter::mk_seq_extract(expr* a, expr* b, expr* c, expr_ref& resu
12651265
if (str().is_extract(a, a1, b1, c1) &&
12661266
m_autil.is_numeral(b1, r1) && r1.is_unsigned() &&
12671267
m_autil.is_numeral(c1, r2) && r2.is_unsigned() &&
1268-
constantPos && constantLen &&
1269-
r1 == 0 && r2 >= pos + len) {
1270-
result = str().mk_substr(a1, b, c);
1271-
return BR_REWRITE1;
1268+
constantPos && constantLen) {
1269+
if (r1 == 0 && r2 >= pos + len) {
1270+
result = str().mk_substr(a1, b, c);
1271+
return BR_REWRITE1;
1272+
}
1273+
// pos2 <= len1
1274+
// 0 <= pos1
1275+
// extract(extract(x, pos1, len1), pos2, len2)
1276+
// =
1277+
// extract(x, pos1 + pos2, min(len1 - pos2, len2))
1278+
//
1279+
if (r1 >= 0 && pos <= r2) {
1280+
r2 = std::min(r2 - pos, len);
1281+
r1 += pos;
1282+
result = str().mk_substr(a1, m_autil.mk_numeral(r1, true), m_autil.mk_numeral(r2, true));
1283+
return BR_REWRITE1;
1284+
}
12721285
}
12731286

12741287
if (str().is_extract(a, a1, b1, c1) &&
@@ -4677,8 +4690,7 @@ bool seq_rewriter::has_fixed_length_constraint(expr* a, unsigned& len) {
46774690
return minl == maxl;
46784691
}
46794692

4680-
bool seq_rewriter::lift_str_from_to_re_ite(expr* r, expr_ref& result)
4681-
{
4693+
bool seq_rewriter::lift_str_from_to_re_ite(expr* r, expr_ref& result) {
46824694
expr* cond = nullptr, * then_r = nullptr, * else_r = nullptr;
46834695
expr_ref then_s(m());
46844696
expr_ref else_s(m());
@@ -5421,6 +5433,20 @@ br_status seq_rewriter::mk_eq_core(expr * l, expr * r, expr_ref & result) {
54215433
if (reduce_eq_empty(l, r, result))
54225434
return BR_REWRITE_FULL;
54235435

5436+
#if 0
5437+
if (reduce_arith_eq(l, r, res) || reduce_arith_eq(r, l, res)) {
5438+
result = mk_and(res);
5439+
TRACE("seq_verbose", tout << result << "\n";);
5440+
return BR_REWRITE3;
5441+
}
5442+
5443+
if (reduce_extract(l, r, res)) {
5444+
result = mk_and(res);
5445+
TRACE("seq_verbose", tout << result << "\n";);
5446+
return BR_REWRITE3;
5447+
}
5448+
#endif
5449+
54245450
if (!reduce_eq(l, r, new_eqs, changed)) {
54255451
result = m().mk_false();
54265452
TRACE("seq_verbose", tout << result << "\n";);
@@ -5654,6 +5680,18 @@ bool seq_rewriter::reduce_eq(expr* l, expr* r, expr_ref_pair_vector& new_eqs, bo
56545680
}
56555681
}
56565682

5683+
bool seq_rewriter::reduce_arith_eq(expr* l, expr* r, expr_ref_vector& res) {
5684+
expr* s = nullptr, *sub = nullptr, *idx = nullptr;
5685+
rational i, n;
5686+
if (str().is_index(l, s, sub, idx) && m_autil.is_numeral(idx, i) && m_autil.is_numeral(r, n)) {
5687+
if (n == 0 && i == 0) {
5688+
res.push_back(str().mk_prefix(sub, s));
5689+
return true;
5690+
}
5691+
}
5692+
return false;
5693+
}
5694+
56575695
void seq_rewriter::add_seqs(expr_ref_vector const& ls, expr_ref_vector const& rs, expr_ref_pair_vector& eqs) {
56585696
if (!ls.empty() || !rs.empty()) {
56595697
sort * s = (ls.empty() ? rs[0] : ls[0])->get_sort();
@@ -6090,6 +6128,31 @@ bool seq_rewriter::reduce_value_clash(expr_ref_vector& ls, expr_ref_vector& rs,
60906128
return false;
60916129
}
60926130

6131+
bool seq_rewriter::reduce_extract(expr* l, expr* r, expr_ref_vector& res) {
6132+
expr* sub = nullptr, *p = nullptr, *ln = nullptr;
6133+
m_es.reset();
6134+
str().get_concat(r, m_es);
6135+
rational pos, len;
6136+
if (str().is_extract(l, sub, p, ln) &&
6137+
m_autil.is_numeral(p, pos) && m_autil.is_numeral(ln, len) &&
6138+
0 <= pos &&
6139+
0 <= len &&
6140+
all_of(m_es, [&](expr* e) { return str().is_unit(e); })) {
6141+
6142+
if (len == m_es.size()) {
6143+
expr_ref_vector result(m());
6144+
for (unsigned i = 0; i < pos.get_unsigned(); ++i)
6145+
result.push_back(str().mk_unit(str().mk_nth_i(sub, m_autil.mk_int(i))));
6146+
result.append(m_es);
6147+
res.push_back(str().mk_prefix(str().mk_concat(result, sub->get_sort()), sub));
6148+
return true;
6149+
}
6150+
6151+
}
6152+
return false;
6153+
}
6154+
6155+
60936156
bool seq_rewriter::reduce_subsequence(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs) {
60946157

60956158
if (ls.size() > rs.size())

src/ast/rewriter/seq_rewriter.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,9 +322,11 @@ class seq_rewriter {
322322
bool reduce_non_overlap(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs);
323323
bool reduce_subsequence(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs);
324324
bool reduce_by_length(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs);
325+
bool reduce_extract(expr* l, expr* r, expr_ref_vector& res);
325326
bool has_var(expr_ref_vector const& es);
326327
bool reduce_itos(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs);
327-
bool reduce_eq_empty(expr* l, expr* r, expr_ref& result);
328+
bool reduce_eq_empty(expr* l, expr* r, expr_ref& result);
329+
bool reduce_arith_eq(expr* l, expr* r, expr_ref_vector& constraints);
328330
std::pair<bool, unsigned> min_length(expr_ref_vector const& es);
329331
std::pair<bool, unsigned> min_length(expr* e);
330332
std::pair<bool, unsigned> min_length(unsigned sz, expr* const* es);

0 commit comments

Comments
 (0)