
    rh                       % S SK Jr  S SKrS SKrS SKrS SKrS SKJr  S SKJr  S SKJ	r	  S SKJ
r
  S SKJr  S SKJr  S S	KJr  S S
KJr  S SKJr  S SKJr  SrSS0rS\S'    " S S5      r " S S\5      r   S   S S jjrS rS rS!S jrS!S jr " S S\	R8                  5      r " S S\R<                  5      r\ S:X  a  S SKr\RB                  " \5        gg)"    )annotationsN)chord)environment)exceptions21)note)pitch)scale)possibility)realizerScale)
resolution)ruleszfiguredBass.segmentr	   z0dict[str, realizerScale.FiguredBassScale | None]_defaultRealizerScalec                      \ rS rSr% / SQrSSSSSSS	.rS
\S'          S         SS jjrSS jrSS jr	SS jr
S rSS jrS rS rS rS rS rS rS rS rSrg) Segment$   )	allSinglePossibilitiessinglePossibilityRulesallCorrectSinglePossibilitiesconsecutivePossibilityRulesspecialResolutionRules"allCorrectConsecutivePossibilitiesresolveDominantSeventhSegmentresolveDiminishedSeventhSegmentresolveAugmentedSixthSegmentzZA :class:`~music21.note.Note` whose pitch
             forms the bass of each possibility.zThe number of parts (including the bass) that possibilities
             should contain, which
             comes directly from :attr:`~music21.figuredBass.rules.Rules.numParts`
             in the Rules object.zA list of allowable pitch names.
             This is derived from bassNote.pitch and notationString
             using :meth:`~music21.figuredBass.realizerScale.FiguredBassScale.getPitchNames`.a|  A list of allowable pitches in the upper parts of a possibility.
             This is derived using
             :meth:`~music21.figuredBass.segment.getPitches`, providing bassNote.pitch,
             :attr:`~music21.figuredBass.rules.Rules.maxPitch`
             from the Rules object, and
             :attr:`~music21.figuredBass.segment.Segment.pitchNamesInChord` as arguments.z}:attr:`~music21.figuredBass.segment.Segment.allPitchesAboveBass`
             represented as a :class:`~music21.chord.Chord`.zLA deepcopy of the :class:`~music21.figuredBass.rules.Rules` object provided.)bassNotenumPartspitchNamesInChordallPitchesAboveBasssegmentChordfbRuleszdict[str, str]	_DOC_ATTRNc                \   [        U[        5      (       a  [        R                  " U5      n[        U[        5      (       a  [        R
                  " U5      nUc/  [        S   c  [        R                  " 5       [        S'   [        S   nUc   eUc  [        R                  " 5       U l        O[        R                  " U5      U l        SU l        SU l        SU l        Xl        XPl        X`l        Uc
  Ub  Xpl        O+UR+                  U R"                  R                  U5      U l        [-        U R(                  U R"                  R                  U R&                  5      U l        [0        R2                  " U R.                  UR4                  S9U l        [8        R:                  " [<        5      U l        g)a_  
A Segment corresponds to a 1:1 realization of a bassNote and notationString
of a :class:`~music21.figuredBass.realizer.FiguredBassLine`.
It is created by passing six arguments: a
:class:`~music21.figuredBass.realizerScale.FiguredBassScale`, a bassNote, a notationString,
a :class:`~music21.figuredBass.rules.Rules` object, a number of parts and a maximum pitch.
Realizations of a Segment are represented
as possibility tuples (see :mod:`~music21.figuredBass.possibility` for more details).

Methods in Python's `itertools`
module are used extensively. Methods
which generate possibilities or possibility progressions return iterators,
which are turned into lists in the examples
for display purposes only.

if fbScale is None, a realizerScale.FiguredBassScale() is created

if fbRules is None, a rules.Rules() instance is created.  Each Segment gets
its own deepcopy of the one given.


Here, a Segment is created using the default values: a FiguredBassScale in C,
a bassNote of C3, an empty notationString, and a default
Rules object.

>>> from music21.figuredBass import segment
>>> s1 = segment.Segment()
>>> s1.bassNote
<music21.note.Note C>
>>> s1.numParts
4
>>> s1.pitchNamesInChord
['C', 'E', 'G']
>>> [str(p) for p in s1.allPitchesAboveBass]
['C3', 'E3', 'G3', 'C4', 'E4', 'G4', 'C5', 'E5', 'G5']
>>> s1.segmentChord
<music21.chord.Chord C3 E3 G3 C4 E4 G4 C5 E5 G5>
Nr	   )quarterLength) 
isinstancestrr   Noter   Pitchr   r   FiguredBassScaler   Rulesr    copydeepcopy_specialResolutionRuleChecking_singlePossibilityRuleChecking#_consecutivePossibilityRuleCheckingr   r   	_maxPitchr   getPitchNames
getPitchesr   r   Chordr#   r   r   Environment_MOD_environRules)selfr   notationStringfbScaler    r   maxPitchlistOfPitchess           U/home/james-whalen/.local/lib/python3.13/site-packages/music21/figuredBass/segment.py__init__Segment.__init__C   sR   \ h$$yy*Hh$${{8,H?$W-51>1O1O1Q%g.+G4G"""? ;;=DL==1DL.2+.2+370  !!m&?%2" &-%:%:4==;N;NP^%_D"#-d.D.D.2mm.A.A.2nn$>  "KK(@(@6>6L6LN(44T:    c                    Uc  [         R                  " 5       nUR                  [        R                  SU R
                  /4S[        R                  SUR                  /4UR                  [        R                  S4/nU$ )a  
A framework for storing single possibility rules and methods to be applied
in :meth:`~music21.figuredBass.segment.Segment.allCorrectSinglePossibilities`.
Takes in a :class:`~music21.figuredBass.rules.Rules` object, fbRules.
If None then a new rules object is created.

Items are added within this method in the following form:

(willRunOnlyIfTrue, methodToRun, keepSolutionsWhichReturn, optionalArgs)

These items are compiled internally when
:meth:`~music21.figuredBass.segment.Segment.allCorrectSinglePossibilities`
is called on a Segment. Here, the compilation of rules and
methods bases on a default fbRules is shown.

>>> from music21.figuredBass import segment
>>> segmentA = segment.Segment()
>>> allSingleRules = segmentA.singlePossibilityRules()
>>> segment.printRules(allSingleRules)
Will run:  Method:                       Keep solutions which return:  Arguments:
True       isIncomplete                  False                         ['C', 'E', 'G']
True       upperPartsWithinLimit         True                          12
True       voiceCrossing                 False                         None

Here, a modified fbRules is provided, which allows for incomplete possibilities.

>>> from music21.figuredBass import rules
>>> fbRules = rules.Rules()
>>> fbRules.forbidIncompletePossibilities = False
>>> allSingleRules = segmentA.singlePossibilityRules(fbRules)
>>> segment.printRules(allSingleRules)
Will run:  Method:                       Keep solutions which return:  Arguments:
False      isIncomplete                  False                         ['C', 'E', 'G']
True       upperPartsWithinLimit         True                          12
True       voiceCrossing                 False                         None
FT)
r   r)   forbidIncompletePossibilitiesr
   isIncompleter   upperPartsWithinLimitupperPartsMaxSemitoneSeparationforbidVoiceCrossingvoiceCrossing)r6   r    singlePossibRuless      r;   r   Segment.singlePossibilityRules   s    L ?kkmG 22))(()+ 2299:< ((**
 ! r>   c                   Uc  [         R                  " 5       nU R                  R                  5       nS[        R
                  SUR                  /4UR                  [        R                  S4UR                  [        R                  S4S[        R                  SUR                  /4UR                  [        R                  S4UR                  [        R                   S4UR"                  [        R$                  S4UR&                  [        R(                  S4UR*                  =(       a    U[        R,                  S[/        U R                  5      UR0                  /4/	nU$ )a  
A framework for storing consecutive possibility rules and methods to be applied
in :meth:`~music21.figuredBass.segment.Segment.allCorrectConsecutivePossibilities`.
Takes in a :class:`~music21.figuredBass.rules.Rules` object, fbRules; if None
then a new rules.Rules() object is created.

Items are added within this method in the following form:

    (willRunOnlyIfTrue, methodToRun, keepSolutionsWhichReturn, optionalArgs)

These items are compiled internally when
:meth:`~music21.figuredBass.segment.Segment.allCorrectConsecutivePossibilities`
is called on a Segment. Here, the compilation of rules and methods
bases on a default fbRules is shown.

>>> from music21.figuredBass import segment
>>> segmentA = segment.Segment()
>>> allConsecutiveRules = segmentA.consecutivePossibilityRules()

>>> segment.printRules(allConsecutiveRules)
Will run:  Method:                       Keep solutions which return:  Arguments:
True       partsSame                     True                          []
False      upperPartsSame                True                          None
True       voiceOverlap                  False                         None
True       partMovementsWithinLimits     True                          []
True       parallelFifths                False                         None
True       parallelOctaves               False                         None
True       hiddenFifth                   False                         None
True       hiddenOctave                  False                         None
False      couldBeItalianA6Resolution    True           [<music21.pitch.Pitch C3>,
                                                         <music21.pitch.Pitch C3>,
                                                         <music21.pitch.Pitch E3>,
                                                         <music21.pitch.Pitch G3>], True

Now, a modified fbRules is provided, allowing hidden octaves and
voice overlap, and limiting the soprano line to stepwise motion.

>>> from music21.figuredBass import rules
>>> fbRules = rules.Rules()
>>> fbRules.forbidVoiceOverlap = False
>>> fbRules.forbidHiddenOctaves = False
>>> fbRules.partMovementLimits.append((1, 2))
>>> allConsecutiveRules = segmentA.consecutivePossibilityRules(fbRules)
>>> segment.printRules(allConsecutiveRules)
Will run:  Method:                       Keep solutions which return:  Arguments:
True       partsSame                     True                          []
False      upperPartsSame                True                          None
False      voiceOverlap                  False                         None
True       partMovementsWithinLimits     True                          [(1, 2)]
True       parallelFifths                False                         None
True       parallelOctaves               False                         None
True       hiddenFifth                   False                         None
False      hiddenOctave                  False                         None
False      couldBeItalianA6Resolution    True           [<music21.pitch.Pitch C3>,
                                                         <music21.pitch.Pitch C3>,
                                                         <music21.pitch.Pitch E3>,
                                                         <music21.pitch.Pitch G3>], True
TF)r   r)   r   isItalianAugmentedSixthr
   	partsSame_partsToCheck_upperPartsRemainSameupperPartsSameforbidVoiceOverlapvoiceOverlappartMovementsWithinLimitspartMovementLimitsforbidParallelFifthsparallelFifthsforbidParallelOctavesparallelOctavesforbidHiddenFifthshiddenFifthforbidHiddenOctaveshiddenOctaveresolveAugmentedSixthProperlycouldBeItalianA6Resolution_unpackTriad&restrictDoublingsInItalianA6Resolution)r6   r    rI   consecutivePossibRuless       r;   r   #Segment.consecutivePossibilityRules   s0   x ?kkmG"&"3"3"K"K"M ;(($1F1F0GH**K,F,FM'')A)A5I;88$A[A[@\]));+E+EuM**K,G,GO'')@)@%H((+*B*BEJ22N7N66d//0'2`2`ac"
 &%r>   c                   Uc  [         R                  " 5       nU R                  R                  5       nU R                  R	                  5       nU R                  R                  5       nUR                  =(       a    UU R                  4UR                  =(       a    UU R                  UR                  /4UR                  =(       a    UU R                  4/nU$ )a	  
A framework for storing methods which perform special resolutions
on Segments. Unlike the methods in
:meth:`~music21.figuredBass.segment.Segment.singlePossibilityRules` and
:meth:`~music21.figuredBass.segment.Segment.consecutivePossibilityRules`,
these methods deal with the Segment itself, and rely on submethods
to resolve the individual possibilities accordingly depending on what
the resolution Segment is.

If fbRules is None, then a new rules.Rules() object is created.

Items are added within this method in the following form:


(willRunOnlyIfTrue, methodToRun, optionalArgs)


These items are compiled internally
when :meth:`~music21.figuredBass.segment.Segment.allCorrectConsecutivePossibilities`
is called on a Segment. Here, the compilation of rules and methods
based on a default fbRules is shown.

>>> from music21.figuredBass import segment
>>> segmentA = segment.Segment()
>>> allSpecialResRules = segmentA.specialResolutionRules()
>>> segment.printRules(allSpecialResRules, maxLength=3)
Will run:  Method:                          Arguments:
False      resolveDominantSeventhSegment    None
False      resolveDiminishedSeventhSegment  False
False      resolveAugmentedSixthSegment     None

Dominant Seventh Segment:

>>> segmentA = segment.Segment(bassNote=note.Note('B2'), notationString='6,5')
>>> allSpecialResRules = segmentA.specialResolutionRules()
>>> segment.printRules(allSpecialResRules, maxLength=3)
Will run:  Method:                          Arguments:
True       resolveDominantSeventhSegment    None
False      resolveDiminishedSeventhSegment  False
False      resolveAugmentedSixthSegment     None

Fully-Diminished Seventh Segment:

>>> segmentA = segment.Segment(bassNote=note.Note('B2'), notationString='-7')
>>> allSpecialResRules = segmentA.specialResolutionRules()
>>> segment.printRules(allSpecialResRules, maxLength=3)
Will run:  Method:                          Arguments:
False      resolveDominantSeventhSegment    None
True       resolveDiminishedSeventhSegment  False
False      resolveAugmentedSixthSegment     None

Augmented Sixth Segment:

>>> segmentA = segment.Segment(bassNote=note.Note('A-2'), notationString='#6,b5')
>>> allSpecialResRules = segmentA.specialResolutionRules()
>>> segment.printRules(allSpecialResRules, maxLength=3)
Will run:  Method:                          Arguments:
False      resolveDominantSeventhSegment    None
False      resolveDiminishedSeventhSegment  False
True       resolveAugmentedSixthSegment     None
)r   r)   r   isDominantSeventhisDiminishedSeventhisAugmentedSixthresolveDominantSeventhProperlyr    resolveDiminishedSeventhProperlyr   doubledRootInDim7rZ   r   )r6   r    ra   rb   rc   specialResRuless         r;   r   Segment.specialResolutionRules$  s    | ?kkmG --??A"//CCE,,==? 33I8I//155M:M44**+- 22G7G113
 r>   c                z   U R                   nUR                  5       (       d  [        S5      e[        U5      n[        R
                  " 5       R                  U5      nUR                  5       nUR                  5       nUR                  S5      nUR                  S5      nUR                  S5      n	UR                   n
UR                  5       S:H  nU
R                  5       nU=(       a    US:H  nUR                  5       S:X  ac  U
R                  5       R                  UR                  :X  a;  U
R                  5       (       d  U
R                  5       (       a  SUR                  l        U
R                  5       R                  UR                  :H  =(       a    U
R                  5       ["        R$                  X/4U
R                  5       R                  UR                  :H  =(       a    U
R                  5       ["        R&                  X/4U
R                  5       R                  UR                  :H  =(       a    U
R                  5       =(       a    US:H  ["        R(                  U/4U
R                  5       R                  U	R                  :H  =(       a    U
R                  5       =(       a    US:H  ["        R*                  U/4U
R                  5       R                  UR                  :H  =(       a    U
R                  5       =(       a    US:H  ["        R,                  U/4U
R                  5       R                  UR                  :H  =(       a    U
R                  5       =(       a    US:H  ["        R.                  U/4/n U R1                  X5      $ ! [         a/    U R2                  R5                  S5        U R7                  U5      s $ f = f)	aX  
Can resolve a Segment whose :attr:`~music21.figuredBass.segment.Segment.segmentChord`
spells out a dominant seventh chord. If no applicable method in
:mod:`~music21.figuredBass.resolution` can be used, the Segment is resolved
as an ordinary Segment.

>>> from music21.figuredBass import segment
>>> segmentA = segment.Segment(bassNote=note.Note('G2'), notationString='7')
>>> allDomPossib = segmentA.allCorrectSinglePossibilities()
>>> allDomPossibList = list(allDomPossib)
>>> len(allDomPossibList)
8
>>> allDomPossibList[2]
(<music21.pitch.Pitch D4>, <music21.pitch.Pitch B3>,
 <music21.pitch.Pitch F3>, <music21.pitch.Pitch G2>)
>>> allDomPossibList[5]
(<music21.pitch.Pitch D5>, <music21.pitch.Pitch B4>,
 <music21.pitch.Pitch F4>, <music21.pitch.Pitch G2>)

Here, the Soprano pitch of resolution (C6) exceeds default maxPitch of B5, so
it's filtered out.

>>> [p.nameWithOctave for p in allDomPossibList[7]]
['B5', 'F5', 'D5', 'G2']

>>> segmentB = segment.Segment(bassNote=note.Note('C3'), notationString='')
>>> domResPairs = segmentA.resolveDominantSeventhSegment(segmentB)
>>> domResPairsList = list(domResPairs)
>>> len(domResPairsList)
7
>>> domResPairsList[2]
((<music21.pitch.Pitch D4>, <...B3>, <...F3>, <...G2>),
 (<...C4>, <...C4>, <...E3>, <...C3>))
>>> domResPairsList[5]
((<...D5>, <...B4>, <...F4>, <...G2>), (<...C5>, <...C5>, <...E4>, <...C3>))
z<Dominant seventh resolution: Not a dominant seventh Segment.            r   Fz[Dominant seventh resolution: No proper resolution available. Executing ordinary resolution.)r   ra   SegmentException_unpackSeventhChordr	   
MajorScalederivegetParallelMinorgetTonicpitchFromDegree	inversionrootnameisMajorTriadisMinorTriadr    r@   r   dominantSeventhToMajorTonicdominantSeventhToMinorTonic dominantSeventhToMinorSubmediant dominantSeventhToMajorSubmediant!dominantSeventhToMajorSubdominant!dominantSeventhToMinorSubdominant_resolveSpecialSegmentr5   warn_resolveOrdinarySegment)r6   segmentBdomChorddomChordInfodominantScale
minorScaletonicsubdominantmajSubmediantminSubmediantresChorddomInversionresInversionresolveV43toI6dominantResolutionMethodss                  r;   r   %Segment.resolveDominantSeventhSegmentu  s.   L $$))++"#abb*84((*11(;"335
&&(#33A6%55a8"2215(( **,1 **,%;,!*; A%MMO((EJJ6**,,0E0E0G0G=BH: ]]_!!UZZ/KH4I4I4K33+- ]]_!!UZZ/KH4I4I4K66.0 mmo""m&8&88 $'')$!#;;	 
 mmo""m&8&88 &))+& A%;;	 
 mmo""k&6&66 &))+& A%<<	 
 mmo""k&6&66 &))+& A%<<	 -%
!:	:..xSS 	:##34 //99		:s   0N 6N:9N:c                   U R                   nUR                  5       (       d  [        S5      e[        U5      n[        R
                  " 5       R                  SUR                  5       5      nUR                  5       nUR                  S5      nUR                   nUR                  5       S:X  a-  UR                  5       S:X  a  SnOUR                  5       S:X  a  SnUR                  5       R                  UR                  :H  =(       a    UR                  5       [        R                  X$/4UR                  5       R                  UR                  :H  =(       a    UR                  5       [        R                   X$/4UR                  5       R                  UR                  :H  =(       a    UR                  5       [        R"                  U/4UR                  5       R                  UR                  :H  =(       a    UR                  5       [        R$                  U/4/n	 U R'                  X5      $ ! [         a/    U R(                  R+                  S5        U R-                  U5      s $ f = f)	a5  
Can resolve a Segment whose :attr:`~music21.figuredBass.segment.Segment.segmentChord`
spells out a diminished seventh chord. If no applicable method in
:mod:`~music21.figuredBass.resolution` can be used, the Segment is resolved
as an ordinary Segment.

>>> from music21.figuredBass import segment
>>> segmentA = segment.Segment(bassNote=note.Note('B2'), notationString='b7')
>>> allDimPossib = segmentA.allCorrectSinglePossibilities()
>>> allDimPossibList = list(allDimPossib)
>>> len(allDimPossibList)
7
>>> [p.nameWithOctave for p in allDimPossibList[4]]
['D5', 'A-4', 'F4', 'B2']
>>> [p.nameWithOctave for p in allDimPossibList[6]]
['A-5', 'F5', 'D5', 'B2']

>>> segmentB = segment.Segment(bassNote=note.Note('C3'), notationString='')
>>> dimResPairs = segmentA.resolveDiminishedSeventhSegment(segmentB)
>>> dimResPairsList = list(dimResPairs)
>>> len(dimResPairsList)
7
>>> dimResPairsList[4]
((<...D5>, <...A-4>, <...F4>, <...B2>), (<...E5>, <...G4>, <...E4>, <...C3>))
>>> dimResPairsList[6]
((<...A-5>, <...F5>, <...D5>, <...B2>), (<...G5>, <...E5>, <...E5>, <...C3>))
z@Diminished seventh resolution: Not a diminished seventh Segment.   rj   rm   r   TFz]Diminished seventh resolution: No proper resolution available. Executing ordinary resolution.)r   rb   rn   ro   r	   HarmonicMinorScalederiveByDegreerv   rs   rt   ru   rw   rx   r   diminishedSeventhToMajorTonicry   diminishedSeventhToMinorTonic#diminishedSeventhToMajorSubdominant#diminishedSeventhToMinorSubdominantr   r5   r   r   )
r6   r   doubledRootdimChorddimChordInfodimScaler   r   r   diminishedResolutionMethodss
             r;   r   'Segment.resolveDiminishedSeventhSegment  s   : $$++--"RT T*84++-<<QP !!#..q1((1$!!#q("##%*# ]]_!!UZZ/KH4I4I4K55(* ]]_!!UZZ/KH4I4I4K88+- ]]_!![%5%55Q(:O:O:Q>>  ]]_!![%5%55Q(:O:O:Q>> '
#	:..xUU 	:##34 //99		:s   H) )6I"!I"c                2   U R                   nUR                  5       (       d  [        S5      eUR                  5       (       a  U R	                  U5      $ UR                  5       (       a  SnO\UR                  5       (       a  SnODUR                  5       (       a  SnO,U R                  R                  S5        U R	                  U5      $ [        R                  " UR                  5       S5      n[        R                  " U5      nUR                   n[        U5      nUR!                  5       S:H  =(       a>    UR#                  5       R$                  UR$                  :H  =(       a    UR'                  5       [        R(                  X7/4UR!                  5       S:H  =(       a>    UR#                  5       R$                  UR$                  :H  =(       a    UR+                  5       [        R,                  X7/4UR/                  S5      R$                  UR                  5       R$                  :H  =(       a    UR'                  5       [        R0                  X7/4/n U R3                  X5      $ ! [         a/    U R                  R                  S5        U R	                  U5      s $ f = f)	a  
Can resolve a Segment whose :attr:`~music21.figuredBass.segment.Segment.segmentChord`
spells out a
French, German, or Swiss augmented sixth chord. Italian augmented sixth Segments
are solved as an
ordinary Segment using :meth:`~music21.figuredBass.possibility.couldBeItalianA6Resolution`.
If no
applicable method in :mod:`~music21.figuredBass.resolution` can be used, the Segment
is resolved
as an ordinary Segment.


>>> from music21.figuredBass import segment
>>> segmentA = segment.Segment(bassNote=note.Note('A-2'), notationString='#6,b5,3')
>>> segmentA.pitchNamesInChord  # spell out a Gr+6 chord
['A-', 'C', 'E-', 'F#']
>>> allAugSixthPossib = segmentA.allCorrectSinglePossibilities()
>>> allAugSixthPossibList = list(allAugSixthPossib)
>>> len(allAugSixthPossibList)
7

>>> allAugSixthPossibList[1]
(<music21.pitch.Pitch C4>, <music21.pitch.Pitch F#3>, <...E-3>, <...A-2>)
>>> allAugSixthPossibList[4]
(<music21.pitch.Pitch C5>, <music21.pitch.Pitch F#4>, <...E-4>, <...A-2>)

>>> segmentB = segment.Segment(bassNote=note.Note('G2'), notationString='')
>>> allAugResPossibPairs = segmentA.resolveAugmentedSixthSegment(segmentB)
>>> allAugResPossibPairsList = list(allAugResPossibPairs)
>>> len(allAugResPossibPairsList)
7
>>> allAugResPossibPairsList[1]
((<...C4>, <...F#3>, <...E-3>, <...A-2>), (<...B3>, <...G3>, <...D3>, <...G2>))
>>> allAugResPossibPairsList[4]
((<...C5>, <...F#4>, <...E-4>, <...A-2>), (<...B4>, <...G4>, <...D4>, <...G2>))
z;Augmented sixth resolution: Not an augmented sixth Segment.rm   rl      z^Augmented sixth resolution: Augmented sixth type not supported. Executing ordinary resolution.M3   zZAugmented sixth resolution: No proper resolution available. Executing ordinary resolution.)r   rc   rn   rI   r   isFrenchAugmentedSixthisGermanAugmentedSixthisSwissAugmentedSixthr5   r   r   
_transposebassr	   rp   ro   ru   rv   rw   rx   augmentedSixthToMajorTonicry   augmentedSixthToMinorTonicrt   augmentedSixthToDominantr   )	r6   r   augSixthChordaugSixthTyper   
majorScaler   augSixthChordInfoaugmentedSixthResolutionMethodss	            r;   r   $Segment.resolveAugmentedSixthSegment  sE   L ))--//"#`aa0022//991133L1133L0022L##WX //99%%m&8&8&:DA%%e,
((/>   "a' ,MMO((EJJ6,))+22\4UW   "a' ,MMO((EJJ6,))+551	3
 ((+00HMMO4H4HH ,))+3313+
' 	:..xYY 	:##34 //99		:s   I 6JJc                    U R                   /U R                  S-
  -  nUR                  [        R                  " U R
                  R                  R                  5      /5        [        R                  " U6 $ )a8  
Returns an iterator through a set of naive possibilities for
a Segment, using :attr:`~music21.figuredBass.segment.Segment.numParts`,
the pitch of :attr:`~music21.figuredBass.segment.Segment.bassNote`, and
:attr:`~music21.figuredBass.segment.Segment.allPitchesAboveBass`.

>>> from music21.figuredBass import segment
>>> segmentA = segment.Segment()
>>> allPossib = segmentA.allSinglePossibilities()
>>> allPossib.__class__
<... 'itertools.product'>


The number of naive possibilities is always the length of
:attr:`~music21.figuredBass.segment.Segment.allPitchesAboveBass`
raised to the (:attr:`~music21.figuredBass.segment.Segment.numParts` - 1)
power. The power is 1 less than the number of parts because
the bass pitch is constant.


>>> allPossibList = list(allPossib)
>>> len(segmentA.allPitchesAboveBass)
9
>>> segmentA.numParts
4
>>> len(segmentA.allPitchesAboveBass) ** (segmentA.numParts-1)
729
>>> len(allPossibList)
729

>>> for i in (81, 275, 426):
...    [str(p) for p in allPossibList[i]]
['E3', 'C3', 'C3', 'C3']
['C4', 'C4', 'G4', 'C3']
['G4', 'G3', 'C4', 'C3']
rm   )	r   r   appendr   r'   r   nameWithOctave	itertoolsproduct)r6   	iterabless     r;   r   Segment.allSinglePossibilitiesu  s\    J --.$--!2CD	%++dmm&9&9&H&HIJK  ),,r>   c                    [        U R                  U R                  5      5      U l        U R	                  5       nU Vs/ s H  o R                  U5      (       d  M  UPM     sn$ s  snf )aZ  
Uses :meth:`~music21.figuredBass.segment.Segment.allSinglePossibilities` and
returns an iterator through a set of correct possibilities for
a Segment, all possibilities which pass all filters in
:meth:`~music21.figuredBass.segment.Segment.singlePossibilityRules`.


>>> from music21.figuredBass import segment
>>> segmentA = segment.Segment()
>>> allPossib = segmentA.allSinglePossibilities()
>>> allCorrectPossib = segmentA.allCorrectSinglePossibilities()


Most of the 729 naive possibilities were filtered out using the default rules set,
leaving only 21.


>>> allPossibList = list(allPossib)
>>> len(allPossibList)
729
>>> allCorrectPossibList = list(allCorrectPossib)
>>> len(allCorrectPossibList)
21

>>> for i in (5, 12, 20):
...   [str(p) for p in allCorrectPossibList[i]]
['E4', 'G3', 'G3', 'C3']
['C5', 'G4', 'E4', 'C3']
['G5', 'G5', 'E5', 'C3']
)_compileRulesr   r    r-   r   _isCorrectSinglePossibility)r6   allApossibAs      r;   r   %Segment.allCorrectSinglePossibilities  sU    > /<''5/7+**,'+YtG/O/OPW/XtYYYs   A$A$c                N   U R                   UR                   :X  d  [        S5      eU R                  UR                  :X  d  [        S5      e[        U R	                  U R
                  5      S5      U l        U R                  S    H  u  p#U" U/UQ76 s  $    U R                  U5      $ )a	  
Returns an iterator through correct (possibA, possibB) pairs.

* If segmentA (self) is a special Segment, meaning that one of the Segment
  resolution methods in :meth:`~music21.figuredBass.segment.Segment.specialResolutionRules`
  needs to be applied, then this method returns every correct possibility of segmentA
  matched up with exactly one resolution possibility.

* If segmentA is an ordinary, non-special Segment, then this method returns every
  combination of correct possibilities of segmentA and correct possibilities of segmentB
  which passes all filters
  in :meth:`~music21.figuredBass.segment.Segment.consecutivePossibilityRules`.

Two notes on segmentA being a special Segment:

1. By default, resolution possibilities are not filtered
   using :meth:`~music21.figuredBass.segment.Segment.singlePossibilityRules`
   rules of segmentB. Filter by setting
   :attr:`~music21.figuredBass.rules.Rules.applySinglePossibRulesToResolution` to True.

2. By default, (possibA, possibB) pairs are not filtered
   using :meth:`~music21.figuredBass.segment.Segment.consecutivePossibilityRules`
   rules of segmentA. Filter by setting
   :attr:`~music21.figuredBass.rules.Rules.applyConsecutivePossibRulesToResolution`
   to True.

>>> from music21.figuredBass import segment
>>> segmentA = segment.Segment(bassNote=note.Note('C3'), notationString='')
>>> segmentB = segment.Segment(bassNote=note.Note('D3'), notationString='4,3')

Here, an ordinary resolution is being executed, because segmentA is an ordinary Segment.

>>> consecutivePairs1 = segmentA.allCorrectConsecutivePossibilities(segmentB)
>>> consecutivePairsList1 = list(consecutivePairs1)
>>> len(consecutivePairsList1)
31
>>> consecutivePairsList1[29]
((<...G5>, <...G5>, <...E5>, <...C3>), (<...G5>, <...F5>, <...B4>, <...D3>))

Here, a special resolution is being executed, because segmentA below is a
special Segment.

>>> segmentA = segment.Segment(bassNote=note.Note('D3'), notationString='4,3')
>>> segmentB = segment.Segment(bassNote=note.Note('C3'), notationString='')
>>> consecutivePairs2 = segmentA.allCorrectConsecutivePossibilities(segmentB)
>>> consecutivePairsList2 = list(consecutivePairs2)
>>> len(consecutivePairsList2)
6
>>> consecutivePairsList2[5]
((<...G5>, <...F5>, <...B4>, <...D3>), (<...G5>, <...E5>, <...C5>, <...C3>))
z6Two segments with unequal numParts cannot be compared.z6Two segments with unequal maxPitch cannot be compared.r   T)r   rn   r/   r   r   r    r,   r   )r6   r   resolutionMethodargss       r;   r   *Segment.allCorrectConsecutivePossibilities  s    j !2!22"#[\\("4"44"#[\\.;''5/
+ )-(K(KD(Q$#H4t44 )R++H55r>   c                T    U R                   S    H  u  p#nU" U/UQ76 U:X  a  M    g   g)z
Takes in a possibility (possibA) from a segmentA (self) and returns True
if the possibility is correct given
:meth:`~music21.figuredBass.segment.Segment.singlePossibilityRules`
from segmentA.
TF)r-   )r6   r   method	isCorrectr   s        r;   r   #Segment._isCorrectSinglePossibility  s9     *.)L)LT)R%V7*T*i7 *S r>   c                T    U R                   S    H  u  p4nU" X/UQ76 U:X  a  M    g   g)z
Takes in a (possibA, possibB) pair from a segmentA (self) and segmentB,
and returns True if the pair is correct given
:meth:`~music21.figuredBass.segment.Segment.consecutivePossibilityRules`
from segmentA.
TF)r.   )r6   r   possibBr   r   r   s         r;    _isCorrectConsecutivePossibility(Segment._isCorrectConsecutivePossibility  s:     *.)Q)QRV)W%V73d3y@ *X r>   c                   ^  [        T R                  T R                  5      5      T l        T R	                  5       nUR	                  5       n[
        R                  " X#5      n[        U 4S jU5      $ )a&  
An ordinary segment is defined as a segment which needs no special resolution, where the
segment does not spell out a special chord, for example, a dominant seventh.


Finds iterators through all possibA and possibB by calling
:meth:`~music21.figuredBass.segment.Segment.allCorrectSinglePossibilities`
on self (segmentA) and segmentB, respectively.
Returns an iterator through (possibA, possibB) pairs for which
:meth:`~music21.figuredBass.segment.Segment._isCorrectConsecutivePossibility` returns True.

>>> from music21.figuredBass import segment
c                0   > TR                  U S   U S   S9$ Nr   rm   )r   r   r   possibABr6   s    r;   <lambda>1Segment._resolveOrdinarySegment.<locals>.<lambda>1  s)    t'L'LU]^_U`V^_`Va (M (cr>   )r   r   r    r.   r   r   r   filter)r6   r   correctAcorrectB	correctABs   `    r;   r   Segment._resolveOrdinarySegment  sg     4A,,T\\:4<055799;%%h9	 c " 	"r>   c                <  ^ ^ [        US5      nUS    H  u  pE/ nU H(  nUR                  [        R                  " U5      5        M*     [	        UT R                  5       /UQ76 n[        T R                  5       U5      n	[        U4S jU	5      n	T R                  R                  (       a  [        U 4S jU	5      n	T R                  R                  (       a9  [        TR                  TR                  5      5      Tl        [        U4S jU	5      n	U	s  $    [        S5      e)Nr   Tc                H   > [         R                  " U S   TR                  S9$ )Nrm   )r   r9   )r
   pitchesWithinLimitr/   r   r   s    r;   r   0Segment._resolveSpecialSegment.<locals>.<lambda>=  s     0N0N !++1-r>   c                0   > TR                  U S   U S   S9$ r   r   r   s    r;   r   r   B  s$    D4Y4Y$QK$QK 5Z 5)r>   c                (   > TR                  U S   S9$ )Nrm   )r   )r   r   s    r;   r   r   I  s    H4X4X$QK 5Y 5)r>   z!No standard resolution available.)r   r   r   repeatmapr   zipr   r    'applyConsecutivePossibRulesToResolution"applySinglePossibRulesToResolutionr   r-   rn   )
r6   r   specialResolutionMethodsresolutionMethodExecutorr   r   r   argresolutionsr   s
   ``        r;   r   Segment._resolveSpecialSegment5  s   #01I1#M (@(F$I  !1!1#!67 .0R0R0TaW`aKD>>@+NI  - I ||CC" $) 	 ||>>:G33H4D4DE;G7" $)	 + )G. BCCr>   )r.   r5   r/   r-   r,   r   r   r    r   r   r   )C3NNNrj   B5N)
r   zstr | note.Noter7   z
str | Noner8   z%realizerScale.FiguredBassScale | Noner    zrules.Rules | Noner9   str | pitch.PitchN)F)__name__
__module____qualname____firstlineno__
_DOC_ORDERr!   __annotations__r<   r   r   r   r   r   r   r   r   r   r   r   r   r   __static_attributes__ r>   r;   r   r   $   s    2J4%a ]@a%!I~ , ,0,0@D-1-1#Q;(Q;!)Q; >Q; +	Q; +Q;l7!rP&dOba:FE:NT:l'-R"ZH?6H

".Dr>   r   c                      \ rS rSrSrS rSrg)OverlaidSegmentiQ  z>
Class to allow Segments to be overlaid with non-chord notes.
c                t   U R                   /U R                  S-
  -  nUR                  [        R                  " U R
                  R                  R                  5      /5        U R                  R                   H+  u  p#[        R                  " UR                  5      /XS-
  '   M-     [        R                  " U6 $ )Nrm   )r   r   r   r   r'   r   r   r    _partPitchLimitsr   r   )r6   r   
partNumber	partPitchs       r;   r   &OverlaidSegment.allSinglePossibilitiesV  s    --.$--!2CD	%++dmm&9&9&H&HIJK'+||'D'D#Z).Y5M5M)N(OI1n% (E  ),,r>   r   N)r   r   r   r   __doc__r   r   r   r>   r;   r   r   Q  s    -r>   r   c                  ^^ [        T[        5      (       a  [        R                  " T5      m[        T[        5      (       a  [        R                  " T5      mTR                  c  [        S5      e[        R                  " U [        TR                  S-   5      5      n[        S U5      n[        R                  " U4S jU5      n[        R                  " U4S jU5      n[        U5      nUR                  5         U$ )a  
Given a list of pitchNames, a bassPitch, and a maxPitch, returns a sorted list of
pitches between the two limits (inclusive) which correspond to items in pitchNames.

>>> from music21.figuredBass import segment
>>> pitches = segment.getPitches()
>>> print(', '.join([p.nameWithOctave for p in pitches]))
C3, E3, G3, C4, E4, G4, C5, E5, G5, C6, E6, G6, C7, E7, G7, C8

>>> pitches = segment.getPitches(['G', 'B', 'D', 'F'], bassPitch=pitch.Pitch('B2'))
>>> print(', '.join([p.nameWithOctave for p in pitches]))
B2, D3, F3, G3, B3, D4, F4, G4, B4, D5, F5, G5, B5, D6, F6, G6, B6, D7, F7, G7, B7

>>> pitches = segment.getPitches(['F##', 'A#', 'C#'], bassPitch=pitch.Pitch('A#3'))
>>> print(', '.join([p.nameWithOctave for p in pitches]))
A#3, C#4, F##4, A#4, C#5, F##5, A#5, C#6, F##6, A#6, C#7, F##7, A#7

The maxPitch must have an octave:

>>> segment.getPitches(maxPitch=pitch.Pitch('E'))
Traceback (most recent call last):
ValueError: maxPitch must be given an octave
z maxPitch must be given an octaverm   c                R    [         R                  " U S   [        U S   5      -   5      $ )Nr   rm   )r   r'   r%   )xs    r;   r   getPitches.<locals>.<lambda>  s    %++adS1Y&67r>   c                   > TU :  $ r   r   )samplePitch	bassPitchs    r;   r   r     s
    i+6Mr>   c                   > U T:  $ r   r   )r  r9   s    r;   r   r     s
    kH6Lr>   )r$   r%   r   r'   octave
ValueErrorr   r   ranger   filterfalselistsort)
pitchNamesr  r9   iter1iter2iter3iter4
allPitchess    ``     r;   r1   r1   `  s    4 )S!!KK	*	(C  ;;x(;<<j%!0C*DEE7?E!!"MuUE!!"LeTEeJOOr>   c                    U R                  5       nU R                  5       nU R                  S5      nU R                  S5      nU R                  S5      nXX4U/nU$ )Nr   r   r   r   rv   getChordStep)seventhChordr   rv   thirdfifthseventhseventhChordInfos          r;   ro   ro     sa    DD%%a(E%%a(E''*GE':r>   c                    U R                  5       nU R                  5       nU R                  S5      nU R                  S5      nXX4/nU$ )Nr   r   r  )threePartChordr   rv   r  r  threePartChordInfos         r;   r\   r\     sO     D D''*E''*Ee3r>   c                <   [         R                  " [        5      n[        [	        U 5      5       Hi  n/ n[	        X   5      U:X  a  X   S   nUS:X  a!  X   SS u  pVnX%   R                  XgU45        MD  US:X  d  ML  X   SS u  pVX%   R                  Xd45        Mk     U$ )Nrj   r   r   rl   )collectionsdefaultdictr	  r  lenr   )	rulesList	maxLengthruleChecking	ruleIndexr   shouldRunMethodr   r   s           r;   r   r     s    **40L3y>*	y#$	1'+D>3<3G!3L0_i)00&T1JK!^(1(<Qq(A%_)00&@ + r>   c                  ^ SmU  H<  n[        US   R                  5      T:  d  M!  [        US   R                  5      S-   mM>     U4S jnSSTS-
  -  -   nUS:X  a  [        S	U S
35        OUS:X  a  [        S	U S35        [        [        U 5      5       H  nSn/ n[        X   5      U:X  a  X   S   nU(       d  SnOFSn[        [        U5      5       H,  n	U[	        Xy   5      -  nU	[        U5      S-
  :X  a  M'  US-  nM.     US:X  a1  X   SS u  pnU" U5      n[	        U
5      S U [	        U5      S U 3nO)US:X  a#  X   SS u  pU" U5      n[	        U
5      S U U 3n[        U5        M     g)a  
Method which can print to the console rules inputted into
:meth:`~music21.figuredBass.segment.Segment.singlePossibilityRules`,
:meth:`~music21.figuredBass.segment.Segment.consecutivePossibilityRules`, and
:meth:`~music21.figuredBass.segment.Segment.specialResolutionRules`.
For the first two methods, maxLength is 4. For the third method, maxLength is 3.

OMIT_FROM_DOCS
maxLength is the maximum length of a rule, a rule which includes arguments,
because arguments are optional.
   rm   rl   c                l   > U R                   ST n[        U5      T:  a  UST[        U5      -
  -  -  nU$ )Nr    )r   r   )m
methodNameMAX_SIZEs     r;   	padMethodprintRules.<locals>.padMethod  s=    ZZ(+
z?X%#C
O!;<<Jr>   zMethod:r)  r   rj   zWill run:  z(Keep solutions which return:  Arguments:r   z
Arguments:Nr  None z, r   1130)r   r   printr  r%   )r!  r"  ruler-  	methodStrr$  ruleToPrintr   
argsString	itemIndexr%  r   r   r,  s                @r;   
printRulesr9    s    HtAw H,47++,q0H  C8a<00IA~I;&NOP	aI;j123y>*	y#$	1'+DJJ"3t9-	c$/22
 CIM1$&J . >3<3G!3L0_iv&F 1"5fXc)nR=PQ[P\]K!^(1(<Qq(A%_v&F 1"5fXj\JKk+ +r>   c                      \ rS rSrSrg)rn   i  r   Nr   r   r   r   r   r   r>   r;   rn   rn         r>   rn   c                      \ rS rSrSrg)Testi  r   Nr;  r   r>   r;   r>  r>    r<  r>   r>  __main__))CEGr   C8)r  r   r9   r   )rj   )"
__future__r   r  r*   r   unittestmusic21r   r   r   r   r   r	   music21.figuredBassr
   r   r   r   r4   r   r   r   r   r1   ro   r\   r   r9  Music21Exceptionrn   TestCaser>  r   mainTestr   r>   r;   <module>rK     s    #            + - * %  TI E 
jD jDZ
-g 
- *,0+/')'('T 2j	|44 		8 	 zT r>   