Exemple #1
0
 def _convert(self, obj):
     if isinstance(obj, FSort):
         return z3.FPSort(obj.exp, obj.mantissa, ctx=self._context)
     elif isinstance(obj, RM):
         if obj == RM_RNE:
             return z3.RNE(ctx=self._context)
         elif obj == RM_RNA:
             return z3.RNA(ctx=self._context)
         elif obj == RM_RTP:
             return z3.RTP(ctx=self._context)
         elif obj == RM_RTN:
             return z3.RTN(ctx=self._context)
         elif obj == RM_RTZ:
             return z3.RTZ(ctx=self._context)
         else:
             raise BackendError("unrecognized rounding mode")
     elif obj is True:
         return z3.BoolVal(True, ctx=self._context)
     elif obj is False:
         return z3.BoolVal(False, ctx=self._context)
     elif isinstance(obj, (numbers.Number, str)):
         return obj
     elif hasattr(obj, '__module__') and obj.__module__ in ('z3', 'z3.z3'):
         return obj
     else:
         l.debug("BackendZ3 encountered unexpected type %s", type(obj))
         raise BackendError("unexpected type %s encountered in BackendZ3" %
                            type(obj))
Exemple #2
0
 def from_real(self,val):
     assert isinstance(val,str)
     if val.lower() == '+inf':
         self._mk_pinf()
     elif val.lower() == '-inf':
         self._mk_ninf()
     elif val.lower() == 'nan':
         self._mk_nan()
     else:
         self.z3_ds = z3.FPVal(val,z3.FPSort(self.ne,self.ns))
Exemple #3
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)]
Exemple #4
0
 def _convert(self, obj, result=None):
     if type(obj) is NativeBVV:
         return z3.BitVecVal(obj.value, obj.bits)
     elif isinstance(obj, FSort):
         return z3.FPSort(obj.exp, obj.mantissa)
     elif isinstance(obj, RM):
         if obj == RM_RNE:
             return z3.RNE()
         elif obj == RM_RNA:
             return z3.RNA()
         elif obj == RM_RTP:
             return z3.RTP()
         elif obj == RM_RTN:
             return z3.RTN()
         elif obj == RM_RTZ:
             return z3.RTZ()
         else:
             raise BackendError("unrecognized rounding mode")
     elif isinstance(obj, NativeFPV):
         val = str(obj.value)
         sort = self._convert(obj.sort)
         if val == 'inf':
             return z3.fpPlusInfinity(sort)
         elif val == '-inf':
             return z3.fpMinusInfinity(sort)
         elif val == '0.0':
             return z3.fpPlusZero(sort)
         elif val == '-0.0':
             return z3.fpMinusZero(sort)
         elif val == 'nan':
             return z3.fpNaN(sort)
         else:
             better_val = str(Decimal(obj.value))
             return z3.FPVal(better_val, sort)
     elif obj is True:
         return z3.BoolVal(True)
     elif obj is False:
         return z3.BoolVal(False)
     elif type(obj) in (int, long, float, str):
         return obj
     elif hasattr(obj, '__module__') and obj.__module__ == 'z3':
         return obj
     else:
         l.debug("BackendZ3 encountered unexpected type %s", type(obj))
         raise BackendError("unexpected type %s encountered in BackendZ3" %
                            type(obj))
Exemple #5
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()))
Exemple #6
0
def main():
    """Lantern demo"""

    # Initialize a PyTorch network
    # Lantern currently supports: Linear, ReLU, Hardtanh, Dropout, Identity
    net = nn.Sequential(nn.Linear(2, 5), nn.ReLU(), nn.Linear(5, 1), nn.ReLU())

    print("A PyTorch network:")
    print(net)
    print()

    # Normally, we would train this network to compute some function. However,
    # for this demo, we'll just use the initialized weights.
    print("Network parameters:")
    print(list(net.parameters()))
    print()

    # lantern.as_z3(model) returns a triple of z3 constraints, input variables,
    # and output variables that directly correspond to the behavior of the
    # given PyTorch network. By default, latnern assumes Real-sorted variables.
    constraints, in_vars, out_vars = lantern.as_z3(net)

    print("Z3 constraints, input variables, output variables (Real-sorted):")
    print(constraints)
    print(in_vars)
    print(out_vars)
    print()

    # The 'payoff' is that we can prove theorems about our network with z3.
    # Trivially, we can ask for a satisfying assignment of variables
    print("A satisfying assignment to the variables in this network:")
    z3.solve(constraints)
    print()

    # However, we can run the network "backwards"; e.g. what is an *input* that
    # causes the network to output the value 0 (if such an input exists)?
    constraints.append(out_vars[0] == 0)
    print("An assignment such that the output variable is 0:")
    z3.solve(constraints)
    print()

    # To more precisely represent the underlying computations, consider using
    # an appropriate floating-point sort; PyTorch defaults to single precision.
    # To speed up satisfiability computations, models can be 'rounded', which
    # truncates the mantissa of every PyTorch model parameter. Note that the
    # exponent part remains the same (11 bits) so that the result can be
    # returned as a Python float. Here, we truncate to 10 bits (half precision).
    rounded_net = lantern.round_model(net, 10)
    constraints, in_vars, out_vars = lantern.as_z3(rounded_net,
                                                   sort=z3.FPSort(11, 10))
    print("Z3 constraints, input, output (FPSort(11, 10)):")
    print(constraints)
    print(in_vars)
    print(out_vars)
    print()

    # We add the constraint that the output must be 0.0, and solve using a
    # solver for FloatingPoint theory.
    print("An assignment such that the output variable is 0.0:")
    constraints.append(out_vars[0] == 0.0)
    z3.solve_using(z3.SolverFor("QF_FP"), *constraints)
    print()

    # Note that the constraints, and variables are all 'ordinary' Z3Py objects.
    print("Happy hacking!")
def generateFiniteLenFloats(name, count, tp, ctx):
	tp = np.dtype(tp)
	fpSort = floatTypes[tp.itemsize]
	if isinstance(fpSort, tuple):
		fpSort = z3.FPSort(*fpSort)
	return [z3.FP(name + "__" + str(i), fpSort) for i in range(count)]
import z3
from z3 import If, Or, Extract, Concat, BitVecVal, FPVal, BitVecSort, RNE, RTZ, fpSignedToFP, fpToSBV, fpFPToFP, fpIsNaN, K, Select, Store, BV2Int

import subprocess
import sys
import traceback
import itertools
import json

Float = z3.FPSort(8, 24)
Double = z3.FPSort(11, 53)

JAVA_HOME = "/usr/lib/jvm/java-8-openjdk-amd64"
JAVA = "{}/bin/java".format(JAVA_HOME)
PATH_DATA_OUTPUT = "pathConstraints.txt"

class StackEntry:
    def __init__(self, branchId, done, isTrue):
        self.branchId = branchId
        self.done = done
        self.isTrue = isTrue

    def __repr__(self):
        return '({}, {}, {})'.format(self.branchId, self.done, self.isTrue)

class Variable:
    def __init__(self, varType, varName):
        self.varType = varType
        self.varName = varName

class Assignment:
Exemple #9
0
    def get_pred(self):
        if self.is_ninf():
            return copy.deepcopy(self)
        if self.is_pzero():
            return Float('-0',ne=self.ne,ns=self.ns).get_pred()
        bv_str = self.get_bv_str()
        #print(bv_str)
        sign = bv_str[0]
        if sign == '0':
            succ = int(bv_str[1:],2) - 1
            return Float(val=z3.simplify(z3.fpBVToFP(z3.Int2BV(z3.IntVal(succ),num_bits = self.ns + self.ne),z3.FPSort(self.ne,self.ns))),ne=self.ne, ns=self.ns)

        else:
            succ = int(bv_str[1:],2) + 1
            return -Float(val=z3.simplify(z3.fpBVToFP(z3.Int2BV(z3.IntVal(succ),num_bits = self.ns + self.ne),z3.FPSort(self.ne,self.ns))),ne=self.ne, ns=self.ns)
Exemple #10
0
 def _mk_nan(self):
     bv = '0' + ('1' * self.ne) + ('1' * (self.ns -1))
     val = int(bv,2)
     self.__dict__ = copy.deepcopy(Float(val=z3.simplify(z3.fpBVToFP(z3.Int2BV(z3.IntVal(val),num_bits = self.ns + self.ne),z3.FPSort(self.ne,self.ns))),ne=self.ne, ns=self.ns).__dict__)
Exemple #11
0
 def _mk_pzero(self):
     self.__dict__ = copy.deepcopy(Float(val=z3.simplify(z3.fpBVToFP(z3.Int2BV(z3.IntVal(0),num_bits = self.ns + self.ne),z3.FPSort(self.ne,self.ns))),ne=self.ne, ns=self.ns).__dict__)