mirror of
https://github.com/Z3Prover/z3
synced 2025-04-07 18:05:21 +00:00
debug arith/mbi
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
fb6e7e146b
commit
ab199dedf9
|
@ -279,19 +279,18 @@ public:
|
|||
display_child(n);
|
||||
return;
|
||||
}
|
||||
if (to_app(n)->get_num_args() > depth && to_app(n)->get_num_args() > 16) {
|
||||
display_child(n);
|
||||
return;
|
||||
}
|
||||
unsigned num_args = to_app(n)->get_num_args();
|
||||
|
||||
if (num_args > 0)
|
||||
m_out << "(";
|
||||
display_name(to_app(n)->get_decl());
|
||||
display_params(to_app(n)->get_decl());
|
||||
for (unsigned i = 0; i < num_args; i++) {
|
||||
for (unsigned i = 0; i < num_args && i < 16; i++) {
|
||||
m_out << " ";
|
||||
display(to_app(n)->get_arg(i), depth-1);
|
||||
}
|
||||
if (num_args >= 16)
|
||||
m_out << " ...";
|
||||
if (num_args > 0)
|
||||
m_out << ")";
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
z3_add_component(cmd_context
|
||||
SOURCES
|
||||
basic_cmds.cpp
|
||||
check_logic.cpp
|
||||
cmd_context.cpp
|
||||
cmd_context_to_goal.cpp
|
||||
cmd_util.cpp
|
||||
|
|
|
@ -35,10 +35,10 @@ Notes:
|
|||
#include "ast/rewriter/seq_rewriter.h"
|
||||
#include "tactic/generic_model_converter.h"
|
||||
#include "solver/solver.h"
|
||||
#include "solver/check_logic.h"
|
||||
#include "solver/progress_callback.h"
|
||||
#include "cmd_context/pdecl.h"
|
||||
#include "cmd_context/tactic_manager.h"
|
||||
#include "cmd_context/check_logic.h"
|
||||
#include "params/context_params.h"
|
||||
|
||||
|
||||
|
|
|
@ -104,6 +104,7 @@ namespace lp_api {
|
|||
unsigned m_bound_propagations1;
|
||||
unsigned m_bound_propagations2;
|
||||
unsigned m_assert_diseq;
|
||||
unsigned m_assert_eq;
|
||||
unsigned m_gomory_cuts;
|
||||
unsigned m_assume_eqs;
|
||||
unsigned m_branch;
|
||||
|
@ -123,6 +124,7 @@ namespace lp_api {
|
|||
st.update("arith-bound-propagations-lp", m_bound_propagations1);
|
||||
st.update("arith-bound-propagations-cheap", m_bound_propagations2);
|
||||
st.update("arith-diseq", m_assert_diseq);
|
||||
st.update("arith-eq", m_assert_eq);
|
||||
st.update("arith-gomory-cuts", m_gomory_cuts);
|
||||
st.update("arith-assume-eqs", m_assume_eqs);
|
||||
st.update("arith-branch", m_branch);
|
||||
|
|
|
@ -424,6 +424,7 @@ namespace sat {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
switch (num_lits) {
|
||||
case 0:
|
||||
set_conflict();
|
||||
|
|
|
@ -296,15 +296,34 @@ namespace arith {
|
|||
return lp::EQ;
|
||||
}
|
||||
|
||||
void solver::mk_eq_axiom(bool is_eq, theory_var v1, theory_var v2) {
|
||||
void solver::mk_eq_axiom(bool is_eq, euf::th_eq const& e) {
|
||||
theory_var v1 = e.v1();
|
||||
theory_var v2 = e.v2();
|
||||
if (is_bool(v1))
|
||||
return;
|
||||
force_push();
|
||||
expr* e1 = var2expr(v1);
|
||||
expr* e2 = var2expr(v2);
|
||||
if (e1->get_id() > e2->get_id())
|
||||
std::swap(e1, e2);
|
||||
|
||||
if (is_eq && m.are_equal(e1, e2))
|
||||
return;
|
||||
if (!is_eq && m.are_distinct(e1, e2))
|
||||
return;
|
||||
|
||||
if (is_eq) {
|
||||
++m_stats.m_assert_eq;
|
||||
euf::enode* n1 = var2enode(v1);
|
||||
euf::enode* n2 = var2enode(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);
|
||||
m_new_eq = true;
|
||||
return;
|
||||
}
|
||||
literal le, ge;
|
||||
if (a.is_numeral(e1))
|
||||
std::swap(e1, e2);
|
||||
|
@ -332,6 +351,7 @@ namespace arith {
|
|||
le = mk_literal(a.mk_le(diff, zero));
|
||||
ge = mk_literal(a.mk_ge(diff, zero));
|
||||
}
|
||||
++m_stats.m_assert_diseq;
|
||||
add_clause(~eq, le);
|
||||
add_clause(~eq, ge);
|
||||
add_clause(~le, ~ge, eq);
|
||||
|
|
|
@ -86,9 +86,10 @@ namespace arith {
|
|||
}
|
||||
|
||||
bool solver::unit_propagate() {
|
||||
if (m_new_bounds.empty() && m_asserted_qhead == m_asserted.size())
|
||||
if (!m_new_eq && m_new_bounds.empty() && m_asserted_qhead == m_asserted.size())
|
||||
return false;
|
||||
|
||||
m_new_eq = false;
|
||||
flush_bound_axioms();
|
||||
|
||||
unsigned qhead = m_asserted_qhead;
|
||||
|
@ -911,6 +912,8 @@ namespace arith {
|
|||
theory_var v = (i + start) % sz;
|
||||
if (is_bool(v))
|
||||
continue;
|
||||
if (!ctx.is_shared(var2enode(v)))
|
||||
continue;
|
||||
ensure_column(v);
|
||||
if (!can_get_ivalue(v))
|
||||
continue;
|
||||
|
@ -945,7 +948,7 @@ namespace arith {
|
|||
continue;
|
||||
if (n1->get_root() == n2->get_root())
|
||||
continue;
|
||||
literal eq = eq_internalize(n1->get_expr(), n2->get_expr());
|
||||
literal eq = eq_internalize(n1, n2);
|
||||
if (s().value(eq) != l_true)
|
||||
return true;
|
||||
}
|
||||
|
@ -1040,7 +1043,6 @@ namespace arith {
|
|||
SASSERT(m_nla->use_nra_model());
|
||||
auto t = get_tv(v);
|
||||
if (t.is_term()) {
|
||||
|
||||
m_todo_terms.push_back(std::make_pair(t, rational::one()));
|
||||
TRACE("nl_value", tout << "v" << v << " " << t.to_string() << "\n";);
|
||||
TRACE("nl_value", tout << "v" << v << " := w" << t.to_string() << "\n";
|
||||
|
@ -1193,8 +1195,13 @@ namespace arith {
|
|||
TRACE("arith", display(tout << "is-conflict: " << is_conflict << "\n"););
|
||||
for (auto const& ev : m_explanation)
|
||||
set_evidence(ev.ci(), m_core, m_eqs);
|
||||
DEBUG_CODE(
|
||||
if (is_conflict) {
|
||||
for (literal c : m_core) VERIFY(s().value(c) == l_false);
|
||||
for (auto p : m_eqs) VERIFY(p.first->get_root() == p.second->get_root());
|
||||
});
|
||||
for (auto const& eq : m_eqs)
|
||||
m_core.push_back(eq_internalize(eq.first->get_expr(), eq.second->get_expr()));
|
||||
m_core.push_back(eq_internalize(eq.first, eq.second));
|
||||
for (literal& c : m_core)
|
||||
c.neg();
|
||||
add_clause(m_core);
|
||||
|
|
|
@ -16,8 +16,8 @@ Author:
|
|||
--*/
|
||||
#pragma once
|
||||
|
||||
#include "util/obj_pair_set.h"
|
||||
#include "ast/ast_trail.h"
|
||||
#include "sat/smt/sat_th.h"
|
||||
#include "ast/arith_decl_plugin.h"
|
||||
#include "math/lp/lp_solver.h"
|
||||
#include "math/lp/lp_primal_simplex.h"
|
||||
|
@ -29,6 +29,7 @@ Author:
|
|||
#include "math/lp/lp_api.h"
|
||||
#include "math/polynomial/algebraic_numbers.h"
|
||||
#include "math/polynomial/polynomial.h"
|
||||
#include "sat/smt/sat_th.h"
|
||||
|
||||
namespace euf {
|
||||
class solver;
|
||||
|
@ -90,7 +91,7 @@ namespace arith {
|
|||
};
|
||||
int_hashtable<var_value_hash, var_value_eq> m_model_eqs;
|
||||
|
||||
|
||||
bool m_new_eq { false };
|
||||
|
||||
|
||||
// temporary values kept during internalization
|
||||
|
@ -303,7 +304,7 @@ namespace arith {
|
|||
void refine_bound(theory_var v, const lp::implied_bound& be);
|
||||
literal is_bound_implied(lp::lconstraint_kind k, rational const& value, api_bound const& b) const;
|
||||
void assert_bound(bool is_true, api_bound& b);
|
||||
void mk_eq_axiom(bool is_eq, theory_var v1, theory_var v2);
|
||||
void mk_eq_axiom(bool is_eq, euf::th_eq const& eq);
|
||||
void assert_idiv_mod_axioms(theory_var u, theory_var v, theory_var w, rational const& r);
|
||||
api_bound* mk_var_bound(sat::literal lit, theory_var v, lp_api::bound_kind bk, rational const& bound);
|
||||
lp::lconstraint_kind bound2constraint_kind(bool is_int, lp_api::bound_kind bk, bool is_true);
|
||||
|
@ -424,8 +425,8 @@ namespace arith {
|
|||
void collect_statistics(statistics& st) const override;
|
||||
euf::th_solver* clone(euf::solver& ctx) override;
|
||||
bool use_diseqs() const override { return true; }
|
||||
void new_eq_eh(euf::th_eq const& eq) override { mk_eq_axiom(true, eq.v1(), eq.v2()); }
|
||||
void new_diseq_eh(euf::th_eq const& de) override { mk_eq_axiom(false, de.v1(), de.v2()); }
|
||||
void new_eq_eh(euf::th_eq const& eq) override { mk_eq_axiom(true, eq); }
|
||||
void new_diseq_eh(euf::th_eq const& de) override { mk_eq_axiom(false, de); }
|
||||
bool unit_propagate() override;
|
||||
void init_model() override { init_variable_values(); }
|
||||
void finalize_model(model& mdl) override { DEBUG_CODE(dbg_finalize_model(mdl);); }
|
||||
|
|
|
@ -83,6 +83,7 @@ namespace euf {
|
|||
if (ext)
|
||||
return ext;
|
||||
ext = alloc(q::solver, *this, fid);
|
||||
m_qsolver = ext;
|
||||
add_solver(ext);
|
||||
return ext;
|
||||
}
|
||||
|
@ -364,11 +365,33 @@ namespace euf {
|
|||
}
|
||||
}
|
||||
|
||||
bool solver::is_self_propagated(th_eq const& e) {
|
||||
if (!e.is_eq())
|
||||
return false;
|
||||
|
||||
m_egraph.begin_explain();
|
||||
m_explain.reset();
|
||||
m_egraph.explain_eq<size_t>(m_explain, e.child(), e.root());
|
||||
m_egraph.end_explain();
|
||||
for (auto p : m_explain) {
|
||||
if (is_literal(p))
|
||||
return false;
|
||||
|
||||
size_t idx = get_justification(p);
|
||||
auto* ext = sat::constraint_base::to_extension(idx);
|
||||
if (ext->get_id() != e.id())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void solver::propagate_th_eqs() {
|
||||
for (; m_egraph.has_th_eq() && !s().inconsistent() && !m_egraph.inconsistent(); m_egraph.next_th_eq()) {
|
||||
th_eq eq = m_egraph.get_th_eq();
|
||||
if (eq.is_eq())
|
||||
m_id2solver[eq.id()]->new_eq_eh(eq);
|
||||
if (eq.is_eq()) {
|
||||
if (!is_self_propagated(eq))
|
||||
m_id2solver[eq.id()]->new_eq_eh(eq);
|
||||
}
|
||||
else
|
||||
m_id2solver[eq.id()]->new_diseq_eh(eq);
|
||||
}
|
||||
|
@ -404,16 +427,22 @@ namespace euf {
|
|||
for (auto* e : m_solvers) {
|
||||
if (!m.inc())
|
||||
return sat::check_result::CR_GIVEUP;
|
||||
if (e == m_qsolver)
|
||||
continue;
|
||||
switch (e->check()) {
|
||||
case sat::check_result::CR_CONTINUE: cont = true; break;
|
||||
case sat::check_result::CR_GIVEUP: give_up = true; break;
|
||||
default: break;
|
||||
}
|
||||
if (s().inconsistent())
|
||||
return sat::check_result::CR_CONTINUE;
|
||||
}
|
||||
if (cont)
|
||||
return sat::check_result::CR_CONTINUE;
|
||||
if (give_up)
|
||||
return sat::check_result::CR_GIVEUP;
|
||||
if (m_qsolver)
|
||||
return m_qsolver->check();
|
||||
TRACE("after_search", s().display(tout););
|
||||
return sat::check_result::CR_DONE;
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@ namespace euf {
|
|||
scoped_ptr<euf::ackerman> m_ackerman;
|
||||
scoped_ptr<sat::dual_solver> m_dual_solver;
|
||||
user::solver* m_user_propagator{ nullptr };
|
||||
th_solver* m_qsolver { nullptr };
|
||||
|
||||
ptr_vector<expr> m_bool_var2expr;
|
||||
ptr_vector<size_t> m_explain;
|
||||
|
@ -147,6 +148,7 @@ namespace euf {
|
|||
// solving
|
||||
void propagate_literals();
|
||||
void propagate_th_eqs();
|
||||
bool is_self_propagated(th_eq const& e);
|
||||
void get_antecedents(literal l, constraint& j, literal_vector& r, bool probing);
|
||||
void new_diseq(enode* a, enode* b, literal lit);
|
||||
|
||||
|
|
|
@ -387,4 +387,9 @@ namespace q {
|
|||
m_plugins.set(fid, p);
|
||||
}
|
||||
|
||||
void mbqi::collect_statistics(statistics& st) const {
|
||||
if (m_solver)
|
||||
m_solver->collect_statistics(st);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -79,6 +79,8 @@ namespace q {
|
|||
void init_search();
|
||||
|
||||
void finalize_model(model& mdl);
|
||||
|
||||
void collect_statistics(statistics& st) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ namespace q {
|
|||
|
||||
void solver::collect_statistics(statistics& st) const {
|
||||
st.update("quantifier asserts", m_stats.m_num_quantifier_asserts);
|
||||
m_mbqi.collect_statistics(st);
|
||||
}
|
||||
|
||||
euf::th_solver* solver::clone(euf::solver& ctx) {
|
||||
|
|
|
@ -150,6 +150,7 @@ namespace euf {
|
|||
bool is_true(sat::literal a, sat::literal b, sat::literal c, sat::literal d) { return is_true(a) || is_true(b, c, c); }
|
||||
|
||||
sat::literal eq_internalize(expr* a, expr* b);
|
||||
sat::literal eq_internalize(enode* a, enode* b) { return eq_internalize(a->get_expr(), b->get_expr()); }
|
||||
|
||||
euf::enode* e_internalize(expr* e);
|
||||
euf::enode* mk_enode(expr* e, bool suppress_args = false);
|
||||
|
|
|
@ -208,6 +208,7 @@ public:
|
|||
}
|
||||
catch (z3_exception& ex) {
|
||||
(void)ex;
|
||||
proc.m_solver->collect_statistics(m_stats);
|
||||
TRACE("sat", tout << ex.msg() << "\n";);
|
||||
throw;
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ namespace smt {
|
|||
// after n1 and n2 are marked as relevant.
|
||||
//
|
||||
data d;
|
||||
if (m_already_processed.find(n1, n2, d))
|
||||
if (m_already_processed.find(n1, n2, d))
|
||||
return;
|
||||
|
||||
TRACE("arith_eq_adapter_profile", tout << "mk #" << n1->get_owner_id() << " #" << n2->get_owner_id() << " " <<
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
z3_add_component(solver
|
||||
SOURCES
|
||||
check_sat_result.cpp
|
||||
check_logic.cpp
|
||||
combined_solver.cpp
|
||||
mus.cpp
|
||||
parallel_tactic.cpp
|
||||
|
|
|
@ -16,7 +16,7 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include "cmd_context/check_logic.h"
|
||||
#include "solver/check_logic.h"
|
||||
#include "solver/smt_logics.h"
|
||||
#include "ast/arith_decl_plugin.h"
|
||||
#include "ast/array_decl_plugin.h"
|
|
@ -62,7 +62,7 @@ public:
|
|||
*/
|
||||
virtual void operator()(goal_ref const & in, goal_ref_buffer& result) = 0;
|
||||
|
||||
virtual void collect_statistics(statistics & st) const {}
|
||||
virtual void collect_statistics(statistics & st) const { }
|
||||
virtual void reset_statistics() {}
|
||||
virtual void cleanup() = 0;
|
||||
virtual void reset() { cleanup(); }
|
||||
|
|
|
@ -39,8 +39,9 @@ public:
|
|||
void insert(obj_pair const & p) { m_set.insert(p); }
|
||||
bool insert_if_not_there(T1 * t1, T2 * t2) { return m_set.insert_if_not_there2(obj_pair(t1, t2)); }
|
||||
bool insert_if_not_there(obj_pair const & p) { return m_set.insert_if_not_there2(p); }
|
||||
void erase(T1 * t1, T2 * t2) { return m_set.erase(obj_pair(t1, t2)); }
|
||||
void erase(obj_pair const & p) { return m_set.erase(p); }
|
||||
void erase(T1 * t1, T2 * t2) { m_set.erase(obj_pair(t1, t2)); }
|
||||
void erase(obj_pair const & p) { m_set.erase(p); }
|
||||
void remove(obj_pair const & p) { erase(p); }
|
||||
bool contains(T1 * t1, T2 * t2) const { return m_set.contains(obj_pair(t1, t2)); }
|
||||
bool contains(obj_pair const & p) const { return m_set.contains(p); }
|
||||
void reset() { m_set.reset(); }
|
||||
|
|
|
@ -376,7 +376,6 @@ public:
|
|||
};
|
||||
|
||||
|
||||
|
||||
template<typename Ctx, typename T>
|
||||
class remove_obj_trail : public trail<Ctx> {
|
||||
obj_hashtable<T>& m_table;
|
||||
|
|
Loading…
Reference in a new issue