コード例 #1
0
ファイル: qe_arith.cpp プロジェクト: NikolajBjorner/z3
static void test2(char const *ex) {
    smt_params params;
    params.m_model = true;
    ast_manager m;
    reg_decl_plugins(m);
    arith_util a(m);
    expr_ref fml = parse_fml(m, ex);
    app_ref_vector vars(m);
    expr_ref_vector lits(m);
    vars.push_back(m.mk_const(symbol("x"), a.mk_real()));
    vars.push_back(m.mk_const(symbol("y"), a.mk_real()));
    vars.push_back(m.mk_const(symbol("z"), a.mk_real()));
    flatten_and(fml, lits);

    smt::context ctx(m, params);
    ctx.push();
    ctx.assert_expr(fml);
    lbool result = ctx.check();
    VERIFY(result == l_true);
    ref<model> md;
    ctx.get_model(md);  
    ctx.pop(1);
    
    std::cout << mk_pp(fml, m) << "\n";

    expr_ref pr1(m), pr2(m), fml2(m);
    expr_ref_vector bound(m);
    ptr_vector<sort> sorts;
    svector<symbol> names;
    for (unsigned i = 0; i < vars.size(); ++i) {
        bound.push_back(vars[i].get());
        names.push_back(vars[i]->get_decl()->get_name());
        sorts.push_back(m.get_sort(vars[i].get()));
    }
    expr_abstract(m, 0, bound.size(), bound.c_ptr(), fml, fml2);
    fml2 = m.mk_exists(bound.size(), sorts.c_ptr(), names.c_ptr(), fml2);
    qe::expr_quant_elim qe(m, params);
    for (unsigned i = 0; i < vars.size(); ++i) {
        VERIFY(qe::arith_project(*md, vars[i].get(), lits));
    }
    pr1 = mk_and(lits);
    qe(m.mk_true(), fml2, pr2);
    std::cout << mk_pp(pr1, m) << "\n";
    std::cout << mk_pp(pr2, m) << "\n";

    expr_ref npr2(m);
    npr2 = m.mk_not(pr2);
    ctx.push();
    ctx.assert_expr(pr1);
    ctx.assert_expr(npr2);
    VERIFY(l_false == ctx.check());
    ctx.pop(1);       
}
コード例 #2
0
ファイル: expr_abstract.cpp プロジェクト: AleksandarZeljic/z3
expr_ref mk_quantifier(bool is_forall, ast_manager& m, unsigned num_bound, app* const* bound, expr* n) {
    expr_ref result(m);
    expr_abstract(m, 0, num_bound, (expr* const*)bound, n, result);    
    if (num_bound > 0) {
        ptr_vector<sort> sorts;
        svector<symbol> names;
        for (unsigned i = 0; i < num_bound; ++i) {
            sorts.push_back(m.get_sort(bound[i]));
            names.push_back(bound[i]->get_decl()->get_name());
        }
        result = m.mk_quantifier(is_forall, num_bound, sorts.c_ptr(), names.c_ptr(), result);
    }
    return result;

}
コード例 #3
0
ファイル: qe_arith.cpp プロジェクト: NikolajBjorner/z3
static void test(app* var, expr_ref& fml) {

    ast_manager& m = fml.get_manager();
    smt_params params;
    params.m_model = true;

    symbol x_name(var->get_decl()->get_name());   
    sort* x_sort = m.get_sort(var);

    expr_ref pr(m);
    expr_ref_vector lits(m);
    flatten_and(fml, lits);

    model_ref md;
    {
        smt::context ctx(m, params);
        ctx.assert_expr(fml);
        lbool result = ctx.check();
        if (result != l_true) return;
        ctx.get_model(md);
    }    
    VERIFY(qe::arith_project(*md, var, lits));
    pr = mk_and(lits);
   
    std::cout << "original:  " << mk_pp(fml, m) << "\n";
    std::cout << "projected: " << mk_pp(pr,  m) << "\n";

    // projection is consistent with model.
    VERIFY(md->is_true(pr));

    // projection implies E x. fml
    {
        qe::expr_quant_elim qelim(m, params);
        expr_ref result(m), efml(m);
        expr* x = var;
        expr_abstract(m, 0, 1, &x, fml, efml);
        efml = m.mk_exists(1, &x_sort, &x_name, efml);
        qelim(m.mk_true(), efml, result);

        smt::context ctx(m, params);
        ctx.assert_expr(pr);
        ctx.assert_expr(m.mk_not(result));
        std::cout << "exists: " << pr << " =>\n" << result << "\n";
        VERIFY(l_false == ctx.check());
    }    

    std::cout << "\n";
}
コード例 #4
0
ファイル: expr_abstract.cpp プロジェクト: therealoneisneo/Z3
void expr_abstractor::operator()(unsigned base, unsigned num_bound, expr* const* bound, expr* n, expr_ref& result) {
    
    expr * curr = 0, *b = 0;
    SASSERT(n->get_ref_count() > 0);

    m_stack.push_back(n);

    for (unsigned i = 0; i < num_bound; ++i) {
        b = bound[i];
        expr* v = m.mk_var(base + num_bound - i - 1, m.get_sort(b));
        m_pinned.push_back(v);
        m_map.insert(b, v);
    }

    while(!m_stack.empty()) {
        curr = m_stack.back();
        if (m_map.contains(curr)) {
            m_stack.pop_back();
            continue;
        }
        switch(curr->get_kind()) {
        case AST_VAR: {
            m_map.insert(curr, curr);
            m_stack.pop_back();
            break;
        }
        case AST_APP: {
            app* a = to_app(curr);
            bool all_visited = true;
            m_args.reset();
            for (unsigned i = 0; i < a->get_num_args(); ++i) {
                if (!m_map.find(a->get_arg(i), b)) {
                    m_stack.push_back(a->get_arg(i));
                    all_visited = false;
                }
                else {
                    m_args.push_back(b);
                }
            }
            if (all_visited) {
                b = m.mk_app(a->get_decl(), m_args.size(), m_args.c_ptr());
                m_pinned.push_back(b);
                m_map.insert(curr, b);
                m_stack.pop_back();
            }
            break;
        }
        case AST_QUANTIFIER: {
            quantifier* q = to_quantifier(curr);
            expr_ref_buffer patterns(m);
            expr_ref result1(m);
            unsigned new_base = base + q->get_num_decls();
        
            for (unsigned i = 0; i < q->get_num_patterns(); ++i) {
                expr_abstract(m, new_base, num_bound, bound, q->get_pattern(i), result1);
                patterns.push_back(result1.get());
            }
            expr_abstract(m, new_base, num_bound, bound, q->get_expr(), result1);
            b = m.update_quantifier(q, patterns.size(), patterns.c_ptr(), result1.get());
            m_pinned.push_back(b);            
            m_map.insert(curr, b);
            m_stack.pop_back();            
            break;
        }
        default:
            UNREACHABLE();
        }
    }
    VERIFY (m_map.find(n, b));
    result = b;
    m_pinned.reset();
    m_map.reset();
    m_stack.reset();
    m_args.reset();   
}
コード例 #5
0
ファイル: api_quant.cpp プロジェクト: AleksandarZeljic/z3
    Z3_ast Z3_API Z3_mk_quantifier_const_ex(Z3_context c, 
                                            Z3_bool is_forall,
                                            unsigned weight,
                                            Z3_symbol quantifier_id,
                                            Z3_symbol skolem_id,
                                            unsigned num_bound,
                                            Z3_app const bound[],
                                            unsigned num_patterns,
                                            Z3_pattern const patterns[],
                                            unsigned num_no_patterns,
                                            Z3_ast const no_patterns[],
                                            Z3_ast body) {
        Z3_TRY;
        LOG_Z3_mk_quantifier_const_ex(c, is_forall, weight, quantifier_id, skolem_id, num_bound, bound, num_patterns, patterns,
                                      num_no_patterns, no_patterns, body);
        RESET_ERROR_CODE();
        svector<Z3_symbol> names;
        svector<Z3_sort> types;
        ptr_vector<expr> bound_asts;
        if (num_patterns > 0 && num_no_patterns > 0) {
            SET_ERROR_CODE(Z3_INVALID_USAGE);
            RETURN_Z3(0);
        }
        if (num_bound == 0) {
            SET_ERROR_CODE(Z3_INVALID_USAGE);
            RETURN_Z3(0);            
        }
        for (unsigned i = 0; i < num_bound; ++i) {
            app* a = to_app(bound[i]);
            if (a->get_kind() != AST_APP) {
                SET_ERROR_CODE(Z3_INVALID_ARG);
                RETURN_Z3(0);
            }
            symbol s(to_app(a)->get_decl()->get_name());
            names.push_back(of_symbol(s));
            types.push_back(of_sort(mk_c(c)->m().get_sort(a)));
            bound_asts.push_back(a);
            if (a->get_family_id() != null_family_id || a->get_num_args() != 0) {
                SET_ERROR_CODE(Z3_INVALID_ARG);
                RETURN_Z3(0);
            }
        }
        // Abstract patterns
        svector<Z3_pattern> _patterns;
        expr_ref_vector pinned(mk_c(c)->m());
        for (unsigned i = 0; i < num_patterns; ++i) {
            expr_ref result(mk_c(c)->m());
            app* pat = to_pattern(patterns[i]);
            SASSERT(mk_c(c)->m().is_pattern(pat));
            expr_abstract(mk_c(c)->m(), 0, num_bound, bound_asts.c_ptr(), pat, result);
            SASSERT(result.get()->get_kind() == AST_APP);        
            pinned.push_back(result.get());
            SASSERT(mk_c(c)->m().is_pattern(result.get()));
            _patterns.push_back(of_pattern(result.get()));
        }
        svector<Z3_ast> _no_patterns;
        for (unsigned i = 0; i < num_no_patterns; ++i) {
            expr_ref result(mk_c(c)->m());
            if (!is_app(to_expr(no_patterns[i]))) {
                SET_ERROR_CODE(Z3_INVALID_ARG);
                RETURN_Z3(0);
            }
            app* pat = to_app(to_expr(no_patterns[i]));
            expr_abstract(mk_c(c)->m(), 0, num_bound, bound_asts.c_ptr(), pat, result);
            SASSERT(result.get()->get_kind() == AST_APP);        
            pinned.push_back(result.get());
            _no_patterns.push_back(of_ast(result.get()));
        }
        expr_ref abs_body(mk_c(c)->m());
        expr_abstract(mk_c(c)->m(), 0, num_bound, bound_asts.c_ptr(), to_expr(body), abs_body);

        Z3_ast result = mk_quantifier_ex_core(c, is_forall, weight, 
                                              quantifier_id,
                                              skolem_id,
                                              num_patterns, _patterns.c_ptr(), 
                                              num_no_patterns, _no_patterns.c_ptr(),
                                              names.size(), types.c_ptr(), names.c_ptr(), 
                                              of_ast(abs_body.get()));
        RETURN_Z3(result);
        Z3_CATCH_RETURN(0);
    }