3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 09:35:32 +00:00

add unit extraction

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-03-06 01:08:17 -08:00
parent 75ba65a18a
commit 718e5a9b6c
27 changed files with 207 additions and 76 deletions

View file

@ -119,6 +119,8 @@ class eq2bv_tactic : public tactic {
}
}
virtual void get_units(obj_map<expr, bool>& units) { units.reset(); }
};
public:

View file

@ -180,6 +180,8 @@ class fm_tactic : public tactic {
m_clauses.back().swap(c);
}
virtual void get_units(obj_map<expr, bool>& units) { units.reset(); }
virtual void operator()(model_ref & md) {
TRACE("fm_mc", model_v2_pp(tout, *md); display(tout););
model_evaluator ev(*(md.get()));

View file

@ -50,6 +50,10 @@ pb2bv_model_converter::~pb2bv_model_converter() {
}
}
void pb2bv_model_converter::get_units(obj_map<expr, bool>& units) {
if (!m_c2bit.empty()) units.reset();
}
void pb2bv_model_converter::operator()(model_ref & md) {
TRACE("pb2bv", tout << "converting model:\n"; model_v2_pp(tout, *md); display(tout););

View file

@ -33,6 +33,7 @@ public:
virtual ~pb2bv_model_converter();
void operator()(model_ref & md) override;
void display(std::ostream & out) override;
void get_units(obj_map<expr, bool>& units) override;
model_converter * translate(ast_translation & translator) override;
};

View file

@ -206,6 +206,10 @@ struct bit_blaster_model_converter : public model_converter {
}
}
void get_units(obj_map<expr, bool>& units) override {
// no-op
}
protected:
bit_blaster_model_converter(ast_manager & m):m_vars(m), m_bits(m) { }
public:

View file

@ -33,60 +33,13 @@ Notes:
--*/
#include "tactic/core/pb_preprocess_tactic.h"
#include "tactic/tactical.h"
#include "tactic/generic_model_converter.h"
#include "ast/for_each_expr.h"
#include "ast/pb_decl_plugin.h"
#include "ast/rewriter/th_rewriter.h"
#include "ast/expr_substitution.h"
#include "ast/ast_pp.h"
class pb_preproc_model_converter : public model_converter {
ast_manager& m;
pb_util pb;
expr_ref_vector m_refs;
svector<std::pair<app*, expr*> > m_const;
public:
pb_preproc_model_converter(ast_manager& m):m(m), pb(m), m_refs(m) {}
virtual void operator()(model_ref & mdl) {
for (auto const& kv : m_const) {
mdl->register_decl(kv.first->get_decl(), kv.second);
}
}
void set_value(expr* e, bool p) {
while (m.is_not(e, e)) {
p = !p;
}
SASSERT(is_app(e));
set_value_p(to_app(e), p?m.mk_true():m.mk_false());
}
virtual model_converter * translate(ast_translation & translator) {
pb_preproc_model_converter* mc = alloc(pb_preproc_model_converter, translator.to());
for (auto const& kv : m_const) {
mc->set_value_p(translator(kv.first), translator(kv.second));
}
return mc;
}
virtual void display(std::ostream & out) {
for (auto const& kv : m_const) {
out << "(model-set " << mk_pp(kv.first, m) << " " << mk_pp(kv.second, m) << ")\n";
}
}
private:
void set_value_p(app* e, expr* v) {
SASSERT(e->get_num_args() == 0);
SASSERT(is_uninterp_const(e));
m_const.push_back(std::make_pair(e, v));
m_refs.push_back(e);
m_refs.push_back(v);
}
};
class pb_preprocess_tactic : public tactic {
struct rec { unsigned_vector pos, neg; rec() { } };
typedef obj_map<app, rec> var_map;
@ -119,24 +72,31 @@ class pb_preprocess_tactic : public tactic {
for (unsigned i = 0; i < m_other.size(); ++i) {
out << "ot " << m_other[i] << ": " << mk_pp(g->form(m_other[i]), m) << "\n";
}
var_map::iterator it = m_vars.begin();
var_map::iterator end = m_vars.end();
for (; it != end; ++it) {
app* e = it->m_key;
unsigned_vector const& pos = it->m_value.pos;
unsigned_vector const& neg = it->m_value.neg;
for (auto const& kv : m_vars) {
app* e = kv.m_key;
unsigned_vector const& pos = kv.m_value.pos;
unsigned_vector const& neg = kv.m_value.neg;
out << mk_pp(e, m) << ": ";
for (unsigned i = 0; i < pos.size(); ++i) {
out << "p: " << pos[i] << " ";
for (unsigned p : pos) {
out << "p: " << p << " ";
}
for (unsigned i = 0; i < neg.size(); ++i) {
out << "n: " << neg[i] << " ";
for (unsigned n : neg) {
out << "n: " << n << " ";
}
out << "\n";
}
}
void set_value(generic_model_converter& mc, expr* e, bool p) {
while (m.is_not(e, e)) {
p = !p;
}
SASSERT(is_app(e));
mc.add(to_app(e), p?m.mk_true():m.mk_false());
}
public:
pb_preprocess_tactic(ast_manager& m, params_ref const& p = params_ref()):
m(m), pb(m), m_r(m) {}
@ -156,7 +116,7 @@ public:
throw tactic_exception("pb-preprocess does not support proofs");
}
pb_preproc_model_converter* pp = alloc(pb_preproc_model_converter, m);
generic_model_converter* pp = alloc(generic_model_converter, m, "pb-preprocess");
g->add(pp);
g->inc_depth();
@ -165,7 +125,7 @@ public:
// decompose(g);
}
bool simplify(goal_ref const& g, pb_preproc_model_converter& mc) {
bool simplify(goal_ref const& g, generic_model_converter& mc) {
reset();
normalize(g);
if (g->inconsistent()) {
@ -203,11 +163,11 @@ public:
TRACE("pb", tout << mk_pp(e, m) << " " << r.pos.size() << " " << r.neg.size() << "\n";);
if (r.pos.empty()) {
replace(r.neg, e, m.mk_false(), g);
mc.set_value(e, false);
set_value(mc, e, false);
}
else if (r.neg.empty()) {
replace(r.pos, e, m.mk_true(), g);
mc.set_value(e, true);
set_value(mc, e, true);
}
if (g->inconsistent()) return false;
++it;
@ -509,7 +469,7 @@ private:
// Implement very special case of resolution.
void resolve(pb_preproc_model_converter& mc, unsigned idx1,
void resolve(generic_model_converter& mc, unsigned idx1,
unsigned_vector const& positions, app* e, bool pos, goal_ref const& g) {
if (positions.size() != 1) return;
unsigned idx2 = positions[0];
@ -558,7 +518,7 @@ private:
else {
args2[j] = m.mk_true();
}
mc.set_value(arg, j != min_index);
set_value(mc, arg, j != min_index);
}
tmp1 = pb.mk_ge(args2.size(), coeffs2.c_ptr(), args2.c_ptr(), k2);

View file

@ -181,6 +181,53 @@ void generic_model_converter::operator()(expr_ref& fml) {
fml = mk_and(fmls);
}
void generic_model_converter::get_units(obj_map<expr, bool>& units) {
th_rewriter rw(m);
expr_safe_replace rep(m);
expr_ref tmp(m);
bool val = false;
expr* f = nullptr;
for (auto const& kv : units) {
rep.insert(kv.m_key, kv.m_value ? m.mk_true() : m.mk_false());
}
for (unsigned i = m_entries.size(); i-- > 0;) {
entry const& e = m_entries[i];
switch (e.m_instruction) {
case HIDE:
tmp = m.mk_const(e.m_f);
if (units.contains(tmp)) {
m.dec_ref(tmp);
units.remove(tmp);
}
break;
case ADD:
if (e.m_f->get_arity() == 0 && m.is_bool(e.m_f->get_range())) {
tmp = m.mk_const(e.m_f);
if (units.contains(tmp)) {
break;
}
tmp = e.m_def;
rep(tmp);
rw(tmp);
if (m.is_true(tmp)) {
tmp = m.mk_const(e.m_f);
m.inc_ref(tmp);
units.insert(tmp, true);
rep.insert(tmp, m.mk_true());
}
else if (m.is_false(tmp)) {
tmp = m.mk_const(e.m_f);
m.inc_ref(tmp);
units.insert(tmp, false);
rep.insert(tmp, m.mk_false());
}
}
break;
}
}
}
/*
\brief simplify definition expansion from model converter in the case they come from blocked clauses.
In this case the definitions are of the form:

View file

@ -71,6 +71,8 @@ public:
void collect(ast_pp_util& visitor) override;
void operator()(expr_ref& fml) override;
void get_units(obj_map<expr, bool>& units) override;
};
typedef ref<generic_model_converter> generic_model_converter_ref;

View file

@ -80,6 +80,9 @@ public:
ast_manager& get_manager() { return m; }
void display(std::ostream & out) override {}
void get_units(obj_map<expr, bool>& units) override { units.reset(); }
};
#endif

View file

@ -71,14 +71,19 @@ public:
}
void operator()(expr_ref & fml) override {
this->m_c1->operator()(fml);
this->m_c2->operator()(fml);
this->m_c1->operator()(fml);
}
void operator()(labels_vec & r) override {
this->m_c2->operator()(r);
this->m_c1->operator()(r);
}
void get_units(obj_map<expr, bool>& fmls) override {
m_c2->get_units(fmls);
m_c1->get_units(fmls);
}
char const * get_name() const override { return "concat-model-converter"; }
@ -125,6 +130,10 @@ public:
fml = r;
}
void get_units(obj_map<expr, bool>& fmls) override {
// no-op
}
void cancel() override {
}

View file

@ -88,6 +88,8 @@ public:
formula and removing these definitions from the model converter.
*/
virtual void operator()(expr_ref& formula) { UNREACHABLE(); }
virtual void get_units(obj_map<expr, bool>& fmls) { UNREACHABLE(); }
};
typedef ref<model_converter> model_converter_ref;