Ejemplo n.º 1
0
sort * float_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) {
    switch (k) {
    case FLOAT_SORT:
        if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) {
            m_manager->raise_exception("expecting two integer parameters to floating point sort");
        }
        if (parameters[0].get_int() <= 1 || parameters[1].get_int() <= 1)
            m_manager->raise_exception("floating point sorts need parameters > 1");
        if (parameters[0].get_int() > parameters[1].get_int())
            m_manager->raise_exception("floating point sorts with ebits > sbits are currently not supported");
        return mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
    case ROUNDING_MODE_SORT:
        return mk_rm_sort();
    case FLOAT16_SORT:
        return mk_float_sort(5, 11);
    case FLOAT32_SORT:
        return mk_float_sort(8, 24);
    case FLOAT64_SORT:
        return mk_float_sort(11, 53);
    case FLOAT128_SORT:
        return mk_float_sort(15, 133);
    default:
        m_manager->raise_exception("unknown floating point theory sort");
        return 0;
    }
}
func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters, parameter const * parameters,
                                           unsigned arity, sort * const * domain, sort * range) {    
    if (m_bv_plugin && arity == 3 && 
        is_sort_of(domain[0], m_bv_fid, BV_SORT) &&
        is_sort_of(domain[1], m_bv_fid, BV_SORT) &&
        is_sort_of(domain[2], m_bv_fid, BV_SORT)) {
        // When the bv_decl_plugin is installed, then we know how to convert 3 bit-vectors into a float!        
        sort * fp = mk_float_sort(domain[2]->get_parameter(0).get_int(), domain[1]->get_parameter(0).get_int()+1);
        symbol name("asFloat");
        return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));    
    }
    else {
        // .. Otherwise we only know how to convert rationals/reals. 
        if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) 
            m_manager->raise_exception("expecting two integer parameters to asFloat");        
		if (arity != 2 && arity != 3)
			m_manager->raise_exception("invalid number of arguments to asFloat operator");
		if (!is_rm_sort(domain[0]) || domain[1] != m_real_sort)
            m_manager->raise_exception("sort mismatch");
        if (arity == 2) {            
            sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
            symbol name("asFloat");
            return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
        }
        else {
            if (domain[2] != m_int_sort)
                m_manager->raise_exception("sort mismatch");     
            sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
            symbol name("asFloat");
            return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
        }
    }
}
Ejemplo n.º 3
0
sort * fpa_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) {
    switch (k) {
    case FLOATING_POINT_SORT:
        if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int()))
            m_manager->raise_exception("expecting two integer parameters to floating point sort (ebits, sbits)");
        return mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
    case ROUNDING_MODE_SORT:
        return mk_rm_sort();
    case FLOAT16_SORT:
        return mk_float_sort(5, 11);
    case FLOAT32_SORT:
        return mk_float_sort(8, 24);
    case FLOAT64_SORT:
        return mk_float_sort(11, 53);
    case FLOAT128_SORT:
        return mk_float_sort(15, 113);
    default:
        m_manager->raise_exception("unknown floating point theory sort");
        return nullptr;
    }
}
Ejemplo n.º 4
0
func_decl * float_decl_plugin::mk_from3bv(decl_kind k, unsigned num_parameters, parameter const * parameters,
                                          unsigned arity, sort * const * domain, sort * range) {
    if (arity != 3)
        m_manager->raise_exception("invalid number of arguments to fp");
    if (!is_sort_of(domain[0], m_bv_fid, BV_SORT) ||
        !is_sort_of(domain[1], m_bv_fid, BV_SORT) ||
        !is_sort_of(domain[2], m_bv_fid, BV_SORT))
        m_manager->raise_exception("sort mismatch");

    sort * fp = mk_float_sort(domain[1]->get_parameter(0).get_int(), domain[2]->get_parameter(0).get_int() + 1);
    symbol name("fp");
    return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k));
}
Ejemplo n.º 5
0
func_decl * fpa_decl_plugin::mk_numeral_decl(mpf const & v) {
    sort * s = mk_float_sort(v.get_ebits(), v.get_sbits());
    func_decl * r = nullptr;
    if (m_fm.is_nan(v))
        r = m_manager->mk_const_decl(symbol("NaN"), s, func_decl_info(m_family_id, OP_FPA_NAN));
    else if (m_fm.is_pinf(v))
        r = m_manager->mk_const_decl(symbol("+oo"), s, func_decl_info(m_family_id, OP_FPA_PLUS_INF));
    else if (m_fm.is_ninf(v))
        r = m_manager->mk_const_decl(symbol("-oo"), s, func_decl_info(m_family_id, OP_FPA_MINUS_INF));
    else if (m_fm.is_pzero(v))
        r = m_manager->mk_const_decl(symbol("+zero"), s, func_decl_info(m_family_id, OP_FPA_PLUS_ZERO));
    else if (m_fm.is_nzero(v))
        r = m_manager->mk_const_decl(symbol("-zero"), s, func_decl_info(m_family_id, OP_FPA_MINUS_ZERO));
    else {
        SASSERT(m_fm.is_regular(v));
        parameter p(mk_id(v), true);
        SASSERT(p.is_external());
        sort * s = mk_float_sort(v.get_ebits(), v.get_sbits());
        r = m_manager->mk_const_decl(symbol("fp.numeral"), s, func_decl_info(m_family_id, OP_FPA_NUM, 1, &p));
    }
    return r;
}
sort * float_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) {
    switch (k) {
    case FLOAT_SORT:
        if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) {
            m_manager->raise_exception("expecting two integer parameters to floating point sort");
        }
        return mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
    case ROUNDING_MODE_SORT:
        return mk_rm_sort();
    default:
        m_manager->raise_exception("unknown floating point theory sort");
        return 0;
    }
}
Ejemplo n.º 7
0
func_decl * float_decl_plugin::mk_to_ubv(decl_kind k, unsigned num_parameters, parameter const * parameters,
                                                 unsigned arity, sort * const * domain, sort * range) {
    if (!m_bv_plugin)
        m_manager->raise_exception("to_fp_unsigned unsupported; use a logic with BV support");
    if (arity != 2)
        m_manager->raise_exception("invalid number of arguments to to_fp_unsigned");
    if (is_rm_sort(domain[0]))
        m_manager->raise_exception("sort mismatch, expected first argument of RoundingMode sort");
    if (!is_sort_of(domain[1], m_bv_fid, BV_SORT))
        m_manager->raise_exception("sort mismatch, expected second argument of BV sort");

    sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
    symbol name("fp.t_ubv");
    return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k));
}
Ejemplo n.º 8
0
func_decl * fpa_decl_plugin::mk_fp(decl_kind k, unsigned num_parameters, parameter const * parameters,
                                   unsigned arity, sort * const * domain, sort * range) {
    if (arity != 3)
        m_manager->raise_exception("invalid number of arguments to fp");
    if (!is_sort_of(domain[0], m_bv_fid, BV_SORT) ||
        (domain[0]->get_parameter(0).get_int() != 1) ||
        !is_sort_of(domain[1], m_bv_fid, BV_SORT) ||
        !is_sort_of(domain[2], m_bv_fid, BV_SORT))
        m_manager->raise_exception("sort mismatch, expected three bit-vectors, the first one of size 1.");

    int eb = (domain[1])->get_parameter(0).get_int();
    int sb = (domain[2])->get_parameter(0).get_int() + 1;
    symbol name("fp");
    sort * fp = mk_float_sort(eb, sb);
    return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k));
}
Ejemplo n.º 9
0
func_decl * fpa_decl_plugin::mk_to_fp_unsigned(decl_kind k, unsigned num_parameters, parameter const * parameters,
                                                 unsigned arity, sort * const * domain, sort * range) {
    SASSERT(m_bv_plugin);
    if (arity != 2)
        m_manager->raise_exception("invalid number of arguments to to_fp_unsigned");
    if (!is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT))
        m_manager->raise_exception("sort mismatch, expected first argument of RoundingMode sort");
    if (!is_sort_of(domain[1], m_bv_fid, BV_SORT))
        m_manager->raise_exception("sort mismatch, expected second argument of bit-vector sort");

    // RoundingMode + 1 BV -> 1 FP
    if (num_parameters != 2)
        m_manager->raise_exception("invalid number of parameters to to_fp_unsigned");
    if (!parameters[0].is_int() || !parameters[1].is_int())
        m_manager->raise_exception("invalid parameter type to to_fp_unsigned");

    int ebits = parameters[0].get_int();
    int sbits = parameters[1].get_int();

    sort * fp = mk_float_sort(ebits, sbits);
    symbol name("to_fp_unsigned");
    return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
}
Ejemplo n.º 10
0
func_decl * float_decl_plugin::mk_float_const_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
                                                   unsigned arity, sort * const * domain, sort * range) {
    sort * s;
    if (num_parameters == 1 && parameters[0].is_ast() && is_sort(parameters[0].get_ast()) && is_float_sort(to_sort(parameters[0].get_ast()))) {
        s = to_sort(parameters[0].get_ast());
    }
    else if (num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int()) {
        s = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
    }
    else if (range != 0 && is_float_sort(range)) {
        s = range;
    }
    else {
        m_manager->raise_exception("sort of floating point constant was not specified");
        UNREACHABLE();
    }

    SASSERT(is_sort_of(s, m_family_id, FLOAT_SORT));

    unsigned ebits = s->get_parameter(0).get_int();
    unsigned sbits = s->get_parameter(1).get_int();
    scoped_mpf val(m_fm);

    switch (k)
    {
    case OP_FLOAT_NAN: m_fm.mk_nan(ebits, sbits, val);
        SASSERT(m_fm.is_nan(val));
        break;
    case OP_FLOAT_MINUS_INF: m_fm.mk_ninf(ebits, sbits, val); break;
    case OP_FLOAT_PLUS_INF: m_fm.mk_pinf(ebits, sbits, val); break;
    case OP_FLOAT_MINUS_ZERO: m_fm.mk_nzero(ebits, sbits, val); break;
    case OP_FLOAT_PLUS_ZERO: m_fm.mk_pzero(ebits, sbits, val); break;
    }

    return mk_value_decl(val);
}
Ejemplo n.º 11
0
func_decl * float_decl_plugin::mk_value_decl(mpf const & v) {
    parameter p(mk_id(v), true);
    SASSERT(p.is_external());
    sort * s = mk_float_sort(v.get_ebits(), v.get_sbits());
    return m_manager->mk_const_decl(symbol("float"),  s, func_decl_info(m_family_id, OP_FLOAT_VALUE, 1, &p));
}
Ejemplo n.º 12
0
func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters, parameter const * parameters,
                                           unsigned arity, sort * const * domain, sort * range) {
    if (m_bv_plugin && arity == 3 &&
        is_sort_of(domain[0], m_bv_fid, BV_SORT) &&
        is_sort_of(domain[1], m_bv_fid, BV_SORT) &&
        is_sort_of(domain[2], m_bv_fid, BV_SORT)) {
        // 3 BVs -> 1 FP
        sort * fp = mk_float_sort(domain[2]->get_parameter(0).get_int(), domain[1]->get_parameter(0).get_int()+1);
        symbol name("fp");
        return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
    }
    else if (m_bv_plugin && arity == 1 && is_sort_of(domain[0], m_bv_fid, BV_SORT)) {
        // 1 BV -> 1 FP
        if (num_parameters != 2)
            m_manager->raise_exception("invalid number of parameters to to_fp");
        if (!parameters[0].is_int() || !parameters[1].is_int())
            m_manager->raise_exception("invalid parameter type to to_fp");
        int ebits = parameters[0].get_int();
        int sbits = parameters[1].get_int();

        sort * fp = mk_float_sort(ebits, sbits);
        symbol name("to_fp");
        return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
    }
    else if (m_bv_plugin && arity == 2 &&
             is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT) &&
             is_sort_of(domain[1], m_bv_fid, BV_SORT)) {
        // Rounding + 1 BV -> 1 FP
        if (num_parameters != 2)
            m_manager->raise_exception("invalid number of parameters to to_fp");
        if (!parameters[0].is_int() || !parameters[1].is_int())
            m_manager->raise_exception("invalid parameter type to to_fp");
        int ebits = parameters[0].get_int();
        int sbits = parameters[1].get_int();

        sort * fp = mk_float_sort(ebits, sbits);
        symbol name("to_fp");
        return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
    }
    else if (arity == 2 &&
             is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT) &&
             is_sort_of(domain[1], m_family_id, FLOAT_SORT)) {
        // Rounding + 1 FP -> 1 FP
        if (num_parameters != 2)
            m_manager->raise_exception("invalid number of parameters to to_fp");
        if (!parameters[0].is_int() || !parameters[1].is_int())
            m_manager->raise_exception("invalid parameter type to to_fp");
        int ebits = parameters[0].get_int();
        int sbits = parameters[1].get_int();
        if (!is_rm_sort(domain[0]))
            m_manager->raise_exception("sort mismatch, expected first argument of RoundingMode sort");
        if (!is_sort_of(domain[1], m_family_id, FLOAT_SORT))
            m_manager->raise_exception("sort mismatch, expected second argument of FloatingPoint sort");

        sort * fp = mk_float_sort(ebits, sbits);
        symbol name("to_fp");
        return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
    }
    else {
        // 1 Real -> 1 FP
        if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int()))
            m_manager->raise_exception("expecting two integer parameters to to_fp");
        if (arity != 2 && arity != 3)
            m_manager->raise_exception("invalid number of arguments to to_fp operator");
        if (arity == 3 && domain[2] != m_int_sort)
            m_manager->raise_exception("sort mismatch, expected second argument of Int sort");
        if (domain[1] != m_real_sort)
            m_manager->raise_exception("sort mismatch, expected second argument of Real sort");

        sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
        symbol name("to_fp");
        return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
    }
}
Ejemplo n.º 13
0
func_decl * fpa_decl_plugin::mk_to_fp(decl_kind k, unsigned num_parameters, parameter const * parameters,
                                        unsigned arity, sort * const * domain, sort * range) {
    if (m_bv_plugin && arity == 3 &&
        is_sort_of(domain[0], m_bv_fid, BV_SORT) &&
        is_sort_of(domain[1], m_bv_fid, BV_SORT) &&
        is_sort_of(domain[2], m_bv_fid, BV_SORT)) {
        // 3 BVs -> 1 FP
        unsigned ebits = domain[1]->get_parameter(0).get_int();
        unsigned sbits = domain[2]->get_parameter(0).get_int() + 1;
        parameter ps[] = { parameter(ebits), parameter(sbits) };
        sort * fp = mk_float_sort(ebits, sbits);
        symbol name("to_fp");
        return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, 2, ps));
    }
    else if (m_bv_plugin && arity == 1 && is_sort_of(domain[0], m_bv_fid, BV_SORT)) {
        // 1 BV -> 1 FP
        if (num_parameters != 2)
            m_manager->raise_exception("invalid number of parameters to to_fp");
        if (!parameters[0].is_int() || !parameters[1].is_int())
            m_manager->raise_exception("invalid parameter type to to_fp");

        int ebits = parameters[0].get_int();
        int sbits = parameters[1].get_int();

        if (domain[0]->get_parameter(0).get_int() != (ebits + sbits))
            m_manager->raise_exception("sort mismatch; invalid bit-vector size, expected bitvector of size (ebits+sbits)");

        sort * fp = mk_float_sort(ebits, sbits);
        symbol name("to_fp");
        return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
    }
    else if (m_bv_plugin && arity == 2 &&
             is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT) &&
             is_sort_of(domain[1], m_bv_fid, BV_SORT)) {
        // RoundingMode + 1 BV -> 1 FP
        if (num_parameters != 2)
            m_manager->raise_exception("invalid number of parameters to to_fp");
        if (!parameters[0].is_int() || !parameters[1].is_int())
            m_manager->raise_exception("invalid parameter type to to_fp");
        int ebits = parameters[0].get_int();
        int sbits = parameters[1].get_int();

        sort * fp = mk_float_sort(ebits, sbits);
        symbol name("to_fp");
        return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
    }
    else if (arity == 2 &&
             is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT) &&
             is_sort_of(domain[1], m_family_id, FLOATING_POINT_SORT)) {
        // Rounding + 1 FP -> 1 FP
        if (num_parameters != 2)
            m_manager->raise_exception("invalid number of parameters to to_fp");
        if (!parameters[0].is_int() || !parameters[1].is_int())
            m_manager->raise_exception("invalid parameter type to to_fp");
        int ebits = parameters[0].get_int();
        int sbits = parameters[1].get_int();
        if (!is_rm_sort(domain[0]))
            m_manager->raise_exception("sort mismatch, expected first argument of RoundingMode sort");
        if (!is_sort_of(domain[1], m_family_id, FLOATING_POINT_SORT))
            m_manager->raise_exception("sort mismatch, expected second argument of FloatingPoint sort");

        sort * fp = mk_float_sort(ebits, sbits);
        symbol name("to_fp");
        return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
    }
    else if (arity == 3 &&
        is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT) &&
        is_sort_of(domain[1], m_arith_fid, REAL_SORT) &&
        is_sort_of(domain[2], m_arith_fid, INT_SORT))
    {
        // Rounding +  1 Real + 1 Int -> 1 FP
        if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int()))
            m_manager->raise_exception("expecting two integer parameters to to_fp");

        sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
        symbol name("to_fp");
        return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
    }
    else if (arity == 3 &&
             is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT) &&
             is_sort_of(domain[1], m_arith_fid, INT_SORT) &&
             is_sort_of(domain[2], m_arith_fid, REAL_SORT))
    {
        // Rounding +  1 Int + 1 Real -> 1 FP
        if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int()))
            m_manager->raise_exception("expecting two integer parameters to to_fp");

        sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
        symbol name("to_fp");
        return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
    }
    else if (arity == 1 &&
             is_sort_of(domain[0], m_arith_fid, REAL_SORT))
    {
        // 1 Real -> 1 FP
        if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int()))
            m_manager->raise_exception("expecting two integer parameters to to_fp");
        if (domain[1] != m_real_sort)
            m_manager->raise_exception("sort mismatch, expected one argument of Real sort");

        sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
        symbol name("to_fp");
        return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
    }
    else if (arity == 2 &&
             is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT) &&
             is_sort_of(domain[1], m_arith_fid, REAL_SORT))
    {
        // Rounding + 1 Real -> 1 FP
        if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int()))
            m_manager->raise_exception("expecting two integer parameters to to_fp");

        sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
        symbol name("to_fp");
        return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
    }
    else if (arity == 2 &&
             is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT) &&
             is_sort_of(domain[1], m_arith_fid, INT_SORT)) {
        // Rounding + 1 Int -> 1 FP
        if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int()))
            m_manager->raise_exception("expecting two integer parameters to to_fp");

        sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
        symbol name("to_fp");
        return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
    }
    else {
        m_manager->raise_exception("Unexpected argument combination for (_ to_fp eb sb). Supported argument combinations are: "
                                   "((_ BitVec 1) (_ BitVec eb) (_ BitVec sb-1)), "
                                   "(_ BitVec (eb+sb)), "
                                   "(Real), "
                                   "(RoundingMode (_ BitVec (eb+sb))), "
                                   "(RoundingMode (_ FloatingPoint eb' sb')), "
                                   "(RoundingMode Int Real), "
                                   "(RoundingMode Real Int), "
                                   "(RoundingMode Int), and "
                                   "(RoundingMode Real)."
                                   );
    }

    return nullptr;
}