PermutaTriangle/comb_spec_searcher

stuck in _group_equiv_in_path() after expanding monotone tree tiling

jaypantone opened this issue · 2 comments

To replicate:

import requests
from tilings.strategies import LocallyFactorableVerificationStrategy
from tilings.tilescope import TileScopePack
from comb_spec_searcher import CombinatorialSpecification

uri = "https://api.permpal.com/garpur_run/62c00d1d3a0324176007e6d1"
data = requests.get(uri).json()
spec = CombinatorialSpecification.from_dict(data["specification"])

T = spec.get_comb_class(365)
pack = TileScopePack.from_dict(data["pack"])
pack = pack.add_basis([ob.patt for ob in spec.root.obstructions])
pack.ver_strats = tuple(
    vs
    for vs in pack.ver_strats
    if not isinstance(vs, LocallyFactorableVerificationStrategy)
)
print("expanding...")
spec.expand_comb_class(T, pack, reverse=False, continue_expanding_verified=True)

The final line hangs. Traceback indicates the problem is the while-loop in:

group_equiv_in_path(self) -> None:
        """
        Group chain of equivalence rules of the specification into equivalence paths.
        """
        self._ungroup_equiv_path()
        not_hidden_classes = {self.root}
        for rule in self:
            if rule.is_equivalence():
                continue
            not_hidden_classes.add(rule.comb_class)
            not_hidden_classes.update(rule.children)
        # Creating paths
        comb_class_stack = [self.root]
        visited: Set[CombinatorialClassType] = set()
        path_rules: List[Rule] = []
        eqv_path_rules: Dict[CombinatorialClassType, EquivalencePathRule] = {}
        while comb_class_stack:
            if path_rules and path_rules[-1].children[0] in not_hidden_classes:
                new_rule: EquivalencePathRule = EquivalencePathRule(path_rules)
                eqv_path_rules[new_rule.comb_class] = new_rule
                path_rules.clear()
            comb_class = comb_class_stack.pop()
            if comb_class in not_hidden_classes and comb_class in visited:
                continue
            visited.add(comb_class)
            rule = self.get_rule(comb_class)
            comb_class_stack.extend(rule.children)
            if rule.is_equivalence() and not isinstance(rule, EquivalencePathRule):
                assert isinstance(rule, Rule)
                assert not path_rules or path_rules[-1].children[0] == rule.comb_class
                path_rules.append(rule)
        # Clearing the equivalences and replacing by paths
        self.rules_dict = {
            comb_class: rule
            for comb_class, rule in self.rules_dict.items()
            if comb_class in not_hidden_classes
        }
        self.rules_dict.update(eqv_path_rules)
        assert self._is_valid_spec()

Printing len(comb_class_stack) shows it stuck at 12.

Seems like it goes back and forth between two classes that use a rule and the reverse:

12
+-+-+-+
|| ||
+-+-+-+
| || |
+-+-+-+
|1| |1|
+-+-+-+
1: Av(0132, 0312, 0321, 1032)
○: Av(01, 10)
●: point
Crossing obstructions:
01: (0, 2), (2, 2)
10: (0, 2), (2, 2)
012: (0, 0), (0, 0), (2, 0)
012: (0, 0), (2, 0), (2, 0)
021: (0, 0), (2, 0), (2, 0)
102: (0, 0), (0, 0), (2, 0)
0321: (0, 0), (0, 0), (0, 0), (2, 0)
Requirement 0:
0: (1, 1)
reverse of 'placing the topmost point in cell (0, 0)'
+-+-+-+                                  +-+
|| ||                               =  ||
+-+-+-+                                  +-+
| || |                                  |1|
+-+-+-+                                  +-+
|1| |1|                                  1: Av+(0132, 0312, 0321, 1032)
+-+-+-+                                  ○: Av(01, 10)
1: Av(0132, 0312, 0321, 1032)            Requirement 0:
○: Av(01, 10)                            0: (0, 0)
●: point
Crossing obstructions:
01: (0, 2), (2, 2)
10: (0, 2), (2, 2)
012: (0, 0), (0, 0), (2, 0)
012: (0, 0), (2, 0), (2, 0)
021: (0, 0), (2, 0), (2, 0)
102: (0, 0), (0, 0), (2, 0)
0321: (0, 0), (0, 0), (0, 0), (2, 0)
Requirement 0:
0: (1, 1)
12
+-+
||
+-+
|1|
+-+
1: Av+(0132, 0312, 0321, 1032)
○: Av(01, 10)
Requirement 0:
0: (0, 0)
placing the topmost point in cell (0, 0)
+-+                                +-+-+-+
||                             =  || ||
+-+                                +-+-+-+
|1|                                | || |
+-+                                +-+-+-+
1: Av+(0132, 0312, 0321, 1032)     |1| |1|
○: Av(01, 10)                      +-+-+-+
Requirement 0:                     1: Av(0132, 0312, 0321, 1032)
0: (0, 0)                          ○: Av(01, 10)
                                   ●: point
                                   Crossing obstructions:
                                   01: (0, 2), (2, 2)
                                   10: (0, 2), (2, 2)
                                   012: (0, 0), (0, 0), (2, 0)
                                   012: (0, 0), (2, 0), (2, 0)
                                   021: (0, 0), (2, 0), (2, 0)
                                   102: (0, 0), (0, 0), (2, 0)
                                   0321: (0, 0), (0, 0), (0, 0), (2, 0)
                                   Requirement 0:
                                   0: (1, 1)
12

fixed by #345