def _populateLoadBalancerConstraints(self): self.hash_function = z3.Function( 'load_balancer_hash_%s' % (self.balancer), z3.IntSort(), z3.IntSort(), z3.IntSort()) p0 = z3.Const('_load_balancer_p0_%s' % (self.balancer), self.ctx.packet) p1 = z3.Const('_load_balancer_p1_%s' % (self.balancer), self.ctx.packet) n0 = z3.Const('_load_balancer_n0_%s' % (self.balancer), self.ctx.node) n1 = z3.Const('_load_balancer_n1_%s' % (self.balancer), self.ctx.node) n2 = z3.Const('_load_balancer_n2_%s' % (self.balancer), self.ctx.node) hash_same = [self.ctx.packet.src(p0) == self.ctx.packet.src(p1), \ self.ctx.packet.dest(p0) == self.ctx.packet.dest(p1), \ self.hash_function(self.ctx.src_port(p0), self.ctx.dest_port(p0)) == \ self.hash_function(self.ctx.src_port(p1), self.ctx.dest_port(p1)), \ self.ctx.send(self.balancer, n0, p0), \ self.ctx.send(self.balancer, n1, p1) ] self.constraints.append(z3.ForAll([n0, p0, n1, p1], \ z3.Implies(z3.And(hash_same), \ n0 == n1))) self.constraints.append(z3.ForAll([n0, p0], \ z3.Implies(\ self.ctx.send(self.balancer, n0, p0), \ z3.And( \ z3.Exists([n1], \ z3.And(self.ctx.recv(n1, self.balancer, p0), \ n1 != n0)), \ z3.Not(z3.Exists([n2], \ z3.And(n2 != n0, \ self.ctx.send(self.balancer, n2, p0)))), \ self.ctx.etime(self.balancer, p0, self.ctx.send_event) > \ self.ctx.etime(self.balancer, p0, self.ctx.recv_event)))))
def cvc4_compliant_formula_sexpr(formula): # Replace z3's select with cvc4's member and z3's store with cvc4's insert # Order of arguments is reverse for member and insert member = z3.Function('member', z3.IntSort(), z3.SetSort(z3.IntSort()), z3.BoolSort()) insert = z3.Function('insert', z3.IntSort(), z3.SetSort(z3.IntSort()), z3.SetSort(z3.IntSort())) cond_mem = lambda expr: z3.is_select(expr) cond_ins = lambda expr: z3.is_store(expr) op_mem = lambda expr: member(expr.arg(1), expr.arg(0)) op_ins = lambda expr: insert(expr.arg(1), expr.arg(0)) trans_mem = transform_expression(formula, [(cond_mem, op_mem)]) trans_ins = transform_expression(trans_mem, [(cond_ins, op_ins)]) formula_sexpr = trans_ins.sexpr() # Replace occurrences of string corresponding to the emptyset in z3 with the one in cvc4 z3_emptyset_str = '((as const (Array Int Bool)) false)' cvc4_emptyset_str = '(as emptyset (Set Int) )' z3_emptyset_str_new = 'empIntSet' if options.synthesis_solver == options.minisy: new_formula_sexpr = formula_sexpr.replace(z3_emptyset_str, z3_emptyset_str_new) else: new_formula_sexpr = formula_sexpr.replace(z3_emptyset_str, cvc4_emptyset_str) return new_formula_sexpr
def _addConstraints(self, solver): solver.add(self.constraints) p = z3.Const('__ips_acl_Packet_%s' % (self.ips), self.ctx.packet) addr_a = z3.Const('__ips_acl_cache_a_%s' % (self.ips), self.ctx.address) port_a = z3.Const('__ips_acl_port_a_%s' % (self.ips), z3.IntSort()) addr_b = z3.Const('__ips_acl_cache_b_%s' % (self.ips), self.ctx.address) port_b = z3.Const('__ips_acl_port_b_%s' % (self.ips), z3.IntSort()) aclConstraints = map(lambda (a, b): z3.And(self.ctx.packet.src(p) == a, \ self.ctx.packet.dest(p) == b), self.acls) eh = z3.Const('__ips_acl_node_%s' % (self.ips), self.ctx.node) # Constraints for what holes are punched # \forall a, b cached(a, b) \iff \exists e, p send(f, e, p) \land # p.src == a \land p.dest == b \land ctime(a, b) = etime(ips, p, R) \land # neg(ACL(p)) if len(aclConstraints) > 0: solver.add(z3.ForAll([addr_a, port_a, addr_b, port_b], self.cached(addr_a, port_a, addr_b, port_b) ==\ z3.Exists([eh, p], \ z3.And(self.ctx.recv(eh, self.ips, p), \ z3.And(self.ctx.packet.src (p) == addr_a, self.ctx.packet.dest(p) == addr_b, \ self.ctx.src_port (p) == port_a, self.ctx.dest_port (p) == port_b, \ self.ctime (addr_a, port_a, addr_b, port_b) == self.ctx.etime(self.ips, p, self.ctx.recv_event), \ z3.Not(z3.Or(aclConstraints))))))) else: solver.add(z3.ForAll([addr_a, port_a, addr_b, port_b], self.cached(addr_a, port_a, addr_b, port_b) ==\ z3.Exists([eh, p], \ z3.And(self.ctx.recv(eh, self.ips, p), \ z3.And(self.ctx.packet.src (p) == addr_a, self.ctx.packet.dest(p) == addr_b, \ self.ctx.src_port (p) == port_a, self.ctx.dest_port (p) == port_b, \ self.ctime (addr_a, port_a, addr_b, port_b) == self.ctx.etime(self.ips, p, self.ctx.recv_event))))))
def translate_type(self, ty): if ty == TINT: return z3.IntSort() if ty == TBOOL: return z3.BoolSort() if isinstance(ty, TARR): return z3.ArraySort(z3.IntSort(), self.translate_type(ty.ty))
def expr_to_z3(expr, typeEnv): if isinstance(expr, ast.AstNumber): return IntVal(expr.num) elif isinstance(expr, ast.AstId): return typeEnv[expr.name](expr.name) elif isinstance(expr, ast.AstTrue): return BoolVal(True) elif isinstance(expr, ast.AstFalse): return BoolVal(False) elif isinstance(expr, ast.AstFuncExpr): params = map((lambda p: expr_to_z3(p, typeEnv)), expr.ops) intsort = map((lambda p: z3.IntSort(ctx=getCtx())), expr.ops) + [z3.IntSort(ctx=getCtx())] f = Function(expr.funcName.name, *intsort) return f(*params) elif isinstance(expr, ast.AstUnExpr): z3_inner = expr_to_z3(expr.expr, typeEnv) if expr.op == '-': return -z3_inner elif expr.op == '!': return Not(z3_inner) else: raise Exception("Unknown unary operator " + str(expr.op)) elif isinstance(expr, ast.AstBinExpr): e1 = expr_to_z3(expr.lhs, typeEnv) e2 = expr_to_z3(expr.rhs, typeEnv) if expr.op == "<==>": return And(Implies(e1, e2), Implies(e2, e1)) elif expr.op == "==>": return Implies(e1, e2) elif expr.op == "||": return Or(e1, e2) elif expr.op == "&&": return And(e1, e2) elif expr.op == "==": return e1 == e2 elif expr.op == "!=": return e1 != e2 elif expr.op == "<": return e1 < e2 elif expr.op == ">": return e1 > e2 elif expr.op == "<=": return e1 <= e2 elif expr.op == ">=": return e1 >= e2 elif expr.op == "+": return e1 + e2 elif expr.op == "-": return e1 - e2 elif expr.op == "*": return e1 * e2 elif expr.op == "div": return e1 / e2 elif expr.op == "mod": return e1 % e2 else: raise Exception("Unknown binary operator " + str(expr.op)) else: raise Exception("Unknown expression " + str(expr))
def getTypedZ3ValFromIdentifier(identifier, types): if type(identifier) == dict: # FIXME how can we handle this here raise NotSupportedException('Complex objects as base for operations cannot be modelled in z3') if type(identifier) == list: arr = z3.Array('ignore_helper_constant_array_' + randomString(), z3.IntSort(), z3.StringSort()) for i, arg in enumerate(identifier): GLOBAL_CONSTRAINTS.append(z3.Select(arr, i) == createZ3ExpressionFromConstraint(arg, types)) ARRAY_LENGTHS[str(arr.decl())] = len(identifier) return arr cur_types = types GLOBAL_IDENTIFIER.add(identifier) cur_types = infered_types[identifier] # if cur_types == 'object': # infered_types[identifier] = '' # cur_types = '' if identifier.endswith('.length'): return z3.Length(z3.String(identifier[:-7])) if cur_types == 'string': return z3.String(identifier) elif cur_types == 'number': return z3.Int(identifier) elif cur_types == 'boolean': return z3.Bool(identifier) elif cur_types == 'array': return z3.Array(identifier, z3.IntSort(), z3.StringSort()) if 'event.data' in identifier or 'event.origin' in identifier or 'event' == identifier: return z3.String(identifier) else: MAKE_UNSOLVABLE.add(identifier) return z3.String(identifier)
def make_2darr(name, f): ARR = Function(name, z3.IntSort(), z3.IntSort(), IntSort()) INIT = [ARR(r, c) == f(r, c) for r in range(R) for c in range(C)] INIT += [ARR(r, -1) == 0 for r in range(-1, R)] INIT += [ARR(-1, c) == 0 for c in range(-1, C)] def call(s): sr, sc = s.src.r, s.src.c dr, dc = s.dst.r, s.dst.c return ARR(dr, dc) - ARR(dr, sc - 1) - ARR(sr - 1, dc) + ARR(sr - 1, sc - 1) return ARR, INIT, call
def get_z3py_variable(v): """Convert the given variable object to a z3py variable""" if v.type.base == "Boolean": if v.type.size < 1: return z3.Bool(v.name) else: return z3.Array(v.name, z3.IntSort(), z3.BoolSort()) else: if v.type.size < 1: return z3.Int(v.name) else: return z3.Array(v.name, z3.IntSort(), z3.IntSort())
def test_get_constraints(self): var1 = SMTVar('var1', z3.IntSort()) var2 = SMTVar('var1', z3.IntSort()) const = var1.var + var2.var > 10 name = 'cosnt1' ctx = SolverContext(z3.Context()) ctx.register_constraint(const, name) self.assertIsNotNone(ctx.get_constraint(name)) self.assertIsNotNone(ctx.get_constraints_info(name)) with self.assertRaises(ValueError): ctx.get_constraint('NotRegistered') with self.assertRaises(ValueError): ctx.get_constraints_info('NotRegistered')
def z3ify_time_constraint(name: str, fn): constraints = [] z3fn = z3.Function(name, z3.IntSort(), z3.IntSort(), z3.BoolSort()) for i, j in itertools.combinations(ALL_SLOTS, 2): ii, jj = z3.IntVal(i.id), z3.IntVal(j.id) if fn(i, j): constraints += [z3fn(ii, jj), z3fn(jj, ii)] else: constraints += [z3.Not(z3fn(ii, jj)), z3.Not(z3fn(jj, ii))] for i in ALL_SLOTS: ii = z3.IntVal(i.id) constraints += [z3fn(ii, ii)] return z3fn, constraints
def convert(t): """Convert term t to Z3 input.""" if t.is_var(): T = t.get_type() if T == nat.natT: return z3.Int(t.name) elif T == TFun(nat.natT, nat.natT): return z3.Function(t.name, z3.IntSort(), z3.IntSort()) elif T == TFun(nat.natT, boolT): return z3.Function(t.name, z3.IntSort(), z3.BoolSort()) elif T == boolT: return z3.Bool(t.name) else: print("convert: unsupported type " + repr(T)) raise NotImplementedError elif t.is_all(): if t.arg.var_T == nat.natT: v = Var(t.arg.var_name, nat.natT) z3_v = z3.Int(t.arg.var_name) return z3.ForAll([z3_v], convert(t.arg.subst_bound(v))) else: raise NotImplementedError elif t.is_implies(): return z3.Implies(convert(t.arg1), convert(t.arg)) elif t.is_equals(): return convert(t.arg1) == convert(t.arg) elif logic.is_conj(t): return z3.And(convert(t.arg1), convert(t.arg)) elif logic.is_disj(t): return z3.Or(convert(t.arg1), convert(t.arg)) elif logic.is_neg(t): return z3.Not(convert(t.arg)) elif nat.is_plus(t): return convert(t.arg1) + convert(t.arg) elif nat.is_times(t): return convert(t.arg1) * convert(t.arg) elif nat.is_binary(t): return nat.from_binary(t) elif t.is_comb(): return convert(t.fun)(convert(t.arg)) elif t.is_const(): if t == logic.true: return z3.BoolVal(True) elif t == logic.false: return z3.BoolVal(False) else: print("convert: unsupported constant " + repr(t)) raise NotImplementedError else: print("convert: unsupported operation " + repr(t)) raise NotImplementedError
def __init__(self, suffix = ''): if suffix != '': s = '_' + suffix else: s = '' xs = [z3.Int('x' + s), z3.Int('y' + s)] self.suffix = s self.variables = xs self.sorts = [z3.IntSort(), z3.IntSort()] self.init = [xs[0] == 0, xs[1] == 1] self.tr = [xs[0] + 1, xs[0] + xs[1]] self.bad = [xs[0] > xs[1]]
def tail_pc(self,pc=None): """ modifies/yields the tail pc (assumes the rule is of kind (II)) """ if pc: name = self.predicate.name() parameters = [z3.IntSort()] arguments = [z3.IntSort().cast(pc)] for i in range(1,self.predicate.arity()): parameters.append(self.predicate.domain(i)) arguments.append(self.tail.arg(i)) parameters.append(z3.BoolSort()) self.predicate = z3.Function(name,*parameters) self.tail = self.predicate(*arguments) else: return self.tail.arg(0)
def head_pc(self,pc=None): """ modifies/yields the head pc """ if pc: name = self.predicate.name() parameters = [z3.IntSort()] arguments = [z3.IntSort().cast(pc)] for i in range(1,self.predicate.arity()): parameters.append(self.predicate.domain(i)) arguments.append(self.head.arg(i)) parameters.append(z3.BoolSort()) self.predicate = z3.Function(name,*parameters) self.head = self.predicate(*arguments) else: return self.head.arg(0)
def get_z3_equality_list(stmt_node, z3_vars, direct_equality= False): global all_z3_vars z3_asserts = [] if not direct_equality: stmt_node = stmt_node.children[0] ## get the equalitystmt first left = stmt_node.children[0] right = stmt_node.children[1] zright = get_z3_expr(right, z3_vars) name = "stmt_rhs_{}".format(stmt_node.line) i = 0 temp_name = name while (temp_name in all_z3_vars): temp_name = name + "_" + str(i) i += 1 name = temp_name zright_temp = z3.Int(name) z3_asserts.append(zright_temp == zright) all_z3_vars[name] = zright_temp if left.data == "select": # we need to update the z3_vars array_name = left.children[0].children[0].value current_label = z3_vars[array_name][1] current_array = z3_vars[array_name][0] new_label = current_label + 1 new_name = "{}_{}".format(array_name, new_label) new_array = z3.Array(new_name, z3.IntSort(), z3.IntSort()) all_z3_vars[new_name] = new_array if (left.children[1].data == "var"): index = z3_vars[left.children[1].children[0].value][0] else: #left children is num index = left.children[1].children[0].value store = z3.Store(current_array, index, zright_temp) z3_vars[array_name] = (new_array, new_label) z3_asserts.append(new_array == store) #LHS equal to new variable if left.data == "var": var_name = left.children[0].value var_label = z3_vars[var_name][1] new_name = "{}_{}".format(var_name, var_label+1) new_var = z3.Int(new_name) all_z3_vars[new_name] = new_var # add the new variable to global list z3_vars[var_name] = (new_var, var_label + 1) z3_asserts.append(new_var == zright_temp) return [(assertion, stmt_node) for assertion in z3_asserts]
def test_3(): import z3 f = z3.Function('f', z3.IntSort(), z3.IntSort()) s = z3.Solver() x = z3.Int('x') s.add(f(0) == x, f(1) == 1, f(2) == 0) s.check() print('Assertions:') for a in s.assertions(): print(str(a)) print('') m = s.model() print('Model: ' + str(m)) print(str(m[f])) #[0 -> 1, 1 -> 1, 2 -> 0, else -> 1] print(str(m[f].num_entries())) #3
def test_model_is_refreshed(self): """ After a push and a pop, the model should be updated. After adding a new assertion, the model should be updated. """ TestVariable = z3.Datatype('TestVariable') TestVariable.declare('test_variable', ('number', z3.IntSort())) TestVariable = TestVariable.create() v1 = z3.Const('v1', TestVariable) v2 = z3.Const('v2', TestVariable) with solver.context(): solver.add(TestVariable.number(v1) == 42) m1 = solver.model() self.assertIsNotNone(m1[v1]) self.assertIsNone(m1[v2]) solver.add(TestVariable.number(v2) == 3) m2 = solver.model() self.assertIsNotNone(m2[v1]) self.assertIsNotNone(m2[v2]) m3 = solver.model() self.assertIsNone(m3[v1]) self.assertIsNone(m3[v2])
def solve(grid): """ . . . .1.1. . .3. """ s = z3.Solver() # Construct atoms to represent the dots Dot = z3.Datatype("Dot") for d in grid.dots(): Dot.declare("dot_{}".format(d)) Dot = Dot.create() dot_atom = {d: getattr(Dot, "dot_{}".format(d)) for d in grid.dots()} # Booleans for each of the points dot = {d: z3.Bool("dot-{}".format(d)) for d in grid.dots()} # Booleans for each of the connectors line = {l: z3.Bool("line-{}".format(l)) for l in grid.lines()} # For each point: if it is on, it must have precisely two adjoining lines activated # If it's off, then there are zero adjoining lines activated bool_to_int = z3.Function("bool_to_int", z3.BoolSort(), z3.IntSort()) s.add(bool_to_int(True) == 1) s.add(bool_to_int(True) != 0) s.add(bool_to_int(False) == 0) s.add(bool_to_int(False) != 1) for d in grid.dots(): # Get all lines coming out of this dot ls = [line[l] for l in d.lines()] sm = z3.Sum(*(bool_to_int(l) for l in ls)) s.add(z3.Implies(dot[d], sm == 2)) s.add(z3.Implies(z3.Not(dot[d]), sm == 0)) # For each line: if it is activated, then the points at both ends are activated for l in line: d1, d2 = l.ends() s.add(z3.Implies(line[l], z3.And(dot[d1], dot[d2]))) # "Is connected to" relationship connected = z3.Function("connected", Dot, Dot, z3.BoolSort()) # For each line: # The Dot at each end is connected to the other iff the line is activated for d1 in grid.dots(): for d2 in grid.dots(): a = dot_atom[d1] b = dot_atom[d2] if (l := grid.line(d1, d2)) is None: # These dots are never connected s.add(connected(a, b) != True) else: s.add(z3.Implies(line[l], connected(a, b))) s.add(z3.Implies(z3.Not(line[l]), z3.Not(connected(a, b))))
def type2sort(typ, ctx): if typ == int: return z3.IntSort(ctx) elif typ == str: return z3.StringSort(ctx) else: raise ValueError(f'Unsupported type: {typ}')
def __init__(cls, name: str, bases: tuple[type, ...], ns: Namespace): sorts = {bool: z3.BoolSort(), int: z3.IntSort(), float: z3.RealSort()} vars = {} try: for var, ann in cls.__annotations__.items(): if isinstance(ann, str): ann = eval(ann) if ann is bool: vars[var] = z3.Bool(var) elif ann is int: vars[var] = z3.Int(var) elif ann is float: vars[var] = z3.Real(var) elif isinstance(ann, dict): in_sort, out_sort = next(iter(ann.items())) out_sort = sorts[out_sort] if isinstance(in_sort, tuple): in_sort = (sorts[x] for x in in_sort) vars[var] = z3.Function(var, *in_sort, out_sort) else: in_sort = sorts[in_sort] vars[var] = z3.Function(var, in_sort, out_sort) except: pass solver = z3.Solver() for term in ns.assertions: solver.add(traverse(term, vars)) assert solver.check(), "Unsatisfiable constraints!" cls.__model = solver.model() cls.__vars = vars
def sorts(name): if name.startswith('bv[') and name.endswith(']'): width = int(name[3:-1]) return z3.BitVecSort(width) if name == 'int': return z3.IntSort() return None
def extract_ospf_graph(network_graph, log): """ Extract a sub graph from the network graph that is relevant to the OSPF Computations :param network_graph: NetworkGraph :param log: logger :return: nx.DiGraph() of the OSPF enabled subgraph """ ospf_graph = nx.DiGraph() # Only local routers for node in network_graph.nodes(): if network_graph.is_local_router( node) and network_graph.is_ospf_enabled(node): ospf_graph.add_node(node) for src, dst in network_graph.edges(): # First skip an edge that is not connecting # two OSPF enabled routers if not network_graph.is_ospf_enabled(src): continue if not network_graph.is_ospf_enabled(dst): continue cost = network_graph.get_edge_ospf_cost(src, dst) if not cost: log.warn("Edge OSPF cost (%s, %s) is None", src, dst) if is_empty(cost): cost = None if not cost: cost = z3.Const("cost_%s_%s" % (src, dst), z3.IntSort()) ospf_graph.add_edge(src, dst, cost=cost) return ospf_graph
def test_symbolic_int(self): # Arrange name = 'TestVar1' z3_ctx = z3.Context() vsort = z3.IntSort(ctx=z3_ctx) value = 10 # Act var = SMTVar(name, vsort) var_before = var.var get_var_before = var.get_var() with self.assertRaises(RuntimeError): self.assertEquals(var.get_value(), value) # Concertize the value solver = z3.Solver(ctx=z3_ctx) solver.add(var.var == value) self.assertEquals(solver.check(), z3.sat) model = solver.model() var.eval(model) # Assert self.assertEquals(var.name, name) self.assertEquals(var.vsort, vsort) self.assertTrue(is_symbolic(var_before)) self.assertTrue(is_symbolic(get_var_before)) self.assertEquals(var.name, name) self.assertEquals(var.vsort, vsort) self.assertEquals(var.var, value) self.assertEquals(var.get_value(), value) self.assertTrue(is_symbolic(var.get_var()))
def type_to_data_sort(ty): dt_name = datatype_name(ty) if dt_name == types.TY_LOC: return data.Loc elif dt_name == types.TY_INT: return z3.IntSort() elif dt_name == types.TY_BOOL: return z3.BoolSort() elif dt_name == types.TY_FLOAT: return z3.RealSort() elif dt_name == types.TY_DEST: return data.Dest elif dt_name == types.TY_CHAR: return data.Char elif dt_name == types.TY_STR: return data.String elif dt_name == types.TY_LIST: elem_sort = type_to_data_sort(ty.arg(0)) return z3sc.listInfo(elem_sort)['sort'] elif dt_name == types.TY_TUPLE: sorts = [] while dt_name != types.TY_UNIT: sorts.append(type_to_data_sort(ty.arg(0))) ty = ty.arg(1) dt_name = datatype_name(ty) return z3sc.tupleInfo(*sorts)['sort'] elif dt_name == types.TY_MSET: elem_sort = type_to_data_sort(ty.arg(0)) return z3sc.setInfo(elem_sort)['sort'] elif dt_name == types.TY_ARROW: return None else: return data.Unknown
def helper(x): if (x is None): return x elif (self.is_uninterpreted_fun(x)): match = [f[1] for f in funQ if f[0] is x] if (len(match) == 1): # found a match return match[0] else: rangeSort = x.decl().range() varName = '|$' + str(x) + '|' if (rangeSort == z3.RealSort()): newVar = z3.Real(varName) elif (rangeSort == z3.IntSort()): newVar = z3.Int(varName) elif (rangeSort == z3.BoolSort()): newVar = z3.Bool(varName) else: raise ExptRewriteFailure( 'unknown sort for range of uninterpreted function -- ' + varName + ' returns a ' + rangeSort + ' ?') funQ.append((x, newVar)) return newVar else: ch = x.children() newch = self.fun_to_var(ch, report) if (len(ch) != len(newch)): raise ExptRewriteFailure('Internal error') elif (len(newch) == x.decl().arity()): return x.decl().__call__(*newch) elif ((x.decl().arity() == 2) and (len(newch) > 2)): return reduce(x.decl(), newch) else: raise ExptRewriteFailure('Internal error')
def compute_rval(self, ctx): # this will only resolve expressions no other classes # FIXME: Untangle this a bit z3_type = ctx.resolve_type(self.z3_type) if self.rval is not None: rval = ctx.resolve_expr(self.rval) if isinstance(rval, int): if isinstance(z3_type, (z3.BitVecSortRef)): rval = z3_cast(rval, z3_type) elif isinstance(rval, list): instance = ctx.gen_instance(UNDEF_LABEL, z3_type) instance.set_list(rval) rval = instance elif z3_type == z3.IntSort(): # at this point rval can not be an int any more # cast any bitvector value to long, no runtime is allowed return rval.as_long() elif z3_type != rval.sort(): msg = f"There was an problem setting {self.lval} to {rval}. " \ f"Type Mismatch! Target type {z3_type} " \ f"does not match with input type {rval.sort()}" raise RuntimeError(msg) else: rval = ctx.gen_instance(UNDEF_LABEL, z3_type) return rval
def main(): b, c = z3.Ints("b c") a = z3.Array("a", z3.IntSort(), z3.IntSort()) f = z3.Function("f", z3.IntSort(), z3.IntSort()) solver = z3.Solver() solver.add(c == b + z3.IntVal(2)) lhs = f(z3.Store(a, b, 3)[c - 2]) rhs = f(c - b + 1) solver.add(lhs != rhs) res = solver.check() if res == z3.sat: print("sat") elif res == z3.unsat: print("unsat") else: print("unknown")
def textx_to_z3py_model(ast, variables): """Translate the given textx AST to z z3py model""" class_name = ast.__class__.__name__ if class_name in [ "Expression", "ExprPrec1", "ExprPrec2", "ExprPrec3", "ExprPrec4" ]: if ast.right is None: return textx_to_z3py_model(ast.left, variables) else: return get_z3_operator_representation( ast.op, textx_to_z3py_model(ast.left, variables), textx_to_z3py_model(ast.right, variables)) elif class_name == "Primary": if ast.value is not None: if ast.sign == "-": return get_z3_operator_representation("neg", ast.value) elif ast.sign == "not": return get_z3_operator_representation("not", ast.value) else: if isinstance(ast.value, bool): return z3.BoolSort().cast(ast.value) elif isinstance(ast.value, int): return z3.IntSort().cast(ast.value) else: return ast.value elif ast.ref is not None: if ast.sign == "-": return get_z3_operator_representation( "neg", textx_to_z3py_model(ast.ref, variables)) if ast.sign == "not": return get_z3_operator_representation( "not", textx_to_z3py_model(ast.ref, variables)) else: return textx_to_z3py_model(ast.ref, variables) else: if ast.sign == "-": return get_z3_operator_representation( "neg", textx_to_z3py_model(ast.body, variables)) if ast.sign == "not": return get_z3_operator_representation( "not", textx_to_z3py_model(ast.body, variables)) else: return textx_to_z3py_model(ast.body, variables) elif class_name == "ExpressionRef": if ast.index is None: return variables[ast.ref] else: return operator.itemgetter( textx_to_z3py_model(ast.index, variables))(variables[ast.ref]) elif class_name == "VariableRef": if ast.index is None: return variables[ast.var.name] else: return operator.itemgetter( textx_to_z3py_model(ast.index, variables))(variables[ast.var.name]) else: raise Exception( "No implementation exists for the simple ast conversion of class [%s]" % class_name)
def recover_value(value, uct_sort): """ Inverse of _extract_value. Given a pythonic value, returns a z3 embedding of it depending on its uct sort. The explicit embedding scheme is as follows: fgsort -> z3.ArithRef fgsetsort -> z3.ArrayRef intsort -> z3.ArithRef intsetsort -> z3.ArrayRef boolsort -> z3.BoolRef :param value: any :param uct_sort: naturalproofs.uct.UCTSort :return: z3.ExprRef """ # TODO: typecheck all the arguments if uct_sort in {fgsort, intsort}: return z3.IntVal(value) elif uct_sort == boolsort: return z3.BoolVal(value) elif uct_sort in {fgsetsort, intsetsort}: expr = z3.EmptySet(z3.IntSort()) for elem in value: expr = z3.SetAdd(expr, z3.IntVal(elem)) else: raise ValueError( 'Sort not supported. Check for a list of available sorts in the naturalproofs.uct module.' )
def __parse_unary_expression__(self, symbol_node: jcmuta.SymbolNode, code: int): """ :param symbol_node: negative, bit_not, logic_not, address_of, dereference :param code: :return: """ operator = symbol_node.get_content().get_token_value() operand = symbol_node.get_child(1) if operator == "negative": u_operand = self.__parse__(operand, code) return -self.__cast_to_numb__(u_operand) elif operator == "bit_not": u_operand = self.__parse__(operand, self.__s_code__) return ~self.__cast_to_bits__(u_operand) elif operator == "logic_not": u_operand = self.__parse__(operand, code) return z3.Not(self.__cast_to_bool__(u_operand)) elif operator == "address_of": return z3.Const(self.__unique_name__(symbol_node), z3.IntSort()) else: name = self.__unique_name__(symbol_node) name = self.__normal_name__(name, symbol_node.get_data_type()) return self.__new_reference__(name, symbol_node.get_data_type(), code)