void context::check_quantifier_free(rule_ref& r) { if (r->has_quantifiers()) { std::stringstream stm; stm << "cannot process quantifiers in rule "; r->display(*this, stm); throw default_exception(stm.str()); } }
bool mk_subsumption_checker::transform_rule(rule * r, rule_subsumption_index& subs_index, rule_ref & res) { unsigned u_len = r->get_uninterpreted_tail_size(); unsigned len = r->get_tail_size(); if(u_len==0) { res = r; return true; } app_ref head(r->get_head(), m); app_ref_vector tail(m); svector<bool> tail_neg; for(unsigned i=0; i<u_len; i++) { app * tail_atom = r->get_tail(i); bool neg = r->is_neg_tail(i); if(m_total_relations.contains(tail_atom->get_decl()) || subs_index.is_subsumed(tail_atom)) { if(neg) { //rule contains negated total relation, this means that it is unsatisfiable //and can be removed return false; } else { //we remove total relations from the tail continue; } } if(!neg && head.get()==tail_atom) { //rule contains its head positively in the tail, therefore //it will never add any new facts to the relation, so it //can be removed return false; } tail.push_back(tail_atom); tail_neg.push_back(neg); } if(tail.size()==u_len) { res = r; return true; } //we just copy the interpreted part of the tail for(unsigned i=u_len; i<len; i++) { tail.push_back(r->get_tail(i)); tail_neg.push_back(r->is_neg_tail(i)); } SASSERT(tail.size()==tail_neg.size()); res = m_context.get_rule_manager().mk(head, tail.size(), tail.c_ptr(), tail_neg.c_ptr()); res->set_accounting_parent_object(m_context, r); m_context.get_rule_manager().fix_unbound_vars(res, true); m_context.get_rule_manager().mk_rule_rewrite_proof(*r, *res.get()); return true; }
void context::check_uninterpreted_free(rule_ref& r) { func_decl* f = 0; if (r->has_uninterpreted_non_predicates(m, f)) { std::stringstream stm; stm << "Uninterpreted '" << f->get_name() << "' in "; r->display(*this, stm); throw default_exception(stm.str()); } }
void mk_interp_tail_simplifier::rule_substitution::get_result(rule_ref & res) { SASSERT(m_rule); apply(m_rule->get_head(), m_head); m_tail.reset(); m_neg.reset(); unsigned tail_len = m_rule->get_tail_size(); for (unsigned i=0; i<tail_len; i++) { app_ref new_tail_el(m); apply(m_rule->get_tail(i), new_tail_el); m_tail.push_back(new_tail_el); m_neg.push_back(m_rule->is_neg_tail(i)); } mk_rule_inliner::remove_duplicate_tails(m_tail, m_neg); SASSERT(m_tail.size() == m_neg.size()); res = m_context.get_rule_manager().mk(m_head, m_tail.size(), m_tail.c_ptr(), m_neg.c_ptr(),m_rule->name()); res->set_accounting_parent_object(m_context, m_rule); res->norm_vars(res.get_manager()); }
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 context::check_existential_tail(rule_ref& r) { unsigned ut_size = r->get_uninterpreted_tail_size(); unsigned t_size = r->get_tail_size(); TRACE("dl", r->display_smt2(get_manager(), tout); tout << "\n";);