mirror of
https://github.com/Z3Prover/z3
synced 2025-05-04 14:25:46 +00:00
Adding bv preprocessing techniques.
This commit is contained in:
parent
5290cd1ff5
commit
ec47a1df50
11 changed files with 1545 additions and 3 deletions
245
src/tactic/bv/bv_bound_chk_tactic.cpp
Normal file
245
src/tactic/bv/bv_bound_chk_tactic.cpp
Normal file
|
@ -0,0 +1,245 @@
|
|||
/*++
|
||||
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;
|
||||
const decl_kind k = f->get_decl_kind();
|
||||
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);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue