Пример #1
0
 void subst(contains_app& x, rational const& vl, expr_ref& fml, expr_ref* def) override {
     app_ref c(m_bv.mk_numeral(vl, m_bv.get_bv_size(x.x())), m);
     m_replace.apply_substitution(x.x(), c, fml);
     if (def) {
         *def = m_bv.mk_numeral(vl, m_bv.get_bv_size(x.x()));
     }
 }
Пример #2
0
        bool reduce_quantifier(
            quantifier * q,
            expr * old_body,
            expr * const * new_patterns,
            expr * const * new_no_patterns,
            expr_ref & result,
            proof_ref & result_pr) {

            if (q->get_kind() == lambda_k) return false;
            m_sorts.reset();
            expr_ref_vector bounds(m);
            bool found = false;
            for (unsigned i = 0; i < q->get_num_decls(); ++i) {
                sort* s = q->get_decl_sort(i);
                if (m_imp.is_fd(s)) {
                    unsigned bv_size = get_bv_size(s);
                    m_sorts.push_back(m_bv.mk_sort(bv_size));
                    unsigned nc = m_dt.get_datatype_num_constructors(s);
                    if (!is_power_of_two(nc) || nc == 1) {
                        bounds.push_back(m_bv.mk_ule(m.mk_var(q->get_num_decls()-i-1, m_sorts[i]), m_bv.mk_numeral(nc-1, bv_size)));
                    }                
                    found = true;
                }
                else {
                    m_sorts.push_back(s);
                }
            }
            if (!found) {
                return false;
            }
            expr_ref new_body_ref(old_body, m), tmp(m);
            if (!bounds.empty()) {
                switch (q->get_kind()) {
                case forall_k:
                    new_body_ref = m.mk_implies(mk_and(bounds), new_body_ref);
                    break;
                case exists_k:
                    bounds.push_back(new_body_ref);
                    new_body_ref = mk_and(bounds);
                    break;
                case lambda_k:
                    UNREACHABLE();
                    break;
                }
            }
            result = m.mk_quantifier(q->get_kind(), q->get_num_decls(), m_sorts.c_ptr(), q->get_decl_names(), new_body_ref, 
                                     q->get_weight(), q->get_qid(), q->get_skid(), 
                                     q->get_num_patterns(), new_patterns,
                                     q->get_num_no_patterns(), new_no_patterns);
            result_pr = nullptr;
            return true;
        }
Пример #3
0
    void operator()(app * n) {
        if (!m.is_bool(n) && !u.is_bv(n))
            throw found();
        family_id fid = n->get_family_id();
        if (fid == m.get_basic_family_id())
            return;
        if (fid == u.get_family_id())
            return;
        if (is_uninterp_const(n))
            return;

        throw found();
    }
Пример #4
0
    void operator()(app * n) {
        sort * s = get_sort(n);
        if (!m.is_bool(s) && !fu.is_float(s) && !fu.is_rm(s) && !bu.is_bv_sort(s) && !au.is_real(s))
            throw found();
        family_id fid = n->get_family_id();
        if (fid == m.get_basic_family_id())
            return;
        if (fid == fu.get_family_id() || fid == bu.get_family_id())
            return;
        if (is_uninterp_const(n))
            return;
        if (au.is_real(s) && au.is_numeral(n))
            return;

        throw found();
    }
Пример #5
0
 bool project(contains_app& x, model_ref& model, expr_ref& fml) override {
     model_evaluator model_eval(*model);
     expr_ref val_x(m);
     rational val(0);
     unsigned bv_size;
     model_eval(x.x(), val_x);
     m_bv.is_numeral(val_x, val, bv_size);
     subst(x, val, fml, nullptr);
     return true;
 }
