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:
parent
60888a93eb
commit
fffc8489bf
4 changed files with 188 additions and 182 deletions
|
@ -119,11 +119,8 @@ extern "C"
|
||||||
facts.push_back (to_expr (fml));
|
facts.push_back (to_expr (fml));
|
||||||
flatten_and (facts);
|
flatten_and (facts);
|
||||||
|
|
||||||
spacer::model_evaluator_util mev (mk_c(c)->m());
|
|
||||||
mev.set_model (*model);
|
|
||||||
|
|
||||||
expr_ref_vector lits (mk_c(c)->m());
|
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 ());
|
expr_ref result (mk_c(c)->m ());
|
||||||
result = mk_and (lits);
|
result = mk_and (lits);
|
||||||
|
|
|
@ -366,7 +366,7 @@ pob *derivation::create_next_child ()
|
||||||
// get an implicant of the summary
|
// get an implicant of the summary
|
||||||
expr_ref_vector u(m), lits (m);
|
expr_ref_vector u(m), lits (m);
|
||||||
u.push_back (rf->get ());
|
u.push_back (rf->get ());
|
||||||
compute_implicant_literals (mev, u, lits);
|
compute_implicant_literals (*model, u, lits);
|
||||||
expr_ref v(m);
|
expr_ref v(m);
|
||||||
v = mk_and (lits);
|
v = mk_and (lits);
|
||||||
|
|
||||||
|
@ -1172,7 +1172,7 @@ expr_ref pred_transformer::get_origin_summary (model_evaluator_util &mev,
|
||||||
|
|
||||||
// -- pick an implicant
|
// -- pick an implicant
|
||||||
expr_ref_vector lits(m);
|
expr_ref_vector lits(m);
|
||||||
compute_implicant_literals (mev, summary, lits);
|
compute_implicant_literals (*mev.get_model(), summary, lits);
|
||||||
|
|
||||||
return mk_and(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()) {
|
if (ctx.reach_dnf()) {
|
||||||
expr_ref_vector u(m), lits(m);
|
expr_ref_vector u(m), lits(m);
|
||||||
u.push_back (res);
|
u.push_back (res);
|
||||||
compute_implicant_literals (mev, u, lits);
|
compute_implicant_literals (*mev.get_model(), u, lits);
|
||||||
res = mk_and (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(pt.get_transition(r));
|
||||||
forms.push_back(n.post());
|
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);
|
expr_ref phi = mk_and (lits);
|
||||||
|
|
||||||
// primed variables of the head
|
// primed variables of the head
|
||||||
|
|
|
@ -405,19 +405,21 @@ namespace spacer {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class implicant_picker {
|
class implicant_picker {
|
||||||
model_evaluator_util &m_mev;
|
model &m_model;
|
||||||
ast_manager &m;
|
ast_manager &m;
|
||||||
arith_util m_arith;
|
arith_util m_arith;
|
||||||
|
|
||||||
expr_ref_vector m_todo;
|
expr_ref_vector m_todo;
|
||||||
expr_mark m_visited;
|
expr_mark m_visited;
|
||||||
|
|
||||||
|
// add literal to the implicant
|
||||||
|
// applies lightweight normalization
|
||||||
void add_literal(expr *e, expr_ref_vector &out) {
|
void add_literal(expr *e, expr_ref_vector &out) {
|
||||||
SASSERT(m.is_bool(e));
|
SASSERT(m.is_bool(e));
|
||||||
|
|
||||||
expr_ref res(m), v(m);
|
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));
|
SASSERT(m.is_true(v) || m.is_false(v));
|
||||||
|
|
||||||
res = m.is_false(v) ? m.mk_not(e) : e;
|
res = m.is_false(v) ? m.mk_not(e) : e;
|
||||||
|
@ -425,7 +427,8 @@ namespace {
|
||||||
if (m.is_distinct(res)) {
|
if (m.is_distinct(res)) {
|
||||||
// --(distinct a b) == (not (= a b))
|
// --(distinct a b) == (not (= a b))
|
||||||
if (to_app(res)->get_num_args() == 2) {
|
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);
|
res = m.mk_not(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -434,38 +437,35 @@ namespace {
|
||||||
if (m.is_not(res, nres)) {
|
if (m.is_not(res, nres)) {
|
||||||
// --(not (xor a b)) == (= a b)
|
// --(not (xor a b)) == (= a b)
|
||||||
if (m.is_xor(nres, f1, f2))
|
if (m.is_xor(nres, f1, f2))
|
||||||
{ res = m.mk_eq(f1, f2); }
|
res = m.mk_eq(f1, f2);
|
||||||
|
|
||||||
// -- split arithmetic inequality
|
// -- split arithmetic inequality
|
||||||
else if (m.is_eq(nres, f1, f2) && m_arith.is_int_real(f1)) {
|
else if (m.is_eq(nres, f1, f2) && m_arith.is_int_real(f1)) {
|
||||||
expr_ref u(m);
|
expr_ref u(m);
|
||||||
u = m_arith.mk_lt(f1, f2);
|
u = m_arith.mk_lt(f1, f2);
|
||||||
if (m_mev.eval (u, v, false) && m.is_true (v))
|
res = m_model.is_true(u) ? u : m_arith.mk_lt(f2, f1);
|
||||||
{ res = u; }
|
|
||||||
else
|
|
||||||
{ res = m_arith.mk_lt(f2, f1); }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_mev.is_true (res)) {
|
if (!m_model.is_true(res)) {
|
||||||
verbose_stream() << "Bad literal: " << mk_pp(res, m) << "\n";
|
verbose_stream() << "Bad literal: " << res << "\n";
|
||||||
}
|
}
|
||||||
SASSERT (m_mev.is_true (res));
|
SASSERT(m_model.is_true(res));
|
||||||
out.push_back(res);
|
out.push_back(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_app(app *a, expr_ref_vector &out) {
|
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));
|
SASSERT(m.is_bool(a));
|
||||||
expr_ref v(m);
|
expr_ref v(m);
|
||||||
m_mev.eval (a, v, false);
|
v = m_model(a);
|
||||||
bool is_true = m.is_true(v);
|
bool is_true = m.is_true(v);
|
||||||
|
|
||||||
if (!is_true && !m.is_false(v)) return;
|
if (!is_true && !m.is_false(v)) return;
|
||||||
|
|
||||||
expr *na, *f1, *f2, *f3;
|
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
|
// noop
|
||||||
}
|
}
|
||||||
else if (a->get_family_id() != m.get_basic_family_id()) {
|
else if (a->get_family_id() != m.get_basic_family_id()) {
|
||||||
|
@ -479,14 +479,15 @@ namespace {
|
||||||
}
|
}
|
||||||
else if (m.is_distinct(a)) {
|
else if (m.is_distinct(a)) {
|
||||||
if (!is_true) {
|
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);
|
m_todo.push_back(f1);
|
||||||
}
|
}
|
||||||
else if (a->get_num_args() == 2) {
|
else if (a->get_num_args() == 2) {
|
||||||
add_literal(a, out);
|
add_literal(a, out);
|
||||||
}
|
}
|
||||||
else {
|
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)) {
|
else if (m.is_and(a)) {
|
||||||
|
@ -495,7 +496,7 @@ namespace {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for(expr* e : *a) {
|
for(expr* e : *a) {
|
||||||
if (m_mev.is_false(e)) {
|
if (m_model.is_false(e)) {
|
||||||
m_todo.push_back(e);
|
m_todo.push_back(e);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -507,16 +508,18 @@ namespace {
|
||||||
m_todo.append(a->get_num_args(), a->get_args());
|
m_todo.append(a->get_num_args(), a->get_args());
|
||||||
else {
|
else {
|
||||||
for(expr * e : *a) {
|
for(expr * e : *a) {
|
||||||
if (m_mev.is_true(e)) {
|
if (m_model.is_true(e)) {
|
||||||
m_todo.push_back(e);
|
m_todo.push_back(e);
|
||||||
break;
|
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.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());
|
m_todo.append(a->get_num_args(), a->get_args());
|
||||||
else
|
else
|
||||||
add_literal(a, out);
|
add_literal(a, out);
|
||||||
|
@ -526,19 +529,19 @@ namespace {
|
||||||
if (m.are_equal(f2, f3)) {
|
if (m.are_equal(f2, f3)) {
|
||||||
m_todo.push_back(f2);
|
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(f2);
|
||||||
m_todo.push_back(f3);
|
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(f2);
|
||||||
m_todo.push_back(f3);
|
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(f1);
|
||||||
m_todo.push_back(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);
|
m_todo.push_back(f1);
|
||||||
m_todo.push_back(f3);
|
m_todo.push_back(f3);
|
||||||
}
|
}
|
||||||
|
@ -548,16 +551,18 @@ namespace {
|
||||||
}
|
}
|
||||||
else if (m.is_implies(a, f1, f2)) {
|
else if (m.is_implies(a, f1, f2)) {
|
||||||
if (is_true) {
|
if (is_true) {
|
||||||
if (m_mev.is_true(f2))
|
if (m_model.is_true(f2))
|
||||||
m_todo.push_back(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);
|
m_todo.push_back(f1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_todo.append(a->get_num_args(), a->get_args());
|
m_todo.append(a->get_num_args(), a->get_args());
|
||||||
}
|
}
|
||||||
else {
|
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();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -579,10 +584,10 @@ namespace {
|
||||||
|
|
||||||
bool pick_implicant(const expr_ref_vector &in, expr_ref_vector &out) {
|
bool pick_implicant(const expr_ref_vector &in, expr_ref_vector &out) {
|
||||||
m_visited.reset();
|
m_visited.reset();
|
||||||
bool is_true = m_mev.is_true (in);
|
bool is_true = m_model.is_true(in);
|
||||||
|
|
||||||
for(expr* e : 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);
|
pick_literals(e, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -592,16 +597,18 @@ namespace {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
implicant_picker (model_evaluator_util &mev) :
|
implicant_picker(model &mdl) :
|
||||||
m_mev (mev), m (m_mev.get_ast_manager ()), m_arith(m), m_todo(m) {}
|
m_model(mdl), m(m_model.get_manager()), m_arith(m), m_todo(m) {}
|
||||||
|
|
||||||
void operator()(expr_ref_vector &in, expr_ref_vector& out) {
|
void operator()(expr_ref_vector &in, expr_ref_vector& out) {
|
||||||
|
model::scoped_model_completion _sc_(m_model, false);
|
||||||
pick_implicant(in, out);
|
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) {
|
expr_ref_vector &res) {
|
||||||
// flatten the formula and remove all trivial literals
|
// flatten the formula and remove all trivial literals
|
||||||
|
|
||||||
|
@ -611,7 +618,7 @@ namespace {
|
||||||
flatten_and(formula);
|
flatten_and(formula);
|
||||||
if (formula.empty()) {return;}
|
if (formula.empty()) {return;}
|
||||||
|
|
||||||
implicant_picker ipick (mev);
|
implicant_picker ipick(mdl);
|
||||||
ipick(formula, res);
|
ipick(formula, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,9 @@ namespace spacer {
|
||||||
|
|
||||||
// TBD: sort out
|
// TBD: sort out
|
||||||
void expand_literals(ast_manager &m, expr_ref_vector& conjs);
|
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 simplify_bounds (expr_ref_vector &lemmas);
|
||||||
void normalize(expr *e, expr_ref &out, bool use_simplify_bounds = true, bool factor_eqs = false);
|
void normalize(expr *e, expr_ref &out, bool use_simplify_bounds = true, bool factor_eqs = false);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue