from .. import math
from ..storage import StorageFormatManager
from .pitchclasses import NumberedPitchClass
from .sets import PitchClassSet


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)
        >>> print(set_class)
        SC(4-29){0, 2, 6, 7}

    ..  container:: example

        Makes aggregate:

        >>> set_class = abjad.SetClass(12, 1, transposition_only=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){2, 6, 8, 9}
        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.
    """

    ### CLASS VARIABLES ##

    __slots__ = (
        "_cardinality",
        "_lex_rank",
        "_prime_form",
        "_rank",
        "_transposition_only",
    )

    _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): (9, 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()
    }

    ### INITIALIZER ###

    def __init__(
        self, cardinality=1, rank=1, *, lex_rank=None, transposition_only=None
    ):
        if bool(transposition_only) and lex_rank is False:
            raise Exception("SG1 set-classes are always lex-rank.")
        cardinality = int(cardinality)
        assert 0 <= cardinality <= 12, repr(cardinality)
        self._cardinality = cardinality
        rank = int(rank)
        assert 1 <= rank, repr(rank)
        self._rank = rank
        assert isinstance(lex_rank, (type(None), type(True)))
        self._lex_rank = lex_rank
        assert isinstance(transposition_only, (type(None), type(True)))
        self._transposition_only = transposition_only
        prime_form = self._unrank(
            self.cardinality,
            self.rank,
            transposition_only=self.transposition_only,
        )
        self._prime_form = prime_form

    ### SPECIAL METHODS ###

    def __eq__(self, argument) -> bool:
        """
        Is true when all initialization values of Abjad value object equal
        the initialization values of ``argument``.
        """
        return StorageFormatManager.compare_objects(self, argument)

    def __hash__(self) -> int:
        """
        Hashes Abjad value object.
        """
        hash_values = StorageFormatManager(self).get_hash_values()
        try:
            result = hash(hash_values)
        except TypeError:
            raise TypeError(f"unhashable type: {self}")
        return result

    def __repr__(self) -> str:
        """
        Gets interpreter representation.
        """
        return StorageFormatManager(self).get_repr_format()

    def __str__(self):
        """
        Gets string representation.

        ..  container:: example

            Gets string of SG2 set-class with Forte rank:

            >>> 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,
            ...     transposition_only=True,
            ...     )
            >>> print(set_class)
            SC(4-29){0, 2, 6, 7}

        Returns string.
        """
        string = f"SC({self.cardinality}-{self.rank}){self.prime_form!s}"
        string = string.replace("PC", "")
        return string

    ### PRIVATE METHODS ###

    @staticmethod
    def _classify_set_classes():
        """
        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 SetClass._yield_all_pitch_class_sets():
            if NumberedPitchClass(0) not in pc_set:
                if 0 < len(pc_set):
                    continue
            prime_form = pc_set.get_prime_form(transposition_only=True)
            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 _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 = PitchClassSet(items=prime_form, item_class=NumberedPitchClass)
        return prime_form

    @staticmethod
    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 = PitchClassSet(subset, item_class=NumberedPitchClass)
            yield subset

    ### PUBLIC PROPERTIES ###

    @property
    def cardinality(self):
        """
        Gets cardinality.

        ..  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

        ..  container:: example

            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

        ..  container:: example

            Gets cardinality of SG1 set-class:

            >>> set_class = abjad.SetClass(
            ...     4, 29,
            ...     transposition_only=True,
            ...     )
            >>> print(set_class)
            SC(4-29){0, 2, 6, 7}

            >>> set_class.cardinality
            4

        Set to integer between 0 and 12, inclusive.

        Returns integer between 0 and 12, inclusive.
        """
        return self._cardinality

    @property
    def is_inversion_equivalent(self):
        """
        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_pitch_class_set(
            ...     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_pitch_class_set(
            ...     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,
            ...     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_pitch_class_set(
            ...     inverted_pitch_class_set,
            ...     transposition_only=True,
            ...     )
            >>> print(inverted_set_class)
            SC(4-15){0, 1, 5, 7}

            >>> set_class.is_inversion_equivalent
            False

        Returns true or false.
        """
        prime_form = self.prime_form
        inverted_pitch_class_set = prime_form.invert()
        inverted_set_class = type(self).from_pitch_class_set(
            inverted_pitch_class_set,
            lex_rank=self.lex_rank,
            transposition_only=self.transposition_only,
        )
        return self == inverted_set_class

    @property
    def lex_rank(self):
        """
        Is true when set-class uses lex rank.

        ..  container:: example

            Uses Forte rank:

            >>> set_class = abjad.SetClass(4, 29)
            >>> set_class
            SetClass(cardinality=4, rank=29)

            >>> print(set_class)
            SC(4-29){0, 1, 3, 7}

        ..  container:: example

            Uses lex rank:

            >>> set_class = abjad.SetClass(
            ...     4, 29,
            ...     lex_rank=True,
            ...     )
            >>> set_class
            SetClass(cardinality=4, rank=29, lex_rank=True)

            >>> print(set_class)
            SC(4-29){0, 3, 6, 9}

        ..  container:: example

            SG1 set-classes always use lex rank:

            >>> set_class = abjad.SetClass(
            ...     4, 29,
            ...     transposition_only=True,
            ...     )
            >>> set_class
            SetClass(cardinality=4, rank=29, transposition_only=True)

            >>> print(set_class)
            SC(4-29){0, 2, 6, 7}

        Set to true, false or none.

        Defaults to none.

        Returns true, false or none.
        """
        return self._lex_rank

    @property
    def prime_form(self):
        """
        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,
            ...     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.
        """
        return self._prime_form

    @property
    def rank(self):
        """
        Gets rank.

        ..  container:: example

            Gets rank 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.rank
            29

        ..  container:: example

            Gets rank 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.rank
            29

        ..  container:: example

            Gets rank of SG1 set-class:

            >>> set_class = abjad.SetClass(
            ...     4, 29,
            ...     transposition_only=True,
            ...     )
            >>> print(set_class)
            SC(4-29){0, 2, 6, 7}

            >>> set_class.rank
            29

        Set to positive integer.

        Returns positive integer.
        """
        return self._rank

    @property
    def transposition_only(self):
        """
        Is true when set-class collects pitch-class sets related only by
        transposition.

        ..  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 set-class:

            >>> set_class = abjad.SetClass(
            ...     4, 29,
            ...     transposition_only=True,
            ...     )
            >>> print(set_class)
            SC(4-29){0, 2, 6, 7}

        Set to true, false or none.

        Defaults to none.

        Returns true, false or none.
        """
        return self._transposition_only

    ### PUBLIC METHODS ###

    # TODO: change to from_selection()
    @staticmethod
    def from_pitch_class_set(pitch_class_set, lex_rank=None, transposition_only=None):
        """
        Makes set-class from ``pitch_class_set``.

        ..  container:: example

            >>> pc_set = abjad.PitchClassSet([9, 0, 3, 5, 6])
            >>> set_class = abjad.SetClass.from_pitch_class_set(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_pitch_class_set(
            ...     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_pitch_class_set(
            ...     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_pitch_class_set(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_pitch_class_set(
            ...     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_pitch_class_set(
            ...     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_pitch_class_set(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_pitch_class_set(
            ...     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_pitch_class_set(
            ...     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_pitch_class_set(pc_set)
            >>> print(set_class)
            SC(3-11){0, 3, 7}

            >>> pc_set = abjad.PitchClassSet([0, 4, 7])
            >>> set_class = abjad.SetClass.from_pitch_class_set(
            ...     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_pitch_class_set(
            ...     pc_set,
            ...     transposition_only=True,
            ...     )
            >>> print(set_class)
            SC(3-17){0, 4, 7}

        Returns set-class.
        """
        pitch_class_set = PitchClassSet(
            items=pitch_class_set, item_class=NumberedPitchClass
        )
        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

    @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){2, 6, 8, 9}
            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
