Skip to content

Commit 51f1e26

Browse files
updates to sls
Signed-off-by: Nikolaj Bjorner <[email protected]>
1 parent 111fcb9 commit 51f1e26

13 files changed

+234
-105
lines changed

src/ast/simplifiers/solve_eqs.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ namespace euf {
329329
m_config.m_context_solve = p.get_bool("context_solve", tp.solve_eqs_context_solve());
330330
for (auto* ex : m_extract_plugins)
331331
ex->updt_params(p);
332+
m_rewriter.updt_params(p);
332333
}
333334

334335
void solve_eqs::collect_param_descrs(param_descrs& r) {

src/ast/sls/bv_sls.cpp

+109-29
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,15 @@ Module Name:
2525

2626
namespace bv {
2727

28-
sls::sls(ast_manager& m):
28+
sls::sls(ast_manager& m, params_ref const& p):
2929
m(m),
3030
bv(m),
3131
m_terms(m),
32-
m_eval(m)
33-
{}
32+
m_eval(m),
33+
m_engine(m, p)
34+
{
35+
updt_params(p);
36+
}
3437

3538
void sls::init() {
3639
m_terms.init();
@@ -67,20 +70,48 @@ namespace bv {
6770
}
6871
}
6972

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+
7096
void sls::reinit_eval() {
97+
init_repair_candidates();
98+
99+
if (m_to_repair.empty())
100+
return;
101+
71102
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);
79107
else if (bv.is_bv(e)) {
80108
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+
84115
return m_rand() % 2 == 0;
85116
};
86117
m_eval.init_eval(m_terms.assertions(), eval);
@@ -119,15 +150,14 @@ namespace bv {
119150
return { false, nullptr };
120151
}
121152

122-
lbool sls::search() {
153+
lbool sls::search1() {
123154
// init and init_eval were invoked
124155
unsigned n = 0;
125156
for (; n++ < m_config.m_max_repairs && m.inc(); ) {
126157
auto [down, e] = next_to_repair();
127158
if (!e)
128159
return l_true;
129160

130-
131161
trace_repair(down, e);
132162

133163
++m_stats.m_moves;
@@ -140,16 +170,32 @@ namespace bv {
140170
return l_undef;
141171
}
142172

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+
143184

144185
lbool sls::operator()() {
145186
lbool res = l_undef;
146187
m_stats.reset();
147188
m_stats.m_restarts = 0;
189+
m_engine_model = false;
190+
148191
do {
149-
res = search();
192+
res = search1();
150193
if (res != l_undef)
151194
break;
152195
trace();
196+
res = search2();
197+
if (res != l_undef)
198+
break;
153199
reinit_eval();
154200
}
155201
while (m.inc() && m_stats.m_restarts++ < m_config.m_max_restarts);
@@ -158,34 +204,60 @@ namespace bv {
158204
}
159205

160206
void sls::try_repair_down(app* e) {
161-
162207
unsigned n = e->get_num_args();
163208
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 {
167213
VERIFY(m_eval.wval(e).commit_eval());
214+
}
168215

169216
for (auto p : m_terms.parents(e))
170217
m_repair_up.insert(p->get_id());
218+
171219
return;
172220
}
173221

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));
179236
return;
180237
}
181238
}
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();
183251
}
184252

185253
void sls::try_repair_up(app* e) {
186254

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+
}
189261
else {
190262
if (!eval_is_correct(e)) {
191263
verbose_stream() << "incorrect eval #" << e->get_id() << " " << mk_bounded_pp(e, m) << "\n";
@@ -224,7 +296,10 @@ namespace bv {
224296
}
225297

226298
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);
228303
auto& terms = m_eval.sort_assertions(m_terms.assertions());
229304
for (expr* e : terms) {
230305
if (!re_eval_is_correct(to_app(e))) {
@@ -273,7 +348,12 @@ namespace bv {
273348
void sls::updt_params(params_ref const& _p) {
274349
sls_params p(_p);
275350
m_config.m_max_restarts = p.max_restarts();
351+
m_config.m_max_repairs = p.max_repairs();
276352
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);
277357
}
278358

279359
void sls::trace_repair(bool down, expr* e) {

src/ast/sls/bv_sls.h

+13-6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Module Name:
2626
#include "ast/sls/sls_valuation.h"
2727
#include "ast/sls/bv_sls_terms.h"
2828
#include "ast/sls/bv_sls_eval.h"
29+
#include "ast/sls/sls_engine.h"
2930
#include "ast/bv_decl_plugin.h"
3031
#include "model/model.h"
3132

@@ -49,6 +50,8 @@ namespace bv {
4950
ptr_vector<expr> m_todo;
5051
random_gen m_rand;
5152
config m_config;
53+
sls_engine m_engine;
54+
bool m_engine_model = false;
5255

5356
std::pair<bool, app*> next_to_repair();
5457

@@ -59,19 +62,23 @@ namespace bv {
5962
void try_repair_up(app* e);
6063
void set_repair_down(expr* e) { m_repair_down = e->get_id(); }
6164

62-
lbool search();
65+
lbool search1();
66+
lbool search2();
6367
void reinit_eval();
6468
void init_repair();
6569
void trace();
6670
void trace_repair(bool down, expr* e);
6771

72+
indexed_uint_set m_to_repair;
73+
void init_repair_candidates();
74+
6875
public:
69-
sls(ast_manager& m);
76+
sls(ast_manager& m, params_ref const& p);
7077

7178
/**
7279
* Add constraints
7380
*/
74-
void assert_expr(expr* e) { m_terms.assert_expr(e); }
81+
void assert_expr(expr* e) { m_terms.assert_expr(e); m_engine.assert_expr(e); }
7582

7683
/*
7784
* Invoke init after all expressions are asserted.
@@ -91,10 +98,10 @@ namespace bv {
9198
lbool operator()();
9299

93100
void updt_params(params_ref const& p);
94-
void collect_statistics(statistics & st) const { m_stats.collect_statistics(st); }
95-
void reset_statistics() { m_stats.reset(); }
101+
void collect_statistics(statistics& st) const { m_stats.collect_statistics(st); m_engine.collect_statistics(st); }
102+
void reset_statistics() { m_stats.reset(); m_engine.reset_statistics(); }
96103

97-
sls_stats const& get_stats() const { return m_stats; }
104+
unsigned get_num_moves() { return m_stats.m_moves + m_engine.get_stats().m_moves; }
98105

99106
std::ostream& display(std::ostream& out);
100107

src/ast/sls/bv_sls_eval.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ namespace bv {
2424
{}
2525

2626
void sls_eval::init_eval(expr_ref_vector const& es, std::function<bool(expr*, unsigned)> const& eval) {
27-
sort_assertions(es);
28-
for (expr* e : m_todo) {
27+
auto& terms = sort_assertions(es);
28+
for (expr* e : terms) {
2929
if (!is_app(e))
3030
continue;
3131
app* a = to_app(e);
@@ -49,7 +49,7 @@ namespace bv {
4949
TRACE("sls", tout << "Unhandled expression " << mk_pp(e, m) << "\n");
5050
}
5151
}
52-
m_todo.reset();
52+
terms.reset();
5353
}
5454

5555
/**
@@ -1698,7 +1698,7 @@ namespace bv {
16981698
}
16991699
if (bv.is_bv(e)) {
17001700
auto& v = eval(to_app(e));
1701-
// verbose_stream() << "committing: " << v << "\n";
1701+
17021702
for (unsigned i = 0; i < v.nw; ++i)
17031703
if (0 != (v.fixed[i] & (v.bits()[i] ^ v.eval[i]))) {
17041704
v.bits().copy_to(v.nw, v.eval);

src/ast/sls/bv_sls_fixed.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@ namespace bv {
108108
else if (bv.is_numeral(t, a))
109109
init_range(s, -a, nullptr, rational(0), false);
110110
}
111+
else if (sign && m.is_eq(e, s, t)) {
112+
if (bv.is_numeral(s, a))
113+
// 1 <= t - a
114+
init_range(nullptr, rational(1), t, -a, false);
115+
else if (bv.is_numeral(t, a))
116+
init_range(nullptr, rational(1), s, -a, false);
117+
}
111118
else if (bv.is_bit2bool(e, s, idx)) {
112119
auto& val = wval(s);
113120
val.try_set_bit(idx, !sign);
@@ -157,7 +164,6 @@ namespace bv {
157164
else
158165
v.add_range(-b, -a);
159166
}
160-
161167
}
162168

163169
void sls_fixed::get_offset(expr* e, expr*& x, rational& offset) {

0 commit comments

Comments
 (0)