@@ -25,12 +25,15 @@ Module Name:
25
25
26
26
namespace bv {
27
27
28
- sls::sls (ast_manager& m):
28
+ sls::sls (ast_manager& m, params_ref const & p ):
29
29
m (m),
30
30
bv (m),
31
31
m_terms (m),
32
- m_eval (m)
33
- {}
32
+ m_eval (m),
33
+ m_engine (m, p)
34
+ {
35
+ updt_params (p);
36
+ }
34
37
35
38
void sls::init () {
36
39
m_terms.init ();
@@ -67,20 +70,48 @@ namespace bv {
67
70
}
68
71
}
69
72
73
+ void sls::init_repair_candidates () {
74
+ m_to_repair.reset ();
75
+ ptr_vector<expr> todo;
76
+ expr_fast_mark1 mark;
77
+ for (auto index : m_repair_roots)
78
+ todo.push_back (m_terms.term (index ));
79
+ for (unsigned i = 0 ; i < todo.size (); ++i) {
80
+ expr* e = todo[i];
81
+ if (mark.is_marked (e))
82
+ continue ;
83
+ mark.mark (e);
84
+ if (!is_app (e))
85
+ continue ;
86
+ for (expr* arg : *to_app (e))
87
+ todo.push_back (arg);
88
+
89
+ if (is_uninterp_const (e))
90
+ m_to_repair.insert (e->get_id ());
91
+
92
+ }
93
+ }
94
+
95
+
70
96
void sls::reinit_eval () {
97
+ init_repair_candidates ();
98
+
99
+ if (m_to_repair.empty ())
100
+ return ;
101
+
71
102
std::function<bool (expr*, unsigned )> eval = [&](expr* e, unsigned i) {
72
- auto should_keep = [&]() {
73
- return m_rand () % 100 <= 92 ;
74
- };
75
- if (m.is_bool (e)) {
76
- if (m_eval.is_fixed0 (e) || should_keep ())
77
- return m_eval.bval0 (e);
78
- }
103
+ unsigned id = e->get_id ();
104
+ bool keep = (m_rand () % 100 <= 50 ) || !m_to_repair.contains (id);
105
+ if (m.is_bool (e) && (m_eval.is_fixed0 (e) || keep))
106
+ return m_eval.bval0 (e);
79
107
else if (bv.is_bv (e)) {
80
108
auto & w = m_eval.wval (e);
81
- if (w.fixed .get (i) || should_keep ())
82
- return w.get_bit (i);
83
- }
109
+ if (w.fixed .get (i) || keep)
110
+ return w.get_bit (i);
111
+ // auto const& z = m_engine.get_value(e);
112
+ // return rational(z).get_bit(i);
113
+ }
114
+
84
115
return m_rand () % 2 == 0 ;
85
116
};
86
117
m_eval.init_eval (m_terms.assertions (), eval);
@@ -119,15 +150,14 @@ namespace bv {
119
150
return { false , nullptr };
120
151
}
121
152
122
- lbool sls::search () {
153
+ lbool sls::search1 () {
123
154
// init and init_eval were invoked
124
155
unsigned n = 0 ;
125
156
for (; n++ < m_config.m_max_repairs && m.inc (); ) {
126
157
auto [down, e] = next_to_repair ();
127
158
if (!e)
128
159
return l_true;
129
160
130
-
131
161
trace_repair (down, e);
132
162
133
163
++m_stats.m_moves ;
@@ -140,16 +170,32 @@ namespace bv {
140
170
return l_undef;
141
171
}
142
172
173
+ lbool sls::search2 () {
174
+ lbool res = l_undef;
175
+ if (m_stats.m_restarts == 0 )
176
+ res = m_engine ();
177
+ else if (m_stats.m_restarts % 1000 == 0 )
178
+ res = m_engine.search_loop ();
179
+ if (res != l_undef)
180
+ m_engine_model = true ;
181
+ return res;
182
+ }
183
+
143
184
144
185
lbool sls::operator ()() {
145
186
lbool res = l_undef;
146
187
m_stats.reset ();
147
188
m_stats.m_restarts = 0 ;
189
+ m_engine_model = false ;
190
+
148
191
do {
149
- res = search ();
192
+ res = search1 ();
150
193
if (res != l_undef)
151
194
break ;
152
195
trace ();
196
+ res = search2 ();
197
+ if (res != l_undef)
198
+ break ;
153
199
reinit_eval ();
154
200
}
155
201
while (m.inc () && m_stats.m_restarts ++ < m_config.m_max_restarts );
@@ -158,34 +204,60 @@ namespace bv {
158
204
}
159
205
160
206
void sls::try_repair_down (app* e) {
161
-
162
207
unsigned n = e->get_num_args ();
163
208
if (n == 0 ) {
164
- if (m.is_bool (e))
165
- m_eval.set (e, m_eval.bval1 (e));
166
- else
209
+ if (m.is_bool (e)) {
210
+ m_eval.set (e, m_eval.bval1 (e));
211
+ }
212
+ else {
167
213
VERIFY (m_eval.wval (e).commit_eval ());
214
+ }
168
215
169
216
for (auto p : m_terms.parents (e))
170
217
m_repair_up.insert (p->get_id ());
218
+
171
219
return ;
172
220
}
173
221
174
- unsigned s = m_rand (n);
175
- for (unsigned i = 0 ; i < n; ++i) {
176
- auto j = (i + s) % n;
177
- if (m_eval.try_repair (e, j)) {
178
- set_repair_down (e->get_arg (j));
222
+ if (n == 2 ) {
223
+ auto d1 = get_depth (e->get_arg (0 ));
224
+ auto d2 = get_depth (e->get_arg (1 ));
225
+ unsigned s = m_rand (d1 + d2 + 2 );
226
+ if (s <= d1 && m_eval.try_repair (e, 0 )) {
227
+ set_repair_down (e->get_arg (0 ));
228
+ return ;
229
+ }
230
+ if (m_eval.try_repair (e, 1 )) {
231
+ set_repair_down (e->get_arg (1 ));
232
+ return ;
233
+ }
234
+ if (m_eval.try_repair (e, 0 )) {
235
+ set_repair_down (e->get_arg (0 ));
179
236
return ;
180
237
}
181
238
}
182
- // search a new root / random walk to repair
239
+ else {
240
+ unsigned s = m_rand (n);
241
+ for (unsigned i = 0 ; i < n; ++i) {
242
+ auto j = (i + s) % n;
243
+ if (m_eval.try_repair (e, j)) {
244
+ set_repair_down (e->get_arg (j));
245
+ return ;
246
+ }
247
+ }
248
+ }
249
+ // repair was not successful, so reset the state to find a different way to repair
250
+ init_repair ();
183
251
}
184
252
185
253
void sls::try_repair_up (app* e) {
186
254
187
- if (m_terms.is_assertion (e) || !m_eval.repair_up (e))
188
- m_repair_roots.insert (e->get_id ());
255
+ if (m_terms.is_assertion (e))
256
+ m_repair_roots.insert (e->get_id ());
257
+ else if (!m_eval.repair_up (e)) {
258
+ // m_repair_roots.insert(e->get_id());
259
+ init_repair ();
260
+ }
189
261
else {
190
262
if (!eval_is_correct (e)) {
191
263
verbose_stream () << " incorrect eval #" << e->get_id () << " " << mk_bounded_pp (e, m) << " \n " ;
@@ -224,7 +296,10 @@ namespace bv {
224
296
}
225
297
226
298
model_ref sls::get_model () {
227
- model_ref mdl = alloc (model, m);
299
+ if (m_engine_model)
300
+ return m_engine.get_model ();
301
+
302
+ model_ref mdl = alloc (model, m);
228
303
auto & terms = m_eval.sort_assertions (m_terms.assertions ());
229
304
for (expr* e : terms) {
230
305
if (!re_eval_is_correct (to_app (e))) {
@@ -273,7 +348,12 @@ namespace bv {
273
348
void sls::updt_params (params_ref const & _p) {
274
349
sls_params p (_p);
275
350
m_config.m_max_restarts = p.max_restarts ();
351
+ m_config.m_max_repairs = p.max_repairs ();
276
352
m_rand.set_seed (p.random_seed ());
353
+ m_terms.updt_params (_p);
354
+ params_ref q = _p;
355
+ q.set_uint (" max_restarts" , 10 );
356
+ m_engine.updt_params (q);
277
357
}
278
358
279
359
void sls::trace_repair (bool down, expr* e) {
0 commit comments