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))
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)
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")