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:
parent
75ba65a18a
commit
718e5a9b6c
27 changed files with 207 additions and 76 deletions
|
@ -119,6 +119,8 @@ class eq2bv_tactic : public tactic {
|
|||
}
|
||||
}
|
||||
|
||||
virtual void get_units(obj_map<expr, bool>& units) { units.reset(); }
|
||||
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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););
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue