Esempio n. 1
0
    void mk_carry(expr * a, expr * b, expr * c, expr_ref & r) {
        expr_ref t1(m()), t2(m()), t3(m());
#if 1
        mk_and(a, b, t1);
        mk_and(a, c, t2);
        mk_and(b, c, t3);
        mk_or(t1, t2, t3, r);
#else
        mk_or(a, b, t1);
        mk_or(a, c, t2);
        mk_or(b, c, t3);
        mk_and(t1, t2, t3, r);
#endif
    }
Esempio n. 2
0
 void udoc_relation::to_formula(expr_ref& fml) const {
     ast_manager& m = fml.get_manager();
     expr_ref_vector disj(m);
     for (unsigned i = 0; i < m_elems.size(); ++i) {
         disj.push_back(to_formula(m_elems[i]));
     }
     fml = mk_or(m, disj.size(), disj.c_ptr());
 }
Esempio n. 3
0
 Z3_probe Z3_API Z3_probe_or(Z3_context c, Z3_probe p1, Z3_probe p2) {
     Z3_TRY;
     LOG_Z3_probe_or(c, p1, p2);
     RESET_ERROR_CODE();
     probe * new_p = mk_or(to_probe_ref(p1), to_probe_ref(p2));
     RETURN_PROBE(new_p);
     Z3_CATCH_RETURN(0);
 }
