@@ -1265,10 +1265,23 @@ br_status seq_rewriter::mk_seq_extract(expr* a, expr* b, expr* c, expr_ref& resu
1265
1265
if (str ().is_extract (a, a1, b1, c1) &&
1266
1266
m_autil.is_numeral (b1, r1) && r1.is_unsigned () &&
1267
1267
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
+ }
1272
1285
}
1273
1286
1274
1287
if (str ().is_extract (a, a1, b1, c1) &&
@@ -4677,8 +4690,7 @@ bool seq_rewriter::has_fixed_length_constraint(expr* a, unsigned& len) {
4677
4690
return minl == maxl;
4678
4691
}
4679
4692
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) {
4682
4694
expr* cond = nullptr , * then_r = nullptr , * else_r = nullptr ;
4683
4695
expr_ref then_s (m ());
4684
4696
expr_ref else_s (m ());
@@ -5421,6 +5433,20 @@ br_status seq_rewriter::mk_eq_core(expr * l, expr * r, expr_ref & result) {
5421
5433
if (reduce_eq_empty (l, r, result))
5422
5434
return BR_REWRITE_FULL;
5423
5435
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
+
5424
5450
if (!reduce_eq (l, r, new_eqs, changed)) {
5425
5451
result = m ().mk_false ();
5426
5452
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
5654
5680
}
5655
5681
}
5656
5682
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
+
5657
5695
void seq_rewriter::add_seqs (expr_ref_vector const & ls, expr_ref_vector const & rs, expr_ref_pair_vector& eqs) {
5658
5696
if (!ls.empty () || !rs.empty ()) {
5659
5697
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,
6090
6128
return false ;
6091
6129
}
6092
6130
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
+
6093
6156
bool seq_rewriter::reduce_subsequence (expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs) {
6094
6157
6095
6158
if (ls.size () > rs.size ())
0 commit comments