Skip to content

Commit 4b51fe4

Browse files
fix #2562
Signed-off-by: Nikolaj Bjorner <[email protected]>
1 parent 69abe16 commit 4b51fe4

File tree

3 files changed

+98
-29
lines changed

3 files changed

+98
-29
lines changed

src/ast/array_decl_plugin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,8 @@ func_decl* array_decl_plugin::mk_select(unsigned arity, sort * const * domain) {
259259
std::stringstream strm;
260260
strm << "domain sort " << sort_ref(domain[i+1], *m_manager) << " and parameter ";
261261
strm << parameter_pp(parameters[i], *m_manager) << " do not match";
262-
m_manager->raise_exception(strm.str());
263262
UNREACHABLE();
263+
m_manager->raise_exception(strm.str());
264264
return nullptr;
265265
}
266266
new_domain.push_back(to_sort(parameters[i].get_ast()));

src/smt/theory_seq.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2228,6 +2228,8 @@ bool theory_seq::is_solved() {
22282228
return false;
22292229
}
22302230

2231+
#if 0
2232+
// debug code
22312233
context& ctx = get_context();
22322234
for (enode* n : ctx.enodes()) {
22332235
expr* e = nullptr;
@@ -2244,6 +2246,7 @@ bool theory_seq::is_solved() {
22442246
}
22452247
}
22462248
}
2249+
#endif
22472250

22482251
return true;
22492252
}

src/tactic/fd_solver/smtfd_solver.cpp

Lines changed: 94 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ namespace smtfd {
368368
bool term_covered(expr* t);
369369
bool sort_covered(sort* s);
370370
void populate_model(model_ref& mdl, expr_ref_vector const& core);
371+
std::ostream& display(std::ostream& out);
371372
};
372373

373374
struct f_app_eq {
@@ -393,7 +394,7 @@ namespace smtfd {
393394
model_ref m_model;
394395
expr_ref_vector m_values;
395396
ast_ref_vector m_pinned;
396-
expr_ref_vector m_args, m_args2, m_vargs;
397+
expr_ref_vector m_args, m_vargs;
397398
f_app_eq m_eq;
398399
f_app_hash m_hash;
399400
scoped_ptr_vector<table> m_tables;
@@ -424,7 +425,8 @@ namespace smtfd {
424425
m_model(mdl),
425426
m_values(m),
426427
m_pinned(m),
427-
m_args(m), m_args2(m), m_vargs(m),
428+
m_args(m),
429+
m_vargs(m),
428430
m_eq(*this),
429431
m_hash(*this)
430432
{
@@ -485,6 +487,26 @@ namespace smtfd {
485487
add_lemma(m.mk_implies(mk_and(m_args), m.mk_eq(f1.m_t, f2.m_t)));
486488
}
487489

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) << "\nterm: " << 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+
488510
expr_ref model_value(expr* t) { return m_context.model_value(t); }
489511
expr_ref model_value(sort* s) { return m_context.model_value(s); }
490512

@@ -529,6 +551,13 @@ namespace smtfd {
529551
return false;
530552
}
531553

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+
532561
void plugin_context::populate_model(model_ref& mdl, expr_ref_vector const& core) {
533562
for (theory_plugin* p : m_plugins) {
534563
p->populate_model(mdl, core);
@@ -737,9 +766,13 @@ namespace smtfd {
737766
expr* stored_value = t->get_arg(t->get_num_args()-1);
738767
expr_ref val1 = eval_abs(sel);
739768
expr_ref val2 = eval_abs(stored_value);
769+
// A[i] = v
740770
if (val1 != val2) {
741771
add_lemma(m.mk_eq(sel, stored_value));
742772
}
773+
m_pinned.push_back(sel);
774+
TRACE("smtfd", tout << sel << "\n";);
775+
check_select(sel);
743776
}
744777

745778
/**
@@ -761,37 +794,64 @@ namespace smtfd {
761794
expr* arg = t->get_arg(0);
762795
expr_ref vT = eval_abs(t);
763796
expr_ref vA = eval_abs(arg);
764-
if (vT == vA) {
765-
return;
766-
}
797+
767798
table& tT = ast2table(vT); // select table of t
768799
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";);
769807
m_vargs.reset();
770-
m_args.reset();
771-
m_args.push_back(t);
772808
for (unsigned i = 0; i + 1 < t->get_num_args(); ++i) {
773809
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) {
777820
for (auto& fA : tA) {
778821
f_app fT;
779822
if (m_context.at_max()) {
780823
break;
781824
}
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);
791836
}
792837
}
793838
}
794839

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+
795855
bool same_array_sort(f_app const& fA, f_app const& fT) const {
796856
return m.get_sort(fA.m_t->get_arg(0)) == m.get_sort(fT.m_t->get_arg(0));
797857
}
@@ -826,20 +886,22 @@ namespace smtfd {
826886
}
827887
}
828888

889+
// arguments, except for array variable are equal.
829890
bool eq(expr_ref_vector const& args, f_app const& f) {
830891
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; ) {
832893
if (args.get(i) != m_values.get(f.m_val_offset + i))
833894
return false;
834895
}
835896
return true;
836897
}
837898

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));
840902
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)));
843905
}
844906
return mk_and(r);
845907
}
@@ -1031,6 +1093,7 @@ namespace smtfd {
10311093
}
10321094
}
10331095
}
1096+
10341097
};
10351098

10361099
class mbqi {
@@ -1268,6 +1331,7 @@ namespace smtfd {
12681331
lbool get_prime_implicate(unsigned num_assumptions, expr * const * assumptions, expr_ref_vector& core) {
12691332
expr_ref_vector asms(m);
12701333
m_fd_sat_solver->get_model(m_model);
1334+
m_model->set_model_completion(true);
12711335
init_literals(num_assumptions, assumptions, asms);
12721336
TRACE("smtfd", display(tout << asms););
12731337
SASSERT(asms.contains(m_not_toggle));
@@ -1285,12 +1349,12 @@ namespace smtfd {
12851349

12861350
lbool check_smt(expr_ref_vector& core) {
12871351
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");
12901353
params_ref p;
12911354
p.set_uint("max_conflicts", m_max_conflicts);
12921355
m_smt_solver->updt_params(p);
12931356
lbool r = m_smt_solver->check_sat(core);
1357+
TRACE("smtfd", tout << "core: " << core << "\nresult: " << r << "\n";);
12941358
update_reason_unknown(r, m_smt_solver);
12951359
switch (r) {
12961360
case l_false: {
@@ -1331,6 +1395,7 @@ namespace smtfd {
13311395
}
13321396
}
13331397
ap.global_check(core);
1398+
TRACE("smtfd", context.display(tout););
13341399
for (expr* f : context) {
13351400
IF_VERBOSE(10, verbose_stream() << "lemma: " << expr_ref(rep(f), m) << "\n");
13361401
assert_fd(f);
@@ -1362,6 +1427,7 @@ namespace smtfd {
13621427
}
13631428
context.populate_model(m_model, core);
13641429

1430+
TRACE("smtfd", tout << has_q << " " << has_non_covered << "\n";);
13651431
if (!has_q) {
13661432
return has_non_covered ? l_false : l_true;
13671433
}
@@ -1434,8 +1500,8 @@ namespace smtfd {
14341500
std::ostream& display(std::ostream& out, unsigned n = 0, expr * const * assumptions = nullptr) const override {
14351501
if (!m_fd_sat_solver) return out;
14361502
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");
14391505
out << m_assumptions << "\n";
14401506
m_abs.display(out);
14411507
return out;

0 commit comments

Comments
 (0)