module Sym.Perm.SSYT
(
GeneralizedPerm
, Entry
, SSYT
, SSYTPair (..)
, Shape (..)
, empty
, null
, display
, fromPerm
, fromGeneralizedPerm
, toPerm
, toGeneralizedPerm
) where
import Prelude hiding (null)
import Data.List hiding (null)
import Sym.Perm
type Row = Int
type Entry = Int
type GeneralizedPerm = [(Int, Int)]
type SSYT = [[Entry]]
data SSYTPair = SSYTPair { insertionTableau :: SSYT
, recordingTableau :: SSYT
} deriving Eq
class Shape a where
shape :: a -> [Int]
instance Shape SSYT where
shape = map length
instance Shape SSYTPair where
shape = shape . recordingTableau
empty :: SSYTPair
empty = SSYTPair [] []
null :: SSYTPair -> Bool
null pq = pq == empty
instance Show SSYTPair where
show (SSYTPair p q) = unwords ["SSYTPair", show p, show q]
display :: SSYTPair -> String
display pq@(SSYTPair p q)
| null pq = "[] []"
| otherwise = intercalate "\n" $ zipWith (++) (pad p') q'
where
p'@(r:_) = map show p
q' = map show q
pad = map $ \s -> take (1+length r) (s ++ repeat ' ')
insertP :: SSYT -> Entry -> (SSYT, Row)
insertP [] k = ([[k]], 1)
insertP (r:rs) k =
let (smaller, larger) = span (<=k) r
in case larger of
[] -> ((r++[k]):rs, 1)
c:cs -> let (rs', i) = insertP rs c
in ((smaller ++ k:cs) : rs', i+1)
insertQ :: SSYT -> Row -> Entry -> SSYT
insertQ [] _ j = [[j]]
insertQ (r:rs) 1 j = (r ++ [j]) : rs
insertQ (r:rs) i j = r : insertQ rs (i1) j
insertPQ :: SSYTPair -> (Entry, Entry) -> SSYTPair
insertPQ (SSYTPair p q) (i,j) =
let (p',k) = insertP p j in SSYTPair p' (insertQ q k i)
trim :: SSYT -> SSYT
trim = takeWhile (/=[])
removeP :: SSYT -> Row -> (SSYT, Entry)
removeP p k = (trim $ reverse vs ++ [init t] ++ p2, e)
where
(p1, p2) = splitAt (k+1) p
(t : ts) = reverse p1
(vs, e) = unbump (last t) ts
unbump x [] = ([], x)
unbump x (r:rs) =
let (r1, r2) = span (<x) r
(us, y) = unbump (last r1) rs
in ((init r1 ++ x:r2) : us, y)
removeQ :: SSYT -> (SSYT, Row, Entry)
removeQ q = (trim q', k, e)
where
f = foldl (\(_,n) x -> (x,n+1)) (0,0) :: [Int] -> (Int, Int)
((e, _), k) = maximum $ zip (map f q) [0..]
q' = [ if i == k then init r else r | (r,i) <- zip q [0..] ]
removePQ :: SSYTPair -> (SSYTPair, (Entry, Entry))
removePQ (SSYTPair p q) = (SSYTPair p' q', (e1, e2))
where
(q', k, e1) = removeQ q
(p', e2) = removeP p k
fromGeneralizedPerm :: GeneralizedPerm -> SSYTPair
fromGeneralizedPerm = foldl insertPQ empty
fromPerm :: Perm -> SSYTPair
fromPerm = fromGeneralizedPerm . zip [0..] . map fromIntegral . toList
toGeneralizedPerm :: SSYTPair -> GeneralizedPerm
toGeneralizedPerm = go []
where
go ijs pq | null pq = ijs
| otherwise = let (rs,ij) = removePQ pq in go (ij:ijs) rs
toPerm :: SSYTPair -> Perm
toPerm = fromList . map (fromIntegral . snd) . toGeneralizedPerm