예제 #1
0
 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););
예제 #2
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;
 }
예제 #3
0
 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;
 }
예제 #4
0
 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;
 }
예제 #5
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;
    }
예제 #6
0
 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);
 }
예제 #7
0
파일: dl_base.cpp 프로젝트: Jornason/z3
 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);        
 }
예제 #8
0
    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)));
            }
        }