Esempio n. 1
0
def get_models(F, M):
    result = []
    s = z3.Solver()
    s.add(F)

    print(s)

    while len(result) < M and s.check() == z3.sat:
        m = s.model()
        result.append(m)
        # Create a new constraint the blocks the current model
        block = []
        for d in m:

            # XXX: hack. Should not be possible to change f without R,C changes...
            if str(d).startswith('f_'):
                continue

            # d is a declaration
            if d.arity() > 0:
                raise z3.Z3Exception("uninterpreted functions are not supported")
            # create a constant from declaration
            c = d()
            if z3.is_array(c) or c.sort().kind() == z3.Z3_UNINTERPRETED_SORT:
                raise z3.Z3Exception("arrays and uninterpreted sorts are not supported")
            block.append(c != m[d])
        s.add(z3.Or(block))
    return result
Esempio n. 2
0
def get_models(F, M):
    result = []
    s = z3.Solver()
    s.add(F)

    print(s)

    while len(result) < M and s.check() == z3.sat:
        m = s.model()
        result.append(m)
        # Create a new constraint the blocks the current model
        block = []
        for d in m:

            # XXX: hack. Should not be possible to change f without R,C changes...
            if str(d).startswith('f_'):
                continue

            # d is a declaration
            if d.arity() > 0:
                raise z3.Z3Exception(
                    "uninterpreted functions are not supported")
            # create a constant from declaration
            c = d()
            if z3.is_array(c) or c.sort().kind() == z3.Z3_UNINTERPRETED_SORT:
                raise z3.Z3Exception(
                    "arrays and uninterpreted sorts are not supported")
            block.append(c != m[d])
        s.add(z3.Or(block))
    return result
def main():
    x = z3.BitVec('x', 8)
    y = z3.BitVec('y', 8)

    s = z3.Solver()
    s.add(((x << 2) + (3 * y)) == z3.BitVecVal(0x41, 8))
    s.add(((x >> 4) - (y << 2)) > z3.BitVecVal(0x10, 8))
    s.add(((x * 5) - (y * 2)) > z3.BitVecVal(0x42, 8))
    s.add(x != z3.BitVecVal(0, 8))
    s.add(y != z3.BitVecVal(0, 8))

    while s.check() == z3.sat:
        # Get a model satisfying the rules.
        model = s.model()

        # Do something with the model
        print model

        # Prevent the same model from showing up again.
        block = []
        for instance in model:
            if instance.arity() > 0:
                raise z3.Z3Exception(
                    "uninterpreted functions are not supported")
            constant = instance()
            if z3.is_array(constant) or constant.sort().kind(
            ) == z3.Z3_UNINTERPRETED_SORT:
                raise Z3Exception(
                    "arrays and uninterpreted sorts are not supported")
            block.append(constant == model[instance])
        inverted_block = z3.Not(z3.And(block))
        s.add(inverted_block)
Esempio n. 4
0
def string_indexOf(x, args):
    if z3.is_array(x):
        if str(x.decl()) not in ARRAY_LENGTHS:
            raise Exception('We do not know how large the underlying array should be thus we cannot include on it')
        helper_int = z3.Int('__ignore_arr_indexOf_helper_' + randomString())
        search_string = createZ3ExpressionFromConstraint(args[0], {})
        all = []
        presentImplications = []
        for i in range(ARRAY_LENGTHS[str(x.decl())]):
            conditional = z3.Select(x, i) == search_string
            all.append(conditional)
            true_imply = z3.Implies(conditional, helper_int <= i)
            false_imply = z3.Implies(z3.Not(conditional), helper_int > i)
            presentImplications.append(true_imply)
            presentImplications.append(false_imply)
        all = z3.Or(all)
        GLOBAL_CONSTRAINTS.append(z3.And(z3.Implies(all, z3.And(presentImplications)), z3.Implies(all, helper_int >= 0),
                                         z3.Implies(z3.mk_not(all), helper_int == -1)))
        return helper_int

    else:
        if len(args) > 1:
            return z3.IndexOf(x, createZ3ExpressionFromConstraint(args[0], {}),
                              createZ3ExpressionFromConstraint(args[1], {}))
        else:
            return z3.IndexOf(x, createZ3ExpressionFromConstraint(args[0], {}), 0)
Esempio n. 5
0
def resolveOpsOnParent(op_obj, types):
    # this is parent or nothing
    if len(op_obj['old_ops']) < 1:
        return None
    val = createZ3ExpressionFromConstraint({'identifier': op_obj['old_identifier'], 'ops': op_obj['old_ops']}, types)

    if val is None or (val.decl().kind() == z3.Z3_OP_UNINTERPRETED and not z3.is_array(val)):
        # this is the case when the parent elems have no ops on them
        return None
    if z3.is_bool(val) and len(val.children()) and val.children()[0].decl().kind() == z3.Z3_OP_UNINTERPRETED:
        return None
    val = transformNonBooleanLazyEvaluations(val)
    return val
Esempio n. 6
0
def createZ3ForBool(var):
    if z3.is_int(var):
        return var != z3.IntVal(0)
    elif z3.is_string(var):
        return var != z3.StringVal('')
    elif z3.is_array(var):
        return z3.BoolVal(True)
    elif z3.is_bool(var):
        return var
    elif var is None:
        # this should be the case when we have a JSON value that is just inside a conditional etc
        return None
    elif z3.is_seq(var):
        # not string but still something ref-like we only found cases where this was string comparisons using <, >, etc.
        return var
    else:
        raise Exception('unhandled type in uninterpreted if')
Esempio n. 7
0
def includes(x, args):
    if z3.is_string(x):
        return string_indexOf(x, args) > -1
    elif z3.is_array(x):
        if str(x.decl()) not in ARRAY_LENGTHS:
            raise Exception('We do not know how large the underlying array should be thus we cannot include on it')
        cc = None
        searched = createZ3ExpressionFromConstraint(args[0], {})
        for i in range(ARRAY_LENGTHS[str(x.decl())]):
            c = z3.Select(x, i) == searched
            if cc is None:
                cc = c
            else:
                cc = z3.Or(cc, c)
        return cc
    else:
        raise Exception('What else should we expect to be called includes on instead of strings and arrays')
Esempio n. 8
0
 def get_models(self, limit=10):
     s = z3.Solver()
     s.add(self.constraints)
     i = 0
     while i < limit and s.check() == z3.sat:
         m = s.model()
         yield i, m, s.statistics()
         i += 1
         block = []
         for d in m:
             # d is a declaration     # ignore room differences in schedules
             if d.arity() <= 0 and not d.name().endswith(
                     'room') and not d.name().endswith('lab'):
                 # create a constant from declaration
                 c = d()
                 if not z3.is_array(
                         c) and c.sort().kind() != z3.Z3_UNINTERPRETED_SORT:
                     block.append(c == m[d])
         s.add(z3.simplify(z3.Not(z3.And(*block))))
def get_models(F, M):
    result = []
    s = z3.Solver()
    s.add(F)
    while len(result) < M and s.check() == z3.sat:
        m = s.model()
        result.append(m)
        # Create a new application the blocks the current model
        block = []
        for d in m:
            # d is a declaration
            if d.arity() > 0:
                raise z3.Z3Exception("uninterpreted functions are not supported")
            # create a constant from declaration
            c = d()
            if z3.is_array(c) or c.sort().kind() == z3.Z3_UNINTERPRETED_SORT:
                raise z3.Z3Exception("arrays and uninterpreted sorts are not supported")
            block.append(c != m[d])
        s.add(z3.Or(block))
    return(result)
Esempio n. 10
0
def get_models(F, M=10):
    s = z3.Solver()
    s.add(F)
    i = 0
    while i < M and s.check() == z3.sat:
        m = s.model()
        yield i, m
        i += 1
        block = []
        for d in m:
            # d is a declaration     # ignore room differences in schedules
            if d.arity() <= 0 and not d.name().endswith('room'):
                # create a constant from declaration
                c = d()
                if not z3.is_array(
                        c) and c.sort().kind() != z3.Z3_UNINTERPRETED_SORT:
                    block.append(c == m[d])
        s.add(z3.simplify(z3.Not(z3.And(*block))))
    else:
        # failed or limit -- print stats of last check
        print(s.statistics())
Esempio n. 11
0
def get_models(F):
    result = []
    s = Solver()
    s.add(F)
    while True:
        if s.check() == sat:
            m = s.model()
            result.append(m)
            # Create a new constraint the blocks the current model
            block = []
            for d in m:
                # d is a declaration
                if d.arity() > 0:
                    raise Z3Exception(
                        "uninterpreted functions are not suppported")
                # create a constant from declaration
                c = d()
                if is_array(c) or c.sort().kind() == Z3_UNINTERPRETED_SORT:
                    raise Z3Exception(
                        "arrays and uninterpreted sorts are not supported")
                block.append(c != m[d])
            s.add(Or(block))
        else:
            return result
Esempio n. 12
0
def createZ3ExpressionFromConstraint(constraint, types, emitParentConstraint=True):
    if type(constraint) != dict:
        if type(constraint) == str:
            return z3.StringVal(constraint)
        if type(constraint) == int:
            return z3.IntVal(constraint)
        if type(constraint) == bool:
            return z3.BoolVal(constraint)
        if constraint is None:
            return None
        raise Exception('Dealing with non-int non-string basic values, aborting!', constraint)
    if 'type' not in constraint:
        if 'isRealValue' in constraint:
            if 'value' in constraint:
                var = getZ3ValFromJSVal(constraint['value'])
            elif 'val' in constraint:
                var = getZ3ValFromJSVal(constraint['val'])
            else:
                raise Exception('Should not encounter realValue without reference to the real value...')
        else:
            if 'identifier' in constraint:
                var = getTypedZ3ValFromIdentifier(constraint['identifier'], types)
            else:
                # probably the empty object when we have something || {}
                return None

        for op in constraint['ops']:
            if 'val' not in op:
                op['val'] = ''
            if op['type'] == 'ops_on_parent_element':
                val = resolveOpsOnParent(op, types)
                if z3.is_array(val):
                    accesed = constraint['identifier'].split('.')[-1]
                    if accesed == 'length':
                        raise NotSupportedException(
                            'z3 cannot use the length of arrays due to their representation as functions')
                    if int(accesed) < 0 and str(val.decl()) in ARRAY_LENGTHS:
                        var = z3.Select(val, ARRAY_LENGTHS[str(val.decl())] + int(accesed))
                    else:
                        var = z3.Select(val, int(accesed))
                elif val is not None:
                    key = str(val)
                    if key not in identifier_substitutions:
                        identifier_substitutions[key] = '__substitute_values_' + randomString()
                    identifier = identifier_substitutions[key]
                    GLOBAL_CONSTRAINTS.append(val == z3.StringVal(identifier))
                    accesed = constraint['identifier'].split('.')[-1]
                    if accesed == 'length':
                        var = z3.Length(z3.String(identifier))
                    else:
                        var = z3.String(identifier + '.' + accesed)

                #     GLOBAL_CONSTRAINTS.append(var == val)
            elif op['type'] == 'member_function':
                var = transformNonBooleanLazyEvaluations(var)
                if op['function_name'] in StringFunctions:
                    var = StringFunctions[op['function_name']](var, op['args'])
                elif op['function_name'] in ArrayFunctions:
                    var = ArrayFunctions[op['function_name']](var, op['args'])
                else:
                    if op['function_name'] in ['call', 'apply', 'bind']:
                        raise NotSupportedException('We do not support function calls over function pointer')
                    raise Exception('String function not supported! ' + op['function_name'])
            elif op['type'] == 'Binary':
                other_var = createZ3ExpressionFromConstraint(op['val'], types)
                if other_var is None:
                    # this is the case when we compare something to null
                    if op['op'] == '===' or op['op'] == '==':
                        var = createZ3ForBool(var)
                        var = z3.Not(var)
                    continue
                var, other_var = coerceTypesIfPossible(var, other_var)
                changed = checkForTypeEqualToString(var, other_var, op)
                if changed is not None:
                    var = changed
                elif op['side'] == 'left':
                    var = BinaryFunctions[op['op']](var, other_var)
                elif op['side'] == 'right':
                    var = BinaryFunctions[op['op']](other_var, var)
                else:
                    var = BinaryFunctions[op['op']](var, other_var)
            elif op['type'] == 'Unary':
                var = UnaryFunctions[op['op']](var)
            elif op['type'] == 'iterator':
                if z3.is_array(var):
                    var = z3.Select(var, op['accessed_elem'])
                else:
                    raise Exception('This should always be an array', var, infered_types)
            elif op['type'] == 'external_function':
                if op['function_name'] == 'JSON.parse':
                    infered_types[constraint['identifier']] = 'JSON'
                    var = z3.String(constraint['identifier'])
                else:
                    logging.debug('Arbitrary external functions not yet support ' + op['function_name'])
            elif op['type'] == 'Logical':
                if op['side'] == 'left' or op['side'] == 'both':
                    l_c = createZ3ForBool(var)
                    r_c = createZ3ForBool(createZ3ExpressionFromConstraint(op['val'], types))
                else:
                    l_c = createZ3ForBool(createZ3ExpressionFromConstraint(op['val'], types))
                    r_c = createZ3ForBool(var)
                if l_c is None or r_c is None:
                    if l_c is None:
                        var = r_c
                    if r_c is None:
                        var = l_c
                    continue
                if op['op'] == '&&':
                    var = z3.And(l_c, r_c)
                else:
                    var = z3.Or(l_c, r_c)
            else:
                logging.debug('Not supported type ' + op['type'])
        return var
    elif constraint['type'] == 'Logical':
        l_c = createZ3ForBool(createZ3ExpressionFromConstraint(constraint['l_val'], types))
        r_c = createZ3ForBool(createZ3ExpressionFromConstraint(constraint['r_val'], types))
        if l_c is None or r_c is None:
            return l_c or r_c
        if constraint['op'] == '&&':
            return z3.And(l_c, r_c)
        else:
            return z3.Or(l_c, r_c)
    elif constraint['type'] == 'Binary':
        return BinaryFunctions[constraint['op']](createZ3ExpressionFromConstraint(constraint['l_val'], types),
                                                 createZ3ExpressionFromConstraint(constraint['r_val'], types))
    elif constraint['type'] == 'Unary':
        return UnaryFunctions[constraint['op']](createZ3ExpressionFromConstraint(constraint['val'], types))
    else:
        raise Exception('Unexpected constraint type')