Exemple #1
0
    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;
    }
    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;
    }