예제 #1
0
def simple_trans_row_len3():
    return Tiling(obstructions=[Obstruction(Perm((0, 1)), [(0, 0), (1, 0)]),
                                Obstruction(Perm((0, 1)), [(1, 0), (2, 0)]),
                                Obstruction(Perm((0, 1)), [(2, 0), (3, 0)]),
                                Obstruction(Perm((0, 1)), [(3, 0), (4, 0)])],
                  requirements=[[Requirement(Perm((0,)), [(1, 0)])],
                                [Requirement(Perm((0,)), [(2, 0)])],
                                [Requirement(Perm((0,)), [(3, 0)])]])
예제 #2
0
    def __init__(self, avoids=tuple(), contains=tuple(), tiling=None):
        if tiling is not None and isinstance(tiling, Tiling):
            self.tiling = tiling
        else:
            obs, reqs = stretch_av_and_co(avoids, contains, [(0, 1), (1, 0)])
            reqs.extend([[Requirement.single_cell(Perm((0,)), (0, 1))],
                         [Requirement.single_cell(Perm((0,)), (1, 0))]])

            self.tiling = Tiling(obs, reqs)
예제 #3
0
def all_requirement_insertions(tiling, **kwargs):
    """Insert all possible requirements the obstruction allow."""
    if kwargs.get("no_reqs", True) and tiling.requirements:
        return
    maxlen = kwargs.get("maxlen", 2)
    ignore_parent = kwargs.get("ignore_parent", False)
    obs_tiling = Tiling(tiling.obstructions,
                        remove_empty=False,
                        derive_empty=False,
                        minimize=False,
                        sorted_input=True)
    for length in range(1, maxlen + 1):
        for gp in obs_tiling.gridded_perms_of_length(length):
            if len(gp.factors()) == 1:
                av = Tiling(
                    (tiling.obstructions + (Obstruction(gp.patt, gp.pos), )),
                    tiling.requirements)
                co = Tiling(tiling.obstructions, (tiling.requirements) +
                            ((Requirement(gp.patt, gp.pos), ), ))
                yield Rule(formal_step="Insert {}.".format(str(gp)),
                           comb_classes=[av, co],
                           ignore_parent=ignore_parent,
                           inferable=[True for _ in range(2)],
                           possibly_empty=[True for _ in range(2)],
                           workable=[True for _ in range(2)],
                           constructor='disjoint')
예제 #4
0
def no_point_tiling():
    """Returns a simple tiling with length of all obs and reqs at least 2. """
    return Tiling(obstructions=[
        Obstruction(Perm((1, 0)), [(0, 1), (0, 1)]),
        Obstruction(Perm((0, 1, 2)), [(0, 0), (1, 0), (1, 0)]),
        Obstruction(Perm((0, 1, 2)), [(1, 0), (1, 0), (2, 0)]),
        Obstruction(Perm((0, 2, 1)), [(0, 2), (0, 2), (1, 2)]),
        Obstruction(Perm((0, 2, 1)), [(0, 2), (1, 2), (1, 2)])
    ],
                  requirements=[[
                      Requirement(Perm((0, 1)), [(0, 0), (0, 0)]),
                      Requirement(Perm((0, 1)), [(0, 0), (2, 0)])
                  ], [Requirement(Perm((0, 2, 1)), [(0, 1), (1, 1), (1, 1)])],
                                [
                                    Requirement(Perm((0, 1)), [(1, 1),
                                                               (2, 1)]),
                                    Requirement(Perm((0, 1)), [(1, 1), (2, 2)])
                                ]])
예제 #5
0
def diverse_tiling():
    """Returns a simple, but diverse tiling.

    The tiling has positive, possibly empty and empty cells and also few
    requirements and a long obstructions."""
    return Tiling(obstructions=[
        Obstruction(Perm((0, 2, 3, 1)), [(0, 0), (1, 1), (1, 1), (2, 0)]),
        Obstruction(Perm((0, 1)), [(1, 0), (1, 0)]),
        Obstruction(Perm((1, 0)), [(1, 0), (1, 0)]),
        Obstruction(Perm((0, 1)), [(2, 1), (2, 1)]),
        Obstruction(Perm((1, 0)), [(2, 1), (2, 1)])
    ],
                  requirements=[[
                      Requirement(Perm((0, 2, 1)), [(0, 1), (0, 2), (1, 2)]),
                      Requirement(Perm((1, 0)), [(0, 2), (0, 1)])
                  ], [Requirement(Perm((0, )), [(1, 0)])],
                                [Requirement(Perm((0, )), [(2, 0)])],
                                [Requirement(Perm((0, )), [(2, 1)])]])
