mirror of
https://github.com/Z3Prover/z3
synced 2025-08-23 19:47:52 +00:00
also, bug fixes to elim_unconstrained (elim_uncnstr2) which is to replace legacy tactic for eliminating unconstrained constants.
204 lines
6.6 KiB
C++
204 lines
6.6 KiB
C++
/*++
|
|
Copyright (c) 2012 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
qfufbv_tactic.cpp
|
|
|
|
Abstract:
|
|
|
|
Tactic for QF_UFBV
|
|
|
|
Author:
|
|
|
|
Leonardo (leonardo) 2012-02-27
|
|
Mikolas Janota
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
#include "tactic/tactical.h"
|
|
#include "tactic/core/simplify_tactic.h"
|
|
#include "tactic/core/propagate_values_tactic.h"
|
|
#include "tactic/core/solve_eqs_tactic.h"
|
|
#include "tactic/core/elim_uncnstr_tactic.h"
|
|
#include "tactic/bv/max_bv_sharing_tactic.h"
|
|
#include "tactic/bv/bv_size_reduction_tactic.h"
|
|
#include "tactic/core/reduce_args_tactic.h"
|
|
#include "tactic/smtlogics/qfbv_tactic.h"
|
|
#include "tactic/smtlogics/qfufbv_tactic_params.hpp"
|
|
///////////////
|
|
#include "model/model_smt2_pp.h"
|
|
#include "ackermannization/lackr.h"
|
|
#include "ackermannization/ackermannization_params.hpp"
|
|
#include "tactic/smtlogics/qfufbv_ackr_model_converter.h"
|
|
///////////////
|
|
#include "sat/sat_solver/inc_sat_solver.h"
|
|
#include "tactic/smtlogics/qfaufbv_tactic.h"
|
|
#include "tactic/smtlogics/qfbv_tactic.h"
|
|
#include "tactic/smtlogics/smt_tactic.h"
|
|
#include "solver/tactic2solver.h"
|
|
#include "tactic/bv/bv_bound_chk_tactic.h"
|
|
#include "ackermannization/ackermannize_bv_tactic.h"
|
|
///////////////
|
|
|
|
class qfufbv_ackr_tactic : public tactic {
|
|
public:
|
|
qfufbv_ackr_tactic(ast_manager& m, params_ref const& p)
|
|
: m_m(m)
|
|
, m_p(p)
|
|
, m_use_sat(false)
|
|
, m_inc_use_sat(false)
|
|
{}
|
|
|
|
char const* name() const override { return "qfufbv_ackr"; }
|
|
|
|
void operator()(goal_ref const & g, goal_ref_buffer & result) override {
|
|
ast_manager& m(g->m());
|
|
tactic_report report("qfufbv_ackr", *g);
|
|
fail_if_unsat_core_generation("qfufbv_ackr", g);
|
|
fail_if_proof_generation("qfufbv_ackr", g);
|
|
|
|
TRACE("goal", g->display(tout););
|
|
// running implementation
|
|
ptr_vector<expr> flas;
|
|
const unsigned sz = g->size();
|
|
for (unsigned i = 0; i < sz; i++) flas.push_back(g->form(i));
|
|
scoped_ptr<solver> uffree_solver = setup_sat();
|
|
lackr imp(m, m_p, m_st, flas, uffree_solver.get());
|
|
const lbool o = imp.operator()();
|
|
flas.reset();
|
|
// report result
|
|
goal_ref resg(alloc(goal, *g, true));
|
|
if (o == l_false)
|
|
resg->assert_expr(m.mk_false());
|
|
if (o == l_undef) {
|
|
g->inc_depth();
|
|
result.push_back(g.get());
|
|
}
|
|
else {
|
|
result.push_back(resg.get());
|
|
}
|
|
// report model
|
|
if (g->models_enabled() && o == l_true) {
|
|
model_ref abstr_model = imp.get_model();
|
|
resg->add(mk_qfufbv_ackr_model_converter(m, imp.get_info(), abstr_model));
|
|
}
|
|
}
|
|
|
|
void updt_params(params_ref const & _p) override {
|
|
qfufbv_tactic_params p(_p);
|
|
m_use_sat = p.sat_backend();
|
|
m_inc_use_sat = p.inc_sat_backend();
|
|
}
|
|
|
|
void collect_statistics(statistics & st) const override {
|
|
ackermannization_params p(m_p);
|
|
if (!p.eager()) st.update("lackr-its", m_st.m_it);
|
|
st.update("ackr-constraints", m_st.m_ackrs_sz);
|
|
}
|
|
|
|
void reset_statistics() override { m_st.reset(); }
|
|
|
|
void cleanup() override { }
|
|
|
|
tactic* translate(ast_manager& m) override {
|
|
return alloc(qfufbv_ackr_tactic, m, m_p);
|
|
}
|
|
private:
|
|
ast_manager& m_m;
|
|
params_ref m_p;
|
|
lackr_stats m_st;
|
|
bool m_use_sat;
|
|
bool m_inc_use_sat;
|
|
|
|
solver* setup_sat() {
|
|
solver * sat = nullptr;
|
|
if (m_use_sat) {
|
|
if (m_inc_use_sat) {
|
|
sat = mk_inc_sat_solver(m_m, m_p);
|
|
}
|
|
else {
|
|
tactic_ref t = mk_qfbv_tactic(m_m, m_p);
|
|
sat = mk_tactic2solver(m_m, t.get(), m_p);
|
|
}
|
|
}
|
|
else {
|
|
tactic_ref t = mk_qfaufbv_tactic(m_m, m_p);
|
|
sat = mk_tactic2solver(m_m, t.get(), m_p);
|
|
}
|
|
SASSERT(sat != nullptr);
|
|
sat->set_produce_models(true);
|
|
return sat;
|
|
}
|
|
|
|
|
|
};
|
|
|
|
static tactic * mk_qfufbv_preamble1(ast_manager & m, params_ref const & p) {
|
|
params_ref simp2_p = p, flat_and_or_p = p;
|
|
flat_and_or_p.set_bool("flat_and_or", false);
|
|
simp2_p.set_bool("pull_cheap_ite", true);
|
|
simp2_p.set_bool("push_ite_bv", false);
|
|
simp2_p.set_bool("local_ctx", true);
|
|
simp2_p.set_uint("local_ctx_limit", 10000000);
|
|
simp2_p.set_bool("ite_extra_rules", true);
|
|
simp2_p.set_bool("mul2concat", true);
|
|
simp2_p.set_bool("flat_and_or", false);
|
|
|
|
params_ref ctx_simp_p;
|
|
ctx_simp_p.set_uint("max_depth", 32);
|
|
ctx_simp_p.set_uint("max_steps", 5000000);
|
|
|
|
return and_then(
|
|
using_params(mk_simplify_tactic(m), flat_and_or_p),
|
|
using_params(mk_propagate_values_tactic(m), flat_and_or_p),
|
|
if_no_proofs(if_no_unsat_cores(mk_bv_bound_chk_tactic(m))),
|
|
//using_params(mk_ctx_simplify_tactic(m_m), ctx_simp_p),
|
|
mk_solve_eqs_tactic(m),
|
|
mk_elim_uncnstr_tactic(m),
|
|
if_no_proofs(if_no_unsat_cores(mk_bv_size_reduction_tactic(m))),
|
|
mk_max_bv_sharing_tactic(m),
|
|
using_params(mk_simplify_tactic(m), simp2_p)
|
|
);
|
|
}
|
|
|
|
static tactic * mk_qfufbv_preamble(ast_manager & m, params_ref const & p) {
|
|
params_ref simp2_p = p, flat_and_or_p = p;
|
|
flat_and_or_p.set_bool("flat_and_or", false);
|
|
return and_then(using_params(mk_simplify_tactic(m), flat_and_or_p),
|
|
using_params(mk_propagate_values_tactic(m), flat_and_or_p),
|
|
mk_solve_eqs_tactic(m),
|
|
mk_elim_uncnstr_tactic(m),
|
|
if_no_proofs(if_no_unsat_cores(mk_reduce_args_tactic(m))),
|
|
if_no_proofs(if_no_unsat_cores(mk_bv_size_reduction_tactic(m))),
|
|
mk_max_bv_sharing_tactic(m),
|
|
if_no_proofs(if_no_unsat_cores(mk_ackermannize_bv_tactic(m,p)))
|
|
);
|
|
}
|
|
|
|
tactic * mk_qfufbv_tactic(ast_manager & m, params_ref const & p) {
|
|
params_ref main_p;
|
|
main_p.set_bool("elim_and", true);
|
|
main_p.set_bool("blast_distinct", true);
|
|
|
|
tactic * const preamble_st = mk_qfufbv_preamble(m, p);
|
|
|
|
tactic * st = using_params(
|
|
and_then(preamble_st,
|
|
cond(mk_is_qfbv_probe(),
|
|
mk_qfbv_tactic(m),
|
|
mk_smt_tactic(m, p))),
|
|
main_p);
|
|
|
|
st->updt_params(p);
|
|
return st;
|
|
}
|
|
|
|
tactic * mk_qfufbv_ackr_tactic(ast_manager & m, params_ref const & p) {
|
|
tactic * const preamble_t = mk_qfufbv_preamble1(m, p);
|
|
|
|
tactic * const actual_tactic = alloc(qfufbv_ackr_tactic, m, p);
|
|
return and_then(preamble_t,
|
|
cond(mk_is_qfufbv_probe(), actual_tactic, mk_smt_tactic(m, p)));
|
|
}
|