mirror of
https://github.com/Z3Prover/z3
synced 2025-08-21 02:30:23 +00:00
merge
Signed-off-by: Miguel Angelo Da Terra Neves <t-mineve@microsoft.com>
This commit is contained in:
commit
37c39f4073
138 changed files with 1404 additions and 2783 deletions
|
@ -1,5 +1,6 @@
|
|||
z3_add_component(tactic
|
||||
SOURCES
|
||||
dependency_converter.cpp
|
||||
equiv_proof_converter.cpp
|
||||
generic_model_converter.cpp
|
||||
goal.cpp
|
||||
|
|
|
@ -90,13 +90,8 @@ public:
|
|||
SASSERT(g->is_well_sorted());
|
||||
}
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
virtual void operator()(goal_ref const & g, goal_ref_buffer & result) {
|
||||
fail_if_proof_generation("aig", g);
|
||||
mc = 0; pc = 0; core = 0;
|
||||
operator()(g);
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
|
|
|
@ -111,11 +111,7 @@ class add_bounds_tactic : public tactic {
|
|||
};
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
mc = 0; pc = 0; core = 0;
|
||||
goal_ref_buffer & result) {
|
||||
tactic_report report("add-bounds", *g);
|
||||
bound_manager bm(m);
|
||||
expr_fast_mark1 visited;
|
||||
|
@ -161,11 +157,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(g, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(g, result);
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
|
|
|
@ -24,10 +24,7 @@ struct arith_bounds_tactic : public tactic {
|
|||
|
||||
|
||||
virtual void operator()(/* in */ goal_ref const & in,
|
||||
/* out */ goal_ref_buffer & result,
|
||||
/* out */ model_converter_ref & mc,
|
||||
/* out */ proof_converter_ref & pc,
|
||||
/* out */ expr_dependency_ref & core) {
|
||||
/* out */ goal_ref_buffer & result) {
|
||||
bounds_arith_subsumption(in, result);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,13 +53,10 @@ public:
|
|||
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
TRACE("card2bv-before", g->display(tout););
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0; result.reset();
|
||||
result.reset();
|
||||
tactic_report report("card2bv", *g);
|
||||
th_rewriter rw1(m, m_params);
|
||||
pb2bv_rewriter rw2(m, m_params);
|
||||
|
@ -90,10 +87,8 @@ public:
|
|||
func_decl_ref_vector const& fns = rw2.fresh_constants();
|
||||
if (!fns.empty()) {
|
||||
generic_model_converter* filter = alloc(generic_model_converter, m);
|
||||
for (unsigned i = 0; i < fns.size(); ++i) {
|
||||
filter->hide(fns[i]);
|
||||
}
|
||||
mc = filter;
|
||||
for (func_decl* f : fns) filter->hide(f);
|
||||
g->add(filter);
|
||||
}
|
||||
|
||||
g->inc_depth();
|
||||
|
|
|
@ -223,16 +223,13 @@ class degree_shift_tactic : public tactic {
|
|||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
m_produce_proofs = g->proofs_enabled();
|
||||
m_produce_models = g->models_enabled();
|
||||
tactic_report report("degree_shift", *g);
|
||||
collect(*g);
|
||||
model_converter_ref mc;
|
||||
discard_non_candidates();
|
||||
if (!m_var2degree.empty()) {
|
||||
prepare_substitution(mc);
|
||||
|
@ -270,6 +267,7 @@ class degree_shift_tactic : public tactic {
|
|||
}
|
||||
}
|
||||
g->inc_depth();
|
||||
g->add(mc.get());
|
||||
result.push_back(g.get());
|
||||
TRACE("degree_shift", g->display(tout); if (mc) mc->display(tout););
|
||||
SASSERT(g->is_well_sorted());
|
||||
|
@ -291,11 +289,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
|
|
|
@ -313,13 +313,10 @@ class diff_neq_tactic : public tactic {
|
|||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
m_produce_models = g->models_enabled();
|
||||
mc = 0; pc = 0; core = 0; result.reset();
|
||||
result.reset();
|
||||
tactic_report report("diff-neq", *g);
|
||||
fail_if_proof_generation("diff-neq", g);
|
||||
fail_if_unsat_core_generation("diff-neq", g);
|
||||
|
@ -332,8 +329,9 @@ class diff_neq_tactic : public tactic {
|
|||
bool r = search();
|
||||
report_tactic_progress(":conflicts", m_num_conflicts);
|
||||
if (r) {
|
||||
if (m_produce_models)
|
||||
mc = model2model_converter(mk_model());
|
||||
if (m_produce_models) {
|
||||
g->add(model2model_converter(mk_model()));
|
||||
}
|
||||
g->reset();
|
||||
}
|
||||
else {
|
||||
|
@ -384,11 +382,8 @@ public:
|
|||
If s is not really in the difference logic fragment, then this is a NOOP.
|
||||
*/
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
|
|
|
@ -41,8 +41,7 @@ public:
|
|||
m_refs(m)
|
||||
{}
|
||||
|
||||
virtual void operator()(model_ref & old_model, unsigned goal_idx) {
|
||||
SASSERT(goal_idx == 0);
|
||||
virtual void operator()(model_ref & old_model) {
|
||||
model * new_model = alloc(model, m);
|
||||
unsigned num = old_model->get_num_constants();
|
||||
for (unsigned i = 0; i < m_nums_as_int.size(); ++i) {
|
||||
|
@ -153,18 +152,13 @@ public:
|
|||
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
|
||||
tactic_report report("elim01", *g);
|
||||
|
||||
expr_safe_replace sub(m);
|
||||
bool2int_model_converter* b2i = alloc(bool2int_model_converter, m);
|
||||
mc = b2i;
|
||||
ref<bool2int_model_converter> b2i = alloc(bool2int_model_converter, m);
|
||||
bound_manager bounds(m);
|
||||
expr_ref_vector axioms(m);
|
||||
bounds(*g);
|
||||
|
@ -179,7 +173,7 @@ public:
|
|||
if (a.is_int(x) &&
|
||||
bounds.has_lower(x, lo, s1) && !s1 && zero <= lo &&
|
||||
bounds.has_upper(x, hi, s2) && !s2 && hi <= m_max_hi && lo <= hi) {
|
||||
add_variable(b2i, sub, x, lo.get_unsigned(), hi.get_unsigned(), axioms);
|
||||
add_variable(b2i.get(), sub, x, lo.get_unsigned(), hi.get_unsigned(), axioms);
|
||||
}
|
||||
else if (a.is_int(x)) {
|
||||
TRACE("pb", tout << "Not adding variable " << mk_pp(x, m) << " has lower: "
|
||||
|
@ -205,9 +199,9 @@ public:
|
|||
}
|
||||
g->update(i, new_curr, new_pr, g->dep(i));
|
||||
}
|
||||
for (unsigned i = 0; i < axioms.size(); ++i) {
|
||||
g->assert_expr(axioms[i].get());
|
||||
}
|
||||
for (expr* a : axioms)
|
||||
g->assert_expr(a);
|
||||
g->add(b2i.get());
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
TRACE("pb", g->display(tout););
|
||||
|
|
|
@ -149,14 +149,8 @@ public:
|
|||
void updt_params(params_ref const & p) {
|
||||
}
|
||||
|
||||
virtual void operator()(
|
||||
goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
virtual void operator()(goal_ref const & g, goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
m_trail.reset();
|
||||
m_fd.reset();
|
||||
m_max.reset();
|
||||
|
@ -212,7 +206,7 @@ public:
|
|||
}
|
||||
}
|
||||
g->inc_depth();
|
||||
mc = mc1.get();
|
||||
g->add(mc1.get());
|
||||
result.push_back(g.get());
|
||||
TRACE("pb", g->display(tout););
|
||||
SASSERT(g->is_well_sorted());
|
||||
|
|
|
@ -257,12 +257,8 @@ class factor_tactic : public tactic {
|
|||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
tactic_report report("factor", *g);
|
||||
bool produce_proofs = g->proofs_enabled();
|
||||
|
||||
|
@ -313,12 +309,9 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
try {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
catch (z3_error & ex) {
|
||||
throw ex;
|
||||
|
|
|
@ -249,12 +249,8 @@ class fix_dl_var_tactic : public tactic {
|
|||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
tactic_report report("fix-dl-var", *g);
|
||||
bool produce_proofs = g->proofs_enabled();
|
||||
m_produce_models = g->models_enabled();
|
||||
|
@ -270,9 +266,9 @@ class fix_dl_var_tactic : public tactic {
|
|||
m_rw.set_substitution(&subst);
|
||||
|
||||
if (m_produce_models) {
|
||||
generic_model_converter * _mc = alloc(generic_model_converter, m);
|
||||
_mc->add(var, zero);
|
||||
mc = _mc;
|
||||
generic_model_converter * mc = alloc(generic_model_converter, m);
|
||||
mc->add(var, zero);
|
||||
g->add(mc);
|
||||
}
|
||||
|
||||
expr_ref new_curr(m);
|
||||
|
@ -321,12 +317,9 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
try {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
catch (rewriter_exception & ex) {
|
||||
throw tactic_exception(ex.msg());
|
||||
|
|
|
@ -180,7 +180,7 @@ class fm_tactic : public tactic {
|
|||
m_clauses.back().swap(c);
|
||||
}
|
||||
|
||||
virtual void operator()(model_ref & md, unsigned goal_idx) {
|
||||
virtual void operator()(model_ref & md) {
|
||||
TRACE("fm_mc", model_v2_pp(tout, *md); display(tout););
|
||||
model_evaluator ev(*(md.get()));
|
||||
ev.set_model_completion(true);
|
||||
|
@ -1550,12 +1550,8 @@ class fm_tactic : public tactic {
|
|||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
tactic_report report("fm", *g);
|
||||
fail_if_proof_generation("fm", g);
|
||||
m_produce_models = g->models_enabled();
|
||||
|
@ -1603,7 +1599,7 @@ class fm_tactic : public tactic {
|
|||
report_tactic_progress(":fm-cost", m_counter);
|
||||
if (!m_inconsistent) {
|
||||
copy_remaining();
|
||||
mc = m_mc.get();
|
||||
m_new_goal->add(concat(g->mc(), m_mc.get()));
|
||||
}
|
||||
}
|
||||
reset_constraints();
|
||||
|
@ -1675,11 +1671,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -159,12 +159,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
m_01s->reset();
|
||||
|
||||
tactic_report report("cardinality-intro", *g);
|
||||
|
@ -173,9 +169,7 @@ public:
|
|||
bounds(*g);
|
||||
|
||||
|
||||
bound_manager::iterator bit = bounds.begin(), bend = bounds.end();
|
||||
for (; bit != bend; ++bit) {
|
||||
expr* x = *bit;
|
||||
for (expr* x : bounds) {
|
||||
bool s1 = false, s2 = false;
|
||||
rational lo, hi;
|
||||
if (a.is_int(x) &&
|
||||
|
@ -197,9 +191,7 @@ public:
|
|||
g->update(i, new_curr, new_pr, g->dep(i));
|
||||
mark_rec(subfmls, new_curr);
|
||||
}
|
||||
expr_set::iterator it = m_01s->begin(), end = m_01s->end();
|
||||
for (; it != end; ++it) {
|
||||
expr* v = *it;
|
||||
for (expr* v : *m_01s) {
|
||||
if (subfmls.is_marked(v)) {
|
||||
g->assert_expr(a.mk_le(v, a.mk_numeral(rational(1), true)));
|
||||
g->assert_expr(a.mk_le(a.mk_numeral(rational(0), true), v));
|
||||
|
|
|
@ -188,15 +188,12 @@ class lia2pb_tactic : public tactic {
|
|||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
fail_if_proof_generation("lia2pb", g);
|
||||
m_produce_models = g->models_enabled();
|
||||
m_produce_unsat_cores = g->unsat_core_enabled();
|
||||
mc = 0; pc = 0; core = 0; result.reset();
|
||||
result.reset();
|
||||
tactic_report report("lia2pb", *g);
|
||||
m_bm.reset(); m_rw.reset(); m_new_deps.reset();
|
||||
|
||||
|
@ -223,10 +220,9 @@ class lia2pb_tactic : public tactic {
|
|||
if (!check_num_bits())
|
||||
throw tactic_exception("lia2pb failed, number of necessary bits exceeds specified threshold (use option :lia2pb-total-bits to increase threshold)");
|
||||
|
||||
generic_model_converter * gmc = 0;
|
||||
ref<generic_model_converter> gmc;
|
||||
if (m_produce_models) {
|
||||
gmc = alloc(generic_model_converter, m);
|
||||
mc = gmc;
|
||||
}
|
||||
|
||||
expr_ref zero(m);
|
||||
|
@ -296,6 +292,7 @@ class lia2pb_tactic : public tactic {
|
|||
g->update(idx, new_curr, new_pr, dep);
|
||||
}
|
||||
g->inc_depth();
|
||||
g->add(gmc.get());
|
||||
result.push_back(g.get());
|
||||
TRACE("lia2pb", g->display(tout););
|
||||
SASSERT(g->is_well_sorted());
|
||||
|
@ -330,12 +327,9 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
try {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
catch (rewriter_exception & ex) {
|
||||
throw tactic_exception(ex.msg());
|
||||
|
|
|
@ -440,19 +440,17 @@ public:
|
|||
\return false if transformation is not possible.
|
||||
*/
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
fail_if_proof_generation("nla2bv", g);
|
||||
fail_if_unsat_core_generation("nla2bv", g);
|
||||
mc = 0; pc = 0; core = 0; result.reset();
|
||||
|
||||
result.reset();
|
||||
|
||||
imp proc(g->m(), m_params);
|
||||
scoped_set_imp setter(*this, proc);
|
||||
model_converter_ref mc;
|
||||
proc(*(g.get()), mc);
|
||||
|
||||
g->add(mc.get());
|
||||
result.push_back(g.get());
|
||||
SASSERT(g->is_well_sorted());
|
||||
}
|
||||
|
|
|
@ -79,12 +79,7 @@ class normalize_bounds_tactic : public tactic {
|
|||
return false;
|
||||
}
|
||||
|
||||
void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
mc = 0; pc = 0; core = 0;
|
||||
void operator()(goal_ref const & in, goal_ref_buffer & result) {
|
||||
bool produce_models = in->models_enabled();
|
||||
bool produce_proofs = in->proofs_enabled();
|
||||
tactic_report report("normalize-bounds", *in);
|
||||
|
@ -100,16 +95,13 @@ class normalize_bounds_tactic : public tactic {
|
|||
generic_model_converter * gmc = 0;
|
||||
if (produce_models) {
|
||||
gmc = alloc(generic_model_converter, m);
|
||||
mc = gmc;
|
||||
in->add(gmc);
|
||||
}
|
||||
|
||||
unsigned num_norm_bounds = 0;
|
||||
expr_substitution subst(m);
|
||||
rational val;
|
||||
bound_manager::iterator it = m_bm.begin();
|
||||
bound_manager::iterator end = m_bm.end();
|
||||
for (; it != end; ++it) {
|
||||
expr * x = *it;
|
||||
for (expr * x : m_bm) {
|
||||
if (is_target(x, val)) {
|
||||
num_norm_bounds++;
|
||||
sort * s = m.get_sort(x);
|
||||
|
@ -171,12 +163,9 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
try {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
catch (rewriter_exception & ex) {
|
||||
throw tactic_exception(ex.msg());
|
||||
|
|
|
@ -27,17 +27,12 @@ pb2bv_model_converter::pb2bv_model_converter(ast_manager & _m) : m(_m) {
|
|||
|
||||
pb2bv_model_converter::pb2bv_model_converter(ast_manager & _m, obj_map<func_decl, expr*> const & c2bit, bound_manager const & bm):
|
||||
m(_m) {
|
||||
obj_map<func_decl, expr*>::iterator it = c2bit.begin();
|
||||
obj_map<func_decl, expr*>::iterator end = c2bit.end();
|
||||
for ( ; it != end; it++) {
|
||||
m_c2bit.push_back(func_decl_pair(it->m_key, to_app(it->m_value)->get_decl()));
|
||||
m.inc_ref(it->m_key);
|
||||
m.inc_ref(to_app(it->m_value)->get_decl());
|
||||
for (auto const& kv : c2bit) {
|
||||
m_c2bit.push_back(func_decl_pair(kv.m_key, to_app(kv.m_value)->get_decl()));
|
||||
m.inc_ref(kv.m_key);
|
||||
m.inc_ref(to_app(kv.m_value)->get_decl());
|
||||
}
|
||||
bound_manager::iterator it2 = bm.begin();
|
||||
bound_manager::iterator end2 = bm.end();
|
||||
for (; it2 != end2; ++it2) {
|
||||
expr * c = *it2;
|
||||
for (expr* c : bm) {
|
||||
SASSERT(is_uninterp_const(c));
|
||||
func_decl * d = to_app(c)->get_decl();
|
||||
if (!c2bit.contains(d)) {
|
||||
|
@ -49,53 +44,43 @@ pb2bv_model_converter::pb2bv_model_converter(ast_manager & _m, obj_map<func_decl
|
|||
}
|
||||
|
||||
pb2bv_model_converter::~pb2bv_model_converter() {
|
||||
svector<func_decl_pair>::const_iterator it = m_c2bit.begin();
|
||||
svector<func_decl_pair>::const_iterator end = m_c2bit.end();
|
||||
for (; it != end; ++it) {
|
||||
m.dec_ref(it->first);
|
||||
m.dec_ref(it->second);
|
||||
for (auto const& kv : m_c2bit) {
|
||||
m.dec_ref(kv.first);
|
||||
m.dec_ref(kv.second);
|
||||
}
|
||||
}
|
||||
|
||||
void pb2bv_model_converter::operator()(model_ref & md) {
|
||||
(*this)(md, 0);
|
||||
}
|
||||
|
||||
void pb2bv_model_converter::operator()(model_ref & md, unsigned goal_idx) {
|
||||
SASSERT(goal_idx == 0);
|
||||
void pb2bv_model_converter::operator()(model_ref & md) {
|
||||
TRACE("pb2bv", tout << "converting model:\n"; model_v2_pp(tout, *md); display(tout););
|
||||
arith_util a_util(m);
|
||||
|
||||
svector<func_decl_pair>::const_iterator it = m_c2bit.begin();
|
||||
svector<func_decl_pair>::const_iterator end = m_c2bit.end();
|
||||
for (; it != end; ++it) {
|
||||
if (it->second) {
|
||||
expr * val = md->get_const_interp(it->second);
|
||||
for (auto const& kv : m_c2bit) {
|
||||
if (kv.second) {
|
||||
expr * val = md->get_const_interp(kv.second);
|
||||
if (val == 0 || m.is_false(val)) {
|
||||
/* false's and don't cares get the integer 0 solution*/
|
||||
md->register_decl(it->first, a_util.mk_numeral(rational(0), true));
|
||||
md->register_decl(kv.first, a_util.mk_numeral(rational(0), true));
|
||||
}
|
||||
else {
|
||||
md->register_decl(it->first, a_util.mk_numeral(rational(1), true));
|
||||
md->register_decl(kv.first, a_util.mk_numeral(rational(1), true));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// it->first is a don't care.
|
||||
md->register_decl(it->first, a_util.mk_numeral(rational(0), true));
|
||||
// kv.first is a don't care.
|
||||
md->register_decl(kv.first, a_util.mk_numeral(rational(0), true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pb2bv_model_converter::display(std::ostream & out) {
|
||||
out << "(pb2bv-model-converter";
|
||||
svector<func_decl_pair>::const_iterator it = m_c2bit.begin();
|
||||
svector<func_decl_pair>::const_iterator end = m_c2bit.end();
|
||||
for (; it != end; ++it) {
|
||||
out << "\n (" << it->first->get_name() << " ";
|
||||
if (it->second == 0)
|
||||
for (auto const& kv : m_c2bit) {
|
||||
out << "\n (" << kv.first->get_name() << " ";
|
||||
if (kv.second == 0)
|
||||
out << "0";
|
||||
else
|
||||
out << it->second->get_name();
|
||||
out << kv.second->get_name();
|
||||
out << ")";
|
||||
}
|
||||
out << ")\n";
|
||||
|
@ -104,11 +89,9 @@ void pb2bv_model_converter::display(std::ostream & out) {
|
|||
model_converter * pb2bv_model_converter::translate(ast_translation & translator) {
|
||||
ast_manager & to = translator.to();
|
||||
pb2bv_model_converter * res = alloc(pb2bv_model_converter, to);
|
||||
svector<func_decl_pair>::iterator it = m_c2bit.begin();
|
||||
svector<func_decl_pair>::iterator end = m_c2bit.end();
|
||||
for (; it != end; it++) {
|
||||
func_decl * f1 = translator(it->first);
|
||||
func_decl * f2 = translator(it->second);
|
||||
for (auto const& kv : m_c2bit) {
|
||||
func_decl * f1 = translator(kv.first);
|
||||
func_decl * f2 = translator(kv.second);
|
||||
res->m_c2bit.push_back(func_decl_pair(f1, f2));
|
||||
to.inc_ref(f1);
|
||||
to.inc_ref(f2);
|
||||
|
|
|
@ -31,10 +31,9 @@ public:
|
|||
pb2bv_model_converter(ast_manager & _m);
|
||||
pb2bv_model_converter(ast_manager & _m, obj_map<func_decl, expr*> const & c2bit, bound_manager const & bm);
|
||||
virtual ~pb2bv_model_converter();
|
||||
virtual void operator()(model_ref & md);
|
||||
virtual void operator()(model_ref & md, unsigned goal_idx);
|
||||
virtual void display(std::ostream & out);
|
||||
virtual model_converter * translate(ast_translation & translator);
|
||||
void operator()(model_ref & md) override;
|
||||
void display(std::ostream & out) override;
|
||||
model_converter * translate(ast_translation & translator) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -886,16 +886,13 @@ private:
|
|||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
TRACE("pb2bv", g->display(tout););
|
||||
SASSERT(g->is_well_sorted());
|
||||
fail_if_proof_generation("pb2bv", g);
|
||||
m_produce_models = g->models_enabled();
|
||||
m_produce_unsat_cores = g->unsat_core_enabled();
|
||||
mc = 0; pc = 0; core = 0; result.reset();
|
||||
result.reset();
|
||||
tactic_report report("pb2bv", *g);
|
||||
m_bm.reset(); m_rw.reset(); m_new_deps.reset();
|
||||
|
||||
|
@ -949,6 +946,7 @@ private:
|
|||
g->update(idx, new_exprs[idx].get(), 0, (m_produce_unsat_cores) ? new_deps[idx].get() : g->dep(idx));
|
||||
|
||||
if (m_produce_models) {
|
||||
model_converter_ref mc;
|
||||
generic_model_converter * mc1 = alloc(generic_model_converter, m);
|
||||
for (auto const& kv : m_const2bit)
|
||||
mc1->hide(kv.m_value);
|
||||
|
@ -957,7 +955,8 @@ private:
|
|||
for (unsigned i = 0; i < num_temps; i++)
|
||||
mc1->hide(m_temporary_ints.get(i));
|
||||
pb2bv_model_converter * mc2 = alloc(pb2bv_model_converter, m, m_const2bit, m_bm);
|
||||
mc = concat(mc1, mc2);
|
||||
mc = concat(mc1, mc2);
|
||||
g->add(mc.get());
|
||||
}
|
||||
|
||||
g->inc_depth();
|
||||
|
@ -999,11 +998,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
virtual void updt_params(params_ref const & p);
|
||||
virtual void collect_param_descrs(param_descrs & r) {}
|
||||
|
||||
virtual void operator()(goal_ref const & g, goal_ref_buffer & result, model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core);
|
||||
virtual void operator()(goal_ref const & g, goal_ref_buffer & result);
|
||||
|
||||
virtual void cleanup();
|
||||
};
|
||||
|
@ -527,14 +527,11 @@ void propagate_ineqs_tactic::updt_params(params_ref const & p) {
|
|||
}
|
||||
|
||||
void propagate_ineqs_tactic::operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
fail_if_proof_generation("propagate-ineqs", g);
|
||||
fail_if_unsat_core_generation("propagate-ineqs", g);
|
||||
mc = 0; pc = 0; core = 0; result.reset();
|
||||
result.reset();
|
||||
goal_ref r;
|
||||
(*m_imp)(g.get(), r);
|
||||
result.push_back(r.get());
|
||||
|
|
|
@ -821,13 +821,9 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
try {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
tactic_report report("purify-arith", *g);
|
||||
TRACE("purify_arith", g->display(tout););
|
||||
bool produce_proofs = g->proofs_enabled();
|
||||
|
@ -835,10 +831,10 @@ public:
|
|||
bool elim_root_objs = m_params.get_bool("elim_root_objects", true);
|
||||
bool elim_inverses = m_params.get_bool("elim_inverses", true);
|
||||
bool complete = m_params.get_bool("complete", true);
|
||||
purify_arith_proc proc(*(g.get()), m_util, produce_proofs, elim_root_objs, elim_inverses, complete);
|
||||
|
||||
purify_arith_proc proc(*(g.get()), m_util, produce_proofs, elim_root_objs, elim_inverses, complete);
|
||||
model_converter_ref mc;
|
||||
proc(mc, produce_models);
|
||||
|
||||
g->add(mc.get());
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
TRACE("purify_arith", g->display(tout););
|
||||
|
|
|
@ -292,15 +292,12 @@ class recover_01_tactic : public tactic {
|
|||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
fail_if_proof_generation("recover-01", g);
|
||||
fail_if_unsat_core_generation("recover-01", g);
|
||||
m_produce_models = g->models_enabled();
|
||||
mc = 0; pc = 0; core = 0; result.reset();
|
||||
result.reset();
|
||||
tactic_report report("recover-01", *g);
|
||||
|
||||
bool saved = false;
|
||||
|
@ -308,7 +305,9 @@ class recover_01_tactic : public tactic {
|
|||
SASSERT(new_goal->depth() == g->depth());
|
||||
SASSERT(new_goal->prec() == g->prec());
|
||||
new_goal->inc_depth();
|
||||
|
||||
new_goal->add(g->mc());
|
||||
new_goal->add(g->pc());
|
||||
|
||||
unsigned sz = g->size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
expr * f = g->form(i);
|
||||
|
@ -327,7 +326,7 @@ class recover_01_tactic : public tactic {
|
|||
|
||||
if (m_produce_models) {
|
||||
gmc = alloc(generic_model_converter, m);
|
||||
mc = gmc;
|
||||
new_goal->add(gmc);
|
||||
}
|
||||
|
||||
dec_ref_key_values(m, bool2int);
|
||||
|
@ -336,25 +335,20 @@ class recover_01_tactic : public tactic {
|
|||
bool recovered = false;
|
||||
expr_substitution _subst(m);
|
||||
subst = &_subst;
|
||||
var2clauses::iterator it = m_var2clauses.begin();
|
||||
var2clauses::iterator end = m_var2clauses.end();
|
||||
for (; it != end; ++it) {
|
||||
if (process(it->m_key, it->m_value)) {
|
||||
for (auto& kv : m_var2clauses) {
|
||||
if (process(kv.m_key, kv.m_value)) {
|
||||
recovered = true;
|
||||
counter++;
|
||||
}
|
||||
else {
|
||||
ptr_vector<app>::iterator it2 = it->m_value.begin();
|
||||
ptr_vector<app>::iterator end2 = it->m_value.end();
|
||||
for (; it2 != end2; ++it2) {
|
||||
new_goal->assert_expr(*it2);
|
||||
for (app* a : kv.m_value) {
|
||||
new_goal->assert_expr(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!recovered) {
|
||||
result.push_back(g.get());
|
||||
mc = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -406,12 +400,9 @@ public:
|
|||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
try {
|
||||
(*m_imp)(g, result, mc, pc, core);
|
||||
(*m_imp)(g, result);
|
||||
}
|
||||
catch (rewriter_exception & ex) {
|
||||
throw tactic_exception(ex.msg());
|
||||
|
|
|
@ -172,8 +172,7 @@ struct bit_blaster_model_converter : public model_converter {
|
|||
return result;
|
||||
}
|
||||
|
||||
void operator()(model_ref & md, unsigned goal_idx) override {
|
||||
SASSERT(goal_idx == 0);
|
||||
void operator()(model_ref & md) override {
|
||||
model * new_model = alloc(model, m());
|
||||
obj_hashtable<func_decl> bits;
|
||||
collect_bits(bits);
|
||||
|
@ -182,10 +181,6 @@ struct bit_blaster_model_converter : public model_converter {
|
|||
md = new_model;
|
||||
}
|
||||
|
||||
void operator()(model_ref & md) override {
|
||||
operator()(md, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief simplisic expansion operator for formulas.
|
||||
It just adds back bit-vector definitions to the formula whether they are used or not.
|
||||
|
|
|
@ -51,11 +51,7 @@ class bit_blaster_tactic : public tactic {
|
|||
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
mc = 0; pc = 0; core = 0;
|
||||
goal_ref_buffer & result) {
|
||||
bool proofs_enabled = g->proofs_enabled();
|
||||
|
||||
if (proofs_enabled && m_blast_quant)
|
||||
|
@ -88,12 +84,10 @@ class bit_blaster_tactic : public tactic {
|
|||
}
|
||||
|
||||
if (change && g->models_enabled())
|
||||
mc = mk_bit_blaster_model_converter(m(), m_rewriter->const2bits());
|
||||
else
|
||||
mc = 0;
|
||||
g->add(mk_bit_blaster_model_converter(m(), m_rewriter->const2bits()));
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
TRACE("after_bit_blaster", g->display(tout); if (mc) mc->display(tout); tout << "\n";);
|
||||
TRACE("after_bit_blaster", g->display(tout); if (g->mc()) g->mc()->display(tout); tout << "\n";);
|
||||
m_rewriter->cleanup();
|
||||
}
|
||||
|
||||
|
@ -135,12 +129,9 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
try {
|
||||
(*m_imp)(g, result, mc, pc, core);
|
||||
(*m_imp)(g, result);
|
||||
}
|
||||
catch (rewriter_exception & ex) {
|
||||
throw tactic_exception(ex.msg());
|
||||
|
|
|
@ -379,11 +379,7 @@ class bv1_blaster_tactic : public tactic {
|
|||
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
mc = 0; pc = 0; core = 0;
|
||||
goal_ref_buffer & result) {
|
||||
|
||||
if (!is_target(*g))
|
||||
throw tactic_exception("bv1 blaster cannot be applied to goal");
|
||||
|
@ -409,7 +405,7 @@ class bv1_blaster_tactic : public tactic {
|
|||
}
|
||||
|
||||
if (g->models_enabled())
|
||||
mc = mk_bv1_blaster_model_converter(m(), m_rw.cfg().m_const2bits);
|
||||
g->add(mk_bv1_blaster_model_converter(m(), m_rw.cfg().m_const2bits));
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
m_rw.cfg().cleanup();
|
||||
|
@ -455,11 +451,8 @@ public:
|
|||
Return a model_converter that converts any model for the updated set into a model for the old set.
|
||||
*/
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(g, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(g, result);
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
|
|
|
@ -136,11 +136,7 @@ class bv_bound_chk_tactic : public tactic {
|
|||
public:
|
||||
bv_bound_chk_tactic(ast_manager & m, params_ref const & p);
|
||||
virtual ~bv_bound_chk_tactic();
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core);
|
||||
void operator()(goal_ref const & g, goal_ref_buffer & result) override;
|
||||
virtual tactic * translate(ast_manager & m);
|
||||
virtual void updt_params(params_ref const & p);
|
||||
void cleanup();
|
||||
|
@ -197,16 +193,12 @@ bv_bound_chk_tactic::~bv_bound_chk_tactic() {
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
void bv_bound_chk_tactic::operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void bv_bound_chk_tactic::operator()(goal_ref const & g, goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
fail_if_proof_generation("bv-bound-chk", g);
|
||||
fail_if_unsat_core_generation("bv-bound-chk", g);
|
||||
TRACE("bv-bound-chk", g->display(tout << "before:"); tout << std::endl;);
|
||||
mc = 0; pc = 0; core = 0; result.reset();
|
||||
result.reset();
|
||||
m_imp->operator()(g);
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
|
||||
virtual ~bv_size_reduction_tactic();
|
||||
|
||||
virtual void operator()(goal_ref const & g, goal_ref_buffer & result, model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core);
|
||||
virtual void operator()(goal_ref const & g, goal_ref_buffer & result);
|
||||
|
||||
virtual void cleanup();
|
||||
};
|
||||
|
@ -382,16 +382,15 @@ bv_size_reduction_tactic::~bv_size_reduction_tactic() {
|
|||
}
|
||||
|
||||
void bv_size_reduction_tactic::operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
fail_if_proof_generation("bv-size-reduction", g);
|
||||
fail_if_unsat_core_generation("bv-size-reduction", g);
|
||||
mc = 0; pc = 0; core = 0; result.reset();
|
||||
result.reset();
|
||||
model_converter_ref mc;
|
||||
m_imp->operator()(*(g.get()), mc);
|
||||
g->inc_depth();
|
||||
g->add(mc.get());
|
||||
result.push_back(g.get());
|
||||
SASSERT(g->is_well_sorted());
|
||||
}
|
||||
|
|
|
@ -53,18 +53,16 @@ class bvarray2uf_tactic : public tactic {
|
|||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core)
|
||||
goal_ref_buffer & result)
|
||||
{
|
||||
SASSERT(g->is_well_sorted());
|
||||
tactic_report report("bvarray2uf", *g);
|
||||
mc = 0; pc = 0; core = 0; result.reset();
|
||||
result.reset();
|
||||
fail_if_unsat_core_generation("bvarray2uf", g);
|
||||
|
||||
TRACE("bvarray2uf", tout << "Before: " << std::endl; g->display(tout); );
|
||||
m_produce_models = g->models_enabled();
|
||||
model_converter_ref mc;
|
||||
|
||||
if (m_produce_models) {
|
||||
generic_model_converter * fmc = alloc(generic_model_converter, m_manager);
|
||||
|
@ -93,6 +91,7 @@ class bvarray2uf_tactic : public tactic {
|
|||
g->assert_expr(m_rw.m_cfg.extra_assertions[i].get());
|
||||
|
||||
g->inc_depth();
|
||||
g->add(mc.get());
|
||||
result.push_back(g.get());
|
||||
TRACE("bvarray2uf", tout << "After: " << std::endl; g->display(tout););
|
||||
SASSERT(g->is_well_sorted());
|
||||
|
@ -129,11 +128,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
|
|
|
@ -116,12 +116,7 @@ public:
|
|||
virtual void collect_param_descrs(param_descrs & r) {
|
||||
}
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
mc = 0; pc = 0; core = 0;
|
||||
virtual void operator()(goal_ref const & g, goal_ref_buffer & result) {
|
||||
bool produce_proofs = g->proofs_enabled();
|
||||
tactic_report report("dt2bv", *g);
|
||||
unsigned size = g->size();
|
||||
|
@ -155,7 +150,7 @@ public:
|
|||
for (auto const& kv : rw.enum2def())
|
||||
filter->add(kv.m_key, kv.m_value);
|
||||
|
||||
mc = filter.get();
|
||||
g->add(filter.get());
|
||||
report_tactic_progress(":fd-num-translated", rw.num_translated());
|
||||
}
|
||||
g->inc_depth();
|
||||
|
|
|
@ -224,13 +224,8 @@ class elim_small_bv_tactic : public tactic {
|
|||
m_rw.cfg().updt_params(p);
|
||||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & g, goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
tactic_report report("elim-small-bv", *g);
|
||||
bool produce_proofs = g->proofs_enabled();
|
||||
fail_if_proof_generation("elim-small-bv", g);
|
||||
|
@ -250,7 +245,7 @@ class elim_small_bv_tactic : public tactic {
|
|||
}
|
||||
g->update(idx, new_curr, new_pr, g->dep(idx));
|
||||
}
|
||||
mc = m_rw.m_cfg.m_mc.get();
|
||||
g->add(m_rw.m_cfg.m_mc.get());
|
||||
|
||||
report_tactic_progress(":elim-small-bv-num-eliminated", m_rw.m_cfg.m_num_eliminated);
|
||||
g->inc_depth();
|
||||
|
@ -288,11 +283,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
|
|
|
@ -237,12 +237,8 @@ class max_bv_sharing_tactic : public tactic {
|
|||
ast_manager & m() const { return m_rw.m(); }
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
tactic_report report("max-bv-sharing", *g);
|
||||
bool produce_proofs = g->proofs_enabled();
|
||||
|
||||
|
@ -299,11 +295,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
|
|
|
@ -113,13 +113,8 @@ class blast_term_ite_tactic : public tactic {
|
|||
m_rw.cfg().updt_params(p);
|
||||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & g, goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
tactic_report report("blast-term-ite", *g);
|
||||
bool produce_proofs = g->proofs_enabled();
|
||||
|
||||
|
@ -172,11 +167,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
|
|
|
@ -54,16 +54,11 @@ public:
|
|||
virtual void updt_params(params_ref const & p) { m_params = p; m_elim_ite.updt_params(p); }
|
||||
virtual void collect_param_descrs(param_descrs & r) { m_elim_ite.collect_param_descrs(r); }
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & g, goal_ref_buffer& result) override {
|
||||
SASSERT(g->is_well_sorted());
|
||||
fail_if_proof_generation("cofactor-term-ite", g);
|
||||
fail_if_unsat_core_generation("cofactor-term-ite", g);
|
||||
tactic_report report("cofactor-term-ite", *g);
|
||||
mc = 0; pc = 0; core = 0;
|
||||
process(*(g.get()));
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
|
|
|
@ -63,10 +63,7 @@ public:
|
|||
|
||||
virtual void collect_param_descrs(param_descrs & r) {}
|
||||
|
||||
virtual void operator()(goal_ref const & g, goal_ref_buffer & result,
|
||||
model_converter_ref & mc, proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
mc = 0;
|
||||
virtual void operator()(goal_ref const & g, goal_ref_buffer & result) {
|
||||
tactic_report report("collect-statistics", *g);
|
||||
|
||||
collect_proc cp(m, m_stats);
|
||||
|
@ -76,10 +73,8 @@ public:
|
|||
for_each_expr(cp, visited, g->form(i));
|
||||
|
||||
std::cout << "(" << std::endl;
|
||||
stats_type::iterator it = m_stats.begin();
|
||||
stats_type::iterator end = m_stats.end();
|
||||
for (; it != end; it++)
|
||||
std::cout << " :" << it->first << " " << it->second << std::endl;
|
||||
for (auto const& kv : m_stats)
|
||||
std::cout << " :" << kv.first << " " << kv.second << std::endl;
|
||||
std::cout << ")" << std::endl;
|
||||
|
||||
g->inc_depth();
|
||||
|
|
|
@ -621,11 +621,7 @@ void ctx_simplify_tactic::get_param_descrs(param_descrs & r) {
|
|||
}
|
||||
|
||||
void ctx_simplify_tactic::operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
mc = 0; pc = 0; core = 0;
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(*(in.get()));
|
||||
in->inc_depth();
|
||||
result.push_back(in.get());
|
||||
|
|
|
@ -55,10 +55,7 @@ public:
|
|||
virtual void collect_param_descrs(param_descrs & r) { get_param_descrs(r); }
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core);
|
||||
goal_ref_buffer & result);
|
||||
|
||||
virtual void cleanup();
|
||||
};
|
||||
|
|
|
@ -74,11 +74,7 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
mc = 0; pc = 0; core = 0;
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(*(in.get()));
|
||||
in->inc_depth();
|
||||
result.push_back(in.get());
|
||||
|
|
|
@ -100,16 +100,13 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
ast_manager & m = g->m();
|
||||
bool produce_proofs = g->proofs_enabled();
|
||||
rw r(m, produce_proofs);
|
||||
m_rw = &r;
|
||||
mc = 0; pc = 0; core = 0; result.reset();
|
||||
result.reset();
|
||||
tactic_report report("distribute-forall", *g);
|
||||
|
||||
expr_ref new_curr(m);
|
||||
|
|
|
@ -183,19 +183,11 @@ tactic * dom_simplify_tactic::translate(ast_manager & m) {
|
|||
return alloc(dom_simplify_tactic, m, m_simplifier->translate(m), m_params);
|
||||
}
|
||||
|
||||
void dom_simplify_tactic::operator()(
|
||||
goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
mc = 0; pc = 0; core = 0;
|
||||
|
||||
void dom_simplify_tactic::operator()(goal_ref const & in, goal_ref_buffer & result) {
|
||||
tactic_report report("dom-simplify", *in.get());
|
||||
simplify_goal(*(in.get()));
|
||||
in->inc_depth();
|
||||
result.push_back(in.get());
|
||||
|
||||
}
|
||||
|
||||
void dom_simplify_tactic::cleanup() {
|
||||
|
|
|
@ -137,11 +137,7 @@ public:
|
|||
static void get_param_descrs(param_descrs & r) {}
|
||||
virtual void collect_param_descrs(param_descrs & r) { get_param_descrs(r); }
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core);
|
||||
void operator()(goal_ref const & in, goal_ref_buffer & result) override;
|
||||
|
||||
virtual void cleanup();
|
||||
};
|
||||
|
|
|
@ -100,12 +100,8 @@ class elim_term_ite_tactic : public tactic {
|
|||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
tactic_report report("elim-term-ite", *g);
|
||||
bool produce_proofs = g->proofs_enabled();
|
||||
m_rw.cfg().m_produce_models = g->models_enabled();
|
||||
|
@ -124,7 +120,7 @@ class elim_term_ite_tactic : public tactic {
|
|||
}
|
||||
g->update(idx, new_curr, new_pr, g->dep(idx));
|
||||
}
|
||||
mc = m_rw.m_cfg.m_mc.get();
|
||||
g->add(m_rw.m_cfg.m_mc.get());
|
||||
report_tactic_progress(":elim-term-ite-consts", m_rw.m_cfg.m_num_fresh);
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
|
@ -162,11 +158,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
|
|
|
@ -816,11 +816,7 @@ class elim_uncnstr_tactic : public tactic {
|
|||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
mc = 0; pc = 0; core = 0;
|
||||
goal_ref_buffer & result) {
|
||||
bool produce_models = g->models_enabled();
|
||||
bool produce_proofs = g->proofs_enabled();
|
||||
|
||||
|
@ -865,8 +861,7 @@ class elim_uncnstr_tactic : public tactic {
|
|||
g->update(idx, new_f, new_pr, g->dep(idx));
|
||||
}
|
||||
if (!modified) {
|
||||
if (round == 0) {
|
||||
mc = 0;
|
||||
if (round == 0) {
|
||||
}
|
||||
else {
|
||||
app_ref_vector & fresh_vars = m_rw->cfg().m_fresh_vars;
|
||||
|
@ -875,15 +870,14 @@ class elim_uncnstr_tactic : public tactic {
|
|||
generic_model_converter * fmc = alloc(generic_model_converter, m());
|
||||
for (app * f : fresh_vars)
|
||||
fmc->hide(f);
|
||||
mc = concat(fmc, m_mc.get());
|
||||
g->add(concat(fmc, m_mc.get()));
|
||||
}
|
||||
else {
|
||||
mc = 0;
|
||||
g->set((model_converter*)nullptr);
|
||||
}
|
||||
}
|
||||
m_mc = 0;
|
||||
m_rw = 0;
|
||||
TRACE("elim_uncnstr", if (mc) mc->display(tout););
|
||||
result.push_back(g.get());
|
||||
g->inc_depth();
|
||||
return;
|
||||
|
@ -933,11 +927,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(g, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(g, result);
|
||||
report_tactic_progress(":num-elim-apps", get_num_elim_apps());
|
||||
}
|
||||
|
||||
|
|
|
@ -144,12 +144,8 @@ class injectivity_tactic : public tactic {
|
|||
}
|
||||
|
||||
void operator()(goal_ref const & goal,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(goal->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
tactic_report report("injectivity", *goal);
|
||||
fail_if_unsat_core_generation("injectivity", goal); // TODO: Support UNSAT cores
|
||||
fail_if_proof_generation("injectivity", goal);
|
||||
|
@ -271,11 +267,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_finder)(g, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_finder)(g, result);
|
||||
|
||||
for (unsigned i = 0; i < g->size(); ++i) {
|
||||
expr* curr = g->form(i);
|
||||
|
|
|
@ -54,13 +54,9 @@ public:
|
|||
virtual void collect_param_descrs(param_descrs & r) { nnf::get_param_descrs(r); }
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
TRACE("nnf", tout << "params: " << m_params << "\n"; g->display(tout););
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
tactic_report report("nnf", *g);
|
||||
bool produce_proofs = g->proofs_enabled();
|
||||
|
||||
|
@ -98,7 +94,7 @@ public:
|
|||
unsigned num_extra_names = dnames.get_num_names();
|
||||
if (num_extra_names > 0) {
|
||||
generic_model_converter * fmc = alloc(generic_model_converter, m);
|
||||
mc = fmc;
|
||||
g->add(fmc);
|
||||
for (unsigned i = 0; i < num_extra_names; i++)
|
||||
fmc->hide(dnames.get_name_decl(i));
|
||||
}
|
||||
|
|
|
@ -128,13 +128,9 @@ class occf_tactic : public tactic {
|
|||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
|
||||
|
||||
fail_if_proof_generation("occf", g);
|
||||
|
||||
bool produce_models = g->models_enabled();
|
||||
|
@ -158,7 +154,7 @@ class occf_tactic : public tactic {
|
|||
continue;
|
||||
if (produce_models && !m_mc) {
|
||||
m_mc = alloc(generic_model_converter, m);
|
||||
mc = m_mc;
|
||||
g->add(m_mc);
|
||||
}
|
||||
expr * keep = 0;
|
||||
new_lits.reset();
|
||||
|
@ -211,11 +207,8 @@ public:
|
|||
virtual void collect_param_descrs(param_descrs & r) {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
|
|
|
@ -48,8 +48,7 @@ class pb_preproc_model_converter : public model_converter {
|
|||
public:
|
||||
pb_preproc_model_converter(ast_manager& m):m(m), pb(m), m_refs(m) {}
|
||||
|
||||
virtual void operator()(model_ref & mdl, unsigned goal_idx) {
|
||||
SASSERT(goal_idx == 0);
|
||||
virtual void operator()(model_ref & mdl) {
|
||||
for (auto const& kv : m_const) {
|
||||
mdl->register_decl(kv.first->get_decl(), kv.second);
|
||||
}
|
||||
|
@ -148,21 +147,17 @@ public:
|
|||
return alloc(pb_preprocess_tactic, m);
|
||||
}
|
||||
|
||||
virtual void operator()(
|
||||
void operator()(
|
||||
goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) override {
|
||||
SASSERT(g->is_well_sorted());
|
||||
pc = 0; core = 0;
|
||||
|
||||
if (g->proofs_enabled()) {
|
||||
throw tactic_exception("pb-preprocess does not support proofs");
|
||||
}
|
||||
|
||||
pb_preproc_model_converter* pp = alloc(pb_preproc_model_converter, m);
|
||||
mc = pp;
|
||||
g->add(pp);
|
||||
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
|
|
|
@ -136,12 +136,8 @@ class propagate_values_tactic : public tactic {
|
|||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
tactic_report report("propagate-values", *g);
|
||||
m_goal = g.get();
|
||||
|
||||
|
@ -240,13 +236,9 @@ public:
|
|||
r.insert("max_rounds", CPK_UINT, "(default: 2) maximum number of rounds.");
|
||||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & in, goal_ref_buffer & result) override {
|
||||
try {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
catch (rewriter_exception & ex) {
|
||||
throw tactic_exception(ex.msg());
|
||||
|
|
|
@ -73,8 +73,8 @@ public:
|
|||
|
||||
virtual ~reduce_args_tactic();
|
||||
|
||||
virtual void operator()(goal_ref const & g, goal_ref_buffer & result, model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core);
|
||||
virtual void cleanup();
|
||||
void operator()(goal_ref const & g, goal_ref_buffer & result) override;
|
||||
void cleanup() override;
|
||||
};
|
||||
|
||||
tactic * mk_reduce_args_tactic(ast_manager & m, params_ref const & p) {
|
||||
|
@ -439,7 +439,7 @@ struct reduce_args_tactic::imp {
|
|||
return f_mc;
|
||||
}
|
||||
|
||||
void operator()(goal & g, model_converter_ref & mc) {
|
||||
void operator()(goal & g) {
|
||||
if (g.inconsistent())
|
||||
return;
|
||||
TRACE("reduce_args", g.display(tout););
|
||||
|
@ -468,9 +468,9 @@ struct reduce_args_tactic::imp {
|
|||
report_tactic_progress(":reduced-funcs", decl2args.size());
|
||||
|
||||
if (g.models_enabled())
|
||||
mc = mk_mc(decl2args, ctx.m_decl2arg2funcs);
|
||||
g.add(mk_mc(decl2args, ctx.m_decl2arg2funcs));
|
||||
|
||||
TRACE("reduce_args", g.display(tout); if (mc) mc->display(tout););
|
||||
TRACE("reduce_args", g.display(tout); if (g.mc()) g.mc()->display(tout););
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -483,15 +483,12 @@ reduce_args_tactic::~reduce_args_tactic() {
|
|||
}
|
||||
|
||||
void reduce_args_tactic::operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
fail_if_proof_generation("reduce-args", g);
|
||||
fail_if_unsat_core_generation("reduce-args", g);
|
||||
mc = 0; pc = 0; core = 0; result.reset();
|
||||
m_imp->operator()(*(g.get()), mc);
|
||||
result.reset();
|
||||
m_imp->operator()(*(g.get()));
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
SASSERT(g->is_well_sorted());
|
||||
|
|
|
@ -93,15 +93,11 @@ void simplify_tactic::get_param_descrs(param_descrs & r) {
|
|||
}
|
||||
|
||||
void simplify_tactic::operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
try {
|
||||
(*m_imp)(*(in.get()));
|
||||
in->inc_depth();
|
||||
result.push_back(in.get());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
}
|
||||
catch (rewriter_exception & ex) {
|
||||
throw tactic_exception(ex.msg());
|
||||
|
|
|
@ -30,21 +30,19 @@ public:
|
|||
simplify_tactic(ast_manager & m, params_ref const & ref = params_ref());
|
||||
virtual ~simplify_tactic();
|
||||
|
||||
virtual void updt_params(params_ref const & p);
|
||||
void updt_params(params_ref const & p) override;
|
||||
|
||||
static void get_param_descrs(param_descrs & r);
|
||||
virtual void collect_param_descrs(param_descrs & r) { get_param_descrs(r); }
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core);
|
||||
void collect_param_descrs(param_descrs & r) override { get_param_descrs(r); }
|
||||
|
||||
virtual void cleanup();
|
||||
void operator()(goal_ref const & in, goal_ref_buffer & result) override;
|
||||
|
||||
void cleanup() override;
|
||||
|
||||
unsigned get_num_steps() const;
|
||||
|
||||
virtual tactic * translate(ast_manager & m) { return alloc(simplify_tactic, m, m_params); }
|
||||
tactic * translate(ast_manager & m) override { return alloc(simplify_tactic, m, m_params); }
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -666,13 +666,9 @@ class solve_eqs_tactic : public tactic {
|
|||
return m_num_eliminated_vars;
|
||||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & g, goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
model_converter_ref mc;
|
||||
tactic_report report("solve_eqs", *g);
|
||||
m_produce_models = g->models_enabled();
|
||||
m_produce_proofs = g->proofs_enabled();
|
||||
|
@ -692,7 +688,6 @@ class solve_eqs_tactic : public tactic {
|
|||
normalize();
|
||||
substitute(*(g.get()));
|
||||
if (g->inconsistent()) {
|
||||
mc = 0;
|
||||
break;
|
||||
}
|
||||
save_elim_vars(mc);
|
||||
|
@ -700,6 +695,7 @@ class solve_eqs_tactic : public tactic {
|
|||
}
|
||||
}
|
||||
g->inc_depth();
|
||||
g->add(mc.get());
|
||||
result.push_back(g.get());
|
||||
TRACE("solve_eqs", g->display(tout););
|
||||
SASSERT(g->is_well_sorted());
|
||||
|
@ -733,12 +729,9 @@ public:
|
|||
r.insert("ite_solver", CPK_BOOL, "(default: true) use if-then-else solver.");
|
||||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result) override {
|
||||
(*m_imp)(in, result);
|
||||
report_tactic_progress(":num-elim-vars", m_imp->get_num_eliminated_vars());
|
||||
}
|
||||
|
||||
|
|
|
@ -46,21 +46,16 @@ class split_clause_tactic : public tactic {
|
|||
}
|
||||
|
||||
class split_pc : public proof_converter {
|
||||
ast_manager & m_manager;
|
||||
app * m_clause;
|
||||
proof * m_clause_pr;
|
||||
ast_manager & m;
|
||||
app_ref m_clause;
|
||||
proof_ref m_clause_pr;
|
||||
public:
|
||||
split_pc(ast_manager & m, app * cls, proof * pr):m_manager(m), m_clause(cls), m_clause_pr(pr) {
|
||||
m.inc_ref(cls);
|
||||
m.inc_ref(pr);
|
||||
split_pc(ast_manager & m, app * cls, proof * pr):m(m), m_clause(cls, m), m_clause_pr(pr, m) {
|
||||
}
|
||||
|
||||
~split_pc() {
|
||||
m_manager.dec_ref(m_clause);
|
||||
m_manager.dec_ref(m_clause_pr);
|
||||
}
|
||||
virtual ~split_pc() { }
|
||||
|
||||
virtual void operator()(ast_manager & m, unsigned num_source, proof * const * source, proof_ref & result) {
|
||||
proof_ref operator()(ast_manager & m, unsigned num_source, proof * const * source) override {
|
||||
// Let m_clause be of the form (l_0 or ... or l_{num_source - 1})
|
||||
// Each source[i] proof is a proof for "false" using l_i as a hypothesis
|
||||
// So, I use lemma for producing a proof for (not l_i) that does not contain the hypothesis,
|
||||
|
@ -73,14 +68,14 @@ class split_clause_tactic : public tactic {
|
|||
expr * not_li = m.mk_not(m_clause->get_arg(i));
|
||||
prs.push_back(m.mk_lemma(pr_i, not_li));
|
||||
}
|
||||
result = m.mk_unit_resolution(prs.size(), prs.c_ptr());
|
||||
return proof_ref(m.mk_unit_resolution(prs.size(), prs.c_ptr()), m);
|
||||
}
|
||||
|
||||
virtual proof_converter * translate(ast_translation & translator) {
|
||||
return alloc(split_pc, translator.to(), translator(m_clause), translator(m_clause_pr));
|
||||
proof_converter * translate(ast_translation & translator) override {
|
||||
return alloc(split_pc, translator.to(), translator(m_clause.get()), translator(m_clause_pr.get()));
|
||||
}
|
||||
|
||||
virtual void display(std::ostream & out) { out << "(split-clause-pc)\n"; }
|
||||
void display(std::ostream & out) override { out << "(split-clause-pc)\n"; }
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -97,23 +92,19 @@ public:
|
|||
virtual ~split_clause_tactic() {
|
||||
}
|
||||
|
||||
virtual void updt_params(params_ref const & p) {
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_largest_clause = p.get_bool("split_largest_clause", false);
|
||||
}
|
||||
|
||||
virtual void collect_param_descrs(param_descrs & r) {
|
||||
void collect_param_descrs(param_descrs & r) override {
|
||||
r.insert("split_largest_clause", CPK_BOOL, "(default: false) split the largest clause in the goal.");
|
||||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result) override {
|
||||
SASSERT(in->is_well_sorted());
|
||||
tactic_report report("split-clause", *in);
|
||||
TRACE("before_split_clause", in->display(tout););
|
||||
pc = 0; mc = 0; core = 0;
|
||||
ast_manager & m = in->m();
|
||||
unsigned cls_pos = select_clause(m, in);
|
||||
if (cls_pos == UINT_MAX) {
|
||||
|
@ -123,16 +114,11 @@ public:
|
|||
app * cls = to_app(in->form(cls_pos));
|
||||
expr_dependency * cls_dep = in->dep(cls_pos);
|
||||
if (produce_proofs)
|
||||
pc = alloc(split_pc, m, cls, in->pr(cls_pos));
|
||||
unsigned cls_sz = cls->get_num_args();
|
||||
report_tactic_progress(":num-new-branches", cls_sz);
|
||||
for (unsigned i = 0; i < cls_sz; i++) {
|
||||
goal * subgoal_i;
|
||||
if (i == cls_sz - 1)
|
||||
subgoal_i = in.get();
|
||||
else
|
||||
subgoal_i = alloc(goal, *in);
|
||||
expr * lit_i = cls->get_arg(i);
|
||||
in->set(alloc(split_pc, m, cls, in->pr(cls_pos)));
|
||||
report_tactic_progress(":num-new-branches", cls->get_num_args());
|
||||
for (expr* lit_i : *cls) {
|
||||
goal * subgoal_i = alloc(goal, *in);
|
||||
subgoal_i->set(in->mc());
|
||||
proof * pr_i = 0;
|
||||
if (produce_proofs)
|
||||
pr_i = m.mk_hypothesis(lit_i);
|
||||
|
@ -140,6 +126,8 @@ public:
|
|||
subgoal_i->inc_depth();
|
||||
result.push_back(subgoal_i);
|
||||
}
|
||||
in->set(concat(in->pc(), result.size(), result.c_ptr()));
|
||||
in->add(dependency_converter::concat(result.size(), result.c_ptr()));
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
|
|
|
@ -39,10 +39,7 @@ public:
|
|||
virtual ~symmetry_reduce_tactic();
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core);
|
||||
goal_ref_buffer & result);
|
||||
virtual void cleanup();
|
||||
};
|
||||
|
||||
|
@ -635,13 +632,10 @@ symmetry_reduce_tactic::~symmetry_reduce_tactic() {
|
|||
}
|
||||
|
||||
void symmetry_reduce_tactic::operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
fail_if_proof_generation("symmetry_reduce", g);
|
||||
fail_if_unsat_core_generation("symmetry_reduce", g);
|
||||
mc = 0; pc = 0; core = 0; result.reset();
|
||||
result.reset();
|
||||
(*m_imp)(*(g.get()));
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
|
|
|
@ -799,12 +799,8 @@ class tseitin_cnf_tactic : public tactic {
|
|||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
tactic_report report("tseitin-cnf", *g);
|
||||
fail_if_proof_generation("tseitin-cnf", g);
|
||||
m_produce_models = g->models_enabled();
|
||||
|
@ -843,9 +839,7 @@ class tseitin_cnf_tactic : public tactic {
|
|||
g->assert_expr(cls);
|
||||
}
|
||||
if (m_produce_models && !m_fresh_vars.empty())
|
||||
mc = m_mc.get();
|
||||
else
|
||||
mc = 0;
|
||||
g->add(m_mc.get());
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
TRACE("tseitin_cnf", g->display(tout););
|
||||
|
@ -884,11 +878,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(in, result);
|
||||
report_tactic_progress(":cnf-aux-vars", m_imp->m_num_aux_vars);
|
||||
}
|
||||
|
||||
|
|
107
src/tactic/dependency_converter.cpp
Normal file
107
src/tactic/dependency_converter.cpp
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*++
|
||||
Copyright (c) 2017 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
dependency_converter.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Utility for converting dependencies across subgoals.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2017-11-19
|
||||
|
||||
Notes:
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
#include "tactic/dependency_converter.h"
|
||||
#include "tactic/goal.h"
|
||||
|
||||
class unit_dependency_converter : public dependency_converter {
|
||||
expr_dependency_ref m_dep;
|
||||
public:
|
||||
|
||||
unit_dependency_converter(expr_dependency_ref& d) : m_dep(d) {}
|
||||
|
||||
virtual expr_dependency_ref operator()() { return m_dep; }
|
||||
|
||||
virtual dependency_converter * translate(ast_translation & translator) {
|
||||
expr_dependency_translation tr(translator);
|
||||
expr_dependency_ref d(tr(m_dep), translator.to());
|
||||
return alloc(unit_dependency_converter, d);
|
||||
}
|
||||
|
||||
virtual void display(std::ostream& out) {
|
||||
out << m_dep << "\n";
|
||||
}
|
||||
};
|
||||
|
||||
class concat_dependency_converter : public dependency_converter {
|
||||
dependency_converter_ref m_dc1;
|
||||
dependency_converter_ref m_dc2;
|
||||
public:
|
||||
|
||||
concat_dependency_converter(dependency_converter* c1, dependency_converter* c2) : m_dc1(c1), m_dc2(c2) {}
|
||||
|
||||
virtual expr_dependency_ref operator()() {
|
||||
expr_dependency_ref d1 = (*m_dc1)();
|
||||
expr_dependency_ref d2 = (*m_dc2)();
|
||||
ast_manager& m = d1.get_manager();
|
||||
return expr_dependency_ref(m.mk_join(d1, d2), m);
|
||||
}
|
||||
|
||||
virtual dependency_converter * translate(ast_translation & translator) {
|
||||
return alloc(concat_dependency_converter, m_dc1->translate(translator), m_dc2->translate(translator));
|
||||
}
|
||||
|
||||
virtual void display(std::ostream& out) {
|
||||
m_dc1->display(out);
|
||||
m_dc2->display(out);
|
||||
}
|
||||
};
|
||||
|
||||
class goal_dependency_converter : public dependency_converter {
|
||||
ast_manager& m;
|
||||
goal_ref_buffer m_goals;
|
||||
public:
|
||||
goal_dependency_converter(unsigned n, goal * const* goals) :
|
||||
m(goals[0]->m()) {
|
||||
for (unsigned i = 0; i < n; ++i) m_goals.push_back(goals[i]);
|
||||
}
|
||||
|
||||
virtual expr_dependency_ref operator()() {
|
||||
expr_dependency_ref result(m.mk_empty_dependencies(), m);
|
||||
for (goal_ref g : m_goals) {
|
||||
dependency_converter_ref dc = g->dc();
|
||||
if (dc) result = m.mk_join(result, (*dc)());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
virtual dependency_converter * translate(ast_translation & translator) {
|
||||
goal_ref_buffer goals;
|
||||
for (goal_ref g : m_goals) goals.push_back(g->translate(translator));
|
||||
return alloc(goal_dependency_converter, goals.size(), goals.c_ptr());
|
||||
}
|
||||
|
||||
virtual void display(std::ostream& out) { out << "goal-dep\n"; }
|
||||
|
||||
};
|
||||
|
||||
dependency_converter * dependency_converter::concat(dependency_converter * mc1, dependency_converter * mc2) {
|
||||
if (!mc1) return mc2;
|
||||
if (!mc2) return mc1;
|
||||
return alloc(concat_dependency_converter, mc1, mc2);
|
||||
}
|
||||
|
||||
dependency_converter* dependency_converter::unit(expr_dependency_ref& d) {
|
||||
return alloc(unit_dependency_converter, d);
|
||||
}
|
||||
|
||||
dependency_converter * dependency_converter::concat(unsigned n, goal * const* goals) {
|
||||
if (n == 0) return nullptr;
|
||||
return alloc(goal_dependency_converter, n, goals);
|
||||
}
|
47
src/tactic/dependency_converter.h
Normal file
47
src/tactic/dependency_converter.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*++
|
||||
Copyright (c) 2017 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
dependency_converter.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Utility for converting dependencies across subgoals.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2017-11-19
|
||||
|
||||
Notes:
|
||||
|
||||
|
||||
--*/
|
||||
#ifndef DEPENDENCY_CONVERTER_H_
|
||||
#define DEPENDENCY_CONVERTER_H_
|
||||
|
||||
#include "util/ref.h"
|
||||
#include "ast/ast_pp_util.h"
|
||||
#include "model/model.h"
|
||||
#include "tactic/converter.h"
|
||||
|
||||
class goal;
|
||||
|
||||
class dependency_converter : public converter {
|
||||
public:
|
||||
static dependency_converter* unit(expr_dependency_ref& d);
|
||||
|
||||
static dependency_converter* concat(dependency_converter * dc1, dependency_converter * dc2);
|
||||
|
||||
static dependency_converter* concat(unsigned n, goal * const* goals);
|
||||
|
||||
virtual expr_dependency_ref operator()() = 0;
|
||||
|
||||
virtual dependency_converter * translate(ast_translation & translator) = 0;
|
||||
};
|
||||
|
||||
typedef ref<dependency_converter> dependency_converter_ref;
|
||||
typedef sref_vector<dependency_converter> dependency_converter_ref_vector;
|
||||
typedef sref_buffer<dependency_converter> dependency_converter_ref_buffer;
|
||||
|
||||
#endif
|
|
@ -35,11 +35,11 @@ public:
|
|||
|
||||
virtual ~equiv_proof_converter() {}
|
||||
|
||||
virtual void operator()(ast_manager & m, unsigned num_source, proof * const * source, proof_ref & result) {
|
||||
m_replace(m, num_source, source, result);
|
||||
proof_ref operator()(ast_manager & m, unsigned num_source, proof * const * source) override {
|
||||
return m_replace(m, num_source, source);
|
||||
}
|
||||
|
||||
virtual proof_converter * translate(ast_translation & translator) {
|
||||
proof_converter * translate(ast_translation & translator) override {
|
||||
return m_replace.translate(translator);
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ public:
|
|||
|
||||
ast_manager& get_manager() { return m; }
|
||||
|
||||
virtual void display(std::ostream & out) {}
|
||||
void display(std::ostream & out) override {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,20 +37,16 @@ public:
|
|||
dealloc(m_bv2fp);
|
||||
}
|
||||
|
||||
virtual void operator()(model_ref & md, unsigned goal_idx) {
|
||||
SASSERT(goal_idx == 0);
|
||||
void operator()(model_ref & md) override {
|
||||
model * new_model = alloc(model, m);
|
||||
convert(md.get(), new_model);
|
||||
md = new_model;
|
||||
}
|
||||
|
||||
virtual void operator()(model_ref & md) {
|
||||
operator()(md, 0);
|
||||
}
|
||||
|
||||
void display(std::ostream & out);
|
||||
void display(std::ostream & out) override;
|
||||
|
||||
virtual model_converter * translate(ast_translation & translator);
|
||||
model_converter * translate(ast_translation & translator) override;
|
||||
|
||||
protected:
|
||||
fpa2bv_model_converter(ast_manager & m) :
|
||||
|
|
|
@ -47,16 +47,13 @@ class fpa2bv_tactic : public tactic {
|
|||
}
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
m_proofs_enabled = g->proofs_enabled();
|
||||
m_produce_models = g->models_enabled();
|
||||
m_produce_unsat_cores = g->unsat_core_enabled();
|
||||
|
||||
mc = 0; pc = 0; core = 0; result.reset();
|
||||
result.reset();
|
||||
tactic_report report("fpa2bv", *g);
|
||||
m_rw.reset();
|
||||
|
||||
|
@ -100,7 +97,7 @@ class fpa2bv_tactic : public tactic {
|
|||
}
|
||||
|
||||
if (g->models_enabled())
|
||||
mc = mk_fpa2bv_model_converter(m, m_conv);
|
||||
g->add(mk_fpa2bv_model_converter(m, m_conv));
|
||||
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
|
@ -110,7 +107,7 @@ class fpa2bv_tactic : public tactic {
|
|||
|
||||
SASSERT(g->is_well_sorted());
|
||||
TRACE("fpa2bv", tout << "AFTER: " << std::endl; g->display(tout);
|
||||
if (mc) mc->display(tout); tout << std::endl; );
|
||||
if (g->mc()) g->mc()->display(tout); tout << std::endl; );
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -140,12 +137,9 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
try {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
catch (rewriter_exception & ex) {
|
||||
throw tactic_exception(ex.msg());
|
||||
|
|
|
@ -24,8 +24,7 @@ Notes:
|
|||
#include "model/model_evaluator.h"
|
||||
|
||||
|
||||
void generic_model_converter::operator()(model_ref & md, unsigned goal_idx) {
|
||||
std::cout << "model converter\n";
|
||||
void generic_model_converter::operator()(model_ref & md) {
|
||||
TRACE("model_converter", tout << "before generic_model_converter\n"; model_v2_pp(tout, *md); display(tout););
|
||||
model_evaluator ev(*(md.get()));
|
||||
ev.set_model_completion(true);
|
||||
|
@ -34,13 +33,11 @@ void generic_model_converter::operator()(model_ref & md, unsigned goal_idx) {
|
|||
unsigned arity;
|
||||
for (unsigned i = m_hide_entries.size(); i-- > 0; ) {
|
||||
entry const& e = m_hide_entries[i];
|
||||
std::cout << "hide " << e.m_f << "\n";
|
||||
md->unregister_decl(e.m_f);
|
||||
}
|
||||
for (unsigned i = m_add_entries.size(); i-- > 0; ) {
|
||||
entry const& e = m_add_entries[i];
|
||||
ev(e.m_def, val);
|
||||
std::cout << e.m_f << " " << e.m_def << " " << val << "\n";
|
||||
TRACE("model_converter", tout << e.m_f->get_name() << " ->\n" << e.m_def << "\n==>\n" << val << "\n";);
|
||||
arity = e.m_f->get_arity();
|
||||
if (arity == 0) {
|
||||
|
|
|
@ -52,19 +52,17 @@ public:
|
|||
|
||||
void add(expr * d, expr* e) { SASSERT(is_app(d) && to_app(d)->get_num_args() == 0); add(to_app(d)->get_decl(), e); }
|
||||
|
||||
virtual void operator()(model_ref & md, unsigned goal_idx);
|
||||
|
||||
virtual void operator()(svector<symbol> & labels, unsigned goal_idx) {}
|
||||
void operator()(labels_vec & labels) override {}
|
||||
|
||||
virtual void operator()(model_ref & md) { operator()(md, 0); }
|
||||
void operator()(model_ref & md) override;
|
||||
|
||||
virtual void cancel() {}
|
||||
void cancel() override {}
|
||||
|
||||
virtual void display(std::ostream & out);
|
||||
void display(std::ostream & out) override;
|
||||
|
||||
virtual model_converter * translate(ast_translation & translator);
|
||||
model_converter * translate(ast_translation & translator) override;
|
||||
|
||||
virtual void collect(ast_pp_util& visitor);
|
||||
void collect(ast_pp_util& visitor) override;
|
||||
|
||||
void operator()(expr_ref& fml) override;
|
||||
};
|
||||
|
|
|
@ -16,11 +16,11 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include "tactic/goal.h"
|
||||
#include "ast/ast_ll_pp.h"
|
||||
#include "ast/ast_smt2_pp.h"
|
||||
#include "ast/for_each_expr.h"
|
||||
#include "ast/well_sorted.h"
|
||||
#include "tactic/goal.h"
|
||||
|
||||
goal::precision goal::mk_union(precision p1, precision p2) {
|
||||
if (p1 == PRECISE) return p2;
|
||||
|
@ -105,6 +105,9 @@ void goal::copy_to(goal & target) const {
|
|||
SASSERT(target.m_core_enabled == m_core_enabled);
|
||||
target.m_inconsistent = m_inconsistent;
|
||||
target.m_precision = mk_union(prec(), target.prec());
|
||||
target.m_mc = m_mc.get();
|
||||
target.m_pc = m_pc.get();
|
||||
target.m_dc = m_dc.get();
|
||||
}
|
||||
|
||||
void goal::push_back(expr * f, proof * pr, expr_dependency * d) {
|
||||
|
@ -344,10 +347,7 @@ void goal::display_with_dependencies(ast_printer & prn, std::ostream & out) cons
|
|||
out << "\n |-";
|
||||
deps.reset();
|
||||
m().linearize(dep(i), deps);
|
||||
ptr_vector<expr>::iterator it = deps.begin();
|
||||
ptr_vector<expr>::iterator end = deps.end();
|
||||
for (; it != end; ++it) {
|
||||
expr * d = *it;
|
||||
for (expr * d : deps) {
|
||||
if (is_uninterp_const(d)) {
|
||||
out << " " << mk_ismt2_pp(d, m());
|
||||
}
|
||||
|
@ -361,10 +361,7 @@ void goal::display_with_dependencies(ast_printer & prn, std::ostream & out) cons
|
|||
}
|
||||
if (!to_pp.empty()) {
|
||||
out << "\n :dependencies-definitions (";
|
||||
obj_hashtable<expr>::iterator it = to_pp.begin();
|
||||
obj_hashtable<expr>::iterator end = to_pp.end();
|
||||
for (; it != end; ++it) {
|
||||
expr * d = *it;
|
||||
for (expr* d : to_pp) {
|
||||
out << "\n (#" << d->get_id() << "\n ";
|
||||
prn.display(out, d, 2);
|
||||
out << ")";
|
||||
|
@ -382,10 +379,7 @@ void goal::display_with_dependencies(std::ostream & out) const {
|
|||
out << "\n |-";
|
||||
deps.reset();
|
||||
m().linearize(dep(i), deps);
|
||||
ptr_vector<expr>::iterator it = deps.begin();
|
||||
ptr_vector<expr>::iterator end = deps.end();
|
||||
for (; it != end; ++it) {
|
||||
expr * d = *it;
|
||||
for (expr * d : deps) {
|
||||
if (is_uninterp_const(d)) {
|
||||
out << " " << mk_ismt2_pp(d, m());
|
||||
}
|
||||
|
@ -510,14 +504,12 @@ void goal::shrink(unsigned j) {
|
|||
unsigned sz = size();
|
||||
for (unsigned i = j; i < sz; i++)
|
||||
m().pop_back(m_forms);
|
||||
if (proofs_enabled()) {
|
||||
if (proofs_enabled())
|
||||
for (unsigned i = j; i < sz; i++)
|
||||
m().pop_back(m_proofs);
|
||||
}
|
||||
if (unsat_core_enabled()) {
|
||||
if (unsat_core_enabled())
|
||||
for (unsigned i = j; i < sz; i++)
|
||||
m().pop_back(m_dependencies);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -662,6 +654,9 @@ goal * goal::translate(ast_translation & translator) const {
|
|||
res->m_inconsistent = m_inconsistent;
|
||||
res->m_depth = m_depth;
|
||||
res->m_precision = m_precision;
|
||||
res->m_pc = m_pc ? m_pc->translate(translator) : nullptr;
|
||||
res->m_mc = m_mc ? m_mc->translate(translator) : nullptr;
|
||||
res->m_dc = m_dc ? m_dc->translate(translator) : nullptr;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,9 @@ Revision History:
|
|||
#include "util/ref.h"
|
||||
#include "util/ref_vector.h"
|
||||
#include "util/ref_buffer.h"
|
||||
#include "tactic/model_converter.h"
|
||||
#include "tactic/proof_converter.h"
|
||||
#include "tactic/dependency_converter.h"
|
||||
|
||||
class goal {
|
||||
public:
|
||||
|
@ -49,6 +52,9 @@ public:
|
|||
|
||||
protected:
|
||||
ast_manager & m_manager;
|
||||
model_converter_ref m_mc;
|
||||
proof_converter_ref m_pc;
|
||||
dependency_converter_ref m_dc;
|
||||
unsigned m_ref_count;
|
||||
expr_array m_forms;
|
||||
expr_array m_proofs;
|
||||
|
@ -71,6 +77,7 @@ protected:
|
|||
unsigned get_not_idx(expr * f) const;
|
||||
void shrink(unsigned j);
|
||||
void reset_core();
|
||||
|
||||
|
||||
public:
|
||||
goal(ast_manager & m, bool models_enabled = true, bool core_enabled = false);
|
||||
|
@ -103,7 +110,7 @@ public:
|
|||
|
||||
void copy_to(goal & target) const;
|
||||
void copy_from(goal const & src) { src.copy_to(*this); }
|
||||
|
||||
|
||||
void assert_expr(expr * f, proof * pr, expr_dependency * d);
|
||||
void assert_expr(expr * f, expr_dependency * d);
|
||||
void assert_expr(expr * f, expr * d) { assert_expr(f, m().mk_leaf(d)); }
|
||||
|
@ -142,6 +149,16 @@ public:
|
|||
bool is_decided() const;
|
||||
bool is_well_sorted() const;
|
||||
|
||||
dependency_converter* dc() { return m_dc.get(); }
|
||||
model_converter* mc() { return m_mc.get(); }
|
||||
proof_converter* pc() { return inconsistent() ? proof2proof_converter(m(), pr(0)) : m_pc.get(); }
|
||||
void add(dependency_converter* d) { m_dc = dependency_converter::concat(m_dc.get(), d); }
|
||||
void add(model_converter* m) { m_mc = concat(m_mc.get(), m); }
|
||||
void add(proof_converter* p) { m_pc = concat(m_pc.get(), p); }
|
||||
void set(dependency_converter* d) { m_dc = d; }
|
||||
void set(model_converter* m) { m_mc = m; }
|
||||
void set(proof_converter* p) { m_pc = p; }
|
||||
|
||||
goal * translate(ast_translation & translator) const;
|
||||
};
|
||||
|
||||
|
|
|
@ -68,14 +68,9 @@ public:
|
|||
this->m_c2->operator()(fml);
|
||||
}
|
||||
|
||||
void operator()(model_ref & m, unsigned goal_idx) override {
|
||||
this->m_c2->operator()(m, goal_idx);
|
||||
this->m_c1->operator()(m, 0);
|
||||
}
|
||||
|
||||
void operator()(labels_vec & r, unsigned goal_idx) override {
|
||||
this->m_c2->operator()(r, goal_idx);
|
||||
this->m_c1->operator()(r, 0);
|
||||
void operator()(labels_vec & r) override {
|
||||
this->m_c2->operator()(r);
|
||||
this->m_c1->operator()(r);
|
||||
}
|
||||
|
||||
char const * get_name() const override { return "concat-model-converter"; }
|
||||
|
@ -98,75 +93,6 @@ model_converter * concat(model_converter * mc1, model_converter * mc2) {
|
|||
return alloc(concat_model_converter, mc1, mc2);
|
||||
}
|
||||
|
||||
class concat_star_model_converter : public concat_star_converter<model_converter> {
|
||||
public:
|
||||
concat_star_model_converter(model_converter * mc1, unsigned num, model_converter * const * mc2s, unsigned * szs):
|
||||
concat_star_converter<model_converter>(mc1, num, mc2s, szs) {
|
||||
}
|
||||
|
||||
void operator()(model_ref & m) override {
|
||||
// TODO: delete method after conversion is complete
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void operator()(model_ref & m, unsigned goal_idx) override {
|
||||
unsigned num = this->m_c2s.size();
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
if (goal_idx < this->m_szs[i]) {
|
||||
// found the model converter that should be used
|
||||
model_converter * c2 = this->m_c2s[i];
|
||||
if (c2)
|
||||
c2->operator()(m, goal_idx);
|
||||
if (m_c1)
|
||||
this->m_c1->operator()(m, i);
|
||||
return;
|
||||
}
|
||||
// invalid goal
|
||||
goal_idx -= this->m_szs[i];
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void operator()(labels_vec & r, unsigned goal_idx) override {
|
||||
unsigned num = this->m_c2s.size();
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
if (goal_idx < this->m_szs[i]) {
|
||||
// found the model converter that should be used
|
||||
model_converter * c2 = this->m_c2s[i];
|
||||
if (c2)
|
||||
c2->operator()(r, goal_idx);
|
||||
if (m_c1)
|
||||
this->m_c1->operator()(r, i);
|
||||
return;
|
||||
}
|
||||
// invalid goal
|
||||
goal_idx -= this->m_szs[i];
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
char const * get_name() const override { return "concat-star-model-converter"; }
|
||||
|
||||
model_converter * translate(ast_translation & translator) override {
|
||||
return this->translate_core<concat_star_model_converter>(translator);
|
||||
}
|
||||
};
|
||||
|
||||
model_converter * concat(model_converter * mc1, unsigned num, model_converter * const * mc2s, unsigned * szs) {
|
||||
SASSERT(num > 0);
|
||||
if (num == 1)
|
||||
return concat(mc1, mc2s[0]);
|
||||
unsigned i;
|
||||
for (i = 0; i < num; i++) {
|
||||
if (mc2s[i] != 0)
|
||||
break;
|
||||
}
|
||||
if (i == num) {
|
||||
// all mc2s are 0
|
||||
return mc1;
|
||||
}
|
||||
return alloc(concat_star_model_converter, mc1, num, mc2s, szs);
|
||||
}
|
||||
|
||||
class model2mc : public model_converter {
|
||||
model_ref m_model;
|
||||
|
@ -182,11 +108,7 @@ public:
|
|||
m = m_model;
|
||||
}
|
||||
|
||||
void operator()(model_ref & m, unsigned goal_idx) override {
|
||||
m = m_model;
|
||||
}
|
||||
|
||||
void operator()(labels_vec & r, unsigned goal_idx) {
|
||||
void operator()(labels_vec & r) {
|
||||
r.append(m_labels.size(), m_labels.c_ptr());
|
||||
}
|
||||
|
||||
|
@ -227,13 +149,13 @@ model_converter * model_and_labels2model_converter(model * m, buffer<symbol> & r
|
|||
void model_converter2model(ast_manager & mng, model_converter * mc, model_ref & m) {
|
||||
if (mc) {
|
||||
m = alloc(model, mng);
|
||||
(*mc)(m, 0);
|
||||
(*mc)(m);
|
||||
}
|
||||
}
|
||||
|
||||
void apply(model_converter_ref & mc, model_ref & m, unsigned gidx) {
|
||||
void apply(model_converter_ref & mc, model_ref & m) {
|
||||
if (mc) {
|
||||
(*mc)(m, gidx);
|
||||
(*mc)(m);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,14 +15,50 @@ Author:
|
|||
|
||||
Notes:
|
||||
|
||||
A model converter, mc, can be used to convert a model for one
|
||||
of a generated subgoal into a model for an initial goal or solver state.
|
||||
For a goal or solver state that is decided, a model converter can be
|
||||
a simple wrapper around a model.
|
||||
|
||||
Logically, given a formula F and subgoal formula F_s a model converter mc
|
||||
for F_s relative to F has the property:
|
||||
|
||||
m |= F_s iff mc(m) |= F for every model m
|
||||
|
||||
For the evaluator associated with models, m, we expect
|
||||
|
||||
eval(m)(F_s) <=> eval(mc(m))(F)
|
||||
|
||||
This property holds for both eval, that decides on a fixed value
|
||||
for constants that have no interpretation in m and for 'peval'
|
||||
(partial eval) that retuns just the constants that are unfixed.
|
||||
(in the model evaluator one can control this behavior using a
|
||||
configuration flag)
|
||||
|
||||
and more generally over the eval method have:
|
||||
|
||||
G => F_s iff peval(mc(e))(G) => F for every formula G
|
||||
|
||||
|
||||
where e is the empty model (a model that does not evaluate any
|
||||
|
||||
When a model converter supports application to a formula it satisfies
|
||||
the following property:
|
||||
|
||||
mc(G) & F_s is SAT iff G & F is SAT
|
||||
|
||||
For a model converter that is a sequence of definitions and removals
|
||||
of functions we can obtain mc(G) by adding back or expanding definitinos
|
||||
that are required to interpret G fully in the context of F_s.
|
||||
|
||||
--*/
|
||||
#ifndef MODEL_CONVERTER_H_
|
||||
#define MODEL_CONVERTER_H_
|
||||
|
||||
#include "util/ref.h"
|
||||
#include "ast/ast_pp_util.h"
|
||||
#include "model/model.h"
|
||||
#include "tactic/converter.h"
|
||||
#include "util/ref.h"
|
||||
|
||||
class labels_vec : public svector<symbol> {};
|
||||
class smt2_pp_environment;
|
||||
|
@ -36,17 +72,11 @@ protected:
|
|||
|
||||
public:
|
||||
|
||||
model_converter(): m_env(0) {}
|
||||
model_converter(): m_env(nullptr) {}
|
||||
|
||||
virtual void operator()(model_ref & m) {} // TODO: delete
|
||||
virtual void operator()(model_ref & m) = 0;
|
||||
|
||||
virtual void operator()(model_ref & m, unsigned goal_idx) {
|
||||
// TODO: make it virtual after the transition to goal/tactic/tactical is complete
|
||||
SASSERT(goal_idx == 0);
|
||||
operator()(m);
|
||||
}
|
||||
|
||||
virtual void operator()(labels_vec & r, unsigned goal_idx) {}
|
||||
virtual void operator()(labels_vec & r) {}
|
||||
|
||||
virtual model_converter * translate(ast_translation & translator) = 0;
|
||||
|
||||
|
@ -61,25 +91,18 @@ public:
|
|||
};
|
||||
|
||||
typedef ref<model_converter> model_converter_ref;
|
||||
typedef sref_vector<model_converter> model_converter_ref_vector;
|
||||
typedef sref_buffer<model_converter> model_converter_ref_buffer;
|
||||
|
||||
model_converter * concat(model_converter * mc1, model_converter * mc2);
|
||||
|
||||
/**
|
||||
\brief \c mc1 is the model converter for a sequence of subgoals of size \c num.
|
||||
Given an i in [0, num), mc2s[i] is the model converter for subgoal i,
|
||||
and num_subgoals[i] is the number of subgoals of subgoals[i].
|
||||
*/
|
||||
model_converter * concat(model_converter * mc1, unsigned num, model_converter * const * mc2s, unsigned * num_subgoals);
|
||||
|
||||
model_converter * model2model_converter(model * m);
|
||||
|
||||
model_converter * model_and_labels2model_converter(model * m, buffer<symbol> &r);
|
||||
|
||||
void model_converter2model(ast_manager & mng, model_converter * mc, model_ref & m);
|
||||
|
||||
void apply(model_converter_ref & mc, model_ref & m, unsigned gidx);
|
||||
void apply(model_converter_ref & mc, model_ref & m);
|
||||
|
||||
typedef sref_vector<model_converter> model_converter_ref_vector;
|
||||
typedef sref_buffer<model_converter> model_converter_ref_buffer;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
z3_add_component(nlsat_smt_tactic
|
||||
SOURCES
|
||||
nl_purify_tactic.cpp
|
||||
COMPONENT_DEPENDENCIES
|
||||
nlsat_tactic
|
||||
smt_tactic
|
||||
TACTIC_HEADERS
|
||||
nl_purify_tactic.h
|
||||
)
|
|
@ -1,799 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
nl_purify_tactic.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Tactic for purifying quantifier-free formulas that mix QF_NRA and other theories.
|
||||
It is designed to allow cooprating between the nlsat solver and other theories
|
||||
in a decoupled way.
|
||||
|
||||
Let goal be formula F.
|
||||
Let NL goal be formula G.
|
||||
Assume F is in NNF.
|
||||
Assume F does not contain mix of real/integers.
|
||||
Assume F is quantifier-free (please, otherwise we need to reprocess from instantiated satisfiable formula)
|
||||
|
||||
For each atomic nl formula f,
|
||||
- introduce a propositional variable p
|
||||
- replace f by p
|
||||
- add clauses p => f to G
|
||||
|
||||
For each interface term t,
|
||||
- introduce interface variable v (or use t if it is already a variable)
|
||||
- replace t by v
|
||||
|
||||
Check satisfiability of G.
|
||||
If satisfiable, then check assignment to p and interface equalities on F
|
||||
If unsat:
|
||||
Retrieve core and add core to G.
|
||||
else:
|
||||
For interface equalities from model of F that are not equal in G, add
|
||||
For interface variables that are equal under one model, but not the other model,
|
||||
create interface predicate p_vw => v = w, add to both F, G.
|
||||
Add interface equations to assumptions, recheck F.
|
||||
If unsat retrieve core add to G.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2015-5-5.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include "tactic/tactical.h"
|
||||
#include "tactic/nlsat_smt/nl_purify_tactic.h"
|
||||
#include "smt/tactic/smt_tactic.h"
|
||||
#include "ast/rewriter/rewriter.h"
|
||||
#include "nlsat/tactic/nlsat_tactic.h"
|
||||
#include "tactic/generic_model_converter.h"
|
||||
#include "util/obj_pair_hashtable.h"
|
||||
#include "ast/rewriter/rewriter_def.h"
|
||||
#include "ast/ast_pp.h"
|
||||
#include "util/trace.h"
|
||||
#include "smt/smt_solver.h"
|
||||
#include "solver/solver.h"
|
||||
#include "model/model_smt2_pp.h"
|
||||
#include "ast/rewriter/expr_safe_replace.h"
|
||||
#include "ast/ast_util.h"
|
||||
#include "solver/solver2tactic.h"
|
||||
|
||||
class nl_purify_tactic : public tactic {
|
||||
|
||||
enum polarity_t {
|
||||
pol_pos,
|
||||
pol_neg,
|
||||
pol_dual
|
||||
};
|
||||
|
||||
ast_manager & m;
|
||||
arith_util m_util;
|
||||
params_ref m_params;
|
||||
bool m_produce_proofs;
|
||||
ref<generic_model_converter> m_fmc;
|
||||
tactic_ref m_nl_tac; // nlsat tactic
|
||||
goal_ref m_nl_g; // nlsat goal
|
||||
ref<solver> m_solver; // SMT solver
|
||||
expr_ref_vector m_eq_preds; // predicates for equality between pairs of interface variables
|
||||
svector<lbool> m_eq_values; // truth value of the equality predicates in nlsat
|
||||
app_ref_vector m_new_reals; // interface real variables
|
||||
app_ref_vector m_new_preds; // abstraction predicates for smt_solver (hide real constraints)
|
||||
expr_ref_vector m_asms; // assumptions to pass to SMT solver
|
||||
ptr_vector<expr> m_ctx_asms; // assumptions passed by context
|
||||
obj_hashtable<expr> m_ctx_asms_set; // assumptions passed by context
|
||||
obj_hashtable<expr> m_used_asms;
|
||||
obj_map<expr, expr*> m_bool2dep;
|
||||
obj_pair_map<expr,expr,expr*> m_eq_pairs; // map pairs of interface variables to auxiliary predicates
|
||||
obj_map<expr,expr*> m_interface_cache; // map of compound real expression to interface variable.
|
||||
obj_map<expr, polarity_t> m_polarities; // polarities of sub-expressions
|
||||
|
||||
public:
|
||||
struct rw_cfg : public default_rewriter_cfg {
|
||||
enum mode_t {
|
||||
mode_interface_var,
|
||||
mode_bool_preds
|
||||
};
|
||||
ast_manager& m;
|
||||
nl_purify_tactic & m_owner;
|
||||
app_ref_vector& m_new_reals;
|
||||
app_ref_vector& m_new_preds;
|
||||
obj_map<expr, polarity_t>& m_polarities;
|
||||
obj_map<expr,expr*>& m_interface_cache;
|
||||
expr_ref_vector m_args;
|
||||
proof_ref_vector m_proofs;
|
||||
mode_t m_mode;
|
||||
|
||||
rw_cfg(nl_purify_tactic & o):
|
||||
m(o.m),
|
||||
m_owner(o),
|
||||
m_new_reals(o.m_new_reals),
|
||||
m_new_preds(o.m_new_preds),
|
||||
m_polarities(o.m_polarities),
|
||||
m_interface_cache(o.m_interface_cache),
|
||||
m_args(m),
|
||||
m_proofs(m),
|
||||
m_mode(mode_interface_var) {
|
||||
}
|
||||
|
||||
virtual ~rw_cfg() {}
|
||||
|
||||
arith_util & u() { return m_owner.m_util; }
|
||||
|
||||
expr * mk_interface_var(expr* arg, proof_ref& arg_pr) {
|
||||
expr* r;
|
||||
if (m_interface_cache.find(arg, r)) {
|
||||
return r;
|
||||
}
|
||||
if (is_uninterp_const(arg)) {
|
||||
m_interface_cache.insert(arg, arg);
|
||||
return arg;
|
||||
}
|
||||
r = m.mk_fresh_const(0, u().mk_real());
|
||||
m_new_reals.push_back(to_app(r));
|
||||
m_owner.m_fmc->hide(r);
|
||||
m_interface_cache.insert(arg, r);
|
||||
expr_ref eq(m);
|
||||
eq = m.mk_eq(r, arg);
|
||||
if (is_real_expression(arg)) {
|
||||
m_owner.m_nl_g->assert_expr(eq); // m.mk_oeq(r, arg)
|
||||
}
|
||||
else {
|
||||
m_owner.m_solver->assert_expr(eq);
|
||||
}
|
||||
if (m_owner.m_produce_proofs) {
|
||||
arg_pr = m.mk_oeq(arg, r);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
bool is_real_expression(expr* e) {
|
||||
return is_app(e) && (to_app(e)->get_family_id() == u().get_family_id());
|
||||
}
|
||||
|
||||
void mk_interface_bool(func_decl * f, unsigned num, expr* const* args, expr_ref& result, proof_ref& pr) {
|
||||
expr_ref old_pred(m.mk_app(f, num, args), m);
|
||||
polarity_t pol = m_polarities.find(old_pred);
|
||||
result = m.mk_fresh_const(0, m.mk_bool_sort());
|
||||
m_polarities.insert(result, pol);
|
||||
m_new_preds.push_back(to_app(result));
|
||||
m_owner.m_fmc->hide(result);
|
||||
if (pol != pol_neg) {
|
||||
m_owner.m_nl_g->assert_expr(m.mk_or(m.mk_not(result), old_pred));
|
||||
}
|
||||
if (pol != pol_pos) {
|
||||
m_owner.m_nl_g->assert_expr(m.mk_or(result, m.mk_not(old_pred)));
|
||||
}
|
||||
if (m_owner.m_produce_proofs) {
|
||||
pr = m.mk_oeq(old_pred, result);
|
||||
}
|
||||
TRACE("nlsat_smt", tout << old_pred << " : " << result << "\n";);
|
||||
}
|
||||
|
||||
bool reduce_quantifier(quantifier * old_q,
|
||||
expr * new_body,
|
||||
expr * const * new_patterns,
|
||||
expr * const * new_no_patterns,
|
||||
expr_ref & result,
|
||||
proof_ref & result_pr) {
|
||||
throw tactic_exception("quantifiers are not supported in mixed-mode nlsat engine");
|
||||
}
|
||||
|
||||
br_status reduce_app(func_decl * f, unsigned num, expr* const* args, expr_ref& result, proof_ref & pr) {
|
||||
if (m_mode == mode_bool_preds) {
|
||||
return reduce_app_bool(f, num, args, result, pr);
|
||||
}
|
||||
else {
|
||||
return reduce_app_real(f, num, args, result, pr);
|
||||
}
|
||||
}
|
||||
|
||||
br_status reduce_app_bool(func_decl * f, unsigned num, expr* const* args, expr_ref& result, proof_ref & pr) {
|
||||
if (f->get_family_id() == m.get_basic_family_id()) {
|
||||
if (f->get_decl_kind() == OP_EQ && u().is_real(args[0])) {
|
||||
mk_interface_bool(f, num, args, result, pr);
|
||||
return BR_DONE;
|
||||
}
|
||||
else {
|
||||
return BR_FAILED;
|
||||
}
|
||||
}
|
||||
if (f->get_family_id() == u().get_family_id()) {
|
||||
switch (f->get_decl_kind()) {
|
||||
case OP_LE: case OP_GE: case OP_LT: case OP_GT:
|
||||
// these are the only real cases of non-linear atomic formulas besides equality.
|
||||
mk_interface_bool(f, num, args, result, pr);
|
||||
return BR_DONE;
|
||||
default:
|
||||
return BR_FAILED;
|
||||
}
|
||||
}
|
||||
return BR_FAILED;
|
||||
}
|
||||
|
||||
// (+ (f x) y)
|
||||
// (f (+ x y))
|
||||
//
|
||||
bool is_arith_op(expr* e) {
|
||||
return is_app(e) && to_app(e)->get_family_id() == u().get_family_id();
|
||||
}
|
||||
|
||||
br_status reduce_app_real(func_decl * f, unsigned num, expr* const* args, expr_ref& result, proof_ref & pr) {
|
||||
bool has_interface = false;
|
||||
bool is_arith = false;
|
||||
if (f->get_family_id() == u().get_family_id()) {
|
||||
switch (f->get_decl_kind()) {
|
||||
case OP_NUM:
|
||||
case OP_IRRATIONAL_ALGEBRAIC_NUM:
|
||||
return BR_FAILED;
|
||||
default:
|
||||
is_arith = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_args.reset();
|
||||
m_proofs.reset();
|
||||
for (unsigned i = 0; i < num; ++i) {
|
||||
expr* arg = args[i];
|
||||
proof_ref arg_pr(m);
|
||||
if (is_arith && !is_arith_op(arg)) {
|
||||
has_interface = true;
|
||||
m_args.push_back(mk_interface_var(arg, arg_pr));
|
||||
}
|
||||
else if (!is_arith && u().is_real(arg)) {
|
||||
has_interface = true;
|
||||
m_args.push_back(mk_interface_var(arg, arg_pr));
|
||||
}
|
||||
else {
|
||||
m_args.push_back(arg);
|
||||
}
|
||||
if (arg_pr) {
|
||||
m_proofs.push_back(arg_pr);
|
||||
}
|
||||
}
|
||||
if (has_interface) {
|
||||
result = m.mk_app(f, num, m_args.c_ptr());
|
||||
if (m_owner.m_produce_proofs) {
|
||||
pr = m.mk_oeq_congruence(m.mk_app(f, num, args), to_app(result), m_proofs.size(), m_proofs.c_ptr());
|
||||
}
|
||||
TRACE("nlsat_smt", tout << result << "\n";);
|
||||
return BR_DONE;
|
||||
}
|
||||
else {
|
||||
return BR_FAILED;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
class rw : public rewriter_tpl<rw_cfg> {
|
||||
rw_cfg m_cfg;
|
||||
public:
|
||||
rw(nl_purify_tactic & o):
|
||||
rewriter_tpl<rw_cfg>(o.m, o.m_produce_proofs, m_cfg),
|
||||
m_cfg(o) {
|
||||
}
|
||||
void set_bool_mode() {
|
||||
m_cfg.m_mode = rw_cfg::mode_bool_preds;
|
||||
}
|
||||
void set_interface_var_mode() {
|
||||
m_cfg.m_mode = rw_cfg::mode_interface_var;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
arith_util & u() { return m_util; }
|
||||
|
||||
void check_point() {
|
||||
if (m.canceled()) {
|
||||
throw tactic_exception(Z3_CANCELED_MSG);
|
||||
}
|
||||
}
|
||||
|
||||
void display_result(std::ostream& out, goal_ref_buffer const& result) {
|
||||
for (unsigned i = 0; i < result.size(); ++i) {
|
||||
result[i]->display_with_dependencies(out << "goal\n");
|
||||
}
|
||||
}
|
||||
|
||||
void update_eq_values(model_ref& mdl) {
|
||||
expr_ref tmp(m);
|
||||
for (unsigned i = 0; i < m_eq_preds.size(); ++i) {
|
||||
expr* pred = m_eq_preds[i].get();
|
||||
m_eq_values[i] = l_undef;
|
||||
if (mdl->eval(pred, tmp)) {
|
||||
if (m.is_true(tmp)) {
|
||||
m_eq_values[i] = l_true;
|
||||
}
|
||||
else if (m.is_false(tmp)) {
|
||||
m_eq_values[i] = l_false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void solve(
|
||||
goal_ref const& g,
|
||||
goal_ref_buffer& result,
|
||||
expr_dependency_ref& core,
|
||||
model_converter_ref& mc) {
|
||||
|
||||
while (true) {
|
||||
check_point();
|
||||
TRACE("nlsat_smt", m_solver->display(tout << "SMT:\n"); m_nl_g->display(tout << "\nNL:\n"); );
|
||||
goal_ref tmp_nl = alloc(goal, m, true, false);
|
||||
model_converter_ref nl_mc;
|
||||
proof_converter_ref nl_pc;
|
||||
expr_dependency_ref nl_core(m);
|
||||
result.reset();
|
||||
tmp_nl->copy_from(*m_nl_g.get());
|
||||
(*m_nl_tac)(tmp_nl, result, nl_mc, nl_pc, nl_core);
|
||||
|
||||
if (is_decided_unsat(result)) {
|
||||
core2result(core, g, result);
|
||||
TRACE("nlsat_smt", tout << "unsat\n";);
|
||||
break;
|
||||
}
|
||||
if (!is_decided_sat(result)) {
|
||||
TRACE("nlsat_smt", tout << "not a unit\n";);
|
||||
break;
|
||||
}
|
||||
// extract evaluation on interface variables.
|
||||
// assert booleans that evaluate to true.
|
||||
// assert equalities between equal interface real variables.
|
||||
|
||||
model_ref mdl_nl, mdl_smt;
|
||||
if (nl_mc.get()) {
|
||||
model_converter2model(m, nl_mc.get(), mdl_nl);
|
||||
update_eq_values(mdl_nl);
|
||||
enforce_equalities(mdl_nl, m_nl_g);
|
||||
|
||||
setup_assumptions(mdl_nl);
|
||||
|
||||
TRACE("nlsat_smt",
|
||||
model_smt2_pp(tout << "nl model\n", m, *mdl_nl.get(), 0);
|
||||
m_solver->display(tout << "smt goal:\n"); tout << "\n";);
|
||||
}
|
||||
result.reset();
|
||||
lbool r = m_solver->check_sat(m_asms.size(), m_asms.c_ptr());
|
||||
if (r == l_false) {
|
||||
// extract the core from the result
|
||||
ptr_vector<expr> ecore, asms;
|
||||
expr_ref_vector clause(m);
|
||||
expr_ref fml(m);
|
||||
get_unsat_core(ecore, asms);
|
||||
|
||||
//
|
||||
// assumptions should also be used for the nlsat tactic,
|
||||
// but since it does not support assumptions at this time
|
||||
// we overapproximate the necessary core and accumulate
|
||||
// all assumptions that are ever used.
|
||||
//
|
||||
for (unsigned i = 0; i < asms.size(); ++i) {
|
||||
m_used_asms.insert(asms[i]);
|
||||
}
|
||||
if (ecore.empty()) {
|
||||
core2result(core, g, result);
|
||||
break;
|
||||
}
|
||||
for (unsigned i = 0; i < ecore.size(); ++i) {
|
||||
clause.push_back(mk_not(m, ecore[i]));
|
||||
}
|
||||
fml = mk_or(m, clause.size(), clause.c_ptr());
|
||||
m_nl_g->assert_expr(fml);
|
||||
continue;
|
||||
}
|
||||
else if (r == l_true) {
|
||||
m_solver->get_model(mdl_smt);
|
||||
if (enforce_equalities(mdl_smt, m_nl_g)) {
|
||||
// SMT enforced a new equality that wasn't true for nlsat.
|
||||
continue;
|
||||
}
|
||||
TRACE("nlsat_smt",
|
||||
m_fmc->display(tout << "joint state is sat\n");
|
||||
nl_mc->display(tout << "nl\n"););
|
||||
if (mdl_nl.get()) {
|
||||
merge_models(*mdl_nl.get(), mdl_smt);
|
||||
}
|
||||
mc = m_fmc.get();
|
||||
apply(mc, mdl_smt, 0);
|
||||
mc = model2model_converter(mdl_smt.get());
|
||||
result.push_back(alloc(goal, m));
|
||||
}
|
||||
else {
|
||||
TRACE("nlsat_smt", tout << "unknown\n";);
|
||||
}
|
||||
break;
|
||||
}
|
||||
TRACE("nlsat_smt", display_result(tout, result););
|
||||
}
|
||||
|
||||
void get_unsat_core(ptr_vector<expr>& core, ptr_vector<expr>& asms) {
|
||||
m_solver->get_unsat_core(core);
|
||||
for (unsigned i = 0; i < core.size(); ++i) {
|
||||
if (m_ctx_asms_set.contains(core[i])) {
|
||||
asms.push_back(core[i]);
|
||||
core[i] = core.back();
|
||||
core.pop_back();
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void core2result(expr_dependency_ref & lcore, goal_ref const& g, goal_ref_buffer& result) {
|
||||
result.reset();
|
||||
proof * pr = 0;
|
||||
lcore = 0;
|
||||
g->reset();
|
||||
obj_hashtable<expr>::iterator it = m_used_asms.begin(), end = m_used_asms.end();
|
||||
for (; it != end; ++it) {
|
||||
lcore = m.mk_join(lcore, m.mk_leaf(m_bool2dep.find(*it)));
|
||||
}
|
||||
g->assert_expr(m.mk_false(), pr, lcore);
|
||||
TRACE("nlsat_smt", g->display_with_dependencies(tout););
|
||||
result.push_back(g.get());
|
||||
}
|
||||
|
||||
void setup_assumptions(model_ref& mdl) {
|
||||
m_asms.reset();
|
||||
m_asms.append(m_ctx_asms.size(), m_ctx_asms.c_ptr());
|
||||
app_ref_vector const& fresh_preds = m_new_preds;
|
||||
expr_ref tmp(m);
|
||||
for (unsigned i = 0; i < fresh_preds.size(); ++i) {
|
||||
expr* pred = fresh_preds[i];
|
||||
if (mdl->eval(pred, tmp)) {
|
||||
polarity_t pol = m_polarities.find(pred);
|
||||
// if assumptinon literals are used to satisfy NL state,
|
||||
// we have to assume them when satisfying SMT state
|
||||
if (pol != pol_neg && m.is_false(tmp)) {
|
||||
m_asms.push_back(m.mk_not(pred));
|
||||
}
|
||||
else if (pol != pol_pos && m.is_true(tmp)) {
|
||||
m_asms.push_back(pred);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < m_eq_preds.size(); ++i) {
|
||||
expr* pred = m_eq_preds[i].get();
|
||||
switch (m_eq_values[i]) {
|
||||
case l_true:
|
||||
m_asms.push_back(pred);
|
||||
break;
|
||||
case l_false:
|
||||
m_asms.push_back(m.mk_not(pred));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
TRACE("nlsat_smt",
|
||||
tout << "assumptions:\n" << m_asms << "\n";);
|
||||
}
|
||||
|
||||
bool enforce_equalities(model_ref& mdl, goal_ref const& nl_g) {
|
||||
TRACE("nlsat_smt", tout << "Enforce equalities " << m_interface_cache.size() << "\n";);
|
||||
bool new_equality = false;
|
||||
expr_ref_vector nums(m);
|
||||
obj_map<expr, expr*> num2var;
|
||||
obj_map<expr, expr*>::iterator it = m_interface_cache.begin(), end = m_interface_cache.end();
|
||||
for (; it != end; ++it) {
|
||||
expr_ref r(m);
|
||||
expr* v, *w, *pred;
|
||||
w = it->m_value;
|
||||
VERIFY(mdl->eval(w, r));
|
||||
TRACE("nlsat_smt", tout << mk_pp(w, m) << " |-> " << r << "\n";);
|
||||
nums.push_back(r);
|
||||
if (num2var.find(r, v)) {
|
||||
if (!m_eq_pairs.find(v, w, pred)) {
|
||||
pred = m.mk_fresh_const(0, m.mk_bool_sort());
|
||||
m_eq_preds.push_back(pred);
|
||||
m_eq_values.push_back(l_true);
|
||||
m_fmc->hide(pred);
|
||||
nl_g->assert_expr(m.mk_or(m.mk_not(pred), m.mk_eq(w, v)));
|
||||
nl_g->assert_expr(m.mk_or(pred, m.mk_not(m.mk_eq(w, v))));
|
||||
m_solver->assert_expr(m.mk_iff(pred, m.mk_eq(w, v)));
|
||||
new_equality = true;
|
||||
m_eq_pairs.insert(v, w, pred);
|
||||
}
|
||||
else {
|
||||
// interface equality is already enforced.
|
||||
}
|
||||
}
|
||||
else {
|
||||
num2var.insert(r, w);
|
||||
}
|
||||
}
|
||||
return new_equality;
|
||||
}
|
||||
|
||||
void merge_models(model const& mdl_nl, model_ref& mdl_smt) {
|
||||
expr_safe_replace num2num(m);
|
||||
expr_ref result(m), val2(m);
|
||||
expr_ref_vector args(m);
|
||||
unsigned sz = mdl_nl.get_num_constants();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
func_decl* v = mdl_nl.get_constant(i);
|
||||
if (u().is_real(v->get_range())) {
|
||||
expr* val = mdl_nl.get_const_interp(v);
|
||||
if (mdl_smt->eval(v, val2)) {
|
||||
if (val != val2) {
|
||||
num2num.insert(val2, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sz = mdl_smt->get_num_functions();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
func_decl* f = mdl_smt->get_function(i);
|
||||
if (has_real(f)) {
|
||||
unsigned arity = f->get_arity();
|
||||
func_interp* f1 = mdl_smt->get_func_interp(f);
|
||||
func_interp* f2 = alloc(func_interp, m, f->get_arity());
|
||||
for (unsigned j = 0; j < f1->num_entries(); ++j) {
|
||||
args.reset();
|
||||
func_entry const* entry = f1->get_entry(j);
|
||||
for (unsigned k = 0; k < arity; ++k) {
|
||||
translate(num2num, entry->get_arg(k), result);
|
||||
args.push_back(result);
|
||||
}
|
||||
translate(num2num, entry->get_result(), result);
|
||||
f2->insert_entry(args.c_ptr(), result);
|
||||
}
|
||||
translate(num2num, f1->get_else(), result);
|
||||
f2->set_else(result);
|
||||
mdl_smt->register_decl(f, f2);
|
||||
}
|
||||
}
|
||||
mdl_smt->copy_const_interps(mdl_nl);
|
||||
}
|
||||
|
||||
bool has_real(func_decl* f) {
|
||||
for (unsigned i = 0; i < f->get_arity(); ++i) {
|
||||
if (u().is_real(f->get_domain(i))) return true;
|
||||
}
|
||||
return u().is_real(f->get_range());
|
||||
}
|
||||
|
||||
void translate(expr_safe_replace& num2num, expr* e, expr_ref& result) {
|
||||
result = 0;
|
||||
if (e) {
|
||||
num2num(e, result);
|
||||
}
|
||||
}
|
||||
|
||||
void get_polarities(goal const& g) {
|
||||
ptr_vector<expr> forms;
|
||||
svector<polarity_t> pols;
|
||||
unsigned sz = g.size();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
forms.push_back(g.form(i));
|
||||
pols.push_back(pol_pos);
|
||||
}
|
||||
polarity_t p, q;
|
||||
while (!forms.empty()) {
|
||||
expr* e = forms.back();
|
||||
p = pols.back();
|
||||
forms.pop_back();
|
||||
pols.pop_back();
|
||||
if (m_polarities.find(e, q)) {
|
||||
if (p == q || q == pol_dual) continue;
|
||||
p = pol_dual;
|
||||
}
|
||||
TRACE("nlsat_smt_verbose", tout << mk_pp(e, m) << "\n";);
|
||||
m_polarities.insert(e, p);
|
||||
if (is_quantifier(e) || is_var(e)) {
|
||||
throw tactic_exception("nl-purify tactic does not support quantifiers");
|
||||
}
|
||||
SASSERT(is_app(e));
|
||||
app* a = to_app(e);
|
||||
func_decl* f = a->get_decl();
|
||||
if (f->get_family_id() == m.get_basic_family_id() && p != pol_dual) {
|
||||
switch(f->get_decl_kind()) {
|
||||
case OP_NOT:
|
||||
p = neg(p);
|
||||
break;
|
||||
case OP_AND:
|
||||
case OP_OR:
|
||||
break;
|
||||
default:
|
||||
p = pol_dual;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
p = pol_dual;
|
||||
}
|
||||
for (unsigned i = 0; i < a->get_num_args(); ++i) {
|
||||
forms.push_back(a->get_arg(i));
|
||||
pols.push_back(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
polarity_t neg(polarity_t p) {
|
||||
switch (p) {
|
||||
case pol_pos: return pol_neg;
|
||||
case pol_neg: return pol_pos;
|
||||
case pol_dual: return pol_dual;
|
||||
}
|
||||
return pol_dual;
|
||||
}
|
||||
|
||||
polarity_t join(polarity_t p, polarity_t q) {
|
||||
if (p == q) return p;
|
||||
return pol_dual;
|
||||
}
|
||||
|
||||
void rewrite_goal(rw& r, goal_ref const& g) {
|
||||
r.reset();
|
||||
expr_ref new_curr(m);
|
||||
proof_ref new_pr(m);
|
||||
unsigned sz = g->size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
expr * curr = g->form(i);
|
||||
r(curr, new_curr, new_pr);
|
||||
if (m_produce_proofs) {
|
||||
proof * pr = g->pr(i);
|
||||
new_pr = m.mk_modus_ponens(pr, new_pr);
|
||||
}
|
||||
g->update(i, new_curr, new_pr, g->dep(i));
|
||||
}
|
||||
}
|
||||
|
||||
void remove_pure_arith(goal_ref const& g) {
|
||||
obj_map<expr, bool> is_pure;
|
||||
unsigned sz = g->size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
expr * curr = g->form(i);
|
||||
if (is_pure_arithmetic(is_pure, curr)) {
|
||||
m_nl_g->assert_expr(curr, g->pr(i), g->dep(i));
|
||||
g->update(i, m.mk_true(), g->pr(i), g->dep(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool is_pure_arithmetic(obj_map<expr, bool>& is_pure, expr* e0) {
|
||||
ptr_vector<expr> todo;
|
||||
todo.push_back(e0);
|
||||
while (!todo.empty()) {
|
||||
expr* e = todo.back();
|
||||
if (is_pure.contains(e)) {
|
||||
todo.pop_back();
|
||||
continue;
|
||||
}
|
||||
if (!is_app(e)) {
|
||||
todo.pop_back();
|
||||
is_pure.insert(e, false);
|
||||
continue;
|
||||
}
|
||||
app* a = to_app(e);
|
||||
bool pure = false, all_found = true, p;
|
||||
pure |= (a->get_family_id() == u().get_family_id()) && u().is_real(a);
|
||||
pure |= (m.is_eq(e) && u().is_real(a->get_arg(0)));
|
||||
pure |= (a->get_family_id() == u().get_family_id()) && m.is_bool(a) && u().is_real(a->get_arg(0));
|
||||
pure |= (a->get_family_id() == m.get_basic_family_id());
|
||||
pure |= is_uninterp_const(a) && u().is_real(a);
|
||||
for (unsigned i = 0; i < a->get_num_args(); ++i) {
|
||||
if (!is_pure.find(a->get_arg(i), p)) {
|
||||
todo.push_back(a->get_arg(i));
|
||||
all_found = false;
|
||||
}
|
||||
else {
|
||||
pure &= p;
|
||||
}
|
||||
}
|
||||
if (all_found) {
|
||||
is_pure.insert(e, pure);
|
||||
todo.pop_back();
|
||||
}
|
||||
}
|
||||
return is_pure.find(e0);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
nl_purify_tactic(ast_manager & m, params_ref const& p):
|
||||
m(m),
|
||||
m_util(m),
|
||||
m_params(p),
|
||||
m_fmc(0),
|
||||
m_nl_tac(mk_nlsat_tactic(m, p)),
|
||||
m_nl_g(0),
|
||||
m_solver(mk_smt_solver(m, p, symbol::null)),
|
||||
m_eq_preds(m),
|
||||
m_new_reals(m),
|
||||
m_new_preds(m),
|
||||
m_asms(m)
|
||||
{}
|
||||
|
||||
virtual ~nl_purify_tactic() {}
|
||||
|
||||
virtual void updt_params(params_ref const & p) {
|
||||
m_params = p;
|
||||
}
|
||||
|
||||
virtual tactic * translate(ast_manager& m) {
|
||||
return alloc(nl_purify_tactic, m, m_params);
|
||||
}
|
||||
|
||||
virtual void collect_statistics(statistics & st) const {
|
||||
m_nl_tac->collect_statistics(st);
|
||||
m_solver->collect_statistics(st);
|
||||
}
|
||||
|
||||
virtual void reset_statistics() {
|
||||
m_nl_tac->reset_statistics();
|
||||
}
|
||||
|
||||
|
||||
virtual void cleanup() {
|
||||
m_solver = mk_smt_solver(m, m_params, symbol::null);
|
||||
m_nl_tac->cleanup();
|
||||
m_eq_preds.reset();
|
||||
m_eq_values.reset();
|
||||
m_new_reals.reset();
|
||||
m_new_preds.reset();
|
||||
m_eq_pairs.reset();
|
||||
m_polarities.reset();
|
||||
m_ctx_asms.reset();
|
||||
m_ctx_asms_set.reset();
|
||||
m_used_asms.reset();
|
||||
m_bool2dep.reset();
|
||||
}
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
|
||||
tactic_report report("qfufnl-purify", *g);
|
||||
TRACE("nlsat_smt", g->display(tout););
|
||||
|
||||
m_produce_proofs = g->proofs_enabled();
|
||||
mc = 0; pc = 0; core = 0;
|
||||
|
||||
fail_if_proof_generation("qfufnra-purify", g);
|
||||
// fail_if_unsat_core_generation("qfufnra-purify", g);
|
||||
rw r(*this);
|
||||
expr_ref_vector clauses(m);
|
||||
m_nl_g = alloc(goal, m, true, false);
|
||||
m_fmc = alloc(generic_model_converter, m);
|
||||
|
||||
// first hoist interface variables,
|
||||
// then annotate subformulas by polarities,
|
||||
// finally extract polynomial inequalities by
|
||||
// creating a place-holder predicate inside the
|
||||
// original goal and extracing pure nlsat clauses.
|
||||
r.set_interface_var_mode();
|
||||
rewrite_goal(r, g);
|
||||
if (!g->unsat_core_enabled()) {
|
||||
remove_pure_arith(g);
|
||||
}
|
||||
get_polarities(*g.get());
|
||||
r.set_bool_mode();
|
||||
rewrite_goal(r, g);
|
||||
|
||||
extract_clauses_and_dependencies(g, clauses, m_ctx_asms, m_bool2dep, m_fmc);
|
||||
|
||||
TRACE("nlsat_smt", tout << clauses << "\n";);
|
||||
|
||||
for (unsigned i = 0; i < m_ctx_asms.size(); ++i) {
|
||||
m_ctx_asms_set.insert(m_ctx_asms[i]);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < clauses.size(); ++i) {
|
||||
m_solver->assert_expr(clauses[i].get());
|
||||
}
|
||||
g->inc_depth();
|
||||
solve(g, result, core, mc);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
tactic * mk_nl_purify_tactic(ast_manager& m, params_ref const& p) {
|
||||
return alloc(nl_purify_tactic, m, p);
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
nl_purify_tactic.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Tactic for purifying quantifier-free formulas that mix QF_NRA and other theories.
|
||||
It is designed to allow cooprating between the nlsat solver and other theories
|
||||
in a decoubled way.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2015-5-5.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef NL_PURIFY_TACTIC_H_
|
||||
#define NL_PURIFY_TACTIC_H_
|
||||
|
||||
#include "util/params.h"
|
||||
class ast_manager;
|
||||
class tactic;
|
||||
|
||||
tactic * mk_nl_purify_tactic(ast_manager & m, params_ref const & p = params_ref());
|
||||
|
||||
/*
|
||||
ADD_TACTIC("nl-purify", "Decompose goal into pure NL-sat formula and formula over other theories.", "mk_nl_purify_tactic(m, p)")
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
@ -210,7 +210,7 @@ private:
|
|||
}
|
||||
generic_model_converter filter(m);
|
||||
for (func_decl* f : m_bv_fns) filter.hide(f);
|
||||
filter(mdl, 0);
|
||||
filter(mdl);
|
||||
}
|
||||
|
||||
void extend_model(model_ref& mdl) {
|
||||
|
@ -225,7 +225,7 @@ private:
|
|||
TRACE("int2bv", tout << mk_pp(kv.m_key, m) << " " << value << "\n";);
|
||||
ext.add(kv.m_key, value);
|
||||
}
|
||||
ext(mdl, 0);
|
||||
ext(mdl);
|
||||
}
|
||||
|
||||
void accumulate_sub(expr_safe_replace& sub) const {
|
||||
|
|
|
@ -167,14 +167,14 @@ public:
|
|||
for (auto const& kv : m_rewriter.enum2bv()) {
|
||||
filter.hide(kv.m_value);
|
||||
}
|
||||
filter(mdl, 0);
|
||||
filter(mdl);
|
||||
}
|
||||
|
||||
void extend_model(model_ref& mdl) {
|
||||
generic_model_converter ext(m);
|
||||
for (auto const& kv : m_rewriter.enum2def())
|
||||
ext.add(kv.m_key, kv.m_value);
|
||||
ext(mdl, 0);
|
||||
ext(mdl);
|
||||
}
|
||||
|
||||
virtual unsigned get_num_assertions() const {
|
||||
|
|
|
@ -541,7 +541,7 @@ public:
|
|||
init();
|
||||
}
|
||||
|
||||
void operator ()(const goal_ref & g,goal_ref_buffer & result,model_converter_ref & mc,proof_converter_ref & pc,expr_dependency_ref & dep) {
|
||||
void operator ()(const goal_ref & g,goal_ref_buffer & result) {
|
||||
ast_manager& m = g->m();
|
||||
solver* s = mk_fd_solver(m, m_params);
|
||||
solver_state* st = alloc(solver_state, 0, s, m_params, cube_task);
|
||||
|
@ -560,8 +560,7 @@ public:
|
|||
switch (is_sat) {
|
||||
case l_true:
|
||||
if (g->models_enabled()) {
|
||||
mc = model2model_converter(mdl.get());
|
||||
mc = concat(fmc.get(), mc.get());
|
||||
g->add(concat(fmc.get(), model2model_converter(mdl.get())));
|
||||
}
|
||||
g->reset();
|
||||
break;
|
||||
|
|
|
@ -118,7 +118,7 @@ public:
|
|||
for (func_decl* f : fns) {
|
||||
filter.hide(f);
|
||||
}
|
||||
filter(mdl, 0);
|
||||
filter(mdl);
|
||||
}
|
||||
|
||||
virtual unsigned get_num_assertions() const {
|
||||
|
|
|
@ -17,6 +17,7 @@ Notes:
|
|||
|
||||
--*/
|
||||
#include "tactic/proof_converter.h"
|
||||
#include "tactic/goal.h"
|
||||
#include "ast/ast_smt2_pp.h"
|
||||
|
||||
class concat_proof_converter : public concat_converter<proof_converter> {
|
||||
|
@ -25,14 +26,14 @@ public:
|
|||
|
||||
virtual char const * get_name() const { return "concat-proof-converter"; }
|
||||
|
||||
virtual void operator()(ast_manager & m, unsigned num_source, proof * const * source, proof_ref & result) {
|
||||
proof_ref operator()(ast_manager & m, unsigned num_source, proof * const * source) override {
|
||||
proof_ref tmp(m);
|
||||
this->m_c2->operator()(m, num_source, source, tmp);
|
||||
tmp = this->m_c2->operator()(m, num_source, source);
|
||||
proof * new_source = tmp.get();
|
||||
this->m_c1->operator()(m, 1, &new_source, result);
|
||||
return this->m_c1->operator()(m, 1, &new_source);
|
||||
}
|
||||
|
||||
virtual proof_converter * translate(ast_translation & translator) {
|
||||
proof_converter * translate(ast_translation & translator) override {
|
||||
return this->translate_core<concat_proof_converter>(translator);
|
||||
}
|
||||
};
|
||||
|
@ -45,66 +46,39 @@ proof_converter * concat(proof_converter * pc1, proof_converter * pc2) {
|
|||
return alloc(concat_proof_converter, pc1, pc2);
|
||||
}
|
||||
|
||||
class concat_star_proof_converter : public concat_star_converter<proof_converter> {
|
||||
class subgoal_proof_converter : public proof_converter {
|
||||
proof_converter_ref m_pc;
|
||||
goal_ref_buffer m_goals;
|
||||
public:
|
||||
concat_star_proof_converter(proof_converter * pc1, unsigned num, proof_converter * const * pc2s, unsigned * szs):
|
||||
concat_star_converter<proof_converter>(pc1, num, pc2s, szs) {
|
||||
subgoal_proof_converter(proof_converter* pc, unsigned n, goal * const* goals):
|
||||
m_pc(pc)
|
||||
{
|
||||
for (unsigned i = 0; i < n; ++i) m_goals.push_back(goals[i]);
|
||||
}
|
||||
|
||||
virtual char const * get_name() const { return "concat-star-proof-converter"; }
|
||||
|
||||
virtual void operator()(ast_manager & m, unsigned num_source, proof * const * source, proof_ref & result) {
|
||||
unsigned num = this->m_szs.size();
|
||||
#ifdef Z3DEBUG
|
||||
unsigned sum = 0;
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
sum += this->m_szs[i];
|
||||
}
|
||||
SASSERT(sum == num_source);
|
||||
#endif
|
||||
proof_ref_buffer tmp_prs(m);
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
unsigned sz = m_szs[i];
|
||||
proof_converter * c2 = m_c2s[i];
|
||||
proof_ref pr(m);
|
||||
if (c2) {
|
||||
(*c2)(m, sz, source, pr);
|
||||
}
|
||||
else {
|
||||
SASSERT(sz == 1);
|
||||
pr = *source;
|
||||
}
|
||||
source += sz;
|
||||
tmp_prs.push_back(pr.get());
|
||||
}
|
||||
if (m_c1) {
|
||||
(*m_c1)(m, tmp_prs.size(), tmp_prs.c_ptr(), result);
|
||||
}
|
||||
else {
|
||||
SASSERT(tmp_prs.size() == 1);
|
||||
result = tmp_prs[0];
|
||||
proof_ref operator()(ast_manager & m, unsigned num_source, proof * const * source) override {
|
||||
// ignore the proofs from the arguments, instead obtain the proofs fromt he subgoals.
|
||||
SASSERT(num_source == 0);
|
||||
proof_converter_ref_buffer pc_buffer;
|
||||
for (goal_ref g : m_goals) {
|
||||
pc_buffer.push_back(g->pc());
|
||||
}
|
||||
return apply(m, m_pc, pc_buffer);
|
||||
}
|
||||
|
||||
virtual proof_converter * translate(ast_translation & translator) {
|
||||
return this->translate_core<concat_star_proof_converter>(translator);
|
||||
proof_converter* translate(ast_translation& tr) override {
|
||||
proof_converter_ref pc1 = m_pc->translate(tr);
|
||||
goal_ref_buffer goals;
|
||||
for (goal_ref g : m_goals) goals.push_back(g->translate(tr));
|
||||
return alloc(subgoal_proof_converter, pc1.get(), goals.size(), goals.c_ptr());
|
||||
}
|
||||
|
||||
void display(std::ostream& out) override {}
|
||||
|
||||
};
|
||||
|
||||
proof_converter * concat(proof_converter * pc1, unsigned num, proof_converter * const * pc2s, unsigned * szs) {
|
||||
SASSERT(num > 0);
|
||||
if (num == 1)
|
||||
return concat(pc1, pc2s[0]);
|
||||
unsigned i;
|
||||
for (i = 0; i < num; i++) {
|
||||
if (pc2s[i] != 0)
|
||||
break;
|
||||
}
|
||||
if (i == num) {
|
||||
// all pc2s are 0
|
||||
return pc1;
|
||||
}
|
||||
return alloc(concat_star_proof_converter, pc1, num, pc2s, szs);
|
||||
proof_converter * concat(proof_converter *pc, unsigned n, goal* const* goals) {
|
||||
return alloc(subgoal_proof_converter, pc, n, goals);
|
||||
}
|
||||
|
||||
class proof2pc : public proof_converter {
|
||||
|
@ -113,16 +87,16 @@ public:
|
|||
proof2pc(ast_manager & m, proof * pr):m_pr(pr, m) {}
|
||||
virtual ~proof2pc() {}
|
||||
|
||||
virtual void operator()(ast_manager & m, unsigned num_source, proof * const * source, proof_ref & result) {
|
||||
proof_ref operator()(ast_manager & m, unsigned num_source, proof * const * source) override {
|
||||
SASSERT(num_source == 0);
|
||||
result = m_pr;
|
||||
return m_pr;
|
||||
}
|
||||
|
||||
virtual proof_converter * translate(ast_translation & translator) {
|
||||
proof_converter * translate(ast_translation & translator) override {
|
||||
return alloc(proof2pc, translator.to(), translator(m_pr.get()));
|
||||
}
|
||||
|
||||
virtual void display(std::ostream & out) {
|
||||
void display(std::ostream & out) override {
|
||||
out << "(proof->proof-converter-wrapper\n" << mk_ismt2_pp(m_pr.get(), m_pr.get_manager()) << ")\n";
|
||||
}
|
||||
};
|
||||
|
@ -136,7 +110,7 @@ proof_converter * proof2proof_converter(ast_manager & m, proof * pr) {
|
|||
void apply(ast_manager & m, proof_converter * pc, proof_ref & pr) {
|
||||
if (pc) {
|
||||
proof * _pr = pr.get();
|
||||
(*pc)(m, 1, &_pr, pr);
|
||||
pr = (*pc)(m, 1, &_pr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,15 +122,15 @@ void apply(ast_manager & m, proof_converter * pc, proof_ref & pr) {
|
|||
|
||||
pc1 and pc2s must be different from 0.
|
||||
*/
|
||||
void apply(ast_manager & m, proof_converter_ref & pc1, proof_converter_ref_buffer & pc2s, proof_ref & result) {
|
||||
proof_ref apply(ast_manager & m, proof_converter_ref & pc1, proof_converter_ref_buffer & pc2s) {
|
||||
SASSERT(pc1);
|
||||
proof_ref_buffer prs(m);
|
||||
unsigned sz = pc2s.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
proof_ref pr(m);
|
||||
SASSERT(pc2s[i]); // proof production is enabled
|
||||
pc2s[i]->operator()(m, 0, 0, pr);
|
||||
pr = pc2s[i]->operator()(m, 0, 0);
|
||||
prs.push_back(pr);
|
||||
}
|
||||
(*pc1)(m, sz, prs.c_ptr(), result);
|
||||
return (*pc1)(m, sz, prs.c_ptr());
|
||||
}
|
||||
|
|
|
@ -20,33 +20,34 @@ Notes:
|
|||
#define PROOF_CONVERTER_H_
|
||||
|
||||
#include "ast/ast.h"
|
||||
#include "tactic/converter.h"
|
||||
#include "util/ref.h"
|
||||
#include "tactic/converter.h"
|
||||
class goal;
|
||||
|
||||
class proof_converter : public converter {
|
||||
public:
|
||||
virtual ~proof_converter() { }
|
||||
virtual void operator()(ast_manager & m, unsigned num_source, proof * const * source, proof_ref & result) = 0;
|
||||
virtual proof_ref operator()(ast_manager & m, unsigned num_source, proof * const * source) = 0;
|
||||
virtual proof_converter * translate(ast_translation & translator) = 0;
|
||||
};
|
||||
|
||||
typedef ref<proof_converter> proof_converter_ref;
|
||||
typedef sref_vector<proof_converter> proof_converter_ref_vector;
|
||||
typedef sref_buffer<proof_converter> proof_converter_ref_buffer;
|
||||
|
||||
|
||||
proof_converter * concat(proof_converter * pc1, proof_converter * pc2);
|
||||
|
||||
/**
|
||||
\brief \c pc1 is the proof converter for a sequence of subgoals of size \c num.
|
||||
Given an i in [0, num), pc2s[i] is the proof converter for subgoal i,
|
||||
and num_subgoals[i] is the number of subgoals of subgoals[i].
|
||||
*/
|
||||
proof_converter * concat(proof_converter * pc1, unsigned num, proof_converter * const * pc2s, unsigned * num_subgoals);
|
||||
\brief create a proof converter that takes a set of subgoals and converts their proofs to a proof of
|
||||
the goal they were derived from.
|
||||
*/
|
||||
proof_converter * concat(proof_converter *pc1, unsigned n, goal* const* goals);
|
||||
|
||||
proof_converter * proof2proof_converter(ast_manager & m, proof * pr);
|
||||
|
||||
typedef sref_vector<proof_converter> proof_converter_ref_vector;
|
||||
typedef sref_buffer<proof_converter> proof_converter_ref_buffer;
|
||||
|
||||
void apply(ast_manager & m, proof_converter_ref & pc1, proof_converter_ref_buffer & pc2s, proof_ref & result);
|
||||
void apply(ast_manager & m, proof_converter * pc, proof_ref & pr);
|
||||
|
||||
proof_ref apply(ast_manager & m, proof_converter_ref & pc1, proof_converter_ref_buffer & pc2s);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -53,8 +53,7 @@ public:
|
|||
};
|
||||
|
||||
|
||||
void replace_proof_converter::operator()(ast_manager & m, unsigned num_source,
|
||||
proof * const * source, proof_ref & result) {
|
||||
proof_ref replace_proof_converter::operator()(ast_manager & m, unsigned num_source, proof * const * source) {
|
||||
SASSERT(num_source == 1);
|
||||
replace_map replace(m);
|
||||
proof_ref p(m);
|
||||
|
@ -73,14 +72,12 @@ void replace_proof_converter::operator()(ast_manager & m, unsigned num_source,
|
|||
replace.apply(tmp);
|
||||
TRACE("proof_converter", tout << mk_pp(source[0], m) << "\n";
|
||||
tout << mk_pp(tmp.get(), m) << "\n";);
|
||||
result = to_app(tmp);
|
||||
return proof_ref(to_app(tmp), m);
|
||||
}
|
||||
|
||||
proof_converter * replace_proof_converter::translate(ast_translation & translator) {
|
||||
replace_proof_converter* rp = alloc(replace_proof_converter, m);
|
||||
for (unsigned i = 0; i < m_proofs.size(); ++i) {
|
||||
rp->insert(translator(m_proofs[i].get()));
|
||||
}
|
||||
for (proof* p : m_proofs) rp->insert(translator(p));
|
||||
return rp;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,9 +34,9 @@ public:
|
|||
|
||||
virtual ~replace_proof_converter() {}
|
||||
|
||||
virtual void operator()(ast_manager & _m, unsigned num_source, proof * const * source, proof_ref & result);
|
||||
proof_ref operator()(ast_manager & _m, unsigned num_source, proof * const * source) override;
|
||||
|
||||
virtual proof_converter * translate(ast_translation & translator);
|
||||
proof_converter * translate(ast_translation & translator) override;
|
||||
|
||||
void insert(proof* p) { m_proofs.push_back(p); }
|
||||
|
||||
|
@ -45,7 +45,7 @@ public:
|
|||
// run the replacements the inverse direction.
|
||||
void invert() { m_proofs.reverse(); }
|
||||
|
||||
virtual void display(std::ostream & out) {}
|
||||
void display(std::ostream & out) override {}
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -46,13 +46,7 @@ public:
|
|||
virtual void collect_param_descrs(param_descrs & r) {
|
||||
}
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
mc = 0; pc = 0; core = 0;
|
||||
|
||||
void operator()(goal_ref const & g, goal_ref_buffer& result) override {
|
||||
TRACE("sine", g->display(tout););
|
||||
TRACE("sine", tout << g->size(););
|
||||
ptr_vector<expr> new_forms;
|
||||
|
@ -67,8 +61,6 @@ public:
|
|||
result.push_back(g.get());
|
||||
TRACE("sine", result[0]->display(tout););
|
||||
SASSERT(g->is_well_sorted());
|
||||
generic_model_converter * fmc = alloc(generic_model_converter, m);
|
||||
mc = fmc;
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
|
|
|
@ -60,18 +60,16 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0; result.reset();
|
||||
result.reset();
|
||||
|
||||
TRACE("sls", g->display(tout););
|
||||
tactic_report report("sls", *g);
|
||||
|
||||
model_converter_ref mc;
|
||||
m_engine->operator()(g, mc);
|
||||
|
||||
g->add(mc.get());
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
TRACE("sls", g->display(tout););
|
||||
|
|
|
@ -11,7 +11,6 @@ z3_add_component(smtlogic_tactics
|
|||
qfnra_tactic.cpp
|
||||
qfufbv_ackr_model_converter.cpp
|
||||
qfufbv_tactic.cpp
|
||||
qfufnra_tactic.cpp
|
||||
qfuf_tactic.cpp
|
||||
quant_tactics.cpp
|
||||
COMPONENT_DEPENDENCIES
|
||||
|
@ -22,7 +21,6 @@ z3_add_component(smtlogic_tactics
|
|||
fp
|
||||
muz
|
||||
nlsat_tactic
|
||||
nlsat_smt_tactic
|
||||
qe
|
||||
sat_solver
|
||||
smt_tactic
|
||||
|
@ -40,6 +38,5 @@ z3_add_component(smtlogic_tactics
|
|||
qfnra_tactic.h
|
||||
qfuf_tactic.h
|
||||
qfufbv_tactic.h
|
||||
qfufnra_tactic.h
|
||||
quant_tactics.h
|
||||
)
|
||||
|
|
|
@ -54,11 +54,7 @@ public:
|
|||
virtual ~qfufbv_ackr_tactic() { }
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
mc = 0;
|
||||
goal_ref_buffer & result) {
|
||||
ast_manager& m(g->m());
|
||||
tactic_report report("qfufbv_ackr", *g);
|
||||
fail_if_unsat_core_generation("qfufbv_ackr", g);
|
||||
|
@ -80,7 +76,7 @@ public:
|
|||
// report model
|
||||
if (g->models_enabled() && (o == l_true)) {
|
||||
model_ref abstr_model = imp->get_model();
|
||||
mc = mk_qfufbv_ackr_model_converter(m, imp->get_info(), abstr_model);
|
||||
g->add(mk_qfufbv_ackr_model_converter(m, imp->get_info(), abstr_model));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -67,16 +67,8 @@ void report_tactic_progress(char const * id, unsigned val) {
|
|||
}
|
||||
}
|
||||
|
||||
void skip_tactic::operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
result.reset();
|
||||
void skip_tactic::operator()(goal_ref const & in, goal_ref_buffer& result) {
|
||||
result.push_back(in.get());
|
||||
mc = 0;
|
||||
pc = 0;
|
||||
core = 0;
|
||||
}
|
||||
|
||||
tactic * mk_skip_tactic() {
|
||||
|
@ -85,17 +77,13 @@ tactic * mk_skip_tactic() {
|
|||
|
||||
class fail_tactic : public tactic {
|
||||
public:
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & in, goal_ref_buffer & result) override {
|
||||
throw tactic_exception("fail tactic");
|
||||
}
|
||||
|
||||
virtual void cleanup() {}
|
||||
void cleanup() override {}
|
||||
|
||||
virtual tactic * translate(ast_manager & m) { return this; }
|
||||
tactic * translate(ast_manager & m) override { return this; }
|
||||
};
|
||||
|
||||
tactic * mk_fail_tactic() {
|
||||
|
@ -108,13 +96,9 @@ class report_verbose_tactic : public skip_tactic {
|
|||
public:
|
||||
report_verbose_tactic(char const * msg, unsigned lvl) : m_msg(msg), m_lvl(lvl) {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & in, goal_ref_buffer& result) override {
|
||||
IF_VERBOSE(m_lvl, verbose_stream() << m_msg << "\n";);
|
||||
skip_tactic::operator()(in, result, mc, pc, core);
|
||||
skip_tactic::operator()(in, result);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -127,14 +111,10 @@ class trace_tactic : public skip_tactic {
|
|||
public:
|
||||
trace_tactic(char const * tag): m_tag(tag) {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & in, goal_ref_buffer& result) override {
|
||||
TRACE(m_tag, in->display(tout););
|
||||
(void)m_tag;
|
||||
skip_tactic::operator()(in, result, mc, pc, core);
|
||||
skip_tactic::operator()(in, result);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -146,14 +126,10 @@ class fail_if_undecided_tactic : public skip_tactic {
|
|||
public:
|
||||
fail_if_undecided_tactic() {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & in, goal_ref_buffer& result) override {
|
||||
if (!in->is_decided())
|
||||
throw tactic_exception("undecided");
|
||||
skip_tactic::operator()(in, result, mc, pc, core);
|
||||
skip_tactic::operator()(in, result);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -161,10 +137,10 @@ tactic * mk_fail_if_undecided_tactic() {
|
|||
return alloc(fail_if_undecided_tactic);
|
||||
}
|
||||
|
||||
void exec(tactic & t, goal_ref const & in, goal_ref_buffer & result, model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) {
|
||||
void exec(tactic & t, goal_ref const & in, goal_ref_buffer & result) {
|
||||
t.reset_statistics();
|
||||
try {
|
||||
t(in, result, mc, pc, core);
|
||||
t(in, result);
|
||||
t.cleanup();
|
||||
}
|
||||
catch (tactic_exception & ex) {
|
||||
|
@ -175,7 +151,7 @@ void exec(tactic & t, goal_ref const & in, goal_ref_buffer & result, model_conve
|
|||
}
|
||||
|
||||
|
||||
lbool check_sat(tactic & t, goal_ref & g, model_ref & md, model_converter_ref& mc, labels_vec & labels, proof_ref & pr, expr_dependency_ref & core, std::string & reason_unknown) {
|
||||
lbool check_sat(tactic & t, goal_ref & g, model_ref & md, labels_vec & labels, proof_ref & pr, expr_dependency_ref & core, std::string & reason_unknown) {
|
||||
bool models_enabled = g->models_enabled();
|
||||
bool proofs_enabled = g->proofs_enabled();
|
||||
bool cores_enabled = g->unsat_core_enabled();
|
||||
|
@ -184,23 +160,21 @@ lbool check_sat(tactic & t, goal_ref & g, model_ref & md, model_converter_ref& m
|
|||
core = 0;
|
||||
ast_manager & m = g->m();
|
||||
goal_ref_buffer r;
|
||||
proof_converter_ref pc;
|
||||
try {
|
||||
exec(t, g, r, mc, pc, core);
|
||||
exec(t, g, r);
|
||||
}
|
||||
catch (tactic_exception & ex) {
|
||||
reason_unknown = ex.msg();
|
||||
return l_undef;
|
||||
}
|
||||
TRACE("tactic_mc", mc->display(tout););
|
||||
TRACE("tactic_check_sat",
|
||||
tout << "r.size(): " << r.size() << "\n";
|
||||
for (unsigned i = 0; i < r.size(); i++) r[i]->display(tout););
|
||||
|
||||
if (is_decided_sat(r)) {
|
||||
if (models_enabled) {
|
||||
if (mc)
|
||||
(*mc)(labels, 0);
|
||||
model_converter_ref mc = r[0]->mc();
|
||||
if (mc.get()) {
|
||||
(*mc)(labels);
|
||||
model_converter2model(m, mc.get(), md);
|
||||
if (!md) {
|
||||
// create empty model.
|
||||
|
@ -217,10 +191,11 @@ lbool check_sat(tactic & t, goal_ref & g, model_ref & md, model_converter_ref& m
|
|||
return l_false;
|
||||
}
|
||||
else {
|
||||
if (models_enabled) {
|
||||
if (models_enabled && r.size() >= 1) {
|
||||
model_converter_ref mc = r[0]->mc();
|
||||
model_converter2model(m, mc.get(), md);
|
||||
if (mc)
|
||||
(*mc)(labels, 0);
|
||||
(*mc)(labels);
|
||||
}
|
||||
reason_unknown = "incomplete";
|
||||
return l_undef;
|
||||
|
|
|
@ -24,8 +24,6 @@ Notes:
|
|||
#include "tactic/goal.h"
|
||||
#include "util/params.h"
|
||||
#include "util/statistics.h"
|
||||
#include "tactic/model_converter.h"
|
||||
#include "tactic/proof_converter.h"
|
||||
#include "tactic/tactic_exception.h"
|
||||
#include "util/lbool.h"
|
||||
|
||||
|
@ -50,19 +48,7 @@ public:
|
|||
|
||||
The list of resultant subgoals is stored in \c result.
|
||||
The content of \c in may be destroyed during the operation.
|
||||
|
||||
The resultant model converter \c mc can be used to convert a model for one of the returned subgoals
|
||||
into a model for \in. If mc == 0, then model construction is disabled or any model for a subgoal
|
||||
of \c in is also a model for \c in.
|
||||
If \c result is decided_sat (i.e., it contains a single empty subgoal), then
|
||||
the model converter is just wrapping the model.
|
||||
|
||||
The resultant proof converter \c pc can be used to convert proofs for each subgoal in \c result
|
||||
into a proof for \c in. If pc == 0, then one of the following conditions should hold:
|
||||
1- proof construction is disabled,
|
||||
2- result contains a single subgoal, and any proof of unsatisfiability for this subgoal is a proof for \c in.
|
||||
3- result is an decided_unsat (i.e., it contains a single unsat subgoal). The actual proof can be extracted from this goal.
|
||||
|
||||
|
||||
The output parameter \c core is used to accumulate the unsat core of closed subgoals.
|
||||
It must be 0 if dependency tracking is disabled, or the result is decided unsat, or
|
||||
no tagged assertions were used to close any subgoal.
|
||||
|
@ -75,11 +61,7 @@ public:
|
|||
|
||||
Therefore, in most cases, pc == 0 and core == 0 for non-branching tactics.
|
||||
*/
|
||||
virtual void operator()(/* in */ goal_ref const & in,
|
||||
/* out */ goal_ref_buffer & result,
|
||||
/* out */ model_converter_ref & mc,
|
||||
/* out */ proof_converter_ref & pc,
|
||||
/* out */ expr_dependency_ref & core) = 0;
|
||||
virtual void operator()(goal_ref const & in, goal_ref_buffer& result) = 0;
|
||||
|
||||
virtual void collect_statistics(statistics & st) const {}
|
||||
virtual void reset_statistics() {}
|
||||
|
@ -119,9 +101,9 @@ void report_tactic_progress(char const * id, unsigned val);
|
|||
|
||||
class skip_tactic : public tactic {
|
||||
public:
|
||||
virtual void operator()(goal_ref const & in, goal_ref_buffer & result, model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core);
|
||||
virtual void cleanup() {}
|
||||
virtual tactic * translate(ast_manager & m) { return this; }
|
||||
void operator()(goal_ref const & in, goal_ref_buffer& result) override;
|
||||
void cleanup() override {}
|
||||
tactic * translate(ast_manager & m) override { return this; }
|
||||
};
|
||||
|
||||
tactic * mk_skip_tactic();
|
||||
|
@ -152,8 +134,8 @@ public:
|
|||
|
||||
#define MK_SIMPLE_TACTIC_FACTORY(NAME, ST) MK_TACTIC_FACTORY(NAME, return ST;)
|
||||
|
||||
void exec(tactic & t, goal_ref const & in, goal_ref_buffer & result, model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core);
|
||||
lbool check_sat(tactic & t, goal_ref & g, model_ref & md, model_converter_ref& mc, labels_vec & labels, proof_ref & pr, expr_dependency_ref & core, std::string & reason_unknown);
|
||||
void exec(tactic & t, goal_ref const & in, goal_ref_buffer & result);
|
||||
lbool check_sat(tactic & t, goal_ref & g, model_ref & md, labels_vec & labels, proof_ref & pr, expr_dependency_ref & core, std::string & reason_unknown);
|
||||
|
||||
// Throws an exception if goal \c in requires proof generation.
|
||||
void fail_if_proof_generation(char const * tactic_name, goal_ref const & in);
|
||||
|
|
|
@ -16,33 +16,28 @@ Author:
|
|||
Notes:
|
||||
|
||||
--*/
|
||||
#include "tactic/tactical.h"
|
||||
#include "util/scoped_timer.h"
|
||||
#include "util/cancel_eh.h"
|
||||
#include "util/cooperate.h"
|
||||
#include "util/scoped_ptr_vector.h"
|
||||
#include "util/z3_omp.h"
|
||||
#include "tactic/tactical.h"
|
||||
|
||||
class binary_tactical : public tactic {
|
||||
protected:
|
||||
tactic * m_t1;
|
||||
tactic * m_t2;
|
||||
|
||||
tactic_ref m_t1;
|
||||
tactic_ref m_t2;
|
||||
|
||||
public:
|
||||
|
||||
binary_tactical(tactic * t1, tactic * t2):
|
||||
m_t1(t1),
|
||||
m_t2(t2) {
|
||||
SASSERT(m_t1);
|
||||
SASSERT(m_t2);
|
||||
m_t1->inc_ref();
|
||||
m_t2->inc_ref();
|
||||
}
|
||||
|
||||
virtual ~binary_tactical() {
|
||||
m_t1->dec_ref();
|
||||
m_t2->dec_ref();
|
||||
}
|
||||
virtual ~binary_tactical() {}
|
||||
|
||||
virtual void updt_params(params_ref const & p) {
|
||||
m_t1->updt_params(p);
|
||||
|
@ -106,108 +101,63 @@ public:
|
|||
and_then_tactical(tactic * t1, tactic * t2):binary_tactical(t1, t2) {}
|
||||
virtual ~and_then_tactical() {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & in, goal_ref_buffer& result) override {
|
||||
|
||||
bool models_enabled = in->models_enabled();
|
||||
bool proofs_enabled = in->proofs_enabled();
|
||||
bool cores_enabled = in->unsat_core_enabled();
|
||||
|
||||
ast_manager & m = in->m();
|
||||
goal_ref_buffer r1;
|
||||
model_converter_ref mc1;
|
||||
proof_converter_ref pc1;
|
||||
expr_dependency_ref core1(m);
|
||||
result.reset();
|
||||
mc = 0;
|
||||
pc = 0;
|
||||
core = 0;
|
||||
m_t1->operator()(in, r1, mc1, pc1, core1);
|
||||
SASSERT(!is_decided(r1) || (!pc1 && !core1)); // the pc and core of decided goals is 0
|
||||
ast_manager & m = in->m();
|
||||
goal_ref_buffer r1;
|
||||
m_t1->operator()(in, r1);
|
||||
unsigned r1_size = r1.size();
|
||||
SASSERT(r1_size > 0);
|
||||
SASSERT(r1_size > 0);
|
||||
if (r1_size == 1) {
|
||||
if (r1[0]->is_decided()) {
|
||||
result.push_back(r1[0]);
|
||||
if (models_enabled) mc = mc1;
|
||||
return;
|
||||
result.push_back(r1[0]);
|
||||
return;
|
||||
}
|
||||
goal_ref r1_0 = r1[0];
|
||||
m_t2->operator()(r1_0, result, mc, pc, core);
|
||||
if (models_enabled) mc = concat(mc1.get(), mc.get());
|
||||
if (proofs_enabled) pc = concat(pc1.get(), pc.get());
|
||||
if (cores_enabled) core = m.mk_join(core1.get(), core);
|
||||
m_t2->operator()(r1_0, result);
|
||||
}
|
||||
else {
|
||||
if (cores_enabled) core = core1;
|
||||
proof_converter_ref_buffer pc_buffer;
|
||||
model_converter_ref_buffer mc_buffer;
|
||||
sbuffer<unsigned> sz_buffer;
|
||||
goal_ref_buffer r2;
|
||||
goal_ref_buffer r2;
|
||||
for (unsigned i = 0; i < r1_size; i++) {
|
||||
goal_ref g = r1[i];
|
||||
r2.reset();
|
||||
model_converter_ref mc2;
|
||||
proof_converter_ref pc2;
|
||||
expr_dependency_ref core2(m);
|
||||
m_t2->operator()(g, r2, mc2, pc2, core2);
|
||||
goal_ref g = r1[i];
|
||||
r2.reset();
|
||||
m_t2->operator()(g, r2);
|
||||
if (is_decided(r2)) {
|
||||
SASSERT(r2.size() == 1);
|
||||
if (is_decided_sat(r2)) {
|
||||
// found solution...
|
||||
// found solution...
|
||||
result.reset();
|
||||
result.push_back(r2[0]);
|
||||
if (models_enabled) {
|
||||
// mc2 contains the actual model
|
||||
model_ref md;
|
||||
md = alloc(model, m);
|
||||
apply(mc2, md, 0);
|
||||
apply(mc1, md, i);
|
||||
mc = model2model_converter(md.get());
|
||||
}
|
||||
SASSERT(!pc); SASSERT(!core);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
SASSERT(is_decided_unsat(r2));
|
||||
// the proof and unsat core of a decided_unsat goal are stored in the node itself.
|
||||
// pc2 and core2 must be 0.
|
||||
SASSERT(!pc2);
|
||||
SASSERT(!core2);
|
||||
if (models_enabled) mc_buffer.push_back(0);
|
||||
if (proofs_enabled) pc_buffer.push_back(proof2proof_converter(m, r2[0]->pr(0)));
|
||||
if (models_enabled || proofs_enabled) sz_buffer.push_back(0);
|
||||
if (cores_enabled) core = m.mk_join(core.get(), r2[0]->dep(0));
|
||||
}
|
||||
}
|
||||
else {
|
||||
result.append(r2.size(), r2.c_ptr());
|
||||
if (models_enabled) mc_buffer.push_back(mc2.get());
|
||||
if (proofs_enabled) pc_buffer.push_back(pc2.get());
|
||||
if (models_enabled || proofs_enabled) sz_buffer.push_back(r2.size());
|
||||
if (cores_enabled) core = m.mk_join(core.get(), core2.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (result.empty()) {
|
||||
// all subgoals were shown to be unsat.
|
||||
// create an decided_unsat goal with the proof
|
||||
in->reset_all();
|
||||
proof_ref pr(m);
|
||||
if (proofs_enabled)
|
||||
apply(m, pc1, pc_buffer, pr);
|
||||
SASSERT(cores_enabled || core == 0);
|
||||
expr_dependency_ref core(m);
|
||||
if (proofs_enabled) {
|
||||
apply(m, in->pc(), pr);
|
||||
}
|
||||
dependency_converter* dc = in->dc();
|
||||
if (cores_enabled && dc) {
|
||||
core = (*dc)();
|
||||
}
|
||||
in->assert_expr(m.mk_false(), pr, core);
|
||||
core = 0;
|
||||
result.push_back(in.get());
|
||||
SASSERT(!mc); SASSERT(!pc); SASSERT(!core);
|
||||
}
|
||||
else {
|
||||
if (models_enabled) mc = concat(mc1.get(), mc_buffer.size(), mc_buffer.c_ptr(), sz_buffer.c_ptr());
|
||||
if (proofs_enabled) pc = concat(pc1.get(), pc_buffer.size(), pc_buffer.c_ptr(), sz_buffer.c_ptr());
|
||||
SASSERT(cores_enabled || core == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -271,92 +221,58 @@ tactic * and_then(unsigned num, tactic * const * ts) {
|
|||
|
||||
class nary_tactical : public tactic {
|
||||
protected:
|
||||
ptr_vector<tactic> m_ts;
|
||||
sref_vector<tactic> m_ts;
|
||||
|
||||
public:
|
||||
nary_tactical(unsigned num, tactic * const * ts) {
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
SASSERT(ts[i]);
|
||||
m_ts.push_back(ts[i]);
|
||||
ts[i]->inc_ref();
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~nary_tactical() {
|
||||
unsigned sz = m_ts.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
m_ts[i]->dec_ref();
|
||||
}
|
||||
}
|
||||
virtual ~nary_tactical() {}
|
||||
|
||||
virtual void updt_params(params_ref const & p) {
|
||||
void updt_params(params_ref const & p) override {
|
||||
TRACE("nary_tactical_updt_params", tout << "updt_params: " << p << "\n";);
|
||||
ptr_vector<tactic>::iterator it = m_ts.begin();
|
||||
ptr_vector<tactic>::iterator end = m_ts.end();
|
||||
for (; it != end; ++it)
|
||||
(*it)->updt_params(p);
|
||||
for (tactic* t : m_ts) t->updt_params(p);
|
||||
}
|
||||
|
||||
virtual void collect_param_descrs(param_descrs & r) {
|
||||
ptr_vector<tactic>::iterator it = m_ts.begin();
|
||||
ptr_vector<tactic>::iterator end = m_ts.end();
|
||||
for (; it != end; ++it)
|
||||
(*it)->collect_param_descrs(r);
|
||||
void collect_param_descrs(param_descrs & r) override {
|
||||
for (tactic* t : m_ts) t->collect_param_descrs(r);
|
||||
}
|
||||
|
||||
virtual void collect_statistics(statistics & st) const {
|
||||
ptr_vector<tactic>::const_iterator it = m_ts.begin();
|
||||
ptr_vector<tactic>::const_iterator end = m_ts.end();
|
||||
for (; it != end; ++it)
|
||||
(*it)->collect_statistics(st);
|
||||
void collect_statistics(statistics & st) const override {
|
||||
for (tactic const* t : m_ts) t->collect_statistics(st);
|
||||
}
|
||||
|
||||
virtual void reset_statistics() {
|
||||
ptr_vector<tactic>::const_iterator it = m_ts.begin();
|
||||
ptr_vector<tactic>::const_iterator end = m_ts.end();
|
||||
for (; it != end; ++it)
|
||||
(*it)->reset_statistics();
|
||||
void reset_statistics() override {
|
||||
for (tactic* t : m_ts) t->reset_statistics();
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
ptr_vector<tactic>::iterator it = m_ts.begin();
|
||||
ptr_vector<tactic>::iterator end = m_ts.end();
|
||||
for (; it != end; ++it)
|
||||
(*it)->cleanup();
|
||||
void cleanup() override {
|
||||
for (tactic* t : m_ts) t->cleanup();
|
||||
}
|
||||
|
||||
virtual void reset() {
|
||||
ptr_vector<tactic>::iterator it = m_ts.begin();
|
||||
ptr_vector<tactic>::iterator end = m_ts.end();
|
||||
for (; it != end; ++it)
|
||||
(*it)->reset();
|
||||
void reset() override {
|
||||
for (tactic* t : m_ts) t->reset();
|
||||
}
|
||||
|
||||
virtual void set_logic(symbol const & l) {
|
||||
ptr_vector<tactic>::iterator it = m_ts.begin();
|
||||
ptr_vector<tactic>::iterator end = m_ts.end();
|
||||
for (; it != end; ++it)
|
||||
(*it)->set_logic(l);
|
||||
void set_logic(symbol const & l) override {
|
||||
for (tactic* t : m_ts) t->set_logic(l);
|
||||
}
|
||||
|
||||
virtual void set_progress_callback(progress_callback * callback) {
|
||||
ptr_vector<tactic>::iterator it = m_ts.begin();
|
||||
ptr_vector<tactic>::iterator end = m_ts.end();
|
||||
for (; it != end; ++it)
|
||||
(*it)->set_progress_callback(callback);
|
||||
void set_progress_callback(progress_callback * callback) override {
|
||||
for (tactic* t : m_ts) t->set_progress_callback(callback);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
template<typename T>
|
||||
tactic * translate_core(ast_manager & m) {
|
||||
ptr_buffer<tactic> new_ts;
|
||||
ptr_vector<tactic>::iterator it = m_ts.begin();
|
||||
ptr_vector<tactic>::iterator end = m_ts.end();
|
||||
for (; it != end; ++it) {
|
||||
tactic * curr = *it;
|
||||
tactic * new_curr = curr->translate(m);
|
||||
new_ts.push_back(new_curr);
|
||||
sref_vector<tactic> new_ts;
|
||||
for (tactic* curr : m_ts) {
|
||||
new_ts.push_back(curr->translate(m));
|
||||
}
|
||||
return alloc(T, new_ts.size(), new_ts.c_ptr());
|
||||
}
|
||||
|
@ -369,31 +285,24 @@ public:
|
|||
|
||||
virtual ~or_else_tactical() {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
virtual void operator()(goal_ref const & in, goal_ref_buffer& result) {
|
||||
goal orig(*(in.get()));
|
||||
unsigned sz = m_ts.size();
|
||||
unsigned i;
|
||||
for (i = 0; i < sz; i++) {
|
||||
tactic * t = m_ts[i];
|
||||
result.reset();
|
||||
mc = 0;
|
||||
pc = 0;
|
||||
core = 0;
|
||||
SASSERT(sz > 0);
|
||||
if (i < sz - 1) {
|
||||
try {
|
||||
t->operator()(in, result, mc, pc, core);
|
||||
t->operator()(in, result);
|
||||
return;
|
||||
}
|
||||
catch (tactic_exception &) {
|
||||
result.reset();
|
||||
}
|
||||
}
|
||||
else {
|
||||
t->operator()(in, result, mc, pc, core);
|
||||
t->operator()(in, result);
|
||||
return;
|
||||
}
|
||||
in->reset_all();
|
||||
|
@ -468,11 +377,7 @@ public:
|
|||
|
||||
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & in, goal_ref_buffer& result) override {
|
||||
bool use_seq;
|
||||
#ifdef _NO_OMP_
|
||||
use_seq = true;
|
||||
|
@ -481,7 +386,7 @@ public:
|
|||
#endif
|
||||
if (use_seq) {
|
||||
// execute tasks sequentially
|
||||
or_else_tactical::operator()(in, result, mc, pc, core);
|
||||
or_else_tactical::operator()(in, result);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -509,15 +414,12 @@ public:
|
|||
#pragma omp parallel for
|
||||
for (int i = 0; i < static_cast<int>(sz); i++) {
|
||||
goal_ref_buffer _result;
|
||||
model_converter_ref _mc;
|
||||
proof_converter_ref _pc;
|
||||
expr_dependency_ref _core(*(managers[i]));
|
||||
|
||||
goal_ref in_copy = in_copies[i];
|
||||
tactic & t = *(ts.get(i));
|
||||
|
||||
try {
|
||||
t(in_copy, _result, _mc, _pc, _core);
|
||||
t(in_copy, _result);
|
||||
bool first = false;
|
||||
#pragma omp critical (par_tactical)
|
||||
{
|
||||
|
@ -533,13 +435,11 @@ public:
|
|||
}
|
||||
}
|
||||
ast_translation translator(*(managers[i]), m, false);
|
||||
for (unsigned k = 0; k < _result.size(); k++) {
|
||||
result.push_back(_result[k]->translate(translator));
|
||||
for (goal* g : _result) {
|
||||
result.push_back(g->translate(translator));
|
||||
}
|
||||
mc = _mc ? _mc->translate(translator) : 0;
|
||||
pc = _pc ? _pc->translate(translator) : 0;
|
||||
expr_dependency_translation td(translator);
|
||||
core = td(_core);
|
||||
goal_ref in2(in_copy->translate(translator));
|
||||
in->copy_from(*(in2.get()));
|
||||
}
|
||||
}
|
||||
catch (tactic_exception & ex) {
|
||||
|
@ -562,7 +462,6 @@ public:
|
|||
}
|
||||
}
|
||||
if (finished_id == UINT_MAX) {
|
||||
mc = 0;
|
||||
switch (ex_kind) {
|
||||
case ERROR_EX: throw z3_error(error_code);
|
||||
case TACTIC_EX: throw tactic_exception(ex_msg.c_str());
|
||||
|
@ -599,11 +498,7 @@ public:
|
|||
par_and_then_tactical(tactic * t1, tactic * t2):and_then_tactical(t1, t2) {}
|
||||
virtual ~par_and_then_tactical() {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & in, goal_ref_buffer& result) override {
|
||||
bool use_seq;
|
||||
#ifdef _NO_OMP_
|
||||
use_seq = true;
|
||||
|
@ -612,43 +507,31 @@ public:
|
|||
#endif
|
||||
if (use_seq) {
|
||||
// execute tasks sequentially
|
||||
and_then_tactical::operator()(in, result, mc, pc, core);
|
||||
and_then_tactical::operator()(in, result);
|
||||
return;
|
||||
}
|
||||
|
||||
// enabling proofs is possible, but requires translating subgoals back.
|
||||
fail_if_proof_generation("par_and_then", in);
|
||||
bool models_enabled = in->models_enabled();
|
||||
bool proofs_enabled = in->proofs_enabled();
|
||||
bool cores_enabled = in->unsat_core_enabled();
|
||||
|
||||
ast_manager & m = in->m();
|
||||
goal_ref_buffer r1;
|
||||
model_converter_ref mc1;
|
||||
proof_converter_ref pc1;
|
||||
expr_dependency_ref core1(m);
|
||||
result.reset();
|
||||
mc = 0;
|
||||
pc = 0;
|
||||
core = 0;
|
||||
m_t1->operator()(in, r1, mc1, pc1, core1);
|
||||
SASSERT(!is_decided(r1) || (!pc1 && !core1)); // the pc and core of decided goals is 0
|
||||
unsigned r1_size = r1.size();
|
||||
goal_ref_buffer r1;
|
||||
m_t1->operator()(in, r1);
|
||||
unsigned r1_size = r1.size();
|
||||
SASSERT(r1_size > 0);
|
||||
if (r1_size == 1) {
|
||||
// Only one subgoal created... no need for parallelism
|
||||
if (r1[0]->is_decided()) {
|
||||
result.push_back(r1[0]);
|
||||
if (models_enabled) mc = mc1;
|
||||
SASSERT(!pc); SASSERT(!core);
|
||||
return;
|
||||
result.push_back(r1[0]);
|
||||
return;
|
||||
}
|
||||
goal_ref r1_0 = r1[0];
|
||||
m_t2->operator()(r1_0, result, mc, pc, core);
|
||||
if (models_enabled) mc = concat(mc1.get(), mc.get());
|
||||
if (proofs_enabled) pc = concat(pc1.get(), pc.get());
|
||||
if (cores_enabled) core = m.mk_join(core1.get(), core);
|
||||
m_t2->operator()(r1_0, result);
|
||||
}
|
||||
else {
|
||||
if (cores_enabled) core = core1;
|
||||
|
||||
scoped_ptr_vector<ast_manager> managers;
|
||||
tactic_ref_vector ts2;
|
||||
|
@ -662,13 +545,9 @@ public:
|
|||
ts2.push_back(m_t2->translate(*new_m));
|
||||
}
|
||||
|
||||
proof_converter_ref_buffer pc_buffer;
|
||||
model_converter_ref_buffer mc_buffer;
|
||||
scoped_ptr_vector<expr_dependency_ref> core_buffer;
|
||||
scoped_ptr_vector<goal_ref_buffer> goals_vect;
|
||||
|
||||
pc_buffer.resize(r1_size);
|
||||
mc_buffer.resize(r1_size);
|
||||
core_buffer.resize(r1_size);
|
||||
goals_vect.resize(r1_size);
|
||||
|
||||
|
@ -684,14 +563,11 @@ public:
|
|||
goal_ref new_g = g_copies[i];
|
||||
|
||||
goal_ref_buffer r2;
|
||||
model_converter_ref mc2;
|
||||
proof_converter_ref pc2;
|
||||
expr_dependency_ref core2(new_m);
|
||||
|
||||
bool curr_failed = false;
|
||||
|
||||
try {
|
||||
ts2[i]->operator()(new_g, r2, mc2, pc2, core2);
|
||||
ts2[i]->operator()(new_g, r2);
|
||||
}
|
||||
catch (tactic_exception & ex) {
|
||||
#pragma omp critical (par_and_then_tactical)
|
||||
|
@ -756,31 +632,12 @@ public:
|
|||
}
|
||||
ast_translation translator(new_m, m, false);
|
||||
SASSERT(r2.size() == 1);
|
||||
result.push_back(r2[0]->translate(translator));
|
||||
if (models_enabled) {
|
||||
// mc2 contains the actual model
|
||||
mc2 = mc2 ? mc2->translate(translator) : 0;
|
||||
model_ref md;
|
||||
md = alloc(model, m);
|
||||
apply(mc2, md, 0);
|
||||
apply(mc1, md, i);
|
||||
mc = model2model_converter(md.get());
|
||||
}
|
||||
SASSERT(!pc); SASSERT(!core);
|
||||
result.push_back(r2[0]->translate(translator));
|
||||
}
|
||||
}
|
||||
else {
|
||||
SASSERT(is_decided_unsat(r2));
|
||||
// the proof and unsat core of a decided_unsat goal are stored in the node itself.
|
||||
// pc2 and core2 must be 0.
|
||||
SASSERT(!pc2);
|
||||
SASSERT(!core2);
|
||||
|
||||
if (models_enabled) mc_buffer.set(i, 0);
|
||||
if (proofs_enabled) {
|
||||
proof * pr = r2[0]->pr(0);
|
||||
pc_buffer.push_back(proof2proof_converter(m, pr));
|
||||
}
|
||||
if (cores_enabled && r2[0]->dep(0) != 0) {
|
||||
expr_dependency_ref * new_dep = alloc(expr_dependency_ref, new_m);
|
||||
*new_dep = r2[0]->dep(0);
|
||||
|
@ -792,11 +649,10 @@ public:
|
|||
goal_ref_buffer * new_r2 = alloc(goal_ref_buffer);
|
||||
goals_vect.set(i, new_r2);
|
||||
new_r2->append(r2.size(), r2.c_ptr());
|
||||
mc_buffer.set(i, mc2.get());
|
||||
pc_buffer.set(i, pc2.get());
|
||||
if (cores_enabled && core2 != 0) {
|
||||
dependency_converter* dc = r1[i]->dc();
|
||||
if (cores_enabled && dc) {
|
||||
expr_dependency_ref * new_dep = alloc(expr_dependency_ref, new_m);
|
||||
*new_dep = core2;
|
||||
*new_dep = (*dc)();
|
||||
core_buffer.set(i, new_dep);
|
||||
}
|
||||
}
|
||||
|
@ -814,25 +670,22 @@ public:
|
|||
|
||||
if (found_solution)
|
||||
return;
|
||||
|
||||
core = 0;
|
||||
sbuffer<unsigned> sz_buffer;
|
||||
|
||||
expr_dependency_ref core(m);
|
||||
for (unsigned i = 0; i < r1_size; i++) {
|
||||
ast_translation translator(*(managers[i]), m, false);
|
||||
goal_ref_buffer * r = goals_vect[i];
|
||||
unsigned j = result.size();
|
||||
if (r != 0) {
|
||||
for (unsigned k = 0; k < r->size(); k++) {
|
||||
result.push_back((*r)[k]->translate(translator));
|
||||
}
|
||||
sz_buffer.push_back(r->size());
|
||||
}
|
||||
else {
|
||||
sz_buffer.push_back(0);
|
||||
if (proofs_enabled) {
|
||||
// update proof converter of r1[i]
|
||||
r1[i]->set(concat(r1[i]->pc(), result.size() - j, result.c_ptr() + j));
|
||||
}
|
||||
if (mc_buffer[i] != 0)
|
||||
mc_buffer.set(i, mc_buffer[i]->translate(translator));
|
||||
if (pc_buffer[i] != 0)
|
||||
pc_buffer.set(i, pc_buffer[i]->translate(translator));
|
||||
|
||||
expr_dependency_translation td(translator);
|
||||
if (core_buffer[i] != 0) {
|
||||
expr_dependency_ref curr_core(m);
|
||||
|
@ -840,24 +693,24 @@ public:
|
|||
core = m.mk_join(curr_core, core);
|
||||
}
|
||||
}
|
||||
if (core) {
|
||||
in->add(dependency_converter::unit(core));
|
||||
}
|
||||
|
||||
if (result.empty()) {
|
||||
// all subgoals were shown to be unsat.
|
||||
// create an decided_unsat goal with the proof
|
||||
in->reset_all();
|
||||
proof_ref pr(m);
|
||||
if (proofs_enabled)
|
||||
apply(m, pc1, pc_buffer, pr);
|
||||
SASSERT(cores_enabled || core == 0);
|
||||
if (proofs_enabled) {
|
||||
apply(m, in->pc(), pr);
|
||||
}
|
||||
dependency_converter* dc = in->dc();
|
||||
if (cores_enabled && dc) {
|
||||
core = (*dc)();
|
||||
}
|
||||
in->assert_expr(m.mk_false(), pr, core);
|
||||
core = 0;
|
||||
result.push_back(in.get());
|
||||
SASSERT(!mc); SASSERT(!pc); SASSERT(!core);
|
||||
}
|
||||
else {
|
||||
if (models_enabled) mc = concat(mc1.get(), mc_buffer.size(), mc_buffer.c_ptr(), sz_buffer.c_ptr());
|
||||
if (proofs_enabled) pc = concat(pc1.get(), pc_buffer.size(), pc_buffer.c_ptr(), sz_buffer.c_ptr());
|
||||
SASSERT(cores_enabled || core == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -885,26 +738,19 @@ tactic * par_and_then(unsigned num, tactic * const * ts) {
|
|||
|
||||
class unary_tactical : public tactic {
|
||||
protected:
|
||||
tactic * m_t;
|
||||
tactic_ref m_t;
|
||||
|
||||
|
||||
public:
|
||||
unary_tactical(tactic * t):
|
||||
m_t(t) {
|
||||
SASSERT(t);
|
||||
t->inc_ref();
|
||||
SASSERT(t);
|
||||
}
|
||||
|
||||
virtual ~unary_tactical() {
|
||||
m_t->dec_ref();
|
||||
}
|
||||
virtual ~unary_tactical() { }
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
m_t->operator()(in, result, mc, pc, core);
|
||||
void operator()(goal_ref const & in, goal_ref_buffer& result) override {
|
||||
m_t->operator()(in, result);
|
||||
}
|
||||
|
||||
virtual void cleanup(void) { m_t->cleanup(); }
|
||||
|
@ -929,16 +775,10 @@ class repeat_tactical : public unary_tactical {
|
|||
|
||||
void operator()(unsigned depth,
|
||||
goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer& result) {
|
||||
// TODO: implement a non-recursive version.
|
||||
if (depth > m_max_depth) {
|
||||
result.push_back(in.get());
|
||||
mc = 0;
|
||||
pc = 0;
|
||||
core = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -947,23 +787,14 @@ class repeat_tactical : public unary_tactical {
|
|||
bool cores_enabled = in->unsat_core_enabled();
|
||||
|
||||
ast_manager & m = in->m();
|
||||
goal_ref_buffer r1;
|
||||
model_converter_ref mc1;
|
||||
proof_converter_ref pc1;
|
||||
expr_dependency_ref core1(m);
|
||||
result.reset();
|
||||
mc = 0;
|
||||
pc = 0;
|
||||
core = 0;
|
||||
goal_ref_buffer r1;
|
||||
result.reset();
|
||||
{
|
||||
goal orig_in(in->m(), proofs_enabled, models_enabled, cores_enabled);
|
||||
orig_in.copy_from(*(in.get()));
|
||||
m_t->operator()(in, r1, mc1, pc1, core1);
|
||||
if (is_equal(orig_in, *(in.get()))) {
|
||||
result.push_back(r1[0]);
|
||||
if (models_enabled) mc = mc1;
|
||||
if (proofs_enabled) pc = pc1;
|
||||
if (cores_enabled) core = core1;
|
||||
m_t->operator()(in, r1);
|
||||
if (r1.size() == 1 && is_equal(orig_in, *(r1[0]))) {
|
||||
result.push_back(r1[0]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -971,61 +802,31 @@ class repeat_tactical : public unary_tactical {
|
|||
SASSERT(r1_size > 0);
|
||||
if (r1_size == 1) {
|
||||
if (r1[0]->is_decided()) {
|
||||
result.push_back(r1[0]);
|
||||
if (models_enabled) mc = mc1;
|
||||
SASSERT(!pc); SASSERT(!core);
|
||||
result.push_back(r1[0]);
|
||||
return;
|
||||
}
|
||||
goal_ref r1_0 = r1[0];
|
||||
operator()(depth+1, r1_0, result, mc, pc, core);
|
||||
if (models_enabled) mc = concat(mc.get(), mc1.get());
|
||||
if (proofs_enabled) pc = concat(pc.get(), pc1.get());
|
||||
if (cores_enabled) core = m.mk_join(core1.get(), core);
|
||||
operator()(depth+1, r1_0, result);
|
||||
}
|
||||
else {
|
||||
if (cores_enabled) core = core1;
|
||||
proof_converter_ref_buffer pc_buffer;
|
||||
model_converter_ref_buffer mc_buffer;
|
||||
sbuffer<unsigned> sz_buffer;
|
||||
goal_ref_buffer r2;
|
||||
for (unsigned i = 0; i < r1_size; i++) {
|
||||
goal_ref g = r1[i];
|
||||
r2.reset();
|
||||
model_converter_ref mc2;
|
||||
proof_converter_ref pc2;
|
||||
expr_dependency_ref core2(m);
|
||||
operator()(depth+1, g, r2, mc2, pc2, core2);
|
||||
r2.reset();
|
||||
operator()(depth+1, g, r2);
|
||||
if (is_decided(r2)) {
|
||||
SASSERT(r2.size() == 1);
|
||||
if (is_decided_sat(r2)) {
|
||||
// found solution...
|
||||
result.push_back(r2[0]);
|
||||
if (models_enabled) {
|
||||
// mc2 contains the actual model
|
||||
model_ref md;
|
||||
if (mc2) (*mc2)(md, 0);
|
||||
if (mc1) (*mc1)(md, i);
|
||||
mc = model2model_converter(md.get());
|
||||
}
|
||||
SASSERT(!pc); SASSERT(!core);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
SASSERT(is_decided_unsat(r2));
|
||||
SASSERT(!pc2);
|
||||
SASSERT(!core2);
|
||||
if (models_enabled) mc_buffer.push_back(0);
|
||||
if (proofs_enabled) pc_buffer.push_back(proof2proof_converter(m, r2[0]->pr(0)));
|
||||
if (models_enabled || proofs_enabled) sz_buffer.push_back(0);
|
||||
if (cores_enabled) core = m.mk_join(core.get(), r2[0]->dep(0));
|
||||
}
|
||||
}
|
||||
else {
|
||||
result.append(r2.size(), r2.c_ptr());
|
||||
if (models_enabled) mc_buffer.push_back(mc2.get());
|
||||
if (proofs_enabled) pc_buffer.push_back(pc2.get());
|
||||
if (models_enabled || proofs_enabled) sz_buffer.push_back(r2.size());
|
||||
if (cores_enabled) core = m.mk_join(core.get(), core2.get());
|
||||
result.append(r2.size(), r2.c_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1034,18 +835,15 @@ class repeat_tactical : public unary_tactical {
|
|||
// create an decided_unsat goal with the proof
|
||||
in->reset_all();
|
||||
proof_ref pr(m);
|
||||
if (proofs_enabled)
|
||||
apply(m, pc1, pc_buffer, pr);
|
||||
SASSERT(cores_enabled || core == 0);
|
||||
expr_dependency_ref core(m);
|
||||
if (proofs_enabled) {
|
||||
apply(m, in->pc(), pr);
|
||||
}
|
||||
if (cores_enabled && in->dc()) {
|
||||
core = (*in->dc())();
|
||||
}
|
||||
in->assert_expr(m.mk_false(), pr, core);
|
||||
core = 0;
|
||||
result.push_back(in.get());
|
||||
SASSERT(!mc); SASSERT(!pc); SASSERT(!core);
|
||||
}
|
||||
else {
|
||||
if (models_enabled) mc = concat(mc1.get(), mc_buffer.size(), mc_buffer.c_ptr(), sz_buffer.c_ptr());
|
||||
if (proofs_enabled) pc = concat(pc1.get(), pc_buffer.size(), pc_buffer.c_ptr(), sz_buffer.c_ptr());
|
||||
SASSERT(cores_enabled || core == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1056,12 +854,8 @@ public:
|
|||
m_max_depth(max_depth) {
|
||||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
operator()(0, in, result, mc, pc, core);
|
||||
void operator()(goal_ref const & in, goal_ref_buffer& result) override {
|
||||
operator()(0, in, result);
|
||||
}
|
||||
|
||||
virtual tactic * translate(ast_manager & m) {
|
||||
|
@ -1079,17 +873,10 @@ class fail_if_branching_tactical : public unary_tactical {
|
|||
public:
|
||||
fail_if_branching_tactical(tactic * t, unsigned threshold):unary_tactical(t), m_threshold(threshold) {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
m_t->operator()(in, result, mc, pc, core);
|
||||
void operator()(goal_ref const & in, goal_ref_buffer& result) override {
|
||||
m_t->operator()(in, result);
|
||||
if (result.size() > m_threshold) {
|
||||
result.reset();
|
||||
mc = 0;
|
||||
pc = 0;
|
||||
core = 0;
|
||||
result.reset(); // assumes in is not strenthened to one of the branches
|
||||
throw tactic_exception("failed-if-branching tactical");
|
||||
}
|
||||
};
|
||||
|
@ -1108,12 +895,8 @@ class cleanup_tactical : public unary_tactical {
|
|||
public:
|
||||
cleanup_tactical(tactic * t):unary_tactical(t) {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
m_t->operator()(in, result, mc, pc, core);
|
||||
void operator()(goal_ref const & in, goal_ref_buffer& result) override {
|
||||
m_t->operator()(in, result);
|
||||
m_t->cleanup();
|
||||
}
|
||||
|
||||
|
@ -1132,16 +915,12 @@ class try_for_tactical : public unary_tactical {
|
|||
public:
|
||||
try_for_tactical(tactic * t, unsigned ts):unary_tactical(t), m_timeout(ts) {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & in, goal_ref_buffer& result) override {
|
||||
cancel_eh<reslimit> eh(in->m().limit());
|
||||
{
|
||||
// Warning: scoped_timer is not thread safe in Linux.
|
||||
scoped_timer timer(m_timeout, &eh);
|
||||
m_t->operator()(in, result, mc, pc, core);
|
||||
m_t->operator()(in, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1202,13 +981,9 @@ public:
|
|||
annotate_tactical(char const* name, tactic* t):
|
||||
unary_tactical(t), m_name(name) {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & in, goal_ref_buffer& result) override {
|
||||
scope _scope(m_name);
|
||||
m_t->operator()(in, result, mc, pc, core);
|
||||
m_t->operator()(in, result);
|
||||
}
|
||||
|
||||
virtual tactic * translate(ast_manager & m) {
|
||||
|
@ -1223,34 +998,27 @@ tactic * annotate_tactic(char const* name, tactic * t) {
|
|||
}
|
||||
|
||||
class cond_tactical : public binary_tactical {
|
||||
probe * m_p;
|
||||
probe_ref m_p;
|
||||
public:
|
||||
cond_tactical(probe * p, tactic * t1, tactic * t2):
|
||||
binary_tactical(t1, t2),
|
||||
m_p(p) {
|
||||
SASSERT(m_p);
|
||||
m_p->inc_ref();
|
||||
}
|
||||
|
||||
~cond_tactical() {
|
||||
m_p->dec_ref();
|
||||
}
|
||||
virtual ~cond_tactical() {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & in, goal_ref_buffer & result) override {
|
||||
if (m_p->operator()(*(in.get())).is_true())
|
||||
m_t1->operator()(in, result, mc, pc, core);
|
||||
m_t1->operator()(in, result);
|
||||
else
|
||||
m_t2->operator()(in, result, mc, pc, core);
|
||||
m_t2->operator()(in, result);
|
||||
}
|
||||
|
||||
virtual tactic * translate(ast_manager & m) {
|
||||
tactic * new_t1 = m_t1->translate(m);
|
||||
tactic * new_t2 = m_t2->translate(m);
|
||||
return alloc(cond_tactical, m_p, new_t1, new_t2);
|
||||
return alloc(cond_tactical, m_p.get(), new_t1, new_t2);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1263,28 +1031,18 @@ tactic * when(probe * p, tactic * t) {
|
|||
}
|
||||
|
||||
class fail_if_tactic : public tactic {
|
||||
probe * m_p;
|
||||
probe_ref m_p;
|
||||
public:
|
||||
fail_if_tactic(probe * p):
|
||||
m_p(p) {
|
||||
SASSERT(m_p);
|
||||
m_p->inc_ref();
|
||||
}
|
||||
|
||||
~fail_if_tactic() {
|
||||
m_p->dec_ref();
|
||||
}
|
||||
virtual ~fail_if_tactic() {}
|
||||
|
||||
void cleanup() {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
mc = 0;
|
||||
pc = 0;
|
||||
core = 0;
|
||||
void operator()(goal_ref const & in, goal_ref_buffer& result) override {
|
||||
if (m_p->operator()(*(in.get())).is_true()) {
|
||||
throw tactic_exception("fail-if tactic");
|
||||
}
|
||||
|
@ -1308,18 +1066,12 @@ class if_no_proofs_tactical : public unary_tactical {
|
|||
public:
|
||||
if_no_proofs_tactical(tactic * t):unary_tactical(t) {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & in, goal_ref_buffer & result) override {
|
||||
if (in->proofs_enabled()) {
|
||||
mc = 0; pc = 0; core = 0;
|
||||
result.reset();
|
||||
result.push_back(in.get());
|
||||
}
|
||||
else {
|
||||
m_t->operator()(in, result, mc, pc, core);
|
||||
m_t->operator()(in, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1330,18 +1082,12 @@ class if_no_unsat_cores_tactical : public unary_tactical {
|
|||
public:
|
||||
if_no_unsat_cores_tactical(tactic * t):unary_tactical(t) {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & in, goal_ref_buffer& result) override {
|
||||
if (in->unsat_core_enabled()) {
|
||||
mc = 0; pc = 0; core = 0;
|
||||
result.reset();
|
||||
result.push_back(in.get());
|
||||
}
|
||||
else {
|
||||
m_t->operator()(in, result, mc, pc, core);
|
||||
m_t->operator()(in, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1352,18 +1098,12 @@ class if_no_models_tactical : public unary_tactical {
|
|||
public:
|
||||
if_no_models_tactical(tactic * t):unary_tactical(t) {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
void operator()(goal_ref const & in, goal_ref_buffer& result) override {
|
||||
if (in->models_enabled()) {
|
||||
mc = 0; pc = 0; core = 0;
|
||||
result.reset();
|
||||
result.push_back(in.get());
|
||||
}
|
||||
else {
|
||||
m_t->operator()(in, result, mc, pc, core);
|
||||
m_t->operator()(in, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,12 +38,8 @@ class macro_finder_tactic : public tactic {
|
|||
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
tactic_report report("macro-finder", *g);
|
||||
|
||||
bool produce_proofs = g->proofs_enabled();
|
||||
|
@ -76,8 +72,7 @@ class macro_finder_tactic : public tactic {
|
|||
func_decl * f = mm.get_macro_interpretation(i, f_interp);
|
||||
evmc->add(f, f_interp);
|
||||
}
|
||||
mc = evmc;
|
||||
|
||||
g->add(evmc);
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
TRACE("macro-finder", g->display(tout););
|
||||
|
@ -118,11 +113,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
|
|
|
@ -36,12 +36,8 @@ class quasi_macros_tactic : public tactic {
|
|||
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
tactic_report report("quasi-macros", *g);
|
||||
|
||||
bool produce_proofs = g->proofs_enabled();
|
||||
|
@ -88,8 +84,7 @@ class quasi_macros_tactic : public tactic {
|
|||
func_decl * f = mm.get_macro_interpretation(i, f_interp);
|
||||
evmc->add(f, f_interp);
|
||||
}
|
||||
mc = evmc;
|
||||
|
||||
g->add(evmc);
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
TRACE("quasi-macros", g->display(tout););
|
||||
|
@ -129,11 +124,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
|
|
|
@ -32,12 +32,8 @@ class ufbv_rewriter_tactic : public tactic {
|
|||
ast_manager & m() const { return m_manager; }
|
||||
|
||||
void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
goal_ref_buffer & result) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
mc = 0; pc = 0; core = 0;
|
||||
tactic_report report("ufbv-rewriter", *g);
|
||||
fail_if_unsat_core_generation("ufbv-rewriter", g);
|
||||
|
||||
|
@ -60,7 +56,8 @@ class ufbv_rewriter_tactic : public tactic {
|
|||
for (unsigned i = 0; i < new_forms.size(); i++)
|
||||
g->assert_expr(new_forms.get(i), produce_proofs ? new_proofs.get(i) : 0, 0);
|
||||
|
||||
mc = 0; // CMW: Remark: The demodulator could potentially remove all references to a variable.
|
||||
// CMW: Remark: The demodulator could potentially
|
||||
// remove all references to a variable.
|
||||
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
|
@ -101,11 +98,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
(*m_imp)(in, result, mc, pc, core);
|
||||
goal_ref_buffer & result) {
|
||||
(*m_imp)(in, result);
|
||||
}
|
||||
|
||||
virtual void cleanup() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue