Repository navigation
Conversation
A 1x1 tiling whose class is closed under rotation (the cyclic shift that moves the
first entry to the end), which is when its basis is rotationally stable, has n times
as many permutations of length n as its min cut, {p : 1 + p in the class}, or its
max cut, {p : p + 1 in the class}, has of length n - 1: exactly one rotation of each
permutation starts with its minimum, and exactly one ends with its maximum. A class
closed under the cyclic shift of the values (its inverse basis is rotationally
stable) has the same two cuts. RotationalCutFactory adds the rule to each cut, the
max cut only when it is a different class, with RotationalCutConstructor:
F(x) = 1 + x (x C(x))' for the whole class, and x (x C(x))' for its nonempty part.
TileScopePack.make_rotational adds the factory to a pack.
It moves the rotationally stable strategy of Permuta's pull request #207, which was
closed in favor of a strategy in Tilings, into a strategy here.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…uts and hints TileScopePack.add_rotational_cuts (was make_rotational) adds the rotational cut strategies to any pack, whose name gets the suffix _rotational_cuts, and tilescope spec's new flag -r/--rotational-cuts does the same on the command line. tilings.hints gathers hints: properties of a class that make it likely that a change to a pack helps the search, where Permuta's enumeration strategies settle a count outright. The first is a class closed under rotation: the hint names its cuts and suggests the rotational cuts. tilescope spec logs the hints that the pack it runs does not follow. The packs' JSON tests cover the new modifier. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Code that builds its own argparse.Namespace for build_pack, as some callers did before the flag existed, broke on the new attribute (an AttributeError, found on a test run on a cluster). build_pack now reads it with getattr, and a test calls it with such a namespace. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the rotational cut strategy (
RotationalCutFactory,RotationalCutStrategyandRotationalCutConstructor, intilings/strategies/rotation.py), the pack modifierTileScopePack.add_rotational_cutswith thetilescope specflag-r/--rotational-cuts, and hints (tilings/hints.py). As discussed on Permuta#207, which was closed because its rotationally stable strategy belongs in Tilings as strategies, not in Permuta as an enumeration strategy, this moves it here.The idea. The rotation of a permutation is the cyclic shift that moves its first entry to the end (
Perm.shift_left). A class is closed under rotation when its basis is, that is, when the basis is rotationally stable. The n rotations of a permutation of length n are distinct, and exactly one of them starts with the minimum. So the class has n times as many permutations of length n as its min cut, {p : 1 + p in the class}, has of length n - 1. Exactly one rotation also ends with the maximum, so the max cut, {p : p + 1 in the class}, counts the class the same way, and it can be a different class: [1324] = {1324, 3241, 2413, 4132} has the cuts Av(213, 4132) and Av(132, 3241). A class closed under the cyclic shift of the values, whose inverse basis is rotationally stable, has the same two cuts and is counted by them in the same way, since (1 + p)^-1 = 1 + p^-1.The strategy.
RotationalCutFactoryapplies to a 1x1 tiling without assumptions whose class is closed under rotation of its positions or of its values, either the whole class or its nonempty permutations (a point requirement). It yields the rule to the min cut, and to the max cut when that is a different class. Added to a pack withadd_rotational_cuts, it applies to every such tiling the search finds, so a cut closed under rotation again is cut too: the lifts of 12, {123, 231, 312} and its own lift, are counted by n and by n(n - 1). The constructor counts the parent as n times the child at n - 1, with the empty permutation at 0 for the whole class. Its equation is F = x (x C)', or 1 + x (x C)' for the whole class. It generates and samples objects: each child object p gives the n rotations of 1 + p, or of p + 1. SoRule.sanity_checkchecks counts, objects and random samples.Hints.
tilings.hints.hints(basis)returns hints: properties of a class that make it likely that a change to a pack helps the search, where Permuta's enumeration strategies settle a count outright. The first is a class closed under rotation: the hint names its cuts and suggests the rotational cuts.tilescope speclogs the hints that the pack it runs does not follow, so a user running a pack on such a class is told to add--rotational-cuts.Tests (
tests/strategies/test_rotation.py,tests/test_hints.py, and the encoding and pack tests):add_rotational_cuts, through JSON;point_placements().add_rotational_cuts()on [1234] = Av(1234, 2341, 3412, 4123), which finds a specification with a rotational cut in about a second, with counts 1, 1, 2, 6, 20, 65, 198, 560, 1480. Its generating function, derived from the cut's (Av(123, 3412)), is (1 - 8x + 27x^2 - 48x^3 + 49x^4 - 27x^5 + 6x^6 - 4x^7)/((1 - 2x)^2 (1 - x)^5).CI's mypy, pylint and
test_positive_reverse_fusionfail on develop too, at the same lines; a separate pull request fixes them. This pull request's own tests pass in every test job.🤖 Generated with Claude Code