mirror of
https://github.com/Z3Prover/z3
synced 2025-05-12 02:04:43 +00:00
Merge branch 'master' of https://github.com/Z3Prover/z3
This commit is contained in:
commit
1e4f524a22
392 changed files with 9183 additions and 4268 deletions
|
@ -37,6 +37,7 @@ Revision History:
|
|||
#include "model/model_pp.h"
|
||||
#include "ast/ast_smt2_pp.h"
|
||||
#include "ast/ast_translation.h"
|
||||
#include "ast/recfun_decl_plugin.h"
|
||||
|
||||
namespace smt {
|
||||
|
||||
|
@ -494,7 +495,7 @@ namespace smt {
|
|||
|
||||
try {
|
||||
TRACE("add_eq", tout << "assigning: #" << n1->get_owner_id() << " = #" << n2->get_owner_id() << "\n";);
|
||||
TRACE("add_eq_detail", tout << "assigning\n" << mk_pp(n1->get_owner(), m_manager) << "\n" << mk_pp(n2->get_owner(), m_manager) << "\n";
|
||||
TRACE("add_eq_detail", tout << "assigning\n" << enode_pp(n1, *this) << "\n" << enode_pp(n2, *this) << "\n";
|
||||
tout << "kind: " << js.get_kind() << "\n";);
|
||||
|
||||
m_stats.m_num_add_eq++;
|
||||
|
@ -518,7 +519,7 @@ namespace smt {
|
|||
// 2. r1 is interpreted but r2 is not.
|
||||
//
|
||||
// The second condition is used to enforce the invariant that if a class contain
|
||||
// an interepreted enode then the root is also interpreted.
|
||||
// an interpreted enode then the root is also interpreted.
|
||||
if ((r1->get_class_size() > r2->get_class_size() && !r2->is_interpreted()) || r1->is_interpreted()) {
|
||||
SASSERT(!r2->is_interpreted());
|
||||
std::swap(n1, n2);
|
||||
|
@ -529,7 +530,7 @@ namespace smt {
|
|||
" n1: #" << n1->get_owner_id() << "\n";);
|
||||
|
||||
// It is necessary to propagate relevancy to other elements of
|
||||
// the equivalence class. This is nessary to enforce the invariant
|
||||
// the equivalence class. This is necessary to enforce the invariant
|
||||
// in the field m_parent of the enode class.
|
||||
if (is_relevant(r1)) { // && !m_manager.is_eq(r1->get_owner())) !is_eq HACK
|
||||
// NOTE for !is_eq HACK... the !is_eq HACK does not propagate relevancy when two
|
||||
|
@ -1232,7 +1233,7 @@ namespace smt {
|
|||
if (depth == 0)
|
||||
return false;
|
||||
if (r1->get_num_parents() < SMALL_NUM_PARENTS) {
|
||||
TRACE("is_ext_diseq", tout << mk_bounded_pp(n1->get_owner(), m_manager) << " " << mk_bounded_pp(n2->get_owner(), m_manager) << " " << depth << "\n";);
|
||||
TRACE("is_ext_diseq", tout << enode_pp(n1, *this) << " " << enode_pp(n2, *this) << " " << depth << "\n";);
|
||||
for (enode * p1 : enode::parents(r1)) {
|
||||
if (!is_relevant(p1))
|
||||
continue;
|
||||
|
@ -1241,7 +1242,7 @@ namespace smt {
|
|||
if (!p1->is_cgr())
|
||||
continue;
|
||||
func_decl * f = p1->get_decl();
|
||||
TRACE("is_ext_diseq", tout << "p1: " << mk_bounded_pp(p1->get_owner(), m_manager) << "\n";);
|
||||
TRACE("is_ext_diseq", tout << "p1: " << enode_pp(p1, *this) << "\n";);
|
||||
unsigned num_args = p1->get_num_args();
|
||||
for (enode * p2 : enode::parents(r2)) {
|
||||
if (!is_relevant(p2))
|
||||
|
@ -1250,7 +1251,7 @@ namespace smt {
|
|||
continue;
|
||||
if (!p2->is_cgr())
|
||||
continue;
|
||||
TRACE("is_ext_diseq", tout << "p2: " << mk_bounded_pp(p2->get_owner(), m_manager) << "\n";);
|
||||
TRACE("is_ext_diseq", tout << "p2: " << enode_pp(p2, *this) << "\n";);
|
||||
if (p1->get_root() != p2->get_root() && p2->get_decl() == f && p2->get_num_args() == num_args) {
|
||||
unsigned j = 0;
|
||||
for (j = 0; j < num_args; j++) {
|
||||
|
@ -1264,7 +1265,7 @@ namespace smt {
|
|||
break;
|
||||
}
|
||||
if (j == num_args) {
|
||||
TRACE("is_ext_diseq", tout << "found parents: " << mk_bounded_pp(p1->get_owner(), m_manager) << " " << mk_bounded_pp(p2->get_owner(), m_manager) << "\n";);
|
||||
TRACE("is_ext_diseq", tout << "found parents: " << enode_pp(p1, *this) << " " << enode_pp(p2, *this) << "\n";);
|
||||
if (is_ext_diseq(p1, p2, depth - 1))
|
||||
return true;
|
||||
}
|
||||
|
@ -1384,7 +1385,10 @@ namespace smt {
|
|||
SASSERT(m_manager.is_eq(n));
|
||||
expr * lhs = n->get_arg(0);
|
||||
expr * rhs = n->get_arg(1);
|
||||
if (val == l_true) {
|
||||
if (m_manager.is_bool(lhs)) {
|
||||
// no-op
|
||||
}
|
||||
else if (val == l_true) {
|
||||
add_eq(get_enode(lhs), get_enode(rhs), eq_justification(l));
|
||||
}
|
||||
else {
|
||||
|
@ -1770,7 +1774,7 @@ namespace smt {
|
|||
|
||||
void context::set_conflict(const b_justification & js, literal not_l) {
|
||||
if (!inconsistent()) {
|
||||
TRACE("set_conflict", display_literal_verbose(tout, not_l); display(tout, js); );
|
||||
TRACE("set_conflict", display_literal_verbose(tout, not_l); display(tout << " ", js); );
|
||||
m_conflict = js;
|
||||
m_not_l = not_l;
|
||||
}
|
||||
|
@ -3207,7 +3211,7 @@ namespace smt {
|
|||
}
|
||||
else {
|
||||
set_conflict(b_justification(tmp_clause.first), null_literal);
|
||||
}
|
||||
}
|
||||
VERIFY(!resolve_conflict());
|
||||
return l_false;
|
||||
next_clause:
|
||||
|
@ -3266,6 +3270,18 @@ namespace smt {
|
|||
m_assumptions.reset();
|
||||
}
|
||||
|
||||
bool context::should_research(lbool r) {
|
||||
if (r != l_false || m_unsat_core.empty()) {
|
||||
return false;
|
||||
}
|
||||
for (theory* th : m_theory_set) {
|
||||
if (th->should_research(m_unsat_core)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
lbool context::mk_unsat_core(lbool r) {
|
||||
if (r != l_false) return r;
|
||||
SASSERT(inconsistent());
|
||||
|
@ -3353,7 +3369,7 @@ namespace smt {
|
|||
add_theory_assumptions(theory_assumptions);
|
||||
if (!theory_assumptions.empty()) {
|
||||
TRACE("search", tout << "Adding theory assumptions to context" << std::endl;);
|
||||
return check(theory_assumptions.size(), theory_assumptions.c_ptr(), reset_cancel, true);
|
||||
return check(0, nullptr, reset_cancel);
|
||||
}
|
||||
|
||||
internalize_assertions();
|
||||
|
@ -3407,19 +3423,24 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
|
||||
lbool context::check(unsigned num_assumptions, expr * const * assumptions, bool reset_cancel, bool already_did_theory_assumptions) {
|
||||
lbool context::check(unsigned num_assumptions, expr * const * assumptions, bool reset_cancel) {
|
||||
if (!check_preamble(reset_cancel)) return l_undef;
|
||||
SASSERT(at_base_level());
|
||||
setup_context(false);
|
||||
expr_ref_vector asms(m_manager, num_assumptions, assumptions);
|
||||
if (!already_did_theory_assumptions) add_theory_assumptions(asms);
|
||||
// introducing proxies: if (!validate_assumptions(asms)) return l_undef;
|
||||
TRACE("unsat_core_bug", tout << asms << "\n";);
|
||||
internalize_assertions();
|
||||
init_assumptions(asms);
|
||||
TRACE("before_search", display(tout););
|
||||
lbool r = search();
|
||||
r = mk_unsat_core(r);
|
||||
lbool r;
|
||||
do {
|
||||
pop_to_base_lvl();
|
||||
expr_ref_vector asms(m_manager, num_assumptions, assumptions);
|
||||
add_theory_assumptions(asms);
|
||||
// introducing proxies: if (!validate_assumptions(asms)) return l_undef;
|
||||
TRACE("unsat_core_bug", tout << asms << "\n";);
|
||||
internalize_assertions();
|
||||
init_assumptions(asms);
|
||||
TRACE("before_search", display(tout););
|
||||
r = search();
|
||||
r = mk_unsat_core(r);
|
||||
}
|
||||
while (should_research(r));
|
||||
r = check_finalize(r);
|
||||
return r;
|
||||
}
|
||||
|
@ -3428,15 +3449,20 @@ namespace smt {
|
|||
if (!check_preamble(true)) return l_undef;
|
||||
TRACE("before_search", display(tout););
|
||||
setup_context(false);
|
||||
expr_ref_vector asms(cube);
|
||||
add_theory_assumptions(asms);
|
||||
// introducing proxies: if (!validate_assumptions(asms)) return l_undef;
|
||||
for (auto const& clause : clauses) if (!validate_assumptions(clause)) return l_undef;
|
||||
internalize_assertions();
|
||||
init_assumptions(asms);
|
||||
for (auto const& clause : clauses) init_clause(clause);
|
||||
lbool r = search();
|
||||
r = mk_unsat_core(r);
|
||||
lbool r;
|
||||
do {
|
||||
pop_to_base_lvl();
|
||||
expr_ref_vector asms(cube);
|
||||
add_theory_assumptions(asms);
|
||||
// introducing proxies: if (!validate_assumptions(asms)) return l_undef;
|
||||
for (auto const& clause : clauses) if (!validate_assumptions(clause)) return l_undef;
|
||||
internalize_assertions();
|
||||
init_assumptions(asms);
|
||||
for (auto const& clause : clauses) init_clause(clause);
|
||||
r = search();
|
||||
r = mk_unsat_core(r);
|
||||
}
|
||||
while (should_research(r));
|
||||
r = check_finalize(r);
|
||||
return r;
|
||||
}
|
||||
|
@ -3770,7 +3796,7 @@ namespace smt {
|
|||
}
|
||||
|
||||
m_stats.m_num_final_checks++;
|
||||
TRACE("final_check_stats", tout << "m_stats.m_num_final_checks = " << m_stats.m_num_final_checks << "\n";);
|
||||
TRACE("final_check_stats", tout << "m_stats.m_num_final_checks = " << m_stats.m_num_final_checks << "\n";);
|
||||
|
||||
final_check_status ok = m_qmanager->final_check_eh(false);
|
||||
if (ok != FC_DONE)
|
||||
|
@ -4067,7 +4093,7 @@ namespace smt {
|
|||
A literal may have been marked relevant within the scope that gets popped during
|
||||
conflict resolution. In this case, the literal is no longer marked as relevant after
|
||||
the pop. This can cause quantifier instantiation to miss relevant triggers and thereby
|
||||
cause incmpleteness.
|
||||
cause incompleteness.
|
||||
*/
|
||||
void context::record_relevancy(unsigned n, literal const* lits) {
|
||||
m_relevant_conflict_literals.reset();
|
||||
|
@ -4281,7 +4307,7 @@ namespace smt {
|
|||
return true;
|
||||
}
|
||||
|
||||
// the variabe is shared if the equivalence class of n
|
||||
// the variable is shared if the equivalence class of n
|
||||
// contains a parent application.
|
||||
|
||||
theory_var_list * l = n->get_th_var_list();
|
||||
|
@ -4290,7 +4316,7 @@ namespace smt {
|
|||
for (enode * parent : enode::parents(n)) {
|
||||
family_id fid = parent->get_owner()->get_family_id();
|
||||
if (fid != th_id && fid != m_manager.get_basic_family_id()) {
|
||||
TRACE("is_shared", tout << mk_pp(n->get_owner(), m_manager) << "\nis shared because of:\n" << mk_pp(parent->get_owner(), m_manager) << "\n";);
|
||||
TRACE("is_shared", tout << enode_pp(n, *this) << "\nis shared because of:\n" << enode_pp(parent, *this) << "\n";);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -4428,6 +4454,29 @@ namespace smt {
|
|||
m_model->register_decl(f, fi);
|
||||
}
|
||||
}
|
||||
recfun::util u(m);
|
||||
func_decl_ref_vector recfuns = u.get_rec_funs();
|
||||
for (func_decl* f : recfuns) {
|
||||
auto& def = u.get_def(f);
|
||||
expr* rhs = def.get_rhs();
|
||||
if (!rhs) continue;
|
||||
if (f->get_arity() == 0) {
|
||||
m_model->register_decl(f, rhs);
|
||||
continue;
|
||||
}
|
||||
|
||||
func_interp* fi = alloc(func_interp, m, f->get_arity());
|
||||
// reverse argument order so that variable 0 starts at the beginning.
|
||||
expr_ref_vector subst(m);
|
||||
for (unsigned i = 0; i < f->get_arity(); ++i) {
|
||||
subst.push_back(m.mk_var(i, f->get_domain(i)));
|
||||
}
|
||||
var_subst sub(m, true);
|
||||
expr_ref bodyr = sub(rhs, subst.size(), subst.c_ptr());
|
||||
|
||||
fi->set_else(bodyr);
|
||||
m_model->register_decl(f, fi);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue