From a2482950bfd0342e9cf9f6ba69bd8ea5a22b5716 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Fri, 7 Nov 2025 12:38:18 +0000 Subject: [PATCH 01/32] Update README.md --- README.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 82a1798..290badf 100644 --- a/README.md +++ b/README.md @@ -1 +1,29 @@ -# MapplePy +############################### +MapplePy +############################### + +MapplePy is a python library for enumerating Cayley permutation classes which avoid non-classical patterns and grid classes. + +A Cayley permutation is a word `π ∈ ℕ*` such that every number between 1 and the maximum value of `π` appears at least once. Cayley permutations can be seen as a generalisation of permutations where repeated values are allowed. Definitions of pattern containment and Cayley permutation classes follow the same ideas as defined for permutations where the patterns contained are also Cayley permutations, so the Cayley permutation class Av(11) describes all permutations. Cayley permutations are in bijection with ordered set partitions. + +If you need support, you can join us in our `Discord support server`_. + +.. _Discord support server: https://discord.gg/ngPZVT5 + +========== +Installing +========== + +To install MapplePy on your system, run the following after cloning the repository: + +.. code-block:: bash + + ./pip install . + +It is also possible to install MapplePy in development mode to work on the +source code, in which case you run the following after cloning the repository: + +.. code-block:: bash + + ./pip install -e . + From 8896d5fd65184900acaec6891d69d73705a80ec1 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Fri, 7 Nov 2025 12:38:35 +0000 Subject: [PATCH 02/32] Rename README.md to README.rst --- README.md => README.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README.md => README.rst (100%) diff --git a/README.md b/README.rst similarity index 100% rename from README.md rename to README.rst From 994a71e23113f8721ee1b609a800a1ae406034a2 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Mon, 16 Mar 2026 15:41:14 +0000 Subject: [PATCH 03/32] added strategy --- mapplings/strategies/mapped_tilescope.py | 1 + mapplings/strategies/tilescope_strategies.py | 61 +++++++++++++++++++- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/mapplings/strategies/mapped_tilescope.py b/mapplings/strategies/mapped_tilescope.py index 95be61f..8d66ad4 100644 --- a/mapplings/strategies/mapped_tilescope.py +++ b/mapplings/strategies/mapped_tilescope.py @@ -19,6 +19,7 @@ MapplingLessThanRowColSeparationStrategy, MapplingLessThanOrEqualRowColSeparationStrategy, MapplingCellInsertionFactory, + MapplingObstructionTransitivityStrategy, ) diff --git a/mapplings/strategies/tilescope_strategies.py b/mapplings/strategies/tilescope_strategies.py index 9a6423e..de0bed2 100644 --- a/mapplings/strategies/tilescope_strategies.py +++ b/mapplings/strategies/tilescope_strategies.py @@ -1,7 +1,11 @@ """Strategies for mapplings tilescope.""" -from typing import Iterator -from gridded_cayley_permutations import Tiling, GriddedCayleyPerm +from typing import Iterator, Iterable +from gridded_cayley_permutations import ( + Tiling, + GriddedCayleyPerm, + ObstructionTransitivity, +) from gridded_cayley_permutations.point_placements import DIRECTIONS from tilescope.strategies import ( FactorStrategy, @@ -14,6 +18,7 @@ RowInsertionFactory, ColInsertionFactory, RequirementInsertionStrategy, + AbstractObstructionTransitivityStrategy, ) from tilescope.strategies.point_placements import ( @@ -30,7 +35,7 @@ ) from comb_spec_searcher.exception import StrategyDoesNotApply from cayley_permutations import CayleyPermutation -from mapplings import MappedTiling +from mapplings import MappedTiling, Parameter from mapplings.algorithms import ( MTRequirementPlacement, Factor, @@ -365,3 +370,53 @@ def decomposition_function(self, comb_class): if algo.separation.row_col_map.is_identity(): raise StrategyDoesNotApply return tuple(map(self.__class__.cleaner, algo.separate())) + + +class MapplingObstructionTransitivityStrategy(AbstractObstructionTransitivityStrategy): + """A strategy for adding new obstructions to the tiling based on the current obstructions.""" + + def decomposition_function( + self, comb_class: MappedTiling + ) -> tuple[MappedTiling, ...]: + """Updates base tiling, avoiding parameters, and containing parameters + based on obstruction transitivity.""" + new_bt_obs = ObstructionTransitivity(comb_class).new_obs() + found_new_obs = bool(new_bt_obs) + new_av_params, found_new = self.obs_trans_for_param_list( + comb_class.avoiding_parameters + ) + found_new_obs = found_new_obs or found_new + new_cont_params = [] + for cont_param_list in comb_class.containment_parameters: + new_cont_param_list, found_new = self.obs_trans_for_param_list( + cont_param_list + ) + new_cont_params.append(new_cont_param_list) + found_new_obs = found_new_obs or found_new + + if not found_new_obs: + raise StrategyDoesNotApply("No new obstructions to add.") + return ( + MappedTiling( + comb_class.add_obstructions(new_bt_obs).tiling, + new_av_params, + new_cont_params, + comb_class.enumerating_parameters, + simplify=True, + ), + ) + + def obs_trans_for_param_list( + self, param_list: Iterable[Parameter] + ) -> tuple[list[Parameter], bool]: + """Does obstruction transitivity on each param in a param list, + returns the new list and a bool if any new obstructions were added.""" + added_obs = False + new_param_list = [] + for param in param_list: + new_obs = ObstructionTransitivity(param).new_obs() + if new_obs: + added_obs = True + param = param.add_obstructions(new_obs) + new_param_list.append(param) + return new_param_list, added_obs From ebda413a1ee2594a094e4e6646876b66fa2420d6 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Mon, 16 Mar 2026 15:46:01 +0000 Subject: [PATCH 04/32] added to strategy packs --- mapplings/strategies/mapped_tilescope.py | 12 ++++++++++++ mapplings/strategies/tilescope_strategies.py | 5 ++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/mapplings/strategies/mapped_tilescope.py b/mapplings/strategies/mapped_tilescope.py index 8d66ad4..63e96c1 100644 --- a/mapplings/strategies/mapped_tilescope.py +++ b/mapplings/strategies/mapped_tilescope.py @@ -39,6 +39,7 @@ def atom_verification_point_placement(cls): MapplingFactorStrategy(), MapplingLessThanOrEqualRowColSeparationStrategy(), MapplingPointPlacementFactory(), + MapplingObstructionTransitivityStrategy(), ], inferral_strats=[ # CleaningStrategy(), @@ -67,6 +68,7 @@ def no_param_ver_point_placement(cls): MapplingFactorStrategy(), MapplingLessThanOrEqualRowColSeparationStrategy(), MapplingPointPlacementFactory(), + MapplingObstructionTransitivityStrategy(), ], inferral_strats=[ # CleaningStrategy(), @@ -96,6 +98,7 @@ def no_param_ver_row_and_col_placement(cls): initial_strats=[ MapplingFactorStrategy(), MapplingLessThanOrEqualRowColSeparationStrategy(), + MapplingObstructionTransitivityStrategy(), ], inferral_strats=[ # CleaningStrategy(), @@ -126,6 +129,7 @@ def atom_verification_row_and_col_placement(cls): initial_strats=[ MapplingFactorStrategy(), MapplingLessThanOrEqualRowColSeparationStrategy(), + MapplingObstructionTransitivityStrategy(), ], inferral_strats=[ # CleaningStrategy(), @@ -155,6 +159,7 @@ def point_placement(cls, rootmt: MappedTiling): MapplingFactorStrategy(), MapplingLessThanOrEqualRowColSeparationStrategy(), MapplingPointPlacementFactory(), + MapplingObstructionTransitivityStrategy(), ], inferral_strats=[ # CleaningStrategy(), @@ -185,6 +190,7 @@ def row_placement(cls, rootmt: MappedTiling): initial_strats=[ MapplingFactorStrategy(), MapplingLessThanOrEqualRowColSeparationStrategy(), + MapplingObstructionTransitivityStrategy(), ], inferral_strats=[ # CleaningStrategy(), @@ -215,6 +221,7 @@ def col_placement(cls, rootmt: MappedTiling): initial_strats=[ MapplingFactorStrategy(), MapplingLessThanOrEqualRowColSeparationStrategy(), + MapplingObstructionTransitivityStrategy(), ], inferral_strats=[ # CleaningStrategy(), @@ -245,6 +252,7 @@ def row_and_col_placement(cls, rootmt: MappedTiling): initial_strats=[ MapplingFactorStrategy(), MapplingLessThanOrEqualRowColSeparationStrategy(), + MapplingObstructionTransitivityStrategy(), ], inferral_strats=[ # CleaningStrategy(), @@ -277,6 +285,7 @@ def point_row_and_col_placement(cls, rootmt: MappedTiling): MapplingFactorStrategy(), MapplingLessThanOrEqualRowColSeparationStrategy(), MapplingPointPlacementFactory(), + MapplingObstructionTransitivityStrategy(), ], inferral_strats=[ # CleaningStrategy(), @@ -309,6 +318,7 @@ def vertical_insertion_encoding(cls): initial_strats=[ MapplingFactorStrategy(), MapplingVerticalInsertionEncodingRequirementInsertionFactory(), + MapplingObstructionTransitivityStrategy(), ], inferral_strats=[], # CleaningStrategy() expansion_strats=[[MapplingVerticalInsertionEncodingPlacementFactory()]], @@ -327,6 +337,7 @@ def horizontal_insertion_encoding(cls): initial_strats=[ MapplingFactorStrategy(), MapplingHorizontalInsertionEncodingRequirementInsertionFactory(), + MapplingObstructionTransitivityStrategy(), ], inferral_strats=[], # CleaningStrategy() expansion_strats=[[MapplingHorizontalInsertionEncodingPlacementFactory()]], @@ -347,6 +358,7 @@ def insertion_row_and_col_placement(cls, rootmt: MappedTiling): MapplingFactorStrategy(), MapplingLessThanOrEqualRowColSeparationStrategy(), MapplingCellInsertionFactory(), + MapplingObstructionTransitivityStrategy(), ], inferral_strats=[ # CleaningStrategy(), diff --git a/mapplings/strategies/tilescope_strategies.py b/mapplings/strategies/tilescope_strategies.py index de0bed2..e376c77 100644 --- a/mapplings/strategies/tilescope_strategies.py +++ b/mapplings/strategies/tilescope_strategies.py @@ -379,7 +379,10 @@ def decomposition_function( self, comb_class: MappedTiling ) -> tuple[MappedTiling, ...]: """Updates base tiling, avoiding parameters, and containing parameters - based on obstruction transitivity.""" + based on obstruction transitivity. + + TODO: As we're adding obstructions, we should simplify the parameter's tilings + too. Should this happen when simplify=True for a mappling?""" new_bt_obs = ObstructionTransitivity(comb_class).new_obs() found_new_obs = bool(new_bt_obs) new_av_params, found_new = self.obs_trans_for_param_list( From ccfe278b7131f2ad75b3060415c9c944ef42cec6 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Wed, 18 Mar 2026 15:22:31 +0000 Subject: [PATCH 05/32] make mappling empty if any empty avoiding params --- mapplings/cleaners/mappling_cleaner.py | 6 +++--- mapplings/mapped_tiling.py | 6 ++++++ mapplings/parameter_list.py | 3 +++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/mapplings/cleaners/mappling_cleaner.py b/mapplings/cleaners/mappling_cleaner.py index b0d7398..a053a80 100644 --- a/mapplings/cleaners/mappling_cleaner.py +++ b/mapplings/cleaners/mappling_cleaner.py @@ -152,6 +152,8 @@ def reap_all_contradictions(mappling: MappedTiling) -> MappedTiling: return MappedTiling.empty_mappling() new_containers.append(new_c_list) new_avoiders = mappling.avoiding_parameters.remove_contradictions(base) + if any(param.dimensions == (0, 0) for param in new_avoiders): + return MappedTiling.empty_mappling() new_enumerators = [] for e_list in mappling.enumerating_parameters: new_e_list = e_list.remove_contradictions(base) @@ -247,7 +249,7 @@ def reduce_all_parameter_gcps(mappling: MappedTiling) -> MappedTiling: avoiders, containers, enumerators = mappling.apply_to_all_parameters( param_reducer ).ace_parameters() - new_avoiders = ParameterList(av for av in avoiders if av.dimensions != (0, 0)) + new_avoiders = ParameterList(avoiders) return MappedTiling(mappling.tiling, new_avoiders, containers, enumerators) @staticmethod @@ -270,7 +272,6 @@ def small_ob_inferral(mappling: MappedTiling) -> MappedTiling: for avoider in new_mappling.avoiding_parameters.apply_to_all( MTCleaner._cayley_ob_adjust_param, (ob,) ) - if avoider.dimensions != (0, 0) ) new_containers = tuple( ParameterList( @@ -293,7 +294,6 @@ def small_ob_inferral(mappling: MappedTiling) -> MappedTiling: for avoider in new_mappling.avoiding_parameters.apply_to_all( MTCleaner._ob_adjust_param, (ob,) ) - if avoider.dimensions != (0, 0) ) new_containers = tuple( ParameterList( diff --git a/mapplings/mapped_tiling.py b/mapplings/mapped_tiling.py index 1f2cf5d..b91f790 100644 --- a/mapplings/mapped_tiling.py +++ b/mapplings/mapped_tiling.py @@ -42,6 +42,12 @@ def __init__( self.containing_parameters = tuple(sorted(containing_parameters)) self.enumerating_parameters = tuple(sorted(enumerating_parameters)) self.tiling = tiling + + if any(param.dimensions == (0, 0) for param in avoiding_parameters): + self.tiling = Tiling.empty_tiling() + self.avoiding_parameters = ParameterList() + self.containing_parameters = tuple() + self.enumerating_parameters = tuple() super().__init__( tiling.obstructions, tiling.requirements, tiling.dimensions, simplify ) diff --git a/mapplings/parameter_list.py b/mapplings/parameter_list.py index 61770be..8321e48 100644 --- a/mapplings/parameter_list.py +++ b/mapplings/parameter_list.py @@ -127,3 +127,6 @@ def __lt__(self, other: object): if isinstance(other, ParameterList): return tuple(sorted(self)) < tuple(sorted(other)) return NotImplemented + + def __getitem__(self, key): + return sorted(self)[key] From b436dc5193e633e62047b3356e4b01491d444885 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Mon, 4 May 2026 10:32:16 +0100 Subject: [PATCH 06/32] missing brackets --- mapplings/strategies/mapped_tilescope.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapplings/strategies/mapped_tilescope.py b/mapplings/strategies/mapped_tilescope.py index 37d6f11..dd4378f 100644 --- a/mapplings/strategies/mapped_tilescope.py +++ b/mapplings/strategies/mapped_tilescope.py @@ -98,7 +98,7 @@ def no_param_ver_row_and_col_placement(cls): initial_strats=[ MapplingFactorStrategy(), MapplingLessThanOrEqualRowColSeparationFactory(), - MapplingObstructionTransitivityStrategy + MapplingObstructionTransitivityStrategy(), ], inferral_strats=[ # CleaningStrategy(), From a580ec860f57f47bc16afbe668fcdcb4aff9e5ab Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Mon, 4 May 2026 12:31:18 +0100 Subject: [PATCH 07/32] typo --- mapplings/strategies/tilescope_strategies.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mapplings/strategies/tilescope_strategies.py b/mapplings/strategies/tilescope_strategies.py index e94c929..a03d644 100644 --- a/mapplings/strategies/tilescope_strategies.py +++ b/mapplings/strategies/tilescope_strategies.py @@ -8,7 +8,6 @@ ) from gridded_cayley_permutations.point_placements import ( DIRECTIONS, - DIR_LEFT_BOT, DIR_RIGHT_BOT, DIR_LEFT_TOP, @@ -27,7 +26,7 @@ AbstractPointPlacementFactory, AbstractRowInsertionFactory, AbstractColInsertionFactory, - AbstractRequirementInsertionStrategy, + AbstractRequirementInsertionStrategy, AbstractObstructionTransitivityStrategy, ) from tilescope.strategies.row_column_separation import LessThanOrEqualRowColSeparation @@ -50,7 +49,6 @@ ) from mapplings.cleaners import MTCleaner, ParamCleaner - MTCleaner.global_log_toggle(1) temp = CombinatorialSpecificationSearcher.status @@ -415,6 +413,8 @@ def __call__( yield MapplingLessThanOrEqualRowColSeparationStrategy( row_order=row_order, ) + + class MapplingObstructionTransitivityStrategy(AbstractObstructionTransitivityStrategy): """A strategy for adding new obstructions to the tiling based on the current obstructions.""" @@ -433,7 +433,7 @@ def decomposition_function( ) found_new_obs = found_new_obs or found_new new_cont_params = [] - for cont_param_list in comb_class.containment_parameters: + for cont_param_list in comb_class.containing_parameters: new_cont_param_list, found_new = self.obs_trans_for_param_list( cont_param_list ) From d5748e7e8d90f32f53e256cc7c602b49bc212262 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Mon, 4 May 2026 13:00:57 +0100 Subject: [PATCH 08/32] add_obstructions to params create params, not tilings Co-authored-by: Copilot --- mapplings/parameter.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mapplings/parameter.py b/mapplings/parameter.py index 6012c18..5548e53 100644 --- a/mapplings/parameter.py +++ b/mapplings/parameter.py @@ -50,6 +50,13 @@ def injective_cells(self) -> set[Cell]: ) return set(product(inj_cols, inj_rows)) + def add_obstructions( + self, obstructions: Iterable[GriddedCayleyPerm] + ) -> "Parameter": + """Returns a new parameter with the obstructions added to the ghost.""" + new_ghost = super().add_obstructions(obstructions) + return Parameter(new_ghost, self.map) + def preimage_of_gcp(self, gcperm: GriddedCayleyPerm) -> Iterator[GriddedCayleyPerm]: """Returns the preimage of a gridded cayley permutation""" for gcp in self.map.preimage_of_gridded_cperm(gcperm): From 4b4fd1f7a1641c778531b11557747f044a25703c Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Mon, 4 May 2026 13:11:09 +0100 Subject: [PATCH 09/32] tox Co-authored-by: Copilot --- mapplings/parameter.py | 6 ++---- mapplings/strategies/tilescope_strategies.py | 3 ++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/mapplings/parameter.py b/mapplings/parameter.py index 5548e53..7ada1c2 100644 --- a/mapplings/parameter.py +++ b/mapplings/parameter.py @@ -50,11 +50,9 @@ def injective_cells(self) -> set[Cell]: ) return set(product(inj_cols, inj_rows)) - def add_obstructions( - self, obstructions: Iterable[GriddedCayleyPerm] - ) -> "Parameter": + def add_obstructions(self, gcps: Iterable[GriddedCayleyPerm]) -> "Parameter": """Returns a new parameter with the obstructions added to the ghost.""" - new_ghost = super().add_obstructions(obstructions) + new_ghost = super().add_obstructions(gcps) return Parameter(new_ghost, self.map) def preimage_of_gcp(self, gcperm: GriddedCayleyPerm) -> Iterator[GriddedCayleyPerm]: diff --git a/mapplings/strategies/tilescope_strategies.py b/mapplings/strategies/tilescope_strategies.py index a03d644..aefa045 100644 --- a/mapplings/strategies/tilescope_strategies.py +++ b/mapplings/strategies/tilescope_strategies.py @@ -30,6 +30,7 @@ AbstractObstructionTransitivityStrategy, ) from tilescope.strategies.row_column_separation import LessThanOrEqualRowColSeparation +from mapplings import MappedTiling, ParameterList, Parameter from comb_spec_searcher import ( @@ -437,7 +438,7 @@ def decomposition_function( new_cont_param_list, found_new = self.obs_trans_for_param_list( cont_param_list ) - new_cont_params.append(new_cont_param_list) + new_cont_params.append(ParameterList(new_cont_param_list)) found_new_obs = found_new_obs or found_new if not found_new_obs: From 295f4e9d7f10b1dcfbf3ae0fc32a41b1ec2421ad Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Mon, 4 May 2026 13:33:47 +0100 Subject: [PATCH 10/32] tox --- mapplings/strategies/tilescope_strategies.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/mapplings/strategies/tilescope_strategies.py b/mapplings/strategies/tilescope_strategies.py index aefa045..52e3256 100644 --- a/mapplings/strategies/tilescope_strategies.py +++ b/mapplings/strategies/tilescope_strategies.py @@ -30,16 +30,13 @@ AbstractObstructionTransitivityStrategy, ) from tilescope.strategies.row_column_separation import LessThanOrEqualRowColSeparation -from mapplings import MappedTiling, ParameterList, Parameter - - from comb_spec_searcher import ( DisjointUnionStrategy, CombinatorialSpecificationSearcher, ) from comb_spec_searcher.exception import StrategyDoesNotApply from cayley_permutations import CayleyPermutation -from mapplings import MappedTiling, Parameter +from mapplings import MappedTiling, Parameter, ParameterList from mapplings.algorithms import ( MTRequirementPlacement, MTFactors, From 7466aca1a213596165022d42753bca9585eeb7ce Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Mon, 4 May 2026 14:36:16 +0100 Subject: [PATCH 11/32] toml rather than setup.py Co-authored-by: Copilot --- pyproject.toml | 22 ++++++++++++++++++++++ setup.py | 14 -------------- 2 files changed, 22 insertions(+), 14 deletions(-) create mode 100644 pyproject.toml delete mode 100644 setup.py diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..8d3e065 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,22 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "mapped_tilings" +version = "0.1.0" +description = "A module for using mapped tilings." +authors = [ + { name = "Reed Acton" }, + { name = "Christian Bean", email = "c.n.bean@keele.ac.uk" }, + { name = "Abigail Ollson" } +] +dependencies = [ + "comb_spec_searcher @ git+https://github.com/PermutaTriangle/comb_spec_searcher@main", + "cayley_perms @ git+https://github.com/Ollson2921/CayleyPerms@main", +] +readme = "README.rst" + +[tool.setuptools.packages.find] +where = ["."] +namespaces = true \ No newline at end of file diff --git a/setup.py b/setup.py deleted file mode 100644 index ed15c21..0000000 --- a/setup.py +++ /dev/null @@ -1,14 +0,0 @@ -from setuptools import setup, find_namespace_packages - -setup( - name="mapped_tilings", - version="0.1.0", - description="A module for using mapped tilings.", - author="Reed Acton, Christian Bean, and Abigail Ollson", - author_email="c.n.bean@keele.ac.uk", - packages=find_namespace_packages(), - install_requires=[ - "comb_spec_searcher @ git+https://github.com/PermutaTriangle/comb_spec_searcher", - "cayley_perms @ git+https://github.com/Ollson2921/CayleyPerms", - ], # external packages as dependencies -) From 0af60673559a7dfca6f933af51c943334dfc949e Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Mon, 4 May 2026 14:39:15 +0100 Subject: [PATCH 12/32] wrong branch --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8d3e065..b960f35 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ authors = [ { name = "Abigail Ollson" } ] dependencies = [ - "comb_spec_searcher @ git+https://github.com/PermutaTriangle/comb_spec_searcher@main", + "comb_spec_searcher @ git+https://github.com/PermutaTriangle/comb_spec_searcher", "cayley_perms @ git+https://github.com/Ollson2921/CayleyPerms@main", ] readme = "README.rst" From 2516812ba038fb57e76dd8a3a76b0b47370d8c96 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Mon, 4 May 2026 15:08:21 +0100 Subject: [PATCH 13/32] hatchling --- pyproject.toml | 34 ++++++++++++++++++++++++++++------ tox.ini | 2 +- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b960f35..e812014 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [build-system] -requires = ["setuptools>=61.0"] -build-backend = "setuptools.build_meta" +requires = ["hatchling"] +build-backend = "hatchling.build" [project] name = "mapped_tilings" @@ -12,11 +12,33 @@ authors = [ { name = "Abigail Ollson" } ] dependencies = [ - "comb_spec_searcher @ git+https://github.com/PermutaTriangle/comb_spec_searcher", + "comb-spec-searcher>=4.2.1", "cayley_perms @ git+https://github.com/Ollson2921/CayleyPerms@main", ] readme = "README.rst" -[tool.setuptools.packages.find] -where = ["."] -namespaces = true \ No newline at end of file +[tool.hatch.metadata] +allow-direct-references = true + +[tool.hatch.build.targets.wheel] +packages = ["mapped_tilings"] + +[tool.hatchling.build.targets.sdist] +include = [ + "mapplings", + "tests", + "README.rst", +] + +[tool.black] +target-version = ["py312"] +line-length = 88 +include = "\\.pyi?$" +exclude = ''' +/( + \.git + | \.venv + | build + | dist +)/ +''' \ No newline at end of file diff --git a/tox.ini b/tox.ini index 8de40f9..1cc54df 100644 --- a/tox.ini +++ b/tox.ini @@ -38,7 +38,7 @@ skip_install = True deps = flake8 commands = - flake8 mapplings tests setup.py + flake8 mapplings tests [testenv:pylint] description = run pylint (static code analysis) From 3f9050c81a4b1ffa355a5e96f34b2addb50421e3 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Mon, 4 May 2026 15:46:09 +0100 Subject: [PATCH 14/32] update black --- pyproject.toml | 2 +- tox.ini | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e812014..c945fd8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ readme = "README.rst" allow-direct-references = true [tool.hatch.build.targets.wheel] -packages = ["mapped_tilings"] +packages = ["."] [tool.hatchling.build.targets.sdist] include = [ diff --git a/tox.ini b/tox.ini index 1cc54df..d09fbe4 100644 --- a/tox.ini +++ b/tox.ini @@ -59,5 +59,5 @@ commands = mypy mapplings description = check that comply with autoformating basepython = {[default]basepython} deps = - black==22.12.0 -commands = black --check --diff . + black>=24.0.0 +commands = black --check --diff mapplings From 6f515a80ee028aeb72d66b3ee81ec034c4981215 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Mon, 4 May 2026 16:04:46 +0100 Subject: [PATCH 15/32] black --- mapplings/algorithms/__init__.py | 1 - mapplings/algorithms/factor.py | 1 - mapplings/mapped_tiling.py | 1 - mapplings/parameter_list.py | 1 - mapplings/strategies/__init__.py | 1 - mapplings/strategies/tilescope_strategies.py | 1 - playground/all_vincular_pairs.py | 6 +++--- 7 files changed, 3 insertions(+), 9 deletions(-) diff --git a/mapplings/algorithms/__init__.py b/mapplings/algorithms/__init__.py index c628412..d4fe5fd 100644 --- a/mapplings/algorithms/__init__.py +++ b/mapplings/algorithms/__init__.py @@ -4,7 +4,6 @@ from .row_col_sep_mt import MTLTRowColSeparation, MTLTORERowColSeparation from .point_placement import MTRequirementPlacement - __all__ = [ "MTFactors", "MTILFactorNormal", diff --git a/mapplings/algorithms/factor.py b/mapplings/algorithms/factor.py index 836cdf2..792ad31 100644 --- a/mapplings/algorithms/factor.py +++ b/mapplings/algorithms/factor.py @@ -9,7 +9,6 @@ from mapplings import MappedTiling, ParameterList, Parameter from mapplings.cleaners import MTCleaner - Cell = tuple[int, int] diff --git a/mapplings/mapped_tiling.py b/mapplings/mapped_tiling.py index 1f2cf5d..750f7cb 100644 --- a/mapplings/mapped_tiling.py +++ b/mapplings/mapped_tiling.py @@ -15,7 +15,6 @@ from .parameter import Parameter from .parameter_list import ParameterList - Objects = DefaultDict[tuple[int, ...], List[GriddedCayleyPerm]] Cell = tuple[int, int] diff --git a/mapplings/parameter_list.py b/mapplings/parameter_list.py index 61770be..9ede2ee 100644 --- a/mapplings/parameter_list.py +++ b/mapplings/parameter_list.py @@ -13,7 +13,6 @@ from .parameter import Parameter - Cell = tuple[int, int] FuncTypeT = TypeVar("FuncTypeT") diff --git a/mapplings/strategies/__init__.py b/mapplings/strategies/__init__.py index 3db7f5d..6dcd69a 100644 --- a/mapplings/strategies/__init__.py +++ b/mapplings/strategies/__init__.py @@ -2,6 +2,5 @@ from .mapped_tilescope import MappedTileScopePack - __all__ = ["MappedTileScopePack"] __version__ = "0.1.0" diff --git a/mapplings/strategies/tilescope_strategies.py b/mapplings/strategies/tilescope_strategies.py index 62d881d..e748b51 100644 --- a/mapplings/strategies/tilescope_strategies.py +++ b/mapplings/strategies/tilescope_strategies.py @@ -44,7 +44,6 @@ ) from mapplings.cleaners import MTCleaner, ParamCleaner - MTCleaner.global_log_toggle(1) temp = CombinatorialSpecificationSearcher.status diff --git a/playground/all_vincular_pairs.py b/playground/all_vincular_pairs.py index c8886fd..339f61e 100644 --- a/playground/all_vincular_pairs.py +++ b/playground/all_vincular_pairs.py @@ -48,9 +48,9 @@ f.write(json_str) spec.get_genf() from_table.append(mappling) - results[ - name - ] = f"Success: {[spec.count_objects_of_size(i) for i in range(check_depth)]}" + results[name] = ( + f"Success: {[spec.count_objects_of_size(i) for i in range(check_depth)]}" + ) except Exception as e: print(f"Av({key1}), Av({key2}): {e}") results[name] = f"Failure: {e}" From d8ba44743ec0d7ce4d8fe6676afaa4ef3eb29514 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Mon, 4 May 2026 20:25:08 +0100 Subject: [PATCH 16/32] css on develop --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c945fd8..6e645c4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ authors = [ { name = "Abigail Ollson" } ] dependencies = [ - "comb-spec-searcher>=4.2.1", + "comb_spec_searcher @ git+https://github.com/PermutaTriangle/comb_spec_searcher@develop", "cayley_perms @ git+https://github.com/Ollson2921/CayleyPerms@main", ] readme = "README.rst" From fab0468e0301d7938d397830efc20dfe16da9f80 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Mon, 4 May 2026 20:31:34 +0100 Subject: [PATCH 17/32] undo last commit --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6e645c4..c945fd8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ authors = [ { name = "Abigail Ollson" } ] dependencies = [ - "comb_spec_searcher @ git+https://github.com/PermutaTriangle/comb_spec_searcher@develop", + "comb-spec-searcher>=4.2.1", "cayley_perms @ git+https://github.com/Ollson2921/CayleyPerms@main", ] readme = "README.rst" From b11ac0b03e25035dfd6644f4c4d70361776bb768 Mon Sep 17 00:00:00 2001 From: ReedActon <110858904+ReedActon@users.noreply.github.com> Date: Thu, 7 May 2026 21:51:21 +0000 Subject: [PATCH 18/32] Unplacement Class Made the Unplacement as a cleaner. --- mapplings/algorithms/__init__.py | 2 + mapplings/cleaners/parameter_cleaner.py | 31 ++--------- mapplings/cleaners/unplacement.py | 68 +++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 27 deletions(-) create mode 100644 mapplings/cleaners/unplacement.py diff --git a/mapplings/algorithms/__init__.py b/mapplings/algorithms/__init__.py index c628412..837b37b 100644 --- a/mapplings/algorithms/__init__.py +++ b/mapplings/algorithms/__init__.py @@ -4,6 +4,7 @@ from .row_col_sep_mt import MTLTRowColSeparation, MTLTORERowColSeparation from .point_placement import MTRequirementPlacement +# from .unplacement import ParamUnplacement __all__ = [ "MTFactors", @@ -12,5 +13,6 @@ "MTLTRowColSeparation", "MTLTORERowColSeparation", "MTRequirementPlacement", + # "ParamUnplacement", ] __version__ = "0.1.0" diff --git a/mapplings/cleaners/parameter_cleaner.py b/mapplings/cleaners/parameter_cleaner.py index 8bbf388..fce459e 100644 --- a/mapplings/cleaners/parameter_cleaner.py +++ b/mapplings/cleaners/parameter_cleaner.py @@ -4,9 +4,9 @@ from itertools import chain from cayley_permutations import CayleyPermutation from gridded_cayley_permutations.row_col_map import RowColMap -from gridded_cayley_permutations.unplacement import PartialUnplacement from gridded_cayley_permutations import Tiling from mapplings import Parameter +from .unplacement import ParamUnplacement from .cleaner import GenericCleaner, Register, CleanerLog @@ -135,33 +135,10 @@ def to_remove( @reg(4, run_on_enumerators=False) def unplace_points(param: Parameter) -> Parameter: """Unplaces all possible points in the parameter""" - algo = PartialUnplacement(param.ghost) - points = param.single_value_cells() - cells, cols, rows = set[tuple[int, int]](), set[int](), set[int]() - for cell in points: - valid = algo.cell_in_valid_region(cell) - if valid[0] and param.col_map[cell[0] - 1] == param.col_map[cell[0] + 1]: - cells.add(cell) - cols.add(cell[0]) - if valid[1] and param.row_map[cell[1] - 1] == param.row_map[cell[1] + 1]: - cells.add(cell) - rows.add(cell[1]) - unplace_cols, unplace_rows = algo.fusable_check(cells, cols, rows) - if not (unplace_cols or unplace_rows): + if not param.positive_cells(): return param - new_ghost = algo.unplace(unplace_cols, unplace_rows) - col_preimages, row_preimages = algo.adjustment_map( - unplace_cols, unplace_rows - ).preimage_map() - new_col_map = { - i: param.col_map[col_preimages[i][0]] - for i in range(new_ghost.dimensions[0]) - } - new_row_map = { - i: param.row_map[row_preimages[i][0]] - for i in range(new_ghost.dimensions[1]) - } - return Parameter(new_ghost, RowColMap(new_col_map, new_row_map)) + algo = ParamUnplacement(param) + return algo.auto_unplace() @staticmethod @reg(3, run_on_enumerators=False) diff --git a/mapplings/cleaners/unplacement.py b/mapplings/cleaners/unplacement.py new file mode 100644 index 0000000..f048d5f --- /dev/null +++ b/mapplings/cleaners/unplacement.py @@ -0,0 +1,68 @@ +"""Contains the ParamUnplacement class""" + +from gridded_cayley_permutations.row_col_map import RowColMap +from gridded_cayley_permutations.unplacement import PartialUnplacement +from mapplings import Parameter, MappedTiling + + +class ParamUnplacement(PartialUnplacement): + """A class for unplacing point rows and cols in a parameter""" + + def __init__(self, param: Parameter): + self.param = param + # self.base = base_tiling + # self.base_obs = base_tiling.obstructions + super().__init__(param.ghost) + + def find_cols_and_rows(self) -> tuple[set[int], set[int]]: + """Uses the initialiser to find all valid rows and cols to unfuse""" + return self.check_cols_and_rows(self.point_cols, self.point_rows) + + def check_cols_and_rows( + self, check_cols: set[int], check_rows: set[int] + ) -> tuple[set[int], set[int]]: + """Filters the input cols and rows to only include those which can be unplaced.""" + valid_cols = check_cols & self.point_cols + valid_rows = check_rows & self.point_rows + try: + valid_cols = { + col + for col in valid_cols + if self.param.col_map[col - 1] == self.param.col_map[col + 1] + } + valid_rows = { + row + for row in valid_rows + if self.param.row_map[row - 1] == self.param.row_map[row + 1] + } + except: + input(self.param) + valid_cols = set(filter(self.col_fuse_check, valid_cols)) + valid_rows = set(filter(self.row_fuse_check, valid_rows)) + return valid_cols, valid_rows + + def param_unplace( + self, unplace_cols: set[int], unplace_rows: set[int] + ) -> Parameter: + """Unplaces rows and cols in the ghost and creates a new row col map""" + new_ghost = self.unplace(unplace_cols, unplace_rows) + + col_preimages, row_preimages = self.adjustment_map( + unplace_cols, unplace_rows + ).preimage_map() + + new_col_map = { + i: self.param.col_map[col_preimages[i][0]] + for i in range(new_ghost.dimensions[0]) + } + new_row_map = { + i: self.param.row_map[row_preimages[i][0]] + for i in range(new_ghost.dimensions[1]) + } + return Parameter(new_ghost, RowColMap(new_col_map, new_row_map)) + + def auto_unplace(self): + """Does all valid unplacements for the tiling's point cells""" + temp = self.param_unplace(set(), self.find_cols_and_rows()[1]) + new_algo = ParamUnplacement(temp) + return new_algo.param_unplace(new_algo.find_cols_and_rows()[0], set()) From 4cf08fb58d2b23f6c9964f2803463d754a5ae8c6 Mon Sep 17 00:00:00 2001 From: ReedActon <110858904+ReedActon@users.noreply.github.com> Date: Thu, 7 May 2026 21:54:23 +0000 Subject: [PATCH 19/32] Get rid of prints --- mapplings/cleaners/unplacement.py | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/mapplings/cleaners/unplacement.py b/mapplings/cleaners/unplacement.py index f048d5f..824640f 100644 --- a/mapplings/cleaners/unplacement.py +++ b/mapplings/cleaners/unplacement.py @@ -14,29 +14,22 @@ def __init__(self, param: Parameter): # self.base_obs = base_tiling.obstructions super().__init__(param.ghost) - def find_cols_and_rows(self) -> tuple[set[int], set[int]]: - """Uses the initialiser to find all valid rows and cols to unfuse""" - return self.check_cols_and_rows(self.point_cols, self.point_rows) - def check_cols_and_rows( self, check_cols: set[int], check_rows: set[int] ) -> tuple[set[int], set[int]]: """Filters the input cols and rows to only include those which can be unplaced.""" valid_cols = check_cols & self.point_cols valid_rows = check_rows & self.point_rows - try: - valid_cols = { - col - for col in valid_cols - if self.param.col_map[col - 1] == self.param.col_map[col + 1] - } - valid_rows = { - row - for row in valid_rows - if self.param.row_map[row - 1] == self.param.row_map[row + 1] - } - except: - input(self.param) + valid_cols = { + col + for col in valid_cols + if self.param.col_map[col - 1] == self.param.col_map[col + 1] + } + valid_rows = { + row + for row in valid_rows + if self.param.row_map[row - 1] == self.param.row_map[row + 1] + } valid_cols = set(filter(self.col_fuse_check, valid_cols)) valid_rows = set(filter(self.row_fuse_check, valid_rows)) return valid_cols, valid_rows From 744c68879ae5eb8961603d57aad95546e4cfaa4d Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Tue, 12 May 2026 14:11:57 +0100 Subject: [PATCH 20/32] only make mappling empty if empty gcp not in obs --- mapplings/cleaners/mappling_cleaner.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mapplings/cleaners/mappling_cleaner.py b/mapplings/cleaners/mappling_cleaner.py index ab8928a..9aeec88 100644 --- a/mapplings/cleaners/mappling_cleaner.py +++ b/mapplings/cleaners/mappling_cleaner.py @@ -153,7 +153,10 @@ def reap_all_contradictions(mappling: MappedTiling) -> MappedTiling: new_containers.append(new_c_list) new_avoiders = mappling.avoiding_parameters.remove_contradictions(base) if any(param.dimensions == (0, 0) for param in new_avoiders): - return MappedTiling.empty_mappling() + if not GriddedCayleyPerm(CayleyPermutation(), ()) in param.obstructions + return MappedTiling.empty_mappling() + new_avoiders = [p for p in new_avoiders if param.dimensions != (0, 0)] + new_enumerators = [] for e_list in mappling.enumerating_parameters: new_e_list = e_list.remove_contradictions(base) From d6a07c90f87452808ac5f9653c1dba4185483929 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Tue, 12 May 2026 14:15:50 +0100 Subject: [PATCH 21/32] dont code online --- mapplings/cleaners/mappling_cleaner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapplings/cleaners/mappling_cleaner.py b/mapplings/cleaners/mappling_cleaner.py index 9aeec88..18623da 100644 --- a/mapplings/cleaners/mappling_cleaner.py +++ b/mapplings/cleaners/mappling_cleaner.py @@ -153,7 +153,7 @@ def reap_all_contradictions(mappling: MappedTiling) -> MappedTiling: new_containers.append(new_c_list) new_avoiders = mappling.avoiding_parameters.remove_contradictions(base) if any(param.dimensions == (0, 0) for param in new_avoiders): - if not GriddedCayleyPerm(CayleyPermutation(), ()) in param.obstructions + if not GriddedCayleyPerm(CayleyPermutation(), ()) in param.obstructions: return MappedTiling.empty_mappling() new_avoiders = [p for p in new_avoiders if param.dimensions != (0, 0)] From 8121808f8e0686701defc5948aa05b73420c8df9 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Tue, 12 May 2026 14:18:26 +0100 Subject: [PATCH 22/32] getting there --- mapplings/cleaners/mappling_cleaner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapplings/cleaners/mappling_cleaner.py b/mapplings/cleaners/mappling_cleaner.py index 18623da..65826be 100644 --- a/mapplings/cleaners/mappling_cleaner.py +++ b/mapplings/cleaners/mappling_cleaner.py @@ -155,7 +155,7 @@ def reap_all_contradictions(mappling: MappedTiling) -> MappedTiling: if any(param.dimensions == (0, 0) for param in new_avoiders): if not GriddedCayleyPerm(CayleyPermutation(), ()) in param.obstructions: return MappedTiling.empty_mappling() - new_avoiders = [p for p in new_avoiders if param.dimensions != (0, 0)] + new_avoiders = [p for p in new_avoiders if p.dimensions != (0, 0)] new_enumerators = [] for e_list in mappling.enumerating_parameters: From 4d842e58b4e28de8318f6be0c4afbb25662dec10 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Tue, 12 May 2026 14:27:38 +0100 Subject: [PATCH 23/32] tox --- mapplings/cleaners/mappling_cleaner.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/mapplings/cleaners/mappling_cleaner.py b/mapplings/cleaners/mappling_cleaner.py index 65826be..2a4ab5e 100644 --- a/mapplings/cleaners/mappling_cleaner.py +++ b/mapplings/cleaners/mappling_cleaner.py @@ -152,18 +152,19 @@ def reap_all_contradictions(mappling: MappedTiling) -> MappedTiling: return MappedTiling.empty_mappling() new_containers.append(new_c_list) new_avoiders = mappling.avoiding_parameters.remove_contradictions(base) - if any(param.dimensions == (0, 0) for param in new_avoiders): - if not GriddedCayleyPerm(CayleyPermutation(), ()) in param.obstructions: - return MappedTiling.empty_mappling() - new_avoiders = [p for p in new_avoiders if p.dimensions != (0, 0)] - + avoiders = [] + for param in new_avoiders: + if param.dimensions == (0,0) and not GriddedCayleyPerm(CayleyPermutation(), ()) in param.obstructions: + return MappedTiling.empty_mappling() + else: + avoiders.append(param) new_enumerators = [] for e_list in mappling.enumerating_parameters: new_e_list = e_list.remove_contradictions(base) if new_e_list: new_enumerators.append(e_list) return MappedTiling( - mappling.tiling, new_avoiders, new_containers, new_enumerators + mappling.tiling, avoiders, new_containers, new_enumerators ) @staticmethod From 744746fc5f45f8d8037262166fbcfb31b2fb8cce Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Tue, 12 May 2026 14:31:56 +0100 Subject: [PATCH 24/32] tox --- mapplings/cleaners/mappling_cleaner.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mapplings/cleaners/mappling_cleaner.py b/mapplings/cleaners/mappling_cleaner.py index 2a4ab5e..b0ab583 100644 --- a/mapplings/cleaners/mappling_cleaner.py +++ b/mapplings/cleaners/mappling_cleaner.py @@ -151,11 +151,14 @@ def reap_all_contradictions(mappling: MappedTiling) -> MappedTiling: if not new_c_list: return MappedTiling.empty_mappling() new_containers.append(new_c_list) - new_avoiders = mappling.avoiding_parameters.remove_contradictions(base) + new_avoiders = mappling.avoiding_parameters.remove_contradictions(base) avoiders = [] for param in new_avoiders: - if param.dimensions == (0,0) and not GriddedCayleyPerm(CayleyPermutation(), ()) in param.obstructions: - return MappedTiling.empty_mappling() + if ( + param.dimensions == (0, 0) + and not GriddedCayleyPerm(CayleyPermutation(()), ()) in param.obstructions + ): + return MappedTiling.empty_mappling() else: avoiders.append(param) new_enumerators = [] From 5938db363731fce765c5cc9b1d5b35ef062ba145 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Tue, 12 May 2026 14:36:25 +0100 Subject: [PATCH 25/32] pylint --- mapplings/cleaners/mappling_cleaner.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/mapplings/cleaners/mappling_cleaner.py b/mapplings/cleaners/mappling_cleaner.py index b0ab583..01d9871 100644 --- a/mapplings/cleaners/mappling_cleaner.py +++ b/mapplings/cleaners/mappling_cleaner.py @@ -151,17 +151,19 @@ def reap_all_contradictions(mappling: MappedTiling) -> MappedTiling: if not new_c_list: return MappedTiling.empty_mappling() new_containers.append(new_c_list) - new_avoiders = mappling.avoiding_parameters.remove_contradictions(base) + new_avoiders = mappling.avoiding_parameters.remove_contradictions(base) avoiders = [] for param in new_avoiders: - if ( - param.dimensions == (0, 0) - and not GriddedCayleyPerm(CayleyPermutation(()), ()) in param.obstructions - ): - return MappedTiling.empty_mappling() + if param.dimensions == (0, 0): + if ( + not GriddedCayleyPerm(CayleyPermutation(()), ()) + in param.obstructions + ): + return MappedTiling.empty_mappling() else: avoiders.append(param) new_enumerators = [] + new_enumerators = [] for e_list in mappling.enumerating_parameters: new_e_list = e_list.remove_contradictions(base) if new_e_list: From 2cf542cf1d0b9e061513a4f4274280a3a34ec646 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Tue, 12 May 2026 14:39:03 +0100 Subject: [PATCH 26/32] mypy --- mapplings/cleaners/mappling_cleaner.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mapplings/cleaners/mappling_cleaner.py b/mapplings/cleaners/mappling_cleaner.py index 01d9871..7e3de15 100644 --- a/mapplings/cleaners/mappling_cleaner.py +++ b/mapplings/cleaners/mappling_cleaner.py @@ -152,7 +152,7 @@ def reap_all_contradictions(mappling: MappedTiling) -> MappedTiling: return MappedTiling.empty_mappling() new_containers.append(new_c_list) new_avoiders = mappling.avoiding_parameters.remove_contradictions(base) - avoiders = [] + avoiders: list[Parameter] = [] for param in new_avoiders: if param.dimensions == (0, 0): if ( @@ -168,9 +168,7 @@ def reap_all_contradictions(mappling: MappedTiling) -> MappedTiling: new_e_list = e_list.remove_contradictions(base) if new_e_list: new_enumerators.append(e_list) - return MappedTiling( - mappling.tiling, avoiders, new_containers, new_enumerators - ) + return MappedTiling(mappling.tiling, avoiders, new_containers, new_enumerators) @staticmethod @reg(2) From 8d3f422702fc81180522479bada00eeb3812a2d4 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Tue, 12 May 2026 14:43:43 +0100 Subject: [PATCH 27/32] mypy --- mapplings/cleaners/mappling_cleaner.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mapplings/cleaners/mappling_cleaner.py b/mapplings/cleaners/mappling_cleaner.py index 7e3de15..7951df6 100644 --- a/mapplings/cleaners/mappling_cleaner.py +++ b/mapplings/cleaners/mappling_cleaner.py @@ -162,8 +162,7 @@ def reap_all_contradictions(mappling: MappedTiling) -> MappedTiling: return MappedTiling.empty_mappling() else: avoiders.append(param) - new_enumerators = [] - new_enumerators = [] + new_enumerators: list[Parameter] = [] for e_list in mappling.enumerating_parameters: new_e_list = e_list.remove_contradictions(base) if new_e_list: From ff02566c5d60a681387d3af20a7f9d31bf020494 Mon Sep 17 00:00:00 2001 From: Abigail Ollson <145692399+Ollson2921@users.noreply.github.com> Date: Tue, 12 May 2026 14:46:17 +0100 Subject: [PATCH 28/32] enumerators are param lists --- mapplings/cleaners/mappling_cleaner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapplings/cleaners/mappling_cleaner.py b/mapplings/cleaners/mappling_cleaner.py index 7951df6..8dcb8a4 100644 --- a/mapplings/cleaners/mappling_cleaner.py +++ b/mapplings/cleaners/mappling_cleaner.py @@ -162,7 +162,7 @@ def reap_all_contradictions(mappling: MappedTiling) -> MappedTiling: return MappedTiling.empty_mappling() else: avoiders.append(param) - new_enumerators: list[Parameter] = [] + new_enumerators: list[ParameterList] = [] for e_list in mappling.enumerating_parameters: new_e_list = e_list.remove_contradictions(base) if new_e_list: From 2f1e9996b2815badea6703ca0ef208c2a58cddeb Mon Sep 17 00:00:00 2001 From: ReedActon <110858904+ReedActon@users.noreply.github.com> Date: Tue, 12 May 2026 23:27:13 +0000 Subject: [PATCH 29/32] Added Base TIling Unplacement will now consider obs on the base tiling --- mapplings/cleaners/mappling_cleaner.py | 31 +++++++++++++++++++------ mapplings/cleaners/parameter_cleaner.py | 16 ++++++------- mapplings/cleaners/unplacement.py | 29 +++++++++++++++++++---- 3 files changed, 57 insertions(+), 19 deletions(-) diff --git a/mapplings/cleaners/mappling_cleaner.py b/mapplings/cleaners/mappling_cleaner.py index f020977..15bdb8c 100644 --- a/mapplings/cleaners/mappling_cleaner.py +++ b/mapplings/cleaners/mappling_cleaner.py @@ -14,6 +14,7 @@ from .cleaner import GenericCleaner, Register, CleanerLog from .parameter_cleaner import ParamCleaner +from .unplacement import ParamUnplacement default_param_cleaner = ParamCleaner.make_full_cleaner("Param Default Cleaner") @@ -83,6 +84,22 @@ def fully_clean_parameters(mappling: MappedTiling) -> MappedTiling: """Applies all parameter cleanning functions to all parameters""" return MTCleaner.clean_parameters(default_param_cleaner)(mappling) + @staticmethod + @reg(7) + def param_unplacement(mappling: MappedTiling) -> MappedTiling: + """Applies point unplacement to all avoiders and containers""" + avoiders, containers, enumerators = mappling.ace_parameters() + new_avoiders = ParameterList( + ParamUnplacement(av, mappling).auto_unplace() for av in avoiders + ) + new_containers = [ + ParameterList( + ParamUnplacement(co, mappling).auto_unplace() for co in c_list + ) + for c_list in containers + ] + return MappedTiling(mappling.tiling, new_avoiders, new_containers, enumerators) + @staticmethod @reg(0) def try_to_kill(mappling: MappedTiling) -> MappedTiling: @@ -106,7 +123,7 @@ def try_to_kill(mappling: MappedTiling) -> MappedTiling: return mappling @staticmethod - @reg(8, False) # Broken + @reg(9, False) # Broken def factor_containters(mappling: MappedTiling) -> MappedTiling: """Factors out the intersection factors of a containing parameter list""" new_containers = list( @@ -129,7 +146,7 @@ def factor_containters(mappling: MappedTiling) -> MappedTiling: ) @staticmethod - @reg(10, update_register=False) + @reg(11, update_register=False) def backmap_points(mappling: MappedTiling) -> MappedTiling: """Backmaps point obstructions to all parameters""" point_obstructions = (ob for ob in mappling.obstructions if len(ob) == 1) @@ -224,7 +241,7 @@ def remove_empty_rows_and_cols(mappling: MappedTiling) -> MappedTiling: ) @staticmethod - @reg(12) + @reg(13) def simple_reduce_redundant_parameters(mappling: MappedTiling) -> MappedTiling: """Removes any parameter implied by another with a basic check""" new_avoiders = mappling.avoiding_parameters.simple_remove_redundant() @@ -251,7 +268,7 @@ def reduce_all_parameter_gcps(mappling: MappedTiling) -> MappedTiling: return MappedTiling(mappling.tiling, new_avoiders, containers, enumerators) @staticmethod - @reg(11) + @reg(12) def small_ob_inferral(mappling: MappedTiling) -> MappedTiling: """Adds point obstructions implied by param point cells and small base tiling obstructions""" @@ -313,7 +330,7 @@ def small_ob_inferral(mappling: MappedTiling) -> MappedTiling: return new_mappling @staticmethod - @reg(7) + @reg(8) def forward_map_parameter_gcps_from_avoiders( mappling: MappedTiling, ) -> MappedTiling: @@ -362,7 +379,7 @@ def forward_map_parameter_gcps_from_avoiders( return MappedTiling(new_base, new_avoiders, containers, enumerators) @staticmethod - @reg(9) + @reg(10) def forward_map_parameter_gcps_from_containers( mappling: MappedTiling, ) -> MappedTiling: @@ -432,7 +449,7 @@ def reap_blank(mappling: MappedTiling) -> MappedTiling: ) @staticmethod - @reg(13) + @reg(14) def remove_blank_rows_and_cols_params(mappling: MappedTiling) -> MappedTiling: """Deletes all rows and cols in the parameters which have no obs or reqs, ignoring point rows and columns and obstructions which are already on the diff --git a/mapplings/cleaners/parameter_cleaner.py b/mapplings/cleaners/parameter_cleaner.py index fce459e..39455c3 100644 --- a/mapplings/cleaners/parameter_cleaner.py +++ b/mapplings/cleaners/parameter_cleaner.py @@ -131,14 +131,14 @@ def to_remove( return Parameter(Tiling([], [], (0, 0)), RowColMap({}, {})) return param.delete_rows_and_columns(cols_to_remove, rows_to_remove) - @staticmethod - @reg(4, run_on_enumerators=False) - def unplace_points(param: Parameter) -> Parameter: - """Unplaces all possible points in the parameter""" - if not param.positive_cells(): - return param - algo = ParamUnplacement(param) - return algo.auto_unplace() + # @staticmethod + # @reg(4, run_on_enumerators=False) + # def unplace_points(param: Parameter) -> Parameter: + # """Unplaces all possible points in the parameter""" + # if not param.positive_cells(): + # return param + # algo = ParamUnplacement(param) + # return algo.auto_unplace() @staticmethod @reg(3, run_on_enumerators=False) diff --git a/mapplings/cleaners/unplacement.py b/mapplings/cleaners/unplacement.py index 824640f..a346b96 100644 --- a/mapplings/cleaners/unplacement.py +++ b/mapplings/cleaners/unplacement.py @@ -1,6 +1,12 @@ """Contains the ParamUnplacement class""" -from gridded_cayley_permutations.row_col_map import RowColMap +from itertools import product +from typing import Iterator + +from gridded_cayley_permutations import RowColMap, GriddedCayleyPermutation +from gridded_cayley_permutations.simplify_obstructions_and_requirements import ( + SimplifyObstructionsAndRequirements as Simplify, +) from gridded_cayley_permutations.unplacement import PartialUnplacement from mapplings import Parameter, MappedTiling @@ -8,12 +14,27 @@ class ParamUnplacement(PartialUnplacement): """A class for unplacing point rows and cols in a parameter""" - def __init__(self, param: Parameter): + def __init__(self, param: Parameter, parent_mappling: MappedTiling): self.param = param - # self.base = base_tiling - # self.base_obs = base_tiling.obstructions + self.base = parent_mappling + self.base_obs = parent_mappling.obstructions super().__init__(param.ghost) + def implied_point_obs(self) -> Iterator[GriddedCayleyPermutation]: + """Finds point obs in the parameter that are implied by the base mappling""" + for cells in product(self.param.empty_cells(), self.param.positive_cells()): + pos = sorted(cells) + pattern = (pos[0][1] > pos[1][1], pos[1][1] > pos[0][1]) + gcp = GriddedCayleyPermutation(pattern, pos) + if self.param.map.map_gridded_cperm(gcp) not in self.base_obs: + yield GriddedCayleyPermutation((0,), (cells[0],)) + + def expected_obs(self) -> set[GriddedCayleyPermutation]: + unsimplified = super().expected_obs() | set(self.implied_point_obs()) + algo = Simplify(unsimplified, tuple(tuple()), self.param.dimensions) + algo.simplify() + return set(algo.obstructions) + def check_cols_and_rows( self, check_cols: set[int], check_rows: set[int] ) -> tuple[set[int], set[int]]: From f12a55287de84654197131e718215e11013df63b Mon Sep 17 00:00:00 2001 From: ReedActon <110858904+ReedActon@users.noreply.github.com> Date: Wed, 13 May 2026 13:12:21 +0000 Subject: [PATCH 30/32] Various FIxes Import fixes and other adjustments to match parent class --- mapplings/cleaners/unplacement.py | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/mapplings/cleaners/unplacement.py b/mapplings/cleaners/unplacement.py index a346b96..6026778 100644 --- a/mapplings/cleaners/unplacement.py +++ b/mapplings/cleaners/unplacement.py @@ -2,8 +2,9 @@ from itertools import product from typing import Iterator +from functools import cached_property -from gridded_cayley_permutations import RowColMap, GriddedCayleyPermutation +from gridded_cayley_permutations import RowColMap, GriddedCayleyPerm from gridded_cayley_permutations.simplify_obstructions_and_requirements import ( SimplifyObstructionsAndRequirements as Simplify, ) @@ -20,17 +21,18 @@ def __init__(self, param: Parameter, parent_mappling: MappedTiling): self.base_obs = parent_mappling.obstructions super().__init__(param.ghost) - def implied_point_obs(self) -> Iterator[GriddedCayleyPermutation]: + def implied_point_obs(self) -> Iterator[GriddedCayleyPerm]: """Finds point obs in the parameter that are implied by the base mappling""" for cells in product(self.param.empty_cells(), self.param.positive_cells()): pos = sorted(cells) pattern = (pos[0][1] > pos[1][1], pos[1][1] > pos[0][1]) - gcp = GriddedCayleyPermutation(pattern, pos) + gcp = GriddedCayleyPerm(pattern, pos) if self.param.map.map_gridded_cperm(gcp) not in self.base_obs: - yield GriddedCayleyPermutation((0,), (cells[0],)) + yield GriddedCayleyPerm((0,), (cells[0],)) - def expected_obs(self) -> set[GriddedCayleyPermutation]: - unsimplified = super().expected_obs() | set(self.implied_point_obs()) + @cached_property + def expected_obs(self) -> set[GriddedCayleyPerm]: + unsimplified = super().expected_obs | set(self.implied_point_obs()) algo = Simplify(unsimplified, tuple(tuple()), self.param.dimensions) algo.simplify() return set(algo.obstructions) @@ -39,8 +41,16 @@ def check_cols_and_rows( self, check_cols: set[int], check_rows: set[int] ) -> tuple[set[int], set[int]]: """Filters the input cols and rows to only include those which can be unplaced.""" - valid_cols = check_cols & self.point_cols - valid_rows = check_rows & self.point_rows + valid_cols = { + col + for col in check_cols & self.positive_cols + if (0 < col < self.dimensions[0] - 1) + } + valid_rows = { + row + for row in check_rows & self.positive_rows + if (0 < row < self.dimensions[1] - 1) + } valid_cols = { col for col in valid_cols @@ -59,6 +69,8 @@ def param_unplace( self, unplace_cols: set[int], unplace_rows: set[int] ) -> Parameter: """Unplaces rows and cols in the ghost and creates a new row col map""" + if not any((unplace_cols, unplace_rows)): + return self.param new_ghost = self.unplace(unplace_cols, unplace_rows) col_preimages, row_preimages = self.adjustment_map( @@ -78,5 +90,5 @@ def param_unplace( def auto_unplace(self): """Does all valid unplacements for the tiling's point cells""" temp = self.param_unplace(set(), self.find_cols_and_rows()[1]) - new_algo = ParamUnplacement(temp) + new_algo = ParamUnplacement(temp, self.base) return new_algo.param_unplace(new_algo.find_cols_and_rows()[0], set()) From f7f8f00d681c59a57773fb206ee8a73f1fbf1d94 Mon Sep 17 00:00:00 2001 From: ReedActon <110858904+ReedActon@users.noreply.github.com> Date: Wed, 13 May 2026 13:15:33 +0000 Subject: [PATCH 31/32] Cleaning No fixed formatting --- mapplings/algorithms/__init__.py | 3 --- mapplings/cleaners/parameter_cleaner.py | 10 ---------- 2 files changed, 13 deletions(-) diff --git a/mapplings/algorithms/__init__.py b/mapplings/algorithms/__init__.py index 837b37b..d4fe5fd 100644 --- a/mapplings/algorithms/__init__.py +++ b/mapplings/algorithms/__init__.py @@ -4,8 +4,6 @@ from .row_col_sep_mt import MTLTRowColSeparation, MTLTORERowColSeparation from .point_placement import MTRequirementPlacement -# from .unplacement import ParamUnplacement - __all__ = [ "MTFactors", "MTILFactorNormal", @@ -13,6 +11,5 @@ "MTLTRowColSeparation", "MTLTORERowColSeparation", "MTRequirementPlacement", - # "ParamUnplacement", ] __version__ = "0.1.0" diff --git a/mapplings/cleaners/parameter_cleaner.py b/mapplings/cleaners/parameter_cleaner.py index 39455c3..733c564 100644 --- a/mapplings/cleaners/parameter_cleaner.py +++ b/mapplings/cleaners/parameter_cleaner.py @@ -6,7 +6,6 @@ from gridded_cayley_permutations.row_col_map import RowColMap from gridded_cayley_permutations import Tiling from mapplings import Parameter -from .unplacement import ParamUnplacement from .cleaner import GenericCleaner, Register, CleanerLog @@ -131,15 +130,6 @@ def to_remove( return Parameter(Tiling([], [], (0, 0)), RowColMap({}, {})) return param.delete_rows_and_columns(cols_to_remove, rows_to_remove) - # @staticmethod - # @reg(4, run_on_enumerators=False) - # def unplace_points(param: Parameter) -> Parameter: - # """Unplaces all possible points in the parameter""" - # if not param.positive_cells(): - # return param - # algo = ParamUnplacement(param) - # return algo.auto_unplace() - @staticmethod @reg(3, run_on_enumerators=False) def insert_blank_size_1(param: Parameter) -> Parameter: From 4daa1980d8cf08eee0f9f00f3066150e24e6c0ca Mon Sep 17 00:00:00 2001 From: ReedActon <110858904+ReedActon@users.noreply.github.com> Date: Wed, 13 May 2026 14:38:24 +0000 Subject: [PATCH 32/32] mypy --- mapplings/cleaners/unplacement.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapplings/cleaners/unplacement.py b/mapplings/cleaners/unplacement.py index 6026778..252e42f 100644 --- a/mapplings/cleaners/unplacement.py +++ b/mapplings/cleaners/unplacement.py @@ -32,7 +32,7 @@ def implied_point_obs(self) -> Iterator[GriddedCayleyPerm]: @cached_property def expected_obs(self) -> set[GriddedCayleyPerm]: - unsimplified = super().expected_obs | set(self.implied_point_obs()) + unsimplified = tuple(super().expected_obs | set(self.implied_point_obs())) algo = Simplify(unsimplified, tuple(tuple()), self.param.dimensions) algo.simplify() return set(algo.obstructions)