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)])]])
Exemple #2
0
def deflated_tiling(tiling, cell, sum_decomp=True):
    """Return tiling where cell is deflated."""
    if sum_decomp:
        extra = Obstruction.single_cell(Perm((1, 0)), cell)
    else:
        extra = Obstruction.single_cell(Perm((0, 1)), cell)
    return Tiling(requirements=tiling.requirements,
                  obstructions=tiling.obstructions + (extra, ))
Exemple #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')
Exemple #4
0
def twist_one_by_ones(tiling):
    """
    Returns all tilings which can reached by twisting a single cell.
    """
    if tiling.requirements:
        raise NotImplementedError("Can't handle requirements")
    one_by_ones = set(tiling.active_cells)
    for ob in tiling.obstructions:
        if not one_by_ones:
            break
        if not ob.is_single_cell():
            for c in ob.pos:
                one_by_ones.discard(c)

    sym_sets = [
        antidiagonal_set, complement_set, inverse_set, rotate_90_clockwise_set,
        rotate_180_clockwise_set, rotate_270_clockwise_set
    ]
    cell_basis = tiling.cell_basis()
    twists = set()
    for cell in one_by_ones:
        av, _ = cell_basis[cell]
        for sym_set in sym_sets:
            sym_av = sym_set(av)
            twisted_obs = (
                [ob for ob in tiling.obstructions if cell not in ob.pos] +
                [Obstruction.single_cell(p, cell) for p in sym_av])
            twists.add(Tiling(twisted_obs))
    return set(twists)
Exemple #5
0
    def __init__(self, n=None, k=None, strategy_pack=None, flogger_kwargs={'processname': 'runner'},**kwargs):
        self.start_tilings = []
        if filename is not None:
            assert n == None and k == None
            f = open(filename, 'r')
            for line in f:
                line = line.strip()
                self.start_tilings.append(Tiling.from_string(line))
            f.close()
        else:
            for basis in combinations(PermSet(n), k):
                self.start_tilings.append(Tiling([Obstruction.single_cell(patt, (0, 0)) for patt in basis]))

        strategy_pack.ver_strats = [verify_points]

        function_kwargs = {"basis": []}
        function_kwargs.update(kwargs.get('kwargs', dict()))

        CombinatorialSpecificationSearcher.__init__(
            self,
            self.start_tilings[0],
            strategy_pack,
            function_kwargs=function_kwargs,
            **kwargs)

        self.start_labels = []
        for start_tiling in self.start_tilings:
            self.classdb.add(start_tiling, expandable=True)
            self.start_labels.append(self.classdb.get_label(start_tiling))
        for label in self.start_labels:
            self.classqueue.add_to_working(label)
Exemple #6
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)])]])
def compute_ineq_ob(left, right):
    """Given an inequality of cells left < right, compute an obstruction."""
    if left[0] == right[0]:
        # same column
        if left[1] < right[1]:
            return Obstruction(Perm((1, 0)), [right, left])
        else:
            return Obstruction(Perm((0, 1)), [right, left])
    elif left[1] == right[1]:
        # same row
        if left[0] < right[0]:
            return Obstruction(Perm((1, 0)), [left, right])
        else:
            return Obstruction(Perm((0, 1)), [right, left])
    else:
        raise ValueError((
            "Can not construct an obstruction from inequality {} < {}").format(
                left, right))
Exemple #8
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)])
                                ]])
Exemple #9
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)))
                      ]])
Exemple #10
0
def can_deflate(tiling, cell, sum_decomp):
    alone_in_row = tiling.only_cell_in_row(cell)
    alone_in_col = tiling.only_cell_in_col(cell)

    if alone_in_row and alone_in_col:
        return False

    deflate_patt = Obstruction.single_cell(
        Perm((1, 0)) if sum_decomp else Perm((0, 1)), cell)

    # we must be sure that no cell in a row or column can interleave
    # with any reinflated components, so collect cells that do not.
    cells_not_interleaving = set([cell])

    for ob in tiling.obstructions:
        if ob == deflate_patt:
            return False
        if ob.is_single_cell() or not ob.occupies(cell):
            continue
        number_points_in_cell = sum(1 for c in ob.pos if c == cell)
        if number_points_in_cell == 1:
            if len(ob) == 2:
                # not interleaving with cell as separating if
                # in same row or column
                other_cell = [c for c in ob.pos if c != cell][0]
                cells_not_interleaving.add(other_cell)
        elif number_points_in_cell == 2:
            if len(ob) != 3:
                return False
            patt_in_cell = ob.get_gridded_perm_in_cells((cell, ))
            if patt_in_cell != deflate_patt:
                # you can interleave with components
                return False
            # we need the other cell to be in between the intended deflate
            # patt in either the row or column
            other_cell = [c for c in ob.pos if c != cell][0]
            if (point_in_between(ob, True, cell, other_cell)
                    or point_in_between(ob, False, cell, other_cell)):
                # this cell does not interleave with inflated components
                cells_not_interleaving.add(other_cell)
            else:
                return False
        elif number_points_in_cell >= 3:
            # you can interleave with components
            return False
    # check that do not interleave with any cells in row or column.
    return (cells_not_interleaving >= tiling.cells_in_row(cell[1])
            and cells_not_interleaving >= tiling.cells_in_col(cell[0]))
    def __init__(self,
                 start_class,
                 strategy_pack,
                 # symmetry=False,
                 forward_equivalence=False,
                 logger_kwargs={'processname': 'runner'},
                 **kwargs):
        """Initialise TileScope."""
        if isinstance(start_class, str):
            basis = Basis([Perm.to_standard([int(c) for c in p])
                           for p in start_class.split('_')])
        elif isinstance(start_class, list):
            basis = Basis(start_class)
        elif isinstance(start_class, Tiling):
            start_tiling = start_class
            if start_class.dimensions == (1, 1):
                basis = Basis([o.patt for o in start_class.obstructions])
            else:
                basis = []

        if not isinstance(start_class, Tiling):
            start_tiling = Tiling(
                            obstructions=[Obstruction.single_cell(patt, (0, 0))
                                          for patt in basis])
        if strategy_pack.symmetries==True:
            symmetries = [Tiling.inverse, Tiling.reverse, Tiling.complement,
                          Tiling.antidiagonal, Tiling.rotate90,
                          Tiling.rotate180, Tiling.rotate270]
            # symmetries = [sym for sym in symmetries
                          # if sym(start_tiling) == start_tiling]
            strategy_pack.symmetries = symmetries
        else:
            symmetries = []

        function_kwargs = {"basis": basis}
        function_kwargs.update(kwargs.get('kwargs', dict()))

        CombinatorialSpecificationSearcher.__init__(
            self,
            start_tiling,
            strategy_pack,
            symmetry=symmetries,
            forward_equivalence=forward_equivalence,
            function_kwargs=function_kwargs,
            logger_kwargs=logger_kwargs,
            **kwargs)
Exemple #12
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')
Exemple #13
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)])
        ]])
    ])
Exemple #14
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, ))
        ]
Exemple #15
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, ))
        ]
Exemple #16
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)])]])
def empty_cell_inferral(tiling, **kwargs):
    """The empty cell inferral strategy.

    The strategy considers each active but non-positive cell and inserts a
    point requirement. If the resulting tiling is empty, then a point
    obstruction can be added into the cell, i.e. the cell is empty."""
    active = set(tiling.active_cells)
    positive = set(tiling.positive_cells)
    empty_cells = []
    for cell in active - positive:
        reqtil = tiling.insert_cell(cell)
        if reqtil.is_empty():
            empty_cells.append(cell)
    newobs = [Obstruction.single_cell(Perm((0,)), cell)
              for cell in empty_cells]
    return InferralRule(
        "The cells {} are empty".format(", ".join(map(str, empty_cells))),
        Tiling(obstructions=tiling.obstructions + tuple(newobs),
               requirements=tiling.requirements))
Exemple #18
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)])]])
Exemple #19
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 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)])]])
Exemple #21
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
Exemple #22
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
Exemple #23
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)
Exemple #24
0
def typical_obstructions_with_local():
    return [
        Obstruction(Perm((0, 1)), ((1, 0), (1, 0))),
        Obstruction(Perm((0, 1)), ((1, 0), (2, 0))),
        Obstruction(Perm((0, 1)), ((1, 0), (3, 0))),
        Obstruction(Perm((0, 1)), ((2, 0), (2, 0))),
        Obstruction(Perm((0, 1)), ((2, 0), (3, 0))),
        Obstruction(Perm((0, 1)), ((3, 1), (3, 1))),
        Obstruction(Perm((0, 2, 1)), ((3, 0), (3, 0), (3, 0))),
        Obstruction(Perm((0, 1, 2)), ((3, 0), (3, 0), (3, 1))),
        Obstruction(Perm((1, 2, 0)), ((1, 0), (1, 0), (1, 0))),
        Obstruction(Perm((3, 2, 1, 0)), ((1, 1), (2, 0), (2, 0), (2, 0))),
        Obstruction(Perm((3, 2, 1, 0)), ((2, 1), (2, 1), (3, 0), (3, 0)))
    ]
Exemple #25
0
def typical_redundant_obstructions():
    """Returns a very typical list of obstructions clustered together in a
    corner of a tiling.  """
    return [
        Obstruction(Perm((0, 1)), ((1, 0), (1, 0))),
        Obstruction(Perm((0, 1)), ((1, 0), (2, 0))),
        Obstruction(Perm((0, 1)), ((1, 0), (3, 0))),
        Obstruction(Perm((0, 1)), ((2, 0), (2, 0))),
        Obstruction(Perm((0, 1)), ((2, 0), (3, 0))),
        Obstruction(Perm((0, 1)), ((3, 1), (3, 1))),
        Obstruction(Perm((1, 0)), ((3, 0), (3, 0))),
        Obstruction(Perm((1, 0)), ((3, 1), (3, 0))),
        Obstruction(Perm((1, 0)), ((3, 1), (3, 1))),
        Obstruction(Perm((0, 1, 2)), ((3, 0), (3, 0), (3, 0))),
        Obstruction(Perm((0, 1, 2)), ((3, 0), (3, 0), (3, 1))),
        Obstruction(Perm((2, 1, 0)), ((1, 0), (1, 0), (1, 0))),
        Obstruction(Perm((2, 1, 0)), ((1, 0), (1, 0), (2, 0))),
        Obstruction(Perm((2, 1, 0)), ((1, 0), (1, 0), (3, 0))),
        Obstruction(Perm((2, 1, 0)), ((1, 0), (2, 0), (2, 0))),
        Obstruction(Perm((2, 1, 0)), ((1, 0), (2, 0), (3, 0))),
        Obstruction(Perm((2, 1, 0)), ((2, 0), (2, 0), (2, 0))),
        Obstruction(Perm((2, 1, 0)), ((2, 0), (2, 0), (3, 0))),
        Obstruction(Perm((3, 2, 1, 0)), ((1, 1), (2, 0), (2, 0), (2, 0))),
        Obstruction(Perm((3, 2, 1, 0)), ((2, 1), (2, 1), (3, 0), (3, 0)))
    ]
Exemple #26
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)
Exemple #27
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)])]])
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)])
                  ]])
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)])]])
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)))]))
    ]))