Beispiel #1
0
    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)
Beispiel #2
0
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')
Beispiel #3
0
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)
Beispiel #4
0
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
Beispiel #5
0
    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)
Beispiel #6
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)