@@ -21,6 +21,7 @@ Module Name:
21
21
#include " ast/rewriter/seq_rewriter.h"
22
22
#include " ast/arith_decl_plugin.h"
23
23
#include " ast/ast_pp.h"
24
+ #include " ast/ast_ll_pp.h"
24
25
#include " ast/ast_util.h"
25
26
#include " util/uint_set.h"
26
27
#include " math/automata/automaton.h"
@@ -546,7 +547,7 @@ br_status seq_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con
546
547
case _OP_STRING_STRIDOF:
547
548
UNREACHABLE ();
548
549
}
549
- CTRACE (" seq " , st != BR_FAILED, tout << result << " \n " ;);
550
+ CTRACE (" seq_verbose " , st != BR_FAILED, tout << result << " \n " ;);
550
551
return st;
551
552
}
552
553
@@ -643,14 +644,38 @@ br_status seq_rewriter::mk_seq_length(expr* a, expr_ref& result) {
643
644
result = m_autil.mk_add (es.size (), es.c_ptr ());
644
645
return BR_REWRITE2;
645
646
}
647
+ expr* c = nullptr , *t = nullptr , *e = nullptr ;
648
+ if (m ().is_ite (a, c, t, e) && (t->get_ref_count () == 1 || e->get_ref_count () == 1 )) {
649
+ result = m ().mk_ite (c, m_util.str .mk_length (t), m_util.str .mk_length (e));
650
+ return BR_REWRITE3;
651
+ }
652
+ #if 0
653
+ expr* s = nullptr, *offs = nullptr, *l = nullptr;
654
+ // len(extract(s, offs, len(s) - offs)) = max(0, len(s) - offs)
655
+ //
656
+ if (m_util.str.is_extract(a, s, offs, l) && is_suffix(s, offs, l)) {
657
+ expr_ref zero(m_autil.mk_int(0), m());
658
+ result = m_autil.mk_sub(m_util.str.mk_length(s), offs);
659
+ result = m().mk_ite(m_autil.mk_ge(result, zero), result, zero);
660
+ return BR_REWRITE_FULL;
661
+ }
662
+ #endif
646
663
return BR_FAILED;
647
664
}
648
665
666
+ bool seq_rewriter::is_suffix (expr* s, expr* offset, expr* len) {
667
+ expr_ref_vector lens (m ());
668
+ rational a, b;
669
+ return
670
+ get_lengths (len, lens, a) &&
671
+ (a.neg (), m_autil.is_numeral (offset, b) && b.is_pos () && a == b);
672
+ }
673
+
649
674
br_status seq_rewriter::mk_seq_extract (expr* a, expr* b, expr* c, expr_ref& result) {
650
675
zstring s;
651
676
rational pos, len;
652
677
653
- TRACE (" seq " , tout << mk_pp (a, m ()) << " " << mk_pp (b, m ()) << " " << mk_pp (c, m ()) << " \n " ;);
678
+ TRACE (" seq_verbose " , tout << mk_pp (a, m ()) << " " << mk_pp (b, m ()) << " " << mk_pp (c, m ()) << " \n " ;);
654
679
bool constantBase = m_util.str .is_string (a, s);
655
680
bool constantPos = m_autil.is_numeral (b, pos);
656
681
bool constantLen = m_autil.is_numeral (c, len);
@@ -702,7 +727,8 @@ br_status seq_rewriter::mk_seq_extract(expr* a, expr* b, expr* c, expr_ref& resu
702
727
m_lhs.reset ();
703
728
expr_ref_vector lens (m ());
704
729
m_util.str .get_concat (a, m_lhs);
705
- if (!get_lengths (b, lens, pos)) {
730
+ TRACE (" seq" , tout << m_lhs << " " << pos << " " << lens << " \n " ;);
731
+ if (!get_lengths (b, lens, pos) || pos.is_neg ()) {
706
732
return BR_FAILED;
707
733
}
708
734
unsigned i = 0 ;
@@ -742,9 +768,20 @@ br_status seq_rewriter::mk_seq_extract(expr* a, expr* b, expr* c, expr_ref& resu
742
768
743
769
// (extract s 0 (len s)) = s
744
770
expr* a2 = nullptr ;
745
- if (_pos == 0 && m_util.str .is_length (c, a2) && a == a2) {
746
- result = a;
747
- return BR_DONE;
771
+ if (_pos == 0 && m_util.str .is_length (c, a2)) {
772
+ m_lhs.reset ();
773
+ m_util.str .get_concat (a, m_lhs);
774
+ if (!m_lhs.empty () && m_lhs.get (0 ) == a2) {
775
+ result = a2;
776
+ return BR_DONE;
777
+ }
778
+ }
779
+
780
+ expr* a1 = nullptr , *b1 = nullptr , *c1 = nullptr ;
781
+ if (m_util.str .is_extract (a, a1, b1, c1) &&
782
+ is_suffix (a1, b1, c1) && is_suffix (a, b, c)) {
783
+ result = m_util.str .mk_substr (a1, m_autil.mk_add (b1, b), m_autil.mk_sub (c1, b));
784
+ return BR_REWRITE3;
748
785
}
749
786
750
787
unsigned offset = 0 ;
@@ -799,7 +836,7 @@ bool seq_rewriter::get_lengths(expr* e, expr_ref_vector& lens, rational& pos) {
799
836
else {
800
837
return false ;
801
838
}
802
- return !pos. is_neg () ;
839
+ return true ;
803
840
}
804
841
805
842
bool seq_rewriter::cannot_contain_suffix (expr* a, expr* b) {
@@ -992,9 +1029,28 @@ br_status seq_rewriter::mk_seq_at(expr* a, expr* b, expr_ref& result) {
992
1029
}
993
1030
994
1031
br_status seq_rewriter::mk_seq_nth (expr* a, expr* b, expr_ref& result) {
1032
+
1033
+ rational pos1, pos2;
1034
+ expr* s = nullptr , *p = nullptr , *len = nullptr ;
1035
+ if (m_util.str .is_unit (a, s) && m_autil.is_numeral (b, pos1) && pos1.is_zero ()) {
1036
+ result = s;
1037
+ return BR_DONE;
1038
+ }
1039
+ if (m_util.str .is_extract (a, s, p, len) && m_autil.is_numeral (p, pos1)) {
1040
+ expr_ref_vector lens (m ());
1041
+ rational pos2;
1042
+ if (get_lengths (len, lens, pos2) && (pos1 == -pos2) && (lens.size () == 1 ) && (lens.get (0 ) == s)) {
1043
+ expr_ref idx (m_autil.mk_int (pos1), m ());
1044
+ idx = m_autil.mk_add (b, idx);
1045
+ expr* es[2 ] = { s, idx };
1046
+ result = m ().mk_app (m_util.get_family_id (), OP_SEQ_NTH, 2 , es);
1047
+ return BR_REWRITE_FULL;
1048
+ }
1049
+ }
1050
+
995
1051
expr* es[2 ] = { a, b};
996
1052
expr* la = m_util.str .mk_length (a);
997
- result = m ().mk_ite (m ().mk_and (m_autil.mk_le ( m_autil.mk_int (0 ), b ), m_autil.mk_lt (b, la)),
1053
+ result = m ().mk_ite (m ().mk_and (m_autil.mk_ge (b, m_autil.mk_int (0 )), m (). mk_not ( m_autil.mk_ge (b, la) )),
998
1054
m ().mk_app (m_util.get_family_id (), OP_SEQ_NTH_I, 2 , es),
999
1055
m ().mk_app (m_util.get_family_id (), OP_SEQ_NTH_U, 2 , es));
1000
1056
return BR_REWRITE_FULL;
@@ -1078,10 +1134,26 @@ br_status seq_rewriter::mk_seq_replace(expr* a, expr* b, expr* c, expr_ref& resu
1078
1134
result = a;
1079
1135
return BR_DONE;
1080
1136
}
1137
+ if (a == b) {
1138
+ result = c;
1139
+ return BR_DONE;
1140
+ }
1081
1141
if (m_util.str .is_empty (b)) {
1082
1142
result = m_util.str .mk_concat (c, a);
1083
1143
return BR_REWRITE1;
1084
1144
}
1145
+
1146
+ if (m_util.str .is_string (b, s2)) {
1147
+ m_lhs.reset ();
1148
+ m_util.str .get_concat (a, m_lhs);
1149
+ if (!m_lhs.empty () && m_util.str .is_string (m_lhs.get (0 ), s1) &&
1150
+ s1.contains (s2)) {
1151
+ m_lhs[0 ] = m_util.str .mk_string (s1.replace (s2, s3));
1152
+ result = m_util.str .mk_concat (m_lhs.size (), m_lhs.c_ptr ());
1153
+ return BR_REWRITE1;
1154
+ }
1155
+ }
1156
+
1085
1157
return BR_FAILED;
1086
1158
}
1087
1159
@@ -1835,7 +1907,7 @@ bool seq_rewriter::reduce_eq(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_
1835
1907
zstring s;
1836
1908
bool lchange = false ;
1837
1909
SASSERT (lhs.empty ());
1838
- TRACE (" seq " , tout << ls << " \n " ; tout << rs << " \n " ;);
1910
+ TRACE (" seq_verbose " , tout << ls << " \n " ; tout << rs << " \n " ;);
1839
1911
// solve from back
1840
1912
while (true ) {
1841
1913
while (!rs.empty () && m_util.str .is_empty (rs.back ())) {
@@ -1943,7 +2015,7 @@ bool seq_rewriter::reduce_eq(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_
1943
2015
else {
1944
2016
break ;
1945
2017
}
1946
- TRACE (" seq " , tout << ls << " == " << rs << " \n " ;);
2018
+ TRACE (" seq_verbose " , tout << ls << " == " << rs << " \n " ;);
1947
2019
1948
2020
change = true ;
1949
2021
lchange = true ;
@@ -2106,7 +2178,7 @@ bool seq_rewriter::reduce_eq(expr* l, expr* r, expr_ref_vector& lhs, expr_ref_ve
2106
2178
return true ;
2107
2179
}
2108
2180
else {
2109
- TRACE (" seq" , tout << mk_pp (l, m ()) << " != " << mk_pp (r, m ()) << " \n " ;);
2181
+ TRACE (" seq" , tout << mk_bounded_pp (l, m ()) << " != " << mk_bounded_pp (r, m ()) << " \n " ;);
2110
2182
return false ;
2111
2183
}
2112
2184
}
0 commit comments