3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-08 12:11:23 +00:00

remove level of indirection for context and ast_manager in smt_theory (#4253)

* remove level of indirection for context and ast_manager in smt_theory

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add request by #4252

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* move to def

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* int

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2020-05-08 16:46:03 -07:00 committed by GitHub
parent 17b8db95c1
commit becf423c77
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
57 changed files with 750 additions and 1257 deletions

View file

@ -34,6 +34,28 @@ Revision History:
using namespace smt;
template<typename Ext>
theory_diff_logic<Ext>::theory_diff_logic(context& ctx):
theory(ctx, ctx.get_manager().mk_family_id("arith")),
m_params(ctx.get_fparams()),
m_util(ctx.get_manager()),
m_arith_eq_adapter(*this, m_util),
m_consistent(true),
m_izero(null_theory_var),
m_rzero(null_theory_var),
m_terms(ctx.get_manager()),
m_asserted_qhead(0),
m_num_core_conflicts(0),
m_num_propagation_calls(0),
m_agility(0.5),
m_lia_or_lra(not_set),
m_non_diff_logic_exprs(false),
m_factory(nullptr),
m_nc_functor(*this),
m_S(ctx.get_manager().limit()),
m_num_simplex_edges(0) {
}
template<typename Ext>
std::ostream& theory_diff_logic<Ext>::atom::display(theory_diff_logic const& th, std::ostream& out) const {
context& ctx = th.get_context();
@ -63,19 +85,13 @@ void theory_diff_logic<Ext>::nc_functor::reset() {
// -----------------------------------------
// theory_diff_logic
template<typename Ext>
void theory_diff_logic<Ext>::init(context * ctx) {
theory::init(ctx);
init_zero();
}
template<typename Ext>
bool theory_diff_logic<Ext>::internalize_term(app * term) {
if (!m_consistent)
return false;
bool result = null_theory_var != mk_term(term);
CTRACE("arith", !result, tout << "Did not internalize " << mk_pp(term, get_manager()) << "\n";);
CTRACE("arith", !result, tout << "Did not internalize " << mk_pp(term, m) << "\n";);
if (!result) {
TRACE("non_diff_logic", tout << "Terms may not be internalized\n";);
found_non_diff_logic_expr(term);
@ -154,9 +170,9 @@ public:
template<typename Ext>
void theory_diff_logic<Ext>::found_non_diff_logic_expr(expr * n) {
if (!m_non_diff_logic_exprs) {
TRACE("non_diff_logic", tout << "found non diff logic expression:\n" << mk_pp(n, get_manager()) << "\n";);
IF_VERBOSE(0, verbose_stream() << "(smt.diff_logic: non-diff logic expression " << mk_pp(n, get_manager()) << ")\n";);
get_context().push_trail(value_trail<context, bool>(m_non_diff_logic_exprs));
TRACE("non_diff_logic", tout << "found non diff logic expression:\n" << mk_pp(n, m) << "\n";);
IF_VERBOSE(0, verbose_stream() << "(smt.diff_logic: non-diff logic expression " << mk_pp(n, m) << ")\n";);
ctx.push_trail(value_trail<context, bool>(m_non_diff_logic_exprs));
m_non_diff_logic_exprs = true;
}
}
@ -165,7 +181,6 @@ template<typename Ext>
bool theory_diff_logic<Ext>::internalize_atom(app * n, bool gate_ctx) {
if (!m_consistent)
return false;
context & ctx = get_context();
if (!m_util.is_le(n) && !m_util.is_ge(n)) {
found_non_diff_logic_expr(n);
return false;
@ -264,7 +279,7 @@ bool theory_diff_logic<Ext>::internalize_atom(app * n, bool gate_ctx) {
m_bool_var2atom.insert(bv, a);
TRACE("arith",
tout << mk_pp(n, get_manager()) << "\n";
tout << mk_pp(n, m) << "\n";
m_graph.display_edge(tout << "pos: ", pos);
m_graph.display_edge(tout << "neg: ", neg);
);
@ -274,8 +289,7 @@ bool theory_diff_logic<Ext>::internalize_atom(app * n, bool gate_ctx) {
template<typename Ext>
void theory_diff_logic<Ext>::internalize_eq_eh(app * atom, bool_var v) {
context & ctx = get_context();
TRACE("arith", tout << mk_pp(atom, get_manager()) << "\n";);
TRACE("arith", tout << mk_pp(atom, m) << "\n";);
app * lhs = to_app(atom->get_arg(0));
app * rhs = to_app(atom->get_arg(1));
app * s;
@ -303,8 +317,8 @@ void theory_diff_logic<Ext>::assign_eh(bool_var v, bool is_true) {
atom * a = nullptr;
VERIFY (m_bool_var2atom.find(v, a));
SASSERT(a);
SASSERT(get_context().get_assignment(v) != l_undef);
SASSERT((get_context().get_assignment(v) == l_true) == is_true);
SASSERT(ctx.get_assignment(v) != l_undef);
SASSERT((ctx.get_assignment(v) == l_true) == is_true);
a->assign_eh(is_true);
m_asserted_atoms.push_back(a);
}
@ -370,12 +384,12 @@ final_check_status theory_diff_logic<Ext>::final_check_eh() {
return FC_GIVEUP;
}
for (enode* n : get_context().enodes()) {
for (enode* n : ctx.enodes()) {
family_id fid = n->get_owner()->get_family_id();
if (fid != get_family_id() &&
fid != get_manager().get_basic_family_id() &&
fid != m.get_basic_family_id() &&
!is_uninterp_const(n->get_owner())) {
TRACE("arith", tout << mk_pp(n->get_owner(), get_manager()) << "\n";);
TRACE("arith", tout << mk_pp(n->get_owner(), m) << "\n";);
return FC_GIVEUP;
}
}
@ -410,7 +424,7 @@ bool theory_diff_logic<Ext>::decompose_linear(app_ref_vector& terms, bool_vector
if (m_util.is_add(n)) {
expr* arg = n->get_arg(0);
if (!is_app(arg)) return false;
expr_ref _n(n, get_manager());
expr_ref _n(n, m);
terms[i] = to_app(arg);
sign = signs[i];
for (unsigned j = 1; j < n->get_num_args(); ++j) {
@ -503,7 +517,7 @@ void theory_diff_logic<Ext>::propagate() {
++m_num_propagation_calls;
if (m_num_propagation_calls * (m_stats.m_num_conflicts + 1) >
m_params.m_arith_adaptive_propagation_threshold * get_context().m_stats.m_num_conflicts) {
m_params.m_arith_adaptive_propagation_threshold * ctx.m_stats.m_num_conflicts) {
m_num_propagation_calls = 1;
TRACE("arith_prop", tout << "propagating: " << m_num_propagation_calls << "\n";);
propagate_core();
@ -517,7 +531,7 @@ void theory_diff_logic<Ext>::propagate() {
// update agility with factor generated by other conflicts.
double g = m_params.m_arith_adaptive_propagation_threshold;
while (m_num_core_conflicts < get_context().m_stats.m_num_conflicts) {
while (m_num_core_conflicts < ctx.m_stats.m_num_conflicts) {
m_agility = m_agility*g;
++m_num_core_conflicts;
}
@ -544,7 +558,7 @@ void theory_diff_logic<Ext>::propagate() {
template<typename Ext>
void theory_diff_logic<Ext>::inc_conflicts() {
get_context().push_trail(value_trail<context, bool>(m_consistent));
ctx.push_trail(value_trail<context, bool>(m_consistent));
m_consistent = false;
m_stats.m_num_conflicts++;
if (m_params.m_arith_adaptive) {
@ -565,7 +579,6 @@ void theory_diff_logic<Ext>::propagate_core() {
template<typename Ext>
bool theory_diff_logic<Ext>::propagate_atom(atom* a) {
context& ctx = get_context();
TRACE("arith", a->display(*this, tout); tout << "\n";);
if (ctx.inconsistent()) {
return false;
@ -589,7 +602,6 @@ void theory_diff_logic<Ext>::new_edge(dl_var src, dl_var dst, unsigned num_edges
TRACE("dl_activity", tout << "\n";);
context& ctx = get_context();
numeral w(0);
for (unsigned i = 0; i < num_edges; ++i) {
w += m_graph.get_weight(edges[i]);
@ -601,7 +613,7 @@ void theory_diff_logic<Ext>::new_edge(dl_var src, dl_var dst, unsigned num_edges
bool is_int = m_util.is_int(n1);
rational num = w.get_rational().to_rational();
expr_ref le(get_manager());
expr_ref le(m);
if (w.is_rational()) {
// x - y <= w
expr* n3 = m_util.mk_numeral(num, is_int);
@ -619,11 +631,11 @@ void theory_diff_logic<Ext>::new_edge(dl_var src, dl_var dst, unsigned num_edges
expr* n3 = m_util.mk_numeral(-num, is_int);
n1 = m_util.mk_mul(m_util.mk_numeral(rational(-1), is_int), n1);
le = m_util.mk_le(m_util.mk_add(n2,n1), n3);
le = get_manager().mk_not(le);
le = m.mk_not(le);
}
if (get_manager().has_trace_stream())log_axiom_instantiation(le);
if (m.has_trace_stream())log_axiom_instantiation(le);
ctx.internalize(le, false);
if (get_manager().has_trace_stream()) get_manager().trace_stream() << "[end-of-instance]\n";
if (m.has_trace_stream()) m.trace_stream() << "[end-of-instance]\n";
ctx.mark_as_relevant(le.get());
literal lit(ctx.get_literal(le));
bool_var bv = lit.var();
@ -638,14 +650,14 @@ void theory_diff_logic<Ext>::new_edge(dl_var src, dl_var dst, unsigned num_edges
lits.push_back(lit);
TRACE("dl_activity",
tout << mk_pp(le, get_manager()) << "\n";
tout << mk_pp(le, m) << "\n";
tout << "edge: " << a->get_pos() << "\n";
ctx.display_literals_verbose(tout, lits.size(), lits.c_ptr());
tout << "\n";
);
justification * js = nullptr;
if (get_manager().proofs_enabled()) {
if (m.proofs_enabled()) {
vector<parameter> params;
params.push_back(parameter(symbol("farkas")));
params.resize(lits.size()+1, parameter(rational(1)));
@ -691,7 +703,6 @@ void theory_diff_logic<Ext>::set_neg_cycle_conflict() {
m_graph.traverse_neg_cycle2(m_params.m_arith_stronger_lemmas, m_nc_functor);
inc_conflicts();
literal_vector const& lits = m_nc_functor.get_lits();
context & ctx = get_context();
TRACE("arith_conflict",
tout << "conflict: ";
for (literal lit : lits) ctx.display_literal_info(tout, lit);
@ -703,7 +714,7 @@ void theory_diff_logic<Ext>::set_neg_cycle_conflict() {
}
vector<parameter> params;
if (get_manager().proofs_enabled()) {
if (m.proofs_enabled()) {
params.push_back(parameter(symbol("farkas")));
for (unsigned i = 0; i <= lits.size(); ++i) {
params.push_back(parameter(rational(1)));
@ -744,9 +755,8 @@ theory_var theory_diff_logic<Ext>::mk_term(app* n) {
app* a, *offset;
theory_var source, target;
enode* e;
context& ctx = get_context();
TRACE("arith", tout << mk_pp(n, get_manager()) << "\n";);
TRACE("arith", tout << mk_pp(n, m) << "\n";);
rational r;
if (m_util.is_numeral(n, r)) {
@ -761,7 +771,7 @@ theory_var theory_diff_logic<Ext>::mk_term(app* n) {
ctx.internalize(arg, false);
}
}
e = get_context().mk_enode(n, false, false, true);
e = ctx.mk_enode(n, false, false, true);
target = mk_var(e);
numeral k(r);
// target - source <= k, source - target <= -k
@ -782,7 +792,6 @@ template<typename Ext>
theory_var theory_diff_logic<Ext>::mk_num(app* n, rational const& r) {
theory_var v = null_theory_var;
enode* e = nullptr;
context& ctx = get_context();
if (r.is_zero()) {
v = get_zero(m_util.is_int(n));
}
@ -812,7 +821,7 @@ theory_var theory_diff_logic<Ext>::mk_var(enode* n) {
theory_var v = theory::mk_var(n);
TRACE("diff_logic_vars", tout << "mk_var: " << v << "\n";);
m_graph.init_var(v);
get_context().attach_th_var(n, this, v);
ctx.attach_th_var(n, this, v);
set_sort(n->get_owner());
return v;
}
@ -838,7 +847,6 @@ void theory_diff_logic<Ext>::set_sort(expr* n) {
template<typename Ext>
theory_var theory_diff_logic<Ext>::mk_var(app* n) {
context & ctx = get_context();
enode* e = nullptr;
theory_var v = null_theory_var;
if (!ctx.e_internalized(n)) {
@ -854,7 +862,7 @@ theory_var theory_diff_logic<Ext>::mk_var(app* n) {
TRACE("non_diff_logic", tout << "Variable should not be interpreted\n";);
found_non_diff_logic_expr(n);
}
TRACE("arith", tout << mk_pp(n, get_manager()) << " |-> " << v << "\n";);
TRACE("arith", tout << mk_pp(n, m) << " |-> " << v << "\n";);
return v;
}
@ -935,7 +943,7 @@ model_value_proc * theory_diff_logic<Ext>::mk_value(enode * n, model_generator &
numeral val = m_graph.get_assignment(v);
num = val.get_rational().to_rational() + m_delta * val.get_infinitesimal().to_rational();
}
TRACE("arith", tout << mk_pp(n->get_owner(), get_manager()) << " |-> " << num << "\n";);
TRACE("arith", tout << mk_pp(n->get_owner(), m) << " |-> " << num << "\n";);
bool is_int = m_util.is_int(n->get_owner());
if (is_int && !num.is_int())
throw default_exception("difference logic solver was used on mixed int/real problem");
@ -956,7 +964,6 @@ void theory_diff_logic<Ext>::display(std::ostream & out) const {
template<typename Ext>
bool theory_diff_logic<Ext>::is_consistent() const {
DEBUG_CODE(
context& ctx = get_context();
for (unsigned i = 0; m_graph.is_feasible_dbg() && i < m_atoms.size(); ++i) {
atom* a = m_atoms[i];
bool_var bv = a->get_bool_var();
@ -974,7 +981,6 @@ bool theory_diff_logic<Ext>::is_consistent() const {
template<class Ext>
theory_var theory_diff_logic<Ext>::expand(bool pos, theory_var v, rational & k) {
context& ctx = get_context();
enode* e = get_enode(v);
rational r;
for (;;) {
@ -1012,8 +1018,6 @@ void theory_diff_logic<Ext>::new_eq_or_diseq(bool is_eq, theory_var v1, theory_v
rational k;
theory_var s = expand(true, v1, k);
theory_var t = expand(false, v2, k);
context& ctx = get_context();
ast_manager& m = get_manager();
if (s == t) {
if (is_eq != k.is_zero()) {
@ -1050,7 +1054,7 @@ void theory_diff_logic<Ext>::new_eq_or_diseq(bool is_eq, theory_var v1, theory_v
UNREACHABLE();
}
if (m.has_trace_stream()) get_manager().trace_stream() << "[end-of-instance]\n";
if (m.has_trace_stream()) m.trace_stream() << "[end-of-instance]\n";
literal l(ctx.get_literal(eq.get()));
if (!is_eq) {
@ -1238,7 +1242,6 @@ theory_diff_logic<Ext>::maximize(theory_var v, expr_ref& blocker, bool& has_shar
has_shared = false;
Simplex& S = m_S;
ast_manager& m = get_manager();
CTRACE("arith",!m_graph.is_feasible_dbg(), m_graph.display(tout););
SASSERT(m_graph.is_feasible_dbg());
@ -1286,7 +1289,7 @@ theory_diff_logic<Ext>::maximize(theory_var v, expr_ref& blocker, bool& has_shar
unsigned edge_id = simplex2edge(v);
literal lit = m_graph.get_explanation(edge_id);
if (lit != null_literal) {
get_context().literal2expr(lit, tmp);
ctx.literal2expr(lit, tmp);
core.push_back(tmp);
}
}
@ -1322,8 +1325,8 @@ theory_var theory_diff_logic<Ext>::add_objective(app* term) {
objective_term objective;
theory_var result = m_objectives.size();
rational q(1), r(0);
expr_ref_vector vr(get_manager());
if (!is_linear(get_manager(), term)) {
expr_ref_vector vr(m);
if (!is_linear(m, term)) {
result = null_theory_var;
}
else if (internalize_objective(term, q, r, objective)) {
@ -1339,7 +1342,6 @@ theory_var theory_diff_logic<Ext>::add_objective(app* term) {
template<typename Ext>
expr_ref theory_diff_logic<Ext>::mk_ineq(theory_var v, inf_eps const& val, bool is_strict) {
ast_manager& m = get_manager();
objective_term const& t = m_objectives[v];
expr_ref e(m), f(m), f2(m);
if (t.size() == 1 && t[0].second.is_one()) {
@ -1402,11 +1404,9 @@ expr_ref theory_diff_logic<Ext>::mk_ge(generic_model_converter& fm, theory_var v
}
#if 0
context & ctx = get_context();
model_ref mdl;
ctx.get_model(mdl);
ptr_vector<expr> formulas(ctx.get_num_asserted_formulas(), ctx.get_asserted_formulas());
ast_manager& m = get_manager();
model_implicant impl_extractor(m);
expr_ref_vector implicants = impl_extractor.minimize_literals(formulas, mdl);
return m.mk_and(o, m.mk_not(m.mk_and(implicants.size(), implicants.c_ptr())));
@ -1449,14 +1449,13 @@ bool theory_diff_logic<Ext>::internalize_objective(expr * n, rational const& m,
template<typename Ext>
theory* theory_diff_logic<Ext>::mk_fresh(context* new_ctx) {
return alloc(theory_diff_logic<Ext>, new_ctx->get_manager(), new_ctx->get_fparams());
return alloc(theory_diff_logic<Ext>, *new_ctx);
}
template<typename Ext>
void theory_diff_logic<Ext>::init_zero() {
if (m_izero != null_theory_var) return;
TRACE("arith", tout << "init zero\n";);
context & ctx = get_context();
app* zero;
enode* e;
zero = m_util.mk_numeral(rational(0), true);