@@ -63,7 +63,7 @@ Alternate to lookahead strategy:
63
63
- create a priority buffer array of vector<ptr_vector<expr>> based on depth.
64
64
- walk from lowest depth up. Reset each inner buffer when processed. Parents always
65
65
have higher depth.
66
- - calculate repair/break score when hitting a predicate based on bval1.
66
+ - calculate repair/break depth when hitting a predicate based on bval1.
67
67
- strval1 and bval1 are modified by
68
68
- use a global timestamp.
69
69
- label each eval subterm by a timestamp that gets set.
@@ -145,9 +145,26 @@ namespace sls {
145
145
auto ve = ctx.get_value (e);
146
146
if (a.is_numeral (ve, r) && r == sx.length ())
147
147
continue ;
148
- update (e, rational (sx.length ()));
148
+ // set e to length of x or
149
+ // set x to a string of length e
150
+
151
+ if (r == 0 || sx.length () == 0 ) {
152
+ verbose_stream () << " todo-create lemma: len(x) = 0 <=> x = \"\"\n " ;
153
+ // create a lemma: len(x) = 0 => x = ""
154
+ }
155
+ if (ctx.rand (2 ) == 0 && update (e, rational (sx.length ())))
156
+ return false ;
157
+ if (r < sx.length () && update (x, sx.extract (0 , r.get_unsigned ())))
158
+ return false ;
159
+ if (update (e, rational (sx.length ())))
160
+ return false ;
161
+ if (r > sx.length () && update (x, sx + zstring (m_chars[ctx.rand (m_chars.size ())])))
162
+ return false ;
163
+ verbose_stream () << mk_pp (x, m) << " = " << sx << " " << ve << " \n " ;
164
+ NOT_IMPLEMENTED_YET ();
149
165
return false ;
150
166
}
167
+
151
168
if ((seq.str .is_index (e, x, y, z) || seq.str .is_index (e, x, y)) && seq.is_string (x->get_sort ())) {
152
169
auto sx = strval0 (x);
153
170
auto sy = strval0 (y);
@@ -603,21 +620,32 @@ namespace sls {
603
620
auto const & R = rhs (eq);
604
621
unsigned i = 0 , j = 0 ; // position into current string
605
622
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.
623
+ double score = 1.0 ; // priority of update. Doubled when score of equal strings are increased.
624
+
625
+ IF_VERBOSE (4 ,
626
+ verbose_stream () << " unify: \" " << strval0 (eq->get_arg (0 )) << " \" == \" " << strval0 (eq->get_arg (1 )) << " \"\n " ;
627
+ for (auto x : L) verbose_stream () << mk_pp (x, m) << " " ;
628
+ verbose_stream () << " == " ;
629
+ for (auto x : R) verbose_stream () << mk_pp (x, m) << " " ;
630
+ verbose_stream () << " \n " ;
631
+ for (auto x : L) verbose_stream () << " \" " << strval0 (x) << " \" " ;
632
+ verbose_stream () << " == " ;
633
+ for (auto x : R) verbose_stream () << " \" " << strval0 (x) << " \" " ;
634
+ verbose_stream () << " \n " ;
635
+ );
636
+
607
637
while (ni < L.size () && nj < R.size ()) {
608
638
auto const & xi = L[ni];
609
639
auto const & yj = R[nj];
610
640
auto const & vi = strval0 (xi);
611
641
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 " );
642
+
615
643
if (vi.length () == i && vj.length () == j) {
616
- depth *= 2 ;
644
+ score *= 2 ;
617
645
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 });
646
+ m_str_updates.push_back ({ xi, vi + zstring (strval0 (R[nj + 1 ])[0 ]), score });
619
647
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 });
648
+ m_str_updates.push_back ({ yj, vj + zstring (strval0 (L[ni + 1 ])[0 ]), score });
621
649
i = 0 ;
622
650
j = 0 ;
623
651
++ni;
@@ -627,48 +655,51 @@ namespace sls {
627
655
if (vi.length () == i) {
628
656
// xi -> vi + vj[j]
629
657
SASSERT (j < vj.length ());
630
- m_str_updates.push_back ({ xi, vi + zstring (vj[j]), depth });
631
- depth *= 2 ;
658
+ m_str_updates.push_back ({ xi, vi + zstring (vj[j]), score });
659
+ score *= 2 ;
632
660
i = 0 ;
633
661
++ni;
634
662
continue ;
635
663
}
636
664
if (vj.length () == j) {
637
665
// yj -> vj + vi[i]
638
666
SASSERT (i < vi.length ());
639
- m_str_updates.push_back ({ yj, vj + zstring (vi[i]), depth });
640
- depth *= 2 ;
667
+ m_str_updates.push_back ({ yj, vj + zstring (vi[i]), score });
668
+ score *= 2 ;
641
669
j = 0 ;
642
670
++nj;
643
671
continue ;
644
672
}
645
673
SASSERT (i < vi.length ());
646
674
SASSERT (j < vj.length ());
647
675
if (is_value (xi) && is_value (yj)) {
676
+ if (vi[i] != vj[j])
677
+ score = 1 ;
648
678
++i, ++j;
649
679
continue ;
650
680
}
681
+
651
682
if (vi[i] == vj[j]) {
652
683
++i, ++j;
653
684
continue ;
654
685
}
655
686
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 });
687
+ m_str_updates.push_back ({ xi, vi.extract (0 , i), score });
688
+ m_str_updates.push_back ({ xi, vi.extract (0 , i) + zstring (vj[j]), score });
658
689
}
659
690
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 });
691
+ m_str_updates.push_back ({ yj, vj.extract (0 , j), score });
692
+ m_str_updates.push_back ({ yj, vj.extract (0 , j) + zstring (vi[i]), score });
662
693
}
663
694
break ;
664
695
}
665
696
for (; ni < L.size (); ++ni)
666
- if (!is_value (L[ni]))
667
- m_str_updates.push_back ({ L[ni], zstring (), depth });
697
+ if (!is_value (L[ni]) && ! strval0 (L[ni]). empty () )
698
+ m_str_updates.push_back ({ L[ni], zstring (), 1 });
668
699
669
700
for (; nj < R.size (); ++nj)
670
- if (!is_value (R[nj]))
671
- m_str_updates.push_back ({ R[nj], zstring (), depth });
701
+ if (!is_value (R[nj]) && ! strval0 (R[nj]). empty () )
702
+ m_str_updates.push_back ({ R[nj], zstring (), 1 });
672
703
673
704
return apply_update ();
674
705
}
@@ -1092,6 +1123,13 @@ namespace sls {
1092
1123
sum_scores += score;
1093
1124
for (auto const & [e, val, score] : m_int_updates)
1094
1125
sum_scores += score;
1126
+
1127
+ IF_VERBOSE (4 ,
1128
+ for (auto const & [e, val, score] : m_str_updates)
1129
+ verbose_stream () << mk_pp (e, m) << " := \" " << val << " \" score: " << score << " \n " ;
1130
+ for (auto const & [e, val, score] : m_int_updates)
1131
+ verbose_stream () << mk_pp (e, m) << " := " << val << " score: " << score << " \n " ;
1132
+ );
1095
1133
1096
1134
while (!m_str_updates.empty () || !m_int_updates.empty ()) {
1097
1135
bool is_str_update = false ;
@@ -1165,6 +1203,7 @@ namespace sls {
1165
1203
if (m_initialized)
1166
1204
return ;
1167
1205
m_initialized = true ;
1206
+ expr_ref val (m);
1168
1207
for (auto lit : ctx.unit_literals ()) {
1169
1208
auto e = ctx.atom (lit.var ());
1170
1209
expr* x, * y, * z;
@@ -1214,6 +1253,12 @@ namespace sls {
1214
1253
if (len_r.is_unsigned ())
1215
1254
ev.max_length = std::min (ev.max_length , len_r.get_unsigned ());
1216
1255
}
1256
+ // TBD: assumes arithmetic is already initialized
1257
+ if (seq.str .is_length (t, x) && ctx.is_fixed (t, val) &&
1258
+ a.is_numeral (val, len_r) && len_r.is_unsigned ()) {
1259
+ auto & ev = get_eval (x);
1260
+ ev.min_length = ev.max_length = len_r.get_unsigned ();
1261
+ }
1217
1262
}
1218
1263
}
1219
1264
0 commit comments