@@ -12,6 +12,7 @@ Module Name:
12
12
Author:
13
13
14
14
Nikolaj Bjorner (nbjorner) 2015-6-12
15
+ Thai Minh Trinh 2017
15
16
*/
16
17
17
18
#include < typeinfo>
@@ -95,18 +96,13 @@ bool theory_seq::solve_eq(expr_ref_vector const& l, expr_ref_vector const& r, de
95
96
}
96
97
TRACE (" seq" , tout << " inserting equality\n " ;);
97
98
bool updated = false ;
98
- if (!m_len_offset.empty ()) {
99
- // Find a better equivalent term for lhs of an equation based on length constraints
100
- expr_ref_vector new_ls (m);
101
- if (find_better_rep (ls, rs, idx, deps, new_ls)) {
102
- eq const & new_eq = eq (m_eq_id++, new_ls, rs, deps);
103
- m_eqs.push_back (new_eq);
104
- TRACE (" seq" , tout << " find_better_rep\n " ;);
105
- TRACE (" seq" , display_equation (tout, new_eq););
106
- updated = true ;
107
- }
99
+ expr_ref_vector new_ls (m);
100
+ if (!m_len_offset.empty () &&
101
+ find_better_rep (ls, rs, idx, deps, new_ls)) {
102
+ // Find a better equivalent term for lhs of an equation based on length constraints
103
+ m_eqs.push_back (eq (m_eq_id++, new_ls, rs, deps));
108
104
}
109
- if (!updated) {
105
+ else {
110
106
m_eqs.push_back (eq (m_eq_id++, ls, rs, deps));
111
107
}
112
108
TRACE (" seq" , tout << " simplified\n " ;);
@@ -115,6 +111,122 @@ bool theory_seq::solve_eq(expr_ref_vector const& l, expr_ref_vector const& r, de
115
111
return false ;
116
112
}
117
113
114
+ bool theory_seq::solve_unit_eq (expr* l, expr* r, dependency* deps) {
115
+ if (l == r) {
116
+ return true ;
117
+ }
118
+ if (is_var (l) && !occurs (l, r) && add_solution (l, r, deps)) {
119
+ return true ;
120
+ }
121
+ if (is_var (r) && !occurs (r, l) && add_solution (r, l, deps)) {
122
+ return true ;
123
+ }
124
+ return false ;
125
+ }
126
+
127
+ bool theory_seq::solve_unit_eq (expr_ref_vector const & l, expr_ref_vector const & r, dependency* deps) {
128
+ if (l.size () == 1 && is_var (l[0 ]) && !occurs (l[0 ], r) && add_solution (l[0 ], mk_concat (r, m.get_sort (l[0 ])), deps)) {
129
+ return true ;
130
+ }
131
+ if (r.size () == 1 && is_var (r[0 ]) && !occurs (r[0 ], l) && add_solution (r[0 ], mk_concat (l, m.get_sort (r[0 ])), deps)) {
132
+ return true ;
133
+ }
134
+ return false ;
135
+ }
136
+
137
+ bool theory_seq::solve_binary_eq (expr_ref_vector const & ls, expr_ref_vector const & rs, dependency* dep) {
138
+ context& ctx = get_context ();
139
+ ptr_vector<expr> xs, ys;
140
+ expr_ref x (m), y (m);
141
+ bool is_binary =
142
+ is_binary_eq (ls, rs, x, xs, ys, y) ||
143
+ is_binary_eq (rs, ls, x, xs, ys, y);
144
+ if (!is_binary) {
145
+ return false ;
146
+ }
147
+ // Equation is of the form x ++ xs = ys ++ y
148
+ // where xs, ys are units.
149
+ if (x != y) {
150
+ return false ;
151
+ }
152
+ if (xs.size () != ys.size ()) {
153
+ TRACE (" seq" , tout << " binary conflict\n " ;);
154
+ set_conflict (dep);
155
+ return false ;
156
+ }
157
+ if (xs.empty ()) {
158
+ // this should have been solved already
159
+ UNREACHABLE ();
160
+ return false ;
161
+ }
162
+
163
+ // Equation is of the form x ++ xs = ys ++ x
164
+ // where |xs| = |ys| are units of same length
165
+ // then xs is a wrap-around of ys
166
+ // x ++ ab = ba ++ x
167
+ //
168
+ if (xs.size () == 1 ) {
169
+ enode* n1 = ensure_enode (xs[0 ]);
170
+ enode* n2 = ensure_enode (ys[0 ]);
171
+ if (n1->get_root () == n2->get_root ()) {
172
+ return false ;
173
+ }
174
+ literal eq = mk_eq (xs[0 ], ys[0 ], false );
175
+ switch (ctx.get_assignment (eq)) {
176
+ case l_false: {
177
+ literal_vector conflict;
178
+ conflict.push_back (~eq);
179
+ TRACE (" seq" , tout << conflict << " \n " ;);
180
+ set_conflict (dep, conflict);
181
+ break ;
182
+ }
183
+ case l_true:
184
+ break ;
185
+ case l_undef:
186
+ ctx.mark_as_relevant (eq);
187
+ propagate_lit (dep, 0 , nullptr , eq);
188
+ m_new_propagation = true ;
189
+ break ;
190
+ }
191
+ }
192
+ return false ;
193
+ }
194
+
195
+
196
+ bool theory_seq::occurs (expr* a, expr_ref_vector const & b) {
197
+ for (auto const & elem : b) {
198
+ if (a == elem || m.is_ite (elem)) return true ;
199
+ }
200
+ return false ;
201
+ }
202
+
203
+ bool theory_seq::occurs (expr* a, expr* b) {
204
+ // true if a occurs under an interpreted function or under left/right selector.
205
+ SASSERT (is_var (a));
206
+ SASSERT (m_todo.empty ());
207
+ expr* e1 = nullptr , *e2 = nullptr ;
208
+ m_todo.push_back (b);
209
+ while (!m_todo.empty ()) {
210
+ b = m_todo.back ();
211
+ if (a == b || m.is_ite (b)) {
212
+ m_todo.reset ();
213
+ return true ;
214
+ }
215
+ m_todo.pop_back ();
216
+ if (m_util.str .is_concat (b, e1 , e2 )) {
217
+ m_todo.push_back (e1 );
218
+ m_todo.push_back (e2 );
219
+ }
220
+ else if (m_util.str .is_unit (b, e1 )) {
221
+ m_todo.push_back (e1 );
222
+ }
223
+ else if (m_util.str .is_nth_i (b, e1 , e2 )) {
224
+ m_todo.push_back (e1 );
225
+ }
226
+ }
227
+ return false ;
228
+ }
229
+
118
230
// TODO: propagate length offsets for last vars
119
231
bool theory_seq::find_better_rep (expr_ref_vector const & ls, expr_ref_vector const & rs, unsigned idx,
120
232
dependency*& deps, expr_ref_vector & res) {
@@ -492,16 +604,12 @@ bool theory_seq::split_lengths(dependency* dep,
492
604
493
605
SASSERT (X != Y);
494
606
495
-
496
607
// |b| < |X| <= |b| + |Y| => x = bY1, Y = Y1Y2
497
608
expr_ref lenXE = mk_len (X);
498
609
expr_ref lenYE = mk_len (Y);
499
610
expr_ref lenb = mk_len (b);
500
- expr_ref le1 (m_autil.mk_le (mk_sub (lenXE, lenb), m_autil.mk_int (0 )), m);
501
- expr_ref le2 (m_autil.mk_le (mk_sub (mk_sub (lenXE, lenb), lenYE),
502
- m_autil.mk_int (0 )), m);
503
- literal lit1 (~mk_literal (le1));
504
- literal lit2 (mk_literal (le2));
611
+ literal lit1 = ~m_ax.mk_le (mk_sub (lenXE, lenb), 0 );
612
+ literal lit2 = m_ax.mk_le (mk_sub (mk_sub (lenXE, lenb), lenYE), 0 );
505
613
literal_vector lits;
506
614
lits.push_back (lit1);
507
615
lits.push_back (lit2);
@@ -738,7 +846,7 @@ unsigned_vector theory_seq::overlap2(expr_ref_vector const& ls, expr_ref_vector
738
846
}
739
847
unsigned_vector result;
740
848
for (unsigned i = 0 ; i < ls.size (); ++i) {
741
- if (eq_unit (ls[i],rs[0 ])) {
849
+ if (eq_unit (ls[i], rs[0 ])) {
742
850
bool same = true ;
743
851
unsigned j = i+1 ;
744
852
while (j < ls.size () && j-i < rs.size ()) {
@@ -757,7 +865,7 @@ unsigned_vector theory_seq::overlap2(expr_ref_vector const& ls, expr_ref_vector
757
865
}
758
866
759
867
bool theory_seq::branch_ternary_variable_base (
760
- dependency* dep, unsigned_vector indexes,
868
+ dependency* dep, unsigned_vector const & indexes,
761
869
expr* const & x, expr_ref_vector const & xs, expr* const & y1, expr_ref_vector const & ys, expr* const & y2) {
762
870
context& ctx = get_context ();
763
871
bool change = false ;
@@ -854,31 +962,30 @@ bool theory_seq::branch_ternary_variable(eq const& e, bool flag1) {
854
962
propagate_eq(dep, lits, y2, ZxsE, true);
855
963
#endif
856
964
}
857
- else {
858
- expr_ref ge (m_autil.mk_ge (mk_len (y2), m_autil.mk_int (xs.size ())), m);
859
- literal lit2 = mk_literal (ge);
860
- if (ctx.get_assignment (lit2) == l_undef) {
861
- TRACE (" seq" , tout << " rec case init\n " ;);
862
- ctx.mark_as_relevant (lit2);
863
- ctx.force_phase (lit2);
864
- }
865
- else if (ctx.get_assignment (lit2) == l_true) {
866
- TRACE (" seq" , tout << " true branch\n " ;);
867
- TRACE (" seq" , display_equation (tout, e););
868
- literal_vector lits;
869
- lits.push_back (lit2);
870
- dependency* dep = e.dep ();
871
- propagate_eq (dep, lits, x, y1ysZ, true );
872
- propagate_eq (dep, lits, y2, ZxsE, true );
873
- }
874
- else {
875
- return branch_ternary_variable_base (e.dep (), indexes, x, xs, y1 , ys, y2);
876
- }
965
+
966
+ literal ge = m_ax.mk_ge (mk_len (y2), xs.size ());
967
+ dependency* dep = e.dep ();
968
+ literal_vector lits;
969
+ switch (ctx.get_assignment (ge)) {
970
+ case l_undef:
971
+ TRACE (" seq" , tout << " rec case init\n " ;);
972
+ ctx.mark_as_relevant (ge);
973
+ ctx.force_phase (ge);
974
+ break ;
975
+ case l_true:
976
+ TRACE (" seq" , tout << " true branch\n " ;);
977
+ TRACE (" seq" , display_equation (tout, e););
978
+ lits.push_back (ge);
979
+ propagate_eq (dep, lits, x, y1ysZ, true );
980
+ propagate_eq (dep, lits, y2, ZxsE, true );
981
+ break ;
982
+ default :
983
+ return branch_ternary_variable_base (e.dep (), indexes, x, xs, y1 , ys, y2);
877
984
}
878
985
return true ;
879
986
}
880
987
881
- bool theory_seq::branch_ternary_variable_base2 (dependency* dep, unsigned_vector indexes,
988
+ bool theory_seq::branch_ternary_variable_base2 (dependency* dep, unsigned_vector const & indexes,
882
989
expr_ref_vector const & xs, expr* const & x, expr* const & y1, expr_ref_vector const & ys, expr* const & y2) {
883
990
context& ctx = get_context ();
884
991
bool change = false ;
@@ -970,18 +1077,17 @@ bool theory_seq::branch_ternary_variable2(eq const& e, bool flag1) {
970
1077
propagate_eq (dep, lits, y1 , xsZ, true );
971
1078
}
972
1079
else {
973
- expr_ref ge (m_autil.mk_ge (mk_len (y1 ), m_autil.mk_int (xs.size ())), m);
974
- literal lit2 = mk_literal (ge);
975
- if (ctx.get_assignment (lit2) == l_undef) {
1080
+ literal ge = m_ax.mk_ge (mk_len (y1 ), xs.size ());
1081
+ if (ctx.get_assignment (ge) == l_undef) {
976
1082
TRACE (" seq" , tout << " rec case init\n " ;);
977
- ctx.mark_as_relevant (lit2 );
978
- ctx.force_phase (lit2 );
1083
+ ctx.mark_as_relevant (ge );
1084
+ ctx.force_phase (ge );
979
1085
}
980
- else if (ctx.get_assignment (lit2 ) == l_true) {
1086
+ else if (ctx.get_assignment (ge ) == l_true) {
981
1087
TRACE (" seq" , tout << " true branch\n " ;);
982
1088
TRACE (" seq" , display_equation (tout, e););
983
1089
literal_vector lits;
984
- lits.push_back (lit2 );
1090
+ lits.push_back (ge );
985
1091
dependency* dep = e.dep ();
986
1092
propagate_eq (dep, lits, x, Zysy2, true );
987
1093
propagate_eq (dep, lits, y1 , xsZ, true );
@@ -1035,36 +1141,34 @@ bool theory_seq::branch_quat_variable(eq const& e) {
1035
1141
expr_ref x1 (x1_l, m);
1036
1142
expr_ref y1 (y1_l, m);
1037
1143
expr_ref sub (mk_sub (mk_len (x1_l), mk_len (y1_l)), m);
1038
- expr_ref le (m_autil .mk_le (sub, m_autil. mk_int ( 0 )), m );
1039
- literal lit2 = mk_literal (le) ;
1040
- if (ctx.get_assignment (lit2 ) == l_undef) {
1144
+ literal le = m_ax .mk_le (sub, 0 );
1145
+ literal_vector lits ;
1146
+ if (ctx.get_assignment (le ) == l_undef) {
1041
1147
TRACE (" seq" , tout << " init branch\n " ;);
1042
1148
TRACE (" seq" , display_equation (tout, e););
1043
- ctx.mark_as_relevant (lit2 );
1044
- ctx.force_phase (lit2 );
1149
+ ctx.mark_as_relevant (le );
1150
+ ctx.force_phase (le );
1045
1151
}
1046
- else if (ctx.get_assignment (lit2 ) == l_false) {
1152
+ else if (ctx.get_assignment (le ) == l_false) {
1047
1153
// |x1| > |y1| => x1 = y1 ++ z1, z1 ++ xs ++ x2 = ys ++ y2
1048
1154
TRACE (" seq" , tout << " false branch\n " ;);
1049
1155
TRACE (" seq" , display_equation (tout, e););
1050
1156
expr_ref Z1 = m_sk.mk_align (ysy2, xsx2, x1, y1 );
1051
1157
expr_ref y1Z1 = mk_concat (y1 , Z1);
1052
1158
expr_ref Z1xsx2 = mk_concat (Z1, xsx2);
1053
- literal_vector lits;
1054
- lits.push_back (~lit2);
1159
+ lits.push_back (~le);
1055
1160
dependency* dep = e.dep ();
1056
1161
propagate_eq (dep, lits, x1, y1Z1, true );
1057
1162
propagate_eq (dep, lits, Z1xsx2, ysy2, true );
1058
1163
}
1059
- else if (ctx.get_assignment (lit2 ) == l_true) {
1164
+ else if (ctx.get_assignment (le ) == l_true) {
1060
1165
// |x1| <= |y1| => x1 ++ z2 = y1, xs ++ x2 = z2 ++ ys ++ y2
1061
1166
TRACE (" seq" , tout << " true branch\n " ;);
1062
1167
TRACE (" seq" , display_equation (tout, e););
1063
1168
expr_ref Z2 = m_sk.mk_align (xsx2, ysy2, y1 , x1);
1064
1169
expr_ref x1Z2 = mk_concat (x1, Z2);
1065
1170
expr_ref Z2ysy2 = mk_concat (Z2, ysy2);
1066
- literal_vector lits;
1067
- lits.push_back (lit2);
1171
+ lits.push_back (le);
1068
1172
dependency* dep = e.dep ();
1069
1173
propagate_eq (dep, lits, x1Z2, y1 , true );
1070
1174
propagate_eq (dep, lits, xsx2, Z2ysy2, true );
@@ -1798,6 +1902,11 @@ bool theory_seq::solve_nth_eq2(expr_ref_vector const& ls, expr_ref_vector const&
1798
1902
return false ;
1799
1903
}
1800
1904
1905
+ /* *
1906
+ match
1907
+ x = unit(nth_i(x,0)) + unit(nth_i(x,1)) + .. + unit(nth_i(x,k-1))
1908
+ */
1909
+
1801
1910
bool theory_seq::solve_nth_eq1 (expr_ref_vector const & ls, expr_ref_vector const & rs, dependency* dep) {
1802
1911
if (solve_nth_eq2 (ls, rs, dep)) {
1803
1912
return true ;
@@ -1822,12 +1931,3 @@ bool theory_seq::solve_nth_eq1(expr_ref_vector const& ls, expr_ref_vector const&
1822
1931
return true ;
1823
1932
}
1824
1933
1825
- bool theory_seq::solve_unit_eq (expr_ref_vector const & l, expr_ref_vector const & r, dependency* deps) {
1826
- if (l.size () == 1 && is_var (l[0 ]) && !occurs (l[0 ], r) && add_solution (l[0 ], mk_concat (r, m.get_sort (l[0 ])), deps)) {
1827
- return true ;
1828
- }
1829
- if (r.size () == 1 && is_var (r[0 ]) && !occurs (r[0 ], l) && add_solution (r[0 ], mk_concat (l, m.get_sort (r[0 ])), deps)) {
1830
- return true ;
1831
- }
1832
- return false ;
1833
- }
0 commit comments