void mk_safe(expr_ref_vector& conjs) { qe::flatten_and(conjs); expand_literals(conjs); for (unsigned i = 0; i < conjs.size(); ++i) { expr * lit = conjs[i].get(); expr * lit_core = lit; m.is_not(lit, lit_core); SASSERT(!m.is_true(lit)); if (!is_uninterp(lit_core) || to_app(lit_core)->get_num_args() != 0) { conjs[i] = mk_proxy(lit); } } m_assumptions.append(conjs); }
// ------------------------ // lemma_bool_inductive_generalizer /// Inductive generalization by dropping and expanding literals void lemma_bool_inductive_generalizer::operator()(lemma_ref &lemma) { if (lemma->get_cube().empty()) return; m_st.count++; scoped_watch _w_(m_st.watch); unsigned uses_level; pred_transformer &pt = lemma->get_pob()->pt(); ast_manager &m = pt.get_ast_manager(); contains_array_op_proc has_array_op(m); check_pred has_arrays(has_array_op, m); expr_ref_vector cube(m); cube.append(lemma->get_cube()); bool dirty = false; expr_ref true_expr(m.mk_true(), m); ptr_vector<expr> processed; expr_ref_vector extra_lits(m); unsigned weakness = lemma->weakness(); unsigned i = 0, num_failures = 0; while (i < cube.size() && (!m_failure_limit || num_failures < m_failure_limit)) { expr_ref lit(m); lit = cube.get(i); if (m_array_only && !has_arrays(lit)) { processed.push_back(lit); ++i; continue; } cube[i] = true_expr; if (cube.size() > 1 && pt.check_inductive(lemma->level(), cube, uses_level, weakness)) { num_failures = 0; dirty = true; for (i = 0; i < cube.size() && processed.contains(cube.get(i)); ++i); } else { // check if the literal can be expanded and any single // literal in the expansion can replace it extra_lits.reset(); extra_lits.push_back(lit); expand_literals(m, extra_lits); SASSERT(extra_lits.size() > 0); bool found = false; if (extra_lits.get(0) != lit && extra_lits.size() > 1) { for (unsigned j = 0, sz = extra_lits.size(); !found && j < sz; ++j) { cube[i] = extra_lits.get(j); if (pt.check_inductive(lemma->level(), cube, uses_level, weakness)) { num_failures = 0; dirty = true; found = true; processed.push_back(extra_lits.get(j)); for (i = 0; i < cube.size() && processed.contains(cube.get(i)); ++i); } } } if (!found) { cube[i] = lit; processed.push_back(lit); ++num_failures; ++m_st.num_failures; ++i; } } } if (dirty) { TRACE("spacer", tout << "Generalized from:\n" << mk_and(lemma->get_cube()) << "\ninto\n" << mk_and(cube) << "\n";); lemma->update_cube(lemma->get_pob(), cube); SASSERT(uses_level >= lemma->level()); lemma->set_level(uses_level); }