3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-19 10:52:02 +00:00

working on symbolic execution for PDR

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2012-10-18 21:01:28 -07:00
parent 3a837037d4
commit 8f5fc3716e
13 changed files with 847 additions and 1014 deletions

View file

@ -28,65 +28,18 @@ Revision History:
namespace pdr {
static void solve_for_next_vars(expr_ref& F, model_node& n, expr_substitution& sub) {
ast_manager& m = F.get_manager();
manager& pm = n.pt().get_pdr_manager();
const model_core & mdl = n.model();
unsigned sz = mdl.get_num_constants();
expr_ref_vector refs(m);
for (unsigned i = 0; i < sz; i++) {
func_decl * d = mdl.get_constant(i);
expr_ref interp(m);
ptr_vector<app> cs;
if (m.is_bool(d->get_range())) {
get_value_from_model(mdl, d, interp);
app* c = m.mk_const(d);
refs.push_back(c);
refs.push_back(interp);
sub.insert(c, interp);
}
}
scoped_ptr<expr_replacer> rep = mk_default_expr_replacer(m);
rep->set_substitution(&sub);
(*rep)(F);
th_rewriter rw(m);
rw(F);
ptr_vector<expr> todo;
todo.push_back(F);
expr* e1, *e2;
while (!todo.empty()) {
expr* e = todo.back();
todo.pop_back();
if (m.is_and(e)) {
todo.append(to_app(e)->get_num_args(), to_app(e)->get_args());
}
else if ((m.is_eq(e, e1, e2) && pm.is_n(e1) && pm.is_o_formula(e2)) ||
(m.is_eq(e, e2, e1) && pm.is_n(e1) && pm.is_o_formula(e2))) {
sub.insert(e1, e2);
TRACE("pdr", tout << mk_pp(e1, m) << " |-> " << mk_pp(e2, m) << "\n";);
}
}
}
//
// eliminate conjuncts from cube as long as state is satisfied.
//
void model_evaluation_generalizer::operator()(model_node& n, expr_ref_vector& cube) {
ptr_vector<expr> forms;
expr_ref_vector forms(cube.get_manager());
forms.push_back(n.state());
forms.push_back(n.pt().transition());
m_model_evaluator.minimize_model(forms, cube);
}
//
// eliminate conjuncts from cube as long as state is satisfied.
//
void bool_model_evaluation_generalizer::operator()(model_node& n, expr_ref_vector& cube) {
ptr_vector<expr> forms;
forms.push_back(n.state());
forms.push_back(n.pt().transition());
m_model_evaluator.minimize_model(forms, cube);
datalog::flatten_and(forms);
ptr_vector<expr> forms1(forms.size(), forms.c_ptr());
model_ref mdl = n.model_ptr();
m_model_evaluator.minimize_model(forms1, mdl, cube);
}
//
@ -121,10 +74,6 @@ namespace pdr {
TRACE("pdr", tout << "old size: " << old_core_size << " new size: " << core.size() << "\n";);
}
//
// extract multiple cores from unreachable state.
//
void core_multi_generalizer::operator()(model_node& n, expr_ref_vector& core, bool& uses_level) {
UNREACHABLE();
@ -207,31 +156,6 @@ namespace pdr {
m_farkas_learner.collect_statistics(st);
}
void model_precond_generalizer::operator()(model_node& n, expr_ref_vector& cube) {
ast_manager& m = n.pt().get_manager();
manager& pm = n.pt().get_pdr_manager();
expr_ref A(m), state(m);
expr_ref_vector states(m);
A = n.pt().get_formulas(n.level(), true);
// extract substitution for next-state variables.
expr_substitution sub(m);
solve_for_next_vars(A, n, sub);
scoped_ptr<expr_replacer> rep = mk_default_expr_replacer(m);
rep->set_substitution(&sub);
A = m.mk_and(A, n.state());
(*rep)(A);
datalog::flatten_and(A, states);
for (unsigned i = 0; i < states.size(); ++i) {
expr* s = states[i].get();
if (pm.is_o_formula(s) && pm.is_homogenous_formula(s)) {
cube.push_back(s);
}
}
TRACE("pdr", for (unsigned i = 0; i < cube.size(); ++i) tout << mk_pp(cube[i].get(), m) << "\n";);
}
/**
< F, phi, i + 1 >
@ -567,78 +491,4 @@ namespace pdr {
uses_level = true;
}
}
//
// cube => n.state() & formula
// so n.state() & cube & ~formula is unsat
// so weaken cube while result is still unsat.
//
void model_farkas_generalizer::operator()(model_node& n, expr_ref_vector& cube) {
ast_manager& m = n.pt().get_manager();
manager& pm = n.pt().get_pdr_manager();
front_end_params& p = m_ctx.get_fparams();
farkas_learner learner(p, m);
expr_ref A0(m), A(m), B(m), state(m);
expr_ref_vector states(m);
A0 = n.pt().get_formulas(n.level(), true);
// extract substitution for next-state variables.
expr_substitution sub(m);
solve_for_next_vars(A0, n, sub);
scoped_ptr<expr_replacer> rep = mk_default_expr_replacer(m);
rep->set_substitution(&sub);
(*rep)(A0);
A0 = m.mk_not(A0);
state = n.state();
(*rep)(state);
datalog::flatten_and(state, states);
ptr_vector<func_decl> preds;
n.pt().find_predecessors(n.model(), preds);
TRACE("pdr", for (unsigned i = 0; i < cube.size(); ++i) tout << mk_pp(cube[i].get(), m) << "\n";);
for (unsigned i = 0; i < preds.size(); ++i) {
pred_transformer& pt = m_ctx.get_pred_transformer(preds[i]);
SASSERT(pt.head() == preds[i]);
expr_ref_vector lemmas(m), o_cube(m), other(m), o_state(m), other_state(m);
pm.partition_o_atoms(cube, o_cube, other, i);
pm.partition_o_atoms(states, o_state, other_state, i);
TRACE("pdr",
tout << "cube:\n";
for (unsigned i = 0; i < cube.size(); ++i) tout << mk_pp(cube[i].get(), m) << "\n";
tout << "o_cube:\n";
for (unsigned i = 0; i < o_cube.size(); ++i) tout << mk_pp(o_cube[i].get(), m) << "\n";
tout << "other:\n";
for (unsigned i = 0; i < other.size(); ++i) tout << mk_pp(other[i].get(), m) << "\n";
tout << "o_state:\n";
for (unsigned i = 0; i < o_state.size(); ++i) tout << mk_pp(o_state[i].get(), m) << "\n";
tout << "other_state:\n";
for (unsigned i = 0; i < other_state.size(); ++i) tout << mk_pp(other_state[i].get(), m) << "\n";
);
A = m.mk_and(A0, pm.mk_and(other), pm.mk_and(other_state));
B = m.mk_and(pm.mk_and(o_cube), pm.mk_and(o_state));
TRACE("pdr",
tout << "A: " << mk_pp(A, m) << "\n";
tout << "B: " << mk_pp(B, m) << "\n";);
if (learner.get_lemma_guesses(A, B, lemmas)) {
cube.append(lemmas);
cube.append(o_state);
TRACE("pdr",
tout << "New lemmas:\n";
for (unsigned i = 0; i < lemmas.size(); ++i) {
tout << mk_pp(lemmas[i].get(), m) << "\n";
}
);
}
}
TRACE("pdr", for (unsigned i = 0; i < cube.size(); ++i) tout << mk_pp(cube[i].get(), m) << "\n";);
}
};