def atLeastOneRule(myBools, x, graph): n = len(graph.items()) for i in range(0, n): # each row x.add(Or(myBools[i])) return x
def concrete_transition_to_abstract(cls, nodes_from, abstract_witness): kripke = abstract_witness.get_kripke() tr = kripke.get_tr_formula() def sub_src(_tr, src_node): return _tr.assign_state(src_node.concrete_label) tr_from_concs = [sub_src(tr, node) for node in nodes_from] dst_vars = tr_from_concs[0].get_var_vectors()[0] in_tag = tr.get_input_vectors()[1] abs_formula = abstract_witness.get_descriptive_formula().substitute( dst_vars, 0).substitute_inputs(in_tag, 0) n_flags = len(tr_from_concs) flags = [Bool('f' + str(i)) for i in xrange(n_flags)] tr_flagged = [ Or(Not(flags[i]), tr_from_concs[i].get_qbf().get_prop()) for i in xrange(n_flags) ] all_tr_flagged = simplify(And(*tr_flagged)) f_inner = simplify( And(all_tr_flagged, abs_formula.get_qbf().get_prop())) q_list = abs_formula.get_qbf().get_q_list() f_qbf = QBF(f_inner, q_list) f = FormulaWrapper(f_qbf, [dst_vars], tr.get_input_vectors()) i, model = QbfSolverSelector.QbfSolverCtor().incremental_solve_flags( f, flags, sat) if i is False: return False return nodes_from[i], next(get_states(model, dst_vars, kripke))
def constrain_no_inside_diagonal(y, x): """Add constraints for diagonally touching cells. "Inside" cells may not diagonally touch each other unless they also share an adjacent cell. """ nw = sg.grid[Point(y, x)] ne = sg.grid[Point(y, x + 1)] sw = sg.grid[Point(y + 1, x)] se = sg.grid[Point(y + 1, x + 1)] sg.solver.add( Implies(And(nw == sym.I, se == sym.I), Or(ne == sym.I, sw == sym.I))) sg.solver.add( Implies(And(ne == sym.I, sw == sym.I), Or(nw == sym.I, se == sym.I)))
def get_state(doubles, browser): if browser == "node": browser = "chrome" elif browser not in ("chrome", "firefox", "safari"): raise ValueError(f"invalid browser {browser}") if browser == "chrome": doubles = doubles[::-1] # from the doubles, generate known piece of the original uint64 generated = [from_double(double, browser) for double in doubles] # setup symbolic state for xorshift128+ ostate0, ostate1 = BitVecs("ostate0 ostate1", 64) sym_state0 = ostate0 sym_state1 = ostate1 solver = Solver() conditions = [] # run symbolic xorshift128+ algorithm for three iterations # using the recovered numbers as constraints for val in generated: sym_state0, sym_state1, ret_conditions = sym_xs128p( solver, sym_state0, sym_state1, val, browser) conditions += ret_conditions if solver.check(conditions) == sat: # get a solved state m = solver.model() state0 = m[ostate0].as_long() state1 = m[ostate1].as_long() solver.add(Or(ostate0 != m[ostate0], ostate1 != m[ostate1])) if solver.check(conditions) == sat: print("WARNING: multiple solutions found! use more doubles!") return state0, state1 else: raise ValueError("unsat model")
def all_ret_val_used_constraint(env: Env) -> Constraint: I, C, F, P, _, o = env for f in F: # TODO Check if there's any performance gain from verifying if p is in # TODO Also, remove kind check if we're only checking for line equality # f.params. constr = Or([f.line == p.line \ for p in P if p not in [q for q in f.params if p.kind == q.kind] #\ and f.kind == p.kind # unplugable components ], f.ctx) if f.kind == o.kind: yield Or(constr, f.line == o.line, f.ctx) else: yield constr
def scheduling_constraints(self): """ DAG scheduling constraints optimization Sets overlap indicator variables """ for gate in self.gate_start_time: for dep_gate in self.dag.successors(gate): if not dep_gate.type == 'op': continue if isinstance(dep_gate.op, Measure): continue if isinstance(dep_gate.op, Barrier): continue fin_g = self.gate_start_time[gate] + self.gate_duration[gate] self.opt.add(self.gate_start_time[dep_gate] > fin_g) for g_1 in self.xtalk_overlap_set: for g_2 in self.xtalk_overlap_set[g_1]: if len(g_2.qargs ) == 2 and self.gate_id[g_1] > self.gate_id[g_2]: # Symmetry breaking: create only overlap variable for a pair # of gates continue s_1 = self.gate_start_time[g_1] f_1 = s_1 + self.gate_duration[g_1] s_2 = self.gate_start_time[g_2] f_2 = s_2 + self.gate_duration[g_2] # This constraint enforces full or zero overlap between two gates before = (f_1 < s_2) after = (f_2 < s_1) overlap1 = And(s_2 <= s_1, f_1 <= f_2) overlap2 = And(s_1 <= s_2, f_2 <= f_1) self.opt.add(Or(before, after, overlap1, overlap2)) intervals_overlap = And(s_2 <= f_1, s_1 <= f_2) self.opt.add( self.overlap_indicator[g_1][g_2] == intervals_overlap)
def add_nurikabe_constraints(sym, sg, rc): """Add the nurikabe constraints (one connected sea with no 2x2 regions).""" # There must be only one sea, containing all black cells. sea_id = Int("sea-id") for p in sg.lattice.points: sg.solver.add(sg.cell_is(p, sym.W) == (rc.region_id_grid[p] != sea_id)) # Constrain sea_id to be the index of one of the points in # the smallest area, among those areas of size greater than 4. area_to_points = defaultdict(list) for p in sg.lattice.points: area_to_points[AREAS[p.y][p.x]].append(p) area_points = min((ps for ps in area_to_points.values() if len(ps) > 4), key=len) sg.solver.add( Or(*[sea_id == sg.lattice.point_to_index(p) for p in area_points])) # The sea is not allowed to contain 2x2 areas of black cells. for sy in range(HEIGHT - 1): for sx in range(WIDTH - 1): pool_cells = [ sg.grid[Point(y, x)] for y in range(sy, sy + 2) for x in range(sx, sx + 2) ] sg.solver.add( Not(And(*[Not(cell == sym.W) for cell in pool_cells])))
def __add_shape_instance_constraints(self): # pylint: disable=R0914 int_vals = {} for i in range(max(len(self.__lattice.points), len(self.__variants))): int_vals[i] = IntVal(i) quadtree = ExpressionQuadTree(self.__lattice.points) for instance_id in [ self.__lattice.point_to_index(p) for p in self.__lattice.points ]: quadtree.add_expr((HAS_INSTANCE_ID, instance_id), lambda p, i=instance_id: fast_eq( self.__shape_instance_grid[p], int_vals[i])) quadtree.add_expr((NOT_HAS_INSTANCE_ID, instance_id), lambda p, i=instance_id: fast_ne( self.__shape_instance_grid[p], int_vals[i])) for shape_index in range(len(self.__variants)): quadtree.add_expr((HAS_SHAPE_TYPE, shape_index), lambda p, i=shape_index: fast_eq( self.__shape_type_grid[p], int_vals[i])) root_options = defaultdict(list) for shape_index, variants in enumerate(self.__variants): # pylint: disable=R1702 for variant in variants: for root_point in self.__lattice.points: instance_id = self.__lattice.point_to_index(root_point) point_payload_tuples = [] for offset_vector, payload in variant.offsets_with_payloads: point = root_point.translate(offset_vector) if point not in self.__shape_instance_grid: point_payload_tuples = None break point_payload_tuples.append((point, payload)) if point_payload_tuples: and_terms = [] for point, payload in point_payload_tuples: and_terms.append( quadtree.get_point_expr( (HAS_INSTANCE_ID, instance_id), point)) and_terms.append( quadtree.get_point_expr( (HAS_SHAPE_TYPE, shape_index), point)) if self.__shape_payload_grid: and_terms.append( self.__shape_payload_grid[point] == payload) and_terms.append( quadtree.get_other_points_expr( (NOT_HAS_INSTANCE_ID, instance_id), [t[0] for t in point_payload_tuples])) root_options[root_point].append(fast_and(*and_terms)) for p in self.__lattice.points: instance_id = self.__lattice.point_to_index(p) not_has_instance_id_expr = quadtree.get_other_points_expr( (NOT_HAS_INSTANCE_ID, instance_id), []) or_terms = root_options[p] if or_terms: or_terms.append(not_has_instance_id_expr) self.__solver.add(Or(*or_terms)) else: self.__solver.add(not_has_instance_id_expr)
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 create_random_query(num_functions=4, num_variables=5, num_clauses=4): # '(((a=x&b=y)&f(a,b,c)=g(a,b,c))&~f(a,b,c)=g(x,y,z)') uf = [UF("f{}".format(i), num_variables) for i in range(num_functions)] smt_vars = [SmtVar("a{}".format(i)) for i in range(num_variables)] str_clauses = [] z3_clauses = [] for _ in range(num_clauses): clause = smt_clause(uf, smt_vars) str_c, z3_c = clause.create_equality() str_clauses.append(str_c) z3_clauses.append(z3_c) str_clause = str_clauses[0] z3_clause = z3_clauses[0] for i in range(1, len(str_clauses)): op = choice(['&', '|'][:1]) if op == '&': z3_clause = And(z3_clause, z3_clauses[i]) else: z3_clause = Or(z3_clause, z3_clauses[i]) str_clause = f"({str_clause}{op}{str_clauses[i]})" return str_clause, z3_clause
def _get_components_in_quantified(cls, abs_targets, tr): untagged_in_vec, tag_input_vector = tr.get_input_vectors() new_state_vars = VarManager.duplicate_vars(tr.get_var_vectors()[0]) new_tag_in_vec = VarManager.duplicate_vars(tag_input_vector) new_untag_in_vec = VarManager.duplicate_vars(untagged_in_vec) abs_targets_sub = [ target.get_descriptive_formula().substitute_inputs( new_tag_in_vec, 0).substitute(new_state_vars, 0).renew_quantifiers() for target in abs_targets ] abs_or = Or(*[_t.get_qbf().get_prop() for _t in abs_targets_sub]) new_q_list = [ _v for _t in abs_targets_sub for _v in _t.get_qbf().get_q_list() ] split_by_formula_tag = FormulaWrapper(QBF(abs_or, new_q_list), [new_state_vars], [new_tag_in_vec]) ## RENAME QUNATIFIED HERE transitions_has_sons = tr.substitute(new_state_vars, 1) \ .substitute_inputs(new_untag_in_vec, 0) \ .substitute_inputs(new_tag_in_vec, 1) # R(u,v) [v<-v'] return split_by_formula_tag, transitions_has_sons
def any_overlap(ranges): predicates = [] already_checked = [] for r1 in ranges: for r2 in already_checked: predicates.append(overlap(r1, r2)) already_checked.append(r1) return Or(predicates)
def has_token(x_list, j): """ Generate a Z3 Boolean expression that represents whether P_j holds the token :param x_list: list of Z3 variables :param j: index of P_j :return: Z3 Boolean expression that if true then P_j is holding the token """ return Or(And(j==0, x_list[0]==x_list[-1]), And(j!=0, x_list[j]!=x_list[j-1]))
def add_clause(self, C): # C = map(neg, C) # self.stream.write("%s 0\n" %" ".join(map(str,C))) f = Or([self.literal(x) for x in C]) self.__solver.add(f) self.stream.write("(assert (or %s))\n" % (' '.join([self.literal_str(x) for x in C]))) self.num_cls += 1
def sort_no_duplicates(z3_int_list): """Sort a list of integers that have distinct values""" n = len(z3_int_list) a = [FreshInt() for i in range(n)] constraints = [Or([a[i] == z3_int_list[j] for j in range(n)]) for i in range(n)] constraints.append(And([a[i] < a[i + 1] for i in range(n - 1)])) return a, constraints
def c(attr): values = v.values(id) if isinstance(values, range): return And(attr >= values.start, attr < values.stop) elif isinstance(values, list): return Or(*(attr == int(x) for x in values)) else: return (attr == int(values))
def __add_grid_agreement_constraints(self): for p in self.__shape_type_grid: self.__solver.add( Or( fast_and(self.__shape_type_grid[p] == -1, self.__shape_instance_grid[p] == -1), fast_and(self.__shape_type_grid[p] != -1, self.__shape_instance_grid[p] != -1)))
def addDistinctRule(myBools, x, numColors, graph): n = len(graph.items()) for i in range(0, n): # each row for c in range(0, numColors): # each color for c2 in range(c + 1, numColors): # each color x.add(Or(Not(myBools[i][c]), Not(myBools[i][c2]))) # this cell cant be both these colors return x
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 myBinOp(op, *L): """ Shortcut to apply operation op to a list L. Returns None if the list is empty. E.g. applying 'And' over a list of formulas f1,f2..,fn yields And(f1,f2,...,fn). >>> from z3 import * >>> myAnd(*[Bool('x'),Bool('y')]) And(x, y) >>> myAnd(*[Bool('x'),None]) x >>> myAnd(*[Bool('x')]) x >>> myAnd(*[]) >>> myAnd(Bool('x'),Bool('y')) And(x, y) >>> myAnd(*[Bool('x'),Bool('y')]) And(x, y) >>> myAnd([Bool('x'),Bool('y')]) And(x, y) >>> myAnd((Bool('x'),Bool('y'))) And(x, y) >>> myAnd(*[Bool('x'),Bool('y'),True]) Traceback (most recent call last): ... AssertionError """ assert op == Z3_OP_OR or op == Z3_OP_AND or op == Z3_OP_IMPLIES if len(L) == 1 and (isinstance(L[0], list) or isinstance(L[0], tuple)): L = L[0] assert all(not isinstance(l, bool) for l in L) L = [l for l in L if is_expr(l)] if L: if len(L) == 1: return L[0] else: if op == Z3_OP_OR: return Or(L) elif op == Z3_OP_AND: return And(L) else: #IMPLIES return Implies(L[0], L[1]) else: return None
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 addAdjacentRule(myBools, x, numColors, graph): n = len(graph.items()) for i in range(0, n): # each row for j in range(0, len(graph[i])): for c in range(0, numColors): # each color if i < graph[i][j]: x.add(Or(Not(myBools[i][c]), Not(myBools[graph[i][j]][c]))) # this cell cant be both these colors return x
def is_consistent(self): return [ Or( self.size == 0, And(ULT(self.start, self.end), is_pow_of_2(self.size), self.size % self.hw_config.subregion_count == 0, self.start % self.size == 0, UGE(self.size, self.hw_config.region_min_size))) ]
def pick_exactly_one(indicators): """return constraints choosing exactly one of several options""" some_value = Or(*indicators) K = len(indicators) unique_value = [ Not(And(indicators[j], indicators[i])) for i in range(K) for j in range(i + 1, K) ] return [some_value] + unique_value
def exhaust_models(solver, variables): while solver.check() == sat: model = solver.model() yield model blocker = [] for var in variables: blocker.append(var != model.eval(var)) solver.add(Or(*blocker))
def solve_z3(self): print("[+] {}".format("Sovling using Z3\n")) symbols = {e: Int(e) for e in self.elements} # first we build a solver with the general constraints for sudoku puzzles: s = Solver() # assure that every cell holds a value of [1,9] for symbol in symbols.values(): s.add(Or([symbol == int(i) for i in self.cols])) # assure that every row covers every value: for row in "ABCDEFGHI": s.add(Distinct([symbols[row + col] for col in "123456789"])) # assure that every column covers every value: for col in "123456789": s.add(Distinct([symbols[row + col] for row in "ABCDEFGHI"])) # assure that every block covers every value: for i in range(3): for j in range(3): s.add( Distinct([ symbols["ABCDEFGHI"[m + i * 3] + "123456789"[n + j * 3]] for m in range(3) for n in range(3) ])) # adding sum constraints if provided if self.constraints is not None: print("[+] {}\n{}".format("Applying constraints", self.constraints)) sum_constr = self.get_constraints() for c in sum_constr: expr = [] for i in c[0]: expr.append("symbols['" + i + "']") s.add(eval("+".join(expr) + "==" + str(c[1]))) # now we put the assumptions of the given puzzle into the solver: for elem, value in self.values.items(): if value in "123456789": s.add(symbols[elem] == value) if not s.check() == sat: raise Exception("Unsolvable") model = s.model() values = {e: model.evaluate(s).as_string() for e, s in symbols.items()} self.solution = values
def __init__( self, worker, distance: int, time_periods: Optional[list] = None, optional: Optional[bool] = False, mode: Optional[str] = "exact", ): if mode not in {"min", "max", "exact"}: raise Exception("Mode should be min, max or exact") super().__init__(optional) starts = [] ends = [] for start_var, end_var in worker.busy_intervals.values(): starts.append(start_var) ends.append(end_var) # sort both lists sorted_starts, c1 = sort_no_duplicates(starts) sorted_ends, c2 = sort_no_duplicates(ends) for c in c1 + c2: self.set_assertions(c) # from now, starts and ends are sorted in asc order # the space between two consecutive tasks is the sorted_start[i+1]-sorted_end[i] # we just have to constraint this variable for i in range(1, len(sorted_starts)): if mode == "min": asst = sorted_starts[i] - sorted_ends[i - 1] >= distance elif mode == "max": asst = sorted_starts[i] - sorted_ends[i - 1] <= distance elif mode == "exact": asst = sorted_starts[i] - sorted_ends[i - 1] == distance # another set of conditions, related to the time periods conditions = [] if time_periods is not None: for ( lower_bound, upper_bound, ) in time_periods: # time_period should be a list also or a tuple conditions.append( And( sorted_starts[i] >= lower_bound, sorted_ends[i - 1] >= lower_bound, sorted_starts[i] <= upper_bound, sorted_ends[i - 1] <= upper_bound, )) else: # add the constraint only if start and ends are positive integers, # that is to say they correspond to a scheduled optional task condition_only_scheduled_tasks = And(sorted_ends[i - 1] >= 0, sorted_starts[i] >= 0) conditions = [condition_only_scheduled_tasks] # finally create the constraint new_cstr = Implies(Or(conditions), asst) self.set_assertions(new_cstr)
def __add_loop_edge_constraints(self): solver = self.__symbol_grid.solver sym: LoopSymbolSet = self.__symbol_grid.symbol_set for p, cell in self.__symbol_grid.grid.items(): for _, d in self.__symbol_grid.lattice.edge_sharing_directions(): np = p.translate(d) dir_syms = sym.symbols_for_direction(d) ncell = self.__symbol_grid.grid.get(np, None) if ncell is not None: opposite_syms = sym.symbols_for_direction(d.negate()) cell_points_dir = Or(*[cell == s for s in dir_syms]) neighbor_points_opposite = Or( *[ncell == s for s in opposite_syms]) solver.add( Implies(cell_points_dir, neighbor_points_opposite)) else: for s in dir_syms: solver.add(cell != s)
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 condense(products, num_split): currIndex = 0 while len(products) > num_split: lastCon = products.pop() products[currIndex] = products[currIndex] + lastCon currIndex = currIndex + 1 if currIndex == num_split: currIndex = 0 products = [Or(*i) for i in products] return products