예제 #6
0
def test_factor_no_unions(simple_tiling, diverse_tiling, no_point_tiling):
    assert len(list(factor(simple_tiling))) == 0
    assert len(list(factor(diverse_tiling))) == 0
    tiling = Tiling(obstructions=[Obstruction(Perm((0, 1)), [(0, 0), (0, 0)])],
                    requirements=[[
                        Requirement(Perm((0, 1)), [(1, 1), (1, 1)]),
                        Requirement(Perm((0, 1)), [(1, 1), (1, 2)])
                    ]])
    strats = [s.comb_classes for s in factor(tiling)]
    assert len(strats) == 1
    factors = strats[0]
    assert set(factors) == set([
        Tiling(requirements=[[
            Requirement(Perm((0, 1)), [(0, 0), (0, 0)]),
            Requirement(Perm((0, 1)), [(0, 0), (0, 1)])
        ]]),
        Tiling(obstructions=[Obstruction(Perm((0, 1)), [(0, 0), (0, 0)])])
    ])

    strats = [
        s.comb_classes for s in factor(diverse_tiling, interleaving=True)
    ]
    assert len(strats) == 1
    factors = strats[0]
    assert len(factors) == 4
    print(diverse_tiling)

    assert set(factors) == set([
        Tiling(obstructions=[
            Obstruction(Perm((0, 2, 3, 1)), [(0, 0), (1, 1), (1, 1), (2, 0)])
        ],
               requirements=[[Requirement(Perm((0, )), [(2, 0)])]]),
        Tiling(obstructions=[
            Obstruction(Perm((0, 1)), [(0, 0), (0, 0)]),
            Obstruction(Perm((1, 0)), [(0, 0), (0, 0)])
        ],
               requirements=[[Requirement(Perm((0, )), [(0, 0)])]]),
        Tiling(obstructions=[
            Obstruction(Perm((0, 1)), [(0, 0), (0, 0)]),
            Obstruction(Perm((1, 0)), [(0, 0), (0, 0)])
        ],
               requirements=[[Requirement(Perm((0, )), [(0, 0)])]]),
        Tiling(requirements=[[
            Requirement(Perm((1, 0)), [(0, 2), (0, 1)]),
            Requirement(Perm((0, 2, 1)), [(0, 1), (0, 2), (1, 2)])
        ]])
    ])
예제 #7
0
 def __init__(self, perm=Perm(), avoids=tuple(), contains=tuple(),
              tiling=None):
     if tiling is not None and isinstance(tiling, Tiling):
         self.tiling = tiling
     else:
         if not isinstance(perm, Perm) or not perm.is_simple():
             raise ValueError("The first argument must be a simple Perm.")
         cells = [(i, v) for i, v in enumerate(perm)]
         obs, reqs = stretch_av_and_co(avoids, contains, cells)
         reqs.extend([[Requirement.single_cell(Perm((0,)), cell)]
                      for cell in cells])
         self.tiling = Tiling(obs, reqs)
예제 #8
0
def test_obstruction_transitivity(simple_trans_row, simple_trans_col,
                                  simple_trans_row_len2,
                                  simple_trans_row_len3):
    strat = obstruction_transitivity(simple_trans_row)
    assert strat.comb_classes[0] == Tiling(
        obstructions=[
            Obstruction(Perm((0, 1)), [(0, 0), (1, 0)]),
            Obstruction(Perm((0, 1)), [(1, 0), (2, 0)]),
            Obstruction(Perm((0, 1)), [(0, 0), (2, 0)])
        ],
        requirements=[[Requirement(Perm((0, )), [(1, 0)])]])

    strat = obstruction_transitivity(simple_trans_col)
    assert strat.comb_classes[0] == Tiling(
        obstructions=[
            Obstruction(Perm((0, 1)), [(0, 0), (0, 1)]),
            Obstruction(Perm((0, 1)), [(0, 1), (0, 2)]),
            Obstruction(Perm((0, 1)), [(0, 0), (0, 2)])
        ],
        requirements=[[Requirement(Perm((0, )), [(0, 1)])]])

    strat = obstruction_transitivity(simple_trans_row_len2)
    assert strat.comb_classes[0] == Tiling(
        obstructions=[
            Obstruction(Perm((0, 1)), [(0, 0), (1, 0)]),
            Obstruction(Perm((0, 1)), [(0, 0), (2, 0)]),
            Obstruction(Perm((0, 1)), [(0, 0), (3, 0)]),
            Obstruction(Perm((0, 1)), [(1, 0), (2, 0)]),
            Obstruction(Perm((0, 1)), [(1, 0), (3, 0)]),
            Obstruction(Perm((0, 1)), [(2, 0), (3, 0)])
        ],
        requirements=[[Requirement(Perm((0, )), [(1, 0)])],
                      [Requirement(Perm((0, )), [(2, 0)])]])

    strat = obstruction_transitivity(simple_trans_row_len3)
    assert strat.comb_classes[0] == Tiling(
        obstructions=[
            Obstruction(Perm((0, 1)), [(0, 0), (1, 0)]),
            Obstruction(Perm((0, 1)), [(0, 0), (2, 0)]),
            Obstruction(Perm((0, 1)), [(0, 0), (3, 0)]),
            Obstruction(Perm((0, 1)), [(0, 0), (4, 0)]),
            Obstruction(Perm((0, 1)), [(1, 0), (2, 0)]),
            Obstruction(Perm((0, 1)), [(1, 0), (3, 0)]),
            Obstruction(Perm((0, 1)), [(1, 0), (4, 0)]),
            Obstruction(Perm((0, 1)), [(2, 0), (3, 0)]),
            Obstruction(Perm((0, 1)), [(2, 0), (4, 0)]),
            Obstruction(Perm((0, 1)), [(3, 0), (4, 0)])
        ],
        requirements=[[Requirement(Perm((0, )), [(1, 0)])],
                      [Requirement(Perm((0, )), [(2, 0)])],
                      [Requirement(Perm((0, )), [(3, 0)])]])
