def check_adversarial_robustness_z3(): from z3 import Reals, Int, Solver, If, And sk, sk_1, zk, zk_1 = Reals('sk sk_1 zk zk_1') i = Int('i') s = Solver() s.add(And(i >= 0, i <= 20, sk_1 >= 0, sk >= 0, zk >= 0, zk_1 >= 0)) A = If(sk * 1 >= 0, sk * 1, 0) B = If(zk * 1 >= 0, zk * 1, 0) s.add(If(i == 0, And(sk >= 0, sk <= 3, zk >= 10, zk <= 21, sk_1 == 0, zk_1 == 0), sk - zk >= sk_1 - zk_1 + 21 / i)) s.add(And(A < B, i == 20)) # # we negate the condition, instead if for all sk condition we check if there exists sk not condition # s.add(sk_ReLU * w > ylim) t = s.check() if t == sat: print("z3 result:", s.model()) return False else: # print("z3 result:", t) return True
def get_dimension(i, axis): if axis == x: return If(pieces_rotation[i], pieces_dimensions[i][y], pieces_dimensions[i][x]) else: return If(pieces_rotation[i], pieces_dimensions[i][x], pieces_dimensions[i][y])
def maximize_distance(bots): o = Optimize() z3_abs = lambda k: If(k >= 0, k, -k) z3_in_ranges = [Int('in_range_of_bot_' + str(i)) for i in xrange(len(bots))] z3_x, z3_y, z3_z = (Int('x'), Int('y'), Int('z')) z3_sum = Int('sum') z3_dist = Int('dist') for i, (x, y, z, r) in enumerate(bots): o.add(z3_in_ranges[i] == If(distance((z3_x, z3_y, z3_z), (x, y, z), z3_abs) <= r, 1, 0)) o.add(z3_sum == sum(z3_in_ranges)) o.add(z3_dist == distance((z3_x, z3_y, z3_z), (0, 0, 0), z3_abs)) h1, h2 = o.maximize(z3_sum), o.minimize(z3_dist) o.check() # o.lower(h1), o.upper(h1) lower, upper = o.lower(h2), o.upper(h2) # o.model()[z3_x], o.model()[z3_y], o.model()[z3_z] if str(lower) != str(upper): raise Exception('lower ({}) != upper ({})'.format(lower, upper)) return (lower, upper)
def add_optimize_targets2(solver, int_dict, order_dict): # new optimize target # A*o1+(1-A)*o2 # o1 = AVG[v'(pkg)/|V(pkg)|] if v'(pkg)!=|V(pkg)| ((not installed)) # o2 = (|P|-|P'|)/|P| if p is installed, p belongs to P' A = 0.5 o1 = Real("o1") o2 = Real("o2") sum_ins = Int("sum_ins") sum_all = Int("sum_all") count_ins = Int("count_ins") sum_ins, sum_all, count_ins = 0, 0, 0 count_all = 0 for pkg in int_dict: sum_ins = If(int_dict[pkg] != len(order_dict[pkg]), sum_ins + int_dict[pkg], sum_ins) count_ins = If(int_dict[pkg] != len(order_dict[pkg]), count_ins + 1, count_ins) sum_all = If(int_dict[pkg] != len(order_dict[pkg]), sum_all + len(order_dict[pkg]), sum_all) count_all += 1 o1 = ToReal(sum_ins) / ToReal(sum_all) o2 = 1 - (ToReal(count_ins) / count_all) target = A * o1 + (1 - A) * o2 solver.maximize(target) return solver
def snake_sums(g): for y in range(g.height): row = sum(If(g.snake(x, y), g.digit(x, y), 0) for x in range(g.width)) g.add(row == g.rows[y]) for x in range(g.width): row = sum(If(g.snake(x, y), g.digit(x, y), 0) for y in range(g.height)) g.add(row == g.columns[x])
def bsort_step(A0, A1, tmp, i0, j0, i1, j1, dim): return If( j0 < dim - 1, \ And( \ If( i0 < dim - 1, \ And(invert(A0, A1, tmp, i0, i1),i1 == i0 + 1), \ i1 == i0 + 1), \ j1 == j0 + 1), \ And(j1 == j0 + 1, A1 == A0))
def addTimeVars(self): timeConstraints = [] self.waitBefores = [] # Create the wait before variables, which indicate, at each # time step t, how much time should be waited before starting # that time step. This value must be non-negative. for t in range(len(self.tasks)): self.waitBefores.append(z3.Int("waitBefore" + str(t))) self.solver.add(self.waitBefores[t] >= 0) if len(self.tasks) == 0: firstMoveTime = 0 else: firstMoveTime = self.waitBefores[0] # The firstMoveTime is the time it takes to get to the first # location. Add a constraint for each location that could # possibly come first, that if it does come first, add the # time it takes to get to it to firstMoveTime for task in self.tasks: firstMoveTime += If(self.taskVars[task][0], self.world.time(self.startLoc, task.location), 0) # Set this expression equal to a new variable. firstVar = z3.Int("TimeToFirstNode") timeConstraints.append(firstVar == firstMoveTime) # Aggregate the time variables. self.timeVars = [firstVar] # For each time step, create a new time variable. for t in range(len(self.tasks) - 1): # Start with the time variable from the previous iteration. time = self.timeVars[t] + self.waitBefores[t + 1] # This little while loop trick allows us to get every pair # of tasks. tasksLeft = list(self.tasks) while len(tasksLeft) > 0: task1 = tasksLeft.pop() for task2 in tasksLeft: # If we traveled between these two tasks from this # time step to the next, add the time taken to our # time variable. time += If(Or(And(self.taskVars[task1][t], self.taskVars[task2][t+1]), \ And(self.taskVars[task2][t], self.taskVars[task1][t+1])),\ self.taskDistance(task1,task2), 0) # Add the time taken accomplishing a task at this step # to the time variable. time += If(self.taskVars[task1][t], self.world.duration(task1.ID), 0) # Create a new time variable that cooresponds to this expression. var = z3.Int("TimeVar" + str(t)) timeConstraints.append(var == time) # Add it to our aggregate. self.timeVars.append(var) if self.debugPrint: print "Added time variables: " + str(self.timeVars) for constraint in timeConstraints: self.solver.add(constraint) if self.debugPrint: print "Added time constraints: " + str(timeConstraints)
def and_(self, global_state): stack = global_state.mstate.stack op1, op2 = stack.pop(), stack.pop() if type(op1) == BoolRef: op1 = If(op1, BitVecVal(1, 256), BitVecVal(0, 256)) if type(op2) == BoolRef: op2 = If(op2, BitVecVal(1, 256), BitVecVal(0, 256)) stack.append(op1 & op2) return [global_state]
def and_(self, global_state): try: stack = global_state.mstate.stack op1, op2 = stack.pop(), stack.pop() if type(op1) == BoolRef: op1 = If(op1, BitVecVal(1, 256), BitVecVal(0, 256)) if type(op2) == BoolRef: op2 = If(op2, BitVecVal(1, 256), BitVecVal(0, 256)) stack.append(op1 & op2) except IndexError: raise StackUnderflowException() return [global_state]
def main(): """Star Battle solver example.""" sym = grilops.SymbolSet([("EMPTY", " "), ("STAR", "*")]) lattice = grilops.get_rectangle_lattice(HEIGHT, WIDTH) sg = grilops.SymbolGrid(lattice, sym) # There must be exactly two stars per column. for y in range(HEIGHT): sg.solver.add( Sum(*[ If(sg.cell_is(Point(y, x), sym.STAR), 1, 0) for x in range(WIDTH) ]) == 2) # There must be exactly two stars per row. for x in range(WIDTH): sg.solver.add( Sum(*[ If(sg.cell_is(Point(y, x), sym.STAR), 1, 0) for y in range(HEIGHT) ]) == 2) # There must be exactly two stars per area. area_cells = defaultdict(list) for y in range(HEIGHT): for x in range(WIDTH): area_cells[AREAS[y][x]].append(sg.grid[Point(y, x)]) for cells in area_cells.values(): sg.solver.add(Sum(*[If(c == sym.STAR, 1, 0) for c in cells]) == 2) # Stars may not touch each other, not even diagonally. for y in range(HEIGHT): for x in range(WIDTH): p = Point(y, x) sg.solver.add( Implies( sg.cell_is(p, sym.STAR), And(*[ n.symbol == sym.EMPTY for n in sg.vertex_sharing_neighbors(p) ]))) if sg.solve(): sg.print() if sg.is_unique(): print("Unique solution") else: print("Alternate solution") sg.print() else: print("No solution")
def SIGNEXTEND(i, x): bitBV = i * 8 + 7 bitInt = BV2Int(i) * 8 + 7 test = BitVecVal(1, x.size()) << bitBV mask = test - 1 return If( bitInt >= x.size(), x, If( (x & test) == 0, x & mask, x | ~mask ) )
def choose_op(a1, a2, op): r = If(op == 0, a2 + a1, If(op == 1, a1 - a2, If(op == 2, a2 * a1, If(op == 3 and a2 != 0, UDiv(a1, a2), False ) ) ) ) return r
def __add_single_loop_constraints(self): solver = self.__symbol_grid.solver sym: LoopSymbolSet = self.__symbol_grid.symbol_set cell_count = len(self.__symbol_grid.grid) for p in self.__symbol_grid.grid: v = Int(f"log-{LoopConstrainer._instance_index}-{p.y}-{p.x}") solver.add(v >= -cell_count) solver.add(v < cell_count) self.__loop_order_grid[p] = v solver.add(Distinct(*self.__loop_order_grid.values())) for p, cell in self.__symbol_grid.grid.items(): li = self.__loop_order_grid[p] solver.add(If(sym.is_loop(cell), li >= 0, li < 0)) for idx, d1, d2 in self.__all_direction_pairs(): pi = p.translate(d1) pj = p.translate(d2) if pi in self.__loop_order_grid and pj in self.__loop_order_grid: solver.add( Implies( And(cell == idx, li > 0), Or(self.__loop_order_grid[pi] == li - 1, self.__loop_order_grid[pj] == li - 1)))
def main(): bots = [] with open("input.txt") as f: for line in f: bots.append(tuple(map(int, re.findall(r"-?\d+", line)))) x, y, z, r = max(bots, key=lambda b: b[3]) in_range = sum( (abs(x - b[0]) + abs(y - b[1]) + abs(z - b[2]) <= r) for b in bots) print("Part 1:", in_range) x, y, z = Int("x"), Int("y"), Int("z") point = (x, y, z) count = sum(If(z3_dist(b[:3], point) <= b[3], 1, 0) for b in bots) opt = Optimize() opt.maximize(count) opt.minimize(z3_dist(point, (0, 0, 0))) opt.check() model = opt.model() result = model[x].as_long() + model[y].as_long() + model[z].as_long() print("Part 2:", result)
def _load(self, item: Union[int, ExprRef], clean=False) -> Any: x = BitVecVal(item, 256) if isinstance(item, int) else item symbolic_base_value = If( x > self._size, BitVecVal(0, 8), BitVec("{}_calldata_{}".format(self.tx_id, str(item)), 8), ) return_value = symbolic_base_value for r_index, r_value in self._reads: return_value = If(r_index == item, r_value, return_value) if not clean: self._reads.append((item, symbolic_base_value)) return simplify(return_value)
def add_pick(self, name, size, typ, _): """Adds constraints for statement <name> := pick <size> <typ> <where> <typ> is optional. When omitted, pick from all agents. The last argument is the "where" clause and is currently ignored. """ size = int(size) steps = self.cli[Args.STEPS] def can_pick(tid, name): for ag in self.info.spawn.values(): if name in ag.picks: return self.isOfType(tid, ag.name) p = [IntVector(f"{name}_{i}", size) for i in range(steps)] for step in range(steps): # if agent cannot actually use the pick, set to 0 if_can_pick = [ # Honor agent type, self.isOfType(x, typ) for x in p[step] ] if typ else [ # If pick is untyped, x should still be a valid id self.isAnAgent(x) for x in p[step] ] # picks should be distinct if_can_pick.extend(p[step][i] != p[step][j] for j in range(size) for i in range(j)) # Agent cannot pick itself if_can_pick.extend(x != self.sched[step] for x in p[step]) self.s.add( If(can_pick(self.sched[step], name), And(if_can_pick), And([x == 0 for x in p[step]]))) self.picks[name] = (p, size, typ)
def link_symbols_to_shapes(sym, sg, sc): """Add constraints to ensure the symbols match the shapes.""" for p in sg.lattice.points: sg.solver.add( If(sc.shape_type_grid[p] != -1, sg.cell_is(p, sc.shape_type_grid[p]), sg.cell_is(p, sym.W)))
def main(args): data = [extract(s.strip()) for s in sys.stdin] data = [(x[3], tuple(x[:-1])) for x in data] m = max(data) in_range = [x for x in data if dist(x[1], m[1]) <= m[0]] print(len(in_range)) x = Int('x') y = Int('y') z = Int('z') orig = (x, y, z) cost = Int('cost') cost_expr = x * 0 for r, pos in data: cost_expr += If(z3_dist(orig, pos) <= r, 1, 0) opt = Optimize() print("let's go") opt.add(cost == cost_expr) opt.maximize(cost) # I didn't do this step in my initial #2 ranking solution but I # suppose you should. # z3 does them lexicographically by default. opt.minimize(z3_dist((0, 0, 0), (x, y, z))) opt.check() model = opt.model() # print(model) pos = (model[x].as_long(), model[y].as_long(), model[z].as_long()) print("position:", pos) print("num in range:", model[cost].as_long()) print("distance:", dist((0, 0, 0), pos))
def BYTE(i, x): bit = (i + 1) * 8 return If( UGT(i, x.size() / 8 - 1), BitVecVal(0, x.size()), (LShR(x, (x.size() - bit))) & 0xff )
def constrain_path_order(sg, path_order_grid): """The path order variables must contain the path traversal order.""" for p in LATTICE.points: cell = sg.grid[p] po = path_order_grid[p] sg.solver.add(If(SYM.is_loop(cell), po >= 0, po < 0)) npo = path_order_grid.get(p.translate(N), None) epo = path_order_grid.get(p.translate(E), None) spo = path_order_grid.get(p.translate(S), None) wpo = path_order_grid.get(p.translate(W), None) ncond, econd, scond, wcond = False, False, False, False if npo is not None: ncond = npo == po - 1 if epo is not None: econd = epo == po - 1 if spo is not None: scond = spo == po - 1 if wpo is not None: wcond = wpo == po - 1 sg.solver.add(Implies(And(cell == SYM.NS, po > 0), Or(ncond, scond))) sg.solver.add(Implies(And(cell == SYM.EW, po > 0), Or(econd, wcond))) sg.solver.add(Implies(And(cell == SYM.NE, po > 0), Or(ncond, econd))) sg.solver.add(Implies(And(cell == SYM.SE, po > 0), Or(scond, econd))) sg.solver.add(Implies(And(cell == SYM.SW, po > 0), Or(scond, wcond))) sg.solver.add(Implies(And(cell == SYM.NW, po > 0), Or(ncond, wcond)))
def eq_(self, global_state): state = global_state.mstate op1 = state.stack.pop() op2 = state.stack.pop() if type(op1) == BoolRef: op1 = If(op1, BitVecVal(1, 256), BitVecVal(0, 256)) if type(op2) == BoolRef: op2 = If(op2, BitVecVal(1, 256), BitVecVal(0, 256)) exp = op1 == op2 state.stack.append(exp) return [global_state]
def solve_with(self, input_image, output_index): x = RealVector('x', len(input_image[0])) for i in range(len(input_image[0])): if i >= self.pixels_to_change: # x[i] = image[i] self.solver.add(x[i] == input_image[0][i].item()) else: # 0 <= x[i] <= 1 self.solver.add(x[i] >= 0) self.solver.add(x[i] <= 1) fc1_weights = fetch_weights(1) fc1_shape = fc1_weights.size() # o1 = fc1^T * x o1 = [ Sum([fc1_weights[i, j].item() * x[j] for j in range(fc1_shape[1])]) for i in range(fc1_shape[0]) ] # y1 = ReLU(o1) y1 = [If(o1[i] > 0, o1[i], 0) for i in range(fc1_shape[0])] fc2_weights = fetch_weights(2) fc2_shape = fc2_weights.size() # y2 = fc2^T * y1 y2 = [ Sum([ fc2_weights[i, j].item() * y1[j] for j in range(fc2_shape[1]) ]) for i in range(fc2_shape[0]) ] # If any y2 output is higher than the expected y2, # the model output changes self.solver.add( Or([ y2[output_index] < y2[i] for i in range(len(y2)) if i != output_index ])) # self.solver.add(And([y2[output_index] > y2[i] # for i in range(len(y2)) if i != output_index])) # Check if the classification can change check = self.solver.check() sat = str(check) == 'sat' if sat: m = self.solver.model() # Substitute the model back in x_new = input_image.clone().detach() for i in range(self.pixels_to_change): x_new[0][i] = model_to_val(m, x[i]) for i in range(self.pixels_to_change, len(input_image[0])): x_new[0][i] = input_image[0][i] return x_new elif str(check) == 'unknown': return 'timeout' else: return 'unsat'
def main(): """Kuromasu solver example.""" sym = grilops.SymbolSet([("B", chr(0x2588) * 2), ("W", " ")]) lattice = grilops.get_rectangle_lattice(HEIGHT, WIDTH) sg = grilops.SymbolGrid(lattice, sym) rc = grilops.regions.RegionConstrainer(lattice, solver=sg.solver, complete=False) for p, c in GIVENS.items(): # Numbered cells may not be black. sg.solver.add(sg.cell_is(p, sym.W)) # Each number on the board represents the number of white cells that can be # seen from that cell, including itself. A cell can be seen from another # cell if they are in the same row or column, and there are no black cells # between them in that row or column. visible_cell_count = 1 + sum( grilops.sightlines.count_cells( sg, n.location, n.direction, stop=lambda c: c == sym.B) for n in sg.edge_sharing_neighbors(p)) sg.solver.add(visible_cell_count == c) # All the white cells must be connected horizontally or vertically. Enforce # this by requiring all white cells to have the same region ID. Force the # root of this region to be the first given, to reduce the space of # possibilities. white_root = min(GIVENS.keys()) white_region_id = lattice.point_to_index(white_root) for p in lattice.points: # No two black cells may be horizontally or vertically adjacent. sg.solver.add( Implies( sg.cell_is(p, sym.B), And(*[n.symbol == sym.W for n in sg.edge_sharing_neighbors(p)]))) # All white cells must have the same region ID. All black cells must not # be part of a region. sg.solver.add( If(sg.cell_is(p, sym.W), rc.region_id_grid[p] == white_region_id, rc.region_id_grid[p] == -1)) def print_grid(): sg.print(lambda p, _: f"{GIVENS[(p.y, p.x)]:02}" if (p.y, p.x) in GIVENS else None) if sg.solve(): print_grid() print() if sg.is_unique(): print("Unique solution") else: print("Alternate solution") print_grid() else: print("No solution")
def if_expr(self, expr): b = expr.bool_expr.convert(self) t = expr.true_expr.convert(self) f = expr.false_expr.convert(self) (hit, result) = self.checkCache("If", [b,t,f], sort=False) if hit: return result else: return self.cache(If(b,t,f), result)
def test_abs_between(constantPitch): assert Interval.absBetween( constantPitch, ConstPitch(constantPitch.letter + Interval.SECOND().semitoneDistance, constantPitch.octave)) == Interval(logicalAbs(2)) assert Interval.absBetween( ConstPitch(constantPitch.letter + Interval.SECOND().semitoneDistance, constantPitch.octave), constantPitch) == Interval(If(False, -2, 2))
def snake_orthogonally_connected(g): # Orthogonally, we don't branch for x, y in g.coords(): c = g.snake(x, y) number_surrounding = sum( BoolToInt(g.snake(x2, y2)) for x2, y2 in orthogonal(g, x, y)) is_head = (x, y) == g.head is_tail = (x, y) == g.tail is_endpoint = Or(is_head, is_tail) g.add(Implies(c, number_surrounding == If(is_endpoint, 1, 2)))
def conditional_update(cyc, update_func, update_cond, mixmethod): return binary_anded([ If( update_cond(cyc, idx), dat(x) == update_func(idx, lft(x)) if mixmethod(idx) else dat(x) == update_func(idx, rght(x)), dat(x) == update_func(idx, rght(x)) if mixmethod(idx) else dat(x) == update_func(idx, lft(x))) for idx, dat in enumerate(cyc) ])
def target_cells_use_all_available_pieces(self, board, pieces): constraints = [] for (piece, quantity) in collections.Counter(pieces).items(): constraints.append( Sum([ If(cell == piece, 1, 0) for (_, _, value, cell) in board if self.is_cell_empty(value) ]) == quantity) return constraints
def __init__( self, task, condition: BoolRef, optional: Optional[bool] = False ) -> None: super().__init__(optional) if not task.optional: raise TypeError("Task %s must be optional." % task.name) self.set_z3_assertions( If(condition, task.scheduled == True, task.scheduled == False) )
def _load(self, item: Union[int, ExprRef]) -> Any: if isinstance(item, int): try: return self._calldata[item] except IndexError: return 0 value = BitVecVal(0x0, 8) for i in range(self.size): value = If(item == i, self._calldata[i], value) return value