Repository: PermutaTriangle/Tilings

Issue:
Broken `from_dict` in `RearrangeAssumptionStrategy`
The assert in this function is raised because `d` still contains `workable: True`. I'm not sure where that is supposed to be sent.
```py
    @classmethod
    def from_dict(cls, d: dict) -> "RearrangeAssumptionStrategy":
        assumption = TrackingAssumption.from_dict(d.pop("assumption"))
        sub_assumption = TrackingAssumption.from_dict(d.pop("sub_assumption"))
        assert not d
        return cls(assumption, sub_assumption)
```

Discussion:

Patch:
diff --git a/tilings/strategies/fusion/constructor.py b/tilings/strategies/fusion/constructor.py
index 6f645fa..e3e3c06 100644
--- a/tilings/strategies/fusion/constructor.py
+++ b/tilings/strategies/fusion/constructor.py
@@ -139,27 +139,14 @@ class FusionConstructor(Constructor[Tiling, GriddedPerm]):
 
     def _init_checked(self):
         """
-        The lists in reversed_extra_parameters can have size at most two (in
-        which case one of the two variables is a subset of the other), unless,
-        they are contained entirely within the fused region, in which case it
-        can have up to 3, namely left, right and both. This is checked in the
-        first assertion.
+        The lists in reversed_extra_parameters can have size at most three.
+        This is checked in the first assertion.
 
         Moreover, if two parent assumptions map to the same assumption, then one
         of them is one sided, and the other covers both sides, OR they are all
         contained fully in fuse region. This is checked in the second assertion.
         """
-        assert all(
-            len(val) <= 2
-            or (
-                len(val) == 3
-                and all(
-                    self.extra_parameters[parent_var] == self.fuse_parameter
-                    for parent_var in val
-                )
-            )
-            for val in self.reversed_extra_parameters.values()
-        )
+        assert all(len(val) <= 3 for val in self.reversed_extra_parameters.values())
         assert all(
             (
                 any(
diff --git a/tilings/strategies/rearrange_assumption.py b/tilings/strategies/rearrange_assumption.py
index 64ceac3..cb2a1f6 100644
--- a/tilings/strategies/rearrange_assumption.py
+++ b/tilings/strategies/rearrange_assumption.py
@@ -171,7 +171,6 @@ class RearrangeConstructor(Constructor[Tiling, GriddedPerm]):
         new_ass_var_child = sympy.var(child.extra_parameters[self.new_ass_child_idx])
         ass_var_parent = sympy.var(parent.extra_parameters[self.ass_parent_idx])
         subass_var_child = sympy.var(child.extra_parameters[self.subass_child_idx])
-        print(subs)
         subs[new_ass_var_child] = subs.get(new_ass_var_child, 1) * ass_var_parent
         subs[subass_var_child] *= ass_var_parent
         return subs
@@ -352,6 +351,7 @@ class RearrangeAssumptionStrategy(Strategy[Tiling, GriddedPerm]):
         d.pop("ignore_parent")
         d.pop("inferrable")
         d.pop("possibly_empty")
+        d.pop("workable")
         d["assumption"] = self.assumption.to_jsonable()
         d["sub_assumption"] = self.sub_assumption.to_jsonable()
         return d


Test patch:
diff --git a/tests/strategies/test_json_encoding.py b/tests/strategies/test_json_encoding.py
index df70a84..6bf2134 100644
--- a/tests/strategies/test_json_encoding.py
+++ b/tests/strategies/test_json_encoding.py
@@ -6,7 +6,7 @@ import pytest
 from comb_spec_searcher import Strategy
 from permuta import Perm
 from permuta.misc import DIR_EAST, DIR_NORTH, DIR_SOUTH, DIR_WEST, DIRS
-from tilings import GriddedPerm
+from tilings import GriddedPerm, TrackingAssumption
 from tilings.strategies import (
     AllPlacementsFactory,
     BasicVerificationStrategy,
@@ -25,6 +25,7 @@ from tilings.strategies import (
     ObstructionTransitivityFactory,
     OneByOneVerificationStrategy,
     PatternPlacementFactory,
+    RearrangeAssumptionFactory,
     RequirementCorroborationFactory,
     RequirementExtensionFactory,
     RequirementInsertionFactory,
@@ -47,6 +48,7 @@ from tilings.strategies.factor import (
 )
 from tilings.strategies.fusion import ComponentFusionStrategy, FusionStrategy
 from tilings.strategies.obstruction_inferral import ObstructionInferralStrategy
+from tilings.strategies.rearrange_assumption import RearrangeAssumptionStrategy
 from tilings.strategies.requirement_insertion import RequirementInsertionStrategy
 from tilings.strategies.requirement_placement import RequirementPlacementStrategy
 from tilings.strategies.sliding import SlidingStrategy
@@ -373,10 +375,17 @@ strategy_objects = (
         SplittingStrategy("monotone"),
         SplittingStrategy("all"),
     ]
+    + [RearrangeAssumptionFactory()]
+    + [
+        RearrangeAssumptionStrategy(
+            TrackingAssumption(
+                [GriddedPerm((0,), [(0, 0)]), GriddedPerm((0,), [(1, 0)])]
+            ),
+            TrackingAssumption([GriddedPerm((0,), [(0, 0)])]),
+        )
+    ]
 )
 
-# TODO add tests for: ComponentFusionStrategy, FusionStrategy
-
 
 @pytest.mark.parametrize("strategy", strategy_objects)
 def test_json_encoding(strategy):
diff --git a/tests/strategies/test_sanity_check.py b/tests/strategies/test_sanity_check.py
index 6c65b19..10f4edb 100644
--- a/tests/strategies/test_sanity_check.py
+++ b/tests/strategies/test_sanity_check.py
@@ -368,6 +368,37 @@ rules_to_check = [
             ),
         )
     ),
+    FusionStrategy(row_idx=1, col_idx=None, tracked=True)(
+        Tiling(
+            obstructions=(
+                GriddedPerm((0, 1), ((0, 0), (0, 0))),
+                GriddedPerm((0, 1, 2), ((0, 0), (0, 1), (0, 1))),
+                GriddedPerm((0, 1, 2), ((0, 0), (0, 1), (0, 2))),
+                GriddedPerm((0, 1, 2), ((0, 0), (0, 2), (0, 2))),
+                GriddedPerm((0, 1, 2), ((0, 1), (0, 1), (0, 1))),
+                GriddedPerm((0, 1, 2), ((0, 1), (0, 1), (0, 2))),
+                GriddedPerm((0, 1, 2), ((0, 1), (0, 2), (0, 2))),
+                GriddedPerm((0, 1, 2), ((0, 2), (0, 2), (0, 2))),
+            ),
+            assumptions=(
+                TrackingAssumption((GriddedPerm((0,), ((0, 0),)),)),
+                TrackingAssumption(
+                    (GriddedPerm((0,), ((0, 0),)), GriddedPerm((0,), ((0, 1),)))
+                ),
+                TrackingAssumption(
+                    (
+                        GriddedPerm((0,), ((0, 0),)),
+                        GriddedPerm((0,), ((0, 1),)),
+                        GriddedPerm((0,), ((0, 2),)),
+                    )
+                ),
+                TrackingAssumption(
+                    (GriddedPerm((0,), ((0, 0),)), GriddedPerm((0,), ((0, 2),)))
+                ),
+                TrackingAssumption((GriddedPerm((0,), ((0, 2),)),)),
+            ),
+        )
+    ),
 ]