def test_z3_to_array_doc(self):
        s = z3.BitVecSort(8)
        s2 = z3.BitVecSort(2)

        def bv(x):
            return z3.BitVecVal(x, s)

        def bv2(x):
            return z3.BitVecVal(x, s2)

        x = z3.Var(0, s)
        y = z3.Var(1, s)
        types = [primitives.TYPES['int4']] * 2
        e1 = z3.Extract(3, 2, x) == bv2(3)
        e2 = z3.And(
            z3.Extract(3, 2, x) == bv2(3),
            z3.Extract(7, 6, x) == bv2(2))
        e3 = z3.And(
            z3.Extract(3, 2, x) == bv2(3),
            z3.Extract(7, 6, x) == bv2(2), y == bv(4))
        e4 = z3.And(
            z3.Extract(5, 4, x) == bv2(1),
            z3.Not(
                z3.And(
                    z3.Extract(3, 2, x) == bv2(3),
                    z3.Extract(7, 6, x) == bv2(2), y == bv(4))))
        e5 = z3.And(
            True, z3.Not(z3.Extract(5, 4, x) == bv2(1)),
            z3.Not(
                z3.And(
                    z3.Extract(3, 2, x) == bv2(3),
                    z3.Extract(7, 6, x) == bv2(2), y == bv(4))))

        r1 = [z3r.Cube({0: z3r.Masked(0xc, 0xc)}, 1)]
        r2 = [z3r.Cube({0: z3r.Masked(0x8c, 0xcc)}, 1)]
        r3 = [z3r.Cube({0: z3r.Masked(0x8c, 0xcc), 1: 4}, 1)]
        r4 = [
            z3r.Doc(z3r.Cube({0: z3r.Masked(0x10, 0x30)}, 1),
                    [z3r.Cube({
                        0: z3r.Masked(0x8c, 0xcc),
                        1: 4
                    }, 1)])
        ]
        r5 = [
            z3r.Doc(z3r.Cube({}, 1), [
                z3r.Cube({0: z3r.Masked(0x10, 0x30)}, 1),
                z3r.Cube({
                    0: z3r.Masked(0x8c, 0xcc),
                    1: 4
                }, 1)
            ])
        ]
        for (r, e) in [(r1, e1), (r2, e2), (r3, e3), (r4, e4), (r5, e5)]:
            self.assertEqual(r, z3r.z3_to_array(e, types))
    def test_z3_to_array(self):
        s = z3.BitVecSort(4)

        def bv(x):
            return z3.BitVecVal(x, s)

        x = z3.Var(0, s)
        y = z3.Var(1, s)
        z = z3.Var(2, s)
        types = [primitives.TYPES['int4']] * 3

        def project(grid):
            return [{k: x for k, x in row.faces.items()} for row in grid]

        e0 = x == bv(3)
        e1 = z3.And(x == bv(3), y == bv(2), z == bv(1))
        e2 = z3.Or(e1, z3.And(x == bv(13), y == bv(12), z == bv(11)))
        e3 = z3.Or(x == bv(6), y == bv(5), z == bv(4))
        self.assertEqual([{0: 3}], project(z3r.z3_to_array(e0, types)))
        self.assertEqual([{
            0: 3,
            1: 2,
            2: 1
        }], project(z3r.z3_to_array(e1, types)))
        self.assertEqual([{
            0: 3,
            1: 2,
            2: 1
        }, {
            0: 13,
            1: 12,
            2: 11
        }], project(z3r.z3_to_array(e2, types)))
        self.assertEqual([{
            0: 6
        }, {
            1: 5
        }, {
            2: 4
        }], project(z3r.z3_to_array(e3, types)))
        self.assertIs(True,
                      z3r.z3_to_array(z3.simplify(z3.And(True, True)), z3r))
        self.assertIs(False,
                      z3r.z3_to_array(z3.simplify(z3.And(True, False)), z3r))
示例#3
0
def fp_add_cover(fp, pred, lemma, level=-1):
    # no trivial lemmas
    if z3.is_true(lemma): return

    assert (z3.is_app(pred))
    sub = []
    for i in range(0, pred.num_args()):
        arg = pred.arg(i)
        sub.append((arg, z3.Var(i, arg.decl().range())))

    tlemma = z3.substitute(lemma, sub)
    if verbose:
        print "Lemma for ", pred.decl(), ": ", tlemma
    fp.add_cover(level, pred.decl(), tlemma)
示例#4
0
def piecewise(fp):
    # program CFG
    program = Program(fp)
    parameters = program.parameters[1:]
    variables = [
        z3.Var(i, sort)
        for (i, sort) in zip(list(range(len(parameters))), parameters)
    ]
    arguments = program.arguments[1:]

    # loops identification
    loops = program.loops_identification()
    # proving termination...
    rank = dict()
    for node in loops:
        # ...for all loops involving each node
        if loops[node]:
            if debug: print('\nloop:', loops[node], '\n')
            loop = set([n for path in loops[node] for n in path])  # loop nodes
            entry = set([(n, node)
                         for n in program.prev[node] - loop])  # entry edges
            edges = set([
                n for path in loops[node] for n in zip(path[:-1], path[1:])
            ])  # loop edges
            # exit = set([(node,n)
            #     for n in program.next[node] - loop])  # exit edges
            exit = set([(i, n) for i in loop
                        for n in program.next[i] - loop])  # exit edges

            bits = list()  # (potentially) terminating bits
            pieces = [[z3.IntSort().cast(0)]]  # candidate ranking functions
            bit = program.get_bit(entry, node, 'max', pieces, edges, exit)
            while bit:
                bit[node][0][-len(pieces)] -= bit[node][-1][-len(pieces)]
                bits.append(bit[node][0][:len(bit[node][0]) - len(pieces) + 1])
                rankings = ranking(bits, variables)
                for i in range(len(bits)):
                    rankings = ranking(bits[:i + 1], variables)
                if not rankings:
                    if debug: print()
                    del bits[:-1]
                    rankings = ranking(bits, variables)
                if debug:
                    print(
                        'bit:',
                        list(
                            zip(arguments + ['-' for component in pieces],
                                bits[-1])))
                pieces[0].extend(rankings)
                if debug:
                    print('pieces:', [[
                        z3.substitute_vars(x, *arguments) for x in component
                    ] for component in pieces])
                bit = program.get_bit(entry, node, 'max', pieces, edges, exit)
            # check candidate ranking functions
            point = program.termination(entry, node, 'max', pieces, edges,
                                        exit)
            pieces = [[z3.substitute_vars(x, *arguments) for x in component]
                      for component in pieces]
            if point:
                rank[node] = (False, point)
                if debug: print('\nnon-terminating execution:', point)
                if debug: print('(partial) loop ranking functions:', pieces)
            else:
                rank[node] = (True, pieces)
                if debug: print('\nloop ranking functions:', pieces)
    if debug: print('\nranking functions:', rank)
    if all([r[0] for r in list(rank.values())]):
        stat("Result", "TRUE")
    else:
        stat("Result", "FALSE")