3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 17:45:32 +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

@ -110,6 +110,9 @@ else()
set(lib_type "STATIC")
endif()
add_library(libz3 ${lib_type} ${object_files})
target_include_directories(libz3 INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/api>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
set_target_properties(libz3 PROPERTIES
# VERSION determines the version in the filename of the shared library.
# SOVERSION determines the value of the DT_SONAME field on ELF platforms.

View file

@ -129,7 +129,7 @@ func_decl * array_decl_plugin::mk_const(sort * s, unsigned arity, sort * const *
m_manager->raise_exception("invalid const array definition, parameter is not an array sort");
return nullptr;
}
if (!m_manager->compatible_sorts(get_array_range(s), domain[0])) {
if (get_array_range(s) != domain[0]) {
m_manager->raise_exception("invalid const array definition, sort mismatch between array range and argument");
return nullptr;
}

View file

@ -126,14 +126,14 @@ namespace opt {
wth->reset_local();
}
else {
wth = alloc(smt::theory_wmaxsat, m, m_c.fm());
wth = alloc(smt::theory_wmaxsat, m_c.smt_context(), m, m_c.fm());
m_c.smt_context().register_plugin(wth);
}
smt::theory_id th_pb = m.get_family_id("pb");
smt::theory_pb* pb = dynamic_cast<smt::theory_pb*>(m_c.smt_context().get_theory(th_pb));
if (!pb) {
theory_pb_params params;
pb = alloc(smt::theory_pb, m, params);
pb = alloc(smt::theory_pb, m_c.smt_context());
m_c.smt_context().register_plugin(pb);
}
return wth;

View file

@ -109,7 +109,7 @@ namespace opt {
smt::theory_id th_id = m.get_family_id("pb");
smt::theory* th = get_context().get_theory(th_id);
if (!th) {
get_context().register_plugin(alloc(smt::theory_pb, m, m_params));
get_context().register_plugin(alloc(smt::theory_pb, get_context()));
}
}
@ -119,7 +119,7 @@ namespace opt {
smt::theory* arith_theory = ctx.get_theory(arith_id);
if (!arith_theory) {
ctx.register_plugin(alloc(smt::theory_mi_arith, m, m_params));
ctx.register_plugin(alloc(smt::theory_mi_arith, ctx));
arith_theory = ctx.get_theory(arith_id);
SASSERT(arith_theory);
}

View file

@ -210,7 +210,7 @@ namespace smt {
<< " " << mk_pp(ge, m) << ": " << ge_lit
<< " " << mk_pp(t1_eq_t2, m) << ": " << t1_eq_t2_lit << "\n";);
if (m_params.m_arith_add_binary_bounds) {
if (m_owner.get_fparams().m_arith_add_binary_bounds) {
TRACE("arith_eq_adapter", tout << "adding binary bounds...\n";);
ctx.mk_th_axiom(tid, le_lit, ge_lit, m_proof_hint.size(), m_proof_hint.c_ptr());
}
@ -219,7 +219,7 @@ namespace smt {
ctx.add_relevancy_eh(n1->get_owner(), eh);
ctx.add_relevancy_eh(n2->get_owner(), eh);
}
if (!m_params.m_arith_lazy_adapter && !ctx.at_base_level() &&
if (!m_owner.get_fparams().m_arith_lazy_adapter && !ctx.at_base_level() &&
n1->get_iscope_lvl() <= ctx.get_base_level() && n2->get_iscope_lvl() <= ctx.get_base_level()) {
m_restart_pairs.push_back(enode_pair(n1, n2));
}

View file

@ -62,7 +62,6 @@ namespace smt {
private:
theory & m_owner;
theory_arith_params & m_params;
arith_util & m_util;
already_processed m_already_processed;
@ -74,7 +73,7 @@ namespace smt {
enode * get_enode(theory_var v) const { return m_owner.get_enode(v); }
public:
arith_eq_adapter(theory & owner, theory_arith_params & params, arith_util & u):m_owner(owner), m_params(params), m_util(u) {}
arith_eq_adapter(theory & owner, arith_util & u):m_owner(owner), m_util(u) {}
void new_eq_eh(theory_var v1, theory_var v2);
void new_diseq_eh(theory_var v1, theory_var v2);
void reset_eh();

View file

@ -28,7 +28,6 @@ using namespace smt;
bool theory_seq::solve_eqs(unsigned i) {
context& ctx = get_context();
bool change = false;
for (; !ctx.inconsistent() && i < m_eqs.size(); ++i) {
if (solve_eq(i)) {
@ -43,7 +42,6 @@ bool theory_seq::solve_eqs(unsigned i) {
bool theory_seq::solve_eq(unsigned idx) {
const eq& e = m_eqs[idx];
context& ctx = get_context();
expr_ref_vector& ls = m_ls;
expr_ref_vector& rs = m_rs;
m_ls.reset();
@ -126,7 +124,6 @@ bool theory_seq::solve_unit_eq(expr_ref_vector const& l, expr_ref_vector const&
}
bool theory_seq::solve_binary_eq(expr_ref_vector const& ls, expr_ref_vector const& rs, dependency* dep) {
context& ctx = get_context();
ptr_vector<expr> xs, ys;
expr_ref x(m), y(m);
if (!is_binary_eq(ls, rs, x, xs, ys, y) &&
@ -254,8 +251,6 @@ bool theory_seq::find_better_rep(expr_ref_vector const& ls, expr_ref_vector cons
// disabled until functionality is clarified
return false;
context& ctx = get_context();
if (ls.empty() || rs.empty())
return false;
expr* l_fst = find_fst_non_empty_var(ls);
@ -328,7 +323,6 @@ bool theory_seq::find_better_rep(expr_ref_vector const& ls, expr_ref_vector cons
}
bool theory_seq::has_len_offset(expr_ref_vector const& ls, expr_ref_vector const& rs, int & offset) {
context& ctx = get_context();
if (ls.empty() || rs.empty())
return false;
@ -407,7 +401,6 @@ bool theory_seq::len_based_split() {
*/
bool theory_seq::len_based_split(eq const& e) {
context& ctx = get_context();
expr_ref_vector const& ls = e.ls();
expr_ref_vector const& rs = e.rs();
@ -537,7 +530,6 @@ bool theory_seq::is_complex(eq const& e) {
bool theory_seq::split_lengths(dependency* dep,
expr_ref_vector const& ls, expr_ref_vector const& rs,
vector<rational> const& ll, vector<rational> const& rl) {
context& ctx = get_context();
expr_ref X(m), Y(m), b(m);
if (ls.empty() || rs.empty()) {
return false;
@ -646,7 +638,6 @@ bool theory_seq::branch_binary_variable(eq const& e) {
// x is either a prefix of ys, all of ys ++ y or ys ++ y1, such that y = y1 ++ y2, y2 = xs
rational lenX, lenY;
context& ctx = get_context();
if (branch_variable_eq(e)) {
return true;
}
@ -713,7 +704,6 @@ bool theory_seq::branch_unit_variable() {
void theory_seq::branch_unit_variable(dependency* dep, expr* X, expr_ref_vector const& units) {
SASSERT(is_var(X));
context& ctx = get_context();
rational lenX;
if (!get_length(X, lenX)) {
TRACE("seq", tout << "enforce length on " << mk_bounded_pp(X, m, 2) << "\n";);
@ -748,7 +738,7 @@ void theory_seq::branch_unit_variable(dependency* dep, expr* X, expr_ref_vector
}
bool theory_seq::branch_ternary_variable1() {
int start = get_context().get_random_value();
int start = ctx.get_random_value();
for (unsigned i = 0; i < m_eqs.size(); ++i) {
if (branch_ternary_variable(m_eqs[(i + start) % m_eqs.size()]))
return true;
@ -759,7 +749,7 @@ bool theory_seq::branch_ternary_variable1() {
}
bool theory_seq::branch_ternary_variable2() {
int start = get_context().get_random_value();
int start = ctx.get_random_value();
for (unsigned i = 0; i < m_eqs.size(); ++i) {
eq const& e = m_eqs[(i + start) % m_eqs.size()];
if (branch_ternary_variable(e, true)) {
@ -842,7 +832,6 @@ unsigned_vector theory_seq::overlap2(expr_ref_vector const& ls, expr_ref_vector
bool theory_seq::branch_ternary_variable_base(
dependency* dep, unsigned_vector const& indexes,
expr* x, expr_ref_vector const& xs, expr* y1, expr_ref_vector const& ys, expr* y2) {
context& ctx = get_context();
bool change = false;
for (auto ind : indexes) {
TRACE("seq", tout << "ind = " << ind << "\n";);
@ -892,7 +881,6 @@ bool theory_seq::branch_ternary_variable(eq const& e, bool flag1) {
}
rational lenX, lenY1, lenY2;
context& ctx = get_context();
if (!get_length(x, lenX)) {
add_length_to_eqc(x);
}
@ -942,7 +930,6 @@ bool theory_seq::branch_ternary_variable(eq const& e, bool flag1) {
bool theory_seq::branch_ternary_variable_base2(
dependency* dep, unsigned_vector const& indexes,
expr_ref_vector const& xs, expr* x, expr* y1, expr_ref_vector const& ys, expr* y2) {
context& ctx = get_context();
sort* srt = m.get_sort(x);
bool change = false;
for (auto ind : indexes) {
@ -990,7 +977,6 @@ bool theory_seq::branch_ternary_variable2(eq const& e, bool flag1) {
dependency* dep = e.dep();
rational lenX, lenY1, lenY2;
context& ctx = get_context();
if (!get_length(x, lenX)) {
add_length_to_eqc(x);
}
@ -1058,7 +1044,6 @@ bool theory_seq::branch_quat_variable(eq const& e) {
dependency* dep = e.dep();
rational lenX1, lenX2, lenY1, lenY2;
context& ctx = get_context();
if (!get_length(x1, lenX1)) {
add_length_to_eqc(x1);
}
@ -1115,7 +1100,6 @@ bool theory_seq::branch_quat_variable(eq const& e) {
int theory_seq::find_fst_non_empty_idx(expr_ref_vector const& xs) {
context & ctx = get_context();
for (unsigned i = 0; i < xs.size(); ++i) {
expr* x = xs[i];
if (!is_var(x)) return -1;
@ -1140,7 +1124,6 @@ expr* theory_seq::find_fst_non_empty_var(expr_ref_vector const& x) {
}
bool theory_seq::branch_variable_eq() {
context& ctx = get_context();
unsigned sz = m_eqs.size();
int start = ctx.get_random_value();
@ -1195,7 +1178,7 @@ bool theory_seq::find_branch_candidate(unsigned& start, dependency* dep, expr_re
return false;
}
TRACE("seq", tout << mk_pp(l, m) << ": " << get_context().get_scope_level() << " - start:" << start << "\n";);
TRACE("seq", tout << mk_pp(l, m) << ": " << ctx.get_scope_level() << " - start:" << start << "\n";);
expr_ref v0(m);
v0 = m_util.str.mk_empty(m.get_sort(l));
@ -1228,7 +1211,6 @@ bool theory_seq::find_branch_candidate(unsigned& start, dependency* dep, expr_re
all_units &= m_util.str.is_unit(r);
}
if (all_units) {
context& ctx = get_context();
literal_vector lits;
lits.push_back(~mk_eq_empty(l));
for (unsigned i = 0; i < rs.size(); ++i) {
@ -1282,7 +1264,6 @@ bool theory_seq::can_be_equal(unsigned szl, expr* const* ls, unsigned szr, expr*
lbool theory_seq::assume_equality(expr* l, expr* r) {
context& ctx = get_context();
if (m_exclude.contains(l, r)) {
return l_false;
}
@ -1400,7 +1381,7 @@ bool theory_seq::check_length_coherence0(expr* e) {
}
if (p || r != l_false) {
if (!get_context().at_base_level()) {
if (!ctx.at_base_level()) {
m_trail_stack.push(push_replay(alloc(replay_length_coherence, m, e)));
}
return true;
@ -1440,7 +1421,6 @@ bool theory_seq::check_length_coherence() {
}
bool theory_seq::reduce_length_eq() {
context& ctx = get_context();
int start = ctx.get_random_value();
for (unsigned i = 0; !ctx.inconsistent() && i < m_eqs.size(); ++i) {

View file

@ -26,7 +26,6 @@ Author:
using namespace smt;
bool theory_seq::solve_nqs(unsigned i) {
context & ctx = get_context();
for (; !ctx.inconsistent() && i < m_nqs.size(); ++i) {
if (solve_ne(i)) {
m_nqs.erase_and_swap(i--);
@ -48,7 +47,6 @@ bool theory_seq::solve_ne(unsigned idx) {
bool theory_seq::check_ne_literals(unsigned idx, unsigned& num_undef_lits) {
ne const& n = m_nqs[idx];
context& ctx = get_context();
for (literal lit : n.lits()) {
switch (ctx.get_assignment(lit)) {
case l_false:
@ -73,7 +71,6 @@ bool theory_seq::check_ne_literals(unsigned idx, unsigned& num_undef_lits) {
bool theory_seq::propagate_ne2lit(unsigned idx) {
ne const& n = m_nqs[idx];
context& ctx = get_context();
if (!n.eqs().empty()) {
return false;
}
@ -145,7 +142,6 @@ bool theory_seq::propagate_ne2eq(unsigned idx, expr_ref_vector const& es) {
bool theory_seq::reduce_ne(unsigned idx) {
ne const& n = m_nqs[idx];
context& ctx = get_context();
bool updated = false;
dependency* new_deps = n.dep();
vector<decomposed_eq> new_eqs;
@ -257,7 +253,6 @@ bool theory_seq::branch_nqs() {
lbool theory_seq::branch_nq(ne const& n) {
context& ctx = get_context();
literal eq_len = mk_eq(mk_len(n.l()), mk_len(n.r()), false);
ctx.mark_as_relevant(eq_len);
switch (ctx.get_assignment(eq_len)) {

View file

@ -2832,9 +2832,8 @@ namespace smt {
}
TRACE("internalize", tout << this << " " << th->get_family_id() << "\n";);
SASSERT(std::find(m_theory_set.begin(), m_theory_set.end(), th) == m_theory_set.end());
SASSERT(!already_internalized_theory(th));
th->init(this);
m_theories.register_plugin(th);
th->init();
m_theory_set.push_back(th);
{
#ifdef Z3DEBUG
@ -4475,7 +4474,7 @@ namespace smt {
bool context::has_case_splits() {
for (unsigned i = get_num_b_internalized(); i-- > 0; ) {
if (get_assignment(i) == l_undef)
if (is_relevant(i) && get_assignment(i) == l_undef)
return true;
}
return false;

View file

@ -232,7 +232,7 @@ namespace smt {
void setup::setup_QF_BVRE() {
setup_QF_BV();
setup_QF_LIA();
m_context.register_plugin(alloc(theory_seq, m_manager, m_params));
m_context.register_plugin(alloc(theory_seq, m_context));
}
void setup::setup_QF_UF(static_features const & st) {
@ -302,19 +302,19 @@ namespace smt {
// to compute the actual value of epsilon even if the input does not have rational numbers.
// Example: (x < 1) and (x > 0)
if (m_manager.proofs_enabled()) {
m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_mi_arith, m_context));
}
else {
if (m_params.m_arith_auto_config_simplex || st.m_num_uninterpreted_constants > 4 * st.m_num_bool_constants
|| st.m_num_ite_terms > 0 /* theory_rdl and theory_frdl do not support ite-terms */) {
// if (!st.m_has_rational && !m_params.m_model && st.arith_k_sum_is_small()) {
// TRACE("rdl_bug", tout << "using theory_smi_arith\n";);
// m_context.register_plugin(alloc(smt::theory_smi_arith, m_manager, m_params));
// m_context.register_plugin(alloc(smt::theory_smi_arith, m_context));
// }
// else {
TRACE("rdl_bug", tout << "using theory_mi_arith\n";);
//setup_lra_arith();
m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_mi_arith, m_context));
// }
}
else {
@ -322,9 +322,9 @@ namespace smt {
m_params.m_arith_propagation_strategy = ARITH_PROP_AGILITY;
m_params.m_arith_add_binary_bounds = true;
if (!st.m_has_rational && !m_params.m_model && st.arith_k_sum_is_small())
m_context.register_plugin(alloc(smt::theory_frdl, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_frdl, m_context));
else
m_context.register_plugin(alloc(smt::theory_rdl, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_rdl, m_context));
}
}
}
@ -375,25 +375,25 @@ namespace smt {
tout << "ARITH_EQ_BOUNDS: " << m_params.m_arith_eq_bounds << "\n";);
if (m_manager.proofs_enabled()) {
m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_mi_arith, m_context));
}
else if (!m_params.m_arith_auto_config_simplex && is_dense(st)) {
TRACE("setup", tout << "using dense diff logic...\n";);
m_params.m_phase_selection = PS_CACHING_CONSERVATIVE;
if (st.arith_k_sum_is_small())
m_context.register_plugin(alloc(smt::theory_dense_si, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_dense_si, m_context));
else
m_context.register_plugin(alloc(smt::theory_dense_i, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_dense_i, m_context));
}
else {
// if (st.arith_k_sum_is_small()) {
// TRACE("setup", tout << "using small integer simplex...\n";);
// m_context.register_plugin(alloc(smt::theory_si_arith, m_manager, m_params));
// TRACE("setup", tout << "using small integer simplex...\n";
// m_context.register_plugin(alloc(smt::theory_si_arith, m_context));
// }
// else {
TRACE("setup", tout << "using big integer simplex...\n";);
m_context.register_plugin(alloc(smt::theory_i_arith, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_i_arith, m_context));
// }
}
}
@ -428,12 +428,12 @@ namespace smt {
m_params.m_restart_strategy = RS_GEOMETRIC;
if (m_manager.proofs_enabled()) {
m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_mi_arith, m_context));
}
else if (st.arith_k_sum_is_small())
m_context.register_plugin(alloc(smt::theory_dense_si, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_dense_si, m_context));
else
m_context.register_plugin(alloc(smt::theory_dense_i, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_dense_i, m_context));
return;
}
}
@ -443,12 +443,12 @@ namespace smt {
m_params.m_restart_factor = 1.5;
m_params.m_restart_adaptive = false;
if (m_manager.proofs_enabled()) {
m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_mi_arith, m_context));
}
// else if (st.arith_k_sum_is_small())
// m_context.register_plugin(alloc(smt::theory_dense_si, m_manager, m_params));
// m_context.register_plugin(alloc(smt::theory_dense_si, m_context));
else
m_context.register_plugin(alloc(smt::theory_i_arith, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_i_arith, m_context));
}
void setup::setup_QF_LRA() {
@ -567,7 +567,7 @@ namespace smt {
m_params.m_bv_cc = false;
m_params.m_bb_ext_gates = true;
m_params.m_nnf_cnf = false;
m_context.register_plugin(alloc(smt::theory_bv, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_bv, m_context));
}
void setup::setup_QF_AUFBV() {
@ -576,7 +576,7 @@ namespace smt {
m_params.m_bv_cc = false;
m_params.m_bb_ext_gates = true;
m_params.m_nnf_cnf = false;
m_context.register_plugin(alloc(smt::theory_bv, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_bv, m_context));
setup_arrays();
}
@ -653,7 +653,7 @@ namespace smt {
//
m_params.m_ng_lift_ite = LI_FULL;
TRACE("setup", tout << "max_eager_multipatterns: " << m_params.m_qi_max_eager_multipatterns << "\n";);
m_context.register_plugin(alloc(smt::theory_i_arith, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_i_arith, m_context));
setup_arrays();
}
@ -711,12 +711,12 @@ namespace smt {
void setup::setup_QF_FP() {
setup_QF_BV();
m_context.register_plugin(alloc(smt::theory_fpa, m_manager));
m_context.register_plugin(alloc(smt::theory_fpa, m_context));
}
void setup::setup_QF_FPBV() {
setup_QF_BV();
m_context.register_plugin(alloc(smt::theory_fpa, m_manager));
m_context.register_plugin(alloc(smt::theory_fpa, m_context));
}
void setup::setup_QF_S() {
@ -731,7 +731,7 @@ namespace smt {
}
else if (m_params.m_string_solver == "empty") {
m_context.register_plugin(alloc(smt::theory_seq_empty, m_manager));
m_context.register_plugin(alloc(smt::theory_seq_empty, m_context));
}
else if (m_params.m_string_solver == "none") {
// don't register any solver.
@ -747,7 +747,7 @@ namespace smt {
void setup::setup_i_arith() {
if (AS_OLD_ARITH == m_params.m_arith_mode) {
m_context.register_plugin(alloc(smt::theory_i_arith, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_i_arith, m_context));
}
else {
setup_lra_arith();
@ -755,20 +755,19 @@ namespace smt {
}
void setup::setup_lra_arith() {
// m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_lra, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_lra, m_context));
}
void setup::setup_mi_arith() {
switch (m_params.m_arith_mode) {
case AS_OPTINF:
m_context.register_plugin(alloc(smt::theory_inf_arith, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_inf_arith, m_context));
break;
case AS_NEW_ARITH:
setup_lra_arith();
break;
default:
m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_mi_arith, m_context));
break;
}
}
@ -790,59 +789,59 @@ namespace smt {
}
switch(mode) {
case AS_NO_ARITH:
m_context.register_plugin(alloc(smt::theory_dummy, m_manager.mk_family_id("arith"), "no arithmetic"));
m_context.register_plugin(alloc(smt::theory_dummy, m_context, m_manager.mk_family_id("arith"), "no arithmetic"));
break;
case AS_DIFF_LOGIC:
m_params.m_arith_eq2ineq = true;
if (fixnum) {
if (int_only)
m_context.register_plugin(alloc(smt::theory_fidl, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_fidl, m_context));
else
m_context.register_plugin(alloc(smt::theory_frdl, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_frdl, m_context));
}
else {
if (int_only)
m_context.register_plugin(alloc(smt::theory_idl, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_idl, m_context));
else
m_context.register_plugin(alloc(smt::theory_rdl, m_manager, m_params));
}
m_context.register_plugin(alloc(smt::theory_rdl, m_context));
}
break;
case AS_DENSE_DIFF_LOGIC:
m_params.m_arith_eq2ineq = true;
if (fixnum) {
if (int_only)
m_context.register_plugin(alloc(smt::theory_dense_si, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_dense_si, m_context));
else
m_context.register_plugin(alloc(smt::theory_dense_smi, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_dense_smi, m_context));
}
else {
if (int_only)
m_context.register_plugin(alloc(smt::theory_dense_i, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_dense_i, m_context));
else
m_context.register_plugin(alloc(smt::theory_dense_mi, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_dense_mi, m_context));
}
break;
case AS_UTVPI:
m_params.m_arith_eq2ineq = true;
if (int_only)
m_context.register_plugin(alloc(smt::theory_iutvpi, m_manager));
m_context.register_plugin(alloc(smt::theory_iutvpi, m_context));
else
m_context.register_plugin(alloc(smt::theory_rutvpi, m_manager));
m_context.register_plugin(alloc(smt::theory_rutvpi, m_context));
break;
case AS_OPTINF:
m_context.register_plugin(alloc(smt::theory_inf_arith, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_inf_arith, m_context));
break;
case AS_OLD_ARITH:
if (m_params.m_arith_int_only && int_only)
m_context.register_plugin(alloc(smt::theory_i_arith, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_i_arith, m_context));
else
m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_mi_arith, m_context));
break;
case AS_NEW_ARITH:
setup_lra_arith();
break;
default:
m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_mi_arith, m_context));
break;
}
}
@ -850,10 +849,10 @@ namespace smt {
void setup::setup_bv() {
switch(m_params.m_bv_mode) {
case BS_NO_BV:
m_context.register_plugin(alloc(smt::theory_dummy, m_manager.mk_family_id("bv"), "no bit-vector"));
m_context.register_plugin(alloc(smt::theory_dummy, m_context, m_manager.mk_family_id("bv"), "no bit-vector"));
break;
case BS_BLASTER:
m_context.register_plugin(alloc(smt::theory_bv, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_bv, m_context));
break;
}
}
@ -861,33 +860,33 @@ namespace smt {
void setup::setup_arrays() {
switch(m_params.m_array_mode) {
case AR_NO_ARRAY:
m_context.register_plugin(alloc(smt::theory_dummy, m_manager.mk_family_id("array"), "no array"));
m_context.register_plugin(alloc(smt::theory_dummy, m_context, m_manager.mk_family_id("array"), "no array"));
break;
case AR_SIMPLE:
m_context.register_plugin(alloc(smt::theory_array, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_array, m_context));
break;
case AR_MODEL_BASED:
throw default_exception("The model-based array theory solver is deprecated");
break;
case AR_FULL:
m_context.register_plugin(alloc(smt::theory_array_full, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_array_full, m_context));
break;
}
}
void setup::setup_datatypes() {
TRACE("datatype", tout << "registering theory datatype...\n";);
m_context.register_plugin(alloc(theory_datatype, m_manager));
m_context.register_plugin(alloc(theory_datatype, m_context));
}
void setup::setup_recfuns() {
TRACE("recfun", tout << "registering theory recfun...\n";);
theory_recfun * th = alloc(theory_recfun, m_manager);
theory_recfun * th = alloc(theory_recfun, m_context);
m_context.register_plugin(th);
}
void setup::setup_dl() {
m_context.register_plugin(mk_theory_dl(m_manager));
m_context.register_plugin(mk_theory_dl(m_context));
}
void setup::setup_seq_str(static_features const & st) {
@ -899,7 +898,7 @@ namespace smt {
setup_seq();
}
else if (m_params.m_string_solver == "empty") {
m_context.register_plugin(alloc(smt::theory_seq_empty, m_manager));
m_context.register_plugin(alloc(smt::theory_seq_empty, m_context));
}
else if (m_params.m_string_solver == "none") {
// don't register any solver.
@ -918,30 +917,30 @@ namespace smt {
}
void setup::setup_card() {
m_context.register_plugin(alloc(theory_pb, m_manager, m_params));
m_context.register_plugin(alloc(theory_pb, m_context));
}
void setup::setup_fpa() {
setup_bv();
m_context.register_plugin(alloc(theory_fpa, m_manager));
m_context.register_plugin(alloc(theory_fpa, m_context));
}
void setup::setup_str() {
setup_arith();
m_context.register_plugin(alloc(theory_str, m_manager, m_params));
m_context.register_plugin(alloc(theory_str, m_context, m_manager, m_params));
}
void setup::setup_seq() {
m_context.register_plugin(alloc(smt::theory_seq, m_manager, m_params));
m_context.register_plugin(alloc(smt::theory_seq, m_context));
}
void setup::setup_CSP() {
setup_unknown();
m_context.register_plugin(alloc(smt::theory_jobscheduler, m_manager));
m_context.register_plugin(alloc(smt::theory_jobscheduler, m_context));
}
void setup::setup_special_relations() {
m_context.register_plugin(alloc(smt::theory_special_relations, m_manager));
m_context.register_plugin(alloc(smt::theory_special_relations, m_context, m_manager));
}
void setup::setup_unknown() {

View file

@ -22,23 +22,15 @@ Revision History:
namespace smt {
void theory::init(context * ctx) {
SASSERT(m_context == 0);
m_context = ctx;
m_manager = &(ctx->get_manager());
}
void theory::reset_eh() {
m_var2enode.reset();
}
void theory::push_scope_eh() {
SASSERT(m_context);
m_var2enode_lim.push_back(m_var2enode.size());
}
void theory::pop_scope_eh(unsigned num_scopes) {
SASSERT(m_context);
unsigned scope_lvl = m_var2enode_lim.size();
SASSERT(num_scopes <= scope_lvl);
unsigned new_lvl = scope_lvl - num_scopes;
@ -109,19 +101,17 @@ namespace smt {
}
bool theory::is_relevant_and_shared(enode * n) const {
context & ctx = get_context();
return ctx.is_relevant(n) && ctx.is_shared(n);
}
bool theory::assume_eq(enode * n1, enode * n2) {
return get_context().assume_eq(n1, n2);
return ctx.assume_eq(n1, n2);
}
literal theory::mk_eq(expr * a, expr * b, bool gate_ctx) {
if (a == b) {
return true_literal;
}
context & ctx = get_context();
app_ref eq(ctx.mk_eq_atom(a, b), get_manager());
TRACE("mk_var_bug", tout << "mk_eq: " << eq->get_id() << " " << a->get_id() << " " << b->get_id() << "\n";
tout << mk_ll_pp(a, get_manager()) << "\n" << mk_ll_pp(b, get_manager()););
@ -130,7 +120,6 @@ namespace smt {
}
literal theory::mk_preferred_eq(expr* a, expr* b) {
context& ctx = get_context();
ctx.assume_eq(ensure_enode(a), ensure_enode(b));
literal lit = mk_eq(a, b, false);
ctx.force_phase(lit);
@ -138,7 +127,6 @@ namespace smt {
}
enode* theory::ensure_enode(expr* e) {
context& ctx = get_context();
if (!ctx.e_internalized(e)) {
ctx.internalize(e, false);
}
@ -147,22 +135,25 @@ namespace smt {
return n;
}
theory::theory(family_id fid):
theory::theory(context& ctx, family_id fid):
m_id(fid),
m_context(nullptr),
m_manager(nullptr) {
ctx(ctx),
m(ctx.get_manager()) {
}
theory::~theory() {
}
smt_params const& theory::get_fparams() const {
return ctx.get_fparams();
}
void theory::log_axiom_instantiation(literal_vector const& ls) {
ast_manager& m = get_manager();
expr_ref_vector fmls(m);
expr_ref tmp(m);
for (literal l : ls) {
get_context().literal2expr(l, tmp);
ctx.literal2expr(l, tmp);
fmls.push_back(tmp);
}
log_axiom_instantiation(mk_or(fmls));
@ -196,8 +187,8 @@ namespace smt {
enode *orig = std::get<0>(n);
enode *substituted = std::get<1>(n);
if (orig != nullptr) {
quantifier_manager::log_justification_to_root(out, orig, already_visited, get_context(), get_manager());
quantifier_manager::log_justification_to_root(out, substituted, already_visited, get_context(), get_manager());
quantifier_manager::log_justification_to_root(out, orig, already_visited, ctx, get_manager());
quantifier_manager::log_justification_to_root(out, substituted, already_visited, ctx, get_manager());
}
}
out << "[new-match] " << static_cast<void *>(nullptr) << " " << family_name << "#" << axiom_id << " " << family_name << "#" << pattern_id;
@ -221,7 +212,7 @@ namespace smt {
}
theory_var theory::get_th_var(expr* e) const {
return get_th_var(get_context().get_enode(e));
return get_th_var(ctx.get_enode(e));
}
};

View file

@ -30,16 +30,16 @@ namespace smt {
class model_value_proc;
class theory {
protected:
theory_id m_id;
context * m_context;
ast_manager * m_manager;
context & ctx;
ast_manager & m;
enode_vector m_var2enode;
unsigned_vector m_var2enode_lim;
friend class context;
friend class arith_value;
protected:
virtual void init(context * ctx);
/* ---------------------------------------------------
@ -351,11 +351,12 @@ namespace smt {
public:
theory(family_id fid);
theory(context& ctx, family_id fid);
virtual ~theory();
virtual void setup() {
}
virtual void setup() {}
virtual void init() {}
theory_id get_id() const {
return m_id;
@ -366,17 +367,15 @@ namespace smt {
}
context & get_context() const {
SASSERT(m_context);
return *m_context;
return ctx;
}
context & ctx() const { return get_context(); }
ast_manager & get_manager() const {
SASSERT(m_manager);
return *m_manager;
return m;
}
smt_params const& get_fparams() const;
enode * get_enode(theory_var v) const {
SASSERT(v < static_cast<int>(m_var2enode.size()));
return m_var2enode[v];
@ -453,7 +452,7 @@ namespace smt {
void log_axiom_unit(app* r) {
log_axiom_instantiation(r);
m_manager->trace_stream() << "[end-of-instance]\n";
m.trace_stream() << "[end-of-instance]\n";
}
public:

View file

@ -1059,7 +1059,7 @@ namespace smt {
//
// -----------------------------------
public:
theory_arith(ast_manager & m, theory_arith_params & params);
theory_arith(context& ctx);
~theory_arith() override;
theory * mk_fresh(context * new_ctx) override;

View file

@ -419,7 +419,7 @@ namespace smt {
literal l(get_bool_var(), !m_is_true);
// out << "v" << bound::get_var() << " " << bound::get_bound_kind() << " " << get_k() << " ";
// out << l << ":";
th.get_context().display_detailed_literal(out, l);
th.ctx.display_detailed_literal(out, l);
}
// -----------------------------------
@ -766,7 +766,7 @@ namespace smt {
<< "#" << b->get_owner_id() << " " << mk_pp(b->get_owner(), m) << "\n";
}
for (literal l : m_lits) {
out << l << ":"; th.get_context().display_detailed_literal(out, l) << "\n";
out << l << ":"; th.ctx.display_detailed_literal(out, l) << "\n";
}
}
@ -964,7 +964,6 @@ namespace smt {
template<typename Ext>
bool theory_arith<Ext>::is_safe_to_leave(theory_var x, bool inc, bool& has_int, bool& shared) {
context& ctx = get_context();
shared |= ctx.is_shared(get_enode(x));
column & c = m_columns[x];
typename svector<col_entry>::iterator it = c.begin_entries();
@ -1023,7 +1022,6 @@ namespace smt {
return false;
}
else {
context & ctx = get_context();
SASSERT(ctx.e_internalized(n));
enode * e = ctx.get_enode(n);
if (is_attached_to_var(e)) {
@ -1059,7 +1057,7 @@ namespace smt {
template<typename Ext>
inf_eps_rational<inf_rational> theory_arith<Ext>::maximize(theory_var v, expr_ref& blocker, bool& has_shared) {
TRACE("bound_bug", display_var(tout, v); display(tout););
if (get_context().get_fparams().m_threads > 1)
if (ctx.get_fparams().m_threads > 1)
throw default_exception("multi-threaded optimization is not supported");
has_shared = false;
if (!m_nl_monomials.empty()) {
@ -1126,7 +1124,6 @@ namespace smt {
template<typename Ext>
expr_ref theory_arith<Ext>::mk_ge(generic_model_converter& fm, theory_var v, inf_numeral const& val) {
ast_manager& m = get_manager();
context& ctx = get_context();
std::ostringstream strm;
strm << val << " <= " << mk_pp(get_enode(v)->get_owner(), get_manager());
app* b = m.mk_const(symbol(strm.str().c_str()), m.mk_bool_sort());
@ -1158,7 +1155,6 @@ namespace smt {
m_params.m_arith_bound_prop = BP_NONE;
SASSERT(propagation_mode() == BP_NONE); // bound propagation rules are not (yet) handled.
if (bound) {
context& ctx = get_context();
m_bound_watch = ctx.get_bool_var(bound);
}
else {
@ -1189,7 +1185,6 @@ namespace smt {
unsigned num_eqs, enode_pair const * eqs,
unsigned num_params, parameter* params) {
ast_manager& m = get_manager();
context& ctx = get_context();
expr_ref tmp(m), vq(m);
expr* x, *y, *e;
if (null_bool_var == m_bound_watch) {
@ -1332,7 +1327,6 @@ namespace smt {
bool& has_shared, // determine if pivot involves shared variable
theory_var& x_i) { // base variable to pivot with x_j
context& ctx = get_context();
x_i = null_theory_var;
init_gains(x_j, inc, min_gain, max_gain);
has_shared |= ctx.is_shared(get_enode(x_j));
@ -1517,7 +1511,6 @@ namespace smt {
template<typename Ext>
bool theory_arith<Ext>::has_interface_equality(theory_var x) {
theory_var num = get_num_vars();
context& ctx = get_context();
enode* r = get_enode(x)->get_root();
for (theory_var v = 0; v < num; v++) {
if (v == x) continue;
@ -1543,7 +1536,6 @@ namespace smt {
m_stats.m_max_min++;
unsigned best_efforts = 0;
bool inc = false;
context& ctx = get_context();
SASSERT(!maintain_integrality || valid_assignment());
@ -1764,7 +1756,7 @@ namespace smt {
theory_var s = r.get_base_var();
numeral const & coeff = r[it->m_row_idx].m_coeff;
update_gains(inc, s, coeff, min_gain, max_gain);
has_shared |= get_context().is_shared(get_enode(s));
has_shared |= ctx.is_shared(get_enode(s));
}
bool result = false;
if (safe_gain(min_gain, max_gain)) {
@ -2185,7 +2177,7 @@ namespace smt {
enode * r = n->get_root();
enode_vector::const_iterator it = r->begin_parents();
enode_vector::const_iterator end = r->end_parents();
TRACE("shared", tout << get_context().get_scope_level() << " " << v << " " << r->get_num_parents() << "\n";);
TRACE("shared", tout << ctx.get_scope_level() << " " << v << " " << r->get_num_parents() << "\n";);
for (; it != end; ++it) {
enode * parent = *it;
app * o = parent->get_owner();
@ -2237,7 +2229,7 @@ namespace smt {
}
if (result)
get_context().push_trail(restore_size_trail<context, std::pair<theory_var, theory_var>, false>(m_assume_eq_candidates, old_sz));
ctx.push_trail(restore_size_trail<context, std::pair<theory_var, theory_var>, false>(m_assume_eq_candidates, old_sz));
return delayed_assume_eqs();
}
@ -2246,7 +2238,7 @@ namespace smt {
if (m_assume_eq_head == m_assume_eq_candidates.size())
return false;
get_context().push_trail(value_trail<context, unsigned>(m_assume_eq_head));
ctx.push_trail(value_trail<context, unsigned>(m_assume_eq_head));
while (m_assume_eq_head < m_assume_eq_candidates.size()) {
std::pair<theory_var, theory_var> const & p = m_assume_eq_candidates[m_assume_eq_head];
theory_var v1 = p.first;

View file

@ -31,19 +31,18 @@ namespace smt {
template<typename Ext>
void theory_arith<Ext>::found_unsupported_op(app * n) {
if (!m_found_unsupported_op) {
TRACE("arith", tout << "found non supported expression:\n" << mk_pp(n, get_manager()) << "\n";);
get_context().push_trail(value_trail<context, bool>(m_found_unsupported_op));
TRACE("arith", tout << "found non supported expression:\n" << mk_pp(n, m) << "\n";);
ctx.push_trail(value_trail<context, bool>(m_found_unsupported_op));
m_found_unsupported_op = true;
}
}
template<typename Ext>
void theory_arith<Ext>::found_underspecified_op(app * n) {
context& ctx = get_context();
m_underspecified_ops.push_back(n);
ctx.push_trail(push_back_vector<context, ptr_vector<app>>(m_underspecified_ops));
if (!m_found_underspecified_op) {
TRACE("arith", tout << "found underspecified expression:\n" << mk_pp(n, get_manager()) << "\n";);
TRACE("arith", tout << "found underspecified expression:\n" << mk_pp(n, m) << "\n";);
ctx.push_trail(value_trail<context, bool>(m_found_underspecified_op));
m_found_underspecified_op = true;
}
@ -76,7 +75,7 @@ namespace smt {
bool theory_arith<Ext>::process_atoms() const {
if (!adaptive())
return true;
unsigned total_conflicts = get_context().get_num_conflicts();
unsigned total_conflicts = ctx.get_num_conflicts();
if (total_conflicts < 10)
return true;
double f = static_cast<double>(get_num_conflicts())/static_cast<double>(total_conflicts);
@ -106,7 +105,7 @@ namespace smt {
SASSERT(r == static_cast<int>(m_columns.size()));
SASSERT(check_vector_sizes());
bool is_int = is_int_expr(n->get_owner());
TRACE("mk_arith_var", tout << mk_pp(n->get_owner(), get_manager()) << " is_int: " << is_int << "\n";);
TRACE("mk_arith_var", tout << mk_pp(n->get_owner(), m) << " is_int: " << is_int << "\n";);
m_columns .push_back(column());
m_data .push_back(var_data(is_int));
if (random_initial_value()) {
@ -134,9 +133,9 @@ namespace smt {
SASSERT(check_vector_sizes());
SASSERT(m_var_occs[r].empty());
TRACE("mk_arith_var",
tout << "#" << n->get_owner_id() << " :=\n" << mk_ll_pp(n->get_owner(), get_manager()) << "\n";
tout << "#" << n->get_owner_id() << " :=\n" << mk_ll_pp(n->get_owner(), m) << "\n";
tout << "is_attached_to_var: " << is_attached_to_var(n) << ", var: " << n->get_th_var(get_id()) << "\n";);
get_context().attach_th_var(n, this, r);
ctx.attach_th_var(n, this, r);
SASSERT(m_var_occs.back().empty());
return r;
}
@ -183,7 +182,6 @@ namespace smt {
*/
template<typename Ext>
enode * theory_arith<Ext>::mk_enode(app * n) {
context & ctx = get_context();
if (ctx.e_internalized(n))
return ctx.get_enode(n);
else
@ -267,7 +265,6 @@ namespace smt {
*/
template<typename Ext>
void theory_arith<Ext>::internalize_internal_monomial(app * m, unsigned r_id) {
context & ctx = get_context();
if (ctx.e_internalized(m)) {
enode * e = ctx.get_enode(m);
if (is_attached_to_var(e)) {
@ -312,15 +309,15 @@ namespace smt {
*/
template<typename Ext>
theory_var theory_arith<Ext>::internalize_add(app * n) {
TRACE("add_bug", tout << "n: " << mk_pp(n, get_manager()) << "\n";);
CTRACE("internalize_add_bug", n->get_num_args() == 2 && n->get_arg(0) == n->get_arg(1), tout << "n: " << mk_pp(n, get_manager()) << "\n";);
TRACE("add_bug", tout << "n: " << mk_pp(n, m) << "\n";);
CTRACE("internalize_add_bug", n->get_num_args() == 2 && n->get_arg(0) == n->get_arg(1), tout << "n: " << mk_pp(n, m) << "\n";);
SASSERT(m_util.is_add(n));
unsigned r_id = mk_row();
scoped_row_vars _sc(m_row_vars, m_row_vars_top);
for (expr* arg : *n) {
if (is_var(arg)) {
std::ostringstream strm;
strm << mk_pp(n, get_manager()) << " contains a free variable";
strm << mk_pp(n, m) << " contains a free variable";
throw default_exception(strm.str());
}
internalize_internal_monomial(to_app(arg), r_id);
@ -348,17 +345,17 @@ namespace smt {
\brief Internalize a term (* x y z) that does not contain a coefficient (numeral).
*/
template<typename Ext>
theory_var theory_arith<Ext>::internalize_mul_core(app * m) {
TRACE("internalize_mul_core", tout << "internalizing...\n" << mk_pp(m, get_manager()) << "\n";);
if (!m_util.is_mul(m))
return internalize_term_core(m);
for (expr* arg : *m) {
theory_var theory_arith<Ext>::internalize_mul_core(app * t) {
TRACE("internalize_mul_core", tout << "internalizing...\n" << mk_pp(t, m) << "\n";);
if (!m_util.is_mul(t))
return internalize_term_core(t);
for (expr* arg : *t) {
theory_var v = internalize_term_core(to_app(arg));
if (v == null_theory_var) {
mk_var(mk_enode(to_app(arg)));
}
}
enode * e = mk_enode(m);
enode * e = mk_enode(t);
theory_var v = e->get_th_var(get_id());
if (v == null_theory_var) {
v = mk_var(e);
@ -410,7 +407,6 @@ namespace smt {
template<typename Ext>
theory_var theory_arith<Ext>::mk_binary_op(app * n) {
SASSERT(n->get_num_args() == 2);
context & ctx = get_context();
if (ctx.e_internalized(n))
return expr2var(n);
ctx.internalize(n->get_arg(0), false);
@ -423,7 +419,6 @@ namespace smt {
theory_var theory_arith<Ext>::internalize_div(app * n) {
rational r(1);
theory_var s = mk_binary_op(n);
context & ctx = get_context();
if (!m_util.is_numeral(n->get_arg(1), r) || r.is_zero()) found_underspecified_op(n);
if (!ctx.relevancy())
mk_div_axiom(n->get_arg(0), n->get_arg(1));
@ -434,7 +429,6 @@ namespace smt {
theory_var theory_arith<Ext>::internalize_idiv(app * n) {
rational r;
theory_var s = mk_binary_op(n);
context & ctx = get_context();
if (!m_util.is_numeral(n->get_arg(1), r) || r.is_zero()) found_underspecified_op(n);
app * mod = m_util.mk_mod(n->get_arg(0), n->get_arg(1));
ctx.internalize(mod, false);
@ -445,10 +439,9 @@ namespace smt {
template<typename Ext>
theory_var theory_arith<Ext>::internalize_mod(app * n) {
TRACE("arith_mod", tout << "internalizing...\n" << mk_pp(n, get_manager()) << "\n";);
TRACE("arith_mod", tout << "internalizing...\n" << mk_pp(n, m) << "\n";);
rational r(1);
theory_var s = mk_binary_op(n);
context & ctx = get_context();
if (!m_util.is_numeral(n->get_arg(1), r) || r.is_zero()) found_underspecified_op(n);
if (!ctx.relevancy())
mk_idiv_mod_axioms(n->get_arg(0), n->get_arg(1));
@ -459,7 +452,6 @@ namespace smt {
theory_var theory_arith<Ext>::internalize_rem(app * n) {
rational r(1);
theory_var s = mk_binary_op(n);
context & ctx = get_context();
if (!m_util.is_numeral(n->get_arg(1), r) || r.is_zero()) found_underspecified_op(n);
if (!ctx.relevancy()) {
mk_rem_axiom(n->get_arg(0), n->get_arg(1));
@ -469,8 +461,6 @@ namespace smt {
template<typename Ext>
void theory_arith<Ext>::mk_axiom(expr * ante, expr * conseq, bool simplify_conseq) {
ast_manager & m = get_manager();
context & ctx = get_context();
th_rewriter & s = ctx.get_rewriter();
expr_ref s_ante(m), s_conseq(m);
expr* s_conseq_n, * s_ante_n;
@ -526,7 +516,6 @@ namespace smt {
template<typename Ext>
void theory_arith<Ext>::mk_div_axiom(expr * p, expr * q) {
if (!m_util.is_zero(q)) {
ast_manager & m = get_manager();
expr_ref div(m), zero(m), eqz(m), eq(m);
TRACE("div_axiom_bug", tout << "expanding div_axiom for: " << mk_pp(p, m) << " / " << mk_pp(q, m) << "\n";);
div = m_util.mk_div(p, q);
@ -540,9 +529,8 @@ namespace smt {
template<typename Ext>
void theory_arith<Ext>::mk_idiv_mod_axioms(expr * dividend, expr * divisor) {
th_rewriter & s = get_context().get_rewriter();
th_rewriter & s = ctx.get_rewriter();
if (!m_util.is_zero(divisor)) {
ast_manager & m = get_manager();
// if divisor is zero, then idiv and mod are uninterpreted functions.
expr_ref div(m), mod(m), zero(m), abs_divisor(m), one(m);
expr_ref eqz(m), eq(m), lower(m), upper(m);
@ -565,7 +553,6 @@ namespace smt {
mk_axiom(eqz, lower, false);
mk_axiom(eqz, upper, !m_util.is_numeral(abs_divisor));
rational k;
context& ctx = get_context();
if (!m_util.is_numeral(divisor)) {
// (=> (> y 0) (<= (* y (div x y)) x))
@ -577,7 +564,6 @@ namespace smt {
mk_axiom(div_non_pos, div_ge, false);
}
(void)ctx;
if (m_params.m_arith_enum_const_mod && m_util.is_numeral(divisor, k) &&
k.is_pos() && k < rational(8)) {
rational j(0);
@ -601,7 +587,6 @@ namespace smt {
template<typename Ext>
void theory_arith<Ext>::mk_rem_axiom(expr * dividend, expr * divisor) {
// if divisor is zero, then rem is an uninterpreted function.
ast_manager & m = get_manager();
expr * zero = m_util.mk_numeral(rational(0), true);
expr * rem = m_util.mk_rem(dividend, divisor);
expr * mod = m_util.mk_mod(dividend, divisor);
@ -623,7 +608,6 @@ namespace smt {
template<typename Ext>
void theory_arith<Ext>::mk_to_int_axiom(app * n) {
SASSERT(m_util.is_to_int(n));
ast_manager & m = get_manager();
expr* x = n->get_arg(0);
// to_int (to_real x) = x
@ -645,7 +629,6 @@ namespace smt {
template<typename Ext>
theory_var theory_arith<Ext>::internalize_to_int(app * n) {
SASSERT(n->get_num_args() == 1);
context & ctx = get_context();
if (ctx.e_internalized(n))
return expr2var(n);
/* theory_var arg = */ internalize_term_core(to_app(n->get_arg(0)));
@ -663,7 +646,6 @@ namespace smt {
template<typename Ext>
void theory_arith<Ext>::mk_is_int_axiom(app * n) {
SASSERT(m_util.is_is_int(n));
ast_manager & m = get_manager();
expr* x = n->get_arg(0);
expr* eq = m.mk_eq(m_util.mk_to_real(m_util.mk_to_int(x)), x);
mk_axiom(m.mk_not(n), eq);
@ -673,7 +655,6 @@ namespace smt {
template<typename Ext>
void theory_arith<Ext>::internalize_is_int(app * n) {
SASSERT(n->get_num_args() == 1);
context & ctx = get_context();
if (ctx.b_internalized(n))
return;
/* theory_var arg = */ internalize_term_core(to_app(n->get_arg(0)));
@ -688,10 +669,9 @@ namespace smt {
template<typename Ext>
theory_var theory_arith<Ext>::internalize_to_real(app * n) {
SASSERT(n->get_num_args() == 1);
context & ctx = get_context();
if (ctx.e_internalized(n))
return expr2var(n);
TRACE("to_real_bug", tout << "to-real\n" << mk_ismt2_pp(n, get_manager()) << "\n";);
TRACE("to_real_bug", tout << "to-real\n" << mk_ismt2_pp(n, m) << "\n";);
theory_var arg = internalize_term_core(to_app(n->get_arg(0)));
// n may be internalized by the call above if n is of the form (to_real (to_int t))
// The internalizer for (to_int t) will create (to_real (to_int t)) and internalize it.
@ -720,7 +700,6 @@ namespace smt {
template<typename Ext>
theory_var theory_arith<Ext>::internalize_numeral(app * n, numeral const& val) {
context& ctx = get_context();
if (ctx.e_internalized(n)) {
return mk_var(ctx.get_enode(n));
}
@ -764,8 +743,7 @@ namespace smt {
*/
template<typename Ext>
theory_var theory_arith<Ext>::internalize_term_core(app * n) {
TRACE("arith_internalize_detail", tout << "internalize_term_core:\n" << mk_pp(n, get_manager()) << "\n";);
context & ctx = get_context();
TRACE("arith_internalize_detail", tout << "internalize_term_core:\n" << mk_pp(n, m) << "\n";);
if (ctx.e_internalized(n)) {
enode * e = ctx.get_enode(n);
if (is_attached_to_var(e))
@ -816,10 +794,10 @@ namespace smt {
return mk_var(mk_enode(n));
}
TRACE("arith_internalize_detail", tout << "before:\n" << mk_pp(n, get_manager()) << "\n";);
TRACE("arith_internalize_detail", tout << "before:\n" << mk_pp(n, m) << "\n";);
if (!ctx.e_internalized(n))
ctx.internalize(n, false);
TRACE("arith_internalize_detail", tout << "after:\n" << mk_pp(n, get_manager()) << "\n";);
TRACE("arith_internalize_detail", tout << "after:\n" << mk_pp(n, m) << "\n";);
enode * e = ctx.get_enode(n);
if (!is_attached_to_var(e))
return mk_var(e);
@ -985,14 +963,14 @@ namespace smt {
template<typename Ext>
void theory_arith<Ext>::mk_clause(literal l1, literal l2, unsigned num_params, parameter * params) {
TRACE("arith", literal lits[2]; lits[0] = l1; lits[1] = l2; get_context().display_literals_verbose(tout, 2, lits); tout << "\n";);
get_context().mk_th_axiom(get_id(), l1, l2, num_params, params);
TRACE("arith", literal lits[2]; lits[0] = l1; lits[1] = l2; ctx.display_literals_verbose(tout, 2, lits); tout << "\n";);
ctx.mk_th_axiom(get_id(), l1, l2, num_params, params);
}
template<typename Ext>
void theory_arith<Ext>::mk_clause(literal l1, literal l2, literal l3, unsigned num_params, parameter * params) {
TRACE("arith", literal lits[3]; lits[0] = l1; lits[1] = l2; lits[2] = l3; get_context().display_literals_verbose(tout, 3, lits); tout << "\n";);
get_context().mk_th_axiom(get_id(), l1, l2, l3, num_params, params);
TRACE("arith", literal lits[3]; lits[0] = l1; lits[1] = l2; lits[2] = l3; ctx.display_literals_verbose(tout, 3, lits); tout << "\n";);
ctx.mk_th_axiom(get_id(), l1, l2, l3, num_params, params);
}
template<typename Ext>
@ -1000,7 +978,7 @@ namespace smt {
theory_var v = a1->get_var();
atoms & occs = m_var_occs[v];
TRACE("mk_bound_axioms", tout << "add bound axioms for v" << v << " " << a1 << "\n";);
if (!get_context().is_searching()) {
if (!ctx.is_searching()) {
//
// NB. We make an assumption that user push calls propagation
// before internal scopes are pushed. This flushes all newly
@ -1247,8 +1225,7 @@ namespace smt {
template<typename Ext>
bool theory_arith<Ext>::internalize_atom(app * n, bool gate_ctx) {
TRACE("arith_internalize", tout << "internalizing atom:\n" << mk_pp(n, this->get_manager()) << "\n";);
context & ctx = get_context();
TRACE("arith_internalize", tout << "internalizing atom:\n" << mk_pp(n, m) << "\n";);
SASSERT(m_util.is_le(n) || m_util.is_ge(n) || m_util.is_is_int(n));
SASSERT(!ctx.b_internalized(n));
atom_kind kind;
@ -1313,7 +1290,7 @@ namespace smt {
template<typename Ext>
bool theory_arith<Ext>::internalize_term(app * term) {
TRACE("arith_internalize", tout << "internalising term:\n" << mk_pp(term, this->get_manager()) << "\n";);
TRACE("arith_internalize", tout << "internalising term:\n" << mk_pp(term, m) << "\n";);
theory_var v = internalize_term_core(term);
TRACE("arith_internalize", tout << "theory_var: " << v << "\n";);
return v != null_theory_var;
@ -1322,8 +1299,7 @@ namespace smt {
template<typename Ext>
void theory_arith<Ext>::internalize_eq_eh(app * atom, bool_var v) {
expr* _lhs = nullptr, *_rhs = nullptr;
if (m_params.m_arith_eager_eq_axioms && get_manager().is_eq(atom, _lhs, _rhs) && is_app(_lhs) && is_app(_rhs)) {
context & ctx = get_context();
if (m_params.m_arith_eager_eq_axioms && m.is_eq(atom, _lhs, _rhs) && is_app(_lhs) && is_app(_rhs)) {
app * lhs = to_app(_lhs);
app * rhs = to_app(_rhs);
enode * n1 = ctx.get_enode(lhs);
@ -1334,7 +1310,7 @@ namespace smt {
if (n1->get_th_var(get_id()) != null_theory_var &&
n2->get_th_var(get_id()) != null_theory_var &&
n1 != n2) {
TRACE("mk_axioms_bug", tout << mk_bounded_pp(atom, get_manager(), 5) << "\n";);
TRACE("mk_axioms_bug", tout << mk_bounded_pp(atom, m, 5) << "\n";);
m_arith_eq_adapter.mk_axioms(n1, n2);
}
}
@ -1350,15 +1326,15 @@ namespace smt {
TRACE("arith_verbose", tout << "p" << v << " := " << (is_true?"true":"false") << "\n";);
atom * a = get_bv2a(v);
if (!a) return;
SASSERT(get_context().get_assignment(a->get_bool_var()) != l_undef);
SASSERT((get_context().get_assignment(a->get_bool_var()) == l_true) == is_true);
SASSERT(ctx.get_assignment(a->get_bool_var()) != l_undef);
SASSERT((ctx.get_assignment(a->get_bool_var()) == l_true) == is_true);
a->assign_eh(is_true, get_epsilon(a->get_var()));
m_asserted_bounds.push_back(a);
}
template<typename Ext>
void theory_arith<Ext>::relevant_eh(app * n) {
TRACE("arith_relevant_eh", tout << "relevant_eh: " << mk_pp(n, get_manager()) << "\n";);
TRACE("arith_relevant_eh", tout << "relevant_eh: " << mk_pp(n, m) << "\n";);
if (m_util.is_mod(n))
mk_idiv_mod_axioms(n->get_arg(0), n->get_arg(1));
else if (m_util.is_rem(n))
@ -1374,8 +1350,8 @@ namespace smt {
template<typename Ext>
void theory_arith<Ext>::new_eq_eh(theory_var v1, theory_var v2) {
TRACE("arith_new_eq_eh", tout << "#" << get_enode(v1)->get_owner_id() << " = #" << get_enode(v2)->get_owner_id() << "\n";);
TRACE("arith_new_eq_eh_detail", tout << mk_pp(get_enode(v1)->get_owner(), get_manager()) << "\n" <<
mk_pp(get_enode(v2)->get_owner(), get_manager()) << "\n";);
TRACE("arith_new_eq_eh_detail", tout << mk_pp(get_enode(v1)->get_owner(), m) << "\n" <<
mk_pp(get_enode(v2)->get_owner(), m) << "\n";);
enode * n1 = get_enode(v1);
@ -1401,10 +1377,9 @@ namespace smt {
else {
if (n1->get_owner_id() > n2->get_owner_id())
std::swap(n1, n2);
sort * st = get_manager().get_sort(n1->get_owner());
sort * st = m.get_sort(n1->get_owner());
app * minus_one = m_util.mk_numeral(rational::minus_one(), st);
app * s = m_util.mk_add(n1->get_owner(), m_util.mk_mul(minus_one, n2->get_owner()));
context & ctx = get_context();
ctx.internalize(s, false);
enode * e_s = ctx.get_enode(s);
ctx.mark_as_relevant(e_s);
@ -1430,8 +1405,8 @@ namespace smt {
template<typename Ext>
void theory_arith<Ext>::new_diseq_eh(theory_var v1, theory_var v2) {
TRACE("arith_new_diseq_eh", tout << mk_bounded_pp(get_enode(v1)->get_owner(), get_manager()) << "\n" <<
mk_bounded_pp(get_enode(v2)->get_owner(), get_manager()) << "\n";);
TRACE("arith_new_diseq_eh", tout << mk_bounded_pp(get_enode(v1)->get_owner(), m) << "\n" <<
mk_bounded_pp(get_enode(v2)->get_owner(), m) << "\n";);
m_stats.m_assert_diseq++;
m_arith_eq_adapter.new_diseq_eh(v1, v2);
}
@ -1463,7 +1438,7 @@ namespace smt {
final_check_status result = FC_DONE;
final_check_status ok;
do {
if (get_context().get_cancel_flag()) {
if (ctx.get_cancel_flag()) {
return FC_GIVEUP;
}
@ -1497,7 +1472,7 @@ namespace smt {
case FC_CONTINUE:
TRACE("arith",
tout << "continue arith..."
<< (get_context().inconsistent()?"inconsistent\n":"\n"););
<< (ctx.inconsistent()?"inconsistent\n":"\n"););
return FC_CONTINUE;
}
}
@ -1518,7 +1493,7 @@ namespace smt {
return FC_CONTINUE;
if (delayed_assume_eqs())
return FC_CONTINUE;
get_context().push_trail(value_trail<context, unsigned>(m_final_check_idx));
ctx.push_trail(value_trail<context, unsigned>(m_final_check_idx));
m_liberal_final_check = true;
m_changed_assignment = false;
final_check_status result = final_check_core();
@ -1566,7 +1541,7 @@ namespace smt {
failed();
return false;
}
if (get_context().get_cancel_flag()) {
if (ctx.get_cancel_flag()) {
return true;
}
CASSERT("arith", satisfy_bounds());
@ -1698,19 +1673,19 @@ namespace smt {
}
template<typename Ext>
theory_arith<Ext>::theory_arith(ast_manager & m, theory_arith_params & params):
theory(m.mk_family_id("arith")),
m_params(params),
theory_arith<Ext>::theory_arith(context& ctx):
theory(ctx, ctx.get_manager().mk_family_id("arith")),
m_params(ctx.get_fparams()),
m_util(m),
m_arith_eq_solver(m),
m_found_unsupported_op(false),
m_found_underspecified_op(false),
m_arith_eq_adapter(*this, params, m_util),
m_arith_eq_adapter(*this, m_util),
m_asserted_qhead(0),
m_row_vars_top(0),
m_to_patch(1024),
m_blands_rule(false),
m_random(params.m_arith_random_seed),
m_random(ctx.get_fparams().m_arith_random_seed),
m_num_conflicts(0),
m_branch_cut_counter(0),
m_eager_gcd(m_params.m_arith_eager_gcd),
@ -1733,7 +1708,7 @@ namespace smt {
template<typename Ext>
theory* theory_arith<Ext>::mk_fresh(context* new_ctx) {
return alloc(theory_arith<Ext>, new_ctx->get_manager(), new_ctx->get_fparams());
return alloc(theory_arith<Ext>, *new_ctx);
}
template<typename Ext>
@ -1846,7 +1821,7 @@ namespace smt {
SASSERT(!is_non_base(v));
add_row(r1, c, get_var_row(v), false);
}
get_manager().limit().inc(sz);
m.limit().inc(sz);
}
// -----------------------------------
@ -1899,7 +1874,7 @@ namespace smt {
if (is_base(v) && !m_to_patch.contains(v) && (below_lower(v) || above_upper(v))) {
m_to_patch.insert(v);
}
get_manager().limit().inc();
m.limit().inc();
}
/**
@ -1974,7 +1949,7 @@ namespace smt {
DIVIDE_ROW(it->m_coeff /= tmp);
}
get_manager().limit().inc(r.size());
m.limit().inc(r.size());
set_var_row(x_i, -1);
set_var_row(x_j, r_id);
@ -2028,7 +2003,7 @@ namespace smt {
a_kj = r2[it->m_row_idx].m_coeff;
a_kj.neg();
add_row(it->m_row_id, a_kj, r_id, apply_gcd_test);
get_manager().limit().inc((r1_sz + r2.size()) * (a_kj.storage_size()));
m.limit().inc((r1_sz + r2.size()) * (a_kj.storage_size()));
}
}
else {
@ -2210,7 +2185,7 @@ namespace smt {
template<typename Ext>
theory_var theory_arith<Ext>::select_pivot(theory_var x_i, bool is_below, numeral & out_a_ij) {
TRACE("select_pivot", tout << "m_blands_rule: " << m_blands_rule << " v" << x_i << "\n";);
CTRACE("select_pivot_info", x_i > 500, get_context().display(tout););
CTRACE("select_pivot_info", x_i > 500, ctx.display(tout););
if (m_blands_rule)
return select_blands_pivot_core(x_i, is_below, out_a_ij);
else if (is_below)
@ -2352,7 +2327,7 @@ namespace smt {
return false;
}
TRACE("arith_make_feasible_detail", display(tout););
if (get_context().get_cancel_flag()) {
if (ctx.get_cancel_flag()) {
return true;
}
}
@ -2794,7 +2769,6 @@ namespace smt {
if (!relax_bounds() && (!ante.lits().empty() || !ante.eqs().empty())) {
return;
}
context & ctx = get_context();
row_entry const & entry = r[idx];
numeral coeff = entry.m_coeff;
if (relax_bounds()) {
@ -2903,7 +2877,7 @@ namespace smt {
for (atom* a : as) {
bool_var bv = a->get_bool_var();
literal l(bv);
if (get_context().get_assignment(bv) == l_undef) {
if (ctx.get_assignment(bv) == l_undef) {
inf_numeral const & k2 = a->get_k();
delta.reset();
if (a->get_atom_kind() == A_LOWER) {
@ -2966,7 +2940,6 @@ namespace smt {
template<typename Ext>
void theory_arith<Ext>::dump_lemmas(literal l, antecedents const& ante) {
context & ctx = get_context();
if (dump_lemmas()) {
TRACE("arith", ante.display(tout) << " --> "; ctx.display_detailed_literal(tout, l); tout << "\n";);
ctx.display_lemma_as_smt_problem(ante.lits().size(), ante.lits().c_ptr(),
@ -2977,7 +2950,6 @@ namespace smt {
template<typename Ext>
void theory_arith<Ext>::dump_lemmas(literal l, derived_bound const& ante) {
context & ctx = get_context();
if (dump_lemmas()) {
ctx.display_lemma_as_smt_problem(ante.lits().size(), ante.lits().c_ptr(),
ante.eqs().size(), ante.eqs().c_ptr(), l);
@ -2987,7 +2959,6 @@ namespace smt {
template<typename Ext>
void theory_arith<Ext>::assign_bound_literal(literal l, row const & r, unsigned idx, bool is_lower, inf_numeral & delta) {
m_stats.m_bound_props++;
context & ctx = get_context();
antecedents ante(*this);
explain_bound(r, idx, is_lower, delta, ante);
@ -3091,7 +3062,6 @@ namespace smt {
void theory_arith<Ext>::set_conflict(unsigned num_literals, literal const * lits, unsigned num_eqs, enode_pair const * eqs,
antecedents& bounds, char const* proof_rule) {
SASSERT(num_literals != 0 || num_eqs != 0);
context & ctx = get_context();
m_stats.m_conflicts++;
m_num_conflicts++;
TRACE("arith_conflict",
@ -3230,7 +3200,7 @@ namespace smt {
for (theory_var v = 0; v < num; v++) {
if (is_int_src(v))
continue;
if (!get_context().is_shared(get_enode(v)))
if (!ctx.is_shared(get_enode(v)))
continue;
inf_numeral const & val = get_value(v);
if (Ext::is_infinite(val)) {
@ -3263,13 +3233,13 @@ namespace smt {
}
template<typename Ext>
void theory_arith<Ext>::init_model(model_generator & m) {
void theory_arith<Ext>::init_model(model_generator & mg) {
TRACE("theory_arith", tout << "init model invoked...\n";
for (app* n : m_underspecified_ops) {
tout << mk_pp(n, get_manager()) << "\n";
tout << mk_pp(n, m) << "\n";
});
m_factory = alloc(arith_factory, get_manager());
m.register_factory(m_factory);
m_factory = alloc(arith_factory, m);
mg.register_factory(m_factory);
if (!m_model_depends_on_computed_epsilon) {
compute_epsilon();
refine_epsilon();

View file

@ -71,7 +71,7 @@ void theory_arith<Ext>::mark_dependents(theory_var v, svector<theory_var> & vars
expr * n = var2expr(v);
SASSERT(m_util.is_mul(n));
for (expr * curr : *to_app(n)) {
if (get_context().e_internalized(curr)) {
if (ctx.e_internalized(curr)) {
theory_var v = expr2var(curr);
SASSERT(v != null_theory_var);
mark_var(v, vars, already_found);
@ -120,7 +120,6 @@ void theory_arith<Ext>::get_non_linear_cluster(svector<theory_var> & vars) {
return;
var_set already_found;
row_set already_visited_rows;
context & ctx = get_context();
for (theory_var v : m_nl_monomials) {
expr * n = var2expr(v);
if (ctx.is_relevant(n))
@ -539,7 +538,6 @@ template<typename Ext>
bool theory_arith<Ext>::propagate_nl_bounds() {
m_dep_manager.reset();
bool propagated = false;
context & ctx = get_context();
for (unsigned i = 0; i < m_nl_monomials.size(); i++) {
theory_var v = m_nl_monomials[i];
expr * m = var2expr(v);
@ -626,7 +624,6 @@ bool theory_arith<Ext>::check_monomial_assignment(theory_var v, bool & computed_
template<typename Ext>
bool theory_arith<Ext>::check_monomial_assignments() {
bool computed_epsilon = false;
context & ctx = get_context();
for (theory_var v : m_nl_monomials) {
TRACE("non_linear", tout << "v" << v << " is relevant: " << ctx.is_relevant(get_enode(v)) << "\n";
tout << "check_monomial_assignments result: " << check_monomial_assignment(v, computed_epsilon) << "\n";
@ -653,7 +650,6 @@ bool theory_arith<Ext>::check_monomial_assignments() {
template<typename Ext>
theory_var theory_arith<Ext>::find_nl_var_for_branching() {
TRACE("nl_branching", tout << "looking for variable to branch...\n"; display(tout););
context & ctx = get_context();
theory_var target = null_theory_var;
bool bounded = false;
unsigned n = 0;
@ -717,7 +713,6 @@ bool theory_arith<Ext>::branch_nl_int_var(theory_var v) {
else
bound = m_util.mk_eq(var2expr(v), m_util.mk_numeral(rational(0), true));
TRACE("non_linear", tout << "new bound:\n" << mk_pp(bound, get_manager()) << "\n";);
context & ctx = get_context();
ast_manager & m = get_manager();
{
std::function<expr*(void)> fn = [&]() { return m.mk_or(bound, m.mk_not(bound)); };
@ -739,7 +734,7 @@ bool theory_arith<Ext>::is_monomial_linear(expr * m) const {
SASSERT(is_pure_monomial(m));
unsigned num_nl_vars = 0;
for (expr* arg : *to_app(m)) {
if (!get_context().e_internalized(arg))
if (!ctx.e_internalized(arg))
return false;
theory_var _var = expr2var(arg);
CTRACE("non_linear", is_fixed(_var),
@ -811,7 +806,6 @@ bool theory_arith<Ext>::propagate_linear_monomial(theory_var v) {
TRACE("non_linear", tout << "new linear monomial... k: " << k << "\n";);
expr * x_n = k.is_zero() ? nullptr : get_monomial_non_fixed_var(m);
TRACE("non_linear_bug", if (x_n != 0) { tout << "x_n: " << mk_bounded_pp(x_n, get_manager()) << "\nx_n: #" << x_n->get_id() << "\n"; });
context & ctx = get_context();
derived_bound * new_lower = nullptr;
derived_bound * new_upper = nullptr;
if (x_n != nullptr) {
@ -832,7 +826,7 @@ bool theory_arith<Ext>::propagate_linear_monomial(theory_var v) {
ctx.internalize(rhs, false);
ctx.mark_as_relevant(rhs);
}
TRACE("non_linear_bug", tout << "enode: " << get_context().get_enode(rhs) << " enode_id: " << get_context().get_enode(rhs)->get_owner_id() << "\n";);
TRACE("non_linear_bug", tout << "enode: " << ctx.get_enode(rhs) << " enode_id: " << ctx.get_enode(rhs)->get_owner_id() << "\n";);
theory_var new_v = expr2var(rhs);
SASSERT(new_v != null_theory_var);
new_lower = alloc(derived_bound, new_v, inf_numeral(0), B_LOWER);
@ -1126,7 +1120,6 @@ void theory_arith<Ext>::display_coeff_exprs(std::ostream & out, buffer<coeff_exp
*/
template<typename Ext>
bool theory_arith<Ext>::get_polynomial_info(buffer<coeff_expr> const & p, sbuffer<var_num_occs> & varinfo) {
context & ctx = get_context();
varinfo.reset();
m_var2num_occs.reset();
@ -1841,7 +1834,7 @@ void theory_arith<Ext>::set_conflict(v_dependency * d) {
derived_bound b(null_theory_var, inf_numeral(0), B_LOWER);
dependency2new_bound(d, b);
set_conflict(b, ante, "arith_nl");
TRACE("non_linear", for (literal lit : b.m_lits) get_context().display_literal_verbose(tout, lit) << "\n"; tout << "\n";);
TRACE("non_linear", for (literal lit : b.m_lits) ctx.display_literal_verbose(tout, lit) << "\n"; tout << "\n";);
}
/**
@ -2107,7 +2100,6 @@ bool theory_arith<Ext>::internalize_gb_eq(grobner::equation const * eq) {
else
args.push_back(monomial2expr(eq->get_monomial(i), is_int));
}
context & ctx = get_context();
th_rewriter& s = ctx.get_rewriter();
expr_ref pol(get_manager());
SASSERT(!args.empty());
@ -2145,7 +2137,7 @@ void theory_arith<Ext>::update_statistics(grobner & gb) {
template<typename Ext>
void theory_arith<Ext>::set_gb_exhausted() {
IF_VERBOSE(3, verbose_stream() << "Grobner basis computation interrupted. Increase threshold using NL_ARITH_GB_THRESHOLD=<limit>\n";);
get_context().push_trail(value_trail<context, bool>(m_nl_gb_exhausted));
ctx.push_trail(value_trail<context, bool>(m_nl_gb_exhausted));
m_nl_gb_exhausted = true;
}
@ -2225,7 +2217,7 @@ bool theory_arith<Ext>::scan_for_linear(ptr_vector<grobner::equation>& eqs, grob
template<typename Ext>
bool theory_arith<Ext>::compute_basis_loop(grobner & gb) {
while (gb.get_num_new_equations() < m_params.m_nl_arith_gb_threshold) {
if (get_context().get_cancel_flag()) {
if (ctx.get_cancel_flag()) {
return false;
}
if (gb.compute_basis_step())
@ -2260,7 +2252,7 @@ typename theory_arith<Ext>::gb_result theory_arith<Ext>::compute_grobner(svector
compute_basis(gb, warn);
update_statistics(gb);
TRACE("non_linear_gb", tout << "after:\n"; gb.display(tout););
if (get_context().get_cancel_flag())
if (ctx.get_cancel_flag())
return GB_FAIL;
if (get_gb_eqs_and_look_for_conflict(eqs, gb))
return GB_PROGRESS;
@ -2282,7 +2274,7 @@ bool theory_arith<Ext>::max_min_nl_vars() {
expr * n = var2expr(v);
SASSERT(is_pure_monomial(n));
for (expr * curr : *to_app(n)) {
if (get_context().e_internalized(curr)) {
if (ctx.e_internalized(curr)) {
theory_var v = expr2var(curr);
SASSERT(v != null_theory_var);
mark_var(v, vars, already_found);
@ -2321,12 +2313,12 @@ final_check_status theory_arith<Ext>::process_non_linear() {
return FC_GIVEUP;
}
get_context().push_trail(value_trail<context, unsigned>(m_nl_rounds));
ctx.push_trail(value_trail<context, unsigned>(m_nl_rounds));
m_nl_rounds++;
elim_quasi_base_rows();
move_non_base_vars_to_bounds();
TRACE("non_linear_verbose", tout << "processing non linear constraints...\n"; get_context().display(tout););
TRACE("non_linear_verbose", tout << "processing non linear constraints...\n"; ctx.display(tout););
if (!make_feasible()) {
TRACE("non_linear", tout << "failed to move variables to bounds.\n";);
failed();
@ -2345,7 +2337,7 @@ final_check_status theory_arith<Ext>::process_non_linear() {
bool progress;
unsigned old_idx = m_nl_strategy_idx;
get_context().push_trail(value_trail<context, unsigned>(m_nl_strategy_idx));
ctx.push_trail(value_trail<context, unsigned>(m_nl_strategy_idx));
do {
progress = false;

View file

@ -24,12 +24,14 @@ Revision History:
namespace smt {
theory_array::theory_array(ast_manager & m, theory_array_params & params):
theory_array_base(m),
m_params(params),
theory_array::theory_array(context& ctx):
theory_array_base(ctx),
m_params(ctx.get_fparams()),
m_find(*this),
m_trail_stack(*this),
m_final_check_idx(0) {
if (!ctx.relevancy())
m_params.m_array_laziness = 0;
}
theory_array::~theory_array() {
@ -37,17 +39,11 @@ namespace smt {
m_var_data.reset();
}
void theory_array::init(context * ctx) {
theory_array_base::init(ctx);
if (!ctx->relevancy())
m_params.m_array_laziness = 0;
}
void theory_array::merge_eh(theory_var v1, theory_var v2, theory_var, theory_var) {
// v1 is the new root
TRACE("array",
tout << "merging v" << v1 << " v" << v2 << "\n"; display_var(tout, v1);
tout << mk_pp(get_enode(v1)->get_owner(), get_manager()) << " <- " << mk_pp(get_enode(v2)->get_owner(), get_manager()) << "\n";);
tout << mk_pp(get_enode(v1)->get_owner(), m) << " <- " << mk_pp(get_enode(v2)->get_owner(), m) << "\n";);
SASSERT(v1 == find(v1));
var_data * d1 = m_var_data[v1];
var_data * d2 = m_var_data[v2];
@ -67,8 +63,6 @@ namespace smt {
}
theory_var theory_array::mk_var(enode * n) {
ast_manager& m = get_manager();
context& ctx = get_context();
theory_var r = theory_array_base::mk_var(n);
VERIFY(r == static_cast<theory_var>(m_find.mk_var()));
SASSERT(r == static_cast<int>(m_var_data.size()));
@ -95,7 +89,7 @@ namespace smt {
v = find(v);
var_data * d = m_var_data[v];
d->m_parent_selects.push_back(s);
TRACE("array", tout << v << " " << mk_pp(s->get_owner(), get_manager()) << " " << mk_pp(get_enode(v)->get_owner(), get_manager()) << "\n";);
TRACE("array", tout << v << " " << mk_pp(s->get_owner(), m) << " " << mk_pp(get_enode(v)->get_owner(), m) << "\n";);
m_trail_stack.push(push_back_trail<theory_array, enode *, false>(d->m_parent_selects));
for (enode* n : d->m_stores) {
instantiate_axiom2a(s, n);
@ -202,7 +196,7 @@ namespace smt {
}
void theory_array::instantiate_axiom1(enode * store) {
TRACE("array", tout << "axiom 1:\n" << mk_bounded_pp(store->get_owner(), get_manager()) << "\n";);
TRACE("array", tout << "axiom 1:\n" << mk_bounded_pp(store->get_owner(), m) << "\n";);
SASSERT(is_store(store));
m_stats.m_num_axiom1++;
assert_store_axiom1(store);
@ -244,8 +238,7 @@ namespace smt {
// Internalize the term. If it has already been internalized, return false.
//
bool theory_array::internalize_term_core(app * n) {
TRACE("array_bug", tout << mk_bounded_pp(n, get_manager()) << "\n";);
context & ctx = get_context();
TRACE("array_bug", tout << mk_bounded_pp(n, m) << "\n";);
unsigned num_args = n->get_num_args();
for (unsigned i = 0; i < num_args; i++)
ctx.internalize(n->get_arg(i), false);
@ -256,7 +249,7 @@ namespace smt {
if (!is_attached_to_var(e))
mk_var(e);
if (get_manager().is_bool(n)) {
if (m.is_bool(n)) {
bool_var bv = ctx.mk_bool_var(n);
ctx.set_var_theory(bv, get_id());
ctx.set_enode_flag(bv, true);
@ -270,11 +263,10 @@ namespace smt {
found_unsupported_op(n);
return false;
}
TRACE("array_bug", tout << mk_bounded_pp(n, get_manager()) << "\n";);
TRACE("array_bug", tout << mk_bounded_pp(n, m) << "\n";);
if (!internalize_term_core(n)) {
return true;
}
context & ctx = get_context();
enode * arg0 = ctx.get_enode(n->get_arg(0));
if (!is_attached_to_var(arg0))
mk_var(arg0);
@ -315,8 +307,8 @@ namespace smt {
v2 = find(v2);
var_data * d1 = m_var_data[v1];
TRACE("ext", tout << "extensionality: " << d1->m_is_array << "\n"
<< mk_bounded_pp(get_enode(v1)->get_owner(), get_manager(), 5) << "\n"
<< mk_bounded_pp(get_enode(v2)->get_owner(), get_manager(), 5) << "\n";);
<< mk_bounded_pp(get_enode(v1)->get_owner(), m, 5) << "\n"
<< mk_bounded_pp(get_enode(v2)->get_owner(), m, 5) << "\n";);
if (d1->m_is_array) {
SASSERT(m_var_data[v2]->m_is_array);
@ -327,12 +319,11 @@ namespace smt {
void theory_array::relevant_eh(app * n) {
if (m_params.m_array_laziness == 0)
return;
if (get_manager().is_ite(n)) {
TRACE("array", tout << "relevant ite " << mk_pp(n, get_manager()) << "\n";);
if (m.is_ite(n)) {
TRACE("array", tout << "relevant ite " << mk_pp(n, m) << "\n";);
}
if (!is_store(n) && !is_select(n))
return;
context & ctx = get_context();
if (!ctx.e_internalized(n)) ctx.internalize(n, false);
enode * arg = ctx.get_enode(n->get_arg(0));
theory_var v_arg = arg->get_th_var(get_id());
@ -399,7 +390,7 @@ namespace smt {
}
}
bool should_giveup = m_found_unsupported_op || has_propagate_up_trail();
if (r == FC_DONE && should_giveup && !get_context().get_fparams().m_array_fake_support)
if (r == FC_DONE && should_giveup && !ctx.get_fparams().m_array_fake_support)
r = FC_GIVEUP;
CTRACE("array", r != FC_DONE || m_found_unsupported_op, tout << r << "\n";);
return r;

View file

@ -55,7 +55,6 @@ namespace smt {
th_trail_stack m_trail_stack;
unsigned m_final_check_idx;
void init(context * ctx) override;
theory_var mk_var(enode * n) override;
bool internalize_atom(app * atom, bool gate_ctx) override;
bool internalize_term(app * term) override;
@ -96,10 +95,10 @@ namespace smt {
static void display_ids(std::ostream & out, unsigned n, enode * const * v);
public:
theory_array(ast_manager & m, theory_array_params & params);
theory_array(context& ctx);
~theory_array() override;
theory * mk_fresh(context * new_ctx) override { return alloc(theory_array, new_ctx->get_manager(), new_ctx->get_fparams()); }
theory * mk_fresh(context * new_ctx) override { return alloc(theory_array, *new_ctx); }
char const * get_name() const override { return "array"; }

View file

@ -26,28 +26,28 @@ Revision History:
namespace smt {
theory_array_base::theory_array_base(ast_manager & m):
theory(m.mk_family_id("array")),
theory_array_base::theory_array_base(context& ctx):
theory(ctx, ctx.get_manager().mk_family_id("array")),
m_found_unsupported_op(false),
m_array_weak_head(0)
{
}
void theory_array_base::add_weak_var(theory_var v) {
get_context().push_trail(push_back_vector<context, svector<theory_var>>(m_array_weak_trail));
ctx.push_trail(push_back_vector<context, svector<theory_var>>(m_array_weak_trail));
m_array_weak_trail.push_back(v);
}
void theory_array_base::found_unsupported_op(expr * n) {
if (!get_context().get_fparams().m_array_fake_support && !m_found_unsupported_op) {
TRACE("array", tout << mk_ll_pp(n, get_manager()) << "\n";);
get_context().push_trail(value_trail<context, bool>(m_found_unsupported_op));
if (!ctx.get_fparams().m_array_fake_support && !m_found_unsupported_op) {
TRACE("array", tout << mk_ll_pp(n, m) << "\n";);
ctx.push_trail(value_trail<context, bool>(m_found_unsupported_op));
m_found_unsupported_op = true;
}
}
app * theory_array_base::mk_select(unsigned num_args, expr * const * args) {
app * r = get_manager().mk_app(get_family_id(), OP_SELECT, 0, nullptr, num_args, args);
app * r = m.mk_app(get_family_id(), OP_SELECT, 0, nullptr, num_args, args);
TRACE("mk_var_bug", tout << "mk_select: " << r->get_id() << " num_args: " << num_args;
for (unsigned i = 0; i < num_args; i++) tout << " " << args[i]->get_id();
tout << "\n";);
@ -55,14 +55,14 @@ namespace smt {
}
app * theory_array_base::mk_store(unsigned num_args, expr * const * args) {
return get_manager().mk_app(get_family_id(), OP_STORE, 0, nullptr, num_args, args);
return m.mk_app(get_family_id(), OP_STORE, 0, nullptr, num_args, args);
}
app * theory_array_base::mk_default(expr * a) {
sort * s = get_manager().get_sort(a);
sort * s = m.get_sort(a);
unsigned num_params = get_dimension(s);
parameter const* params = s->get_info()->get_parameters();
return get_manager().mk_app(get_family_id(), OP_ARRAY_DEFAULT, num_params, params, 1, & a);
return m.mk_app(get_family_id(), OP_ARRAY_DEFAULT, num_params, params, 1, & a);
}
unsigned theory_array_base::get_dimension(sort * s) const {
@ -72,14 +72,13 @@ namespace smt {
}
void theory_array_base::assert_axiom(unsigned num_lits, literal * lits) {
context & ctx = get_context();
TRACE("array_axiom",
tout << "literals:\n";
for (unsigned i = 0; i < num_lits; ++i) {
expr * e = ctx.bool_var2expr(lits[i].var());
if (lits[i].sign())
tout << "not ";
tout << mk_pp(e, get_manager()) << " ";
tout << mk_pp(e, m) << " ";
tout << "\n";
});
ctx.mk_th_axiom(get_id(), num_lits, lits);
@ -97,8 +96,6 @@ namespace smt {
void theory_array_base::assert_store_axiom1_core(enode * e) {
app * n = e->get_owner();
SASSERT(is_store(n));
context & ctx = get_context();
ast_manager & m = get_manager();
ptr_buffer<expr> sel_args;
unsigned num_args = n->get_num_args();
SASSERT(num_args >= 3);
@ -137,14 +134,12 @@ namespace smt {
*/
void theory_array_base::assert_store_axiom2_core(enode * store, enode * select) {
TRACE("array", tout << "generating axiom2: #" << store->get_owner_id() << " #" << select->get_owner_id() << "\n";
tout << mk_bounded_pp(store->get_owner(), get_manager()) << "\n" << mk_bounded_pp(select->get_owner(), get_manager()) << "\n";);
tout << mk_bounded_pp(store->get_owner(), m) << "\n" << mk_bounded_pp(select->get_owner(), m) << "\n";);
SASSERT(is_store(store));
SASSERT(is_select(select));
SASSERT(store->get_num_args() == 1 + select->get_num_args());
ptr_buffer<expr> sel1_args, sel2_args;
context & ctx = get_context();
ast_manager & m = get_manager();
enode * a = store->get_arg(0);
enode * const * is = select->get_args() + 1;
enode * const * js = store->get_args() + 1;
@ -211,7 +206,7 @@ namespace smt {
break;
if (i == num_args)
return false;
if (get_context().add_fingerprint(store, store->get_owner_id(), select->get_num_args() - 1, select->get_args() + 1)) {
if (ctx.add_fingerprint(store, store->get_owner_id(), select->get_num_args() - 1, select->get_args() + 1)) {
TRACE("array", tout << "adding axiom2 to todo queue\n";);
m_axiom2_todo.push_back(std::make_pair(store, select));
return true;
@ -228,8 +223,7 @@ namespace smt {
unsigned dimension = get_dimension(s_array);
func_decl_ref_vector * ext_skolems = nullptr;
if (!m_sort2skolem.find(s_array, ext_skolems)) {
array_util util(get_manager());
ast_manager & m = get_manager();
array_util util(m);
ext_skolems = alloc(func_decl_ref_vector, m);
for (unsigned i = 0; i < dimension; ++i) {
func_decl * ext_sk_decl = util.mk_array_ext(s_array, i);
@ -258,7 +252,6 @@ namespace smt {
v1' = v1, v2' = v2, i1 = i2, select(v1', i1) /= select(v2', i2) in the logical context.
*/
bool theory_array_base::already_diseq(enode * v1, enode * v2) {
context & ctx = get_context();
enode * r1 = v1->get_root();
enode * r2 = v2->get_root();
@ -295,7 +288,6 @@ namespace smt {
}
bool theory_array_base::assert_extensionality(enode * n1, enode * n2) {
context & ctx = get_context();
if (n1->get_owner_id() > n2->get_owner_id())
std::swap(n1, n2);
enode * nodes[2] = { n1, n2 };
@ -311,7 +303,6 @@ namespace smt {
TRACE("array", tout << "congruent: #" << a1->get_owner_id() << " #" << a2->get_owner_id() << "\n";);
SASSERT(is_array_sort(a1));
SASSERT(is_array_sort(a2));
context & ctx = get_context();
if (a1->get_owner_id() > a2->get_owner_id())
std::swap(a1, a2);
enode * nodes[2] = { a1, a2 };
@ -324,8 +315,6 @@ namespace smt {
void theory_array_base::assert_extensionality_core(enode * n1, enode * n2) {
app * e1 = n1->get_owner();
app * e2 = n2->get_owner();
context & ctx = get_context();
ast_manager & m = get_manager();
func_decl_ref_vector * funcs = nullptr;
sort * s = m.get_sort(e1);
@ -364,8 +353,6 @@ namespace smt {
void theory_array_base::assert_congruent_core(enode * n1, enode * n2) {
app * e1 = n1->get_owner();
app * e2 = n2->get_owner();
context & ctx = get_context();
ast_manager & m = get_manager();
sort* s = m.get_sort(e1);
unsigned dimension = get_array_arity(s);
literal n1_eq_n2 = mk_eq(e1, e2, true);
@ -397,7 +384,6 @@ namespace smt {
}
expr_ref theory_array_base::instantiate_lambda(app* e) {
ast_manager& m = get_manager();
quantifier * q = m.is_lambda_def(e->get_decl());
expr_ref f(e, m);
if (q) {
@ -426,7 +412,7 @@ namespace smt {
!m_axiom2_todo.empty() ||
!m_extensionality_todo.empty() ||
!m_congruent_todo.empty() ||
(!get_context().get_fparams().m_array_weak && has_propagate_up_trail());
(!ctx.get_fparams().m_array_weak && has_propagate_up_trail());
}
void theory_array_base::propagate() {
@ -443,8 +429,8 @@ namespace smt {
assert_congruent_core(m_congruent_todo[i].first, m_congruent_todo[i].second);
m_extensionality_todo.reset();
m_congruent_todo.reset();
if (!get_context().get_fparams().m_array_weak && has_propagate_up_trail()) {
get_context().push_trail(value_trail<context, unsigned>(m_array_weak_head));
if (!ctx.get_fparams().m_array_weak && has_propagate_up_trail()) {
ctx.push_trail(value_trail<context, unsigned>(m_array_weak_head));
for (; m_array_weak_head < m_array_weak_trail.size(); ++m_array_weak_head) {
set_prop_upward(m_array_weak_trail[m_array_weak_head]);
}
@ -502,7 +488,6 @@ namespace smt {
#if 0
void theory_array_base::collect_shared_vars(sbuffer<theory_var> & result) {
TRACE("array_shared", tout << "collecting shared vars...\n";);
context & ctx = get_context();
ptr_buffer<enode> to_unmark;
unsigned num_vars = get_num_vars();
for (unsigned i = 0; i < num_vars; i++) {
@ -537,7 +522,6 @@ namespace smt {
}
void theory_array_base::collect_shared_vars(sbuffer<theory_var> & result) {
context & ctx = get_context();
ptr_buffer<enode> to_unmark;
unsigned num_vars = get_num_vars();
for (unsigned i = 0; i < num_vars; i++) {
@ -571,8 +555,6 @@ namespace smt {
Return the number of new interface equalities.
*/
unsigned theory_array_base::mk_interface_eqs() {
context & ctx = get_context();
ast_manager & m = get_manager();
sbuffer<theory_var> roots;
collect_shared_vars(roots);
unsigned result = 0;
@ -642,7 +624,7 @@ namespace smt {
void theory_array_base::set_default(theory_var v, enode* n) {
TRACE("array", tout << "set default: " << v << " " << mk_pp(n->get_owner(), get_manager()) << "\n";);
TRACE("array", tout << "set default: " << v << " " << mk_pp(n->get_owner(), m) << "\n";);
v = mg_find(v);
if (m_defaults[v] == 0) {
m_defaults[v] = n;
@ -674,36 +656,36 @@ namespace smt {
return n;
}
void theory_array_base::mg_merge(theory_var n, theory_var m) {
n = mg_find(n);
m = mg_find(m);
if (n != m) {
SASSERT(m_parents[n] < 0);
SASSERT(m_parents[m] < 0);
if (m_parents[n] > m_parents[m]) {
std::swap(n, m);
void theory_array_base::mg_merge(theory_var u, theory_var v) {
u = mg_find(u);
v = mg_find(v);
if (u != v) {
SASSERT(m_parents[u] < 0);
SASSERT(m_parents[v] < 0);
if (m_parents[u] > m_parents[v]) {
std::swap(u, v);
}
m_parents[n] += m_parents[m];
m_parents[m] = n;
m_parents[u] += m_parents[v];
m_parents[v] = u;
if (m_defaults[n] == 0) {
m_defaults[n] = m_defaults[m];
if (m_defaults[u] == 0) {
m_defaults[u] = m_defaults[v];
}
CTRACE("array", m_defaults[m],
tout << mk_pp(m_defaults[m]->get_root()->get_owner(), get_manager()) << "\n";
tout << mk_pp(m_defaults[n]->get_root()->get_owner(), get_manager()) << "\n";
CTRACE("array", m_defaults[v],
tout << mk_pp(m_defaults[v]->get_root()->get_owner(), m) << "\n";
tout << mk_pp(m_defaults[u]->get_root()->get_owner(), m) << "\n";
);
// NB. it may be the case that m_defaults[m] != m_defaults[n]
// NB. it may be the case that m_defaults[u] != m_defaults[v]
// when m and n are finite arrays.
}
}
void theory_array_base::init_model(model_generator & m) {
m_factory = alloc(array_factory, get_manager(), m.get_model());
m.register_factory(m_factory);
void theory_array_base::init_model(model_generator & mg) {
m_factory = alloc(array_factory, m, mg.get_model());
mg.register_factory(m_factory);
m_use_unspecified_default = is_unspecified_default_ok();
collect_defaults();
collect_selects();
@ -718,7 +700,6 @@ namespace smt {
That is, other modules (such as smt_model_finder) may set the default value to an arbitrary value.
*/
bool theory_array_base::is_unspecified_default_ok() const {
context & ctx = get_context();
int num_vars = get_num_vars();
for (theory_var v = 0; v < num_vars; ++v) {
enode * n = get_enode(v);
@ -746,7 +727,6 @@ namespace smt {
if (m_use_unspecified_default)
return;
context & ctx = get_context();
//
// Create equivalence classes for defaults.
@ -768,7 +748,7 @@ namespace smt {
mg_merge(v, get_representative(w));
TRACE("array", tout << "merge: " << mk_pp(n->get_owner(), get_manager()) << " " << v << " " << w << "\n";);
TRACE("array", tout << "merge: " << mk_pp(n->get_owner(), m) << " " << v << " " << w << "\n";);
}
else if (is_const(n)) {
set_default(v, n->get_arg(0));
@ -817,10 +797,10 @@ namespace smt {
for (theory_var v = 0; v < num_vars; ++v) {
enode * r = get_enode(v)->get_root();
if (is_representative(v) && get_context().is_relevant(r)) {
if (is_representative(v) && ctx.is_relevant(r)) {
for (enode * parent : r->get_const_parents()) {
if (parent->get_cg() == parent &&
get_context().is_relevant(parent) &&
ctx.is_relevant(parent) &&
is_select(parent) &&
parent->get_arg(0)->get_root() == r) {
select_set * s = get_select_set(r);
@ -835,11 +815,11 @@ namespace smt {
void theory_array_base::propagate_select_to_store_parents(enode * r, enode * sel, enode_pair_vector & todo) {
SASSERT(r->get_root() == r);
SASSERT(is_select(sel));
if (!get_context().is_relevant(r)) {
if (!ctx.is_relevant(r)) {
return;
}
for (enode * parent : r->get_const_parents()) {
if (get_context().is_relevant(parent) &&
if (ctx.is_relevant(parent) &&
is_store(parent) &&
parent->get_arg(0)->get_root() == r) {
// propagate upward
@ -999,11 +979,11 @@ namespace smt {
return is_decl_of(f, get_id(), OP_ARRAY_EXT);
}
model_value_proc * theory_array_base::mk_value(enode * n, model_generator & m) {
SASSERT(get_context().is_relevant(n));
model_value_proc * theory_array_base::mk_value(enode * n, model_generator & mg) {
SASSERT(ctx.is_relevant(n));
theory_var v = n->get_th_var(get_id());
SASSERT(v != null_theory_var);
sort * s = get_manager().get_sort(n->get_owner());
sort * s = m.get_sort(n->get_owner());
enode * else_val_n = get_default(v);
array_value_proc * result = nullptr;
@ -1013,7 +993,7 @@ namespace smt {
}
else {
if (else_val_n != nullptr) {
SASSERT(get_context().is_relevant(else_val_n));
SASSERT(ctx.is_relevant(else_val_n));
result = alloc(array_value_proc, get_id(), s, else_val_n);
}
else {
@ -1021,18 +1001,18 @@ namespace smt {
void * else_val = m_else_values[r];
// DISABLED. It seems wrong, since different nodes can share the same
// else_val according to the mg class.
// SASSERT(else_val == 0 || get_context().is_relevant(UNTAG(app*, else_val)));
// SASSERT(else_val == 0 || ctx.is_relevant(UNTAG(app*, else_val)));
if (else_val == nullptr) {
sort * range = to_sort(s->get_parameter(s->get_num_parameters() - 1).get_ast());
// IMPORTANT:
// The implementation should not assume a fresh value is created for
// the else_val if the range is finite
TRACE("array", tout << mk_pp(n->get_owner(), get_manager()) << " " << mk_pp(range, get_manager()) << " " << range->is_infinite() << "\n";);
TRACE("array", tout << mk_pp(n->get_owner(), m) << " " << mk_pp(range, m) << " " << range->is_infinite() << "\n";);
if (range->is_infinite())
else_val = TAG(void*, m.mk_extra_fresh_value(range), 1);
else_val = TAG(void*, mg.mk_extra_fresh_value(range), 1);
else
else_val = TAG(void*, m.get_some_value(range), 0);
else_val = TAG(void*, mg.get_some_value(range), 0);
m_else_values[r] = else_val;
}
if (GET_TAG(else_val) == 0) {
@ -1053,19 +1033,19 @@ namespace smt {
unsigned num = select->get_num_args();
for (unsigned j = 1; j < num; ++j)
args.push_back(select->get_arg(j));
SASSERT(get_context().is_relevant(select));
SASSERT(ctx.is_relevant(select));
result->add_entry(args.size(), args.c_ptr(), select);
}
}
TRACE("array",
tout << mk_pp(n->get_root()->get_owner(), get_manager()) << "\n";
tout << mk_pp(n->get_root()->get_owner(), m) << "\n";
if (sel_set) {
for (enode* s : *sel_set) {
tout << "#" << s->get_root()->get_owner()->get_id() << " " << mk_pp(s->get_owner(), get_manager()) << "\n";
tout << "#" << s->get_root()->get_owner()->get_id() << " " << mk_pp(s->get_owner(), m) << "\n";
}
}
if (else_val_n) {
tout << "else: " << mk_pp(else_val_n->get_owner(), get_manager()) << "\n";
tout << "else: " << mk_pp(else_val_n->get_owner(), m) << "\n";
});
return result;
}

View file

@ -207,7 +207,7 @@ namespace smt {
model_value_proc * mk_value(enode * n, model_generator & m) override;
bool include_func_interp(func_decl* f) override;
public:
theory_array_base(ast_manager & m);
theory_array_base(context& ctx);
~theory_array_base() override { restore_sorts(0); }
};

View file

@ -27,9 +27,9 @@ Revision History:
namespace smt {
theory_array_full::theory_array_full(ast_manager & m, theory_array_params & params) :
theory_array(m, params),
m_sort2epsilon(m) {}
theory_array_full::theory_array_full(context& ctx) :
theory_array(ctx),
m_sort2epsilon(ctx.get_manager()) {}
theory_array_full::~theory_array_full() {
std::for_each(m_var_data_full.begin(), m_var_data_full.end(), delete_proc<var_data_full>());
@ -37,7 +37,7 @@ namespace smt {
}
theory* theory_array_full::mk_fresh(context* new_ctx) {
return alloc(theory_array_full, new_ctx->get_manager(), new_ctx->get_fparams());
return alloc(theory_array_full, *new_ctx);
}
void theory_array_full::add_map(theory_var v, enode* s) {
@ -133,7 +133,7 @@ namespace smt {
// call set_prop_upward on array arguments.
//
void theory_array_full::set_prop_upward(enode * n) {
TRACE("array", tout << mk_pp(n->get_owner(), get_manager()) << "\n";);
TRACE("array", tout << mk_pp(n->get_owner(), m) << "\n";);
if (is_store(n)) {
set_prop_upward(n->get_arg(0)->get_th_var(get_id()));
}
@ -246,11 +246,10 @@ namespace smt {
}
bool theory_array_full::internalize_term(app * n) {
context & ctx = get_context();
if (ctx.e_internalized(n)) {
return true;
}
TRACE("array", tout << mk_pp(n, get_manager()) << "\n";);
TRACE("array", tout << mk_pp(n, m) << "\n";);
if (is_store(n) || is_select(n)) {
return theory_array::internalize_term(n);
@ -345,8 +344,8 @@ namespace smt {
add_as_array(v1, n);
}
TRACE("array",
tout << mk_pp(get_enode(v1)->get_owner(), get_manager()) << "\n";
tout << mk_pp(get_enode(v2)->get_owner(), get_manager()) << "\n";
tout << mk_pp(get_enode(v1)->get_owner(), m) << "\n";
tout << mk_pp(get_enode(v2)->get_owner(), m) << "\n";
tout << "merge in\n"; display_var(tout, v2);
tout << "after merge\n"; display_var(tout, v1););
}
@ -355,7 +354,7 @@ namespace smt {
SASSERT(v != null_theory_var);
v = find(v);
var_data* d = m_var_data[v];
TRACE("array", tout << "v" << v << " " << mk_pp(get_enode(v)->get_owner(), get_manager()) << " "
TRACE("array", tout << "v" << v << " " << mk_pp(get_enode(v)->get_owner(), m) << " "
<< d->m_prop_upward << " " << m_params.m_array_delay_exp_axiom << "\n";);
for (enode * store : d->m_stores) {
SASSERT(is_store(store));
@ -369,7 +368,7 @@ namespace smt {
void theory_array_full::add_parent_select(theory_var v, enode * s) {
TRACE("array",
tout << v << " select parent: " << mk_pp(s->get_owner(), get_manager()) << "\n";
tout << v << " select parent: " << mk_pp(s->get_owner(), m) << "\n";
display_var(tout, v);
);
theory_array::add_parent_select(v,s);
@ -394,12 +393,11 @@ namespace smt {
}
void theory_array_full::relevant_eh(app* n) {
TRACE("array", tout << mk_pp(n, get_manager()) << "\n";);
TRACE("array", tout << mk_pp(n, m) << "\n";);
theory_array::relevant_eh(n);
if (!is_default(n) && !is_select(n) && !is_map(n) && !is_const(n) && !is_as_array(n)){
return;
}
context & ctx = get_context();
if (!ctx.e_internalized(n)) ctx.internalize(n, false);;
enode* node = ctx.get_enode(n);
if (is_select(n)) {
@ -455,8 +453,6 @@ namespace smt {
SASSERT(map->get_num_args() > 0);
func_decl* f = to_func_decl(map->get_decl()->get_parameter(0).get_ast());
context& ctx = get_context();
ast_manager& m = get_manager();
TRACE("array_map_bug", tout << "invoked instantiate_select_map_axiom\n";
tout << sl->get_owner_id() << " " << mp->get_owner_id() << "\n";
@ -470,8 +466,8 @@ namespace smt {
m_stats.m_num_map_axiom++;
TRACE("array",
tout << mk_bounded_pp(mp->get_owner(), get_manager()) << "\n";
tout << mk_bounded_pp(sl->get_owner(), get_manager()) << "\n";);
tout << mk_bounded_pp(mp->get_owner(), m) << "\n";
tout << mk_bounded_pp(sl->get_owner(), m) << "\n";);
unsigned num_args = select->get_num_args();
unsigned num_arrays = map->get_num_args();
ptr_buffer<expr> args1, args2;
@ -518,12 +514,10 @@ namespace smt {
SASSERT(is_map(mp));
app* map = mp->get_owner();
ast_manager& m = get_manager();
context& ctx = get_context();
if (!ctx.add_fingerprint(this, m_default_map_fingerprint, 1, &mp)) {
return false;
}
TRACE("array", tout << mk_bounded_pp(map, get_manager()) << "\n";);
TRACE("array", tout << mk_bounded_pp(map, m) << "\n";);
m_stats.m_num_default_map_axiom++;
@ -544,13 +538,12 @@ namespace smt {
bool theory_array_full::instantiate_default_const_axiom(enode* cnst) {
context& ctx = get_context();
if (!ctx.add_fingerprint(this, m_default_const_fingerprint, 1, &cnst)) {
return false;
}
m_stats.m_num_default_const_axiom++;
SASSERT(is_const(cnst));
TRACE("array", tout << mk_bounded_pp(cnst->get_owner(), get_manager()) << "\n";);
TRACE("array", tout << mk_bounded_pp(cnst->get_owner(), m) << "\n";);
expr* val = cnst->get_arg(0)->get_owner();
expr* def = mk_default(cnst->get_owner());
ctx.internalize(def, false);
@ -565,20 +558,19 @@ namespace smt {
bool theory_array_full::instantiate_default_as_array_axiom(enode* arr) {
return false;
#if 0
context& ctx = get_context();
if (!ctx.add_fingerprint(this, m_default_as_array_fingerprint, 1, &arr)) {
return false;
}
m_stats.m_num_default_as_array_axiom++;
SASSERT(is_as_array(arr));
TRACE("array", tout << mk_bounded_pp(arr->get_owner(), get_manager()) << "\n";);
TRACE("array", tout << mk_bounded_pp(arr->get_owner(), m) << "\n";);
expr* def = mk_default(arr->get_owner());
func_decl * f = array_util(get_manager()).get_as_array_func_decl(arr->get_owner());
func_decl * f = array_util(m).get_as_array_func_decl(arr->get_owner());
ptr_vector<expr> args;
for (unsigned i = 0; i < f->get_arity(); ++i) {
args.push_back(mk_epsilon(f->get_domain(i)));
}
expr_ref val(get_manager().mk_app(f, args.size(), args.c_ptr()), get_manager());
expr_ref val(m.mk_app(f, args.size(), args.c_ptr()), m);
ctx.internalize(def, false);
ctx.internalize(val.get(), false);
return try_assign_eq(val.get(), def);
@ -587,7 +579,7 @@ namespace smt {
bool theory_array_full::has_large_domain(app* array_term) {
SASSERT(is_array_sort(array_term));
sort* s = get_manager().get_sort(array_term);
sort* s = m.get_sort(array_term);
unsigned dim = get_dimension(s);
parameter const * params = s->get_info()->get_parameters();
rational sz(1);
@ -613,7 +605,6 @@ namespace smt {
SASSERT(is_const(cnst));
SASSERT(is_select(select));
SASSERT(cnst->get_num_args() == 1);
context& ctx = get_context();
unsigned num_args = select->get_num_args();
if (!ctx.add_fingerprint(cnst, cnst->get_owner_id(), select->get_num_args() - 1, select->get_args() + 1)) {
return false;
@ -628,10 +619,10 @@ namespace smt {
expr * sel = mk_select(sel_args.size(), sel_args.c_ptr());
expr * val = cnst->get_owner()->get_arg(0);
TRACE("array", tout << "new select-const axiom...\n";
tout << "const: " << mk_bounded_pp(cnst->get_owner(), get_manager()) << "\n";
tout << "select: " << mk_bounded_pp(select->get_owner(), get_manager()) << "\n";
tout << " sel/const: " << mk_bounded_pp(sel, get_manager()) << "\n";
tout << "value: " << mk_bounded_pp(val, get_manager()) << "\n";
tout << "const: " << mk_bounded_pp(cnst->get_owner(), m) << "\n";
tout << "select: " << mk_bounded_pp(select->get_owner(), m) << "\n";
tout << " sel/const: " << mk_bounded_pp(sel, m) << "\n";
tout << "value: " << mk_bounded_pp(val, m) << "\n";
tout << "#" << sel->get_id() << " = #" << val->get_id() << "\n";
);
@ -648,7 +639,6 @@ namespace smt {
SASSERT(is_as_array(arr->get_owner()));
SASSERT(is_select(select));
SASSERT(arr->get_num_args() == 0);
context& ctx = get_context();
unsigned num_args = select->get_num_args();
if (!ctx.add_fingerprint(arr, arr->get_owner_id(), select->get_num_args() - 1, select->get_args() + 1)) {
return false;
@ -661,13 +651,13 @@ namespace smt {
sel_args.push_back(select->get_owner()->get_arg(i));
}
expr * sel = mk_select(sel_args.size(), sel_args.c_ptr());
func_decl * f = array_util(get_manager()).get_as_array_func_decl(arr->get_owner());
expr_ref val(get_manager().mk_app(f, sel_args.size()-1, sel_args.c_ptr()+1), get_manager());
func_decl * f = array_util(m).get_as_array_func_decl(arr->get_owner());
expr_ref val(m.mk_app(f, sel_args.size()-1, sel_args.c_ptr()+1), m);
TRACE("array", tout << "new select-as-array axiom...\n";
tout << "as-array: " << mk_bounded_pp(arr->get_owner(), get_manager()) << "\n";
tout << "select: " << mk_bounded_pp(select->get_owner(), get_manager()) << "\n";
tout << " sel/as-array: " << mk_bounded_pp(sel, get_manager()) << "\n";
tout << "value: " << mk_bounded_pp(val.get(), get_manager()) << "\n";
tout << "as-array: " << mk_bounded_pp(arr->get_owner(), m) << "\n";
tout << "select: " << mk_bounded_pp(select->get_owner(), m) << "\n";
tout << " sel/as-array: " << mk_bounded_pp(sel, m) << "\n";
tout << "value: " << mk_bounded_pp(val.get(), m) << "\n";
tout << "#" << sel->get_id() << " = #" << val->get_id() << "\n";
);
@ -681,8 +671,6 @@ namespace smt {
SASSERT(is_store(store));
SASSERT(store->get_num_args() >= 3);
app* store_app = store->get_owner();
context& ctx = get_context();
ast_manager& m = get_manager();
if (!ctx.add_fingerprint(this, m_default_store_fingerprint, store->get_num_args(), store->get_args())) {
return false;
}
@ -729,7 +717,7 @@ namespace smt {
if (m_sort2epsilon.find(s, eps)) {
return eps;
}
eps = get_manager().mk_fresh_const("epsilon", s);
eps = m.mk_fresh_const("epsilon", s);
m_trail_stack.push(
ast2ast_trail<theory_array, sort, app>(m_sort2epsilon, s, eps));
return eps;
@ -756,7 +744,7 @@ namespace smt {
while (!m_eqsv.empty()) {
literal eq = m_eqsv.back();
m_eqsv.pop_back();
get_context().mark_as_relevant(eq);
ctx.mark_as_relevant(eq);
assert_axiom(eq);
r = FC_CONTINUE;
}
@ -788,8 +776,8 @@ namespace smt {
bool theory_array_full::try_assign_eq(expr* v1, expr* v2) {
TRACE("array",
tout << mk_bounded_pp(v1, get_manager()) << "\n==\n"
<< mk_bounded_pp(v2, get_manager()) << "\n";);
tout << mk_bounded_pp(v1, m) << "\n==\n"
<< mk_bounded_pp(v2, m) << "\n";);
if (m_eqs.contains(v1, v2)) {
return false;
@ -797,10 +785,10 @@ namespace smt {
else {
m_eqs.insert(v1, v2, true);
literal eq(mk_eq(v1, v2, true));
if (get_manager().has_trace_stream()) log_axiom_instantiation(get_context().bool_var2expr(eq.var()));
get_context().mark_as_relevant(eq);
if (m.has_trace_stream()) log_axiom_instantiation(ctx.bool_var2expr(eq.var()));
ctx.mark_as_relevant(eq);
assert_axiom(eq);
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";
// m_eqsv.push_back(eq);
return true;

View file

@ -95,7 +95,7 @@ namespace smt {
public:
theory_array_full(ast_manager & m, theory_array_params & params);
theory_array_full(context& ctx);
~theory_array_full() override;
theory * mk_fresh(context * new_ctx) override;
@ -103,12 +103,6 @@ namespace smt {
void merge_eh(theory_var v1, theory_var v2, theory_var, theory_var) override;
void display_var(std::ostream & out, theory_var v) const override;
void collect_statistics(::statistics & st) const override;
void init(context* ctx) override {
// the parent class is theory_array.
// theory::init(ctx);
theory_array::init(ctx);
}
};
};

View file

@ -28,17 +28,13 @@ Revision History:
namespace smt {
void theory_bv::init(context * ctx) {
theory::init(ctx);
}
theory_var theory_bv::mk_var(enode * n) {
theory_var r = theory::mk_var(n);
m_find.mk_var();
m_bits.push_back(literal_vector());
m_wpos.push_back(0);
m_zero_one_bits.push_back(zero_one_bits());
get_context().attach_th_var(n, this, r);
ctx.attach_th_var(n, this, r);
return r;
}
@ -52,7 +48,6 @@ namespace smt {
enode * n = get_enode(v);
app * owner = n->get_owner();
unsigned bv_size = get_bv_size(n);
context & ctx = get_context();
bool is_relevant = ctx.is_relevant(n);
literal_vector & bits = m_bits[v];
TRACE("bv", tout << "v" << v << "\n";);
@ -80,7 +75,6 @@ namespace smt {
};
void theory_bv::mk_bit2bool(app * n) {
context & ctx = get_context();
SASSERT(!ctx.b_internalized(n));
TRACE("bv", tout << "bit2bool: " << mk_pp(n, ctx.get_manager()) << "\n";);
@ -148,14 +142,12 @@ namespace smt {
}
void theory_bv::process_args(app * n) {
context & ctx = get_context();
for (expr* arg : *n) {
ctx.internalize(arg, false);
}
}
enode * theory_bv::mk_enode(app * n) {
context & ctx = get_context();
enode * e;
if (ctx.e_internalized(n)) {
e = ctx.get_enode(n);
@ -182,7 +174,6 @@ namespace smt {
return n->get_arg(idx);
}
else {
context & ctx = get_context();
app * arg = to_app(n->get_owner()->get_arg(idx));
SASSERT(ctx.e_internalized(arg));
return ctx.get_enode(arg);
@ -194,7 +185,6 @@ namespace smt {
}
void theory_bv::get_bits(theory_var v, expr_ref_vector & r) {
context & ctx = get_context();
literal_vector & bits = m_bits[v];
for (literal lit : bits) {
expr_ref l(get_manager());
@ -212,7 +202,6 @@ namespace smt {
}
inline void theory_bv::get_arg_bits(app * n, unsigned idx, expr_ref_vector & r) {
context & ctx = get_context();
app * arg = to_app(n->get_arg(idx));
SASSERT(ctx.e_internalized(arg));
get_bits(ctx.get_enode(arg), r);
@ -239,8 +228,6 @@ namespace smt {
enode * e1 = get_enode(v1);
enode * e2 = get_enode(v2);
literal l = ~(mk_eq(e1->get_owner(), e2->get_owner(), true));
context & ctx = get_context();
ast_manager & m = get_manager();
expr * eq = ctx.bool_var2expr(l.var());
if (m.has_trace_stream()) {
app_ref body(m);
@ -282,7 +269,6 @@ namespace smt {
\brief Add bit l to the given variable.
*/
void theory_bv::add_bit(theory_var v, literal l) {
context & ctx = get_context();
literal_vector & bits = m_bits[v];
unsigned idx = bits.size();
bits.push_back(l);
@ -314,15 +300,13 @@ namespace smt {
void theory_bv::simplify_bit(expr * s, expr_ref & r) {
// proof_ref p(get_manager());
// if (get_context().at_base_level())
// if (ctx.at_base_level())
// ctx.get_rewriter()(s, r, p);
// else
r = s;
}
void theory_bv::init_bits(enode * n, expr_ref_vector const & bits) {
context & ctx = get_context();
ast_manager & m = get_manager();
theory_var v = n->get_th_var(get_id());
SASSERT(v != null_theory_var);
unsigned sz = bits.size();
@ -344,7 +328,6 @@ namespace smt {
\brief Find an unassigned bit for m_wpos[v], if such bit cannot be found invoke fixed_var_eh
*/
void theory_bv::find_wpos(theory_var v) {
context & ctx = get_context();
literal_vector const & bits = m_bits[v];
unsigned sz = bits.size();
unsigned & wpos = m_wpos[v];
@ -446,8 +429,6 @@ namespace smt {
return;
}
++m_stats.m_num_eq_dynamic;
ast_manager& m = get_manager();
context & ctx = get_context();
app* o1 = get_enode(v1)->get_owner();
app* o2 = get_enode(v2)->get_owner();
literal oeq = mk_eq(o1, o2, true);
@ -492,7 +473,6 @@ namespace smt {
get_bv_size(v2) == sz && get_fixed_value(v2, val2) && val == val2) {
if (get_enode(v)->get_root() != get_enode(v2)->get_root()) {
SASSERT(get_bv_size(v) == get_bv_size(v2));
context & ctx = get_context();
TRACE("fixed_var_eh", tout << "detected equality: v" << v << " = v" << v2 << "\n";
display_var(tout, v);
display_var(tout, v2););
@ -515,7 +495,6 @@ namespace smt {
}
bool theory_bv::get_fixed_value(theory_var v, numeral & result) const {
context & ctx = get_context();
result.reset();
literal_vector const & bits = m_bits[v];
literal_vector::const_iterator it = bits.begin();
@ -531,8 +510,7 @@ namespace smt {
}
bool theory_bv::get_fixed_value(app* x, numeral & result) const {
context& ctx = get_context();
CTRACE("bv", !ctx.e_internalized(x), tout << "not internalized " << mk_pp(x, get_manager()) << "\n";);
CTRACE("bv", !ctx.e_internalized(x), tout << "not internalized " << mk_pp(x, m) << "\n";);
if (!ctx.e_internalized(x)) return false;
enode * e = ctx.get_enode(x);
theory_var v = e->get_th_var(get_id());
@ -541,8 +519,7 @@ namespace smt {
void theory_bv::internalize_num(app * n) {
SASSERT(!get_context().e_internalized(n));
ast_manager & m = get_manager();
SASSERT(!ctx.e_internalized(n));
numeral val;
unsigned sz;
m_util.is_numeral(n, val, sz);
@ -569,7 +546,6 @@ namespace smt {
}
void theory_bv::internalize_mkbv(app* n) {
ast_manager& m = get_manager();
expr_ref_vector bits(m);
process_args(n);
enode * e = mk_enode(n);
@ -578,9 +554,8 @@ namespace smt {
}
void theory_bv::internalize_bv2int(app* n) {
SASSERT(!get_context().e_internalized(n));
context& ctx = get_context();
TRACE("bv", tout << mk_bounded_pp(n, get_manager()) << "\n";);
SASSERT(!ctx.e_internalized(n));
TRACE("bv", tout << mk_bounded_pp(n, m) << "\n";);
process_args(n);
mk_enode(n);
if (!ctx.relevancy()) {
@ -594,11 +569,9 @@ namespace smt {
// create the axiom:
// n = bv2int(k) = ite(bit2bool(k[sz-1],2^{sz-1},0) + ... + ite(bit2bool(k[0],1,0))
//
SASSERT(get_context().e_internalized(n));
SASSERT(ctx.e_internalized(n));
SASSERT(m_util.is_bv2int(n));
ast_manager & m = get_manager();
TRACE("bv2int_bug", tout << "bv2int:\n" << mk_pp(n, m) << "\n";);
context & ctx = get_context();
sort * int_sort = m.get_sort(n);
app * k = to_app(n->get_arg(0));
SASSERT(m_util.is_bv_sort(m.get_sort(k)));
@ -648,9 +621,8 @@ namespace smt {
}
void theory_bv::internalize_int2bv(app* n) {
SASSERT(!get_context().e_internalized(n));
SASSERT(!ctx.e_internalized(n));
SASSERT(n->get_num_args() == 1);
context& ctx = get_context();
process_args(n);
mk_enode(n);
theory_var v = ctx.get_enode(n)->get_th_var(get_id());
@ -671,10 +643,8 @@ namespace smt {
// bit2bool(i,n) == ((e div 2^i) mod 2 != 0)
// for i = 0,.., sz-1
//
SASSERT(get_context().e_internalized(n));
SASSERT(ctx.e_internalized(n));
SASSERT(m_util.is_int2bv(n));
ast_manager & m = get_manager();
context& ctx = get_context();
parameter param(m_autil.mk_int());
expr* n_expr = n;
@ -720,10 +690,9 @@ namespace smt {
#define MK_UNARY(NAME, BLAST_OP) \
void theory_bv::NAME(app * n) { \
SASSERT(!get_context().e_internalized(n)); \
SASSERT(!ctx.e_internalized(n)); \
SASSERT(n->get_num_args() == 1); \
process_args(n); \
ast_manager & m = get_manager(); \
enode * e = mk_enode(n); \
expr_ref_vector arg1_bits(m), bits(m); \
get_arg_bits(e, 0, arg1_bits); \
@ -733,10 +702,9 @@ namespace smt {
#define MK_BINARY(NAME, BLAST_OP) \
void theory_bv::NAME(app * n) { \
SASSERT(!get_context().e_internalized(n)); \
SASSERT(!ctx.e_internalized(n)); \
SASSERT(n->get_num_args() == 2); \
process_args(n); \
ast_manager & m = get_manager(); \
enode * e = mk_enode(n); \
expr_ref_vector arg1_bits(m), arg2_bits(m), bits(m); \
get_arg_bits(e, 0, arg1_bits); \
@ -749,10 +717,9 @@ namespace smt {
#define MK_AC_BINARY(NAME, BLAST_OP) \
void theory_bv::NAME(app * n) { \
SASSERT(!get_context().e_internalized(n)); \
SASSERT(!ctx.e_internalized(n)); \
SASSERT(n->get_num_args() >= 2); \
process_args(n); \
ast_manager & m = get_manager(); \
enode * e = mk_enode(n); \
expr_ref_vector arg_bits(m); \
expr_ref_vector bits(m); \
@ -776,11 +743,9 @@ namespace smt {
#define MK_BINARY_COND(NAME, BLAST_OP) \
void theory_bv::NAME(app * n) { \
SASSERT(!get_context().e_internalized(n)); \
SASSERT(!ctx.e_internalized(n)); \
SASSERT(n->get_num_args() == 2); \
process_args(n); \
ast_manager & m = get_manager(); \
context& ctx = get_context(); \
enode * e = mk_enode(n); \
expr_ref_vector arg1_bits(m), arg2_bits(m), bits(m); \
expr_ref cond(m), s_cond(m); \
@ -794,14 +759,13 @@ namespace smt {
literal l(ctx.get_literal(s_cond)); \
ctx.mark_as_relevant(l); \
ctx.mk_th_axiom(get_id(), 1, &l); \
TRACE("bv", tout << mk_pp(cond, get_manager()) << "\n"; tout << l << "\n";); \
TRACE("bv", tout << mk_pp(cond, m) << "\n"; tout << l << "\n";); \
}
void theory_bv::internalize_sub(app *n) {
SASSERT(!get_context().e_internalized(n));
SASSERT(!ctx.e_internalized(n));
SASSERT(n->get_num_args() == 2);
process_args(n);
ast_manager & m = get_manager();
process_args(n);
enode * e = mk_enode(n);
expr_ref_vector arg1_bits(m), arg2_bits(m), bits(m);
get_arg_bits(e, 0, arg1_bits);
@ -838,10 +802,9 @@ namespace smt {
#define MK_PARAMETRIC_UNARY(NAME, BLAST_OP) \
void theory_bv::NAME(app * n) { \
SASSERT(!get_context().e_internalized(n)); \
SASSERT(!ctx.e_internalized(n)); \
SASSERT(n->get_num_args() == 1); \
process_args(n); \
ast_manager & m = get_manager(); \
enode * e = mk_enode(n); \
expr_ref_vector arg1_bits(m), bits(m); \
get_arg_bits(e, 0, arg1_bits); \
@ -890,7 +853,7 @@ namespace smt {
bool theory_bv::internalize_term_core(app * term) {
SASSERT(term->get_family_id() == get_family_id());
TRACE("bv", tout << "internalizing term: " << mk_bounded_pp(term, get_manager()) << "\n";);
TRACE("bv", tout << "internalizing term: " << mk_bounded_pp(term, m) << "\n";);
if (approximate_term(term)) {
return false;
}
@ -942,14 +905,14 @@ namespace smt {
}
return params().m_bv_enable_int2bv2int;
default:
TRACE("bv_op", tout << "unsupported operator: " << mk_ll_pp(term, get_manager()) << "\n";);
TRACE("bv_op", tout << "unsupported operator: " << mk_ll_pp(term, m) << "\n";);
UNREACHABLE();
return false;
}
}
bool theory_bv::internalize_term(app * term) {
scoped_suspend_rlimit _suspend_cancel(get_manager().limit());
scoped_suspend_rlimit _suspend_cancel(m.limit());
try {
return internalize_term_core(term);
}
@ -963,8 +926,6 @@ namespace smt {
void theory_bv::NAME(app *n) { \
SASSERT(n->get_num_args() == 2); \
process_args(n); \
ast_manager & m = get_manager(); \
context & ctx = get_context(); \
expr_ref_vector arg1_bits(m), arg2_bits(m); \
get_arg_bits(n, 0, arg1_bits); \
get_arg_bits(n, 1, arg2_bits); \
@ -998,8 +959,6 @@ namespace smt {
void theory_bv::internalize_le(app * n) {
SASSERT(n->get_num_args() == 2);
process_args(n);
ast_manager & m = get_manager();
context & ctx = get_context();
expr_ref_vector arg1_bits(m), arg2_bits(m);
get_arg_bits(n, 0, arg1_bits);
get_arg_bits(n, 1, arg2_bits);
@ -1024,7 +983,6 @@ namespace smt {
}
bool theory_bv::internalize_carry(app * n, bool gate_ctx) {
context & ctx = get_context();
ctx.internalize(n->get_arg(0), true);
ctx.internalize(n->get_arg(1), true);
ctx.internalize(n->get_arg(2), true);
@ -1058,7 +1016,6 @@ namespace smt {
}
bool theory_bv::internalize_xor3(app * n, bool gate_ctx) {
context & ctx = get_context();
ctx.internalize(n->get_arg(0), true);
ctx.internalize(n->get_arg(1), true);
ctx.internalize(n->get_arg(2), true);
@ -1094,7 +1051,7 @@ namespace smt {
}
bool theory_bv::internalize_atom(app * atom, bool gate_ctx) {
TRACE("bv", tout << "internalizing atom: " << mk_bounded_pp(atom, get_manager()) << "\n";);
TRACE("bv", tout << "internalizing atom: " << mk_bounded_pp(atom, m) << "\n";);
SASSERT(atom->get_family_id() == get_family_id());
if (approximate_term(atom)) {
return false;
@ -1125,11 +1082,11 @@ namespace smt {
unsigned num_args = n->get_num_args();
for (unsigned i = 0; i <= num_args; i++) {
expr* arg = (i == num_args)?n:n->get_arg(i);
sort* s = get_manager().get_sort(arg);
sort* s = m.get_sort(arg);
if (m_util.is_bv_sort(s) && m_util.get_bv_size(arg) > params().m_bv_blast_max_size) {
if (!m_approximates_large_bvs) {
TRACE("bv", tout << "found large size bit-vector:\n" << mk_pp(n, get_manager()) << "\n";);
get_context().push_trail(value_trail<context, bool>(m_approximates_large_bvs));
TRACE("bv", tout << "found large size bit-vector:\n" << mk_pp(n, m) << "\n";);
ctx.push_trail(value_trail<context, bool>(m_approximates_large_bvs));
m_approximates_large_bvs = true;
}
return true;
@ -1141,17 +1098,17 @@ namespace smt {
void theory_bv::apply_sort_cnstr(enode * n, sort * s) {
if (!is_attached_to_var(n) && !approximate_term(n->get_owner())) {
mk_bits(mk_var(n));
if (get_context().is_relevant(n)) {
if (ctx.is_relevant(n)) {
relevant_eh(n->get_owner());
}
}
}
void theory_bv::new_eq_eh(theory_var v1, theory_var v2) {
TRACE("bv_eq", tout << "new_eq: " << mk_pp(get_enode(v1)->get_owner(), get_manager()) << " = " << mk_pp(get_enode(v2)->get_owner(), get_manager()) << "\n";);
TRACE("bv", tout << "new_eq_eh v" << v1 << " = v" << v2 << " @ " << get_context().get_scope_level() <<
" relevant1: " << get_context().is_relevant(get_enode(v1)) <<
" relevant2: " << get_context().is_relevant(get_enode(v2)) << "\n";);
TRACE("bv_eq", tout << "new_eq: " << mk_pp(get_enode(v1)->get_owner(), m) << " = " << mk_pp(get_enode(v2)->get_owner(), m) << "\n";);
TRACE("bv", tout << "new_eq_eh v" << v1 << " = v" << v2 << " @ " << ctx.get_scope_level() <<
" relevant1: " << ctx.is_relevant(get_enode(v1)) <<
" relevant2: " << ctx.is_relevant(get_enode(v2)) << "\n";);
m_find.merge(v1, v2);
}
@ -1164,8 +1121,6 @@ namespace smt {
void theory_bv::expand_diseq(theory_var v1, theory_var v2) {
SASSERT(get_bv_size(v1) == get_bv_size(v2));
context & ctx = get_context();
ast_manager & m = get_manager();
if (v1 > v2) {
std::swap(v1, v2);
}
@ -1242,7 +1197,7 @@ namespace smt {
void theory_bv::assign_eh(bool_var v, bool is_true) {
atom * a = get_bv2a(v);
TRACE("bv", tout << "assert: p" << v << " #" << get_context().bool_var2expr(v)->get_id() << " is_true: " << is_true << "\n";);
TRACE("bv", tout << "assert: p" << v << " #" << ctx.bool_var2expr(v)->get_id() << " is_true: " << is_true << "\n";);
if (a->is_bit()) {
// The following optimization is not correct.
// Boolean variables created for performing bit-blasting are reused.
@ -1262,7 +1217,7 @@ namespace smt {
propagate_bits();
#if WATCH_DISEQ
if (!get_context().inconsistent() && m_diseq_watch.size() > static_cast<unsigned>(v)) {
if (!ctx.inconsistent() && m_diseq_watch.size() > static_cast<unsigned>(v)) {
unsigned sz = m_diseq_watch[v].size();
for (unsigned i = 0; i < sz; ++i) {
auto const & p = m_diseq_watch[v][i];
@ -1275,7 +1230,6 @@ namespace smt {
}
void theory_bv::propagate_bits() {
context & ctx = get_context();
for (unsigned i = 0; i < m_prop_queue.size(); i++) {
var_pos const & entry = m_prop_queue[i];
theory_var v = entry.first;
@ -1327,8 +1281,6 @@ namespace smt {
void theory_bv::assign_bit(literal consequent, theory_var v1, theory_var v2, unsigned idx, literal antecedent, bool propagate_eqc) {
m_stats.m_num_bit2core++;
context & ctx = get_context();
ast_manager & m = get_manager();
SASSERT(ctx.get_assignment(antecedent) == l_true);
SASSERT(m_bits[v2][idx].var() == consequent.var());
SASSERT(consequent.var() != antecedent.var());
@ -1389,8 +1341,6 @@ namespace smt {
}
void theory_bv::relevant_eh(app * n) {
ast_manager & m = get_manager();
context & ctx = get_context();
TRACE("bv", tout << "relevant: " << ctx.e_internalized(n) << ": " << mk_pp(n, m) << "\n";);
if (m.is_bool(n)) {
bool_var v = ctx.get_bool_var(n);
@ -1450,8 +1400,8 @@ namespace smt {
m_diseq_watch_lim.shrink(m_diseq_watch_lim.size()-num_scopes);
#endif
theory::pop_scope_eh(num_scopes);
TRACE("bv_verbose", m_find.display(tout << get_context().get_scope_level() << " - "
<< num_scopes << " = " << (get_context().get_scope_level() - num_scopes) << "\n"););
TRACE("bv_verbose", m_find.display(tout << ctx.get_scope_level() << " - "
<< num_scopes << " = " << (ctx.get_scope_level() - num_scopes) << "\n"););
}
final_check_status theory_bv::final_check_eh() {
@ -1485,14 +1435,14 @@ namespace smt {
}
smt_params const& theory_bv::params() const {
return get_context().get_fparams();
return ctx.get_fparams();
}
theory_bv::theory_bv(ast_manager & m, bit_blaster_params const & bb_params):
theory(m.mk_family_id("bv")),
m_util(m),
m_autil(m),
m_bb(m, bb_params),
theory_bv::theory_bv(context& ctx):
theory(ctx, ctx.get_manager().mk_family_id("bv")),
m_util(ctx.get_manager()),
m_autil(ctx.get_manager()),
m_bb(ctx.get_manager(), ctx.get_fparams()),
m_trail_stack(*this),
m_find(*this),
m_approximates_large_bvs(false) {
@ -1504,7 +1454,7 @@ namespace smt {
}
theory* theory_bv::mk_fresh(context* new_ctx) {
return alloc(theory_bv, new_ctx->get_manager(), new_ctx->get_fparams());
return alloc(theory_bv, *new_ctx);
}
@ -1516,7 +1466,6 @@ namespace smt {
return; // conflict was detected
}
m_prop_queue.reset();
context & ctx = get_context();
literal_vector & bits1 = m_bits[v1];
literal_vector & bits2 = m_bits[v2];
SASSERT(bits1.size() == bits2.size());
@ -1680,7 +1629,7 @@ namespace smt {
};
inline justification * theory_bv::mk_bit_eq_justification(theory_var v1, theory_var v2, literal consequent, literal antecedent) {
return get_context().mk_justification(bit_eq_justification(get_id(), get_enode(v1), get_enode(v2), consequent, antecedent));
return ctx.mk_justification(bit_eq_justification(get_id(), get_enode(v1), get_enode(v2), consequent, antecedent));
}
void theory_bv::unmerge_eh(theory_var v1, theory_var v2) {
@ -1717,9 +1666,9 @@ namespace smt {
// SASSERT(check_zero_one_bits(v2));
}
void theory_bv::init_model(model_generator & m) {
m_factory = alloc(bv_factory, get_manager());
m.register_factory(m_factory);
void theory_bv::init_model(model_generator & mg) {
m_factory = alloc(bv_factory, m);
mg.register_factory(m_factory);
}
model_value_proc * theory_bv::mk_value(enode * n, model_generator & mg) {
@ -1744,7 +1693,6 @@ namespace smt {
out.width(4);
out << get_enode(find(v))->get_owner_id();
out << std::right << ", bits:";
context & ctx = get_context();
literal_vector const & bits = m_bits[v];
for (literal lit : bits) {
out << " " << lit << ":";
@ -1757,7 +1705,6 @@ namespace smt {
}
void theory_bv::display_bit_atom(std::ostream & out, bool_var v, bit_atom const * a) const {
context & ctx = get_context();
out << "#" << ctx.bool_var2expr(v)->get_id() << " ->";
var_pos_occ * curr = a->m_occs;
while (curr) {
@ -1769,7 +1716,6 @@ namespace smt {
void theory_bv::display_atoms(std::ostream & out) const {
out << "atoms:\n";
context & ctx = get_context();
unsigned num = ctx.get_num_bool_vars();
for (unsigned v = 0; v < num; v++) {
atom * a = get_bv2a(v);
@ -1798,7 +1744,6 @@ namespace smt {
}
bool theory_bv::check_assignment(theory_var v) {
context & ctx = get_context();
if (!is_root(v))
return true;
if (!ctx.is_relevant(get_enode(v))) {
@ -1843,7 +1788,7 @@ namespace smt {
\remark The method does nothing if v is not the root of the equivalence class.
*/
bool theory_bv::check_zero_one_bits(theory_var v) {
if (get_context().inconsistent())
if (ctx.inconsistent())
return true; // property is only valid if the context is not in a conflict.
if (is_root(v) && is_bv(v)) {
bool_vector bits[2];
@ -1887,9 +1832,9 @@ namespace smt {
}
bool theory_bv::check_invariant() {
if (get_manager().limit().get_cancel_flag())
if (m.limit().get_cancel_flag())
return true;
if (get_context().inconsistent())
if (ctx.inconsistent())
return true;
unsigned num = get_num_vars();
for (unsigned v = 0; v < num; v++) {

View file

@ -223,7 +223,6 @@ namespace smt {
void assert_bv2int_axiom(app* n);
protected:
void init(context * ctx) override;
theory_var mk_var(enode * n) override;
bool internalize_atom(app * atom, bool gate_ctx) override;
bool internalize_term(app * term) override;
@ -254,7 +253,7 @@ namespace smt {
smt_params const& params() const;
public:
theory_bv(ast_manager & m, bit_blaster_params const & bb_params);
theory_bv(context& ctx);
~theory_bv() override;
theory * mk_fresh(context * new_ctx) override;

View file

@ -75,7 +75,7 @@ namespace smt {
theory* theory_datatype::mk_fresh(context* new_ctx) {
return alloc(theory_datatype, new_ctx->get_manager());
return alloc(theory_datatype, *new_ctx);
}
/**
@ -83,19 +83,17 @@ namespace smt {
antecedent may be null_literal
*/
void theory_datatype::assert_eq_axiom(enode * lhs, expr * rhs, literal antecedent) {
ast_manager & m = get_manager();
if (antecedent != null_literal) {
std::function<void(void)> fn = [&]() {
app_ref body(m);
body = m.mk_eq(lhs->get_owner(), rhs);
body = m.mk_implies(get_context().bool_var2expr(antecedent.var()), body);
body = m.mk_implies(ctx.bool_var2expr(antecedent.var()), body);
log_axiom_instantiation(body, 1, &lhs);
};
scoped_trace_stream _st(m, fn);
}
context & ctx = get_context();
if (m.proofs_enabled()) {
literal l(mk_eq(lhs->get_owner(), rhs, true));
ctx.mark_as_relevant(l);
@ -139,13 +137,12 @@ namespace smt {
where acc_i are the accessors of constructor c.
*/
void theory_datatype::assert_is_constructor_axiom(enode * n, func_decl * c, literal antecedent) {
ast_manager& m = get_manager();
app* e = n->get_owner();
TRACE("datatype_bug", tout << "creating axiom (= n (c (acc_1 n) ... (acc_m n))) for\n"
<< mk_pp(c, m) << " " << mk_pp(e, m) << "\n";);
m_stats.m_assert_cnstr++;
SASSERT(m_util.is_constructor(c));
SASSERT(m_util.is_datatype(get_manager().get_sort(e)));
SASSERT(m_util.is_datatype(m.get_sort(e)));
SASSERT(c->get_range() == m.get_sort(e));
ptr_vector<expr> args;
@ -170,7 +167,6 @@ namespace smt {
m_stats.m_assert_accessor++;
SASSERT(is_constructor(n));
ast_manager & m = get_manager();
func_decl * d = n->get_decl();
ptr_vector<func_decl> const & accessors = *m_util.get_constructor_accessors(d);
SASSERT(n->get_num_args() == accessors.size());
@ -180,7 +176,7 @@ namespace smt {
for (unsigned i = 0; i < n->get_num_args(); ++i) {
bindings.push_back(n->get_arg(i)->get_owner());
}
unsigned base_id = get_manager().has_trace_stream() && accessors.size() > 0 ? m_util.plugin().get_axiom_base_id(d->get_name()) : 0;
unsigned base_id = m.has_trace_stream() && accessors.size() > 0 ? m_util.plugin().get_axiom_base_id(d->get_name()) : 0;
unsigned i = 0;
for (func_decl * acc : accessors) {
app_ref acc_app(m.mk_app(acc, n->get_owner()), m);
@ -206,8 +202,7 @@ namespace smt {
SASSERT(m_util.get_recognizer_constructor(r->get_decl()) == c->get_decl());
SASSERT(c->get_root() == r->get_arg(0)->get_root());
TRACE("recognizer_conflict",
tout << mk_ismt2_pp(c->get_owner(), get_manager()) << "\n" << mk_ismt2_pp(r->get_owner(), get_manager()) << "\n";);
context & ctx = get_context();
tout << mk_ismt2_pp(c->get_owner(), m) << "\n" << mk_ismt2_pp(r->get_owner(), m) << "\n";);
literal l(ctx.enode2bool_var(r));
SASSERT(ctx.get_assignment(l) == l_false);
l.neg();
@ -228,8 +223,6 @@ namespace smt {
void theory_datatype::assert_update_field_axioms(enode * n) {
m_stats.m_assert_update_field++;
SASSERT(is_update_field(n));
context & ctx = get_context();
ast_manager & m = get_manager();
app* own = n->get_owner();
expr* arg1 = own->get_arg(0);
func_decl * upd = n->get_decl();
@ -272,7 +265,6 @@ namespace smt {
SASSERT(r == static_cast<int>(m_var_data.size()));
m_var_data.push_back(alloc(var_data));
var_data * d = m_var_data[r];
context & ctx = get_context();
ctx.attach_th_var(n, this, r);
if (is_constructor(n)) {
d->m_constructor = n;
@ -282,7 +274,6 @@ namespace smt {
assert_update_field_axioms(n);
}
else {
ast_manager & m = get_manager();
sort * s = m.get_sort(n->get_owner());
if (m_util.get_datatype_num_constructors(s) == 1) {
func_decl * c = m_util.get_datatype_constructors(s)->get(0);
@ -297,21 +288,20 @@ namespace smt {
}
bool theory_datatype::internalize_atom(app * atom, bool gate_ctx) {
TRACE("datatype", tout << "internalizing atom:\n" << mk_pp(atom, get_manager()) << "\n";);
TRACE("datatype", tout << "internalizing atom:\n" << mk_pp(atom, m) << "\n";);
return internalize_term(atom);
}
bool theory_datatype::internalize_term(app * term) {
TRACE("datatype", tout << "internalizing term:\n" << mk_pp(term, get_manager()) << "\n";);
context & ctx = get_context();
TRACE("datatype", tout << "internalizing term:\n" << mk_pp(term, m) << "\n";);
unsigned num_args = term->get_num_args();
for (unsigned i = 0; i < num_args; i++)
ctx.internalize(term->get_arg(i), false);
// the internalization of the arguments may trigger the internalization of term.
if (ctx.e_internalized(term))
return true;
enode * e = ctx.mk_enode(term, false, get_manager().is_bool(term), true); // possible optimization, the third argument may be set to false, if the term (actually, atom) is not in the context of a gate.
if (get_manager().is_bool(term)) {
enode * e = ctx.mk_enode(term, false, m.is_bool(term), true); // possible optimization, the third argument may be set to false, if the term (actually, atom) is not in the context of a gate.
if (m.is_bool(term)) {
bool_var bv = ctx.mk_bool_var(term);
ctx.set_var_theory(bv, get_id());
ctx.set_enode_flag(bv, true);
@ -342,9 +332,9 @@ namespace smt {
//
for (unsigned i = 0; i < num_args; i++) {
enode * arg = e->get_arg(i);
sort * s = get_manager().get_sort(arg->get_owner());
sort * s = m.get_sort(arg->get_owner());
if (m_autil.is_array(s) && m_util.is_datatype(get_array_range(s))) {
app_ref def(m_autil.mk_default(arg->get_owner()), get_manager());
app_ref def(m_autil.mk_default(arg->get_owner()), m);
if (!ctx.e_internalized(def)) {
ctx.internalize(def, false);
}
@ -389,16 +379,16 @@ namespace smt {
// (assert (> (len a) 1)
//
// If the theory variable is not created for 'a', then a wrong model will be generated.
TRACE("datatype", tout << "apply_sort_cnstr: #" << n->get_owner_id() << " " << mk_pp(n->get_owner(), get_manager()) << "\n";);
TRACE("datatype", tout << "apply_sort_cnstr: #" << n->get_owner_id() << " " << mk_pp(n->get_owner(), m) << "\n";);
TRACE("datatype_bug",
tout << "apply_sort_cnstr:\n" << mk_pp(n->get_owner(), get_manager()) << " ";
tout << "apply_sort_cnstr:\n" << mk_pp(n->get_owner(), m) << " ";
tout << m_util.is_datatype(s) << " ";
if (m_util.is_datatype(s)) tout << "is-infinite: " << s->is_infinite() << " ";
if (m_util.is_datatype(s)) tout << "attached: " << is_attached_to_var(n) << " ";
tout << "\n";);
if (!is_attached_to_var(n) &&
(get_context().has_quantifiers() ||
(ctx.has_quantifiers() ||
(m_util.is_datatype(s) && m_util.has_nested_arrays()) ||
(m_util.is_datatype(s) && !s->is_infinite()))) {
mk_var(n);
@ -418,7 +408,6 @@ namespace smt {
}
void theory_datatype::assign_eh(bool_var v, bool is_true) {
context & ctx = get_context();
enode * n = ctx.bool_var2enode(v);
if (!is_recognizer(n))
return;
@ -451,8 +440,7 @@ namespace smt {
}
void theory_datatype::relevant_eh(app * n) {
context & ctx = get_context();
TRACE("datatype", tout << "relevant_eh: " << mk_pp(n, get_manager()) << "\n";);
TRACE("datatype", tout << "relevant_eh: " << mk_pp(n, m) << "\n";);
SASSERT(ctx.relevancy());
if (is_recognizer(n)) {
SASSERT(ctx.e_internalized(n));
@ -522,7 +510,6 @@ namespace smt {
// collect equalities on all children that may have been used.
bool found = false;
ast_manager& m = get_manager();
for (enode * arg : enode::args(parentc)) {
// found an argument which is equal to root
if (arg->get_root() == child->get_root()) {
@ -548,7 +535,7 @@ namespace smt {
// explain the cycle root -> ... -> app -> root
void theory_datatype::occurs_check_explain(enode * app, enode * root) {
TRACE("datatype", tout << "occurs_check_explain " << mk_bounded_pp(app->get_owner(), get_manager()) << " <-> " << mk_bounded_pp(root->get_owner(), get_manager()) << "\n";);
TRACE("datatype", tout << "occurs_check_explain " << mk_bounded_pp(app->get_owner(), m) << " <-> " << mk_bounded_pp(root->get_owner(), m) << "\n";);
// first: explain that root=v, given that app=cstor(...,v,...)
@ -570,7 +557,7 @@ namespace smt {
TRACE("datatype",
tout << "occurs_check\n";
for (enode_pair const& p : m_used_eqs) {
tout << enode_eq_pp(p, get_context());
tout << enode_eq_pp(p, ctx);
});
}
@ -599,7 +586,7 @@ namespace smt {
}
// explore `arg` (with parent)
expr* earg = arg->get_owner();
sort* s = get_manager().get_sort(earg);
sort* s = m.get_sort(earg);
if (m_util.is_datatype(s)) {
m_parent.insert(arg->get_root(), parent);
oc_push_stack(arg);
@ -613,7 +600,7 @@ namespace smt {
occurs_check_explain(parent, aarg);
return true;
}
if (m_util.is_datatype(get_manager().get_sort(aarg->get_owner()))) {
if (m_util.is_datatype(m.get_sort(aarg->get_owner()))) {
m_parent.insert(aarg->get_root(), parent);
oc_push_stack(aarg);
}
@ -625,12 +612,11 @@ namespace smt {
ptr_vector<enode> const& theory_datatype::get_array_args(enode* n) {
m_array_args.reset();
context& ctx = get_context();
theory_array* th = dynamic_cast<theory_array*>(ctx.get_theory(m_autil.get_family_id()));
for (enode* p : th->parent_selects(n)) {
m_array_args.push_back(p);
}
app_ref def(m_autil.mk_default(n->get_owner()), get_manager());
app_ref def(m_autil.mk_default(n->get_owner()), m);
m_array_args.push_back(ctx.get_enode(def));
return m_array_args;
}
@ -643,7 +629,7 @@ namespace smt {
a3 = cons(v3, a1)
*/
bool theory_datatype::occurs_check(enode * n) {
TRACE("datatype", tout << "occurs check: " << enode_pp(n, get_context()) << "\n";);
TRACE("datatype", tout << "occurs check: " << enode_pp(n, ctx) << "\n";);
m_stats.m_occurs_check++;
bool res = false;
@ -657,7 +643,7 @@ namespace smt {
if (oc_cycle_free(app)) continue;
TRACE("datatype", tout << "occurs check loop: " << enode_pp(app, get_context()) << (op==ENTER?" enter":" exit")<< "\n";);
TRACE("datatype", tout << "occurs check loop: " << enode_pp(app, ctx) << (op==ENTER?" enter":" exit")<< "\n";);
switch (op) {
case ENTER:
@ -672,7 +658,6 @@ namespace smt {
if (res) {
// m_used_eqs should contain conflict
context & ctx = get_context();
region & r = ctx.get_region();
clear_mark();
ctx.set_conflict(ctx.mk_justification(ext_theory_conflict_justification(get_id(), r, 0, nullptr, m_used_eqs.size(), m_used_eqs.c_ptr())));
@ -698,11 +683,11 @@ namespace smt {
}
theory_datatype_params const& theory_datatype::params() const {
return get_context().get_fparams();
return ctx.get_fparams();
}
theory_datatype::theory_datatype(ast_manager & m):
theory(m.mk_family_id("datatype")),
theory_datatype::theory_datatype(context& ctx):
theory(ctx, ctx.get_manager().mk_family_id("datatype")),
m_util(m),
m_autil(m),
m_find(*this),
@ -734,7 +719,7 @@ namespace smt {
var_data * d = m_var_data[v];
out << "v" << v << " #" << get_enode(v)->get_owner_id() << " -> v" << m_find.find(v) << " ";
if (d->m_constructor)
out << enode_pp(d->m_constructor, get_context());
out << enode_pp(d->m_constructor, ctx);
else
out << "(null)";
out << "\n";
@ -744,9 +729,9 @@ namespace smt {
return false;
}
void theory_datatype::init_model(model_generator & m) {
m_factory = alloc(datatype_factory, get_manager(), m.get_model());
m.register_factory(m_factory);
void theory_datatype::init_model(model_generator & mg) {
m_factory = alloc(datatype_factory, m, mg.get_model());
mg.register_factory(m_factory);
}
class datatype_value_proc : public model_value_proc {
@ -777,10 +762,10 @@ namespace smt {
result->add_dependency(arg);
}
TRACE("datatype",
tout << mk_pp(n->get_owner(), get_manager()) << "\n";
tout << mk_pp(n->get_owner(), m) << "\n";
tout << "depends on\n";
for (enode* arg : enode::args(d->m_constructor)) {
tout << " " << mk_pp(arg->get_owner(), get_manager()) << "\n";
tout << " " << mk_pp(arg->get_owner(), m) << "\n";
});
return result;
}
@ -792,7 +777,6 @@ namespace smt {
var_data * d1 = m_var_data[v1];
var_data * d2 = m_var_data[v2];
if (d2->m_constructor != nullptr) {
context & ctx = get_context();
if (d1->m_constructor != nullptr && d1->m_constructor->get_decl() != d2->m_constructor->get_decl()) {
region & r = ctx.get_region();
enode_pair p(d1->m_constructor, d2->m_constructor);
@ -824,7 +808,6 @@ namespace smt {
void theory_datatype::add_recognizer(theory_var v, enode * recognizer) {
SASSERT(is_recognizer(recognizer));
context & ctx = get_context();
v = m_find.find(v);
var_data * d = m_var_data[v];
sort * s = recognizer->get_decl()->get_domain(0);
@ -867,12 +850,11 @@ namespace smt {
void theory_datatype::propagate_recognizer(theory_var v, enode * recognizer) {
SASSERT(is_recognizer(recognizer));
SASSERT(static_cast<int>(m_find.find(v)) == v);
context & ctx = get_context();
SASSERT(ctx.get_assignment(recognizer) == l_false);
unsigned num_unassigned = 0;
unsigned unassigned_idx = UINT_MAX;
enode * n = get_enode(v);
sort * dt = get_manager().get_sort(n->get_owner());
sort * dt = m.get_sort(n->get_owner());
var_data * d = m_var_data[v];
CTRACE("datatype", d->m_recognizers.empty(), ctx.display(tout););
SASSERT(!d->m_recognizers.empty());
@ -905,7 +887,7 @@ namespace smt {
// conflict
SASSERT(!lits.empty());
region & reg = ctx.get_region();
TRACE("datatype_conflict", tout << mk_ismt2_pp(recognizer->get_owner(), get_manager()) << "\n";
TRACE("datatype_conflict", tout << mk_ismt2_pp(recognizer->get_owner(), m) << "\n";
for (literal l : lits) {
ctx.display_detailed_literal(tout, l) << "\n";
}
@ -922,7 +904,7 @@ namespace smt {
if (!r) {
ptr_vector<func_decl> const & constructors = *m_util.get_datatype_constructors(dt);
func_decl * rec = m_util.get_constructor_is(constructors[unassigned_idx]);
app_ref rec_app(get_manager().mk_app(rec, n->get_owner()), get_manager());
app_ref rec_app(m.mk_app(rec, n->get_owner()), m);
ctx.internalize(rec_app, false);
consequent = literal(ctx.get_bool_var(rec_app));
}
@ -948,8 +930,6 @@ namespace smt {
If first is true, it means that v does not have recognizer yet.
*/
void theory_datatype::mk_split(theory_var v) {
context & ctx = get_context();
ast_manager & m = get_manager();
v = m_find.find(v);
enode * n = get_enode(v);
sort * s = m.get_sort(n->get_owner());

View file

@ -130,7 +130,7 @@ namespace smt {
bool is_shared(theory_var v) const override;
theory_datatype_params const& params() const;
public:
theory_datatype(ast_manager & m);
theory_datatype(context& ctx);
~theory_datatype() override;
theory * mk_fresh(context * new_ctx) override;
void display(std::ostream & out) const override;

View file

@ -277,7 +277,7 @@ namespace smt {
//
// -----------------------------------
public:
theory_dense_diff_logic(ast_manager & m, theory_arith_params & p);
theory_dense_diff_logic(context& ctx);
~theory_dense_diff_logic() override { reset_eh(); }
theory * mk_fresh(context * new_ctx) override;

View file

@ -29,11 +29,11 @@ Revision History:
namespace smt {
template<typename Ext>
theory_dense_diff_logic<Ext>::theory_dense_diff_logic(ast_manager & m, theory_arith_params & p):
theory(m.mk_family_id("arith")),
m_params(p),
m_autil(m),
m_arith_eq_adapter(*this, p, m_autil),
theory_dense_diff_logic<Ext>::theory_dense_diff_logic(context& ctx):
theory(ctx, ctx.get_manager().mk_family_id("arith")),
m_params(ctx.get_fparams()),
m_autil(ctx.get_manager()),
m_arith_eq_adapter(*this, m_autil),
m_non_diff_logic_exprs(false),
m_var_value_table(DEFAULT_HASHTABLE_INITIAL_CAPACITY, var_value_hash(*this), var_value_eq(*this)) {
m_edges.push_back(edge());
@ -41,12 +41,12 @@ namespace smt {
template<typename Ext>
theory* theory_dense_diff_logic<Ext>::mk_fresh(context * new_ctx) {
return alloc(theory_dense_diff_logic<Ext>, new_ctx->get_manager(), new_ctx->get_fparams());
return alloc(theory_dense_diff_logic<Ext>, *new_ctx);
}
template<typename Ext>
inline app * theory_dense_diff_logic<Ext>::mk_zero_for(expr * n) {
return m_autil.mk_numeral(rational(0), get_manager().get_sort(n));
return m_autil.mk_numeral(rational(0), m.get_sort(n));
}
template<typename Ext>
@ -66,13 +66,12 @@ namespace smt {
c.m_edge_id = self_edge_id;
c.m_distance.reset();
SASSERT(check_vector_sizes());
get_context().attach_th_var(n, this, v);
ctx.attach_th_var(n, this, v);
return v;
}
template<typename Ext>
theory_var theory_dense_diff_logic<Ext>::internalize_term_core(app * n) {
context & ctx = get_context();
if (ctx.e_internalized(n)) {
enode * e = ctx.get_enode(n);
if (is_attached_to_var(e))
@ -125,9 +124,9 @@ namespace smt {
template<typename Ext>
void theory_dense_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";);
get_context().push_trail(value_trail<context, bool>(m_non_diff_logic_exprs));
IF_VERBOSE(0, verbose_stream() << "(smt.diff_logic: non-diff logic expression " << mk_pp(n, get_manager()) << ")\n";);
TRACE("non_diff_logic", tout << "found non diff logic expression:\n" << mk_pp(n, m) << "\n";);
ctx.push_trail(value_trail<context, bool>(m_non_diff_logic_exprs));
IF_VERBOSE(0, verbose_stream() << "(smt.diff_logic: non-diff logic expression " << mk_pp(n, m) << ")\n";);
m_non_diff_logic_exprs = true;
}
}
@ -138,8 +137,7 @@ namespace smt {
found_non_diff_logic_expr(n); // little hack... TODO: change to no_memory and return l_undef if SAT
return false;
}
TRACE("ddl", tout << "internalizing atom:\n" << mk_pp(n, get_manager()) << "\n";);
context & ctx = get_context();
TRACE("ddl", tout << "internalizing atom:\n" << mk_pp(n, m) << "\n";);
SASSERT(!ctx.b_internalized(n));
SASSERT(m_autil.is_le(n) || m_autil.is_ge(n));
theory_var source, target;
@ -170,15 +168,15 @@ namespace smt {
s = mk_zero_for(t);
}
else {
TRACE("ddl", tout << "failed to internalize:\n" << mk_pp(n, get_manager()) << "\n";);
TRACE("ddl", tout << "failed to internalize:\n" << mk_pp(n, m) << "\n";);
found_non_diff_logic_expr(n);
return false;
}
TRACE("arith", tout << expr_ref(lhs, get_manager()) << " " << expr_ref(s, get_manager()) << " " << expr_ref(t, get_manager()) << "\n";);
TRACE("arith", tout << expr_ref(lhs, m) << " " << expr_ref(s, m) << " " << expr_ref(t, m) << "\n";);
source = internalize_term_core(s);
target = internalize_term_core(t);
if (source == null_theory_var || target == null_theory_var) {
TRACE("ddl", tout << "failed to internalize:\n" << mk_pp(n, get_manager()) << "\n";);
TRACE("ddl", tout << "failed to internalize:\n" << mk_pp(n, m) << "\n";);
found_non_diff_logic_expr(n);
return false;
}
@ -195,18 +193,18 @@ namespace smt {
m_bv2atoms.setx(bv, a, 0);
m_matrix[source][target].m_occs.push_back(a);
m_matrix[target][source].m_occs.push_back(a);
TRACE("ddl", tout << "succeeded internalizing:\n" << mk_pp(n, get_manager()) << "\n";);
TRACE("ddl", tout << "succeeded internalizing:\n" << mk_pp(n, m) << "\n";);
return true;
}
template<typename Ext>
void theory_dense_diff_logic<Ext>::mk_clause(literal l1, literal l2) {
get_context().mk_th_axiom(get_id(), l1, l2);
ctx.mk_th_axiom(get_id(), l1, l2);
}
template<typename Ext>
void theory_dense_diff_logic<Ext>::mk_clause(literal l1, literal l2, literal l3) {
get_context().mk_th_axiom(get_id(), l1, l2, l3);
ctx.mk_th_axiom(get_id(), l1, l2, l3);
}
template<typename Ext>
@ -215,9 +213,9 @@ namespace smt {
found_non_diff_logic_expr(term); // little hack... TODO: change to no_memory and return l_undef if SAT
return false;
}
TRACE("ddl", tout << "internalizing term: " << mk_pp(term, get_manager()) << "\n";);
TRACE("ddl", tout << "internalizing term: " << mk_pp(term, m) << "\n";);
theory_var v = internalize_term_core(term);
TRACE("ddl", tout << mk_pp(term, get_manager()) << "\ninternalization result: " << (v != null_theory_var) << "\n";);
TRACE("ddl", tout << mk_pp(term, m) << "\ninternalization result: " << (v != null_theory_var) << "\n";);
if (v == null_theory_var)
found_non_diff_logic_expr(term);
return v != null_theory_var;
@ -225,10 +223,9 @@ namespace smt {
template<typename Ext>
void theory_dense_diff_logic<Ext>::internalize_eq_eh(app * atom, bool_var v) {
TRACE("ddl", tout << "eq-eh: " << mk_pp(atom, get_manager()) << "\n";);
TRACE("ddl", tout << "eq-eh: " << mk_pp(atom, m) << "\n";);
if (memory::above_high_watermark())
return;
context & ctx = get_context();
app * lhs = to_app(atom->get_arg(0));
app * rhs = to_app(atom->get_arg(1));
app * s;
@ -258,13 +255,13 @@ namespace smt {
template<typename Ext>
void theory_dense_diff_logic<Ext>::assign_eh(bool_var v, bool is_true) {
if (get_context().has_th_justification(v, get_id())) {
if (ctx.has_th_justification(v, get_id())) {
TRACE("ddl", tout << "ignoring atom propagated by the theory.\n";);
return;
}
atom * a = m_bv2atoms.get(v, 0);
if (!a) {
SASSERT(get_manager().is_eq(get_context().bool_var2expr(v)));
SASSERT(m.is_eq(ctx.bool_var2expr(v)));
return;
}
m_stats.m_num_assertions++;
@ -540,7 +537,6 @@ namespace smt {
template<typename Ext>
void theory_dense_diff_logic<Ext>::assign_literal(literal l, theory_var source, theory_var target) {
context & ctx = get_context();
literal_vector & antecedents = m_tmp_literals;
antecedents.reset();
get_antecedents(source, target, antecedents);
@ -553,7 +549,6 @@ namespace smt {
SASSERT(c.m_edge_id != null_edge_id);
numeral neg_dist = c.m_distance;
neg_dist.neg();
context & ctx = get_context();
typename atoms::const_iterator it = c.m_occs.begin();
typename atoms::const_iterator end = c.m_occs.end();
for (; it != end; ++it) {
@ -597,7 +592,6 @@ namespace smt {
get_antecedents(target, source, antecedents);
if (l != null_literal)
antecedents.push_back(l);
context & ctx = get_context();
region & r = ctx.get_region();
ctx.set_conflict(ctx.mk_justification(theory_conflict_justification(get_id(), r, antecedents.size(), antecedents.c_ptr())));
@ -698,7 +692,7 @@ namespace smt {
out.width(5);
out << std::left << get_enode(a->get_source())->get_owner_id() << " <= ";
out.width(10);
out << std::left << a->get_offset() << " assignment: " << get_context().get_assignment(a->get_bool_var()) << "\n";
out << std::left << a->get_offset() << " assignment: " << ctx.get_assignment(a->get_bool_var()) << "\n";
}
template<typename Ext>
@ -733,7 +727,7 @@ namespace smt {
TRACE("ddl_model",
tout << "ddl model\n";
for (theory_var v = 0; v < num_vars; v++) {
tout << "#" << mk_pp(get_enode(v)->get_owner(), get_manager()) << " = " << m_assignment[v] << "\n";
tout << "#" << mk_pp(get_enode(v)->get_owner(), m) << " = " << m_assignment[v] << "\n";
});
}
@ -811,11 +805,11 @@ namespace smt {
enode * n = get_enode(v);
if (m_autil.is_zero(n->get_owner()) && !m_assignment[v].is_zero()) {
numeral val = m_assignment[v];
sort * s = get_manager().get_sort(n->get_owner());
sort * s = m.get_sort(n->get_owner());
// adjust the value of all variables that have the same sort.
for (int v2 = 0; v2 < num_vars; ++v2) {
enode * n2 = get_enode(v2);
if (get_manager().get_sort(n2->get_owner()) == s) {
if (m.get_sort(n2->get_owner()) == s) {
m_assignment[v2] -= val;
}
}
@ -825,14 +819,14 @@ namespace smt {
TRACE("ddl_model",
tout << "ddl model\n";
for (theory_var v = 0; v < num_vars; v++) {
tout << "#" << mk_pp(get_enode(v)->get_owner(), get_manager()) << " = " << m_assignment[v] << "\n";
tout << "#" << mk_pp(get_enode(v)->get_owner(), m) << " = " << m_assignment[v] << "\n";
});
}
template<typename Ext>
void theory_dense_diff_logic<Ext>::init_model(model_generator & m) {
m_factory = alloc(arith_factory, get_manager());
m.register_factory(m_factory);
void theory_dense_diff_logic<Ext>::init_model(model_generator & mg) {
m_factory = alloc(arith_factory, m);
mg.register_factory(m_factory);
if (!m_assignment.empty()) {
fix_zero();
compute_epsilon();
@ -880,7 +874,6 @@ namespace smt {
return false;
}
else {
context& ctx = get_context();
enode * e = nullptr;
theory_var v = 0;
if (ctx.e_internalized(n)) {
@ -924,7 +917,6 @@ namespace smt {
template<typename Ext>
inf_eps_rational<inf_rational> theory_dense_diff_logic<Ext>::maximize(theory_var v, expr_ref& blocker, bool& has_shared) {
typedef simplex::simplex<simplex::mpq_ext> Simplex;
ast_manager& m = get_manager();
Simplex S(m.limit());
objective_term const& objective = m_objectives[v];
has_shared = false;
@ -1025,7 +1017,7 @@ namespace smt {
unsigned edge_id = v - num_nodes;
literal lit = m_edges[edge_id].m_justification;
if (lit != null_literal) {
get_context().literal2expr(lit, tmp);
ctx.literal2expr(lit, tmp);
core.push_back(tmp);
}
}
@ -1053,12 +1045,12 @@ namespace smt {
template<typename Ext>
theory_var theory_dense_diff_logic<Ext>::add_objective(app* term) {
TRACE("opt", tout << mk_pp(term, get_manager()) << "\n";);
TRACE("opt", tout << mk_pp(term, m) << "\n";);
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)) {
@ -1085,7 +1077,6 @@ namespace smt {
template<typename Ext>
expr_ref theory_dense_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);
TRACE("opt", tout << "mk_ineq " << v << " " << val << "\n";);

View file

@ -226,26 +226,7 @@ namespace smt {
void set_sort(expr* n);
public:
theory_diff_logic(ast_manager& m, smt_params & params):
theory(m.mk_family_id("arith")),
m_params(params),
m_util(m),
m_arith_eq_adapter(*this, params, m_util),
m_consistent(true),
m_izero(null_theory_var),
m_rzero(null_theory_var),
m_terms(m),
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(m.limit()),
m_num_simplex_edges(0) {
}
theory_diff_logic(context& ctx);
~theory_diff_logic() override {
reset_eh();
@ -255,13 +236,13 @@ namespace smt {
char const * get_name() const override { return "difference-logic"; }
void init() override { init_zero(); }
/**
\brief See comment in theory::mk_eq_atom
*/
app * mk_eq_atom(expr * lhs, expr * rhs) override { return m_util.mk_eq(lhs, rhs); }
void init(context * ctx) override;
bool internalize_atom(app * atom, bool gate_ctx) override;
bool internalize_term(app * term) override;

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);

View file

@ -102,11 +102,11 @@ namespace smt {
};
public:
theory_dl(ast_manager& m):
theory(m.mk_family_id("datalog_relation")),
m_util(m),
m_bv(m),
m_trail(m)
theory_dl(context& ctx):
theory(ctx, ctx.get_manager().mk_family_id("datalog_relation")),
m_util(ctx.get_manager()),
m_bv(ctx.get_manager()),
m_trail(ctx.get_manager())
{
}
@ -115,7 +115,6 @@ namespace smt {
bool internalize_atom(app * atom, bool gate_ctx) override {
TRACE("theory_dl", tout << mk_pp(atom, m()) << "\n";);
context& ctx = get_context();
if (ctx.b_internalized(atom)) {
return true;
}
@ -155,7 +154,7 @@ namespace smt {
}
theory * mk_fresh(context * new_ctx) override {
return alloc(theory_dl, new_ctx->get_manager());
return alloc(theory_dl, *new_ctx);
}
void init_model(smt::model_generator & m) override {
@ -210,13 +209,12 @@ namespace smt {
m_vals.insert(s, v);
add_trail(r);
add_trail(v);
get_context().push_trail(insert_obj_map<context,sort,func_decl*>(m_reps, s));
get_context().push_trail(insert_obj_map<context,sort,func_decl*>(m_vals, s));
ctx.push_trail(insert_obj_map<context,sort,func_decl*>(m_reps, s));
ctx.push_trail(insert_obj_map<context,sort,func_decl*>(m_vals, s));
}
}
bool mk_rep(app* n) {
context & ctx = get_context();
unsigned num_args = n->get_num_args();
enode * e = nullptr;
for (unsigned i = 0; i < num_args; i++) {
@ -255,7 +253,6 @@ namespace smt {
app_ref lt(m()), le(m());
lt = u().mk_lt(x,y);
le = b().mk_ule(m().mk_app(r,y),m().mk_app(r,x));
context& ctx = get_context();
if (m().has_trace_stream()) {
app_ref body(m());
body = m().mk_eq(lt, le);
@ -276,7 +273,6 @@ namespace smt {
void assert_cnstr(expr* e) {
TRACE("theory_dl", tout << mk_pp(e, m()) << "\n";);
context& ctx = get_context();
if (m().has_trace_stream()) log_axiom_instantiation(e);
ctx.internalize(e, false);
if (m().has_trace_stream()) m().trace_stream() << "[end-of-instance]\n";
@ -287,11 +283,11 @@ namespace smt {
void add_trail(ast* a) {
m_trail.push_back(a);
get_context().push_trail(push_back_vector<context,ast_ref_vector>(m_trail));
ctx.push_trail(push_back_vector<context,ast_ref_vector>(m_trail));
}
};
theory* mk_theory_dl(ast_manager& m) { return alloc(theory_dl, m); }
theory* mk_theory_dl(context& ctx) { return alloc(theory_dl, ctx); }
};

View file

@ -22,7 +22,7 @@ Revision History:
namespace smt {
theory* mk_theory_dl(ast_manager& m);
theory* mk_theory_dl(context& ctx);
};

View file

@ -29,8 +29,8 @@ namespace smt {
}
}
theory_dummy::theory_dummy(family_id fid, char const * name):
theory(fid),
theory_dummy::theory_dummy(context& ctx, family_id fid, char const * name):
theory(ctx, fid),
m_theory_exprs(false),
m_name(name) {
}

View file

@ -46,10 +46,10 @@ namespace smt {
void display(std::ostream& out) const override {}
public:
theory_dummy(family_id fid, char const * name);
theory_dummy(context& ctx, family_id fid, char const * name);
~theory_dummy() override {}
theory * mk_fresh(context * new_ctx) override { return alloc(theory_dummy, get_family_id(), m_name); }
theory * mk_fresh(context * new_ctx) override { return alloc(theory_dummy, *new_ctx, get_family_id(), m_name); }
char const * get_name() const override;
};

View file

@ -84,20 +84,20 @@ namespace smt {
}
}
theory_fpa::theory_fpa(ast_manager & m) :
theory(m.mk_family_id("fpa")),
m_converter(m, this),
m_rw(m, m_converter, params_ref()),
m_th_rw(m),
theory_fpa::theory_fpa(context& ctx) :
theory(ctx, ctx.get_manager().mk_family_id("fpa")),
m_converter(ctx.get_manager(), this),
m_rw(ctx.get_manager(), m_converter, params_ref()),
m_th_rw(ctx.get_manager()),
m_trail_stack(*this),
m_fpa_util(m_converter.fu()),
m_bv_util(m_converter.bu()),
m_arith_util(m_converter.au()),
m_is_initialized(false)
m_is_initialized(true)
{
params_ref p;
p.set_bool("arith_lhs", true);
m_th_rw.updt_params(p);
m_th_rw.updt_params(p);
}
theory_fpa::~theory_fpa()
@ -105,7 +105,6 @@ namespace smt {
m_trail_stack.reset();
if (m_is_initialized) {
ast_manager & m = get_manager();
dec_ref_map_key_values(m, m_conversions);
dec_ref_collection_values(m, m_is_added_to_model);
@ -120,11 +119,6 @@ namespace smt {
SASSERT(m_is_added_to_model.empty());
}
void theory_fpa::init(context * ctx) {
smt::theory::init(ctx);
m_is_initialized = true;
}
app * theory_fpa::fpa_value_proc::mk_value(model_generator & mg, expr_ref_vector const & values) {
TRACE("t_fpa_detail",
ast_manager & m = m_th.get_manager();
@ -233,7 +227,6 @@ namespace smt {
app_ref theory_fpa::wrap(expr * e) {
SASSERT(m_fpa_util.is_float(e) || m_fpa_util.is_rm(e));
SASSERT(!m_fpa_util.is_bvwrap(e));
ast_manager & m = get_manager();
app_ref res(m);
if (m_fpa_util.is_fp(e)) {
@ -267,7 +260,6 @@ namespace smt {
SASSERT(!m_fpa_util.is_fp(e));
SASSERT(m_bv_util.is_bv(e));
SASSERT(m_fpa_util.is_float(s) || m_fpa_util.is_rm(s));
ast_manager & m = get_manager();
app_ref res(m);
unsigned bv_sz = m_bv_util.get_bv_size(e);
@ -293,8 +285,7 @@ namespace smt {
}
expr_ref theory_fpa::convert_atom(expr * e) {
ast_manager & m = get_manager();
TRACE("t_fpa_detail", tout << "converting atom: " << mk_ismt2_pp(e, get_manager()) << std::endl;);
TRACE("t_fpa_detail", tout << "converting atom: " << mk_ismt2_pp(e, m) << std::endl;);
expr_ref res(m);
proof_ref pr(m);
m_rw(e, res);
@ -306,15 +297,14 @@ namespace smt {
expr_ref theory_fpa::convert_term(expr * e) {
SASSERT(m_fpa_util.is_rm(e) || m_fpa_util.is_float(e));
ast_manager & m = get_manager();
expr_ref e_conv(m), res(m);
proof_ref pr(m);
m_rw(e, e_conv);
TRACE("t_fpa_detail", tout << "term: " << mk_ismt2_pp(e, get_manager()) << std::endl;
tout << "converted term: " << mk_ismt2_pp(e_conv, get_manager()) << std::endl;);
TRACE("t_fpa_detail", tout << "term: " << mk_ismt2_pp(e, m) << std::endl;
tout << "converted term: " << mk_ismt2_pp(e_conv, m) << std::endl;);
if (m_fpa_util.is_rm(e)) {
SASSERT(m_fpa_util.is_bv2rm(e_conv));
@ -340,7 +330,7 @@ namespace smt {
expr_ref theory_fpa::convert_conversion_term(expr * e) {
SASSERT(to_app(e)->get_family_id() == get_family_id());
/* This is for the conversion functions fp.to_* */
expr_ref res(get_manager());
expr_ref res(m);
m_rw(e, res);
m_th_rw(res, res);
return res;
@ -348,7 +338,6 @@ namespace smt {
expr_ref theory_fpa::convert(expr * e)
{
ast_manager & m = get_manager();
expr_ref res(m);
expr * ccnv;
TRACE("t_fpa", tout << "converting " << mk_ismt2_pp(e, m) << std::endl;);
@ -384,8 +373,6 @@ namespace smt {
expr_ref theory_fpa::mk_side_conditions()
{
ast_manager & m = get_manager();
context & ctx = get_context();
expr_ref res(m), t(m);
expr_ref_vector fmls(m);
@ -405,31 +392,26 @@ namespace smt {
}
void theory_fpa::assert_cnstr(expr * e) {
if (get_manager().is_true(e)) return;
TRACE("t_fpa_detail", tout << "asserting " << mk_ismt2_pp(e, get_manager()) << "\n";);
context & ctx = get_context();
if (get_manager().has_trace_stream()) log_axiom_instantiation(e);
if (m.is_true(e)) return;
TRACE("t_fpa_detail", tout << "asserting " << mk_ismt2_pp(e, m) << "\n";);
if (m.has_trace_stream()) log_axiom_instantiation(e);
ctx.internalize(e, 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";
literal lit(ctx.get_literal(e));
ctx.mark_as_relevant(lit);
ctx.mk_th_axiom(get_id(), 1, &lit);
}
void theory_fpa::attach_new_th_var(enode * n) {
context & ctx = get_context();
theory_var v = mk_var(n);
ctx.attach_th_var(n, this, v);
TRACE("t_fpa", tout << "new theory var: " << mk_ismt2_pp(n->get_owner(), get_manager()) << " := " << v << "\n";);
TRACE("t_fpa", tout << "new theory var: " << mk_ismt2_pp(n->get_owner(), m) << " := " << v << "\n";);
}
bool theory_fpa::internalize_atom(app * atom, bool gate_ctx) {
TRACE("t_fpa_internalize", tout << "internalizing atom: " << mk_ismt2_pp(atom, get_manager()) << std::endl;);
TRACE("t_fpa_internalize", tout << "internalizing atom: " << mk_ismt2_pp(atom, m) << std::endl;);
SASSERT(atom->get_family_id() == get_family_id());
ast_manager & m = get_manager();
context & ctx = get_context();
if (ctx.b_internalized(atom))
return true;
@ -450,12 +432,9 @@ namespace smt {
}
bool theory_fpa::internalize_term(app * term) {
TRACE("t_fpa_internalize", tout << "internalizing term: " << mk_ismt2_pp(term, get_manager()) << "\n";);
TRACE("t_fpa_internalize", tout << "internalizing term: " << mk_ismt2_pp(term, m) << "\n";);
SASSERT(term->get_family_id() == get_family_id());
SASSERT(!get_context().e_internalized(term));
ast_manager & m = get_manager();
context & ctx = get_context();
SASSERT(!ctx.e_internalized(term));
unsigned num_args = term->get_num_args();
for (unsigned i = 0; i < num_args; i++)
@ -493,14 +472,12 @@ namespace smt {
}
void theory_fpa::apply_sort_cnstr(enode * n, sort * s) {
TRACE("t_fpa", tout << "apply sort cnstr for: " << mk_ismt2_pp(n->get_owner(), get_manager()) << "\n";);
TRACE("t_fpa", tout << "apply sort cnstr for: " << mk_ismt2_pp(n->get_owner(), m) << "\n";);
SASSERT(s->get_family_id() == get_family_id());
SASSERT(m_fpa_util.is_float(s) || m_fpa_util.is_rm(s));
SASSERT(m_fpa_util.is_float(n->get_owner()) || m_fpa_util.is_rm(n->get_owner()));
SASSERT(n->get_owner()->get_decl()->get_range() == s);
ast_manager & m = get_manager();
context & ctx = get_context();
app_ref owner(n->get_owner(), m);
if (!is_attached_to_var(n)) {
@ -523,7 +500,6 @@ namespace smt {
}
void theory_fpa::new_eq_eh(theory_var x, theory_var y) {
ast_manager & m = get_manager();
enode * e_x = get_enode(x);
enode * e_y = get_enode(y);
@ -567,7 +543,6 @@ namespace smt {
}
void theory_fpa::new_diseq_eh(theory_var x, theory_var y) {
ast_manager & m = get_manager();
enode * e_x = get_enode(x);
enode * e_y = get_enode(y);
@ -614,7 +589,7 @@ namespace smt {
}
theory* theory_fpa::mk_fresh(context* new_ctx) {
return alloc(theory_fpa, new_ctx->get_manager());
return alloc(theory_fpa, *new_ctx);
}
void theory_fpa::push_scope_eh() {
@ -629,8 +604,6 @@ namespace smt {
}
void theory_fpa::assign_eh(bool_var v, bool is_true) {
ast_manager & m = get_manager();
context & ctx = get_context();
expr * e = ctx.bool_var2expr(v);
TRACE("t_fpa", tout << "assign_eh for: " << v << " (" << is_true << "):\n" << mk_ismt2_pp(e, m) << "\n";);
@ -645,7 +618,6 @@ namespace smt {
}
void theory_fpa::relevant_eh(app * n) {
ast_manager & m = get_manager();
TRACE("t_fpa", tout << "relevant_eh for: " << mk_ismt2_pp(n, m) << "\n";);
mpf_manager & mpfm = m_fpa_util.fm();
@ -678,7 +650,7 @@ namespace smt {
else {
expr_ref wu(m);
wu = m.mk_eq(unwrap(wrapped, m.get_sort(n)), n);
TRACE("t_fpa", tout << "w/u eq: " << std::endl << mk_ismt2_pp(wu, get_manager()) << std::endl;);
TRACE("t_fpa", tout << "w/u eq: " << std::endl << mk_ismt2_pp(wu, m) << std::endl;);
assert_cnstr(wu);
}
}
@ -709,7 +681,6 @@ namespace smt {
dealloc(m_factory);
m_factory = nullptr;
}
ast_manager & m = get_manager();
dec_ref_map_key_values(m, m_conversions);
dec_ref_collection_values(m, m_is_added_to_model);
theory::reset_eh();
@ -723,13 +694,11 @@ namespace smt {
void theory_fpa::init_model(model_generator & mg) {
TRACE("t_fpa", tout << "initializing model" << std::endl; display(tout););
ast_manager & m = get_manager();
m_factory = alloc(fpa_value_factory, m, get_family_id());
mg.register_factory(m_factory);
}
enode* theory_fpa::ensure_enode(expr* e) {
context& ctx = get_context();
if (!ctx.e_internalized(e)) {
ctx.internalize(e, false);
}
@ -739,8 +708,6 @@ namespace smt {
}
app* theory_fpa::get_ite_value(expr* e) {
ast_manager & m = get_manager();
context& ctx = get_context();
expr* e1, *e2, *e3;
while (m.is_ite(e, e1, e2, e3) && ctx.e_internalized(e)) {
if (ctx.get_enode(e2)->get_root() == ctx.get_enode(e)->get_root()) {
@ -757,11 +724,9 @@ namespace smt {
}
model_value_proc * theory_fpa::mk_value(enode * n, model_generator & mg) {
TRACE("t_fpa", tout << "mk_value for: " << mk_ismt2_pp(n->get_owner(), get_manager()) <<
" (sort " << mk_ismt2_pp(get_manager().get_sort(n->get_owner()), get_manager()) << ")\n";);
TRACE("t_fpa", tout << "mk_value for: " << mk_ismt2_pp(n->get_owner(), m) <<
" (sort " << mk_ismt2_pp(m.get_sort(n->get_owner()), m) << ")\n";);
ast_manager & m = get_manager();
context & ctx = get_context();
app_ref owner(m);
owner = get_ite_value(n->get_owner());
@ -840,7 +805,6 @@ namespace smt {
}
void theory_fpa::finalize_model(model_generator & mg) {
ast_manager & m = get_manager();
proto_model & mdl = mg.get_model();
proto_model new_model(m);
@ -869,8 +833,6 @@ namespace smt {
void theory_fpa::display(std::ostream & out) const
{
ast_manager & m = get_manager();
context & ctx = get_context();
bool first = true;
for (enode* n : ctx.enodes()) {

View file

@ -177,11 +177,9 @@ namespace smt {
void finalize_model(model_generator & mg) override;
public:
theory_fpa(ast_manager & m);
theory_fpa(context& ctx);
~theory_fpa() override;
void init(context * ctx) override;
void display(std::ostream & out) const override;
protected:

View file

@ -55,7 +55,6 @@ namespace smt {
}
bool theory_jobscheduler::internalize_term(app * term) {
context & ctx = get_context();
if (ctx.e_internalized(term))
return true;
for (expr* arg : *term) {
@ -71,7 +70,6 @@ namespace smt {
bool theory_jobscheduler::internalize_atom(app * atom, bool gate_ctx) {
TRACE("csp", tout << mk_pp(atom, m) << "\n";);
context & ctx = get_context();
SASSERT(u.is_model(atom));
for (expr* arg : *atom) {
if (!ctx.e_internalized(arg)) ctx.internalize(arg, false);
@ -199,7 +197,6 @@ namespace smt {
literal theory_jobscheduler::mk_literal(expr * e) {
expr_ref _e(e, m);
context& ctx = get_context();
if (!ctx.e_internalized(e)) {
ctx.internalize(e, false);
}
@ -228,7 +225,6 @@ namespace smt {
}
literal theory_jobscheduler::mk_le(enode* l, enode* r) {
context& ctx = get_context();
expr_ref le(a.mk_le(l->get_owner(), r->get_owner()), m);
ctx.get_rewriter()(le);
return mk_literal(le);
@ -240,7 +236,7 @@ namespace smt {
literal theory_jobscheduler::mk_eq_lit(expr * l, expr * r) {
literal lit = mk_eq(l, r, false);
get_context().mark_as_relevant(lit);
ctx.mark_as_relevant(lit);
return lit;
}
@ -290,7 +286,6 @@ namespace smt {
void theory_jobscheduler::propagate_end_time(unsigned j, unsigned r) {
time_t slb = est(j);
time_t clb = ect(j, r, slb);
context& ctx = get_context();
if (clb > end(j)) {
job_info const& ji = m_jobs[j];
@ -384,7 +379,6 @@ namespace smt {
lits.push_back(~mk_le(start_e, t1));
expr_ref rhs(a.mk_add(start_e->get_owner(), a.mk_int(rational(delta, rational::ui64()))), m);
lits.push_back(mk_eq_lit(end_e->get_owner(), rhs));
context& ctx = get_context();
ctx.mk_clause(lits.size(), lits.c_ptr(), nullptr, CLS_TH_LEMMA, nullptr);
ast_manager& m = get_manager();
if (m.has_trace_stream()) {
@ -457,7 +451,6 @@ namespace smt {
}
if (j == last_job) break;
}
context& ctx = get_context();
ctx.mk_clause(lits.size(), lits.c_ptr(), nullptr, CLS_TH_LEMMA, nullptr);
}
@ -503,9 +496,9 @@ namespace smt {
}
}
theory_jobscheduler::theory_jobscheduler(ast_manager& m):
theory(m.get_family_id("csp")),
m(m),
theory_jobscheduler::theory_jobscheduler(context& ctx):
theory(ctx, ctx.get_manager().get_family_id("csp")),
m(ctx.get_manager()),
u(m),
a(m),
m_bound_qhead(0) {
@ -576,7 +569,7 @@ namespace smt {
}
theory * theory_jobscheduler::mk_fresh(context * new_ctx) {
return alloc(theory_jobscheduler, new_ctx->get_manager());
return alloc(theory_jobscheduler, *new_ctx);
}
time_t theory_jobscheduler::get_lo(expr* e) {
@ -657,7 +650,6 @@ namespace smt {
unsigned r = m_resources.size();
m_resources.push_back(res_info());
res_info& ri = m_resources.back();
context& ctx = get_context();
app_ref res(u.mk_resource(r), m);
if (!ctx.e_internalized(res)) ctx.internalize(res, false);
ri.m_resource = ctx.get_enode(res);
@ -673,7 +665,6 @@ namespace smt {
unsigned j = m_jobs.size();
m_jobs.push_back(job_info());
job_info& ji = m_jobs.back();
context& ctx = get_context();
app_ref job(u.mk_job(j), m);
app_ref start(u.mk_start(j), m);
app_ref end(u.mk_end(j), m);
@ -691,7 +682,7 @@ namespace smt {
}
void theory_jobscheduler::add_job_resource(unsigned j, unsigned r, unsigned loadpct, uint64_t cap, time_t finite_capacity_end, properties const& ps) {
SASSERT(get_context().at_base_level());
SASSERT(ctx.at_base_level());
SASSERT(0 <= loadpct && loadpct <= 100);
SASSERT(0 <= cap);
job_info& ji = ensure_job(j);
@ -707,7 +698,7 @@ namespace smt {
void theory_jobscheduler::add_resource_available(unsigned r, unsigned max_loadpct, time_t start, time_t end, properties const& ps) {
SASSERT(get_context().at_base_level());
SASSERT(ctx.at_base_level());
SASSERT(1 <= max_loadpct && max_loadpct <= 100);
SASSERT(start <= end);
res_info& ri = ensure_resource(r);
@ -731,7 +722,6 @@ namespace smt {
*/
void theory_jobscheduler::add_done() {
TRACE("csp", tout << "add-done begin\n";);
context & ctx = get_context();
// sort availability intervals
for (res_info& ri : m_resources) {
@ -819,7 +809,6 @@ namespace smt {
#if 0
job_info const& ji = m_jobs[j];
literal l2 = mk_le(ji.m_end, jr.m_finite_capacity_end);
context& ctx = get_context();
if (m.has_trace_stream()) {
app_ref body(m);
body = m.mk_implies(ctx.bool_var2expr(eq.var()), ctx.bool_var2expr(l2.var()));
@ -832,7 +821,6 @@ namespace smt {
// resource(j) = r => start(j) <= lst(j, r, end(j, r))
void theory_jobscheduler::assert_last_start_time(unsigned j, unsigned r, literal eq) {
context& ctx = get_context();
time_t t;
if (lst(j, r, t)) {
literal le = mk_le(m_jobs[j].m_start, t);
@ -863,7 +851,6 @@ namespace smt {
if (!first_available(jr, m_resources[r], idx)) return;
vector<res_available>& available = m_resources[r].m_available;
literal l2 = mk_ge(m_jobs[j].m_start, available[idx].m_start);
context& ctx = get_context();
if (m.has_trace_stream()) {
app_ref body(m);
body = m.mk_implies(ctx.bool_var2expr(eq.var()), ctx.bool_var2expr(l2.var()));
@ -881,7 +868,6 @@ namespace smt {
SASSERT(resource_available(jr, available[idx]));
literal l2 = mk_ge(m_jobs[j].m_start, available[idx1].m_start);
literal l3 = mk_le(m_jobs[j].m_start, available[idx].m_end);
context& ctx = get_context();
if (m.has_trace_stream()) {
app_ref body(m);
body = m.mk_implies(ctx.bool_var2expr(eq.var()), m.mk_or(ctx.bool_var2expr(l2.var()), ctx.bool_var2expr(l3.var())));
@ -899,7 +885,6 @@ namespace smt {
SASSERT(resource_available(jr, available[idx]));
literal l2 = mk_le(m_jobs[j].m_end, available[idx].m_end);
literal l3 = mk_ge(m_jobs[j].m_start, available[idx1].m_start);
context& ctx = get_context();
if (m.has_trace_stream()) {
app_ref body(m);
body = m.mk_implies(ctx.bool_var2expr(eq.var()), m.mk_or(ctx.bool_var2expr(l2.var()), ctx.bool_var2expr(l3.var())));
@ -914,7 +899,6 @@ namespace smt {
*/
bool theory_jobscheduler::split_job2resource(unsigned j) {
job_info const& ji = m_jobs[j];
context& ctx = get_context();
if (ji.m_is_bound) return false;
auto const& jrs = ji.m_resources;
for (job_resource const& jr : jrs) {

View file

@ -133,7 +133,7 @@ namespace smt {
public:
theory_jobscheduler(ast_manager& m);
theory_jobscheduler(context& ctx);
~theory_jobscheduler() override {}

View file

@ -170,7 +170,6 @@ class theory_lra::imp {
theory_lra& th;
ast_manager& m;
theory_arith_params& m_arith_params;
arith_util a;
arith_eq_adapter m_arith_eq_adapter;
vector<rational> m_columns;
@ -362,6 +361,7 @@ class theory_lra::imp {
context& ctx() const { return th.get_context(); }
theory_id get_id() const { return th.get_id(); }
theory_arith_params const& params() const { return ctx().get_fparams(); }
bool is_int(theory_var v) const { return is_int(get_enode(v)); }
bool is_int(enode* n) const { return a.is_int(n->get_owner()); }
bool is_real(theory_var v) const { return is_real(get_enode(v)); }
@ -373,42 +373,6 @@ class theory_lra::imp {
lp::lar_solver& lp(){ return *m_solver.get(); }
const lp::lar_solver& lp() const { return *m_solver.get(); }
void init_solver() {
if (m_solver) return;
reset_variable_values();
m_solver = alloc(lp::lar_solver);
// initialize 0, 1 variables:
get_one(true);
get_one(false);
get_zero(true);
get_zero(false);
smt_params_helper lpar(ctx().get_params());
lp().settings().set_resource_limit(m_resource_limit);
lp().settings().simplex_strategy() = static_cast<lp::simplex_strategy_enum>(lpar.arith_simplex_strategy());
lp().settings().bound_propagation() = BP_NONE != propagation_mode();
lp().settings().m_enable_hnf = lpar.arith_enable_hnf();
lp().settings().m_print_external_var_name = lpar.arith_print_ext_var_names();
lp().set_track_pivoted_rows(lpar.arith_bprop_on_pivoted_rows());
lp().settings().report_frequency = lpar.arith_rep_freq();
lp().settings().print_statistics = lpar.arith_print_stats();
// todo : do not use m_arith_branch_cut_ratio for deciding on cheap cuts
unsigned branch_cut_ratio = ctx().get_fparams().m_arith_branch_cut_ratio;
lp().set_cut_strategy(branch_cut_ratio);
lp().settings().m_int_run_gcd_test = ctx().get_fparams().m_arith_gcd_test;
lp().settings().set_random_seed(ctx().get_fparams().m_random_seed);
m_switcher.m_use_nla = true;
m_lia = alloc(lp::int_solver, *m_solver.get());
get_one(true);
get_zero(true);
get_one(false);
get_zero(false);
}
void ensure_nra() {
if (!m_nra) {
m_nra = alloc(nra::solver, *m_solver.get(), m.limit(), ctx().get_params());
@ -753,7 +717,7 @@ class theory_lra::imp {
}
bool reflect(app* n) const {
return m_arith_params.m_arith_reflect || is_underspecified(n);
return params().m_arith_reflect || is_underspecified(n);
}
bool has_var(expr* n) {
@ -995,11 +959,10 @@ class theory_lra::imp {
public:
imp(theory_lra& th, ast_manager& m, theory_arith_params& ap):
imp(theory_lra& th, ast_manager& m):
th(th), m(m),
m_arith_params(ap),
a(m),
m_arith_eq_adapter(th, ap, a),
m_arith_eq_adapter(th, a),
m_internalize_head(0),
m_one_var(UINT_MAX),
m_zero_var(UINT_MAX),
@ -1022,8 +985,40 @@ public:
std::for_each(m_internalize_states.begin(), m_internalize_states.end(), delete_proc<internalize_state>());
}
void init(context* ctx) {
init_solver();
void init() {
if (m_solver) return;
reset_variable_values();
m_solver = alloc(lp::lar_solver);
// initialize 0, 1 variables:
get_one(true);
get_one(false);
get_zero(true);
get_zero(false);
smt_params_helper lpar(ctx().get_params());
lp().settings().set_resource_limit(m_resource_limit);
lp().settings().simplex_strategy() = static_cast<lp::simplex_strategy_enum>(lpar.arith_simplex_strategy());
lp().settings().bound_propagation() = BP_NONE != propagation_mode();
lp().settings().m_enable_hnf = lpar.arith_enable_hnf();
lp().settings().m_print_external_var_name = lpar.arith_print_ext_var_names();
lp().set_track_pivoted_rows(lpar.arith_bprop_on_pivoted_rows());
lp().settings().report_frequency = lpar.arith_rep_freq();
lp().settings().print_statistics = lpar.arith_print_stats();
// todo : do not use m_arith_branch_cut_ratio for deciding on cheap cuts
unsigned branch_cut_ratio = ctx().get_fparams().m_arith_branch_cut_ratio;
lp().set_cut_strategy(branch_cut_ratio);
lp().settings().m_int_run_gcd_test = ctx().get_fparams().m_arith_gcd_test;
lp().settings().set_random_seed(ctx().get_fparams().m_random_seed);
m_switcher.m_use_nla = true;
m_lia = alloc(lp::int_solver, *m_solver.get());
get_one(true);
get_zero(true);
get_one(false);
get_zero(false);
}
void internalize_is_int(app * n) {
@ -1433,7 +1428,7 @@ public:
};
if_trace_stream _ts(m, log);
}
if (m_arith_params.m_arith_enum_const_mod && k.is_pos() && k < rational(8)) {
if (params().m_arith_enum_const_mod && k.is_pos() && k < rational(8)) {
unsigned _k = k.get_unsigned();
literal_buffer lits;
expr_ref_vector exprs(m);
@ -3064,13 +3059,13 @@ public:
}
bool dump_lemmas() const { return m_arith_params.m_arith_dump_lemmas; }
bool dump_lemmas() const { return params().m_arith_dump_lemmas; }
bool propagate_eqs() const { return m_arith_params.m_arith_propagate_eqs && m_num_conflicts < m_arith_params.m_arith_propagation_threshold; }
bool propagate_eqs() const { return params().m_arith_propagate_eqs && m_num_conflicts < params().m_arith_propagation_threshold; }
bound_prop_mode propagation_mode() const { return m_num_conflicts < m_arith_params.m_arith_propagation_threshold ? m_arith_params.m_arith_bound_prop : BP_NONE; }
bound_prop_mode propagation_mode() const { return m_num_conflicts < params().m_arith_propagation_threshold ? params().m_arith_bound_prop : BP_NONE; }
unsigned small_lemma_size() const { return m_arith_params.m_arith_small_lemma_size; }
unsigned small_lemma_size() const { return params().m_arith_small_lemma_size; }
bool proofs_enabled() const { return m.proofs_enabled(); }
@ -3544,7 +3539,7 @@ public:
}
bool validate_conflict(literal_vector const& core, svector<enode_pair> const& eqs) {
if (m_arith_params.m_arith_mode != AS_NEW_ARITH) return true;
if (params().m_arith_mode != AS_NEW_ARITH) return true;
scoped_arith_mode _sa(ctx().get_fparams());
context nctx(m, ctx().get_fparams(), ctx().get_params());
add_background(nctx);
@ -3563,7 +3558,7 @@ public:
}
bool validate_assign(literal lit, literal_vector const& core, svector<enode_pair> const& eqs) {
if (m_arith_params.m_arith_mode != AS_NEW_ARITH) return true;
if (params().m_arith_mode != AS_NEW_ARITH) return true;
scoped_arith_mode _sa(ctx().get_fparams());
context nctx(m, ctx().get_fparams(), ctx().get_params());
m_core.push_back(~lit);
@ -3578,7 +3573,7 @@ public:
}
bool validate_eq(enode* x, enode* y) {
if (m_arith_params.m_arith_mode == AS_NEW_ARITH) return true;
if (params().m_arith_mode == AS_NEW_ARITH) return true;
context nctx(m, ctx().get_fparams(), ctx().get_params());
add_background(nctx);
nctx.assert_expr(m.mk_not(m.mk_eq(x->get_owner(), y->get_owner())));
@ -3913,20 +3908,20 @@ public:
}
};
theory_lra::theory_lra(ast_manager& m, theory_arith_params& ap):
theory(m.get_family_id("arith")) {
m_imp = alloc(imp, *this, m, ap);
theory_lra::theory_lra(context& ctx):
theory(ctx, ctx.get_manager().get_family_id("arith")) {
m_imp = alloc(imp, *this, ctx.get_manager());
}
theory_lra::~theory_lra() {
dealloc(m_imp);
}
theory* theory_lra::mk_fresh(context* new_ctx) {
return alloc(theory_lra, new_ctx->get_manager(), new_ctx->get_fparams());
return alloc(theory_lra, *new_ctx);
}
void theory_lra::init(context * ctx) {
theory::init(ctx);
m_imp->init(ctx);
void theory_lra::init() {
m_imp->init();
}
bool theory_lra::internalize_atom(app * atom, bool gate_ctx) {
return m_imp->internalize_atom(atom, gate_ctx);
}

View file

@ -28,13 +28,13 @@ namespace smt {
imp* m_imp;
public:
theory_lra(ast_manager& m, theory_arith_params& ap);
theory_lra(context& ctx);
~theory_lra() override;
theory* mk_fresh(context* new_ctx) override;
char const* get_name() const override { return "arithmetic"; }
void init(context * ctx) override;
void init() override;
bool internalize_atom(app * atom, bool gate_ctx) override;
bool internalize_term(app * term) override;

View file

@ -433,17 +433,17 @@ namespace smt {
// ------------------------
// theory_pb
theory_pb::theory_pb(ast_manager& m, theory_pb_params& p):
theory(m.mk_family_id("pb")),
m_params(p),
pb(m),
theory_pb::theory_pb(context& ctx):
theory(ctx, ctx.get_manager().mk_family_id("pb")),
m_params(ctx.get_fparams()),
pb(ctx.get_manager()),
m_restart_lim(3),
m_restart_inc(0),
m_antecedent_exprs(m),
m_cardinality_exprs(m)
m_antecedent_exprs(ctx.get_manager()),
m_cardinality_exprs(ctx.get_manager())
{
m_learn_complements = p.m_pb_learn_complements;
m_conflict_frequency = p.m_pb_conflict_frequency;
m_learn_complements = ctx.get_fparams().m_pb_learn_complements;
m_conflict_frequency = ctx.get_fparams().m_pb_conflict_frequency;
}
theory_pb::~theory_pb() {
@ -451,12 +451,10 @@ namespace smt {
}
theory * theory_pb::mk_fresh(context * new_ctx) {
return alloc(theory_pb, new_ctx->get_manager(), new_ctx->get_fparams());
return alloc(theory_pb, *new_ctx);
}
bool theory_pb::internalize_atom(app * atom, bool gate_ctx) {
context& ctx = get_context();
ast_manager& m = get_manager();
if (ctx.b_internalized(atom)) {
return true;
@ -593,8 +591,6 @@ namespace smt {
}
literal theory_pb::compile_arg(expr* arg) {
context& ctx = get_context();
ast_manager& m = get_manager();
bool_var bv;
bool has_bv = false;
@ -784,7 +780,6 @@ namespace smt {
}
bool theory_pb::internalize_card(app * atom, bool gate_ctx) {
context& ctx = get_context();
if (ctx.b_internalized(atom)) {
return true;
}
@ -841,7 +836,6 @@ namespace smt {
// \brief define cardinality constraint as conjunction.
//
void theory_pb::card2conjunction(card const& c) {
context& ctx = get_context();
literal lit = c.lit();
literal_vector& lits = get_literals();
for (unsigned i = 0; i < c.size(); ++i) {
@ -856,7 +850,6 @@ namespace smt {
}
void theory_pb::card2disjunction(card const& c) {
context& ctx = get_context();
literal lit = c.lit();
literal_vector& lits = get_literals();
for (unsigned i = 0; i < c.size(); ++i) {
@ -902,7 +895,6 @@ namespace smt {
}
std::ostream& theory_pb::display(std::ostream& out, card const& c, bool values) const {
context& ctx = get_context();
out << c.lit();
if (c.lit() != null_literal) {
if (values) {
@ -936,7 +928,6 @@ namespace smt {
void theory_pb::add_clause(card& c, literal_vector const& lits) {
m_stats.m_num_conflicts++;
context& ctx = get_context();
justification* js = nullptr;
c.inc_propagations(*this);
if (!resolve_conflict(c, lits)) {
@ -949,7 +940,6 @@ namespace smt {
}
void theory_pb::add_assign(card& c, literal l) {
context& ctx = get_context();
if (ctx.get_assignment(l) == l_true) {
return;
}
@ -1001,7 +991,6 @@ namespace smt {
void theory_pb::assign_eh(bool_var v, bool is_true) {
ptr_vector<ineq>* ineqs = nullptr;
context& ctx = get_context();
literal nlit(v, is_true);
init_watch(v);
TRACE("pb", tout << "assign: " << ~nlit << "\n";);
@ -1057,7 +1046,6 @@ namespace smt {
}
literal_vector& theory_pb::get_all_literals(ineq& c, bool negate) {
context& ctx = get_context();
literal_vector& lits = get_literals();
for (unsigned i = 0; i < c.size(); ++i) {
literal l = c.lit(i);
@ -1078,7 +1066,6 @@ namespace smt {
literal_vector& theory_pb::get_helpful_literals(ineq& c, bool negate) {
scoped_mpz sum(m_mpz_mgr);
mpz const& k = c.mpz_k();
context& ctx = get_context();
literal_vector& lits = get_literals();
for (unsigned i = 0; sum < k && i < c.size(); ++i) {
literal l = c.lit(i);
@ -1093,7 +1080,6 @@ namespace smt {
}
literal_vector& theory_pb::get_unhelpful_literals(ineq& c, bool negate) {
context& ctx = get_context();
literal_vector& lits = get_literals();
for (unsigned i = 0; i < c.size(); ++i) {
literal l = c.lit(i);
@ -1121,7 +1107,6 @@ namespace smt {
and/or relatively few compared to number of argumets.
*/
void theory_pb::assign_ineq(ineq& c, bool is_true) {
context& ctx = get_context();
ctx.push_trail(value_trail<context, scoped_mpz>(c.m_max_sum));
ctx.push_trail(value_trail<context, scoped_mpz>(c.m_min_sum));
ctx.push_trail(value_trail<context, unsigned>(c.m_nfixed));
@ -1192,7 +1177,6 @@ namespace smt {
*/
bool theory_pb::assign_watch_ge(bool_var v, bool is_true, ineq_watch& watch, unsigned watch_index) {
bool removed = false;
context& ctx = get_context();
ineq& c = *watch[watch_index];
unsigned w = c.find_lit(v, 0, c.watch_size());
SASSERT(ctx.get_assignment(c.lit()) == l_true);
@ -1326,7 +1310,7 @@ namespace smt {
// for testing
literal theory_pb::assert_ge(context& ctx, unsigned k, unsigned n, literal const* xs) {
theory_pb_params p;
theory_pb th(ctx.get_manager(), p);
theory_pb th(ctx);
psort_expr ps(ctx, th);
psort_nw<psort_expr> sort(ps);
return sort.ge(false, k, n, xs);
@ -1342,7 +1326,6 @@ namespace smt {
bool theory_pb::gc() {
context& ctx = get_context();
unsigned z = 0, nz = 0;
m_occs.reset();
@ -1469,7 +1452,6 @@ namespace smt {
void theory_pb::init_watch_literal(ineq& c) {
context& ctx = get_context();
scoped_mpz max_k(m_mpz_mgr);
c.m_watch_sum.reset();
c.m_watch_sz = 0;
@ -1512,7 +1494,6 @@ namespace smt {
void theory_pb::add_assign(ineq& c, literal_vector const& lits, literal l) {
inc_propagations(c);
m_stats.m_num_propagations++;
context& ctx = get_context();
TRACE("pb", tout << "#prop:" << c.m_num_propagations << " - " << lits;
tout << " => " << l << "\n";
display(tout, c, true););
@ -1528,7 +1509,6 @@ namespace smt {
void theory_pb::add_clause(ineq& c, literal_vector const& lits) {
inc_propagations(c);
m_stats.m_num_conflicts++;
context& ctx = get_context();
TRACE("pb", tout << "#prop:" << c.m_num_propagations << " - " << lits << "\n";
display(tout, c, true););
justification* js = nullptr;
@ -1557,7 +1537,6 @@ namespace smt {
}
void theory_pb::process_antecedent(literal l, int offset) {
context& ctx = get_context();
SASSERT(ctx.get_assignment(l) == l_false);
bool_var v = l.var();
unsigned lvl = ctx.get_assign_level(v);
@ -1570,7 +1549,6 @@ namespace smt {
}
void theory_pb::process_card(card& c, int offset) {
context& ctx = get_context();
SASSERT(c.k() <= c.size());
SASSERT(ctx.get_assignment(c.lit()) == l_true);
for (unsigned i = c.k(); i < c.size(); ++i) {
@ -1586,7 +1564,6 @@ namespace smt {
bool theory_pb::validate_lemma() {
int value = -m_bound;
context& ctx = get_context();
normalize_active_coeffs();
for (unsigned i = 0; i < m_active_vars.size(); ++i) {
bool_var v = m_active_vars[i];
@ -1610,7 +1587,6 @@ namespace smt {
static bool validating = true; // false;
if (validating) return true;
validating = true;
ast_manager& m = get_manager();
smt_params fp;
kernel k(m, fp);
expr_ref notB(m.mk_not(B), m);
@ -1628,7 +1604,6 @@ namespace smt {
}
app_ref theory_pb::justification2expr(b_justification& js, literal conseq) {
ast_manager& m = get_manager();
app_ref result(m.mk_true(), m);
expr_ref_vector args(m);
vector<rational> coeffs;
@ -1692,7 +1667,6 @@ namespace smt {
Note that an asserting literal should be false with respect to the resolvent inequality.
*/
literal theory_pb::get_asserting_literal(literal p) {
context& ctx = get_context();
unsigned lvl = 0;
TRACE("pb", tout << p << " " << ctx.get_assignment(p) << "\n";);
@ -1831,8 +1805,6 @@ namespace smt {
TRACE("pb", display(tout, c, true); );
bool_var v;
context& ctx = get_context();
ast_manager& m = get_manager();
m_conflict_lvl = 0;
for (literal lit : confl) {
SASSERT(ctx.get_assignment(lit) == l_false);
@ -2044,14 +2016,14 @@ namespace smt {
}
bool theory_pb::is_proof_justification(justification const& j) const {
return typeid(smt::justification_proof_wrapper) == typeid(j) || get_manager().proofs_enabled();
return typeid(smt::justification_proof_wrapper) == typeid(j) || m.proofs_enabled();
}
justification* theory_pb::justify(literal l1, literal l2) {
literal lits[2] = { l1, l2 };
justification* js = nullptr;
if (proofs_enabled()) {
js = get_context().mk_justification(theory_axiom_justification(get_id(), get_context().get_region(), 2, lits));
js = ctx.mk_justification(theory_axiom_justification(get_id(), ctx.get_region(), 2, lits));
}
return js;
}
@ -2059,7 +2031,7 @@ namespace smt {
justification* theory_pb::justify(literal_vector const& lits) {
justification* js = nullptr;
if (proofs_enabled()) {
js = get_context().mk_justification(theory_axiom_justification(get_id(), get_context().get_region(), lits.size(), lits.c_ptr()));
js = ctx.mk_justification(theory_axiom_justification(get_id(), ctx.get_region(), lits.size(), lits.c_ptr()));
}
return js;
}
@ -2082,11 +2054,11 @@ namespace smt {
void theory_pb::validate_assign(ineq const& c, literal_vector const& lits, literal l) const {
uint_set nlits;
for (literal lit : lits) {
SASSERT(get_context().get_assignment(lit) == l_true);
SASSERT(ctx.get_assignment(lit) == l_true);
nlits.insert((~lit).index());
}
SASSERT(get_context().get_assignment(l) == l_undef);
SASSERT(get_context().get_assignment(c.lit()) == l_true);
SASSERT(ctx.get_assignment(l) == l_undef);
SASSERT(ctx.get_assignment(c.lit()) == l_true);
nlits.insert(l.index());
numeral sum = numeral::zero();
for (unsigned i = 0; i < c.size(); ++i) {
@ -2115,7 +2087,6 @@ namespace smt {
}
void theory_pb::validate_final_check(card& c) {
context& ctx = get_context();
if (ctx.get_assignment(c.lit()) == l_undef) {
TRACE("pb", display(tout << "is undef ", c, true););
return;
@ -2147,7 +2118,6 @@ namespace smt {
}
void theory_pb::validate_final_check(ineq& c) {
context& ctx = get_context();
if (ctx.get_assignment(c.lit()) == l_undef) {
TRACE("pb", tout << c.lit() << " is undef\n";);
@ -2182,7 +2152,6 @@ namespace smt {
}
bool theory_pb::validate_antecedents(literal_vector const& lits) {
context& ctx = get_context();
for (literal lit : lits) {
if (ctx.get_assignment(lit) != l_true) {
return false;
@ -2192,7 +2161,6 @@ namespace smt {
}
bool theory_pb::validate_unit_propagation(card const& c) {
context& ctx = get_context();
for (unsigned i = c.k(); i < c.size(); ++i) {
if (ctx.get_assignment(c.lit(i)) != l_false) {
return false;
@ -2202,13 +2170,11 @@ namespace smt {
}
app_ref theory_pb::literal2expr(literal lit) {
ast_manager& m = get_manager();
app_ref arg(m.mk_const(symbol((unsigned)lit.var()), m.mk_bool_sort()), m);
return app_ref(lit.sign() ? m.mk_not(arg) : arg, m);
}
app_ref theory_pb::active2expr() {
ast_manager& m = get_manager();
expr_ref_vector args(m);
vector<rational> coeffs;
normalize_active_coeffs();
@ -2225,7 +2191,6 @@ namespace smt {
// display methods
void theory_pb::display_resolved_lemma(std::ostream& out) const {
context& ctx = get_context();
out << "num marks: " << m_num_marks << "\n";
out << "conflict level: " << m_conflict_lvl << "\n";
for (literal r : m_resolved) {
@ -2264,12 +2229,10 @@ namespace smt {
}
std::ostream& theory_pb::display(std::ostream& out, arg_t const& c, bool values) const {
return c.display(get_context(), out, values);
return c.display(ctx, out, values);
}
std::ostream& theory_pb::display(std::ostream& out, ineq const& c, bool values) const {
ast_manager& m = get_manager();
context& ctx = get_context();
out << c.lit();
if (c.lit() != null_literal) {
if (values) {
@ -2389,7 +2352,6 @@ namespace smt {
}
model_value_proc * theory_pb::mk_value(enode * n, model_generator & mg) {
context& ctx = get_context();
app* a = n->get_owner();
pb_model_value_proc* p = alloc(pb_model_value_proc, a);
for (unsigned i = 0; i < a->get_num_args(); ++i) {

View file

@ -404,7 +404,7 @@ namespace smt {
justification* justify(literal_vector const& lits);
public:
theory_pb(ast_manager& m, theory_pb_params& p);
theory_pb(context& ctx);
~theory_pb() override;

View file

@ -27,9 +27,8 @@ Revision History:
namespace smt {
theory_recfun::theory_recfun(ast_manager & m)
: theory(m.mk_family_id("recfun")),
m(m),
theory_recfun::theory_recfun(context& ctx)
: theory(ctx, ctx.get_manager().mk_family_id("recfun")),
m_plugin(*reinterpret_cast<recfun::decl::plugin*>(m.get_plugin(get_family_id()))),
m_util(m_plugin.u()),
m_disabled_guards(m),
@ -38,6 +37,7 @@ namespace smt {
m_num_rounds(0),
m_q_case_expand(),
m_q_body_expand() {
m_num_rounds = 0;
}
theory_recfun::~theory_recfun() {
@ -47,12 +47,7 @@ namespace smt {
char const * theory_recfun::get_name() const { return "recfun"; }
theory* theory_recfun::mk_fresh(context* new_ctx) {
return alloc(theory_recfun, new_ctx->get_manager());
}
void theory_recfun::init(context* ctx) {
theory::init(ctx);
m_num_rounds = 0;
return alloc(theory_recfun, *new_ctx);
}
void theory_recfun::init_search_eh() {
@ -64,16 +59,16 @@ namespace smt {
return false;
}
for (expr * arg : *atom) {
ctx().internalize(arg, false);
ctx.internalize(arg, false);
}
if (!ctx().e_internalized(atom)) {
ctx().mk_enode(atom, false, true, false);
if (!ctx.e_internalized(atom)) {
ctx.mk_enode(atom, false, true, false);
}
if (!ctx().b_internalized(atom)) {
bool_var v = ctx().mk_bool_var(atom);
ctx().set_var_theory(v, get_id());
if (!ctx.b_internalized(atom)) {
bool_var v = ctx.mk_bool_var(atom);
ctx.set_var_theory(v, get_id());
}
if (!ctx().relevancy() && u().is_defined(atom)) {
if (!ctx.relevancy() && u().is_defined(atom)) {
push_case_expand(alloc(case_expansion, u(), atom));
}
return true;
@ -84,12 +79,12 @@ namespace smt {
return false;
}
for (expr* e : *term) {
ctx().internalize(e, false);
ctx.internalize(e, false);
}
// the internalization of the arguments may have triggered the internalization of term.
if (!ctx().e_internalized(term)) {
ctx().mk_enode(term, false, false, true);
if (!ctx().relevancy() && u().is_defined(term)) {
if (!ctx.e_internalized(term)) {
ctx.mk_enode(term, false, false, true);
if (!ctx.relevancy() && u().is_defined(term)) {
push_case_expand(alloc(case_expansion, u(), term));
}
}
@ -128,7 +123,7 @@ namespace smt {
* body-expand it.
*/
void theory_recfun::relevant_eh(app * n) {
SASSERT(ctx().relevancy());
SASSERT(ctx.relevancy());
TRACEFN("relevant_eh: (defined) " << u().is_defined(n) << " " << mk_pp(n, m));
if (u().is_defined(n) && u().has_defs()) {
push_case_expand(alloc(case_expansion, u(), n));
@ -182,8 +177,8 @@ namespace smt {
m_q_guards.reset();
for (literal_vector & c : m_q_clauses) {
TRACEFN("add axiom " << pp_lits(ctx(), c));
ctx().mk_th_axiom(get_id(), c);
TRACEFN("add axiom " << pp_lits(ctx, c));
ctx.mk_th_axiom(get_id(), c);
}
m_q_clauses.clear();
@ -229,7 +224,7 @@ namespace smt {
m_disabled_guards.push_back(nguard);
SASSERT(!m_guard2pending.contains(nguard));
m_guard2pending.insert(nguard, alloc(expr_ref_vector, guards));
TRACEFN("add clause\n" << pp_lits(ctx(), c));
TRACEFN("add clause\n" << pp_lits(ctx, c));
m_q_clauses.push_back(std::move(c));
}
@ -271,7 +266,7 @@ namespace smt {
* then body-expand i-th case of `f(t1...tn)`
*/
void theory_recfun::assign_eh(bool_var v, bool is_true) {
expr* e = ctx().bool_var2expr(v);
expr* e = ctx.bool_var2expr(v);
if (is_true && u().is_case_pred(e)) {
TRACEFN("assign_case_pred_true " << mk_pp(e, m));
// body-expand
@ -289,15 +284,15 @@ namespace smt {
var_subst subst(m, true);
expr_ref new_body(m);
new_body = subst(e, args.size(), args.c_ptr());
ctx().get_rewriter()(new_body); // simplify
ctx.get_rewriter()(new_body); // simplify
set_depth_rec(depth + 1, new_body);
return new_body;
}
literal theory_recfun::mk_literal(expr* e) {
ctx().internalize(e, false);
literal lit = ctx().get_literal(e);
ctx().mark_as_relevant(lit);
ctx.internalize(e, false);
literal lit = ctx.get_literal(e);
ctx.mark_as_relevant(lit);
return lit;
}
@ -315,7 +310,7 @@ namespace smt {
else {
lit = mk_eq(l, r, false);
}
ctx().mark_as_relevant(lit);
ctx.mark_as_relevant(lit);
return lit;
}
@ -336,8 +331,8 @@ namespace smt {
literal lit = mk_eq_lit(lhs, rhs);
std::function<literal(void)> fn = [&]() { return lit; };
scoped_trace_stream _tr(*this, fn);
ctx().mk_th_axiom(get_id(), 1, &lit);
TRACEFN("macro expansion yields " << pp_lit(ctx(), lit));
ctx.mk_th_axiom(get_id(), 1, &lit);
TRACEFN("macro expansion yields " << pp_lit(ctx, lit));
}
/**
@ -385,15 +380,15 @@ namespace smt {
// to close the available cases.
{
scoped_trace_stream _tr2(*this, preds);
ctx().mk_th_axiom(get_id(), preds);
ctx.mk_th_axiom(get_id(), preds);
}
(void)max_depth;
// add_induction_lemmas(max_depth);
}
void theory_recfun::add_induction_lemmas(unsigned depth) {
if (depth > 4 && ctx().get_fparams().m_induction && induction::should_try(ctx())) {
ctx().get_induction()();
if (depth > 4 && ctx.get_fparams().m_induction && induction::should_try(ctx)) {
ctx.get_induction()();
}
}
@ -407,11 +402,11 @@ namespace smt {
literal c[2] = {~concl, guard};
std::function<literal_vector(void)> fn = [&]() { return literal_vector(2, c); };
scoped_trace_stream _tr(*this, fn);
ctx().mk_th_axiom(get_id(), 2, c);
ctx.mk_th_axiom(get_id(), 2, c);
}
std::function<literal_vector(void)> fn1 = [&]() { return lguards; };
scoped_trace_stream _tr1(*this, fn1);
ctx().mk_th_axiom(get_id(), lguards);
ctx.mk_th_axiom(get_id(), lguards);
}
/**
@ -445,9 +440,9 @@ namespace smt {
clause.push_back(mk_eq_lit(lhs, rhs));
std::function<literal_vector(void)> fn = [&]() { return clause; };
scoped_trace_stream _tr(*this, fn);
ctx().mk_th_axiom(get_id(), clause);
ctx.mk_th_axiom(get_id(), clause);
TRACEFN("body " << pp_body_expansion(e,m));
TRACEFN(pp_lits(ctx(), clause));
TRACEFN(pp_lits(ctx, clause));
}
final_check_status theory_recfun::final_check_eh() {
@ -482,7 +477,7 @@ namespace smt {
unsigned depth = get_depth(ne);
if (depth < current_depth)
n = 0;
if (depth <= current_depth && (get_context().get_random_value() % (++n)) == 0) {
if (depth <= current_depth && (ctx.get_random_value() % (++n)) == 0) {
to_delete = e;
current_depth = depth;
}

View file

@ -89,7 +89,6 @@ namespace smt {
friend std::ostream& operator<<(std::ostream&, pp_body_expansion const &);
ast_manager& m;
recfun::decl::plugin& m_plugin;
recfun::util& m_util;
stats m_stats;
@ -158,10 +157,9 @@ namespace smt {
void new_eq_eh(theory_var v1, theory_var v2) override {}
void new_diseq_eh(theory_var v1, theory_var v2) override {}
void add_theory_assumptions(expr_ref_vector & assumptions) override;
void init(context* ctx) override;
public:
theory_recfun(ast_manager & m);
theory_recfun(context& ctx);
~theory_recfun() override;
theory * mk_fresh(context * new_ctx) override;
void init_search_eh() override;

View file

@ -274,10 +274,8 @@ void theory_seq::exclusion_table::display(std::ostream& out) const {
}
theory_seq::theory_seq(ast_manager& m, theory_seq_params const & params):
theory(m.mk_family_id("seq")),
m(m),
m_params(params),
theory_seq::theory_seq(context& ctx):
theory(ctx, ctx.get_manager().mk_family_id("seq")),
m_rep(m, m_dm),
m_lts_checked(false),
m_eq_id(0),
@ -313,6 +311,13 @@ theory_seq::theory_seq(ast_manager& m, theory_seq_params const & params):
m_new_propagation(false),
m_mk_aut(m) {
}
theory_seq::~theory_seq() {
m_trail_stack.reset();
}
void theory_seq::init() {
params_ref p;
p.set_bool("coalesce_chars", false);
m_rewrite.updt_params(p);
@ -323,16 +328,7 @@ theory_seq::theory_seq(ast_manager& m, theory_seq_params const & params):
std::function<literal(expr*,bool)> mk_eq_emp = [&](expr* e, bool p) { return mk_eq_empty(e, p); };
m_ax.add_axiom5 = add_ax;
m_ax.mk_eq_empty2 = mk_eq_emp;
}
theory_seq::~theory_seq() {
m_trail_stack.reset();
}
void theory_seq::init(context* ctx) {
theory::init(ctx);
m_arith_value.init(ctx);
m_arith_value.init(&ctx);
}
#define TRACEFIN(s) { TRACE("seq", tout << ">>" << s << "\n";); IF_VERBOSE(31, verbose_stream() << s << "\n"); }
@ -351,8 +347,8 @@ final_check_status theory_seq::final_check_eh() {
return FC_DONE;
}
m_new_propagation = false;
TRACE("seq", display(tout << "level: " << get_context().get_scope_level() << "\n"););
TRACE("seq_verbose", get_context().display(tout););
TRACE("seq", display(tout << "level: " << ctx.get_scope_level() << "\n"););
TRACE("seq_verbose", ctx.display(tout););
if (simplify_and_solve_eqs()) {
++m_stats.m_solve_eqs;
@ -378,7 +374,7 @@ final_check_status theory_seq::final_check_eh() {
TRACEFIN("zero_length");
return FC_CONTINUE;
}
if (m_params.m_split_w_len && len_based_split()) {
if (get_fparams().m_split_w_len && len_based_split()) {
++m_stats.m_branch_variable;
TRACEFIN("split_based_on_length");
return FC_CONTINUE;
@ -499,7 +495,6 @@ bool theory_seq::fixed_length(expr* len_e, bool is_zero) {
}
context& ctx = get_context();
m_trail_stack.push(insert_obj_trail<theory_seq, expr>(m_fixed, e));
m_fixed.insert(e);
@ -535,13 +530,12 @@ bool theory_seq::fixed_length(expr* len_e, bool is_zero) {
lit => s != ""
*/
void theory_seq::propagate_non_empty(literal lit, expr* s) {
SASSERT(get_context().get_assignment(lit) == l_true);
SASSERT(ctx.get_assignment(lit) == l_true);
propagate_lit(nullptr, 1, &lit, ~mk_eq_empty(s));
}
bool theory_seq::propagate_is_conc(expr* e, expr* conc) {
TRACE("seq", tout << mk_pp(conc, m) << " is non-empty\n";);
context& ctx = get_context();
literal lit = ~mk_eq_empty(e);
if (ctx.get_assignment(lit) == l_true) {
propagate_lit(nullptr, 1, &lit, mk_eq(e, conc, false));
@ -574,7 +568,6 @@ void theory_seq::mk_decompose(expr* e, expr_ref& head, expr_ref& tail) {
\brief Check extensionality (for sequences).
*/
bool theory_seq::check_extensionality() {
context& ctx = get_context();
unsigned sz = get_num_vars();
unsigned_vector seqs;
for (unsigned v = 0; v < sz; ++v) {
@ -633,7 +626,6 @@ bool theory_seq::check_extensionality() {
\brief check negated contains constraints.
*/
bool theory_seq::check_contains() {
context & ctx = get_context();
for (unsigned i = 0; !ctx.inconsistent() && i < m_ncs.size(); ++i) {
if (solve_nc(i)) {
m_ncs.erase_and_swap(i--);
@ -643,7 +635,6 @@ bool theory_seq::check_contains() {
}
bool theory_seq::check_lts() {
context& ctx = get_context();
if (m_lts.empty() || m_lts_checked) {
return false;
}
@ -719,7 +710,6 @@ bool theory_seq::is_solved() {
#if 0
// debug code
context& ctx = get_context();
for (enode* n : ctx.enodes()) {
expr* e = nullptr;
rational len1, len2;
@ -744,8 +734,6 @@ bool theory_seq::is_solved() {
\brief while extracting dependency literals ensure that they have all been asserted on the context.
*/
void theory_seq::linearize(dependency* dep, enode_pair_vector& eqs, literal_vector& lits) const {
context & ctx = get_context();
(void)ctx;
DEBUG_CODE(for (literal lit : lits) SASSERT(ctx.get_assignment(lit) == l_true); );
svector<assumption> assumptions;
const_cast<dependency_manager&>(m_dm).linearize(dep, assumptions);
@ -765,7 +753,6 @@ void theory_seq::linearize(dependency* dep, enode_pair_vector& eqs, literal_vect
void theory_seq::propagate_lit(dependency* dep, unsigned n, literal const* _lits, literal lit) {
if (lit == true_literal) return;
context& ctx = get_context();
literal_vector lits(n, _lits);
if (lit == false_literal) {
@ -801,7 +788,6 @@ void theory_seq::set_conflict(dependency* dep, literal_vector const& _lits) {
}
void theory_seq::set_conflict(enode_pair_vector const& eqs, literal_vector const& lits) {
context& ctx = get_context();
TRACE("seq", display_deps(tout << "assert conflict:", lits, eqs););
ctx.set_conflict(
ctx.mk_justification(
@ -814,7 +800,6 @@ bool theory_seq::propagate_eq(dependency* dep, enode* n1, enode* n2) {
if (n1->get_root() == n2->get_root()) {
return false;
}
context& ctx = get_context();
literal_vector lits;
enode_pair_vector eqs;
linearize(dep, eqs, lits);
@ -877,7 +862,6 @@ bool theory_seq::lift_ite(expr_ref_vector const& ls, expr_ref_vector const& rs,
if (ls.size() != 1 || rs.size() != 1) {
return false;
}
context& ctx = get_context();
expr* c = nullptr, *t = nullptr, *e = nullptr;
expr* l = ls[0], *r = rs[0];
if (m.is_ite(r)) {
@ -904,7 +888,6 @@ bool theory_seq::lift_ite(expr_ref_vector const& ls, expr_ref_vector const& rs,
bool theory_seq::simplify_eq(expr_ref_vector& ls, expr_ref_vector& rs, dependency* deps) {
context& ctx = get_context();
expr_ref_pair_vector& new_eqs = m_new_eqs;
new_eqs.reset();
bool changed = false;
@ -987,7 +970,7 @@ bool theory_seq::solve_itos(expr* n, expr_ref_vector const& rs, dependency* dep)
m_is_digit.insert(u);
m_trail_stack.push(insert_obj_trail<theory_seq, expr>(m_is_digit, u));
literal is_digit = m_ax.is_digit(u);
if (get_context().get_assignment(is_digit) != l_true) {
if (ctx.get_assignment(is_digit) != l_true) {
propagate_lit(dep, 0, nullptr, is_digit);
}
}
@ -1155,7 +1138,6 @@ bool theory_seq::reduce_length_eq(expr_ref_vector const& ls, expr_ref_vector con
}
bool theory_seq::reduce_length(unsigned i, unsigned j, bool front, expr_ref_vector const& ls, expr_ref_vector const& rs, dependency* deps) {
context& ctx = get_context();
expr* const* ls1 = ls.c_ptr();
expr* const* ls2 = ls.c_ptr()+i;
expr* const* rs1 = rs.c_ptr();
@ -1204,13 +1186,11 @@ bool theory_seq::reduce_length(unsigned i, unsigned j, bool front, expr_ref_vect
to another.
*/
bool theory_seq::is_safe_to_copy(bool_var v) const {
context & ctx = get_context();
expr* e = ctx.bool_var2expr(v);
return !m_sk.is_skolem(e);
}
bool theory_seq::get_length(expr* e, expr_ref& len, literal_vector& lits) {
context& ctx = get_context();
expr* s, *i, *l;
rational r;
if (m_util.str.is_extract(e, s, i, l)) {
@ -1307,7 +1287,6 @@ bool theory_seq::get_length(expr* e, expr_ref& len, literal_vector& lits) {
bool theory_seq::solve_nc(unsigned idx) {
nc const& n = m_ncs[idx];
literal len_gt = n.len_gt();
context& ctx = get_context();
expr_ref c(m);
#if 1
expr* a = nullptr, *b = nullptr;
@ -1519,7 +1498,6 @@ bool theory_seq::explain_empty(expr_ref_vector& es, dependency*& dep) {
}
bool theory_seq::simplify_and_solve_eqs() {
context & ctx = get_context();
m_new_solution = true;
while (m_new_solution && !ctx.inconsistent()) {
m_new_solution = false;
@ -1537,7 +1515,6 @@ bool theory_seq::internalize_atom(app* a, bool) {
bool theory_seq::internalize_term(app* term) {
m_has_seq = true;
context & ctx = get_context();
if (ctx.e_internalized(term)) {
enode* e = ctx.get_enode(term);
mk_var(e);
@ -1638,7 +1615,7 @@ bool theory_seq::check_int_string() {
bool theory_seq::check_int_string(expr* e) {
expr* n = nullptr;
if (get_context().inconsistent())
if (ctx.inconsistent())
return true;
if (m_util.str.is_itos(e, n) && !m_util.str.is_stoi(n) && add_length_to_eqc(e))
return true;
@ -1781,13 +1758,12 @@ std::ostream& theory_seq::display_deps_smt2(std::ostream& out, literal_vector co
<< ")\n";
}
for (literal l : lits) {
get_context().display_literal_smt2(out, l) << "\n";
ctx.display_literal_smt2(out, l) << "\n";
}
return out;
}
std::ostream& theory_seq::display_lit(std::ostream& out, literal l) const {
context& ctx = get_context();
if (l == true_literal) {
out << " true";
}
@ -1833,7 +1809,7 @@ void theory_seq::init_search_eh() {
m_re2aut.reset();
m_res.reset();
m_automata.reset();
auto as = get_context().get_fparams().m_arith_mode;
auto as = get_fparams().m_arith_mode;
if (m_has_seq && as != AS_OLD_ARITH && as != AS_NEW_ARITH) {
throw default_exception("illegal arithmetic solver used with string solver");
}
@ -2001,7 +1977,6 @@ app* theory_seq::get_ite_value(expr* e) {
model_value_proc * theory_seq::mk_value(enode * n, model_generator & mg) {
app* e = n->get_owner();
context& ctx = get_context();
TRACE("seq", tout << mk_pp(e, m) << "\n";);
// Shortcut for well-founded values to avoid some quadratic overhead
@ -2136,7 +2111,6 @@ void theory_seq::validate_model(model& mdl) {
#if 0
ptr_vector<expr> fmls;
context& ctx = get_context();
ctx.get_asserted_formulas(fmls);
validate_model_proc proc(*this, mdl);
for (expr* f : fmls) {
@ -2245,7 +2219,7 @@ expr_ref theory_seq::elim_skolem(expr* e) {
}
void theory_seq::validate_axiom(literal_vector const& lits) {
if (get_context().get_fparams().m_seq_validate) {
if (get_fparams().m_seq_validate) {
enode_pair_vector eqs;
literal_vector _lits;
for (literal lit : lits) _lits.push_back(~lit);
@ -2256,7 +2230,7 @@ void theory_seq::validate_axiom(literal_vector const& lits) {
void theory_seq::validate_conflict(enode_pair_vector const& eqs, literal_vector const& lits) {
IF_VERBOSE(10, display_deps_smt2(verbose_stream() << "cn ", lits, eqs));
if (get_context().get_fparams().m_seq_validate) {
if (get_fparams().m_seq_validate) {
expr_ref_vector fmls(m);
validate_fmls(eqs, lits, fmls);
}
@ -2264,7 +2238,7 @@ void theory_seq::validate_conflict(enode_pair_vector const& eqs, literal_vector
void theory_seq::validate_assign(literal lit, enode_pair_vector const& eqs, literal_vector const& lits) {
IF_VERBOSE(10, display_deps_smt2(verbose_stream() << "eq ", lits, eqs); display_lit(verbose_stream(), ~lit) << "\n");
if (get_context().get_fparams().m_seq_validate) {
if (get_fparams().m_seq_validate) {
literal_vector _lits(lits);
_lits.push_back(~lit);
expr_ref_vector fmls(m);
@ -2276,7 +2250,7 @@ void theory_seq::validate_assign_eq(enode* a, enode* b, enode_pair_vector const&
IF_VERBOSE(10, display_deps(verbose_stream() << "; assign-eq\n", lits, eqs);
verbose_stream() << "(not (= " << mk_bounded_pp(a->get_owner(), m)
<< " " << mk_bounded_pp(b->get_owner(), m) << "))\n");
if (get_context().get_fparams().m_seq_validate) {
if (get_fparams().m_seq_validate) {
expr_ref_vector fmls(m);
fmls.push_back(m.mk_not(m.mk_eq(a->get_owner(), b->get_owner())));
validate_fmls(eqs, lits, fmls);
@ -2284,7 +2258,6 @@ void theory_seq::validate_assign_eq(enode* a, enode* b, enode_pair_vector const&
}
void theory_seq::validate_fmls(enode_pair_vector const& eqs, literal_vector const& lits, expr_ref_vector& fmls) {
context& ctx = get_context();
smt_params fp;
fp.m_seq_validate = false;
expr_ref fml(m);
@ -2329,8 +2302,8 @@ theory_var theory_seq::mk_var(enode* n) {
else {
theory_var v = theory::mk_var(n);
m_find.mk_var();
get_context().attach_th_var(n, this, v);
get_context().mark_as_relevant(n);
ctx.attach_th_var(n, this, v);
ctx.mark_as_relevant(n);
return v;
}
}
@ -2427,7 +2400,6 @@ bool theory_seq::expand1(expr* e0, dependency*& eqs, expr_ref& result) {
expr* e1, *e2, *e3;
expr_ref arg1(m), arg2(m);
context& ctx = get_context();
if (m_util.str.is_concat(e, e1, e2)) {
arg1 = try_expand(e1, deps);
arg2 = try_expand(e2, deps);
@ -2529,7 +2501,6 @@ void theory_seq::add_dependency(dependency*& dep, enode* a, enode* b) {
void theory_seq::propagate() {
context & ctx = get_context();
while (m_axioms_head < m_axioms.size() && !ctx.inconsistent()) {
expr_ref e(m);
e = m_axioms[m_axioms_head].get();
@ -2562,7 +2533,7 @@ void theory_seq::deque_axiom(expr* n) {
TRACE("seq", tout << "deque: " << mk_bounded_pp(n, m, 2) << "\n";);
if (m_util.str.is_length(n)) {
m_ax.add_length_axiom(n);
if (!get_context().at_base_level()) {
if (!ctx.at_base_level()) {
m_trail_stack.push(push_replay(alloc(replay_axiom, m, n)));
}
}
@ -2651,7 +2622,6 @@ void theory_seq::propagate_in_re(expr* n, bool is_true) {
expr* s = nullptr, *_re = nullptr;
VERIFY(m_util.str.is_in_re(n, s, _re));
expr_ref re(_re, m);
context& ctx = get_context();
literal lit = ctx.get_literal(n);
if (!is_true) {
re = m_util.re.mk_complement(re);
@ -2761,7 +2731,6 @@ bool theory_seq::upper_bound(expr* e, rational& hi) const {
// the lower bound is not updated for all the enodes in the same eqc,
// we have to traverse the eqc to query for the better lower bound.
bool theory_seq::lower_bound2(expr* _e, rational& lo) {
context& ctx = get_context();
expr_ref e = mk_len(_e);
expr_ref _lo(m);
theory_mi_arith* tha = get_th_arith<theory_mi_arith>(ctx, m_autil.get_family_id(), e);
@ -2848,7 +2817,7 @@ bool theory_seq::get_length(expr* e, rational& val) {
void theory_seq::ensure_nth(literal lit, expr* s, expr* idx) {
TRACE("seq", tout << "ensure-nth: " << lit << " " << mk_bounded_pp(s, m, 2) << " " << mk_bounded_pp(idx, m, 2) << "\n";);
rational r;
SASSERT(get_context().get_assignment(lit) == l_true);
SASSERT(ctx.get_assignment(lit) == l_true);
VERIFY(m_autil.is_numeral(idx, r) && r.is_unsigned());
unsigned _idx = r.get_unsigned();
expr_ref head(m), tail(m), conc(m), len1(m), len2(m);
@ -2876,7 +2845,6 @@ literal theory_seq::mk_simplified_literal(expr * _e) {
literal theory_seq::mk_literal(expr* _e) {
expr_ref e(_e, m);
context& ctx = get_context();
ensure_enode(e);
return ctx.get_literal(e);
}
@ -2888,7 +2856,6 @@ literal theory_seq::mk_seq_eq(expr* a, expr* b) {
literal theory_seq::mk_eq_empty(expr* _e, bool phase) {
context& ctx = get_context();
expr_ref e(_e, m);
SASSERT(m_util.is_seq(e));
expr_ref emp(m);
@ -2915,7 +2882,6 @@ literal theory_seq::mk_eq_empty(expr* _e, bool phase) {
}
void theory_seq::add_axiom(literal l1, literal l2, literal l3, literal l4, literal l5) {
context& ctx = get_context();
literal_vector lits;
if (l1 == true_literal || l2 == true_literal || l3 == true_literal || l4 == true_literal || l5 == true_literal) return;
if (l1 != null_literal && l1 != false_literal) { ctx.mark_as_relevant(l1); lits.push_back(l1); }
@ -2955,7 +2921,6 @@ bool theory_seq::propagate_eq(literal lit, expr* e1, expr* e2, bool add_to_eqs)
}
bool theory_seq::propagate_eq(dependency* deps, literal_vector const& _lits, expr* e1, expr* e2, bool add_to_eqs) {
context& ctx = get_context();
enode* n1 = ensure_enode(e1);
enode* n2 = ensure_enode(e2);
@ -2997,7 +2962,6 @@ bool theory_seq::propagate_eq(dependency* deps, literal_vector const& _lits, exp
}
void theory_seq::assign_eh(bool_var v, bool is_true) {
context & ctx = get_context();
expr* e = ctx.bool_var2expr(v);
expr* e1 = nullptr, *e2 = nullptr;
expr_ref f(m);
@ -3194,18 +3158,18 @@ void theory_seq::new_diseq_eh(theory_var v1, theory_var v2) {
}
m_exclude.update(e1, e2);
expr_ref eq(m.mk_eq(e1, e2), m);
TRACE("seq", tout << "new disequality " << get_context().get_scope_level() << ": " << mk_bounded_pp(eq, m, 2) << "\n";);
TRACE("seq", tout << "new disequality " << ctx.get_scope_level() << ": " << mk_bounded_pp(eq, m, 2) << "\n";);
m_rewrite(eq);
if (!m.is_false(eq)) {
literal lit = mk_eq(e1, e2, false);
get_context().mark_as_relevant(lit);
ctx.mark_as_relevant(lit);
if (m_util.str.is_empty(e2)) {
std::swap(e1, e2);
}
dependency* dep = m_dm.mk_leaf(assumption(~lit));
m_nqs.push_back(ne(e1, e2, dep));
if (get_context().get_assignment(lit) != l_undef) {
if (ctx.get_assignment(lit) != l_undef) {
solve_nqs(m_nqs.size() - 1);
}
}
@ -3225,7 +3189,6 @@ void theory_seq::push_scope_eh() {
}
void theory_seq::pop_scope_eh(unsigned num_scopes) {
context& ctx = get_context();
m_trail_stack.pop_scope(num_scopes);
theory::pop_scope_eh(num_scopes);
m_dm.pop_scope(num_scopes);
@ -3271,7 +3234,7 @@ void theory_seq::relevant_eh(app* n) {
add_length_limit(arg, m_max_unfolding_depth, true);
}
if (m_util.str.is_length(n, arg) && !has_length(arg) && get_context().e_internalized(arg)) {
if (m_util.str.is_length(n, arg) && !has_length(arg) && ctx.e_internalized(arg)) {
add_length_to_eqc(arg);
}
}
@ -3283,7 +3246,7 @@ eautomaton* theory_seq::get_automaton(expr* re) {
return result;
}
if (!m_mk_aut.has_solver()) {
m_mk_aut.set_solver(alloc(seq_expr_solver, m, get_context().get_fparams()));
m_mk_aut.set_solver(alloc(seq_expr_solver, m, ctx.get_fparams()));
}
result = m_mk_aut(re);
CTRACE("seq", result, { display_expr d(m); result->display(tout, d); });
@ -3320,7 +3283,7 @@ bool theory_seq::is_accept(expr* e, expr*& s, expr*& idx, expr*& re, unsigned& i
step(s, idx, re, i, j, t) -> accept(s, idx + 1, re, j)
*/
void theory_seq::propagate_step(literal lit, expr* step) {
SASSERT(get_context().get_assignment(lit) == l_true);
SASSERT(ctx.get_assignment(lit) == l_true);
expr* re = nullptr, *s = nullptr, *t = nullptr, *idx = nullptr, *i = nullptr, *j = nullptr;
VERIFY(m_sk.is_step(step, s, idx, re, i, j, t));
@ -3354,7 +3317,6 @@ void theory_seq::propagate_accept(literal lit, expr* acc) {
++m_stats.m_propagate_automata;
expr *e = nullptr, *idx = nullptr, *re = nullptr;
unsigned src = 0;
context& ctx = get_context();
rational _idx;
eautomaton* aut = nullptr;
if (!is_accept(acc, e, idx, re, src, aut))
@ -3384,7 +3346,7 @@ void theory_seq::propagate_accept(literal lit, expr* acc) {
for (auto const& mv : mvs) {
expr_ref nth = mk_nth(e, idx);
expr_ref t = mv.t()->accept(nth);
get_context().get_rewriter()(t);
ctx.get_rewriter()(t);
expr_ref step_e(m_sk.mk_step(e, idx, re, src, mv.dst(), t), m);
lits.push_back(mk_literal(step_e));
}
@ -3435,7 +3397,7 @@ bool theory_seq::should_research(expr_ref_vector & unsat_core) {
s_min = s;
n = 0;
}
else if (k == k_min && get_context().get_random_value() % (++n) == 0) {
else if (k == k_min && ctx.get_random_value() % (++n) == 0) {
s_min = s;
}
}
@ -3473,7 +3435,6 @@ void theory_seq::propagate_length_limit(expr* e) {
*/
void theory_seq::propagate_not_prefix(expr* e) {
context& ctx = get_context();
expr* e1 = nullptr, *e2 = nullptr;
VERIFY(m_util.str.is_prefix(e, e1, e2));
literal lit = ctx.get_literal(e);
@ -3494,7 +3455,6 @@ void theory_seq::propagate_not_prefix(expr* e) {
*/
void theory_seq::propagate_not_suffix(expr* e) {
context& ctx = get_context();
expr* e1 = nullptr, *e2 = nullptr;
VERIFY(m_util.str.is_suffix(e, e1, e2));
literal lit = ctx.get_literal(e);
@ -3512,7 +3472,6 @@ void theory_seq::propagate_not_suffix(expr* e) {
}
bool theory_seq::canonizes(bool is_true, expr* e) {
context& ctx = get_context();
dependency* deps = nullptr;
expr_ref cont(m);
if (!canonize(e, deps, cont)) cont = e;

View file

@ -367,8 +367,6 @@ namespace smt {
};
typedef hashtable<rational, rational::hash_proc, rational::eq_proc> rational_set;
ast_manager& m;
theory_seq_params const& m_params;
dependency_manager m_dm;
solution_map m_rep; // unification representative.
scoped_vector<eq> m_eqs; // set of current equations.
@ -427,7 +425,6 @@ namespace smt {
obj_hashtable<expr> m_fixed; // string variables that are fixed length.
obj_hashtable<expr> m_is_digit; // expressions that have been constrained to be digits
void init(context* ctx) override;
final_check_status final_check_eh() override;
bool internalize_atom(app* atom, bool) override;
bool internalize_term(app*) override;
@ -443,7 +440,7 @@ namespace smt {
void relevant_eh(app* n) override;
bool should_research(expr_ref_vector &) override;
void add_theory_assumptions(expr_ref_vector & assumptions) override;
theory* mk_fresh(context* new_ctx) override { return alloc(theory_seq, new_ctx->get_manager(), new_ctx->get_fparams()); }
theory* mk_fresh(context* new_ctx) override { return alloc(theory_seq, *new_ctx); }
char const * get_name() const override { return "seq"; }
bool include_func_interp(func_decl* f) override { return m_util.str.is_nth_u(f); }
bool is_safe_to_copy(bool_var v) const override;
@ -683,9 +680,10 @@ namespace smt {
std::ostream& display_nc(std::ostream& out, nc const& nc) const;
std::ostream& display_lit(std::ostream& out, literal l) const;
public:
theory_seq(ast_manager& m, theory_seq_params const & params);
theory_seq(context& ctx);
~theory_seq() override;
void init() override;
// model building
app* mk_value(app* a);

View file

@ -33,11 +33,11 @@ namespace smt {
bool internalize_term(app*) override { return internalize_atom(nullptr,false); }
void new_eq_eh(theory_var, theory_var) override { }
void new_diseq_eh(theory_var, theory_var) override {}
theory* mk_fresh(context* new_ctx) override { return alloc(theory_seq_empty, new_ctx->get_manager()); }
theory* mk_fresh(context* new_ctx) override { return alloc(theory_seq_empty, *new_ctx); }
char const * get_name() const override { return "seq-empty"; }
void display(std::ostream& out) const override {}
public:
theory_seq_empty(ast_manager& m):theory(m.mk_family_id("seq")), m_used(false) {}
theory_seq_empty(context& ctx):theory(ctx, ctx.get_manager().mk_family_id("seq")), m_used(false) {}
void init_model(model_generator & mg) override {
mg.register_factory(alloc(seq_factory, get_manager(), get_family_id(), mg.get_model()));
}

View file

@ -90,8 +90,8 @@ namespace smt {
return out;
}
theory_special_relations::theory_special_relations(ast_manager& m):
theory(m.mk_family_id("special_relations")),
theory_special_relations::theory_special_relations(context& ctx, ast_manager& m):
theory(ctx, m.mk_family_id("special_relations")),
m_util(m),
m_can_propagate(false) {
}
@ -101,7 +101,7 @@ namespace smt {
}
theory * theory_special_relations::mk_fresh(context * new_ctx) {
return alloc(theory_special_relations, new_ctx->get_manager());
return alloc(theory_special_relations, *new_ctx, new_ctx->get_manager());
}
/**
@ -112,7 +112,6 @@ namespace smt {
assert f(term,c) or term != a
*/
void theory_special_relations::internalize_next(func_decl* f, app* term) {
context& ctx = get_context();
ast_manager& m = get_manager();
func_decl* nxt = term->get_decl();
expr* src = term->get_arg(0);
@ -143,7 +142,6 @@ namespace smt {
m_relations.insert(atm->get_decl(), r);
for (unsigned i = 0; i < m_atoms_lim.size(); ++i) r->push();
}
context& ctx = get_context();
expr* arg0 = atm->get_arg(0);
expr* arg1 = atm->get_arg(1);
theory_var v0 = mk_var(arg0);
@ -158,7 +156,6 @@ namespace smt {
}
theory_var theory_special_relations::mk_var(expr* e) {
context& ctx = get_context();
if (!ctx.e_internalized(e)) {
ctx.internalize(e, false);
}
@ -203,7 +200,7 @@ namespace smt {
if (extract_equalities(*kv.m_value)) {
new_equality = true;
}
if (get_context().inconsistent()) {
if (ctx.inconsistent()) {
return FC_CONTINUE;
}
}
@ -221,7 +218,6 @@ namespace smt {
}
enode* theory_special_relations::ensure_enode(expr* e) {
context& ctx = get_context();
if (!ctx.e_internalized(e)) {
ctx.internalize(e, false);
}
@ -233,7 +229,7 @@ namespace smt {
literal theory_special_relations::mk_literal(expr* _e) {
expr_ref e(_e, get_manager());
ensure_enode(e);
return get_context().get_literal(e);
return ctx.get_literal(e);
}
theory_var theory_special_relations::mk_var(enode* n) {
@ -242,8 +238,8 @@ namespace smt {
}
else {
theory_var v = theory::mk_var(n);
get_context().attach_th_var(n, this, v);
get_context().mark_as_relevant(n);
ctx.attach_th_var(n, this, v);
ctx.mark_as_relevant(n);
return v;
}
}
@ -270,7 +266,6 @@ namespace smt {
//
func_decl* tcf = r.decl();
func_decl* f = to_func_decl(tcf->get_parameter(0).get_ast());
context& ctx = get_context();
ast_manager& m = get_manager();
bool new_assertion = false;
graph r_graph;
@ -471,7 +466,6 @@ namespace smt {
void theory_special_relations::set_conflict(relation& r) {
literal_vector const& lits = r.m_explanation;
context & ctx = get_context();
TRACE("special_relations", ctx.display_literals_verbose(tout, lits) << "\n";);
vector<parameter> params;
ctx.set_conflict(
@ -519,7 +513,6 @@ namespace smt {
bool new_eq = false;
int_vector scc_id;
u_map<unsigned> roots;
context& ctx = get_context();
ast_manager& m = get_manager();
(void)m;
r.m_graph.compute_zero_edge_scc(scc_id);
@ -950,7 +943,7 @@ namespace smt {
for (atom* ap : r.m_asserted_atoms) {
atom& a = *ap;
if (!a.phase()) continue;
SASSERT(get_context().get_assignment(a.var()) == l_true);
SASSERT(ctx.get_assignment(a.var()) == l_true);
expr* x = get_enode(a.v1())->get_root()->get_owner();
expr* y = get_enode(a.v2())->get_root()->get_owner();
expr* cb = connected_body;
@ -1151,7 +1144,6 @@ namespace smt {
}
void theory_special_relations::display_atom(std::ostream & out, atom& a) const {
context& ctx = get_context();
expr* e = ctx.bool_var2expr(a.var());
out << (a.phase() ? "" : "(not ") << mk_pp(e, get_manager()) << (a.phase() ? "" : ")") << "\n";
}

View file

@ -177,7 +177,7 @@ namespace smt {
void internalize_next(func_decl* f, app * term);
public:
theory_special_relations(ast_manager& m);
theory_special_relations(context& ctx, ast_manager& m);
~theory_special_relations() override;
theory * mk_fresh(context * new_ctx) override;

View file

@ -33,8 +33,23 @@
namespace smt {
theory_str::theory_str(ast_manager & m, theory_str_params const & params):
theory(m.mk_family_id("seq")),
class seq_expr_solver : public expr_solver {
kernel m_kernel;
public:
seq_expr_solver(ast_manager& m, smt_params& fp):
m_kernel(m, fp) {}
lbool check_sat(expr* e) override {
m_kernel.push();
m_kernel.assert_expr(e);
lbool r = m_kernel.check();
m_kernel.pop(1);
return r;
}
};
theory_str::theory_str(context& ctx, ast_manager & m, theory_str_params const & params):
theory(ctx, m.mk_family_id("seq")),
m_params(params),
/* Options */
opt_EagerStringConstantLengthAssertions(true),
@ -63,7 +78,7 @@ namespace smt {
tmpXorVarCount(0),
avoidLoopCut(true),
loopDetected(false),
m_theoryStrOverlapAssumption_term(m),
m_theoryStrOverlapAssumption_term(m.mk_true(), m),
contains_map(m),
string_int_conversion_terms(m),
totalCacheAccessCount(0),
@ -76,7 +91,6 @@ namespace smt {
fixed_length_assumptions(m),
bitvector_character_constants(m)
{
initialize_charset();
}
theory_str::~theory_str() {
@ -87,6 +101,11 @@ namespace smt {
regex_automata.clear();
}
void theory_str::init() {
initialize_charset();
m_mk_aut.set_solver(alloc(seq_expr_solver, get_manager(), ctx.get_fparams()));
}
void theory_str::reset_internal_data_structures() {
//m_trail.reset();
m_delayed_axiom_setup_terms.reset();
@ -173,26 +192,6 @@ namespace smt {
return u.str.mk_string(sym);
}
class seq_expr_solver : public expr_solver {
kernel m_kernel;
public:
seq_expr_solver(ast_manager& m, smt_params& fp):
m_kernel(m, fp) {}
lbool check_sat(expr* e) override {
m_kernel.push();
m_kernel.assert_expr(e);
lbool r = m_kernel.check();
m_kernel.pop(1);
return r;
}
};
void theory_str::init(context * ctx) {
theory::init(ctx);
m_mk_aut.set_solver(alloc(seq_expr_solver, get_manager(),
get_context().get_fparams()));
}
void theory_str::collect_statistics(::statistics & st) const {
st.update("str refine equation", m_stats.m_refine_eq);
st.update("str refine negated equation", m_stats.m_refine_neq);
@ -281,7 +280,6 @@ namespace smt {
}
if (get_manager().is_true(_e)) return;
context & ctx = get_context();
ast_manager& m = get_manager();
TRACE("str", tout << "asserting " << mk_ismt2_pp(_e, m) << std::endl;);
expr_ref e(_e, m);
@ -305,7 +303,6 @@ namespace smt {
void theory_str::assert_axiom_rw(expr * e) {
if (e == nullptr)
return;
context & ctx = get_context();
ast_manager & m = get_manager();
expr_ref _e(e, m);
ctx.get_rewriter()(_e);
@ -329,7 +326,6 @@ namespace smt {
}
bool theory_str::internalize_term(app * term) {
context & ctx = get_context();
ast_manager & m = get_manager();
SASSERT(term->get_family_id() == get_family_id());
@ -371,7 +367,6 @@ namespace smt {
}
enode* theory_str::ensure_enode(expr* e) {
context& ctx = get_context();
if (!ctx.e_internalized(e)) {
ctx.internalize(e, false);
}
@ -403,8 +398,8 @@ namespace smt {
theory_var v = theory::mk_var(n);
m_find.mk_var();
TRACE("str", tout << "new theory var v#" << v << " find " << m_find.find(v) << std::endl;);
get_context().attach_th_var(n, this, v);
get_context().mark_as_relevant(n);
ctx.attach_th_var(n, this, v);
ctx.mark_as_relevant(n);
return v;
}
}
@ -522,7 +517,6 @@ namespace smt {
literal theory_str::mk_literal(expr* _e) {
ast_manager & m = get_manager();
expr_ref e(_e, m);
context& ctx = get_context();
ensure_enode(e);
return ctx.get_literal(e);
}
@ -557,7 +551,6 @@ namespace smt {
app * theory_str::mk_int_var(std::string name) {
context & ctx = get_context();
ast_manager & m = get_manager();
TRACE("str", tout << "creating integer variable " << name << " at scope level " << sLevel << std::endl;);
@ -581,7 +574,6 @@ namespace smt {
}
app * theory_str::mk_str_var(std::string name) {
context & ctx = get_context();
TRACE("str", tout << "creating string variable " << name << " at scope level " << sLevel << std::endl;);
@ -609,7 +601,6 @@ namespace smt {
}
void theory_str::add_nonempty_constraint(expr * s) {
context & ctx = get_context();
ast_manager & m = get_manager();
expr_ref ax1(mk_not(m, ctx.mk_eq_atom(s, mk_string(""))), m);
@ -631,7 +622,6 @@ namespace smt {
}
app_ref theory_str::mk_nonempty_str_var() {
context & ctx = get_context();
ast_manager & m = get_manager();
std::stringstream ss;
@ -677,7 +667,7 @@ namespace smt {
app * contains = u.str.mk_contains(haystack, needle); // TODO double-check semantics/argument order
m_trail.push_back(contains);
// immediately force internalization so that axiom setup does not fail
get_context().internalize(contains, false);
ctx.internalize(contains, false);
set_up_axioms(contains);
return contains;
}
@ -687,7 +677,7 @@ namespace smt {
app * indexof = u.str.mk_index(haystack, needle, mk_int(0));
m_trail.push_back(indexof);
// immediately force internalization so that axiom setup does not fail
get_context().internalize(indexof, false);
ctx.internalize(indexof, false);
set_up_axioms(indexof);
return indexof;
}
@ -757,7 +747,6 @@ namespace smt {
}
expr * theory_str::mk_concat(expr * n1, expr * n2) {
context & ctx = get_context();
ast_manager & m = get_manager();
ENSURE(n1 != nullptr);
ENSURE(n2 != nullptr);
@ -850,7 +839,6 @@ namespace smt {
}
void theory_str::propagate() {
context & ctx = get_context();
candidate_model.reset();
while (can_propagate()) {
TRACE("str", tout << "propagating..." << std::endl;);
@ -960,7 +948,6 @@ namespace smt {
app * a_cat = cat->get_owner();
SASSERT(u.str.is_concat(a_cat));
context & ctx = get_context();
ast_manager & m = get_manager();
TRACE("str", tout << "attempting to flatten " << mk_pp(a_cat, m) << std::endl;);
@ -1051,7 +1038,6 @@ namespace smt {
* Length(x) == strlen(x)
*/
void theory_str::instantiate_basic_string_axioms(enode * str) {
context & ctx = get_context();
ast_manager & m = get_manager();
TRACE("str", tout << "set up basic string axioms on " << mk_pp(str->get_owner(), m) << std::endl;);
@ -1144,7 +1130,6 @@ namespace smt {
* (lhs == rhs) -> ( Length(lhs) == Length(rhs) )
*/
void theory_str::instantiate_str_eq_length_axiom(enode * lhs, enode * rhs) {
context & ctx = get_context();
ast_manager & m = get_manager();
app * a_lhs = lhs->get_owner();
@ -1166,7 +1151,6 @@ namespace smt {
}
void theory_str::instantiate_axiom_CharAt(enode * e) {
context & ctx = get_context();
ast_manager & m = get_manager();
expr* arg0, *arg1;
app * expr = e->get_owner();
@ -1197,12 +1181,11 @@ namespace smt {
expr_ref axiom(m.mk_ite(cond, thenBranch, elseBranch), m);
expr_ref reductionVar(ctx.mk_eq_atom(expr, ts1), m);
expr_ref finalAxiom(m.mk_and(axiom, reductionVar), m);
get_context().get_rewriter()(finalAxiom);
ctx.get_rewriter()(finalAxiom);
assert_axiom(finalAxiom);
}
void theory_str::instantiate_axiom_prefixof(enode * e) {
context & ctx = get_context();
ast_manager & m = get_manager();
app * expr = e->get_owner();
@ -1239,7 +1222,6 @@ namespace smt {
}
void theory_str::instantiate_axiom_suffixof(enode * e) {
context & ctx = get_context();
ast_manager & m = get_manager();
app * expr = e->get_owner();
@ -1276,7 +1258,6 @@ namespace smt {
}
void theory_str::instantiate_axiom_Contains(enode * e) {
context & ctx = get_context();
ast_manager & m = get_manager();
app * ex = e->get_owner();
@ -1326,7 +1307,6 @@ namespace smt {
}
void theory_str::instantiate_axiom_Indexof(enode * e) {
context & ctx = get_context();
th_rewriter & rw = ctx.get_rewriter();
ast_manager & m = get_manager();
@ -1429,7 +1409,6 @@ namespace smt {
}
void theory_str::instantiate_axiom_Indexof_extended(enode * _e) {
context & ctx = get_context();
th_rewriter & rw = ctx.get_rewriter();
ast_manager & m = get_manager();
@ -1581,7 +1560,6 @@ namespace smt {
}
void theory_str::instantiate_axiom_LastIndexof(enode * e) {
context & ctx = get_context();
ast_manager & m = get_manager();
app * expr = e->get_owner();
@ -1650,7 +1628,6 @@ namespace smt {
}
void theory_str::instantiate_axiom_Substr(enode * e) {
context & ctx = get_context();
ast_manager & m = get_manager();
expr* substrBase = nullptr;
expr* substrPos = nullptr;
@ -1743,7 +1720,6 @@ namespace smt {
// of t in s, if any, by t'. Note that if t is empty, the result is to prepend
// t' to s; also, if t does not occur in s then the result is s.
void theory_str::instantiate_axiom_Replace(enode * e) {
context & ctx = get_context();
ast_manager & m = get_manager();
app * ex = e->get_owner();
@ -1805,7 +1781,6 @@ namespace smt {
}
void theory_str::instantiate_axiom_str_to_int(enode * e) {
context & ctx = get_context();
ast_manager & m = get_manager();
app * ex = e->get_owner();
@ -1851,7 +1826,6 @@ namespace smt {
}
void theory_str::instantiate_axiom_int_to_str(enode * e) {
context & ctx = get_context();
ast_manager & m = get_manager();
app * ex = e->get_owner();
@ -1889,7 +1863,7 @@ namespace smt {
expr * theory_str::mk_RegexIn(expr * str, expr * regexp) {
app * regexIn = u.re.mk_in_re(str, regexp);
// immediately force internalization so that axiom setup does not fail
get_context().internalize(regexIn, false);
ctx.internalize(regexIn, false);
set_up_axioms(regexIn);
return regexIn;
}
@ -1916,7 +1890,6 @@ namespace smt {
}
void theory_str::attach_new_th_var(enode * n) {
context & ctx = get_context();
theory_var v = mk_var(n);
ctx.attach_th_var(n, this, v);
TRACE("str", tout << "new theory var: " << mk_ismt2_pp(n->get_owner(), get_manager()) << " := v#" << v << std::endl;);
@ -1929,7 +1902,7 @@ namespace smt {
candidate_model.reset();
m_basicstr_axiom_todo.reset();
m_concat_axiom_todo.reset();
pop_scope_eh(get_context().get_scope_level());
pop_scope_eh(ctx.get_scope_level());
}
/*
@ -1943,7 +1916,6 @@ namespace smt {
* Then add an assertion: (y2 == (Concat ce m2)) AND ("str3" == (Concat abc x2)) -> (y2 != "str3")
*/
bool theory_str::new_eq_check(expr * lhs, expr * rhs) {
context & ctx = get_context();
ast_manager & m = get_manager();
// skip this check if we defer consistency checking, as we can do it for every EQC in final check
@ -2001,7 +1973,6 @@ namespace smt {
if (!is_app(n)) {
return null_theory_var;
}
context & ctx = get_context();
if (ctx.e_internalized(to_app(n))) {
enode * e = ctx.get_enode(to_app(n));
return e->get_th_var(get_id());
@ -2113,7 +2084,6 @@ namespace smt {
*/
void theory_str::simplify_parent(expr * nn, expr * eq_str) {
ast_manager & m = get_manager();
context & ctx = get_context();
TRACE("str", tout << "simplifying parents of " << mk_ismt2_pp(nn, m)
<< " with respect to " << mk_ismt2_pp(eq_str, m) << std::endl;);
@ -2405,7 +2375,6 @@ namespace smt {
expr * theory_str::simplify_concat(expr * node) {
ast_manager & m = get_manager();
context & ctx = get_context();
std::map<expr*, expr*> resolvedMap;
ptr_vector<expr> argVec;
get_nodes_in_concat(node, argVec);
@ -2453,7 +2422,6 @@ namespace smt {
// (i.e. the equivalent of a len_exists flag in get_len_value()).
bool theory_str::infer_len_concat(expr * n, rational & nLen) {
context & ctx = get_context();
ast_manager & m = get_manager();
expr * arg0 = to_app(n)->get_arg(0);
expr * arg1 = to_app(n)->get_arg(1);
@ -2493,7 +2461,6 @@ namespace smt {
return;
}
context & ctx = get_context();
ast_manager & m = get_manager();
expr * arg0 = to_app(n)->get_arg(0);
@ -2602,14 +2569,12 @@ namespace smt {
}
void theory_str::add_theory_aware_branching_info(expr * term, double priority, lbool phase) {
context & ctx = get_context();
ctx.internalize(term, false);
bool_var v = ctx.get_bool_var(term);
ctx.add_theory_aware_branching_info(v, priority, phase);
}
void theory_str::generate_mutual_exclusion(expr_ref_vector & terms) {
context & ctx = get_context();
// pull each literal out of the arrangement disjunction
literal_vector ls;
for (expr * e : terms) {
@ -2638,7 +2603,6 @@ namespace smt {
*/
void theory_str::simplify_concat_equality(expr * nn1, expr * nn2) {
ast_manager & m = get_manager();
context & ctx = get_context();
app * a_nn1 = to_app(nn1);
SASSERT(a_nn1->get_num_args() == 2);
@ -3048,7 +3012,6 @@ namespace smt {
void theory_str::process_concat_eq_type1(expr * concatAst1, expr * concatAst2) {
ast_manager & mgr = get_manager();
context & ctx = get_context();
bool overlapAssumptionUsed = false;
@ -3440,7 +3403,6 @@ namespace smt {
void theory_str::process_concat_eq_type2(expr * concatAst1, expr * concatAst2) {
ast_manager & mgr = get_manager();
context & ctx = get_context();
bool overlapAssumptionUsed = false;
@ -3792,7 +3754,6 @@ namespace smt {
void theory_str::process_concat_eq_type3(expr * concatAst1, expr * concatAst2) {
ast_manager & mgr = get_manager();
context & ctx = get_context();
bool overlapAssumptionUsed = false;
@ -4141,7 +4102,6 @@ namespace smt {
void theory_str::process_concat_eq_type4(expr * concatAst1, expr * concatAst2) {
ast_manager & mgr = get_manager();
context & ctx = get_context();
TRACE("str", tout << "process_concat_eq TYPE 4" << std::endl
<< "concatAst1 = " << mk_ismt2_pp(concatAst1, mgr) << std::endl
<< "concatAst2 = " << mk_ismt2_pp(concatAst2, mgr) << std::endl;
@ -4242,7 +4202,6 @@ namespace smt {
void theory_str::process_concat_eq_type5(expr * concatAst1, expr * concatAst2) {
ast_manager & mgr = get_manager();
context & ctx = get_context();
TRACE("str", tout << "process_concat_eq TYPE 5" << std::endl
<< "concatAst1 = " << mk_ismt2_pp(concatAst1, mgr) << std::endl
<< "concatAst2 = " << mk_ismt2_pp(concatAst2, mgr) << std::endl;
@ -4343,7 +4302,6 @@ namespace smt {
void theory_str::process_concat_eq_type6(expr * concatAst1, expr * concatAst2) {
ast_manager & mgr = get_manager();
context & ctx = get_context();
TRACE("str", tout << "process_concat_eq TYPE 6" << std::endl
<< "concatAst1 = " << mk_ismt2_pp(concatAst1, mgr) << std::endl
<< "concatAst2 = " << mk_ismt2_pp(concatAst2, mgr) << std::endl;
@ -4588,7 +4546,6 @@ namespace smt {
}
bool theory_str::get_arith_value(expr* e, rational& val) const {
context& ctx = get_context();
ast_manager & m = get_manager();
(void)m;
if (!ctx.e_internalized(e)) {
@ -4615,7 +4572,7 @@ namespace smt {
}
arith_value v(get_manager());
v.init(&get_context());
v.init(&ctx);
bool strict;
return v.get_lo_equiv(_e, lo, strict);
}
@ -4627,7 +4584,7 @@ namespace smt {
}
arith_value v(get_manager());
v.init(&get_context());
v.init(&ctx);
bool strict;
return v.get_up_equiv(_e, hi, strict);
}
@ -4638,7 +4595,6 @@ namespace smt {
return false;
}
context& ctx = get_context();
ast_manager & m = get_manager();
TRACE("str", tout << "checking len value of " << mk_ismt2_pp(e, m) << std::endl;);
@ -4713,7 +4669,6 @@ namespace smt {
*/
bool theory_str::in_same_eqc(expr * n1, expr * n2) {
if (n1 == n2) return true;
context & ctx = get_context();
// similar to get_eqc_value(), make absolutely sure
// that we've set this up properly for the context
@ -4769,7 +4724,6 @@ namespace smt {
}
void theory_str::check_contain_by_eqc_val(expr * varNode, expr * constNode) {
context & ctx = get_context();
ast_manager & m = get_manager();
TRACE("str", tout << "varNode = " << mk_pp(varNode, m) << ", constNode = " << mk_pp(constNode, m) << std::endl;);
@ -4903,7 +4857,6 @@ namespace smt {
}
void theory_str::check_contain_by_substr(expr * varNode, expr_ref_vector & willEqClass) {
context & ctx = get_context();
ast_manager & m = get_manager();
expr_ref_vector litems(m);
@ -4977,7 +4930,6 @@ namespace smt {
}
void theory_str::check_contain_by_eq_nodes(expr * n1, expr * n2) {
context & ctx = get_context();
ast_manager & m = get_manager();
if (in_contain_idx_map(n1) && in_contain_idx_map(n2)) {
@ -5409,7 +5361,6 @@ namespace smt {
// haven't computed grounded concats for "node" (de-aliased)
// ---------------------------------------------------------
context & ctx = get_context();
// const strings: node is de-aliased
if (u.str.is_string(node)) {
@ -5639,7 +5590,6 @@ namespace smt {
void theory_str::check_subsequence(expr* str, expr* strDeAlias, expr* subStr, expr* subStrDeAlias, expr* boolVar,
std::map<expr*, std::map<std::vector<expr*>, std::set<expr*> > > & groundedMap) {
context & ctx = get_context();
ast_manager & m = get_manager();
std::map<std::vector<expr*>, std::set<expr*> >::iterator itorStr = groundedMap[strDeAlias].begin();
std::map<std::vector<expr*>, std::set<expr*> >::iterator itorSubStr;
@ -5840,7 +5790,6 @@ namespace smt {
// - note that these are different from the semantics in Z3str2
bool theory_str::check_length_const_string(expr * n1, expr * constStr) {
ast_manager & mgr = get_manager();
context & ctx = get_context();
zstring tmp;
u.str.is_string(constStr, tmp);
@ -5892,7 +5841,6 @@ namespace smt {
}
bool theory_str::check_length_concat_concat(expr * n1, expr * n2) {
context & ctx = get_context();
ast_manager & mgr = get_manager();
ptr_vector<expr> concat1Args;
@ -5963,7 +5911,6 @@ namespace smt {
}
bool theory_str::check_length_concat_var(expr * concat, expr * var) {
context & ctx = get_context();
ast_manager & mgr = get_manager();
rational varLen;
@ -5999,7 +5946,6 @@ namespace smt {
}
bool theory_str::check_length_var_var(expr * var1, expr * var2) {
context & ctx = get_context();
ast_manager & mgr = get_manager();
rational var1Len, var2Len;
@ -6283,7 +6229,6 @@ namespace smt {
*/
void theory_str::solve_concat_eq_str(expr * concat, expr * str) {
ast_manager & m = get_manager();
context & ctx = get_context();
TRACE("str", tout << mk_ismt2_pp(concat, m) << " == " << mk_ismt2_pp(str, m) << std::endl;);
@ -6620,7 +6565,6 @@ namespace smt {
void theory_str::handle_equality(expr * lhs, expr * rhs) {
ast_manager & m = get_manager();
context & ctx = get_context();
// both terms must be of sort String
sort * lhs_sort = m.get_sort(lhs);
sort * rhs_sort = m.get_sort(rhs);
@ -6768,7 +6712,6 @@ namespace smt {
// Check that a string's length can be 0 iff it is the empty string.
void theory_str::check_eqc_empty_string(expr * lhs, expr * rhs) {
context & ctx = get_context();
ast_manager & m = get_manager();
rational nn1Len, nn2Len;
@ -6864,7 +6807,6 @@ namespace smt {
void theory_str::set_up_axioms(expr * ex) {
ast_manager & m = get_manager();
context & ctx = get_context();
// workaround for #3756:
// the map existing_toplevel_exprs is never cleared on backtracking.
@ -6982,13 +6924,13 @@ namespace smt {
lbool theory_str::validate_unsat_core(expr_ref_vector & unsat_core) {
app * target_term = to_app(get_manager().mk_not(m_theoryStrOverlapAssumption_term));
get_context().internalize(target_term, false);
enode* e1 = get_context().get_enode(target_term);
ctx.internalize(target_term, false);
enode* e1 = ctx.get_enode(target_term);
for (unsigned i = 0; i < unsat_core.size(); ++i) {
app * core_term = to_app(unsat_core.get(i));
// not sure if this is the correct way to compare terms in this context
if (!get_context().e_internalized(core_term)) continue;
enode *e2 = get_context().get_enode(core_term);
if (!ctx.e_internalized(core_term)) continue;
enode *e2 = ctx.get_enode(core_term);
if (e1 == e2) {
TRACE("str", tout << "overlap detected in unsat core, changing UNSAT to UNKNOWN" << std::endl;);
return l_undef;
@ -6999,7 +6941,6 @@ namespace smt {
}
void theory_str::init_search_eh() {
context & ctx = get_context();
reset_internal_data_structures();
@ -7067,7 +7008,7 @@ namespace smt {
void theory_str::assign_eh(bool_var v, bool is_true) {
candidate_model.reset();
expr * e = get_context().bool_var2expr(v);
expr * e = ctx.bool_var2expr(v);
TRACE("str", tout << "assert: v" << v << " " << mk_pp(e, get_manager()) << " is_true: " << is_true << std::endl;);
DEBUG_CODE(
for (auto * f : existing_toplevel_exprs) {
@ -7131,7 +7072,6 @@ namespace smt {
TRACE("str", tout << "checking scopes of variables in the current assignment" << std::endl;);
context & ctx = get_context();
ast_manager & m = get_manager();
expr_ref_vector assignments(m);
@ -7147,7 +7087,6 @@ namespace smt {
}
void theory_str::pop_scope_eh(unsigned num_scopes) {
context & ctx = get_context();
sLevel -= num_scopes;
TRACE("str", tout << "pop " << num_scopes << " to " << sLevel << std::endl;);
candidate_model.reset();
@ -7209,7 +7148,6 @@ namespace smt {
void theory_str::dump_assignments() {
TRACE_CODE(
ast_manager & m = get_manager();
context & ctx = get_context();
tout << "dumping all assignments:" << std::endl;
expr_ref_vector assignments(m);
ctx.get_assignments(assignments);
@ -7294,7 +7232,6 @@ namespace smt {
void theory_str::classify_ast_by_type_in_positive_context(std::map<expr*, int> & varMap,
std::map<expr*, int> & concatMap, std::map<expr*, int> & unrollMap) {
context & ctx = get_context();
ast_manager & m = get_manager();
expr_ref_vector assignments(m);
ctx.get_assignments(assignments);
@ -7352,7 +7289,6 @@ namespace smt {
std::map<expr*, std::map<expr*, int> > & concat_eq_concat_map,
std::map<expr*, std::set<expr*> > & unrollGroupMap) {
#ifdef _TRACE
context & ctx = get_context();
ast_manager & mgr = get_manager();
{
tout << "(0) alias: variables" << std::endl;
@ -7517,7 +7453,6 @@ namespace smt {
std::map<expr*, std::map<expr*, int> > concat_eq_concat_map;
std::map<expr*, std::map<expr*, int> > depMap;
context & ctx = get_context();
ast_manager & m = get_manager();
// note that the old API concatenated these assignments into
@ -8071,7 +8006,6 @@ namespace smt {
bool theory_str::finalcheck_str2int(app * a) {
SASSERT(u.str.is_stoi(a));
bool axiomAdd = false;
context & ctx = get_context();
ast_manager & m = get_manager();
expr * S = a->get_arg(0);
@ -8156,7 +8090,6 @@ namespace smt {
bool theory_str::finalcheck_int2str(app * a) {
bool axiomAdd = false;
context & ctx = get_context();
ast_manager & m = get_manager();
expr * N = a->get_arg(0);
@ -8247,7 +8180,6 @@ namespace smt {
bool theory_str::propagate_length_within_eqc(expr * var) {
bool res = false;
ast_manager & m = get_manager();
context & ctx = get_context();
TRACE("str", tout << "propagate_length_within_eqc: " << mk_ismt2_pp(var, m) << std::endl ;);
@ -8286,7 +8218,6 @@ namespace smt {
}
bool theory_str::propagate_length(std::set<expr*> & varSet, std::set<expr*> & concatSet, std::map<expr*, int> & exprLenMap) {
context & ctx = get_context();
ast_manager & m = get_manager();
expr_ref_vector assignments(m);
ctx.get_assignments(assignments);
@ -8370,7 +8301,6 @@ namespace smt {
}
final_check_status theory_str::final_check_eh() {
context & ctx = get_context();
ast_manager & m = get_manager();
//expr_ref_vector assignments(m);
@ -8723,7 +8653,7 @@ namespace smt {
TRACE("str", tout << "using fixed-length model construction" << std::endl;);
arith_value v(get_manager());
v.init(&get_context());
v.init(&ctx);
final_check_status arith_fc_status = v.final_check();
if (arith_fc_status != FC_DONE) {
TRACE("str", tout << "arithmetic solver not done yet, continuing search" << std::endl;);
@ -8884,7 +8814,7 @@ namespace smt {
owner = n->get_owner();
// If the owner is not internalized, it doesn't have an enode associated.
SASSERT(get_context().e_internalized(owner));
SASSERT(ctx.e_internalized(owner));
app * val = mk_value_helper(owner);
if (val != nullptr) {
@ -8905,7 +8835,6 @@ namespace smt {
unsigned theory_str::get_refine_length(expr* ex, expr_ref_vector& extra_deps){
ast_manager & m = get_manager();
context & ctx = get_context();
TRACE("str_fl", tout << "finding length for " << mk_ismt2_pp(ex, m) << std::endl;);
if (u.str.is_string(ex)) {
@ -8991,7 +8920,6 @@ namespace smt {
expr* theory_str::refine_eq(expr* lhs, expr* rhs, unsigned offset) {
TRACE("str_fl", tout << "refine eq " << offset << std::endl;);
ast_manager & m = get_manager();
context & ctx = get_context();
expr_ref_vector Gamma(m);
expr_ref_vector Delta(m);
@ -9112,7 +9040,6 @@ namespace smt {
expr* theory_str::refine_dis(expr* lhs, expr* rhs) {
ast_manager & m = get_manager();
context & ctx = get_context();
expr_ref lesson(m);
lesson = m.mk_not(ctx.mk_eq_atom(lhs, rhs));

View file

@ -778,10 +778,11 @@ protected:
void refresh_theory_var(expr * e);
public:
theory_str(ast_manager & m, theory_str_params const & params);
theory_str(context& ctx, ast_manager & m, theory_str_params const & params);
~theory_str() override;
char const * get_name() const override { return "seq"; }
void init() override;
void display(std::ostream & out) const override;
void collect_statistics(::statistics & st) const override;
@ -801,8 +802,7 @@ protected:
void new_eq_eh(theory_var, theory_var) override;
void new_diseq_eh(theory_var, theory_var) override;
theory* mk_fresh(context* c) override { return alloc(theory_str, c->get_manager(), m_params); }
void init(context * ctx) override;
theory* mk_fresh(context* c) override { return alloc(theory_str, *c, c->get_manager(), m_params); }
void init_search_eh() override;
void add_theory_assumptions(expr_ref_vector & assumptions) override;
lbool validate_unsat_core(expr_ref_vector & unsat_core) override;

View file

@ -88,7 +88,6 @@ namespace smt {
bool theory_str::fixed_length_reduce_suffix(smt::kernel & subsolver, expr_ref f, expr_ref & cex) {
ast_manager & m = get_manager();
context & ctx = get_context();
ast_manager & sub_m = subsolver.m();
context & sub_ctx = subsolver.get_context();
@ -151,7 +150,6 @@ namespace smt {
bool theory_str::fixed_length_reduce_negative_suffix(smt::kernel & subsolver, expr_ref f, expr_ref & cex) {
ast_manager & m = get_manager();
context & ctx = get_context();
ast_manager & sub_m = subsolver.m();
context & sub_ctx = subsolver.get_context();
@ -206,7 +204,6 @@ namespace smt {
bool theory_str::fixed_length_reduce_prefix(smt::kernel & subsolver, expr_ref f, expr_ref & cex) {
ast_manager & m = get_manager();
context & ctx = get_context();
ast_manager & sub_m = subsolver.m();
context & sub_ctx = subsolver.get_context();
@ -269,7 +266,6 @@ namespace smt {
bool theory_str::fixed_length_reduce_negative_prefix(smt::kernel & subsolver, expr_ref f, expr_ref & cex) {
ast_manager & m = get_manager();
context & ctx = get_context();
ast_manager & sub_m = subsolver.m();
context & sub_ctx = subsolver.get_context();
@ -323,7 +319,6 @@ namespace smt {
bool theory_str::fixed_length_reduce_contains(smt::kernel & subsolver, expr_ref f, expr_ref & cex) {
ast_manager & m = get_manager();
context & ctx = get_context();
ast_manager & sub_m = subsolver.m();
context & sub_ctx = subsolver.get_context();
@ -391,7 +386,6 @@ namespace smt {
bool theory_str::fixed_length_reduce_negative_contains(smt::kernel & subsolver, expr_ref f, expr_ref & cex) {
ast_manager & m = get_manager();
context & ctx = get_context();
ast_manager & sub_m = subsolver.m();
context & sub_ctx = subsolver.get_context();
@ -463,7 +457,6 @@ namespace smt {
bool theory_str::fixed_length_reduce_regex_membership(smt::kernel & subsolver, expr_ref f, expr_ref & cex, bool polarity) {
ast_manager & m = get_manager();
context & ctx = get_context();
ast_manager & sub_m = subsolver.m();
context & sub_ctx = subsolver.get_context();
@ -776,7 +769,6 @@ namespace smt {
bool theory_str::fixed_length_reduce_eq(smt::kernel & subsolver, expr_ref lhs, expr_ref rhs, expr_ref & cex) {
ast_manager & m = get_manager();
context & ctx = get_context();
ast_manager & sub_m = subsolver.m();
context & sub_ctx = subsolver.get_context();
@ -873,7 +865,6 @@ namespace smt {
TRACE("str",
ast_manager & m = get_manager();
context & ctx = get_context();
tout << "dumping all formulas:" << std::endl;
for (expr_ref_vector::iterator i = formulas.begin(); i != formulas.end(); ++i) {
expr * ex = *i;
@ -1154,7 +1145,6 @@ namespace smt {
if (m.is_true(f_new)) {
// do nothing
} else if (m.is_false(f_new)) {
context & ctx = get_context();
expr * needle = nullptr, *haystack = nullptr;
if (u.str.is_contains(f, haystack, needle)) {
expr_ref haystack_assignment(m);

View file

@ -48,7 +48,6 @@ namespace smt {
void theory_str::solve_regex_automata() {
context & ctx = get_context();
ast_manager & m = get_manager();
// TODO since heuristics might fail, the "no progress" flag might need to be handled specially here
@ -999,7 +998,6 @@ namespace smt {
*/
expr_ref theory_str::infer_all_regex_lengths(expr * lenVar, expr * re, expr_ref_vector & freeVariables) {
ENSURE(u.is_re(re));
context & ctx = get_context();
ast_manager & m = get_manager();
expr * sub1;
expr * sub2;
@ -1127,7 +1125,6 @@ namespace smt {
*/
void theory_str::find_automaton_initial_bounds(expr * str_in_re, eautomaton * aut) {
ENSURE(aut != nullptr);
context & ctx = get_context();
ast_manager & m = get_manager();
expr_ref_vector rhs(m);
@ -1362,7 +1359,6 @@ namespace smt {
}
expr_ref theory_str::aut_path_rewrite_constraint(expr * cond, expr * ch_var) {
context & ctx = get_context();
ast_manager & m = get_manager();
expr_ref retval(m);
@ -1419,7 +1415,6 @@ namespace smt {
*/
expr_ref theory_str::generate_regex_path_constraints(expr * stringTerm, eautomaton * aut, rational lenVal, expr_ref & characterConstraints) {
ENSURE(aut != nullptr);
context & ctx = get_context();
ast_manager & m = get_manager();
if (lenVal.is_zero()) {

View file

@ -199,21 +199,21 @@ namespace smt {
}
public:
theory_utvpi(ast_manager& m);
theory_utvpi(context& ctx);
~theory_utvpi() override;
theory * mk_fresh(context * new_ctx) override;
char const * get_name() const override { return "utvpi-logic"; }
void init() override { init_zero(); }
/**
\brief See comment in theory::mk_eq_atom
*/
app * mk_eq_atom(expr * lhs, expr * rhs) override { return a.mk_eq(lhs, rhs); }
void init(context * ctx) override;
bool internalize_atom(app * atom, bool gate_ctx) override;
bool internalize_term(app * term) override;

View file

@ -57,10 +57,10 @@ namespace smt {
template<typename Ext>
theory_utvpi<Ext>::theory_utvpi(ast_manager& m):
theory(m.mk_family_id("arith")),
a(m),
m_arith_eq_adapter(*this, m_params, a),
theory_utvpi<Ext>::theory_utvpi(context& ctx):
theory(ctx, ctx.get_manager().mk_family_id("arith")),
a(ctx.get_manager()),
m_arith_eq_adapter(*this, a),
m_consistent(true),
m_izero(null_theory_var),
m_rzero(null_theory_var),
@ -70,7 +70,7 @@ namespace smt {
m_lia(false),
m_lra(false),
m_non_utvpi_exprs(false),
m_test(m),
m_test(ctx.get_manager()),
m_factory(nullptr),
m_var_value_table(DEFAULT_HASHTABLE_INITIAL_CAPACITY, var_value_hash(*this), var_value_eq(*this)) {
}
@ -98,16 +98,15 @@ namespace smt {
template<typename Ext>
theory_var theory_utvpi<Ext>::mk_var(enode* n) {
th_var v = theory::mk_var(n);
TRACE("utvpi", tout << v << " " << mk_pp(n->get_owner(), get_manager()) << "\n";);
TRACE("utvpi", tout << v << " " << mk_pp(n->get_owner(), m) << "\n";);
m_graph.init_var(to_var(v));
m_graph.init_var(neg(to_var(v)));
get_context().attach_th_var(n, this, v);
ctx.attach_th_var(n, this, v);
return v;
}
template<typename Ext>
theory_var theory_utvpi<Ext>::mk_var(expr* n) {
context & ctx = get_context();
enode* e = nullptr;
th_var v = null_theory_var;
m_lia |= a.is_int(n);
@ -154,8 +153,6 @@ namespace smt {
rational k(0);
th_var s = expand(true, v1, k);
th_var t = expand(false, v2, k);
context& ctx = get_context();
ast_manager& m = get_manager();
if (s == t) {
if (is_eq != k.is_zero()) {
@ -193,7 +190,7 @@ namespace smt {
template<typename Ext>
void theory_utvpi<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) {
@ -206,7 +203,6 @@ namespace smt {
void theory_utvpi<Ext>::set_conflict() {
inc_conflicts();
literal_vector const& lits = m_nc_functor.get_lits();
context & ctx = get_context();
IF_VERBOSE(20, ctx.display_literals_smt2(verbose_stream() << "conflict:\n", lits));
TRACE("utvpi", ctx.display_literals_smt2(tout << "conflict:\n", lits););
@ -216,7 +212,7 @@ namespace smt {
}
vector<parameter> params;
if (get_manager().proofs_enabled()) {
if (m.proofs_enabled()) {
params.push_back(parameter(symbol("farkas")));
for (unsigned i = 0; i < m_nc_functor.get_coeffs().size(); ++i) {
params.push_back(parameter(rational(m_nc_functor.get_coeffs()[i])));
@ -238,24 +234,18 @@ namespace smt {
return;
}
std::stringstream msg;
msg << "found non utvpi logic expression:\n" << mk_pp(n, get_manager()) << "\n";
msg << "found non utvpi logic expression:\n" << mk_pp(n, m) << "\n";
TRACE("utvpi", tout << msg.str(););
warning_msg("%s", msg.str().c_str());
get_context().push_trail(value_trail<context, bool>(m_non_utvpi_exprs));
ctx.push_trail(value_trail<context, bool>(m_non_utvpi_exprs));
m_non_utvpi_exprs = true;
}
template<typename Ext>
void theory_utvpi<Ext>::init(context* ctx) {
theory::init(ctx);
init_zero();
}
template<typename Ext>
void theory_utvpi<Ext>::init_zero() {
if (m_izero == null_theory_var) {
m_izero = mk_var(get_context().mk_enode(a.mk_numeral(rational(0), true), false, false, true));
m_rzero = mk_var(get_context().mk_enode(a.mk_numeral(rational(0), false), false, false, true));
m_izero = mk_var(ctx.mk_enode(a.mk_numeral(rational(0), true), false, false, true));
m_rzero = mk_var(ctx.mk_enode(a.mk_numeral(rational(0), false), false, false, true));
}
}
@ -297,7 +287,6 @@ namespace smt {
template<typename Ext>
void theory_utvpi<Ext>::internalize_eq_eh(app * atom, bool_var v) {
context & ctx = get_context();
app * lhs = to_app(atom->get_arg(0));
app * rhs = to_app(atom->get_arg(1));
if (a.is_numeral(rhs)) {
@ -317,7 +306,6 @@ namespace smt {
bool theory_utvpi<Ext>::internalize_atom(app * n, bool) {
if (!m_consistent)
return false;
context & ctx = get_context();
if (!a.is_le(n) && !a.is_ge(n) && !a.is_lt(n) && !a.is_gt(n)) {
found_non_utvpi_expr(n);
return false;
@ -357,7 +345,7 @@ namespace smt {
m_atoms.push_back(atom(bv, pos, neg));
TRACE("utvpi",
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);
);
@ -369,8 +357,8 @@ namespace smt {
bool theory_utvpi<Ext>::internalize_term(app * term) {
if (!m_consistent)
return false;
bool result = !get_context().inconsistent() && null_theory_var != mk_term(term);
CTRACE("utvpi", !result, tout << "Did not internalize " << mk_pp(term, get_manager()) << "\n";);
bool result = !ctx.inconsistent() && null_theory_var != mk_term(term);
CTRACE("utvpi", !result, tout << "Did not internalize " << mk_pp(term, m) << "\n";);
return result;
}
@ -378,8 +366,8 @@ namespace smt {
void theory_utvpi<Ext>::assign_eh(bool_var v, bool is_true) {
m_stats.m_num_assertions++;
unsigned idx = m_bool_var2atom.find(v);
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);
m_atoms[idx].assign_eh(is_true);
m_asserted_atoms.push_back(idx);
}
@ -471,7 +459,7 @@ namespace smt {
m_nc_functor.reset();
VERIFY(m_graph.find_shortest_zero_edge_path(v1, v2, UINT_MAX, m_nc_functor));
VERIFY(m_graph.find_shortest_zero_edge_path(v2, v1, UINT_MAX, m_nc_functor));
IF_VERBOSE(1, verbose_stream() << "parity conflict " << mk_pp(e->get_owner(), get_manager()) << "\n";);
IF_VERBOSE(1, verbose_stream() << "parity conflict " << mk_pp(e->get_owner(), m) << "\n";);
set_conflict();
return false;
@ -510,7 +498,7 @@ namespace smt {
template<typename Ext>
void theory_utvpi<Ext>::propagate() {
bool consistent = is_consistent() && !get_context().inconsistent();
bool consistent = is_consistent() && !ctx.inconsistent();
while (consistent && can_propagate()) {
unsigned idx = m_asserted_atoms[m_asserted_qhead];
m_asserted_qhead++;
@ -532,8 +520,7 @@ namespace smt {
template<typename Ext>
theory_var theory_utvpi<Ext>::mk_term(app* n) {
TRACE("utvpi", tout << mk_pp(n, get_manager()) << "\n";);
context& ctx = get_context();
TRACE("utvpi", tout << mk_pp(n, m) << "\n";);
bool cl = m_test.linearize(n);
if (!cl) {
@ -571,7 +558,6 @@ namespace smt {
template<typename Ext>
theory_var theory_utvpi<Ext>::mk_num(app* n, rational const& r) {
theory_var v = null_theory_var;
context& ctx = get_context();
if (r.is_zero()) {
v = get_zero(n);
if (!ctx.e_internalized(n)) {
@ -602,7 +588,6 @@ namespace smt {
template<typename Ext>
theory_var theory_utvpi<Ext>::expand(bool pos, th_var v, rational & k) {
context& ctx = get_context();
enode* e = get_enode(v);
expr* x, *y;
rational r;
@ -831,7 +816,6 @@ namespace smt {
template<typename Ext>
void theory_utvpi<Ext>::model_validate() {
context& ctx = get_context();
for (auto const& a : m_atoms) {
bool_var b = a.get_bool_var();
if (!ctx.is_relevant(b)) {
@ -853,13 +837,13 @@ namespace smt {
CTRACE("utvpi", !ok,
tout << "validation failed:\n";
tout << "Assignment: " << assign << "\n";
tout << mk_pp(e, get_manager()) << "\n";
tout << mk_pp(e, m) << "\n";
a.display(*this, tout);
tout << "\n";
display(tout);
m_graph.display_agl(tout);
);
// CTRACE("utvpi", ok, tout << "validation success: " << mk_pp(e, get_manager()) << "\n";);
// CTRACE("utvpi", ok, tout << "validation success: " << mk_pp(e, m) << "\n";);
SASSERT(ok);
}
}
@ -873,10 +857,10 @@ namespace smt {
if (a.is_lt(e, e1, e2) || a.is_gt(e, e2, e1)) {
return eval_num(e1) < eval_num(e2);
}
if (get_manager().is_eq(e, e1, e2)) {
if (m.is_eq(e, e1, e2)) {
return eval_num(e1) == eval_num(e2);
}
TRACE("utvpi", tout << "expression not handled: " << mk_pp(e, get_manager()) << "\n";);
TRACE("utvpi", tout << "expression not handled: " << mk_pp(e, m) << "\n";);
return false;
}
@ -909,7 +893,7 @@ namespace smt {
if (is_uninterp_const(e)) {
return mk_value(mk_var(e), a.is_int(e));
}
TRACE("utvpi", tout << "expression not handled: " << mk_pp(e, get_manager()) << "\n";);
TRACE("utvpi", tout << "expression not handled: " << mk_pp(e, m) << "\n";);
UNREACHABLE();
return rational(0);
}
@ -926,7 +910,7 @@ namespace smt {
SASSERT(!is_int || num.is_int());
TRACE("utvpi",
expr* n = get_enode(v)->get_owner();
tout << mk_pp(n, get_manager()) << " |-> (" << val1 << " - " << val2 << ")/2 = " << num << "\n";);
tout << mk_pp(n, m) << " |-> (" << val1 << " - " << val2 << ")/2 = " << num << "\n";);
return num;
}
@ -936,7 +920,7 @@ namespace smt {
theory_var v = n->get_th_var(get_id());
bool is_int = a.is_int(n->get_owner());
rational num = mk_value(v, is_int);
TRACE("utvpi", tout << mk_pp(n->get_owner(), get_manager()) << " |-> " << num << "\n";);
TRACE("utvpi", tout << mk_pp(n->get_owner(), m) << " |-> " << num << "\n";);
return alloc(expr_wrapper_proc, m_factory->mk_num_value(num, is_int));
}
@ -980,7 +964,7 @@ namespace smt {
template<typename Ext>
theory* theory_utvpi<Ext>::mk_fresh(context* new_ctx) {
return alloc(theory_utvpi<Ext>, new_ctx->get_manager());
return alloc(theory_utvpi<Ext>, *new_ctx);
}

View file

@ -25,8 +25,8 @@ Notes:
namespace smt {
theory_wmaxsat::theory_wmaxsat(ast_manager& m, generic_model_converter& mc):
theory(m.mk_family_id("weighted_maxsat")),
theory_wmaxsat::theory_wmaxsat(context& ctx, ast_manager& m, generic_model_converter& mc):
theory(ctx, m.mk_family_id("weighted_maxsat")),
m_mc(mc),
m_vars(m),
m_fmls(m),
@ -88,7 +88,6 @@ namespace smt {
}
expr* theory_wmaxsat::assert_weighted(expr* fml, rational const& w) {
context & ctx = get_context();
ast_manager& m = get_manager();
app_ref var(m), wfml(m);
var = m.mk_fresh_const("w", m.mk_bool_sort());
@ -109,7 +108,6 @@ namespace smt {
}
void theory_wmaxsat::disable_var(expr* var) {
context& ctx = get_context();
SASSERT(ctx.b_internalized(var));
bool_var bv = ctx.get_bool_var(var);
theory_var tv = m_bool2var[bv];
@ -118,7 +116,6 @@ namespace smt {
}
bool_var theory_wmaxsat::register_var(app* var, bool attach) {
context & ctx = get_context();
bool_var bv;
SASSERT(!ctx.e_internalized(var));
enode* x = ctx.mk_enode(var, false, true, true);
@ -159,7 +156,6 @@ namespace smt {
void theory_wmaxsat::assign_eh(bool_var v, bool is_true) {
if (is_true) {
if (m_normalize) normalize();
context& ctx = get_context();
theory_var tv = m_bool2var[v];
if (m_assigned[tv] || !m_enabled[tv]) return;
scoped_mpz w(m_mpz);
@ -212,7 +208,6 @@ namespace smt {
void theory_wmaxsat::propagate() {
context& ctx = get_context();
for (unsigned i = 0; m_propagate && i < m_vars.size(); ++i) {
bool_var bv = m_var2bool[i];
lbool asgn = ctx.get_assignment(bv);
@ -256,7 +251,7 @@ namespace smt {
tout << mk_pp(get_enode(m_costs[i])->get_owner(), get_manager()) << " ";
}
tout << "\n";
//get_context().display(tout);
//ctx.display(tout);
);
}
expr_ref result(m.mk_or(disj.size(), disj.c_ptr()), m);
@ -273,7 +268,6 @@ namespace smt {
return;
}
++m_stats.m_num_blocks;
context& ctx = get_context();
literal_vector lits;
compare_cost compare_cost(*this);
svector<theory_var> costs(m_costs);
@ -293,7 +287,6 @@ namespace smt {
}
bool theory_wmaxsat::max_unassigned_is_blocked() {
context& ctx = get_context();
unsigned max_unassigned = m_max_unassigned_index;
if (max_unassigned < m_sorted_vars.size() &&
m_zcost + m_zweights[m_sorted_vars[max_unassigned]] < m_zmin_cost) {
@ -322,7 +315,6 @@ namespace smt {
void theory_wmaxsat::propagate(bool_var v) {
++m_stats.m_num_propagations;
context& ctx = get_context();
literal_vector lits;
literal lit(v, true);

View file

@ -56,7 +56,7 @@ namespace smt {
bool_vector m_assigned, m_enabled;
stats m_stats;
public:
theory_wmaxsat(ast_manager& m, generic_model_converter& mc);
theory_wmaxsat(context& ctx, ast_manager& m, generic_model_converter& mc);
~theory_wmaxsat() override;
void get_assignment(bool_vector& result);
expr* assert_weighted(expr* fml, rational const& w);