def only_root_placements( cls, length: int = 3, max_num_req: Optional[int] = 1, max_placement_rules_per_req: Optional[int] = None, partial: bool = False, ) -> "TileScopePack": partial_str = "partial_" if partial else "" if max_num_req is not None: name = ( f"only_length_{length}_{max_num_req}_reqs_root_{partial_str}placements" ) else: name = f"only_length_{length}_root_{partial_str}placements" placement_factory = strat.RequirementPlacementFactory( max_rules_per_req=max_placement_rules_per_req, partial=partial ) return TileScopePack( initial_strats=[ strat.RootInsertionFactory(maxreqlen=length, max_num_req=max_num_req), strat.FactorFactory(unions=True, ignore_parent=False, workable=False), ], ver_strats=[ strat.BasicVerificationStrategy(), strat.InsertionEncodingVerificationStrategy(), strat.OneByOneVerificationStrategy(), strat.LocallyFactorableVerificationStrategy(), ], inferral_strats=[ strat.RowColumnSeparationStrategy(), strat.ObstructionTransitivityFactory(), ], expansion_strats=[[placement_factory]], name=name, )
def requirement_placements( cls, length: int = 2, partial: bool = False ) -> "TileScopePack": name = "".join( [ "length_{length}_" if length != 2 else "", "partial_" if partial else "", "requirement_placements", ] ) initial_strats: List[CSSstrategy] = [strat.FactorFactory()] if length > 1: initial_strats.append(strat.RequirementCorroborationFactory()) return TileScopePack( initial_strats=initial_strats, ver_strats=[ strat.BasicVerificationStrategy(), strat.InsertionEncodingVerificationStrategy(), strat.OneByOneVerificationStrategy(), strat.LocallyFactorableVerificationStrategy(), ], inferral_strats=[ strat.RowColumnSeparationStrategy(), strat.ObstructionTransitivityFactory(), ], expansion_strats=[ [ strat.RequirementInsertionFactory(maxreqlen=length), strat.PatternPlacementFactory(partial=partial), ], ], name=name, )
def all_the_strategies(cls, length: int = 1) -> "TileScopePack": initial_strats: List[CSSstrategy] = [strat.FactorFactory()] if length > 1: initial_strats.append(strat.RequirementCorroborationFactory()) return TileScopePack( initial_strats=initial_strats, ver_strats=[ strat.BasicVerificationStrategy(), strat.InsertionEncodingVerificationStrategy(), strat.OneByOneVerificationStrategy(), strat.LocallyFactorableVerificationStrategy(), ], inferral_strats=[ strat.RowColumnSeparationStrategy(), strat.ObstructionTransitivityFactory(), ], expansion_strats=[ [ strat.RequirementInsertionFactory(maxreqlen=length), strat.AllPlacementsFactory(), ], ], name=f"all_the_strategies_{length}", )
def regular_insertion_encoding(cls, direction: int) -> "TileScopePack": """This pack finds insertion encodings.""" if direction not in DIRS: raise ValueError(f"Must be direction in {DIRS}.") place_row = direction in (DIR_NORTH, DIR_SOUTH) place_col = not place_row direction_str = { DIR_EAST: "left", DIR_WEST: "right", DIR_NORTH: "bottom", DIR_SOUTH: "top", } name = f"regular_insertion_encoding_{direction_str[direction]}" return TileScopePack( initial_strats=[ strat.FactorFactory(), strat.CellInsertionFactory(ignore_parent=True, one_cell_only=True), ], ver_strats=[strat.BasicVerificationStrategy()], inferral_strats=[], expansion_strats=[ [ strat.RowAndColumnPlacementFactory( place_col=place_col, place_row=place_row, dirs=[direction] ) ] ], name=name, )
def requirement_placements(cls, length: int = 2, partial: bool = False) -> "TileScopePack": name = "{}{}requirement_placements".format( "length_{}_".format(length) if length != 2 else "", "partial_" if partial else "", ) return TileScopePack( initial_strats=[ strat.FactorFactory(), strat.RequirementCorroborationFactory(), ], ver_strats=[ strat.BasicVerificationStrategy(), strat.InsertionEncodingVerificationStrategy(), strat.OneByOneVerificationStrategy(), strat.LocallyFactorableVerificationStrategy(), ], inferral_strats=[ strat.RowColumnSeparationStrategy(), strat.ObstructionTransitivityFactory(), ], expansion_strats=[ [strat.RequirementInsertionFactory(maxreqlen=length)], [strat.PatternPlacementFactory(partial=partial)], ], name=name, )
def row_and_col_placements(cls, row_only: bool = False, col_only: bool = False, partial: bool = False) -> "TileScopePack": if row_only and col_only: raise ValueError("Can't be row and col only.") place_row = not col_only place_col = not row_only both = place_col and place_row name = "{}{}{}{}_placements".format( "partial_" if partial else "", "row" if not col_only else "", "_and_" if both else "", "col" if not row_only else "", ) rowcol_strat = strat.RowAndColumnPlacementFactory(place_row=place_row, place_col=place_col, partial=partial) return TileScopePack( initial_strats=[strat.FactorFactory()], ver_strats=[ strat.BasicVerificationStrategy(), strat.InsertionEncodingVerificationStrategy(), strat.OneByOneVerificationStrategy(), strat.LocallyFactorableVerificationStrategy(), ], inferral_strats=[ strat.RowColumnSeparationStrategy(), strat.ObstructionTransitivityFactory(), ], expansion_strats=[[rowcol_strat]], name=name, )
def insertion_point_placements(cls, length: int = 1, partial: bool = False) -> "TileScopePack": name = "insertion_" if length > 1: name += "length_{}_".format(length) partial_str = "partial_" if partial else "" name += f"{partial_str}point_placements" return TileScopePack( initial_strats=[ strat.FactorFactory(), strat.RequirementCorroborationFactory(), strat.CellInsertionFactory(maxreqlen=length, ignore_parent=True), ], ver_strats=[ strat.BasicVerificationStrategy(), strat.InsertionEncodingVerificationStrategy(), strat.OneByOneVerificationStrategy(), strat.LocallyFactorableVerificationStrategy(), ], inferral_strats=[ strat.RowColumnSeparationStrategy(), strat.ObstructionTransitivityFactory(), ], expansion_strats=[[strat.PatternPlacementFactory(partial=partial)] ], name=name, )
def cell_insertions(cls, length: int): return TileScopePack( initial_strats=[], ver_strats=[ strat.BasicVerificationStrategy(), strat.InsertionEncodingVerificationStrategy(), strat.OneByOneVerificationStrategy(), ], inferral_strats=[], expansion_strats=[[strat.CellInsertionFactory(maxreqlen=length)]], name="length_{length}_cell_insertions", )
def point_and_row_and_col_placements( cls, length: int = 1, row_only: bool = False, col_only: bool = False, partial: bool = False, ) -> "TileScopePack": if row_only and col_only: raise ValueError("Can't be row and col only.") place_row = not col_only place_col = not row_only both = place_col and place_row name = "".join( [ "length_{length}_" if length > 1 else "", "partial_" if partial else "", "point_and_", "row" if not col_only else "", "_and_" if both else "", "col" if not row_only else "", "_placements", ] ) rowcol_strat = strat.RowAndColumnPlacementFactory( place_row=place_row, place_col=place_col, partial=partial ) initial_strats: List[CSSstrategy] = [strat.FactorFactory()] if length > 1: initial_strats.append(strat.RequirementCorroborationFactory()) return TileScopePack( initial_strats=initial_strats, ver_strats=[ strat.BasicVerificationStrategy(), strat.InsertionEncodingVerificationStrategy(), strat.OneByOneVerificationStrategy(), strat.LocallyFactorableVerificationStrategy(), ], inferral_strats=[ strat.RowColumnSeparationStrategy(), strat.ObstructionTransitivityFactory(), ], expansion_strats=[ [ strat.CellInsertionFactory(maxreqlen=length), strat.PatternPlacementFactory(partial=partial), rowcol_strat, ], ], name=name, )
def test_reverse_equiv(): """A specification that should use reverse equivalence.""" pack = TileScopePack( initial_strats=[ strat.FactorFactory(), strat.RequirementCorroborationFactory(), strat.RequirementPlacementFactory(partial=False), ], inferral_strats=[strat.RowColumnSeparationStrategy()], expansion_strats=[[strat.CellInsertionFactory()]], ver_strats=[strat.BasicVerificationStrategy()], iterative=False, name="test pack", ) basis = (Perm((0, 1, 3, 2)), Perm((0, 2, 3, 1)), Perm((1, 0, 3, 2))) # From https://oeis.org/A033321 expected_enum = [ 1, 1, 2, 6, 21, 79, 311, 1265, 5275, 22431, 96900, 424068, 1876143 ] x, f = sympy.symbols("x f") expected_min_poly = sympy.sympify("-4*f^2*x^2 + 8*f^2*x - 4*f*x - 4*f + 4") searcher = TileScope(basis, pack) spec = searcher.auto_search(smallest=True) assert [spec.count_objects_of_size(i) for i in range(13)] == expected_enum genf = spec.get_genf() assert sympy.simplify(expected_min_poly.subs(f, genf)) == 0 assert taylor_expand(genf, 12) == expected_enum # In order to avoid ReccursionError we go incrementally for i in range(0, 100): spec.count_objects_of_size(i) assert spec.count_objects_of_size(50) == 86055297645519796258217673160170 assert ( spec.count_objects_of_size(100) == 2733073112795720153237297124938915907723365837935699807314396095313) len4_perms = tuple(spec.generate_objects_of_size(4)) assert len(len4_perms) == 21 assert all(p not in len4_perms for p in basis) len8_perms = tuple(spec.generate_objects_of_size(8)) assert len(len8_perms) == 5275 assert len(set(len8_perms)) == 5275 for _ in range(10): gp = spec.random_sample_object_of_size(10) print(gp) assert gp.patt.avoids(*basis) av = Av(basis) for i in range(10): assert set(av.of_length(i)) == set( gp.patt for gp in spec.generate_objects_of_size(i)) assert spec.random_sample_object_of_size(i).patt in av
def make_elementary(self) -> "TileScopePack": """ Create a new pack by using only one by one and elementary verification. """ if ( strat.ElementaryVerificationStrategy() in self and strat.OneByOneVerificationStrategy() in self and len(self.ver_strats) == 2 and self.iterative ): raise ValueError("The pack is already elementary.") pack = self.make_iterative() pack = pack.add_verification(strat.BasicVerificationStrategy(), replace=True) pack = pack.add_verification(strat.OneByOneVerificationStrategy()) return pack.add_verification( strat.ElementaryVerificationStrategy(), "elementary" )
def all_the_strategies(cls, length: int = 1) -> "TileScopePack": return TileScopePack( initial_strats=[ strat.FactorFactory(unions=False), strat.RequirementCorroborationFactory(), ], ver_strats=[ strat.BasicVerificationStrategy(), strat.InsertionEncodingVerificationStrategy(), strat.OneByOneVerificationStrategy(), strat.LocallyFactorableVerificationStrategy(), ], inferral_strats=[ strat.RowColumnSeparationStrategy(), strat.ObstructionTransitivityFactory(), ], expansion_strats=[ [strat.RequirementInsertionFactory(maxreqlen=length)], [strat.AllPlacementsFactory()], ], name="all_the_strategies", )
def _basic_verify(tiling: Tiling) -> Optional[VerificationRule]: try: return strats.BasicVerificationStrategy()(tiling) except StrategyDoesNotApply: return None