Esempio n. 4
0
void bool_rewriter::mk_and_as_or(unsigned num_args, expr * const * args, expr_ref & result) {
    expr_ref_buffer new_args(m());
    for (unsigned i = 0; i < num_args; i++) {
        expr_ref tmp(m());
        mk_not(args[i], tmp);
        new_args.push_back(tmp);
    }
    expr_ref tmp(m());
    mk_or(new_args.size(), new_args.c_ptr(), tmp);
    mk_not(tmp, result);
}
Esempio n. 5
0
void extract_clauses_and_dependencies(goal_ref const& g, expr_ref_vector& clauses, ptr_vector<expr>& assumptions, expr2expr_map& bool2dep, ref<filter_model_converter>& fmc) {
    expr2expr_map dep2bool;
    ptr_vector<expr> deps;
    ast_manager& m = g->m();
    expr_ref_vector clause(m);
    unsigned sz = g->size();
    for (unsigned i = 0; i < sz; i++) {
        expr * f            = g->form(i);
        expr_dependency * d = g->dep(i);
        if (d == 0 || !g->unsat_core_enabled()) {
            clauses.push_back(f);
        }
        else {
            // create clause (not d1 \/ ... \/ not dn \/ f) when the d's are the assumptions/dependencies of f.
            clause.reset();
            clause.push_back(f);
            deps.reset();
            m.linearize(d, deps);
            SASSERT(!deps.empty()); // d != 0, then deps must not be empty
            ptr_vector<expr>::iterator it  = deps.begin();
            ptr_vector<expr>::iterator end = deps.end();
            for (; it != end; ++it) {
                expr * d = *it;
                if (is_uninterp_const(d) && m.is_bool(d)) {
                    // no need to create a fresh boolean variable for d
                    if (!bool2dep.contains(d)) {
                        assumptions.push_back(d);
                        bool2dep.insert(d, d);
                    }
                    clause.push_back(m.mk_not(d));
                }
                else {
                    // must normalize assumption
                    expr * b = 0;
                    if (!dep2bool.find(d, b)) {
                        b = m.mk_fresh_const(0, m.mk_bool_sort());
                        dep2bool.insert(d, b);
                        bool2dep.insert(b, d);
                        assumptions.push_back(b);
                        if (!fmc) {
                            fmc = alloc(filter_model_converter, m);
                        }
                        fmc->insert(to_app(b)->get_decl());
                    }
                    clause.push_back(m.mk_not(b));
                }
            }
            SASSERT(clause.size() > 1);
            expr_ref cls(m);
            cls = mk_or(m, clause.size(), clause.c_ptr());
            clauses.push_back(cls);
        }
    }
}
Esempio n. 6
0
tactic * mk_qffp_approx_tactic(ast_manager & m, params_ref const & p) {
    params_ref simp_p = p;
    simp_p.set_bool("arith_lhs", true);
    simp_p.set_bool("elim_and", true);

    tactic * st = and_then(mk_simplify_tactic(m, simp_p),
                           mk_propagate_values_tactic(m, p),
                           using_params(mk_simplify_tactic(m, p), simp_p),
                           cond(mk_or(mk_produce_proofs_probe(), mk_produce_unsat_cores_probe()),
                                mk_smt_tactic(),
                                cond(mk_is_qffp_probe(),
                                     mk_fpa2bv_approx_tactic(m, p),
                                     mk_qfnra_tactic(m, p))),
                           mk_fail_if_undecided_tactic());
    
    st->updt_params(p);
    return st;
}
bool basic_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) {
    set_reduce_invoked();
    SASSERT(f->get_family_id() == m_manager.get_basic_family_id());
    basic_op_kind k = static_cast<basic_op_kind>(f->get_decl_kind());
    switch (k) {
    case OP_FALSE:
    case OP_TRUE:
        return false;
    case OP_EQ:
        SASSERT(num_args == 2);
        mk_eq(args[0], args[1], result);
        return true;
    case OP_DISTINCT:
        mk_distinct(num_args, args, result);
        return true;
    case OP_ITE:
        SASSERT(num_args == 3);
        mk_ite(args[0], args[1], args[2], result);
        return true;
    case OP_AND:
        mk_and(num_args, args, result);
        return true;
    case OP_OR:
        mk_or(num_args, args, result);
        return true;
    case OP_IMPLIES:
        mk_implies(args[0], args[1], result);
        return true;
    case OP_IFF:
        mk_iff(args[0], args[1], result);
        return true;
    case OP_XOR:
        mk_xor(args[0], args[1], result);
        return true;
    case OP_NOT:
        SASSERT(num_args == 1);
        mk_not(args[0], result);
        return true;
    default:
        UNREACHABLE();
        return false;
    }
}
Esempio n. 8
0
    unsigned aig_exporter::expr_to_aig(const expr *e) {
        unsigned id;
        if (m_aig_expr_id_map.find(e, id))
            return id;

        if (is_uninterp_const(e))
            return get_var(e);

        switch (e->get_kind()) {
        case AST_APP: {
            const app *a = to_app(e);
            switch (a->get_decl_kind()) {
            case OP_OR:
                SASSERT(a->get_num_args() > 0);
                id = expr_to_aig(a->get_arg(0));
                for (unsigned i = 1; i < a->get_num_args(); ++i) {
                    id = mk_or(id, expr_to_aig(a->get_arg(i)));
                }
                m_aig_expr_id_map.insert(e, id);
                return id;

            case OP_NOT:
                return neg(expr_to_aig(a->get_arg(0)));

            case OP_FALSE:
                return 0;

            case OP_TRUE:
                return 1;
            }
            break;}

        case AST_VAR:
            return get_var(e);
        default:
            UNREACHABLE();
        }
        
        UNREACHABLE();
        return 0;
    }
Esempio n. 9
0
    proof *mk_unit_resolution_core(unsigned num_args, proof* const *args)
    {

        ptr_buffer<proof> pf_args;
        pf_args.push_back(args [0]);

        app *cls_fact = to_app(m.get_fact(args[0]));
        ptr_buffer<expr> cls;
        if (m.is_or(cls_fact)) {
            for (unsigned i = 0, sz = cls_fact->get_num_args(); i < sz; ++i)
            { cls.push_back(cls_fact->get_arg(i)); }
        } else { cls.push_back(cls_fact); }

        // construct new resovent
        ptr_buffer<expr> new_fact_cls;
        bool found;
        // XXX quadratic
        for (unsigned i = 0, sz = cls.size(); i < sz; ++i) {
            found = false;
            for (unsigned j = 1; j < num_args; ++j) {
                if (m.is_complement(cls.get(i), m.get_fact(args [j]))) {
                    found = true;
                    pf_args.push_back(args [j]);
                    break;
                }
            }
            if (!found) {
                new_fact_cls.push_back(cls.get(i));
            }
        }

        SASSERT(new_fact_cls.size() + pf_args.size() - 1 == cls.size());
        expr_ref new_fact(m);
        new_fact = mk_or(m, new_fact_cls.size(), new_fact_cls.c_ptr());

        // create new proof step
        proof *res = m.mk_unit_resolution(pf_args.size(), pf_args.c_ptr(), new_fact);
        m_pinned.push_back(res);
        return res;
    }
