3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-20 12:53:38 +00:00

Switched compute_implicant_literals to use new model API

This commit is contained in:
Arie Gurfinkel 2018-06-16 13:43:30 -07:00
parent 60888a93eb
commit fffc8489bf
4 changed files with 188 additions and 182 deletions

View file

@ -119,11 +119,8 @@ extern "C"
facts.push_back (to_expr (fml));
flatten_and (facts);
spacer::model_evaluator_util mev (mk_c(c)->m());
mev.set_model (*model);
expr_ref_vector lits (mk_c(c)->m());
spacer::compute_implicant_literals (mev, facts, lits);
spacer::compute_implicant_literals (*model, facts, lits);
expr_ref result (mk_c(c)->m ());
result = mk_and (lits);

View file

@ -366,7 +366,7 @@ pob *derivation::create_next_child ()
// get an implicant of the summary
expr_ref_vector u(m), lits (m);
u.push_back (rf->get ());
compute_implicant_literals (mev, u, lits);
compute_implicant_literals (*model, u, lits);
expr_ref v(m);
v = mk_and (lits);
@ -1172,7 +1172,7 @@ expr_ref pred_transformer::get_origin_summary (model_evaluator_util &mev,
// -- pick an implicant
expr_ref_vector lits(m);
compute_implicant_literals (mev, summary, lits);
compute_implicant_literals (*mev.get_model(), summary, lits);
return mk_and(lits);
}
@ -3599,7 +3599,7 @@ reach_fact *pred_transformer::mk_rf (pob& n, model_evaluator_util &mev,
if (ctx.reach_dnf()) {
expr_ref_vector u(m), lits(m);
u.push_back (res);
compute_implicant_literals (mev, u, lits);
compute_implicant_literals (*mev.get_model(), u, lits);
res = mk_and (lits);
}
@ -3670,7 +3670,7 @@ bool context::create_children(pob& n, datalog::rule const& r,
forms.push_back(pt.get_transition(r));
forms.push_back(n.post());
compute_implicant_literals (mev, forms, lits);
compute_implicant_literals (*mev.get_model(), forms, lits);
expr_ref phi = mk_and (lits);
// primed variables of the head

View file

@ -405,19 +405,21 @@ namespace spacer {
namespace {
class implicant_picker {
model_evaluator_util &m_mev;
model &m_model;
ast_manager &m;
arith_util m_arith;
expr_ref_vector m_todo;
expr_mark m_visited;
// add literal to the implicant
// applies lightweight normalization
void add_literal(expr *e, expr_ref_vector &out) {
SASSERT(m.is_bool(e));
expr_ref res(m), v(m);
m_mev.eval (e, v, false);
v = m_model(e);
// the literal must have a value
SASSERT(m.is_true(v) || m.is_false(v));
res = m.is_false(v) ? m.mk_not(e) : e;
@ -425,7 +427,8 @@ namespace {
if (m.is_distinct(res)) {
// --(distinct a b) == (not (= a b))
if (to_app(res)->get_num_args() == 2) {
res = m.mk_eq (to_app(res)->get_arg(0), to_app(res)->get_arg(1));
res = m.mk_eq(to_app(res)->get_arg(0),
to_app(res)->get_arg(1));
res = m.mk_not(res);
}
}
@ -434,38 +437,35 @@ namespace {
if (m.is_not(res, nres)) {
// --(not (xor a b)) == (= a b)
if (m.is_xor(nres, f1, f2))
{ res = m.mk_eq(f1, f2); }
res = m.mk_eq(f1, f2);
// -- split arithmetic inequality
else if (m.is_eq(nres, f1, f2) && m_arith.is_int_real(f1)) {
expr_ref u(m);
u = m_arith.mk_lt(f1, f2);
if (m_mev.eval (u, v, false) && m.is_true (v))
{ res = u; }
else
{ res = m_arith.mk_lt(f2, f1); }
res = m_model.is_true(u) ? u : m_arith.mk_lt(f2, f1);
}
}
if (!m_mev.is_true (res)) {
verbose_stream() << "Bad literal: " << mk_pp(res, m) << "\n";
if (!m_model.is_true(res)) {
verbose_stream() << "Bad literal: " << res << "\n";
}
SASSERT (m_mev.is_true (res));
SASSERT(m_model.is_true(res));
out.push_back(res);
}
void process_app(app *a, expr_ref_vector &out) {
if (m_visited.is_marked(a)) { return; }
if (m_visited.is_marked(a)) return;
SASSERT(m.is_bool(a));
expr_ref v(m);
m_mev.eval (a, v, false);
v = m_model(a);
bool is_true = m.is_true(v);
if (!is_true && !m.is_false(v)) return;
expr *na, *f1, *f2, *f3;
if (m.is_true(a) || m.is_false(a)) {
SASSERT(!m.is_false(a));
if (m.is_true(a)) {
// noop
}
else if (a->get_family_id() != m.get_basic_family_id()) {
@ -479,14 +479,15 @@ namespace {
}
else if (m.is_distinct(a)) {
if (!is_true) {
f1 = qe::project_plugin::pick_equality(m, *m_mev.get_model(), a);
f1 = qe::project_plugin::pick_equality(m, m_model, a);
m_todo.push_back(f1);
}
else if (a->get_num_args() == 2) {
add_literal(a, out);
}
else {
m_todo.push_back(m.mk_distinct_expanded(a->get_num_args(), a->get_args()));
m_todo.push_back(m.mk_distinct_expanded(a->get_num_args(),
a->get_args()));
}
}
else if (m.is_and(a)) {
@ -495,7 +496,7 @@ namespace {
}
else {
for(expr* e : *a) {
if (m_mev.is_false(e)) {
if (m_model.is_false(e)) {
m_todo.push_back(e);
break;
}
@ -507,16 +508,18 @@ namespace {
m_todo.append(a->get_num_args(), a->get_args());
else {
for(expr * e : *a) {
if (m_mev.is_true(e)) {
if (m_model.is_true(e)) {
m_todo.push_back(e);
break;
}
}
}
}
else if (m.is_eq(a, f1, f2) || (is_true && m.is_not(a, na) && m.is_xor (na, f1, f2))) {
else if (m.is_eq(a, f1, f2) ||
(is_true && m.is_not(a, na) && m.is_xor(na, f1, f2))) {
if (!m.are_equal(f1, f2) && !m.are_distinct(f1, f2)) {
if (m.is_bool(f1) && (!is_uninterp_const(f1) || !is_uninterp_const(f2)))
if (m.is_bool(f1) &&
(!is_uninterp_const(f1) || !is_uninterp_const(f2)))
m_todo.append(a->get_num_args(), a->get_args());
else
add_literal(a, out);
@ -526,19 +529,19 @@ namespace {
if (m.are_equal(f2, f3)) {
m_todo.push_back(f2);
}
else if (m_mev.is_true (f2) && m_mev.is_true (f3)) {
else if (m_model.is_true(f2) && m_model.is_true(f3)) {
m_todo.push_back(f2);
m_todo.push_back(f3);
}
else if (m_mev.is_false(f2) && m_mev.is_false(f3)) {
else if (m_model.is_false(f2) && m_model.is_false(f3)) {
m_todo.push_back(f2);
m_todo.push_back(f3);
}
else if (m_mev.is_true(f1)) {
else if (m_model.is_true(f1)) {
m_todo.push_back(f1);
m_todo.push_back(f2);
}
else if (m_mev.is_false(f1)) {
else if (m_model.is_false(f1)) {
m_todo.push_back(f1);
m_todo.push_back(f3);
}
@ -548,16 +551,18 @@ namespace {
}
else if (m.is_implies(a, f1, f2)) {
if (is_true) {
if (m_mev.is_true(f2))
if (m_model.is_true(f2))
m_todo.push_back(f2);
else if (m_mev.is_false(f1))
else if (m_model.is_false(f1))
m_todo.push_back(f1);
}
else
m_todo.append(a->get_num_args(), a->get_args());
}
else {
IF_VERBOSE(0, verbose_stream () << "Unexpected expression: " << mk_pp(a, m) << "\n");
IF_VERBOSE(0,
verbose_stream() << "Unexpected expression: "
<< mk_pp(a, m) << "\n");
UNREACHABLE();
}
}
@ -579,10 +584,10 @@ namespace {
bool pick_implicant(const expr_ref_vector &in, expr_ref_vector &out) {
m_visited.reset();
bool is_true = m_mev.is_true (in);
bool is_true = m_model.is_true(in);
for(expr* e : in) {
if (is_true || m_mev.is_true(e)) {
if (is_true || m_model.is_true(e)) {
pick_literals(e, out);
}
}
@ -592,16 +597,18 @@ namespace {
public:
implicant_picker (model_evaluator_util &mev) :
m_mev (mev), m (m_mev.get_ast_manager ()), m_arith(m), m_todo(m) {}
implicant_picker(model &mdl) :
m_model(mdl), m(m_model.get_manager()), m_arith(m), m_todo(m) {}
void operator()(expr_ref_vector &in, expr_ref_vector& out) {
model::scoped_model_completion _sc_(m_model, false);
pick_implicant(in, out);
}
};
}
void compute_implicant_literals (model_evaluator_util &mev, expr_ref_vector &formula,
void compute_implicant_literals(model &mdl,
expr_ref_vector &formula,
expr_ref_vector &res) {
// flatten the formula and remove all trivial literals
@ -611,7 +618,7 @@ namespace {
flatten_and(formula);
if (formula.empty()) {return;}
implicant_picker ipick (mev);
implicant_picker ipick(mdl);
ipick(formula, res);
}

View file

@ -129,7 +129,9 @@ namespace spacer {
// TBD: sort out
void expand_literals(ast_manager &m, expr_ref_vector& conjs);
void compute_implicant_literals (model_evaluator_util &mev, expr_ref_vector &formula, expr_ref_vector &res);
void compute_implicant_literals(model &mdl,
expr_ref_vector &formula,
expr_ref_vector &res);
void simplify_bounds (expr_ref_vector &lemmas);
void normalize(expr *e, expr_ref &out, bool use_simplify_bounds = true, bool factor_eqs = false);