Beispiel #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)))
Beispiel #2
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)
Beispiel #3
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')
Beispiel #4
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
Beispiel #5
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
Beispiel #6
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)))
Beispiel #7
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)]
Beispiel #8
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)
Beispiel #9
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)
Beispiel #10
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
Beispiel #11
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
Beispiel #12
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
Beispiel #13
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()))
    def __add__(self, other):
        if isinstance(other, SymbolicSeq):
            return SymbolicSeq(self.z3var + other.z3var)
        else:
            return SymbolicSeq(self.z3var + other)

    def __eq__(self, other):
        if isinstance(other, SymbolicSeq):
            return z3.Eq(self.z3var, other.z3var)
        else:
            return NotImplemented


_TYPE_TO_SMT_SORT = {
    int: z3.IntSort(),
    float: z3.Float64(),
    bool: z3.BoolSort(),
    str: z3.StringSort(),
}


def type_to_smt_sort(t: Type):
    if t in _TYPE_TO_SMT_SORT:
        return _TYPE_TO_SMT_SORT[t]
    origin = getattr(t, '__origin__', None)
    if origin in (List, Sequence, Container):
        item_type = t.__args__[0]
        return z3.SeqSort(type_to_smt_sort(item_type))
    elif origin in (Dict, Mapping):
        key_type, val_type = t.__args__
        return z3.ArraySort(type_to_smt_sort(key_type),
Beispiel #15
0
def f642i64(f: f64) -> i64:
    if utils.is_all_real(f):
        return struct.unpack('<q', struct.pack('<d', f))[0]
    return z3.fpToIEEEBV(f, z3.Float64())
Beispiel #16
0
def i642f64(i: i64) -> f64:
    if utils.is_all_real(i):
        i = int2i64(i)
        return struct.unpack('<i', struct.pack('<q', i))[0]
    return z3.fpToFP(i, z3.Float64())
Beispiel #17
0
from .esilclasses import *
import z3

SIZE = 64
FSIZE = z3.Float64()

ONE = z3.BitVecVal(1, SIZE)
ZERO = z3.BitVecVal(0, SIZE)
NEGONE = z3.BitVecVal(-1, SIZE)

FONE = z3.FPVal(1.0, FSIZE)
FZERO = z3.FPVal(0.0, FSIZE)
FNEGONE = z3.FPVal(-1.0, FSIZE)

INT = 1
FLOAT = 2

FPM = z3.RTZ()


def pop_values(stack,
               state,
               num: int = 1,
               signext=False) -> List[z3.BitVecRef]:
    size = state.esil["size"]
    val_type = state.esil["type"]
    return [
        get_value(stack.pop(), state, signext, size, val_type)
        for i in range(num)
    ]