3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-27 02:45:51 +00:00

working on new solver core

This commit is contained in:
Nikolaj Bjorner 2020-12-30 14:38:35 -08:00
parent f519c58ace
commit 523578e3f6
13 changed files with 224 additions and 81 deletions

View file

@ -23,8 +23,8 @@ Notes:
namespace euf {
enode* egraph::mk_enode(expr* f, unsigned num_args, enode * const* args) {
enode* n = enode::mk(m_region, f, num_args, args);
enode* egraph::mk_enode(expr* f, unsigned generation, unsigned num_args, enode * const* args) {
enode* n = enode::mk(m_region, f, generation, num_args, args);
m_nodes.push_back(n);
m_exprs.push_back(f);
if (is_app(f) && num_args > 0) {
@ -83,10 +83,10 @@ namespace euf {
n->set_update_children();
}
enode* egraph::mk(expr* f, unsigned num_args, enode *const* args) {
enode* egraph::mk(expr* f, unsigned generation, unsigned num_args, enode *const* args) {
SASSERT(!find(f));
force_push();
enode *n = mk_enode(f, num_args, args);
enode *n = mk_enode(f, generation, num_args, args);
SASSERT(n->class_size() == 1);
if (num_args == 0 && m.is_unique_value(f))
n->mark_interpreted();
@ -552,6 +552,7 @@ namespace euf {
void egraph::push_congruence(enode* n1, enode* n2, bool comm) {
SASSERT(is_app(n1->get_expr()));
SASSERT(n1->get_decl() == n2->get_decl());
m_uses_congruence = true;
if (m_used_cc && !comm) {
m_used_cc(to_app(n1->get_expr()), to_app(n2->get_expr()));
}
@ -598,6 +599,7 @@ namespace euf {
void egraph::begin_explain() {
SASSERT(m_todo.empty());
m_uses_congruence = false;
}
void egraph::end_explain() {
@ -672,15 +674,16 @@ namespace euf {
out << " " << p->get_expr_id();
out << "] ";
}
if (n->value() != l_undef) {
if (n->value() != l_undef)
out << "[v" << n->bool_var() << " := " << (n->value() == l_true ? "T":"F") << "] ";
}
if (n->has_th_vars()) {
out << "[t";
for (auto v : enode_th_vars(n))
out << " " << v.get_id() << ":" << v.get_var();
out << "] ";
}
if (n->generation() > 0)
out << "[g " << n->generation() << "] ";
if (n->m_target && m_display_justification)
n->m_justification.display(out << "[j " << n->m_target->get_expr_id() << " ", m_display_justification) << "] ";
out << "\n";
@ -722,7 +725,7 @@ namespace euf {
for (unsigned j = 0; j < n1->num_args(); ++j)
args.push_back(old_expr2new_enode[n1->get_arg(j)->get_expr_id()]);
expr* e2 = tr(e1);
enode* n2 = mk(e2, args.size(), args.c_ptr());
enode* n2 = mk(e2, n1->generation(), args.size(), args.c_ptr());
old_expr2new_enode.setx(e1->get_id(), n2, nullptr);
n2->set_value(n2->value());
n2->m_bool_var = n1->m_bool_var;

View file

@ -164,6 +164,7 @@ namespace euf {
bool_vector m_th_propagates_diseqs;
enode_vector m_todo;
stats m_stats;
bool m_uses_congruence { false };
std::function<void(expr*,expr*,expr*)> m_used_eq;
std::function<void(app*,app*)> m_used_cc;
std::function<void(std::ostream&, void*)> m_display_justification;
@ -180,7 +181,7 @@ namespace euf {
void add_literal(enode* n, bool is_eq);
void undo_eq(enode* r1, enode* n1, unsigned r2_num_parents);
void undo_add_th_var(enode* n, theory_id id);
enode* mk_enode(expr* f, unsigned num_args, enode * const* args);
enode* mk_enode(expr* f, unsigned generation, unsigned num_args, enode * const* args);
void force_push();
void set_conflict(enode* n1, enode* n2, justification j);
void merge(enode* n1, enode* n2, justification j);
@ -217,7 +218,7 @@ namespace euf {
egraph(ast_manager& m);
~egraph();
enode* find(expr* f) const { return m_expr2enode.get(f->get_id(), nullptr); }
enode* mk(expr* f, unsigned n, enode *const* args);
enode* mk(expr* f, unsigned generation, unsigned n, enode *const* args);
enode_vector const& enodes_of(func_decl* f);
void push() { ++m_num_scopes; }
void pop(unsigned num_scopes);
@ -272,6 +273,7 @@ namespace euf {
void begin_explain();
void end_explain();
bool uses_congruence() const { return m_uses_congruence; }
template <typename T>
void explain(ptr_vector<T>& justifications);
template <typename T>

View file

@ -45,17 +45,18 @@ namespace euf {
bool m_commutative{ false };
bool m_update_children{ false };
bool m_interpreted{ false };
bool m_merge_enabled{ true };
bool m_is_equality{ false };
lbool m_value;
unsigned m_bool_var { UINT_MAX };
unsigned m_class_size{ 1 };
unsigned m_table_id{ UINT_MAX };
bool m_merge_enabled{ true };
bool m_is_equality{ false }; // Does the expression represent an equality
lbool m_value; // Assignment by SAT solver for Boolean node
unsigned m_bool_var { UINT_MAX }; // SAT solver variable associated with Boolean node
unsigned m_class_size{ 1 }; // Size of the equivalence class if the enode is the root.
unsigned m_table_id{ UINT_MAX };
unsigned m_generation { 0 }; // Tracks how many quantifier instantiation rounds were needed to generate this enode.
enode_vector m_parents;
enode* m_next{ nullptr };
enode* m_root{ nullptr };
enode* m_target{ nullptr };
enode* m_cg { nullptr };
enode* m_next { nullptr };
enode* m_root { nullptr };
enode* m_target { nullptr };
enode* m_cg { nullptr };
th_var_list m_th_vars;
justification m_justification;
unsigned m_num_args{ 0 };
@ -72,13 +73,14 @@ namespace euf {
return sizeof(enode) + num_args * sizeof(enode*);
}
static enode* mk(region& r, expr* f, unsigned num_args, enode* const* args) {
static enode* mk(region& r, expr* f, unsigned generation, unsigned num_args, enode* const* args) {
SASSERT(num_args <= (is_app(f) ? to_app(f)->get_num_args() : 0));
void* mem = r.allocate(get_enode_size(num_args));
enode* n = new (mem) enode();
n->m_expr = f;
n->m_next = n;
n->m_root = n;
n->m_generation = generation,
n->m_commutative = num_args == 2 && is_app(f) && to_app(f)->get_decl()->is_commutative();
n->m_num_args = num_args;
n->m_merge_enabled = true;
@ -142,9 +144,12 @@ namespace euf {
enode* get_arg(unsigned i) const { SASSERT(i < num_args()); return m_args[i]; }
unsigned hash() const { return m_expr->hash(); }
unsigned get_table_id() const { return m_table_id; }
void set_table_id(unsigned t) { m_table_id = t; }
unsigned generation() const { return m_generation; }
void mark1() { m_mark1 = true; }
void unmark1() { m_mark1 = false; }
bool is_marked1() { return m_mark1; }