def build_pack(args: argparse.Namespace) -> TileScopePack: if args.strategy_pack not in BASE_PACK: parser.error( "Invalid strategy pack. Use 'tilescope list' to see available packs. " "Perhaps you got the order wrong? A valid command should be of " "the form 'tilescope spec {basis} {pack}'.") pack_builder: PackBuilder = BASE_PACK[args.strategy_pack] kwargs = dict() if args.length is not None: valid_kwarg_or_error(pack_builder, "length", args.strategy_pack) kwargs["length"] = args.length if args.strategy_pack == "regular_insertion_encoding": basis = [Perm.to_standard(p) for p in args.basis.split("_")] if is_insertion_encodable_maximum(basis): kwargs["direction"] = DIR_SOUTH elif is_insertion_encodable_rightmost(basis): kwargs["direction"] = DIR_WEST else: parser.error( "The basis does not have regular insertion encoding, " "so try another pack. Note: the extra args of the 'tilescope' " "command don't work with this pack, use instead the packs " "insertion_row_and_col_placements which expands in a similar " "fashion, but has more powerful strategies.") pack = pack_builder(**kwargs) if args.fusion: pack = pack.make_fusion() if args.database: pack = pack.make_database() if args.symmetries: pack = pack.add_all_symmetry() if args.elementary: pack = pack.make_elementary() return pack
def pack(comb_class: Tiling) -> StrategyPack: if any(isinstance(ass, ComponentAssumption) for ass in comb_class.assumptions): raise InvalidOperationError( "Can't find generating function with component assumption." ) # pylint: disable=import-outside-toplevel from tilings.tilescope import TileScopePack assert comb_class.dimensions == (1, 1) basis, _ = comb_class.cell_basis()[(0, 0)] if any( any(p.contains(patt) for patt in basis) for p in [ Perm((0, 2, 1)), Perm((1, 2, 0)), Perm((1, 0, 2)), Perm((2, 0, 1)), ] ): # subclass of Av(231) or a symmetry, use point placements! return TileScopePack.point_and_row_and_col_placements().add_verification( BasicVerificationStrategy(), replace=True ) if is_insertion_encodable_maximum(basis): return TileScopePack.regular_insertion_encoding(3) if is_insertion_encodable_rightmost(basis): return TileScopePack.regular_insertion_encoding(2) # if it is the class or positive class if not comb_class.requirements or ( len(comb_class.requirements) == 1 and len(comb_class.requirements[0]) == 1 and len(comb_class.requirements[0][0]) <= 2 ): if basis in ([Perm((0, 1, 2))], [Perm((2, 1, 0))]): # Av(123) or Av(321) - use fusion! return ( TileScopePack.row_and_col_placements(row_only=True) .make_fusion(tracked=True) .add_basis(basis) ) if (Perm((0, 1, 2)) in basis or Perm((2, 1, 0)) in basis) and all( len(p) <= 4 for p in basis ): # is a subclass of Av(123) avoiding patterns of length <= 4 # experimentally showed that such clsses always terminates return TileScopePack.row_and_col_placements().add_basis(basis) raise InvalidOperationError( "Cannot get a specification for one by one verification for " f"subclass Av({basis})" )
def has_rightmost_insertion_encoding(tiling: Tiling) -> bool: return tiling.dimensions[0] == 1 and all( is_insertion_encodable_rightmost(basis) for basis, _ in tiling.cell_basis().values() )