@@ -368,6 +368,7 @@ namespace smtfd {
368
368
bool term_covered (expr* t);
369
369
bool sort_covered (sort* s);
370
370
void populate_model (model_ref& mdl, expr_ref_vector const & core);
371
+ std::ostream& display (std::ostream& out);
371
372
};
372
373
373
374
struct f_app_eq {
@@ -393,7 +394,7 @@ namespace smtfd {
393
394
model_ref m_model;
394
395
expr_ref_vector m_values;
395
396
ast_ref_vector m_pinned;
396
- expr_ref_vector m_args, m_args2, m_vargs;
397
+ expr_ref_vector m_args, m_vargs;
397
398
f_app_eq m_eq;
398
399
f_app_hash m_hash;
399
400
scoped_ptr_vector<table> m_tables;
@@ -424,7 +425,8 @@ namespace smtfd {
424
425
m_model (mdl),
425
426
m_values (m),
426
427
m_pinned (m),
427
- m_args (m), m_args2(m), m_vargs(m),
428
+ m_args (m),
429
+ m_vargs (m),
428
430
m_eq (*this ),
429
431
m_hash (*this )
430
432
{
@@ -485,6 +487,26 @@ namespace smtfd {
485
487
add_lemma (m.mk_implies (mk_and (m_args), m.mk_eq (f1.m_t , f2.m_t )));
486
488
}
487
489
490
+ std::ostream& display (std::ostream& out) {
491
+ for (table* tb : m_tables) {
492
+ display (out, *tb);
493
+ }
494
+ return out;
495
+ }
496
+
497
+ std::ostream& display (std::ostream& out, table& t) {
498
+ out << " table\n " ;
499
+ for (auto const & k : t) {
500
+ out << " key: " << mk_pp (k.m_f , m) << " \n term: " << mk_pp (k.m_t , m) << " \n " ;
501
+ out << " args:\n " ;
502
+ for (unsigned i = 0 ; i <= k.m_t ->get_num_args (); ++i) {
503
+ out << mk_pp (m_values.get (k.m_val_offset + i), m) << " \n " ;
504
+ }
505
+ out << " \n " ;
506
+ }
507
+ return out;
508
+ }
509
+
488
510
expr_ref model_value (expr* t) { return m_context.model_value (t); }
489
511
expr_ref model_value (sort* s) { return m_context.model_value (s); }
490
512
@@ -529,6 +551,13 @@ namespace smtfd {
529
551
return false ;
530
552
}
531
553
554
+ std::ostream& plugin_context::display (std::ostream& out) {
555
+ for (theory_plugin* p : m_plugins) {
556
+ p->display (out);
557
+ }
558
+ return out;
559
+ }
560
+
532
561
void plugin_context::populate_model (model_ref& mdl, expr_ref_vector const & core) {
533
562
for (theory_plugin* p : m_plugins) {
534
563
p->populate_model (mdl, core);
@@ -737,9 +766,13 @@ namespace smtfd {
737
766
expr* stored_value = t->get_arg (t->get_num_args ()-1 );
738
767
expr_ref val1 = eval_abs (sel);
739
768
expr_ref val2 = eval_abs (stored_value);
769
+ // A[i] = v
740
770
if (val1 != val2) {
741
771
add_lemma (m.mk_eq (sel, stored_value));
742
772
}
773
+ m_pinned.push_back (sel);
774
+ TRACE (" smtfd" , tout << sel << " \n " ;);
775
+ check_select (sel);
743
776
}
744
777
745
778
/* *
@@ -761,37 +794,64 @@ namespace smtfd {
761
794
expr* arg = t->get_arg (0 );
762
795
expr_ref vT = eval_abs (t);
763
796
expr_ref vA = eval_abs (arg);
764
- if (vT == vA) {
765
- return ;
766
- }
797
+
767
798
table& tT = ast2table (vT); // select table of t
768
799
table& tA = ast2table (vA); // select table of arg
800
+
801
+ if (vT == vA) {
802
+ TRACE (" smtfd" , display (tout << " eq\n " , tT););
803
+ return ;
804
+ }
805
+
806
+ TRACE (" smtfd" , tout << mk_pp (t, m) << " \n " << vT << " \n " << vA << " \n " ;);
769
807
m_vargs.reset ();
770
- m_args.reset ();
771
- m_args.push_back (t);
772
808
for (unsigned i = 0 ; i + 1 < t->get_num_args (); ++i) {
773
809
m_vargs.push_back (eval_abs (t->get_arg (i)));
774
- m_args.push_back (t->get_arg (i));
775
- }
776
-
810
+ }
811
+ reconcile_stores (t, tT, tA);
812
+ }
813
+
814
+ //
815
+ // T = store(A, i, v)
816
+ // T[j] = w: i = j or A[j] = T[j]
817
+ // A[j] = w: i = j or T[j] = A[j]
818
+ //
819
+ void reconcile_stores (app* t, table& tT, table& tA) {
777
820
for (auto & fA : tA) {
778
821
f_app fT ;
779
822
if (m_context.at_max ()) {
780
823
break ;
781
824
}
782
- if (tT.find (fA , fT ) && value_of (fA ) != value_of (fT ) && !eq (m_vargs, fA )) {
783
- SASSERT (same_array_sort (fA , fT ));
784
- m_args2.reset ();
785
- for (unsigned i = 0 ; i < t->get_num_args (); ++i) {
786
- m_args2.push_back (fA .m_t ->get_arg (i));
787
- }
788
- expr_ref eq = mk_eq_idxs (m_args, m_args2);
789
- m_args2[0 ] = t;
790
- add_lemma (m.mk_implies (m.mk_eq (t->get_arg (0 ), fA .m_t ->get_arg (0 )), m.mk_or (eq, m.mk_eq (fA .m_t , m_autil.mk_select (m_args2)))));
825
+ if (!tT.find (fA , fT ) || (value_of (fA ) != value_of (fT ) && !eq (m_vargs, fA ))) {
826
+ add_select_store_axiom (t, fA );
827
+ }
828
+ }
829
+ for (auto & fT : tT) {
830
+ f_app fA ;
831
+ if (m_context.at_max ()) {
832
+ break ;
833
+ }
834
+ if (!tA.find (fT , fA )) {
835
+ add_select_store_axiom (t, fT );
791
836
}
792
837
}
793
838
}
794
839
840
+ void add_select_store_axiom (app* t, f_app& f) {
841
+ SASSERT (m_autil.is_store (t));
842
+ expr* a = t->get_arg (0 );
843
+ m_args.reset ();
844
+ for (expr* arg : *f.m_t ) {
845
+ m_args.push_back (arg);
846
+ }
847
+ expr_ref eq = mk_eq_idxs (t, f.m_t );
848
+ m_args[0 ] = t;
849
+ expr_ref sel1 (m_autil.mk_select (m_args), m);
850
+ m_args[0 ] = a;
851
+ expr_ref sel2 (m_autil.mk_select (m_args), m);
852
+ add_lemma (m.mk_or (eq, m.mk_eq (sel1, sel2)));
853
+ }
854
+
795
855
bool same_array_sort (f_app const & fA , f_app const & fT ) const {
796
856
return m.get_sort (fA .m_t ->get_arg (0 )) == m.get_sort (fT .m_t ->get_arg (0 ));
797
857
}
@@ -826,20 +886,22 @@ namespace smtfd {
826
886
}
827
887
}
828
888
889
+ // arguments, except for array variable are equal.
829
890
bool eq (expr_ref_vector const & args, f_app const & f) {
830
891
SASSERT (args.size () == f.m_t ->get_num_args ());
831
- for (unsigned i = args.size (); i-- > 0 ; ) {
892
+ for (unsigned i = args.size (); i-- > 1 ; ) {
832
893
if (args.get (i) != m_values.get (f.m_val_offset + i))
833
894
return false ;
834
895
}
835
896
return true ;
836
897
}
837
898
838
- expr_ref mk_eq_idxs (expr_ref_vector const & es1, expr_ref_vector const & es2) {
839
- SASSERT (es1.size () == es2.size ());
899
+ expr_ref mk_eq_idxs (app* t, app* s) {
900
+ SASSERT (m_autil.is_store (t));
901
+ SASSERT (m_autil.is_select (s));
840
902
expr_ref_vector r (m);
841
- for (unsigned i = es1. size () ; i-- > 1 ; ) {
842
- r.push_back (m.mk_eq (es1[i], es2[i] ));
903
+ for (unsigned i = 1 ; i < s-> get_num_args (); ++i ) {
904
+ r.push_back (m.mk_eq (t-> get_arg (i), s-> get_arg (i) ));
843
905
}
844
906
return mk_and (r);
845
907
}
@@ -1031,6 +1093,7 @@ namespace smtfd {
1031
1093
}
1032
1094
}
1033
1095
}
1096
+
1034
1097
};
1035
1098
1036
1099
class mbqi {
@@ -1268,6 +1331,7 @@ namespace smtfd {
1268
1331
lbool get_prime_implicate (unsigned num_assumptions, expr * const * assumptions, expr_ref_vector& core) {
1269
1332
expr_ref_vector asms (m);
1270
1333
m_fd_sat_solver->get_model (m_model);
1334
+ m_model->set_model_completion (true );
1271
1335
init_literals (num_assumptions, assumptions, asms);
1272
1336
TRACE (" smtfd" , display (tout << asms););
1273
1337
SASSERT (asms.contains (m_not_toggle));
@@ -1285,12 +1349,12 @@ namespace smtfd {
1285
1349
1286
1350
lbool check_smt (expr_ref_vector& core) {
1287
1351
rep (core);
1288
- TRACE (" smtfd" , tout << " core: " << core << " \n " ;);
1289
- IF_VERBOSE (10 , verbose_stream () << " core: " << core << " \n " );
1352
+ IF_VERBOSE (10 , verbose_stream () << " core: " << core.size () << " \n " );
1290
1353
params_ref p;
1291
1354
p.set_uint (" max_conflicts" , m_max_conflicts);
1292
1355
m_smt_solver->updt_params (p);
1293
1356
lbool r = m_smt_solver->check_sat (core);
1357
+ TRACE (" smtfd" , tout << " core: " << core << " \n result: " << r << " \n " ;);
1294
1358
update_reason_unknown (r, m_smt_solver);
1295
1359
switch (r) {
1296
1360
case l_false: {
@@ -1331,6 +1395,7 @@ namespace smtfd {
1331
1395
}
1332
1396
}
1333
1397
ap.global_check (core);
1398
+ TRACE (" smtfd" , context.display (tout););
1334
1399
for (expr* f : context) {
1335
1400
IF_VERBOSE (10 , verbose_stream () << " lemma: " << expr_ref (rep (f), m) << " \n " );
1336
1401
assert_fd (f);
@@ -1362,6 +1427,7 @@ namespace smtfd {
1362
1427
}
1363
1428
context.populate_model (m_model, core);
1364
1429
1430
+ TRACE (" smtfd" , tout << has_q << " " << has_non_covered << " \n " ;);
1365
1431
if (!has_q) {
1366
1432
return has_non_covered ? l_false : l_true;
1367
1433
}
@@ -1434,8 +1500,8 @@ namespace smtfd {
1434
1500
std::ostream& display (std::ostream& out, unsigned n = 0 , expr * const * assumptions = nullptr ) const override {
1435
1501
if (!m_fd_sat_solver) return out;
1436
1502
m_fd_sat_solver->display (out);
1437
- m_fd_core_solver->display (out);
1438
- m_smt_solver->display (out);
1503
+ // m_fd_core_solver->display(out << "core solver\n" );
1504
+ // m_smt_solver->display(out << "smt solver\n" );
1439
1505
out << m_assumptions << " \n " ;
1440
1506
m_abs.display (out);
1441
1507
return out;
0 commit comments