mirror of
https://github.com/Z3Prover/z3
synced 2025-08-07 03:31:23 +00:00
experiment with delayed disequalities
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
ee216b5274
commit
ffd4323573
5 changed files with 86 additions and 7 deletions
|
@ -172,7 +172,7 @@ namespace euf {
|
||||||
IF_VERBOSE(0, verbose_stream() << mk_pp(f, m) << " not handled\n");
|
IF_VERBOSE(0, verbose_stream() << mk_pp(f, m) << " not handled\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::init_search() {
|
void solver::init_search() {
|
||||||
TRACE("before_search", s().display(tout););
|
TRACE("before_search", s().display(tout););
|
||||||
m_reason_unknown.clear();
|
m_reason_unknown.clear();
|
||||||
for (auto* s : m_solvers)
|
for (auto* s : m_solvers)
|
||||||
|
|
|
@ -45,10 +45,15 @@ namespace q {
|
||||||
quantifier* q = to_quantifier(e);
|
quantifier* q = to_quantifier(e);
|
||||||
|
|
||||||
if (l.sign() == is_forall(e)) {
|
if (l.sign() == is_forall(e)) {
|
||||||
|
if (m_quantifiers_are_positive && is_forall(e))
|
||||||
|
return;
|
||||||
sat::literal lit = skolemize(q);
|
sat::literal lit = skolemize(q);
|
||||||
add_clause(~l, lit);
|
add_clause(~l, lit);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (m_quantifiers_are_positive && is_exists(e))
|
||||||
|
return;
|
||||||
|
|
||||||
quantifier* q_flat = nullptr;
|
quantifier* q_flat = nullptr;
|
||||||
if (!m_flat.find(q, q_flat)) {
|
if (!m_flat.find(q, q_flat)) {
|
||||||
if (expand(q)) {
|
if (expand(q)) {
|
||||||
|
@ -141,10 +146,37 @@ namespace q {
|
||||||
return mk_literal(body);
|
return mk_literal(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class insert_skolem : public trail {
|
||||||
|
obj_map<quantifier, expr_ref_vector*>& sk;
|
||||||
|
quantifier* q;
|
||||||
|
public:
|
||||||
|
insert_skolem(obj_map<quantifier, expr_ref_vector*>& sk, quantifier* q):
|
||||||
|
sk(sk),
|
||||||
|
q(q)
|
||||||
|
{}
|
||||||
|
void undo() override {
|
||||||
|
dealloc(sk[q]);
|
||||||
|
sk.remove(q);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
sat::literal solver::skolemize(quantifier* q) {
|
sat::literal solver::skolemize(quantifier* q) {
|
||||||
|
expr_ref_vector* sk = nullptr;
|
||||||
std::function<expr* (quantifier*, unsigned)> mk_var = [&](quantifier* q, unsigned i) {
|
std::function<expr* (quantifier*, unsigned)> mk_var = [&](quantifier* q, unsigned i) {
|
||||||
return m.mk_fresh_const(q->get_decl_name(i), q->get_decl_sort(i));
|
expr * t = nullptr;
|
||||||
|
if (sk->size() <= i) {
|
||||||
|
t = m.mk_fresh_const(q->get_decl_name(i), q->get_decl_sort(i));
|
||||||
|
sk->push_back(t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
t = sk->get(i);
|
||||||
|
return t;
|
||||||
};
|
};
|
||||||
|
if (!m_skolems.find(q, sk)) {
|
||||||
|
sk = alloc(expr_ref_vector, m);
|
||||||
|
m_skolems.insert(q, sk);
|
||||||
|
ctx.push(insert_skolem(m_skolems, q));
|
||||||
|
}
|
||||||
return instantiate(q, is_forall(q), mk_var);
|
return instantiate(q, is_forall(q), mk_var);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,8 @@ namespace q {
|
||||||
obj_map<sort, expr*> m_unit_table;
|
obj_map<sort, expr*> m_unit_table;
|
||||||
expr_ref_vector m_expanded;
|
expr_ref_vector m_expanded;
|
||||||
der_rewriter m_der;
|
der_rewriter m_der;
|
||||||
|
bool m_quantifiers_are_positive = false;
|
||||||
|
obj_map<quantifier, expr_ref_vector*> m_skolems;
|
||||||
|
|
||||||
sat::literal instantiate(quantifier* q, bool negate, std::function<expr* (quantifier*, unsigned)>& mk_var);
|
sat::literal instantiate(quantifier* q, bool negate, std::function<expr* (quantifier*, unsigned)>& mk_var);
|
||||||
sat::literal skolemize(quantifier* q);
|
sat::literal skolemize(quantifier* q);
|
||||||
|
|
|
@ -1466,7 +1466,6 @@ namespace smt {
|
||||||
|
|
||||||
template<typename Ext>
|
template<typename Ext>
|
||||||
void theory_arith<Ext>::restart_eh() {
|
void theory_arith<Ext>::restart_eh() {
|
||||||
return;
|
|
||||||
m_arith_eq_adapter.restart_eh();
|
m_arith_eq_adapter.restart_eh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1304,17 +1304,60 @@ public:
|
||||||
TRACE("arith", tout << "eq " << v1 << " == " << v2 << "\n";);
|
TRACE("arith", tout << "eq " << v1 << " == " << v2 << "\n";);
|
||||||
if (!is_int(v1) && !is_real(v1))
|
if (!is_int(v1) && !is_real(v1))
|
||||||
return;
|
return;
|
||||||
m_arith_eq_adapter.new_eq_eh(v1, v2);
|
|
||||||
|
if (true) {
|
||||||
|
enode* n1 = get_enode(v1);
|
||||||
|
enode* n2 = get_enode(v2);
|
||||||
|
lpvar w1 = register_theory_var_in_lar_solver(v1);
|
||||||
|
lpvar w2 = register_theory_var_in_lar_solver(v2);
|
||||||
|
auto cs = lp().add_equality(w1, w2);
|
||||||
|
add_eq_constraint(cs.first, n1, n2);
|
||||||
|
add_eq_constraint(cs.second, n1, n2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_arith_eq_adapter.new_eq_eh(v1, v2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool use_diseqs() const {
|
bool use_diseqs() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svector<std::pair<theory_var, theory_var>> m_diseqs;
|
||||||
|
unsigned m_diseqs_qhead = 0;
|
||||||
|
|
||||||
void new_diseq_eh(theory_var v1, theory_var v2) {
|
void new_diseq_eh(theory_var v1, theory_var v2) {
|
||||||
TRACE("arith", tout << "v" << v1 << " != " << "v" << v2 << "\n";);
|
TRACE("arith", tout << "v" << v1 << " != " << "v" << v2 << "\n";);
|
||||||
++m_stats.m_assert_diseq;
|
++m_stats.m_assert_diseq;
|
||||||
m_arith_eq_adapter.new_diseq_eh(v1, v2);
|
if (false) {
|
||||||
|
if (is_eq(v1, v2)) {
|
||||||
|
m_arith_eq_adapter.new_diseq_eh(v1, v2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_diseqs.push_back({v1, v2});
|
||||||
|
ctx().push_trail(push_back_vector(m_diseqs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_arith_eq_adapter.new_diseq_eh(v1, v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool delayed_diseqs() {
|
||||||
|
if (m_diseqs_qhead == m_diseqs.size())
|
||||||
|
return false;
|
||||||
|
verbose_stream() << m_diseqs_qhead << " out of " << m_diseqs.size() << "\n";
|
||||||
|
ctx().push_trail(value_trail(m_diseqs_qhead));
|
||||||
|
bool has_eq = false;
|
||||||
|
while (m_diseqs_qhead < m_diseqs.size()) {
|
||||||
|
auto [v1,v2] = m_diseqs[m_diseqs_qhead];
|
||||||
|
if (is_eq(v1, v2)) {
|
||||||
|
verbose_stream() << "bad diseq " << m_diseqs_qhead << "\n";
|
||||||
|
m_arith_eq_adapter.new_diseq_eh(v1, v2);
|
||||||
|
has_eq = true;
|
||||||
|
}
|
||||||
|
++m_diseqs_qhead;
|
||||||
|
}
|
||||||
|
return has_eq;
|
||||||
}
|
}
|
||||||
|
|
||||||
void apply_sort_cnstr(enode* n, sort*) {
|
void apply_sort_cnstr(enode* n, sort*) {
|
||||||
|
@ -1361,7 +1404,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void restart_eh() {
|
void restart_eh() {
|
||||||
return;
|
|
||||||
m_arith_eq_adapter.restart_eh();
|
m_arith_eq_adapter.restart_eh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1800,6 +1842,10 @@ public:
|
||||||
TRACE("arith", display(tout););
|
TRACE("arith", display(tout););
|
||||||
random_update();
|
random_update();
|
||||||
m_model_eqs.reset();
|
m_model_eqs.reset();
|
||||||
|
|
||||||
|
if (delayed_diseqs())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
|
||||||
theory_var sz = static_cast<theory_var>(th.get_num_vars());
|
theory_var sz = static_cast<theory_var>(th.get_num_vars());
|
||||||
unsigned old_sz = m_assume_eq_candidates.size();
|
unsigned old_sz = m_assume_eq_candidates.size();
|
||||||
|
@ -1943,7 +1989,7 @@ public:
|
||||||
|
|
||||||
final_check_status final_check_eh() {
|
final_check_status final_check_eh() {
|
||||||
|
|
||||||
// verbose_stream() << "final " << ctx().get_scope_level() << " " << ctx().assigned_literals().size() << "\n";
|
// verbose_stream() << "final " << ctx().get_scope_level() << " " << ctx().assigned_literals().size() << "\n";
|
||||||
//ctx().display(verbose_stream());
|
//ctx().display(verbose_stream());
|
||||||
//exit(0);
|
//exit(0);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue