@@ -224,6 +224,23 @@ namespace sls {
224
224
return m_values.get (id, nullptr );
225
225
}
226
226
227
+ ptr_vector<expr> const & seq_plugin::lhs (expr* eq) {
228
+ auto & ev = get_eval (eq);
229
+ if (ev.lhs .empty ()) {
230
+ expr* x, * y;
231
+ VERIFY (m.is_eq (eq, x, y));
232
+ seq.str .get_concat (x, ev.lhs );
233
+ seq.str .get_concat (y, ev.rhs );
234
+ }
235
+ return ev.lhs ;
236
+ }
237
+
238
+ ptr_vector<expr> const & seq_plugin::rhs (expr* eq) {
239
+ lhs (eq);
240
+ auto & e = get_eval (eq);
241
+ return e.rhs ;
242
+ }
243
+
227
244
zstring& seq_plugin::strval0 (expr* e) {
228
245
SASSERT (seq.is_string (e->get_sort ()));
229
246
return get_eval (e).val0 .svalue ;
@@ -557,8 +574,10 @@ namespace sls {
557
574
bool is_true = ctx.is_true (e);
558
575
expr* x, * y;
559
576
VERIFY (m.is_eq (e, x, y));
560
- verbose_stream () << is_true << " : " << mk_bounded_pp (e, m, 3 ) << " \n " ;
577
+ IF_VERBOSE ( 3 , verbose_stream () << is_true << " : " << mk_bounded_pp (e, m, 3 ) << " \n " ) ;
561
578
if (ctx.is_true (e)) {
579
+ if (ctx.rand (10 ) != 0 )
580
+ return repair_down_str_eq_unify (e);
562
581
if (!is_value (x))
563
582
m_str_updates.push_back ({ x, strval1 (y), 1 });
564
583
if (!is_value (y))
@@ -579,6 +598,81 @@ namespace sls {
579
598
return apply_update ();
580
599
}
581
600
601
+ bool seq_plugin::repair_down_str_eq_unify (app* eq) {
602
+ auto const & L = lhs (eq);
603
+ auto const & R = rhs (eq);
604
+ unsigned i = 0 , j = 0 ; // position into current string
605
+ unsigned ni = 0 , nj = 0 ; // current string in concatenation
606
+ double depth = 1.0 ; // priority of update. Doubled when depth of equal strings are increased.
607
+ while (ni < L.size () && nj < R.size ()) {
608
+ auto const & xi = L[ni];
609
+ auto const & yj = R[nj];
610
+ auto const & vi = strval0 (xi);
611
+ auto const & vj = strval0 (yj);
612
+ IF_VERBOSE (4 ,
613
+ verbose_stream () << " unify: \" " << vi << " \" = \" " << vj << " \" incides " << i << " " << j << " \n " ;
614
+ verbose_stream () << vi.length () << " " << vj.length () << " \n " );
615
+ if (vi.length () == i && vj.length () == j) {
616
+ depth *= 2 ;
617
+ if (nj + 1 < R.size () && !strval0 (R[nj + 1 ]).empty ())
618
+ m_str_updates.push_back ({ xi, vi + zstring (strval0 (R[nj + 1 ])[0 ]), depth });
619
+ if (ni + 1 < L.size () && !strval0 (L[ni + 1 ]).empty ())
620
+ m_str_updates.push_back ({ yj, vj + zstring (strval0 (L[ni + 1 ])[0 ]), depth });
621
+ i = 0 ;
622
+ j = 0 ;
623
+ ++ni;
624
+ ++nj;
625
+ continue ;
626
+ }
627
+ if (vi.length () == i) {
628
+ // xi -> vi + vj[j]
629
+ SASSERT (j < vj.length ());
630
+ m_str_updates.push_back ({ xi, vi + zstring (vj[j]), depth});
631
+ depth *= 2 ;
632
+ i = 0 ;
633
+ ++ni;
634
+ continue ;
635
+ }
636
+ if (vj.length () == j) {
637
+ // yj -> vj + vi[i]
638
+ SASSERT (i < vi.length ());
639
+ m_str_updates.push_back ({ yj, vj + zstring (vi[i]), depth });
640
+ depth *= 2 ;
641
+ j = 0 ;
642
+ ++nj;
643
+ continue ;
644
+ }
645
+ SASSERT (i < vi.length ());
646
+ SASSERT (j < vj.length ());
647
+ if (is_value (xi) && is_value (yj)) {
648
+ ++i, ++j;
649
+ continue ;
650
+ }
651
+ if (vi[i] == vj[j]) {
652
+ ++i, ++j;
653
+ continue ;
654
+ }
655
+ if (!is_value (xi)) {
656
+ m_str_updates.push_back ({ xi, vi.extract (0 , i), depth });
657
+ m_str_updates.push_back ({ xi, vi.extract (0 , i) + zstring (vj[j]), depth});
658
+ }
659
+ if (!is_value (yj)) {
660
+ m_str_updates.push_back ({ yj, vj.extract (0 , j), depth });
661
+ m_str_updates.push_back ({ yj, vj.extract (0 , j) + zstring (vi[i]), depth });
662
+ }
663
+ break ;
664
+ }
665
+ for (; ni < L.size (); ++ni)
666
+ if (!is_value (L[ni]))
667
+ m_str_updates.push_back ({ L[ni], zstring (), depth });
668
+
669
+ for (; nj < R.size (); ++nj)
670
+ if (!is_value (R[nj]))
671
+ m_str_updates.push_back ({ R[nj], zstring (), depth });
672
+
673
+ return apply_update ();
674
+ }
675
+
582
676
bool seq_plugin::repair_down_seq (app* e) {
583
677
switch (e->get_decl_kind ()) {
584
678
case OP_SEQ_CONTAINS:
@@ -1021,7 +1115,7 @@ namespace sls {
1021
1115
auto [e, value, score] = m_str_updates[i];
1022
1116
1023
1117
if (update (e, value)) {
1024
- verbose_stream () << " set value " << mk_bounded_pp (e, m) << " := \" " << value << " \"\n " ;
1118
+ IF_VERBOSE ( 3 , verbose_stream () << " set value " << mk_bounded_pp (e, m) << " := \" " << value << " \"\n " ) ;
1025
1119
m_str_updates.reset ();
1026
1120
m_int_updates.reset ();
1027
1121
return true ;
@@ -1034,7 +1128,7 @@ namespace sls {
1034
1128
else {
1035
1129
auto [e, value, score] = m_int_updates[i];
1036
1130
1037
- verbose_stream () << " set value " << mk_bounded_pp (e, m) << " := " << value << " \n " ;
1131
+ IF_VERBOSE ( 3 , verbose_stream () << " set value " << mk_bounded_pp (e, m) << " := " << value << " \n " ) ;
1038
1132
1039
1133
if (update (e, value)) {
1040
1134
m_int_updates.reset ();
0 commit comments