def tuple_array_create(self, arr_type, fields, const_array, domain): # Two things this can be: a constant array where each element has the # provided value, or just an array of values. As it happens, this is # trivial to implement in Z3. arr_sort = self.convert_sort(arr_type) if const_array: ast = z3.K(arr_sort.dom_sort.sort, fields[0].ast) arr_ast = Z3ast(ast, self, arr_sort) else: # Generate a fresh array arr_name = "fresh_tuple_array_create_{}".format(self.fresh_arr_idx) self.fresh_arr_idx += 1 arr = z3.Const(arr_name, arr_sort.sort) arr_ast = Z3ast(arr, self, arr_sort) # Save initial ast... it's not referred to anywhere, and passing # it into update method won't keep it alive. self.store_ast(arr_ast) # Store at increasing indexes, the values from fields. Alas, there # isn't a python utility for easy constant int creation like C++. for x in range(len(fields)): intval = esbmc.BigInt(x) dom_type = esbmc.type.unsignedbv.make( arr_sort.dom_sort.data_width) intexpr = esbmc.expr.constant_int.make(dom_type, intval) arr_ast = arr_ast.update(self, fields[x], x, intexpr) return arr_ast
def createConstantArray(awidth, dwidth, mem_values): asize = z3.BitVecSort(awidth) arr = z3.K(asize, z3.BitVecVal(mem_values[-1], dwidth)) for [a, d] in mem_values[:-1]: az3 = z3.BitVecVal(a, awidth) dz3 = z3.BitVecVal(d, dwidth) arr = z3.Update(arr, az3, dz3) return arr
def __init__(self, domain: int, value_range: int, value: int): """Initializes an array with a default value. :param domain: The domain for the array (10 -> all the values that a bv of size 10 could take) :param value_range: The range for the values in the array (10 -> all the values that a bv of size 10 could take) :param value: The default value to use for this array """ self.domain = z3.BitVecSort(domain) self.value = z3.BitVecVal(value, value_range) self.raw = z3.K(self.domain, self.value)
def convert_array_of(self, val, domain_width): # Z3 directly supports initialized constant arrays dom = z3.BitVecSort(domain_width, self.ctx) ast = z3.K(dom, val.ast) result_sort_ast = ast.sort() z3_result_sort = Z3sort(result_sort_ast, esbmc.solve.smt_sort_kind.array, val.sort.data_width, domain_width) self.store_sort(z3_result_sort) return Z3ast(ast, self, z3_result_sort)
def mk_eqs_from_model(m, consts, model_completion=False): eqs = [] for const in consts: # treat arrays specially due to the else_value sort = const.sort() if isinstance(sort, z3.ArraySortRef): val_interp = m[const] if (val_interp is not None) and isinstance(val_interp, z3.FuncInterp): idx_sort = sort.domain() val_sort = sort.range() val = z3.K(val_sort, val_interp.else_value()) for i in range(val_interp.num_entries()): entry = val_interp.entry(i) val = z3.Store(val, entry.arg_value(0), entry.value()) else: val = m.eval(const, model_completion=model_completion) else: val = m.eval(const, model_completion=model_completion) eqs.append(const == val) return eqs
def f2(): a, b, c, d = z3.BitVecs('a b c d', 3) # 4 bitvectors variable tuple = z3.Datatype('tuple') # new data type 'tuple' tuple.declare( 'tuple', ('f1', z3.BitVecSort(3)), ('f2', z3.BitVecSort(3))) # f1, f2 are for accessing element in tuples tuple = tuple.create() tuple1 = tuple.tuple(a, b) # tuple1 -> (a, b) tuple2 = tuple.tuple(b, c) # tuple2 -> (b, c) tuple1_f2 = tuple.f2(tuple1) # a #tuple1_f2 = tuple.f2(tuple1) # b tuple2_f1 = tuple.f1(tuple2) # c print(tuple1_f2, tuple2_f1) if (tuple1_f2 == tuple2_f1): print("hi") arr0 = z3.K(tuple, False) # arr0 -> arr0[tuple] = false arr1 = z3.Store(arr0, tuple1, True) # arr1 -> arr0[tuple1] = true arr2 = z3.Store(arr1, tuple2, True) # arr -> arr0[tuple2] = true print(arr0) print(arr1) print(arr2) #print(arr1[tuple1]) #print(arr2[tuple2]) #print(arr0) #print(arr1) #print(arr2) s = z3.Solver() s.add(tuple1_f1 == tuple2_f2) # a = c s.add(tuple1_f1 == tuple1_f2) # a = b
def get_zero_array(index_size=VECTOR_LEN, value_size=VECTOR_LEN): return z3.K(z3.BitVecSort(index_size), z3.BitVecVal(0, value_size))
import z3 from z3.z3 import _to_expr_ref import collections MemorySort = z3.ArraySort(z3.BitVecSort(256), z3.BitVecSort(8)) StorageSort = z3.ArraySort(z3.BitVecSort(256), z3.BitVecSort(256)) MemoryEmpty = z3.K(z3.BitVecSort(256), z3.BitVecVal(0, 8)) StorageEmpty = z3.K(z3.BitVecSort(256), z3.BitVecVal(0, 256)) from . import mem ContractState = collections.namedtuple('ContractState', 'code storage balance nonce') ContractState.__new__.__defaults__ = (None, None, None) def cached(fn): def wrapper(self, *args): if fn.__name__ not in self._cache: self._cache[fn.__name__] = fn(self, *args) return self._cache[fn.__name__] return wrapper def storage_empty_policy(name, addr): return StorageEmpty def storage_any_policy(name, addr):