3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-15 23:35:26 +00:00

added facility to persist model transformations

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-11-02 00:05:52 -05:00
commit fd49a0c89c
195 changed files with 3601 additions and 2139 deletions

View file

@ -11,7 +11,9 @@ Abstract:
Author:
Nikolaj Bjorner (nbjorner) 2016-2-12
Nuno Lopes (nlopes) 2016-2-12
Nikolaj Bjorner (nbjorner)
--*/
@ -650,11 +652,11 @@ namespace {
return false;
if (old == intr)
return true;
m_scopes.insert(undo_bound(t1, old, false));
m_scopes.push_back(undo_bound(t1, old, false));
old = intr;
} else {
m_bound.insert(t1, b);
m_scopes.insert(undo_bound(t1, interval(), true));
m_scopes.push_back(undo_bound(t1, interval(), true));
}
}
return true;
@ -692,7 +694,8 @@ namespace {
bool was_updated = true;
if (b.is_full() && b.tight) {
r = m.mk_true();
} else if (m_bound.find(t1, ctx)) {
}
else if (m_bound.find(t1, ctx)) {
if (ctx.implies(b)) {
r = m.mk_true();
}
@ -703,12 +706,15 @@ namespace {
r = m.mk_eq(t1, m_bv.mk_numeral(rational(intr.l, rational::ui64()),
m.get_sort(t1)));
}
else {
was_updated = false;
}
}
else {
was_updated = false;
}
CTRACE("bv", was_updated, tout << mk_pp(t, m) << " " << b << " (ctx: " << ctx << ") (intr: " << intr << "): " << r << "\n";);
TRACE("bv", tout << mk_pp(t, m) << " " << b << " (ctx: " << ctx << ") (intr: " << intr << "): " << r << "\n";);
if (sign && was_updated)
r = m.mk_not(r);
}
@ -801,6 +807,10 @@ namespace {
return alloc(dom_bv_bounds_simplifier, m, m_params);
}
virtual unsigned scope_level() const {
return m_scopes.size();
}
};
}

View file

@ -11,7 +11,8 @@ Abstract:
Author:
Nikolaj Bjorner (nbjorner) 2016-2-12
Nuno Lopes (nlopes) 2016-2-12
Nikolaj Bjorner (nbjorner)
--*/
@ -21,8 +22,15 @@ Author:
tactic * mk_bv_bounds_tactic(ast_manager & m, params_ref const & p = params_ref());
tactic * mk_dom_bv_bounds_tactic(ast_manager & m, params_ref const & p = params_ref());
/*
ADD_TACTIC("propagate-bv-bounds", "propagate bit-vector bounds by simplifying implied or contradictory bounds.", "mk_bv_bounds_tactic(m, p)")
ADD_TACTIC("propagate-bv-bounds-new", "propagate bit-vector bounds by simplifying implied or contradictory bounds.", "mk_dom_bv_bounds_tactic(m, p)")
*/
#endif

View file