Esempio n. 10
0
 void mk_clause(unsigned n, literal const* lits) {
     m_clauses.push_back(mk_or(m, n, lits));
 }
        br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, 
            proof_ref & result_pr)
        {
            if (m.is_not(f) && (m.is_and(args[0]) || m.is_or(args[0]))) {
                SASSERT(num == 1);
                expr_ref tmp(m);
                app* a = to_app(args[0]);
                m_app_args.reset();
                for (expr* arg : *a) {
                    m_brwr.mk_not(arg, tmp);
                    m_app_args.push_back(tmp);
                }
                if (m.is_and(args[0])) {
                    result = mk_or(m_app_args); 
                }
                else {
                    result = mk_and(m_app_args); 
                }
                return BR_REWRITE2;
            }
            if (!m.is_and(f) && !m.is_or(f)) { 
                return BR_FAILED; 
            }
            if (num == 0) {
                if (m.is_and(f)) {
                    result = m.mk_true();
                }
                else {
                    result = m.mk_false();
                }
                return BR_DONE;
            }
            if (num == 1) {
                result = args[0];
                return BR_DONE;
            }

            m_app_args.reset();
            m_app_args.append(num, args);

            std::sort(m_app_args.c_ptr(), m_app_args.c_ptr()+m_app_args.size(), m_expr_cmp);

            remove_duplicates(m_app_args);

            bool have_rewritten_args = false;

            have_rewritten_args = detect_equivalences(m_app_args, m.is_or(f));

            if (m_app_args.size()==1) {
                result = m_app_args[0].get();
            }
            else {
                if (m.is_and(f)) {
                    result = m.mk_and(m_app_args.size(), m_app_args.c_ptr());
                }
                else {
                    SASSERT(m.is_or(f));
                    result = m.mk_or(m_app_args.size(), m_app_args.c_ptr());
                }
            }

            if (have_rewritten_args) {
                return BR_REWRITE1;
            }
            return BR_DONE;
        }
