-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Haskell Music Theory
--   
--   Haskell music theory library
@package hmt
@version 0.15


-- | Robert Morris and D. Starr. "The Structure of All-Interval Series".
--   <i>Journal of Music Theory</i>, 18:364-389, 1974.
module Music.Theory.Z12.Morris_1974

-- | <a>msum</a> <a>.</a> <a>map</a> <a>return</a>.
--   
--   <pre>
--   observeAll (fromList [1..7]) == [1..7]
--   </pre>
fromList :: MonadPlus m => [a] -> m a

-- | <a>MonadPlus</a> all-interval series.
--   
--   <pre>
--   [0,1,3,2,9,5,10,4,7,11,8,6] `elem` observeAll (all_interval_m 12)
--   length (observeAll (all_interval_m 12)) == 3856
--   map (length . observeAll . all_interval_m) [4,6,8,10] == [2,4,24,288]
--   </pre>
all_interval_m :: MonadPlus m => Int -> m [Int]

-- | <a>observeAll</a> of <a>all_interval_m</a>.
--   
--   <pre>
--   let r = [[0,1,5,2,4,3],[0,2,1,4,5,3],[0,4,5,2,1,3],[0,5,1,4,2,3]]
--   in all_interval 6 == r
--   </pre>
all_interval :: Int -> [[Int]]


-- | Z12 set class database.
module Music.Theory.Z12.Literature

-- | Set class database with descriptors for historically and theoretically
--   significant set classes, indexed by Forte name.
--   
--   <pre>
--   lookup "6-Z17" sc_db == Just "All-Trichord Hexachord"
--   lookup "7-35" sc_db == Just "diatonic collection (d)"
--   </pre>
sc_db :: [(String, String)]

module Music.Theory.Z12

-- | Z12 are modulo 12 integers.
--   
--   <pre>
--   map signum [-1,0::Z12,1] == [1,0,1]
--   map abs [-1,0::Z12,1] == [11,0,1]
--   </pre>
newtype Z12
Z12 :: Int -> Z12

-- | Cyclic <a>Enum</a> instance for Z12.
--   
--   <pre>
--   pred (0::Z12) == 11
--   succ (11::Z12) == 0
--   [9::Z12 .. 3] == [9,10,11,0,1,2,3]
--   [9::Z12,11 .. 3] == [9,11,1,3]
--   </pre>

-- | <a>Bounded</a> instance for Z12.
--   
--   <pre>
--   [minBound::Z12 .. maxBound] == [0::Z12 .. 11]
--   </pre>

-- | The Z12 modulo (ie. <tt>12</tt>) as a <a>Z12</a> value. This is
--   required when lifting generalised <tt>Z</tt> functions to <a>Z12</a>.
--   It is <i>not</i> the same as writing <tt>12::Z12</tt>.
--   
--   <pre>
--   z12_modulo == Z12 12
--   z12_modulo /= 12
--   (12::Z12) == 0
--   show z12_modulo == "(Z12 12)"
--   </pre>
z12_modulo :: Z12

-- | Basis for Z12 show instance.
--   
--   <pre>
--   map show [-1,0::Z12,1,z12_modulo] == ["11","0","1","(Z12 12)"]
--   </pre>
z12_showsPrec :: Int -> Z12 -> ShowS

-- | Lift unary function over integers to Z12.
--   
--   <pre>
--   lift_unary_Z12 (negate) 7 == 5
--   </pre>
lift_unary_Z12 :: (Int -> Int) -> Z12 -> Z12

-- | Lift unary function over integers to Z12.
--   
--   <pre>
--   map (lift_binary_Z12 (+) 4) [1,5,6] == [5,9,10]
--   </pre>
lift_binary_Z12 :: (Int -> Int -> Int) -> Z12 -> Z12 -> Z12

-- | Raise an error if the internal <a>Z12</a> value is negative.
check_negative :: (Int -> Int) -> Z12 -> Z12

-- | Convert integral to <a>Z12</a>.
--   
--   <pre>
--   map to_Z12 [-9,-3,0,13] == [3,9,0,1]
--   </pre>
to_Z12 :: Integral i => i -> Z12

-- | Convert <a>Z12</a> to integral.
from_Z12 :: Integral i => Z12 -> i

-- | Z12 not in set.
--   
--   <pre>
--   complement [0,2,4,5,7,9,11] == [1,3,6,8,10]
--   </pre>
complement :: [Z12] -> [Z12]
instance GHC.Real.Real Music.Theory.Z12.Z12
instance GHC.Real.Integral Music.Theory.Z12.Z12
instance GHC.Classes.Ord Music.Theory.Z12.Z12
instance GHC.Classes.Eq Music.Theory.Z12.Z12
instance GHC.Enum.Enum Music.Theory.Z12.Z12
instance GHC.Enum.Bounded Music.Theory.Z12.Z12
instance GHC.Show.Show Music.Theory.Z12.Z12
instance GHC.Num.Num Music.Theory.Z12.Z12


-- | Pitch-class set (unordered) operations on <a>Z12</a>.
module Music.Theory.Z12.TTO

-- | Map to pitch-class and reduce to set.
--   
--   <pre>
--   pcset [1,13] == [1]
--   </pre>
pcset :: (Integral a) => [a] -> [Z12]

-- | Transpose by n.
--   
--   <pre>
--   tn 4 [1,5,6] == [5,9,10]
--   tn 4 [0,4,8] == [0,4,8]
--   </pre>
tn :: Z12 -> [Z12] -> [Z12]

-- | Invert about n.
--   
--   <pre>
--   invert 6 [4,5,6] == [6,7,8]
--   invert 0 [0,1,3] == [0,9,11]
--   </pre>
invert :: Z12 -> [Z12] -> [Z12]

-- | Composition of <a>invert</a> about <tt>0</tt> and <a>tn</a>.
--   
--   <pre>
--   tni 4 [1,5,6] == [3,10,11]
--   (invert 0 . tn  4) [1,5,6] == [2,3,7]
--   </pre>
tni :: Z12 -> [Z12] -> [Z12]

-- | Modulo 12 multiplication
--   
--   <pre>
--   mn 11 [0,1,4,9] == invert 0 [0,1,4,9]
--   </pre>
mn :: Z12 -> [Z12] -> [Z12]

-- | M5, ie. <a>mn</a> <tt>5</tt>.
--   
--   <pre>
--   m5 [0,1,3] == [0,3,5]
--   </pre>
m5 :: [Z12] -> [Z12]

-- | T-related sets of <i>p</i>.
--   
--   <pre>
--   length (t_related [0,1,3]) == 12
--   t_related [0,3,6,9] == [[0,3,6,9],[1,4,7,10],[2,5,8,11]]
--   </pre>
t_related :: [Z12] -> [[Z12]]

-- | T/I-related set of <i>p</i>.
--   
--   <pre>
--   length (ti_related [0,1,3]) == 24
--   ti_related [0,3,6,9] == [[0,3,6,9],[1,4,7,10],[2,5,8,11]]
--   </pre>
ti_related :: [Z12] -> [[Z12]]


-- | Generalised Z-<i>n</i> functions.
module Music.Theory.Z
lift_unary_Z :: Integral a => a -> (t -> a) -> t -> a
lift_binary_Z :: Integral a => a -> (s -> t -> a) -> s -> t -> a
z_add :: Integral a => a -> a -> a -> a
z_sub :: Integral a => a -> a -> a -> a
z_mul :: Integral a => a -> a -> a -> a
z_negate :: Integral a => a -> a -> a
z_fromInteger :: Integral a => a -> Integer -> a
z_signum :: t -> t1 -> t2
z_abs :: t -> t1 -> t2
to_Z :: Integral i => i -> i -> i
from_Z :: (Integral i, Num n) => i -> n

-- | Z not in set.
--   
--   <pre>
--   z_complement 5 [0,2,3] == [1,4]
--   z_complement 12 [0,2,4,5,7,9,11] == [1,3,6,8,10]
--   </pre>
z_complement :: (Enum a, Eq a, Num a) => a -> [a] -> [a]
z_quot :: Integral i => i -> i -> i -> i
z_rem :: Integral c => c -> c -> c -> c
z_div :: Integral c => c -> c -> c -> c
z_mod :: Integral c => c -> c -> c -> c
z_quotRem :: Integral t => t -> t -> t -> (t, t)
z_divMod :: Integral t => t -> t -> t -> (t, t)
z_toInteger :: Integral i => i -> i -> i


-- | Serial (ordered) pitch-class operations on <tt>Z</tt>.
module Music.Theory.Z.SRO

-- | Transpose <i>p</i> by <i>n</i>.
--   
--   <pre>
--   tn 5 4 [0,1,4] == [4,0,3]
--   tn 12 4 [1,5,6] == [5,9,10]
--   </pre>
tn :: (Integral i, Functor f) => i -> i -> f i -> f i

-- | Invert <i>p</i> about <i>n</i>.
--   
--   <pre>
--   invert 5 0 [0,1,4] == [0,4,1]
--   invert 12 6 [4,5,6] == [8,7,6]
--   invert 12 0 [0,1,3] == [0,11,9]
--   </pre>
invert :: (Integral i, Functor f) => i -> i -> f i -> f i

-- | Composition of <a>invert</a> about <tt>0</tt> and <a>tn</a>.
--   
--   <pre>
--   tni 5 1 [0,1,3] == [1,0,3]
--   tni 12 4 [1,5,6] == [3,11,10]
--   (invert 12 0 . tn  12 4) [1,5,6] == [7,3,2]
--   </pre>
tni :: (Integral i, Functor f) => i -> i -> f i -> f i

-- | Modulo multiplication.
--   
--   <pre>
--   mn 12 11 [0,1,4,9] == tni 12 0 [0,1,4,9]
--   </pre>
mn :: (Integral i, Functor f) => i -> i -> f i -> f i

-- | T-related sequences of <i>p</i>.
--   
--   <pre>
--   length (t_related 12 [0,3,6,9]) == 12
--   </pre>
t_related :: (Integral i, Functor f) => i -> f i -> [f i]

-- | T/I-related sequences of <i>p</i>.
--   
--   <pre>
--   length (ti_related 12 [0,1,3]) == 24
--   length (ti_related 12 [0,3,6,9]) == 24
--   ti_related 12 [0] == map return [0..11]
--   </pre>
ti_related :: (Eq (f i), Integral i, Functor f) => i -> f i -> [f i]

-- | R/T/I-related sequences of <i>p</i>.
--   
--   <pre>
--   length (rti_related 12 [0,1,3]) == 48
--   length (rti_related 12 [0,3,6,9]) == 24
--   </pre>
rti_related :: Integral i => i -> [i] -> [[i]]

-- | Variant of <a>tn</a>, transpose <i>p</i> so first element is <i>n</i>.
--   
--   <pre>
--   tn_to 12 5 [0,1,3] == [5,6,8]
--   map (tn_to 12 0) [[0,1,3],[1,3,0],[3,0,1]]
--   </pre>
tn_to :: Integral a => a -> a -> [a] -> [a]

-- | Variant of <a>invert</a>, inverse about <i>n</i>th element.
--   
--   <pre>
--   map (invert_ix 12 0) [[0,1,3],[3,4,6]] == [[0,11,9],[3,2,0]]
--   map (invert_ix 12 1) [[0,1,3],[3,4,6]] == [[2,1,11],[5,4,2]]
--   </pre>
invert_ix :: Integral i => i -> Int -> [i] -> [i]

-- | The standard t-matrix of <i>p</i>.
--   
--   <pre>
--   tmatrix 12 [0,1,3] == [[0,1,3]
--                         ,[11,0,2]
--                         ,[9,10,0]]
--   </pre>
tmatrix :: Integral i => i -> [i] -> [[i]]


-- | Ronald C. Read. "Every one a winner or how to avoid isomorphism search
--   when cataloguing combinatorial configurations." /Annals of Discrete
--   Mathematics/ 2:107–20, 1978.
module Music.Theory.Z.Read_1978

-- | Coding.
type Code = Int

-- | Bit array.
type Array = [Bool]

-- | Pretty printer for <a>Array</a>.
array_pp :: Array -> String

-- | Parse PP of <a>Array</a>.
--   
--   <pre>
--   parse_array "01001" == [False,True,False,False,True]
--   </pre>
parse_array :: String -> Array

-- | Generate <a>Code</a> from <a>Array</a>, the coding is most to least
--   significant.
--   
--   <pre>
--   array_to_code (map toEnum [1,1,0,0,1,0,0,0,1,1,1,0,0]) == 6428
--   </pre>
array_to_code :: Array -> Code

-- | Inverse of <a>array_to_code</a>.
--   
--   <pre>
--   code_to_array 13 6428 == map toEnum [1,1,0,0,1,0,0,0,1,1,1,0,0]
--   </pre>
code_to_array :: Int -> Code -> Array

-- | Array to set.
--   
--   <pre>
--   array_to_set (map toEnum [1,1,0,0,1,0,0,0,1,1,1,0,0]) == [0,1,4,8,9,10]
--   T.encode [0,1,4,8,9,10] == 1811
--   </pre>
array_to_set :: Integral i => [Bool] -> [i]

-- | Inverse of <a>array_to_set</a>, <i>z</i> is the degree of the array.
set_to_array :: Integral i => i -> [i] -> Array

-- | <a>array_to_code</a> of <a>set_to_array</a>.
--   
--   <pre>
--   set_to_code 12 [0,2,3,5]
--   map (set_to_code 12) (T.ti_related 12 [0,2,3,5])
--   </pre>
set_to_code :: Integral i => i -> [i] -> Code

-- | Logical complement.
array_complement :: Array -> Array

-- | The <i>prime</i> form is the <a>maximum</a> encoding.
--   
--   <pre>
--   array_is_prime (set_to_array 12 [0,2,3,5]) == False
--   </pre>
array_is_prime :: Array -> Bool

-- | The augmentation rule adds <tt>1</tt> in each empty slot at end of
--   array.
--   
--   <pre>
--   map array_pp (array_augment (parse_array "01000")) == ["01100","01010","01001"]
--   </pre>
array_augment :: Array -> [Array]

-- | Enumerate first half of the set-classes under given <i>prime</i>
--   function. The second half can be derived as the complement of the
--   first.
--   
--   <pre>
--   import Music.Theory.Z12.Forte_1973
--   length scs == 224
--   map (length . scs_n) [0..12] == [1,1,6,12,29,38,50,38,29,12,6,1,1]
--   </pre>
--   
--   <pre>
--   let z12 = map (fmap (map array_to_set)) (enumerate_half array_is_prime 12)
--   map (length . snd) z12 == [1,1,6,12,29,38,50]
--   </pre>
--   
--   This can become slow, edit <i>z</i> to find out. It doesn't matter
--   about <i>n</i>. This can be edited so that small <i>n</i> would run
--   quickly even for large <i>z</i>.
--   
--   <pre>
--   fmap (map array_to_set) (lookup 5 (enumerate_half array_is_prime 16))
--   </pre>
enumerate_half :: (Array -> Bool) -> Int -> [(Int, [Array])]

-- | Encoder for <a>encode_prime</a>.
--   
--   <pre>
--   encode [0,1,3,6,8,9] == 843
--   </pre>
encode :: Integral i => [i] -> Code

-- | Decoder for <a>encode_prime</a>.
--   
--   <pre>
--   decode 12 843 == [0,1,3,6,8,9]
--   </pre>
decode :: Integral i => i -> Code -> [i]

-- | Binary encoding prime form algorithm, equalivalent to Rahn.
--   
--   <pre>
--   encode_prime 12 [0,1,3,6,8,9] == [0,2,3,6,7,9]
--   Music.Theory.Z12.Rahn_1980.rahn_prime [0,1,3,6,8,9] == [0,2,3,6,7,9]
--   </pre>
encode_prime :: Integral i => i -> [i] -> [i]


-- | Ronald C. Read. "Every one a winner or how to avoid isomorphism search
--   when cataloguing combinatorial configurations." /Annals of Discrete
--   Mathematics/ 2:107–20, 1978.
module Music.Theory.Z12.Read_1978
type Code = Code

-- | Encoder for <a>encode_prime</a>.
--   
--   <pre>
--   encode [0,1,3,6,8,9] == 843
--   </pre>
encode :: [Z12] -> Code

-- | Decoder for <a>encode_prime</a>.
--   
--   <pre>
--   decode 843 == [0,1,3,6,8,9]
--   </pre>
decode :: Code -> [Z12]

-- | Binary encoding prime form algorithm, equalivalent to Rahn.
--   
--   <pre>
--   encode_prime [0,1,3,6,8,9] == [0,2,3,6,7,9]
--   Music.Theory.Z12.Rahn_1980.rahn_prime [0,1,3,6,8,9] == [0,2,3,6,7,9]
--   </pre>
encode_prime :: [Z12] -> [Z12]


-- | <a>http://www.unicode.org/charts/PDF/U1D100.pdf</a>
module Music.Theory.Unicode
type Unicode_Table = [(Int, String)]
unicode :: [Unicode_Table]
accidentals :: Unicode_Table
notes :: Unicode_Table
rests :: Unicode_Table
clefs :: Unicode_Table


-- | Tuple functions.
--   
--   Uniform tuples have types <a>T2</a>, <a>T3</a> etc. and functions
--   names are prefixed <tt>t2_</tt> etc.
--   
--   Heterogenous tuples (products) are prefixed <tt>p2_</tt> etc.
module Music.Theory.Tuple
p2_swap :: (s, t) -> (t, s)

-- | Uniform two-tuple.
type T2 a = (a, a)
t2 :: [t] -> T2 t
t2_list :: T2 a -> [a]
t2_swap :: T2 t -> T2 t
t2_map :: (p -> q) -> T2 p -> T2 q
t2_zipWith :: (p -> q -> r) -> T2 p -> T2 q -> T2 r
t2_infix :: (a -> a -> b) -> T2 a -> b

-- | Infix <a>mappend</a>.
--   
--   <pre>
--   t2_join ([1,2],[3,4]) == [1,2,3,4]
--   </pre>
t2_join :: Monoid m => T2 m -> m
t2_concat :: [T2 [a]] -> T2 [a]
t2_sort :: Ord t => (t, t) -> (t, t)

-- | Left rotation.
--   
--   <pre>
--   p3_rotate_left (1,2,3) == (2,3,1)
--   </pre>
p3_rotate_left :: (s, t, u) -> (t, u, s)
p3_fst :: (a, b, c) -> a
p3_snd :: (a, b, c) -> b
p3_third :: (a, b, c) -> c
type T3 a = (a, a, a)
t3 :: [t] -> T3 t
t3_rotate_left :: T3 t -> T3 t
t3_fst :: T3 t -> t
t3_snd :: T3 t -> t
t3_third :: T3 t -> t
t3_map :: (p -> q) -> T3 p -> T3 q
t3_zipWith :: (p -> q -> r) -> T3 p -> T3 q -> T3 r
t3_list :: T3 a -> [a]
t3_infix :: (a -> a -> a) -> T3 a -> a
t3_join :: T3 [a] -> [a]
p4_fst :: (a, b, c, d) -> a
p4_snd :: (a, b, c, d) -> b
p4_third :: (a, b, c, d) -> c
p4_fourth :: (a, b, c, d) -> d
type T4 a = (a, a, a, a)
t4 :: [t] -> T4 t
t4_list :: T4 t -> [t]
t4_fst :: T4 t -> t
t4_snd :: T4 t -> t
t4_third :: T4 t -> t
t4_fourth :: T4 t -> t
t4_map :: (p -> q) -> T4 p -> T4 q
t4_zipWith :: (p -> q -> r) -> T4 p -> T4 q -> T4 r
t4_infix :: (a -> a -> a) -> T4 a -> a
t4_join :: T4 [a] -> [a]
p5_fst :: (a, b, c, d, e) -> a
p5_snd :: (a, b, c, d, e) -> b
p5_third :: (a, b, c, d, e) -> c
p5_fourth :: (a, b, c, d, e) -> d
p5_fifth :: (a, b, c, d, e) -> e
type T5 a = (a, a, a, a, a)
t5 :: [t] -> T5 t
t5_list :: T5 t -> [t]
t5_map :: (p -> q) -> T5 p -> T5 q
t5_fst :: T5 t -> t
t5_snd :: T5 t -> t
t5_fourth :: T5 t -> t
t5_fifth :: T5 t -> t
t5_infix :: (a -> a -> a) -> T5 a -> a
t5_join :: T5 [a] -> [a]
p6_fst :: (a, b, c, d, e, f) -> a
p6_snd :: (a, b, c, d, e, f) -> b
p6_third :: (a, b, c, d, e, f) -> c
p6_fourth :: (a, b, c, d, e, f) -> d
p6_fifth :: (a, b, c, d, e, f) -> e
p6_sixth :: (a, b, c, d, e, f) -> f
type T6 a = (a, a, a, a, a, a)
t6 :: [t] -> T6 t
t6_list :: T6 t -> [t]
t6_map :: (p -> q) -> T6 p -> T6 q
type T7 a = (a, a, a, a, a, a, a)
t7_list :: T7 t -> [t]
t7_map :: (p -> q) -> T7 p -> T7 q
type T8 a = (a, a, a, a, a, a, a, a)
t8_list :: T8 t -> [t]
t8_map :: (p -> q) -> T8 p -> T8 q
type T9 a = (a, a, a, a, a, a, a, a, a)
t9_list :: T9 t -> [t]
t9_map :: (p -> q) -> T9 p -> T9 q

module Music.Theory.Time.Notation

-- | Fractional seconds.
type FSEC = Double

-- | Minutes, seconds as <tt>(min,sec)</tt>
type MINSEC = (Int, Int)

-- | Minutes, seconds, centi-seconds as <tt>(min,sec,csec)</tt>
type MINCSEC = (Int, Int, Int)

-- | Fractional seconds to <tt>(min,sec)</tt>.
--   
--   <pre>
--   map fsec_to_minsec [59.49,60,60.51] == [(0,59),(1,0),(1,1)]
--   </pre>
fsec_to_minsec :: FSEC -> MINSEC

-- | <a>MINSEC</a> pretty printer.
--   
--   <pre>
--   map (minsec_pp . fsec_to_minsec) [59,61] == ["00:59","01:01"]
--   </pre>
minsec_pp :: MINSEC -> String

-- | Fractional seconds to <tt>(min,sec,csec)</tt>.
--   
--   <pre>
--   map fsec_to_mincsec [1,1.5,4/3] == [(0,1,0),(0,1,50),(0,1,33)]
--   </pre>
fsec_to_mincsec :: FSEC -> MINCSEC

-- | <a>MINCSEC</a> pretty printer.
--   
--   <pre>
--   map (mincsec_pp . fsec_to_mincsec) [1,4/3] == ["00:01.00","00:01.33"]
--   </pre>
mincsec_pp :: MINCSEC -> String
span_pp :: (t -> String) -> (t, t) -> String

module Music.Theory.Time.Duration

-- | Duration stored as <i>hours</i>, <i>minutes</i>, <i>seconds</i> and
--   <i>milliseconds</i>.
data Duration
Duration :: Int -> Int -> Int -> Int -> Duration
[hours] :: Duration -> Int
[minutes] :: Duration -> Int
[seconds] :: Duration -> Int
[milliseconds] :: Duration -> Int

-- | Convert fractional <i>seconds</i> to integral
--   <i>(seconds,milliseconds)</i>.
--   
--   <pre>
--   s_sms 1.75 == (1,750)
--   </pre>
s_sms :: (RealFrac n, Integral i) => n -> (i, i)

-- | Inverse of <a>s_sms</a>.
--   
--   <pre>
--   sms_s (1,750) == 1.75
--   </pre>
sms_s :: (Integral i) => (i, i) -> Double

-- | <a>Read</a> function for <a>Duration</a> tuple.
read_duration_tuple :: String -> (Int, Int, Int, Int)

-- | <a>Read</a> function for <a>Duration</a>. Allows either
--   <tt>H:M:S.MS</tt> or <tt>M:S.MS</tt> or <tt>S.MS</tt>.
--   
--   <pre>
--   read_duration "01:35:05.250" == Duration 1 35 5 250
--   read_duration    "35:05.250" == Duration 0 35 5 250
--   read_duration       "05.250" == Duration 0 0 5 250
--   </pre>
read_duration :: String -> Duration

-- | <a>Show</a> function for <a>Duration</a>.
--   
--   <pre>
--   show_duration (Duration 1 35 5 250) == "01:35:05.250"
--   show (Duration 1 15 0 000) == "01:15:00.000"
--   </pre>
show_duration :: Duration -> String
normalise_minutes :: Duration -> Duration
normalise_seconds :: Duration -> Duration
normalise_milliseconds :: Duration -> Duration
normalise_duration :: Duration -> Duration

-- | Extract <a>Duration</a> tuple applying filter function at each element
--   
--   <pre>
--   duration_tuple id (Duration 1 35 5 250) == (1,35,5,250)
--   </pre>
duration_to_tuple :: (Int -> a) -> Duration -> (a, a, a, a)

-- | Inverse of <a>duration_to_tuple</a>.
tuple_to_duration :: (a -> Int) -> (a, a, a, a) -> Duration
duration_to_hours :: Fractional n => Duration -> n
duration_to_minutes :: Fractional n => Duration -> n
duration_to_seconds :: Fractional n => Duration -> n
hours_to_duration :: RealFrac a => a -> Duration
minutes_to_duration :: RealFrac a => a -> Duration
seconds_to_duration :: RealFrac a => a -> Duration
nil_duration :: Duration
negate_duration :: Duration -> Duration
duration_diff :: Duration -> Duration -> Duration
instance GHC.Classes.Eq Music.Theory.Time.Duration.Duration
instance GHC.Read.Read Music.Theory.Time.Duration.Duration
instance GHC.Show.Show Music.Theory.Time.Duration.Duration

module Music.Theory.Tiling.Canon

-- | Sequence.
type S = [Int]

-- | Canon of <i>(period,sequence,multipliers,displacements)</i>.
type R = (Int, S, [Int], [Int])

-- | Voice.
type V = [Int]

-- | Tiling (sequence)
type T = [[Int]]

-- | Cycle at <i>period</i>.
--   
--   <pre>
--   take 9 (p_cycle 18 [0,2,5]) == [0,2,5,18,20,23,36,38,41]
--   </pre>
p_cycle :: Int -> [Int] -> [Int]

-- | Element of <i>(sequence,multiplier,displacement)</i>.
type E = (S, Int, Int)

-- | Resolve sequence from <a>E</a>.
--   
--   <pre>
--   e_to_seq ([0,2,5],2,1) == [1,5,11]
--   e_to_seq ([0,1],3,4) == [4,7]
--   e_to_seq ([0],1,2) == [2]
--   </pre>
e_to_seq :: E -> [Int]

-- | Infer <a>E</a> from sequence.
--   
--   <pre>
--   e_from_seq [1,5,11] == ([0,2,5],2,1)
--   e_from_seq [4,7] == ([0,1],3,4)
--   e_from_seq [2] == ([0],1,2)
--   </pre>
e_from_seq :: [Int] -> E

-- | Set of <a>V</a> from <a>R</a>.
r_voices :: R -> [V]

-- | <a>concatMap</a> of <a>r_voices</a>.
rr_voices :: [R] -> [V]

-- | Retrograde of <a>T</a>, the result <a>T</a> is sorted.
--   
--   <pre>
--   let r = [[0,7,14],[1,5,9],[2,4,6],[3,8,13],[10,11,12]]
--   in t_retrograde [[0,7,14],[1,6,11],[2,3,4],[5,9,13],[8,10,12]] == r
--   </pre>
t_retrograde :: T -> T

-- | The normal form of <a>T</a> is the <a>min</a> of <i>t</i> and it's
--   <a>t_retrograde</a>.
--   
--   <pre>
--   let r = [[0,7,14],[1,5,9],[2,4,6],[3,8,13],[10,11,12]]
--   in t_normal [[0,7,14],[1,6,11],[2,3,4],[5,9,13],[8,10,12]] == r
--   </pre>
t_normal :: T -> T

-- | Derive set of <a>R</a> from <a>T</a>.
--   
--   <pre>
--   let {r = [(21,[0,1,2],[10,8,2,4,7,5,1],[0,1,2,3,5,8,14])]
--       ;t = [[0,10,20],[1,9,17],[2,4,6],[3,7,11],[5,12,19],[8,13,18],[14,15,16]]}
--   in r_from_t t == r
--   </pre>
r_from_t :: T -> [R]

-- | <a>msum</a> <a>.</a> <a>map</a> <a>return</a>.
--   
--   <pre>
--   observeAll (fromList [1..7]) == [1..7]
--   </pre>
fromList :: MonadPlus m => [a] -> m a

-- | Search for <i>perfect</i> tilings of the sequence <a>S</a> using
--   multipliers from <i>m</i> to degree <i>n</i> with <i>k</i> parts.
perfect_tilings_m :: MonadPlus m => [S] -> [Int] -> Int -> Int -> m T

-- | <a>t_normal</a> of <a>observeAll</a> of <a>perfect_tilings_m</a>.
--   
--   <pre>
--   perfect_tilings [[0,1]] [1..3] 6 3 == []
--   </pre>
--   
--   <pre>
--   let r = [[[0,7,14],[1,5,9],[2,4,6],[3,8,13],[10,11,12]]]
--   in perfect_tilings [[0,1,2]] [1,2,4,5,7] 15 5 == r
--   </pre>
--   
--   <pre>
--   length (perfect_tilings [[0,1,2]] [1..12] 15 5) == 1
--   </pre>
--   
--   <pre>
--   let r = [[[0,1],[2,5],[3,7],[4,6]]
--           ,[[0,1],[2,6],[3,5],[4,7]]
--           ,[[0,2],[1,4],[3,7],[5,6]]]
--   in perfect_tilings [[0,1]] [1..4] 8 4 == r
--   </pre>
--   
--   <pre>
--   let r = [[[0,1],[2,5],[3,7],[4,9],[6,8]]
--           ,[[0,1],[2,7],[3,5],[4,8],[6,9]]
--           ,[[0,2],[1,4],[3,8],[5,9],[6,7]]
--           ,[[0,2],[1,5],[3,6],[4,9],[7,8]]
--           ,[[0,3],[1,6],[2,4],[5,9],[7,8]]]
--   in perfect_tilings [[0,1]] [1..5] 10 5 == r
--   </pre>
--   
--   Johnson 2004, p.2
--   
--   <pre>
--   let r = [[0,6,12],[1,8,15],[2,11,20],[3,5,7],[4,9,14],[10,13,16],[17,18,19]]
--   in perfect_tilings [[0,1,2]] [1,2,3,5,6,7,9] 21 7 == [r]
--   </pre>
--   
--   <pre>
--   let r = [[0,10,20],[1,9,17],[2,4,6],[3,7,11],[5,12,19],[8,13,18],[14,15,16]]
--   in perfect_tilings [[0,1,2]] [1,2,4,5,7,8,10] 21 7 == [t_retrograde r]
--   </pre>
perfect_tilings :: [S] -> [Int] -> Int -> Int -> [T]

-- | Variant of <a>elem</a> for ordered sequences, which can therefore
--   return <a>False</a> when searching infinite sequences.
--   
--   <pre>
--   5 `elemOrd` [0,2..] == False &amp;&amp; 10 `elemOrd` [0,2..] == True
--   </pre>
elemOrd :: Ord a => a -> [a] -> Bool

-- | A <tt>.*</tt> diagram of <i>n</i> places of <a>V</a>.
--   
--   <pre>
--   v_dot_star 18 [0,2..] == "*.*.*.*.*.*.*.*.*."
--   </pre>
v_dot_star :: Int -> V -> String

-- | A white space and index diagram of <i>n</i> places of <a>V</a>.
--   
--   <pre>
--   &gt;&gt;&gt; mapM_ (putStrLn . v_space_ix 9) [[0,2..],[1,3..]]
--   &gt;
--   &gt;  0   2   4   6   8
--   &gt;    1   3   5   7
--   </pre>
v_space_ix :: Int -> V -> String

-- | Insert <tt>|</tt> every <i>n</i> places.
--   
--   <pre>
--   with_bars 6 (v_dot_star 18 [0,2..]) == "*.*.*.|*.*.*.|*.*.*."
--   </pre>
with_bars :: Int -> String -> String

-- | Variant with measure length <i>m</i> and number of measures <i>n</i>.
--   
--   <pre>
--   v_dot_star_m 6 3 [0,2..] == "*.*.*.|*.*.*.|*.*.*."
--   </pre>
v_dot_star_m :: Int -> Int -> V -> String

-- | Print <tt>.*</tt> diagram.
v_print :: Int -> [V] -> IO ()

-- | Variant to print <tt>|</tt> at measures.
v_print_m :: Int -> Int -> [V] -> IO ()

-- | Variant that discards first <i>k</i> measures.
v_print_m_from :: Int -> Int -> Int -> [V] -> IO ()


-- | Tom Johnson. "Perfect Rhythmic Tilings". Technical report, IRCAM, 24
--   January 2004. MaMuX Lecture.
module Music.Theory.Tiling.Johnson_2004

-- | <tt>{0,1,2}</tt> order 5, p.1
--   
--   <pre>
--   &gt;&gt;&gt; v_print 15 (r_voices p1)
--   &gt;
--   &gt; ..***..........
--   &gt; ........*.*.*..
--   &gt; .....*...*...*.
--   &gt; .*....*....*...
--   &gt; *......*......*
--   </pre>
p1 :: R

-- | <tt>{0,1,2}</tt> order 7, p.2
--   
--   <pre>
--   &gt;&gt;&gt; v_print 21 (r_voices p2)
--   &gt;
--   &gt; ..............***....
--   &gt; ..*.*.*..............
--   &gt; ...*...*...*.........
--   &gt; ........*....*....*..
--   &gt; .....*......*......*.
--   &gt; .*.......*.......*...
--   &gt; *.........*.........*
--   </pre>
p2 :: R

-- | <tt>{0,1}</tt> order 4, p.3
--   
--   <pre>
--   &gt;&gt;&gt; v_print 8 (r_voices p3)
--   &gt;
--   &gt; *...*...
--   &gt; .**.....
--   &gt; ...*..*.
--   &gt; .....*.*
--   </pre>
p3 :: R

-- | <tt>{0,1}</tt> order 5, p.4
--   
--   <pre>
--   &gt;&gt;&gt; mapM_ (v_print 10 . r_voices) p4
--   &gt;
--   &gt; *...*.....
--   &gt; .**.......
--   &gt; ...*....*.
--   &gt; .....*.*..
--   &gt; ......*..*
--   &gt;
--   &gt; *....*....
--   &gt; .**.......
--   &gt; ...*..*...
--   &gt; ....*...*.
--   &gt; .......*.*
--   &gt;
--   &gt; *...*.....
--   &gt; .*....*...
--   &gt; ..**......
--   &gt; .....*..*.
--   &gt; .......*.*
--   </pre>
p4 :: [R]

-- | Open <tt>{1,2,3}</tt> order 5, p.4
--   
--   <pre>
--   &gt;&gt;&gt; v_print 18 (r_voices p4_b)
--   &gt;
--   &gt; ...***............
--   &gt; ........*.*.*.....
--   &gt; .........*...*...*
--   &gt; .*....*....*......
--   &gt; *......*......*...
--   </pre>
p4_b :: R


-- | Tom Johnson. "Tiling in my Music". <i>The Experimental Music
--   Yearbook</i>, 1, 2009.
module Music.Theory.Tiling.Johnson_2009

-- | Tilework for Clarinet, p.3
--   
--   <pre>
--   &gt;&gt;&gt; v_print 36 (rr_voices p3)
--   &gt;
--   &gt; *.*..*............*.*..*............
--   &gt; .*.*..*............*.*..*...........
--   &gt; ........*.*..*............*.*..*....
--   &gt; ....*..*.*............*..*.*........
--   &gt; ...........*..*.*............*..*.*.
--   &gt; ............*..*.*............*..*.*
--   </pre>
p3 :: [R]

-- | Tilework for String Quartet, p.5
--   
--   <pre>
--   &gt;&gt;&gt; mapM_ (v_print 24 . r_voices) p5
--   &gt;
--   &gt; ******......******......
--   &gt; ......******......******
--   &gt;
--   &gt; *.****.*....*.****.*....
--   &gt; ......*.****.*....*.****
--   &gt;
--   &gt; **.***..*...**.***..*...
--   &gt; ......**.***..*...**.***
--   &gt;
--   &gt; *..***.**...*..***.**...
--   &gt; ......*..***.**...*..***
--   </pre>
p5 :: [R]

-- | Extra Perfect (p.7)
--   
--   <pre>
--   &gt;&gt;&gt; v_print_m_from 18 6 6 (r_voices p7)
--   &gt;
--   &gt; **.*..|......|......|......|......|......
--   &gt; ......|.*.*..|.*....|......|......|......
--   &gt; ......|......|......|......|.*..*.|....*.
--   &gt; ......|......|...*..|.*....|...*..|......
--   &gt; ......|......|....*.|...*..|......|.*....
--   &gt; ......|*.....|*.....|......|*.....|......
--   &gt; ....*.|......|......|*.....|......|...*..
--   &gt; ......|......|......|....*.|......|*.....
--   </pre>
p7 :: R

-- | Tilework for Log Drums (2005), p.10
--   
--   <pre>
--   &gt;&gt;&gt; v_print 18 (r_voices p10)
--   &gt;
--   &gt; *.*.*.............
--   &gt; .*...*...*........
--   &gt; ...*...*...*......
--   &gt; ......*...*...*...
--   &gt; ........*...*...*.
--   &gt; .............*.*.*
--   </pre>
p10 :: R

-- | Self-Similar Melodies (1996), p.11
--   
--   <pre>
--   &gt;&gt;&gt; v_print_m 20 5 (r_voices p11)
--   &gt;
--   &gt; *.....*.....*..*..*.|....*.....*.....*...|..*..*..*.....*.....|*.....*.....*..*..*.|....*.....*.....*...
--   &gt; ....................|*.....*.....*..*..*.|....*.....*.....*...|..*..*..*.....*.....|*.....*.....*..*..*.
--   &gt; ....................|....................|*.....*.....*..*..*.|....*.....*.....*...|..*..*..*.....*.....
--   </pre>
p11 :: R


-- | Set operations on lists.
module Music.Theory.Set.List

-- | Remove duplicate elements with <a>nub</a> and then <a>sort</a>.
--   
--   <pre>
--   set_l [3,3,3,2,2,1] == [1,2,3]
--   </pre>
set :: (Ord a) => [a] -> [a]

-- | Size of powerset of set of cardinality <i>n</i>, ie. <tt>2</tt>
--   <a>^</a> <i>n</i>.
--   
--   <pre>
--   map n_powerset [6..9] == [64,128,256,512]
--   </pre>
n_powerset :: Integral n => n -> n

-- | Powerset, ie. set of all subsets.
--   
--   <pre>
--   sort (powerset [1,2]) == [[],[1],[1,2],[2]]
--   map length (map (\n -&gt; powerset [1..n]) [6..9]) == [64,128,256,512]
--   </pre>
powerset :: [a] -> [[a]]

-- | Two element subsets.
--   
--   <pre>
--   pairs [1,2,3] == [(1,2),(1,3),(2,3)]
--   </pre>
pairs :: [a] -> [(a, a)]

-- | Three element subsets.
--   
--   <pre>
--   triples [1..4] == [(1,2,3),(1,2,4),(1,3,4),(2,3,4)]
--   </pre>
--   
--   <pre>
--   let f n = genericLength (triples [1..n]) == nk_combinations n 3
--   in all f [1..15]
--   </pre>
triples :: [a] -> [(a, a, a)]

-- | Set expansion (ie. to multiset of degree <i>n</i>).
--   
--   <pre>
--   expand_set 4 [1,2,3] == [[1,1,2,3],[1,2,2,3],[1,2,3,3]]
--   </pre>
expand_set :: (Ord a) => Int -> [a] -> [[a]]

-- | All distinct multiset partitions, see <a>partitions</a>.
--   
--   <pre>
--   partitions "aab" == [["aab"],["a","ab"],["b","aa"],["b","a","a"]]
--   </pre>
--   
--   <pre>
--   partitions "abc" == [["abc"]
--                       ,["bc","a"],["b","ac"],["c","ab"]
--                       ,["c","b","a"]]
--   </pre>
partitions :: Eq a => [a] -> [[[a]]]

-- | Cartesian product of two sets.
--   
--   <pre>
--   let r = [('a',1),('a',2),('b',1),('b',2),('c',1),('c',2)]
--   in cartesian_product "abc" [1,2] == r
--   </pre>
cartesian_product :: [a] -> [b] -> [(a, b)]


-- | Set operations on <tt>Set</tt>s.
module Music.Theory.Set.Set
set :: (Ord a) => [a] -> Set a
powerset :: Ord a => Set a -> Set (Set a)
pairs :: Ord a => Set a -> Set (a, a)


-- | Common music notation note and alteration values.
module Music.Theory.Pitch.Note

-- | Enumeration of common music notation note names (<tt>C</tt> to
--   <tt>B</tt>).
data Note_T
C :: Note_T
D :: Note_T
E :: Note_T
F :: Note_T
G :: Note_T
A :: Note_T
B :: Note_T

-- | Transform <a>Note_T</a> to pitch-class number.
--   
--   <pre>
--   map note_to_pc [C,E,G] == [0,4,7]
--   </pre>
note_to_pc :: Integral i => Note_T -> i

-- | Modal transposition of <a>Note_T</a> value.
--   
--   <pre>
--   note_t_transpose C 2 == E
--   </pre>
note_t_transpose :: Note_T -> Int -> Note_T

-- | Enumeration of common music notation note alterations.
data Alteration_T
DoubleFlat :: Alteration_T
ThreeQuarterToneFlat :: Alteration_T
Flat :: Alteration_T
QuarterToneFlat :: Alteration_T
Natural :: Alteration_T
QuarterToneSharp :: Alteration_T
Sharp :: Alteration_T
ThreeQuarterToneSharp :: Alteration_T
DoubleSharp :: Alteration_T

-- | Generic form.
generic_alteration_to_diff :: Integral i => Alteration_T -> Maybe i

-- | Transform <a>Alteration_T</a> to semitone alteration. Returns
--   <a>Nothing</a> for non-semitone alterations.
--   
--   <pre>
--   map alteration_to_diff [Flat,QuarterToneSharp] == [Just (-1),Nothing]
--   </pre>
alteration_to_diff :: Alteration_T -> Maybe Int

-- | Is <a>Alteration_T</a> 12-ET.
alteration_is_12et :: Alteration_T -> Bool

-- | Transform <a>Alteration_T</a> to semitone alteration.
--   
--   <pre>
--   map alteration_to_diff_err [Flat,Sharp] == [-1,1]
--   </pre>
alteration_to_diff_err :: Integral i => Alteration_T -> i

-- | Transform <a>Alteration_T</a> to fractional semitone alteration, ie.
--   allow quarter tones.
--   
--   <pre>
--   alteration_to_fdiff QuarterToneSharp == 0.5
--   </pre>
alteration_to_fdiff :: Fractional n => Alteration_T -> n

-- | Transform fractional semitone alteration to <a>Alteration_T</a>, ie.
--   allow quarter tones.
--   
--   <pre>
--   map fdiff_to_alteration [-0.5,0.5] == [Just QuarterToneFlat
--                                         ,Just QuarterToneSharp]
--   </pre>
fdiff_to_alteration :: (Fractional n, Eq n) => n -> Maybe Alteration_T

-- | Raise <a>Alteration_T</a> by a quarter tone where possible.
--   
--   <pre>
--   alteration_raise_quarter_tone Flat == Just QuarterToneFlat
--   alteration_raise_quarter_tone DoubleSharp == Nothing
--   </pre>
alteration_raise_quarter_tone :: Alteration_T -> Maybe Alteration_T

-- | Lower <a>Alteration_T</a> by a quarter tone where possible.
--   
--   <pre>
--   alteration_lower_quarter_tone Sharp == Just QuarterToneSharp
--   alteration_lower_quarter_tone DoubleFlat == Nothing
--   </pre>
alteration_lower_quarter_tone :: Alteration_T -> Maybe Alteration_T

-- | Edit <a>Alteration_T</a> by a quarter tone where possible,
--   <tt>-0.5</tt> lowers, <tt>0</tt> retains, <tt>0.5</tt> raises.
--   
--   <pre>
--   import Data.Ratio
--   alteration_edit_quarter_tone (-1 % 2) Flat == Just ThreeQuarterToneFlat
--   </pre>
alteration_edit_quarter_tone :: (Fractional n, Eq n) => n -> Alteration_T -> Maybe Alteration_T

-- | Simplify <a>Alteration_T</a> to standard 12ET by deleting quarter
--   tones.
--   
--   <pre>
--   Data.List.nub (map alteration_clear_quarter_tone [minBound..maxBound])
--   </pre>
alteration_clear_quarter_tone :: Alteration_T -> Alteration_T

-- | Unicode has entries for <i>Musical Symbols</i> in the range
--   <tt>U+1D100</tt> through <tt>U+1D1FF</tt>. The <tt>3/4</tt> symbols
--   are non-standard, here they correspond to <tt>MUSICAL SYMBOL FLAT
--   DOWN</tt> and <tt>MUSICAL SYMBOL SHARP UP</tt>.
--   
--   <pre>
--   map alteration_symbol [minBound .. maxBound] == "𝄫𝄭♭𝄳♮𝄲♯𝄰𝄪"
--   </pre>
alteration_symbol :: Alteration_T -> Char

-- | The <tt>ISO</tt> ASCII spellings for alterations. Naturals as written
--   as the empty string.
--   
--   <pre>
--   mapMaybe alteration_iso_m [Flat .. Sharp] == ["b","","#"]
--   </pre>
alteration_iso_m :: Alteration_T -> Maybe String

-- | The <tt>ISO</tt> ASCII spellings for alterations.
alteration_iso :: Alteration_T -> String

-- | The <i>Tonhöhe</i> ASCII spellings for alterations.
--   
--   See <a>http://www.musiccog.ohio-state.edu/Humdrum/guide04.html</a> and
--   <a>http://lilypond.org/doc/v2.16/Documentation/notation/writing-pitches</a>
--   
--   <pre>
--   map alteration_tonh [Flat .. Sharp] == ["es","eh","","ih","is"]
--   </pre>
alteration_tonh :: Alteration_T -> String

-- | Generalised alteration, given as a rational semitone difference and a
--   string representation of the alteration.
type Alteration_T' = (Rational, String)

-- | Transform <a>Alteration_T</a> to <a>Alteration_T'</a>.
--   
--   <pre>
--   let r = [(-1,"♭"),(0,"♮"),(1,"♯")]
--   in map alteration_t' [Flat,Natural,Sharp] == r
--   </pre>
alteration_t' :: Alteration_T -> Alteration_T'

-- | Function to spell a <tt>PitchClass</tt>.
type Spelling n = n -> (Note_T, Alteration_T)
instance GHC.Show.Show Music.Theory.Pitch.Note.Alteration_T
instance GHC.Classes.Ord Music.Theory.Pitch.Note.Alteration_T
instance GHC.Enum.Bounded Music.Theory.Pitch.Note.Alteration_T
instance GHC.Enum.Enum Music.Theory.Pitch.Note.Alteration_T
instance GHC.Classes.Eq Music.Theory.Pitch.Note.Alteration_T
instance GHC.Show.Show Music.Theory.Pitch.Note.Note_T
instance GHC.Classes.Ord Music.Theory.Pitch.Note.Note_T
instance GHC.Enum.Bounded Music.Theory.Pitch.Note.Note_T
instance GHC.Enum.Enum Music.Theory.Pitch.Note.Note_T
instance GHC.Classes.Eq Music.Theory.Pitch.Note.Note_T


-- | Spelling rules for common music notation.
module Music.Theory.Pitch.Spelling

-- | Variant of <a>Spelling</a> for incomplete functions.
type Spelling_M i = i -> Maybe (Note_T, Alteration_T)

-- | Spelling for natural (♮) notes only.
--   
--   <pre>
--   map pc_spell_natural_m [0,1] == [Just (C,Natural),Nothing]
--   </pre>
pc_spell_natural_m :: Integral i => Spelling_M i

-- | Erroring variant of <a>pc_spell_natural_m</a>.
--   
--   <pre>
--   map pc_spell_natural [0,5,7] == [(C,Natural),(F,Natural),(G,Natural)]
--   </pre>
pc_spell_natural :: Integral i => Spelling i

-- | Use spelling from simplest key-signature. Note that this is ambiguous
--   for <tt>8</tt>, which could be either G Sharp (♯) in <i>A Major</i> or
--   A Flat (♭) in <i>E Flat (♭) Major</i>.
--   
--   <pre>
--   map pc_spell_ks [6,8] == [(F,Sharp),(A,Flat)]
--   </pre>
pc_spell_ks :: Integral i => Spelling i

-- | Use always sharp (♯) spelling.
--   
--   <pre>
--   map pc_spell_sharp [6,8] == [(F,Sharp),(G,Sharp)]
--   Data.List.nub (map (snd . pc_spell_sharp) [1,3,6,8,10]) == [Sharp]
--   octpc_to_pitch pc_spell_sharp (4,6) == Pitch F Sharp 4
--   </pre>
pc_spell_sharp :: Integral i => Spelling i

-- | Use always flat (♭) spelling.
--   
--   <pre>
--   map pc_spell_flat [6,8] == [(G,Flat),(A,Flat)]
--   Data.List.nub (map (snd . pc_spell_flat) [1,3,6,8,10]) == [Flat]
--   </pre>
pc_spell_flat :: Integral i => Spelling i


-- | Extensions to <a>Data.Maybe</a>.
module Music.Theory.Maybe

-- | Variant of unzip.
--   
--   <pre>
--   let r = ([Just 1,Nothing,Just 3],[Just 'a',Nothing,Just 'c'])
--   in maybe_unzip [Just (1,'a'),Nothing,Just (3,'c')] == r
--   </pre>
maybe_unzip :: [Maybe (a, b)] -> ([Maybe a], [Maybe b])

-- | Replace <a>Nothing</a> elements with last <a>Just</a> value. This does
--   not alter the length of the list.
--   
--   <pre>
--   maybe_latch 1 [Nothing,Just 2,Nothing,Just 4] == [1,2,2,4]
--   </pre>
maybe_latch :: a -> [Maybe a] -> [a]

-- | Variant requiring initial value is not <a>Nothing</a>.
--   
--   <pre>
--   maybe_latch1 [Just 1,Nothing,Nothing,Just 4] == [1,1,1,4]
--   </pre>
maybe_latch1 :: [Maybe a] -> [a]

-- | <a>map</a> of <a>fmap</a>.
--   
--   <pre>
--   maybe_map negate [Nothing,Just 2] == [Nothing,Just (-2)]
--   </pre>
maybe_map :: (a -> b) -> [Maybe a] -> [Maybe b]

-- | If either is <a>Nothing</a> then <a>False</a>, else <i>eq</i> of
--   values.
maybe_eq_by :: (t -> u -> Bool) -> Maybe t -> Maybe u -> Bool

-- | Join two values, either of which may be missing.
maybe_join' :: (s -> t) -> (s -> s -> t) -> Maybe s -> Maybe s -> Maybe t

-- | <a>maybe_join'</a> of <a>id</a>
maybe_join :: (t -> t -> t) -> Maybe t -> Maybe t -> Maybe t

-- | Apply predicate inside <a>Maybe</a>.
--   
--   <pre>
--   maybe_predicate even (Just 3) == Nothing
--   </pre>
maybe_predicate :: (a -> Bool) -> Maybe a -> Maybe a

-- | <a>map</a> of <a>maybe_predicate</a>.
--   
--   <pre>
--   let r = [Nothing,Nothing,Nothing,Just 4]
--   in maybe_filter even [Just 1,Nothing,Nothing,Just 4] == r
--   </pre>
maybe_filter :: (a -> Bool) -> [Maybe a] -> [Maybe a]

-- | Variant of <a>filter</a> that retains <a>Nothing</a> as a placeholder
--   for removed elements.
--   
--   <pre>
--   filter_maybe even [1..4] == [Nothing,Just 2,Nothing,Just 4]
--   </pre>
filter_maybe :: (a -> Bool) -> [a] -> [Maybe a]


-- | Math functions.
module Music.Theory.Math

-- | Real (alias for <a>Double</a>).
type R = Double

-- | 
--   <a>http://reference.wolfram.com/mathematica/ref/FractionalPart.html</a>
integral_and_fractional_parts :: (Integral i, RealFrac t) => t -> (i, t)

-- | Type specialised.
integer_and_fractional_parts :: RealFrac t => t -> (Integer, t)

-- | 
--   <a>http://reference.wolfram.com/mathematica/ref/FractionalPart.html</a>
--   
--   <pre>
--   import Sound.SC3.Plot {- hsc3-plot -}
--   plotTable1 (map fractional_part [-2.0,-1.99 .. 2.0])
--   </pre>
fractional_part :: RealFrac a => a -> a

-- | <a>http://reference.wolfram.com/mathematica/ref/SawtoothWave.html</a>
--   
--   <pre>
--   plotTable1 (map sawtooth_wave [-2.0,-1.99 .. 2.0])
--   </pre>
sawtooth_wave :: RealFrac a => a -> a

-- | Pretty printer for <a>Rational</a> that elides denominators of
--   <tt>1</tt>.
--   
--   <pre>
--   map rational_pp [1,3/2,2] == ["1","3/2","2"]
--   </pre>
rational_pp :: (Show a, Integral a) => Ratio a -> String

-- | Pretty print ratio as <tt>:</tt> separated integers.
--   
--   <pre>
--   map ratio_pp [1,3/2,2] == ["1:1","3:2","2:1"]
--   </pre>
ratio_pp :: Rational -> String

-- | Predicate that is true if <tt>n/d</tt> can be simplified, ie. where
--   <a>gcd</a> of <tt>n</tt> and <tt>d</tt> is not <tt>1</tt>.
--   
--   <pre>
--   let r = [False,True,False]
--   in map rational_simplifies [(2,3),(4,6),(5,7)] == r
--   </pre>
rational_simplifies :: Integral a => (a, a) -> Bool

-- | <a>numerator</a> and <a>denominator</a> of rational.
rational_nd :: Integral t => Ratio t -> (t, t)

-- | Rational as a whole number, or <a>Nothing</a>.
rational_whole :: Integral a => Ratio a -> Maybe a

-- | Erroring variant.
rational_whole_err :: Integral a => Ratio a -> a

-- | Variant of <a>showFFloat</a>. The <a>Show</a> instance for floats
--   resorts to exponential notation very readily.
--   
--   <pre>
--   [show 0.01,realfloat_pp 2 0.01] == ["1.0e-2","0.01"]
--   </pre>
realfloat_pp :: RealFloat a => Int -> a -> String

-- | Type specialised <a>realfloat_pp</a>.
float_pp :: Int -> Float -> String

-- | Type specialised <a>realfloat_pp</a>.
double_pp :: Int -> Double -> String

-- | Show <i>only</i> positive and negative values, always with sign.
--   
--   <pre>
--   map num_diff_str [-2,-1,0,1,2] == ["-2","-1","","+1","+2"]
--   map show [-2,-1,0,1,2] == ["-2","-1","0","1","2"]
--   </pre>
num_diff_str :: (Num a, Ord a, Show a) => a -> String


-- | Clarence Barlow. "Two Essays on Theory". <i>Computer Music
--   Journal</i>, 11(1):44-60, 1987. Translated by Henning Lohner.
module Music.Theory.Meter.Barlow_1987
traceShow :: a -> b -> b

-- | One indexed variant of <a>genericIndex</a>.
--   
--   <pre>
--   map (at [11..13]) [1..3] == [11,12,13]
--   </pre>
at :: (Integral n) => [a] -> n -> a

-- | Variant of <a>at</a> with boundary rules and specified error message.
--   
--   <pre>
--   map (at' 'x' [11..13]) [0..4] == [1,11,12,13,1]
--   at' 'x' [0] 3 == undefined
--   </pre>
at' :: (Num a, Show a, Integral n, Show n, Show m) => m -> [a] -> n -> a

-- | Variant of <a>mod</a> with input constraints.
--   
--   <pre>
--   mod' (-1) 2 == 1
--   </pre>
mod' :: (Integral a, Show a) => a -> a -> a

-- | Specialised variant of <a>fromIntegral</a>.
to_r :: (Integral n, Show n) => n -> R

-- | Variant on <a>div</a> with input constraints.
div' :: (Integral a, Show a) => String -> a -> a -> a

-- | A stratification is a tree of integral subdivisions.
type Stratification t = [t]

-- | Indispensibilities from stratification.
--   
--   <pre>
--   indispensibilities [3,2,2] == [11,0,6,3,9,1,7,4,10,2,8,5]
--   indispensibilities [2,3,2] == [11,0,6,2,8,4,10,1,7,3,9,5]
--   indispensibilities [2,2,3] == [11,0,4,8,2,6,10,1,5,9,3,7]
--   indispensibilities [3,5] == [14,0,9,3,6,12,1,10,4,7,13,2,11,5,8]
--   </pre>
indispensibilities :: (Integral n, Show n) => Stratification n -> [n]

-- | The indispensibility measure (ψ).
--   
--   <pre>
--   map (lower_psi [2] 1) [1..2] == [1,0]
--   map (lower_psi [3] 1) [1..3] == [2,0,1]
--   map (lower_psi [2,2] 2) [1..4] == [3,0,2,1]
--   map (lower_psi [5] 1) [1..5] == [4,0,3,1,2]
--   map (lower_psi [3,2] 2) [1..6] == [5,0,3,1,4,2]
--   map (lower_psi [2,3] 2) [1..6] == [5,0,2,4,1,3]
--   </pre>
lower_psi :: (Integral a, Show a) => Stratification a -> a -> a -> a

-- | The first <i>n</i>th primes, reversed.
--   
--   <pre>
--   reverse_primes 14 == [43,41,37,31,29,23,19,17,13,11,7,5,3,2]
--   </pre>
reverse_primes :: (Integral n, Show n) => n -> [n]

-- | Generate prime stratification for <i>n</i>.
--   
--   <pre>
--   map prime_stratification [2,3,5,7,11] == [[2],[3],[5],[7],[11]]
--   map prime_stratification [6,8,9,12] == [[3,2],[2,2,2],[3,3],[3,2,2]]
--   map prime_stratification [22,10,4,1] == [[11,2],[5,2],[2,2],[]]
--   map prime_stratification [18,16,12] == [[3,3,2],[2,2,2,2],[3,2,2]]
--   </pre>
prime_stratification :: (Integral n, Show n) => n -> Stratification n

-- | Fundamental indispensibilities for prime numbers (Ψ).
--   
--   <pre>
--   map (upper_psi 2) [1..2] == [1,0]
--   map (upper_psi 3) [1..3] == [2,0,1]
--   map (upper_psi 5) [1..5] == [4,0,3,1,2]
--   map (upper_psi 7) [1..7] == [6,0,4,2,5,1,3]
--   map (upper_psi 11) [1..11] == [10,0,6,4,9,1,7,3,8,2,5]
--   map (upper_psi 13) [1..13] == [12,0,7,4,10,1,8,5,11,2,9,3,6]
--   </pre>
upper_psi :: (Integral a, Show a) => a -> a -> a

-- | Table such that each subsequent row deletes the least indispensibile
--   pulse.
--   
--   <pre>
--   thinning_table [3,2] == [[True,True,True,True,True,True]
--                           ,[True,False,True,True,True,True]
--                           ,[True,False,True,False,True,True]
--                           ,[True,False,True,False,True,False]
--                           ,[True,False,False,False,True,False]
--                           ,[True,False,False,False,False,False]]
--   </pre>
thinning_table :: (Integral n, Show n) => Stratification n -> [[Bool]]

-- | Trivial pretty printer for <a>thinning_table</a>.
--   
--   <pre>
--   putStrLn (thinning_table_pp [3,2])
--   putStrLn (thinning_table_pp [2,3])
--   </pre>
--   
--   <pre>
--   ******   ******
--   *.****   *.****
--   *.*.**   *.**.*
--   *.*.*.   *..*.*
--   *...*.   *..*..
--   *.....   *.....
--   </pre>
thinning_table_pp :: (Integral n, Show n) => Stratification n -> String

-- | Scale values against length of list minus one.
--   
--   <pre>
--   relative_to_length [0..5] == [0.0,0.2,0.4,0.6,0.8,1.0]
--   </pre>
relative_to_length :: (Real a, Fractional b) => [a] -> [b]

-- | Variant of <a>indispensibilities</a> that scales value to lie in
--   <tt>(0,1)</tt>.
--   
--   relative_indispensibilities [3,2] == [1,0,0.6,0.2,0.8,0.4]
relative_indispensibilities :: (Integral n, Show n) => Stratification n -> [R]

-- | Align two meters (given as stratifications) to least common multiple
--   of their degrees. The <a>indispensibilities</a> function is given as
--   an argument so that it may be relative if required. This generates
--   Table 7 (p.58).
--   
--   <pre>
--   let r = [(5,5),(0,0),(2,3),(4,1),(1,4),(3,2)]
--   in align_meters indispensibilities [2,3] [3,2] == r
--   </pre>
--   
--   <pre>
--   let r = [(1,1),(0,0),(0.4,0.6),(0.8,0.2),(0.2,0.8),(0.6,0.4)]
--   in align_meters relative_indispensibilities [2,3] [3,2] == r
--   </pre>
--   
--   <pre>
--   align_meters indispensibilities [2,2,3] [3,5]
--   align_meters relative_indispensibilities [2,2,3] [3,5]
--   </pre>
align_meters :: (t -> [b]) -> t -> t -> [(b, b)]

-- | Type pairing a stratification and a tempo.
type S_MM t = ([t], t)

-- | Variant of <a>div</a> that requires <a>mod</a> be <tt>0</tt>.
whole_div :: Integral a => a -> a -> a

-- | Variant of <a>quot</a> that requires <a>rem</a> be <tt>0</tt>.
whole_quot :: Integral a => a -> a -> a

-- | Rule to prolong stratification of two <a>S_MM</a> values such that
--   pulse at the deeper level are aligned. (Paragraph 2, p.58)
--   
--   <pre>
--   let x = ([2,2,2],1)
--   in prolong_stratifications x x == (fst x,fst x)
--   </pre>
--   
--   <pre>
--   let r = ([2,5,3,3,2],[3,2,5,5])
--   in prolong_stratifications ([2,5],50) ([3,2],60) == r
--   </pre>
--   
--   <pre>
--   prolong_stratifications ([2,2,3],5) ([3,5],4) == ([2,2,3],[3,5])
--   </pre>
prolong_stratifications :: (Integral n, Show n) => S_MM n -> S_MM n -> ([n], [n])

-- | Arithmetic mean (average) of a list.
--   
--   <pre>
--   mean [0..5] == 2.5
--   </pre>
mean :: Fractional a => [a] -> a

-- | Square of <i>n</i>.
--   
--   <pre>
--   square 5 == 25
--   </pre>
square :: Num a => a -> a

-- | Composition of <a>prolong_stratifications</a> and <a>align_meters</a>.
--   
--   <pre>
--   align_s_mm indispensibilities ([2,2,3],5) ([3,5],4)
--   </pre>
align_s_mm :: (Integral n, Show n) => ([n] -> [t]) -> S_MM n -> S_MM n -> [(t, t)]

-- | An attempt at Equation 5 of the <i>CMJ</i> paper. When <i>n</i> is
--   <i>h-1</i> the output is incorrect (it is the product of the correct
--   values for <i>n</i> at <i>h-1</i> and <i>h</i>).
--   
--   <pre>
--   map (upper_psi' 5) [1..5] /= [4,0,3,1,2]
--   map (upper_psi' 7) [1..7] /= [6,0,4,2,5,1,3]
--   map (upper_psi' 11) [1..11] /= [10,0,6,4,9,1,7,3,8,2,5]
--   map (upper_psi' 13) [1..13] /= [12,0,7,4,10,1,8,5,11,2,9,3,6]
--   </pre>
upper_psi' :: (Integral a, Show a) => a -> a -> a

-- | The <i>MPS</i> limit equation given on p.58.
--   
--   <pre>
--   mps_limit 3 == 21 + 7/9
--   </pre>
mps_limit :: Floating a => a -> a

-- | The square of the product of the input sequence is summed, then
--   divided by the square of the sequence length.
--   
--   <pre>
--   mean_square_product [(0,0),(1,1),(2,2),(3,3)] == 6.125
--   mean_square_product [(2,3),(4,5)] == (6^2 + 20^2) / 2^2
--   </pre>
mean_square_product :: Fractional n => [(n, n)] -> n

-- | An incorrect attempt at the description in paragraph two of p.58 of
--   the <i>CMJ</i> paper.
--   
--   <pre>
--   let p ~= q = abs (p - q) &lt; 1e-4
--   metrical_affinity [2,3] 1 [3,2] 1 ~= 0.0324
--   metrical_affinity [2,2,3] 20 [3,5] 16 ~= 0.0028
--   </pre>
metrical_affinity :: (Integral n, Show n) => [n] -> n -> [n] -> n -> R

-- | An incorrect attempt at Equation 6 of the <i>CMJ</i> paper, see
--   omega_z.
--   
--   <pre>
--   let p ~= q = abs (p - q) &lt; 1e-4
--   metrical_affinity' [2,2,2] 1 [2,2,2] 1 ~= 1.06735
--   metrical_affinity' [2,2,2] 1 [2,2,3] 1 ~= 0.57185
--   metrical_affinity' [2,2,2] 1 [2,3,2] 1 ~= 0.48575
--   metrical_affinity' [2,2,2] 1 [3,2,2] 1 ~= 0.45872
--   </pre>
--   
--   <pre>
--   metrical_affinity' [3,2,2] 3 [2,2,3] 2 ~= 0.10282
--   </pre>
metrical_affinity' :: (Integral t, Show t) => [t] -> t -> [t] -> t -> R


-- | List functions.
module Music.Theory.List

-- | Bracket sequence with left and right values.
--   
--   <pre>
--   bracket ('&lt;','&gt;') "1,2,3" == "&lt;1,2,3&gt;"
--   </pre>
bracket :: (a, a) -> [a] -> [a]

-- | Variant where brackets are sequences.
--   
--   <pre>
--   bracket_l ("&lt;:",":&gt;") "1,2,3" == "&lt;:1,2,3:&gt;"
--   </pre>
bracket_l :: ([a], [a]) -> [a] -> [a]

-- | Generic form of <a>rotate_left</a>.
genericRotate_left :: Integral i => i -> [a] -> [a]

-- | Left rotation.
--   
--   <pre>
--   rotate_left 1 [1..3] == [2,3,1]
--   rotate_left 3 [1..5] == [4,5,1,2,3]
--   </pre>
rotate_left :: Int -> [a] -> [a]

-- | Generic form of <a>rotate_right</a>.
genericRotate_right :: Integral n => n -> [a] -> [a]

-- | Right rotation.
--   
--   <pre>
--   rotate_right 1 [1..3] == [3,1,2]
--   </pre>
rotate_right :: Int -> [a] -> [a]

-- | Rotate left by <i>n</i> <a>mod</a> <i>#p</i> places.
--   
--   <pre>
--   rotate 1 [1..3] == [2,3,1]
--   rotate 8 [1..5] == [4,5,1,2,3]
--   </pre>
rotate :: (Integral n) => n -> [a] -> [a]

-- | Rotate right by <i>n</i> places.
--   
--   <pre>
--   rotate_r 8 [1..5] == [3,4,5,1,2]
--   </pre>
rotate_r :: (Integral n) => n -> [a] -> [a]

-- | All rotations.
--   
--   <pre>
--   rotations [0,1,3] == [[0,1,3],[1,3,0],[3,0,1]]
--   </pre>
rotations :: [a] -> [[a]]

-- | Generic form of <a>adj2</a>.
genericAdj2 :: (Integral n) => n -> [t] -> [(t, t)]

-- | Adjacent elements of list, at indicated distance, as pairs.
--   
--   <pre>
--   adj2 1 [1..5] == [(1,2),(2,3),(3,4),(4,5)]
--   adj2 2 [1..4] == [(1,2),(3,4)]
--   adj2 3 [1..5] == [(1,2),(4,5)]
--   </pre>
adj2 :: Int -> [t] -> [(t, t)]

-- | Append first element to end of list.
--   
--   <pre>
--   close [1..3] == [1,2,3,1]
--   </pre>
close :: [a] -> [a]

-- | <a>adj2</a> <a>.</a> <a>close</a>.
--   
--   <pre>
--   adj2_cyclic 1 [1..3] == [(1,2),(2,3),(3,1)]
--   </pre>
adj2_cyclic :: Int -> [t] -> [(t, t)]

-- | Interleave elements of <i>p</i> and <i>q</i>.
--   
--   <pre>
--   interleave [1..3] [4..6] == [1,4,2,5,3,6]
--   interleave ".+-" "abc" == ".a+b-c"
--   interleave [1..3] [] == []
--   </pre>
interleave :: [b] -> [b] -> [b]

-- | Variant that continues with the longer input.
--   
--   <pre>
--   interleave_continue ".+-" "abc" == ".a+b-c"
--   interleave_continue [1..3] [] == [1..3]
--   interleave_continue [] [1..3] == [1..3]
--   </pre>
interleave_continue :: [a] -> [a] -> [a]

-- | <a>interleave</a> of <a>rotate_left</a> by <i>i</i> and <i>j</i>.
--   
--   <pre>
--   interleave_rotations 9 3 [1..13] == [10,4,11,5,12,6,13,7,1,8,2,9,3,10,4,11,5,12,6,13,7,1,8,2,9,3]
--   </pre>
interleave_rotations :: Int -> Int -> [b] -> [b]

-- | Count occurences of elements in list.
--   
--   <pre>
--   histogram "hohoh" == [('h',3),('o',2)]
--   </pre>
histogram :: (Ord a, Integral i) => [a] -> [(a, i)]

-- | List segments of length <i>i</i> at distance <i>j</i>.
--   
--   <pre>
--   segments 2 1 [1..5] == [[1,2],[2,3],[3,4],[4,5]]
--   segments 2 2 [1..5] == [[1,2],[3,4]]
--   </pre>
segments :: Int -> Int -> [a] -> [[a]]

-- | <a>foldl1</a> <a>intersect</a>.
--   
--   <pre>
--   intersect_l [[1,2],[1,2,3],[1,2,3,4]] == [1,2]
--   </pre>
intersect_l :: Eq a => [[a]] -> [a]

-- | <a>foldl1</a> <a>union</a>.
--   
--   <pre>
--   sort (union_l [[1,3],[2,3],[3]]) == [1,2,3]
--   </pre>
union_l :: Eq a => [[a]] -> [a]

-- | Intersection of adjacent elements of list at distance <i>n</i>.
--   
--   <pre>
--   adj_intersect 1 [[1,2],[1,2,3],[1,2,3,4]] == [[1,2],[1,2,3]]
--   </pre>
adj_intersect :: Eq a => Int -> [[a]] -> [[a]]

-- | List of cycles at distance <i>n</i>.
--   
--   <pre>
--   cycles 2 [1..6] == [[1,3,5],[2,4,6]]
--   cycles 3 [1..9] == [[1,4,7],[2,5,8],[3,6,9]]
--   cycles 4 [1..8] == [[1,5],[2,6],[3,7],[4,8]]
--   </pre>
cycles :: Int -> [a] -> [[a]]

-- | Given accesors for <i>key</i> and <i>value</i> collate input.
--   
--   <pre>
--   let r = [('A',"a"),('B',"bd"),('C',"ce"),('D',"f")]
--   in collate_on fst snd (zip "ABCBCD" "abcdef")
--   </pre>
collate_on :: (Eq k, Ord k) => (a -> k) -> (a -> v) -> [a] -> [(k, [v])]

-- | <a>collate_on</a> of <a>fst</a> and <a>snd</a>.
--   
--   <pre>
--   collate (zip [1,2,1] "abc") == [(1,"ac"),(2,"b")]
--   </pre>
collate :: Ord a => [(a, b)] -> [(a, [b])]

-- | Make <i>assoc</i> list with given <i>key</i>.
--   
--   <pre>
--   with_key 'a' [1..3] == [('a',1),('a',2),('a',3)]
--   </pre>
with_key :: k -> [v] -> [(k, v)]

-- | Intervals to values, zero is <i>n</i>.
--   
--   <pre>
--   dx_d 5 [1,2,3] == [5,6,8,11]
--   </pre>
dx_d :: (Num a) => a -> [a] -> [a]

-- | Variant that takes initial value and separates final value. This is an
--   appropriate function for <a>mapAccumL</a>.
--   
--   <pre>
--   dx_d' 5 [1,2,3] == (11,[5,6,8])
--   dx_d' 0 [1,1,1] == (3,[0,1,2])
--   </pre>
dx_d' :: Num t => t -> [t] -> (t, [t])

-- | Integrate, ie. pitch class segment to interval sequence.
--   
--   <pre>
--   d_dx [5,6,8,11] == [1,2,3]
--   d_dx [] == []
--   </pre>
d_dx :: (Num a) => [a] -> [a]

-- | Elements of <i>p</i> not in <i>q</i>.
--   
--   <pre>
--   [1,2,3] `difference` [1,2] == [3]
--   </pre>
difference :: (Eq a) => [a] -> [a] -> [a]

-- | Is <i>p</i> a subset of <i>q</i>, ie. is <a>intersect</a> of <i>p</i>
--   and <i>q</i> <a>==</a> <i>p</i>.
--   
--   <pre>
--   is_subset [1,2] [1,2,3] == True
--   </pre>
is_subset :: Eq a => [a] -> [a] -> Bool

-- | Is <i>p</i> a superset of <i>q</i>, ie. <a>flip</a> <a>is_subset</a>.
--   
--   <pre>
--   is_superset [1,2,3] [1,2] == True
--   </pre>
is_superset :: Eq a => [a] -> [a] -> Bool

-- | Is <i>p</i> a subsequence of <i>q</i>, ie. synonym for
--   <a>isInfixOf</a>.
--   
--   <pre>
--   subsequence [1,2] [1,2,3] == True
--   </pre>
subsequence :: (Eq a) => [a] -> [a] -> Bool

-- | Variant of <a>elemIndices</a> that requires <i>e</i> to be unique in
--   <i>p</i>.
--   
--   <pre>
--   elem_index_unique 'a' "abcda" == undefined
--   </pre>
elem_index_unique :: (Eq a) => a -> [a] -> Int

-- | Basis of <a>find_bounds</a>. There is an option to consider the last
--   element specially, and if equal to the last span is given.
find_bounds' :: Bool -> (t -> s -> Ordering) -> [(t, t)] -> s -> Maybe (t, t)

-- | Find adjacent elements of list that bound element under given
--   comparator.
--   
--   <pre>
--   let {f = find_bounds True compare [1..5]
--       ;r = [Nothing,Just (1,2),Just (3,4),Just (4,5)]}
--   in map f [0,1,3.5,5] == r
--   </pre>
find_bounds :: Bool -> (t -> s -> Ordering) -> [t] -> s -> Maybe (t, t)

-- | Variant of <a>drop</a> from right of list.
--   
--   <pre>
--   dropRight 1 [1..9] == [1..8]
--   </pre>
dropRight :: Int -> [a] -> [a]

-- | Variant of <a>dropWhile</a> from right of list.
--   
--   <pre>
--   dropWhileRight Data.Char.isDigit "A440" == "A"
--   </pre>
dropWhileRight :: (a -> Bool) -> [a] -> [a]

-- | Apply <i>f</i> at first element, and <i>g</i> at all other elements.
--   
--   <pre>
--   at_head negate id [1..5] == [-1,2,3,4,5]
--   </pre>
at_head :: (a -> b) -> (a -> b) -> [a] -> [b]

-- | Apply <i>f</i> at all but last element, and <i>g</i> at last element.
--   
--   <pre>
--   at_last (* 2) negate [1..4] == [2,4,6,-4]
--   </pre>
at_last :: (a -> b) -> (a -> b) -> [a] -> [b]

-- | Separate list into an initial list and a last element tuple.
--   
--   <pre>
--   separate_last [1..5] == ([1..4],5)
--   </pre>
separate_last :: [a] -> ([a], a)

-- | Replace directly repeated elements with <a>Nothing</a>.
--   
--   <pre>
--   indicate_repetitions "abba" == [Just 'a',Just 'b',Nothing,Just 'a']
--   </pre>
indicate_repetitions :: Eq a => [a] -> [Maybe a]

-- | <a>groupBy</a> does not make adjacent comparisons, it compares each
--   new element to the start of the group. This function is the adjacent
--   variant.
--   
--   <pre>
--   groupBy (&lt;) [1,2,3,2,4,1,5,9] == [[1,2,3,2,4],[1,5,9]]
--   adjacent_groupBy (&lt;) [1,2,3,2,4,1,5,9] == [[1,2,3],[2,4],[1,5,9]]
--   </pre>
adjacent_groupBy :: (a -> a -> Bool) -> [a] -> [[a]]

-- | <a>groupBy</a> on <i>structure</i> of <a>Maybe</a>, ie. all
--   <a>Just</a> compare equal.
--   
--   <pre>
--   let r = [[Just 1],[Nothing,Nothing],[Just 4,Just 5]]
--   in group_just [Just 1,Nothing,Nothing,Just 4,Just 5] == r
--   </pre>
group_just :: [Maybe a] -> [[Maybe a]]

-- | Predicate to determine if all elements of the list are <a>==</a>.
all_eq :: Eq n => [n] -> Bool

-- | <a>groupBy</a> of <a>sortBy</a>.
--   
--   <pre>
--   let r = [[('1','a'),('1','c')],[('2','d')],[('3','b'),('3','e')]]
--   in sort_group_on fst (zip "13123" "abcde") == r
--   </pre>
sort_group_on :: Ord b => (a -> b) -> [a] -> [[a]]

-- | Maybe cons element onto list.
--   
--   <pre>
--   Nothing `mcons` "something" == "something"
--   Just 's' `mcons` "omething" == "something"
--   </pre>
mcons :: Maybe a -> [a] -> [a]

-- | Comparison function type.
type Compare_F a = a -> a -> Ordering

-- | If <i>f</i> compares <a>EQ</a>, defer to <i>g</i>.
two_stage_compare :: Compare_F a -> Compare_F a -> Compare_F a

-- | Invert <a>Ordering</a>.
ordering_invert :: Ordering -> Ordering

-- | Sort sequence <i>a</i> based on ordering of sequence <i>b</i>.
--   
--   <pre>
--   sort_to "abc" [1,3,2] == "acb"
--   sort_to "adbce" [1,4,2,3,5] == "abcde"
--   </pre>
sort_to :: Ord i => [e] -> [i] -> [e]

-- | <a>flip</a> of <a>sort_to</a>.
--   
--   <pre>
--   sort_on [1,4,2,3,5] "adbce" == "abcde"
--   </pre>
sort_on :: Ord i => [i] -> [e] -> [e]

-- | <a>sortBy</a> of <a>two_stage_compare</a>.
sort_by_two_stage :: (Ord b, Ord c) => (a -> b) -> (a -> c) -> [a] -> [a]

-- | Given a comparison function, merge two ascending lists.
--   
--   <pre>
--   mergeBy compare [1,3,5] [2,4] == [1..5]
--   </pre>
merge_by :: Compare_F a -> [a] -> [a] -> [a]

-- | <a>mergeBy</a> of <a>two_stage_compare</a>.
merge_by_two_stage :: Ord b => (a -> b) -> Compare_F c -> (a -> c) -> [a] -> [a] -> [a]

-- | <tt>mergeBy</tt> <a>compare</a>.
merge :: Ord a => [a] -> [a] -> [a]

-- | Merge list of sorted lists given comparison function. Note that this
--   is not equal to <a>mergeAll</a>.
merge_set_by :: (a -> a -> Ordering) -> [[a]] -> [a]

-- | <a>merge_set_by</a> of <a>compare</a>.
--   
--   <pre>
--   merge_set [[1,3,5,7,9],[2,4,6,8],[10]] == [1..10]
--   </pre>
merge_set :: Ord a => [[a]] -> [a]

-- | <a>merge_by</a> variant that joins (resolves) equal elements.
--   
--   <pre>
--   let {left p _ = p
--       ;right _ q = q
--       ;cmp = compare `on` fst
--       ;p = zip [1,3,5] "abc"
--       ;q = zip [1,2,3] "ABC"
--       ;left_r = [(1,'a'),(2,'B'),(3,'b'),(5,'c')]
--       ;right_r = [(1,'A'),(2,'B'),(3,'C'),(5,'c')]}
--   in merge_by_resolve left cmp p q == left_r &amp;&amp;
--      merge_by_resolve right cmp p q == right_r
--   </pre>
merge_by_resolve :: (a -> a -> a) -> Compare_F a -> [a] -> [a] -> [a]

-- | Apply <i>f</i> to both elements of a two-tuple, ie. <tt>bimap</tt>
--   <i>f</i> <i>f</i>.
bimap1 :: (t -> u) -> (t, t) -> (u, u)


-- | Permutation functions.
module Music.Theory.Permutations

-- | Factorial function.
--   
--   <pre>
--   (factorial 13,maxBound::Int)
--   </pre>
factorial :: (Ord a, Num a) => a -> a

-- | Number of <i>k</i> element permutations of a set of <i>n</i> elements.
--   
--   <pre>
--   (nk_permutations 4 3,nk_permutations 13 3) == (24,1716)
--   </pre>
nk_permutations :: Integral a => a -> a -> a

-- | Number of <i>nk</i> permutations where <i>n</i> <a>==</a> <i>k</i>.
--   
--   <pre>
--   map n_permutations [1..8] == [1,2,6,24,120,720,5040,40320]
--   n_permutations 16 `div` 1000000 == 20922789
--   </pre>
n_permutations :: (Integral a) => a -> a

-- | Generate the permutation from <i>p</i> to <i>q</i>, ie. the
--   permutation that, when applied to <i>p</i>, gives <i>q</i>.
--   
--   <pre>
--   apply_permutation (permutation [0,1,3] [1,0,3]) [0,1,3] == [1,0,3]
--   </pre>
permutation :: (Eq a) => [a] -> [a] -> Permute

-- | Apply permutation <i>f</i> to <i>p</i>.
--   
--   <pre>
--   let p = permutation [1..4] [4,3,2,1]
--   in apply_permutation p [1..4] == [4,3,2,1]
--   </pre>
apply_permutation :: (Eq a) => Permute -> [a] -> [a]

-- | Composition of <a>apply_permutation</a> and <a>from_cycles</a>.
--   
--   <pre>
--   apply_permutation_c [[0,3],[1,2]] [1..4] == [4,3,2,1]
--   apply_permutation_c [[0,2],[1],[3,4]] [1..5] == [3,2,1,5,4]
--   apply_permutation_c [[0,1,4],[2,3]] [1..5] == [2,5,4,3,1]
--   apply_permutation_c [[0,1,3],[2,4]] [1..5] == [2,4,5,1,3]
--   </pre>
apply_permutation_c :: (Eq a) => [[Int]] -> [a] -> [a]

-- | True if the inverse of <i>p</i> is <i>p</i>.
--   
--   <pre>
--   non_invertible (permutation [0,1,3] [1,0,3]) == True
--   </pre>
--   
--   <pre>
--   let p = permutation [1..4] [4,3,2,1]
--   in non_invertible p == True &amp;&amp; P.cycles p == [[0,3],[1,2]]
--   </pre>
non_invertible :: Permute -> Bool

-- | Generate a permutation from the cycles <i>c</i>.
--   
--   <pre>
--   apply_permutation (from_cycles [[0,1,2,3]]) [1..4] == [2,3,4,1]
--   </pre>
from_cycles :: [[Int]] -> Permute

-- | Generate all permutations of size <i>n</i>.
--   
--   <pre>
--   map one_line (permutations_n 3) == [[1,2,3],[1,3,2]
--                                      ,[2,1,3],[2,3,1]
--                                      ,[3,1,2],[3,2,1]]
--   </pre>
permutations_n :: Int -> [Permute]

-- | Composition of <i>q</i> then <i>p</i>.
--   
--   <pre>
--   let {p = from_cycles [[0,2],[1],[3,4]]
--       ;q = from_cycles [[0,1,4],[2,3]]
--       ;r = p `compose` q}
--   in apply_permutation r [1,2,3,4,5] == [2,4,5,1,3]
--   </pre>
compose :: Permute -> Permute -> Permute

-- | Two line notation of <i>p</i>.
--   
--   <pre>
--   two_line (permutation [0,1,3] [1,0,3]) == ([1,2,3],[2,1,3])
--   </pre>
two_line :: Permute -> ([Int], [Int])

-- | One line notation of <i>p</i>.
--   
--   <pre>
--   one_line (permutation [0,1,3] [1,0,3]) == [2,1,3]
--   </pre>
--   
--   <pre>
--   map one_line (permutations_n 3) == [[1,2,3],[1,3,2]
--                                      ,[2,1,3],[2,3,1]
--                                      ,[3,1,2],[3,2,1]]
--   </pre>
one_line :: Permute -> [Int]

-- | Variant of <a>one_line</a> that produces a compact string.
--   
--   <pre>
--   one_line_compact (permutation [0,1,3] [1,0,3]) == "213"
--   </pre>
--   
--   <pre>
--   let p = permutations_n 3
--   in unwords (map one_line_compact p) == "123 132 213 231 312 321"
--   </pre>
one_line_compact :: Permute -> String

-- | Multiplication table of symmetric group <i>n</i>.
--   
--   <pre>
--   unlines (map (unwords . map one_line_compact) (multiplication_table 3))
--   </pre>
--   
--   <pre>
--   ==&gt; 123 132 213 231 312 321
--       132 123 312 321 213 231
--       213 231 123 132 321 312
--       231 213 321 312 123 132
--       312 321 132 123 231 213
--       321 312 231 213 132 123
--   </pre>
multiplication_table :: Int -> [[Permute]]


-- | List permutation functions.
module Music.Theory.Permutations.List

-- | Generate all permutations.
--   
--   <pre>
--   permutations [0,3] == [[0,3],[3,0]]
--   length (permutations [1..5]) == P.n_permutations 5
--   </pre>
permutations :: (Eq a) => [a] -> [[a]]

-- | Generate all distinct permutations of a multi-set.
--   
--   <pre>
--   multiset_permutations [0,1,1] == [[0,1,1],[1,1,0],[1,0,1]]
--   </pre>
multiset_permutations :: (Ord a) => [a] -> [[a]]


-- | Symetric Group S4 as related to the composition "Nomos Alpha" by
--   Iannis Xenakis. In particular in relation to the discussion in
--   "Towards a Philosophy of Music", <i>Formalized Music</i> pp. 219 --
--   221
module Music.Theory.Xenakis.S4

-- | <a>Label</a>s for elements of the symmetric group P4.
data Label
A :: Label
B :: Label
C :: Label
D :: Label
D2 :: Label
E :: Label
E2 :: Label
G :: Label
G2 :: Label
I :: Label
L :: Label
L2 :: Label
Q1 :: Label
Q2 :: Label
Q3 :: Label
Q4 :: Label
Q5 :: Label
Q6 :: Label
Q7 :: Label
Q8 :: Label
Q9 :: Label
Q10 :: Label
Q11 :: Label
Q12 :: Label

-- | Initial half of <a>Seq</a> (ie. #4). The complete <a>Seq</a> is formed
--   by appending the <a>complement</a> of the <a>Half_Seq</a>.
type Half_Seq = [Int]

-- | Complete sequence (ie. #8).
type Seq = [Int]

-- | Complement of a <a>Half_Seq</a>.
--   
--   <pre>
--   map complement [[4,1,3,2],[6,7,8,5]] == [[8,5,7,6],[2,3,4,1]]
--   </pre>
complement :: Half_Seq -> Half_Seq

-- | Form <a>Seq</a> from <a>Half_Seq</a>.
--   
--   <pre>
--   full_seq [3,2,4,1] == [3,2,4,1,7,6,8,5]
--   label_of (full_seq [3,2,4,1]) == G2
--   label_of (full_seq [1,4,2,3]) == L
--   </pre>
full_seq :: Half_Seq -> Seq

-- | Lower <a>Half_Seq</a>, ie. <a>complement</a> or <a>id</a>.
--   
--   <pre>
--   map lower [[4,1,3,2],[6,7,8,5]] == [[4,1,3,2],[2,3,4,1]]
--   </pre>
lower :: Half_Seq -> Half_Seq

-- | Application of <a>Label</a> <i>p</i> on <i>q</i>.
--   
--   <pre>
--   l_on Q1 I == Q1
--   l_on D A == G
--   [l_on L L,l_on E D,l_on D E] == [L2,C,B]
--   </pre>
l_on :: Label -> Label -> Label

-- | <a>Seq</a> of <a>Label</a>, inverse of <a>label_of</a>.
--   
--   <pre>
--   seq_of Q1 == [8,7,5,6,4,3,1,2]
--   </pre>
seq_of :: Label -> Seq

-- | <a>Half_Seq</a> of <a>Label</a>, ie. <a>half_seq</a> <a>.</a>
--   <a>seq_of</a>.
--   
--   <pre>
--   half_seq_of Q1 == [8,7,5,6]
--   </pre>
half_seq_of :: Label -> Seq

-- | <a>Half_Seq</a> of <a>Seq</a>, ie. <a>take</a> <tt>4</tt>.
--   
--   <pre>
--   complement (half_seq (seq_of Q7)) == [3,4,2,1]
--   </pre>
half_seq :: Seq -> Half_Seq

-- | Reverse table <a>lookup</a>.
--   
--   <pre>
--   reverse_lookup 'b' (zip [1..] ['a'..]) == Just 2
--   lookup 2 (zip [1..] ['a'..]) == Just 'b'
--   </pre>
reverse_lookup :: (Eq a) => a -> [(b, a)] -> Maybe b

-- | <a>Label</a> of <a>Seq</a>, inverse of <a>seq_of</a>.
--   
--   <pre>
--   label_of [8,7,5,6,4,3,1,2] == Q1
--   label_of (seq_of Q4) == Q4
--   </pre>
label_of :: Seq -> Label

-- | <a>True</a> if two <a>Half_Seq</a>s are complementary, ie. form a
--   <a>Seq</a>.
--   
--   <pre>
--   complementary [4,2,1,3] [8,6,5,7] == True
--   </pre>
complementary :: Half_Seq -> Half_Seq -> Bool

-- | Relation between to <a>Half_Seq</a> values as a
--   <i>(complementary,permutation)</i> pair.
type Rel = (Bool, Permute)

-- | Determine <a>Rel</a> of <a>Half_Seq</a>s.
--   
--   <pre>
--   relate [1,4,2,3] [1,3,4,2] == (False,P.listPermute 4 [0,3,1,2])
--   relate [1,4,2,3] [8,5,6,7] == (True,P.listPermute 4 [1,0,2,3])
--   </pre>
relate :: Half_Seq -> Half_Seq -> Rel

-- | <a>Rel</a> from <a>Label</a> <i>p</i> to <i>q</i>.
--   
--   <pre>
--   relate_l L L2 == (False,P.listPermute 4 [0,3,1,2])
--   </pre>
relate_l :: Label -> Label -> Rel

-- | <a>relate</a> adjacent <a>Half_Seq</a>, see also <a>relations_l</a>.
relations :: [Half_Seq] -> [Rel]

-- | <a>relate</a> adjacent <a>Label</a>s.
--   
--   <pre>
--   relations_l [L2,L,A] == [(False,P.listPermute 4 [0,2,3,1])
--                           ,(False,P.listPermute 4 [2,0,1,3])]
--   </pre>
relations_l :: [Label] -> [Rel]

-- | Apply <a>Rel</a> to <a>Half_Seq</a>.
--   
--   <pre>
--   apply_relation (False,P.listPermute 4 [0,3,1,2]) [1,4,2,3] == [1,3,4,2]
--   </pre>
apply_relation :: Rel -> Half_Seq -> Half_Seq

-- | Apply sequence of <a>Rel</a> to initial <a>Half_Seq</a>.
apply_relations :: [Rel] -> Half_Seq -> [Half_Seq]

-- | Variant of <a>apply_relations</a>.
--   
--   <pre>
--   apply_relations_l (relations_l [L2,L,A,Q1]) L2 == [L2,L,A,Q1]
--   </pre>
apply_relations_l :: [Rel] -> Label -> [Label]

-- | Enumeration of set of <i>faces</i> of a cube.
data Face
F_Back :: Face
F_Front :: Face
F_Right :: Face
F_Left :: Face
F_Bottom :: Face
F_Top :: Face

-- | Table indicating set of faces of cubes as drawn in Fig. VIII-6
--   (p.220).
--   
--   <pre>
--   lookup [1,4,6,7] faces == Just F_Left
--   reverse_lookup F_Right faces == Just [2,3,5,8]
--   </pre>
faces :: [([Int], Face)]

-- | Fig. VIII-6. Hexahedral (Octahedral) Group (p. 220)
--   
--   <pre>
--   length viii_6_l == 24
--   take 7 viii_6_l == [L2,L,A,Q1,Q7,Q3,Q9]
--   </pre>
viii_6_l :: [Label]

-- | Fig. VIII-7 (p.221)
--   
--   <pre>
--   map (take 4) (take 4 viii_7) == [[I,A,B,C]
--                                   ,[A,I,C,B]
--                                   ,[B,C,I,A]
--                                   ,[C,B,A,I]]
--   </pre>
viii_7 :: [[Label]]

-- | Fig. VIII-6/b <tt>Labels</tt> (p.221)
--   
--   <pre>
--   length viii_6b_l == length viii_6_l
--   take 8 viii_6b_l == [I,A,B,C,D2,D,E2,E]
--   </pre>
viii_6b_l :: [Label]

-- | Fig. VIII-6/b <a>Half_Seq</a>.
--   
--   <pre>
--   viii_6b_p' == map half_seq_of viii_6b_l
--   nub (map (length . nub) viii_6b_p') == [4]
--   </pre>
viii_6b_p' :: [Half_Seq]

-- | Variant of <a>viii_6b</a> with <a>Half_Seq</a>.
viii_6b' :: [(Label, Half_Seq)]

-- | Fig. VIII-6/b.
--   
--   <pre>
--   map (viii_6b !!) [0,8,16] == [(I,[1,2,3,4,5,6,7,8])
--                                ,(G2,[3,2,4,1,7,6,8,5])
--                                ,(Q8,[6,8,5,7,2,4,1,3])]
--   </pre>
viii_6b :: [(Label, Seq)]

-- | The sequence of <a>Rel</a> to give <a>viii_6_l</a> from <a>L2</a>.
--   
--   <pre>
--   apply_relations_l viii_6_relations L2 == viii_6_l
--   length (nub viii_6_relations) == 14
--   </pre>
viii_6_relations :: [Rel]

-- | The sequence of <a>Rel</a> to give <a>viii_6b_l</a> from <a>I</a>.
--   
--   <pre>
--   apply_relations_l viii_6b_relations I == viii_6b_l
--   length (nub viii_6b_relations) == 10
--   </pre>
viii_6b_relations :: [Rel]
instance GHC.Show.Show Music.Theory.Xenakis.S4.Face
instance GHC.Classes.Ord Music.Theory.Xenakis.S4.Face
instance GHC.Enum.Bounded Music.Theory.Xenakis.S4.Face
instance GHC.Enum.Enum Music.Theory.Xenakis.S4.Face
instance GHC.Classes.Eq Music.Theory.Xenakis.S4.Face
instance GHC.Show.Show Music.Theory.Xenakis.S4.Label
instance GHC.Enum.Bounded Music.Theory.Xenakis.S4.Label
instance GHC.Enum.Enum Music.Theory.Xenakis.S4.Label
instance GHC.Classes.Ord Music.Theory.Xenakis.S4.Label
instance GHC.Classes.Eq Music.Theory.Xenakis.S4.Label


-- | Place notation (method ringing).
--   
--   Morris, R. G. T. "Place Notation" Central Council of Church Bell
--   Ringers (1984). <a>http://www.cccbr.org.uk/bibliography/</a>
module Music.Theory.Permutations.Morris_1984

-- | A change either swaps all adjacent bells, or holds a subset of bells.
data Change
Swap_All :: Change
Hold :: [Int] -> Change

-- | A method is a sequence of changes, if symmetrical only have the
--   changes are given and the lead end.
data Method
Method :: [Change] -> (Maybe Change) -> Method

-- | Compete list of <a>Change</a>s at <a>Method</a>, writing out
--   symmetries.
method_changes :: Method -> [Change]

-- | Parse a change notation.
--   
--   <pre>
--   map parse_change ["-","x","38"] == [Swap_All,Swap_All,Hold [3,8]]
--   </pre>
parse_change :: String -> Change

-- | Separate changes.
--   
--   <pre>
--   split_changes "-38-14-1258-36-14-58-16-78"
--   split_changes "345.145.5.1.345" == ["345","145","5","1","345"]
--   </pre>
split_changes :: String -> [String]

-- | Parse <a>Method</a> from the sequence of changes with possible lead
--   end.
--   
--   <pre>
--   parse_method ("-38-14-1258-36-14-58-16-78",Just "12")
--   </pre>
parse_method :: (String, Maybe String) -> Method
is_swap_all :: String -> Bool

-- | Swap elemets of two-tuple (pair).
--   
--   <pre>
--   swap_pair (1,2) == (2,1)
--   </pre>
swap_pair :: (s, t) -> (t, s)

-- | Flatten list of pairs.
--   
--   <pre>
--   flatten_pairs [(1,2),(3,4)] == [1..4]
--   </pre>
flatten_pairs :: [(a, a)] -> [a]

-- | Swap all adjacent pairs at list.
--   
--   <pre>
--   swap_all [1 .. 8] == [2,1,4,3,6,5,8,7]
--   </pre>
swap_all :: [a] -> [a]

-- | Parse abbreviated <a>Hold</a> notation, characters are hexedecimal.
--   
--   <pre>
--   to_abbrev "38A" == [3,8,10]
--   </pre>
to_abbrev :: String -> [Int]

-- | Given a <a>Hold</a> notation, generate permutation cycles.
--   
--   <pre>
--   let r = [Right (1,2),Left 3,Right (4,5),Right (6,7),Left 8]
--   in gen_swaps 8 [3,8] == r
--   </pre>
--   
--   <pre>
--   let r = [Left 1,Left 2,Right (3,4),Right (5,6),Right (7,8)]
--   gen_swaps 8 [1,2] == r
--   </pre>
gen_swaps :: (Num t, Ord t) => t -> [t] -> [Either t (t, t)]

-- | Two-tuple to two element list.
pair_to_list :: (t, t) -> [t]

-- | Swap notation to plain permutation cycles notation.
--   
--   <pre>
--   let n = [Left 1,Left 2,Right (3,4),Right (5,6),Right (7,8)]
--   in swaps_to_cycles n == [[1],[2],[3,4],[5,6],[7,8]]
--   </pre>
swaps_to_cycles :: [Either t (t, t)] -> [[t]]

-- | One-indexed permutation cycles to zero-indexed.
--   
--   <pre>
--   let r = [[0],[1],[2,3],[4,5],[6,7]]
--   in to_zero_indexed [[1],[2],[3,4],[5,6],[7,8]] == r
--   </pre>
to_zero_indexed :: Enum t => [[t]] -> [[t]]

-- | Apply abbreviated <a>Hold</a> notation, given cardinality.
--   
--   <pre>
--   swap_abbrev 8 [3,8] [2,1,4,3,6,5,8,7] == [1,2,4,6,3,8,5,7]
--   </pre>
swap_abbrev :: Eq a => Int -> [Int] -> [a] -> [a]

-- | Apply a <a>Change</a>.
apply_change :: Eq a => Int -> Change -> [a] -> [a]

-- | Apply a <a>Method</a>, gives next starting sequence and the course of
--   the method.
--   
--   <pre>
--   let r = ([1,2,4,5,3]
--           ,[[1,2,3,4,5],[2,1,3,4,5],[2,3,1,4,5],[3,2,4,1,5],[3,4,2,5,1]
--            ,[4,3,2,5,1],[4,2,3,1,5],[2,4,1,3,5],[2,1,4,3,5],[1,2,4,3,5]])
--   in apply_method cambridgeshire_slow_course_doubles [1..5] == r
--   </pre>
apply_method :: Eq a => Method -> [a] -> ([a], [[a]])

-- | Iteratively apply a <a>Method</a> until it closes (ie. arrives back at
--   the starting sequence).
--   
--   <pre>
--   length (closed_method cambridgeshire_slow_course_doubles [1..5]) == 3
--   </pre>
closed_method :: Eq a => Method -> [a] -> [[[a]]]

-- | <a>concat</a> of <a>closed_method</a> with initial sequence appended.
closed_method' :: Eq a => Method -> [a] -> [[a]]

-- | Cambridgeshire Slow Course Doubles.
--   
--   
--   <a>https://rsw.me.uk/blueline/methods/view/Cambridgeshire_Slow_Course_Doubles</a>
--   
--   <pre>
--   length (closed_method cambridgeshire_slow_course_doubles [1..5]) == 3
--   </pre>
cambridgeshire_slow_course_doubles :: Method

-- | Double Cambridge Cyclic Bob Minor.
--   
--   
--   <a>https://rsw.me.uk/blueline/methods/view/Double_Cambridge_Cyclic_Bob_Minor</a>
--   
--   <pre>
--   length (closed_method double_cambridge_cyclic_bob_minor [1..6]) == 5
--   </pre>
double_cambridge_cyclic_bob_minor :: Method

-- | Hammersmith Bob Triples
--   
--   <a>https://rsw.me.uk/blueline/methods/view/Hammersmith_Bob_Triples</a>
--   
--   <pre>
--   length (closed_method hammersmith_bob_triples [1..7]) == 6
--   </pre>
hammersmith_bob_triples :: Method

-- | Cambridge Surprise Major.
--   
--   
--   <a>https://rsw.me.uk/blueline/methods/view/Cambridge_Surprise_Major</a>
--   
--   <pre>
--   length (closed_method cambridge_surprise_major [1..8]) == 7
--   </pre>
cambridge_surprise_major :: Method

-- | Smithsonian Surprise Royal.
--   
--   
--   <a>https://rsw.me.uk/blueline/methods/view/Smithsonian_Surprise_Royal</a>
--   
--   <pre>
--   length (closed_method smithsonian_surprise_royal [1..10]) == 9
--   </pre>
smithsonian_surprise_royal :: Method
instance GHC.Show.Show Music.Theory.Permutations.Morris_1984.Method
instance GHC.Classes.Eq Music.Theory.Permutations.Morris_1984.Method
instance GHC.Show.Show Music.Theory.Permutations.Morris_1984.Change
instance GHC.Classes.Eq Music.Theory.Permutations.Morris_1984.Change


-- | Common music notation pitch values.
module Music.Theory.Pitch

-- | Pitch classes are modulo twelve integers.
type PitchClass = Int

-- | Octaves are integers, the octave of middle C is <tt>4</tt>.
type Octave = Int

-- | <a>Octave</a> and <a>PitchClass</a> duple.
type Octave_PitchClass i = (i, i)
type OctPC = (Octave, PitchClass)

-- | Common music notation pitch value.
data Pitch
Pitch :: Note_T -> Alteration_T -> Octave -> Pitch
[note] :: Pitch -> Note_T
[alteration] :: Pitch -> Alteration_T
[octave] :: Pitch -> Octave

-- | Generalised pitch, given by a generalised alteration.
data Pitch'
Pitch' :: Note_T -> Alteration_T' -> Octave -> Pitch'

-- | Pretty printer for <a>Pitch'</a>.
pitch'_pp :: Pitch' -> String

-- | <a>Pitch'</a> printed without octave.
pitch'_class_pp :: Pitch' -> String

-- | Simplify <a>Pitch</a> to standard 12ET by deleting quarter tones.
--   
--   <pre>
--   let p = Pitch A QuarterToneSharp 4
--   in alteration (pitch_clear_quarter_tone p) == Sharp
--   </pre>
pitch_clear_quarter_tone :: Pitch -> Pitch

-- | <a>Pitch</a> to <a>Octave</a> and <a>PitchClass</a> notation.
--   
--   <pre>
--   pitch_to_octpc (Pitch F Sharp 4) == (4,6)
--   </pre>
pitch_to_octpc :: Integral i => Pitch -> Octave_PitchClass i

-- | Is <a>Pitch</a> 12-ET.
pitch_is_12et :: Pitch -> Bool

-- | <a>Pitch</a> to midi note number notation.
--   
--   <pre>
--   pitch_to_midi (Pitch A Natural 4) == 69
--   </pre>
pitch_to_midi :: Integral i => Pitch -> i

-- | <a>Pitch</a> to fractional midi note number notation.
--   
--   <pre>
--   pitch_to_fmidi (Pitch A QuarterToneSharp 4) == 69.5
--   </pre>
pitch_to_fmidi :: Fractional n => Pitch -> n

-- | Extract <a>PitchClass</a> of <a>Pitch</a>
--   
--   <pre>
--   pitch_to_pc (Pitch A Natural 4) == 9
--   pitch_to_pc (Pitch F Sharp 4) == 6
--   </pre>
pitch_to_pc :: Pitch -> PitchClass

-- | <a>Pitch</a> comparison, implemented via <a>pitch_to_fmidi</a>.
--   
--   <pre>
--   pitch_compare (Pitch A Natural 4) (Pitch A QuarterToneSharp 4) == LT
--   </pre>
pitch_compare :: Pitch -> Pitch -> Ordering

-- | Given <a>Spelling</a> function translate from <a>OctPC</a> notation to
--   <a>Pitch</a>.
octpc_to_pitch :: Integral i => Spelling i -> Octave_PitchClass i -> Pitch

-- | Normalise <a>OctPC</a> value, ie. ensure <a>PitchClass</a> is in
--   (0,11).
--   
--   <pre>
--   octpc_nrm (4,16) == (5,4)
--   </pre>
octpc_nrm :: Integral i => Octave_PitchClass i -> Octave_PitchClass i

-- | Transpose <a>OctPC</a> value.
--   
--   <pre>
--   octpc_trs 7 (4,9) == (5,4)
--   octpc_trs (-11) (4,9) == (3,10)
--   </pre>
octpc_trs :: Integral i => i -> Octave_PitchClass i -> Octave_PitchClass i

-- | <a>OctPC</a> value to integral <i>midi</i> note number.
--   
--   <pre>
--   octpc_to_midi (4,9) == 69
--   </pre>
octpc_to_midi :: Integral i => Octave_PitchClass i -> i

-- | <a>fromIntegral</a> of <a>octpc_to_midi</a>.
octpc_to_fmidi :: (Integral i, Num n) => Octave_PitchClass i -> n

-- | Inverse of <a>octpc_to_midi</a>.
--   
--   <pre>
--   midi_to_octpc 69 == (4,9)
--   </pre>
midi_to_octpc :: Integral i => i -> Octave_PitchClass i

-- | Enumerate range, inclusive.
--   
--   <pre>
--   octpc_range ((3,8),(4,1)) == [(3,8),(3,9),(3,10),(3,11),(4,0),(4,1)]
--   </pre>
octpc_range :: (OctPC, OctPC) -> [OctPC]

-- | Midi note number to <a>Pitch</a>.
--   
--   <pre>
--   let r = ["C4","E♭4","F♯4"]
--   in map (pitch_pp . midi_to_pitch pc_spell_ks) [60,63,66] == r
--   </pre>
midi_to_pitch :: Integral i => Spelling i -> i -> Pitch

-- | Fractional midi note number to <a>Pitch</a>.
--   
--   <pre>
--   import Music.Theory.Pitch.Spelling
--   pitch_pp (fmidi_to_pitch pc_spell_ks 65.5) == "F𝄲4"
--   pitch_pp (fmidi_to_pitch pc_spell_ks 66.5) == "F𝄰4"
--   pitch_pp (fmidi_to_pitch pc_spell_ks 67.5) == "A𝄭4"
--   pitch_pp (fmidi_to_pitch pc_spell_ks 69.5) == "B𝄭4"
--   </pre>
fmidi_to_pitch :: RealFrac n => Spelling Int -> n -> Pitch

-- | Composition of <a>pitch_to_fmidi</a> and then <a>fmidi_to_pitch</a>.
--   
--   <pre>
--   import Music.Theory.Pitch.Name as T
--   import Music.Theory.Pitch.Spelling as T
--   </pre>
--   
--   <pre>
--   pitch_tranpose T.pc_spell_ks 2 T.ees5 == T.f5
--   </pre>
pitch_tranpose :: RealFrac n => Spelling Int -> n -> Pitch -> Pitch

-- | Set octave of <i>p2</i> so that it nearest to <i>p1</i>.
--   
--   <pre>
--   import Music.Theory.Pitch.Name as T
--   </pre>
--   
--   <pre>
--   let {r = ["B1","C2","C#2"];f = pitch_in_octave_nearest T.cis2}
--   in map (pitch_pp_iso . f) [T.b4,T.c4,T.cis4] == r
--   </pre>
pitch_in_octave_nearest :: Pitch -> Pitch -> Pitch

-- | Raise <a>Note_T</a> of <a>Pitch</a>, account for octave transposition.
--   
--   <pre>
--   pitch_note_raise (Pitch B Natural 3) == Pitch C Natural 4
--   </pre>
pitch_note_raise :: Pitch -> Pitch

-- | Lower <a>Note_T</a> of <a>Pitch</a>, account for octave transposition.
--   
--   <pre>
--   pitch_note_lower (Pitch C Flat 4) == Pitch B Flat 3
--   </pre>
pitch_note_lower :: Pitch -> Pitch

-- | Rewrite <a>Pitch</a> to not use <tt>3/4</tt> tone alterations, ie.
--   re-spell to <tt>1/4</tt> alteration.
--   
--   <pre>
--   let {p = Pitch A ThreeQuarterToneFlat 4
--       ;q = Pitch G QuarterToneSharp 4}
--   in pitch_rewrite_threequarter_alteration p == q
--   </pre>
pitch_rewrite_threequarter_alteration :: Pitch -> Pitch

-- | Apply function to <a>octave</a> of <a>PitchClass</a>.
--   
--   <pre>
--   pitch_edit_octave (+ 1) (Pitch A Natural 4) == Pitch A Natural 5
--   </pre>
pitch_edit_octave :: (Octave -> Octave) -> Pitch -> Pitch

-- | <i>Midi</i> note number to cycles per second.
--   
--   <pre>
--   map midi_to_cps [60,69] == [261.6255653005986,440.0]
--   </pre>
midi_to_cps :: (Integral i, Floating f) => i -> f

-- | Fractional <i>midi</i> note number to cycles per second.
--   
--   <pre>
--   map fmidi_to_cps [69,69.1] == [440.0,442.5488940698553]
--   </pre>
fmidi_to_cps :: Floating a => a -> a

-- | <a>fmidi_to_cps</a> of <a>pitch_to_fmidi</a>.
pitch_to_cps :: Floating n => Pitch -> n

-- | Frequency (cycles per second) to <i>midi</i> note number, ie.
--   <a>round</a> of <a>cps_to_fmidi</a>.
--   
--   <pre>
--   map cps_to_midi [261.6,440] == [60,69]
--   </pre>
cps_to_midi :: (Integral i, Floating f, RealFrac f) => f -> i

-- | Frequency (cycles per second) to fractional <i>midi</i> note number.
--   
--   <pre>
--   cps_to_fmidi 440 == 69
--   cps_to_fmidi (fmidi_to_cps 60.25) == 60.25
--   </pre>
cps_to_fmidi :: Floating a => a -> a

-- | Midi note number with cents detune.
type Midi_Detune = (Int, Double)

-- | Frequency (in hertz) to <a>Midi_Detune</a>.
--   
--   <pre>
--   map (fmap round . cps_to_midi_detune) [440.00,508.35] == [(69,0),(71,50)]
--   </pre>
cps_to_midi_detune :: Double -> Midi_Detune

-- | Inverse of <a>cps_to_midi_detune</a>.
midi_detune_to_cps :: Midi_Detune -> Double

-- | <a>midi_to_cps</a> of <a>octpc_to_midi</a>.
--   
--   <pre>
--   octpc_to_cps (4,9) == 440
--   </pre>
octpc_to_cps :: (Integral i, Floating n) => Octave_PitchClass i -> n

-- | <a>midi_to_octpc</a> of <a>cps_to_midi</a>.
cps_to_octpc :: (Floating f, RealFrac f, Integral i) => f -> Octave_PitchClass i

-- | Slight generalisation of ISO pitch representation. Allows octave to be
--   elided, pitch names to be lower case, and double sharps written as
--   <tt>##</tt>.
--   
--   See <a>http://www.musiccog.ohio-state.edu/Humdrum/guide04.html</a>
--   
--   <pre>
--   let r = [Pitch C Natural 4,Pitch A Flat 5,Pitch F DoubleSharp 6]
--   in mapMaybe (parse_iso_pitch_oct 4) ["C","Ab5","f##6",""] == r
--   </pre>
parse_iso_pitch_oct :: Octave -> String -> Maybe Pitch

-- | Variant of <a>parse_iso_pitch_oct</a> requiring octave.
parse_iso_pitch :: String -> Maybe Pitch

-- | Pretty printer for <a>Pitch</a> (unicode, see
--   <a>alteration_symbol</a>).
--   
--   <pre>
--   pitch_pp (Pitch E Flat 4) == "E♭4"
--   pitch_pp (Pitch F QuarterToneSharp 3) == "F𝄲3"
--   </pre>
pitch_pp :: Pitch -> String

-- | <a>Pitch</a> printed without octave.
pitch_class_pp :: Pitch -> String

-- | Sequential list of <i>n</i> pitch class names starting from <i>k</i>.
--   
--   <pre>
--   pitch_class_names_12et 11 2 == ["B","C"]
--   </pre>
pitch_class_names_12et :: Integral n => n -> n -> [String]

-- | Pretty printer for <a>Pitch</a> (ISO, ASCII, see
--   <a>alteration_iso</a>).
--   
--   <pre>
--   pitch_pp_iso (Pitch E Flat 4) == "Eb4"
--   pitch_pp_iso (Pitch F DoubleSharp 3) == "Fx3"
--   </pre>
pitch_pp_iso :: Pitch -> String

-- | Pretty printer for <a>Pitch</a> (ASCII, see <a>alteration_tonh</a>).
--   
--   <pre>
--   pitch_pp_hly (Pitch E Flat 4) == "ees4"
--   pitch_pp_hly (Pitch F QuarterToneSharp 3) == "fih3"
--   pitch_pp_hly (Pitch B Natural 6) == "b6"
--   </pre>
pitch_pp_hly :: Pitch -> String

-- | Pretty printer for <a>Pitch</a> (Tonhöhe, see <a>alteration_tonh</a>).
--   
--   <pre>
--   pitch_pp_tonh (Pitch E Flat 4) == "Es4"
--   pitch_pp_tonh (Pitch F QuarterToneSharp 3) == "Fih3"
--   pitch_pp_tonh (Pitch B Natural 6) == "H6"
--   </pre>
pitch_pp_tonh :: Pitch -> String
instance GHC.Show.Show Music.Theory.Pitch.Pitch'
instance GHC.Classes.Eq Music.Theory.Pitch.Pitch'
instance GHC.Show.Show Music.Theory.Pitch.Pitch
instance GHC.Classes.Eq Music.Theory.Pitch.Pitch
instance GHC.Classes.Ord Music.Theory.Pitch.Pitch


-- | Constants names for <a>Pitch</a> values. <i>eses</i> indicates double
--   flat, <i>eseh</i> three quarter tone flat, <i>es</i> flat, <i>eh</i>
--   quarter tone flat, <i>ih</i> quarter tone sharp, <i>is</i> sharp,
--   <i>isih</i> three quarter tone sharp and <i>isis</i> double sharp.
module Music.Theory.Pitch.Name
a0 :: Pitch
b0 :: Pitch
bes0 :: Pitch
ais0 :: Pitch
bis0 :: Pitch
c1 :: Pitch
d1 :: Pitch
e1 :: Pitch
f1 :: Pitch
g1 :: Pitch
a1 :: Pitch
b1 :: Pitch
ces1 :: Pitch
des1 :: Pitch
ees1 :: Pitch
fes1 :: Pitch
ges1 :: Pitch
aes1 :: Pitch
bes1 :: Pitch
cis1 :: Pitch
dis1 :: Pitch
eis1 :: Pitch
fis1 :: Pitch
gis1 :: Pitch
ais1 :: Pitch
bis1 :: Pitch
c2 :: Pitch
d2 :: Pitch
e2 :: Pitch
f2 :: Pitch
g2 :: Pitch
a2 :: Pitch
b2 :: Pitch
ces2 :: Pitch
des2 :: Pitch
ees2 :: Pitch
fes2 :: Pitch
ges2 :: Pitch
aes2 :: Pitch
bes2 :: Pitch
cis2 :: Pitch
dis2 :: Pitch
eis2 :: Pitch
fis2 :: Pitch
gis2 :: Pitch
ais2 :: Pitch
bis2 :: Pitch
cisis2 :: Pitch
disis2 :: Pitch
eisis2 :: Pitch
fisis2 :: Pitch
gisis2 :: Pitch
aisis2 :: Pitch
bisis2 :: Pitch
ceseh2 :: Pitch
deseh2 :: Pitch
eeseh2 :: Pitch
feseh2 :: Pitch
geseh2 :: Pitch
aeseh2 :: Pitch
beseh2 :: Pitch
ceh2 :: Pitch
deh2 :: Pitch
eeh2 :: Pitch
feh2 :: Pitch
geh2 :: Pitch
aeh2 :: Pitch
beh2 :: Pitch
cih2 :: Pitch
dih2 :: Pitch
eih2 :: Pitch
fih2 :: Pitch
gih2 :: Pitch
aih2 :: Pitch
bih2 :: Pitch
cisih2 :: Pitch
disih2 :: Pitch
eisih2 :: Pitch
fisih2 :: Pitch
gisih2 :: Pitch
aisih2 :: Pitch
bisih2 :: Pitch
c3 :: Pitch
d3 :: Pitch
e3 :: Pitch
f3 :: Pitch
g3 :: Pitch
a3 :: Pitch
b3 :: Pitch
ces3 :: Pitch
des3 :: Pitch
ees3 :: Pitch
fes3 :: Pitch
ges3 :: Pitch
aes3 :: Pitch
bes3 :: Pitch
cis3 :: Pitch
dis3 :: Pitch
eis3 :: Pitch
fis3 :: Pitch
gis3 :: Pitch
ais3 :: Pitch
bis3 :: Pitch
ceses3 :: Pitch
deses3 :: Pitch
eeses3 :: Pitch
feses3 :: Pitch
geses3 :: Pitch
aeses3 :: Pitch
beses3 :: Pitch
cisis3 :: Pitch
disis3 :: Pitch
eisis3 :: Pitch
fisis3 :: Pitch
gisis3 :: Pitch
aisis3 :: Pitch
bisis3 :: Pitch
ceseh3 :: Pitch
deseh3 :: Pitch
eeseh3 :: Pitch
feseh3 :: Pitch
geseh3 :: Pitch
aeseh3 :: Pitch
beseh3 :: Pitch
ceh3 :: Pitch
deh3 :: Pitch
eeh3 :: Pitch
feh3 :: Pitch
geh3 :: Pitch
aeh3 :: Pitch
beh3 :: Pitch
cih3 :: Pitch
dih3 :: Pitch
eih3 :: Pitch
fih3 :: Pitch
gih3 :: Pitch
aih3 :: Pitch
bih3 :: Pitch
cisih3 :: Pitch
disih3 :: Pitch
eisih3 :: Pitch
fisih3 :: Pitch
gisih3 :: Pitch
aisih3 :: Pitch
bisih3 :: Pitch
c4 :: Pitch
d4 :: Pitch
e4 :: Pitch
f4 :: Pitch
g4 :: Pitch
a4 :: Pitch
b4 :: Pitch
ces4 :: Pitch
des4 :: Pitch
ees4 :: Pitch
fes4 :: Pitch
ges4 :: Pitch
aes4 :: Pitch
bes4 :: Pitch
cis4 :: Pitch
dis4 :: Pitch
eis4 :: Pitch
fis4 :: Pitch
gis4 :: Pitch
ais4 :: Pitch
bis4 :: Pitch
ceses4 :: Pitch
deses4 :: Pitch
eeses4 :: Pitch
feses4 :: Pitch
geses4 :: Pitch
aeses4 :: Pitch
beses4 :: Pitch
cisis4 :: Pitch
disis4 :: Pitch
eisis4 :: Pitch
fisis4 :: Pitch
gisis4 :: Pitch
aisis4 :: Pitch
bisis4 :: Pitch
ceseh4 :: Pitch
deseh4 :: Pitch
eeseh4 :: Pitch
feseh4 :: Pitch
geseh4 :: Pitch
aeseh4 :: Pitch
beseh4 :: Pitch
ceh4 :: Pitch
deh4 :: Pitch
eeh4 :: Pitch
feh4 :: Pitch
geh4 :: Pitch
aeh4 :: Pitch
beh4 :: Pitch
cih4 :: Pitch
dih4 :: Pitch
eih4 :: Pitch
fih4 :: Pitch
gih4 :: Pitch
aih4 :: Pitch
bih4 :: Pitch
cisih4 :: Pitch
disih4 :: Pitch
eisih4 :: Pitch
fisih4 :: Pitch
gisih4 :: Pitch
aisih4 :: Pitch
bisih4 :: Pitch
c5 :: Pitch
d5 :: Pitch
e5 :: Pitch
f5 :: Pitch
g5 :: Pitch
a5 :: Pitch
b5 :: Pitch
ces5 :: Pitch
des5 :: Pitch
ees5 :: Pitch
fes5 :: Pitch
ges5 :: Pitch
aes5 :: Pitch
bes5 :: Pitch
cis5 :: Pitch
dis5 :: Pitch
eis5 :: Pitch
fis5 :: Pitch
gis5 :: Pitch
ais5 :: Pitch
bis5 :: Pitch
ceses5 :: Pitch
deses5 :: Pitch
eeses5 :: Pitch
feses5 :: Pitch
geses5 :: Pitch
aeses5 :: Pitch
beses5 :: Pitch
cisis5 :: Pitch
disis5 :: Pitch
eisis5 :: Pitch
fisis5 :: Pitch
gisis5 :: Pitch
aisis5 :: Pitch
bisis5 :: Pitch
ceseh5 :: Pitch
deseh5 :: Pitch
eeseh5 :: Pitch
feseh5 :: Pitch
geseh5 :: Pitch
aeseh5 :: Pitch
beseh5 :: Pitch
ceh5 :: Pitch
deh5 :: Pitch
eeh5 :: Pitch
feh5 :: Pitch
geh5 :: Pitch
aeh5 :: Pitch
beh5 :: Pitch
cih5 :: Pitch
dih5 :: Pitch
eih5 :: Pitch
fih5 :: Pitch
gih5 :: Pitch
aih5 :: Pitch
bih5 :: Pitch
cisih5 :: Pitch
disih5 :: Pitch
eisih5 :: Pitch
fisih5 :: Pitch
gisih5 :: Pitch
aisih5 :: Pitch
bisih5 :: Pitch
c6 :: Pitch
d6 :: Pitch
e6 :: Pitch
f6 :: Pitch
g6 :: Pitch
a6 :: Pitch
b6 :: Pitch
ces6 :: Pitch
des6 :: Pitch
ees6 :: Pitch
fes6 :: Pitch
ges6 :: Pitch
aes6 :: Pitch
bes6 :: Pitch
cis6 :: Pitch
dis6 :: Pitch
eis6 :: Pitch
fis6 :: Pitch
gis6 :: Pitch
ais6 :: Pitch
bis6 :: Pitch
ceseh6 :: Pitch
deseh6 :: Pitch
eeseh6 :: Pitch
feseh6 :: Pitch
geseh6 :: Pitch
aeseh6 :: Pitch
beseh6 :: Pitch
ceh6 :: Pitch
deh6 :: Pitch
eeh6 :: Pitch
feh6 :: Pitch
geh6 :: Pitch
aeh6 :: Pitch
beh6 :: Pitch
cih6 :: Pitch
dih6 :: Pitch
eih6 :: Pitch
fih6 :: Pitch
gih6 :: Pitch
aih6 :: Pitch
bih6 :: Pitch
cisih6 :: Pitch
disih6 :: Pitch
eisih6 :: Pitch
fisih6 :: Pitch
gisih6 :: Pitch
aisih6 :: Pitch
bisih6 :: Pitch
c7 :: Pitch
d7 :: Pitch
e7 :: Pitch
f7 :: Pitch
g7 :: Pitch
a7 :: Pitch
b7 :: Pitch
ces7 :: Pitch
des7 :: Pitch
ees7 :: Pitch
fes7 :: Pitch
ges7 :: Pitch
aes7 :: Pitch
bes7 :: Pitch
cis7 :: Pitch
dis7 :: Pitch
eis7 :: Pitch
fis7 :: Pitch
gis7 :: Pitch
ais7 :: Pitch
bis7 :: Pitch
c8 :: Pitch
cis8 :: Pitch
d8 :: Pitch


-- | Spelling for chromatic clusters.
module Music.Theory.Pitch.Spelling.Cluster

-- | Spelling table for chromatic clusters.
--   
--   <pre>
--   let f (p,q) = p == sort (map (snd . pitch_to_octpc) q)
--   in all f spell_cluster_c4_table == True
--   </pre>
spell_cluster_c4_table :: [([PitchClass], [Pitch])]

-- | Spelling for chromatic clusters. Sequence must be ascending. Pitch
--   class <tt>0</tt> maps to <a>c4</a>, if there is no <tt>0</tt> then all
--   notes are in octave <tt>4</tt>.
--   
--   <pre>
--   let f = fmap (map pitch_pp) . spell_cluster_c4
--   in map f [[11,0],[11]] == [Just ["B3","C4"],Just ["B4"]]
--   </pre>
--   
--   <pre>
--   fmap (map pitch_pp) (spell_cluster_c4 [10,11]) == Just ["A♯4","B4"]
--   </pre>
spell_cluster_c4 :: [PitchClass] -> Maybe [Pitch]

-- | Variant of <a>spell_cluster_c4</a> that runs <a>pitch_edit_octave</a>.
--   An octave of <tt>4</tt> is the identitiy, <tt>3</tt> an octave below,
--   <tt>5</tt> an octave above.
--   
--   <pre>
--   fmap (map pitch_pp) (spell_cluster_c 3 [11,0]) == Just ["B2","C3"]
--   fmap (map pitch_pp) (spell_cluster_c 3 [10,11]) == Just ["A♯3","B3"]
--   </pre>
spell_cluster_c :: Octave -> [PitchClass] -> Maybe [Pitch]

-- | Variant of <a>spell_cluster_c4</a> that runs <a>pitch_edit_octave</a>
--   so that the left-most note is in the octave given by <i>f</i>.
--   
--   <pre>
--   import Data.Maybe
--   </pre>
--   
--   <pre>
--   let {f n = if n &gt;= 11 then 3 else 4
--       ;g = map pitch_pp .fromJust . spell_cluster_f f
--       ;r = [["B3","C4"],["B3"],["C4"],["A♯4","B4"]]}
--   in map g [[11,0],[11],[0],[10,11]] == r
--   </pre>
spell_cluster_f :: (PitchClass -> Octave) -> [PitchClass] -> Maybe [Pitch]

-- | Variant of <a>spell_cluster_c4</a> that runs <a>pitch_edit_octave</a>
--   so that the left-most note is in octave <i>o</i>.
--   
--   <pre>
--   fmap (map pitch_pp) (spell_cluster_left 3 [11,0]) == Just ["B3","C4"]
--   fmap (map pitch_pp) (spell_cluster_left 3 [10,11]) == Just ["A♯3","B3"]
--   </pre>
spell_cluster_left :: Octave -> [PitchClass] -> Maybe [Pitch]


-- | <i>Bel(R)</i> is a simplified form of the <i>Bel</i> notation
--   described in:
--   
--   <ul>
--   <li>Bernard Bel. "Time and musical structures". <i>Interface (Journal
--   of New Music Research)</i> Volume 19, Issue 2-3, 1990.
--   (<a>http://hal.archives-ouvertes.fr/hal-00134160</a>)</li>
--   <li>Bernard Bel. "Two algorithms for the instantiation of structures
--   of musical objects". Centre National de la Recherche Scientifique,
--   1992. <i>GRTC 458</i>
--   (<a>http://www.lpl.univ-aix.fr/~belbernard/music/2algorithms.pdf</a>)</li>
--   </ul>
--   
--   For patterns without tempo indications, the two notations should give
--   equivalent phase diagrams, for instance (Bel 1990, §11, p.24):
--   
--   <pre>
--   &gt; bel_ascii_pp "ab{ab,cde}cd"
--   
--   Bel(R): "ab{ab,cde}cd", Dur: 7
--   
--   a _ b _ a _ _ b _ _ c _ d _
--           c _ d _ e _        
--   </pre>
--   
--   and:
--   
--   <pre>
--   &gt; bel_ascii_pp "{a{bc,def},ghijk}"
--   
--   Bel(R): "{a{bc,def},ghijk}", Dur: 5
--   
--   a _ _ _ _ _ _ _ _ _ b _ _ _ _ _ _ _ _ _ _ _ _ _ _ c _ _ _ _ _ _ _ _ _ _ _ _ _ _
--                       d _ _ _ _ _ _ _ _ _ e _ _ _ _ _ _ _ _ _ f _ _ _ _ _ _ _ _ _
--   g _ _ _ _ _ _ _ h _ _ _ _ _ _ _ i _ _ _ _ _ _ _ j _ _ _ _ _ _ _ k _ _ _ _ _ _ _
--   </pre>
--   
--   The <i>Bel</i> notation allows <i>n</i>-ary parallel structures, ie.
--   <tt>{a_bcd_e,a_f_gh_,ji_a_i_}</tt> (Bel 1992, p.29), however
--   <i>Bel(R)</i> allows only binary structures. The parallel
--   interpretation rules are associative:
--   
--   <pre>
--   &gt; bel_ascii_pp "{a_bcd_e,{a_f_gh_,ji_a_i_}}"
--   
--   Bel(R): "{a_bcd_e,{a_f_gh_,ji_a_i_}}", Dur: 7
--   
--   a _ b c d _ e
--   a _ f _ g h _
--   j i _ a _ i _
--   </pre>
--   
--   <i>Bel(R)</i> does allow unary parallel structures (see <a>Iso</a>),
--   which can be used to <i>isolate</i> tempo changes:
--   
--   <pre>
--   &gt; bel_ascii_pp "ab{*2cd}ef{*2/3gh}ij"
--   
--   Bel(R): "ab{*2cd}ef{*2/3gh}ij", Dur: 10
--   
--   a _ b _ c d e _ f _ g _ _ h _ _ i _ j _
--   </pre>
--   
--   Patterns with tempo indications have completely different meanings in
--   <i>Bel</i> and <i>Bel(R)</i>, though in both cases parallel nodes
--   delimit the scope of tempo markings.
--   
--   <i>Bel(R)</i> replaces the <tt>/n</tt> notation for explicit tempo
--   marks with a <tt>*n</tt> notation to indicate a tempo multiplier, and
--   a set of bracketing notations to specify interpretation rules for
--   parallel (concurrent) temporal structures.
--   
--   The tempo indication <tt>/1</tt> in the expression
--   <tt>ab{/1ab,cde}cd</tt> (Bel 1990, p.24) requires that the inner
--   <tt>ab</tt> have the same tempo as the outer <tt>ab</tt>, which is
--   implicitly <tt>/1</tt>. Setting the tempo of one part of a parallel
--   structure requires assigning a tempo to the other part in order that
--   the two parts have equal duration. Here the tempo assigned to
--   <tt>cde</tt> is <tt>/1.5</tt>, but since fractional tempi are not
--   allowed the expression is re-written as <tt>/2ab{/2ab,/3cde}/2cd</tt>.
--   
--   Importantly the explicit tempo indications make it possible to write
--   syntactically correct expressions in <i>Bel</i> that do not have a
--   coherent interpretation, ie. <tt>{/1ab,/1cde}</tt>. Determining if a
--   coherent set of tempos can be assigned, and assigning these tempos, is
--   the object of the interpretation system.
--   
--   In comparison, all syntactically valid <i>Bel(R)</i> strings have an
--   interpretation. The expression <tt>{*1ab,*1cde}</tt> is trivially
--   equal to <tt>{ab,cde}</tt>, and tempo marks in parallel parts do not
--   interact:
--   
--   <pre>
--   &gt; bel_ascii_pp "{a*2b,*3c/2d/3e}"
--   
--   Bel(R): "{a*2b,*3c*1/2d*1/3e}", Dur: 3
--   
--   a _ _ _ _ _ b _ _
--   c d _ e _ _ _ _ _
--   </pre>
--   
--   Here <tt>a</tt> is twice the duration of <tt>b</tt>, and <tt>e</tt> is
--   three times the duration of <tt>d</tt>, which is twice the duration of
--   <tt>c</tt> (in <i>Bel(R)</i> <tt>/n</tt> is equivalent to
--   <tt>*1/n</tt>). The duration of any <i>Bel(R)</i> expression can be
--   calculated directly, given an initial <a>Tempo</a>:
--   
--   <pre>
--   bel_dur 1 (bel_char_parse "a*2b") == 3/2
--   bel_dur 1 (bel_char_parse "*3c/2d/3e") == 3
--   </pre>
--   
--   Therefore in the composite expression the left part is slowed by a
--   factor of two to align with the right part.
--   
--   The <i>Bel</i> string <tt>ab{/1ab,cde}cd</tt> can be re-written in
--   <i>Bel(R)</i> as either <tt>ab~{ab,cde}cd</tt> or
--   <tt>ab(ab,cde)cd</tt>. The absolute tempo indication is replaced by
--   notations giving alternate modes of interpretation for the parallel
--   structure.
--   
--   In the first case the <tt>~</tt> indicates the <i>opposite</i> of the
--   normal rule for parallel nodes. The normal rule is the same as for
--   <i>Bel</i> and is that the duration of the whole is equal to duration
--   of the longer of the two parts. The <tt>~</tt> inverts this so that
--   the whole has the duration of the shorter of the two parts, and the
--   longer part is scaled to have equal duration.
--   
--   In the second case the parentheses <tt>()</tt> replacing the braces
--   <tt>{}</tt> indicates that the duration of the whole is equal to the
--   duration of the left side, and that the right is to be scaled.
--   Similarly, a <tt>~</tt> preceding parentheses indicates the duration
--   of the whole should be the duration of the right side, and the left
--   scaled.
--   
--   <pre>
--   &gt; bel_ascii_pp "ab~{ab,cde}cd"
--   
--   Bel(R): "ab~{ab,cde}cd", Dur: 6
--   
--   a _ _ b _ _ a _ _ b _ _ c _ _ d _ _
--               c _ d _ e _            
--   </pre>
--   
--   There is one other parallel mode that has no equivalent in <i>Bel</i>
--   notation. It is a mode that does not scale either part, leaving a
--   <i>hole</i> at the end of the shorter part, and is indicated by square
--   brackets:
--   
--   <pre>
--   &gt; bel_ascii_pp "ab[ab,cde]cd"
--   
--   Bel(R): "ab[ab,cde]cd", Dur: 7
--   
--   a b a b   c d
--       c d e    
--   </pre>
--   
--   The <i>Bel</i> string <tt>/2abc/3de</tt> (Bel 1992, p.53) can be
--   written as <tt>*2abc*1/2*3de</tt>, or equivalently as
--   <tt>*2abc*3/2de</tt>:
--   
--   <pre>
--   &gt; bel_ascii_pp "*2abc*3/2de"
--   
--   Bel(R): "*2abc*3/2de", Dur: 13/6
--   
--   a _ _ b _ _ c _ _ d _ e _
--   </pre>
--   
--   It can also be written using the shorthand notation for rest
--   sequences, where an integer <i>n</i> indicates a sequence of <i>n</i>
--   rests, as:
--   
--   <pre>
--   &gt; bel_ascii_pp "(9,abc)(4,de)"
--   
--   Bel(R): "(---------,abc)(----,de)", Dur: 13
--   
--   - - - - - - - - - - - - -
--   a _ _ b _ _ c _ _ d _ e _
--   </pre>
--   
--   In the <i>Bel</i> string <tt>{ab{/3abc,de},fghijk}</tt> (Bel 1992,
--   p.20) the tempo indication does not change the inter-relation of the
--   parts but rather scales the parallel node altogether, and can be
--   re-written in <i>Bel(R)</i> notation as:
--   
--   <pre>
--   &gt; bel_ascii_pp "{ab*3{abc,de},fghijk}"
--   
--   Bel(R): "{ab*3{abc,de},fghijk}", Dur: 6
--   
--   a _ _ _ _ _ b _ _ _ _ _ a _ b _ c _
--                           d _ _ e _ _
--   f _ _ g _ _ h _ _ i _ _ j _ _ k _ _
--   </pre>
--   
--   Curiously the following example (Bel 1990, p. 24) does not correspond
--   to the phase diagram given:
--   
--   <pre>
--   &gt; bel_ascii_pp "{i{ab,cde},jk}"
--   
--   Bel(R): "{i{ab,cde},jk}", Dur: 4
--   
--   i _ a _ _ b _ _
--       c _ d _ e _
--   j _ _ _ k _ _ _
--   </pre>
--   
--   The paper assigns tempi of <tt>/6</tt> to both <tt>i</tt> and
--   <tt>ab</tt>, which in <i>Bel(R)</i> could be written:
--   
--   <pre>
--   &gt; bel_ascii_pp "{i~{ab,cde},jk}"
--   
--   Bel(R): "{i~{ab,cde},jk}", Dur: 3
--   
--   i _ _ _ _ _ a _ _ _ _ _ b _ _ _ _ _
--               c _ _ _ d _ _ _ e _ _ _
--   j _ _ _ _ _ _ _ _ k _ _ _ _ _ _ _ _
--   </pre>
module Music.Theory.Time.Bel1990.R

-- | Types of <a>Par</a> nodes.
data Par_Mode
Par_Left :: Par_Mode
Par_Right :: Par_Mode
Par_Min :: Par_Mode
Par_Max :: Par_Mode
Par_None :: Par_Mode

-- | The different <a>Par</a> modes are indicated by bracket types.
par_mode_brackets :: Par_Mode -> (String, String)
bel_brackets_match :: (Char, Char) -> Bool

-- | Tempo is rational. The duration of a <a>Term</a> is the reciprocal of
--   the <a>Tempo</a> that is in place at the <a>Term</a>.
type Tempo = Rational

-- | Terms are the leaf nodes of the temporal structure.
data Term a
Value :: a -> Term a
Rest :: Term a
Continue :: Term a

-- | Recursive temporal structure.
data Bel a

-- | Leaf node
Node :: (Term a) -> Bel a

-- | Isolate
Iso :: (Bel a) -> Bel a

-- | Sequence
Seq :: (Bel a) -> (Bel a) -> Bel a

-- | Parallel
Par :: Par_Mode -> (Bel a) -> (Bel a) -> Bel a

-- | Tempo multiplier
Mul :: Tempo -> Bel a

-- | Pretty printer for <a>Bel</a>, given pretty printer for the term type.
bel_pp :: (a -> String) -> Bel a -> String

-- | <a>bel_pp</a> of <a>return</a>.
bel_char_pp :: Bel Char -> String

-- | Analyse a Par node giving (duration,LHS-tempo-*,RHS-tempo-*).
--   
--   <pre>
--   par_analyse 1 Par_Left (nseq "cd") (nseq "efg") == (2,1,3/2)
--   par_analyse 1 Par_Right (nseq "cd") (nseq "efg") == (3,2/3,1)
--   par_analyse 1 Par_Min (nseq "cd") (nseq "efg") == (2,1,3/2)
--   par_analyse 1 Par_Max (nseq "cd") (nseq "efg") == (3,2/3,1)
--   par_analyse 1 Par_None (nseq "cd") (nseq "efg") == (3,1,1)
--   </pre>
par_analyse :: Tempo -> Par_Mode -> Bel a -> Bel a -> (Rational, Rational, Rational)

-- | Duration element of <a>par_analyse</a>.
par_dur :: Tempo -> Par_Mode -> Bel a -> Bel a -> Rational

-- | Calculate final tempo and duration of <a>Bel</a>.
bel_tdur :: Tempo -> Bel a -> (Tempo, Rational)

-- | <a>snd</a> of <a>bel_tdur</a>.
bel_dur :: Tempo -> Bel a -> Rational

-- | Time point.
type Time = Rational

-- | Voices are named as a sequence of left and right directions within
--   nested <a>Par</a> structures.
type Voice = [Char]

-- | Linear state. <a>Time</a> is the start time of the term, <a>Tempo</a>
--   is the active tempo &amp; therefore the reciprocal of the duration,
--   <a>Voice</a> is the part label.
type L_St = (Time, Tempo, Voice)

-- | Linear term.
type L_Term a = (L_St, Term a)

-- | Start time of <a>L_Term</a>.
lterm_time :: L_Term a -> Time

-- | Duration of <a>L_Term</a> (reciprocal of tempo).
lterm_duration :: L_Term a -> Time

-- | End time of <a>L_Term</a>.
lterm_end_time :: L_Term a -> Time

-- | Linear form of <a>Bel</a>, an ascending sequence of <a>L_Term</a>.
type L_Bel a = [L_Term a]

-- | Linearise <a>Bel</a> given initial <a>L_St</a>, ascending by
--   construction.
bel_linearise :: L_St -> Bel a -> (L_Bel a, L_St)

-- | Merge two ascending <a>L_Bel</a>.
lbel_merge :: L_Bel a -> L_Bel a -> L_Bel a

-- | Set of unique <a>Tempo</a> at <a>L_Bel</a>.
lbel_tempi :: L_Bel a -> [Tempo]

-- | Multiply <a>Tempo</a> by <i>n</i>, and divide <a>Time</a> by <i>n</i>.
lbel_tempo_mul :: Rational -> L_Bel a -> L_Bel a

-- | After normalisation all start times and durations are integral.
lbel_normalise :: L_Bel a -> L_Bel a

-- | All leftmost voices are re-written to the last non-left turning point.
--   
--   <pre>
--   map voice_normalise ["","l","ll","lll"] == replicate 4 ""
--   voice_normalise "lllrlrl" == "rlrl"
--   </pre>
voice_normalise :: Voice -> Voice

-- | <a>==</a> <a>on</a> <a>voice_normalise</a>
voice_eq :: Voice -> Voice -> Bool

-- | Unique <a>Voice</a>s at <a>L_Bel</a>.
lbel_voices :: L_Bel a -> [Voice]

-- | The duration of <a>L_Bel</a>.
lbel_duration :: L_Bel a -> Time

-- | Locate an <a>L_Term</a> that is active at the indicated <a>Time</a>
--   and in the indicated <a>Voice</a>.
lbel_lookup :: (Time, Voice) -> L_Bel a -> Maybe (L_Term a)

-- | Calculate grid (phase diagram) for <a>L_Bel</a>.
lbel_grid :: L_Bel a -> [[Maybe (Term a)]]

-- | <a>lbel_grid</a> of <a>bel_linearise</a>.
bel_grid :: Bel a -> [[Maybe (Term a)]]

-- | <i>Bel</i> type phase diagram for <a>Bel</a> of <a>Char</a>.
--   Optionally print whitespace between columns.
bel_ascii :: Bool -> Bel Char -> String

-- | <a>putStrLn</a> of <a>bel_ascii</a>.
bel_ascii_pr :: Bel Char -> IO ()

-- | Infix form for <a>Seq</a>.
(~>) :: Bel a -> Bel a -> Bel a

-- | <a>foldl1</a> of <a>Seq</a>.
--   
--   <pre>
--   lseq [Node Rest] == Node Rest
--   lseq [Node Rest,Node Continue] == Seq (Node Rest) (Node Continue)
--   </pre>
lseq :: [Bel a] -> Bel a

-- | <a>Node</a> of <a>Value</a>.
node :: a -> Bel a

-- | <a>lseq</a> of <a>Node</a>
nseq :: [a] -> Bel a

-- | Variant of <a>nseq</a> where <tt>_</tt> is read as <a>Continue</a> and
--   <tt>-</tt> as <a>Rest</a>.
cseq :: String -> Bel Char

-- | <a>Par</a> of <a>Par_Max</a>, this is the default <a>Par_Mode</a>.
par :: Bel a -> Bel a -> Bel a

-- | <a>Node</a> of <a>Rest</a>.
rest :: Bel a

-- | <a>lseq</a> of <a>replicate</a> of <a>rest</a>.
nrests :: Integral n => n -> Bel a

-- | Verify that <a>bel_char_pp</a> of <a>bel_char_parse</a> is <a>id</a>.
bel_parse_pp_ident :: String -> Bool

-- | Run <a>bel_char_parse</a>, and print both <a>bel_char_pp</a> and
--   <a>bel_ascii</a>.
--   
--   <pre>
--   bel_ascii_pp "{i{ab,{c[d,oh]e,sr{p,qr}}},{jk,ghjkj}}"
--   </pre>
bel_ascii_pp :: String -> IO ()

-- | A <a>Char</a> parser.
type P a = GenParser Char () a

-- | Parse <a>Rest</a> <a>Term</a>.
--   
--   <pre>
--   P.parse p_rest "" "-"
--   </pre>
p_rest :: P (Term a)

-- | Parse <a>Rest</a> <a>Term</a>.
--   
--   <pre>
--   P.parse p_nrests "" "3"
--   </pre>
p_nrests :: P (Bel a)

-- | Parse <a>Continue</a> <a>Term</a>.
--   
--   <pre>
--   P.parse p_continue "" "_"
--   </pre>
p_continue :: P (Term a)

-- | Parse <a>Char</a> <a>Value</a> <a>Term</a>.
--   
--   <pre>
--   P.parse p_char_value "" "a"
--   </pre>
p_char_value :: P (Term Char)

-- | Parse <a>Char</a> <a>Term</a>.
--   
--   <pre>
--   P.parse (P.many1 p_char_term) "" "-_a"
--   </pre>
p_char_term :: P (Term Char)

-- | Parse <a>Char</a> <a>Node</a>.
--   
--   <pre>
--   P.parse (P.many1 p_char_node) "" "-_a"
--   </pre>
p_char_node :: P (Bel Char)

-- | Parse positive <a>Integer</a>.
--   
--   <pre>
--   P.parse p_integer "" "3"
--   </pre>
p_integer :: P Integer

-- | Parse positive <a>Rational</a>.
--   
--   <pre>
--   P.parse (p_rational `P.sepBy` (P.char ',')) "" "3%5,2/3"
--   </pre>
p_rational :: P Rational

-- | Parse positive <a>Double</a>.
--   
--   <pre>
--   P.parse p_double "" "3.5"
--   P.parse (p_double `P.sepBy` (P.char ',')) "" "3.5,7.2,1.0"
--   </pre>
p_double :: P Double

-- | Parse positive number as <a>Rational</a>.
--   
--   <pre>
--   P.parse (p_number `P.sepBy` (P.char ',')) "" "7%2,3.5,3"
--   </pre>
p_number :: P Rational

-- | Parse <a>Mul</a>.
--   
--   <pre>
--   P.parse (P.many1 p_mul) "" "/3*3/2"
--   </pre>
p_mul :: P (Bel a)

-- | Given parser for <a>Bel</a> <i>a</i>, generate <a>Iso</a> parser.
p_iso :: P (Bel a) -> P (Bel a)

-- | <a>p_iso</a> of <a>p_char_bel</a>.
--   
--   <pre>
--   P.parse p_char_iso "" "{abcde}"
--   </pre>
p_char_iso :: P (Bel Char)

-- | Given parser for <a>Bel</a> <i>a</i>, generate <a>Par</a> parser.
p_par :: P (Bel a) -> P (Bel a)

-- | <a>p_par</a> of <a>p_char_bel</a>.
--   
--   <pre>
--   P.parse p_char_par "" "{ab,{c,de}}"
--   P.parse p_char_par "" "{ab,~(c,de)}"
--   </pre>
p_char_par :: P (Bel Char)

-- | Parse <a>Bel</a> <a>Char</a>.
--   
--   <pre>
--   P.parse (P.many1 p_char_bel) "" "-_a*3"
--   </pre>
p_char_bel :: P (Bel Char)

-- | Run parser for <a>Bel</a> of <a>Char</a>.
bel_char_parse :: String -> Bel Char
instance GHC.Show.Show a => GHC.Show.Show (Music.Theory.Time.Bel1990.R.Bel a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Music.Theory.Time.Bel1990.R.Bel a)
instance GHC.Show.Show a => GHC.Show.Show (Music.Theory.Time.Bel1990.R.Term a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Music.Theory.Time.Bel1990.R.Term a)
instance GHC.Show.Show Music.Theory.Time.Bel1990.R.Par_Mode
instance GHC.Classes.Eq Music.Theory.Time.Bel1990.R.Par_Mode


-- | "Sieves" by Iannis Xenakis and John Rahn <i>Perspectives of New
--   Music</i> Vol. 28, No. 1 (Winter, 1990), pp. 58-78
module Music.Theory.Xenakis.Sieve

-- | Synonym for <a>Integer</a>
type I = Integer

-- | A Sieve.
data Sieve

-- | <a>Empty</a> <a>Sieve</a>
Empty :: Sieve

-- | Primitive <a>Sieve</a> of <i>modulo</i> and <i>index</i>
L :: (I, I) -> Sieve

-- | <a>Union</a> of two <a>Sieve</a>s
Union :: Sieve -> Sieve -> Sieve

-- | <a>Intersection</a> of two <a>Sieve</a>s
Intersection :: Sieve -> Sieve -> Sieve

-- | The <a>Union</a> of a list of <a>Sieve</a>s, ie. <a>foldl1</a>
--   <a>Union</a>.
union :: [Sieve] -> Sieve

-- | The <a>Intersection</a> of a list of <a>Sieve</a>s, ie. <a>foldl1</a>
--   <a>Intersection</a>.
intersection :: [Sieve] -> Sieve

-- | Unicode synonym for <a>Union</a>.
(∪) :: Sieve -> Sieve -> Sieve
infixl 3 ∪

-- | Unicode synonym for <a>Intersection</a>.
(∩) :: Sieve -> Sieve -> Sieve
infixl 4 ∩

-- | Variant of <a>L</a>, ie. <a>curry</a> <a>L</a>.
--   
--   <pre>
--   l 15 19 == L (15,19)
--   </pre>
l :: I -> I -> Sieve

-- | unicode synonym for <a>l</a>.
(⋄) :: I -> I -> Sieve
infixl 5 ⋄

-- | In a <i>normal</i> <a>Sieve</a> <i>m</i> is <a>&gt;</a> <i>i</i>.
--   
--   <pre>
--   normalise (L (15,19)) == L (15,4)
--   </pre>
normalise :: Sieve -> Sieve

-- | Predicate to test if a <a>Sieve</a> is <i>normal</i>.
--   
--   <pre>
--   is_normal (L (15,4)) == True
--   </pre>
is_normal :: Sieve -> Bool

-- | Predicate to determine if an <a>I</a> is an element of the
--   <a>Sieve</a>.
--   
--   <pre>
--   map (element (L (3,1))) [1..4] == [True,False,False,True]
--   map (element (L (15,4))) [4,19 .. 49] == [True,True,True,True]
--   </pre>
element :: Sieve -> I -> Bool

-- | Construct the sequence defined by a <a>Sieve</a>. Note that building a
--   sieve that contains an intersection clause that has no elements gives
--   <tt>_|_</tt>.
--   
--   <pre>
--   let {d = [0,2,4,5,7,9,11]
--       ;r = d ++ map (+ 12) d}
--   in take 14 (build (union (map (l 12) d))) == r
--   </pre>
build :: Sieve -> [I]

-- | Variant of <a>build</a> that gives the first <i>n</i> places of the
--   <a>reduce</a> of <a>Sieve</a>.
--   
--   <pre>
--   buildn 6 (union (map (l 8) [0,3,6])) == [0,3,6,8,11,14]
--   buildn 12 (L (3,2)) == [2,5,8,11,14,17,20,23,26,29,32,35]
--   buildn 9 (L (8,0)) == [0,8,16,24,32,40,48,56,64]
--   buildn 3 (L (3,2) ∩ L (8,0)) == [8,32,56]
--   buildn 12 (L (3,1) ∪ L (4,0)) == [0,1,4,7,8,10,12,13,16,19,20,22]
--   buildn 14 (5⋄4 ∪ 3⋄2 ∪ 7⋄3) == [2,3,4,5,8,9,10,11,14,17,19,20,23,24]
--   buildn 6 (3⋄0 ∪ 4⋄0) == [0,3,4,6,8,9]
--   buildn 8 (5⋄2 ∩ 2⋄0 ∪ 7⋄3) == [2,3,10,12,17,22,24,31]
--   buildn 12 (5⋄1 ∪ 7⋄2) == [1,2,6,9,11,16,21,23,26,30,31,36]
--   </pre>
--   
--   <pre>
--   buildn 10 (3⋄2 ∩ 4⋄7 ∪ 6⋄9 ∩ 15⋄18) == [3,11,23,33,35,47,59,63,71,83]
--   </pre>
--   
--   <pre>
--   let {s = 3⋄2∩4⋄7∩6⋄11∩8⋄7 ∪ 6⋄9∩15⋄18 ∪ 13⋄5∩8⋄6∩4⋄2 ∪ 6⋄9∩15⋄19
--       ;s' = 24⋄23 ∪ 30⋄3 ∪ 104⋄70}
--   in buildn 16 s == buildn 16 s'
--   </pre>
--   
--   <pre>
--   buildn 10 (24⋄23 ∪ 30⋄3 ∪ 104⋄70) == [3,23,33,47,63,70,71,93,95,119]
--   </pre>
--   
--   <pre>
--   let r = [2,3,4,5,8,9,10,11,14,17,19,20,23,24,26,29,31]
--   in buildn 17 (5⋄4 ∪ 3⋄2 ∪ 7⋄3) == r
--   </pre>
--   
--   <pre>
--   let r = [0,1,3,6,9,10,11,12,15,16,17,18,21,24,26,27,30]
--   in buildn 17 (5⋄1 ∪ 3⋄0 ∪ 7⋄3) == r
--   </pre>
--   
--   <pre>
--   let r = [0,2,3,4,6,7,9,11,12,15,17,18,21,22,24,25,27,30,32]
--   in buildn 19 (5⋄2 ∪ 3⋄0 ∪ 7⋄4) == r
--   </pre>
buildn :: Int -> Sieve -> [I]

-- | Standard differentiation function.
--   
--   <pre>
--   differentiate [1,3,6,10] == [2,3,4]
--   differentiate [0,2,4,5,7,9,11,12] == [2,2,1,2,2,2,1]
--   </pre>
differentiate :: (Num a) => [a] -> [a]

-- | Euclid's algorithm for computing the greatest common divisor.
--   
--   <pre>
--   euclid 1989 867 == 51
--   </pre>
euclid :: (Integral a) => a -> a -> a

-- | Bachet De Méziriac's algorithm.
--   
--   <pre>
--   de_meziriac 15 4 == 3 &amp;&amp; euclid 15 4 == 1
--   </pre>
de_meziriac :: (Integral a) => a -> a -> a

-- | Attempt to reduce the <a>Intersection</a> of two <a>L</a> nodes to a
--   singular <a>L</a> node.
--   
--   <pre>
--   reduce_intersection (3,2) (4,7) == Just (12,11)
--   reduce_intersection (12,11) (6,11) == Just (12,11)
--   reduce_intersection (12,11) (8,7) == Just (24,23)
--   </pre>
reduce_intersection :: (Integral t) => (t, t) -> (t, t) -> Maybe (t, t)

-- | Reduce the number of nodes at a <a>Sieve</a>.
--   
--   <pre>
--   reduce (L (3,2) ∪ Empty) == L (3,2)
--   reduce (L (3,2) ∩ Empty) == L (3,2)
--   reduce (L (3,2) ∩ L (4,7)) == L (12,11)
--   reduce (L (6,9) ∩ L (15,18)) == L (30,3)
--   </pre>
--   
--   <pre>
--   let s = 3⋄2∩4⋄7∩6⋄11∩8⋄7 ∪ 6⋄9∩15⋄18 ∪ 13⋄5∩8⋄6∩4⋄2 ∪ 6⋄9∩15⋄19
--   in reduce s == (24⋄23 ∪ 30⋄3 ∪ 104⋄70)
--   </pre>
--   
--   <pre>
--   let s = 3⋄2∩4⋄7∩6⋄11∩8⋄7 ∪ 6⋄9∩15⋄18 ∪ 13⋄5∩8⋄6∩4⋄2 ∪ 6⋄9∩15⋄19
--   in reduce s == (24⋄23 ∪ 30⋄3 ∪ 104⋄70)
--   </pre>
reduce :: Sieve -> Sieve
instance GHC.Show.Show Music.Theory.Xenakis.Sieve.Sieve
instance GHC.Classes.Eq Music.Theory.Xenakis.Sieve.Sieve


-- | Allen Forte. <i>The Structure of Atonal Music</i>. Yale University
--   Press, New Haven, 1973.
module Music.Theory.Z.Forte_1973

-- | T-related rotations of <i>p</i>.
--   
--   <pre>
--   t_rotations 12 [0,1,3] == [[0,1,3],[0,2,11],[0,9,10]]
--   </pre>
t_rotations :: Integral a => a -> [a] -> [[a]]

-- | T/I-related rotations of <i>p</i>.
--   
--   <pre>
--   ti_rotations 12 [0,1,3] == [[0,1,3],[0,2,11],[0,9,10]
--                              ,[0,9,11],[0,2,3],[0,1,10]]
--   </pre>
ti_rotations :: Integral a => a -> [a] -> [[a]]

-- | Variant with default value for empty input list case.
minimumBy_or :: a -> (a -> a -> Ordering) -> [a] -> a

-- | Prime form rule requiring comparator, considering <a>t_rotations</a>.
t_cmp_prime :: Integral a => a -> ([a] -> [a] -> Ordering) -> [a] -> [a]

-- | Prime form rule requiring comparator, considering <a>ti_rotations</a>.
ti_cmp_prime :: Integral a => a -> ([a] -> [a] -> Ordering) -> [a] -> [a]

-- | Forte comparison function (rightmost first then leftmost outwards).
--   
--   <pre>
--   forte_cmp [0,1,3,6,8,9] [0,2,3,6,7,9] == LT
--   </pre>
forte_cmp :: (Ord t) => [t] -> [t] -> Ordering

-- | Forte prime form, ie. <tt>cmp_prime</tt> of <a>forte_cmp</a>.
--   
--   <pre>
--   forte_prime 12 [0,1,3,6,8,9] == [0,1,3,6,8,9]
--   forte_prime 5 [0,1,4] == [0,1,2]
--   </pre>
--   
--   <pre>
--   S.set (map (forte_prime 5) (S.powerset [0..4]))
--   </pre>
forte_prime :: Integral a => a -> [a] -> [a]

-- | Transpositional equivalence prime form, ie. <a>t_cmp_prime</a> of
--   <a>forte_cmp</a>.
--   
--   <pre>
--   (forte_prime 12 [0,2,3],t_prime 12 [0,2,3]) == ([0,1,3],[0,2,3])
--   </pre>
t_prime :: Integral a => a -> [a] -> [a]

-- | Interval class of i interval <i>i</i>.
--   
--   <pre>
--   map (ic 5) [1,2,3,4] == [1,2,2,1]
--   map (ic 12) [5,6,7] == [5,6,5]
--   map (ic 12 . to_Z 12) [-13,-1,0,1,13] == [1,1,0,1,1]
--   </pre>
ic :: Integral a => a -> a -> a

-- | Forte notation for interval class vector.
--   
--   <pre>
--   icv 12 [0,1,2,4,7,8] == [3,2,2,3,3,2]
--   </pre>
icv :: (Integral i, Num n) => i -> [i] -> [n]

-- | Basic interval pattern, see Allen Forte "The Basic Interval Patterns"
--   <i>JMT</i> 17/2 (1973):234-272
--   
--   <pre>
--   &gt;&gt;&gt; bip 0t95728e3416
--   11223344556
--   </pre>
--   
--   <pre>
--   bip 12 [0,10,9,5,7,2,8,11,3,4,1,6] == [1,1,2,2,3,3,4,4,5,5,6]
--   </pre>
bip :: Integral a => a -> [a] -> [a]


-- | Allen Forte. <i>The Structure of Atonal Music</i>. Yale University
--   Press, New Haven, 1973.
module Music.Theory.Z12.Forte_1973

-- | T-related rotations of <i>p</i>.
--   
--   <pre>
--   t_rotations [0,1,3] == [[0,1,3],[0,2,11],[0,9,10]]
--   </pre>
t_rotations :: [Z12] -> [[Z12]]

-- | T/I-related rotations of <i>p</i>.
--   
--   <pre>
--   ti_rotations [0,1,3] == [[0,1,3],[0,2,11],[0,9,10]
--                           ,[0,9,11],[0,2,3],[0,1,10]]
--   </pre>
ti_rotations :: [Z12] -> [[Z12]]

-- | Forte prime form, ie. <tt>cmp_prime</tt> of <tt>forte_cmp</tt>.
--   
--   <pre>
--   forte_prime [0,1,3,6,8,9] == [0,1,3,6,8,9]
--   </pre>
forte_prime :: [Z12] -> [Z12]

-- | Transpositional equivalence prime form, ie. <tt>t_cmp_prime</tt> of
--   <tt>forte_cmp</tt>.
--   
--   <pre>
--   (forte_prime [0,2,3],t_prime [0,2,3]) == ([0,1,3],[0,2,3])
--   </pre>
t_prime :: [Z12] -> [Z12]

-- | Synonym for <a>String</a>.
type SC_Name = String

-- | The set-class table (Forte prime forms).
--   
--   <pre>
--   length sc_table == 224
--   </pre>
sc_table :: [(SC_Name, [Z12])]

-- | Lookup a set-class name. The input set is subject to
--   <a>forte_prime</a> before lookup.
--   
--   <pre>
--   sc_name [0,2,3,6,7] == "5-Z18"
--   sc_name [0,1,4,6,7,8] == "6-Z17"
--   </pre>
sc_name :: [Z12] -> SC_Name

-- | Lookup a set-class given a set-class name.
--   
--   <pre>
--   sc "6-Z17" == [0,1,2,4,7,8]
--   </pre>
sc :: SC_Name -> [Z12]

-- | List of set classes (the set class universe).
--   
--   <pre>
--   let r = [("0-1",[0,0,0,0,0,0])
--           ,("1-1",[0,0,0,0,0,0])
--           ,("2-1",[1,0,0,0,0,0])
--           ,("2-2",[0,1,0,0,0,0])
--           ,("2-3",[0,0,1,0,0,0])
--           ,("2-4",[0,0,0,1,0,0])
--           ,("2-5",[0,0,0,0,1,0])
--           ,("2-6",[0,0,0,0,0,1])
--           ,("3-1",[2,1,0,0,0,0])
--           ,("3-2",[1,1,1,0,0,0])
--           ,("3-3",[1,0,1,1,0,0])
--           ,("3-4",[1,0,0,1,1,0])
--           ,("3-5",[1,0,0,0,1,1])
--           ,("3-6",[0,2,0,1,0,0])
--           ,("3-7",[0,1,1,0,1,0])
--           ,("3-8",[0,1,0,1,0,1])
--           ,("3-9",[0,1,0,0,2,0])
--           ,("3-10",[0,0,2,0,0,1])
--           ,("3-11",[0,0,1,1,1,0])
--           ,("3-12",[0,0,0,3,0,0])
--           ,("4-1",[3,2,1,0,0,0])
--           ,("4-2",[2,2,1,1,0,0])
--           ,("4-3",[2,1,2,1,0,0])
--           ,("4-4",[2,1,1,1,1,0])
--           ,("4-5",[2,1,0,1,1,1])
--           ,("4-6",[2,1,0,0,2,1])
--           ,("4-7",[2,0,1,2,1,0])
--           ,("4-8",[2,0,0,1,2,1])
--           ,("4-9",[2,0,0,0,2,2])
--           ,("4-10",[1,2,2,0,1,0])
--           ,("4-11",[1,2,1,1,1,0])
--           ,("4-12",[1,1,2,1,0,1])
--           ,("4-13",[1,1,2,0,1,1])
--           ,("4-14",[1,1,1,1,2,0])
--           ,("4-Z15",[1,1,1,1,1,1])
--           ,("4-16",[1,1,0,1,2,1])
--           ,("4-17",[1,0,2,2,1,0])
--           ,("4-18",[1,0,2,1,1,1])
--           ,("4-19",[1,0,1,3,1,0])
--           ,("4-20",[1,0,1,2,2,0])
--           ,("4-21",[0,3,0,2,0,1])
--           ,("4-22",[0,2,1,1,2,0])
--           ,("4-23",[0,2,1,0,3,0])
--           ,("4-24",[0,2,0,3,0,1])
--           ,("4-25",[0,2,0,2,0,2])
--           ,("4-26",[0,1,2,1,2,0])
--           ,("4-27",[0,1,2,1,1,1])
--           ,("4-28",[0,0,4,0,0,2])
--           ,("4-Z29",[1,1,1,1,1,1])
--           ,("5-1",[4,3,2,1,0,0])
--           ,("5-2",[3,3,2,1,1,0])
--           ,("5-3",[3,2,2,2,1,0])
--           ,("5-4",[3,2,2,1,1,1])
--           ,("5-5",[3,2,1,1,2,1])
--           ,("5-6",[3,1,1,2,2,1])
--           ,("5-7",[3,1,0,1,3,2])
--           ,("5-8",[2,3,2,2,0,1])
--           ,("5-9",[2,3,1,2,1,1])
--           ,("5-10",[2,2,3,1,1,1])
--           ,("5-11",[2,2,2,2,2,0])
--           ,("5-Z12",[2,2,2,1,2,1])
--           ,("5-13",[2,2,1,3,1,1])
--           ,("5-14",[2,2,1,1,3,1])
--           ,("5-15",[2,2,0,2,2,2])
--           ,("5-16",[2,1,3,2,1,1])
--           ,("5-Z17",[2,1,2,3,2,0])
--           ,("5-Z18",[2,1,2,2,2,1])
--           ,("5-19",[2,1,2,1,2,2])
--           ,("5-20",[2,1,1,2,3,1])
--           ,("5-21",[2,0,2,4,2,0])
--           ,("5-22",[2,0,2,3,2,1])
--           ,("5-23",[1,3,2,1,3,0])
--           ,("5-24",[1,3,1,2,2,1])
--           ,("5-25",[1,2,3,1,2,1])
--           ,("5-26",[1,2,2,3,1,1])
--           ,("5-27",[1,2,2,2,3,0])
--           ,("5-28",[1,2,2,2,1,2])
--           ,("5-29",[1,2,2,1,3,1])
--           ,("5-30",[1,2,1,3,2,1])
--           ,("5-31",[1,1,4,1,1,2])
--           ,("5-32",[1,1,3,2,2,1])
--           ,("5-33",[0,4,0,4,0,2])
--           ,("5-34",[0,3,2,2,2,1])
--           ,("5-35",[0,3,2,1,4,0])
--           ,("5-Z36",[2,2,2,1,2,1])
--           ,("5-Z37",[2,1,2,3,2,0])
--           ,("5-Z38",[2,1,2,2,2,1])
--           ,("6-1",[5,4,3,2,1,0])
--           ,("6-2",[4,4,3,2,1,1])
--           ,("6-Z3",[4,3,3,2,2,1])
--           ,("6-Z4",[4,3,2,3,2,1])
--           ,("6-5",[4,2,2,2,3,2])
--           ,("6-Z6",[4,2,1,2,4,2])
--           ,("6-7",[4,2,0,2,4,3])
--           ,("6-8",[3,4,3,2,3,0])
--           ,("6-9",[3,4,2,2,3,1])
--           ,("6-Z10",[3,3,3,3,2,1])
--           ,("6-Z11",[3,3,3,2,3,1])
--           ,("6-Z12",[3,3,2,2,3,2])
--           ,("6-Z13",[3,2,4,2,2,2])
--           ,("6-14",[3,2,3,4,3,0])
--           ,("6-15",[3,2,3,4,2,1])
--           ,("6-16",[3,2,2,4,3,1])
--           ,("6-Z17",[3,2,2,3,3,2])
--           ,("6-18",[3,2,2,2,4,2])
--           ,("6-Z19",[3,1,3,4,3,1])
--           ,("6-20",[3,0,3,6,3,0])
--           ,("6-21",[2,4,2,4,1,2])
--           ,("6-22",[2,4,1,4,2,2])
--           ,("6-Z23",[2,3,4,2,2,2])
--           ,("6-Z24",[2,3,3,3,3,1])
--           ,("6-Z25",[2,3,3,2,4,1])
--           ,("6-Z26",[2,3,2,3,4,1])
--           ,("6-27",[2,2,5,2,2,2])
--           ,("6-Z28",[2,2,4,3,2,2])
--           ,("6-Z29",[2,2,4,2,3,2])
--           ,("6-30",[2,2,4,2,2,3])
--           ,("6-31",[2,2,3,4,3,1])
--           ,("6-32",[1,4,3,2,5,0])
--           ,("6-33",[1,4,3,2,4,1])
--           ,("6-34",[1,4,2,4,2,2])
--           ,("6-35",[0,6,0,6,0,3])
--           ,("6-Z36",[4,3,3,2,2,1])
--           ,("6-Z37",[4,3,2,3,2,1])
--           ,("6-Z38",[4,2,1,2,4,2])
--           ,("6-Z39",[3,3,3,3,2,1])
--           ,("6-Z40",[3,3,3,2,3,1])
--           ,("6-Z41",[3,3,2,2,3,2])
--           ,("6-Z42",[3,2,4,2,2,2])
--           ,("6-Z43",[3,2,2,3,3,2])
--           ,("6-Z44",[3,1,3,4,3,1])
--           ,("6-Z45",[2,3,4,2,2,2])
--           ,("6-Z46",[2,3,3,3,3,1])
--           ,("6-Z47",[2,3,3,2,4,1])
--           ,("6-Z48",[2,3,2,3,4,1])
--           ,("6-Z49",[2,2,4,3,2,2])
--           ,("6-Z50",[2,2,4,2,3,2])
--           ,("7-1",[6,5,4,3,2,1])
--           ,("7-2",[5,5,4,3,3,1])
--           ,("7-3",[5,4,4,4,3,1])
--           ,("7-4",[5,4,4,3,3,2])
--           ,("7-5",[5,4,3,3,4,2])
--           ,("7-6",[5,3,3,4,4,2])
--           ,("7-7",[5,3,2,3,5,3])
--           ,("7-8",[4,5,4,4,2,2])
--           ,("7-9",[4,5,3,4,3,2])
--           ,("7-10",[4,4,5,3,3,2])
--           ,("7-11",[4,4,4,4,4,1])
--           ,("7-Z12",[4,4,4,3,4,2])
--           ,("7-13",[4,4,3,5,3,2])
--           ,("7-14",[4,4,3,3,5,2])
--           ,("7-15",[4,4,2,4,4,3])
--           ,("7-16",[4,3,5,4,3,2])
--           ,("7-Z17",[4,3,4,5,4,1])
--           ,("7-Z18",[4,3,4,4,4,2])
--           ,("7-19",[4,3,4,3,4,3])
--           ,("7-20",[4,3,3,4,5,2])
--           ,("7-21",[4,2,4,6,4,1])
--           ,("7-22",[4,2,4,5,4,2])
--           ,("7-23",[3,5,4,3,5,1])
--           ,("7-24",[3,5,3,4,4,2])
--           ,("7-25",[3,4,5,3,4,2])
--           ,("7-26",[3,4,4,5,3,2])
--           ,("7-27",[3,4,4,4,5,1])
--           ,("7-28",[3,4,4,4,3,3])
--           ,("7-29",[3,4,4,3,5,2])
--           ,("7-30",[3,4,3,5,4,2])
--           ,("7-31",[3,3,6,3,3,3])
--           ,("7-32",[3,3,5,4,4,2])
--           ,("7-33",[2,6,2,6,2,3])
--           ,("7-34",[2,5,4,4,4,2])
--           ,("7-35",[2,5,4,3,6,1])
--           ,("7-Z36",[4,4,4,3,4,2])
--           ,("7-Z37",[4,3,4,5,4,1])
--           ,("7-Z38",[4,3,4,4,4,2])
--           ,("8-1",[7,6,5,4,4,2])
--           ,("8-2",[6,6,5,5,4,2])
--           ,("8-3",[6,5,6,5,4,2])
--           ,("8-4",[6,5,5,5,5,2])
--           ,("8-5",[6,5,4,5,5,3])
--           ,("8-6",[6,5,4,4,6,3])
--           ,("8-7",[6,4,5,6,5,2])
--           ,("8-8",[6,4,4,5,6,3])
--           ,("8-9",[6,4,4,4,6,4])
--           ,("8-10",[5,6,6,4,5,2])
--           ,("8-11",[5,6,5,5,5,2])
--           ,("8-12",[5,5,6,5,4,3])
--           ,("8-13",[5,5,6,4,5,3])
--           ,("8-14",[5,5,5,5,6,2])
--           ,("8-Z15",[5,5,5,5,5,3])
--           ,("8-16",[5,5,4,5,6,3])
--           ,("8-17",[5,4,6,6,5,2])
--           ,("8-18",[5,4,6,5,5,3])
--           ,("8-19",[5,4,5,7,5,2])
--           ,("8-20",[5,4,5,6,6,2])
--           ,("8-21",[4,7,4,6,4,3])
--           ,("8-22",[4,6,5,5,6,2])
--           ,("8-23",[4,6,5,4,7,2])
--           ,("8-24",[4,6,4,7,4,3])
--           ,("8-25",[4,6,4,6,4,4])
--           ,("8-26",[4,5,6,5,6,2])
--           ,("8-27",[4,5,6,5,5,3])
--           ,("8-28",[4,4,8,4,4,4])
--           ,("8-Z29",[5,5,5,5,5,3])
--           ,("9-1",[8,7,6,6,6,3])
--           ,("9-2",[7,7,7,6,6,3])
--           ,("9-3",[7,6,7,7,6,3])
--           ,("9-4",[7,6,6,7,7,3])
--           ,("9-5",[7,6,6,6,7,4])
--           ,("9-6",[6,8,6,7,6,3])
--           ,("9-7",[6,7,7,6,7,3])
--           ,("9-8",[6,7,6,7,6,4])
--           ,("9-9",[6,7,6,6,8,3])
--           ,("9-10",[6,6,8,6,6,4])
--           ,("9-11",[6,6,7,7,7,3])
--           ,("9-12",[6,6,6,9,6,3])
--           ,("10-1",[9,8,8,8,8,4])
--           ,("10-2",[8,9,8,8,8,4])
--           ,("10-3",[8,8,9,8,8,4])
--           ,("10-4",[8,8,8,9,8,4])
--           ,("10-5",[8,8,8,8,9,4])
--           ,("10-6",[8,8,8,8,8,5])
--           ,("11-1",[10,10,10,10,10,5])
--           ,("12-1",[12,12,12,12,12,6])]
--   in let icvs = map icv scs in zip (map sc_name scs) icvs == r
--   </pre>
scs :: [[Z12]]

-- | Cardinality <i>n</i> subset of <a>scs</a>.
--   
--   <pre>
--   map (length . scs_n) [1..11] == [1,6,12,29,38,50,38,29,12,6,1]
--   </pre>
scs_n :: Integral i => i -> [[Z12]]

-- | Basic interval pattern, see Allen Forte "The Basic Interval Patterns"
--   <i>JMT</i> 17/2 (1973):234-272
--   
--   <pre>
--   &gt;&gt;&gt; bip 0t95728e3416
--   11223344556
--   </pre>
--   
--   <pre>
--   bip [0,10,9,5,7,2,8,11,3,4,1,6] == [1,1,2,2,3,3,4,4,5,5,6]
--   bip (pco "0t95728e3416") == [1,1,2,2,3,3,4,4,5,5,6]
--   </pre>
bip :: [Z12] -> [Z12]

-- | Interval class of Z12 interval <i>i</i>.
--   
--   <pre>
--   map ic [5,6,7] == [5,6,5]
--   map ic [-13,-1,0,1,13] == [1,1,0,1,1]
--   </pre>
ic :: Z12 -> Z12

-- | Forte notation for interval class vector.
--   
--   <pre>
--   icv [0,1,2,4,7,8] == [3,2,2,3,3,2]
--   </pre>
icv :: Integral i => [Z12] -> [i]


-- | Michael Buchler. "Relative Saturation of Subsets and Interval Cycles
--   as a Means for Determining Set-Class Similarity". PhD thesis,
--   University of Rochester, 1998
module Music.Theory.Metric.Buchler_1998

-- | Predicate for list with cardinality <i>n</i>.
of_c :: Integral n => n -> [a] -> Bool

-- | Set classes of cardinality <i>n</i>.
--   
--   <pre>
--   sc_table_n 2 == [[0,1],[0,2],[0,3],[0,4],[0,5],[0,6]]
--   </pre>
sc_table_n :: (Integral n) => n -> [[Z12]]

-- | Minima and maxima of ICV of SCs of cardinality <i>n</i>.
--   
--   <pre>
--   icv_minmax 5 == ([0,0,0,1,0,0],[4,4,4,4,4,2])
--   </pre>
icv_minmax :: (Integral n, Integral b) => n -> ([b], [b])
data R
MIN :: R
MAX :: R
type D n = (R, n)

-- | Pretty printer for <a>R</a>.
--   
--   <pre>
--   map r_pp [MIN,MAX] == ["+","-"]
--   </pre>
r_pp :: R -> String

-- | <a>SATV</a> element measure with given funtion.
satv_f :: (Integral n) => ((n, n, n) -> D n) -> [Z12] -> [D n]

-- | Pretty printer for SATV element.
--   
--   <pre>
--   satv_e_pp (satv_a [0,1,2,6,7,8]) == "&lt;-1,+2,+0,+0,-1,-0&gt;"
--   </pre>
satv_e_pp :: Show i => [D i] -> String
type SATV i = ([D i], [D i])

-- | Pretty printer for <a>SATV</a>.
satv_pp :: Show i => SATV i -> String

-- | <tt>SATVa</tt> measure.
--   
--   <pre>
--   satv_e_pp (satv_a [0,1,2,6,7,8]) == "&lt;-1,+2,+0,+0,-1,-0&gt;"
--   satv_e_pp (satv_a [0,1,2,3,4]) == "&lt;-0,-1,-2,+0,+0,+0&gt;"
--   </pre>
satv_a :: Integral i => [Z12] -> [D i]

-- | <tt>SATVb</tt> measure.
--   
--   <pre>
--   satv_e_pp (satv_b [0,1,2,6,7,8]) == "&lt;+4,-4,-5,-4,+4,+3&gt;"
--   satv_e_pp (satv_b [0,1,2,3,4]) == "&lt;+4,+3,+2,-3,-4,-2&gt;"
--   </pre>
satv_b :: Integral i => [Z12] -> [D i]

-- | <a>SATV</a> measure.
--   
--   <pre>
--   satv_pp (satv [0,3,6,9]) == "(&lt;+0,+0,-0,+0,+0,-0&gt;,&lt;-3,-3,+4,-3,-3,+2&gt;)"
--   satv_pp (satv [0,1,3,4,8]) == "(&lt;-2,+1,-2,-1,-2,+0&gt;,&lt;+2,-3,+2,+2,+2,-2&gt;)"
--   satv_pp (satv [0,1,2,6,7,8]) == "(&lt;-1,+2,+0,+0,-1,-0&gt;,&lt;+4,-4,-5,-4,+4,+3&gt;)"
--   satv_pp (satv [0,4]) == "(&lt;+0,+0,+0,-0,+0,+0&gt;,&lt;-1,-1,-1,+1,-1,-1&gt;)"
--   satv_pp (satv [0,1,3,4,6,9]) == "(&lt;+2,+2,-0,+0,+2,-1&gt;,&lt;-3,-4,+5,-4,-3,+2&gt;)"
--   satv_pp (satv [0,1,3,6,7,9]) == "(&lt;+2,+2,-1,+0,+2,-0&gt;,&lt;-3,-4,+4,-4,-3,+3&gt;)"
--   satv_pp (satv [0,1,2,3,6]) == "(&lt;-1,-2,-2,+0,+1,-1&gt;,&lt;+3,+2,+2,-3,-3,+1&gt;)"
--   satv_pp (satv [0,1,2,3,4,6]) == "(&lt;-1,-2,-2,+0,+1,+1&gt;,&lt;+4,+4,+3,-4,-4,-2&gt;)"
--   satv_pp (satv [0,1,3,6,8]) == "(&lt;+1,-2,-2,+0,-1,-1&gt;,&lt;-3,+2,+2,-3,+3,+1&gt;)"
--   satv_pp (satv [0,2,3,5,7,9]) == "(&lt;+1,-2,-2,+0,-1,+1&gt;,&lt;-4,+4,+3,-4,+4,-2&gt;)"
--   </pre>
satv :: Integral i => [Z12] -> SATV i

-- | <a>SATV</a> reorganised by <a>R</a>.
--   
--   <pre>
--   satv_minmax (satv [0,1,2,6,7,8]) == ([4,2,0,0,4,3],[1,4,5,4,1,0])
--   </pre>
satv_minmax :: SATV i -> ([i], [i])

-- | Absolute difference.
abs_dif :: Num a => a -> a -> a

-- | Sum of numerical components of <tt>a</tt> and <tt>b</tt> parts of
--   <a>SATV</a>.
--   
--   <pre>
--   satv_n_sum (satv [0,1,2,6,7,8]) == [5,6,5,4,5,3]
--   satv_n_sum (satv [0,3,6,9]) = [3,3,4,3,3,2]
--   </pre>
satv_n_sum :: Num c => SATV c -> [c]
two_part_difference_vector :: (Integral i) => [D i] -> SATV i -> [i]
two_part_difference_vector_set :: (Integral i) => SATV i -> SATV i -> ([i], [i])

-- | <tt>SATSIM</tt> metric.
--   
--   <pre>
--   satsim [0,1,2,6,7,8] [0,3,6,9] == 25/46
--   satsim [0,4] [0,1,3,4,6,9] == 25/34
--   satsim [0,4] [0,1,3,6,7,9] == 25/34
--   satsim [0,1,2,3,6] [0,1,2,3,4,6] == 1/49
--   satsim [0,1,3,6,8] [0,2,3,5,7,9] == 1/49
--   satsim [0,1,2,3,4] [0,1,4,5,7] == 8/21
--   satsim [0,1,2,3,4] [0,2,4,6,8] == 4/7
--   satsim [0,1,4,5,7] [0,2,4,6,8] == 4/7
--   </pre>
satsim :: Integral a => [Z12] -> [Z12] -> Ratio a

-- | Table of <a>satsim</a> measures for all <tt>SC</tt> pairs.
--   
--   <pre>
--   length satsim_table == 24310
--   </pre>
satsim_table :: Integral i => [(([Z12], [Z12]), Ratio i)]

-- | Histogram of values at <a>satsim_table</a>.
--   
--   <pre>
--   satsim_table_histogram == T.histogram (map snd satsim_table)
--   </pre>
satsim_table_histogram :: Integral i => [(Ratio i, i)]
instance GHC.Show.Show Music.Theory.Metric.Buchler_1998.R
instance GHC.Classes.Eq Music.Theory.Metric.Buchler_1998.R


-- | Robert Morris. "A Similarity Index for Pitch-Class Sets". Perspectives
--   of New Music, 18(2):445-460, 1980.
module Music.Theory.Metric.Morris_1980

-- | SIM
--   
--   <pre>
--   icv [0,1,3,6] == [1,1,2,0,1,1] &amp;&amp; icv [0,2,4,7] == [0,2,1,1,2,0]
--   sim [0,1,3,6] [0,2,4,7] == 6
--   sim [0,1,2,4,5,8] [0,1,3,7] == 9
--   </pre>
sim :: Integral a => [Z12] -> [Z12] -> a

-- | ASIM
--   
--   <pre>
--   asim [0,1,3,6] [0,2,4,7] == 6/12
--   asim [0,1,2,4,5,8] [0,1,3,7] == 9/21
--   asim [0,1,2,3,4] [0,1,4,5,7] == 2/5
--   asim [0,1,2,3,4] [0,2,4,6,8] == 3/5
--   asim [0,1,4,5,7] [0,2,4,6,8] == 3/5
--   </pre>
asim :: (Integral n) => [Z12] -> [Z12] -> Ratio n


-- | John Rahn. <i>Basic Atonal Theory</i>. Longman, New York, 1980.
module Music.Theory.Z12.Rahn_1980

-- | Rahn prime form (comparison is rightmost inwards).
--   
--   <pre>
--   rahn_cmp [0,1,3,6,8,9] [0,2,3,6,7,9] == GT
--   </pre>
rahn_cmp :: Ord a => [a] -> [a] -> Ordering

-- | Rahn prime form, ie. <tt>ti_cmp_prime</tt> of <a>rahn_cmp</a>.
--   
--   <pre>
--   rahn_prime [0,1,3,6,8,9] == [0,2,3,6,7,9]
--   </pre>
--   
--   <pre>
--   import Music.Theory.Z12.Forte_1973
--   </pre>
--   
--   <pre>
--   let s = [[0,1,3,7,8]
--           ,[0,1,3,6,8,9],[0,1,3,5,8,9]
--           ,[0,1,2,4,7,8,9]
--           ,[0,1,2,4,5,7,9,10]]
--   in all (\p -&gt; forte_prime p /= rahn_prime p) s == True
--   </pre>
rahn_prime :: [Z12] -> [Z12]


-- | Marcus Castrén. <i>RECREL: A Similarity Measure for Set-Classes</i>.
--   PhD thesis, Sibelius Academy, Helsinki, 1994.
module Music.Theory.Z12.Castren_1994

-- | Is <i>p</i> symmetrical under inversion.
--   
--   <pre>
--   import Music.Theory.Z12.Forte_1973
--   map inv_sym (scs_n 2) == [True,True,True,True,True,True]
--   map (fromEnum.inv_sym) (scs_n 3) == [1,0,0,0,0,1,0,0,1,1,0,1]
--   </pre>
inv_sym :: [Z12] -> Bool

-- | If <i>p</i> is not <a>inv_sym</a> then <tt>(p,invert 0 p)</tt> else
--   <a>Nothing</a>.
--   
--   <pre>
--   sc_t_ti [0,2,4] == Nothing
--   sc_t_ti [0,1,3] == Just ([0,1,3],[0,2,3])
--   </pre>
sc_t_ti :: [Z12] -> Maybe ([Z12], [Z12])

-- | Transpositional equivalence variant of Forte's <tt>sc_table</tt>. The
--   inversionally related classes are distinguished by labels <tt>A</tt>
--   and <tt>B</tt>; the class providing the <i>best normal order</i>
--   (Forte 1973) is always the <tt>A</tt> class. If neither <tt>A</tt> nor
--   <tt>B</tt> appears in the name of a set-class, it is inversionally
--   symmetrical.
--   
--   <pre>
--   (length sc_table,length t_sc_table) == (224,352)
--   lookup "5-Z18B" t_sc_table == Just [0,2,3,6,7]
--   </pre>
t_sc_table :: [(SC_Name, [Z12])]

-- | Lookup a set-class name. The input set is subject to <tt>t_prime</tt>
--   before lookup.
--   
--   <pre>
--   t_sc_name [0,2,3,6,7] == "5-Z18B"
--   t_sc_name [0,1,4,6,7,8] == "6-Z17B"
--   </pre>
t_sc_name :: [Z12] -> SC_Name

-- | Lookup a set-class given a set-class name.
--   
--   <pre>
--   t_sc "6-Z17A" == [0,1,2,4,7,8]
--   </pre>
t_sc :: SC_Name -> [Z12]

-- | List of set classes.
t_scs :: [[Z12]]

-- | Cardinality <i>n</i> subset of <a>t_scs</a>.
--   
--   <pre>
--   map (length . t_scs_n) [2..10] == [6,19,43,66,80,66,43,19,6]
--   </pre>
t_scs_n :: Integral i => i -> [[Z12]]

-- | T-related <i>q</i> that are subsets of <i>p</i>.
--   
--   <pre>
--   t_subsets [0,1,2,3,4] [0,1]  == [[0,1],[1,2],[2,3],[3,4]]
--   t_subsets [0,1,2,3,4] [0,1,4] == [[0,1,4]]
--   t_subsets [0,2,3,6,7] [0,1,4] == [[2,3,6]]
--   </pre>
t_subsets :: [Z12] -> [Z12] -> [[Z12]]

-- | T/I-related <i>q</i> that are subsets of <i>p</i>.
--   
--   <pre>
--   ti_subsets [0,1,2,3,4] [0,1]  == [[0,1],[1,2],[2,3],[3,4]]
--   ti_subsets [0,1,2,3,4] [0,1,4] == [[0,1,4],[0,3,4]]
--   ti_subsets [0,2,3,6,7] [0,1,4] == [[2,3,6],[3,6,7]]
--   </pre>
ti_subsets :: [Z12] -> [Z12] -> [[Z12]]

-- | Trivial run length encoder.
--   
--   <pre>
--   rle "abbcccdde" == [(1,'a'),(2,'b'),(3,'c'),(2,'d'),(1,'e')]
--   </pre>
rle :: (Eq a, Integral i) => [a] -> [(i, a)]

-- | Inverse of <a>rle</a>.
--   
--   <pre>
--   rle_decode [(5,'a'),(4,'b')] == "aaaaabbbb"
--   </pre>
rle_decode :: (Integral i) => [(i, a)] -> [a]

-- | Length of <i>rle</i> encoded sequence.
--   
--   <pre>
--   rle_length [(5,'a'),(4,'b')] == 9
--   </pre>
rle_length :: (Integral i) => [(i, a)] -> i

-- | T-equivalence <i>n</i>-class vector (subset-class vector, nCV).
--   
--   <pre>
--   t_n_class_vector 2 [0..4] == [4,3,2,1,0,0]
--   rle (t_n_class_vector 3 [0..4]) == [(1,3),(2,2),(2,1),(4,0),(1,1),(9,0)]
--   rle (t_n_class_vector 4 [0..4]) == [(1,2),(3,1),(39,0)]
--   </pre>
t_n_class_vector :: (Num a, Integral i) => i -> [Z12] -> [a]

-- | T/I-equivalence <i>n</i>-class vector (subset-class vector, nCV).
--   
--   <pre>
--   ti_n_class_vector 2 [0..4] == [4,3,2,1,0,0]
--   ti_n_class_vector 3 [0,1,2,3,4] == [3,4,2,0,0,1,0,0,0,0,0,0]
--   rle (ti_n_class_vector 4 [0,1,2,3,4]) == [(2,2),(1,1),(26,0)]
--   </pre>
ti_n_class_vector :: (Num b, Integral i) => i -> [Z12] -> [b]

-- | <tt>icv</tt> scaled by sum of <i>icv</i>.
--   
--   <pre>
--   dyad_class_percentage_vector [0,1,2,3,4] == [40,30,20,10,0,0]
--   dyad_class_percentage_vector [0,1,4,5,7] == [20,10,20,20,20,10]
--   </pre>
dyad_class_percentage_vector :: Integral i => [Z12] -> [i]

-- | <i>rel</i> metric.
--   
--   <pre>
--   rel [0,1,2,3,4] [0,1,4,5,7] == 40
--   rel [0,1,2,3,4] [0,2,4,6,8] == 60
--   rel [0,1,4,5,7] [0,2,4,6,8] == 60
--   </pre>
rel :: Integral i => [Z12] -> [Z12] -> Ratio i


-- | David Lewin. "A Response to a Response: On PC Set Relatedness".
--   <i>Perspectives of New Music</i>, 18(1-2):498-502, 1980.
module Music.Theory.Z12.Lewin_1980

-- | REL function with given <i>ncv</i> function (see <a>t_rel</a> and
--   <a>ti_rel</a>).
rel :: Floating n => (Int -> [a] -> [n]) -> [a] -> [a] -> n

-- | T-equivalence REL function.
--   
--   Kuusi 2001, 7.5.2
--   
--   <pre>
--   let (~=) p q = abs (p - q) &lt; 1e-2
--   t_rel [0,1,2,3,4] [0,2,3,6,7] ~= 0.44
--   t_rel [0,1,2,3,4] [0,2,4,6,8] ~= 0.28
--   t_rel [0,2,3,6,7] [0,2,4,6,8] ~= 0.31
--   </pre>
t_rel :: Floating n => [Z12] -> [Z12] -> n

-- | T/I-equivalence REL function.
--   
--   Buchler 1998, Fig. 3.38
--   
--   <pre>
--   let (~=) p q = abs (p - q) &lt; 1e-3
--   let a = [0,2,3,5,7]::[Z12]
--   let b = [0,2,3,4,5,8]::[Z12]
--   let g = [0,1,2,3,5,6,8,10]::[Z12]
--   let j = [0,2,3,4,5,6,8]::[Z12]
--   ti_rel a b ~= 0.593
--   ti_rel a g ~= 0.648
--   ti_rel a j ~= 0.509
--   ti_rel b g ~= 0.712
--   ti_rel b j ~= 0.892
--   ti_rel g j ~= 0.707
--   </pre>
ti_rel :: Floating n => [Z12] -> [Z12] -> n


-- | Serial (ordered) pitch-class operations on <a>Z12</a>.
module Music.Theory.Z12.SRO

-- | Transpose <i>p</i> by <i>n</i>.
--   
--   <pre>
--   tn 4 [1,5,6] == [5,9,10]
--   </pre>
tn :: Z12 -> [Z12] -> [Z12]

-- | Invert <i>p</i> about <i>n</i>.
--   
--   <pre>
--   invert 6 [4,5,6] == [8,7,6]
--   invert 0 [0,1,3] == [0,11,9]
--   </pre>
invert :: Z12 -> [Z12] -> [Z12]

-- | Composition of <a>invert</a> about <tt>0</tt> and <a>tn</a>.
--   
--   <pre>
--   tni 4 [1,5,6] == [3,11,10]
--   (invert 0 . tn  4) [1,5,6] == [7,3,2]
--   </pre>
tni :: Z12 -> [Z12] -> [Z12]

-- | Modulo 12 multiplication
--   
--   <pre>
--   mn 11 [0,1,4,9] == tni 0 [0,1,4,9]
--   </pre>
mn :: Z12 -> [Z12] -> [Z12]

-- | M5, ie. <a>mn</a> <tt>5</tt>.
--   
--   <pre>
--   m5 [0,1,3] == [0,5,3]
--   </pre>
m5 :: [Z12] -> [Z12]

-- | T-related sequences of <i>p</i>.
--   
--   <pre>
--   length (t_related [0,3,6,9]) == 12
--   </pre>
t_related :: [Z12] -> [[Z12]]

-- | T/I-related sequences of <i>p</i>.
--   
--   <pre>
--   length (ti_related [0,1,3]) == 24
--   length (ti_related [0,3,6,9]) == 24
--   ti_related [0] == map return [0..11]
--   </pre>
ti_related :: [Z12] -> [[Z12]]

-- | R/T/I-related sequences of <i>p</i>.
--   
--   <pre>
--   length (rti_related [0,1,3]) == 48
--   length (rti_related [0,3,6,9]) == 24
--   </pre>
rti_related :: [Z12] -> [[Z12]]

-- | T/M/I-related sequences of <i>p</i>.
tmi_related :: [Z12] -> [[Z12]]

-- | R/T/M/I-related sequences of <i>p</i>.
rtmi_related :: [Z12] -> [[Z12]]

-- | r/R/T/M/I-related sequences of <i>p</i>.
rrtmi_related :: [Z12] -> [[Z12]]

-- | Variant of <a>tn</a>, transpose <i>p</i> so first element is <i>n</i>.
--   
--   <pre>
--   tn_to 5 [0,1,3] == [5,6,8]
--   map (tn_to 0) [[0,1,3],[1,3,0],[3,0,1]] == [[0,1,3],[0,2,11],[0,9,10]]
--   </pre>
tn_to :: Z12 -> [Z12] -> [Z12]

-- | Variant of <a>invert</a>, inverse about <i>n</i>th element.
--   
--   <pre>
--   map (invert_ix 0) [[0,1,3],[3,4,6]] == [[0,11,9],[3,2,0]]
--   map (invert_ix 1) [[0,1,3],[3,4,6]] == [[2,1,11],[5,4,2]]
--   </pre>
invert_ix :: Int -> [Z12] -> [Z12]

-- | The standard t-matrix of <i>p</i>.
--   
--   <pre>
--   tmatrix [0,1,3] == [[0,1,3]
--                      ,[11,0,2]
--                      ,[9,10,0]]
--   </pre>
tmatrix :: [Z12] -> [[Z12]]


-- | Robert Morris. /Composition with Pitch-Classes: A Theory of
--   Compositional Design/. Yale University Press, New Haven, 1987.
module Music.Theory.Z12.Morris_1987

-- | <tt>INT</tt> operator.
--   
--   <pre>
--   int [0,1,3,6,10] == [1,2,3,4]
--   </pre>
int :: [Z12] -> [Z12]

-- | Serial Operator,of the form rRTMI.
data SRO
SRO :: Z12 -> Bool -> Z12 -> Bool -> Bool -> SRO

-- | Serial operation.
--   
--   <pre>
--   &gt;&gt;&gt; sro T4 156
--   59A
--   </pre>
--   
--   <pre>
--   sro (rnrtnmi "T4") (pco "156") == [5,9,10]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; echo 024579 | sro RT4I
--   79B024
--   </pre>
--   
--   <pre>
--   sro (SRO 0 True 4 False True) [0,2,4,5,7,9] == [7,9,11,0,2,4]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; sro T4I 156
--   3BA
--   </pre>
--   
--   <pre>
--   sro (rnrtnmi "T4I") (pco "156") == [3,11,10]
--   sro (SRO 0 False 4 False True) [1,5,6] == [3,11,10]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; echo 156 | sro T4  | sro T0I
--   732
--   </pre>
--   
--   <pre>
--   (sro (rnrtnmi "T0I") . sro (rnrtnmi "T4")) (pco "156") == [7,3,2]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; echo 024579 | sro RT4I
--   79B024
--   </pre>
--   
--   <pre>
--   sro (rnrtnmi "RT4I") (pco "024579") == [7,9,11,0,2,4]
--   </pre>
--   
--   <pre>
--   sro (SRO 1 True 1 True False) [0,1,2,3] == [11,6,1,4]
--   sro (SRO 1 False 4 True True) [0,1,2,3] == [11,6,1,4]
--   </pre>
sro :: SRO -> [Z12] -> [Z12]

-- | The total set of serial operations.
sros :: [Z12] -> [(SRO, [Z12])]

-- | The set of transposition <a>SRO</a>s.
sro_Tn :: [SRO]

-- | The set of transposition and inversion <a>SRO</a>s.
sro_TnI :: [SRO]

-- | The set of retrograde and transposition and inversion <a>SRO</a>s.
sro_RTnI :: [SRO]

-- | The set of transposition,<tt>M5</tt> and inversion <a>SRO</a>s.
sro_TnMI :: [SRO]

-- | The set of retrograde,transposition,<tt>M5</tt> and inversion
--   <a>SRO</a>s.
sro_RTnMI :: [SRO]
instance GHC.Show.Show Music.Theory.Z12.Morris_1987.SRO
instance GHC.Classes.Eq Music.Theory.Z12.Morris_1987.SRO


-- | Haskell implementations of <tt>pct</tt> operations. See
--   <a>http://slavepianos.org/rd/?t=pct</a>.
module Music.Theory.Z12.Drape_1999

-- | Cardinality filter
--   
--   <pre>
--   cf [0,3] (cg [1..4]) == [[1,2,3],[1,2,4],[1,3,4],[2,3,4],[]]
--   </pre>
cf :: (Integral n) => [n] -> [[a]] -> [[a]]

-- | Combinatorial sets formed by considering each set as possible values
--   for slot.
--   
--   <pre>
--   cgg [[0,1],[5,7],[3]] == [[0,5,3],[0,7,3],[1,5,3],[1,7,3]]
--   </pre>
cgg :: [[a]] -> [[a]]

-- | Combinations generator, ie. synonym for <a>powerset</a>.
--   
--   <pre>
--   sort (cg [0,1,3]) == [[],[0],[0,1],[0,1,3],[0,3],[1],[1,3],[3]]
--   </pre>
cg :: [a] -> [[a]]

-- | Powerset filtered by cardinality.
--   
--   <pre>
--   &gt;&gt;&gt; cg -r3 0159
--   015
--   019
--   059
--   159
--   </pre>
--   
--   <pre>
--   cg_r 3 [0,1,5,9] == [[0,1,5],[0,1,9],[0,5,9],[1,5,9]]
--   </pre>
cg_r :: (Integral n) => n -> [a] -> [[a]]

-- | Cyclic interval segment.
ciseg :: [Z12] -> [Z12]

-- | Synonynm for <a>complement</a>.
--   
--   <pre>
--   &gt;&gt;&gt; cmpl 02468t
--   13579B
--   </pre>
--   
--   <pre>
--   cmpl [0,2,4,6,8,10] == [1,3,5,7,9,11]
--   </pre>
cmpl :: [Z12] -> [Z12]

-- | Form cycle.
--   
--   <pre>
--   &gt;&gt;&gt; cyc 056
--   0560
--   </pre>
--   
--   <pre>
--   cyc [0,5,6] == [0,5,6,0]
--   </pre>
cyc :: [a] -> [a]

-- | Diatonic set name. <tt>d</tt> for diatonic set, <tt>m</tt> for melodic
--   minor set, <tt>o</tt> for octotonic set.
d_nm :: (Integral a) => [a] -> Maybe Char

-- | Diatonic implications.
dim :: [Z12] -> [(Z12, [Z12])]

-- | Variant of <a>dim</a> that is closer to the <tt>pct</tt> form.
--   
--   <pre>
--   &gt;&gt;&gt; dim 016
--   T1d
--   T1m
--   T0o
--   </pre>
--   
--   <pre>
--   dim_nm [0,1,6] == [(1,'d'),(1,'m'),(0,'o')]
--   </pre>
dim_nm :: [Z12] -> [(Z12, Char)]

-- | Diatonic interval set to interval set.
--   
--   <pre>
--   &gt;&gt;&gt; dis 24
--   1256
--   </pre>
--   
--   <pre>
--   dis [2,4] == [1,2,5,6]
--   </pre>
dis :: (Integral t) => [Int] -> [t]

-- | Degree of intersection.
--   
--   <pre>
--   &gt;&gt;&gt; echo 024579e | doi 6 | sort -u
--   024579A
--   024679B
--   </pre>
--   
--   <pre>
--   let p = [0,2,4,5,7,9,11]
--   in doi 6 p p == [[0,2,4,5,7,9,10],[0,2,4,6,7,9,11]]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; echo 01234 | doi 2 7-35 | sort -u
--   13568AB
--   </pre>
--   
--   <pre>
--   doi 2 (T.sc "7-35") [0,1,2,3,4] == [[1,3,5,6,8,10,11]]
--   </pre>
doi :: Int -> [Z12] -> [Z12] -> [[Z12]]

-- | Forte name.
fn :: [Z12] -> String

-- | p <a>has_ess</a> q is true iff p can embed q in sequence.
has_ess :: [Z12] -> [Z12] -> Bool

-- | Embedded segment search.
--   
--   <pre>
--   &gt;&gt;&gt; echo 23a | ess 0164325
--   2B013A9
--   923507A
--   </pre>
--   
--   <pre>
--   ess [2,3,10] [0,1,6,4,3,2,5] == [[9,2,3,5,0,7,10],[2,11,0,1,3,10,9]]
--   </pre>
ess :: [Z12] -> [Z12] -> [[Z12]]

-- | Can the set-class q (under prime form algorithm pf) be drawn from the
--   pcset p.
has_sc_pf :: (Integral a) => ([a] -> [a]) -> [a] -> [a] -> Bool

-- | Can the set-class q be drawn from the pcset p.
has_sc :: [Z12] -> [Z12] -> Bool

-- | Interval cycle filter.
--   
--   <pre>
--   &gt;&gt;&gt; echo 22341 | icf
--   22341
--   </pre>
--   
--   <pre>
--   icf [[2,2,3,4,1]] == [[2,2,3,4,1]]
--   </pre>
icf :: (Num a, Eq a) => [[a]] -> [[a]]

-- | Interval class set to interval sets.
--   
--   <pre>
--   &gt;&gt;&gt; ici -c 123
--   123
--   129
--   1A3
--   1A9
--   </pre>
--   
--   <pre>
--   ici_c [1,2,3] == [[1,2,3],[1,2,9],[1,10,3],[1,10,9]]
--   </pre>
ici :: (Num t) => [Int] -> [[t]]

-- | Interval class set to interval sets, concise variant.
--   
--   <pre>
--   ici_c [1,2,3] == [[1,2,3],[1,2,9],[1,10,3],[1,10,9]]
--   </pre>
ici_c :: [Int] -> [[Int]]

-- | Interval-class segment.
--   
--   <pre>
--   &gt;&gt;&gt; icseg 013265e497t8
--   12141655232
--   </pre>
--   
--   <pre>
--   icseg [0,1,3,2,6,5,11,4,9,7,10,8] == [1,2,1,4,1,6,5,5,2,3,2]
--   </pre>
icseg :: [Z12] -> [Z12]

-- | Interval segment (INT).
iseg :: [Z12] -> [Z12]

-- | Imbrications.
imb :: (Integral n) => [n] -> [a] -> [[a]]

-- | <a>issb</a> gives the set-classes that can append to <tt>p</tt> to
--   give <tt>q</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; issb 3-7 6-32
--   3-7
--   3-2
--   3-11
--   </pre>
--   
--   <pre>
--   issb (T.sc "3-7") (T.sc "6-32") == ["3-2","3-7","3-11"]
--   </pre>
issb :: [Z12] -> [Z12] -> [String]

-- | Matrix search.
--   
--   <pre>
--   &gt;&gt;&gt; mxs 024579 642 | sort -u
--   6421B9
--   B97642
--   </pre>
--   
--   <pre>
--   T.set (mxs [0,2,4,5,7,9] [6,4,2]) == [[6,4,2,1,11,9],[11,9,7,6,4,2]]
--   </pre>
mxs :: [Z12] -> [Z12] -> [[Z12]]

-- | Normalize.
--   
--   <pre>
--   &gt;&gt;&gt; nrm 0123456543210
--   0123456
--   </pre>
--   
--   <pre>
--   nrm [0,1,2,3,4,5,6,5,4,3,2,1,0] == [0,1,2,3,4,5,6]
--   </pre>
nrm :: (Ord a) => [a] -> [a]

-- | Normalize, retain duplicate elements.
nrm_r :: (Ord a) => [a] -> [a]

-- | Pitch-class invariances (called <tt>pi</tt> at <tt>pct</tt>).
--   
--   <pre>
--   &gt;&gt;&gt; pi 0236 12
--   0236
--   6320
--   532B
--   B235
--   </pre>
--   
--   <pre>
--   pci [0,2,3,6] [1,2] == [[0,2,3,6],[5,3,2,11],[6,3,2,0],[11,2,3,5]]
--   </pre>
pci :: [Z12] -> [Z12] -> [[Z12]]

-- | Relate sets.
--   
--   <pre>
--   &gt;&gt;&gt; rs 0123 641e
--   T1M
--   </pre>
--   
--   <pre>
--   import Music.Theory.Z12.Morris_1987.Parse
--   rs [0,1,2,3] [6,4,1,11] == [(rnrtnmi "T1M",[1,6,11,4])
--                              ,(rnrtnmi "T4MI",[4,11,6,1])]
--   </pre>
rs :: [Z12] -> [Z12] -> [(SRO, [Z12])]

-- | Relate segments.
--   
--   <pre>
--   &gt;&gt;&gt; rsg 156 3BA
--   T4I
--   </pre>
--   
--   <pre>
--   rsg [1,5,6] [3,11,10] == [rnrtnmi "T4I",rnrtnmi "r1RT4MI"]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; rsg 0123 05t3
--   T0M
--   </pre>
--   
--   <pre>
--   rsg [0,1,2,3] [0,5,10,3] == [rnrtnmi "T0M",rnrtnmi "RT3MI"]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; rsg 0123 4e61
--   RT1M
--   </pre>
--   
--   <pre>
--   rsg [0,1,2,3] [4,11,6,1] == [rnrtnmi "T4MI",rnrtnmi "RT1M"]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; echo e614 | rsg 0123
--   r3RT1M
--   </pre>
--   
--   <pre>
--   rsg [0,1,2,3] [11,6,1,4] == [rnrtnmi "r1T4MI",rnrtnmi "r1RT1M"]
--   </pre>
rsg :: [Z12] -> [Z12] -> [SRO]

-- | Subsets.
sb :: [[Z12]] -> [[Z12]]

-- | Super set-class.
--   
--   <pre>
--   &gt;&gt;&gt; spsc 4-11 4-12
--   5-26[02458]
--   </pre>
--   
--   <pre>
--   spsc [T.sc "4-11",T.sc "4-12"] == ["5-26"]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; spsc 3-11 3-8
--   4-27[0258]
--   4-Z29[0137]
--   </pre>
--   
--   <pre>
--   spsc [T.sc "3-11",T.sc "3-8"] == ["4-27","4-Z29"]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; spsc `fl 3`
--   6-Z17[012478]
--   </pre>
--   
--   <pre>
--   spsc (cf [3] T.scs) == ["6-Z17"]
--   </pre>
spsc :: [[Z12]] -> [String]


-- | Parsers for pitch class sets and sequences, and for <a>SRO</a>s.
module Music.Theory.Z12.Morris_1987.Parse

-- | Parse a Morris format serial operator descriptor.
--   
--   <pre>
--   rnrtnmi "r2RT3MI" == SRO 2 True 3 True True
--   </pre>
rnrtnmi :: String -> SRO

-- | Parse a <i>pitch class object</i> string. Each <a>Char</a> is either a
--   number, a space which is ignored, or a letter name for the numbers 10
--   (<tt>t</tt> or <tt>a</tt> or <tt>A</tt>) or 11 (<tt>e</tt> or
--   <tt>B</tt> or <tt>b</tt>).
--   
--   <pre>
--   pco "13te" == [1,3,10,11]
--   pco "13te" == pco "13ab"
--   </pre>
pco :: String -> [Z12]


-- | Common music notation intervals.
module Music.Theory.Interval

-- | Interval type or degree.
data Interval_T
Unison :: Interval_T
Second :: Interval_T
Third :: Interval_T
Fourth :: Interval_T
Fifth :: Interval_T
Sixth :: Interval_T
Seventh :: Interval_T

-- | Interval quality.
data Interval_Q
Diminished :: Interval_Q
Minor :: Interval_Q
Perfect :: Interval_Q
Major :: Interval_Q
Augmented :: Interval_Q

-- | Common music notation interval. An <a>Ordering</a> of <a>LT</a>
--   indicates an ascending interval, <a>GT</a> a descending interval, and
--   <a>EQ</a> a unison.
data Interval
Interval :: Interval_T -> Interval_Q -> Ordering -> Octave -> Interval
[interval_type] :: Interval -> Interval_T
[interval_quality] :: Interval -> Interval_Q
[interval_direction] :: Interval -> Ordering
[interval_octave] :: Interval -> Octave

-- | Interval type between <a>Note_T</a> values.
--   
--   <pre>
--   map (interval_ty C) [E,B] == [Third,Seventh]
--   </pre>
interval_ty :: Note_T -> Note_T -> Interval_T

-- | Table of interval qualities. For each <a>Interval_T</a> gives directed
--   semitone interval counts for each allowable <a>Interval_Q</a>. For
--   lookup function see <a>interval_q</a>, for reverse lookup see
--   <a>interval_q_reverse</a>.
interval_q_tbl :: Integral n => [(Interval_T, [(n, Interval_Q)])]

-- | Lookup <a>Interval_Q</a> for given <a>Interval_T</a> and semitone
--   count.
--   
--   <pre>
--   interval_q Unison 11 == Just Diminished
--   interval_q Third 5 == Just Augmented
--   interval_q Fourth 5 == Just Perfect
--   interval_q Unison 3 == Nothing
--   </pre>
interval_q :: Interval_T -> Int -> Maybe Interval_Q

-- | Lookup semitone difference of <a>Interval_T</a> with
--   <a>Interval_Q</a>.
--   
--   <pre>
--   interval_q_reverse Third Minor == Just 3
--   interval_q_reverse Unison Diminished == Just 11
--   </pre>
interval_q_reverse :: Interval_T -> Interval_Q -> Maybe Int

-- | Semitone difference of <a>Interval</a>.
--   
--   <pre>
--   interval_semitones (interval (Pitch C Sharp 4) (Pitch E Sharp 5)) == 16
--   interval_semitones (interval (Pitch C Natural 4) (Pitch D Sharp 3)) == -9
--   </pre>
interval_semitones :: Interval -> Int

-- | Inclusive set of <a>Note_T</a> within indicated interval. This is not
--   equal to <a>enumFromTo</a> which is not circular.
--   
--   <pre>
--   note_span E B == [E,F,G,A,B]
--   note_span B D == [B,C,D]
--   enumFromTo B D == []
--   </pre>
note_span :: Note_T -> Note_T -> [Note_T]

-- | Invert <a>Ordering</a>, ie. <a>GT</a> becomes <a>LT</a> and vice
--   versa.
--   
--   <pre>
--   map invert_ordering [LT,EQ,GT] == [GT,EQ,LT]
--   </pre>
invert_ordering :: Ordering -> Ordering

-- | Determine <a>Interval</a> between two <a>Pitch</a>es.
--   
--   <pre>
--   interval (Pitch C Sharp 4) (Pitch D Flat 4) == Interval Second Diminished EQ 0
--   interval (Pitch C Sharp 4) (Pitch E Sharp 5) == Interval Third Major LT 1
--   </pre>
interval :: Pitch -> Pitch -> Interval

-- | Apply <a>invert_ordering</a> to <a>interval_direction</a> of
--   <a>Interval</a>.
--   
--   <pre>
--   invert_interval (Interval Third Major LT 1) == Interval Third Major GT 1
--   </pre>
invert_interval :: Interval -> Interval

-- | The signed difference in semitones between two <a>Interval_Q</a>
--   values when applied to the same <a>Interval_T</a>. Can this be written
--   correctly without knowing the Interval_T?
--   
--   <pre>
--   quality_difference_m Minor Augmented == Just 2
--   quality_difference_m Augmented Diminished == Just (-3)
--   quality_difference_m Major Perfect == Nothing
--   </pre>
quality_difference_m :: Interval_Q -> Interval_Q -> Maybe Int

-- | Erroring variant of <a>quality_difference_m</a>.
quality_difference :: Interval_Q -> Interval_Q -> Int

-- | Transpose a <a>Pitch</a> by an <a>Interval</a>.
--   
--   <pre>
--   transpose (Interval Third Diminished LT 0) (Pitch C Sharp 4) == Pitch E Flat 4
--   </pre>
pitch_transpose :: Interval -> Pitch -> Pitch

-- | Make leftwards (perfect fourth) and and rightwards (perfect fifth)
--   circles from <a>Pitch</a>.
--   
--   <pre>
--   let c = circle_of_fifths (Pitch F Sharp 4)
--   in map pitch_to_pc (snd c) == [6,1,8,3,10,5,12,7,2,9,4,11]
--   </pre>
circle_of_fifths :: Pitch -> ([Pitch], [Pitch])

-- | Parse a positive integer into interval type and octave displacement.
--   
--   <pre>
--   mapMaybe parse_interval_type (map show [1 .. 15])
--   </pre>
parse_interval_type :: String -> Maybe (Interval_T, Octave)

-- | Parse interval quality notation.
--   
--   <pre>
--   mapMaybe parse_interval_quality "dmPMA" == [minBound .. maxBound]
--   </pre>
parse_interval_quality :: Char -> Maybe Interval_Q

-- | Degree of interval type and octave displacement. Inverse of
--   <a>parse_interval_type</a>.
--   
--   <pre>
--   map interval_type_degree [(Third,0),(Second,1),(Unison,2)] == [3,9,15]
--   </pre>
interval_type_degree :: (Interval_T, Octave) -> Int

-- | Inverse of 'parse_interval_quality.
interval_quality_pp :: Interval_Q -> Char

-- | Parse standard common music interval notation.
--   
--   <pre>
--   let i = mapMaybe parse_interval (words "P1 d2 m2 M2 A3 P8 +M9 -M2")
--   in unwords (map interval_pp i) == "P1 d2 m2 M2 A3 P8 M9 -M2"
--   </pre>
--   
--   <pre>
--   mapMaybe (fmap interval_octave . parse_interval) (words "d1 d8 d15") == [-1,0,1]
--   </pre>
parse_interval :: String -> Maybe Interval

-- | Pretty printer for intervals, inverse of <a>parse_interval</a>.
interval_pp :: Interval -> String

-- | Standard names for the intervals within the octave, divided into
--   perfect, major and minor at the left, and diminished and augmented at
--   the right.
--   
--   <pre>
--   let {bimap f (p,q) = (f p,f q)
--       ;f = mapMaybe (fmap interval_semitones . parse_interval)}
--   in bimap f std_interval_names
--   </pre>
std_interval_names :: ([String], [String])
instance GHC.Show.Show Music.Theory.Interval.Interval
instance GHC.Classes.Eq Music.Theory.Interval.Interval
instance GHC.Show.Show Music.Theory.Interval.Interval_Q
instance GHC.Classes.Ord Music.Theory.Interval.Interval_Q
instance GHC.Enum.Bounded Music.Theory.Interval.Interval_Q
instance GHC.Enum.Enum Music.Theory.Interval.Interval_Q
instance GHC.Classes.Eq Music.Theory.Interval.Interval_Q
instance GHC.Show.Show Music.Theory.Interval.Interval_T
instance GHC.Classes.Ord Music.Theory.Interval.Interval_T
instance GHC.Enum.Bounded Music.Theory.Interval.Interval_T
instance GHC.Enum.Enum Music.Theory.Interval.Interval_T
instance GHC.Classes.Eq Music.Theory.Interval.Interval_T


-- | Constants names for ascending <a>Interval</a> values.
module Music.Theory.Interval.Name
perfect_fourth :: Interval
perfect_fifth :: Interval
major_seventh :: Interval


-- | Spelling rules for <a>Interval</a> values.
module Music.Theory.Interval.Spelling

-- | Simplest spelling for semitone intervals. This is ambiguous for
--   <tt>6</tt> which could be either <i>aug.4</i> or <i>dim.5</i>.
--   
--   <pre>
--   i_to_interval 6 == Interval Fourth Augmented LT 0
--   map i_to_interval [0..11]
--   </pre>
i_to_interval :: Int -> Interval

-- | Perform some interval simplifications. For non-tonal music some
--   spellings are poor, ie. (f,g#).
--   
--   <pre>
--   interval_simplify (Interval Second Augmented LT 0) == Interval Third Minor LT 0
--   interval_simplify (Interval Seventh Augmented GT 0) == Interval Unison Perfect GT 1
--   </pre>
interval_simplify :: Interval -> Interval


-- | Common music keys.
module Music.Theory.Key

-- | Enumeration of common music notation modes.
data Mode_T
Minor_Mode :: Mode_T
Major_Mode :: Mode_T

-- | A common music notation key is a <a>Note_T</a>, <a>Alteration_T</a>,
--   <a>Mode_T</a> triple.
type Key = (Note_T, Alteration_T, Mode_T)

-- | Distance along circle of fifths path of indicated <a>Key</a>. A
--   positive number indicates the number of sharps, a negative number the
--   number of flats.
--   
--   <pre>
--   key_fifths (A,Natural,Minor_Mode) == 0
--   key_fifths (A,Natural,Major_Mode) == 3
--   key_fifths (C,Natural,Minor_Mode) == -3
--   </pre>
key_fifths :: Key -> Int
instance GHC.Show.Show Music.Theory.Key.Mode_T
instance GHC.Classes.Ord Music.Theory.Key.Mode_T
instance GHC.Classes.Eq Music.Theory.Key.Mode_T


-- | <a>Data.Function</a> related functions.
module Music.Theory.Function

-- | <a>&amp;&amp;</a> of predicates.
predicate_and :: (t -> Bool) -> (t -> Bool) -> t -> Bool

-- | <a>all</a> of predicates.
--   
--   <pre>
--   let r = [False,False,True,False,True,False]
--   in map (predicate_all [(&gt; 0),(&lt; 5),even]) [0..5] == r
--   </pre>
predicate_all :: [t -> Bool] -> t -> Bool

-- | <a>||</a> of predicates.
predicate_or :: (t -> Bool) -> (t -> Bool) -> t -> Bool

-- | <a>any</a> of predicates.
--   
--   <pre>
--   let r = [True,False,True,False,True,True]
--   in map (predicate_any [(== 0),(== 5),even]) [0..5] == r
--   </pre>
predicate_any :: [t -> Bool] -> t -> Bool

-- | <a>fmap</a> <a>.</a> <a>fmap</a>, ie. <tt>(t -&gt; c) -&gt; (a -&gt; b
--   -&gt; t) -&gt; a -&gt; b -&gt; c</tt>.
(.:) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
infixr 8 .:

-- | <a>fmap</a> <a>.</a> <a>.:</a>, ie. <tt>(t -&gt; d) -&gt; (a -&gt; b
--   -&gt; c -&gt; t) -&gt; a -&gt; b -&gt; c -&gt; d</tt>.
(.::) :: (Functor f, Functor g, Functor h) => (a -> b) -> f (g (h a)) -> f (g (h b))
infixr 8 .::

-- | <a>fmap</a> <a>.</a> <a>.::</a>.
(.:::) :: (Functor f, Functor g, Functor h, Functor i) => (a -> b) -> f (g (h (i a))) -> f (g (h (i b)))
infixr 8 .:::

-- | <a>fmap</a> <a>.</a> <a>.:::</a>.
(.::::) :: (Functor f, Functor g, Functor h, Functor i, Functor j) => (a -> b) -> f (g (h (i (j a)))) -> f (g (h (i (j b))))
infixr 8 .::::

-- | <a>fmap</a> <a>.</a> <a>.::::</a>.
(.:::::) :: (Functor f, Functor g, Functor h, Functor i, Functor j, Functor k) => (a -> b) -> f (g (h (i (j (k a))))) -> f (g (h (i (j (k b)))))
infixr 8 .:::::


-- | Basic temporal sequence functions.
module Music.Theory.Time.Seq

-- | Sequence of elements with uniform duration.
type Useq t a = (t, [a])

-- | Duration sequence. The duration is the <i>forward</i> duration of the
--   value, if it has other durations they must be encoded at <i>a</i>.
type Dseq t a = [(t, a)]

-- | Inter-offset sequence. The duration is the interval <i>before</i> the
--   value. To indicate the duration of the final value <i>a</i> must have
--   an <i>nil</i> (end of sequence) value.
type Iseq t a = [(t, a)]

-- | Pattern sequence. The duration is a triple of <i>logical</i>,
--   <i>sounding</i> and <i>forward</i> durations.
type Pseq t a = [((t, t, t), a)]

-- | Time-point sequence. To express holes <i>a</i> must have a
--   <i>empty</i> value. To indicate the duration of the final value
--   <i>a</i> must have an <i>nil</i> (end of sequence) value.
type Tseq t a = [(t, a)]

-- | Window sequence. The temporal field is (<i>time</i>,<i>duration</i>).
--   Holes exist where <tt>t(n) + d(n)</tt> <a>&lt;</a> <tt>t(n+1)</tt>.
--   Overlaps exist where the same relation is <a>&gt;</a>.
type Wseq t a = [((t, t), a)]
pseq_zip :: [t] -> [t] -> [t] -> [a] -> Pseq t a
wseq_zip :: [t] -> [t] -> [a] -> Wseq t a

-- | Given functions for deriving start and end times calculate time span
--   of sequence.
--   
--   <pre>
--   seq_tspan id id [] == (0,0)
--   seq_tspan id id (zip [0..9] ['a'..]) == (0,9)
--   </pre>
seq_tspan :: Num n => (t -> n) -> (t -> n) -> [(t, a)] -> (n, n)
tseq_tspan :: Num t => Tseq t a -> (t, t)
wseq_tspan :: Num t => Wseq t a -> (t, t)
dseq_dur :: Num t => Dseq t a -> t
iseq_dur :: Num t => Iseq t a -> t
pseq_dur :: Num t => Pseq t a -> t

-- | The interval of <a>tseq_tspan</a>.
--   
--   <pre>
--   tseq_dur (zip [0..] "abcde|") == 5
--   </pre>
tseq_dur :: Num t => Tseq t a -> t

-- | The interval of <a>wseq_tspan</a>.
--   
--   <pre>
--   wseq_dur (zip (zip [0..] (repeat 2)) "abcde") == 6
--   </pre>
wseq_dur :: Num t => Wseq t a -> t

-- | Keep only elements in the indicated temporal window.
--   
--   <pre>
--   let r = [((5,1),'e'),((6,1),'f'),((7,1),'g'),((8,1),'h')]
--   in wseq_twindow (5,9) (zip (zip [1..10] (repeat 1)) ['a'..]) == r
--   </pre>
wseq_twindow :: (Num t, Ord t) => (t, t) -> Wseq t a -> Wseq t a
dseq_append :: Dseq t a -> Dseq t a -> Dseq t a
iseq_append :: Iseq t a -> Iseq t a -> Iseq t a
pseq_append :: Pseq t a -> Pseq t a -> Pseq t a

-- | Merge comparing only on time.
tseq_merge :: Ord t => Tseq t a -> Tseq t a -> Tseq t a

-- | Merge, where times are equal compare values.
tseq_merge_by :: Ord t => Compare_F a -> Tseq t a -> Tseq t a -> Tseq t a

-- | Merge, where times are equal apply <i>f</i> to form a single value.
--   
--   <pre>
--   let {p = zip [1,3,5] "abc"
--       ;q = zip [1,2,3] "ABC"
--       ;left_r = [(1,'a'),(2,'B'),(3,'b'),(5,'c')]
--       ;right_r = [(1,'A'),(2,'B'),(3,'C'),(5,'c')]}
--   in tseq_merge_resolve (\x _ -&gt; x) p q == left_r &amp;&amp;
--      tseq_merge_resolve (\_ x -&gt; x) p q == right_r
--   </pre>
tseq_merge_resolve :: Ord t => (a -> a -> a) -> Tseq t a -> Tseq t a -> Tseq t a
wseq_merge :: Ord t => Wseq t a -> Wseq t a -> Wseq t a
tseq_lookup_window_by :: (t -> t -> Ordering) -> Tseq t e -> t -> (Maybe (t, e), Maybe (t, e))
tseq_lookup_active_by :: (t -> t -> Ordering) -> Tseq t e -> t -> Maybe e
tseq_lookup_active :: Ord t => Tseq t e -> t -> Maybe e
tseq_lookup_active_by_def :: e -> (t -> t -> Ordering) -> Tseq t e -> t -> e
tseq_lookup_active_def :: Ord t => e -> Tseq t e -> t -> e
data Interpolation_T
None :: Interpolation_T
Linear :: Interpolation_T

-- | Variant of <a>Tseq</a> where nodes have an <tt>Intepolation_T</tt>
--   value.
type Lseq t a = Tseq (t, Interpolation_T) a

-- | Linear interpolation.
lerp :: (Fractional t, Real t, Fractional e) => (t, e) -> (t, e) -> t -> e

-- | Temporal map.
lseq_tmap :: (t -> t') -> Lseq t a -> Lseq t' a

-- | This can give <a>Nothing</a> if <i>t</i> precedes the <a>Lseq</a> or
--   if <i>t</i> is after the final element of <a>Lseq</a> and that element
--   has an interpolation type other than <a>None</a>.
lseq_lookup :: (Fractional t, Real t, Fractional e) => (t -> t -> Ordering) -> Lseq t e -> t -> Maybe e

-- | <a>error</a>ing variant.
lseq_lookup_err :: (Fractional t, Real t, Fractional e) => (t -> t -> Ordering) -> Lseq t e -> t -> e
seq_tmap :: (t -> t') -> [(t, a)] -> [(t', a)]
seq_map :: (b -> c) -> [(a, b)] -> [(a, c)]

-- | Map <i>t</i> and <i>e</i> simultaneously.
seq_bimap :: (t -> t') -> (e -> e') -> [(t, e)] -> [(t', e')]
seq_tfilter :: (t -> Bool) -> [(t, a)] -> [(t, a)]
seq_filter :: (b -> Bool) -> [(a, b)] -> [(a, b)]
seq_find :: (a -> Bool) -> [(t, a)] -> Maybe (t, a)

-- | <a>mapMaybe</a> variant.
seq_map_maybe :: (p -> Maybe q) -> [(t, p)] -> [(t, q)]

-- | Variant of <a>catMaybes</a>.
seq_cat_maybes :: [(t, Maybe q)] -> [(t, q)]

-- | If value is unchanged, according to <i>f</i>, replace with
--   <a>Nothing</a>.
--   
--   <pre>
--   let r = [(1,'s'),(2,'t'),(4,'r'),(6,'i'),(7,'n'),(9,'g')]
--   in seq_cat_maybes (seq_changed_by (==) (zip [1..] "sttrrinng")) == r
--   </pre>
seq_changed_by :: (a -> a -> Bool) -> [(t, a)] -> [(t, Maybe a)]

-- | <a>seq_changed_by</a> <a>==</a>.
seq_changed :: Eq a => [(t, a)] -> [(t, Maybe a)]

-- | Apply <i>f</i> at time points of <a>Wseq</a>.
wseq_tmap_st :: (t -> t) -> Wseq t a -> Wseq t a

-- | Apply <i>f</i> at durations of elements of <a>Wseq</a>.
wseq_tmap_dur :: (t -> t) -> Wseq t a -> Wseq t a

-- | Given a function that determines a <i>voice</i> for a value, partition
--   a sequence into voices.
seq_partition :: Ord v => (a -> v) -> [(t, a)] -> [(v, [(t, a)])]

-- | Type specialised <a>seq_partition</a>.
--   
--   <pre>
--   let {p = zip [0,1,3,5] (zip (repeat 0) "abcd")
--       ;q = zip [2,4,6,7] (zip (repeat 1) "ABCD")
--       ;sq = tseq_merge p q}
--   in tseq_partition fst sq == [(0,p),(1,q)]
--   </pre>
tseq_partition :: Ord v => (a -> v) -> Tseq t a -> [(v, Tseq t a)]
wseq_partition :: Ord v => (a -> v) -> Wseq t a -> [(v, Wseq t a)]

-- | Given a decision predicate and a join function, recursively join
--   adjacent elements.
--   
--   <pre>
--   coalesce_f undefined undefined [] == []
--   coalesce_f (==) const "abbcccbba" == "abcba"
--   coalesce_f (==) (+) [1,2,2,3,3,3] == [1,4,6,3]
--   </pre>
coalesce_f :: (t -> t -> Bool) -> (t -> t -> t) -> [t] -> [t]

-- | <a>coalesce_f</a> using <a>mappend</a> for the join function.
coalesce_m :: Monoid t => (t -> t -> Bool) -> [t] -> [t]

-- | Form of <a>coalesce_f</a> where the decision predicate is on the
--   <i>element</i>, and a join function sums the <i>times</i>.
--   
--   <pre>
--   let r = [(1,'a'),(2,'b'),(3,'c'),(2,'d'),(1,'e')]
--   in seq_coalesce (==) const (useq_to_dseq (1,"abbcccdde")) == r
--   </pre>
seq_coalesce :: Num t => (a -> a -> Bool) -> (a -> a -> a) -> [(t, a)] -> [(t, a)]
dseq_coalesce :: Num t => (a -> a -> Bool) -> (a -> a -> a) -> Dseq t a -> Dseq t a

-- | Given <i>equality</i> predicate, simplify sequence by summing
--   durations of adjacent <i>equal</i> elements. This is a special case of
--   <a>dseq_coalesce</a> where the <i>join</i> function is <a>const</a>.
--   The implementation is simpler and non-recursive.
--   
--   <pre>
--   let {d = useq_to_dseq (1,"abbcccdde")
--       ;r = dseq_coalesce (==) const d}
--   in dseq_coalesce' (==) d == r
--   </pre>
dseq_coalesce' :: Num t => (a -> a -> Bool) -> Dseq t a -> Dseq t a
iseq_coalesce :: Num t => (a -> a -> Bool) -> (a -> a -> a) -> Iseq t a -> Iseq t a
seq_tcoalesce :: (t -> t -> Bool) -> (a -> a -> a) -> [(t, a)] -> [(t, a)]
tseq_tcoalesce :: Eq t => (a -> a -> a) -> Tseq t a -> Tseq t a
wseq_tcoalesce :: ((t, t) -> (t, t) -> Bool) -> (a -> a -> a) -> Wseq t a -> Wseq t a

-- | Post-process <a>groupBy</a> of <i>cmp</i> <a>on</a> <a>fst</a>.
--   
--   <pre>
--   let r = [(0,"a"),(1,"bc"),(2,"de"),(3,"f")]
--   in group_f (==) (zip [0,1,1,2,2,3] ['a'..]) == r
--   </pre>
group_f :: (Eq t, Num t) => (t -> t -> Bool) -> [(t, a)] -> [(t, [a])]

-- | Group values at equal time points.
--   
--   <pre>
--   let r = [(0,"a"),(1,"bc"),(2,"de"),(3,"f")]
--   in tseq_group (zip [0,1,1,2,2,3] ['a'..]) == r
--   </pre>
tseq_group :: (Eq t, Num t) => Tseq t a -> Tseq t [a]

-- | Group values where the inter-offset time is <tt>0</tt> to the left.
--   
--   <pre>
--   let r = [(0,"a"),(1,"bcd"),(1,"ef")]
--   in iseq_group (zip [0,1,0,0,1,0] ['a'..]) == r
--   </pre>
iseq_group :: (Eq t, Num t) => Iseq t a -> Iseq t [a]

-- | Set durations so that there are no gaps or overlaps.
--   
--   <pre>
--   let r = wseq_zip [0,3,5] [3,2,1] "abc"
--   in wseq_fill_dur (wseq_zip [0,3,5] [2,1,1] "abc") == r
--   </pre>
wseq_fill_dur :: Num t => Wseq t a -> Wseq t a
dseq_lcm :: Dseq Rational e -> Integer

-- | Scale by lcm so that all durations are integral.
dseq_set_whole :: [Dseq Rational e] -> [Dseq Integer e]

-- | Given a a default value, a <a>Tseq</a> <i>sq</i> and a list of
--   time-points <i>t</i>, generate a Tseq that is a union of the
--   timepoints at <i>sq</i> and <i>t</i> where times in <i>t</i> not at
--   <i>sq</i> are given the <i>current</i> value, or <i>def</i> if there
--   is no value.
--   
--   <pre>
--   tseq_latch 'a' [(2,'b'),(4,'c')] [1..5] == zip [1..5] "abbcc"
--   </pre>
tseq_latch :: Ord t => a -> Tseq t a -> [t] -> Tseq t a

-- | Transform <a>Wseq</a> to <a>Tseq</a> by discaring durations.
wseq_discard_dur :: Wseq t a -> Tseq t a

-- | Edit durations to ensure that notes don't overlap. If the same note is
--   played simultaneously delete shorter note. If a note extends into a
--   later note shorten duration (apply <i>d_fn</i> to iot).
wseq_remove_overlaps :: (Eq e, Ord t, Num t) => (e -> e -> Bool) -> (t -> t) -> Wseq t e -> Wseq t e

-- | Unjoin elements (assign equal time stamps to all elements).
seq_unjoin :: [(t, [e])] -> [(t, e)]

-- | Type specialised.
wseq_unjoin :: Wseq t [e] -> Wseq t e

-- | Container for values that have <i>on</i> and <i>off</i> modes.
data On_Off a
On :: a -> On_Off a
Off :: a -> On_Off a

-- | Structural comparison at <a>On_Off</a>, <a>On</a> compares less than
--   <a>Off</a>.
cmp_on_off :: On_Off a -> On_Off b -> Ordering

-- | Translate container types.
either_to_on_off :: Either a a -> On_Off a

-- | Translate container types.
on_off_to_either :: On_Off a -> Either a a

-- | Convert <a>Wseq</a> to <a>Tseq</a> transforming elements to <a>On</a>
--   and <a>Off</a> parts. When merging, <i>off</i> elements precede
--   <i>on</i> elements at equal times.
--   
--   <pre>
--   let {sq = [((0,5),'a'),((2,2),'b')]
--       ;r = [(0,On 'a'),(2,On 'b'),(4,Off 'b'),(5,Off 'a')]}
--   in wseq_on_off sq == r
--   </pre>
--   
--   <pre>
--   let {sq = [((0,1),'a'),((1,1),'b'),((2,1),'c')]
--       ;r = [(0,On 'a'),(1,Off 'a')
--            ,(1,On 'b'),(2,Off 'b')
--            ,(2,On 'c'),(3,Off 'c')]}
--   in wseq_on_off sq == r
--   </pre>
wseq_on_off :: (Num t, Ord t) => Wseq t a -> Tseq t (On_Off a)

-- | <a>on_off_to_either</a> of <a>wseq_on_off</a>.
wseq_on_off_either :: (Num t, Ord t) => Wseq t a -> Tseq t (Either a a)

-- | Variant that applies <i>on</i> and <i>off</i> functions to nodes.
--   
--   <pre>
--   let {sq = [((0,5),'a'),((2,2),'b')]
--       ;r = [(0,'A'),(2,'B'),(4,'b'),(5,'a')]}
--   in wseq_on_off_f Data.Char.toUpper id sq == r
--   </pre>
wseq_on_off_f :: (Ord t, Num t) => (a -> b) -> (a -> b) -> Wseq t a -> Tseq t b

-- | Inverse of <a>wseq_on_off</a> given a predicate function for locating
--   the <i>off</i> node of an <i>on</i> node.
--   
--   <pre>
--   let {sq = [(0,On 'a'),(2,On 'b'),(4,Off 'b'),(5,Off 'a')]
--       ;r = [((0,5),'a'),((2,2),'b')]}
--   in tseq_on_off_to_wseq (==) sq == r
--   </pre>
tseq_on_off_to_wseq :: Num t => (a -> a -> Bool) -> Tseq t (On_Off a) -> Wseq t a
useq_to_dseq :: Useq t a -> Dseq t a

-- | The conversion requires a start time and a <i>nil</i> value used as an
--   <i>eof</i> marker. Productive given indefinite input sequence.
--   
--   <pre>
--   let r = zip [0,1,3,6,8,9] "abcde|"
--   in dseq_to_tseq 0 '|' (zip [1,2,3,2,1] "abcde") == r
--   </pre>
--   
--   <pre>
--   let {d = zip [1,2,3,2,1] "abcde"
--       ;r = zip [0,1,3,6,8,9,10] "abcdeab"}
--   in take 7 (dseq_to_tseq 0 undefined (cycle d)) == r
--   </pre>
dseq_to_tseq :: Num t => t -> a -> Dseq t a -> Tseq t a

-- | Variant where the <i>nil</i> is take as the last element of the
--   sequence.
--   
--   <pre>
--   let r = zip [0,1,3,6,8,9] "abcdee"
--   in dseq_to_tseq_last 0 (zip [1,2,3,2,1] "abcde") == r
--   </pre>
dseq_to_tseq_last :: Num t => t -> Dseq t a -> Tseq t a

-- | The conversion requires a start time and does not consult the
--   <i>logical</i> duration.
--   
--   <pre>
--   let p = pseq_zip (repeat undefined) (cycle [1,2]) (cycle [1,1,2]) "abcdef"
--   in pseq_to_wseq 0 p == wseq_zip [0,1,2,4,5,6] (cycle [1,2]) "abcdef"
--   </pre>
pseq_to_wseq :: Num t => t -> Pseq t a -> Wseq t a

-- | The last element of <a>Tseq</a> is required to be an <i>eof</i> marker
--   that has no duration and is not represented in the <a>Dseq</a>.
--   
--   <pre>
--   let r = zip [1,2,3,2,1] "abcde"
--   in tseq_to_dseq undefined (zip [0,1,3,6,8,9] "abcde|") == r
--   </pre>
--   
--   <pre>
--   let r = zip [1,2,3,2,1] "-abcd"
--   in tseq_to_dseq '-' (zip [1,3,6,8,9] "abcd|") == r
--   </pre>
tseq_to_dseq :: (Ord t, Num t) => a -> Tseq t a -> Dseq t a

-- | The last element of <a>Tseq</a> is required to be an <i>eof</i> marker
--   that has no duration and is not represented in the <a>Wseq</a>. The
--   duration of each value is either derived from the value, if an
--   <i>dur</i> function is given, or else the inter-offset time.
--   
--   <pre>
--   let r = wseq_zip [0,1,3,6,8] [1,2,3,2,1] "abcde"
--   in tseq_to_wseq Nothing (zip [0,1,3,6,8,9] "abcde|") == r
--   </pre>
--   
--   <pre>
--   let r = wseq_zip [0,1,3,6,8] (map fromEnum "abcde") "abcde"
--   in tseq_to_wseq (Just fromEnum) (zip [0,1,3,6,8,9] "abcde|") == r
--   </pre>
tseq_to_wseq :: Num t => Maybe (a -> t) -> Tseq t a -> Wseq t a
tseq_to_iseq :: Num t => Tseq t a -> Dseq t a

-- | Requires start time.
--   
--   <pre>
--   let r = zip (zip [0,1,3,6,8,9] [1,2,3,2,1]) "abcde"
--   in dseq_to_wseq 0 (zip [1,2,3,2,1] "abcde") == r
--   </pre>
dseq_to_wseq :: Num t => t -> Dseq t a -> Wseq t a

-- | Inverse of <a>dseq_to_wseq</a>. The <i>empty</i> value is used to fill
--   holes in <a>Wseq</a>. If values overlap at <a>Wseq</a> durations are
--   truncated.
--   
--   <pre>
--   let w = wseq_zip [0,1,3,6,8,9] [1,2,3,2,1] "abcde"
--   in wseq_to_dseq '-' w == zip [1,2,3,2,1] "abcde"
--   </pre>
--   
--   <pre>
--   let w = wseq_zip [3,10] [6,2] "ab"
--   in wseq_to_dseq '-' w == zip [3,6,1,2] "-a-b"
--   </pre>
--   
--   <pre>
--   let w = wseq_zip [0,1] [2,2] "ab"
--   in wseq_to_dseq '-' w == zip [1,2] "ab"
--   </pre>
--   
--   <pre>
--   let w = wseq_zip [0,0,0] [2,2,2] "abc"
--   in wseq_to_dseq '-' w == zip [0,0,2] "abc"
--   </pre>
wseq_to_dseq :: (Num t, Ord t) => a -> Wseq t a -> Dseq t a

-- | Given a list of <a>Dseq</a> (measures) convert to a list of
--   <a>Tseq</a> and the end time of the overall sequence.
--   
--   <pre>
--   let r = [[(0,'a'),(1,'b'),(3,'c')],[(4,'d'),(7,'e'),(9,'f')]]
--   in dseql_to_tseql 0 [zip [1,2,1] "abc",zip [3,2,1] "def"] == (10,r)
--   </pre>
dseql_to_tseql :: Num t => t -> [Dseq t a] -> (t, [Tseq t a])
dseq_tmap :: (t -> t') -> Dseq t a -> Dseq t' a
pseq_tmap :: ((t, t, t) -> (t', t', t')) -> Pseq t a -> Pseq t' a
tseq_tmap :: (t -> t') -> Dseq t a -> Dseq t' a
tseq_bimap :: (t -> t') -> (e -> e') -> Tseq t e -> Tseq t' e'
wseq_tmap :: ((t, t) -> (t', t')) -> Wseq t a -> Wseq t' a
dseq_map :: (a -> b) -> Dseq t a -> Dseq t b
pseq_map :: (a -> b) -> Pseq t a -> Pseq t b
tseq_map :: (a -> b) -> Tseq t a -> Tseq t b
wseq_map :: (a -> b) -> Wseq t a -> Wseq t b
dseq_tfilter :: (t -> Bool) -> Dseq t a -> Dseq t a
iseq_tfilter :: (t -> Bool) -> Iseq t a -> Iseq t a
pseq_tfilter :: ((t, t, t) -> Bool) -> Pseq t a -> Pseq t a
tseq_tfilter :: (t -> Bool) -> Tseq t a -> Tseq t a
wseq_tfilter :: ((t, t) -> Bool) -> Wseq t a -> Wseq t a
dseq_filter :: (a -> Bool) -> Dseq t a -> Dseq t a
iseq_filter :: (a -> Bool) -> Iseq t a -> Iseq t a
pseq_filter :: (a -> Bool) -> Pseq t a -> Pseq t a
tseq_filter :: (a -> Bool) -> Tseq t a -> Tseq t a
wseq_filter :: (a -> Bool) -> Wseq t a -> Wseq t a
wseq_map_maybe :: (a -> Maybe b) -> Wseq t a -> Wseq t b
wseq_cat_maybes :: Wseq t (Maybe a) -> Wseq t a
instance GHC.Show.Show a => GHC.Show.Show (Music.Theory.Time.Seq.On_Off a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Music.Theory.Time.Seq.On_Off a)
instance GHC.Show.Show Music.Theory.Time.Seq.Interpolation_T
instance GHC.Enum.Enum Music.Theory.Time.Seq.Interpolation_T
instance GHC.Classes.Eq Music.Theory.Time.Seq.Interpolation_T


-- | Either
module Music.Theory.Either

-- | Maybe <a>Left</a> of <a>Either</a>.
fromLeft :: Either a b -> Maybe a

-- | Maybe <a>Right</a> of <a>Either</a>.
fromRight :: Either a b -> Maybe b


-- | Tuning theory
module Music.Theory.Tuning

-- | An approximation of a ratio.
type Approximate_Ratio = Double

-- | A real valued division of a semi-tone into one hundred parts, and
--   hence of the octave into <tt>1200</tt> parts.
type Cents = Double

-- | A tuning specified <a>Either</a> as a sequence of exact ratios, or as
--   a sequence of possibly inexact <a>Cents</a>.
data Tuning
Tuning :: Either [Rational] [Cents] -> Rational -> Tuning
[ratios_or_cents] :: Tuning -> Either [Rational] [Cents]
[octave_ratio] :: Tuning -> Rational

-- | Divisions of octave.
--   
--   <pre>
--   divisions ditone == 12
--   </pre>
divisions :: Tuning -> Int

-- | <a>Maybe</a> exact ratios of <a>Tuning</a>.
ratios :: Tuning -> Maybe [Rational]

-- | <a>error</a>ing variant.
ratios_err :: Tuning -> [Rational]

-- | Possibly inexact <a>Cents</a> of tuning.
cents :: Tuning -> [Cents]

-- | <a>map</a> <a>round</a> <a>.</a> <a>cents</a>.
cents_i :: Integral i => Tuning -> [i]

-- | Variant of <a>cents</a> that includes octave at right.
cents_octave :: Tuning -> [Cents]

-- | Convert from interval in cents to frequency ratio.
--   
--   <pre>
--   map cents_to_ratio [0,701.9550008653874,1200] == [1,3/2,2]
--   </pre>
cents_to_ratio :: Floating a => a -> a

-- | Possibly inexact <a>Approximate_Ratio</a>s of tuning.
approximate_ratios :: Tuning -> [Approximate_Ratio]

-- | Cyclic form, taking into consideration <a>octave_ratio</a>.
approximate_ratios_cyclic :: Tuning -> [Approximate_Ratio]

-- | <a>Maybe</a> exact ratios reconstructed from possibly inexact
--   <a>Cents</a> of <a>Tuning</a>.
--   
--   <pre>
--   let r = [1,17/16,9/8,13/11,5/4,4/3,7/5,3/2,11/7,5/3,16/9,15/8]
--   in reconstructed_ratios 1e-2 werckmeister_iii == Just r
--   </pre>
reconstructed_ratios :: Double -> Tuning -> Maybe [Rational]

-- | Convert from a <a>Floating</a> ratio to <i>cents</i>.
--   
--   <pre>
--   let r = [0,498,702,1200]
--   in map (round . fratio_to_cents) [1,4/3,3/2,2] == r
--   </pre>
fratio_to_cents :: (Real r, Floating n) => r -> n

-- | Type specialised <a>fratio_to_cents</a>.
approximate_ratio_to_cents :: Approximate_Ratio -> Cents

-- | Type specialised <a>fromRational</a>.
approximate_ratio :: Rational -> Approximate_Ratio

-- | <a>approximate_ratio_to_cents</a> <a>.</a> <a>approximate_ratio</a>.
ratio_to_cents :: Rational -> Cents

-- | Construct an exact <a>Rational</a> that approximates <a>Cents</a> to
--   within <i>epsilon</i>.
--   
--   <pre>
--   map (reconstructed_ratio 1e-5) [0,700,1200] == [1,442/295,2]
--   </pre>
--   
--   <pre>
--   ratio_to_cents (442/295) == 699.9976981706734
--   </pre>
reconstructed_ratio :: Double -> Cents -> Rational

-- | Frequency <i>n</i> cents from <i>f</i>.
--   
--   <pre>
--   import Music.Theory.Pitch
--   map (cps_shift_cents 440) [-100,100] == map octpc_to_cps [(4,8),(4,10)]
--   </pre>
cps_shift_cents :: Floating a => a -> a -> a

-- | Interval in <i>cents</i> from <i>p</i> to <i>q</i>, ie.
--   <a>ratio_to_cents</a> of <i>p</i> <a>/</a> <i>q</i>.
--   
--   <pre>
--   cps_difference_cents 440 (octpc_to_cps (5,2)) == 500
--   </pre>
--   
--   <pre>
--   let abs_dif i j = abs (i - j)
--   in cps_difference_cents 440 (fmidi_to_cps 69.1) `abs_dif` 10 &lt; 1e9
--   </pre>
cps_difference_cents :: (Real r, Fractional r, Floating n) => r -> r -> n

-- | The Syntonic comma.
--   
--   <pre>
--   syntonic_comma == 81/80
--   </pre>
syntonic_comma :: Rational

-- | The Pythagorean comma.
--   
--   <pre>
--   pythagorean_comma == 3^12 / 2^19
--   </pre>
pythagorean_comma :: Rational

-- | Mercators comma.
--   
--   <pre>
--   mercators_comma == 3^53 / 2^84
--   </pre>
mercators_comma :: Rational

-- | Calculate <i>n</i>th root of <i>x</i>.
--   
--   <pre>
--   12 `nth_root` 2 == twelve_tone_equal_temperament_comma
--   </pre>
nth_root :: (Floating a, Eq a) => a -> a -> a

-- | 12-tone equal temperament comma (ie. 12th root of 2).
--   
--   <pre>
--   twelve_tone_equal_temperament_comma == 1.0594630943592953
--   </pre>
twelve_tone_equal_temperament_comma :: (Floating a, Eq a) => a

-- | Make <i>n</i> division equal temperament.
equal_temperament :: Integral n => n -> Tuning

-- | 12-tone equal temperament.
--   
--   <pre>
--   cents equal_temperament_12 == [0,100..1100]
--   </pre>
equal_temperament_12 :: Tuning

-- | 19-tone equal temperament.
equal_temperament_19 :: Tuning

-- | 31-tone equal temperament.
equal_temperament_31 :: Tuning

-- | 53-tone equal temperament.
equal_temperament_53 :: Tuning

-- | 72-tone equal temperament.
--   
--   <pre>
--   let r = [0,17,33,50,67,83,100]
--   in take 7 (map round (cents equal_temperament_72)) == r
--   </pre>
equal_temperament_72 :: Tuning

-- | Raise or lower the frequency <i>q</i> by octaves until it is in the
--   octave starting at <i>p</i>.
--   
--   <pre>
--   fold_cps_to_octave_of 55 392 == 98
--   </pre>
fold_cps_to_octave_of :: (Ord a, Fractional a) => a -> a -> a

-- | Harmonic series on <i>n</i>.
harmonic_series_cps :: (Num t, Enum t) => t -> [t]

-- | <i>n</i> elements of <a>harmonic_series_cps</a>.
--   
--   <pre>
--   let r = [55,110,165,220,275,330,385,440,495,550,605,660,715,770,825,880,935]
--   in harmonic_series_cps_n 17 55 == r
--   </pre>
harmonic_series_cps_n :: (Num a, Enum a) => Int -> a -> [a]

-- | Sub-harmonic series on <i>n</i>.
subharmonic_series_cps :: (Fractional t, Enum t) => t -> [t]

-- | <i>n</i> elements of <a>harmonic_series_cps</a>.
--   
--   <pre>
--   let r = [1760,880,587,440,352,293,251,220,196,176,160,147,135,126,117,110,104]
--   in map round (subharmonic_series_cps_n 17 1760) == r
--   </pre>
subharmonic_series_cps_n :: (Fractional t, Enum t) => Int -> t -> [t]

-- | <i>n</i>th partial of <i>f1</i>, ie. one indexed.
--   
--   <pre>
--   map (partial 55) [1,5,3] == [55,275,165]
--   </pre>
partial :: (Num a, Enum a) => a -> Int -> a

-- | Fold ratio until within an octave, ie. <tt>1</tt> <a>&lt;</a> <i>n</i>
--   <a>&lt;=</a> <tt>2</tt>.
--   
--   <pre>
--   map fold_ratio_to_octave [2/3,3/4] == [4/3,3/2]
--   </pre>
fold_ratio_to_octave :: Integral i => Ratio i -> Ratio i

-- | The interval between two pitches <i>p</i> and <i>q</i> given as ratio
--   multipliers of a fundamental is <i>q</i> <a>/</a> <i>p</i>. The
--   classes over such intervals consider the <a>fold_ratio_to_octave</a>
--   of both <i>p</i> to <i>q</i> and <i>q</i> to <i>p</i>.
--   
--   <pre>
--   map ratio_interval_class [2/3,3/2,3/4,4/3] == [3/2,3/2,3/2,3/2]
--   </pre>
ratio_interval_class :: Integral i => Ratio i -> Ratio i

-- | Derivative harmonic series, based on <i>k</i>th partial of <i>f1</i>.
--   
--   <pre>
--   import Music.Theory.Pitch
--   </pre>
--   
--   <pre>
--   let {r = [52,103,155,206,258,309,361,412,464,515,567,618,670,721,773]
--       ;d = harmonic_series_cps_derived 5 (octpc_to_cps (1,4))}
--   in map round (take 15 d) == r
--   </pre>
harmonic_series_cps_derived :: (Ord a, Fractional a, Enum a) => Int -> a -> [a]

-- | Harmonic series to <i>n</i>th harmonic (folded).
--   
--   <pre>
--   harmonic_series_folded 17 == [1,17/16,9/8,5/4,11/8,3/2,13/8,7/4,15/8]
--   </pre>
--   
--   <pre>
--   let r = [0,105,204,386,551,702,841,969,1088]
--   in map (round . ratio_to_cents) (harmonic_series_folded 17) == r
--   </pre>
harmonic_series_folded :: Integer -> [Rational]

-- | <a>ratio_to_cents</a> variant of <a>harmonic_series_folded</a>.
--   
--   <pre>
--   map round (harmonic_series_folded_c 21) == [0,105,204,298,386,471,551,702,841,969,1088]
--   </pre>
harmonic_series_folded_c :: Integer -> [Cents]

-- | <tt>12</tt>-tone tuning of first <tt>21</tt> elements of the harmonic
--   series.
--   
--   <pre>
--   cents_i harmonic_series_folded_21 == [0,105,204,298,386,471,551,702,841,969,1088]
--   divisions harmonic_series_folded_21 == 11
--   </pre>
harmonic_series_folded_21 :: Tuning

-- | Give cents difference from nearest 12ET tone.
--   
--   <pre>
--   let r = [50,-49,-2,0,2,49,50]
--   in map cents_et12_diff [650,651,698,700,702,749,750] == r
--   </pre>
cents_et12_diff :: Integral n => n -> n

-- | Fractional form of <a>cents_et12_diff</a>.
fcents_et12_diff :: Real n => n -> n

-- | The class of cents intervals has range <tt>(0,600)</tt>.
--   
--   <pre>
--   map cents_interval_class [50,1150,1250] == [50,50,50]
--   </pre>
--   
--   <pre>
--   let r = concat [[0,50 .. 550],[600],[550,500 .. 0]]
--   in map cents_interval_class [1200,1250 .. 2400] == r
--   </pre>
cents_interval_class :: Integral a => a -> a

-- | Fractional form of <a>cents_interval_class</a>.
fcents_interval_class :: Real a => a -> a

-- | Always include the sign, elide <tt>0</tt>.
cents_diff_pp :: (Num a, Ord a, Show a) => a -> String

-- | Given brackets, print cents difference.
cents_diff_br :: (Num a, Ord a, Show a) => (String, String) -> a -> String

-- | <a>cents_diff_br</a> with parentheses.
--   
--   <pre>
--   map cents_diff_text [-1,0,1] == ["(-1)","","(+1)"]
--   </pre>
cents_diff_text :: (Num a, Ord a, Show a) => a -> String

-- | <a>cents_diff_br</a> with markdown superscript (<tt>^</tt>).
cents_diff_md :: (Num a, Ord a, Show a) => a -> String

-- | <a>cents_diff_br</a> with HTML superscript (<tt><a>sup</a></tt>).
cents_diff_html :: (Num a, Ord a, Show a) => a -> String

-- | (<i>n</i> -&gt; <i>dt</i>). Function from midi note number <i>n</i> to
--   <tt>Midi_Detune</tt> <i>dt</i>. The incoming note number is the key
--   pressed, which may be distant from the note sounded.
type Midi_Tuning_F = Int -> Midi_Detune

-- | (t,c,k) where t=tuning (must have 12 divisions of octave), c=cents
--   deviation (ie. constant detune offset), k=midi offset (ie. value to be
--   added to incoming midi note number).
type D12_Midi_Tuning = (Tuning, Cents, Int)

-- | <a>Midi_Tuning_F</a> for <a>D12_Midi_Tuning</a>.
--   
--   <pre>
--   import Music.Theory.Tuning.Gann
--   let f = d12_midi_tuning_f (la_monte_young,-74.7,-3)
--   octpc_to_midi (-1,11) == 11
--   map (round . midi_detune_to_cps . f) [62,63,69] == [293,298,440]
--   </pre>
d12_midi_tuning_f :: D12_Midi_Tuning -> Midi_Tuning_F

-- | (t,f0,k) where t=tuning, f0=fundamental frequency, k=midi note number
--   for f0, n=gamut
type CPS_Midi_Tuning = (Tuning, Double, Int, Int)

-- | <a>Midi_Tuning_F</a> for <a>CPS_Midi_Tuning</a>.
cps_midi_tuning_f :: CPS_Midi_Tuning -> Midi_Tuning_F
instance GHC.Show.Show Music.Theory.Tuning.Tuning
instance GHC.Classes.Eq Music.Theory.Tuning.Tuning


-- | Clarence Barlow. "Two Essays on Theory". <i>Computer Music
--   Journal</i>, 11(1):44-60, 1987. Translated by Henning Lohner.
module Music.Theory.Interval.Barlow_1987

-- | Barlow's <i>indigestibility</i> function for prime numbers.
--   
--   <pre>
--   map barlow [1,2,3,5,7,11,13] == [0,1,8/3,32/5,72/7,200/11,288/13]
--   </pre>
barlow :: (Integral a, Fractional b) => a -> b

-- | Generate list of factors of <i>n</i> from <i>x</i>.
--   
--   <pre>
--   factor primes 315 == [3,3,5,7]
--   </pre>
factor :: Integral a => [a] -> a -> [a]

-- | <a>factor</a> <i>n</i> from <a>primes</a>.
--   
--   <pre>
--   prime_factors 315 == [3,3,5,7]
--   </pre>
prime_factors :: Integral a => a -> [a]

-- | Collect number of occurences of each element of a sorted list.
--   
--   <pre>
--   multiplicities [1,1,1,2,2,3] == [(1,3),(2,2),(3,1)]
--   </pre>
multiplicities :: (Eq a, Integral n) => [a] -> [(a, n)]

-- | <a>multiplicities</a> <a>.</a> <a>prime_factors</a>.
--   
--   <pre>
--   prime_factors_m 315 == [(3,2),(5,1),(7,1)]
--   </pre>
prime_factors_m :: Integral a => a -> [(a, a)]

-- | Merging function for <a>rational_prime_factors_m</a>.
merge :: (Ord a, Num b, Eq b) => [(a, b)] -> [(a, b)] -> [(a, b)]

-- | Collect the prime factors in a rational number given as a numerator/
--   denominator pair (n,m). Prime factors are listed in ascending order
--   with their positive or negative multiplicities, depending on whether
--   the prime factor occurs in the numerator or the denominator (after
--   cancelling out common factors).
--   
--   <pre>
--   rational_prime_factors_m (16,15) == [(2,4),(3,-1),(5,-1)]
--   rational_prime_factors_m (10,9) == [(2,1),(3,-2),(5,1)]
--   rational_prime_factors_m (81,64) == [(2,-6),(3,4)]
--   rational_prime_factors_m (27,16) == [(2,-4),(3,3)]
--   rational_prime_factors_m (12,7) == [(2,2),(3,1),(7,-1)]
--   </pre>
rational_prime_factors_m :: Integral b => (b, b) -> [(b, b)]

-- | Variant of <a>rational_prime_factors_m</a> giving results in a table
--   up to the <i>n</i>th prime.
--   
--   <pre>
--   rational_prime_factors_t 6 (12,7) == [2,1,0,-1,0,0]
--   </pre>
rational_prime_factors_t :: Integral b => Int -> (b, b) -> [b]

-- | Compute the disharmonicity of the interval <i>(p,q)</i> using the
--   prime valuation function <i>pv</i>.
--   
--   <pre>
--   map (disharmonicity barlow) [(9,10),(8,9)] ~= [12.733333,8.333333]
--   </pre>
disharmonicity :: (Integral a, Num b) => (a -> b) -> (a, a) -> b

-- | The reciprocal of <a>disharmonicity</a>.
--   
--   <pre>
--   map (harmonicity barlow) [(9,10),(8,9)] ~= [0.078534,0.120000]
--   </pre>
harmonicity :: (Integral a, Fractional b) => (a -> b) -> (a, a) -> b

-- | Variant of <a>harmonicity</a> with <a>Ratio</a> input.
harmonicity_r :: (Integral a, Fractional b) => (a -> b) -> Ratio a -> b

-- | <a>uncurry</a> (<a>%</a>).
to_rational :: Integral a => (a, a) -> Ratio a

-- | Make <a>numerator</a> <a>denominator</a> pair of <i>n</i>.
from_rational :: Integral t => Ratio t -> (t, t)

-- | Set of 1. interval size (cents), 2. intervals as product of powers of
--   primes, 3. frequency ratio and 4. harmonicity value.
type Table_2_Row = (Double, [Integer], Rational, Double)

-- | Table 2 (p.45)
--   
--   <pre>
--   length (table_2 0.06) == 24
--   </pre>
table_2 :: Double -> [Table_2_Row]

-- | Pretty printer for <a>Table_2_Row</a> values.
--   
--   <pre>
--   mapM_ (putStrLn . table_2_pp) (table_2 0.06)
--   </pre>
--   
--   <pre>
--      0.000 |  0  0  0  0  0  0 |  1:1  | Infinity
--    111.731 |  4 -1 -1  0  0  0 | 15:16 | 0.076531
--    182.404 |  1 -2  1  0  0  0 |  9:10 | 0.078534
--    203.910 | -3  2  0  0  0  0 |  8:9  | 0.120000
--    231.174 |  3  0  0 -1  0  0 |  7:8  | 0.075269
--    266.871 | -1 -1  0  1  0  0 |  6:7  | 0.071672
--    294.135 |  5 -3  0  0  0  0 | 27:32 | 0.076923
--    315.641 |  1  1 -1  0  0  0 |  5:6  | 0.099338
--    386.314 | -2  0  1  0  0  0 |  4:5  | 0.119048
--    407.820 | -6  4  0  0  0  0 | 64:81 | 0.060000
--    435.084 |  0  2  0 -1  0  0 |  7:9  | 0.064024
--    498.045 |  2 -1  0  0  0  0 |  3:4  | 0.214286
--    519.551 | -2  3 -1  0  0  0 | 20:27 | 0.060976
--    701.955 | -1  1  0  0  0  0 |  2:3  | 0.272727
--    764.916 |  1 -2  0  1  0  0 |  9:14 | 0.060172
--    813.686 |  3  0 -1  0  0  0 |  5:8  | 0.106383
--    884.359 |  0 -1  1  0  0  0 |  3:5  | 0.110294
--    905.865 | -4  3  0  0  0  0 | 16:27 | 0.083333
--    933.129 |  2  1  0 -1  0  0 |  7:12 | 0.066879
--    968.826 | -2  0  0  1  0  0 |  4:7  | 0.081395
--    996.090 |  4 -2  0  0  0  0 |  9:16 | 0.107143
--   1017.596 |  0  2 -1  0  0  0 |  5:9  | 0.085227
--   1088.269 | -3  1  1  0  0  0 |  8:15 | 0.082873
--   1200.000 |  1  0  0  0  0  0 |  1:2  | 1.000000
--   </pre>
table_2_pp :: Table_2_Row -> String


-- | Bill Alves.
module Music.Theory.Tuning.Alves

-- | Ratios for <a>harrison_ditone</a>.
--   
--   <pre>
--   let c = [0,114,204,294,408,498,612,702,816,906,996,1110]
--   in map (round . ratio_to_cents) harrison_ditone_r == c
--   </pre>
harrison_ditone_r :: [Rational]

-- | Ditone/pythagorean tuning, see
--   <a>http://www.billalves.com/porgitaro/ditonesettuning.html</a>
--   
--   <pre>
--   cents_i harrison_ditone == [0,114,204,294,408,498,612,702,816,906,996,1110]
--   </pre>
harrison_ditone :: Tuning


-- | Bill Alves. "Pleng: Composing for a Justly Tuned Gender Barung". 1/1:
--   Journal of the Just Intonation Network, 1:4-11, Spring 1997.
--   <a>http://www2.hmc.edu/~alves/pleng.html</a>
module Music.Theory.Tuning.Alves_1997
alves_slendro_r :: [Rational]

-- | HMC <i>slendro</i> tuning.
--   
--   <pre>
--   cents_i alves_slendro == [0,231,498,765,996]
--   </pre>
alves_slendro :: Tuning
alves_pelog_bem_r :: [Rational]

-- | HMC <i>pelog bem</i> tuning.
--   
--   <pre>
--   cents_i alves_pelog_bem == [0,231,316,702,814]
--   </pre>
alves_pelog_bem :: Tuning
alves_pelog_barang_r :: [Rational]

-- | HMC <i>pelog 2,3,4,6,7</i> tuning.
--   
--   <pre>
--   cents_i alves_pelog_barang == [0,386,471,857,969]
--   </pre>
alves_pelog_barang :: Tuning
alves_pelog_23467_r :: [Rational]

-- | HMC <i>pelog barang</i> tuning.
--   
--   <pre>
--   cents_i alves_pelog_23467 == [0,386,471,702,969]
--   </pre>
alves_pelog_23467 :: Tuning


-- | Equal temperament tuning tables.
module Music.Theory.Tuning.ET

-- | <a>octpc_to_pitch</a> and <a>octpc_to_cps</a>.
octpc_to_pitch_cps :: (Floating n) => OctPC -> (Pitch, n)

-- | 12-tone equal temperament table equating <a>Pitch</a> and frequency
--   over range of human hearing, where <tt>A4</tt> = <tt>440</tt>hz.
--   
--   <pre>
--   length tbl_12et == 132
--   let min_max l = (minimum l,maximum l)
--   min_max (map (round . snd) tbl_12et) == (16,31609)
--   </pre>
tbl_12et :: [(Pitch, Double)]

-- | 24-tone equal temperament variant of <a>tbl_12et</a>.
--   
--   <pre>
--   length tbl_24et == 264
--   min_max (map (round . snd) tbl_24et) == (16,32535)
--   </pre>
tbl_24et :: [(Pitch, Double)]

-- | Given an <tt>ET</tt> table (or like) find bounds of frequency.
--   
--   <pre>
--   let r = Just (at_pair octpc_to_pitch_cps ((3,11),(4,0)))
--   in bounds_et_table tbl_12et 256 == r
--   </pre>
bounds_et_table :: Ord s => [(t, s)] -> s -> Maybe ((t, s), (t, s))

-- | <a>bounds_et_table</a> of <a>tbl_12et</a>.
--   
--   <pre>
--   map bounds_12et_tone (hsn 17 55)
--   </pre>
bounds_12et_tone :: Double -> Maybe ((Pitch, Double), (Pitch, Double))

-- | Tuple indicating nearest <a>Pitch</a> to <i>frequency</i> with
--   <tt>ET</tt> frequency, and deviation in hertz and <a>Cents</a>.
type HS_R p = (Double, p, Double, Double, Cents)

-- | <i>n</i>-decimal places.
--   
--   <pre>
--   ndp 3 (1/3) == "0.333"
--   </pre>
ndp :: Int -> Double -> String

-- | Pretty print <a>HS_R</a>.
hs_r_pp :: (p -> String) -> Int -> HS_R p -> [String]
hs_r_pitch_pp :: Int -> HS_R Pitch -> [String]

-- | Form <a>HS_R</a> for <i>frequency</i> by consulting table.
--   
--   <pre>
--   let {f = 256
--       ;f' = octpc_to_cps (4,0)
--       ;r = (f,Pitch C Natural 4,f',f-f',fratio_to_cents (f/f'))}
--   in nearest_et_table_tone tbl_12et 256 == r
--   </pre>
nearest_et_table_tone :: [(p, Double)] -> Double -> HS_R p

-- | <a>nearest_et_table_tone</a> for <a>tbl_12et</a>.
nearest_12et_tone :: Double -> HS_R Pitch

-- | <a>nearest_et_table_tone</a> for <a>tbl_24et</a>.
--   
--   <pre>
--   let r = "55.0 A1 55.0 0.0 0.0"
--   in unwords (hs_r_pitch_pp 1 (nearest_24et_tone 55)) == r
--   </pre>
nearest_24et_tone :: Double -> HS_R Pitch

-- | Monzo 72-edo HEWM notation. The domain is (-9,9).
--   <a>http://www.tonalsoft.com/enc/number/72edo.aspx</a>
--   
--   <pre>
--   let r = ["+","&gt;","^","#&lt;","#-","#","#+","#&gt;","#^"]
--   in map alteration_72et_monzo [1 .. 9] == r
--   </pre>
--   
--   <pre>
--   let r = ["-","&lt;","v","b&gt;","b+","b","b-","b&lt;","bv"]
--   in map alteration_72et_monzo [-1,-2 .. -9] == r
--   </pre>
alteration_72et_monzo :: Integral n => n -> String

-- | Given a midi note number and <tt>1/6</tt> deviation determine
--   <a>Pitch'</a> and frequency.
--   
--   <pre>
--   let {f = pitch'_pp . fst . pitch_72et
--       ;r = "C4 C+4 C&gt;4 C^4 C#&lt;4 C#-4 C#4 C#+4 C#&gt;4 C#^4"}
--   in unwords (map f (zip (repeat 60) [0..9])) == r
--   </pre>
--   
--   <pre>
--   let {f = pitch'_pp . fst . pitch_72et
--       ;r = "A4 A+4 A&gt;4 A^4 Bb&lt;4 Bb-4 Bb4 Bb+4 Bb&gt;4 Bv4"}
--   in unwords (map f (zip (repeat 69) [0..9]))
--   </pre>
--   
--   <pre>
--   let {f = pitch'_pp . fst . pitch_72et
--       ;r = "Bb4 Bb+4 Bb&gt;4 Bv4 B&lt;4 B-4 B4 B+4 B&gt;4 B^4"}
--   in unwords (map f (zip (repeat 70) [0..9])) == r
--   </pre>
pitch_72et :: (Int, Int) -> (Pitch', Double)

-- | 72-tone equal temperament table equating <a>Pitch'</a> and frequency
--   over range of human hearing, where <tt>A4</tt> = <tt>440</tt>hz.
--   
--   <pre>
--   length tbl_72et == 792
--   min_max (map (round . snd) tbl_72et) == (16,33167)
--   </pre>
tbl_72et :: [(Pitch', Double)]

-- | <a>nearest_et_table_tone</a> for <a>tbl_72et</a>.
--   
--   <pre>
--   let r = "324.0 E&lt;4 323.3 0.7 3.5"
--   in unwords (hs_r_pp pitch'_pp 1 (nearest_72et_tone 324))
--   </pre>
--   
--   <pre>
--   let {f = take 2 . hs_r_pp pitch'_pp 1 . nearest_72et_tone . snd}
--   in mapM_ (print . unwords . f) tbl_72et
--   </pre>
nearest_72et_tone :: Double -> HS_R Pitch'

-- | <a>Pitch</a> with 12-ET/24-ET tuning deviation given in <a>Cents</a>.
type Pitch_Detune = (Pitch, Cents)

-- | Exract <a>Pitch_Detune</a> from <a>HS_R</a>.
hsr_to_pitch_detune :: HS_R Pitch -> Pitch_Detune

-- | Nearest 12-ET <a>Pitch_Detune</a> to indicated frequency (hz).
--   
--   <pre>
--   nearest_pitch_detune_12et 452.8929841231365
--   </pre>
nearest_pitch_detune_12et :: Double -> Pitch_Detune

-- | Nearest 24-ET <a>Pitch_Detune</a> to indicated frequency (hz).
--   
--   <pre>
--   nearest_pitch_detune_24et 452.8929841231365
--   </pre>
nearest_pitch_detune_24et :: Double -> Pitch_Detune

-- | Given <i>near</i> function, <i>f0</i> and ratio derive
--   <a>Pitch_Detune</a>.
ratio_to_pitch_detune :: (Double -> HS_R Pitch) -> OctPC -> Rational -> Pitch_Detune

-- | Frequency (hz) of <a>Pitch_Detune</a>.
--   
--   <pre>
--   pitch_detune_to_cps (octpc_to_pitch pc_spell_ks (4,9),50)
--   </pre>
pitch_detune_to_cps :: Floating n => Pitch_Detune -> n

-- | <a>ratio_to_pitch_detune</a> of <a>nearest_12et_tone</a>
ratio_to_pitch_detune_12et :: OctPC -> Rational -> Pitch_Detune

-- | <a>ratio_to_pitch_detune</a> of <a>nearest_24et_tone</a>
ratio_to_pitch_detune_24et :: OctPC -> Rational -> Pitch_Detune
pitch_detune_in_octave_nearest :: Pitch -> Pitch_Detune -> Pitch_Detune

-- | Markdown pretty-printer for <a>Pitch_Detune</a>.
pitch_detune_md :: Pitch_Detune -> String

-- | HTML pretty-printer for <a>Pitch_Detune</a>.
pitch_detune_html :: Pitch_Detune -> String

-- | No-octave variant of <a>pitch_detune_md</a>.
pitch_class_detune_md :: Pitch_Detune -> String

-- | No-octave variant of <a>pitch_detune_html</a>.
pitch_class_detune_html :: Pitch_Detune -> String


-- | Kyle Gann.
module Music.Theory.Tuning.Gann

-- | Cents for <a>pietro_aaron_1523</a>.
--   
--   <pre>
--   let c = [0,76,193,310,386,503,580,697,773,890,1007,1083]
--   in map round pietro_aaron_1523_c == c
--   </pre>
pietro_aaron_1523_c :: [Cents]

-- | Pietro Aaron (1523) meantone temperament, see
--   <a>http://www.kylegann.com/histune.html</a>
--   
--   <pre>
--   cents_i pietro_aaron_1523 == [0,76,193,310,386,503,580,697,773,890,1007,1083]
--   </pre>
pietro_aaron_1523 :: Tuning

-- | Andreas Werckmeister (1645-1706),
--   <a>http://www.kylegann.com/histune.html</a>.
werckmeister_iii_c :: [Cents]

-- | Cents for <a>thomas_young_1799</a>.
--   
--   <pre>
--   let c = [0,94,196,298,392,500,592,698,796,894,1000,1092]
--   in map round thomas_young_1799_c == c
--   </pre>
thomas_young_1799_c :: [Cents]

-- | Thomas Young (1799), Well Temperament,
--   <a>http://www.kylegann.com/histune.html</a>.
--   
--   <pre>
--   cents_i thomas_young_1799 == [0,94,196,298,392,500,592,698,796,894,1000,1092]
--   </pre>
thomas_young_1799 :: Tuning

-- | Ratios for <a>zarlino</a>.
zarlino_r :: [Rational]

-- | Gioseffo Zarlino, 1588, see
--   <a>http://www.kylegann.com/tuning.html</a>.
--   
--   <pre>
--   divisions zarlino == 16
--   cents_i zarlino == [0,71,182,204,294,316,386,498,569,590,702,773,884,996,1018,1088]
--   </pre>
zarlino :: Tuning

-- | Ratios for <a>la_monte_young</a>.
--   
--   <pre>
--   let c = [0,177,204,240,471,444,675,702,738,969,942,1173]
--   in map (round . ratio_to_cents) la_monte_young_r == c
--   </pre>
la_monte_young_r :: [Rational]

-- | La Monte Young's "The Well-Tuned Piano", see
--   <a>http://www.kylegann.com/wtp.html</a>.
--   
--   <pre>
--   cents_i la_monte_young == [0,177,204,240,471,444,675,702,738,969,942,1173]
--   </pre>
la_monte_young :: Tuning

-- | Ratios for <a>ben_johnston</a>.
--   
--   <pre>
--   let c = [0,105,204,298,386,471,551,702,841,906,969,1088]
--   in map (round . ratio_to_cents) ben_johnston_r == c
--   </pre>
ben_johnston_r :: [Rational]

-- | Ben Johnston's "Suite for Microtonal Piano" (1977), see
--   <a>http://www.kylegann.com/tuning.html</a>
--   
--   <pre>
--   cents_i ben_johnston == [0,105,204,298,386,471,551,702,841,906,969,1088]
--   </pre>
ben_johnston :: Tuning

-- | Ratios for <a>gann_arcana_xvi</a>.
gann_arcana_xvi_r :: [Rational]

-- | Kyle Gann, _Arcana XVI_, see
--   <a>http://www.kylegann.com/Arcana.html</a>.
--   
--   <pre>
--   let r = [0,84,112,204,267,316,347,386,471,498,520,583,663,702,734,814,845,884,898,969,1018,1049,1088,1161]
--   in cents_i gann_arcana_xvi == r
--   </pre>
gann_arcana_xvi :: Tuning

-- | Ratios for <a>gann_superparticular</a>.
gann_superparticular_r :: [Rational]

-- | Kyle Gann, _Superparticular_, see
--   <a>http://www.kylegann.com/Super.html</a>.
--   
--   <pre>
--   divisions gann_superparticular == 22
--   </pre>
--   
--   <pre>
--   let r = [0,165,182,204,231,267,316,386,435,498,551,583,617,702,782,765,814,884,933,969,996,1018]
--   in cents_i gann_superparticular == r
--   </pre>
gann_superparticular :: Tuning


-- | Max Meyer. "The musician's arithmetic: drill problems for an
--   introduction to the scientific study of musical composition." The
--   University of Missouri, 1929. p.22
module Music.Theory.Tuning.Meyer_1929

-- | Odd numbers to <i>n</i>.
--   
--   <pre>
--   odd_to 7 == [1,3,5,7]
--   </pre>
odd_to :: (Num t, Enum t) => t -> [t]

-- | Generate initial row for <i>n</i>.
--   
--   <pre>
--   row 7 == [1,5/4,3/2,7/4]
--   </pre>
row :: Integral i => i -> [Ratio i]

-- | Generate initial column for <i>n</i>.
--   
--   <pre>
--   column 7 == [1,8/5,4/3,8/7]
--   </pre>
column :: Integral i => i -> [Ratio i]

-- | <a>fold_to_octave</a> <a>.</a> <a>*</a>.
in_oct_mul :: Integral i => Ratio i -> Ratio i -> Ratio i

-- | Given <i>row</i> and <i>column</i> generate matrix value at
--   <i>(i,j)</i>.
--   
--   <pre>
--   inner (row 7,column 7) (1,2) == 6/5
--   </pre>
inner :: Integral i => ([Ratio i], [Ratio i]) -> (i, i) -> Ratio i
meyer_table_rck :: Integral i => i -> ([Ratio i], [Ratio i], i)

-- | Meyer table in form <i>(r,c,n)</i>.
--   
--   <pre>
--   meyer_table_indices 7 == [(0,0,1/1),(0,1,5/4),(0,2,3/2),(0,3,7/4)
--                            ,(1,0,8/5),(1,1,1/1),(1,2,6/5),(1,3,7/5)
--                            ,(2,0,4/3),(2,1,5/3),(2,2,1/1),(2,3,7/6)
--                            ,(3,0,8/7),(3,1,10/7),(3,2,12/7),(3,3,1/1)]
--   </pre>
meyer_table_indices :: Integral i => i -> [(i, i, Ratio i)]

-- | Meyer table as set of rows.
--   
--   <pre>
--   meyer_table_rows 7 == [[1/1, 5/4, 3/2,7/4]
--                         ,[8/5, 1/1, 6/5,7/5]
--                         ,[4/3, 5/3, 1/1,7/6]
--                         ,[8/7,10/7,12/7,1/1]]
--   </pre>
--   
--   <pre>
--   let r = [[ 1/1,   9/8,   5/4,  11/8,   3/2,  13/8,   7/4,  15/8]
--           ,[16/9,   1/1,  10/9,  11/9,   4/3,  13/9,  14/9,   5/3]
--           ,[ 8/5,   9/5,   1/1,  11/10,  6/5,  13/10,  7/5,   3/2]
--           ,[16/11, 18/11, 20/11,  1/1,  12/11, 13/11, 14/11, 15/11]
--           ,[ 4/3,   3/2,   5/3,  11/6,   1/1,  13/12,  7/6,   5/4]
--           ,[16/13, 18/13, 20/13, 22/13, 24/13,  1/1,  14/13, 15/13]
--           ,[ 8/7,   9/7,   10/7, 11/7,  12/7,  13/7,   1/1,  15/14]
--           ,[16/15,  6/5,    4/3, 22/15,  8/5,  26/15, 28/15,  1/1]]
--   in meyer_table_rows 15 == r
--   </pre>
meyer_table_rows :: Integral a => a -> [[Ratio a]]

-- | Third element of three-tuple.
t3_3 :: (t1, t2, t3) -> t3

-- | Set of unique ratios in <i>n</i> table.
--   
--   <pre>
--   elements 7 == [1,8/7,7/6,6/5,5/4,4/3,7/5,10/7,3/2,8/5,5/3,12/7,7/4]
--   </pre>
--   
--   <pre>
--   elements 9 == [1,10/9,9/8,8/7,7/6,6/5,5/4,9/7,4/3,7/5,10/7
--                 ,3/2,14/9,8/5,5/3,12/7,7/4,16/9,9/5]
--   </pre>
elements :: Integral i => i -> [Ratio i]

-- | Number of unique elements at <i>n</i> table.
--   
--   <pre>
--   map degree [7,9,11,13,15] == [13,19,29,41,49]
--   </pre>
degree :: Integral i => i -> i

-- | <a>http://en.wikipedia.org/wiki/Farey_sequence</a>
--   
--   <pre>
--   let r = [[0,1/2,1]
--           ,[0,1/3,1/2,2/3,1]
--           ,[0,1/4,1/3,1/2,2/3,3/4,1]
--           ,[0,1/5,1/4,1/3,2/5,1/2,3/5,2/3,3/4,4/5,1]
--           ,[0,1/6,1/5,1/4,1/3,2/5,1/2,3/5,2/3,3/4,4/5,5/6,1]]
--   in map farey_sequence [2..6] == r
--   </pre>
farey_sequence :: Integral a => a -> [Ratio a]


-- | <a>http://www.microtonal-synthesis.com/scales.html</a>
module Music.Theory.Tuning.Microtonal_Synthesis

-- | Ratios for <a>pythagorean</a>.
--   
--   <pre>
--   let c = [0,90,204,294,408,498,612,702,792,906,996,1110]
--   in map (round . ratio_to_cents) pythagorean_r == c
--   </pre>
pythagorean_r :: [Rational]

-- | Pythagorean tuning,
--   <a>http://www.microtonal-synthesis.com/scale_pythagorean.html</a>.
--   
--   <pre>
--   divisions pythagorean == 12
--   cents_i pythagorean == [0,90,204,294,408,498,612,702,792,906,996,1110]
--   </pre>
pythagorean :: Tuning

-- | Ratios for <a>five_limit_tuning</a>.
--   
--   <pre>
--   let c = [0,112,204,316,386,498,590,702,814,884,996,1088]
--   in map (round . ratio_to_cents) five_limit_tuning_r == c
--   </pre>
five_limit_tuning_r :: [Rational]

-- | Five-limit tuning (five limit just intonation).
--   
--   <pre>
--   cents_i five_limit_tuning == [0,112,204,316,386,498,590,702,814,884,996,1088]
--   </pre>
five_limit_tuning :: Tuning

-- | Ratios for <a>septimal_tritone_just_intonation</a>.
--   
--   <pre>
--   let c = [0,112,204,316,386,498,583,702,814,884,1018,1088]
--   in map (round . ratio_to_cents) septimal_tritone_just_intonation == c
--   </pre>
septimal_tritone_just_intonation_r :: [Rational]

-- | Septimal tritone Just Intonation, see
--   <a>http://www.microtonal-synthesis.com/scale_just_intonation.html</a>
--   
--   <pre>
--   cents_i septimal_tritone_just_intonation == [0,112,204,316,386,498,583,702,814,884,1018,1088]
--   </pre>
septimal_tritone_just_intonation :: Tuning

-- | Ratios for <a>seven_limit_just_intonation</a>.
--   
--   <pre>
--   let c = [0,112,204,316,386,498,583,702,814,884,969,1088]
--   in map (round . ratio_to_cents) seven_limit_just_intonation == c
--   </pre>
seven_limit_just_intonation_r :: [Rational]

-- | Seven limit Just Intonation.
--   
--   <pre>
--   cents_i seven_limit_just_intonation == [0,112,204,316,386,498,583,702,814,884,969,1088]
--   </pre>
seven_limit_just_intonation :: Tuning

-- | Approximate ratios for <a>kirnberger_iii</a>.
--   
--   <pre>
--   let c = [0,90,193,294,386,498,590,697,792,890,996,1088]
--   in map (round.to_cents) kirnberger_iii_ar == c
--   </pre>
kirnberger_iii_ar :: [Approximate_Ratio]

-- | <a>http://www.microtonal-synthesis.com/scale_kirnberger.html</a>.
--   
--   <pre>
--   cents_i kirnberger_iii == [0,90,193,294,386,498,590,697,792,890,996,1088]
--   </pre>
kirnberger_iii :: Tuning
vallotti_c :: [Cents]

-- | Vallotti &amp; Young scale (Vallotti version), see
--   <a>http://www.microtonal-synthesis.com/scale_vallotti_young.html</a>.
--   
--   <pre>
--   cents_i vallotti == [0,94,196,298,392,502,592,698,796,894,1000,1090]
--   </pre>
vallotti :: Tuning
mayumi_reinhard_r :: [Rational]

-- | Mayumi Reinhard 13-limit Just Intonation scale,
--   <a>http://www.microtonal-synthesis.com/scale_reinhard.html</a>.
--   
--   <pre>
--   cents_i mayumi_reinhard == [0,128,139,359,454,563,637,746,841,911,1072,1183]
--   </pre>
mayumi_reinhard :: Tuning

-- | Ratios for <a>lou_harrison_16</a>.
--   
--   <pre>
--   length lou_harrison_16_r == 16
--   </pre>
--   
--   <pre>
--   let c = [0,112,182,231,267,316,386,498,603,702,814,884,933,969,1018,1088]
--   in map (round . ratio_to_cents) lou_harrison_16_r == c
--   </pre>
lou_harrison_16_r :: [Rational]

-- | Lou Harrison 16 tone Just Intonation scale, see
--   <a>http://www.microtonal-synthesis.com/scale_harrison_16.html</a>
--   
--   <pre>
--   let r = [0,112,182,231,267,316,386,498,603,702,814,884,933,969,1018,1088]
--   in cents_i lou_harrison_16 == r
--   </pre>
lou_harrison_16 :: Tuning

-- | Ratios for <a>partch_43</a>.
partch_43_r :: [Rational]

-- | Harry Partch 43 tone scale, see
--   <a>http://www.microtonal-synthesis.com/scale_partch.html</a>
--   
--   <pre>
--   cents_i partch_43 == [0,22,53,84,112,151,165
--                        ,182,204,231,267,294,316
--                        ,347,386,418,435
--                        ,471,498,520,551,583,617,649
--                        ,680,702,729,765,782,814,853,884,906,933
--                        ,969,996,1018,1035,1049,1088,1116,1147,1178]
--   </pre>
partch_43 :: Tuning

-- | Ratios for <a>ben_johnston_25</a>.
ben_johnston_25_r :: [Rational]

-- | Ben Johnston 25 note just enharmonic scale, see
--   <a>http://www.microtonal-synthesis.com/scale_johnston_25.html</a>
ben_johnston_25 :: Tuning


-- | Larry Polansky. "Psaltery (for Lou Harrison)". Frog Peak Music, 1978.
module Music.Theory.Tuning.Polansky_1978

-- | Three interlocking harmonic series on 1:5:3, by Larry Polansky in
--   "Psaltery".
--   
--   <pre>
--   import qualified Music.Theory.Tuning.Scala as T
--   let fn = "/home/rohan/opt/scala/scl/polansky_ps.scl"
--   s &lt;- T.load fn
--   T.scale_pitch_representations s == (0,50)
--   1 : Data.Either.rights (T.scale_pitches s) == psaltery
--   </pre>
psaltery :: [Rational]

-- | <a>fold_ratio_to_octave</a> of <a>psaltery</a>.
--   
--   <pre>
--   length psaltery == 51 &amp;&amp; length psaltery_o == 21
--   psaltery_o == [1,65/64,33/32,17/16,35/32,9/8,75/64,39/32
--                 ,5/4,21/16,85/64,11/8,45/32
--                 ,3/2,25/16,51/32,13/8,27/16,55/32,7/4,15/8]
--   </pre>
psaltery_o :: [Rational]


-- | Larry Polansky. "Tuning Systems in American Gamelan, Part I: Interval
--   Sizes in Javanese Slendro". <i>Balungan</i>, 1(2):9-11, 1984
module Music.Theory.Tuning.Polansky_1984
k_manisrenga :: Fractional n => [n]
k_kanjutmesem :: Fractional n => [n]
k_udanriris :: Fractional n => [n]
k_pengawesari :: Fractional n => [n]
k_rarasrum :: Fractional n => [n]
k_hardjanagara :: Fractional n => [n]
k_madukentir :: Fractional n => [n]
k_surak :: Fractional n => [n]

-- | The set of <i>K</i> slendro tunings.
--   
--   <pre>
--   map length k_set == replicate (length k_set) 5
--   minimum (concat k_set) == 206
--   maximum (concat k_set) == 268.5
--   </pre>
k_set :: Fractional n => [[n]]

-- | Given a set of equal length lists calculate the average value of each
--   position.
--   
--   <pre>
--   calculate_averages [[1,2,3],[3,2,1]] == [2,2,2]
--   </pre>
calculate_averages :: Fractional n => [[n]] -> [n]

-- | Averages of <i>K</i> set, p. 10.
--   
--   <pre>
--   k_averages == [233.8125,245.0625,234.0,240.8125,251.875]
--   </pre>
k_averages :: Fractional n => [n]
gm_1 :: Fractional n => [n]
gm_2 :: Fractional n => [n]
gm_3 :: Fractional n => [n]
gm_4 :: Fractional n => [n]
gm_5 :: Fractional n => [n]
gm_6 :: Fractional n => [n]
gm_7 :: Fractional n => [n]
gm_8 :: Fractional n => [n]

-- | The set of <i>GM</i> (Gadja Mada University) slendro tunings.
--   
--   <pre>
--   map length gm_set == replicate (length gm_set) 5
--   minimum (concat gm_set) == 218
--   maximum (concat gm_set) == 262
--   </pre>
gm_set :: Fractional n => [[n]]

-- | Averages of <i>GM</i> set, p. 10.
--   
--   <pre>
--   gm_averages == [234.0,240.25,247.625,243.125,254.0625]
--   </pre>
gm_averages :: Fractional n => [n]

-- | Association list giving interval boundaries for interval class
--   categories (pp.10-11).
i_categories :: Num n => [((n, n), String)]

-- | Categorise an interval.
i_category :: (Ord a, Num a) => a -> String

-- | Pad <a>String</a> to right with spaces until at least <i>n</i>
--   characters.
--   
--   <pre>
--   map (pad 3) ["S","E-L"] == ["S  ","E-L"]
--   </pre>
pad :: Int -> String -> String

-- | Pretty interval category table (pp. 10-11).
--   
--   <pre>
--   i_category_table k_set ==
--    ["S    L    S    S    L  "
--    ,"S    L    S    S    L  "
--    ,"L    L    S    S    S  "
--    ,"L    S    S    S    L  "
--    ,"S    S    L    S    L  "
--    ,"S    E-L  S    L    L  "
--    ,"L    E    E    S    S  "
--    ,"S    S    S-E  L    L  "]
--   </pre>
--   
--   <pre>
--   i_category_table gm_set ==
--    ["S    L    E-L  E    L  "
--    ,"L    S-E  E    S    L  "
--    ,"S    S-E  S    L    S-E"
--    ,"S    L    L    S    L  "
--    ,"S    S-E  E-L  S    L  "
--    ,"S    S-E  E    E    L  "
--    ,"S-E  S    L    E    L  "
--    ,"S    S    E-L  L    L  "]
--   </pre>
i_category_table :: (Ord a, Num a) => [[a]] -> [String]

-- | Rational tuning derived from <a>gm_averages</a>, p.11.
--   
--   <pre>
--   polansky_1984_r == sort polansky_1984_r
--   polansky_1984_r == [1/1,8/7,21/16,512/343,12/7,96/49]
--   </pre>
--   
--   <pre>
--   import Music.Theory.List
--   d_dx polansky_1984_r == [1/7,19/112,989/5488,76/343,12/49]
--   </pre>
polansky_1984_r :: [Rational]

-- | <a>ratio_to_cents</a> of <a>polansky_1984_r</a>.
--   
--   <pre>
--   import Music.Theory.List
--   map round (d_dx polansky_1984_c) == [231,240,223,240,231]
--   </pre>
polansky_1984_c :: [Cents]


-- | Larry Polansky. "Notes on Piano Study #5". _1/1, The Journal of the
--   Just Intonation Newtork_, 1(4), Autumn 1985.
module Music.Theory.Tuning.Polansky_1985c

-- | The tuning has four octaves, these ratios are per-octave.
ps5_jpr_r :: [[Rational]]

-- | Four-octave tuning.
--   
--   <pre>
--   import Data.List.Split
--   </pre>
--   
--   <pre>
--   let r = [[   0,  84, 204, 316, 386, 498, 583, 702, 814, 884, 969,1088]
--           ,[1200,1284,1404,1516,1586,1698,1783,1902,2014,2084,2169,2288]
--           ,[2400,2453,2604,2716,2786,2871,2951,3102,3214,3241,3369,3488]
--           ,[3600,3684,3804,3867,3986,4098,4151,4302,4414,4506,4569,4688]]
--   in chunksOf 12 (cents_i ps5_jpr) == r
--   </pre>
--   
--   <pre>
--   let r = [[0,84,204,316,386,498,583,702,814,884,969,1088]
--           ,[0,84,204,316,386,498,583,702,814,884,969,1088]
--           ,[0,53,204,316,386,471,551,702,814,841,969,1088]
--           ,[0,84,204,267,386,498,551,702,814,906,969,1088]]
--   chunksOf 12 (map (`mod` 1200) (cents_i ps5_jpr))
--   </pre>
ps5_jpr :: Tuning


-- | Larry Polansky. "Notes on the Tunings of Three Central Javanese
--   Slendro/Pelog Pairs". <i>Experimental Musical Instruments</i>,
--   6(2):12-13,16-17, 1990.
module Music.Theory.Tuning.Polansky_1990

-- | Kanjutmesem Slendro (S1,S2,S3,S5,S6,S1')
--   
--   <pre>
--   L.d_dx kanjutmesem_s == [252,238,241,236,253]
--   </pre>
kanjutmesem_s :: Num n => [n]

-- | Kanjutmesem Pelog (P1,P2,P3,P4,P5,P6,P7,P1')
--   
--   <pre>
--   L.d_dx kanjutmesem_p == [141,141,272,140,115,172,246]
--   </pre>
kanjutmesem_p :: Num n => [n]

-- | Darius Slendro (S1,S2,S3,S5,S6,S1')
--   
--   <pre>
--   L.d_dx darius_s == [204,231,267,231,267]
--   ax_r darius_s == [9/8,8/7,7/6,8/7,7/6]
--   </pre>
darius_s :: Num n => [n]

-- | Madeleine Pelog (P1,P2,P3,P4,P5,P6,P7,P1')
--   
--   <pre>
--   L.d_dx madeleine_p == [139,128,336,99,94,173,231]
--   ax_r madeleine_p == [13/12,14/13,17/14,18/17,19/18,21/19,8/7]
--   </pre>
madeleine_p :: Num n => [n]

-- | Lipur Sih Slendro (S1,S2,S3,S5,S6,S1')
--   
--   <pre>
--   L.d_dx lipur_sih_s == [273,236,224,258,256]
--   </pre>
lipur_sih_s :: Num n => [n]

-- | Lipur Sih Pelog (P1,P2,P3,P4,P5,P6,P7,P1')
--   
--   <pre>
--   L.d_dx lipur_sih_p == [110,153,253,146,113,179]
--   </pre>
lipur_sih_p :: Num n => [n]

-- | Idealized ET Slendro, 5-tone equal temperament (p.17)
--   
--   <pre>
--   L.d_dx idealized_et_s == [240,240,240,240,240]
--   </pre>
idealized_et_s :: Num n => [n]

-- | Idealized ET Pelog, subset of 9-tone equal temperament (p.17)
--   
--   <pre>
--   L.d_dx idealized_et_p == [400/3,800/3,400/3,400/3,400/3,400/3,800/3]
--   </pre>
idealized_et_p :: Integral n => [Ratio n]

-- | Reconstruct approximate ratios to within <tt>1e-3</tt> from intervals.
ax_r :: Real n => [n] -> [Rational]


-- | Terry Riley.
module Music.Theory.Tuning.Riley

-- | Ratios for <a>riley_albion</a>.
--   
--   <pre>
--   let r = [0,112,204,316,386,498,610,702,814,884,996,1088]
--   in map (round . ratio_to_cents) riley_albion_r == r
--   </pre>
riley_albion_r :: [Rational]

-- | Riley's five-limit tuning as used in _The Harp of New Albion_, see
--   <a>http://www.ex-tempore.org/Volx1/hudson/hudson.htm</a>.
--   
--   <pre>
--   cents_i riley_albion == [0,112,204,316,386,498,610,702,814,884,996,1088]
--   </pre>
riley_albion :: Tuning


-- | Parser for the Scala scale file format. See
--   <a>http://www.huygens-fokker.org/scala/scl_format.html</a> for
--   details. This module succesfully parses all 4496 scales in v.81 of the
--   scale library.
module Music.Theory.Tuning.Scala

-- | A <tt>.scl</tt> pitch is either in <tt>Cents</tt> or is a
--   <a>Ratio</a>.
type Pitch i = Either Cents (Ratio i)

-- | A scale has a description, a degree, and a list of <a>Pitch</a>es.
type Scale i = (String, i, [Pitch i])

-- | Text description of scale.
scale_description :: Scale i -> String

-- | The degree of the scale (number of <a>Pitch</a>es).
scale_degree :: Scale i -> i

-- | The <a>Pitch</a>es at <a>Scale</a>.
scale_pitches :: Scale i -> [Pitch i]

-- | The last <a>Pitch</a> element of the scale (ie. the <i>ocatve</i>).
scale_octave :: Scale i -> Maybe (Pitch i)

-- | Is <a>scale_octave</a> perfect, ie. <a>Ratio</a> of <tt>2</tt> or
--   <tt>Cents</tt> of <tt>1200</tt>.
perfect_octave :: Integral i => Scale i -> Bool

-- | A pair giving the number of <tt>Cents</tt> and number of <a>Ratio</a>
--   pitches at <a>Scale</a>.
scale_pitch_representations :: (Integral t) => Scale i -> (t, t)

-- | Pitch as <a>Cents</a>, conversion by <a>to_cents_r</a> if necessary.
pitch_cents :: Pitch Integer -> Cents
type Epsilon = Double

-- | Pitch as <a>Rational</a>, conversion by <a>reconstructed_ratio</a> if
--   necessary, hence <i>epsilon</i>.
pitch_ratio :: Epsilon -> Pitch Integer -> Rational

-- | Make scale pitches uniform, conforming to the most promininent pitch
--   type.
scale_uniform :: Epsilon -> Scale Integer -> Scale Integer

-- | Scale as list of <a>Cents</a> (ie. <a>pitch_cents</a>) with <tt>0</tt>
--   prefix.
scale_cents :: Scale Integer -> [Cents]

-- | Scale as list of <a>Rational</a> (ie. <a>pitch_ratio</a>) with
--   <tt>1</tt> prefix.
scale_ratios :: Epsilon -> Scale Integer -> [Rational]

-- | Comment lines being with <tt>!</tt>.
comment_p :: String -> Bool

-- | Remove <tt>r</tt>.
filter_cr :: String -> String

-- | Logical <i>or</i> of list of predicates.
p_or :: [a -> Bool] -> a -> Bool

-- | Remove to end of line <tt>!</tt> comments.
remove_eol_comments :: String -> String

-- | Remove comments and null lines.
--   
--   <pre>
--   filter_comments ["!a","b","","c"] == ["b","c"]
--   </pre>
filter_comments :: [String] -> [String]

-- | Delete trailing <tt>.</tt>, <a>read</a> fails for <tt>700.</tt>.
delete_trailing_point :: String -> String

-- | Pitches are either cents (with decimal point) or ratios (with
--   <tt>/</tt>).
--   
--   <pre>
--   map pitch ["700.0","3/2","2"] == [Left 700,Right (3/2),Right 2]
--   </pre>
pitch :: (Read i, Integral i) => String -> Pitch i

-- | Pitch lines may contain commentary.
pitch_ln :: (Read i, Integral i) => String -> Pitch i

-- | Parse <tt>.scl</tt> file.
parse :: (Read i, Integral i) => String -> Scale i

-- | Load <tt>.scl</tt> file.
--   
--   <pre>
--   s &lt;- load "/home/rohan/data/scala/81/scl/xenakis_chrom.scl"
--   scale_pitch_representations s == (6,1)
--   scale_ratios 1e-3 s == [1,21/20,29/23,179/134,280/187,11/7,100/53,2]
--   </pre>
load :: (Read i, Integral i) => FilePath -> IO (Scale i)

-- | Subset of files in <i>dir</i> with an extension in <i>ext</i>.
dir_subset :: [String] -> FilePath -> IO [FilePath]

-- | Load all <tt>.scl</tt> files at <i>dir</i>.
--   
--   <pre>
--   db &lt;- load_dir "/home/rohan/data/scala/81/scl"
--   length db == 4496
--   length (filter ((== 0) . scale_degree) db) == 0
--   length (filter (== Just (Right 2)) (map scale_octave db)) == 3855
--   </pre>
--   
--   <pre>
--   let r = [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24
--           ,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44
--           ,45,46,47,48,49,50,51,53,54,55,56,57,58,59,60,61,62,63,64
--           ,65,66,67,68,69,70,71,72,74,75,77,78,79,80,81,84,87,88
--           ,90,91,92,95,96,99,100,101,105,110,112,117,118,130,140,171
--           ,180,271,311,342,366,441,612]
--   in nub (sort (map scale_degree db)) == r
--   </pre>
--   
--   <pre>
--   let r = ["Xenakis's Byzantine Liturgical mode, 5 + 19 + 6 parts"
--           ,"Xenakis's Byzantine Liturgical mode, 12 + 11 + 7 parts"
--           ,"Xenakis's Byzantine Liturgical mode, 7 + 16 + 7 parts"]
--   in filter (isInfixOf "Xenakis") (map scale_description db) == r
--   </pre>
--   
--   <pre>
--   length (filter (not . perfect_octave) db) == 544
--   </pre>
--   
--   <pre>
--   mapM_ (putStrLn.scale_description) (filter (not . perfect_octave) db)
--   </pre>
load_dir :: (Read i, Integral i) => FilePath -> IO [Scale i]


-- | Syntonic tuning.
module Music.Theory.Tuning.Syntonic

-- | Construct an isomorphic layout of <i>r</i> rows and <i>c</i> columns
--   with an upper left value of <i>(i,j)</i>.
mk_isomorphic_layout :: Integral a => a -> a -> (a, a) -> [[(a, a)]]

-- | A minimal isomorphic note layout.
--   
--   <pre>
--   let [i,j,k] = mk_isomorphic_layout 3 5 (3,-4)
--   in [i,take 4 j,(2,-4):take 4 k] == minimal_isomorphic_note_layout
--   </pre>
minimal_isomorphic_note_layout :: [[(Int, Int)]]

-- | Make a rank two regular temperament from a list of <i>(i,j)</i>
--   positions by applying the scalars <i>a</i> and <i>b</i>.
rank_two_regular_temperament :: Integral a => a -> a -> [(a, a)] -> [a]

-- | Syntonic tuning system based on <a>mk_isomorphic_layout</a> of
--   <tt>5</tt> rows and <tt>7</tt> columns starting at <tt>(3,-4)</tt> and
--   a <a>rank_two_regular_temperament</a> with <i>a</i> of <tt>1200</tt>
--   and indicated <i>b</i>.
mk_syntonic_tuning :: Int -> [Cents]

-- | <a>mk_syntonic_tuning</a> of <tt>697</tt>.
--   
--   <pre>
--   divisions syntonic_697 == 17
--   </pre>
--   
--   <pre>
--   let c = [0,79,194,273,309,388,467,503,582,697,776,812,891,970,1006,1085,1164]
--   in cents_i syntonic_697 == c
--   </pre>
syntonic_697 :: Tuning

-- | <a>mk_syntonic_tuning</a> of <tt>702</tt>.
--   
--   <pre>
--   divisions syntonic_702 == 17
--   </pre>
--   
--   <pre>
--   let c = [0,24,114,204,294,318,408,498,522,612,702,792,816,906,996,1020,1110]
--   in cents_i syntonic_702 == c
--   </pre>
syntonic_702 :: Tuning


-- | Andreas Werckmeister (1645-1706).
module Music.Theory.Tuning.Werckmeister

-- | Approximate ratios for <a>werckmeister_iii</a>.
--   
--   <pre>
--   let c = [0,90,192,294,390,498,588,696,792,888,996,1092]
--   in map (round . ratio_to_cents) werckmeister_iii_ar == c
--   </pre>
werckmeister_iii_ar :: [Approximate_Ratio]

-- | Cents for <a>werckmeister_iii</a>.
werckmeister_iii_ar_c :: [Cents]

-- | Werckmeister III, Andreas Werckmeister (1645-1706)
--   
--   <pre>
--   cents_i werckmeister_iii == [0,90,192,294,390,498,588,696,792,888,996,1092]
--   </pre>
werckmeister_iii :: Tuning

-- | Approximate ratios for <a>werckmeister_iv</a>.
--   
--   <pre>
--   let c = [0,82,196,294,392,498,588,694,784,890,1004,1086]
--   in map (round . ratio_to_cents) werckmeister_iv_ar == c
--   </pre>
werckmeister_iv_ar :: [Approximate_Ratio]

-- | Cents for <a>werckmeister_iv</a>.
werckmeister_iv_c :: [Cents]

-- | Werckmeister IV, Andreas Werckmeister (1645-1706)
--   
--   <pre>
--   cents_i werckmeister_iv == [0,82,196,294,392,498,588,694,784,890,1004,1086]
--   </pre>
werckmeister_iv :: Tuning

-- | Approximate ratios for <a>werckmeister_v</a>.
--   
--   <pre>
--   let c = [0,96,204,300,396,504,600,702,792,900,1002,1098]
--   in map (round . ratio_to_cents) werckmeister_v_ar == c
--   </pre>
werckmeister_v_ar :: [Approximate_Ratio]

-- | Cents for <a>werckmeister_v</a>.
werckmeister_v_c :: [Cents]

-- | Werckmeister V, Andreas Werckmeister (1645-1706)
--   
--   <pre>
--   cents_i werckmeister_v == [0,96,204,300,396,504,600,702,792,900,1002,1098]
--   </pre>
werckmeister_v :: Tuning

-- | Ratios for <a>werckmeister_vi</a>.
--   
--   <pre>
--   let c = [0,91,196,298,395,498,595,698,793,893,1000,1097]
--   in map (round . ratio_to_cents) werckmeister_vi_r == c
--   </pre>
werckmeister_vi_r :: [Rational]

-- | Werckmeister VI, Andreas Werckmeister (1645-1706)
--   
--   <pre>
--   cents_i werckmeister_vi == [0,91,196,298,395,498,595,698,793,893,1000,1097]
--   </pre>
werckmeister_vi :: Tuning


-- | Common music notation dynamic marks.
module Music.Theory.Dynamic_Mark

-- | Enumeration of dynamic mark symbols.
data Dynamic_Mark_T
Niente :: Dynamic_Mark_T
PPPPP :: Dynamic_Mark_T
PPPP :: Dynamic_Mark_T
PPP :: Dynamic_Mark_T
PP :: Dynamic_Mark_T
P :: Dynamic_Mark_T
MP :: Dynamic_Mark_T
MF :: Dynamic_Mark_T
F :: Dynamic_Mark_T
FF :: Dynamic_Mark_T
FFF :: Dynamic_Mark_T
FFFF :: Dynamic_Mark_T
FFFFF :: Dynamic_Mark_T
FP :: Dynamic_Mark_T
SF :: Dynamic_Mark_T
SFP :: Dynamic_Mark_T
SFPP :: Dynamic_Mark_T
SFZ :: Dynamic_Mark_T
SFFZ :: Dynamic_Mark_T

-- | Lookup MIDI velocity for <a>Dynamic_Mark_T</a>. The range is linear in
--   <tt>0-127</tt>.
--   
--   <pre>
--   let r = [0,6,17,28,39,50,61,72,83,94,105,116,127]
--   in mapMaybe dynamic_mark_midi [Niente .. FFFFF] == r
--   </pre>
--   
--   <pre>
--   map dynamic_mark_midi [FP,SF,SFP,SFPP,SFZ,SFFZ] == replicate 6 Nothing
--   </pre>
dynamic_mark_midi :: (Num n, Enum n) => Dynamic_Mark_T -> Maybe n

-- | Error variant.
dynamic_mark_midi_err :: Integral n => Dynamic_Mark_T -> n

-- | Map midi velocity (0-127) to dynamic mark.
--   
--   <pre>
--   histogram (mapMaybe midi_dynamic_mark [0 .. 127])
--   </pre>
midi_dynamic_mark :: (Ord n, Eq n, Num n, Enum n) => n -> Maybe Dynamic_Mark_T

-- | Translate <i>fixed</i> <a>Dynamic_Mark_T</a>s to <i>db</i> amplitude
--   over given <i>range</i>.
--   
--   <pre>
--   mapMaybe (dynamic_mark_db 120) [Niente,P,F,FFFFF] == [-120,-70,-40,0]
--   mapMaybe (dynamic_mark_db 60) [Niente,P,F,FFFFF] == [-60,-35,-20,0]
--   </pre>
dynamic_mark_db :: Fractional n => n -> Dynamic_Mark_T -> Maybe n

-- | <a>http://www.csounds.com/manual/html/ampmidid.html</a>
--   
--   <pre>
--   import Sound.SC3.Plot
--   plotTable [map (ampmidid 20) [0 .. 127],map (ampmidid 60) [0 .. 127]]
--   </pre>
ampmidid :: Floating a => a -> a -> a

-- | JMcC (SC3) equation.
--   
--   <pre>
--   plotTable1 (map amp_db [0,0.005 .. 1])
--   </pre>
amp_db :: Floating a => a -> a

-- | JMcC (SC3) equation.
--   
--   <pre>
--   plotTable1 (map db_amp [-60,-59 .. 0])
--   </pre>
db_amp :: Floating a => a -> a

-- | Enumeration of hairpin indicators.
data Hairpin_T
Crescendo :: Hairpin_T
Diminuendo :: Hairpin_T
End_Hairpin :: Hairpin_T

-- | The <a>Hairpin_T</a> implied by a ordered pair of
--   <a>Dynamic_Mark_T</a>s.
--   
--   <pre>
--   map (implied_hairpin MF) [MP,F] == [Just Diminuendo,Just Crescendo]
--   </pre>
implied_hairpin :: Dynamic_Mark_T -> Dynamic_Mark_T -> Maybe Hairpin_T

-- | A node in a dynamic sequence.
type Dynamic_Node = (Maybe Dynamic_Mark_T, Maybe Hairpin_T)

-- | The empty <a>Dynamic_Node</a>.
empty_dynamic_node :: Dynamic_Node

-- | Calculate a <a>Dynamic_Node</a> sequence from a sequence of
--   <a>Dynamic_Mark_T</a>s.
--   
--   <pre>
--   dynamic_sequence [PP,MP,MP,PP] == [(Just PP,Just Crescendo)
--                                     ,(Just MP,Just End_Hairpin)
--                                     ,(Nothing,Just Diminuendo)
--                                     ,(Just PP,Just End_Hairpin)]
--   </pre>
dynamic_sequence :: [Dynamic_Mark_T] -> [Dynamic_Node]

-- | Delete redundant (unaltered) dynamic marks.
--   
--   <pre>
--   let s = [Just P,Nothing,Just P,Just P,Just F]
--   in delete_redundant_marks s == [Just P,Nothing,Nothing,Nothing,Just F]
--   </pre>
delete_redundant_marks :: [Maybe Dynamic_Mark_T] -> [Maybe Dynamic_Mark_T]

-- | Variant of <a>dynamic_sequence</a> for sequences of
--   <a>Dynamic_Mark_T</a> with holes (ie. rests). Runs
--   <a>delete_redundant_marks</a>.
--   
--   <pre>
--   let r = [Just (Just P,Just Crescendo),Just (Just F,Just End_Hairpin)
--           ,Nothing,Just (Just P,Nothing)]
--   in dynamic_sequence_sets [Just P,Just F,Nothing,Just P] == r
--   </pre>
--   
--   <pre>
--   let s = [Just P,Nothing,Just P]
--   in dynamic_sequence_sets s = [Just (Just P,Nothing),Nothing,Nothing]
--   </pre>
dynamic_sequence_sets :: [Maybe Dynamic_Mark_T] -> [Maybe Dynamic_Node]

-- | Apply <a>Hairpin_T</a> and <a>Dynamic_Mark_T</a> functions in that
--   order as required by <a>Dynamic_Node</a>.
--   
--   <pre>
--   let f _ x = show x
--   in apply_dynamic_node f f (Nothing,Just Crescendo) undefined
--   </pre>
apply_dynamic_node :: (a -> Dynamic_Mark_T -> a) -> (a -> Hairpin_T -> a) -> Dynamic_Node -> a -> a

-- | ASCII pretty printer for <a>Dynamic_Mark_T</a>.
dynamic_mark_ascii :: Dynamic_Mark_T -> String

-- | ASCII pretty printer for <a>Hairpin_T</a>.
hairpin_ascii :: Hairpin_T -> String

-- | ASCII pretty printer for <a>Dynamic_Node</a>.
dynamic_node_ascii :: Dynamic_Node -> String

-- | ASCII pretty printer for <a>Dynamic_Node</a> sequence.
dynamic_sequence_ascii :: [Dynamic_Node] -> String
instance GHC.Show.Show Music.Theory.Dynamic_Mark.Hairpin_T
instance GHC.Enum.Bounded Music.Theory.Dynamic_Mark.Hairpin_T
instance GHC.Enum.Enum Music.Theory.Dynamic_Mark.Hairpin_T
instance GHC.Classes.Ord Music.Theory.Dynamic_Mark.Hairpin_T
instance GHC.Classes.Eq Music.Theory.Dynamic_Mark.Hairpin_T
instance GHC.Show.Show Music.Theory.Dynamic_Mark.Dynamic_Mark_T
instance GHC.Enum.Bounded Music.Theory.Dynamic_Mark.Dynamic_Mark_T
instance GHC.Enum.Enum Music.Theory.Dynamic_Mark.Dynamic_Mark_T
instance GHC.Classes.Ord Music.Theory.Dynamic_Mark.Dynamic_Mark_T
instance GHC.Classes.Eq Music.Theory.Dynamic_Mark.Dynamic_Mark_T


-- | Common music notation duration model.
module Music.Theory.Duration

-- | Common music notation durational model
data Duration
Duration :: Integer -> Integer -> Rational -> Duration

-- | division of whole note
[division] :: Duration -> Integer

-- | number of dots
[dots] :: Duration -> Integer

-- | tuplet modifier
[multiplier] :: Duration -> Rational

-- | Are multipliers equal?
duration_meq :: Duration -> Duration -> Bool

-- | Compare durations with equal multipliers.
duration_compare_meq :: Duration -> Duration -> Maybe Ordering

-- | Erroring variant of <a>duration_compare_meq</a>.
duration_compare_meq_err :: Duration -> Duration -> Ordering

-- | <a>Ord</a> instance in terms of <a>duration_compare_meq_err</a>.
order_pair :: Ordering -> (t, t) -> (t, t)

-- | Sort a pair of equal type values using given comparison function.
--   
--   <pre>
--   sort_pair compare ('b','a') == ('a','b')
--   </pre>
sort_pair :: (t -> t -> Ordering) -> (t, t) -> (t, t)
sort_pair_m :: (t -> t -> Maybe Ordering) -> (t, t) -> Maybe (t, t)

-- | True if neither duration is dotted.
no_dots :: (Duration, Duration) -> Bool

-- | Sum undotted divisions, input is required to be sorted.
sum_dur_undotted :: (Integer, Integer) -> Maybe Duration

-- | Sum dotted divisions, input is required to be sorted.
--   
--   <pre>
--   sum_dur_dotted (4,1,4,1) == Just (Duration 2 1 1)
--   sum_dur_dotted (4,0,2,1) == Just (Duration 1 0 1)
--   sum_dur_dotted (8,1,4,0) == Just (Duration 4 2 1)
--   sum_dur_dotted (16,0,4,2) == Just (Duration 2 0 1)
--   </pre>
sum_dur_dotted :: (Integer, Integer, Integer, Integer) -> Maybe Duration

-- | Sum durations. Not all durations can be summed, and the present
--   algorithm is not exhaustive.
--   
--   <pre>
--   import Music.Theory.Duration.Name
--   sum_dur quarter_note eighth_note == Just dotted_quarter_note
--   sum_dur dotted_quarter_note eighth_note == Just half_note
--   sum_dur quarter_note dotted_eighth_note == Just double_dotted_quarter_note
--   </pre>
sum_dur :: Duration -> Duration -> Maybe Duration

-- | Erroring variant of <a>sum_dur</a>.
sum_dur' :: Duration -> Duration -> Duration

-- | Give <tt>MusicXML</tt> type for division.
--   
--   <pre>
--   map whole_note_division_to_musicxml_type [2,4] == ["half","quarter"]
--   </pre>
whole_note_division_to_musicxml_type :: Integer -> String

-- | Variant of <a>whole_note_division_to_musicxml_type</a> extracting
--   <a>division</a> from <a>Duration</a>.
--   
--   <pre>
--   duration_to_musicxml_type quarter_note == "quarter"
--   </pre>
duration_to_musicxml_type :: Duration -> String

-- | Give <i>Lilypond</i> notation for <a>Duration</a>. Note that the
--   duration multiplier is <i>not</i> written.
--   
--   <pre>
--   import Music.Theory.Duration.Name
--   map duration_to_lilypond_type [half_note,dotted_quarter_note] == ["2","4."]
--   </pre>
duration_to_lilypond_type :: Duration -> String

-- | Calculate number of beams at notated division.
--   
--   <pre>
--   whole_note_division_to_beam_count 32 == Just 3
--   </pre>
whole_note_division_to_beam_count :: Integer -> Maybe Integer

-- | Calculate number of beams at <a>Duration</a>.
--   
--   <pre>
--   map duration_beam_count [half_note,sixteenth_note] == [0,2]
--   </pre>
duration_beam_count :: Duration -> Integer
whole_note_division_pp :: Integer -> Maybe Char
duration_pp :: Duration -> Maybe String

-- | Duration to <tt>**recip</tt> notation.
--   
--   <a>http://humdrum.org/Humdrum/representations/recip.rep.html</a>
--   
--   <pre>
--   let d = map (\z -&gt; Duration z 0 1) [0,1,2,4,8,16,32]
--   in map duration_recip_pp d == ["0","1","2","4","8","16","32"]
--   </pre>
--   
--   <pre>
--   let d = [Duration 1 1 (1/3),Duration 4 1 1,Duration 4 1 (2/3)]
--   in map duration_recip_pp d == ["3.","4.","6."]
--   </pre>
duration_recip_pp :: Duration -> String
instance GHC.Show.Show Music.Theory.Duration.Duration
instance GHC.Classes.Eq Music.Theory.Duration.Duration
instance GHC.Classes.Ord Music.Theory.Duration.Duration


-- | Names for common music notation durations.
module Music.Theory.Duration.Name
breve :: Duration
whole_note :: Duration
half_note :: Duration
quarter_note :: Duration
eighth_note :: Duration
sixteenth_note :: Duration
thirtysecond_note :: Duration
dotted_breve :: Duration
dotted_whole_note :: Duration
dotted_half_note :: Duration
dotted_quarter_note :: Duration
dotted_eighth_note :: Duration
dotted_sixteenth_note :: Duration
dotted_thirtysecond_note :: Duration
double_dotted_breve :: Duration
double_dotted_whole_note :: Duration
double_dotted_half_note :: Duration
double_dotted_quarter_note :: Duration
double_dotted_eighth_note :: Duration
double_dotted_sixteenth_note :: Duration
double_dotted_thirtysecond_note :: Duration


-- | Abbreviated names for <a>Duration</a> values when written as literals.
--   There are <i>letter</i> names where <a>w</a> is <a>whole_note</a> and
--   so on, and <i>numerical</i> names where <a>_4</a> is
--   <a>quarter_note</a> and so on. In both cases a <tt>'</tt> extension
--   means a <tt>dot</tt> so that <a>e''</a> is a double dotted
--   <a>eighth_note</a>.
--   
--   <pre>
--   zipWith duration_compare_meq [e,e,e,e'] [e,s,q,e] == [EQ,GT,LT,GT]
--   zipWith sum_dur [e,q,q'] [e,e,e] == [Just q,Just q',Just h]
--   zipWith sum_dur' [e,q,q'] [e,e,e] == [q,q',h]
--   </pre>
module Music.Theory.Duration.Name.Abbreviation
w :: Duration
h :: Duration
q :: Duration
e :: Duration
s :: Duration
w' :: Duration
h' :: Duration
q' :: Duration
e' :: Duration
s' :: Duration
w'' :: Duration
h'' :: Duration
q'' :: Duration
e'' :: Duration
s'' :: Duration
_1 :: Duration
_2 :: Duration
_4 :: Duration
_8 :: Duration
_16 :: Duration
_32 :: Duration
_1' :: Duration
_2' :: Duration
_4' :: Duration
_8' :: Duration
_16' :: Duration
_32' :: Duration
_1'' :: Duration
_2'' :: Duration
_4'' :: Duration
_8'' :: Duration
_16'' :: Duration
_32'' :: Duration


-- | Rational quarter-note notation for durations.
module Music.Theory.Duration.RQ

-- | Rational Quarter-Note
type RQ = Rational

-- | Rational quarter note to duration value. It is a mistake to hope this
--   could handle tuplets directly since, for instance, a <tt>3:2</tt>
--   dotted note will be of the same duration as a plain undotted note.
--   
--   <pre>
--   rq_to_duration (3/4) == Just dotted_eighth_note
--   </pre>
rq_to_duration :: RQ -> Maybe Duration

-- | Is <a>RQ</a> a <i>cmn</i> duration.
--   
--   <pre>
--   map rq_is_cmn [1/4,1/5,1/8,3/32] == [True,False,True,False]
--   </pre>
rq_is_cmn :: RQ -> Bool

-- | Variant of <a>rq_to_duration</a> with error message.
rq_to_duration_err :: Show a => a -> RQ -> Duration

-- | Convert a whole note division integer to an <a>RQ</a> value.
--   
--   <pre>
--   map whole_note_division_to_rq [1,2,4,8] == [4,2,1,1/2]
--   </pre>
whole_note_division_to_rq :: Integer -> RQ

-- | Apply dots to an <a>RQ</a> duration.
--   
--   <pre>
--   map (rq_apply_dots 1) [1,2] == [3/2,7/4]
--   </pre>
rq_apply_dots :: RQ -> Integer -> RQ

-- | Convert <a>Duration</a> to <a>RQ</a> value, see <a>rq_to_duration</a>
--   for partial inverse.
--   
--   <pre>
--   let d = [half_note,dotted_quarter_note,dotted_whole_note]
--   in map duration_to_rq d == [2,3/2,6]
--   </pre>
duration_to_rq :: Duration -> RQ

-- | <a>compare</a> function for <a>Duration</a> via <a>duration_to_rq</a>.
--   
--   <pre>
--   half_note `duration_compare_rq` quarter_note == GT
--   </pre>
duration_compare_rq :: Duration -> Duration -> Ordering

-- | <a>RQ</a> modulo.
--   
--   <pre>
--   map (rq_mod (5/2)) [3/2,3/4,5/2] == [1,1/4,0]
--   </pre>
rq_mod :: RQ -> RQ -> RQ

-- | Is <i>p</i> divisible by <i>q</i>, ie. is the <a>denominator</a> of
--   <tt>p/q</tt> <a>==</a> <tt>1</tt>.
--   
--   <pre>
--   map (rq_divisible_by (3%2)) [1%2,1%3] == [True,False]
--   </pre>
rq_divisible_by :: RQ -> RQ -> Bool

-- | Is <a>RQ</a> a whole number (ie. is <a>denominator</a> <a>==</a>
--   <tt>1</tt>.
--   
--   <pre>
--   map rq_is_integral [1,3/2,2] == [True,False,True]
--   </pre>
rq_is_integral :: RQ -> Bool

-- | Return <a>numerator</a> of <a>RQ</a> if <a>denominator</a> <a>==</a>
--   <tt>1</tt>.
--   
--   <pre>
--   map rq_integral [1,3/2,2] == [Just 1,Nothing,Just 2]
--   </pre>
rq_integral :: RQ -> Maybe Integer

-- | Derive the tuplet structure of a set of <a>RQ</a> values.
--   
--   <pre>
--   rq_derive_tuplet_plain [1/2] == Nothing
--   rq_derive_tuplet_plain [1/2,1/2] == Nothing
--   rq_derive_tuplet_plain [1/4,1/4] == Nothing
--   rq_derive_tuplet_plain [1/3,2/3] == Just (3,2)
--   rq_derive_tuplet_plain [1/2,1/3,1/6] == Just (6,4)
--   rq_derive_tuplet_plain [1/3,1/6] == Just (6,4)
--   rq_derive_tuplet_plain [2/5,3/5] == Just (5,4)
--   rq_derive_tuplet_plain [1/3,1/6,2/5,1/10] == Just (30,16)
--   </pre>
--   
--   <pre>
--   map rq_derive_tuplet_plain [[1/3,1/6],[2/5,1/10]] == [Just (6,4)
--                                                        ,Just (10,8)]
--   </pre>
rq_derive_tuplet_plain :: [RQ] -> Maybe (Integer, Integer)

-- | Derive the tuplet structure of a set of <a>RQ</a> values.
--   
--   <pre>
--   rq_derive_tuplet [1/4,1/8,1/8] == Nothing
--   rq_derive_tuplet [1/3,2/3] == Just (3,2)
--   rq_derive_tuplet [1/2,1/3,1/6] == Just (3,2)
--   rq_derive_tuplet [2/5,3/5] == Just (5,4)
--   rq_derive_tuplet [1/3,1/6,2/5,1/10] == Just (15,8)
--   </pre>
rq_derive_tuplet :: [RQ] -> Maybe (Integer, Integer)

-- | Remove tuplet multiplier from value, ie. to give notated duration.
--   This seems odd but is neccessary to avoid ambiguity. Ie. is <tt>1</tt>
--   a quarter note or a <tt>3:2</tt> tuplet dotted-quarter-note etc.
--   
--   <pre>
--   map (rq_un_tuplet (3,2)) [1,2/3,1/2,1/3] == [3/2,1,3/4,1/2]
--   </pre>
rq_un_tuplet :: (Integer, Integer) -> RQ -> RQ

-- | If an <a>RQ</a> duration is un-representable by a single <i>cmn</i>
--   duration, give tied notation.
--   
--   <pre>
--   catMaybes (map rq_to_cmn [1..9]) == [(4,1),(4,3),(8,1)]
--   </pre>
--   
--   <pre>
--   map rq_to_cmn [5/4,5/8] == [Just (1,1/4),Just (1/2,1/8)]
--   </pre>
rq_to_cmn :: RQ -> Maybe (RQ, RQ)

-- | Predicate to determine if a segment can be notated either without a
--   tuplet or with a single tuplet.
--   
--   <pre>
--   rq_can_notate [1/2,1/4,1/4] == True
--   rq_can_notate [1/3,1/6] == True
--   rq_can_notate [2/5,1/10] == True
--   rq_can_notate [1/3,1/6,2/5,1/10] == False
--   rq_can_notate [4/7,1/7,6/7,3/7] == True
--   rq_can_notate [4/7,1/7,2/7] == True
--   </pre>
rq_can_notate :: [RQ] -> Bool


-- | Duration annotations.
module Music.Theory.Duration.Annotation

-- | Standard music notation durational model annotations
data D_Annotation
Tie_Right :: D_Annotation
Tie_Left :: D_Annotation
Begin_Tuplet :: (Integer, Integer, Duration) -> D_Annotation
End_Tuplet :: D_Annotation

-- | Annotated <a>Duration</a>.
type Duration_A = (Duration, [D_Annotation])
begin_tuplet :: D_Annotation -> Maybe (Integer, Integer, Duration)
da_begin_tuplet :: Duration_A -> Maybe (Integer, Integer, Duration)
begins_tuplet :: D_Annotation -> Bool

-- | Does <a>Duration_A</a> begin a tuplet?
da_begins_tuplet :: Duration_A -> Bool

-- | Does <a>Duration_A</a> end a tuplet?
da_ends_tuplet :: Duration_A -> Bool

-- | Is <a>Duration_A</a> tied to the the right?
da_tied_right :: Duration_A -> Bool

-- | Annotate a sequence of <a>Duration_A</a> as a tuplet.
--   
--   <pre>
--   import Music.Theory.Duration.Name
--   da_tuplet (3,2) [(quarter_note,[Tie_Left]),(eighth_note,[Tie_Right])]
--   </pre>
da_tuplet :: (Integer, Integer) -> [Duration_A] -> [Duration_A]

-- | Transform predicates into <a>Ordering</a> predicate such that if
--   <i>f</i> holds then <a>LT</a>, if <i>g</i> holds then <a>GT</a> else
--   <a>EQ</a>.
--   
--   <pre>
--   map (begin_end_cmp (== '{') (== '}')) "{a}" == [LT,EQ,GT]
--   </pre>
begin_end_cmp :: (t -> Bool) -> (t -> Bool) -> t -> Ordering

-- | Variant of <a>begin_end_cmp</a>, predicates are constructed by
--   <a>==</a>.
--   
--   <pre>
--   map (begin_end_cmp_eq '{' '}') "{a}" == [LT,EQ,GT]
--   </pre>
begin_end_cmp_eq :: Eq t => t -> t -> t -> Ordering

-- | Given an <a>Ordering</a> predicate where <a>LT</a> opens a group,
--   <a>GT</a> closes a group, and <a>EQ</a> continues current group,
--   construct tree from list.
--   
--   <pre>
--   let {l = "a {b {c d} e f} g h i"
--       ;t = group_tree (begin_end_cmp_eq '{' '}') l}
--   in catMaybes (flatten t) == l
--   </pre>
--   
--   <pre>
--   let d = putStrLn . drawTree . fmap show
--   in d (group_tree (begin_end_cmp_eq '(' ')') "a(b(cd)ef)ghi")
--   </pre>
group_tree :: (a -> Ordering) -> [a] -> Tree (Maybe a)

-- | Group tuplets into a <a>Tree</a>. Branch nodes have label
--   <a>Nothing</a>, leaf nodes label <a>Just</a> <a>Duration_A</a>.
--   
--   <pre>
--   import Music.Theory.Duration.Name.Abbreviation
--   </pre>
--   
--   <pre>
--   let d = [(q,[])
--           ,(e,[Begin_Tuplet (3,2,e)])
--           ,(s,[Begin_Tuplet (3,2,s)]),(s,[]),(s,[End_Tuplet])
--           ,(e,[End_Tuplet])
--           ,(q,[])]
--   in catMaybes (flatten (da_group_tuplets d)) == d
--   </pre>
da_group_tuplets :: [Duration_A] -> Tree (Maybe Duration_A)

-- | Variant of <a>break</a> that places separator at left.
--   
--   <pre>
--   break_left (== 3) [1..6] == ([1..3],[4..6])
--   break_left (== 3) [1..3] == ([1..3],[])
--   </pre>
break_left :: (a -> Bool) -> [a] -> ([a], [a])

-- | Variant of <a>break_left</a> that balances begin &amp; end predicates.
--   
--   <pre>
--   break_left (== ')') "test (sep) _) balanced"
--   sep_balanced True (== '(') (== ')') "test (sep) _) balanced"
--   sep_balanced False (== '(') (== ')') "(test (sep) _) balanced"
--   </pre>
sep_balanced :: Bool -> (a -> Bool) -> (a -> Bool) -> [a] -> ([a], [a])

-- | Group non-nested tuplets, ie. groups nested tuplets at one level.
da_group_tuplets_nn :: [Duration_A] -> [Either Duration_A [Duration_A]]

-- | Keep right variant of <a>zipWith</a>, unused rhs values are returned.
--   
--   <pre>
--   zip_with_kr (,) [1..3] ['a'..'e'] == ([(1,'a'),(2,'b'),(3,'c')],"de")
--   </pre>
zip_with_kr :: (a -> b -> c) -> [a] -> [b] -> ([c], [b])

-- | Keep right variant of <a>zip</a>, unused rhs values are returned.
--   
--   <pre>
--   zip_kr [1..4] ['a'..'f'] == ([(1,'a'),(2,'b'),(3,'c'),(4,'d')],"ef")
--   </pre>
zip_kr :: [a] -> [b] -> ([(a, b)], [b])

-- | <a>zipWith</a> variant that adopts the shape of the lhs.
--   
--   <pre>
--   let {p = [Left 1,Right [2,3],Left 4]
--       ;q = "abcd"}
--   in nn_reshape (,) p q == [Left (1,'a'),Right [(2,'b'),(3,'c')],Left (4,'d')]
--   </pre>
nn_reshape :: (a -> b -> c) -> [Either a [a]] -> [b] -> [Either c [c]]

-- | Replace elements at <a>Traversable</a> with result of joining with
--   elements from list.
adopt_shape :: Traversable t => (a -> b -> c) -> [b] -> t a -> t c

-- | Variant of <a>adopt_shape</a> that considers only <a>Just</a> elements
--   at <a>Traversable</a>.
--   
--   <pre>
--   let {s = "a(b(cd)ef)ghi"
--       ;t = group_tree (begin_end_cmp_eq '(' ')') s}
--   in adopt_shape_m (,) [1..13] t
--   </pre>
adopt_shape_m :: Traversable t => (a -> b -> c) -> [b] -> t (Maybe a) -> t (Maybe c)

-- | Does <i>a</i> have <a>Tie_Left</a> and <a>Tie_Right</a>?
d_annotated_tied_lr :: [D_Annotation] -> (Bool, Bool)

-- | Does <i>d</i> have <a>Tie_Left</a> and <a>Tie_Right</a>?
duration_a_tied_lr :: Duration_A -> (Bool, Bool)
instance GHC.Show.Show Music.Theory.Duration.Annotation.D_Annotation
instance GHC.Classes.Eq Music.Theory.Duration.Annotation.D_Annotation


-- | <a>RQ</a> values with <i>tie right</i> qualifier.
module Music.Theory.Duration.RQ.Tied

-- | Boolean.
type Tied_Right = Bool

-- | <a>RQ</a> with <i>tie right</i>.
type RQ_T = (RQ, Tied_Right)

-- | Construct <a>RQ_T</a>.
rqt :: Tied_Right -> RQ -> RQ_T

-- | <a>RQ</a> field of <a>RQ_T</a>.
rqt_rq :: RQ_T -> RQ

-- | <tt>Tied</tt> field of <a>RQ_T</a>.
rqt_tied :: RQ_T -> Tied_Right

-- | Is <a>RQ_T</a> tied right.
is_tied_right :: RQ_T -> Bool

-- | <a>RQ_T</a> variant of <a>rq_un_tuplet</a>.
--   
--   <pre>
--   rqt_un_tuplet (3,2) (1,T) == (3/2,T)
--   </pre>
--   
--   <pre>
--   let f = rqt_un_tuplet (7,4)
--   in map f [(2/7,F),(4/7,T),(1/7,F)] == [(1/2,F),(1,T),(1/4,F)]
--   </pre>
rqt_un_tuplet :: (Integer, Integer) -> RQ_T -> RQ_T

-- | Transform <a>RQ</a> to untied <a>RQ_T</a>.
--   
--   <pre>
--   rq_rqt 3 == (3,F)
--   </pre>
rq_rqt :: RQ -> RQ_T

-- | Tie last element only of list of <a>RQ</a>.
--   
--   <pre>
--   rq_tie_last [1,2,3] == [(1,F),(2,F),(3,T)]
--   </pre>
rq_tie_last :: [RQ] -> [RQ_T]

-- | Transform a list of <a>RQ_T</a> to a list of <a>Duration_A</a>. The
--   flag indicates if the initial value is tied left.
--   
--   <pre>
--   rqt_to_duration_a False [(1,T),(1/4,T),(3/4,F)]
--   </pre>
rqt_to_duration_a :: Bool -> [RQ_T] -> [Duration_A]

-- | <a>RQ_T</a> variant of <a>rq_can_notate</a>.
rqt_can_notate :: [RQ_T] -> Bool

-- | <a>RQ_T</a> variant of <a>rq_to_cmn</a>.
--   
--   <pre>
--   rqt_to_cmn (5,T) == Just ((4,T),(1,T))
--   rqt_to_cmn (5/4,T) == Just ((1,T),(1/4,T))
--   rqt_to_cmn (5/7,F) == Just ((4/7,T),(1/7,F))
--   </pre>
rqt_to_cmn :: RQ_T -> Maybe (RQ_T, RQ_T)

-- | List variant of <a>rqt_to_cmn</a>.
--   
--   <pre>
--   rqt_to_cmn_l (5,T) == [(4,T),(1,T)]
--   </pre>
rqt_to_cmn_l :: RQ_T -> [RQ_T]

-- | <a>concatMap</a> <a>rqt_to_cmn_l</a>.
--   
--   <pre>
--   rqt_set_to_cmn [(1,T),(5/4,F)] == [(1,T),(1,T),(1/4,F)]
--   </pre>
--   
--   <pre>
--   rqt_set_to_cmn [(1/5,True),(1/20,False),(1/2,False),(1/4,True)]
--   </pre>
rqt_set_to_cmn :: [RQ_T] -> [RQ_T]


-- | <a>RQ</a> sub-divisions.
module Music.Theory.Duration.RQ.Division

-- | Divisions of <i>n</i> <a>RQ</a> into <i>i</i> equal parts grouped as
--   <i>j</i>. A quarter and eighth note triplet is written
--   <tt>(1,1,[2,1],False)</tt>.
type RQ_Div = (Rational, Integer, [Integer], Tied_Right)

-- | Variant of <a>RQ_Div</a> where <i>n</i> is <tt>1</tt>.
type RQ1_Div = (Integer, [Integer], Tied_Right)

-- | Lift <a>RQ1_Div</a> to <a>RQ_Div</a>.
rq1_div_to_rq_div :: RQ1_Div -> RQ_Div

-- | Verify that grouping <i>j</i> sums to the divisor <i>i</i>.
rq_div_verify :: RQ_Div -> Bool
rq_div_mm_verify :: Int -> [RQ_Div] -> [(Integer, [RQ])]

-- | Translate from <a>RQ_Div</a> to a sequence of <a>RQ</a> values.
--   
--   <pre>
--   rq_div_to_rq_set_t (1,5,[1,3,1],True) == ([1/5,3/5,1/5],True)
--   rq_div_to_rq_set_t (1/2,6,[3,1,2],False) == ([1/4,1/12,1/6],False)
--   </pre>
rq_div_to_rq_set_t :: RQ_Div -> ([RQ], Tied_Right)

-- | Translate from result of <a>rq_div_to_rq_set_t</a> to seqeunce of
--   <a>RQ_T</a>.
--   
--   <pre>
--   rq_set_t_to_rqt ([1/5,3/5,1/5],True) == [(1/5,_f),(3/5,_f),(1/5,_t)]
--   </pre>
rq_set_t_to_rqt :: ([RQ], Tied_Right) -> [RQ_T]

-- | Transform sequence of <a>RQ_Div</a> into sequence of <a>RQ</a>,
--   discarding any final tie.
--   
--   <pre>
--   let q = [(1,5,[1,3,1],True),(1/2,6,[3,1,2],True)]
--   in rq_div_seq_rq q == [1/5,3/5,9/20,1/12,1/6]
--   </pre>
rq_div_seq_rq :: [RQ_Div] -> [RQ]

-- | Partitions of an <a>Integral</a> that sum to <i>n</i>. This includes
--   the two 'trivial paritions, into a set <i>n</i> <tt>1</tt>, and a set
--   of <tt>1</tt> <i>n</i>.
--   
--   <pre>
--   partitions_sum 4 == [[1,1,1,1],[2,1,1],[2,2],[3,1],[4]]
--   </pre>
--   
--   <pre>
--   map (length . partitions_sum) [9..15] == [30,42,56,77,101,135,176]
--   </pre>
partitions_sum :: Integral i => i -> [[i]]

-- | The <a>multiset_permutations</a> of <a>partitions_sum</a>.
--   
--   <pre>
--   map (length . partitions_sum_p) [9..12] == [256,512,1024,2048]
--   </pre>
partitions_sum_p :: Integral i => i -> [[i]]

-- | The set of all <a>RQ1_Div</a> that sum to <i>n</i>, a variant on
--   <a>partitions_sum_p</a>.
--   
--   <pre>
--   map (length . rq1_div_univ) [3..5] == [8,16,32]
--   map (length . rq1_div_univ) [9..12] == [512,1024,2048,4096]
--   </pre>
rq1_div_univ :: Integer -> [RQ1_Div]


-- | Time Signatures.
module Music.Theory.Time_Signature

-- | A Time Signature is a <i>(numerator,denominator)</i> pair.
type Time_Signature = (Integer, Integer)

-- | Tied, non-multiplied durations to fill a whole measure.
--   
--   <pre>
--   ts_whole_note (3,8) == [dotted_quarter_note]
--   ts_whole_note (2,2) == [whole_note]
--   </pre>
ts_whole_note :: Time_Signature -> [Duration]

-- | Duration of measure in <a>RQ</a>.
--   
--   <pre>
--   map ts_whole_note_rq [(3,8),(2,2)] == [3/2,4]
--   </pre>
ts_whole_note_rq :: Time_Signature -> RQ

-- | Duration, in <a>RQ</a>, of a measure of indicated
--   <a>Time_Signature</a>.
--   
--   <pre>
--   map ts_rq [(3,4),(5,8)] == [3,5/2]
--   </pre>
ts_rq :: Time_Signature -> RQ

-- | <a>Time_Signature</a> derived from whole note duration in <a>RQ</a>
--   form.
--   
--   <pre>
--   map rq_to_ts [4,3/2,7/4,6] == [(4,4),(3,8),(7,16),(6,4)]
--   </pre>
rq_to_ts :: Rational -> Time_Signature

-- | Uniform division of time signature.
--   
--   <pre>
--   ts_divisions (3,4) == [1,1,1]
--   ts_divisions (3,8) == [1/2,1/2,1/2]
--   ts_divisions (2,2) == [2,2]
--   ts_divisions (1,1) == [4]
--   </pre>
ts_divisions :: Time_Signature -> [RQ]

-- | Convert a duration to a pulse count in relation to the indicated time
--   signature.
--   
--   <pre>
--   ts_duration_pulses (3,8) quarter_note == 2
--   </pre>
ts_duration_pulses :: Time_Signature -> Duration -> Rational

-- | Rewrite time signature to indicated denominator.
--   
--   <pre>
--   ts_rewrite 8 (3,4) == (6,8)
--   </pre>
ts_rewrite :: Integer -> Time_Signature -> Time_Signature

-- | Sum time signatures.
--   
--   <pre>
--   ts_sum [(3,16),(1,2)] == (11,16)
--   </pre>
ts_sum :: [Time_Signature] -> Time_Signature

-- | A composite time signature is a sequence of <a>Time_Signature</a>s.
type Composite_Time_Signature = [Time_Signature]

-- | The <a>RQ</a> is the <a>sum</a> of <a>ts_rq</a> of the elements.
--   
--   <pre>
--   cts_rq [(3,4),(1,8)] == 3 + 1/2
--   </pre>
cts_rq :: Composite_Time_Signature -> RQ

-- | The divisions are the <a>concat</a> of the <a>ts_divisions</a> of the
--   elements.
--   
--   <pre>
--   cts_divisions [(3,4),(1,8)] == [1,1,1,1/2]
--   </pre>
cts_divisions :: Composite_Time_Signature -> [RQ]

-- | Pulses are 1-indexed, RQ locations are 0-indexed.
--   
--   <pre>
--   map (cts_pulse_to_rq [(2,4),(1,8),(1,4)]) [1 .. 4] == [0,1,2,2 + 1/2]
--   </pre>
cts_pulse_to_rq :: Composite_Time_Signature -> Int -> RQ

-- | Variant that gives the <i>window</i> of the pulse (ie. the start
--   location and the duration).
--   
--   <pre>
--   let r = [(0,1),(1,1),(2,1/2),(2 + 1/2,1)]
--   in map (cts_pulse_to_rqw [(2,4),(1,8),(1,4)]) [1 .. 4] == r
--   </pre>
cts_pulse_to_rqw :: Composite_Time_Signature -> Int -> (RQ, RQ)

-- | A rational time signature is a <a>Composite_Time_Signature</a> where
--   the parts are <a>Rational</a>.
type Rational_Time_Signature = [(Rational, Rational)]

-- | The <a>sum</a> of the RQ of the elements.
--   
--   <pre>
--   rts_rq [(3,4),(1,8)] == 3 + 1/2
--   rts_rq [(3/2,4),(1/2,8)] == 3/2 + 1/4
--   </pre>
rts_rq :: Rational_Time_Signature -> RQ

-- | The <i>divisions</i> of the elements.
--   
--   <pre>
--   rts_divisions [(3,4),(1,8)] == [1,1,1,1/2]
--   rts_divisions [(3/2,4),(1/2,8)] == [1,1/2,1/4]
--   </pre>
rts_divisions :: Rational_Time_Signature -> [[RQ]]
rts_derive :: [RQ] -> Rational_Time_Signature

-- | Pulses are 1-indexed, RQ locations are 0-indexed.
--   
--   <pre>
--   map (rts_pulse_to_rq [(2,4),(1,8),(1,4)]) [1 .. 4] == [0,1,2,2 + 1/2]
--   map (rts_pulse_to_rq [(3/2,4),(1/2,8),(1/4,4)]) [1 .. 4] == [0,1,3/2,7/4]
--   </pre>
rts_pulse_to_rq :: Rational_Time_Signature -> Int -> RQ

-- | Variant that gives the <i>window</i> of the pulse (ie. the start
--   location and the duration).
--   
--   <pre>
--   let r = [(0,1),(1,1),(2,1/2),(2 + 1/2,1)]
--   in map (rts_pulse_to_rqw [(2,4),(1,8),(1,4)]) [1 .. 4] == r
--   </pre>
rts_pulse_to_rqw :: Rational_Time_Signature -> Int -> (RQ, RQ)


-- | Functions to generate a click track from a metric structure.
module Music.Theory.Duration.CT

-- | 1-indexed.
type Measure = Int

-- | 1-indexed.
type Pulse = Int

-- | Transform measures given as <a>RQ</a> divisions to absolute <a>RQ</a>
--   locations. <i>mdv</i> abbreviates measure divisions.
--   
--   <pre>
--   mdv_to_mrq [[1,2,1],[3,2,1]] == [[0,1,3],[4,7,9]]
--   </pre>
mdv_to_mrq :: [[RQ]] -> [[RQ]]

-- | Lookup function for (<a>Measure</a>,<a>Pulse</a>) indexed structure.
mp_lookup_err :: [[a]] -> (Measure, Pulse) -> a

-- | Comparison for (<a>Measure</a>,<a>Pulse</a>) indices.
mp_compare :: (Measure, Pulse) -> (Measure, Pulse) -> Ordering

-- | Latch measures (ie. make measures contiguous, hold previous value).
--   
--   <pre>
--   unzip (ct_ext 10 'a' [(3,'b'),(8,'c')]) == ([1..10],"aabbbbbccc")
--   </pre>
ct_ext :: Int -> a -> [(Measure, a)] -> [(Measure, a)]

-- | Variant that requires a value at measure one (first measure).
ct_ext1 :: Int -> [(Measure, a)] -> [(Measure, a)]

-- | <a>rts_divisions</a> of <a>ct_ext1</a>.
ct_dv_seq :: Int -> Tseq Measure Rational_Time_Signature -> [(Measure, [[RQ]])]

-- | <a>ct_dv_seq</a> without measures numbers.
ct_mdv_seq :: Int -> Tseq Measure Rational_Time_Signature -> [[RQ]]

-- | <a>mdv_to_mrq</a> of <a>ct_mdv_seq</a>.
ct_rq :: Int -> Tseq Measure Rational_Time_Signature -> [[RQ]]
ct_mp_lookup :: [[RQ]] -> (Measure, Pulse) -> RQ
ct_m_to_rq :: [[RQ]] -> [(Measure, t)] -> [(RQ, t)]

-- | Latch rehearsal mark sequence, only indicating marks. Initial mark is
--   <tt>.</tt>.
--   
--   <pre>
--   ct_mark_seq 2 [] == [(1,Just '.'),(2,Nothing)]
--   </pre>
--   
--   <pre>
--   let r = [(1,Just '.'),(3,Just 'A'),(8,Just 'B')]
--   in filter (isJust . snd) (ct_mark_seq 10 [(3,'A'),(8,'B')]) == r
--   </pre>
ct_mark_seq :: Int -> Tseq Measure Char -> Tseq Measure (Maybe Char)

-- | Indicate measures prior to marks.
--   
--   <pre>
--   ct_pre_mark [] == []
--   ct_pre_mark [(1,'A')] == []
--   ct_pre_mark [(3,'A'),(8,'B')] == [(2,Just ()),(7,Just ())]
--   </pre>
ct_pre_mark :: [(Measure, a)] -> [(Measure, Maybe ())]

-- | Contiguous pre-mark sequence.
--   
--   <pre>
--   ct_pre_mark_seq 1 [(1,'A')] == [(1,Nothing)]
--   ct_pre_mark_seq 10 [(3,'A'),(8,'B')]
--   </pre>
ct_pre_mark_seq :: Measure -> Tseq Measure Char -> Tseq Measure (Maybe ())
ct_tempo_lseq_rq :: [[RQ]] -> Lseq (Measure, Pulse) RQ -> Lseq RQ RQ

-- | Interpolating lookup of tempo sequence (<a>lseq_lookup_err</a>).
ct_tempo_at :: Lseq RQ RQ -> RQ -> Rational

-- | Types of nodes.
data CT_Node

-- | The start of a measure with a rehearsal mark.
CT_Mark :: RQ -> CT_Node

-- | The start of a regular measure.
CT_Start :: RQ -> CT_Node

-- | A regular pulse.
CT_Normal :: RQ -> CT_Node

-- | The start of a pulse group within a measure.
CT_Edge :: RQ -> CT_Node

-- | A regular pulse in a measure prior to a rehearsal mark.
CT_Pre :: RQ -> CT_Node

-- | The end of the track.
CT_End :: CT_Node

-- | Lead-in of <tt>(pulse,tempo,count)</tt>.
ct_leadin :: (RQ, Double, Int) -> Dseq Double CT_Node

-- | Prepend initial element to start of list.
--   
--   <pre>
--   delay1 "abc" == "aabc"
--   </pre>
delay1 :: [a] -> [a]
ct_measure :: Lseq RQ RQ -> ([RQ], Maybe Char, Maybe (), [[RQ]]) -> [(Rational, CT_Node)]

-- | Click track definition.
data CT
CT :: Int -> [(Measure, Rational_Time_Signature)] -> [(Measure, Char)] -> Lseq (Measure, Pulse) RQ -> (RQ, Int) -> CT
[ct_len] :: CT -> Int
[ct_ts] :: CT -> [(Measure, Rational_Time_Signature)]
[ct_mark] :: CT -> [(Measure, Char)]
[ct_tempo] :: CT -> Lseq (Measure, Pulse) RQ
[ct_count] :: CT -> (RQ, Int)

-- | Initial tempo, if given.
ct_tempo0 :: CT -> Maybe RQ

-- | Erroring variant.
ct_tempo0_err :: CT -> RQ
ct_measures :: CT -> [Dseq Rational CT_Node]
ct_dseq' :: CT -> Dseq Rational CT_Node
ct_dseq :: CT -> Dseq Double CT_Node
ct_rq_measure :: [[RQ]] -> RQ -> Maybe Measure
ct_rq_mp :: [[RQ]] -> RQ -> Maybe (Measure, Pulse)
ct_rq_mp_err :: [[RQ]] -> RQ -> (Measure, Pulse)
ct_mp_to_rq :: [[RQ]] -> [((Measure, Pulse), t)] -> [(RQ, t)]
instance GHC.Show.Show Music.Theory.Duration.CT.CT
instance GHC.Show.Show Music.Theory.Duration.CT.CT_Node
instance GHC.Classes.Eq Music.Theory.Duration.CT.CT_Node


-- | Notation of a sequence of <a>RQ</a> values as annotated
--   <a>Duration</a> values.
--   
--   <ol>
--   <li>Separate input sequence into measures, adding tie annotations as
--   required (see <a>to_measures_ts</a>). Ensure all <a>RQ_T</a> values
--   can be notated as <i>common music notation</i> durations.</li>
--   <li>Separate each measure into pulses (see <a>m_divisions_ts</a>).
--   Further subdivides pulses to ensure <i>cmn</i> tuplet notation. See
--   <a>to_divisions_ts</a> for a composition of <a>to_measures_ts</a> and
--   <a>m_divisions_ts</a>.</li>
--   <li>Simplify each measure (see <a>m_simplify</a> and
--   <a>default_rule</a>). Coalesces tied durations where appropriate.</li>
--   <li>Notate measures (see <a>m_notate</a> or <a>mm_notate</a>).</li>
--   <li>Ascribe values to notated durations, see <a>ascribe</a>.</li>
--   </ol>
module Music.Theory.Duration.Sequence.Notate

-- | Variant of <a>catMaybes</a>. If all elements of the list are <tt>Just
--   a</tt>, then gives <tt>Just [a]</tt> else gives <a>Nothing</a>.
--   
--   <pre>
--   all_just (map Just [1..3]) == Just [1..3]
--   all_just [Just 1,Nothing,Just 3] == Nothing
--   </pre>
all_just :: [Maybe a] -> Maybe [a]

-- | Variant of <a>rights</a> that preserves first <a>Left</a>.
--   
--   <pre>
--   all_right (map Right [1..3]) == Right [1..3]
--   all_right [Right 1,Left 'a',Left 'b'] == Left 'a'
--   </pre>
all_right :: [Either a b] -> Either a [b]

-- | Applies a <i>join</i> function to the first two elements of the list.
--   If the <i>join</i> function succeeds the joined element is considered
--   for further coalescing.
--   
--   <pre>
--   coalesce (\p q -&gt; Just (p + q)) [1..5] == [15]
--   </pre>
--   
--   <pre>
--   let jn p q = if even p then Just (p + q) else Nothing
--   in coalesce jn [1..5] == map sum [[1],[2,3],[4,5]]
--   </pre>
coalesce :: (a -> a -> Maybe a) -> [a] -> [a]

-- | Variant of <a>coalesce</a> with accumulation parameter.
--   
--   <pre>
--   coalesce_accum (\i p q -&gt; Left (p + q)) 0 [1..5] == [(0,15)]
--   </pre>
--   
--   <pre>
--   let jn i p q = if even p then Left (p + q) else Right (p + i)
--   in coalesce_accum jn 0 [1..7] == [(0,1),(1,5),(6,9),(15,13)]
--   </pre>
--   
--   <pre>
--   let jn i p q = if even p then Left (p + q) else Right [p,q]
--   in coalesce_accum jn [] [1..5] == [([],1),([1,2],5),([5,4],9)]
--   </pre>
coalesce_accum :: (b -> a -> a -> Either a b) -> b -> [a] -> [(b, a)]

-- | Variant of <a>coalesce_accum</a> that accumulates running sum.
--   
--   <pre>
--   let f i p q = if i == 1 then Just (p + q) else Nothing
--   in coalesce_sum (+) 0 f [1,1/2,1/4,1/4] == [1,1]
--   </pre>
coalesce_sum :: (b -> a -> b) -> b -> (b -> a -> a -> Maybe a) -> [a] -> [a]

-- | Lower <a>Either</a> to <a>Maybe</a> by discarding <a>Left</a>.
either_to_maybe :: Either a b -> Maybe b

-- | Take elements while the sum of the prefix is less than or equal to the
--   indicated value. Returns also the difference between the prefix sum
--   and the requested sum. Note that zero elements are kept left.
--   
--   <pre>
--   take_sum_by id 3 [2,1] == ([2,1],0,[])
--   take_sum_by id 3 [2,2] == ([2],1,[2])
--   take_sum_by id 3 [2,1,0,1] == ([2,1,0],0,[1])
--   take_sum_by id 3 [4] == ([],3,[4])
--   take_sum_by id 0 [1..5] == ([],0,[1..5])
--   </pre>
take_sum_by :: (Ord n, Num n) => (a -> n) -> n -> [a] -> ([a], n, [a])

-- | Variant of <a>take_sum_by</a> with <a>id</a> function.
take_sum :: (Ord a, Num a) => a -> [a] -> ([a], a, [a])

-- | Variant of <a>take_sum</a> that requires the prefix to sum to value.
--   
--   <pre>
--   take_sum_by_eq id 3 [2,1,0,1] == Just ([2,1,0],[1])
--   take_sum_by_eq id 3 [2,2] == Nothing
--   </pre>
take_sum_by_eq :: (Ord n, Num n) => (a -> n) -> n -> [a] -> Maybe ([a], [a])

-- | Recursive variant of <a>take_sum_by_eq</a>.
--   
--   <pre>
--   split_sum_by_eq id [3,3] [2,1,0,3] == Just [[2,1,0],[3]]
--   split_sum_by_eq id [3,3] [2,2,2] == Nothing
--   </pre>
split_sum_by_eq :: (Ord n, Num n) => (a -> n) -> [n] -> [a] -> Maybe [[a]]

-- | Split sequence such that the prefix sums to precisely <i>m</i>. The
--   third element of the result indicates if it was required to divide an
--   element. Note that zero elements are kept left. If the required sum is
--   non positive, or the input list does not sum to at least the required
--   sum, gives nothing.
--   
--   <pre>
--   split_sum 5 [2,3,1] == Just ([2,3],[1],Nothing)
--   split_sum 5 [2,1,3] == Just ([2,1,2],[1],Just (2,1))
--   split_sum 2 [3/2,3/2,3/2] == Just ([3/2,1/2],[1,3/2],Just (1/2,1))
--   split_sum 6 [1..10] == Just ([1..3],[4..10],Nothing)
--   fmap (\(a,_,c)-&gt;(a,c)) (split_sum 5 [1..]) == Just ([1,2,2],Just (2,1))
--   split_sum 0 [1..] == Nothing
--   split_sum 3 [1,1] == Nothing
--   split_sum 3 [2,1,0] == Just ([2,1,0],[],Nothing)
--   split_sum 3 [2,1,0,1] == Just ([2,1,0],[1],Nothing)
--   </pre>
split_sum :: (Ord a, Num a) => a -> [a] -> Maybe ([a], [a], Maybe (a, a))

-- | Alias for <a>True</a>, used locally for documentation.
_t :: Bool

-- | Alias for <a>False</a>, used locally for documentation.
_f :: Bool

-- | Variant of <a>split_sum</a> that operates at <a>RQ_T</a> sequences.
--   
--   <pre>
--   let r = Just ([(3,_f),(2,_t)],[(1,_f)])
--   in rqt_split_sum 5 [(3,_f),(2,_t),(1,_f)] == r
--   </pre>
--   
--   <pre>
--   let r = Just ([(3,_f),(1,_t)],[(1,_t),(1,_f)])
--   in rqt_split_sum 4 [(3,_f),(2,_t),(1,_f)] == r
--   </pre>
--   
--   <pre>
--   rqt_split_sum 4 [(5/2,False)] == Nothing
--   </pre>
rqt_split_sum :: RQ -> [RQ_T] -> Maybe ([RQ_T], [RQ_T])

-- | Separate <a>RQ_T</a> values in sequences summing to <a>RQ</a> values.
--   This is a recursive variant of <a>rqt_split_sum</a>. Note that is does
--   not ensure <i>cmn</i> notation of values.
--   
--   <pre>
--   let d = [(2,_f),(2,_f),(2,_f)]
--   in rqt_separate [3,3] d == Right [[(2,_f),(1,_t)]
--                                    ,[(1,_f),(2,_f)]]
--   </pre>
--   
--   <pre>
--   let d = [(5/8,_f),(1,_f),(3/8,_f)]
--   in rqt_separate [1,1] d == Right [[(5/8,_f),(3/8,_t)]
--                                    ,[(5/8,_f),(3/8,_f)]]
--   </pre>
--   
--   <pre>
--   let d = [(4/7,_t),(1/7,_f),(1,_f),(6/7,_f),(3/7,_f)]
--   in rqt_separate [1,1,1] d == Right [[(4/7,_t),(1/7,_f),(2/7,_t)]
--                                      ,[(5/7,_f),(2/7,_t)]
--                                      ,[(4/7,_f),(3/7,_f)]]
--   </pre>
rqt_separate :: [RQ] -> [RQ_T] -> Either String [[RQ_T]]
rqt_separate_m :: [RQ] -> [RQ_T] -> Maybe [[RQ_T]]

-- | If the input <a>RQ_T</a> sequence cannot be notated (see
--   <a>rqt_can_notate</a>) separate into equal parts, so long as each part
--   is not less than <i>i</i>.
--   
--   <pre>
--   rqt_separate_tuplet undefined [(1/3,_f),(1/6,_f)]
--   rqt_separate_tuplet undefined [(4/7,_t),(1/7,_f),(2/7,_f)]
--   </pre>
--   
--   <pre>
--   let d = map rq_rqt [1/3,1/6,2/5,1/10]
--   in rqt_separate_tuplet (1/8) d == Right [[(1/3,_f),(1/6,_f)]
--                                           ,[(2/5,_f),(1/10,_f)]]
--   </pre>
--   
--   <pre>
--   let d = [(1/5,True),(1/20,False),(1/2,False),(1/4,True)]
--   in rqt_separate_tuplet (1/16) d
--   </pre>
--   
--   <pre>
--   let d = [(2/5,_f),(1/5,_f),(1/5,_f),(1/5,_t),(1/2,_f),(1/2,_f)]
--   in rqt_separate_tuplet (1/2) d
--   </pre>
--   
--   <pre>
--   let d = [(4/10,True),(1/10,False),(1/2,True)]
--   in rqt_separate_tuplet (1/2) d
--   </pre>
rqt_separate_tuplet :: RQ -> [RQ_T] -> Either String [[RQ_T]]

-- | Recursive variant of <a>rqt_separate_tuplet</a>.
--   
--   <pre>
--   let d = map rq_rqt [1,1/3,1/6,2/5,1/10]
--   in rqt_tuplet_subdivide (1/8) d == [[(1/1,_f)]
--                                      ,[(1/3,_f),(1/6,_f)]
--                                      ,[(2/5,_f),(1/10,_f)]]
--   </pre>
rqt_tuplet_subdivide :: RQ -> [RQ_T] -> [[RQ_T]]

-- | Sequence variant of <a>rqt_tuplet_subdivide</a>.
--   
--   <pre>
--   let d = [(1/5,True),(1/20,False),(1/2,False),(1/4,True)]
--   in rqt_tuplet_subdivide_seq (1/2) [d]
--   </pre>
rqt_tuplet_subdivide_seq :: RQ -> [[RQ_T]] -> [[RQ_T]]

-- | If a tuplet is all tied, it ought to be a plain value?!
--   
--   <pre>
--   rqt_tuplet_sanity_ [(4/10,_t),(1/10,_f)] == [(1/2,_f)]
--   </pre>
rqt_tuplet_sanity_ :: [RQ_T] -> [RQ_T]
rqt_tuplet_subdivide_seq_sanity_ :: RQ -> [[RQ_T]] -> [[RQ_T]]

-- | Separate <a>RQ</a> sequence into measures given by <a>RQ</a> length.
--   
--   <pre>
--   to_measures_rq [3,3] [2,2,2] == Right [[(2,_f),(1,_t)],[(1,_f),(2,_f)]]
--   to_measures_rq [3,3] [6] == Right [[(3,_t)],[(3,_f)]]
--   to_measures_rq [1,1,1] [3] == Right [[(1,_t)],[(1,_t)],[(1,_f)]]
--   to_measures_rq [3,3] [2,2,1]
--   to_measures_rq [3,2] [2,2,2]
--   </pre>
--   
--   <pre>
--   let d = [4/7,33/28,9/20,4/5]
--   in to_measures_rq [3] d == Right [[(4/7,_f),(33/28,_f),(9/20,_f),(4/5,_f)]]
--   </pre>
to_measures_rq :: [RQ] -> [RQ] -> Either String [[RQ_T]]

-- | Variant of <a>to_measures_rq</a> that ensures <a>RQ_T</a> are
--   <i>cmn</i> durations. This is not a good composition.
--   
--   <pre>
--   to_measures_rq_cmn [6,6] [5,5,2] == Right [[(4,_t),(1,_f),(1,_t)]
--                                             ,[(4,_f),(2,_f)]]
--   </pre>
--   
--   <pre>
--   let r = [[(4/7,_t),(1/7,_f),(1,_f),(6/7,_f),(3/7,_f)]]
--   in to_measures_rq_cmn [3] [5/7,1,6/7,3/7] == Right r
--   </pre>
--   
--   <pre>
--   to_measures_rq_cmn [1,1,1] [5/7,1,6/7,3/7] == Right [[(4/7,_t),(1/7,_f),(2/7,_t)]
--                                                       ,[(4/7,_t),(1/7,_f),(2/7,_t)]
--                                                       ,[(4/7,_f),(3/7,_f)]]
--   </pre>
to_measures_rq_cmn :: [RQ] -> [RQ] -> Either String [[RQ_T]]

-- | Variant of <a>to_measures_rq</a> with measures given by
--   <a>Time_Signature</a> values. Does not ensure <a>RQ_T</a> are
--   <i>cmn</i> durations.
--   
--   <pre>
--   to_measures_ts [(1,4)] [5/8,3/8] /= Right [[(1/2,_t),(1/8,_f),(3/8,_f)]]
--   to_measures_ts [(1,4)] [5/7,2/7] /= Right [[(4/7,_t),(1/7,_f),(2/7,_f)]]
--   </pre>
--   
--   <pre>
--   let {m = replicate 18 (1,4)
--       ;x = [3/4,2,5/4,9/4,1/4,3/2,1/2,7/4,1,5/2,11/4,3/2]}
--   in to_measures_ts m x == Right [[(3/4,_f),(1/4,_t)],[(1/1,_t)]
--                                  ,[(3/4,_f),(1/4,_t)],[(1/1,_f)]
--                                  ,[(1/1,_t)],[(1/1,_t)]
--                                  ,[(1/4,_f),(1/4,_f),(1/2,_t)],[(1/1,_f)]
--                                  ,[(1/2,_f),(1/2,_t)],[(1/1,_t)]
--                                  ,[(1/4,_f),(3/4,_t)],[(1/4,_f),(3/4,_t)]
--                                  ,[(1/1,_t)],[(3/4,_f),(1/4,_t)]
--                                  ,[(1/1,_t)],[(1/1,_t)]
--                                  ,[(1/2,_f),(1/2,_t)],[(1/1,_f)]]
--   </pre>
--   
--   <pre>
--   to_measures_ts [(3,4)] [4/7,33/28,9/20,4/5]
--   to_measures_ts (replicate 3 (1,4)) [4/7,33/28,9/20,4/5]
--   </pre>
to_measures_ts :: [Time_Signature] -> [RQ] -> Either String [[RQ_T]]

-- | Variant of <a>to_measures_ts</a> that allows for duration field
--   operation but requires that measures be well formed. This is useful
--   for re-grouping measures after notation and ascription.
to_measures_ts_by_eq :: (a -> RQ) -> [Time_Signature] -> [a] -> Maybe [[a]]

-- | Divide measure into pulses of indicated <a>RQ</a> durations. Measure
--   must be of correct length but need not contain only <i>cmn</i>
--   durations. Pulses are further subdivided if required to notate tuplets
--   correctly, see <a>rqt_tuplet_subdivide_seq</a>.
--   
--   <pre>
--   let d = [(1/4,_f),(1/4,_f),(2/3,_t),(1/6,_f),(16/15,_f),(1/5,_f)
--           ,(1/5,_f),(2/5,_t),(1/20,_f),(1/2,_f),(1/4,_t)]
--   in m_divisions_rq [1,1,1,1] d
--   </pre>
--   
--   <pre>
--   m_divisions_rq [1,1,1] [(4/7,_f),(33/28,_f),(9/20,_f),(4/5,_f)]
--   </pre>
m_divisions_rq :: [RQ] -> [RQ_T] -> Either String [[RQ_T]]

-- | Variant of <a>m_divisions_rq</a> that determines pulse divisions from
--   <a>Time_Signature</a>.
--   
--   <pre>
--   let d = [(4/7,_t),(1/7,_f),(2/7,_f)]
--   in m_divisions_ts (1,4) d == Just [d]
--   </pre>
--   
--   <pre>
--   let d = map rq_rqt [1/3,1/6,2/5,1/10]
--   in m_divisions_ts (1,4) d == Just [[(1/3,_f),(1/6,_f)]
--                                     ,[(2/5,_f),(1/10,_f)]]
--   </pre>
--   
--   <pre>
--   let d = map rq_rqt [4/7,33/28,9/20,4/5]
--   in m_divisions_ts (3,4) d == Just [[(4/7,_f),(3/7,_t)]
--                                     ,[(3/4,_f),(1/4,_t)]
--                                     ,[(1/5,_f),(4/5,_f)]]
--   </pre>
m_divisions_ts :: Time_Signature -> [RQ_T] -> Either String [[RQ_T]]

-- | Composition of <a>to_measures_rq</a> and <a>m_divisions_rq</a>, where
--   measures are initially given as sets of divisions.
--   
--   <pre>
--   let m = [[1,1,1],[1,1,1]]
--   in to_divisions_rq m [2,2,2] == Right [[[(1,_t)],[(1,_f)],[(1,_t)]]
--                                        ,[[(1,_f)],[(1,_t)],[(1,_f)]]]
--   </pre>
--   
--   <pre>
--   let d = [2/7,1/7,4/7,5/7,8/7,1,1/7]
--   in to_divisions_rq [[1,1,1,1]] d == Right [[[(2/7,_f),(1/7,_f),(4/7,_f)]
--                                             ,[(4/7,_t),(1/7,_f),(2/7,_t)]
--                                             ,[(6/7,_f),(1/7,_t)]
--                                             ,[(6/7,_f),(1/7,_f)]]]
--   </pre>
--   
--   <pre>
--   let d = [5/7,1,6/7,3/7]
--   in to_divisions_rq [[1,1,1]] d == Right [[[(4/7,_t),(1/7,_f),(2/7,_t)]
--                                           ,[(4/7,_t),(1/7,_f),(2/7,_t)]
--                                           ,[(4/7,_f),(3/7,_f)]]]
--   </pre>
--   
--   <pre>
--   let d = [2/7,1/7,4/7,5/7,1,6/7,3/7]
--   in to_divisions_rq [[1,1,1,1]] d == Right [[[(2/7,_f),(1/7,_f),(4/7,_f)]
--                                             ,[(4/7,_t),(1/7,_f),(2/7,_t)]
--                                             ,[(4/7,_t),(1/7,_f),(2/7,_t)]
--                                             ,[(4/7,_f),(3/7,_f)]]]
--   </pre>
--   
--   <pre>
--   let d = [4/7,33/28,9/20,4/5]
--   in to_divisions_rq [[1,1,1]] d == Right [[[(4/7,_f),(3/7,_t)]
--                                            ,[(3/4,_f),(1/4,_t)]
--                                            ,[(1/5,_f),(4/5,_f)]]]
--   </pre>
--   
--   <pre>
--   let {p = [[1/2,1,1/2],[1/2,1]]
--       ;d = map (/6) [1,1,1,1,1,1,4,1,2,1,1,2,1,3]}
--   in to_divisions_rq p d == Right [[[(1/6,_f),(1/6,_f),(1/6,_f)]
--                                    ,[(1/6,_f),(1/6,_f),(1/6,_f),(1/2,True)]
--                                    ,[(1/6,_f),(1/6,_f),(1/6,True)]]
--                                   ,[[(1/6,_f),(1/6,_f),(1/6,_f)]
--                                    ,[(1/3,_f),(1/6,_f),(1/2,_f)]]]
--   </pre>
to_divisions_rq :: [[RQ]] -> [RQ] -> Either String [[[RQ_T]]]

-- | Variant of <a>to_divisions_rq</a> with measures given as set of
--   <a>Time_Signature</a>.
--   
--   <pre>
--   let d = [3/5,2/5,1/3,1/6,7/10,17/15,1/2,1/6]
--   in to_divisions_ts [(4,4)] d == Just [[[(3/5,_f),(2/5,_f)]
--                                         ,[(1/3,_f),(1/6,_f),(1/2,_t)]
--                                         ,[(1/5,_f),(4/5,_t)]
--                                         ,[(1/3,_f),(1/2,_f),(1/6,_f)]]]
--   </pre>
--   
--   <pre>
--   let d = [3/5,2/5,1/3,1/6,7/10,29/30,1/2,1/3]
--   in to_divisions_ts [(4,4)] d == Just [[[(3/5,_f),(2/5,_f)]
--                                         ,[(1/3,_f),(1/6,_f),(1/2,_t)]
--                                         ,[(1/5,_f),(4/5,_t)]
--                                         ,[(1/6,_f),(1/2,_f),(1/3,_f)]]]
--   </pre>
--   
--   <pre>
--   let d = [3/5,2/5,1/3,1/6,7/10,4/5,1/2,1/2]
--   in to_divisions_ts [(4,4)] d == Just [[[(3/5,_f),(2/5,_f)]
--                                         ,[(1/3,_f),(1/6,_f),(1/2,_t)]
--                                         ,[(1/5,_f),(4/5,_f)]
--                                         ,[(1/2,_f),(1/2,_f)]]]
--   </pre>
--   
--   <pre>
--   let d = [4/7,33/28,9/20,4/5]
--   in to_divisions_ts [(3,4)] d == Just [[[(4/7,_f),(3/7,_t)]
--                                         ,[(3/4,_f),(1/4,_t)]
--                                         ,[(1/5,_f),(4/5,_f)]]]
--   </pre>
to_divisions_ts :: [Time_Signature] -> [RQ] -> Either String [[[RQ_T]]]

-- | Pulse tuplet derivation.
--   
--   <pre>
--   p_tuplet_rqt [(2/3,_f),(1/3,_t)] == Just ((3,2),[(1,_f),(1/2,_t)])
--   p_tuplet_rqt (map rq_rqt [1/3,1/6]) == Just ((3,2),[(1/2,_f),(1/4,_f)])
--   p_tuplet_rqt (map rq_rqt [2/5,1/10]) == Just ((5,4),[(1/2,_f),(1/8,_f)])
--   p_tuplet_rqt (map rq_rqt [1/3,1/6,2/5,1/10])
--   </pre>
p_tuplet_rqt :: [RQ_T] -> Maybe ((Integer, Integer), [RQ_T])

-- | Notate pulse, ie. derive tuplet if neccesary. The flag indicates if
--   the initial value is tied left.
--   
--   <pre>
--   p_notate False [(2/3,_f),(1/3,_t)]
--   p_notate False [(2/5,_f),(1/10,_t)]
--   p_notate False [(1/4,_t),(1/8,_f),(1/8,_f)]
--   p_notate False (map rq_rqt [1/3,1/6])
--   p_notate False (map rq_rqt [2/5,1/10])
--   p_notate False (map rq_rqt [1/3,1/6,2/5,1/10]) == Nothing
--   </pre>
p_notate :: Bool -> [RQ_T] -> Either String [Duration_A]

-- | Notate measure.
--   
--   <pre>
--   m_notate True [[(2/3,_f),(1/3,_t)],[(1,_t)],[(1,_f)]]
--   </pre>
--   
--   <pre>
--   let f = m_notate False . concat
--   </pre>
--   
--   <pre>
--   fmap f (to_divisions_ts [(4,4)] [3/5,2/5,1/3,1/6,7/10,17/15,1/2,1/6])
--   fmap f (to_divisions_ts [(4,4)] [3/5,2/5,1/3,1/6,7/10,29/30,1/2,1/3])
--   </pre>
m_notate :: Bool -> [[RQ_T]] -> Either String [Duration_A]

-- | Multiple measure notation.
--   
--   <pre>
--   let d = [2/7,1/7,4/7,5/7,8/7,1,1/7]
--   in fmap mm_notate (to_divisions_ts [(4,4)] d)
--   </pre>
--   
--   <pre>
--   let d = [2/7,1/7,4/7,5/7,1,6/7,3/7]
--   in fmap mm_notate (to_divisions_ts [(4,4)] d)
--   </pre>
--   
--   <pre>
--   let d = [3/5,2/5,1/3,1/6,7/10,4/5,1/2,1/2]
--   in fmap mm_notate (to_divisions_ts [(4,4)] d)
--   </pre>
--   
--   <pre>
--   let {p = [[1/2,1,1/2],[1/2,1]]
--       ;d = map (/6) [1,1,1,1,1,1,4,1,2,1,1,2,1,3]}
--   in fmap mm_notate (to_divisions_rq p d)
--   </pre>
mm_notate :: [[[RQ_T]]] -> Either String [[Duration_A]]

-- | Structure given to <a>Simplify_P</a> to decide simplification. The
--   structure is <i>(ts,start-rq,(left-rq,right-rq))</i>.
type Simplify_T = (Time_Signature, RQ, (RQ, RQ))

-- | Predicate function at <a>Simplify_T</a>.
type Simplify_P = Simplify_T -> Bool

-- | Variant of <a>Simplify_T</a> allowing multiple rules.
type Simplify_M = ([Time_Signature], [RQ], [(RQ, RQ)])

-- | Transform <a>Simplify_M</a> to <a>Simplify_P</a>.
meta_table_p :: Simplify_M -> Simplify_P

-- | Transform <a>Simplify_M</a> to set of <a>Simplify_T</a>.
meta_table_t :: Simplify_M -> [Simplify_T]

-- | The default table of simplifiers.
--   
--   <pre>
--   default_table ((3,4),1,(1,1)) == True
--   </pre>
default_table :: Simplify_P

-- | The default eighth-note pulse simplifier rule.
--   
--   <pre>
--   default_8_rule ((3,8),0,(1/2,1/2)) == True
--   default_8_rule ((3,8),1/2,(1/2,1/2)) == True
--   default_8_rule ((3,8),1,(1/2,1/2)) == True
--   default_8_rule ((2,8),0,(1/2,1/2)) == True
--   default_8_rule ((5,8),0,(1,1/2)) == True
--   default_8_rule ((5,8),0,(2,1/2)) == True
--   </pre>
default_8_rule :: Simplify_P

-- | The default quarter note pulse simplifier rule.
--   
--   <pre>
--   default_4_rule ((3,4),0,(1,1/2)) == True
--   default_4_rule ((3,4),0,(1,3/4)) == True
--   default_4_rule ((4,4),1,(1,1)) == False
--   default_4_rule ((4,4),2,(1,1)) == True
--   default_4_rule ((4,4),2,(1,2)) == True
--   default_4_rule ((4,4),0,(2,1)) == True
--   default_4_rule ((3,4),1,(1,1)) == False
--   </pre>
default_4_rule :: Simplify_P

-- | The default simplifier rule. To extend provide a list of
--   <a>Simplify_T</a>.
default_rule :: [Simplify_T] -> Simplify_P

-- | Measure simplifier. Apply given <a>Simplify_P</a>.
m_simplify :: Simplify_P -> Time_Signature -> [Duration_A] -> [Duration_A]

-- | Pulse simplifier predicate, which is <a>const</a> <a>True</a>.
p_simplify_rule :: Simplify_P

-- | Pulse simplifier.
--   
--   <pre>
--   import Music.Theory.Duration.Name.Abbreviation
--   p_simplify [(q,[Tie_Right]),(e,[Tie_Left])] == [(q',[])]
--   p_simplify [(e,[Tie_Right]),(q,[Tie_Left])] == [(q',[])]
--   p_simplify [(q,[Tie_Right]),(e',[Tie_Left])] == [(q'',[])]
--   p_simplify [(q'',[Tie_Right]),(s,[Tie_Left])] == [(h,[])]
--   p_simplify [(e,[Tie_Right]),(s,[Tie_Left]),(e',[])] == [(e',[]),(e',[])]
--   </pre>
--   
--   <pre>
--   let f = rqt_to_duration_a False
--   in p_simplify (f [(1/8,_t),(1/4,_t),(1/8,_f)]) == f [(1/2,_f)]
--   </pre>
p_simplify :: [Duration_A] -> [Duration_A]

-- | Notate RQ duration sequence. Derive pulse divisions from
--   <a>Time_Signature</a> if not given directly. Composition of
--   <a>to_divisions_ts</a>, <a>mm_notate</a> <a>m_simplify</a>.
--   
--   <pre>
--   let ts = [(4,8),(3,8)]
--       ts_p = [[1/2,1,1/2],[1/2,1]]
--       rq = map (/6) [1,1,1,1,1,1,4,1,2,1,1,2,1,3]
--       sr x = T.default_rule [] x
--   in T.notate_rqp sr ts (Just ts_p) rq
--   </pre>
notate_rqp :: Simplify_P -> [Time_Signature] -> Maybe [[RQ]] -> [RQ] -> Either String [[Duration_A]]

-- | Variant of <a>notate_rqp</a> without pulse divisions (derive).
--   
--   <pre>
--   notate (default_rule [((3,2),0,(2,2)),((3,2),0,(4,2))]) [(3,2)] [6]
--   </pre>
notate :: Simplify_P -> [Time_Signature] -> [RQ] -> Either String [[Duration_A]]

-- | Variant of <a>zip</a> that retains elements of the right hand (rhs)
--   list where elements of the left hand (lhs) list meet the given lhs
--   predicate. If the right hand side is longer the remaining elements to
--   be processed are given. It is an error for the right hand side to be
--   short.
--   
--   <pre>
--   zip_hold_lhs even [1..5] "abc" == ([],zip [1..6] "abbcc")
--   zip_hold_lhs odd [1..6] "abc" == ([],zip [1..6] "aabbcc")
--   zip_hold_lhs even [1] "ab" == ("b",[(1,'a')])
--   zip_hold_lhs even [1,2] "a" == undefined
--   </pre>
zip_hold_lhs :: (Show t, Show x) => (x -> Bool) -> [x] -> [t] -> ([t], [(x, t)])

-- | Variant of <a>zip_hold</a> that requires the right hand side to be
--   precisely the required length.
--   
--   <pre>
--   zip_hold_lhs_err even [1..5] "abc" == zip [1..6] "abbcc"
--   zip_hold_lhs_err odd [1..6] "abc" == zip [1..6] "aabbcc"
--   zip_hold_lhs_err id [False,False] "a" == undefined
--   zip_hold_lhs_err id [False] "ab" == undefined
--   </pre>
zip_hold_lhs_err :: (Show t, Show x) => (x -> Bool) -> [x] -> [t] -> [(x, t)]

-- | Variant of <a>zip</a> that retains elements of the right hand (rhs)
--   list where elements of the left hand (lhs) list meet the given lhs
--   predicate, and elements of the lhs list where elements of the rhs meet
--   the rhs predicate. If the right hand side is longer the remaining
--   elements to be processed are given. It is an error for the right hand
--   side to be short.
--   
--   <pre>
--   zip_hold even (const False) [1..5] "abc" == ([],zip [1..6] "abbcc")
--   zip_hold odd (const False) [1..6] "abc" == ([],zip [1..6] "aabbcc")
--   zip_hold even (const False) [1] "ab" == ("b",[(1,'a')])
--   zip_hold even (const False) [1,2] "a" == undefined
--   </pre>
--   
--   <pre>
--   zip_hold odd even [1,2,6] [1..5] == ([4,5],[(1,1),(2,1),(6,2),(6,3)])
--   </pre>
zip_hold :: (Show t, Show x) => (x -> Bool) -> (t -> Bool) -> [x] -> [t] -> ([t], [(x, t)])

-- | Zip a list of <a>Duration_A</a> elements duplicating elements of the
--   right hand sequence for tied durations.
--   
--   <pre>
--   let {Just d = to_divisions_ts [(4,4),(4,4)] [3,3,2]
--       ;f = map snd . snd . flip m_ascribe "xyz"}
--   in fmap f (notate d) == Just "xxxyyyzz"
--   </pre>
m_ascribe :: Show x => [Duration_A] -> [x] -> ([x], [(Duration_A, x)])

-- | <a>snd</a> <a>.</a> <a>m_ascribe</a>.
ascribe :: Show x => [Duration_A] -> [x] -> [(Duration_A, x)]

-- | Variant of <a>m_ascribe</a> for a set of measures.
mm_ascribe :: Show x => [[Duration_A]] -> [x] -> [[(Duration_A, x)]]

-- | 'mm_ascribe of <a>notate</a>.
notate_mm_ascribe :: Show a => [Simplify_T] -> [Time_Signature] -> Maybe [[RQ]] -> [RQ] -> [a] -> Either String [[(Duration_A, a)]]
notate_mm_ascribe_err :: Show a => [Simplify_T] -> [Time_Signature] -> Maybe [[RQ]] -> [RQ] -> [a] -> [[(Duration_A, a)]]

-- | Group elements as <i>chords</i> where a chord element is indicated by
--   the given predicate.
--   
--   <pre>
--   group_chd even [1,2,3,4,4,5,7,8] == [[1,2],[3,4,4],[5],[7,8]]
--   </pre>
group_chd :: (x -> Bool) -> [x] -> [[x]]

-- | Variant of <a>ascribe</a> that groups the <i>rhs</i> elements using
--   <a>group_chd</a> and with the indicated <i>chord</i> function, then
--   rejoins the resulting sequence.
ascribe_chd :: Show x => (x -> Bool) -> [Duration_A] -> [x] -> [(Duration_A, x)]

-- | Variant of <a>mm_ascribe</a> using <a>group_chd</a>
mm_ascribe_chd :: Show x => (x -> Bool) -> [[Duration_A]] -> [x] -> [[(Duration_A, x)]]


-- | Common music notation tempo indications.
module Music.Theory.Tempo_Marking

-- | A tempo marking is in terms of a common music notation
--   <a>Duration</a>.
type Tempo_Marking = (Duration, Rational)

-- | Duration of a RQ value, in seconds, given indicated tempo.
--   
--   <pre>
--   rq_to_seconds (quarter_note,90) 1 == 60/90
--   </pre>
rq_to_seconds :: Tempo_Marking -> RQ -> Rational

-- | The duration, in seconds, of a pulse at the indicated time signature
--   and tempo marking.
--   
--   <pre>
--   import Music.Theory.Duration.Name
--   pulse_duration (6,8) (quarter_note,60) == 1/2
--   </pre>
pulse_duration :: Time_Signature -> Tempo_Marking -> Rational

-- | The duration, in seconds, of a measure at the indicated time signaure
--   and tempo marking.
--   
--   <pre>
--   measure_duration (3,4) (quarter_note,90) == 2
--   measure_duration (6,8) (quarter_note,120) == 3/2
--   </pre>
measure_duration :: Time_Signature -> Tempo_Marking -> Rational

-- | <a>Fractional</a> variant of <a>measure_duration</a>.
measure_duration_f :: Fractional c => Time_Signature -> Tempo_Marking -> c

-- | Italian terms and markings from Wittner metronome (W.-Germany).
--   <a>http://wittner-gmbh.de/</a>
metronome_table_wittner :: Num n => [(String, (n, n))]

-- | Italian terms and markings from Nikko Seiki metronome (Japan).
--   <a>http://nikkoseiki.com/</a>
metronome_table_nikko :: Num n => [(String, (n, n))]

-- | Lookup metronome mark in table.
--   
--   <pre>
--   mm_name metronome_table_nikko 72 == Just "Andante"
--   </pre>
mm_name :: (Num a, Ord a) => [(String, (a, a))] -> a -> Maybe String


-- | Polansky, Larry and Bassein, Richard "Possible and Impossible Melody:
--   Some Formal Aspects of Contour" <i>Journal of Music Theory</i> 36/2,
--   1992 (pp.259-284) (<a>http://www.jstor.org/pss/843933</a>)
module Music.Theory.Contour.Polansky_1992

-- | Replace the <i>i</i>th value at <i>ns</i> with <i>x</i>.
--   
--   <pre>
--   replace "test" 2 'n' == "tent"
--   </pre>
replace :: Integral i => [a] -> i -> a -> [a]

-- | Are all elements equal.
--   
--   <pre>
--   all_equal "aaa" == True
--   </pre>
all_equal :: Eq a => [a] -> Bool

-- | Compare adjacent elements (p.262) left to right.
--   
--   <pre>
--   compare_adjacent [0,1,3,2] == [LT,LT,GT]
--   </pre>
compare_adjacent :: Ord a => [a] -> [Ordering]

-- | Construct set of <i>n</i> <a>-</a> <tt>1</tt> adjacent indices, left
--   right order.
--   
--   <pre>
--   adjacent_indices 5 == [(0,1),(1,2),(2,3),(3,4)]
--   </pre>
adjacent_indices :: Integral i => i -> [(i, i)]

-- | All <i>(i,j)</i> indices, in half matrix order.
--   
--   <pre>
--   all_indices 4 == [(0,1),(0,2),(0,3),(1,2),(1,3),(2,3)]
--   </pre>
all_indices :: Integral i => i -> [(i, i)]

-- | Generic variant of <a>fromEnum</a> (p.263).
genericFromEnum :: (Integral i, Enum e) => e -> i

-- | Generic variant of <a>toEnum</a> (p.263).
genericToEnum :: (Integral i, Enum e) => i -> e

-- | Specialised <a>genericFromEnum</a>.
ord_to_int :: Integral a => Ordering -> a

-- | Specialised <a>genericToEnum</a>.
int_to_ord :: Integral a => a -> Ordering

-- | Invert <a>Ordering</a>.
--   
--   <pre>
--   map ord_invert [LT,EQ,GT] == [GT,EQ,LT]
--   </pre>
ord_invert :: Ordering -> Ordering

-- | A list notation for matrices.
type Matrix a = [[a]]

-- | Apply <i>f</i> to construct <a>Matrix</a> from sequence.
--   
--   <pre>
--   matrix_f (,) [1..3] == [[(1,1),(1,2),(1,3)]
--                          ,[(2,1),(2,2),(2,3)]
--                          ,[(3,1),(3,2),(3,3)]]
--   </pre>
matrix_f :: (a -> a -> b) -> [a] -> Matrix b

-- | Construct <a>matrix_f</a> with <a>compare</a> (p.263).
--   
--   <pre>
--   contour_matrix [1..3] == [[EQ,LT,LT],[GT,EQ,LT],[GT,GT,EQ]]
--   </pre>
contour_matrix :: Ord a => [a] -> Matrix Ordering

-- | Half matrix notation for contour.
data Contour_Half_Matrix
Contour_Half_Matrix :: Int -> Matrix Ordering -> Contour_Half_Matrix
[contour_half_matrix_n] :: Contour_Half_Matrix -> Int
[contour_half_matrix_m] :: Contour_Half_Matrix -> Matrix Ordering

-- | Half <a>Matrix</a> of contour given comparison function <i>f</i>.
--   
--   <pre>
--   half_matrix_f (flip (-)) [2,10,6,7] == [[8,4,5],[-4,-3],[1]]
--   half_matrix_f (flip (-)) [5,0,3,2] == [[-5,-2,-3],[3,2],[-1]]
--   half_matrix_f compare [5,0,3,2] == [[GT,GT,GT],[LT,LT],[GT]]
--   </pre>
half_matrix_f :: (a -> a -> b) -> [a] -> Matrix b

-- | Construct <a>Contour_Half_Matrix</a> (p.264)
contour_half_matrix :: Ord a => [a] -> Contour_Half_Matrix

-- | <a>Show</a> function for <a>Contour_Half_Matrix</a>.
contour_half_matrix_str :: Contour_Half_Matrix -> String

-- | <i>Description</i> notation of contour.
data Contour_Description
Contour_Description :: Int -> Map (Int, Int) Ordering -> Contour_Description
[contour_description_n] :: Contour_Description -> Int
[contour_description_m] :: Contour_Description -> Map (Int, Int) Ordering

-- | Construct <a>Contour_Description</a> of contour (p.264).
--   
--   <pre>
--   let c = [[3,2,4,1],[3,2,1,4]]
--   in map (show.contour_description) c == ["202 02 2","220 20 0"]
--   </pre>
contour_description :: Ord a => [a] -> Contour_Description

-- | <a>Show</a> function for <a>Contour_Description</a> (p.264).
contour_description_str :: Contour_Description -> String

-- | Convert from <a>Contour_Half_Matrix</a> notation to
--   <a>Contour_Description</a>.
half_matrix_to_description :: Contour_Half_Matrix -> Contour_Description

-- | Ordering from <i>i</i>th to <i>j</i>th element of sequence described
--   at <i>d</i>.
--   
--   <pre>
--   contour_description_ix (contour_description "abdc") (0,3) == LT
--   </pre>
contour_description_ix :: Contour_Description -> (Int, Int) -> Ordering

-- | <a>True</a> if contour is all descending, equal or ascending.
--   
--   <pre>
--   let c = ["abc","bbb","cba"]
--   in map (uniform.contour_description) c == [True,True,True]
--   </pre>
uniform :: Contour_Description -> Bool

-- | <a>True</a> if contour does not containt any <a>EQ</a> elements.
--   
--   <pre>
--   let c = ["abc","bbb","cba"]
--   map (no_equalities.contour_description) c == [True,False,True]
--   </pre>
no_equalities :: Contour_Description -> Bool

-- | Set of all contour descriptions.
--   
--   <pre>
--   map (length.all_contours) [3,4,5] == [27,729,59049]
--   </pre>
all_contours :: Int -> [Contour_Description]

-- | A sequence of orderings <i>(i,j)</i> and <i>(j,k)</i> may imply
--   ordering for <i>(i,k)</i>.
--   
--   <pre>
--   map implication [(LT,EQ),(EQ,EQ),(EQ,GT)] == [Just LT,Just EQ,Just GT]
--   </pre>
implication :: (Ordering, Ordering) -> Maybe Ordering

-- | List of all violations at a <a>Contour_Description</a> (p.266).
violations :: Contour_Description -> [(Int, Int, Int, Ordering)]

-- | Is the number of <a>violations</a> zero.
is_possible :: Contour_Description -> Bool

-- | All possible contour descriptions
--   
--   <pre>
--   map (length.possible_contours) [3,4,5] == [13,75,541]
--   </pre>
possible_contours :: Int -> [Contour_Description]

-- | All impossible contour descriptions
--   
--   <pre>
--   map (length.impossible_contours) [3,4,5] == [14,654,58508]
--   </pre>
impossible_contours :: Int -> [Contour_Description]

-- | Calculate number of contours of indicated degree (p.263).
--   
--   <pre>
--   map contour_description_lm [2..7] == [1,3,6,10,15,21]
--   </pre>
--   
--   <pre>
--   let r = [3,27,729,59049,14348907]
--   in map (\n -&gt; 3 ^ n) (map contour_description_lm [2..6]) == r
--   </pre>
contour_description_lm :: Integral a => a -> a

-- | Truncate a <a>Contour_Description</a> to have at most <i>n</i>
--   elements.
--   
--   <pre>
--   let c = contour_description [3,2,4,1]
--   in contour_truncate c 3 == contour_description [3,2,4]
--   </pre>
contour_truncate :: Contour_Description -> Int -> Contour_Description

-- | Is <a>Contour_Description</a> <i>p</i> a prefix of <i>q</i>.
--   
--   <pre>
--   let {c = contour_description [3,2,4,1]
--       ;d = contour_description [3,2,4]}
--   in d `contour_is_prefix_of` c == True
--   </pre>
contour_is_prefix_of :: Contour_Description -> Contour_Description -> Bool

-- | Are <a>Contour_Description</a>s <i>p</i> and <i>q</i> equal at column
--   <i>n</i>.
--   
--   <pre>
--   let {c = contour_description [3,2,4,1,5]
--       ;d = contour_description [3,2,4,1]}
--   in map (contour_eq_at c d) [0..4] == [True,True,True,True,False]
--   </pre>
contour_eq_at :: Contour_Description -> Contour_Description -> Int -> Bool

-- | Derive an <a>Integral</a> contour that would be described by
--   <a>Contour_Description</a>. Diverges for impossible contours.
--   
--   <pre>
--   draw_contour (contour_description "abdc") == [0,1,3,2]
--   </pre>
draw_contour :: Integral i => Contour_Description -> [i]

-- | Invert <a>Contour_Description</a>.
--   
--   <pre>
--   let c = contour_description "abdc"
--   in draw_contour (contour_description_invert c) == [3,2,0,1]
--   </pre>
contour_description_invert :: Contour_Description -> Contour_Description

-- | Function to perhaps generate an element and a new state from an
--   initial state. This is the function provided to <a>unfoldr</a>.
type Build_f st e = st -> Maybe (e, st)

-- | Function to test is a partial sequence conforms to the target
--   sequence.
type Conforms_f e = Int -> [e] -> Bool

-- | Transform a <a>Build_f</a> to produce at most <i>n</i> elements.
--   
--   <pre>
--   let f i = Just (i,succ i)
--   in unfoldr (build_f_n f) (5,'a') == "abcde"
--   </pre>
build_f_n :: Build_f st e -> Build_f (Int, st) e

-- | Attempt to construct a sequence of <i>n</i> elements given a
--   <a>Build_f</a> to generate possible elements, a <a>Conforms_f</a> that
--   the result sequence must conform to at each step, an <a>Int</a> to
--   specify the maximum number of elements to generate when searching for
--   a solution, and an initial state.
--   
--   <pre>
--   let {b_f i = Just (i,i+1)
--       ;c_f i x = odd (sum x `div` i)}
--   in build_sequence 6 b_f c_f 20 0 == (Just [1,2,6,11,15,19],20)
--   </pre>
build_sequence :: Int -> Build_f st e -> Conforms_f e -> Int -> st -> (Maybe [e], st)

-- | Attempt to construct a sequence that has a specified contour. The
--   arguments are a <a>Build_f</a> to generate possible elements, a
--   <a>Contour_Description</a> that the result sequence must conform to,
--   an <a>Int</a> to specify the maximum number of elements to generate
--   when searching for a solution, and an initial state.
--   
--   <pre>
--   import System.Random
--   </pre>
--   
--   <pre>
--   let {f = Just . randomR ('a','z')
--       ;c = contour_description "atdez"
--       ;st = mkStdGen 2347}
--   in fst (build_contour f c 1024 st) == Just "nvruy"
--   </pre>
build_contour :: (Ord e) => Build_f st e -> Contour_Description -> Int -> st -> (Maybe [e], st)

-- | A variant on <a>build_contour</a> that retries a specified number of
--   times using the final state of the failed attempt as the state for the
--   next try.
--   
--   <pre>
--   let {f = Just . randomR ('a','z')
--       ;c = contour_description "atdezjh"
--       ;st = mkStdGen 2347}
--   in fst (build_contour_retry f c 64 8 st) == Just "nystzvu"
--   </pre>
build_contour_retry :: (Ord e) => Build_f st e -> Contour_Description -> Int -> Int -> st -> (Maybe [e], st)

-- | A variant on <a>build_contour_retry</a> that returns the set of all
--   sequences constructed.
--   
--   <pre>
--   let {f = Just . randomR ('a','z')
--       ;c = contour_description "atdezjh"
--       ;st = mkStdGen 2347}
--   in length (build_contour_set f c 64 64 st) == 60
--   </pre>
build_contour_set :: (Ord e) => Build_f st e -> Contour_Description -> Int -> Int -> st -> [[e]]

-- | Variant of <a>build_contour_set</a> that halts when an generated
--   sequence is a duplicate of an already generated sequence.
--   
--   <pre>
--   let {f = randomR ('a','f')
--       ;c = contour_description "cafe"
--       ;st = mkStdGen 2346836
--       ;r = build_contour_set_nodup f c 64 64 st}
--   in filter ("c" `isPrefixOf`) r == ["cafe","cbed","caed"]
--   </pre>
build_contour_set_nodup :: Ord e => Build_f st e -> Contour_Description -> Int -> Int -> st -> [[e]]

-- | Example from p.262 (quarter-note durations)
--   
--   <pre>
--   ex_1 == [2,3/2,1/2,1,2]
--   compare_adjacent ex_1 == [GT,GT,LT,LT]
--   show (contour_half_matrix ex_1) == "2221 220 00 0"
--   draw_contour (contour_description ex_1) == [3,2,0,1,3]
--   </pre>
--   
--   <pre>
--   let d = contour_description_invert (contour_description ex_1)
--   in (show d,is_possible d) == ("0001 002 22 2",True)
--   </pre>
ex_1 :: [Rational]

-- | Example on p.265 (pitch)
--   
--   <pre>
--   ex_2 == [0,5,3]
--   show (contour_description ex_2) == "00 2"
--   </pre>
ex_2 :: [Integer]

-- | Example on p.265 (pitch)
--   
--   <pre>
--   ex_3 == [12,7,6,7,8,7]
--   show (contour_description ex_3) == "22222 2101 000 01 2"
--   contour_description_ix (contour_description ex_3) (0,5) == GT
--   is_possible (contour_description ex_3) == True
--   </pre>
ex_3 :: [Integer]

-- | Example on p.266 (impossible)
--   
--   <pre>
--   show ex_4 == "2221 220 00 1"
--   is_possible ex_4 == False
--   violations ex_4 == [(0,3,4,GT),(1,3,4,GT)]
--   </pre>
ex_4 :: Contour_Description
instance GHC.Classes.Eq Music.Theory.Contour.Polansky_1992.Contour_Description
instance GHC.Classes.Eq Music.Theory.Contour.Polansky_1992.Contour_Half_Matrix
instance GHC.Show.Show Music.Theory.Contour.Polansky_1992.Contour_Half_Matrix
instance GHC.Show.Show Music.Theory.Contour.Polansky_1992.Contour_Description


-- | Larry Polansky. "Morphological Metrics". Journal of New Music
--   Research, 25(4):289-368, 1996.
module Music.Theory.Metric.Polansky_1996

-- | Distance function, ordinarily <i>n</i> below is in <a>Num</a>,
--   <a>Fractional</a> or <a>Real</a>.
type Interval a n = a -> a -> n

-- | <a>fromIntegral</a> <a>.</a> <a>-</a>.
dif_i :: (Integral a, Num b) => a -> a -> b

-- | <a>realToFrac</a> <a>.</a> <a>-</a>.
dif_r :: (Real a, Fractional b) => a -> a -> b

-- | <a>abs</a> <a>.</a> <i>f</i>.
abs_dif :: Num n => Interval a n -> a -> a -> n

-- | Square.
sqr :: Num a => a -> a

-- | <a>sqr</a> <a>.</a> <i>f</i>.
sqr_dif :: Num n => Interval a n -> a -> a -> n

-- | <a>sqr</a> <a>.</a> <a>abs</a> <a>.</a> <i>f</i>.
sqr_abs_dif :: Num n => Interval a n -> a -> a -> n

-- | <a>sqrt</a> <a>.</a> <a>abs</a> <a>.</a> <i>f</i>.
sqrt_abs_dif :: Floating c => Interval a c -> a -> a -> c

-- | City block metric, p.296
--   
--   <pre>
--   city_block_metric (-) (1,2) (3,5) == 2+3
--   </pre>
city_block_metric :: Num n => Interval a n -> (a, a) -> (a, a) -> n

-- | Two-dimensional euclidean metric, p.297.
--   
--   <pre>
--   euclidean_metric_2 (-) (1,2) (3,5) == sqrt (4+9)
--   </pre>
euclidean_metric_2 :: Floating n => Interval a n -> (a, a) -> (a, a) -> n

-- | <i>n</i>-dimensional euclidean metric
--   
--   <pre>
--   euclidean_metric_l (-) [1,2] [3,5] == sqrt (4+9)
--   euclidean_metric_l (-) [1,2,3] [2,4,6] == sqrt (1+4+9)
--   </pre>
euclidean_metric_l :: Floating c => Interval b c -> [b] -> [b] -> c

-- | Cube root.
--   
--   <pre>
--   map cbrt [1,8,27] == [1,2,3]
--   </pre>
cbrt :: Floating a => a -> a

-- | <i>n</i>-th root
--   
--   <pre>
--   map (nthrt 4) [1,16,81] == [1,2,3]
--   </pre>
nthrt :: Floating a => a -> a -> a

-- | Two-dimensional Minkowski metric, p.297
--   
--   <pre>
--   minkowski_metric_2 (-) 1 (1,2) (3,5) == 5
--   minkowski_metric_2 (-) 2 (1,2) (3,5) == sqrt (4+9)
--   minkowski_metric_2 (-) 3 (1,2) (3,5) == cbrt (8+27)
--   </pre>
minkowski_metric_2 :: Floating a => Interval t a -> a -> (t, t) -> (t, t) -> a

-- | <i>n</i>-dimensional Minkowski metric
--   
--   <pre>
--   minkowski_metric_l (-) 2 [1,2,3] [2,4,6] == sqrt (1+4+9)
--   minkowski_metric_l (-) 3 [1,2,3] [2,4,6] == cbrt (1+8+27)
--   </pre>
minkowski_metric_l :: Floating a => Interval t a -> a -> [t] -> [t] -> a

-- | Integration with <i>f</i>.
--   
--   <pre>
--   d_dx (-) [0,2,4,1,0] == [2,2,-3,-1]
--   d_dx (-) [2,3,0,4,1] == [1,-3,4,-3]
--   </pre>
d_dx :: Interval a n -> [a] -> [n]

-- | <a>map</a> <a>abs</a> <a>.</a> <a>d_dx</a>.
--   
--   <pre>
--   d_dx_abs (-) [0,2,4,1,0] == [2,2,3,1]
--   d_dx_abs (-) [2,3,0,4,1] == [1,3,4,3]
--   </pre>
d_dx_abs :: Num n => Interval a n -> [a] -> [n]

-- | Ordered linear magnitude (no delta), p.300
--   
--   <pre>
--   olm_no_delta' [0,2,4,1,0] [2,3,0,4,1] == 1.25
--   </pre>
olm_no_delta' :: Fractional a => [a] -> [a] -> a

-- | Ordered linear magintude (general form) p.302
--   
--   <pre>
--   olm_general (abs_dif (-)) [0,2,4,1,0] [2,3,0,4,1] == 1.25
--   olm_general (abs_dif (-)) [1,5,12,2,9,6] [7,6,4,9,8,1] == 4.6
--   </pre>
olm_general :: (Fractional a, Enum a, Fractional n) => Interval a n -> [a] -> [a] -> n

-- | <a>Delta</a> (Δ) determines an interval given a sequence and an index.
type Delta n a = [n] -> Int -> a

-- | <i>f</i> at indices <i>i</i> and <i>i+1</i> of <i>x</i>.
--   
--   <pre>
--   map (ix_dif (-) [0,1,3,6,10]) [0..3] == [-1,-2,-3,-4]
--   </pre>
ix_dif :: Interval a t -> Delta a t

-- | <a>abs</a> <a>.</a> <a>ix_dif</a>
--   
--   <pre>
--   map (abs_ix_dif (-) [0,2,4,1,0]) [0..3] == [2,2,3,1]
--   </pre>
abs_ix_dif :: Num n => Interval a n -> Delta a n

-- | <a>sqr</a> <a>.</a> <a>abs_ix_dif</a>
--   
--   <pre>
--   map (sqr_abs_ix_dif (-) [0,2,4,1,0]) [0..3] == [4,4,9,1]
--   map (sqr_abs_ix_dif (-) [2,3,0,4,1]) [0..3] == [1,9,16,9]
--   </pre>
sqr_abs_ix_dif :: Num n => Interval a n -> Delta a n

-- | <a>Psi</a> (Ψ) joins <a>Delta</a> equivalent intervals from
--   morphologies <i>m</i> and <i>n</i>.
type Psi a = a -> a -> a

-- | Ordered linear magintude (generalised-interval form) p.305
--   
--   <pre>
--   olm (abs_dif dif_r) (abs_ix_dif dif_r) (const 1) [1,5,12,2,9,6] [7,6,4,9,8,1] == 4.6
--   olm (abs_dif dif_r) (abs_ix_dif dif_r) maximum [1,5,12,2,9,6] [7,6,4,9,8,1] == 0.46
--   </pre>
olm :: (Fractional a, Enum a) => Psi a -> Delta n a -> ([a] -> a) -> [n] -> [n] -> a
olm_no_delta :: (Real a, Real n, Enum n, Fractional n) => [a] -> [a] -> n
olm_no_delta_squared :: (Enum a, Floating a) => [a] -> [a] -> a
second_order :: (Num n) => ([n] -> [n] -> t) -> [n] -> [n] -> t
olm_no_delta_second_order :: (Real a, Enum a, Fractional a) => [a] -> [a] -> a
olm_no_delta_squared_second_order :: (Enum a, Floating a) => [a] -> [a] -> a

-- | Second order binomial coefficient, p.307
--   
--   <pre>
--   map second_order_binonial_coefficient [2..10] == [1,3,6,10,15,21,28,36,45]
--   </pre>
second_order_binonial_coefficient :: Fractional a => a -> a

-- | <a>d_dx</a> of <a>flip</a> <a>compare</a>.
--   
--   <pre>
--   direction_interval [5,9,3,2] == [LT,GT,GT]
--   direction_interval [2,5,6,6] == [LT,LT,EQ]
--   </pre>
direction_interval :: Ord i => [i] -> [Ordering]

-- | Histogram of list of <a>Ordering</a>s.
--   
--   <pre>
--   ord_hist [LT,GT,GT] == (1,0,2)
--   </pre>
ord_hist :: Integral t => [Ordering] -> (t, t, t)

-- | Histogram of <i>directions</i> of adjacent elements, p.312.
--   
--   <pre>
--   direction_vector [5,9,3,2] == (1,0,2)
--   direction_vector [2,5,6,6] == (2,1,0)
--   </pre>
direction_vector :: Integral i => (Ord a) => [a] -> (i, i, i)

-- | Unordered linear direction, p.311 (Fig. 5)
--   
--   <pre>
--   uld [5,9,3,2] [2,5,6,6] == 2/3
--   uld [5,3,6,1,4] [3,6,1,4,2] == 0
--   </pre>
uld :: (Integral n, Ord a) => [a] -> [a] -> Ratio n

-- | Ordered linear direction, p.312
--   
--   <pre>
--   direction_interval [5,3,6,1,4] == [GT,LT,GT,LT]
--   direction_interval [3,6,1,4,2] == [LT,GT,LT,GT]
--   old [5,3,6,1,4] [3,6,1,4,2] == 1
--   </pre>
old :: (Ord i, Integral a) => [i] -> [i] -> Ratio a

-- | Ordered combinatorial direction, p.314
--   
--   <pre>
--   ocd [5,9,3,2] [2,5,6,6] == 5/6
--   ocd [5,3,6,1,4] [3,6,1,4,2] == 4/5
--   </pre>
ocd :: (Ord a, Integral i) => [a] -> [a] -> Ratio i

-- | Unordered combinatorial direction, p.314
--   
--   <pre>
--   ucd [5,9,3,2] [2,5,6,6] == 5/6
--   ucd [5,3,6,1,4] [3,6,1,4,2] == 0
--   ucd [5,3,7,6] [2,1,2,1] == 1/2
--   ucd [2,1,2,1] [8,3,5,4] == 1/3
--   ucd [5,3,7,6] [8,3,5,4] == 1/3
--   </pre>
ucd :: (Integral n, Ord a) => [a] -> [a] -> Ratio n

-- | <a>half_matrix_f</a>, Fig.9, p.318
--   
--   <pre>
--   let r = [[2,3,1,4]
--             ,[1,3,6]
--               ,[4,7]
--                 ,[3]]
--   in combinatorial_magnitude_matrix (abs_dif (-)) [5,3,2,6,9] == r
--   </pre>
combinatorial_magnitude_matrix :: Interval a n -> [a] -> [[n]]

-- | Unordered linear magnitude (simplified), p.320-321
--   
--   <pre>
--   let r = abs (sum [5,4,3,6] - sum [12,2,11,7]) / 4
--   in ulm_simplified (abs_dif (-)) [1,6,2,5,11] [3,15,13,2,9] == r
--   </pre>
--   
--   <pre>
--   ulm_simplified (abs_dif (-)) [1,5,12,2,9,6] [7,6,4,9,8,1] == 3
--   </pre>
ulm_simplified :: Fractional n => Interval a n -> [a] -> [a] -> n
ocm_zcm :: (Fractional n, Num a) => Interval a n -> [a] -> [a] -> (n, n, [n])

-- | Ordered combinatorial magnitude (OCM), p.323
--   
--   <pre>
--   ocm (abs_dif (-)) [1,6,2,5,11] [3,15,13,2,9] == 5.2
--   ocm (abs_dif (-)) [1,5,12,2,9,6] [7,6,4,9,8,1] == 3.6
--   </pre>
ocm :: (Fractional a, Enum a, Fractional n) => Interval a n -> [a] -> [a] -> n

-- | Ordered combinatorial magnitude (OCM), p.323
--   
--   <pre>
--   ocm_absolute_scaled (abs_dif (-)) [1,6,2,5,11] [3,15,13,2,9] == 0.4
--   ocm_absolute_scaled (abs_dif (-)) [1,5,12,2,9,6] [7,6,4,9,8,1] == 54/(15*11)
--   </pre>
ocm_absolute_scaled :: (Ord a, Fractional a, Enum a, Ord n, Fractional n) => Interval a n -> [a] -> [a] -> n


-- | Combination functions.
module Music.Theory.Combinations

-- | Number of <i>k</i> element combinations of a set of <i>n</i> elements.
--   
--   <pre>
--   (nk_combinations 6 3,nk_combinations 13 3) == (20,286)
--   </pre>
nk_combinations :: Integral a => a -> a -> a

-- | <i>k</i> element subsets of <i>s</i>.
--   
--   <pre>
--   combinations 3 [1..4] == [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
--   length (combinations 3 [1..5]) == nk_combinations 5 3
--   </pre>
combinations :: Integral t => t -> [a] -> [[a]]


-- | Common music notation clefs.
module Music.Theory.Clef

-- | Clef enumeration type.
data Clef_T
Bass :: Clef_T
Tenor :: Clef_T
Alto :: Clef_T
Treble :: Clef_T
Percussion :: Clef_T

-- | Clef with octave offset.
data Clef i
Clef :: Clef_T -> i -> Clef i
[clef_t] :: Clef i -> Clef_T
[clef_octave] :: Clef i -> i

-- | Give clef range as a <a>Pitch</a> pair indicating the notes below and
--   above the staff.
--   
--   <pre>
--   map clef_range [Treble,Bass] == [Just (d4,g5),Just (f2,b3)]
--   clef_range Percussion == Nothing
--   </pre>
clef_range :: Clef_T -> Maybe (Pitch, Pitch)

-- | Suggest a <a>Clef</a> given a <a>Pitch</a>.
--   
--   <pre>
--   map clef_suggest [c2,c4] == [Clef Bass (-1),Clef Treble 0]
--   </pre>
clef_suggest :: Integral i => Pitch -> Clef i

-- | Set <a>clef_octave</a> to <tt>0</tt>.
clef_zero :: Integral i => Clef i -> Clef i

-- | Set <a>clef_octave</a> to be no further than <i>r</i> from <tt>0</tt>.
clef_restrict :: Integral i => i -> Clef i -> Clef i
instance GHC.Show.Show i => GHC.Show.Show (Music.Theory.Clef.Clef i)
instance GHC.Classes.Ord i => GHC.Classes.Ord (Music.Theory.Clef.Clef i)
instance GHC.Classes.Eq i => GHC.Classes.Eq (Music.Theory.Clef.Clef i)
instance GHC.Show.Show Music.Theory.Clef.Clef_T
instance GHC.Classes.Ord Music.Theory.Clef.Clef_T
instance GHC.Classes.Eq Music.Theory.Clef.Clef_T

module Music.Theory.Instrument.Choir

-- | Voice types.
data Voice
Bass :: Voice
Tenor :: Voice
Alto :: Voice
Soprano :: Voice

-- | Single character abbreviation for <a>Voice</a>.
voice_abbrev :: Voice -> Char

-- | Standard <tt>Clef</tt> for <a>Voice</a>.
voice_clef :: Integral i => Voice -> Clef i

-- | Table giving ranges for <a>Voice</a>s.
type Voice_Rng_Tbl = [(Voice, (Pitch, Pitch))]

-- | More or less standard choir ranges, <i>inclusive</i>.
voice_rng_tbl_std :: Voice_Rng_Tbl

-- | More conservative ranges, <i>inclusive</i>.
voice_rng_tbl_safe :: Voice_Rng_Tbl

-- | Erroring variant.
lookup_err :: Eq a => a -> [(a, b)] -> b

-- | Lookup voice range table.
voice_rng :: Voice_Rng_Tbl -> Voice -> (Pitch, Pitch)

-- | Lookup <a>voice_rng_tbl_std</a>.
voice_rng_std :: Voice -> (Pitch, Pitch)

-- | Lookup <a>voice_rng_tbl_safe</a>.
voice_rng_safe :: Voice -> (Pitch, Pitch)

-- | Is <i>p</i> <a>&gt;=</a> <i>l</i> and <a>&lt;=</a> <i>r</i>.
in_range_inclusive :: Ord a => a -> (a, a) -> Bool

-- | Is <i>p</i> in range for <i>v</i>, (<i>std</i> &amp; <i>safe</i>).
--   
--   <pre>
--   map (in_voice_rng T.c4) [Bass .. Soprano]
--   </pre>
in_voice_rng :: Pitch -> Voice -> (Bool, Bool)

-- | Given <i>tbl</i> list <a>Voice</a>s that can sing <a>Pitch</a>.
possible_voices :: Voice_Rng_Tbl -> Pitch -> [Voice]

-- | <i>std</i> variant.
possible_voices_std :: Pitch -> [Voice]

-- | <i>safe</i> variant.
possible_voices_safe :: Pitch -> [Voice]

-- | Enumeration of SATB voices.
satb :: [Voice]

-- | Names of <a>satb</a>.
satb_name :: [String]

-- | <a>voice_abbrev</a> of <a>satb</a> as <a>String</a>s.
satb_abbrev :: [String]

-- | Voice &amp; part number.
type Part = (Voice, Int)

-- | <i>k</i> part choir, ordered by voice.
ch_satb_seq :: Int -> [Part]

-- | <a>ch_satb_seq</a> grouped in parts.
--   
--   <pre>
--   map (map part_nm) (ch_parts 8)
--   </pre>
ch_parts :: Int -> [[Part]]

-- | Abreviated name for part.
--   
--   <pre>
--   part_nm (Soprano,1) == "S1"
--   </pre>
part_nm :: Part -> String

-- | <i>k</i> SATB choirs, grouped by choir.
--   
--   <pre>
--   k_ch_groups 2
--   </pre>
k_ch_groups :: Int -> [[Part]]

-- | <a>concat</a> of <a>k_ch_groups</a>.
k_ch_groups' :: Int -> [Part]

-- | Two <i>k</i> part SATB choirs in score order.
--   
--   <pre>
--   map part_nm (concat (dbl_ch_parts 8))
--   </pre>
dbl_ch_parts :: Int -> [[Part]]

-- | <a>voice_clef</a> for <a>Part</a>s.
mk_clef_seq :: [Part] -> [Clef Int]
instance GHC.Show.Show Music.Theory.Instrument.Choir.Voice
instance GHC.Enum.Bounded Music.Theory.Instrument.Choir.Voice
instance GHC.Enum.Enum Music.Theory.Instrument.Choir.Voice
instance GHC.Classes.Ord Music.Theory.Instrument.Choir.Voice
instance GHC.Classes.Eq Music.Theory.Instrument.Choir.Voice


-- | Tom Johnson. "Networks". In Conference on Mathematics and Computation
--   in Music, Berlin, May 2007.
module Music.Theory.Block_Design.Johnson_2007
data Design i
Design :: [i] -> [[i]] -> Design i
c_7_3_1 :: (Num i) => [i]
b_7_3_1 :: (Ord i, Num i) => ([[i]], [[i]])
d_7_3_1 :: (Enum n, Ord n, Num n) => (Design n, Design n)
n_7_3_1 :: Num i => [(i, i)]
p_9_3_1 :: Num i => [[i]]
b_13_4_1 :: (Enum i, Num i, Ord i) => ([[i]], [[i]])
d_13_4_1 :: (Enum n, Ord n, Num n) => (Design n, Design n)
n_13_4_1 :: Num i => [(i, i)]
b_12_4_3 :: Integral i => [[i]]
n_12_4_3 :: Num i => [(i, i)]


-- | Godfried T. Toussaint et. al. "The distance geometry of music"
--   <i>Journal of Computational Geometry: Theory and Applications</i>
--   Volume 42, Issue 5, July, 2009
--   (<a>http://dx.doi.org/10.1016/j.comgeo.2008.04.005</a>)
module Music.Theory.Bjorklund

-- | Bjorklund's algorithm to construct a binary sequence of <i>n</i> bits
--   with <i>k</i> ones such that the <i>k</i> ones are distributed as
--   evenly as possible among the (<i>n</i> - <i>k</i>) zeroes.
--   
--   <pre>
--   bjorklund (5,9) == [True,False,True,False,True,False,True,False,True]
--   xdot (bjorklund (5,9)) == "x.x.x.x.x"
--   </pre>
--   
--   <pre>
--   let es = [(2,3),(2,5)
--            ,(3,4),(3,5),(3,8)
--            ,(4,7),(4,9),(4,12),(4,15)
--            ,(5,6),(5,7),(5,8),(5,9),(5,11),(5,12),(5,13),(5,16)
--            ,(6,7),(6,13)
--            ,(7,8),(7,9),(7,10),(7,12),(7,15),(7,16),(7,17),(7,18)
--            ,(8,17),(8,19)
--            ,(9,14),(9,16),(9,22),(9,23)
--            ,(11,12),(11,24)
--            ,(13,24)
--            ,(15,34)]
--   in map (\e -&gt; let e' = bjorklund e in (e,xdot e',iseq_str e')) es
--   </pre>
--   
--   <pre>
--   [((2,3),"xx.","(12)")
--   ,((2,5),"x.x..","(23)")
--   ,((3,4),"xxx.","(112)")
--   ,((3,5),"x.x.x","(221)")
--   ,((3,8),"x..x..x.","(332)")
--   ,((4,7),"x.x.x.x","(2221)")
--   ,((4,9),"x.x.x.x..","(2223)")
--   ,((4,12),"x..x..x..x..","(3333)")
--   ,((4,15),"x...x...x...x..","(4443)")
--   ,((5,6),"xxxxx.","(11112)")
--   ,((5,7),"x.xx.xx","(21211)")
--   ,((5,8),"x.xx.xx.","(21212)")
--   ,((5,9),"x.x.x.x.x","(22221)")
--   ,((5,11),"x.x.x.x.x..","(22223)")
--   ,((5,12),"x..x.x..x.x.","(32322)")
--   ,((5,13),"x..x.x..x.x..","(32323)")
--   ,((5,16),"x..x..x..x..x...","(33334)")
--   ,((6,7),"xxxxxx.","(111112)")
--   ,((6,13),"x.x.x.x.x.x..","(222223)")
--   ,((7,8),"xxxxxxx.","(1111112)")
--   ,((7,9),"x.xxx.xxx","(2112111)")
--   ,((7,10),"x.xx.xx.xx","(2121211)")
--   ,((7,12),"x.xx.x.xx.x.","(2122122)")
--   ,((7,15),"x.x.x.x.x.x.x..","(2222223)")
--   ,((7,16),"x..x.x.x..x.x.x.","(3223222)")
--   ,((7,17),"x..x.x..x.x..x.x.","(3232322)")
--   ,((7,18),"x..x.x..x.x..x.x..","(3232323)")
--   ,((8,17),"x.x.x.x.x.x.x.x..","(22222223)")
--   ,((8,19),"x..x.x.x..x.x.x..x.","(32232232)")
--   ,((9,14),"x.xx.xx.xx.xx.","(212121212)")
--   ,((9,16),"x.xx.x.x.xx.x.x.","(212221222)")
--   ,((9,22),"x..x.x..x.x..x.x..x.x.","(323232322)")
--   ,((9,23),"x..x.x..x.x..x.x..x.x..","(323232323)")
--   ,((11,12),"xxxxxxxxxxx.","(11111111112)")
--   ,((11,24),"x..x.x.x.x.x..x.x.x.x.x.","(32222322222)")
--   ,((13,24),"x.xx.x.x.x.x.xx.x.x.x.x.","(2122222122222)")
--   ,((15,34),"x..x.x.x.x..x.x.x.x..x.x.x.x..x.x.","(322232223222322)")]
--   </pre>
bjorklund :: (Int, Int) -> [Bool]

-- | <i>xdot</i> notation for pattern.
--   
--   <pre>
--   xdot (bjorklund (5,9)) == "x.x.x.x.x"
--   </pre>
xdot :: [Bool] -> String

-- | The <a>iseq</a> of a pattern is the distance between <a>True</a>
--   values.
--   
--   <pre>
--   iseq (bjorklund (5,9)) == [2,2,2,2,1]
--   </pre>
iseq :: [Bool] -> [Int]

-- | <a>iseq</a> of pattern as compact string.
--   
--   <pre>
--   iseq_str (bjorklund (5,9)) == "(22221)"
--   </pre>
iseq_str :: [Bool] -> String


-- | Regular array data as markdown (MD) tables.
module Music.Theory.Array.MD

-- | Append <i>k</i> to the right of <i>l</i> until result has <i>n</i>
--   places.
pad_right :: a -> Int -> [a] -> [a]

-- | Append <i>k</i> to each row of <i>tbl</i> as required to be regular
--   (all rows equal length).
make_regular :: a -> [[a]] -> [[a]]

-- | Delete trailing <a>Char</a> where <a>isSpace</a> holds.
delete_trailing_whitespace :: [Char] -> [Char]

-- | Optional header row then data rows.
type MD_Table t = (Maybe [String], [[t]])

-- | Join second table to right of initial table.
md_table_join :: MD_Table a -> MD_Table a -> MD_Table a

-- | Add a row number column at the front of the table.
md_number_rows :: MD_Table String -> MD_Table String

-- | Markdown table, perhaps with header. Table is in row order. Options
--   are: <i>pad_left</i>.
--   
--   <pre>
--   md_table_opt False (Nothing,[["a","bc","def"],["ghij","klm","no","p"]])
--   </pre>
md_table_opt :: Bool -> MD_Table String -> [String]
md_table' :: MD_Table String -> [String]

-- | <a>curry</a> of <a>md_table'</a>.
md_table :: Maybe [String] -> [[String]] -> [String]

-- | Variant relying on <a>Show</a> instances.
--   
--   <pre>
--   md_table_show Nothing [[1..4],[5..8],[9..12]]
--   </pre>
md_table_show :: Show t => Maybe [String] -> [[t]] -> [String]

-- | Variant in column order (ie. <a>transpose</a>).
--   
--   <pre>
--   md_table_column_order [["a","bc","def"],["ghij","klm","no"]]
--   </pre>
md_table_column_order :: Maybe [String] -> [[String]] -> [String]

-- | Two-tuple <a>show</a> variant.
md_table_p2 :: (Show a, Show b) => Maybe [String] -> ([a], [b]) -> [String]

-- | Three-tuple <a>show</a> variant.
md_table_p3 :: (Show a, Show b, Show c) => Maybe [String] -> ([a], [b], [c]) -> [String]

-- | Matrix form, ie. header in both first row and first column, in each
--   case displaced by one location which is empty.
--   
--   <pre>
--   let t = md_matrix "" (map return "abc") (map (map show) [[1,2,3],[2,3,1],[3,1,2]])
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putStrLn $ unlines $ md_table' t
--   - - - -
--     a b c
--   a 1 2 3
--   b 2 3 1
--   c 3 1 2
--   - - - -
--   </pre>
md_matrix :: a -> [a] -> [[a]] -> MD_Table a

-- | Variant for <a>String</a> tables where <i>nil</i> is the empty string
--   and the header cells are in bold.
md_matrix_bold :: [String] -> [[String]] -> MD_Table String


-- | Regular matrix array data, CSV, column &amp; row indexing.
module Music.Theory.Array.CSV

-- | <tt>A</tt> indexed case-insensitive column references. The column
--   following <tt>Z</tt> is <tt>AA</tt>.
data Column_Ref
Column_Ref :: String -> Column_Ref
[column_ref_string] :: Column_Ref -> String

-- | Inclusive range of column references.
type Column_Range = (Column_Ref, Column_Ref)

-- | <tt>1</tt>-indexed row reference.
type Row_Ref = Int

-- | Zero index of <a>Row_Ref</a>.
row_index :: Row_Ref -> Int

-- | Inclusive range of row references.
type Row_Range = (Row_Ref, Row_Ref)

-- | Cell reference, column then row.
type Cell_Ref = (Column_Ref, Row_Ref)

-- | Inclusive range of cell references.
type Cell_Range = (Cell_Ref, Cell_Ref)

-- | Case folding letter to index function. Only valid for ASCII letters.
--   
--   <pre>
--   map letter_index ['A' .. 'Z'] == [0 .. 25]
--   map letter_index ['a','d' .. 'm'] == [0,3 .. 12]
--   </pre>
letter_index :: Char -> Int

-- | Inverse of <a>letter_index</a>.
--   
--   <pre>
--   map index_letter [0,3 .. 12] == ['A','D' .. 'M']
--   </pre>
index_letter :: Int -> Char

-- | Translate column reference to <tt>0</tt>-index.
--   
--   <pre>
--   :set -XOverloadedStrings
--   map column_index ["A","c","z","ac","XYZ"] == [0,2,25,28,17575]
--   </pre>
column_index :: Column_Ref -> Int

-- | Column reference to interior index within specified range. Type
--   specialised <a>index</a>.
--   
--   <pre>
--   map (Data.Ix.index ('A','Z')) ['A','C','Z'] == [0,2,25]
--   map (interior_column_index ("A","Z")) ["A","C","Z"] == [0,2,25]
--   </pre>
--   
--   <pre>
--   map (Data.Ix.index ('B','C')) ['B','C'] == [0,1]
--   map (interior_column_index ("B","C")) ["B","C"] == [0,1]
--   </pre>
interior_column_index :: Column_Range -> Column_Ref -> Int

-- | Inverse of <a>column_index</a>.
--   
--   <pre>
--   let c = ["A","Z","AA","AZ","BA","BZ","CA"]
--   in map column_ref [0,25,26,51,52,77,78] == c
--   </pre>
--   
--   <pre>
--   column_ref (0+25+1+25+1+25+1) == "CA"
--   </pre>
column_ref :: Int -> Column_Ref

-- | Type specialised <a>pred</a>.
--   
--   <pre>
--   column_ref_pred "DF" == "DE"
--   </pre>
column_ref_pred :: Column_Ref -> Column_Ref

-- | Type specialised <a>succ</a>.
--   
--   <pre>
--   column_ref_succ "DE" == "DF"
--   </pre>
column_ref_succ :: Column_Ref -> Column_Ref

-- | Bimap of <a>column_index</a>.
--   
--   <pre>
--   column_indices ("b","p") == (1,15)
--   column_indices ("B","IT") == (1,253)
--   </pre>
column_indices :: Column_Range -> (Int, Int)

-- | Type specialised <a>range</a>.
--   
--   <pre>
--   column_range ("L","R") == ["L","M","N","O","P","Q","R"]
--   Data.Ix.range ('L','R') == "LMNOPQR"
--   </pre>
column_range :: Column_Range -> [Column_Ref]

-- | Type specialised <a>inRange</a>.
--   
--   <pre>
--   map (column_in_range ("L","R")) ["A","N","Z"] == [False,True,False]
--   map (column_in_range ("L","R")) ["L","N","R"] == [True,True,True]
--   </pre>
--   
--   <pre>
--   map (Data.Ix.inRange ('L','R')) ['A','N','Z'] == [False,True,False]
--   map (Data.Ix.inRange ('L','R')) ['L','N','R'] == [True,True,True]
--   </pre>
column_in_range :: Column_Range -> Column_Ref -> Bool

-- | Type specialised <a>rangeSize</a>.
--   
--   <pre>
--   map column_range_size [("A","Z"),("AA","ZZ")] == [26,26 * 26]
--   Data.Ix.rangeSize ('A','Z') == 26
--   </pre>
column_range_size :: Column_Range -> Int

-- | Type specialised <a>range</a>.
row_range :: Row_Range -> [Row_Ref]

-- | The standard uppermost leftmost cell reference, <tt>A1</tt>.
--   
--   <pre>
--   Just cell_ref_minima == parse_cell_ref "A1"
--   </pre>
cell_ref_minima :: Cell_Ref

-- | Cell reference parser for standard notation of (column,row).
--   
--   <pre>
--   parse_cell_ref "CC348" == Just ("CC",348)
--   </pre>
parse_cell_ref :: String -> Maybe Cell_Ref

-- | Cell reference pretty printer.
--   
--   <pre>
--   cell_ref_pp ("CC",348) == "CC348"
--   </pre>
cell_ref_pp :: Cell_Ref -> String

-- | Translate cell reference to <tt>0</tt>-indexed pair.
--   
--   <pre>
--   cell_index ("CC",348) == (80,347)
--   Data.Ix.index (("AA",1),("ZZ",999)) ("CC",348) == 54293
--   </pre>
cell_index :: Cell_Ref -> (Int, Int)

-- | Type specialised <a>range</a>, cells are in column-order.
--   
--   <pre>
--   cell_range (("AA",1),("AC",1)) == [("AA",1),("AB",1),("AC",1)]
--   </pre>
--   
--   <pre>
--   let r = [("AA",1),("AA",2),("AB",1),("AB",2),("AC",1),("AC",2)]
--   in cell_range (("AA",1),("AC",2)) == r
--   </pre>
--   
--   <pre>
--   Data.Ix.range (('A',1),('C',1)) == [('A',1),('B',1),('C',1)]
--   </pre>
--   
--   <pre>
--   let r = [('A',1),('A',2),('B',1),('B',2),('C',1),('C',2)]
--   in Data.Ix.range (('A',1),('C',2)) == r
--   </pre>
cell_range :: Cell_Range -> [Cell_Ref]

-- | Variant of <a>cell_range</a> in row-order.
--   
--   <pre>
--   let r = [(AA,1),(AB,1),(AC,1),(AA,2),(AB,2),(AC,2)]
--   in cell_range_row_order (("AA",1),("AC",2)) == r
--   </pre>
cell_range_row_order :: Cell_Range -> [Cell_Ref]

-- | When reading a CSV file is the first row a header?
type CSV_Has_Header = Bool
type CSV_Delimiter = Char
type CSV_Allow_Linebreaks = Bool

-- | When writing a CSV file should the delimiters be aligned, ie. should
--   columns be padded with spaces, and if so at which side of the data?
data CSV_Align_Columns
CSV_No_Align :: CSV_Align_Columns
CSV_Align_Left :: CSV_Align_Columns
CSV_Align_Right :: CSV_Align_Columns

-- | CSV options.
type CSV_Opt = (CSV_Has_Header, CSV_Delimiter, CSV_Allow_Linebreaks, CSV_Align_Columns)

-- | Default CSV options, no header, comma delimiter, no linebreaks, no
--   alignment.
def_csv_opt :: CSV_Opt

-- | Plain list representation of a two-dimensional table of <i>a</i> in
--   row-order. Tables are regular, ie. all rows have equal numbers of
--   columns.
type Table a = [[a]]

-- | CSV table, ie. a table with perhaps a header.
type CSV_Table a = (Maybe [String], Table a)

-- | Read <a>Table</a> from <tt>CSV</tt> file.
csv_table_read :: CSV_Opt -> (String -> a) -> FilePath -> IO (CSV_Table a)

-- | Read <a>Table</a> only with <a>def_csv_opt</a>.
csv_table_read' :: (String -> a) -> FilePath -> IO (Table a)

-- | Read and process <tt>CSV</tt> <a>Table</a>.
csv_table_with :: CSV_Opt -> (String -> a) -> FilePath -> (CSV_Table a -> b) -> IO b
csv_table_align :: CSV_Align_Columns -> Table String -> Table String

-- | Write <a>Table</a> to <tt>CSV</tt> file.
csv_table_write :: (a -> String) -> CSV_Opt -> FilePath -> CSV_Table a -> IO ()

-- | Write <a>Table</a> only (no header).
csv_table_write' :: (a -> String) -> CSV_Opt -> FilePath -> Table a -> IO ()

-- | <tt>0</tt>-indexed (row,column) cell lookup.
table_lookup :: Table a -> (Int, Int) -> a

-- | Row data.
table_row :: Table a -> Row_Ref -> [a]

-- | Column data.
table_column :: Table a -> Column_Ref -> [a]

-- | Lookup value across columns.
table_column_lookup :: Eq a => Table a -> (Column_Ref, Column_Ref) -> a -> Maybe a

-- | Table cell lookup.
table_cell :: Table a -> Cell_Ref -> a

-- | <tt>0</tt>-indexed (row,column) cell lookup over column range.
table_lookup_row_segment :: Table a -> (Int, (Int, Int)) -> [a]

-- | Range of cells from row.
table_row_segment :: Table a -> (Row_Ref, Column_Range) -> [a]

-- | Translate <a>Table</a> to <a>Array</a>. It is assumed that the
--   <a>Table</a> is regular, ie. all rows have an equal number of columns.
--   
--   <pre>
--   let a = table_to_array [[0,1,3],[2,4,5]]
--   in (bounds a,indices a,elems a)
--   </pre>
--   
--   <pre>
--   &gt; (((A,1),(C,2))
--   &gt; ,[(A,1),(A,2),(B,1),(B,2),(C,1),(C,2)]
--   &gt; ,[0,2,1,4,3,5])
--   </pre>
table_to_array :: Table a -> Array Cell_Ref a

-- | <a>table_to_array</a> of <a>csv_table_read</a>.
csv_array_read :: CSV_Opt -> (String -> a) -> FilePath -> IO (Array Cell_Ref a)
instance Data.String.IsString Music.Theory.Array.CSV.Column_Ref
instance GHC.Read.Read Music.Theory.Array.CSV.Column_Ref
instance GHC.Show.Show Music.Theory.Array.CSV.Column_Ref
instance GHC.Classes.Eq Music.Theory.Array.CSV.Column_Ref
instance GHC.Classes.Ord Music.Theory.Array.CSV.Column_Ref
instance GHC.Enum.Enum Music.Theory.Array.CSV.Column_Ref
instance GHC.Arr.Ix Music.Theory.Array.CSV.Column_Ref


-- | Functions for reading midi note data from CSV files.
module Music.Theory.Array.CSV.Midi

-- | Variant of <a>reads</a> requiring exact match.
reads_exact :: Read a => String -> Maybe a

-- | Variant of <a>reads_exact</a> that errors on failure.
reads_err :: Read a => String -> a

-- | The required header field.
csv_midi_note_data_hdr :: [String]

-- | Midi note data, header is <tt>time,on/off,note,velocity</tt>.
--   Translation values for on/off are consulted.
--   
--   <pre>
--   let fn = "/home/rohan/cvs/uc/uc-26/daily-practice/2014-08-13.1.csv"
--   csv_midi_note_data_read' ("ON","OFF") fn :: IO [(Double,Either String String,Double,Double)]
--   </pre>
csv_midi_note_data_read' :: (Read t, Real t, Read n, Real n) => (m, m) -> FilePath -> IO [(t, Either m String, n, n)]

-- | Variant of <a>csv_midi_note_data_read'</a> that errors on non on/off
--   data.
csv_midi_note_data_read :: (Read t, Real t, Read n, Real n) => (m, m) -> FilePath -> IO [(t, m, n, n)]

-- | <tt>Tseq</tt> form of <tt>csv_read_midi_note_data</tt>.
midi_tseq_read :: (Read t, Real t, Read n, Real n) => FilePath -> IO (Tseq t (On_Off (n, n)))

-- | Translate from <tt>Tseq</tt> form to <tt>Wseq</tt> form.
midi_tseq_to_midi_wseq :: (Num t, Eq n) => Tseq t (On_Off (n, n)) -> Wseq t (n, n)

-- | Off-velocity is zero.
midi_wseq_to_midi_tseq :: (Num t, Ord t) => Wseq t (n, n) -> Tseq t (On_Off (n, n))

-- | Writer.
csv_midi_note_data_write :: (Eq m, Show t, Real t, Show n, Real n) => (m, m) -> FilePath -> [(t, m, n, n)] -> IO ()

-- | <tt>Tseq</tt> form of <a>csv_midi_note_data_write</a>.
midi_tseq_write :: (Show t, Real t, Show n, Real n) => FilePath -> Tseq t (On_Off (n, n)) -> IO ()
