3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-20 21:03:39 +00:00

checkpoint

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2012-11-01 13:28:10 -07:00
parent ef0ee9a0c4
commit c096fb534b
4 changed files with 465 additions and 320 deletions

View file

@ -139,6 +139,10 @@ bool expr_substitution::find(expr * c, expr * & def, proof * & def_pr, expr_depe
return false; return false;
} }
bool expr_substitution::contains(expr * s) {
return m_subst.contains(s);
}
void expr_substitution::reset() { void expr_substitution::reset() {
dec_ref_map_key_values(m_manager, m_subst); dec_ref_map_key_values(m_manager, m_subst);
if (proofs_enabled()) if (proofs_enabled())

View file

@ -47,6 +47,7 @@ public:
void erase(expr * s); void erase(expr * s);
bool find(expr * s, expr * & def, proof * & def_pr); bool find(expr * s, expr * & def, proof * & def_pr);
bool find(expr * s, expr * & def, proof * & def_pr, expr_dependency * & def_dep); bool find(expr * s, expr * & def, proof * & def_pr, expr_dependency * & def_dep);
bool contains(expr * s);
void reset(); void reset();
void cleanup(); void cleanup();
}; };

View file

@ -21,35 +21,102 @@ Revision History:
#include"ast_smt2_pp.h" #include"ast_smt2_pp.h"
#include"ref_util.h" #include"ref_util.h"
#include"expr_replacer.h" #include"expr_replacer.h"
#include"model.h"
#include"expr_substitution.h"
assertion_stack::assertion_stack(ast_manager & m, bool models_enabled, bool core_enabled): struct assertion_stack::imp {
ast_manager & m_manager;
bool m_models_enabled; // model generation is enabled.
bool m_proofs_enabled; // proof production is enabled. m_manager.proofs_enabled() must be true if m_proofs_enabled == true
bool m_core_enabled; // unsat core extraction is enabled.
bool m_inconsistent;
ptr_vector<expr> m_forms;
ptr_vector<proof> m_proofs;
ptr_vector<expr_dependency> m_deps;
unsigned m_form_qhead; // position of first uncommitted assertion
unsigned m_mc_qhead;
// Set of declarations that can't be eliminated
obj_hashtable<func_decl> m_forbidden_set;
func_decl_ref_vector m_forbidden;
// Limited model converter support, it supports only extensions and filters.
// It should be viewed as combination of extension_model_converter and
// filter_model_converter for goals.
expr_substitution m_csubst; // substitution for eliminated constants
// Model converter is just two sequences: func_decl and tag.
// Tag 0 (extension) func_decl was eliminated, and its definition is in m_vsubst or m_fsubst.
// Tag 1 (filter) func_decl was introduced by tactic, and must be removed from model.
ptr_vector<func_decl> m_mc;
char_vector m_mc_tag;
struct scope {
unsigned m_forms_lim;
unsigned m_forbidden_lim;
unsigned m_mc_lim;
bool m_inconsistent_old;
};
svector<scope> m_scopes;
imp(ast_manager & m, bool models_enabled, bool core_enabled):
m_manager(m), m_manager(m),
m_forbidden(m), m_forbidden(m),
m_csubst(m, core_enabled) { m_csubst(m, core_enabled) {
init(m.proofs_enabled(), models_enabled, core_enabled); init(m.proofs_enabled(), models_enabled, core_enabled);
} }
assertion_stack::assertion_stack(ast_manager & m, bool proofs_enabled, bool models_enabled, bool core_enabled): imp(ast_manager & m, bool proofs_enabled, bool models_enabled, bool core_enabled):
m_manager(m), m_manager(m),
m_forbidden(m), m_forbidden(m),
m_csubst(m, core_enabled, proofs_enabled) { m_csubst(m, core_enabled, proofs_enabled) {
init(proofs_enabled, models_enabled, core_enabled); init(proofs_enabled, models_enabled, core_enabled);
} }
void assertion_stack::init(bool proofs_enabled, bool models_enabled, bool core_enabled) { void init(bool proofs_enabled, bool models_enabled, bool core_enabled) {
m_ref_count = 0;
m_models_enabled = models_enabled; m_models_enabled = models_enabled;
m_proofs_enabled = proofs_enabled; m_proofs_enabled = proofs_enabled;
m_core_enabled = core_enabled; m_core_enabled = core_enabled;
m_inconsistent = false; m_inconsistent = false;
m_form_qhead = 0; m_form_qhead = 0;
} }
assertion_stack::~assertion_stack() { ~imp() {
reset(); reset();
} }
void assertion_stack::reset() { ast_manager & m() const { return m_manager; }
bool models_enabled() const { return m_models_enabled; }
bool proofs_enabled() const { return m_proofs_enabled; }
bool unsat_core_enabled() const { return m_core_enabled; }
bool inconsistent() const { return m_inconsistent; }
unsigned size() const { return m_forms.size(); }
unsigned qhead() const { return m_form_qhead; }
expr * form(unsigned i) const { return m_forms[i]; }
proof * pr(unsigned i) const {
if (proofs_enabled())
return m_proofs[i];
else
return 0;
}
expr_dependency * dep(unsigned i) const {
if (unsat_core_enabled())
return m_deps[i];
else
return 0;
}
void reset() {
m_inconsistent = false; m_inconsistent = false;
m_form_qhead = 0; m_form_qhead = 0;
m_mc_qhead = 0; m_mc_qhead = 0;
@ -62,9 +129,9 @@ void assertion_stack::reset() {
m_mc_tag.reset(); m_mc_tag.reset();
m_csubst.reset(); m_csubst.reset();
m_scopes.reset(); m_scopes.reset();
} }
void assertion_stack::expand(expr * f, proof * pr, expr_dependency * dep, expr_ref & new_f, proof_ref & new_pr, expr_dependency_ref & new_dep) { void expand(expr * f, proof * pr, expr_dependency * dep, expr_ref & new_f, proof_ref & new_pr, expr_dependency_ref & new_dep) {
scoped_ptr<expr_replacer> r = mk_default_expr_replacer(m()); scoped_ptr<expr_replacer> r = mk_default_expr_replacer(m());
(*r)(f, new_f, new_pr, new_dep); (*r)(f, new_f, new_pr, new_dep);
// new_pr is a proof for f == new_f // new_pr is a proof for f == new_f
@ -75,9 +142,9 @@ void assertion_stack::expand(expr * f, proof * pr, expr_dependency * dep, expr_r
if (unsat_core_enabled()) { if (unsat_core_enabled()) {
new_dep = m().mk_join(dep, new_dep); new_dep = m().mk_join(dep, new_dep);
} }
} }
void assertion_stack::push_back(expr * f, proof * pr, expr_dependency * d) { void push_back(expr * f, proof * pr, expr_dependency * d) {
if (m().is_true(f)) if (m().is_true(f))
return; return;
if (m().is_false(f)) { if (m().is_false(f)) {
@ -96,9 +163,9 @@ void assertion_stack::push_back(expr * f, proof * pr, expr_dependency * d) {
m().inc_ref(d); m().inc_ref(d);
m_deps.push_back(d); m_deps.push_back(d);
} }
} }
void assertion_stack::quick_process(bool save_first, expr * & f, expr_dependency * d) { void quick_process(bool save_first, expr * & f, expr_dependency * d) {
if (!m().is_and(f) && !(m().is_not(f) && m().is_or(to_app(f)->get_arg(0)))) { if (!m().is_and(f) && !(m().is_not(f) && m().is_or(to_app(f)->get_arg(0)))) {
if (!save_first) { if (!save_first) {
push_back(f, 0, d); push_back(f, 0, d);
@ -146,18 +213,18 @@ void assertion_stack::quick_process(bool save_first, expr * & f, expr_dependency
} }
} }
} }
} }
void assertion_stack::process_and(bool save_first, app * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr) { void process_and(bool save_first, app * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr) {
unsigned num = f->get_num_args(); unsigned num = f->get_num_args();
for (unsigned i = 0; i < num; i++) { for (unsigned i = 0; i < num; i++) {
if (m_inconsistent) if (m_inconsistent)
return; return;
slow_process(save_first && i == 0, f->get_arg(i), m().mk_and_elim(pr, i), d, out_f, out_pr); slow_process(save_first && i == 0, f->get_arg(i), m().mk_and_elim(pr, i), d, out_f, out_pr);
} }
} }
void assertion_stack::process_not_or(bool save_first, app * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr) { void process_not_or(bool save_first, app * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr) {
unsigned num = f->get_num_args(); unsigned num = f->get_num_args();
for (unsigned i = 0; i < num; i++) { for (unsigned i = 0; i < num; i++) {
if (m_inconsistent) if (m_inconsistent)
@ -173,9 +240,9 @@ void assertion_stack::process_not_or(bool save_first, app * f, proof * pr, expr_
slow_process(save_first && i == 0, not_child, m().mk_not_or_elim(pr, i), d, out_f, out_pr); slow_process(save_first && i == 0, not_child, m().mk_not_or_elim(pr, i), d, out_f, out_pr);
} }
} }
} }
void assertion_stack::slow_process(bool save_first, expr * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr) { void slow_process(bool save_first, expr * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr) {
if (m().is_and(f)) if (m().is_and(f))
process_and(save_first, to_app(f), pr, d, out_f, out_pr); process_and(save_first, to_app(f), pr, d, out_f, out_pr);
else if (m().is_not(f) && m().is_or(to_app(f)->get_arg(0))) else if (m().is_not(f) && m().is_or(to_app(f)->get_arg(0)))
@ -187,15 +254,15 @@ void assertion_stack::slow_process(bool save_first, expr * f, proof * pr, expr_d
else { else {
push_back(f, pr, d); push_back(f, pr, d);
} }
} }
void assertion_stack::slow_process(expr * f, proof * pr, expr_dependency * d) { void slow_process(expr * f, proof * pr, expr_dependency * d) {
expr_ref out_f(m()); expr_ref out_f(m());
proof_ref out_pr(m()); proof_ref out_pr(m());
slow_process(false, f, pr, d, out_f, out_pr); slow_process(false, f, pr, d, out_f, out_pr);
} }
void assertion_stack::assert_expr(expr * f, proof * pr, expr_dependency * d) { void assert_expr(expr * f, proof * pr, expr_dependency * d) {
SASSERT(proofs_enabled() == (pr != 0 && !m().is_undef_proof(pr))); SASSERT(proofs_enabled() == (pr != 0 && !m().is_undef_proof(pr)));
if (m_inconsistent) if (m_inconsistent)
return; return;
@ -205,14 +272,9 @@ void assertion_stack::assert_expr(expr * f, proof * pr, expr_dependency * d) {
slow_process(f, pr, d); slow_process(f, pr, d);
else else
quick_process(false, f, d); quick_process(false, f, d);
} }
#ifdef Z3DEBUG void update(unsigned i, expr * f, proof * pr, expr_dependency * d) {
// bool assertion_stack::is_expanded(expr * f) {
// }
#endif
void assertion_stack::update(unsigned i, expr * f, proof * pr, expr_dependency * d) {
SASSERT(i >= m_form_qhead); SASSERT(i >= m_form_qhead);
SASSERT(proofs_enabled() == (pr != 0 && !m().is_undef_proof(pr))); SASSERT(proofs_enabled() == (pr != 0 && !m().is_undef_proof(pr)));
if (m_inconsistent) if (m_inconsistent)
@ -261,9 +323,9 @@ void assertion_stack::update(unsigned i, expr * f, proof * pr, expr_dependency *
} }
} }
} }
} }
void assertion_stack::expand_and_update(unsigned i, expr * f, proof * pr, expr_dependency * d) { void expand_and_update(unsigned i, expr * f, proof * pr, expr_dependency * d) {
SASSERT(i >= m_form_qhead); SASSERT(i >= m_form_qhead);
SASSERT(proofs_enabled() == (pr != 0 && !m().is_undef_proof(pr))); SASSERT(proofs_enabled() == (pr != 0 && !m().is_undef_proof(pr)));
if (m_inconsistent) if (m_inconsistent)
@ -271,9 +333,9 @@ void assertion_stack::expand_and_update(unsigned i, expr * f, proof * pr, expr_d
expr_ref new_f(m()); proof_ref new_pr(m()); expr_dependency_ref new_d(m()); expr_ref new_f(m()); proof_ref new_pr(m()); expr_dependency_ref new_d(m());
expand(f, pr, d, new_f, new_pr, new_d); expand(f, pr, d, new_f, new_pr, new_d);
update(i, new_f, new_pr, new_d); update(i, new_f, new_pr, new_d);
} }
void assertion_stack::push() { void push() {
commit(); commit();
m_scopes.push_back(scope()); m_scopes.push_back(scope());
scope & s = m_scopes.back(); scope & s = m_scopes.back();
@ -281,31 +343,45 @@ void assertion_stack::push() {
s.m_forbidden_lim = m_forbidden.size(); s.m_forbidden_lim = m_forbidden.size();
s.m_mc_lim = m_mc.size(); s.m_mc_lim = m_mc.size();
s.m_inconsistent_old = m_inconsistent; s.m_inconsistent_old = m_inconsistent;
} }
void assertion_stack::pop(unsigned num_scopes) { void pop(unsigned num_scopes) {
} }
void assertion_stack::commit() { void commit() {
} }
unsigned scope_lvl() const {
return m_scopes.size();
}
bool is_forbidden(func_decl * f) const {
return m_forbidden_set.contains(f);
}
#define MC_TAG_EXTENSION 0 #define MC_TAG_EXTENSION 0
#define MC_TAG_FILTER 1 #define MC_TAG_FILTER 1
void assertion_stack::add_filter(func_decl * f) { void add_filter(func_decl * f) {
m().inc_ref(f); m().inc_ref(f);
m_mc.push_back(f); m_mc.push_back(f);
m_mc_tag.push_back(MC_TAG_FILTER); m_mc_tag.push_back(MC_TAG_FILTER);
} }
void assertion_stack::add_definition(app * c, expr * def, proof * pr, expr_dependency * dep) { void add_definition(app * c, expr * def, proof * pr, expr_dependency * dep) {
SASSERT(c->get_num_args() == 0);
SASSERT(!m_csubst.contains(c));
m_csubst.insert(c, def, pr, dep);
func_decl * d = c->get_decl();
m().inc_ref(d);
m_mc.push_back(d);
m_mc_tag.push_back(MC_TAG_EXTENSION);
}
} void convert(model_ref & m) {
}
void assertion_stack::convert(model_ref & m) { void display(std::ostream & out) const {
}
void assertion_stack::display(std::ostream & out) const {
out << "(assertion-stack"; out << "(assertion-stack";
unsigned sz = size(); unsigned sz = size();
for (unsigned i = 0; i < sz; i++) { for (unsigned i = 0; i < sz; i++) {
@ -315,9 +391,9 @@ void assertion_stack::display(std::ostream & out) const {
out << mk_ismt2_pp(form(i), m(), 2); out << mk_ismt2_pp(form(i), m(), 2);
} }
out << ")" << std::endl; out << ")" << std::endl;
} }
bool assertion_stack::is_well_sorted() const { bool is_well_sorted() const {
unsigned sz = size(); unsigned sz = size();
for (unsigned i = 0; i < sz; i++) { for (unsigned i = 0; i < sz; i++) {
expr * t = form(i); expr * t = form(i);
@ -325,4 +401,118 @@ bool assertion_stack::is_well_sorted() const {
return false; return false;
} }
return true; return true;
}
};
assertion_stack::assertion_stack(ast_manager & m, bool models_enabled, bool core_enabled) {
m_imp = alloc(imp, m, models_enabled, core_enabled);
}
assertion_stack::assertion_stack(ast_manager & m, bool proofs_enabled, bool models_enabled, bool core_enabled) {
m_imp = alloc(imp, m, proofs_enabled, models_enabled, core_enabled);
}
assertion_stack::~assertion_stack() {
dealloc(m_imp);
}
void assertion_stack::reset() {
m_imp->reset();
}
ast_manager & assertion_stack::m() const {
return m_imp->m();
}
bool assertion_stack::models_enabled() const {
return m_imp->models_enabled();
}
bool assertion_stack::proofs_enabled() const {
return m_imp->proofs_enabled();
}
bool assertion_stack::unsat_core_enabled() const {
return m_imp->unsat_core_enabled();
}
bool assertion_stack::inconsistent() const {
return m_imp->inconsistent();
}
unsigned assertion_stack::size() const {
return m_imp->size();
}
unsigned assertion_stack::qhead() const {
return m_imp->qhead();
}
expr * assertion_stack::form(unsigned i) const {
return m_imp->form(i);
}
proof * assertion_stack::pr(unsigned i) const {
return m_imp->pr(i);
}
expr_dependency * assertion_stack::dep(unsigned i) const {
return m_imp->dep(i);
}
void assertion_stack::assert_expr(expr * f, proof * pr, expr_dependency * d) {
return m_imp->assert_expr(f, pr, d);
}
void assertion_stack::assert_expr(expr * f) {
assert_expr(f, proofs_enabled() ? m().mk_asserted(f) : 0, 0);
}
void assertion_stack::update(unsigned i, expr * f, proof * pr, expr_dependency * d) {
m_imp->update(i, f, pr, d);
}
void assertion_stack::expand_and_update(unsigned i, expr * f, proof * pr, expr_dependency * d) {
m_imp->expand_and_update(i, f, pr, d);
}
void assertion_stack::commit() {
m_imp->commit();
}
void assertion_stack::push() {
m_imp->push();
}
void assertion_stack::pop(unsigned num_scopes) {
m_imp->pop(num_scopes);
}
unsigned assertion_stack::scope_lvl() const {
return m_imp->scope_lvl();
}
bool assertion_stack::is_well_sorted() const {
return m_imp->is_well_sorted();
}
bool assertion_stack::is_forbidden(func_decl * f) const {
return m_imp->is_forbidden(f);
}
void assertion_stack::add_filter(func_decl * f) {
m_imp->add_filter(f);
}
void assertion_stack::add_definition(app * c, expr * def, proof * pr, expr_dependency * dep) {
m_imp->add_definition(c, def, pr, dep);
}
void assertion_stack::convert(model_ref & m) {
m_imp->convert(m);
}
void assertion_stack::display(std::ostream & out) const {
m_imp->display(out);
} }

View file

@ -41,54 +41,10 @@ Revision History:
#include"ast.h" #include"ast.h"
#include"model.h" #include"model.h"
#include"expr_substitution.h"
class assertion_stack { class assertion_stack {
ast_manager & m_manager; struct imp;
unsigned m_ref_count; imp * m_imp;
bool m_models_enabled; // model generation is enabled.
bool m_proofs_enabled; // proof production is enabled. m_manager.proofs_enabled() must be true if m_proofs_enabled == true
bool m_core_enabled; // unsat core extraction is enabled.
bool m_inconsistent;
ptr_vector<expr> m_forms;
ptr_vector<proof> m_proofs;
ptr_vector<expr_dependency> m_deps;
unsigned m_form_qhead; // position of first uncommitted assertion
unsigned m_mc_qhead;
// Set of declarations that can't be eliminated
obj_hashtable<func_decl> m_forbidden_set;
func_decl_ref_vector m_forbidden;
// Limited model converter support, it supports only extensions and filters.
// It should be viewed as combination of extension_model_converter and
// filter_model_converter for goals.
expr_substitution m_csubst; // substitution for eliminated constants
// Model converter is just two sequences: func_decl and tag.
// Tag 0 (extension) func_decl was eliminated, and its definition is in m_vsubst or m_fsubst.
// Tag 1 (filter) func_decl was introduced by tactic, and must be removed from model.
ptr_vector<func_decl> m_mc;
char_vector m_mc_tag;
struct scope {
unsigned m_forms_lim;
unsigned m_forbidden_lim;
unsigned m_mc_lim;
bool m_inconsistent_old;
};
svector<scope> m_scopes;
void init(bool proofs_enabled, bool models_enabled, bool core_enabled);
void expand(expr * f, proof * pr, expr_dependency * dep, expr_ref & new_f, proof_ref & new_pr, expr_dependency_ref & new_dep);
void push_back(expr * f, proof * pr, expr_dependency * d);
void quick_process(bool save_first, expr * & f, expr_dependency * d);
void process_and(bool save_first, app * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr);
void process_not_or(bool save_first, app * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr);
void slow_process(bool save_first, expr * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr);
void slow_process(expr * f, proof * pr, expr_dependency * d);
public: public:
assertion_stack(ast_manager & m, bool models_enabled = true, bool core_enabled = true); assertion_stack(ast_manager & m, bool models_enabled = true, bool core_enabled = true);
assertion_stack(ast_manager & m, bool proofs_enabled, bool models_enabled, bool core_enabled); assertion_stack(ast_manager & m, bool proofs_enabled, bool models_enabled, bool core_enabled);
@ -96,42 +52,36 @@ public:
void reset(); void reset();
void inc_ref() { ++m_ref_count; } ast_manager & m() const;
void dec_ref() { --m_ref_count; if (m_ref_count == 0) dealloc(this); }
ast_manager & m() const { return m_manager; } bool models_enabled() const;
bool proofs_enabled() const;
bool unsat_core_enabled() const;
bool inconsistent() const;
bool models_enabled() const { return m_models_enabled; } unsigned size() const;
bool proofs_enabled() const { return m_proofs_enabled; } unsigned qhead() const;
bool unsat_core_enabled() const { return m_core_enabled; } expr * form(unsigned i) const;
bool inconsistent() const { return m_inconsistent; } proof * pr(unsigned i) const;
expr_dependency * dep(unsigned i) const;
unsigned size() const { return m_forms.size(); }
unsigned qhead() const { return m_form_qhead; }
expr * form(unsigned i) const { return m_forms[i]; }
proof * pr(unsigned i) const { return proofs_enabled() ? static_cast<proof*>(m_proofs[i]) : 0; }
expr_dependency * dep(unsigned i) const { return unsat_core_enabled() ? m_deps[i] : 0; }
void assert_expr(expr * f, proof * pr, expr_dependency * d); void assert_expr(expr * f, proof * pr, expr_dependency * d);
void assert_expr(expr * f) { void assert_expr(expr * f);
assert_expr(f, proofs_enabled() ? m().mk_asserted(f) : 0, 0);
}
void update(unsigned i, expr * f, proof * pr = 0, expr_dependency * dep = 0); void update(unsigned i, expr * f, proof * pr = 0, expr_dependency * dep = 0);
void expand_and_update(unsigned i, expr * f, proof * pr = 0, expr_dependency * d = 0); void expand_and_update(unsigned i, expr * f, proof * pr = 0, expr_dependency * d = 0);
void commit(); void commit();
void push(); void push();
void pop(unsigned num_scopes); void pop(unsigned num_scopes);
unsigned scope_lvl() const { return m_scopes.size(); } unsigned scope_lvl() const;
bool is_well_sorted() const; bool is_well_sorted() const;
bool is_forbidden(func_decl * f) const { return m_forbidden_set.contains(f); } bool is_forbidden(func_decl * f) const;
void add_filter(func_decl * f); void add_filter(func_decl * f);
void add_definition(app * c, expr * def, proof * pr, expr_dependency * dep); void add_definition(app * c, expr * def, proof * pr, expr_dependency * dep);
void convert(model_ref & m); void convert(model_ref & m);
void display(std::ostream & out) const; void display(std::ostream & out) const;
}; };