3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-05-03 05:47:01 +00:00
z3/src/tactic/bv/bv_bound_chk_tactic.cpp
Nikolaj Bjorner e3f0aff318 address ubuntu warning and add shortcuts for maxsat
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2016-10-03 16:22:13 -07:00

244 lines
6.9 KiB
C++

/*++
Copyright (c) 2016 Microsoft Corporation
Module Name:
bv_bound_chk_tactic.cpp
Abstract:
Author:
Mikolas Janota
Revision History:
--*/
#include"bv_bound_chk_tactic.h"
#include"ast.h"
#include"rewriter.h"
#include"rewriter_def.h"
#include"bv_bounds.h"
#include"rewriter_params.hpp"
#include"bool_rewriter.h"
#include"cooperate.h"
struct bv_bound_chk_stats {
unsigned m_unsats;
unsigned m_singletons;
unsigned m_reduces;
bv_bound_chk_stats() : m_unsats(0), m_singletons(0), m_reduces(0) {};
};
struct bv_bound_chk_rewriter_cfg : public default_rewriter_cfg {
ast_manager & m_m;
unsigned m_bv_ineq_consistency_test_max;
bool_rewriter m_b_rw;
unsigned long long m_max_steps;
unsigned long long m_max_memory; // in bytes
bv_bound_chk_stats& m_stats;
bv_bound_chk_rewriter_cfg(ast_manager & m, bv_bound_chk_stats& stats)
: m_m(m), m_b_rw(m), m_stats(stats) {}
~bv_bound_chk_rewriter_cfg() {}
void updt_params(params_ref const & _p) {
rewriter_params p(_p);
m_bv_ineq_consistency_test_max = p.bv_ineq_consistency_test_max();
m_max_memory = p.max_memory();
m_max_steps = p.max_steps();
}
ast_manager & m() const { return m_m; }
bool rewrite_patterns() const { return false; }
bool flat_assoc(func_decl * f) const { return true; }
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) {
const br_status st = reduce_app_core(f, num, args, result, result_pr);
CTRACE("bv_bound_chk_step", st != BR_FAILED,
tout << f->get_name() << "\n";
for (unsigned i = 0; i < num; i++) tout << mk_ismt2_pp(args[i], m()) << "\n";
tout << "---------->\n" << mk_ismt2_pp(result, m()) << "\n";);
return st;
}
br_status reduce_app_core(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) {
result_pr = 0;
const family_id fid = f->get_family_id();
if (fid != m_b_rw.get_fid()) return BR_FAILED;
bv_bounds bvb(m());
const br_status rv = bvb.rewrite(m_bv_ineq_consistency_test_max, f, num, args, result);
if (rv != BR_FAILED && (m_m.is_false(result) || m_m.is_true(result))) m_stats.m_unsats++;
else if (rv != BR_FAILED && bvb.singletons().size()) m_stats.m_singletons++;
else if (rv != BR_FAILED && is_app(result) && to_app(result)->get_num_args() < num) m_stats.m_reduces++;
return rv;
}
bool max_steps_exceeded(unsigned long long num_steps) const {
cooperate("bv-bound-chk");
if (num_steps > m_max_steps)
return true;
if (memory::get_allocation_size() > m_max_memory)
throw tactic_exception(TACTIC_MAX_MEMORY_MSG);
return false;
}
void reset_statistics() {
m_stats.m_unsats = 0;
m_stats.m_singletons = 0;
m_stats.m_reduces = 0;
}
void collect_statistics(statistics & st) const {
st.update("unsat bv bounds", m_stats.m_unsats);
st.update("bv singletons", m_stats.m_singletons);
st.update("bv reduces", m_stats.m_reduces);
}
};
struct bv_bound_chk_rewriter : public rewriter_tpl<bv_bound_chk_rewriter_cfg> {
bv_bound_chk_rewriter_cfg m_cfg;
bv_bound_chk_rewriter(ast_manager & m, params_ref const & p, bv_bound_chk_stats& stats)
: rewriter_tpl<bv_bound_chk_rewriter_cfg>(m, false, m_cfg)
, m_cfg(m, stats)
{
updt_params(p);
}
virtual ~bv_bound_chk_rewriter() {}
void updt_params(params_ref const & _p) {
m_cfg.updt_params(_p);
}
void collect_statistics(statistics & st) const {
m_cfg.collect_statistics(st);
}
void reset_statistics() {
m_cfg.reset_statistics();
}
};
class bv_bound_chk_tactic : public tactic {
class imp;
imp * m_imp;
params_ref m_params;
bv_bound_chk_stats m_stats;
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);
virtual tactic * translate(ast_manager & m);
virtual void updt_params(params_ref const & p);
void cleanup();
void collect_statistics(statistics & st) const;
void reset_statistics();
};
class bv_bound_chk_tactic::imp {
bv_bound_chk_rewriter m_rw;
public:
imp(ast_manager & m, params_ref const & p, bv_bound_chk_stats& stats)
: m_rw(m, p, stats) { }
virtual ~imp() { }
ast_manager& m() { return m_rw.m(); }
void operator()(goal_ref const & g) {
SASSERT(g->is_well_sorted());
tactic_report report("bv-bound-chk", *g);
ast_manager& m(g->m());
expr_ref new_curr(m);
const unsigned size = g->size();
for (unsigned idx = 0; idx < size; idx++) {
if (g->inconsistent()) break;
expr * curr = g->form(idx);
m_rw(curr, new_curr);
g->update(idx, new_curr);
}
m_rw.m_cfg.cleanup();
}
virtual void updt_params(params_ref const & p) {
m_rw.updt_params(p);
}
void collect_statistics(statistics & st) const {
m_rw.collect_statistics(st);
}
void reset_statistics() {
m_rw.reset_statistics();
}
};
bv_bound_chk_tactic::bv_bound_chk_tactic(ast_manager & m, params_ref const & p)
: m_params(p)
{
m_imp = alloc(imp, m, p, m_stats);
}
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) {
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();
m_imp->operator()(g);
g->inc_depth();
result.push_back(g.get());
TRACE("bv-bound-chk", g->display(tout << "after:"););
SASSERT(g->is_well_sorted());
}
tactic * bv_bound_chk_tactic::translate(ast_manager & m) {
return alloc(bv_bound_chk_tactic, m, m_params);
}
void bv_bound_chk_tactic::updt_params(params_ref const & p) {
m_params = p;
m_imp->updt_params(p);
}
void bv_bound_chk_tactic::cleanup() {
imp * d = alloc(imp, m_imp->m(), m_params, m_stats);
std::swap(d, m_imp);
dealloc(d);
}
void bv_bound_chk_tactic::collect_statistics(statistics & st) const {
m_imp->collect_statistics(st);
}
void bv_bound_chk_tactic::reset_statistics() {
m_imp->reset_statistics();
}
tactic* mk_bv_bound_chk_tactic(ast_manager & m, params_ref const & p) {
return alloc(bv_bound_chk_tactic, m, p);
}