@ -117,7 +117,7 @@ func_decl_ref bvarray2uf_rewriter_cfg::mk_uf_for_array(expr * e) {
if (is_uninterp_const(e)) {
if (m_emc)
m_emc->insert(to_app(e)->get_decl(),
m_array_util.mk_as_array(m_manager.get_sort(e), bv_f));
m_array_util.mk_as_array(bv_f));
}
else if (m_fmc)
m_fmc->insert(bv_f);
@ -193,7 +193,7 @@ br_status bvarray2uf_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr
if (is_uninterp_const(e)) {
if (m_emc)
m_emc->insert(e->get_decl(),
m_array_util.mk_as_array(m_manager.get_sort(e), bv_f));
m_array_util.mk_as_array(bv_f));
}
else if (m_fmc)
m_fmc->insert(bv_f);
@ -207,7 +207,7 @@ br_status bvarray2uf_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr
q = m_manager.mk_forall(1, sorts, names, body);
extra_assertions.push_back(q);
result = m_array_util.mk_as_array(f->get_range(), bv_f);
result = m_array_util.mk_as_array(bv_f);
TRACE("bvarray2uf_rw", tout << "result: " << mk_ismt2_pp(result, m_manager) << ")" << std::endl;);
res = BR_DONE;
@ -234,7 +234,7 @@ br_status bvarray2uf_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr
if (is_bv_array(t)) {
// From [1]: For every array term t we create a fresh uninterpreted function f_t.
f_t = mk_uf_for_array(t);
result = m_array_util.mk_as_array(m_manager.get_sort(t), f_t);
result = m_array_util.mk_as_array(f_t);
res = BR_DONE;
}
else if (has_bv_arrays) {
@ -274,7 +274,7 @@ br_status bvarray2uf_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr
expr * v = args[0];
func_decl_ref f_t(mk_uf_for_array(t), m_manager);
result = m_array_util.mk_as_array(f->get_range(), f_t);
result = m_array_util.mk_as_array(f_t);
res = BR_DONE;
// Add \forall x . f_t(x) = v
@ -321,7 +321,7 @@ br_status bvarray2uf_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr
expr_ref frllx(m_manager.mk_forall(1, sorts, names, body), m_manager);
extra_assertions.push_back(frllx);
result = m_array_util.mk_as_array(f->get_range(), f_t);
result = m_array_util.mk_as_array(f_t);
res = BR_DONE;
}
else if (m_array_util.is_store(f)) {
@ -342,7 +342,7 @@ br_status bvarray2uf_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr
func_decl_ref f_s(mk_uf_for_array(s), m_manager);
func_decl_ref f_t(mk_uf_for_array(t), m_manager);
result = m_array_util.mk_as_array(f->get_range(), f_t);
result = m_array_util.mk_as_array(f_t);
res = BR_DONE;
sort * sorts[1] = { get_index_sort(f->get_range()) };

View file

@ -29,13 +29,13 @@ public:
converter():m_ref_count(0) {}
virtual ~converter() {}
void inc_ref() { ++m_ref_count; std::cout << "inc_ref " << m_ref_count << " " << this << "\n"; }
void inc_ref() { ++m_ref_count; }
void dec_ref() {
--m_ref_count;
if (m_ref_count == 0) {
std::cout << "dec_ref " << this << "\n";
dealloc(this);
}
if (m_ref_count == 0) {
dealloc(this);
}
}
virtual void cancel() {}

View file

@ -242,7 +242,7 @@ expr_ref dom_simplify_tactic::simplify_ite(app * ite) {
r = new_t;
}
else {
TRACE("tactic", tout << new_c << "\n" << new_t << "\n" << new_e << "\n";);
TRACE("simplify", tout << new_c << "\n" << new_t << "\n" << new_e << "\n";);
r = m.mk_ite(new_c, new_t, new_e);
}
}
@ -441,7 +441,7 @@ ptr_vector<expr> const & dom_simplify_tactic::tree(expr * e) {
}
// ----------------------
// ---------------------
// expr_substitution_simplifier
bool expr_substitution_simplifier::assert_expr(expr * t, bool sign) {

View file

@ -83,6 +83,8 @@ class dom_simplifier {
virtual void pop(unsigned num_scopes) = 0;
virtual dom_simplifier * translate(ast_manager & m) = 0;
virtual unsigned scope_level() const = 0;
};
@ -93,7 +95,6 @@ class dom_simplify_tactic : public tactic {
expr_ref_vector m_trail, m_args;
obj_map<expr, expr*> m_result;
expr_dominators m_dominators;
unsigned m_scope_level;
unsigned m_depth;
unsigned m_max_depth;
ptr_vector<expr> m_empty;
@ -116,9 +117,9 @@ class dom_simplify_tactic : public tactic {
ptr_vector<expr> const & tree(expr * e);
expr* idom(expr *e) const { return m_dominators.idom(e); }
unsigned scope_level() { return m_scope_level; }
void pop(unsigned n) { SASSERT(n <= m_scope_level); m_scope_level -= n; m_simplifier->pop(n); }
bool assert_expr(expr* f, bool sign) { m_scope_level++; return m_simplifier->assert_expr(f, sign); }
unsigned scope_level() { return m_simplifier->scope_level(); }
void pop(unsigned n) { SASSERT(n <= m_simplifier->scope_level()); m_simplifier->pop(n); }
bool assert_expr(expr* f, bool sign) { return m_simplifier->assert_expr(f, sign); }
bool init(goal& g);
@ -126,8 +127,7 @@ public:
dom_simplify_tactic(ast_manager & m, dom_simplifier* s, params_ref const & p = params_ref()):
m(m), m_simplifier(s), m_params(p),
m_trail(m), m_args(m),
m_dominators(m),
m_scope_level(0), m_depth(0), m_max_depth(1024), m_forward(true) {}
m_dominators(m), m_depth(0), m_max_depth(1024), m_forward(true) {}
virtual ~dom_simplify_tactic();
@ -169,6 +169,8 @@ public:
virtual void pop(unsigned num_scopes) { m_scoped_substitution.pop(num_scopes); }
virtual unsigned scope_level() const { return m_scoped_substitution.scope_level(); }
virtual dom_simplifier * translate(ast_manager & m) {
SASSERT(m_subst.empty());
return alloc(expr_substitution_simplifier, m);

View file

@ -33,7 +33,6 @@ Notes:
class bounded_int2bv_solver : public solver_na2as {
ast_manager& m;
params_ref m_params;
mutable bv_util m_bv;
mutable arith_util m_arith;
mutable expr_ref_vector m_assertions;
@ -53,7 +52,6 @@ public:
bounded_int2bv_solver(ast_manager& m, params_ref const& p, solver* s):
solver_na2as(m),
m(m),
m_params(p),
m_bv(m),
m_arith(m),
m_assertions(m),
@ -63,6 +61,7 @@ public:
m_rewriter_ctx(m, p),
m_rewriter(m, m_rewriter_ctx)
{
solver::updt_params(p);
m_bounds.push_back(alloc(bound_manager, m));
}
@ -144,7 +143,7 @@ public:
return m_solver->check_sat(num_assumptions, assumptions);
}
virtual void updt_params(params_ref const & p) { m_solver->updt_params(p); }
virtual void updt_params(params_ref const & p) { solver::updt_params(p); m_solver->updt_params(p); }
virtual void collect_param_descrs(param_descrs & r) { m_solver->collect_param_descrs(r); }
virtual void set_produce_models(bool f) { m_solver->set_produce_models(f); }
virtual void set_progress_callback(progress_callback * callback) { m_solver->set_progress_callback(callback); }

View file

@ -20,32 +20,31 @@ Notes:
--*/
#include "solver/solver_na2as.h"
#include "tactic/tactic.h"
#include "ast/bv_decl_plugin.h"
#include "ast/datatype_decl_plugin.h"
#include "ast/rewriter/enum2bv_rewriter.h"
#include "tactic/extension_model_converter.h"
#include "tactic/filter_model_converter.h"
#include "ast/ast_pp.h"
#include "model/model_smt2_pp.h"
#include "tactic/tactic.h"
#include "tactic/extension_model_converter.h"
#include "tactic/filter_model_converter.h"
#include "tactic/portfolio/enum2bv_solver.h"
#include "solver/solver_na2as.h"
#include "ast/rewriter/enum2bv_rewriter.h"
class enum2bv_solver : public solver_na2as {
ast_manager& m;
params_ref m_params;
ref<solver> m_solver;
enum2bv_rewriter m_rewriter;
ast_manager& m;
ref<solver> m_solver;
enum2bv_rewriter m_rewriter;
public:
enum2bv_solver(ast_manager& m, params_ref const& p, solver* s):
solver_na2as(m),
m(m),
m_params(p),
m_solver(s),
m_rewriter(m, p)
{
solver::updt_params(p);
}
virtual ~enum2bv_solver() {}
@ -85,11 +84,11 @@ public:
}
virtual lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions) {
m_solver->updt_params(m_params);
m_solver->updt_params(get_params());
return m_solver->check_sat(num_assumptions, assumptions);
}
virtual void updt_params(params_ref const & p) { m_solver->updt_params(p); }
virtual void updt_params(params_ref const & p) { solver::updt_params(p); m_solver->updt_params(p); }
virtual void collect_param_descrs(param_descrs & r) { m_solver->collect_param_descrs(r); }
virtual void set_produce_models(bool f) { m_solver->set_produce_models(f); }
virtual void set_progress_callback(progress_callback * callback) { m_solver->set_progress_callback(callback); }
@ -119,8 +118,8 @@ public:
// ensure that enumeration variables that
// don't occur in the constraints
// are also internalized.
for (unsigned i = 0; i < vars.size(); ++i) {
expr_ref tmp(m.mk_eq(vars[i], vars[i]), m);
for (expr* v : vars) {
expr_ref tmp(m.mk_eq(v, v), m);
proof_ref proof(m);
m_rewriter(tmp, tmp, proof);
}
@ -128,13 +127,13 @@ public:
m_solver->assert_expr(bounds);
// translate enumeration constants to bit-vectors.
for (unsigned i = 0; i < vars.size(); ++i) {
for (expr* v : vars) {
func_decl* f = 0;
if (is_app(vars[i]) && is_uninterp_const(vars[i]) && m_rewriter.enum2bv().find(to_app(vars[i])->get_decl(), f)) {
if (is_app(v) && is_uninterp_const(v) && m_rewriter.enum2bv().find(to_app(v)->get_decl(), f)) {
bvars.push_back(m.mk_const(f));
}
else {
bvars.push_back(vars[i]);
bvars.push_back(v);
}
}
lbool r = m_solver->get_consequences(asms, bvars, consequences);
@ -161,20 +160,16 @@ public:
void filter_model(model_ref& mdl) {
filter_model_converter filter(m);
obj_map<func_decl, func_decl*>::iterator it = m_rewriter.enum2bv().begin(), end = m_rewriter.enum2bv().end();
for (; it != end; ++it) {
filter.insert(it->m_value);
for (auto const& kv : m_rewriter.enum2bv()) {
filter.insert(kv.m_value);
}
filter(mdl, 0);
}
void extend_model(model_ref& mdl) {
extension_model_converter ext(m);
obj_map<func_decl, expr*>::iterator it = m_rewriter.enum2def().begin(), end = m_rewriter.enum2def().end();
for (; it != end; ++it) {
ext.insert(it->m_key, it->m_value);
}
for (auto const& kv : m_rewriter.enum2def())
ext.insert(kv.m_key, kv.m_value);
ext(mdl, 0);
}

View file

@ -27,7 +27,6 @@ Notes:
class pb2bv_solver : public solver_na2as {
ast_manager& m;
params_ref m_params;
mutable expr_ref_vector m_assertions;
mutable ref<solver> m_solver;
mutable th_rewriter m_th_rewriter;
@ -38,12 +37,12 @@ public:
pb2bv_solver(ast_manager& m, params_ref const& p, solver* s):
solver_na2as(m),
m(m),
m_params(p),
m_assertions(m),
m_solver(s),
m_th_rewriter(m, p),
m_rewriter(m, p)
{
solver::updt_params(p);
}
virtual ~pb2bv_solver() {}
@ -78,8 +77,8 @@ public:
return m_solver->check_sat(num_assumptions, assumptions);
}
virtual void updt_params(params_ref const & p) { m_solver->updt_params(p); m_rewriter.updt_params(p); }
virtual void collect_param_descrs(param_descrs & r) { m_solver->collect_param_descrs(r); m_rewriter.collect_param_descrs(r); }
virtual void updt_params(params_ref const & p) { solver::updt_params(p); m_rewriter.updt_params(p); m_solver->updt_params(p); }
virtual void collect_param_descrs(param_descrs & r) { m_solver->collect_param_descrs(r); m_rewriter.collect_param_descrs(r);}
virtual void set_produce_models(bool f) { m_solver->set_produce_models(f); }
virtual void set_progress_callback(progress_callback * callback) { m_solver->set_progress_callback(callback); }
virtual void collect_statistics(statistics & st) const {

View file

@ -238,7 +238,7 @@ bool bvsls_opt_engine::what_if(
mpz bvsls_opt_engine::find_best_move(
ptr_vector<func_decl> & to_evaluate,
mpz score,
mpz & score,
unsigned & best_const,
mpz & best_value,
unsigned & new_bit,

View file

@ -61,7 +61,7 @@ protected:
bool what_if(func_decl * fd, const unsigned & fd_inx, const mpz & temp,
mpz & best_score, unsigned & best_const, mpz & best_value);
mpz find_best_move(ptr_vector<func_decl> & to_evaluate, mpz score,
mpz find_best_move(ptr_vector<func_decl> & to_evaluate, mpz & score,
unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move,
mpz const & max_score, expr * objective);

View file

@ -41,7 +41,24 @@ class sls_tracker {
struct value_score {
value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), score_prune(0.0), has_pos_occ(0), has_neg_occ(0), distance(0), touched(1) {};
value_score(value_score && other) :
m(other.m),
value(std::move(other.value)),
score(other.score),
score_prune(other.score_prune),
has_pos_occ(other.has_pos_occ),
has_neg_occ(other.has_neg_occ),
distance(other.distance),
touched(other.touched) {}
~value_score() { if (m) m->del(value); }
void operator=(value_score && other) {
this->~value_score();
new (this) value_score(std::move(other));
}
value_score& operator=(value_score& other) {
UNREACHABLE();
return *this;
}
unsynch_mpz_manager * m;
mpz value;
double score;
@ -50,15 +67,6 @@ class sls_tracker {
unsigned has_neg_occ;
unsigned distance; // max distance from any root
unsigned touched;
value_score & operator=(const value_score & other) {
SASSERT(m == 0 || m == other.m);
if (m) m->set(value, 0); else m = other.m;
m->set(value, other.value);
score = other.score;
distance = other.distance;
touched = other.touched;
return *this;
}
};
public:
@ -294,7 +302,7 @@ public:
if (!m_scores.contains(n)) {
value_score vs;
vs.m = & m_mpz_manager;
m_scores.insert(n, vs);
m_scores.insert(n, std::move(vs));
}
// Update uplinks
@ -539,7 +547,7 @@ public:
rational r_val;
unsigned bv_sz;
m_bv_util.is_numeral(val, r_val, bv_sz);
mpq q = r_val.to_mpq();
const mpq& q = r_val.to_mpq();
SASSERT(m_mpz_manager.is_one(q.denominator()));
set_value(fd, q.numerator());
}
@ -630,7 +638,7 @@ public:
if (m_bv_util.is_bv_sort(s))
return get_random_bv(s);
else if (m_manager.is_bool(s))
return get_random_bool();
return m_mpz_manager.dup(get_random_bool());
else
NOT_IMPLEMENTED_YET(); // This only works for bit-vectors for now.
}
@ -653,9 +661,7 @@ public:
TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); );
for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) {
mpz temp = m_zero;
set_value(it->m_value, temp);
m_mpz_manager.del(temp);
set_value(it->m_value, m_zero);
}
}
@ -931,7 +937,7 @@ public:
rational q;
if (!m_bv_util.is_numeral(n, q, bv_sz))
NOT_IMPLEMENTED_YET();
mpq temp = q.to_mpq();
const mpq& temp = q.to_mpq();
SASSERT(m_mpz_manager.is_one(temp.denominator()));
m_mpz_manager.set(result, temp.numerator());
}
@ -1039,7 +1045,6 @@ public:
unsigned pos = -1;
if (m_ucb)
{
value_score vscore;
double max = -1.0;
// Andreas: Commented things here might be used for track_unsat data structures as done in SLS for SAT. But seems to have no benefit.
/* for (unsigned i = 0; i < m_where_false.size(); i++) {
@ -1048,7 +1053,7 @@ public:
expr * e = as[i];
if (m_mpz_manager.neq(get_value(e), m_one))
{
vscore = m_scores.find(e);
value_score & vscore = m_scores.find(e);
// Andreas: Select the assertion with the greatest ucb score. Potentially add some noise.
// double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched);
double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched) + m_ucb_noise * get_random_uint(8);