예제 #1
0
func_decl * bv_decl_plugin::mk_reduction(ptr_vector<func_decl> & decls, decl_kind k, char const * name, unsigned bv_size) {
    force_ptr_array_size(decls, bv_size + 1);

    if (decls[bv_size] == 0) {
        sort * d = get_bv_sort(bv_size);
        sort * r = get_bv_sort(1);
        decls[bv_size] = m_manager->mk_func_decl(symbol(name), d, r, func_decl_info(m_family_id, k));
        m_manager->inc_ref(decls[bv_size]);
    }

    return decls[bv_size];
}
예제 #2
0
func_decl * bv_decl_plugin::mk_comp(unsigned bv_size) {
    force_ptr_array_size(m_bv_comp, bv_size + 1);

    if (m_bv_comp[bv_size] == 0) {
        sort * d = get_bv_sort(bv_size);
        sort * r = get_bv_sort(1);
        func_decl_info info(m_family_id, OP_BCOMP);
        info.set_commutative();
        m_bv_comp[bv_size] = m_manager->mk_func_decl(symbol("bvcomp"), d, d, r, info);
        m_manager->inc_ref(m_bv_comp[bv_size]);
    }

    return m_bv_comp[bv_size];
}
예제 #3
0
void bv_decl_plugin::set_manager(ast_manager * m, family_id id) {
    decl_plugin::set_manager(m, id);

    for (unsigned i = 1; i <= 64; i++) {
        mk_bv_sort(i);
    }
    m_bit0 = m->mk_const_decl(symbol("bit0"), get_bv_sort(1), func_decl_info(m_family_id, OP_BIT0));
    m_bit1 = m->mk_const_decl(symbol("bit1"), get_bv_sort(1), func_decl_info(m_family_id, OP_BIT1));
    m->inc_ref(m_bit0);
    m->inc_ref(m_bit1);

    sort * b = m->mk_bool_sort();
    sort * d[3] = {b, b, b};
    m_carry = m_manager->mk_func_decl(symbol("carry"), 3, d, b, func_decl_info(m_family_id, OP_CARRY));
    m_manager->inc_ref(m_carry);
    m_xor3 = m_manager->mk_func_decl(symbol("xor3"), 3, d, b, func_decl_info(m_family_id, OP_XOR3));
    m_manager->inc_ref(m_xor3);

    m_int_sort = m_manager->mk_sort(m_manager->mk_family_id("arith"), INT_SORT);
    SASSERT(m_int_sort != 0); // arith_decl_plugin must be installed before bv_decl_plugin.
    m_manager->inc_ref(m_int_sort);
}
예제 #4
0
func_decl * bv_decl_plugin::mk_mkbv(unsigned arity, sort * const * domain) {
    for (unsigned i = 0; i < arity; i++) {
        if (!m_manager->is_bool(domain[i])) {
            m_manager->raise_exception("invalid mkbv operator");
            return nullptr;
        }
    }
    unsigned bv_size = arity;
    m_mkbv.reserve(bv_size+1);
    if (m_mkbv[bv_size] == 0) {
        m_mkbv[bv_size] = m_manager->mk_func_decl(m_mkbv_sym, arity, domain, get_bv_sort(bv_size), func_decl_info(m_family_id, OP_MKBV));
        m_manager->inc_ref(m_mkbv[bv_size]);
    }
    return m_mkbv[bv_size];
}
func_decl * bv_decl_plugin::mk_num_decl(unsigned num_parameters, parameter const * parameters, unsigned arity) {
    if (!(num_parameters == 2 && arity == 0 && parameters[0].is_rational() && parameters[1].is_int())) {
        m_manager->raise_exception("invalid bit-vector numeral declaration");
        return 0;
    }
    unsigned bv_size = parameters[1].get_int();
    // TODO: sign an error if the parameters[0] is out of range, that is, it is a value not in [0, 2^{bv_size})
    // This cannot be enforced now, since some Z3 modules try to generate these invalid numerals.
    // After SMT-COMP, I should find all offending modules.
    // For now, I will just simplify the numeral here.
    parameter p0(mod(parameters[0].get_rational(), power_of_two(bv_size)));
    parameter ps[2] = { p0, parameters[1] };
    sort * bv = get_bv_sort(bv_size);
    return m_manager->mk_const_decl(m_bv_sym, bv, func_decl_info(m_family_id, OP_BV_NUM, num_parameters, ps));
}
예제 #6
0
func_decl * bv_decl_plugin::mk_binary(ptr_vector<func_decl> & decls, decl_kind k,
                                    char const * name, unsigned bv_size, bool ac, bool idempotent) {
    force_ptr_array_size(decls, bv_size + 1);

    if (decls[bv_size] == 0) {
        sort * s = get_bv_sort(bv_size);
        func_decl_info info(m_family_id, k);
        info.set_associative(ac);
        info.set_flat_associative(ac);
        info.set_commutative(ac);
        info.set_idempotent(idempotent);
        decls[bv_size] = m_manager->mk_func_decl(symbol(name), s, s, s, info);
        m_manager->inc_ref(decls[bv_size]);
    }

    return decls[bv_size];
}
func_decl * bv_decl_plugin::mk_int2bv(unsigned bv_size, unsigned num_parameters, parameter const * parameters,
                                    unsigned arity, sort * const * domain) {
    force_ptr_array_size(m_int2bv, bv_size + 1);

    if (arity != 1) {
        m_manager->raise_exception("expecting one argument to int2bv");
        return 0;
    }

    if (m_int2bv[bv_size] == 0) {
        sort * s = get_bv_sort(bv_size);
        m_int2bv[bv_size] = m_manager->mk_func_decl(symbol("int2bv"), domain[0], s, 
                                                    func_decl_info(m_family_id, OP_INT2BV, num_parameters, parameters));
        m_manager->inc_ref(m_int2bv[bv_size]);
    }

    return m_int2bv[bv_size];
}
예제 #8
0
func_decl * bv_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
                                         unsigned arity, sort * const * domain, sort * range) {
    int bv_size;
    if (k == OP_INT2BV && get_int2bv_size(num_parameters, parameters, bv_size)) {
        // bv_size is filled in.
    }
    else if (k == OP_BV_NUM) {
        return mk_num_decl(num_parameters, parameters, arity);
    }
    else if (k == OP_BIT0) {
        return m_bit0;
    }
    else if (k == OP_BIT1) {
        return m_bit1;
    }
    else if (k == OP_CARRY) {
        return m_carry;
    }
    else if (k == OP_XOR3) {
        return m_xor3;
    }
    else if (k == OP_MKBV) {
        return mk_mkbv(arity, domain);
    }
    else if (arity == 0) {
        m_manager->raise_exception("no arguments supplied to bit-vector operator");
        return nullptr;
    }
    else if (!get_bv_size(domain[0], bv_size)) {
        m_manager->raise_exception("could not extract bit-vector size");
        return nullptr;
    }
    func_decl * r = mk_func_decl(k, bv_size);
    if (r != nullptr) {
        if (arity != r->get_arity()) {
            if (r->get_info()->is_associative())
                arity = r->get_arity();
            else {
                m_manager->raise_exception("declared arity mismatches supplied arity");
                return nullptr;
            }
        }
        for (unsigned i = 0; i < arity; ++i) {
            if (domain[i] != r->get_domain(i)) {
                m_manager->raise_exception("declared sorts do not match supplied sorts");
                return nullptr;
            }
        }
        return r;
    }
    int r_size;
    switch (k) {
    case OP_BIT2BOOL:
        return mk_bit2bool(bv_size, num_parameters, parameters, arity, domain);
    case OP_INT2BV:
        return mk_int2bv(bv_size, num_parameters, parameters, arity, domain);
    case OP_BV2INT:
        return mk_bv2int(bv_size, num_parameters, parameters, arity, domain);
    case OP_CONCAT:
        if (!get_concat_size(arity, domain, r_size))
            m_manager->raise_exception("invalid concat application");
        return m_manager->mk_func_decl(m_concat_sym, arity, domain, get_bv_sort(r_size),
                                       func_decl_info(m_family_id, k));
    case OP_SIGN_EXT:
        if (!get_extend_size(num_parameters, parameters, arity, domain, r_size))
            m_manager->raise_exception("invalid sign_extend application");
        return m_manager->mk_func_decl(m_sign_extend_sym, arity, domain, get_bv_sort(r_size),
                                       func_decl_info(m_family_id, k, num_parameters, parameters));
    case OP_ZERO_EXT:
        if (!get_extend_size(num_parameters, parameters, arity, domain, r_size))
            m_manager->raise_exception("invalid zero_extend application");
        return m_manager->mk_func_decl(m_zero_extend_sym, arity, domain, get_bv_sort(r_size),
                                       func_decl_info(m_family_id, k, num_parameters, parameters));
    case OP_EXTRACT:
        if (!get_extract_size(num_parameters, parameters, arity, domain, r_size))
            m_manager->raise_exception("invalid extract application");
        return m_manager->mk_func_decl(m_extract_sym, arity, domain, get_bv_sort(r_size),
                                       func_decl_info(m_family_id, k, num_parameters, parameters));
    case OP_ROTATE_LEFT:
        if (arity != 1)
            m_manager->raise_exception("rotate left expects one argument");
        return m_manager->mk_func_decl(m_rotate_left_sym, arity, domain, domain[0],
                                       func_decl_info(m_family_id, k, num_parameters, parameters));
    case OP_ROTATE_RIGHT:
        if (arity != 1)
            m_manager->raise_exception("rotate right expects one argument");
        return m_manager->mk_func_decl(m_rotate_right_sym, arity, domain, domain[0],
                                       func_decl_info(m_family_id, k, num_parameters, parameters));
    case OP_REPEAT:
        if (arity != 1)
            m_manager->raise_exception("repeat expects one argument");
        if (num_parameters != 1 || !parameters[0].is_int() || parameters[0].get_int() == 0)
            m_manager->raise_exception("repeat expects one nonzero integer parameter");
        if (!get_bv_size(domain[0], bv_size))
            m_manager->raise_exception("repeat expects an argument with bit-vector sort");
        return m_manager->mk_func_decl(m_repeat_sym, arity, domain, get_bv_sort(bv_size * parameters[0].get_int()),
                                       func_decl_info(m_family_id, k, num_parameters, parameters));
    default:
        return nullptr;
    }
}