z3-z3-4.13.0.src.tactic.bv.bv_bound_chk_tactic.cpp Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2016 Microsoft Corporation
Module Name:
bv_bound_chk_tactic.cpp
Abstract:
Author:
Mikolas Janota
Revision History:
--*/
#include "tactic/bv/bv_bound_chk_tactic.h"
#include "ast/ast.h"
#include "params/rewriter_params.hpp"
#include "ast/rewriter/rewriter.h"
#include "ast/rewriter/rewriter_def.h"
#include "ast/rewriter/bv_bounds.h"
#include "ast/rewriter/bool_rewriter.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 = nullptr;
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().empty()) 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 {
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 m_cfg;
bv_bound_chk_rewriter(ast_manager & m, params_ref const & p, bv_bound_chk_stats& stats)
: rewriter_tpl(m, false, m_cfg)
, m_cfg(m, stats)
{
updt_params(p);
}
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);
void operator()(goal_ref const & g, goal_ref_buffer & result) override;
~bv_bound_chk_tactic() override;
tactic * translate(ast_manager & m) override;
void updt_params(params_ref const & p) override;
void cleanup() override;
void collect_statistics(statistics & st) const override;
void reset_statistics() override;
char const* name() const override { return "bv_bound_chk"; }
};
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() = default;
ast_manager& m() { return m_rw.m(); }
void operator()(goal_ref const & g) {
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) {
fail_if_proof_generation("bv-bound-chk", g);
fail_if_unsat_core_generation("bv-bound-chk", g);
result.reset();
m_imp->operator()(g);
g->inc_depth();
result.push_back(g.get());
}
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.append(p);
m_imp->updt_params(m_params);
}
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);
}