-
Notifications
You must be signed in to change notification settings - Fork 0
/
Sym.hs
134 lines (115 loc) · 3.89 KB
/
Sym.hs
1
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
-- |
-- Copyright : Anders Claesson 2013
-- Maintainer : Anders Claesson <anders.claesson@gmail.com>
--
module Sym
(
Permutation(..)
, perms
, lift
, lift2
) where
import Data.Ord
import Sym.Perm.SSYT (SSYTPair (..))
import qualified Sym.Perm.SSYT as Y
import Data.List
import Sym.Perm.Meta (Perm)
import qualified Sym.Perm.Meta as P
import qualified Sym.Perm.D8 as D8
-- The permutation typeclass
-- -------------------------
-- | The class of permutations. Minimal complete definition: 'st',
-- 'act' and 'idperm'. The default implementation of 'size' can be
-- somewhat slow, so you may want to implement it as well.
class Permutation a where
-- | The standardization map. If there is an underlying linear
-- order on @a@ then @st@ is determined by the unique order
-- preserving map from @[0..]@ to that order. In any case, the
-- standardization map should be equivariant with respect to the
-- group action defined below; i.e., it should hold that
--
-- > st (u `act` v) == u `act` st v
--
st :: a -> Perm
-- | A (left) /group action/ of 'Perm' on @a@. As for any group
-- action it should hold that
--
-- > (u `act` v) `act` w == u `act` (v `act` w) && idperm n `act` v == v
--
-- where @v,w::a@ and @u::Perm@ are of size @n@.
act :: Perm -> a -> a
-- | The size of a permutation. The default implementation derived from
--
-- > size == size . st
--
-- This is not a circular definition as 'size' on 'Perm' is
-- implemented independently. If the implementation of 'st' is
-- slow, then it can be worth while to override the standard
-- definiton; any implementation should, however, satisfy the
-- identity above.
{-# INLINE size #-}
size :: a -> Int
size = P.size . st
-- | The identity permutation of the given size.
idperm :: Int -> a
-- | The group theoretical inverse. It should hold that
--
-- > inverse == unst . inverse . st
--
-- and this is the default implementation.
{-# INLINE inverse #-}
inverse :: a -> a
inverse = unst . D8.inverse . st
-- | Predicate determining if two permutations are
-- order-isomorphic. The default implementation uses
--
-- > u `ordiso` v == u == st v
--
-- Equivalently, one could use
--
-- > u `ordiso` v == inverse u `act` v == idperm (size u)
--
{-# INLINE ordiso #-}
ordiso :: Perm -> a -> Bool
ordiso u v = u == st v
-- | The inverse of 'st'. It should hold that
--
-- > unst w == w `act` idperm (P.size w)
--
-- and this is the default implementation.
unst :: Perm -> a
unst w = w `act` idperm (P.size w)
instance Permutation Perm where
st = id
act = P.act
idperm = P.idperm
inverse = D8.inverse
ordiso = (==)
unst = id
-- | A String viewed as a permutation of its characters. The alphabet
-- is ordered as
--
-- > ['1'..'9'] ++ ['A'..'Z'] ++ ['a'..]
--
instance Permutation String where
st = P.mkPerm
act v = map snd . sortBy (comparing fst) . zip (P.toList (D8.inverse v))
size = length
idperm n = take n $ ['1'..'9'] ++ ['A'..'Z'] ++ ['a'..]
instance Permutation SSYTPair where
st = Y.toPerm
unst = Y.fromPerm
u `act` v = unst $ u `act` st v
size (SSYTPair p _) = sum $ map length p
idperm n = SSYTPair p p where p = [[0..n-1]]
inverse (SSYTPair p q) = SSYTPair q p
-- | The list of all permutations of the given size.
perms :: Permutation a => Int -> [a]
perms = map unst . P.perms
-- | Lifts a function on 'Perm's to one on any permutations.
lift :: (Permutation a) => (Perm -> Perm) -> a -> a
lift f = unst . f . st
-- | Like 'lift' but for functions of two variables.
lift2 :: (Permutation a) => (Perm -> Perm -> Perm) -> a -> a -> a
lift2 f u v = unst $ f (st u) (st v)