@@ -28,7 +28,7 @@ namespace smt {
28
28
29
29
expr_ref context::antecedent2fml (index_set const & vars) {
30
30
expr_ref_vector premises (m);
31
- for (unsigned v : vars) {
31
+ for (unsigned v : vars) {
32
32
expr* e = bool_var2expr (v);
33
33
e = m_assumption2orig.find (e);
34
34
premises.push_back (get_assignment (v) != l_false ? e : m.mk_not (e));
@@ -159,11 +159,16 @@ namespace smt {
159
159
160
160
unsigned context::delete_unfixed (expr_ref_vector& unfixed) {
161
161
ptr_vector<expr> to_delete;
162
- for (auto const & kv : m_var2val) {
162
+ for (auto const & kv : m_var2val) {
163
163
expr* k = kv.m_key ;
164
164
expr* v = kv.m_value ;
165
165
if (m.is_bool (k)) {
166
166
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
+ );
167
172
switch (get_assignment (lit)) {
168
173
case l_true:
169
174
if (m.is_false (v)) {
@@ -193,52 +198,55 @@ namespace smt {
193
198
to_delete.push_back (k);
194
199
}
195
200
}
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 );
199
204
}
200
205
return to_delete.size ();
201
206
}
202
207
203
- #define are_equal (v, k ) (e_internalized(k) && e_internalized(v) && get_enode(k)->get_root () == get_enode(v)->get_root())
204
-
205
208
//
206
209
// Extract equalities that are congruent at the search level.
207
210
// Add a clause to short-circuit the congruence justifications for
208
211
// next rounds.
209
212
//
210
213
unsigned context::extract_fixed_eqs (expr_ref_vector& conseq) {
211
214
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
+ };
212
220
ptr_vector<expr> to_delete;
213
221
expr_ref fml (m), eq (m);
214
- for (auto const & kv : m_var2val) {
222
+ for (auto const & kv : m_var2val) {
215
223
expr* k = kv.m_key ;
216
224
expr* v = kv.m_value ;
217
225
if (!m.is_bool (k) && are_equal (k, v)) {
218
226
literal_vector literals;
219
227
m_conflict_resolution->eq2literals (get_enode (v), get_enode (k), literals);
220
228
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 ());
224
232
}
225
233
226
234
fml = m.mk_eq (m_var2orig.find (k), v);
227
235
fml = m.mk_implies (antecedent2fml (s), fml);
228
236
conseq.push_back (fml);
229
237
to_delete.push_back (k);
230
238
231
- for (unsigned i = 0 ; i < literals. size (); ++i) {
232
- literals[i] .neg ();
233
- }
239
+ for (literal& lit : literals)
240
+ lit .neg ();
241
+
234
242
literal lit = mk_diseq (k, v);
235
243
literals.push_back (lit);
236
244
mk_clause (literals.size (), literals.c_ptr (), nullptr );
237
245
TRACE (" context" , display_literals_verbose (tout, literals.size (), literals.c_ptr ()););
238
246
}
239
247
}
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 );
242
250
}
243
251
return to_delete.size ();
244
252
}
@@ -270,18 +278,25 @@ namespace smt {
270
278
m_var2val.reset ();
271
279
m_var2orig.reset ();
272
280
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) {
276
294
if (is_uninterp_const (v)) {
277
295
vars.push_back (v);
278
296
m_var2orig.insert (v, v);
279
297
}
280
298
else {
281
- if (!pushed) {
282
- pushed = true ;
283
- push ();
284
- }
299
+ push ();
285
300
expr_ref c (m.mk_fresh_const (" v" , m.get_sort (v)), m);
286
301
expr_ref eq (m.mk_eq (c, v), m);
287
302
assert_expr (eq);
@@ -295,10 +310,7 @@ namespace smt {
295
310
m_assumption2orig.insert (a, a);
296
311
}
297
312
else {
298
- if (!pushed) {
299
- pushed = true ;
300
- push ();
301
- }
313
+ push ();
302
314
expr_ref c (m.mk_fresh_const (" a" , m.get_sort (a)), m);
303
315
expr_ref eq (m.mk_eq (c, a), m);
304
316
assert_expr (eq);
@@ -309,9 +321,13 @@ namespace smt {
309
321
lbool is_sat = check (assumptions.size (), assumptions.c_ptr ());
310
322
if (is_sat != l_true) {
311
323
TRACE (" context" , tout << is_sat << " \n " ;);
312
- if (pushed) pop (1 );
313
324
return is_sat;
314
325
}
326
+ if (m_qmanager->has_quantifiers ()) {
327
+ IF_VERBOSE (1 , verbose_stream () << " (get-consequences :unsupported-quantifiers)\n " ;);
328
+ return l_undef;
329
+ }
330
+
315
331
TRACE (" context" , display (tout););
316
332
317
333
index_set _assumptions;
@@ -352,7 +368,6 @@ namespace smt {
352
368
if (num_vars >= chunk_size)
353
369
break ;
354
370
if (get_cancel_flag ()) {
355
- if (pushed) pop (1 );
356
371
return l_undef;
357
372
}
358
373
expr* e = kv.m_key ;
@@ -365,12 +380,14 @@ namespace smt {
365
380
++num_vars;
366
381
push_scope ();
367
382
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
+ }
374
391
}
375
392
}
376
393
SASSERT (!inconsistent ());
@@ -380,11 +397,10 @@ namespace smt {
380
397
while (true ) {
381
398
is_sat = bounded_search ();
382
399
if (is_sat != l_true && m_last_search_failure != OK) {
383
- if (pushed) pop (1 );
384
400
return is_sat;
385
401
}
386
402
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 " ;);
388
404
inc_limits ();
389
405
continue ;
390
406
}
@@ -408,9 +424,6 @@ namespace smt {
408
424
409
425
end_search ();
410
426
DEBUG_CODE (validate_consequences (assumptions, vars, conseq, unfixed););
411
- if (pushed) {
412
- pop (1 );
413
- }
414
427
return l_true;
415
428
}
416
429
0 commit comments