Пример #6
0
        bool reduce_arg(expr* a, expr_ref& result) {

            sort* s = get_sort(a);
            if (!m_imp.is_fd(s)) {
                return false;
            }
            unsigned bv_size = get_bv_size(s);

            if (is_var(a)) {
                result = m.mk_var(to_var(a)->get_idx(), m_bv.mk_sort(bv_size));
                return true;
            }
            SASSERT(is_app(a));
            func_decl* f = to_app(a)->get_decl();
            if (m_dt.is_constructor(f)) {
                unsigned idx = m_dt.get_constructor_idx(f);
                result = m_bv.mk_numeral(idx, bv_size);
            }
            else if (is_uninterp_const(a)) {
                func_decl* f_fresh;
                if (m_imp.m_enum2bv.find(f, f_fresh)) {
                    result = m.mk_const(f_fresh);
                    return true;
                }

                // create a fresh variable, add bounds constraints for it.
                unsigned nc = m_dt.get_datatype_num_constructors(s);
                result = m.mk_fresh_const(f->get_name().str().c_str(), m_bv.mk_sort(bv_size));
                f_fresh = to_app(result)->get_decl();
                if (!is_power_of_two(nc) || nc == 1) {
                    m_imp.m_bounds.push_back(m_bv.mk_ule(result, m_bv.mk_numeral(nc-1, bv_size)));
                }                
                expr_ref f_def(m);
                ptr_vector<func_decl> const& cs = *m_dt.get_datatype_constructors(s);
                f_def = m.mk_const(cs[nc-1]);
                for (unsigned i = nc - 1; i > 0; ) {
                    --i;
                    f_def = m.mk_ite(m.mk_eq(result, m_bv.mk_numeral(i,bv_size)), m.mk_const(cs[i]), f_def);
                }
                m_imp.m_enum2def.insert(f, f_def);
                m_imp.m_enum2bv.insert(f, f_fresh);
                m_imp.m_bv2enum.insert(f_fresh, f);
                m_imp.m_enum_consts.push_back(f);
                m_imp.m_enum_bvs.push_back(f_fresh);
                m_imp.m_enum_defs.push_back(f_def);
            }
            else {
                throw_non_fd(a);
            }
            ++m_imp.m_num_translated;
            return true;
        }
Пример #7
0
 br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) {
     expr_ref a0(m), a1(m);
     expr_ref_vector _args(m);
     if (m.is_eq(f) && reduce_arg(args[0], a0) && reduce_arg(args[1], a1)) {
         result = m.mk_eq(a0, a1);
         return BR_DONE;
     }
     else if (m.is_distinct(f) && reduce_args(num, args, _args)) {
         result = m.mk_distinct(_args.size(), _args.c_ptr());
         return BR_DONE;
     }
     else if (m_dt.is_recognizer(f) && reduce_arg(args[0], a0)) {
         unsigned idx = m_dt.get_recognizer_constructor_idx(f);
         a1 = m_bv.mk_numeral(rational(idx), get_sort(a0));
         result = m.mk_eq(a0, a1);
         return BR_DONE;
     }
     else {
         check_for_fd(num, args);
         return BR_FAILED;
     }
 }
Пример #8
0
 bool get_num_branches(contains_app& x, expr* fml, rational& nb) override {
     unsigned sz = m_bv.get_bv_size(x.x());
     nb = power(rational(2), sz);
     return true;
 }
Пример #9
0
    virtual void operator()(
        goal_ref const & g, 
        goal_ref_buffer & result, 
        model_converter_ref & mc, 
        proof_converter_ref & pc,
        expr_dependency_ref & core) {
        SASSERT(g->is_well_sorted());
        mc = 0; pc = 0; core = 0;
        m_trail.reset();
        m_fd.reset();
        m_max.reset();
        m_nonfd.reset();
        m_bounds.reset();
        ref<bvmc> mc1 = alloc(bvmc);

        tactic_report report("eq2bv", *g);

        m_bounds(*g);

        for (unsigned i = 0; i < g->size(); i++) {            
            collect_fd(g->form(i));
        }
        cleanup_fd(mc1);
        
        if (m_max.empty()) {
            result.push_back(g.get());
            return;
        }

        for (unsigned i = 0; i < g->size(); i++) {            
            expr_ref   new_curr(m);
            proof_ref  new_pr(m);  
            if (is_bound(g->form(i))) {
                g->update(i, m.mk_true(), 0, 0);
                continue;
            }
            m_rw(g->form(i), new_curr, new_pr);
            if (m.proofs_enabled() && !new_pr) {
                new_pr = m.mk_rewrite(g->form(i), new_curr);
                new_pr = m.mk_modus_ponens(g->pr(i), new_pr);
            }
            g->update(i, new_curr, new_pr, g->dep(i));
        }
        obj_map<expr, unsigned>::iterator it = m_max.begin(), end = m_max.end();
        for (; it != end; ++it) {
            expr* c = it->m_key;
            bool strict;
            rational r;
            if (m_bounds.has_lower(c, r, strict)) {
                SASSERT(!strict);
                expr* d = m_fd.find(c);
                g->assert_expr(bv.mk_ule(bv.mk_numeral(r, m.get_sort(d)), d), m_bounds.lower_dep(c));
            }
            if (m_bounds.has_upper(c, r, strict)) {
                SASSERT(!strict);
                expr* d = m_fd.find(c);
                g->assert_expr(bv.mk_ule(d, bv.mk_numeral(r, m.get_sort(d))), m_bounds.upper_dep(c));
            }
        }        
        g->inc_depth();
        mc = mc1.get();
        result.push_back(g.get());
        TRACE("pb", g->display(tout););