mirror of
https://github.com/Z3Prover/z3
synced 2025-04-29 20:05:51 +00:00
add priority queue to instantiation
This commit is contained in:
parent
22b0c3aa70
commit
46f754c43d
19 changed files with 1138 additions and 541 deletions
|
@ -17,12 +17,15 @@ Author:
|
|||
#pragma once
|
||||
|
||||
#include "util/nat_set.h"
|
||||
#include "util/dlist.h"
|
||||
#include "ast/quantifier_stat.h"
|
||||
#include "ast/pattern/pattern_inference.h"
|
||||
#include "solver/solver.h"
|
||||
#include "sat/smt/sat_th.h"
|
||||
#include "sat/smt/q_mam.h"
|
||||
#include "sat/smt/q_clause.h"
|
||||
#include "sat/smt/q_fingerprint.h"
|
||||
#include "sat/smt/q_queue.h"
|
||||
#include "sat/smt/q_eval.h"
|
||||
|
||||
namespace euf {
|
||||
class solver;
|
||||
|
@ -35,6 +38,9 @@ namespace q {
|
|||
class ematch {
|
||||
struct stats {
|
||||
unsigned m_num_instantiations;
|
||||
unsigned m_num_propagations;
|
||||
unsigned m_num_conflicts;
|
||||
unsigned m_num_redundant;
|
||||
|
||||
stats() { reset(); }
|
||||
|
||||
|
@ -43,95 +49,27 @@ namespace q {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
struct lit {
|
||||
expr_ref lhs;
|
||||
expr_ref rhs;
|
||||
bool sign;
|
||||
lit(expr_ref const& lhs, expr_ref const& rhs, bool sign):
|
||||
lhs(lhs), rhs(rhs), sign(sign) {}
|
||||
std::ostream& display(std::ostream& out) const;
|
||||
};
|
||||
|
||||
struct remove_binding;
|
||||
struct insert_binding;
|
||||
|
||||
struct binding : public dll_base<binding> {
|
||||
unsigned m_max_generation;
|
||||
unsigned m_min_top_generation;
|
||||
unsigned m_max_top_generation;
|
||||
euf::enode* m_nodes[0];
|
||||
|
||||
binding(unsigned max_generation, unsigned min_top, unsigned max_top):
|
||||
m_max_generation(max_generation),
|
||||
m_min_top_generation(min_top),
|
||||
m_max_top_generation(max_top) {}
|
||||
|
||||
euf::enode* const* nodes() { return m_nodes; }
|
||||
|
||||
};
|
||||
|
||||
binding* alloc_binding(unsigned n, unsigned max_generation, unsigned min_top, unsigned max_top);
|
||||
binding* alloc_binding(unsigned n, app* pat, unsigned max_generation, unsigned min_top, unsigned max_top);
|
||||
void add_binding(clause& c, app* pat, euf::enode* const* _binding, unsigned max_generation, unsigned min_top, unsigned max_top);
|
||||
|
||||
struct clause {
|
||||
vector<lit> m_lits;
|
||||
quantifier_ref m_q;
|
||||
sat::literal m_literal;
|
||||
q::quantifier_stat* m_stat { nullptr };
|
||||
binding* m_bindings { nullptr };
|
||||
|
||||
clause(ast_manager& m): m_q(m) {}
|
||||
|
||||
void add_binding(ematch& em, euf::enode* const* b, unsigned max_generation, unsigned min_top, unsigned max_top);
|
||||
std::ostream& display(euf::solver& ctx, std::ostream& out) const;
|
||||
lit const& operator[](unsigned i) const { return m_lits[i]; }
|
||||
lit& operator[](unsigned i) { return m_lits[i]; }
|
||||
unsigned size() const { return m_lits.size(); }
|
||||
unsigned num_decls() const { return m_q->get_num_decls(); }
|
||||
};
|
||||
|
||||
struct fingerprint {
|
||||
clause& c;
|
||||
binding& b;
|
||||
unsigned max_generation;
|
||||
fingerprint(clause& c, binding& b, unsigned max_generation):
|
||||
c(c), b(b), max_generation(max_generation) {}
|
||||
unsigned hash() const;
|
||||
bool eq(fingerprint const& other) const;
|
||||
};
|
||||
|
||||
struct fingerprint_hash_proc {
|
||||
bool operator()(fingerprint const* f) const { return f->hash(); }
|
||||
};
|
||||
struct fingerprint_eq_proc {
|
||||
bool operator()(fingerprint const* a, fingerprint const* b) const { return a->eq(*b); }
|
||||
};
|
||||
typedef ptr_hashtable<fingerprint, fingerprint_hash_proc, fingerprint_eq_proc> fingerprints;
|
||||
|
||||
struct justification {
|
||||
expr* m_lhs, *m_rhs;
|
||||
bool m_sign;
|
||||
clause& m_clause;
|
||||
euf::enode* const* m_binding;
|
||||
justification(lit const& l, clause& c, euf::enode* const* b):
|
||||
m_lhs(l.lhs), m_rhs(l.rhs), m_sign(l.sign), m_clause(c), m_binding(b) {}
|
||||
sat::ext_constraint_idx to_index() const {
|
||||
return sat::constraint_base::mem2base(this);
|
||||
}
|
||||
static justification& from_index(size_t idx) {
|
||||
return *reinterpret_cast<justification*>(sat::constraint_base::from_index(idx)->mem());
|
||||
}
|
||||
static size_t get_obj_size() { return sat::constraint_base::obj_size(sizeof(justification)); }
|
||||
};
|
||||
sat::ext_justification_idx mk_justification(unsigned idx, clause& c, euf::enode* const* b);
|
||||
|
||||
struct pop_clause;
|
||||
struct scoped_mark_reset;
|
||||
|
||||
|
||||
euf::solver& ctx;
|
||||
solver& m_qs;
|
||||
ast_manager& m;
|
||||
q::quantifier_stat_gen m_qstat_gen;
|
||||
eval m_eval;
|
||||
quantifier_stat_gen m_qstat_gen;
|
||||
fingerprints m_fingerprints;
|
||||
scoped_ptr<binding> m_tmp_binding;
|
||||
unsigned m_tmp_binding_capacity { 0 };
|
||||
queue m_inst_queue;
|
||||
pattern_inference_rw m_infer_patterns;
|
||||
scoped_ptr<q::mam> m_mam, m_lazy_mam;
|
||||
ptr_vector<clause> m_clauses;
|
||||
|
@ -139,47 +77,35 @@ namespace q {
|
|||
vector<unsigned_vector> m_watch; // expr_id -> clause-index*
|
||||
stats m_stats;
|
||||
expr_fast_mark1 m_mark;
|
||||
unsigned m_generation_propagation_threshold{ 3 };
|
||||
|
||||
struct scoped_mark_reset;
|
||||
|
||||
nat_set m_node_in_queue;
|
||||
nat_set m_clause_in_queue;
|
||||
unsigned m_qhead { 0 };
|
||||
unsigned_vector m_queue;
|
||||
unsigned_vector m_clause_queue;
|
||||
|
||||
ptr_vector<app> m_ground;
|
||||
void ensure_ground_enodes(expr* e);
|
||||
void ensure_ground_enodes(clause const& c);
|
||||
|
||||
// compare s, t modulo sign under binding
|
||||
lbool compare(unsigned n, euf::enode* const* binding, expr* s, expr* t);
|
||||
lbool compare_rec(unsigned n, euf::enode* const* binding, expr* s, expr* t);
|
||||
euf::enode_vector m_eval, m_indirect_nodes;
|
||||
euf::enode* eval(unsigned n, euf::enode* const* binding, expr* e);
|
||||
|
||||
bool propagate(euf::enode* const* binding, clause& c);
|
||||
void instantiate(binding& b, clause& c);
|
||||
sat::literal instantiate(clause& c, euf::enode* const* binding, lit const& l);
|
||||
|
||||
// register as callback into egraph.
|
||||
void on_merge(euf::enode* root, euf::enode* other);
|
||||
void insert_to_propagate(unsigned node_id);
|
||||
void insert_clause_in_queue(unsigned idx);
|
||||
|
||||
void add_watch(euf::enode* root, unsigned clause_idx);
|
||||
void init_watch(expr* e, unsigned clause_idx);
|
||||
void init_watch(clause& c, unsigned idx);
|
||||
|
||||
// extract explanation
|
||||
ptr_vector<size_t> m_explain;
|
||||
void explain(clause& c, unsigned literal_idx, euf::enode* const* binding);
|
||||
void explain_eq(unsigned n, euf::enode* const* binding, expr* s, expr* t);
|
||||
void explain_diseq(unsigned n, euf::enode* const* binding, expr* s, expr* t);
|
||||
void init_watch(clause& c);
|
||||
|
||||
void attach_ground_pattern_terms(expr* pat);
|
||||
clause* clausify(quantifier* q);
|
||||
|
||||
fingerprint* add_fingerprint(clause& c, binding& b, unsigned max_generation);
|
||||
|
||||
void set_tmp_binding(fingerprint& fp);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -187,7 +113,7 @@ namespace q {
|
|||
|
||||
bool operator()();
|
||||
|
||||
bool propagate();
|
||||
bool propagate(bool flush);
|
||||
|
||||
void init_search();
|
||||
|
||||
|
@ -200,6 +126,11 @@ namespace q {
|
|||
// callback from mam
|
||||
void on_binding(quantifier* q, app* pat, euf::enode* const* binding, unsigned max_generation, unsigned min_gen, unsigned max_gen);
|
||||
|
||||
// callback from queue
|
||||
lbool eval(euf::enode* const* binding, clause& c) { return m_eval(binding, c); }
|
||||
void add_instantiation(clause& c, binding& b, sat::literal lit);
|
||||
bool propagate(euf::enode* const* binding, unsigned max_generation, clause& c);
|
||||
|
||||
std::ostream& display(std::ostream& out) const;
|
||||
std::ostream& display_constraint(std::ostream& out, sat::ext_constraint_idx idx) const;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue