Ejemplo n.º 1
0
def verify_solution(ez, X_star,symbolTable,printModel=False):
    assert isinstance(symbolTable, collections.OrderedDict)
    assert isinstance(ez, z3.ExprRef)
    assert len(symbolTable)==X_star.size
    model=[]
    # (sympy.Symbol('x'), 
    for (s,val) in zip(symbolTable.items(), X_star): 
        var, sort = s[0],s[1]
        var=rename_var(var)
        
#        if ("!" in varr) or ("@" in var):
#            symVar="x_"+str(expr_z3.hash()) STOP HERE
        
        if sort == Sort.Float32:
            var_z3=z3.FP(str(var),z3.Float32())
            val_z3=z3.FPVal(val,z3.Float32())
        elif sort == Sort.Float64:
            var_z3=z3.FP(str(var),z3.Float64())
            val_z3=z3.FPVal(val,z3.Float64())
        else:
            raise NotImplementedError("Unexpected type %s" %sort)            
        model.append((var_z3,val_z3))
    if printModel:
        print "model: "
        print model

    ##Nice for debugging.     
    #print "p"*90
    #print z3.substitute(ez, *model)

    return _is_true(z3.simplify(z3.substitute(ez, *model)))
Ejemplo n.º 2
0
def get_z3_var(vartype, name, datatype_name=None, ctx=None):
    var = None
    if isinstance(vartype, z3.z3.DatatypeSortRef):  # discrete values datatype
        var = z3.Const(name, vartype)
    elif vartype is Types.INT:
        var = z3.BitVec(name, 32, ctx=ctx)
    elif vartype is Types.INTEGER:
        var = z3.Int(name, ctx=ctx)
    elif vartype is Types.FLOAT:
        var = z3.FP(name, z3.Float32(), ctx=ctx)
    elif vartype is Types.REAL:
        var = z3.Real(name, ctx=ctx)
    elif vartype is Types.BOOL:
        var = z3.Bool(name, ctx=ctx)
    elif vartype is Types.STRING:
        var = z3.String(name, ctx=ctx)
    elif isinstance(vartype, list):
        datatype = _get_datatype_from_list(vartype, datatype_name)
        var = z3.Const(name, datatype)
        vartype = datatype
    else:
        raise ValueError(
            f"I do not know how to create a z3-variable for type {vartype} (name: {name})"
        )

    assert var is not None, f"Var wasn't converted: vartype: {vartype}, name: {name}"

    var.type = vartype
    return var
Ejemplo n.º 3
0
 def visit_float_is_infinite(self, e):
     arg = e.arg(0)
     self._check_fp_sort(arg)
     arg_sort = arg.sort()
     pos_inf = None
     neg_inf = None
     if self._is_float32_sort(arg_sort):
         pos_inf = z3.fpPlusInfinity(z3.Float32())
         neg_inf = z3.fpMinusInfinity(z3.Float32())
     elif self._is_float64_sort(arg_sort):
         pos_inf = z3.fpPlusInfinity(z3.Float64())
         neg_inf = z3.fpMinusInfinity(z3.Float64())
     else:
         raise CoralPrinterException('Unhandled fp.isInfinite op case')
     temp = z3.Or(z3.fpEQ(arg, pos_inf), z3.fpEQ(arg, neg_inf))
     self.visit(temp)
Ejemplo n.º 4
0
def get_z3_val(valtype, value, name, datatype_name=None, ctx=None):
    val = None
    if isinstance(valtype, z3.z3.DatatypeSortRef):  # discrete values datatype
        val = getattr(valtype, value)
    elif valtype is Types.INT:
        try:
            val = z3.BitVecVal(value, 32, ctx=ctx)
        except Exception as exc:
            raise ValueError(
                f"Error during INT conversion. Cannot convert value: {value}, type: {type(value)}, name: {name}"
            )
    elif valtype is Types.INTEGER:
        try:
            val = z3.IntVal(value, ctx=ctx)
        except Exception as exc:
            raise ValueError(
                f"Error during INTEGER conversion. Cannot convert value: {value}, type: {type(value)}, name: {name}"
            )
    elif valtype is Types.FLOAT:
        try:
            val = z3.FPVal(value, z3.Float32(), ctx=ctx)
        except Exception as exc:
            raise ValueError(
                f"Error during FLOAT conversion. Cannot convert value: {value}, type: {type(value)}, name: {name}"
            )
    elif valtype is Types.REAL:
        try:
            val = z3.RealVal(value, ctx=ctx)
        except Exception as exc:
            raise ValueError(
                f"Error during REAL conversion. Cannot convert value: {value}, type: {type(value)}, name: {name}"
            )
    elif valtype is Types.BOOL:
        try:
            val = z3.BoolVal(value, ctx=ctx)
        except Exception as exc:
            raise ValueError(
                f"Error during BOOL conversion of value to INT. value: {value}, type: {type(value)}, name: {name}"
            )
    elif valtype is Types.STRING:
        try:
            val = z3.StringVal(value, ctx=ctx)
        except Exception as exc:
            raise ValueError(
                f"Error during STRING conversion of value to INT. value: {value}, type: {type(value)}, name: {name}"
            )
    elif isinstance(valtype, list):
        datatype = _get_datatype_from_list(valtype, datatype_name)
        val = getattr(datatype, value)
        valtype = datatype
    else:
        raise ValueError(
            f"I do not know how to create a z3-value for type {valtype}")

    assert val is not None, f"Value wasn't converted: valtype: {valtype}, value: {value}, name: {name}"
    val.type = valtype
    return val
Ejemplo n.º 5
0
def gen_symbolic_value(var_type, name):
    if var_type == bin_format.i32:
        return z3.BitVec(name, 32)
    if var_type == bin_format.i64:
        return z3.BitVec(name, 64)
    if var_type == bin_format.f32:
        return z3.FP(f'f32_{i}', z3.Float32())
    if var_type == bin_format.f64:
        return z3.FP(name, z3.Float64())
    raise TypeError('Unsupported variable type')
Ejemplo n.º 6
0
def fp_size_to_sort(size):
    size_class = z3.Float64()

    if size == 16:
        size_class = z3.Float16()
    elif size == 32:
        size_class = z3.Float32()
    elif size == 128:
        size_class = z3.Float128()

    return size_class
Ejemplo n.º 7
0
def _getSort(expr_z3):
    assert isinstance(expr_z3, z3.ExprRef)
    if expr_z3.sort() == z3.Float32():
        return Sort.Float32
    if expr_z3.sort() == z3.Float64():
        return Sort.Float64
    if expr_z3.sort() == z3.RealSort():
        return Sort.Real
    if expr_z3.sort() == z3.IntSort():
        return Sort.Int
    return Sort.UNKNOWN
Ejemplo n.º 8
0
def verify_solution(ez, X_star, symbolTable, printModel=False):
    assert isinstance(symbolTable, collections.OrderedDict)
    assert isinstance(ez, z3.ExprRef)
    assert isinstance(res, op.OptimizeResult)
    assert len(symbolTable) == X_star.size
    model = []
    # (sympy.Symbol('x'),
    for (s, val) in zip(symbolTable.items(), X_star):
        var, sort = s[0], s[1]
        if sort == Sort.Float32:
            var_z3 = z3.FP(str(var), z3.Float32())
            val_z3 = z3.FPVal(val, z3.Float32())
        elif sort == Sort.Float64:
            var_z3 = z3.FP(str(var), z3.Float64())
            val_z3 = z3.FPVal(val, z3.Float64())
        else:
            raise NotImplementedError("Unexpected type %s" % sort)
        model.append((var_z3, val_z3))
    if printModel:
        print "model: "
        print model
    return _is_true(z3.simplify(z3.substitute(ez, *model)))
Ejemplo n.º 9
0
def _ty_sort(ty):
    'Translate a Type expression to a Z3 Sort'

    if isinstance(ty, IntType):
        return z3.BitVecSort(ty.width)

    return {
        PtrType: z3.BitVecSort(64),
        HalfType: z3.FloatHalf(),
        SingleType: z3.Float32(),
        DoubleType: z3.Float64(),
        FP128Type: z3.Float128(),
        X86FP80Type: z3.FPSort(15, 64),
    }[type(ty)]
Ejemplo n.º 10
0
 def visit_float_is_positive(self, e):
     arg = e.arg(0)
     self._check_fp_sort(arg)
     arg_sort = e.arg(0).sort()
     zero = None
     # FIXME: This isn't sound. We can't distinguish +0 and -0
     # in Coral's constraint language
     self._unsound_translation('fp.isPositive')
     if self._is_float32_sort(arg_sort):
         zero = z3.fpPlusZero(z3.Float32())
     elif self._is_float64_sort(arg_sort):
         zero = z3.fpPlusZero(z3.Float64())
     else:
         raise CoralPrinterException('Unhandled fp.isPositive case')
     tmp = z3.fpGT(arg, zero)
     self.visit(tmp)
Ejemplo n.º 11
0
 def visit_float_is_zero(self, e):
     arg = e.arg(0)
     self._check_fp_sort(arg)
     arg_sort = arg.sort()
     zero = None
     # It doesn't matter if we pick +0 or -0 as we are using
     # the fp.eq operator which can't distinguish them, so
     # the choice of +0 is arbitrary.
     if self._is_float32_sort(arg_sort):
         zero = z3.fpPlusZero(z3.Float32())
     elif self._is_float64_sort(arg_sort):
         zero = z3.fpPlusZero(z3.Float64())
     else:
         raise CoralPrinterException('Unhandled fp.isZero op case')
     temp = z3.fpEQ(arg, zero)
     self.visit(temp)
Ejemplo n.º 12
0
def prepare_float(val, signext=False, size=SIZE) -> z3.FPRef:
    if z3.is_fp(val):
        return val

    size_class = z3.Float64()
    if size == 32:
        size_class = z3.Float32()
    elif size == 128:
        size_class = z3.Float128()

    if type(val) in (int, float):
        result = z3.FPVal(val)
    else:
        bv_val = prepare(val, signext, size)
        result = z3.fpBVToFP(bv_val, size_class)

    return result
Ejemplo n.º 13
0
def gen_symbolic_args(func: 'instance.FunctionInstance'):
    symbolic_params = []
    for i, e in enumerate(func.functype.args):
        if e == bin_format.i32:
            symbolic_params.append(z3.BitVec(f'i32_bv_{i}', 32))
        elif e == bin_format.i64:
            symbolic_params.append(z3.BitVec(f'i64_bv_{i}', 64))
        elif e == bin_format.f32:
            # f32_bv = z3.BitVec(f'f32_bv_{i}', 32)
            # symbolic_params.append(z3.fpBVToFP(f32_bv, z3.Float32()))
            # another approach
            symbolic_params.append(z3.FP(f'f32_{i}', z3.Float32()))
        else:
            # f64_bv = z3.BitVec(f'f64_bv_{i}', 64)
            # symbolic_params.append(z3.fpBVToFP(f64_bv, z3.Float64()))
            # another approach
            symbolic_params.append(z3.FP(f'f64_{i}', z3.Float64()))
    return symbolic_params
Ejemplo n.º 14
0
def gen_symbolic_args(func: 'instance.FunctionInstance'):
    symbolic_params = list()
    for i, e in enumerate(func.functype.args):
        if e == bin_format.i32:
            symbolic_params.append(z3.BitVec(f'i32_bv_{i}', 32))
        elif e == bin_format.i64:
            symbolic_params.append(z3.BitVec(f'i64_bv_{i}', 64))
        elif e == bin_format.f32:
            # The first approach is bit-vector based
            # f32_bv = z3.BitVec(f'f32_bv_{i}', 32)
            # symbolic_params.append(z3.fpBVToFP(f32_bv, z3.Float32()))
            # The second approach is float-point based
            symbolic_params.append(z3.FP(f'f32_{i}', z3.Float32()))
        else:
            # The first approach is bit-vector based
            # f64_bv = z3.BitVec(f'f64_bv_{i}', 64)
            # symbolic_params.append(z3.fpBVToFP(f64_bv, z3.Float64()))
            # The second approach is float-point based
            symbolic_params.append(z3.FP(f'f64_{i}', z3.Float64()))
    return symbolic_params
Ejemplo n.º 15
0
def interp(tree, lookup, z3_mode):
    """Evaluate the arithmetic expression.

    Pass a tree as a Lark `Tree` object for the parsed expression. For
    `lookup`, provide a function for mapping variable names to values.
    """

    op = tree.data
    if op in ('add', 'sub', 'mul', 'div', 'shl', 'shr'):  # Binary operators.
        lhs = interp(tree.children[0], lookup, z3_mode)
        rhs = interp(tree.children[1], lookup, z3_mode)
        if op == 'add':
            return lhs + rhs
        elif op == 'sub':
            return lhs - rhs
        elif op == 'mul':
            return lhs * rhs
        elif op == 'div':
            return lhs / rhs
        elif op == 'shl':
            return lhs << rhs
        elif op == 'shr':
            return lhs >> rhs
    elif op == 'neg':  # Negation.
        sub = interp(tree.children[0], lookup, z3_mode)
        return -sub
    elif op == 'int':  # Literal number.
        if z3_mode:
            return z3.BitVecVal(int(tree.children[0]), 32)
        else:
            return int(tree.children[0])
    elif op == 'float':  # Literal number.
        if z3_mode:
            return z3.BitVecVal(float(tree.children[0]), 32)
        else:
            return float(tree.children[0])
    elif op == 'var':  # Variable lookup.
        return lookup(tree.children[0])
    elif op == 'if':  # Conditional.
        cond = interp(tree.children[0], lookup, z3_mode)
        true = interp(tree.children[1], lookup, z3_mode)
        false = interp(tree.children[2], lookup, z3_mode)
        return (cond != 0) * true + (cond == 0) * false
    elif op == "intcast":
        child = interp(tree.children[0], lookup, z3_mode)
        if z3_mode:
            return z3.BV2Int(child)
        else:
            return int(child)
    elif op == "floatcast":
        child = interp(tree.children[0], lookup, z3_mode)
        if z3_mode:
            return z3.fpBVToFP(child, z3.Float32())
        else:
            return float(child)
    elif op == "int2bv":
        child = interp(tree.children[0], lookup, z3_mode)
        if z3_mode:
            return z3.Int2BV(child, 32)
        else:
            return child
    elif op == "float2bv":
        child = interp(tree.children[0], lookup, z3_mode)
        if z3_mode:
            return z3.fpToIEEEBV(child)
        else:
            return child
Ejemplo n.º 16
0
def _gen(expr_z3, symbolTable, cache, result):

    ###Leaf: var
    if _is_variable(expr_z3):
        if DEBUG: print "-- Branch _is_variable with ", expr_z3
        symVar = expr_z3.decl().name()

        symVar = rename_var(symVar)

        if z3.is_int(expr_z3): symType = Sort.Int
        elif z3.is_fp(expr_z3):
            if expr_z3.sort() == z3.Float64():
                symType = Sort.Float64
            elif expr_z3.sort() == z3.Float32():
                symType = Sort.Float32
            else:
                raise NotImplementedError("Unexpected sort.", expr_z3.sort())
        elif z3.is_real(expr_z3):
            symType = Sort.Float
            warnings.warn(
                "****WARNING****: Real variable '%s' treated as floating point"
                % symVar)
        else:
            raise NotImplementedError("Unexpected type for %s" % symbolName)
        if (symVar in symbolTable.keys()):
            assert symType == symbolTable[symVar]
        else:
            symbolTable[symVar] = symType

        if expr_z3.sort() == z3.Float32():
            symVar = "TR32(%s)" % symVar  # do the same ting for verify !!!!!!!!

        return symVar

    ###Leaf: val
    if _is_value(expr_z3):
        if DEBUG: print "-- Branch _is_value"
        if z3.is_fp(expr_z3) or z3.is_real(expr_z3):
            if DEBUG: print "---- Sub-Branch FP or Real"
            if isinstance(expr_z3, z3.FPNumRef):
                if DEBUG: print "------- Sub-Sub-Branch _is_FPNumRef"
                try:
                    str_ret = str(sympy.Float(str(expr_z3), 17))

                except ValueError:
                    if expr_z3.isInf() and expr_z3.decl().kind(
                    ) == z3.Z3_OP_FPA_PLUS_INF:
                        str_ret = "INFINITY"
                    elif expr_z3.isInf() and expr_z3.decl().kind(
                    ) == z3.Z3_OP_FPA_MINUS_INF:
                        str_ret = "- INFINITY"
                    elif expr_z3.isNaN():
                        str_ret = "NAN"
                    else:
                        offset = 127 if expr_z3.sort() == z3.Float32(
                        ) else 1023
                        #Z3 new version needs the offset to be taken into consideration
                        expr_z3_exponent = expr_z3.exponent_as_long() - offset

                        str_ret = str(
                            sympy.Float((-1)**float(expr_z3.sign()) *
                                        float(str(expr_z3.significand())) *
                                        2**(expr_z3_exponent), 17))

            else:
                if DEBUG:
                    print "------- Sub-Sub-Branch other than FPNumRef, probably FPRef"
                str_ret = str(sympy.Float(str((expr_z3)), 17))
        elif z3.is_int(expr_z3):
            if DEBUG: print "---- Sub-Branch Integer"
            str_ret = str(sympy.Integer(str(expr_z3)))
        elif _is_true(expr_z3):

            str_ret = "0"
        elif _is_false(expr_z3):
            str_ret = "1"
        else:
            raise NotImplementedError(
                "[XSat: Coral Benchmarking] type not considered ")

        if expr_z3.sort() == z3.Float32():
            str_ret = str_ret + "f"

        return str_ret

    #if (expr_z3 in cache): return cache[expr_z3]

    #cache will be a set of defined IDs
    #if (var_name(expr_z3) in cache): return cache[expr_z3]

    if (expr_z3.get_id() in cache): return var_name(expr_z3)

    cache.add(expr_z3.get_id())
    #cache[expr_z3]=var_name(expr_z3)

    sort_z3 = expr_z3.decl().kind()

    expr_type = 'double'
    if expr_z3.sort() == z3.FPSort(8, 24): expr_type = 'float'

    ###
    if sort_z3 == z3.Z3_OP_FPA_LE:
        if DEBUG: print "-- Branch _is_le"
        lhs = _gen(expr_z3.arg(0), symbolTable, cache, result)
        rhs = _gen(expr_z3.arg(1), symbolTable, cache, result)
        toAppend= "double %s = DLE(%s,%s); " \
                  %( var_name(expr_z3), \
                     lhs,\
                     rhs,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    #########!!!!!!!!!!!! need to do something
    if sort_z3 == z3.Z3_OP_FPA_TO_FP:
        if DEBUG: print "-- Branch _is_fpFP"
        assert expr_z3.num_args() == 2
        if not (_is_RNE(expr_z3.arg(0))):
            warnings.warn(
                "WARNING!!! I expect the first argument of fpFP is RNE, but it is ",
                expr_z3.arg(0))

        x = _gen(expr_z3.arg(1), symbolTable, cache, result)
        if expr_z3.sort() == z3.FPSort(8, 24):
            x = "TR32(%s)" % x
        #else if expr_z3.sort()==z3.FPSort(8,24):
        #    x = "TR(%s)"  %x

        toAppend= "%s %s = %s; " \
                  %( expr_type, var_name(expr_z3), \
                     x,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    if sort_z3 == z3.Z3_OP_FPA_LT:
        if DEBUG: print "-- Branch _is_lt"
        lhs = _gen(expr_z3.arg(0), symbolTable, cache, result)
        rhs = _gen(expr_z3.arg(1), symbolTable, cache, result)
        toAppend= "double %s = DLT(%s,%s);" \
                  %( var_name(expr_z3), \
                     lhs,\
                     rhs,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    if _is_eq(expr_z3):
        if DEBUG: print "-- Branch _is_eq"
        lhs = _gen(expr_z3.arg(0), symbolTable, cache, result)
        rhs = _gen(expr_z3.arg(1), symbolTable, cache, result)
        toAppend= "double %s = DEQ(%s,%s);" \
                  %( var_name(expr_z3), \
                        lhs,\
                     rhs,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    if _is_fpMul(expr_z3):
        if DEBUG: print "-- Branch _is_fpMul"
        if not _is_RNE(expr_z3.arg(0)):
            warnings.warn(
                "WARNING!!! arg(0) is not RNE but is treated as RNE. arg(0) = ",
                expr_z3.arg(0))
        assert expr_z3.num_args() == 3
        lhs = _gen(expr_z3.arg(1), symbolTable, cache, result)
        rhs = _gen(expr_z3.arg(2), symbolTable, cache, result)
        toAppend= "%s %s = %s*%s; " \
                  %( expr_type, var_name(expr_z3), \
                        lhs,\
                     rhs,\

                  )
        result.append(toAppend)
        return var_name(expr_z3)

    if _is_fpDiv(expr_z3):
        if DEBUG: print "-- Branch _is_fpDiv"
        if not _is_RNE(expr_z3.arg(0)):
            warnings.warn(
                "WARNING!!! arg(0) is not RNE but is treated as RNE. arg(0) = ",
                expr_z3.arg(0))
        assert expr_z3.num_args() == 3
        lhs = _gen(expr_z3.arg(1), symbolTable, cache, result)
        rhs = _gen(expr_z3.arg(2), symbolTable, cache, result)
        toAppend= "%s %s = %s/%s; " \
                  %(expr_type,  var_name(expr_z3), \
                        lhs,\
                     rhs,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    if _is_fpAdd(expr_z3):
        if DEBUG: print "-- Branch _is_fpAdd"
        if not _is_RNE(expr_z3.arg(0)):
            warnings.warn(
                "WARNING!!! arg(0) is not RNE but is treated as RNE. arg(0) = ",
                expr_z3.arg(0))
        assert expr_z3.num_args() == 3
        lhs = _gen(expr_z3.arg(1), symbolTable, cache, result)
        rhs = _gen(expr_z3.arg(2), symbolTable, cache, result)
        toAppend= "%s %s = %s+%s;" \
                  %( expr_type, var_name(expr_z3), \
                        lhs,\
                     rhs,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    if z3.is_and(expr_z3):
        if DEBUG: print "-- Branch _is_and"
        ##TODO Not sure if symbolTable will be treated in a multi-threaded way
        toAppendExpr = _gen(expr_z3.arg(0), symbolTable, cache, result)
        for i in range(1, expr_z3.num_args()):
            toAppendExpr = 'BAND( %s,%s )' % (
                toAppendExpr, _gen(expr_z3.arg(i), symbolTable, cache, result))

        toAppend= "double %s = %s; " \
                  %( var_name(expr_z3), \
                     toAppendExpr,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    if z3.is_not(expr_z3):
        if DEBUG: print "-- Branch _is_not"
        assert expr_z3.num_args() == 1
        if not (expr_z3.arg(0).num_args() == 2):
            warnings.warn(
                "WARNING!!! arg(0) is not RNE but is treated as RNE. arg(0) = ",
                expr_z3.arg(0))
        op1 = _gen(expr_z3.arg(0).arg(0), symbolTable, cache, result)
        op2 = _gen(expr_z3.arg(0).arg(1), symbolTable, cache, result)
        if _is_ge(expr_z3.arg(0)):
            a = "DLT(%s,%s)" % (op1, op2)
        elif _is_gt(expr_z3.arg(0)):
            a = "DLE(%s,%s)" % (op1, op2)
        elif _is_le(expr_z3.arg(0)):
            a = "DGT(%s,%s)" % (op1, op2)
        elif _is_lt(expr_z3.arg(0)):
            a = "DGE(%s,%s)" % (op1, op2)
        elif _is_eq(expr_z3.arg(0)):
            a = "DNE(%s,%s)" % (op1, op2)
        elif _is_distinct(expr_z3.arg(0)):
            a = "DEQ(%s,%s)" % (op1, op2)
        else:
            raise NotImplementedError(
                "Not implemented case 004 for expr_z3  =  %s. 'Not(or... )' is not handled yet"
                % expr_z3)
        toAppend= "%s %s = %s; " \
                  %( expr_type, var_name(expr_z3), \
                     a,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    if _is_fpNeg(expr_z3):
        if DEBUG: print "-- Branch _is_fpNeg"
        assert expr_z3.num_args() == 1
        op1 = _gen(expr_z3.arg(0), symbolTable, cache, result)
        toAppend = "%s %s =  - %s ;" \
                  %(expr_type, var_name(expr_z3), \
                     op1,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    raise NotImplementedError(
        "Not implemented case 002 for expr_z3  =  %s, kind(%s)" %
        (expr_z3, expr_z3.decl().kind()))
Ejemplo n.º 17
0
    def cast(self, value, is_type, to_type):
        if is_type is Types.STRING and isinstance(to_type,
                                                  z3.z3.DatatypeSortRef):
            # the value is a string and it should be cast to a datatyperef
            # (i.e. an enum-type), just return the value because we can deal with it
            return value

        value_is_int = isinstance(value, int)
        value_is_float = isinstance(value, float)

        if is_type is to_type:  # already correct type, just return the value
            return value
            """ INT <---> INTEGER """
        elif is_type is Types.INT and to_type is Types.INTEGER:
            if value_is_int or value_is_float:
                return value  # this happens if it is an int numeral (e.g. 2)
            else:
                return z3.BV2Int(value)
        elif is_type is Types.INTEGER and to_type is Types.INT:
            if value_is_int or value_is_float:
                return value
            else:
                return z3.Int2BV(value, 32)
            """ INT <---> FLOAT """
        elif is_type is Types.FLOAT and to_type is Types.INT:
            if value_is_float:
                return value  # this happens if it is a float numeral (e.g. 3.14)
            else:
                return z3.fpToSBV(z3.RNE(), value, z3.BitVecSort(32))
        elif is_type is Types.INT and to_type is Types.FLOAT:
            if value_is_int:
                return value
            else:
                return z3.fpSignedToFP(z3.RNE(), value, z3.Float32())
            """ INTEGER <---> FLOAT """
        elif is_type is Types.FLOAT and to_type is Types.INTEGER:
            if value_is_float:
                return value  # this happens if it is a float numeral (e.g. 3.14)
            else:
                return self.cast(self.cast(value, Types.FLOAT, Types.INT),
                                 Types.INT, Types.INTEGER)
        elif is_type is Types.INTEGER and to_type is Types.FLOAT:
            if value_is_int:
                return value
            else:
                return self.cast(self.cast(value, Types.INTEGER, Types.INT),
                                 Types.INT, Types.FLOAT)
            """ from REAL """
        elif is_type is Types.REAL and to_type is Types.INTEGER:
            if value_is_float:
                return value
            else:
                return z3.ToInt(value)
        elif is_type is Types.REAL and to_type is Types.INT:
            return self.cast(self.cast(value, Types.REAL, Types.INTEGER),
                             Types.INTEGER, Types.INT)
        elif is_type is Types.REAL and to_type is Types.FLOAT:
            """
            Rounding modes: probably should make these parameterizable!
            roundNearestTiesToEven ... RNE() = default
            roundNearestTiesToAway ... RNA()
            roundTowardPositive ...... RTP()
            roundTowardNegative ...... RTN()
            roundTowardZero .......... RTZ()
            """
            if value_is_int or value_is_float:  # int numeral
                return value
            else:
                return z3.fpRealToFP(z3.RNE(), value, z3.Float32())
            """ to REAL """
        elif is_type is Types.INT and to_type is Types.REAL:
            if value_is_int or value_is_float:  # int numeral
                return value
            else:
                return z3.ToReal(self.cast(value, Types.INT, Types.INTEGER))
        elif is_type is Types.INTEGER and to_type is Types.REAL:
            if value_is_int or value_is_float:  # int numeral
                return value
            else:
                return z3.ToReal(value)
        elif is_type is Types.FLOAT and to_type is Types.REAL:
            if value_is_int or value_is_float:
                return value  # this happens if it is a float numeral (e.g. 3.14)
            else:
                return z3.fpToReal(value)
            """ FROM BOOL conversions """
        elif is_type is Types.BOOL and to_type is Types.INT:
            return z3.If(value, z3.BitVecVal(1, 32), z3.BitVecVal(0, 32))
        elif is_type is Types.BOOL and to_type is Types.INTEGER:
            return z3.If(value, 1, 0)
        elif is_type is Types.BOOL and to_type is Types.REAL:
            return z3.If(value, 1.0, 0.0)
        elif is_type is Types.BOOL and to_type is Types.FLOAT:
            return z3.If(value, z3.FPVal(1.0, z3.Float32()),
                         z3.FPVal(0.0, z3.Float32()))
            """ TO BOOL conversions """
        elif is_type is Types.INT and to_type is Types.BOOL:
            return value == 1
        elif is_type is Types.INTEGER and to_type is Types.BOOL:
            return value == 1
        elif is_type is Types.REAL and to_type is Types.BOOL:
            return value == 1
        elif is_type is Types.FLOAT and to_type is Types.BOOL:
            return value == 1

        raise TypeError(f"Don't know how to cast from {is_type} to {to_type}!")
Ejemplo n.º 18
0
def f322i32(f: f32) -> i32:
    if utils.is_all_real(f):
        return struct.unpack('<i', struct.pack('<f', f))[0]
    return z3.fpToIEEEBV(f, z3.Float32())
Ejemplo n.º 19
0
def i322f32(i: i32) -> f32:
    if utils.is_all_real(i):
        i = int2i32(i)
        return struct.unpack('<f', struct.pack('<i', i))[0]
    return z3.fpToFP(i, z3.Float32())