module Music.Theory.Duration.RQ.Division where
import Data.List.Split
import Data.Ratio
import Music.Theory.Duration.RQ
import Music.Theory.Duration.RQ.Tied
import Music.Theory.List
import Music.Theory.Permutations.List
type RQ_Div = (Rational,Integer,[Integer],Tied_Right)
type RQ1_Div = (Integer,[Integer],Tied_Right)
rq1_div_to_rq_div :: RQ1_Div -> RQ_Div
rq1_div_to_rq_div (i,j,k) = (1,i,j,k)
rq_div_verify :: RQ_Div -> Bool
rq_div_verify (_,n,m,_) = n == sum m
rq_div_mm_verify :: Int -> [RQ_Div] -> [(Integer,[RQ])]
rq_div_mm_verify n x =
let q = map (sum . fst . rq_div_to_rq_set_t) x
in zip [1..] (chunksOf n q)
rq_div_to_rq_set_t :: RQ_Div -> ([RQ],Tied_Right)
rq_div_to_rq_set_t (n,k,d,t) =
let q = map ((* n) . (% k)) d
in (q,t)
rq_set_t_to_rqt :: ([RQ],Tied_Right) -> [RQ_T]
rq_set_t_to_rqt (x,t) = at_last (\i -> (i,False)) (\i -> (i,t)) x
rq_div_seq_rq :: [RQ_Div] -> [RQ]
rq_div_seq_rq =
let f i qq = case qq of
[] -> maybe [] return i
q:qq' -> let (r,t) = rq_div_to_rq_set_t q
r' = maybe r (\j -> at_head (+ j) id r) i
in if t
then let (r'',i') = separate_last r'
in r'' ++ f (Just i') qq'
else r' ++ f Nothing qq'
in f Nothing
partitions_sum :: Integral i => i -> [[i]]
partitions_sum n =
let f p = if null p then 0 else head p
in case n of
0 -> [[]]
_ -> [x:y | x <- [1..n], y <- partitions_sum (n x), x >= f y]
partitions_sum_p :: Integral i => i -> [[i]]
partitions_sum_p = concatMap multiset_permutations . partitions_sum
rq1_div_univ :: Integer -> [RQ1_Div]
rq1_div_univ n =
let f l = [(n,l,k) | k <- [False,True]]
in concatMap f (partitions_sum_p n)