-- | Robert Morris and D. Starr. \"The Structure of All-Interval Series\". -- /Journal of Music Theory/, 18:364-389, 1974. module Music.Theory.Z12.Morris_1974 where import Control.Monad.Logic {- logict -} -- | 'msum' '.' 'map' 'return'. -- -- > observeAll (fromList [1..7]) == [1..7] fromList :: MonadPlus m => [a] -> m a fromList = msum . map return -- | 'MonadPlus' all-interval series. -- -- > [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] all_interval_m :: MonadPlus m => Int -> m [Int] all_interval_m n = let rec p q = if length p == n then return (reverse p) else do i <- fromList [1 .. n - 1] guard (i `notElem` p) let j:_ = p m = abs ((i - j) `mod` n) guard (m `notElem` q) rec (i:p) (m:q) in rec [0] [] -- | 'observeAll' of 'all_interval_m'. -- -- > 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 all_interval :: Int -> [[Int]] all_interval = observeAll . all_interval_m