import dataclasses
from . import math as _math
from . import pcollections as _pcollections
from . import pitch as _pitch
[docs]@dataclasses.dataclass(slots=True, unsafe_hash=True)
class SetClass:
"""
Set-class.
.. container:: example
Makes SG2 set-class from Forte rank:
>>> set_class = abjad.SetClass(4, 29)
>>> print(set_class)
SC(4-29){0, 1, 3, 7}
Makes SG2 set-class from lex rank:
>>> set_class = abjad.SetClass(4, 29, lex_rank=True)
>>> print(set_class)
SC(4-29){0, 3, 6, 9}
Makes SG1 set-class:
>>> set_class = abjad.SetClass(4, 29, transposition_only=True, lex_rank=True)
>>> print(set_class)
SC(4-29){0, 2, 6, 7}
.. container:: example
Makes aggregate:
>>> set_class = abjad.SetClass(12, 1, transposition_only=True, lex_rank=True)
>>> print(set_class)
SC(12-1){0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
.. container:: example
Lists SG2 tetrachords, pentachords, hexachords by Forte rank:
>>> set_classes = abjad.SetClass.list_set_classes(cardinality=4)
>>> for set_class in set_classes:
... print(set_class)
...
SC(4-1){0, 1, 2, 3}
SC(4-2){0, 1, 2, 4}
SC(4-3){0, 1, 3, 4}
SC(4-4){0, 1, 2, 5}
SC(4-5){0, 1, 2, 6}
SC(4-6){0, 1, 2, 7}
SC(4-7){0, 1, 4, 5}
SC(4-8){0, 1, 5, 6}
SC(4-9){0, 1, 6, 7}
SC(4-10){0, 2, 3, 5}
SC(4-11){0, 1, 3, 5}
SC(4-12){0, 2, 3, 6}
SC(4-13){0, 1, 3, 6}
SC(4-14){0, 2, 3, 7}
SC(4-15){0, 1, 4, 6}
SC(4-16){0, 1, 5, 7}
SC(4-17){0, 3, 4, 7}
SC(4-18){0, 1, 4, 7}
SC(4-19){0, 1, 4, 8}
SC(4-20){0, 1, 5, 8}
SC(4-21){0, 2, 4, 6}
SC(4-22){0, 2, 4, 7}
SC(4-23){0, 2, 5, 7}
SC(4-24){0, 2, 4, 8}
SC(4-25){0, 2, 6, 8}
SC(4-26){0, 3, 5, 8}
SC(4-27){0, 2, 5, 8}
SC(4-28){0, 3, 6, 9}
SC(4-29){0, 1, 3, 7}
>>> set_classes = abjad.SetClass.list_set_classes(cardinality=5)
>>> for set_class in set_classes:
... print(set_class)
...
SC(5-1){0, 1, 2, 3, 4}
SC(5-2){0, 1, 2, 3, 5}
SC(5-3){0, 1, 2, 4, 5}
SC(5-4){0, 1, 2, 3, 6}
SC(5-5){0, 1, 2, 3, 7}
SC(5-6){0, 1, 2, 5, 6}
SC(5-7){0, 1, 2, 6, 7}
SC(5-8){0, 2, 3, 4, 6}
SC(5-9){0, 1, 2, 4, 6}
SC(5-10){0, 1, 3, 4, 6}
SC(5-11){0, 2, 3, 4, 7}
SC(5-12){0, 1, 3, 5, 6}
SC(5-13){0, 1, 2, 4, 8}
SC(5-14){0, 1, 2, 5, 7}
SC(5-15){0, 1, 2, 6, 8}
SC(5-16){0, 1, 3, 4, 7}
SC(5-17){0, 1, 3, 4, 8}
SC(5-18){0, 1, 4, 5, 7}
SC(5-19){0, 1, 3, 6, 7}
SC(5-20){0, 1, 3, 7, 8}
SC(5-21){0, 1, 4, 5, 8}
SC(5-22){0, 1, 4, 7, 8}
SC(5-23){0, 2, 3, 5, 7}
SC(5-24){0, 1, 3, 5, 7}
SC(5-25){0, 2, 3, 5, 8}
SC(5-26){0, 2, 4, 5, 8}
SC(5-27){0, 1, 3, 5, 8}
SC(5-28){0, 2, 3, 6, 8}
SC(5-29){0, 1, 3, 6, 8}
SC(5-30){0, 1, 4, 6, 8}
SC(5-31){0, 1, 3, 6, 9}
SC(5-32){0, 1, 4, 6, 9}
SC(5-33){0, 2, 4, 6, 8}
SC(5-34){0, 2, 4, 6, 9}
SC(5-35){0, 2, 4, 7, 9}
SC(5-36){0, 1, 2, 4, 7}
SC(5-37){0, 3, 4, 5, 8}
SC(5-38){0, 1, 2, 5, 8}
>>> set_classes = abjad.SetClass.list_set_classes(cardinality=6)
>>> for set_class in set_classes:
... print(set_class)
...
SC(6-1){0, 1, 2, 3, 4, 5}
SC(6-2){0, 1, 2, 3, 4, 6}
SC(6-3){0, 1, 2, 3, 5, 6}
SC(6-4){0, 1, 2, 4, 5, 6}
SC(6-5){0, 1, 2, 3, 6, 7}
SC(6-6){0, 1, 2, 5, 6, 7}
SC(6-7){0, 1, 2, 6, 7, 8}
SC(6-8){0, 2, 3, 4, 5, 7}
SC(6-9){0, 1, 2, 3, 5, 7}
SC(6-10){0, 1, 3, 4, 5, 7}
SC(6-11){0, 1, 2, 4, 5, 7}
SC(6-12){0, 1, 2, 4, 6, 7}
SC(6-13){0, 1, 3, 4, 6, 7}
SC(6-14){0, 1, 3, 4, 5, 8}
SC(6-15){0, 1, 2, 4, 5, 8}
SC(6-16){0, 1, 4, 5, 6, 8}
SC(6-17){0, 1, 2, 4, 7, 8}
SC(6-18){0, 1, 2, 5, 7, 8}
SC(6-19){0, 1, 3, 4, 7, 8}
SC(6-20){0, 1, 4, 5, 8, 9}
SC(6-21){0, 2, 3, 4, 6, 8}
SC(6-22){0, 1, 2, 4, 6, 8}
SC(6-23){0, 2, 3, 5, 6, 8}
SC(6-24){0, 1, 3, 4, 6, 8}
SC(6-25){0, 1, 3, 5, 6, 8}
SC(6-26){0, 1, 3, 5, 7, 8}
SC(6-27){0, 1, 3, 4, 6, 9}
SC(6-28){0, 1, 3, 5, 6, 9}
SC(6-29){0, 1, 3, 6, 8, 9}
SC(6-30){0, 1, 3, 6, 7, 9}
SC(6-31){0, 1, 3, 5, 8, 9}
SC(6-32){0, 2, 4, 5, 7, 9}
SC(6-33){0, 2, 3, 5, 7, 9}
SC(6-34){0, 1, 3, 5, 7, 9}
SC(6-35){0, 2, 4, 6, 8, 10}
SC(6-36){0, 1, 2, 3, 4, 7}
SC(6-37){0, 1, 2, 3, 4, 8}
SC(6-38){0, 1, 2, 3, 7, 8}
SC(6-39){0, 2, 3, 4, 5, 8}
SC(6-40){0, 1, 2, 3, 5, 8}
SC(6-41){0, 1, 2, 3, 6, 8}
SC(6-42){0, 1, 2, 3, 6, 9}
SC(6-43){0, 1, 2, 5, 6, 8}
SC(6-44){0, 1, 2, 5, 6, 9}
SC(6-45){0, 2, 3, 4, 6, 9}
SC(6-46){0, 1, 2, 4, 6, 9}
SC(6-47){0, 1, 2, 4, 7, 9}
SC(6-48){0, 1, 2, 5, 7, 9}
SC(6-49){0, 1, 3, 4, 7, 9}
SC(6-50){0, 1, 4, 6, 7, 9}
There are 352 SG1 set-classes and 224 SG2 set-classes.
.. container:: example
Gets cardinality of SG2 set-class with Forte rank:
>>> set_class = abjad.SetClass(4, 29)
>>> print(set_class)
SC(4-29){0, 1, 3, 7}
>>> set_class.cardinality
4
Gets cardinality of SG2 set-class with lex rank:
>>> set_class = abjad.SetClass(
... 4, 29,
... lex_rank=True,
... )
>>> print(set_class)
SC(4-29){0, 3, 6, 9}
>>> set_class.cardinality
4
Gets cardinality of SG1 set-class:
>>> set_class = abjad.SetClass(
... 4, 29,
... lex_rank=True,
... transposition_only=True,
... )
>>> print(set_class)
SC(4-29){0, 2, 6, 7}
>>> set_class.cardinality
4
.. container:: example
Initializes SG2 set-class with Forte rank:
>>> set_class = abjad.SetClass(4, 29)
>>> print(set_class)
SC(4-29){0, 1, 3, 7}
.. container:: example
Initializes SG2 set-class with lex rank:
>>> set_class = abjad.SetClass(
... 4, 29,
... lex_rank=True,
... )
>>> print(set_class)
SC(4-29){0, 3, 6, 9}
.. container:: example
Initializes SG1 (transposition-only) set-class:
>>> set_class = abjad.SetClass(
... 4, 29,
... lex_rank=True,
... transposition_only=True,
... )
>>> print(set_class)
SC(4-29){0, 2, 6, 7}
"""
cardinality: int = 1
rank: int = 1
lex_rank: bool = False
transposition_only: bool = False
_forte_identifier_to_prime_form = {
# 0
(0, 1): (),
# 1
(1, 1): (0,),
# 2
(2, 1): (0, 1),
(2, 2): (0, 2),
(2, 3): (0, 3),
(2, 4): (0, 4),
(2, 5): (0, 5),
(2, 6): (0, 6),
# 3
(3, 1): (0, 1, 2),
(3, 2): (0, 1, 3),
(3, 3): (0, 1, 4),
(3, 4): (0, 1, 5),
(3, 5): (0, 1, 6),
(3, 6): (0, 2, 4),
(3, 7): (0, 2, 5),
(3, 8): (0, 2, 6),
(3, 9): (0, 2, 7),
(3, 10): (0, 3, 6),
(3, 11): (0, 3, 7),
(3, 12): (0, 4, 8),
# 4
(4, 1): (0, 1, 2, 3),
(4, 2): (0, 1, 2, 4),
(4, 3): (0, 1, 3, 4),
(4, 4): (0, 1, 2, 5),
(4, 5): (0, 1, 2, 6),
(4, 6): (0, 1, 2, 7),
(4, 7): (0, 1, 4, 5),
(4, 8): (0, 1, 5, 6),
(4, 9): (0, 1, 6, 7),
(4, 10): (0, 2, 3, 5),
(4, 11): (0, 1, 3, 5),
(4, 12): (0, 2, 3, 6),
(4, 13): (0, 1, 3, 6),
(4, 14): (0, 2, 3, 7),
(4, 15): (0, 1, 4, 6),
(4, 16): (0, 1, 5, 7),
(4, 17): (0, 3, 4, 7),
(4, 18): (0, 1, 4, 7),
(4, 19): (0, 1, 4, 8),
(4, 20): (0, 1, 5, 8),
(4, 21): (0, 2, 4, 6),
(4, 22): (0, 2, 4, 7),
(4, 23): (0, 2, 5, 7),
(4, 24): (0, 2, 4, 8),
(4, 25): (0, 2, 6, 8),
(4, 26): (0, 3, 5, 8),
(4, 27): (0, 2, 5, 8),
(4, 28): (0, 3, 6, 9),
(4, 29): (0, 1, 3, 7),
# 5
(5, 1): (0, 1, 2, 3, 4),
(5, 2): (0, 1, 2, 3, 5),
(5, 3): (0, 1, 2, 4, 5),
(5, 4): (0, 1, 2, 3, 6),
(5, 5): (0, 1, 2, 3, 7),
(5, 6): (0, 1, 2, 5, 6),
(5, 7): (0, 1, 2, 6, 7),
(5, 8): (0, 2, 3, 4, 6),
(5, 9): (0, 1, 2, 4, 6),
(5, 10): (0, 1, 3, 4, 6),
(5, 11): (0, 2, 3, 4, 7),
(5, 12): (0, 1, 3, 5, 6),
(5, 13): (0, 1, 2, 4, 8),
(5, 14): (0, 1, 2, 5, 7),
(5, 15): (0, 1, 2, 6, 8),
(5, 16): (0, 1, 3, 4, 7),
(5, 17): (0, 1, 3, 4, 8),
(5, 18): (0, 1, 4, 5, 7),
(5, 19): (0, 1, 3, 6, 7),
(5, 20): (0, 1, 3, 7, 8),
(5, 21): (0, 1, 4, 5, 8),
(5, 22): (0, 1, 4, 7, 8),
(5, 23): (0, 2, 3, 5, 7),
(5, 24): (0, 1, 3, 5, 7),
(5, 25): (0, 2, 3, 5, 8),
(5, 26): (0, 2, 4, 5, 8),
(5, 27): (0, 1, 3, 5, 8),
(5, 28): (0, 2, 3, 6, 8),
(5, 29): (0, 1, 3, 6, 8),
(5, 30): (0, 1, 4, 6, 8),
(5, 31): (0, 1, 3, 6, 9),
(5, 32): (0, 1, 4, 6, 9),
(5, 33): (0, 2, 4, 6, 8),
(5, 34): (0, 2, 4, 6, 9),
(5, 35): (0, 2, 4, 7, 9),
(5, 36): (0, 1, 2, 4, 7),
(5, 37): (0, 3, 4, 5, 8),
(5, 38): (0, 1, 2, 5, 8),
# 6
(6, 1): (0, 1, 2, 3, 4, 5),
(6, 2): (0, 1, 2, 3, 4, 6),
(6, 3): (0, 1, 2, 3, 5, 6),
(6, 4): (0, 1, 2, 4, 5, 6),
(6, 5): (0, 1, 2, 3, 6, 7),
(6, 6): (0, 1, 2, 5, 6, 7),
(6, 7): (0, 1, 2, 6, 7, 8),
(6, 8): (0, 2, 3, 4, 5, 7),
(6, 9): (0, 1, 2, 3, 5, 7),
(6, 10): (0, 1, 3, 4, 5, 7),
(6, 11): (0, 1, 2, 4, 5, 7),
(6, 12): (0, 1, 2, 4, 6, 7),
(6, 13): (0, 1, 3, 4, 6, 7),
(6, 14): (0, 1, 3, 4, 5, 8),
(6, 15): (0, 1, 2, 4, 5, 8),
(6, 16): (0, 1, 4, 5, 6, 8),
(6, 17): (0, 1, 2, 4, 7, 8),
(6, 18): (0, 1, 2, 5, 7, 8),
(6, 19): (0, 1, 3, 4, 7, 8),
(6, 20): (0, 1, 4, 5, 8, 9),
(6, 21): (0, 2, 3, 4, 6, 8),
(6, 22): (0, 1, 2, 4, 6, 8),
(6, 23): (0, 2, 3, 5, 6, 8),
(6, 24): (0, 1, 3, 4, 6, 8),
(6, 25): (0, 1, 3, 5, 6, 8),
(6, 26): (0, 1, 3, 5, 7, 8),
(6, 27): (0, 1, 3, 4, 6, 9),
(6, 28): (0, 1, 3, 5, 6, 9),
(6, 29): (0, 1, 3, 6, 8, 9),
(6, 30): (0, 1, 3, 6, 7, 9),
(6, 31): (0, 1, 3, 5, 8, 9),
(6, 32): (0, 2, 4, 5, 7, 9),
(6, 33): (0, 2, 3, 5, 7, 9),
(6, 34): (0, 1, 3, 5, 7, 9),
(6, 35): (0, 2, 4, 6, 8, 10),
(6, 36): (0, 1, 2, 3, 4, 7),
(6, 37): (0, 1, 2, 3, 4, 8),
(6, 38): (0, 1, 2, 3, 7, 8),
(6, 39): (0, 2, 3, 4, 5, 8),
(6, 40): (0, 1, 2, 3, 5, 8),
(6, 41): (0, 1, 2, 3, 6, 8),
(6, 42): (0, 1, 2, 3, 6, 9),
(6, 43): (0, 1, 2, 5, 6, 8),
(6, 44): (0, 1, 2, 5, 6, 9),
(6, 45): (0, 2, 3, 4, 6, 9),
(6, 46): (0, 1, 2, 4, 6, 9),
(6, 47): (0, 1, 2, 4, 7, 9),
(6, 48): (0, 1, 2, 5, 7, 9),
(6, 49): (0, 1, 3, 4, 7, 9),
(6, 50): (0, 1, 4, 6, 7, 9),
}
assert len(_forte_identifier_to_prime_form) == 137
_lex_identifier_to_prime_form = {
# 0
(0, 1): (),
# 1
(1, 1): (0,),
# 2
(2, 1): (0, 1),
(2, 2): (0, 2),
(2, 3): (0, 3),
(2, 4): (0, 4),
(2, 5): (0, 5),
(2, 6): (0, 6),
# 3
(3, 1): (0, 1, 2),
(3, 2): (0, 1, 3),
(3, 3): (0, 1, 4),
(3, 4): (0, 1, 5),
(3, 5): (0, 1, 6),
(3, 6): (0, 2, 4),
(3, 7): (0, 2, 5),
(3, 8): (0, 2, 6),
(3, 9): (0, 2, 7),
(3, 10): (0, 3, 6),
(3, 11): (0, 3, 7),
(3, 12): (0, 4, 8),
# 4
(4, 1): (0, 1, 2, 3),
(4, 2): (0, 1, 2, 4),
(4, 3): (0, 1, 2, 5),
(4, 4): (0, 1, 2, 6),
(4, 5): (0, 1, 2, 7),
(4, 6): (0, 1, 3, 4),
(4, 7): (0, 1, 3, 5),
(4, 8): (0, 1, 3, 6),
(4, 9): (0, 1, 3, 7),
(4, 10): (0, 1, 4, 5),
(4, 11): (0, 1, 4, 6),
(4, 12): (0, 1, 4, 7),
(4, 13): (0, 1, 4, 8),
(4, 14): (0, 1, 5, 6),
(4, 15): (0, 1, 5, 7),
(4, 16): (0, 1, 5, 8),
(4, 17): (0, 1, 6, 7),
(4, 18): (0, 2, 3, 5),
(4, 19): (0, 2, 3, 6),
(4, 20): (0, 2, 3, 7),
(4, 21): (0, 2, 4, 6),
(4, 22): (0, 2, 4, 7),
(4, 23): (0, 2, 4, 8),
(4, 24): (0, 2, 5, 7),
(4, 25): (0, 2, 5, 8),
(4, 26): (0, 2, 6, 8),
(4, 27): (0, 3, 4, 7),
(4, 28): (0, 3, 5, 8),
(4, 29): (0, 3, 6, 9),
# 5
(5, 1): (0, 1, 2, 3, 4),
(5, 2): (0, 1, 2, 3, 5),
(5, 3): (0, 1, 2, 3, 6),
(5, 4): (0, 1, 2, 3, 7),
(5, 5): (0, 1, 2, 4, 5),
(5, 6): (0, 1, 2, 4, 6),
(5, 7): (0, 1, 2, 4, 7),
(5, 8): (0, 1, 2, 4, 8),
(5, 9): (0, 1, 2, 5, 6),
(5, 10): (0, 1, 2, 5, 7),
(5, 11): (0, 1, 2, 5, 8),
(5, 12): (0, 1, 2, 6, 7),
(5, 13): (0, 1, 2, 6, 8),
(5, 14): (0, 1, 3, 4, 6),
(5, 15): (0, 1, 3, 4, 7),
(5, 16): (0, 1, 3, 4, 8),
(5, 17): (0, 1, 3, 5, 6),
(5, 18): (0, 1, 3, 5, 7),
(5, 19): (0, 1, 3, 5, 8),
(5, 20): (0, 1, 3, 6, 7),
(5, 21): (0, 1, 3, 6, 8),
(5, 22): (0, 1, 3, 6, 9),
(5, 23): (0, 1, 3, 7, 8),
(5, 24): (0, 1, 4, 5, 7),
(5, 25): (0, 1, 4, 5, 8),
(5, 26): (0, 1, 4, 6, 8),
(5, 27): (0, 1, 4, 7, 8),
(5, 28): (0, 1, 4, 7, 9),
(5, 29): (0, 2, 3, 4, 6),
(5, 30): (0, 2, 3, 4, 7),
(5, 31): (0, 2, 3, 5, 7),
(5, 32): (0, 2, 3, 5, 8),
(5, 33): (0, 2, 3, 6, 8),
(5, 34): (0, 2, 4, 5, 8),
(5, 35): (0, 2, 4, 6, 8),
(5, 36): (0, 2, 4, 6, 9),
(5, 37): (0, 2, 4, 7, 9),
(5, 38): (0, 3, 4, 5, 8),
# 6
(6, 1): (0, 1, 2, 3, 4, 5),
(6, 2): (0, 1, 2, 3, 4, 6),
(6, 3): (0, 1, 2, 3, 4, 7),
(6, 4): (0, 1, 2, 3, 4, 8),
(6, 5): (0, 1, 2, 3, 5, 6),
(6, 6): (0, 1, 2, 3, 5, 7),
(6, 7): (0, 1, 2, 3, 5, 8),
(6, 8): (0, 1, 2, 3, 6, 7),
(6, 9): (0, 1, 2, 3, 6, 8),
(6, 10): (0, 1, 2, 3, 6, 9),
(6, 11): (0, 1, 2, 3, 7, 8),
(6, 12): (0, 1, 2, 4, 5, 6),
(6, 13): (0, 1, 2, 4, 5, 7),
(6, 14): (0, 1, 2, 4, 5, 8),
(6, 15): (0, 1, 2, 4, 6, 7),
(6, 16): (0, 1, 2, 4, 6, 8),
(6, 17): (0, 1, 2, 4, 6, 9),
(6, 18): (0, 1, 2, 4, 7, 8),
(6, 19): (0, 1, 2, 4, 7, 9),
(6, 20): (0, 1, 2, 5, 6, 7),
(6, 21): (0, 1, 2, 5, 6, 8),
(6, 22): (0, 1, 2, 5, 7, 8),
(6, 23): (0, 1, 2, 5, 7, 9),
(6, 24): (0, 1, 2, 5, 8, 9),
(6, 25): (0, 1, 2, 6, 7, 8),
(6, 26): (0, 1, 3, 4, 5, 7),
(6, 27): (0, 1, 3, 4, 5, 8),
(6, 28): (0, 1, 3, 4, 6, 7),
(6, 29): (0, 1, 3, 4, 6, 8),
(6, 30): (0, 1, 3, 4, 6, 9),
(6, 31): (0, 1, 3, 4, 7, 8),
(6, 32): (0, 1, 3, 4, 7, 9),
(6, 33): (0, 1, 3, 5, 6, 8),
(6, 34): (0, 1, 3, 5, 6, 9),
(6, 35): (0, 1, 3, 5, 7, 8),
(6, 36): (0, 1, 3, 5, 7, 9),
(6, 37): (0, 1, 3, 5, 8, 9),
(6, 38): (0, 1, 3, 6, 7, 9),
(6, 39): (0, 1, 3, 6, 8, 9),
(6, 40): (0, 1, 4, 5, 6, 8),
(6, 41): (0, 1, 4, 5, 8, 9),
(6, 42): (0, 1, 4, 6, 7, 9),
(6, 43): (0, 2, 3, 4, 5, 7),
(6, 44): (0, 2, 3, 4, 5, 8),
(6, 45): (0, 2, 3, 4, 6, 8),
(6, 46): (0, 2, 3, 4, 6, 9),
(6, 47): (0, 2, 3, 5, 6, 8),
(6, 48): (0, 2, 3, 5, 7, 9),
(6, 49): (0, 2, 4, 5, 7, 9),
(6, 50): (0, 2, 4, 6, 8, 10),
# 7
(7, 1): (0, 1, 2, 3, 4, 5, 6),
(7, 2): (0, 1, 2, 3, 4, 5, 7),
(7, 3): (0, 1, 2, 3, 4, 5, 8),
(7, 4): (0, 1, 2, 3, 4, 6, 7),
(7, 5): (0, 1, 2, 3, 4, 6, 8),
(7, 6): (0, 1, 2, 3, 4, 6, 9),
(7, 7): (0, 1, 2, 3, 4, 7, 8),
(7, 8): (0, 1, 2, 3, 4, 7, 9),
(7, 9): (0, 1, 2, 3, 5, 6, 7),
(7, 10): (0, 1, 2, 3, 5, 6, 8),
(7, 11): (0, 1, 2, 3, 5, 6, 9),
(7, 12): (0, 1, 2, 3, 5, 7, 8),
(7, 13): (0, 1, 2, 3, 5, 7, 9),
(7, 14): (0, 1, 2, 3, 5, 8, 9),
(7, 15): (0, 1, 2, 3, 6, 7, 8),
(7, 16): (0, 1, 2, 3, 6, 8, 9),
(7, 17): (0, 1, 2, 4, 5, 6, 8),
(7, 18): (0, 1, 2, 4, 5, 6, 9),
(7, 19): (0, 1, 2, 4, 5, 7, 8),
(7, 20): (0, 1, 2, 4, 5, 7, 9),
(7, 21): (0, 1, 2, 4, 5, 8, 9),
(7, 22): (0, 1, 2, 4, 6, 7, 8),
(7, 23): (0, 1, 2, 4, 6, 7, 9),
(7, 24): (0, 1, 2, 4, 6, 8, 10),
(7, 25): (0, 1, 2, 4, 6, 8, 9),
(7, 26): (0, 1, 2, 4, 7, 8, 9),
(7, 27): (0, 1, 2, 5, 6, 8, 9),
(7, 28): (0, 1, 3, 4, 5, 6, 8),
(7, 29): (0, 1, 3, 4, 5, 7, 8),
(7, 30): (0, 1, 3, 4, 5, 7, 9),
(7, 31): (0, 1, 3, 4, 6, 7, 9),
(7, 32): (0, 1, 3, 4, 6, 8, 10),
(7, 33): (0, 1, 3, 4, 6, 8, 9),
(7, 34): (0, 1, 3, 5, 6, 7, 9),
(7, 35): (0, 1, 3, 5, 6, 8, 10),
(7, 36): (0, 2, 3, 4, 5, 6, 8),
(7, 37): (0, 2, 3, 4, 5, 7, 9),
(7, 38): (0, 2, 3, 4, 6, 7, 9),
# 8
(8, 1): (0, 1, 2, 3, 4, 5, 6, 7),
(8, 2): (0, 1, 2, 3, 4, 5, 6, 8),
(8, 3): (0, 1, 2, 3, 4, 5, 6, 9),
(8, 4): (0, 1, 2, 3, 4, 5, 7, 8),
(8, 5): (0, 1, 2, 3, 4, 5, 7, 9),
(8, 6): (0, 1, 2, 3, 4, 5, 8, 9),
(8, 7): (0, 1, 2, 3, 4, 6, 7, 8),
(8, 8): (0, 1, 2, 3, 4, 6, 7, 9),
(8, 9): (0, 1, 2, 3, 4, 6, 8, 10),
(8, 10): (0, 1, 2, 3, 4, 6, 8, 9),
(8, 11): (0, 1, 2, 3, 4, 7, 8, 9),
(8, 12): (0, 1, 2, 3, 5, 6, 7, 8),
(8, 13): (0, 1, 2, 3, 5, 6, 7, 9),
(8, 14): (0, 1, 2, 3, 5, 6, 8, 9),
(8, 15): (0, 1, 2, 3, 5, 7, 8, 10),
(8, 16): (0, 1, 2, 3, 5, 7, 8, 9),
(8, 17): (0, 1, 2, 3, 5, 7, 9, 10),
(8, 18): (0, 1, 2, 3, 6, 7, 8, 9),
(8, 19): (0, 1, 2, 4, 5, 6, 7, 9),
(8, 20): (0, 1, 2, 4, 5, 6, 8, 10),
(8, 21): (0, 1, 2, 4, 5, 6, 8, 9),
(8, 22): (0, 1, 2, 4, 5, 7, 8, 10),
(8, 23): (0, 1, 2, 4, 5, 7, 8, 9),
(8, 24): (0, 1, 2, 4, 5, 7, 9, 10),
(8, 25): (0, 1, 2, 4, 6, 7, 8, 10),
(8, 26): (0, 1, 3, 4, 5, 6, 7, 9),
(8, 27): (0, 1, 3, 4, 5, 6, 8, 9),
(8, 28): (0, 1, 3, 4, 6, 7, 9, 10),
(8, 29): (0, 2, 3, 4, 5, 6, 7, 9),
# 9
(9, 1): (0, 1, 2, 3, 4, 5, 6, 7, 8),
(9, 2): (0, 1, 2, 3, 4, 5, 6, 7, 9),
(9, 3): (0, 1, 2, 3, 4, 5, 6, 8, 10),
(9, 4): (0, 1, 2, 3, 4, 5, 6, 8, 9),
(9, 5): (0, 1, 2, 3, 4, 5, 7, 8, 9),
(9, 6): (0, 1, 2, 3, 4, 5, 7, 9, 10),
(9, 7): (0, 1, 2, 3, 4, 6, 7, 8, 9),
(9, 8): (0, 1, 2, 3, 4, 6, 7, 9, 10),
(9, 9): (0, 1, 2, 3, 4, 6, 8, 9, 10),
(9, 10): (0, 1, 2, 3, 5, 6, 7, 8, 10),
(9, 11): (0, 1, 2, 3, 5, 6, 8, 9, 10),
(9, 12): (0, 1, 2, 4, 5, 6, 8, 9, 10),
# 10
(10, 1): (0, 1, 2, 3, 4, 5, 6, 7, 8, 10),
(10, 2): (0, 1, 2, 3, 4, 5, 6, 7, 8, 9),
(10, 3): (0, 1, 2, 3, 4, 5, 6, 7, 9, 10),
(10, 4): (0, 1, 2, 3, 4, 5, 6, 8, 9, 10),
(10, 5): (0, 1, 2, 3, 4, 5, 7, 8, 9, 10),
(10, 6): (0, 1, 2, 3, 4, 6, 7, 8, 9, 10),
# 11
(11, 1): (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
# 12
(12, 1): (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11),
}
assert len(_lex_identifier_to_prime_form) == 224
_transposition_only_identifier_to_prime_form = {
# 0
(0, 1): (),
# 1
(1, 1): (0),
# 2
(2, 1): (0, 1),
(2, 2): (0, 2),
(2, 3): (0, 3),
(2, 4): (0, 4),
(2, 5): (0, 5),
(2, 6): (0, 6),
# 3
(3, 1): (0, 1, 2),
(3, 2): (0, 1, 3),
(3, 3): (0, 1, 4),
(3, 4): (0, 1, 5),
(3, 5): (0, 1, 6),
(3, 6): (0, 2, 3),
(3, 7): (0, 2, 4),
(3, 8): (0, 2, 5),
(3, 9): (0, 2, 6),
(3, 10): (0, 2, 7),
(3, 11): (0, 3, 4),
(3, 12): (0, 3, 5),
(3, 13): (0, 3, 6),
(3, 14): (0, 3, 7),
(3, 15): (0, 4, 5),
(3, 16): (0, 4, 6),
(3, 17): (0, 4, 7),
(3, 18): (0, 4, 8),
(3, 19): (0, 5, 6),
# 4
(4, 1): (0, 1, 2, 3),
(4, 2): (0, 1, 2, 4),
(4, 3): (0, 1, 2, 5),
(4, 4): (0, 1, 2, 6),
(4, 5): (0, 1, 2, 7),
(4, 6): (0, 1, 3, 4),
(4, 7): (0, 1, 3, 5),
(4, 8): (0, 1, 3, 6),
(4, 9): (0, 1, 3, 7),
(4, 10): (0, 1, 4, 5),
(4, 11): (0, 1, 4, 6),
(4, 12): (0, 1, 4, 7),
(4, 13): (0, 1, 4, 8),
(4, 14): (0, 1, 5, 6),
(4, 15): (0, 1, 5, 7),
(4, 16): (0, 1, 5, 8),
(4, 17): (0, 1, 6, 7),
(4, 18): (0, 2, 3, 4),
(4, 19): (0, 2, 3, 5),
(4, 20): (0, 2, 3, 6),
(4, 21): (0, 2, 3, 7),
(4, 22): (0, 2, 4, 5),
(4, 23): (0, 2, 4, 6),
(4, 24): (0, 2, 4, 7),
(4, 25): (0, 2, 4, 8),
(4, 26): (0, 2, 5, 6),
(4, 27): (0, 2, 5, 7),
(4, 28): (0, 2, 5, 8),
(4, 29): (0, 2, 6, 7),
(4, 30): (0, 2, 6, 8),
(4, 31): (0, 3, 4, 5),
(4, 32): (0, 3, 4, 6),
(4, 33): (0, 3, 4, 7),
(4, 34): (0, 3, 4, 8),
(4, 35): (0, 3, 5, 6),
(4, 36): (0, 3, 5, 7),
(4, 37): (0, 3, 5, 8),
(4, 38): (0, 3, 6, 7),
(4, 39): (0, 3, 6, 8),
(4, 40): (0, 3, 6, 9),
(4, 41): (0, 4, 5, 6),
(4, 42): (0, 4, 5, 7),
(4, 43): (0, 4, 6, 7),
# 5
(5, 1): (0, 1, 2, 3, 4),
(5, 2): (0, 1, 2, 3, 5),
(5, 3): (0, 1, 2, 3, 6),
(5, 4): (0, 1, 2, 3, 7),
(5, 5): (0, 1, 2, 4, 5),
(5, 6): (0, 1, 2, 4, 6),
(5, 7): (0, 1, 2, 4, 7),
(5, 8): (0, 1, 2, 4, 8),
(5, 9): (0, 1, 2, 5, 6),
(5, 10): (0, 1, 2, 5, 7),
(5, 11): (0, 1, 2, 5, 8),
(5, 12): (0, 1, 2, 6, 7),
(5, 13): (0, 1, 2, 6, 8),
(5, 14): (0, 1, 3, 4, 5),
(5, 15): (0, 1, 3, 4, 6),
(5, 16): (0, 1, 3, 4, 7),
(5, 17): (0, 1, 3, 4, 8),
(5, 18): (0, 1, 3, 5, 6),
(5, 19): (0, 1, 3, 5, 7),
(5, 20): (0, 1, 3, 5, 8),
(5, 21): (0, 1, 3, 6, 7),
(5, 22): (0, 1, 3, 6, 8),
(5, 23): (0, 1, 3, 6, 9),
(5, 24): (0, 1, 3, 7, 8),
(5, 25): (0, 1, 4, 5, 6),
(5, 26): (0, 1, 4, 5, 7),
(5, 27): (0, 1, 4, 5, 8),
(5, 28): (0, 1, 4, 6, 7),
(5, 29): (0, 1, 4, 6, 8),
(5, 30): (0, 1, 4, 6, 9),
(5, 31): (0, 1, 4, 7, 8),
(5, 32): (0, 1, 4, 7, 9),
(5, 33): (0, 1, 5, 6, 7),
(5, 34): (0, 1, 5, 7, 8),
(5, 35): (0, 2, 3, 4, 5),
(5, 36): (0, 2, 3, 4, 6),
(5, 37): (0, 2, 3, 4, 7),
(5, 38): (0, 2, 3, 4, 8),
(5, 39): (0, 2, 3, 5, 6),
(5, 40): (0, 2, 3, 5, 7),
(5, 41): (0, 2, 3, 5, 8),
(5, 42): (0, 2, 3, 6, 7),
(5, 43): (0, 2, 3, 6, 8),
(5, 44): (0, 2, 3, 6, 9),
(5, 45): (0, 2, 4, 5, 6),
(5, 46): (0, 2, 4, 5, 7),
(5, 47): (0, 2, 4, 5, 8),
(5, 48): (0, 2, 4, 6, 7),
(5, 49): (0, 2, 4, 6, 8),
(5, 50): (0, 2, 4, 6, 9),
(5, 51): (0, 2, 4, 7, 8),
(5, 52): (0, 2, 4, 7, 9),
(5, 53): (0, 2, 5, 6, 7),
(5, 54): (0, 2, 5, 6, 8),
(5, 55): (0, 2, 5, 7, 8),
(5, 56): (0, 3, 4, 5, 6),
(5, 57): (0, 3, 4, 5, 7),
(5, 58): (0, 3, 4, 5, 8),
(5, 59): (0, 3, 4, 6, 7),
(5, 60): (0, 3, 4, 6, 8),
(5, 61): (0, 3, 4, 7, 8),
(5, 62): (0, 3, 5, 6, 7),
(5, 63): (0, 3, 5, 6, 8),
(5, 64): (0, 3, 5, 7, 8),
(5, 65): (0, 3, 6, 7, 8),
(5, 66): (0, 4, 5, 6, 7),
# 6
(6, 1): (0, 1, 2, 3, 4, 5),
(6, 2): (0, 1, 2, 3, 4, 6),
(6, 3): (0, 1, 2, 3, 4, 7),
(6, 4): (0, 1, 2, 3, 4, 8),
(6, 5): (0, 1, 2, 3, 5, 6),
(6, 6): (0, 1, 2, 3, 5, 7),
(6, 7): (0, 1, 2, 3, 5, 8),
(6, 8): (0, 1, 2, 3, 6, 7),
(6, 9): (0, 1, 2, 3, 6, 8),
(6, 10): (0, 1, 2, 3, 6, 9),
(6, 11): (0, 1, 2, 3, 7, 8),
(6, 12): (0, 1, 2, 4, 5, 6),
(6, 13): (0, 1, 2, 4, 5, 7),
(6, 14): (0, 1, 2, 4, 5, 8),
(6, 15): (0, 1, 2, 4, 6, 7),
(6, 16): (0, 1, 2, 4, 6, 8),
(6, 17): (0, 1, 2, 4, 6, 9),
(6, 18): (0, 1, 2, 4, 7, 8),
(6, 19): (0, 1, 2, 4, 7, 9),
(6, 20): (0, 1, 2, 5, 6, 7),
(6, 21): (0, 1, 2, 5, 6, 8),
(6, 22): (0, 1, 2, 5, 6, 9),
(6, 23): (0, 1, 2, 5, 7, 8),
(6, 24): (0, 1, 2, 5, 7, 9),
(6, 25): (0, 1, 2, 5, 8, 9),
(6, 26): (0, 1, 2, 6, 7, 8),
(6, 27): (0, 1, 3, 4, 5, 6),
(6, 28): (0, 1, 3, 4, 5, 7),
(6, 29): (0, 1, 3, 4, 5, 8),
(6, 30): (0, 1, 3, 4, 6, 7),
(6, 31): (0, 1, 3, 4, 6, 8),
(6, 32): (0, 1, 3, 4, 6, 9),
(6, 33): (0, 1, 3, 4, 7, 8),
(6, 34): (0, 1, 3, 4, 7, 9),
(6, 35): (0, 1, 3, 5, 6, 7),
(6, 36): (0, 1, 3, 5, 6, 8),
(6, 37): (0, 1, 3, 5, 6, 9),
(6, 38): (0, 1, 3, 5, 7, 8),
(6, 39): (0, 1, 3, 5, 7, 9),
(6, 40): (0, 1, 3, 5, 8, 9),
(6, 41): (0, 1, 3, 6, 7, 8),
(6, 42): (0, 1, 3, 6, 7, 9),
(6, 43): (0, 1, 3, 6, 8, 9),
(6, 44): (0, 1, 4, 5, 6, 7),
(6, 45): (0, 1, 4, 5, 6, 8),
(6, 46): (0, 1, 4, 5, 7, 8),
(6, 47): (0, 1, 4, 5, 8, 9),
(6, 48): (0, 1, 4, 6, 7, 8),
(6, 49): (0, 1, 4, 6, 7, 9),
(6, 50): (0, 1, 4, 6, 8, 9),
(6, 51): (0, 2, 3, 4, 5, 6),
(6, 52): (0, 2, 3, 4, 5, 7),
(6, 53): (0, 2, 3, 4, 5, 8),
(6, 54): (0, 2, 3, 4, 6, 7),
(6, 55): (0, 2, 3, 4, 6, 8),
(6, 56): (0, 2, 3, 4, 6, 9),
(6, 57): (0, 2, 3, 4, 7, 8),
(6, 58): (0, 2, 3, 4, 7, 9),
(6, 59): (0, 2, 3, 5, 6, 7),
(6, 60): (0, 2, 3, 5, 6, 8),
(6, 61): (0, 2, 3, 5, 6, 9),
(6, 62): (0, 2, 3, 5, 7, 8),
(6, 63): (0, 2, 3, 5, 7, 9),
(6, 64): (0, 2, 3, 6, 7, 8),
(6, 65): (0, 2, 3, 6, 8, 9),
(6, 66): (0, 2, 4, 5, 6, 7),
(6, 67): (0, 2, 4, 5, 6, 8),
(6, 68): (0, 2, 4, 5, 6, 9),
(6, 69): (0, 2, 4, 5, 7, 8),
(6, 70): (0, 2, 4, 5, 7, 9),
(6, 71): (0, 2, 4, 6, 7, 8),
(6, 72): (0, 2, 4, 6, 7, 9),
(6, 73): (0, 2, 4, 6, 8, 10),
(6, 74): (0, 2, 4, 6, 8, 9),
(6, 75): (0, 2, 5, 6, 7, 8),
(6, 76): (0, 3, 4, 5, 6, 7),
(6, 77): (0, 3, 4, 5, 6, 8),
(6, 78): (0, 3, 4, 5, 7, 8),
(6, 79): (0, 3, 4, 6, 7, 8),
(6, 80): (0, 3, 5, 6, 7, 8),
# 7
(7, 1): (0, 1, 2, 3, 4, 5, 6),
(7, 2): (0, 1, 2, 3, 4, 5, 7),
(7, 3): (0, 1, 2, 3, 4, 5, 8),
(7, 4): (0, 1, 2, 3, 4, 6, 7),
(7, 5): (0, 1, 2, 3, 4, 6, 8),
(7, 6): (0, 1, 2, 3, 4, 6, 9),
(7, 7): (0, 1, 2, 3, 4, 7, 8),
(7, 8): (0, 1, 2, 3, 4, 7, 9),
(7, 9): (0, 1, 2, 3, 5, 6, 7),
(7, 10): (0, 1, 2, 3, 5, 6, 8),
(7, 11): (0, 1, 2, 3, 5, 6, 9),
(7, 12): (0, 1, 2, 3, 5, 7, 8),
(7, 13): (0, 1, 2, 3, 5, 7, 9),
(7, 14): (0, 1, 2, 3, 5, 8, 9),
(7, 15): (0, 1, 2, 3, 6, 7, 8),
(7, 16): (0, 1, 2, 3, 6, 7, 9),
(7, 17): (0, 1, 2, 3, 6, 8, 9),
(7, 18): (0, 1, 2, 4, 5, 6, 7),
(7, 19): (0, 1, 2, 4, 5, 6, 8),
(7, 20): (0, 1, 2, 4, 5, 6, 9),
(7, 21): (0, 1, 2, 4, 5, 7, 8),
(7, 22): (0, 1, 2, 4, 5, 7, 9),
(7, 23): (0, 1, 2, 4, 5, 8, 9),
(7, 24): (0, 1, 2, 4, 6, 7, 8),
(7, 25): (0, 1, 2, 4, 6, 7, 9),
(7, 26): (0, 1, 2, 4, 6, 8, 10),
(7, 27): (0, 1, 2, 4, 6, 8, 9),
(7, 28): (0, 1, 2, 4, 7, 8, 9),
(7, 29): (0, 1, 2, 5, 6, 7, 8),
(7, 30): (0, 1, 2, 5, 6, 8, 9),
(7, 31): (0, 1, 2, 5, 7, 8, 9),
(7, 32): (0, 1, 3, 4, 5, 6, 7),
(7, 33): (0, 1, 3, 4, 5, 6, 8),
(7, 34): (0, 1, 3, 4, 5, 6, 9),
(7, 35): (0, 1, 3, 4, 5, 7, 8),
(7, 36): (0, 1, 3, 4, 5, 7, 9),
(7, 37): (0, 1, 3, 4, 5, 8, 9),
(7, 38): (0, 1, 3, 4, 6, 7, 8),
(7, 39): (0, 1, 3, 4, 6, 7, 9),
(7, 40): (0, 1, 3, 4, 6, 8, 10),
(7, 41): (0, 1, 3, 4, 6, 8, 9),
(7, 42): (0, 1, 3, 5, 6, 7, 8),
(7, 43): (0, 1, 3, 5, 6, 7, 9),
(7, 44): (0, 1, 3, 5, 6, 8, 10),
(7, 45): (0, 1, 3, 5, 6, 8, 9),
(7, 46): (0, 1, 3, 5, 7, 8, 9),
(7, 47): (0, 1, 4, 5, 6, 7, 8),
(7, 48): (0, 1, 4, 6, 7, 8, 9),
(7, 49): (0, 2, 3, 4, 5, 6, 7),
(7, 50): (0, 2, 3, 4, 5, 6, 8),
(7, 51): (0, 2, 3, 4, 5, 6, 9),
(7, 52): (0, 2, 3, 4, 5, 7, 8),
(7, 53): (0, 2, 3, 4, 5, 7, 9),
(7, 54): (0, 2, 3, 4, 6, 7, 8),
(7, 55): (0, 2, 3, 4, 6, 7, 9),
(7, 56): (0, 2, 3, 4, 6, 8, 9),
(7, 57): (0, 2, 3, 5, 6, 7, 8),
(7, 58): (0, 2, 3, 5, 6, 7, 9),
(7, 59): (0, 2, 3, 5, 6, 8, 9),
(7, 60): (0, 2, 3, 5, 7, 8, 9),
(7, 61): (0, 2, 4, 5, 6, 7, 8),
(7, 62): (0, 2, 4, 5, 6, 7, 9),
(7, 63): (0, 2, 4, 5, 6, 8, 9),
(7, 64): (0, 2, 4, 5, 7, 8, 9),
(7, 65): (0, 2, 4, 6, 7, 8, 9),
(7, 66): (0, 3, 4, 5, 6, 7, 8),
# 8
(8, 1): (0, 1, 2, 3, 4, 5, 6, 7),
(8, 2): (0, 1, 2, 3, 4, 5, 6, 8),
(8, 3): (0, 1, 2, 3, 4, 5, 6, 9),
(8, 4): (0, 1, 2, 3, 4, 5, 7, 8),
(8, 5): (0, 1, 2, 3, 4, 5, 7, 9),
(8, 6): (0, 1, 2, 3, 4, 5, 8, 9),
(8, 7): (0, 1, 2, 3, 4, 6, 7, 8),
(8, 8): (0, 1, 2, 3, 4, 6, 7, 9),
(8, 9): (0, 1, 2, 3, 4, 6, 8, 10),
(8, 10): (0, 1, 2, 3, 4, 6, 8, 9),
(8, 11): (0, 1, 2, 3, 4, 7, 8, 9),
(8, 12): (0, 1, 2, 3, 5, 6, 7, 8),
(8, 13): (0, 1, 2, 3, 5, 6, 7, 9),
(8, 14): (0, 1, 2, 3, 5, 6, 8, 10),
(8, 15): (0, 1, 2, 3, 5, 6, 8, 9),
(8, 16): (0, 1, 2, 3, 5, 7, 8, 10),
(8, 17): (0, 1, 2, 3, 5, 7, 8, 9),
(8, 18): (0, 1, 2, 3, 5, 7, 9, 10),
(8, 19): (0, 1, 2, 3, 6, 7, 8, 9),
(8, 20): (0, 1, 2, 4, 5, 6, 7, 8),
(8, 21): (0, 1, 2, 4, 5, 6, 7, 9),
(8, 22): (0, 1, 2, 4, 5, 6, 8, 10),
(8, 23): (0, 1, 2, 4, 5, 6, 8, 9),
(8, 24): (0, 1, 2, 4, 5, 7, 8, 10),
(8, 25): (0, 1, 2, 4, 5, 7, 8, 9),
(8, 26): (0, 1, 2, 4, 5, 7, 9, 10),
(8, 27): (0, 1, 2, 4, 6, 7, 8, 10),
(8, 28): (0, 1, 2, 4, 6, 7, 8, 9),
(8, 29): (0, 1, 2, 4, 6, 7, 9, 10),
(8, 30): (0, 1, 3, 4, 5, 6, 7, 8),
(8, 31): (0, 1, 3, 4, 5, 6, 7, 9),
(8, 32): (0, 1, 3, 4, 5, 6, 8, 9),
(8, 33): (0, 1, 3, 4, 5, 7, 8, 9),
(8, 34): (0, 1, 3, 4, 6, 7, 8, 9),
(8, 35): (0, 1, 3, 4, 6, 7, 9, 10),
(8, 36): (0, 1, 3, 5, 6, 7, 8, 9),
(8, 37): (0, 2, 3, 4, 5, 6, 7, 8),
(8, 38): (0, 2, 3, 4, 5, 6, 7, 9),
(8, 39): (0, 2, 3, 4, 5, 6, 8, 9),
(8, 40): (0, 2, 3, 4, 5, 7, 8, 9),
(8, 41): (0, 2, 3, 4, 6, 7, 8, 9),
(8, 42): (0, 2, 3, 5, 6, 7, 8, 9),
(8, 43): (0, 2, 4, 5, 6, 7, 8, 9),
# 9
(9, 1): (0, 1, 2, 3, 4, 5, 6, 7, 8),
(9, 2): (0, 1, 2, 3, 4, 5, 6, 7, 9),
(9, 3): (0, 1, 2, 3, 4, 5, 6, 8, 10),
(9, 4): (0, 1, 2, 3, 4, 5, 6, 8, 9),
(9, 5): (0, 1, 2, 3, 4, 5, 7, 8, 10),
(9, 6): (0, 1, 2, 3, 4, 5, 7, 8, 9),
(9, 7): (0, 1, 2, 3, 4, 5, 7, 9, 10),
(9, 8): (0, 1, 2, 3, 4, 6, 7, 8, 10),
(9, 9): (0, 1, 2, 3, 4, 6, 7, 8, 9),
(9, 10): (0, 1, 2, 3, 4, 6, 7, 9, 10),
(9, 11): (0, 1, 2, 3, 4, 6, 8, 9, 10),
(9, 12): (0, 1, 2, 3, 5, 6, 7, 8, 10),
(9, 13): (0, 1, 2, 3, 5, 6, 7, 8, 9),
(9, 14): (0, 1, 2, 3, 5, 6, 7, 9, 10),
(9, 15): (0, 1, 2, 3, 5, 6, 8, 9, 10),
(9, 16): (0, 1, 2, 4, 5, 6, 7, 8, 9),
(9, 17): (0, 1, 2, 4, 5, 6, 8, 9, 10),
(9, 18): (0, 1, 3, 4, 5, 6, 7, 8, 9),
(9, 19): (0, 2, 3, 4, 5, 6, 7, 8, 9),
# 10
(10, 1): (0, 1, 2, 3, 4, 5, 6, 7, 8, 10),
(10, 2): (0, 1, 2, 3, 4, 5, 6, 7, 8, 9),
(10, 3): (0, 1, 2, 3, 4, 5, 6, 7, 9, 10),
(10, 4): (0, 1, 2, 3, 4, 5, 6, 8, 9, 10),
(10, 5): (0, 1, 2, 3, 4, 5, 7, 8, 9, 10),
(10, 6): (0, 1, 2, 3, 4, 6, 7, 8, 9, 10),
# 11
(11, 1): (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
# 12
(12, 1): (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11),
}
assert len(_transposition_only_identifier_to_prime_form) == 352
_prime_form_to_forte_identifier = {
v: k for k, v in _forte_identifier_to_prime_form.items()
}
_prime_form_to_lex_identifier = {
v: k for k, v in _lex_identifier_to_prime_form.items()
}
_prime_form_to_transposition_only_identifier = {
v: k for k, v in _transposition_only_identifier_to_prime_form.items()
}
[docs] def __post_init__(self):
if bool(self.transposition_only) and self.lex_rank is False:
raise Exception("SG1 (transposition-only) set-classes must be lex-rank.")
self.cardinality = int(self.cardinality)
assert 0 <= self.cardinality <= 12, repr(self.cardinality)
self.rank = int(self.rank)
assert 1 <= self.rank, repr(self.rank)
assert isinstance(self.lex_rank, type(None) | bool)
assert isinstance(self.transposition_only, type(None) | bool)
[docs] def __str__(self) -> str:
"""
Gets string representation.
Gets string of SG2 set-class with Forte rank:
.. container:: example
>>> set_class = abjad.SetClass(4, 29)
>>> print(set_class)
SC(4-29){0, 1, 3, 7}
.. container:: example
Gets string of SG2 set-class with lex rank:
>>> set_class = abjad.SetClass(
... 4, 29,
... lex_rank=True,
... )
>>> print(set_class)
SC(4-29){0, 3, 6, 9}
.. container:: example
Gets string of SG1 set-class:
>>> set_class = abjad.SetClass(
... 4, 29,
... lex_rank=True,
... transposition_only=True,
... )
>>> print(set_class)
SC(4-29){0, 2, 6, 7}
"""
string = f"SC({self.cardinality}-{self.rank}){self.prime_form!s}"
string = string.replace("PC", "")
return string
def _unrank(self, cardinality, rank, transposition_only=None):
pair = (cardinality, rank)
if self.transposition_only:
prime_form = self._transposition_only_identifier_to_prime_form[pair]
elif self.lex_rank:
prime_form = self._lex_identifier_to_prime_form[pair]
else:
prime_form = self._forte_identifier_to_prime_form[pair]
prime_form = _pcollections.PitchClassSet(prime_form)
return prime_form
@property
def is_inversion_equivalent(self) -> bool:
"""
Is true when set-class is inversion-equivalent.
.. container:: example
Is inversion-equivalent:
>>> set_class = abjad.SetClass(4, 29)
>>> print(set_class)
SC(4-29){0, 1, 3, 7}
>>> pitch_class_set = set_class.prime_form
>>> inverted_pitch_class_set = pitch_class_set.invert()
>>> inverted_set_class = abjad.SetClass.from_pitches(
... inverted_pitch_class_set
... )
>>> print(inverted_set_class)
SC(4-29){0, 1, 3, 7}
>>> set_class.is_inversion_equivalent
True
.. container:: example
Is inversion-equivalent:
>>> set_class = abjad.SetClass(
... 4, 29,
... lex_rank=True,
... )
>>> print(set_class)
SC(4-29){0, 3, 6, 9}
>>> pitch_class_set = set_class.prime_form
>>> inverted_pitch_class_set = pitch_class_set.invert()
>>> inverted_set_class = abjad.SetClass.from_pitches(
... inverted_pitch_class_set,
... lex_rank=True,
... )
>>> print(inverted_set_class)
SC(4-29){0, 3, 6, 9}
>>> set_class.is_inversion_equivalent
True
.. container:: example
Is not inversion-equivalent:
>>> set_class = abjad.SetClass(
... 4, 29,
... lex_rank=True,
... transposition_only=True,
... )
>>> print(set_class)
SC(4-29){0, 2, 6, 7}
>>> pitch_class_set = set_class.prime_form
>>> inverted_pitch_class_set = pitch_class_set.invert()
>>> inverted_set_class = abjad.SetClass.from_pitches(
... inverted_pitch_class_set,
... lex_rank=True,
... transposition_only=True,
... )
>>> print(inverted_set_class)
SC(4-15){0, 1, 5, 7}
>>> set_class.is_inversion_equivalent
False
"""
prime_form = self.prime_form
inverted_pitch_class_set = prime_form.invert()
inverted_set_class = type(self).from_pitches(
inverted_pitch_class_set,
lex_rank=self.lex_rank,
transposition_only=self.transposition_only,
)
return self == inverted_set_class
@property
def prime_form(self) -> _pcollections.PitchClassSet:
"""
Gets prime form.
.. container:: example
Gets prime form of SG2 set-class with Forte rank:
>>> set_class = abjad.SetClass(4, 29)
>>> print(set_class)
SC(4-29){0, 1, 3, 7}
>>> set_class.prime_form
PitchClassSet([0, 1, 3, 7])
.. container:: example
Gets prime form of SG2 set-class with lex rank:
>>> set_class = abjad.SetClass(
... 4, 29,
... lex_rank=True,
... )
>>> print(set_class)
SC(4-29){0, 3, 6, 9}
>>> set_class.prime_form
PitchClassSet([0, 3, 6, 9])
.. container:: example
Gets prime form of SG1 set-class:
>>> set_class = abjad.SetClass(
... 4, 29,
... lex_rank=True,
... transposition_only=True,
... )
>>> print(set_class)
SC(4-29){0, 2, 6, 7}
>>> set_class.prime_form
PitchClassSet([0, 2, 6, 7])
Returns numbered pitch-class set.
"""
prime_form = self._unrank(
self.cardinality,
self.rank,
transposition_only=self.transposition_only,
)
return prime_form
[docs] @staticmethod
def from_pitches(pitches, lex_rank=None, transposition_only=None):
"""
Makes set-class from ``pitches``.
.. container:: example
>>> pc_set = abjad.PitchClassSet([9, 0, 3, 5, 6])
>>> set_class = abjad.SetClass.from_pitches(pc_set)
>>> print(set_class)
SC(5-31){0, 1, 3, 6, 9}
>>> pc_set = abjad.PitchClassSet([9, 0, 3, 5, 6])
>>> set_class = abjad.SetClass.from_pitches(
... pc_set,
... lex_rank=True,
... )
>>> print(set_class)
SC(5-22){0, 1, 3, 6, 9}
>>> pc_set = abjad.PitchClassSet([9, 0, 3, 5, 6])
>>> set_class = abjad.SetClass.from_pitches(
... pc_set,
... transposition_only=True,
... )
>>> print(set_class)
SC(5-44){0, 2, 3, 6, 9}
.. container:: example
>>> pc_set = abjad.PitchClassSet([9, 11, 1, 2, 4, 6])
>>> set_class = abjad.SetClass.from_pitches(pc_set)
>>> print(set_class)
SC(6-32){0, 2, 4, 5, 7, 9}
>>> pc_set = abjad.PitchClassSet([9, 11, 1, 2, 4, 6])
>>> set_class = abjad.SetClass.from_pitches(
... pc_set,
... lex_rank=True,
... )
>>> print(set_class)
SC(6-49){0, 2, 4, 5, 7, 9}
>>> pc_set = abjad.PitchClassSet([9, 11, 1, 2, 4, 6])
>>> set_class = abjad.SetClass.from_pitches(
... pc_set,
... transposition_only=True,
... )
>>> print(set_class)
SC(6-70){0, 2, 4, 5, 7, 9}
.. container:: example
>>> pc_set = abjad.PitchClassSet([11, 0, 5, 6])
>>> set_class = abjad.SetClass.from_pitches(pc_set)
>>> print(set_class)
SC(4-9){0, 1, 6, 7}
>>> pc_set = abjad.PitchClassSet([11, 0, 5, 6])
>>> set_class = abjad.SetClass.from_pitches(
... pc_set,
... lex_rank=True,
... )
>>> print(set_class)
SC(4-17){0, 1, 6, 7}
>>> pc_set = abjad.PitchClassSet([11, 0, 5, 6])
>>> set_class = abjad.SetClass.from_pitches(
... pc_set,
... transposition_only=True,
... )
>>> print(set_class)
SC(4-17){0, 1, 6, 7}
.. container:: example
>>> pc_set = abjad.PitchClassSet([0, 4, 7])
>>> set_class = abjad.SetClass.from_pitches(pc_set)
>>> print(set_class)
SC(3-11){0, 3, 7}
>>> pc_set = abjad.PitchClassSet([0, 4, 7])
>>> set_class = abjad.SetClass.from_pitches(
... pc_set,
... lex_rank=True,
... )
>>> print(set_class)
SC(3-11){0, 3, 7}
>>> pc_set = abjad.PitchClassSet([0, 4, 7])
>>> set_class = abjad.SetClass.from_pitches(
... pc_set,
... transposition_only=True,
... )
>>> print(set_class)
SC(3-17){0, 4, 7}
Returns new set-class.
"""
pitch_class_set = _pcollections.PitchClassSet(pitches)
prime_form = pitch_class_set.get_prime_form(
transposition_only=transposition_only
)
prime_form = tuple([_.number for _ in sorted(prime_form)])
if transposition_only:
pair = SetClass._prime_form_to_transposition_only_identifier[prime_form]
elif lex_rank:
pair = SetClass._prime_form_to_lex_identifier[prime_form]
else:
pair = SetClass._prime_form_to_forte_identifier[prime_form]
cardinality, rank = pair
set_class = SetClass(
cardinality=cardinality,
rank=rank,
lex_rank=lex_rank,
transposition_only=transposition_only,
)
return set_class
[docs] @staticmethod
def list_set_classes(cardinality=None, lex_rank=None, transposition_only=None):
"""
List set-classes.
.. container:: example
Lists SG2 set-classes of cardinality 4 with Forte rank:
>>> set_classes = abjad.SetClass.list_set_classes(
... cardinality=4,
... )
>>> for set_class in set_classes:
... print(set_class)
SC(4-1){0, 1, 2, 3}
SC(4-2){0, 1, 2, 4}
SC(4-3){0, 1, 3, 4}
SC(4-4){0, 1, 2, 5}
SC(4-5){0, 1, 2, 6}
SC(4-6){0, 1, 2, 7}
SC(4-7){0, 1, 4, 5}
SC(4-8){0, 1, 5, 6}
SC(4-9){0, 1, 6, 7}
SC(4-10){0, 2, 3, 5}
SC(4-11){0, 1, 3, 5}
SC(4-12){0, 2, 3, 6}
SC(4-13){0, 1, 3, 6}
SC(4-14){0, 2, 3, 7}
SC(4-15){0, 1, 4, 6}
SC(4-16){0, 1, 5, 7}
SC(4-17){0, 3, 4, 7}
SC(4-18){0, 1, 4, 7}
SC(4-19){0, 1, 4, 8}
SC(4-20){0, 1, 5, 8}
SC(4-21){0, 2, 4, 6}
SC(4-22){0, 2, 4, 7}
SC(4-23){0, 2, 5, 7}
SC(4-24){0, 2, 4, 8}
SC(4-25){0, 2, 6, 8}
SC(4-26){0, 3, 5, 8}
SC(4-27){0, 2, 5, 8}
SC(4-28){0, 3, 6, 9}
SC(4-29){0, 1, 3, 7}
.. container:: example
Lists SG2 set-classes of cardinality 4 with lex rank:
>>> set_classes = abjad.SetClass.list_set_classes(
... cardinality=4,
... lex_rank=True,
... )
>>> for set_class in set_classes:
... print(set_class)
SC(4-1){0, 1, 2, 3}
SC(4-2){0, 1, 2, 4}
SC(4-3){0, 1, 2, 5}
SC(4-4){0, 1, 2, 6}
SC(4-5){0, 1, 2, 7}
SC(4-6){0, 1, 3, 4}
SC(4-7){0, 1, 3, 5}
SC(4-8){0, 1, 3, 6}
SC(4-9){0, 1, 3, 7}
SC(4-10){0, 1, 4, 5}
SC(4-11){0, 1, 4, 6}
SC(4-12){0, 1, 4, 7}
SC(4-13){0, 1, 4, 8}
SC(4-14){0, 1, 5, 6}
SC(4-15){0, 1, 5, 7}
SC(4-16){0, 1, 5, 8}
SC(4-17){0, 1, 6, 7}
SC(4-18){0, 2, 3, 5}
SC(4-19){0, 2, 3, 6}
SC(4-20){0, 2, 3, 7}
SC(4-21){0, 2, 4, 6}
SC(4-22){0, 2, 4, 7}
SC(4-23){0, 2, 4, 8}
SC(4-24){0, 2, 5, 7}
SC(4-25){0, 2, 5, 8}
SC(4-26){0, 2, 6, 8}
SC(4-27){0, 3, 4, 7}
SC(4-28){0, 3, 5, 8}
SC(4-29){0, 3, 6, 9}
.. container:: example
Lists SG1 set-classes of cardinality 4:
>>> set_classes = abjad.SetClass.list_set_classes(
... cardinality=4,
... transposition_only=True,
... )
>>> for set_class in set_classes:
... print(set_class)
SC(4-1){0, 1, 2, 3}
SC(4-2){0, 1, 2, 4}
SC(4-3){0, 1, 2, 5}
SC(4-4){0, 1, 2, 6}
SC(4-5){0, 1, 2, 7}
SC(4-6){0, 1, 3, 4}
SC(4-7){0, 1, 3, 5}
SC(4-8){0, 1, 3, 6}
SC(4-9){0, 1, 3, 7}
SC(4-10){0, 1, 4, 5}
SC(4-11){0, 1, 4, 6}
SC(4-12){0, 1, 4, 7}
SC(4-13){0, 1, 4, 8}
SC(4-14){0, 1, 5, 6}
SC(4-15){0, 1, 5, 7}
SC(4-16){0, 1, 5, 8}
SC(4-17){0, 1, 6, 7}
SC(4-18){0, 2, 3, 4}
SC(4-19){0, 2, 3, 5}
SC(4-20){0, 2, 3, 6}
SC(4-21){0, 2, 3, 7}
SC(4-22){0, 2, 4, 5}
SC(4-23){0, 2, 4, 6}
SC(4-24){0, 2, 4, 7}
SC(4-25){0, 2, 4, 8}
SC(4-26){0, 2, 5, 6}
SC(4-27){0, 2, 5, 7}
SC(4-28){0, 2, 5, 8}
SC(4-29){0, 2, 6, 7}
SC(4-30){0, 2, 6, 8}
SC(4-31){0, 3, 4, 5}
SC(4-32){0, 3, 4, 6}
SC(4-33){0, 3, 4, 7}
SC(4-34){0, 3, 4, 8}
SC(4-35){0, 3, 5, 6}
SC(4-36){0, 3, 5, 7}
SC(4-37){0, 3, 5, 8}
SC(4-38){0, 3, 6, 7}
SC(4-39){0, 3, 6, 8}
SC(4-40){0, 3, 6, 9}
SC(4-41){0, 4, 5, 6}
SC(4-42){0, 4, 5, 7}
SC(4-43){0, 4, 6, 7}
Returns list of set-classes.
"""
if transposition_only:
identifiers = SetClass._transposition_only_identifier_to_prime_form
elif lex_rank:
identifiers = SetClass._lex_identifier_to_prime_form
else:
identifiers = SetClass._forte_identifier_to_prime_form
identifiers = list(identifiers)
if cardinality is not None:
identifiers = [_ for _ in identifiers if _[0] == cardinality]
set_classes = []
for identifier in sorted(identifiers):
cardinality, rank = identifier
set_class = SetClass(
cardinality,
rank,
lex_rank=lex_rank,
transposition_only=transposition_only,
)
set_classes.append(set_class)
return set_classes
def _classify_set_classes(transposition_only=False):
"""
Was only necessary to run during implementation of SetClass.
Generated the ...
_forte_identifier_to_prime_form
_lex_identifier_to_prime_form
_transposition_only_identifier_to_prime_form
... dictionaries attached as class attributes.
Archived here in case other identifier systems are needed in future.
"""
all_prime_forms = {}
for cardinality in range(12 + 1):
all_prime_forms[cardinality] = set()
for pc_set in _yield_all_pitch_class_sets():
if _pitch.NumberedPitchClass(0) not in pc_set:
if 0 < len(pc_set):
continue
prime_form = pc_set.get_prime_form(transposition_only=transposition_only)
all_prime_forms[prime_form.cardinality].add(prime_form)
total = 0
for cardinality in range(12 + 1):
count = len(all_prime_forms[cardinality])
total += count
for cardinality in range(12 + 1):
prime_forms = list(all_prime_forms[cardinality])
prime_forms.sort(key=lambda x: str(x))
for index, prime_form in enumerate(prime_forms):
rank = index + 1
prime_form = str(prime_form)
prime_form = prime_form.replace("{", "(")
prime_form = prime_form.replace("}", ")")
message = f"({cardinality}, {rank}): {prime_form},"
print(message)
print()
message = f"total set-classes: {total}"
print(message)
print()
def _yield_all_pitch_class_sets():
def _helper(binary_string):
result = zip(binary_string, range(len(binary_string)))
result = [string[1] for string in result if string[0] == "1"]
return result
for i in range(4096):
string = _math.integer_to_binary_string(i).zfill(12)
subset = "".join(list(reversed(string)))
subset = _helper(subset)
subset = _pcollections.PitchClassSet(subset)
yield subset