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));
        }
    }
}
func_decl * float_decl_plugin::mk_fused_ma(decl_kind k, unsigned num_parameters, parameter const * parameters,
                                           unsigned arity, sort * const * domain, sort * range) {
    if (arity != 4)
        m_manager->raise_exception("invalid number of arguments to fused_ma operator");
    if (!is_rm_sort(domain[0]) || domain[1] != domain[2] || domain[1] != domain[3] || !is_float_sort(domain[1]))
        m_manager->raise_exception("sort mismatch"); 
    symbol name("fusedMA");
    return m_manager->mk_func_decl(name, arity, domain, domain[1], func_decl_info(m_family_id, k));
}
示例#3
0
func_decl * float_decl_plugin::mk_fma(decl_kind k, unsigned num_parameters, parameter const * parameters,
                                           unsigned arity, sort * const * domain, sort * range) {
    if (arity != 4)
        m_manager->raise_exception("invalid number of arguments to fused_ma operator");
    if (!is_rm_sort(domain[0]))
        m_manager->raise_exception("sort mismatch, expected RoundingMode as first argument");
    if (domain[1] != domain[2] || domain[1] != domain[3] || !is_float_sort(domain[1]))
        m_manager->raise_exception("sort mismatch, expected arguments 1,2,3 of equal FloatingPoint sort");
    symbol name("fp.fma");
    return m_manager->mk_func_decl(name, arity, domain, domain[1], func_decl_info(m_family_id, k));
}
示例#4
0
func_decl * fpa_decl_plugin::mk_bv2rm(decl_kind k, unsigned num_parameters, parameter const * parameters,
                                            unsigned arity, sort * const * domain, sort * range) {
    if (arity != 1)
        m_manager->raise_exception("invalid number of arguments to bv2rm");
    if (!is_sort_of(domain[0], m_bv_fid, BV_SORT) || domain[0]->get_parameter(0).get_int() != 3)
        m_manager->raise_exception("sort mismatch, expected argument of sort bitvector, size 3");
    if (!is_rm_sort(range))
        m_manager->raise_exception("sort mismatch, expected range of RoundingMode sort");

    parameter ps[] = { parameter(3) };
    sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, ps);
    return m_manager->mk_func_decl(symbol("rm"), 1, &bv_srt, range, func_decl_info(m_family_id, k, num_parameters, parameters));
}
示例#5
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));
}
func_decl * float_decl_plugin::mk_rm_unary_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
                                                unsigned arity, sort * const * domain, sort * range) {
    if (arity != 2)
        m_manager->raise_exception("invalid number of arguments to floating point operator");
    if (!is_rm_sort(domain[0]) || !is_float_sort(domain[1]))
        m_manager->raise_exception("sort mismatch"); 
    symbol name;
    switch (k) {
    case OP_FLOAT_SQRT: name = "squareRoot";   break;
    case OP_FLOAT_ROUND_TO_INTEGRAL: name = "roundToIntegral";   break;
    default:
        UNREACHABLE();
        break;
    }
    return m_manager->mk_func_decl(name, arity, domain, domain[1], func_decl_info(m_family_id, k));
}
func_decl * float_decl_plugin::mk_rm_binary_decl(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 floating point operator");
    if (!is_rm_sort(domain[0]) || domain[1] != domain[2] || !is_float_sort(domain[1]))
        m_manager->raise_exception("sort mismatch"); 
    symbol name;
    switch (k) {
    case OP_FLOAT_ADD: name = "+";   break;
    case OP_FLOAT_SUB: name = "-";   break;
    case OP_FLOAT_MUL: name = "*";   break;
    case OP_FLOAT_DIV: name = "/";   break;
    default:
        UNREACHABLE();
        break;
    }
    return m_manager->mk_func_decl(name, arity, domain, domain[1], func_decl_info(m_family_id, k));
}
示例#8
0
func_decl * float_decl_plugin::mk_rm_binary_decl(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 floating point operator");
    if (!is_rm_sort(domain[0]))
        m_manager->raise_exception("sort mismatch, expected first argument of RoundingMode sort");
    if (domain[1] != domain[2] || !is_float_sort(domain[1]))
        m_manager->raise_exception("sort mismatch, expected arguments 1 and 2 of equal FloatingPoint sorts");
    symbol name;
    switch (k) {
    case OP_FLOAT_ADD: name = "fp.add";   break;
    case OP_FLOAT_SUB: name = "fp.sub";   break;
    case OP_FLOAT_MUL: name = "fp.mul";   break;
    case OP_FLOAT_DIV: name = "fp.div";   break;
    default:
        UNREACHABLE();
        break;
    }
    return m_manager->mk_func_decl(name, arity, domain, domain[1], func_decl_info(m_family_id, k));
}
示例#9
0
func_decl * fpa_decl_plugin::mk_bv_wrap(decl_kind k, unsigned num_parameters, parameter const * parameters,
                                                 unsigned arity, sort * const * domain, sort * range) {
    if (arity != 1)
        m_manager->raise_exception("invalid number of arguments to bv_wrap");
    if (!is_float_sort(domain[0]) && !is_rm_sort(domain[0]))
        m_manager->raise_exception("sort mismatch, expected argument of FloatingPoint or RoundingMode sort");

    if (is_float_sort(domain[0]))
    {
        unsigned float_sz = domain[0]->get_parameter(0).get_int() + domain[0]->get_parameter(1).get_int();
        parameter ps[] = { parameter(float_sz) };
        sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, ps);
        return m_manager->mk_func_decl(symbol("bv_wrap"), 1, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters));
    }
    else {
        parameter ps[] = { parameter(3) };
        sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, ps);
        return m_manager->mk_func_decl(symbol("bv_wrap"), 1, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters));
    }
}
示例#10
0
func_decl * fpa_decl_plugin::mk_to_sbv(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 fp.to_sbv");
    if (num_parameters != 1)
        m_manager->raise_exception("invalid number of parameters to fp.to_sbv");
    if (!parameters[0].is_int())
        m_manager->raise_exception("invalid parameter type; fp.to_sbv expects an int parameter");
    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");
    if (parameters[0].get_int() <= 0)
        m_manager->raise_exception("invalid parameter value; fp.to_sbv expects a parameter larger than 0");

    symbol name("fp.to_sbv");
    sort * bvs = m_bv_plugin->mk_sort(BV_SORT, 1, parameters);
    return m_manager->mk_func_decl(name, arity, domain, bvs, func_decl_info(m_family_id, k, num_parameters, parameters));
}
示例#11
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));
    }
}
示例#12
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;
}