예제 #9
0
def all_factor_insertions(tiling, **kwargs):
    ignore_parent = kwargs.get("ignore_parent", False)
    for gp in sorted(set(chain(tiling.obstructions, *tiling.requirements))):
        factors = gp.factors()
        if len(factors) != 1:
            for gp in factors:
                av = Tiling(
                    (tiling.obstructions + (Obstruction(gp.patt, gp.pos), )),
                    tiling.requirements)
                co = Tiling(tiling.obstructions, (tiling.requirements) +
                            ((Requirement(gp.patt, gp.pos), ), ))
                yield Rule(formal_step="Insert {}.".format(str(gp)),
                           comb_classes=[av, co],
                           ignore_parent=ignore_parent,
                           inferable=[True for _ in range(2)],
                           possibly_empty=[True for _ in range(2)],
                           workable=[True for _ in range(2)],
                           constructor='disjoint')
예제 #10
0
def col_insertion_helper(tiling, col, col_cells, regions=False):
    if col_cells is None:
        col_cells = tiling.cells_in_col(col)
    col_req = tuple(Requirement.single_cell(Perm((0, )), c) for c in col_cells)
    col_obs = tuple(Obstruction.single_cell(Perm((0, )), c) for c in col_cells)
    if regions:
        return ([
            Tiling(tiling.obstructions + col_obs, tiling.requirements),
            Tiling(tiling.obstructions, tiling.requirements + (col_req, ))
        ], [{c: frozenset([c])
             for c in tiling.active_cells},
            {c: frozenset([c])
             for c in tiling.active_cells}])
    else:
        return [
            Tiling(tiling.obstructions + col_obs, tiling.requirements),
            Tiling(tiling.obstructions, tiling.requirements + (col_req, ))
        ]
예제 #11
0
def row_insertion_helper(tiling, row, row_cells, regions=False):
    if row_cells is None:
        row_cells = tiling.cells_in_row(row)
    row_req = tuple(Requirement.single_cell(Perm((0, )), c) for c in row_cells)
    row_obs = tuple(Obstruction.single_cell(Perm((0, )), c) for c in row_cells)
    if regions:
        return ([
            Tiling(tiling.obstructions + row_obs, tiling.requirements),
            Tiling(tiling.obstructions, tiling.requirements + (row_req, ))
        ], [{c: frozenset([c])
             for c in tiling.active_cells},
            {c: frozenset([c])
             for c in tiling.active_cells}])
    else:
        return [
            Tiling(tiling.obstructions + row_obs, tiling.requirements),
            Tiling(tiling.obstructions, tiling.requirements + (row_req, ))
        ]
예제 #12
0
def test_all_cell_insertions(typical_redundant_requirements,
                             typical_redundant_obstructions):
    tiling = Tiling(obstructions=typical_redundant_obstructions,
                    requirements=typical_redundant_requirements)
    strats = list(all_cell_insertions(tiling, maxreqlen=3))
    assert all(len(s.comb_classes) == 2 for s in strats)
    s = strats[-1]
    print(tiling)
    print(s.formal_step)
    print(s.comb_classes[0])
    print(s.comb_classes[1])
    assert s.comb_classes[0] == Tiling(
        obstructions=typical_redundant_obstructions +
        [Obstruction(Perm((0, 1, 2)), [(0, 1), (0, 1), (0, 1)])],
        requirements=typical_redundant_requirements)
    assert s.comb_classes[1] == Tiling(
        obstructions=typical_redundant_obstructions,
        requirements=typical_redundant_requirements +
        [[Requirement(Perm((0, 1, 2)), [(0, 1), (0, 1), (0, 1)])]])
예제 #13
0
def test_place_point_of_requirement(no_point_tiling):
    tiling = place_point_of_requirement(no_point_tiling, 2, 1, DIR_WEST)
    tiling2 = Tiling(
        obstructions=[
            Obstruction(Perm((0, 1)), [(0, 1), (1, 3)]),
            Obstruction(Perm((0, 1)), [(2, 2), (2, 2)]),
            Obstruction(Perm((1, 0)), [(0, 1), (0, 1)]),
            Obstruction(Perm((1, 0)), [(0, 3), (0, 1)]),
            Obstruction(Perm((1, 0)), [(0, 3), (0, 3)]),
            Obstruction(Perm((1, 0)), [(2, 2), (2, 2)]),
            Obstruction(Perm((0, 1, 2)), [(0, 0), (1, 0), (1, 0)]),
            Obstruction(Perm((0, 1, 2)), [(0, 0), (1, 0), (3, 0)]),
            Obstruction(Perm((0, 1, 2)), [(0, 0), (3, 0), (3, 0)]),
            Obstruction(Perm((0, 1, 2)), [(1, 0), (1, 0), (4, 0)]),
            Obstruction(Perm((0, 1, 2)), [(1, 0), (3, 0), (4, 0)]),
            Obstruction(Perm((0, 1, 2)), [(3, 0), (3, 0), (4, 0)]),
            Obstruction(Perm((0, 2, 1)), [(0, 1), (1, 1), (1, 1)]),
            Obstruction(Perm((0, 2, 1)), [(0, 1), (1, 1), (3, 1)]),
            Obstruction(Perm((0, 2, 1)), [(0, 3), (1, 3), (1, 3)]),
            Obstruction(Perm((0, 2, 1)), [(0, 3), (1, 3), (3, 3)]),
            Obstruction(Perm((0, 2, 1)), [(0, 4), (0, 4), (1, 4)]),
            Obstruction(Perm((0, 2, 1)), [(0, 4), (0, 4), (3, 4)]),
            Obstruction(Perm((0, 2, 1)), [(0, 4), (1, 4), (1, 4)]),
            Obstruction(Perm((0, 2, 1)), [(0, 4), (1, 4), (3, 4)]),
            Obstruction(Perm((0, 2, 1)), [(0, 4), (3, 4), (3, 4)])
        ],
        requirements=[[Requirement(Perm((0, )), [(2, 2)])],
                      [
                          Requirement(Perm((0, 1)),
                                      [(0, 0), (0, 0)]),
                          Requirement(Perm((0, 1)), [(0, 0), (4, 0)])
                      ], [Requirement(Perm((0, 1)), [(0, 1), (3, 1)])],
                      [
                          Requirement(Perm((0, 1)), [(1, 1), (4, 1)]),
                          Requirement(Perm((0, )), [(4, 3)]),
                          Requirement(Perm((0, )), [(4, 4)]),
                          Requirement(Perm((0, 1)), [(3, 1), (4, 1)])
                      ]])
    assert tiling == tiling2
예제 #14
0
def simple_tiling():
    return Tiling(obstructions=[Obstruction(Perm((1, 0)), [(0, 1), (1, 0)])],
                  requirements=[[
                      Requirement(Perm((0, 1)), [(0, 0), (1, 0)]),
                      Requirement(Perm((0, 1)), [(0, 0), (1, 1)])
                  ]])
예제 #15
0
 def __init__(self, avoids=tuple(), contains=tuple()):
     obs, reqs = stretch_av_and_co(avoids, contains, [(0, 0)])
     reqs.append([Requirement.single_cell(Perm((0,)), (0, 0))])
     self.tiling = Tiling(obs, reqs)
예제 #16
0
def simple_trans_col():
    return Tiling(obstructions=[Obstruction(Perm((0, 1)), [(0, 0), (0, 1)]),
                                Obstruction(Perm((0, 1)), [(0, 1), (0, 2)])],
                  requirements=[[Requirement(Perm((0,)), [(0, 1)])]])
예제 #17
0
def partial_place_point_of_requirement(tiling, req_index, point_index,
                                       force_dir):
    """
    Places the point at point_index in requirement at req_index into tiling on
    its own row or onto its own column depending on force_dir.
    """
    if len(tiling.requirements[req_index]) > 1:
        raise ValueError(
            "Requirement list at {} contains more than 1 requirement.".format(
                req_index))
    # Determine if placing onto own row or column
    row = (force_dir == DIR_NORTH or force_dir == DIR_SOUTH)
    # The requirement
    requirement = tiling.requirements[req_index][0]
    # The cell containing the point
    cell = requirement.pos[point_index]
    # The rest of the requirements
    other_reqs = [
        tiling.requirements[i] for i in range(len(tiling.requirements))
        if i != req_index
    ]
    # Placing the forced occurrence of the point in the requirement
    new_req, forced_obstructions = requirement.partial_place_forced_point(
        point_index, force_dir)
    assert len(new_req) == 1
    # New indices of the point.
    point_cell = (cell[0] if row else cell[0] + 1,
                  cell[1] + 1 if row else cell[1])
    # The set of new obstructions, consisting of the forced obstructions, other
    # obstructions where the point placement has been taken into account and
    # the 12, 21 in the cell.
    newobs = forced_obstructions + list(
        chain.from_iterable(
            ob.place_point(cell, DIR_NONE, partial=True, row=row)
            for ob in tiling.obstructions)) + [
                Obstruction.single_cell(Perm((0, 1)), point_cell),
                Obstruction.single_cell(Perm((1, 0)), point_cell)
            ]
    # If a point cell, make sure neighbouring cells are empty by adding the
    # point obstructions.
    if cell in tiling.point_cells:
        if force_dir == DIR_EAST or force_dir == DIR_WEST:
            newobs = (newobs + [
                Obstruction.single_cell(Perm((0, )),
                                        (point_cell[0] + 1, point_cell[1])),
                Obstruction.single_cell(Perm((0, )),
                                        (point_cell[0] - 1, point_cell[1]))
            ])
        elif force_dir == DIR_NORTH or force_dir == DIR_SOUTH:
            newobs = (newobs + [
                Obstruction.single_cell(Perm((0, )),
                                        (point_cell[0], point_cell[1] + 1)),
                Obstruction.single_cell(Perm((0, )),
                                        (point_cell[0], point_cell[1] - 1))
            ])
    # The new requirements, consisting of the requirement with the point
    # placed, other requirements where point placement has been taken into
    # account and the point requirement in the cell.
    newreqs = [
        list(
            chain.from_iterable(
                req.place_point(cell, DIR_NONE, partial=True, row=row)
                for req in reqs)) for reqs in other_reqs
    ] + [new_req] + [[Requirement.single_cell(Perm((0, )), point_cell)]]
    return Tiling(obstructions=newobs, requirements=newreqs)
예제 #18
0
 def __init__(self, avoids=tuple(), contains=tuple()):
     obs, reqs = stretch_av_and_co(avoids, contains, [(0, 0)])
     obs.extend([Obstruction.single_cell(Perm((0, 1)), (0, 0)),
                  Obstruction.single_cell(Perm((1, 0)), (0, 0))])
     reqs.extend([[Requirement.single_cell(Perm((0,)), (0, 0))]])
     self.tiling = Tiling(obs, reqs)
예제 #19
0
def test_place_point_of_requirement_point_only(diverse_tiling):
    tiling = place_point_of_requirement(diverse_tiling, 0, 0, DIR_WEST)
    assert tiling == Tiling(
        obstructions=[
            Obstruction(Perm((0, )), [(1, 0)]),
            Obstruction(Perm((0, )), [(1, 2)]),
            Obstruction(Perm((0, )), [(2, 0)]),
            Obstruction(Perm((0, )), [(2, 2)]),
            Obstruction(Perm((0, 1)), [(2, 1), (2, 1)]),
            Obstruction(Perm((0, 1)), [(4, 3), (4, 3)]),
            Obstruction(Perm((1, 0)), [(2, 1), (2, 1)]),
            Obstruction(Perm((1, 0)), [(4, 3), (4, 3)]),
            Obstruction(Perm((0, 2, 3, 1)), [(0, 0), (1, 3), (1, 3), (4, 0)]),
            Obstruction(Perm((0, 2, 3, 1)), [(0, 0), (1, 3), (1, 3), (4, 2)]),
            Obstruction(Perm((0, 2, 3, 1)), [(0, 0), (1, 3), (3, 3), (4, 0)]),
            Obstruction(Perm((0, 2, 3, 1)), [(0, 0), (1, 3), (3, 3), (4, 2)]),
            Obstruction(Perm((0, 2, 3, 1)), [(0, 0), (3, 3), (3, 3), (4, 0)]),
            Obstruction(Perm((0, 2, 3, 1)), [(0, 0), (3, 3), (3, 3), (4, 2)]),
            Obstruction(Perm((0, 2, 3, 1)), [(0, 2), (1, 3), (1, 3), (4, 2)]),
            Obstruction(Perm((0, 2, 3, 1)), [(0, 2), (1, 3), (3, 3), (4, 2)]),
            Obstruction(Perm((0, 2, 3, 1)), [(0, 2), (3, 3), (3, 3), (4, 2)])
        ],
        requirements=[[Requirement(Perm((0, )), [(2, 1)])],
                      [Requirement(Perm((0, )), [(4, 3)])],
                      [
                          Requirement(Perm((0, )), [(4, 0)]),
                          Requirement(Perm((0, )), [(4, 2)])
                      ],
                      [
                          Requirement(Perm((1, 0)), [(0, 4), (0, 3)]),
                          Requirement(Perm((0, 2, 1)), [(0, 3), (0, 4),
                                                        (1, 4)]),
                          Requirement(Perm((0, 2, 1)), [(0, 3), (0, 4),
                                                        (3, 4)])
                      ]])

    assert tiling == place_point_of_requirement(diverse_tiling, 0, 0, DIR_EAST)
    assert tiling == place_point_of_requirement(diverse_tiling, 0, 0,
                                                DIR_NORTH)
    assert tiling == place_point_of_requirement(diverse_tiling, 0, 0,
                                                DIR_SOUTH)

    tiling = place_point_of_requirement(diverse_tiling, 1, 0, DIR_WEST)
    assert tiling == Tiling(
        obstructions=[
            Obstruction(Perm((0, )), [(2, 0)]),
            Obstruction(Perm((0, )), [(2, 2)]),
            Obstruction(Perm((0, 1)), [(1, 0), (1, 0)]),
            Obstruction(Perm((0, 1)), [(1, 0), (1, 2)]),
            Obstruction(Perm((0, 1)), [(1, 2), (1, 2)]),
            Obstruction(Perm((0, 1)), [(3, 1), (3, 1)]),
            Obstruction(Perm((0, 1)), [(2, 3), (2, 3)]),
            Obstruction(Perm((0, 1)), [(2, 3), (4, 3)]),
            Obstruction(Perm((0, 1)), [(4, 3), (4, 3)]),
            Obstruction(Perm((1, 0)), [(1, 0), (1, 0)]),
            Obstruction(Perm((1, 0)), [(1, 2), (1, 0)]),
            Obstruction(Perm((1, 0)), [(1, 2), (1, 2)]),
            Obstruction(Perm((1, 0)), [(3, 1), (3, 1)]),
            Obstruction(Perm((1, 0)), [(2, 3), (2, 3)]),
            Obstruction(Perm((1, 0)), [(2, 3), (4, 3)]),
            Obstruction(Perm((1, 0)), [(4, 3), (4, 3)]),
            Obstruction(Perm((0, 1, 2)), [(0, 0), (1, 3), (1, 3)]),
            Obstruction(Perm((0, 2, 3, 1)), [(0, 2), (1, 3), (1, 3), (4, 2)])
        ],
        requirements=[[Requirement(Perm((0, )), [(3, 1)])],
                      [
                          Requirement(Perm((0, )), [(1, 0)]),
                          Requirement(Perm((0, )), [(1, 2)])
                      ],
                      [
                          Requirement(Perm((0, )), [(2, 3)]),
                          Requirement(Perm((0, )), [(4, 3)])
                      ],
                      [
                          Requirement(Perm((1, 0)), [(0, 4), (0, 3)]),
                          Requirement(Perm((0, 2, 1)), [(0, 3), (0, 4),
                                                        (1, 4)])
                      ]])

    tiling = Tiling(requirements=[[Requirement(Perm((0, )), [(0, 0)])]])
    assert place_point_of_requirement(tiling, 0, 0, DIR_SOUTH) == Tiling(
        obstructions=[
            Obstruction(Perm((0, 1)), [(0, 0), (0, 0)]),
            Obstruction(Perm((1, 0)), [(0, 0), (0, 0)])
        ],
        requirements=[[Requirement(Perm((0, )), [(0, 0)])]])
