@@ -893,10 +893,8 @@ namespace smtfd {
893
893
894
894
void check_select (app* t) {
895
895
expr* a = t->get_arg (0 );
896
- if (!m_autil.is_store (a)) {
897
- expr_ref vA = eval_abs (a);
898
- enforce_congruence (vA, t);
899
- }
896
+ expr_ref vA = eval_abs (a);
897
+ enforce_congruence (vA, t);
900
898
}
901
899
902
900
// check that (select(t, t.args) = t.value)
@@ -927,24 +925,34 @@ namespace smtfd {
927
925
return ;
928
926
}
929
927
app* store = to_app (t->get_arg (0 ));
928
+ expr* val = store->get_arg (store->get_num_args ()-1 );
930
929
expr* a = store->get_arg (0 );
931
930
expr_ref_vector eqs (m);
932
931
m_args.reset ();
933
932
m_args.push_back (a);
934
933
bool all_eq = true ;
935
934
for (unsigned i = 1 ; i < t->get_num_args (); ++i) {
936
- expr_ref v1 = eval_abs (t->get_arg (i));
937
- expr_ref v2 = eval_abs (store->get_arg (i));
935
+ expr* arg1 = t->get_arg (i);
936
+ expr* arg2 = store->get_arg (i);
937
+ if (arg1 == arg2) continue ;
938
+ expr_ref v1 = eval_abs (arg1);
939
+ expr_ref v2 = eval_abs (arg2);
938
940
if (v1 != v2) all_eq = false ;
939
- m_args.push_back (t->get_arg (i));
940
- eqs.push_back (m.mk_eq (t->get_arg (i), store->get_arg (i)));
941
+ m_args.push_back (arg1);
942
+ eqs.push_back (m.mk_eq (arg1, arg2));
943
+ }
944
+ if (eqs.empty ()) return ;
945
+ expr_ref eq = mk_and (eqs);
946
+ expr_ref eqV = eval_abs (eq);
947
+ expr_ref val1 = eval_abs (t);
948
+ expr_ref val2 = eval_abs (val);
949
+ if (val1 != val2 && !m.is_false (eqV)) {
950
+ add_lemma (m.mk_implies (mk_and (eqs), m.mk_eq (t, val)));
941
951
}
942
- if (all_eq) return ;
943
952
944
953
app_ref sel (m_autil.mk_select (m_args), m);
945
- expr_ref val1 = eval_abs (sel);
946
- expr_ref val2 = eval_abs (t);
947
- if (val1 != val2) {
954
+ val2 = eval_abs (sel);
955
+ if (val1 != val2 && !m.is_true (eqV)) {
948
956
TRACE (" smtfd" , tout << " select/store: " << mk_bounded_pp (t, m, 2 ) << " \n " ;);
949
957
add_lemma (m.mk_or (m.mk_eq (sel, t), mk_and (eqs)));
950
958
m_pinned.push_back (sel);
@@ -993,7 +1001,7 @@ namespace smtfd {
993
1001
//
994
1002
void reconcile_stores (app* t, expr* vT, table& tT, expr* vA, table& tA) {
995
1003
unsigned r = 0 ;
996
- if (get_lambda (vA) <= 1 ) {
1004
+ if (false && get_lambda (vA) <= 1 ) {
997
1005
return ;
998
1006
}
999
1007
inc_lambda (vT);
@@ -1008,7 +1016,7 @@ namespace smtfd {
1008
1016
++r;
1009
1017
}
1010
1018
}
1011
- #if 0
1019
+ #if 1
1012
1020
// only up-propagation really needed.
1013
1021
for (auto & fT : tT) {
1014
1022
f_app fA ;
@@ -1196,6 +1204,9 @@ namespace smtfd {
1196
1204
if (m_autil.is_store (t)) {
1197
1205
check_store2 (to_app (t));
1198
1206
}
1207
+ else if (m_autil.is_select (t)) {
1208
+ check_select_store (to_app (t));
1209
+ }
1199
1210
break ;
1200
1211
default :
1201
1212
break ;
@@ -1532,7 +1543,11 @@ namespace smtfd {
1532
1543
lbool check_abs (unsigned num_assumptions, expr * const * assumptions) {
1533
1544
expr_ref_vector asms (m);
1534
1545
init_assumptions (num_assumptions, assumptions, asms);
1535
- TRACE (" smtfd" , display (tout << asms << " \n " ););
1546
+ TRACE (" smtfd" ,
1547
+ for (unsigned i = 0 ; i < num_assumptions; ++i) {
1548
+ tout << mk_bounded_pp (assumptions[i], m, 3 ) << " \n " ;
1549
+ }
1550
+ display (tout << asms << " \n " ););
1536
1551
SASSERT (asms.contains (m_toggle));
1537
1552
m_fd_sat_solver->assert_expr (m_toggle);
1538
1553
lbool r = m_fd_sat_solver->check_sat (asms);
0 commit comments