void inductive_property::to_model(model_ref& md) const { md = alloc(model, m); vector<relation_info> const& rs = m_relation_info; expr_ref_vector conjs(m); for (unsigned i = 0; i < rs.size(); ++i) { relation_info ri(rs[i]); func_decl * pred = ri.m_pred; expr_ref prop = fixup_clauses(ri.m_body); func_decl_ref_vector const& sig = ri.m_vars; expr_ref q(m); expr_ref_vector sig_vars(m); for (unsigned j = 0; j < sig.size(); ++j) { sig_vars.push_back(m.mk_const(sig[sig.size()-j-1])); } expr_abstract(m, 0, sig_vars.size(), sig_vars.c_ptr(), prop, q); if (sig.empty()) { md->register_decl(pred, q); } else { func_interp* fi = alloc(func_interp, m, sig.size()); fi->set_else(q); md->register_decl(pred, fi); } } TRACE("pdr", model_smt2_pp(tout, m, *md, 0););
expr_ref inductive_property::fixup_clauses(expr* fml) const { expr_ref_vector conjs(m); expr_ref result(m); flatten_and(fml, conjs); for (unsigned i = 0; i < conjs.size(); ++i) { conjs[i] = fixup_clause(conjs[i].get()); } bool_rewriter(m).mk_and(conjs.size(), conjs.c_ptr(), result); return result; }
expr_ref udoc_relation::to_formula(doc const& d) const { ast_manager& m = get_plugin().get_ast_manager(); expr_ref result(m); expr_ref_vector conjs(m); conjs.push_back(to_formula(d.pos())); for (unsigned i = 0; i < d.neg().size(); ++i) { conjs.push_back(m.mk_not(to_formula(d.neg()[i]))); } result = mk_and(m, conjs.size(), conjs.c_ptr()); return result; }
expr_ref udoc_relation::to_formula(tbv const& t) const { udoc_plugin& p = get_plugin(); ast_manager& m = p.get_ast_manager(); expr_ref result(m); expr_ref_vector conjs(m); for (unsigned i = 0; i < get_num_cols(); ++i) { var_ref v(m); v = m.mk_var(i, get_signature()[i]); unsigned lo = column_idx(i); unsigned hi = column_idx(i+1); rational r(0); unsigned lo1 = lo; bool is_x = true; for (unsigned j = lo; j < hi; ++j) { switch(t[j]) { case BIT_0: if (is_x) is_x = false, lo1 = j, r.reset(); break; case BIT_1: if (is_x) is_x = false, lo1 = j, r.reset(); r += rational::power_of_two(j - lo1); break; case BIT_x: if (!is_x) { SASSERT(p.bv.is_bv_sort(get_signature()[i])); conjs.push_back(m.mk_eq(p.bv.mk_extract(j-1-lo,lo1-lo,v), p.bv.mk_numeral(r,j-lo1))); } is_x = true; break; default: UNREACHABLE(); } } if (!is_x) { expr_ref num(m); if (lo1 == lo) { num = p.mk_numeral(r, get_signature()[i]); conjs.push_back(m.mk_eq(v, num)); } else { num = p.bv.mk_numeral(r, hi-lo1); conjs.push_back(m.mk_eq(p.bv.mk_extract(hi-1-lo,lo1-lo,v), num)); } } } result = mk_and(m, conjs.size(), conjs.c_ptr()); return result; }
void mk_coalesce::merge_rules(rule_ref& tgt, rule const& src) { SASSERT(same_body(*tgt.get(), src)); m_sub1.reset(); m_sub2.reset(); m_idx = 0; app_ref pred(m), head(m); expr_ref fml1(m), fml2(m), fml(m); app_ref_vector tail(m); ptr_vector<sort> sorts1, sorts2; expr_ref_vector conjs1(m), conjs(m); rule_ref res(rm); bool_rewriter bwr(m); svector<bool> is_neg; tgt->get_vars(sorts1); src.get_vars(sorts2); mk_pred(head, src.get_head(), tgt->get_head()); for (unsigned i = 0; i < src.get_uninterpreted_tail_size(); ++i) { mk_pred(pred, src.get_tail(i), tgt->get_tail(i)); tail.push_back(pred); is_neg.push_back(src.is_neg_tail(i)); } extract_conjs(m_sub1, src, fml1); extract_conjs(m_sub2, *tgt.get(), fml2); bwr.mk_or(fml1, fml2, fml); SASSERT(is_app(fml)); tail.push_back(to_app(fml)); is_neg.push_back(false); res = rm.mk(head, tail.size(), tail.c_ptr(), is_neg.c_ptr(), tgt->name()); if (m_ctx.generate_proof_trace()) { src.to_formula(fml1); tgt->to_formula(fml2); res->to_formula(fml); #if 0 sort* ps = m.mk_proof_sort(); sort* domain[3] = { ps, ps, m.mk_bool_sort() }; func_decl* merge = m.mk_func_decl(symbol("merge-clauses"), 3, domain, ps); // TBD: ad-hoc proof rule expr* args[3] = { m.mk_asserted(fml1), m.mk_asserted(fml2), fml }; // ...m_pc->insert(m.mk_app(merge, 3, args)); #else svector<std::pair<unsigned, unsigned> > pos; vector<expr_ref_vector> substs; proof* p = src.get_proof(); p = m.mk_hyper_resolve(1, &p, fml, pos, substs); res->set_proof(m, p); #endif } tgt = res; }
void mk_coalesce::extract_conjs(expr_ref_vector const& sub, rule const& rl, expr_ref& result) { obj_map<expr, unsigned> indices; bool_rewriter bwr(m); rule_ref r(const_cast<rule*>(&rl), rm); ptr_vector<sort> sorts; expr_ref_vector revsub(m), conjs(m); rl.get_vars(sorts); revsub.resize(sorts.size()); svector<bool> valid(sorts.size(), true); for (unsigned i = 0; i < sub.size(); ++i) { expr* e = sub[i]; sort* s = m.get_sort(e); expr_ref w(m.mk_var(i, s), m); if (is_var(e)) { unsigned v = to_var(e)->get_idx(); SASSERT(v < valid.size()); if (sorts[v]) { SASSERT(s == sorts[v]); if (valid[v]) { revsub[v] = w; valid[v] = false; } else { SASSERT(revsub[v].get()); SASSERT(m.get_sort(revsub[v].get()) == s); conjs.push_back(m.mk_eq(revsub[v].get(), w)); } } } else { SASSERT(m.is_value(e)); SASSERT(m.get_sort(e) == m.get_sort(w)); conjs.push_back(m.mk_eq(e, w)); } } for (unsigned i = 0; i < sorts.size(); ++i) { if (valid[i] && sorts[i] && !revsub[i].get()) { revsub[i] = m.mk_var(m_idx++, sorts[i]); } } var_subst vs(m, false); for (unsigned i = r->get_uninterpreted_tail_size(); i < r->get_tail_size(); ++i) { vs(r->get_tail(i), revsub.size(), revsub.c_ptr(), result); conjs.push_back(result); } bwr.mk_and(conjs.size(), conjs.c_ptr(), result); }
void table_base::to_formula(relation_signature const& sig, expr_ref& fml) const { // iterate over rows and build disjunction ast_manager & m = fml.get_manager(); expr_ref_vector disjs(m); expr_ref_vector conjs(m); dl_decl_util util(m); bool_rewriter brw(m); table_fact fact; iterator it = begin(); iterator iend = end(); for(; it != iend; ++it) { const row_interface & r = *it; r.get_fact(fact); conjs.reset(); for (unsigned i = 0; i < fact.size(); ++i) { conjs.push_back(m.mk_eq(m.mk_var(i, sig[i]), util.mk_numeral(fact[i], sig[i]))); } brw.mk_and(conjs.size(), conjs.c_ptr(), fml); disjs.push_back(fml); } brw.mk_or(disjs.size(), disjs.c_ptr(), fml); }
bool mk_array_blast::ackermanize(rule const& r, expr_ref& body, expr_ref& head) { expr_ref_vector conjs(m), trail(m); flatten_and(body, conjs); m_defs.reset(); m_next_var = 0; ptr_vector<expr> todo; obj_map<expr, expr*> cache; ptr_vector<expr> args; app_ref e1(m); app* s; var* v; for (unsigned i = 0; i < conjs.size(); ++i) { expr* e = conjs[i].get(); if (is_select_eq_var(e, s, v)) { todo.append(s->get_num_args(), s->get_args()); } else { todo.push_back(e); } } while (!todo.empty()) { expr* e = todo.back(); if (cache.contains(e)) { todo.pop_back(); continue; } if (is_var(e)) { cache.insert(e, e); todo.pop_back(); continue; } if (!is_app(e)) { return false; } app* ap = to_app(e); bool valid = true; args.reset(); for (unsigned i = 0; i < ap->get_num_args(); ++i) { expr* arg; if (cache.find(ap->get_arg(i), arg)) { args.push_back(arg); } else { todo.push_back(ap->get_arg(i)); valid = false; } } if (valid) { todo.pop_back(); e1 = m.mk_app(ap->get_decl(), args.size(), args.c_ptr()); trail.push_back(e1); if (a.is_select(ap)) { if (m_defs.find(e1, v)) { cache.insert(e, v); } else if (!insert_def(r, e1, 0)) { return false; } else { cache.insert(e, m_defs.find(e1)); } } else { cache.insert(e, e1); } } } for (unsigned i = 0; i < conjs.size(); ++i) { expr* e = conjs[i].get(); if (is_select_eq_var(e, s, v)) { args.reset(); for (unsigned j = 0; j < s->get_num_args(); ++j) { args.push_back(cache.find(s->get_arg(j))); } e1 = m.mk_app(s->get_decl(), args.size(), args.c_ptr()); if (!m_defs.contains(e1) && !insert_def(r, e1, v)) { return false; } conjs[i] = m.mk_eq(v, m_defs.find(e1)); } else { conjs[i] = cache.find(e); } } // perform the Ackermann reduction by creating implications // i1 = i2 => val1 = val2 for each equality pair: // (= val1 (select a_i i1)) // (= val2 (select a_i i2)) defs_t::iterator it1 = m_defs.begin(), end = m_defs.end(); for (; it1 != end; ++it1) { app* a1 = it1->m_key; var* v1 = it1->m_value; defs_t::iterator it2 = it1; ++it2; for (; it2 != end; ++it2) { app* a2 = it2->m_key; var* v2 = it2->m_value; TRACE("dl", tout << mk_pp(a1, m) << " " << mk_pp(a2, m) << "\n";); if (get_select(a1) != get_select(a2)) { continue; } expr_ref_vector eqs(m); ptr_vector<expr> args1, args2; get_select_args(a1, args1); get_select_args(a2, args2); for (unsigned j = 0; j < args1.size(); ++j) { eqs.push_back(m.mk_eq(args1[j], args2[j])); } conjs.push_back(m.mk_implies(m.mk_and(eqs.size(), eqs.c_ptr()), m.mk_eq(v1, v2))); } }