예제 #20
0
def place_requirement_list(tiling, req_list, direction, regions=False):
    """Return the list of tilings obtained by placing the direction-most point
    of a requirement list. This represents a batch strategy, where the
    direction-most point of each requirement in the list is placed."""
    # Compute the points furthest in the given direction.
    min_points = minimum_points(req_list, direction)
    if len([c for _, c in min_points]) != len(set([c for _, c in min_points])):
        # Can't handle list requirements with more than req farthest in the
        # direction in same cell.
        return None
    # For each tiling, compute the tiling where this point is placed furthest
    # in that direction.
    res = []
    if regions:
        forward_maps = []
    for (idx, cell), req in zip(min_points, req_list):
        # Placing the forced occurrence of the point in the requirement
        new_req, forced_obstructions = req.place_forced_point(idx, direction)
        assert len(new_req) == 1
        # Add the forced obstruction to ensure no other requirement has a point
        # further in that direction.
        forced_obstructions = (forced_obstructions + list(
            chain.from_iterable(
                r.other_req_forced_point(cell, direction)
                for r in req_list if r != req)))
        # New indices of the point
        point_cell = (cell[0] + 1, cell[1] + 1)
        # The set of new obstructions, consisting of the forced obstructions,
        # other obstructions where the point placement has been taken into
        # account and the 12, 21 in the cell.
        newobs = forced_obstructions + list(
            chain.from_iterable(
                ob.place_point(cell, DIR_NONE)
                for ob in tiling.obstructions)) + [
                    Obstruction.single_cell(Perm((0, 1)), point_cell),
                    Obstruction.single_cell(Perm((1, 0)), point_cell)
                ]
        # The rest of the requirements
        other_reqs = [reqs for reqs in tiling.requirements if reqs != req_list]
        # The new requirements, consisting of the requirement with the point
        # placed, other requirements where point placement has been taken into
        # account and the point requirement in the cell.
        newreqs = [
            list(
                chain.from_iterable(
                    r.place_point(cell, DIR_NONE) for r in reqs))
            for reqs in other_reqs
        ] + [new_req] + [[Requirement.single_cell(Perm((0, )), point_cell)]]
        placed_tiling = Tiling(newobs, newreqs)
        res.append(placed_tiling)
        if regions:

            def cell_map(c):
                mindex, minval = c
                maxdex = mindex + 1
                maxval = minval + 1
                if mindex >= cell[0]: maxdex += 2
                if minval >= cell[1]: maxval += 2
                if mindex > cell[0]: mindex += 2
                if minval > cell[1]: minval += 2
                return frozenset([(x, y) for x in range(mindex, maxdex)
                                  for y in range(minval, maxval)])

            forward_maps.append({c: cell_map(c) for c in tiling.active_cells})
    if regions:
        return res, forward_maps
    else:
        return res
예제 #21
0
def typical_requirements_with_local():
    """Return a very typical list of requirements of a tiling, including some
    local length 1 requirements."""
    return [[
        Requirement(Perm((0, 1, 2)), ((0, 0), (1, 0), (2, 3))),
        Requirement(Perm((0, 1, 2)), ((0, 0), (1, 0), (2, 4))),
        Requirement(Perm((1, 0, 2)), ((0, 0), (1, 0), (2, 3))),
        Requirement(Perm((1, 0, 2)), ((0, 1), (1, 0), (2, 3)))
    ],
            [
                Requirement(Perm((0, 1)), ((1, 0), (3, 0))),
                Requirement(Perm((0, 1)), ((2, 0), (2, 0))),
                Requirement(Perm((0, 1)), ((2, 0), (3, 0))),
                Requirement(Perm((0, 1)), ((2, 0), (3, 1)))
            ], [Requirement(Perm((0, )), ((3, 0), ))],
            [Requirement(Perm((1, 0)), ((2, 0), (2, 0)))],
            [Requirement(Perm((0, 2, 1)), ((0, 0), (2, 3), (2, 3)))]]
예제 #22
0
def typical_redundant_requirements():
    """Returns a very typical list of requirements of a tiling.  """
    return [[
        Requirement(Perm((0, 1, 2)), ((0, 0), (1, 0), (2, 3))),
        Requirement(Perm((0, 1, 2)), ((0, 0), (1, 0), (2, 4))),
        Requirement(Perm((1, 0, 2)), ((0, 0), (1, 0), (2, 3))),
        Requirement(Perm((1, 0, 2)), ((0, 1), (1, 0), (2, 3)))
    ],
            [
                Requirement(Perm((0, 1, 2)), ((2, 3), (2, 3), (2, 3))),
                Requirement(Perm((1, 0, 2)), ((0, 0), (0, 0), (0, 0))),
                Requirement(Perm((0, 1, 2)), ((1, 0), (1, 0), (1, 0)))
            ],
            [
                Requirement(Perm((0, 1)), ((1, 0), (3, 0))),
                Requirement(Perm((0, 1)), ((2, 0), (2, 0))),
                Requirement(Perm((0, 1)), ((2, 0), (3, 0))),
                Requirement(Perm((0, 1)), ((2, 0), (3, 1)))
            ],
            [
                Requirement(Perm((1, 0)), ((3, 3), (3, 1))),
                Requirement(Perm((1, 0)), ((3, 1), (3, 1))),
                Requirement(Perm((1, 0)), ((3, 1), (3, 0)))
            ]]