Esempio n. 12
0
tactic * mk_qfbv_tactic(ast_manager & m, params_ref const & p) {
    params_ref main_p;
    main_p.set_bool("elim_and", true);
    main_p.set_bool("push_ite_bv", true);
    main_p.set_bool("blast_distinct", true);

    params_ref simp2_p = p;
    simp2_p.set_bool("som", true);
    simp2_p.set_bool("pull_cheap_ite", true);
    simp2_p.set_bool("push_ite_bv", false);
    simp2_p.set_bool("local_ctx", true);
    simp2_p.set_uint("local_ctx_limit", 10000000);
    simp2_p.set_bool("flat", true); // required by som
    simp2_p.set_bool("hoist_mul", false); // required by som

    params_ref local_ctx_p = p;
    local_ctx_p.set_bool("local_ctx", true);

    params_ref solver_p;
    solver_p.set_bool("preprocess", false); // preprocessor of smt::context is not needed.
    
    params_ref no_flat_p;
    no_flat_p.set_bool("flat", false);

    params_ref ctx_simp_p;
    ctx_simp_p.set_uint("max_depth", 32);
    ctx_simp_p.set_uint("max_steps", 50000000);

    params_ref hoist_p;
    hoist_p.set_bool("hoist_mul", true);
    hoist_p.set_bool("som", false);

    params_ref solve_eq_p;
    // conservative guassian elimination. 
    solve_eq_p.set_uint("solve_eqs_max_occs", 2); 

    params_ref big_aig_p;
    big_aig_p.set_bool("aig_per_assertion", false);

    tactic * preamble_st = and_then(and_then(mk_simplify_tactic(m),
                                             mk_propagate_values_tactic(m),
                                             using_params(mk_solve_eqs_tactic(m), solve_eq_p),
                                             mk_elim_uncnstr_tactic(m),
                                             if_no_proofs(if_no_unsat_cores(mk_bv_size_reduction_tactic(m))),
                                             using_params(mk_simplify_tactic(m), simp2_p)),
                                    // Z3 can solve a couple of extra benchmarks by using hoist_mul
                                    // but the timeout in SMT-COMP is too small. 
                                    // Moreover, it impacted negatively some easy benchmarks.
                                    // We should decide later, if we keep it or not.
                                    using_params(mk_simplify_tactic(m), hoist_p),
                                    mk_max_bv_sharing_tactic(m));
    
#ifdef USE_OLD_SAT_SOLVER
    tactic * new_sat = and_then(mk_simplify_tactic(m),
                                mk_smt_tactic());
#else
    tactic * new_sat = cond(mk_or(mk_produce_proofs_probe(), mk_produce_unsat_cores_probe()),
                            and_then(mk_simplify_tactic(m),
                                     mk_smt_tactic()),
                            mk_sat_tactic(m));
#endif    
    
    tactic * st = using_params(and_then(preamble_st,
                                        // If the user sets HI_DIV0=false, then the formula may contain uninterpreted function
                                        // symbols. In this case, we should not use 
                                        cond(mk_is_qfbv_probe(),
                                             cond(mk_is_qfbv_eq_probe(),
                                                  and_then(mk_bv1_blaster_tactic(m),
                                                           using_params(mk_smt_tactic(), solver_p)),
                                                  and_then(mk_bit_blaster_tactic(m),
                                                           when(mk_lt(mk_memory_probe(), mk_const_probe(MEMLIMIT)),
                                                                and_then(using_params(and_then(mk_simplify_tactic(m),
                                                                                               mk_solve_eqs_tactic(m)),
                                                                                      local_ctx_p),
                                                                         if_no_proofs(cond(mk_produce_unsat_cores_probe(),
                                                                                           mk_aig_tactic(),
                                                                                           using_params(mk_aig_tactic(),
                                                                                                        big_aig_p))))),
                                                           new_sat)),
                                             mk_smt_tactic())),
                               main_p);

    st->updt_params(p);
    return st;
}
Esempio n. 13
0
probe * mk_implies(probe * p1, probe * p2) {
    return mk_or(mk_not(p1), p2);
}
Esempio n. 14
0
    void aig_exporter::operator()(std::ostream& out) {
        expr_ref_vector transition_function(m), output_preds(m);
        var_ref_vector input_vars(m);

        rule_counter& vc = m_rm.get_counter();
        expr_ref_vector exprs(m);
        substitution subst(m);

        for (rule_set::decl2rules::iterator I = m_rules.begin_grouped_rules(),
            E = m_rules.end_grouped_rules(); I != E; ++I) {
            for (rule_vector::iterator II = I->get_value()->begin(),
                EE = I->get_value()->end(); II != EE; ++II) {
                rule *r = *II;
                unsigned numqs = r->get_positive_tail_size();
                if (numqs > 1) {
                    std::cerr << "non-linear clauses not supported\n";
                    exit(-1);
                }

                if (numqs != r->get_uninterpreted_tail_size()) {
                    std::cerr << "negation of queries not supported\n";
                    exit(-1);
                }

                exprs.reset();
                assert_pred_id(numqs ? r->get_tail(0)->get_decl() : 0, m_ruleid_var_set, exprs);
                assert_pred_id(r->get_head()->get_decl(), m_ruleid_varp_set, exprs);

                subst.reset();
                subst.reserve(1, vc.get_max_rule_var(*r)+1);
                if (numqs)
                    collect_var_substs(subst, r->get_tail(0), m_latch_vars, exprs);
                collect_var_substs(subst, r->get_head(), m_latch_varsp, exprs);

                for (unsigned i = numqs; i < r->get_tail_size(); ++i) {
                    expr_ref e(m);
                    subst.apply(r->get_tail(i), e);
                    exprs.push_back(e);
                }

                transition_function.push_back(m.mk_and(exprs.size(), exprs.c_ptr()));
            }
        }

        // collect table facts
        if (m_facts) {
            for (fact_vector::const_iterator I = m_facts->begin(), E = m_facts->end(); I != E; ++I) {
                exprs.reset();
                assert_pred_id(0, m_ruleid_var_set, exprs);
                assert_pred_id(I->first, m_ruleid_varp_set, exprs);

                for (unsigned i = 0; i < I->second.size(); ++i) {
                    exprs.push_back(m.mk_eq(get_latch_var(i, m_latch_varsp), I->second[i]));
                }

                transition_function.push_back(m.mk_and(exprs.size(), exprs.c_ptr()));
            }
        }

        expr *tr = m.mk_or(transition_function.size(), transition_function.c_ptr());
        aig_ref aig = m_aigm.mk_aig(tr);
        expr_ref aig_expr(m);
        m_aigm.to_formula(aig, aig_expr);

#if 0
        std::cout << mk_pp(tr, m) << "\n\n";
        std::cout << mk_pp(aig_expr, m) << "\n\n";
#endif

        // make rule_id vars latches
        for (unsigned i = 0; i < m_ruleid_var_set.size(); ++i) {
            m_latch_vars.push_back(m_ruleid_var_set.get(i));
            m_latch_varsp.push_back(m_ruleid_varp_set.get(i));
        }

        // create vars for latches
        for (unsigned i = 0; i < m_latch_vars.size(); ++i) {
            mk_var(m_latch_vars.get(i));
            mk_input_var(m_latch_varsp.get(i));
        }

        unsigned tr_id = expr_to_aig(aig_expr);

        // create latch next state variables: (ite tr varp var)
        unsigned_vector latch_varp_ids;
        for (unsigned i = 0; i < m_latch_vars.size(); ++i) {
            unsigned in_val = mk_and(tr_id, get_var(m_latch_varsp.get(i)));
            unsigned latch_val = mk_and(neg(tr_id), get_var(m_latch_vars.get(i)));
            latch_varp_ids.push_back(mk_or(in_val, latch_val));
        }
        m_latch_varsp.reset();

        // create output variable (true iff an output predicate is derivable)
        unsigned output_id = 0;
        {
            expr_ref_vector output(m);
            const func_decl_set& preds = m_rules.get_output_predicates();

            for (func_decl_set::iterator I = preds.begin(), E = preds.end(); I != E; ++I) {
                exprs.reset();
                assert_pred_id(*I, m_ruleid_var_set, exprs);
                output.push_back(m.mk_and(exprs.size(), exprs.c_ptr()));
            }

            expr *out = m.mk_or(output.size(), output.c_ptr());
            aig = m_aigm.mk_aig(out);
            m_aigm.to_formula(aig, aig_expr);
            output_id = expr_to_aig(aig_expr);

#if 0
            std::cout << "output formula\n";
            std::cout << mk_pp(out, m) << "\n\n";
            std::cout << mk_pp(aig_expr, m) << "\n\n";
#endif
        }

        // 1) print header
        // aag var_index inputs latches outputs andgates
        out << "aag " << (m_next_aig_expr_id-1)/2 << ' ' << m_input_vars.size()
            << ' ' << m_latch_vars.size() << " 1 " << m_num_and_gates << '\n';

        // 2) print inputs
        for (unsigned i = 0; i < m_input_vars.size(); ++i) {
            out << m_input_vars[i] << '\n';
        }
        
        // 3) print latches
        for (unsigned i = 0; i < m_latch_vars.size(); ++i) {
            out << get_var(m_latch_vars.get(i)) << ' ' << latch_varp_ids[i] << '\n';
        }

        // 4) print outputs  (just one for now)
        out << output_id << '\n';

        // 5) print formula
        out << m_buffer.str();
    }