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));
|
||||
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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue