def add_containment_axioms(self, solver: z3.Optimize, confIdx: int, parent: IView[NT], x_dim: bool) -> None: pl, pr = anchor_id_to_z3_var(parent.left_anchor.id, confIdx), anchor_id_to_z3_var( parent.right_anchor.id, confIdx) pt, pb = anchor_id_to_z3_var(parent.top_anchor.id, confIdx), anchor_id_to_z3_var( parent.bottom_anchor.id, confIdx) for child in parent.children: cl, cr = anchor_id_to_z3_var(child.left_anchor.id, confIdx), anchor_id_to_z3_var( child.right_anchor.id, confIdx) ct, cb = anchor_id_to_z3_var(child.top_anchor.id, confIdx), anchor_id_to_z3_var( child.bottom_anchor.id, confIdx) # if child.left_anchor.value >= parent.left_anchor.value: if x_dim: solver.add(cl >= pl) # if child.right_anchor.value <= parent.right_anchor.value: solver.add(cr <= pr) # if child.top_anchor.value >= parent.top_anchor.value: else: solver.add(ct >= pt) # if child.bottom_anchor.value <= parent.bottom_anchor.value: solver.add(cb <= pb) self.add_containment_axioms(solver, confIdx, child, x_dim)
def evalOthers(toRun, name, makeSpec, checkFunc): print(name) lineLengths = toRun.copy() gamutSizes = toRun.copy() tasks = list(itertools.product(lineLengths, gamutSizes)) results = [] print(tasks) res = [] for (length, gamut) in tasks: try: print((length, gamut)) s = cantusSpec(length, gamut, '') opt = Optimize() for c in s.constraints: opt.add(c.formula) checked, _ = timeWithTimeout(lambda: opt.check(), 10) if (checked == sat): cf = [extractPitch(opt.model(), p) for p in s.line] res += doCheck( makeSpec([ConstPitch(x) for x in cf], gamut, ''), lambda x: checkFunc(cf, x), length, gamut, name) except Exception: pass dt = str(datetime.datetime.now()) out = pd.DataFrame(columns=['length', 'gamut', 'mutations', 'time'], data=res) out.to_csv('output/checker/' + name + '/time_' + dt + '.csv')
def add_conf_dims(solver: z3.Optimize, conf: Conformance, confIdx: int, targets: Tuple[IAnchor[NT],IAnchor[NT],IAnchor[NT],IAnchor[NT]]) -> None: top_x, top_y, top_width, top_height = targets top_x_v = anchor_id_to_z3_var(top_x.id, confIdx) top_y_v = anchor_id_to_z3_var(top_y.id, confIdx) top_w_v = anchor_id_to_z3_var(top_width.id, confIdx) top_h_v = anchor_id_to_z3_var(top_height.id, confIdx) solver.add(top_w_v == conf.width) solver.add(top_h_v == conf.height) solver.add(top_x_v == conf.x) solver.add(top_y_v == conf.y)
def doRepair(spec: Spec, check, length, gamut, name): specs = getAllBadSpecs( spec=spec, maxCount=5, doShuffle=True, filterOutUnsatisfiable=False) + [spec] ret = [] for s in specs: numMutations = sum( [1 if 'inverse' in str(x) else 0 for x in s.constraints]) # Using this rather than generator because generator is increadibly slow in this # context for some reason opt = Optimize() for c in s.constraints: opt.add(c.formula) checked, _ = timeWithTimeout(lambda: opt.check(), 10) if (checked == sat): line = [extractPitch(opt.model(), p) for p in s.line] res, runtime = timeWithTimeout(lambda: check(line), 10) if res is not None: ret.append((length, gamut, numMutations, runtime)) return ret
def add_layout_axioms(self, solver: z3.Optimize, confIdx: int, boxes: Iterable[IView[NT]], x_dim: bool, tracking: bool = False) -> None: for box in boxes: w, h = anchor_id_to_z3_var(box.width_anchor.id, confIdx), \ anchor_id_to_z3_var(box.height_anchor.id, confIdx) l, r = anchor_id_to_z3_var(box.left_anchor.id, confIdx), \ anchor_id_to_z3_var(box.right_anchor.id, confIdx) t, b = anchor_id_to_z3_var(box.top_anchor.id, confIdx), \ anchor_id_to_z3_var(box.bottom_anchor.id, confIdx) c_x = anchor_id_to_z3_var(box.center_x_anchor.id, confIdx) c_y = anchor_id_to_z3_var(box.center_y_anchor.id, confIdx) widthAx = w == (r - l) heightAx = h == (b - t) # print('adding axioms:', widthAx, heightAx, w>=0, h >= 0) if tracking: if x_dim: raise Exception('unimplemented') solver.assert_and_track(widthAx, f'{box.name}-wax-{str(confIdx)}') solver.assert_and_track(heightAx, f'{box.name}-hax-{str(confIdx)}') solver.assert_and_track(c_x == (l + r) / 2, f'{box.name}-cx-{str(confIdx)}') solver.assert_and_track(c_y == (t + b) / 2, f'{box.name}-cy-{str(confIdx)}') for idx, anchor in enumerate(box.anchors): solver.assert_and_track( anchor_id_to_z3_var(anchor.id, confIdx) >= 0, f'{box.name}-pos-{str(confIdx)}-{str(idx)}') else: if x_dim: solver.add(widthAx) solver.add(c_x == (l + r) / 2) for anchor in box.x_anchors: solver.add( anchor_id_to_z3_var(anchor.id, confIdx) >= 0) else: solver.add(heightAx) solver.add(c_y == (t + b) / 2) for anchor in box.y_anchors: solver.add( anchor_id_to_z3_var(anchor.id, confIdx) >= 0)
def solve(grid_size_x, grid_size_y, max_height, robots, depots, i_grid, g_grid, timeout=100000): i_grid = deepcopy(i_grid) #print ("Solving: ", grid_size_x, grid_size_y, max_height, robots, depots, i_grid, g_grid) assert(grid_size_y == len(i_grid)) adjacent = defaultdict(list) # A cell X is supporter of another Y if we will use X in order to access Y for x in range(grid_size_x): for y in range (grid_size_y): if x > 0: adjacent [(x, y)].append((x-1, y)) if y > 0: adjacent [(x, y)].append((x, y-1)) if x < grid_size_x - 1: adjacent [(x, y)].append((x+1, y)) if y < grid_size_y - 1: adjacent [(x, y)].append((x, y+1)) intermediate_board=[[Int('intermediate%d-%d' % (c, r)) for c in range(grid_size_x)] for r in range(grid_size_y)] target_board=[[Int('target%d-%d' % (c, r)) for c in range(grid_size_x)] for r in range(grid_size_y)] order=[[Int('order%d-%d' % (c, r)) for c in range(grid_size_x)] for r in range(grid_size_y)] is_supporter=[[Bool('supporter%d-%d' % (c, r)) for c in range(grid_size_x)] for r in range(grid_size_y)] is_supported=[[Bool('supported%d-%d' % (c, r)) for c in range(grid_size_x)] for r in range(grid_size_y)] supporter_variables = {} for x in range(grid_size_x): for y in range (grid_size_y): for (xp, yp) in adjacent[(x,y)]: supporter_variables[(x, y, xp, yp)] = Bool('supporter%d-%d-%d-%d' % (x, y, xp, yp)) all_intermediate_board = [cell for column in intermediate_board for cell in column ] s = Optimize() #s.set("timeout", timeout) for (y, row) in enumerate(g_grid): for (x, tile) in enumerate (row): if (x, y) in depots: s.add (intermediate_board[y][x] == 0) # The depot location must always have height 0 s.add (order[y][x] == 0) # The depot location must always have order 0 else: s.add (order[y][x] > 0) s.add (target_board[y][x] == tile) s.add(intermediate_board[y][x] <= max_height) # Intermediate_Board cannot have more height than max_height s.add(intermediate_board[y][x] >= max(tile, i_grid[y][x])) # Intermediate_Board cannot have negative height # All intermediate_board supporter or greater than 0 must have a supporter s.add(Implies(intermediate_board[y][x] > 0, is_supported[y][x] == True)) s.add (is_supported[y][x] == Or (*[supporter_variables[(x, y, xp, yp)] == True for (xp, yp) in adjacent[(x, y)]])) s.add (is_supporter[y][x] == Or (*[supporter_variables[(xp, yp, x, y)] == True for (xp, yp) in adjacent[(x, y)]])) s.add (Implies(is_supporter[y][x], is_supported[y][x])) for (xp, yp) in adjacent[(x, y)]: # A cell cannot support its supporter (there is a total order of supporters) s.add(Implies(supporter_variables[(x, y, xp, yp)], order[yp][xp] < order[y][x])) # The supporter must give access to the cell s.add(Or(supporter_variables[(x, y, xp, yp)] == False, intermediate_board[y][x] == intermediate_board[yp][xp], intermediate_board[y][x] == intermediate_board[yp][xp] + 1)) # The supporter must give access to remove the cell s.add(Implies(supporter_variables[(x, y, xp, yp)], target_board[y][x] >= target_board[yp][xp])) #s.add(Or(is_supporter[y][x] == False, is_supported[y][x] == False, is_supporter[yp][xp] == False, is_supported[yp][xp] == False, order[y][x] == order[yp][xp], order[y][x] == order[yp][xp] + 1, order[y][x] == order[yp][xp] - 1)) #s.add (intermediate_board[0][0] == 0) h=s.minimize(Sum(*all_intermediate_board)*1000 + Sum([cell for column in order for cell in column ])) s_result = s.check() # print(s) # print(s_result) if str(s_result).strip() == "unsat": #print(s) exit() return None m = s.model() # for r in range(grid_size_y): # sys.stdout.write ("; ") # for c in range(grid_size_x): # sys.stdout.write (str(m[cells[r][c]])+" ") # print ("") target_grid = [[int(m[intermediate_board[r][c]].as_long()) for c in range(grid_size_x)] for r in range(grid_size_y)] order_grid = [[int(m[order[r][c]].as_long()) for c in range(grid_size_x)] for r in range(grid_size_y)] # print ("Init:") # print_grid(i_grid) # print ("Target:") # print_grid(target_grid) # print ("Goal:") # print_grid(g_grid) # print ("Order:") # print_grid(order_grid) # for x in range(grid_size_x): # for y in range (grid_size_y): # for (xp, yp) in adjacent[(x, y)]: # if m[supporter_variables[(x, y, xp, yp)]]: # print ((x, y), " is supported by ", (xp, yp)) # exit() depot_loc = get_location(*depots[0]) plan = [] while i_grid != target_grid: # Pick lowest position that is different. In case of tie, pick the one highest in order different_positions = [(x, y) for x in range(grid_size_x) for y in range (grid_size_y) if i_grid[y][x] < target_grid[y][x] if accessible(i_grid, x, y, True)] if not different_positions: print ("Error: I cannot place the next position") print_grid(i_grid) print () print_grid(target_grid) exit() (x, y) = min(different_positions, key=lambda p : (i_grid[p[1]][p[0]], -order_grid[p[1]][p[0]])) plan.append("(create-block {})".format(depot_loc)) path = get_shortest_path(i_grid, depots[0], (x, y), True, order_grid) if not path: return None prev_loc = path[0] for loc in path[1:-1]: plan.append(move(i_grid, prev_loc, loc)) prev_loc = loc plan.append(place_block(i_grid, path[-2], path[-1])) for loc in path[::-1][2:]: plan.append(move(i_grid, prev_loc, loc)) prev_loc = loc i_grid[y][x] += 1 while i_grid != g_grid: # Pick highest position that is different different_positions = [(x, y) for x in range(grid_size_x) for y in range (grid_size_y) if i_grid[y][x] != g_grid[y][x] if accessible(i_grid, x, y, False)] if not different_positions: print ("Error: I cannot remove a block from the next position") print_grid(i_grid) print () print_grid(g_grid) exit() (x, y) = max(different_positions, key=lambda p : (i_grid[p[1]][p[0]], -order_grid[p[1]][p[0]])) # print("Current grid") # print_grid(i_grid) # print("Goal grid") # print_grid(g_grid) # print("Candidates: ", different_positions) # print ("Remove", (x, y)) path = get_shortest_path(i_grid, depots[0], (x, y), False, order_grid) if not path: return None prev_loc = path[0] for loc in path[1:-1]: plan.append(move(i_grid, prev_loc, loc)) prev_loc = loc plan.append(remove_block(i_grid, path[-2], path[-1])) for loc in path[::-1][2:]: plan.append(move(i_grid, prev_loc, loc)) prev_loc = loc i_grid[y][x] -= 1 plan.append("(destroy-block {})".format(depot_loc)) while plan[-1].startswith("(move"): plan.pop() return (plan)