예제 #23
0
def test_all_cell_insertions_points(simple_tiling):
    strats = [
        s.comb_classes for s in all_cell_insertions(simple_tiling, maxreqlen=1)
    ]
    assert all(len(s) == 2 for s in strats)
    s = strats[0]
    assert s[0] == Tiling(obstructions=[Obstruction(Perm((0, )), [(0, 1)])],
                          requirements=[[
                              Requirement(Perm((0, 1)), [(0, 0), (1, 0)]),
                              Requirement(Perm((0, 1)), [(0, 0), (1, 1)])
                          ]])
    assert s[1] == Tiling(
        obstructions=[Obstruction(Perm((0, )), [(1, 0)])],
        requirements=[[Requirement(Perm((0, )), [(0, 1)])],
                      [Requirement(Perm((0, 1)), [(0, 0), (1, 1)])]])

    s = strats[1]
    assert s[0] == Tiling(
        obstructions=[
            Obstruction(Perm((0, )), ((0, 1), )),
            Obstruction(Perm((0, )), ((1, 0), ))
        ],
        requirements=[[Requirement(Perm((0, 1)), ((0, 0), (1, 1)))]])
    assert s[1] == Tiling(
        obstructions=[Obstruction(Perm((0, )), ((0, 1), ))],
        requirements=[[Requirement(Perm((0, )), ((1, 0), ))],
                      [
                          Requirement(Perm((0, 1)), ((0, 0), (1, 0))),
                          Requirement(Perm((0, 1)), ((0, 0), (1, 1)))
                      ]])

    s = strats[2]
    assert s[0] == Tiling(obstructions=[Obstruction(Perm(tuple()), tuple())])
    assert s[1] == Tiling(
        obstructions=[Obstruction(Perm((1, 0)), ((0, 1), (1, 0)))],
        requirements=[[Requirement(Perm((0, )), ((0, 0), ))],
                      [
                          Requirement(Perm((0, 1)), ((0, 0), (1, 0))),
                          Requirement(Perm((0, 1)), ((0, 0), (1, 1)))
                      ]])

    s = strats[3]
    assert s[0] == Tiling(
        requirements=[[Requirement(Perm((0, 1)), ((0, 0), (1, 0)))]])
    assert s[1] == Tiling(
        obstructions=[Obstruction(Perm((1, 0)), ((0, 1), (1, 0)))],
        requirements=[[Requirement(Perm((0, )), ((1, 1), ))],
                      [
                          Requirement(Perm((0, 1)), ((0, 0), (1, 0))),
                          Requirement(Perm((0, 1)), ((0, 0), (1, 1)))
                      ]])
def test_requirement_corroboration(typical_redundant_requirements,
                                   typical_redundant_obstructions):
    tiling = Tiling(obstructions=[Obstruction(Perm((1, 0)), [(0, 1), (1, 0)])],
                    requirements=[[
                        Requirement(Perm((0, 1)), [(0, 0), (1, 0)]),
                        Requirement(Perm((0, 1)), [(0, 0), (1, 1)])
                    ]])
    reqins = list(strat.comb_classes
                  for strat in requirement_corroboration(tiling, None))
    assert len(reqins) == 2
    strat1, strat2 = reqins

    assert len(strat1) == 2
    til1, til2 = strat1
    assert til1 == Tiling(obstructions=[
        Obstruction(Perm((0, 1)), [(0, 0), (1, 0)]),
        Obstruction(Perm((1, 0)), [(0, 1), (1, 0)])
    ],
                          requirements=[[Requirement(Perm((0, )), [(0, 0)])],
                                        [Requirement(Perm((0, )), [(1, 1)])]])
    assert til2 == Tiling(
        obstructions=[],
        requirements=[[Requirement(Perm((0, 1)), [(0, 0), (1, 0)])]])

    tiling = Tiling(obstructions=typical_redundant_obstructions,
                    requirements=typical_redundant_requirements)
    reqins = list(strat.comb_classes
                  for strat in requirement_corroboration(tiling, None))
    assert len(reqins) == sum(
        len(reqs) for reqs in tiling.requirements if len(reqs) > 1)
    til1, til2 = reqins[0]
    assert (set([til1, til2]) == set([
        Tiling(requirements=[
            [Requirement(Perm((0, 1)), ((2, 0), (3, 1)))],
            [Requirement(Perm((1, 0)), ((3, 2), (3, 1)))],
            [Requirement(Perm((0, 1, 2)), ((0, 0), (1, 0), (2, 2)))],
            [
                Requirement(Perm((0, 1, 2)), ((2, 2), (2, 2), (2, 2))),
                Requirement(Perm((1, 0, 2)), ((0, 0), (0, 0), (0, 0)))
            ]
        ],
               obstructions=typical_redundant_obstructions),
        Tiling(requirements=[[Requirement(Perm((0, 1)), ((2, 0), (3, 1)))],
                             [Requirement(Perm((1, 0)), ((3, 2), (3, 1)))],
                             [
                                 Requirement(Perm((0, 1, 2)),
                                             ((0, 0), (1, 0), (2, 3))),
                                 Requirement(Perm((1, 0, 2)),
                                             ((0, 0), (1, 0), (2, 2))),
                                 Requirement(Perm((1, 0, 2)),
                                             ((0, 1), (1, 0), (2, 2)))
                             ],
                             [
                                 Requirement(Perm((0, 1, 2)),
                                             ((2, 2), (2, 2), (2, 2))),
                                 Requirement(Perm((1, 0, 2)),
                                             ((0, 0), (0, 0), (0, 0)))
                             ]],
               obstructions=(
                   typical_redundant_obstructions +
                   [Obstruction(Perm((0, 1, 2)), ((0, 0), (1, 0), (2, 2)))]))
    ]))
