Beispiel #1
0
void bv_decl_plugin::mk_bv_sort(unsigned bv_size) {
    force_ptr_array_size(m_bv_sorts, bv_size + 1);
    if (m_bv_sorts[bv_size] == 0) {
        parameter p(bv_size);
        sort_size sz;
        if (sort_size::is_very_big_base2(bv_size)) {
            sz = sort_size::mk_very_big();
        }
        else {
            sz = sort_size(rational::power_of_two(bv_size));
        }
        m_bv_sorts[bv_size] = m_manager->mk_sort(symbol("bv"), sort_info(m_family_id, BV_SORT, sz, 1, &p));
        m_manager->inc_ref(m_bv_sorts[bv_size]);
    }
}
/**
   \brief Return the size of the inductive datatype.
   Pre-condition: The given argument constains the parameters of an inductive datatype.
*/
static sort_size get_datatype_size(parameter const * parameters) {
    unsigned num_types          = parameters[0].get_int();
    unsigned tid                = parameters[1].get_int();
    buffer<sort_size> szs(num_types, sort_size());
    buffer<status>    already_found(num_types, WHITE);
    buffer<unsigned>  todo;
    todo.push_back(tid);
    while (!todo.empty()) {
        unsigned tid  = todo.back();
        if (already_found[tid] == BLACK) {
            todo.pop_back();
            continue;
        }
        already_found[tid] = GRAY;
        unsigned o                 = parameters[2 + 2*tid + 1].get_int(); // constructor offset
        unsigned num_constructors  = parameters[o].get_int();
        bool     is_very_big       = false;
        bool     can_process       = true;
        for (unsigned s = 1; s <= num_constructors; s++) {
            unsigned k_i           = parameters[o+s].get_int();
            unsigned num_accessors = parameters[k_i+2].get_int();
            for (unsigned r = 0; r < num_accessors; r++) {
                parameter const & a_type = parameters[k_i+4 + 2*r];
                if (a_type.is_int()) {
                    int tid_prime = a_type.get_int();
                    switch (already_found[tid_prime]) {
                    case WHITE:
                        todo.push_back(tid_prime);
                        can_process = false;
                        break;
                    case GRAY:
                        // type is recursive
                        return sort_size();
                    case BLACK:
                        break;
                    }
                }
                else {
                    SASSERT(a_type.is_ast());
                    sort * ty = to_sort(a_type.get_ast());
                    if (ty->is_infinite()) {
                        // type is infinite
                        return sort_size();
                    }
                    else if (ty->is_very_big()) {
                        is_very_big = true;
                    }
                }
            }
        }
        if (can_process) {
            todo.pop_back();
            already_found[tid] = BLACK;
            if (is_very_big) {
                szs[tid] = sort_size::mk_very_big();
            }
            else {
                // the type is not infinite nor the number of elements is infinite...
                // computing the number of elements
                rational num;
                for (unsigned s = 1; s <= num_constructors; s++) {
                    unsigned k_i           = parameters[o+s].get_int();
                    unsigned num_accessors = parameters[k_i+2].get_int();
                    rational c_num(1);
                    for (unsigned r = 0; r < num_accessors; r++) {
                        parameter const & a_type = parameters[k_i+4 + 2*r];
                        if (a_type.is_int()) {
                            int tid_prime = a_type.get_int();
                            SASSERT(!szs[tid_prime].is_infinite() && !szs[tid_prime].is_very_big());
                            c_num *= rational(szs[tid_prime].size(),rational::ui64());
                        }
                        else {
                            SASSERT(a_type.is_ast());
                            sort * ty = to_sort(a_type.get_ast());
                            SASSERT(!ty->is_infinite() && !ty->is_very_big());
                            c_num *= rational(ty->get_num_elements().size(), rational::ui64());
                        }
                    }
                    num += c_num;
                }
                szs[tid] = sort_size(num);
            }
        }
    }
    return szs[tid];
}