Skip to content

Commit 8dd522d

Browse files
fix #4057 fix #4061
1 parent dcb75c4 commit 8dd522d

File tree

1 file changed

+53
-40
lines changed

1 file changed

+53
-40
lines changed

src/smt/smt_consequences.cpp

Lines changed: 53 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace smt {
2828

2929
expr_ref context::antecedent2fml(index_set const& vars) {
3030
expr_ref_vector premises(m);
31-
for (unsigned v : vars) {
31+
for (unsigned v : vars) {
3232
expr* e = bool_var2expr(v);
3333
e = m_assumption2orig.find(e);
3434
premises.push_back(get_assignment(v) != l_false ? e : m.mk_not(e));
@@ -159,11 +159,16 @@ namespace smt {
159159

160160
unsigned context::delete_unfixed(expr_ref_vector& unfixed) {
161161
ptr_vector<expr> to_delete;
162-
for (auto const& kv : m_var2val) {
162+
for (auto const& kv : m_var2val) {
163163
expr* k = kv.m_key;
164164
expr* v = kv.m_value;
165165
if (m.is_bool(k)) {
166166
literal lit = get_literal(k);
167+
TRACE("context",
168+
tout << "checking " << mk_pp(k, m) << " "
169+
<< mk_pp(v, m) << " " << get_assignment(lit) << "\n";
170+
display(tout);
171+
);
167172
switch (get_assignment(lit)) {
168173
case l_true:
169174
if (m.is_false(v)) {
@@ -193,52 +198,55 @@ namespace smt {
193198
to_delete.push_back(k);
194199
}
195200
}
196-
for (unsigned i = 0; i < to_delete.size(); ++i) {
197-
m_var2val.remove(to_delete[i]);
198-
unfixed.push_back(to_delete[i]);
201+
for (expr* e : to_delete) {
202+
m_var2val.remove(e);
203+
unfixed.push_back(e);
199204
}
200205
return to_delete.size();
201206
}
202207

203-
#define are_equal(v, k) (e_internalized(k) && e_internalized(v) && get_enode(k)->get_root() == get_enode(v)->get_root())
204-
205208
//
206209
// Extract equalities that are congruent at the search level.
207210
// Add a clause to short-circuit the congruence justifications for
208211
// next rounds.
209212
//
210213
unsigned context::extract_fixed_eqs(expr_ref_vector& conseq) {
211214
TRACE("context", tout << "extract fixed consequences\n";);
215+
auto are_equal = [&](expr* k, expr* v) {
216+
return e_internalized(k) &&
217+
e_internalized(v) &&
218+
get_enode(k)->get_root() == get_enode(v)->get_root();
219+
};
212220
ptr_vector<expr> to_delete;
213221
expr_ref fml(m), eq(m);
214-
for (auto const& kv : m_var2val) {
222+
for (auto const& kv : m_var2val) {
215223
expr* k = kv.m_key;
216224
expr* v = kv.m_value;
217225
if (!m.is_bool(k) && are_equal(k, v)) {
218226
literal_vector literals;
219227
m_conflict_resolution->eq2literals(get_enode(v), get_enode(k), literals);
220228
index_set s;
221-
for (unsigned i = 0; i < literals.size(); ++i) {
222-
SASSERT(get_assign_level(literals[i]) <= get_search_level());
223-
s |= m_antecedents.find(literals[i].var());
229+
for (literal lit : literals) {
230+
SASSERT(get_assign_level(lit) <= get_search_level());
231+
s |= m_antecedents.find(lit.var());
224232
}
225233

226234
fml = m.mk_eq(m_var2orig.find(k), v);
227235
fml = m.mk_implies(antecedent2fml(s), fml);
228236
conseq.push_back(fml);
229237
to_delete.push_back(k);
230238

231-
for (unsigned i = 0; i < literals.size(); ++i) {
232-
literals[i].neg();
233-
}
239+
for (literal& lit : literals)
240+
lit.neg();
241+
234242
literal lit = mk_diseq(k, v);
235243
literals.push_back(lit);
236244
mk_clause(literals.size(), literals.c_ptr(), nullptr);
237245
TRACE("context", display_literals_verbose(tout, literals.size(), literals.c_ptr()););
238246
}
239247
}
240-
for (unsigned i = 0; i < to_delete.size(); ++i) {
241-
m_var2val.remove(to_delete[i]);
248+
for (expr* e : to_delete) {
249+
m_var2val.remove(e);
242250
}
243251
return to_delete.size();
244252
}
@@ -270,18 +278,25 @@ namespace smt {
270278
m_var2val.reset();
271279
m_var2orig.reset();
272280
m_assumption2orig.reset();
273-
bool pushed = false;
274-
for (unsigned i = 0; i < vars0.size(); ++i) {
275-
expr* v = vars0[i];
281+
struct scoped_level {
282+
context& c;
283+
unsigned lvl;
284+
scoped_level(context& c):
285+
c(c), lvl(c.get_scope_level()) {}
286+
~scoped_level() {
287+
if (c.get_scope_level() > lvl)
288+
c.pop_scope(c.get_scope_level() - lvl);
289+
}
290+
};
291+
scoped_level _lvl(*this);
292+
293+
for (expr* v : vars0) {
276294
if (is_uninterp_const(v)) {
277295
vars.push_back(v);
278296
m_var2orig.insert(v, v);
279297
}
280298
else {
281-
if (!pushed) {
282-
pushed = true;
283-
push();
284-
}
299+
push();
285300
expr_ref c(m.mk_fresh_const("v", m.get_sort(v)), m);
286301
expr_ref eq(m.mk_eq(c, v), m);
287302
assert_expr(eq);
@@ -295,10 +310,7 @@ namespace smt {
295310
m_assumption2orig.insert(a, a);
296311
}
297312
else {
298-
if (!pushed) {
299-
pushed = true;
300-
push();
301-
}
313+
push();
302314
expr_ref c(m.mk_fresh_const("a", m.get_sort(a)), m);
303315
expr_ref eq(m.mk_eq(c, a), m);
304316
assert_expr(eq);
@@ -309,9 +321,13 @@ namespace smt {
309321
lbool is_sat = check(assumptions.size(), assumptions.c_ptr());
310322
if (is_sat != l_true) {
311323
TRACE("context", tout << is_sat << "\n";);
312-
if (pushed) pop(1);
313324
return is_sat;
314325
}
326+
if (m_qmanager->has_quantifiers()) {
327+
IF_VERBOSE(1, verbose_stream() << "(get-consequences :unsupported-quantifiers)\n";);
328+
return l_undef;
329+
}
330+
315331
TRACE("context", display(tout););
316332

317333
index_set _assumptions;
@@ -352,7 +368,6 @@ namespace smt {
352368
if (num_vars >= chunk_size)
353369
break;
354370
if (get_cancel_flag()) {
355-
if (pushed) pop(1);
356371
return l_undef;
357372
}
358373
expr* e = kv.m_key;
@@ -365,12 +380,14 @@ namespace smt {
365380
++num_vars;
366381
push_scope();
367382
assign(lit, b_justification::mk_axiom(), true);
368-
if (!propagate() && (!resolve_conflict() || inconsistent())) {
369-
TRACE("context", tout << "inconsistent\n";);
370-
SASSERT(inconsistent());
371-
m_conflict = null_b_justification;
372-
m_not_l = null_literal;
373-
SASSERT(m_search_lvl == get_search_level());
383+
while (can_propagate()) {
384+
if (!propagate() && (!resolve_conflict() || inconsistent())) {
385+
TRACE("context", tout << "inconsistent\n";);
386+
SASSERT(inconsistent());
387+
m_conflict = null_b_justification;
388+
m_not_l = null_literal;
389+
SASSERT(m_search_lvl == get_search_level());
390+
}
374391
}
375392
}
376393
SASSERT(!inconsistent());
@@ -380,11 +397,10 @@ namespace smt {
380397
while (true) {
381398
is_sat = bounded_search();
382399
if (is_sat != l_true && m_last_search_failure != OK) {
383-
if (pushed) pop(1);
384400
return is_sat;
385401
}
386402
if (is_sat == l_undef) {
387-
IF_VERBOSE(1, verbose_stream() << "(get-consequences inc-limits)\n";);
403+
IF_VERBOSE(0, verbose_stream() << "(get-consequences inc-limits)\n";);
388404
inc_limits();
389405
continue;
390406
}
@@ -408,9 +424,6 @@ namespace smt {
408424

409425
end_search();
410426
DEBUG_CODE(validate_consequences(assumptions, vars, conseq, unfixed););
411-
if (pushed) {
412-
pop(1);
413-
}
414427
return l_true;
415428
}
416429

0 commit comments

Comments
 (0)