예제 #25
0
def row_placements(tiling, row=True, positive=True, regions=False, **kwargs):
    """Places the points in a row (or col if row=False) in the given
    direction."""
    if row:
        x = tiling.dimensions[1]
        y = tiling.dimensions[0]
        only_cell_in_col = tiling.only_cell_in_col
        directions = [DIR_NORTH, DIR_SOUTH]
    else:
        x = tiling.dimensions[0]
        y = tiling.dimensions[1]
        only_cell_in_col = tiling.only_cell_in_row
        directions = [DIR_EAST, DIR_WEST]

    rows = range(x)
    if kwargs.get("index") is not None:
        rows = [kwargs.get("index")]
    if kwargs.get("direction") is not None:
        directions = [kwargs["direction"]]
    if regions:
        forward_maps = []

    direction = kwargs.get('direction')
    if direction is not None:
        if row:
            if direction == DIR_NORTH:
                directions = [DIR_NORTH]
            elif direction == DIR_SOUTH:
                directions = [DIR_SOUTH]
            else:
                raise ValueError("Can't place rows in direction.")
        else:
            if direction == DIR_EAST:
                directions = [DIR_EAST]
            elif direction == DIR_WEST:
                directions = [DIR_WEST]
            else:
                raise ValueError("Can't place cols in direction.")

    for i in rows:
        place = True
        cells_in_row = []
        for j in range(y):
            cell = (j, i) if row else (i, j)
            if positive and cell not in tiling.positive_cells:
                place = False
                break
            cells_in_row.append(cell)
        if place:
            if (len(cells_in_row) != 1
                    or not cells_in_row[0] in tiling.point_cells
                    or not only_cell_in_col(cells_in_row[0])):
                req_list = tuple(
                    Requirement(Perm((0, )), (cell, ))
                    for cell in cells_in_row)
                if not positive:
                    """Adding the empty row case."""
                    empty_row_tiling = Tiling(
                        tiling.obstructions + tuple(
                            Obstruction(Perm((0, )), (cell, ))
                            for cell in cells_in_row), tiling.requirements)
                    if regions:
                        forward_maps.append(
                            {c: frozenset([c])
                             for c in tiling.active_cells})
                for direction in directions:
                    if regions:
                        tilings, placed_maps = place_requirement_list(
                            tiling, req_list, direction, regions=regions)
                        if not positive:
                            tilings = [empty_row_tiling] + tilings
                        forward_maps.extend(placed_maps)
                        yield tilings, forward_maps
                    else:
                        tilings = place_requirement_list(
                            tiling, req_list, direction)
                    if not positive:
                        tilings = [empty_row_tiling] + tilings
                    yield Rule(formal_step=("Placing {} {} in direction {}."
                                            "".format("row" if row else "col",
                                                      i, direction,
                                                      i, direction,
                                                      int(positive))),
                               comb_classes=tilings,
                               ignore_parent=False,
                               possibly_empty=[True for _ in tilings],
                               inferable=[True for _ in tilings],
                               workable=[True for _ in tilings],
                               constructor='disjoint')
def positive_one_by_one():
    return Tiling(
        obstructions=[Obstruction(Perm((0, 2, 1)), [(0, 0), (0, 0), (0, 0)])],
        requirements=[[Requirement(Perm((0, )), [(0, 0)])]])
예제 #27
0
def place_point_of_requirement(tiling, req_index, point_index, force_dir,
                               **kwargs):
    """
    Places the point at point_index in requirement at req_index into tiling.
    """
    if len(tiling.requirements[req_index]) > 1:
        raise ValueError(
            "Requirement list at {} contains more than 1 requirement.".format(
                req_index))
    # The requirement
    requirement = tiling.requirements[req_index][0]
    # The cell containing the point
    cell = requirement.pos[point_index]
    # The rest of the requirements
    other_reqs = [
        tiling.requirements[i] for i in range(len(tiling.requirements))
        if i != req_index
    ]
    # Placing the forced occurrence of the point in the requirement
    new_req, forced_obstructions = requirement.place_forced_point(
        point_index, force_dir)
    assert len(new_req) == 1
    # New indices of the point
    point_cell = (cell[0] + 1, cell[1] + 1)

    # The set of new obstructions, consisting of the forced obstructions, other
    # obstructions where the point placement has been taken into account and
    # the 12, 21 in the cell.
    newobs = forced_obstructions + list(
        chain.from_iterable(
            ob.place_point(cell, DIR_NONE) for ob in tiling.obstructions)) + [
                Obstruction.single_cell(Perm((0, 1)), point_cell),
                Obstruction.single_cell(Perm((1, 0)), point_cell)
            ]
    # The new requirements, consisting of the requirement with the point
    # placed, other requirements where point placement has been taken into
    # account and the point requirement in the cell.
    newreqs = [
        list(
            chain.from_iterable(
                req.place_point(cell, DIR_NONE) for req in reqs))
        for reqs in other_reqs
    ] + [new_req] + [[Requirement.single_cell(Perm((0, )), point_cell)]]

    placed_tiling = Tiling(obstructions=newobs, requirements=newreqs)
    if kwargs.get('regions', False):

        def cell_map(c):
            mindex, minval = c
            maxdex = mindex + 1
            maxval = minval + 1
            if mindex >= cell[0]:
                maxdex += 2
            if minval >= cell[1]:
                maxval += 2
            if mindex > cell[0]:
                mindex += 2
            if minval > cell[1]:
                minval += 2
            return set([
                placed_tiling.forward_map[(x, y)]
                for x in range(mindex, maxdex) for y in range(minval, maxval)
                if ((x, y) in placed_tiling.forward_map and placed_tiling.
                    forward_map[(x, y)] in placed_tiling.active_cells)
            ])

        return [placed_tiling], [{c: cell_map(c) for c in tiling.active_cells}]

    return placed_tiling