sym 0.2.3 → 0.3
raw patch · 7 files changed
+198/−120 lines, 7 files
Files
- Math/Sym.hs +84/−48
- Math/Sym/Internal.hs +8/−0
- Math/Sym/Stat.hs +7/−1
- cbits/stat.c +13/−0
- include/stat.h +7/−2
- sym.cabal +1/−1
- tests/Properties.hs +78/−68
Math/Sym.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE FlexibleInstances #-}+ -- | -- Module : Math.Sym -- Copyright : (c) Anders Claesson 2012@@ -28,9 +30,9 @@ , generalize -- :: Perm a => (StPerm -> StPerm) -> a -> a -- * Generating permutations- , unrankPerm -- :: Perm a => a -> Integer -> a- , randomPerm -- :: Perm a => a -> IO a- , perms -- :: Perm a => a -> [a]+ , unrankPerm -- :: Perm a => Int -> Integer -> a+ , randomPerm -- :: Perm a => Int -> IO a+ , perms -- :: Perm a => Int -> [a] -- * Sorting operators , stackSort -- :: Perm a => a -> a@@ -42,9 +44,11 @@ , avoiders -- :: Perm a => [StPerm] -> [a] -> [a] , av -- :: [StPerm] -> Int -> [StPerm] - -- * Single point deletions+ -- * Single point extensions and deletions , del -- :: Perm a => Int -> a -> a , shadow -- :: (Ord a, Perm a) => a -> [a]+ , ext -- :: Perm a => Int -> a -> a+ , coshadow -- :: (Ord a, Perm a) => a -> [a] -- * Simple permutations , simple -- :: Perm a => a -> Bool@@ -60,7 +64,10 @@ import Data.Bits (Bits, bitSize, testBit, popCount, shiftL) import Data.List (sort, sortBy, group) import Data.Vector.Storable (Vector)-import qualified Data.Vector.Storable as SV (Vector, toList, fromList, fromListN, empty, map, (++))+import qualified Data.Vector.Storable as SV+ ( Vector, toList, fromList, fromListN, empty, singleton+ , length, map, concat, splitAt+ ) import qualified Math.Sym.Internal as I import Foreign.C.Types (CUInt(..)) @@ -82,7 +89,7 @@ instance Monoid StPerm where mempty = fromVector SV.empty- mappend u v = fromVector $ (SV.++) u' v'+ mappend u v = fromVector $ SV.concat [u', v'] where u' = toVector u v' = SV.map ( + size u) $ toVector v@@ -112,7 +119,7 @@ -- | The /skew sum/ of two permutations. (A definition of the -- /direct sum/ is provided by 'mappend' of the 'Monoid' instance for 'StPerm'.) (/-/) :: StPerm -> StPerm -> StPerm-u /-/ v = fromVector $ (SV.++) u' v'+u /-/ v = fromVector $ SV.concat [u', v'] where u' = SV.map ( + size v) $ toVector u v' = toVector v@@ -136,9 +143,10 @@ -- The permutation typeclass -- ------------------------- --- | The class of permutations. Minimal complete definition: 'st' and--- 'act'. The default implementations of 'size' and 'idperm' can be--- somewhat slow, so you may want to implement them as well.+-- | The class of permutations. Minimal complete definition: 'st'+-- 'act' and 'idperm'. The default implementations of 'size' and+-- 'neutralize' can be somewhat slow, so you may want to implement+-- them as well. class Perm a where -- | The standardization map. If there is an underlying linear@@ -154,7 +162,7 @@ -- | A (left) /group action/ of 'StPerm' on @a@. As for any group -- action it should hold that -- - -- > (u `act` v) `act` w == u `act` (v `act` w) && idperm u `act` v == v+ -- > (u `act` v) `act` w == u `act` (v `act` w) && neutralize u `act` v == v -- act :: StPerm -> a -> a @@ -171,29 +179,31 @@ size :: a -> Int size = size . st - -- | The identity permutation on the same underlying set as the- -- given permutation. It should hold that- -- - -- > st (idperm u) == idperm (st u)- -- - -- Group theoretically, it should also hold that @u . inverse u ==- -- idperm u@. In terms of the group action this means+ -- | The identity permutation of the given size.+ idperm :: Int -> a++ -- | The permutation obtained by acting on the given permutation+ -- with its own inverse; that is, the identity permutation on the+ -- same underlying set as the given permutation. It should hold+ -- that -- - -- > idperm u == inverse (st u) `act` u+ -- > st (neutralize u) == neutralize (st u)+ -- > neutralize u == inverse (st u) `act` u+ -- > neutralize u == idperm (size u) -- - -- and this is the default implementation.- {-# INLINE idperm #-}- idperm :: a -> a- idperm u = inverse (st u) `act` u+ -- The default implementation uses the last of these three equations.+ {-# INLINE neutralize #-}+ neutralize :: a -> a+ neutralize = idperm . size -- | The group theoretical inverse. It should hold that -- - -- > inverse u == inverse (st u) `act` idperm u+ -- > inverse u == inverse (st u) `act` neutralize u -- -- and this is the default implementation. {-# INLINE inverse #-} inverse :: a -> a- inverse u = inverse (st u) `act` idperm u+ inverse u = inverse (st u) `act` neutralize u -- | Predicate determining if two permutations are -- order-isomorphic. The default implementation uses@@ -202,7 +212,7 @@ -- -- Equivalently, one could use -- - -- > u `ordiso` v == inverse u `act` v == idperm v+ -- > u `ordiso` v == inverse u `act` v == neutralize v -- {-# INLINE ordiso #-} ordiso :: StPerm -> a -> Bool@@ -212,7 +222,7 @@ st = id act u v = fromVector $ I.act (toVector u) (toVector v) size = I.size . toVector- idperm = fromVector . I.idperm . size+ idperm = fromVector . I.idperm inverse = fromVector . I.inverse . toVector ordiso = (==) @@ -221,47 +231,60 @@ act' :: Ord a => [a] -> [b] -> [b] act' u = map snd . sortBy (comparing fst) . zip u -instance (Enum a, Ord a) => Perm [a] where- st = fromVector . I.st . I.fromList . map fromEnum- act u = act' $ toList (inverse u)- inverse v = act' v (idperm v)+stL :: Enum a => [a] -> StPerm+stL = fromVector . I.st . I.fromList . map fromEnum++actL :: StPerm -> [a] -> [a]+actL u = act' $ toList (inverse u)++instance Perm String where+ st = stL+ act = actL+ inverse v = act' v (neutralize v) size = length- idperm = sort+ idperm n = take n $ ['1'..'9'] ++ ['A'..'Z'] ++ ['a'..'z'] ++ ['{'..] +instance Perm [Int] where+ st = stL+ act = actL+ inverse v = act' v (neutralize v)+ size = length+ idperm n = [1..n] + -- Generalize -- ---------- -- | Generalize a function on 'StPerm' to a function on any permutations: -- --- > generalize f v = f (st v) `act` idperm v+-- > generalize f v = f (st v) `act` neutralize v -- -- Note that this will only work as intended if @f@ is size preserving. generalize :: Perm a => (StPerm -> StPerm) -> a -> a-generalize f v = f (st v) `act` idperm v+generalize f v = f (st v) `act` neutralize v -- Generating permutations -- ----------------------- -- | @unrankPerm u rank@ is the @rank@-th (Myrvold & Ruskey)--- permutation of @u@. E.g.,+-- permutation of size @n@. E.g., -- --- > unrankPerm ['1'..'9'] 88888 == "561297843"+-- > unrankPerm 9 88888 == "561297843" -- -unrankPerm :: Perm a => a -> Integer -> a-unrankPerm u = (`act` u) . fromVector . I.unrankPerm (size u)+unrankPerm :: Perm a => Int -> Integer -> a+unrankPerm n = (`act` idperm n) . fromVector . I.unrankPerm n --- | @randomPerm u@ is a random permutation of @u@.-randomPerm :: Perm a => a -> IO a-randomPerm u = ((`act` u) . fromVector . I.fromLehmercode) `liftM` I.randomLehmercode (size u)+-- | @randomPerm n@ is a random permutation of size @n@.+randomPerm :: Perm a => Int -> IO a+randomPerm n = ((`act` idperm n) . fromVector . I.fromLehmercode) `liftM` I.randomLehmercode n --- | All permutations of a given permutation. E.g.,+-- | All permutations of a given size. E.g., -- --- > perms "123" == ["123","213","321","132","231","312"]+-- > perms 3 == ["123","213","321","132","231","312"] -- -perms :: Perm a => a -> [a]-perms u = map (`act` u) $ sym (size u)+perms :: Perm a => Int -> [a]+perms n = map (`act` idperm n) $ sym n -- Sorting operators@@ -309,16 +332,29 @@ av ps = avoiders ps . sym --- Single point deletions--- ----------------------+-- Single point extensions and deletions+-- ------------------------------------- -- | Delete the element at a given position del :: Perm a => Int -> a -> a-del i = generalize $ fromVector . I.del i .toVector+del i = generalize $ fromVector . I.del i . toVector -- | The list of all single point deletions shadow :: (Ord a, Perm a) => a -> [a] shadow w = map head . group $ sort [ del i w | i <- [0 .. size w - 1]]++-- | Insert a new largest element at the given position+ext :: Perm a => Int -> a -> a+ext i = generalize' $ fromVector . ext0 . toVector+ where+ generalize' f w = f (st w) `act` idperm (1+size w)+ ext0 w = SV.concat [u, SV.singleton (SV.length w), v]+ where+ (u,v) = SV.splitAt i w++-- | The list of all single point extensions+coshadow :: (Ord a, Perm a) => a -> [a]+coshadow w = map head . group $ sort [ ext i w | i <- [0 .. size w]] -- Simple permutations
Math/Sym/Internal.hs view
@@ -61,6 +61,7 @@ , cyc -- cycles , inv -- inversions , maj -- the major index+ , comaj -- the co-major index , peak -- peaks , vall -- valleys , dasc -- double ascents@@ -330,6 +331,9 @@ foreign import ccall unsafe "stat.h maj" c_maj :: Ptr CLong -> CLong -> CLong +foreign import ccall unsafe "stat.h comaj" c_comaj+ :: Ptr CLong -> CLong -> CLong+ foreign import ccall unsafe "stat.h peak" c_peak :: Ptr CLong -> CLong -> CLong @@ -414,6 +418,10 @@ -- | The major index. maj :: Perm0 -> Int maj = stat c_maj++-- | The co-major index.+comaj :: Perm0 -> Int+comaj = stat c_comaj -- | The number of peaks. peak :: Perm0 -> Int
Math/Sym/Stat.hs view
@@ -26,6 +26,7 @@ , cyc -- cycles , inv -- inversions , maj -- the major index+ , comaj -- the co-major index , peak -- peaks , vall -- valleys , dasc -- double ascents@@ -53,7 +54,8 @@ import Math.Sym (Perm, toVector, st) import Math.Sym.Internal (Perm0) import qualified Math.Sym.Internal as I - ( asc, des, exc, fp, cyc, inv, maj, peak, vall, dasc, ddes, lmin, lmax, rmin, rmax+ ( asc, des, exc, fp, cyc, inv, maj, comaj, peak, vall, dasc, ddes+ , lmin, lmax, rmin, rmax , head, last, lir, ldr, rir, rdr, comp, ep, dim, asc0, des0 , lminValues, lminIndices )@@ -91,6 +93,10 @@ -- | /The major index/ is the sum of descents. maj :: Perm a => a -> Int maj = generalize I.maj++-- | /The co-major index/ is the sum of descents.+comaj :: Perm a => a -> Int+comaj = generalize I.comaj -- | The number of /peaks/: positions @i@ such that @w[i-1] \< w[i]@ and @w[i] \> w[i+1]@. peak :: Perm a => a -> Int
cbits/stat.c view
@@ -112,6 +112,19 @@ return sum; } +/* The co-major index */+long+comaj(const long *w, long len)+{+ long i, sum = 0;++ for (i = 1; i < len; i++, w++) {+ if (*w > *(w+1))+ sum += len - i;+ }+ return sum;+}+ /* The number of peaks */ long
include/stat.h view
@@ -2,8 +2,10 @@ long des (const long *, long); /* descents */ long exc (const long *, long); /* excedances */ long fp (const long *, long); /* fixed points */+long cyc (const long *, long); /* The number of cycles */ long inv (const long *, long); /* inversions */ long maj (const long *, long); /* major index */+long comaj(const long *, long); /* co-major index */ long peak (const long *, long); /* peaks */ long vall (const long *, long); /* valleys */ long dasc (const long *, long); /* double ascents */@@ -14,6 +16,9 @@ long ldr (const long *, long); /* left-most decreasing run */ long comp (const long *, long); /* components */ long ep (const long *, long); /* rank a la Elizalde & Pak */+long dim (const long *, long); /* dimension */+long asc0 (const long *, long); /* small ascents */+long des0 (const long *, long); /* small descents */ -long lmin_values (long *, const long *, long);-long lmin_indices (long *, const long *, long);+long lmin_values (long *, const long *, long); /* values of left-to-right minima */+long lmin_indices (long *, const long *, long); /* indices of left-to-right minima */
sym.cabal view
@@ -1,5 +1,5 @@ Name: sym-Version: 0.2.3+Version: 0.3 Synopsis: Permutations, patterns, and statistics Description: Definitions for permutations with an emphasis on permutation
tests/Properties.hs view
@@ -34,15 +34,10 @@ r2 <- rank n return (n, r1, r2) -moreThan :: Int -> Gen Int-moreThan x = (\d -> x + abs d) `liftM` choose (1, 100)--vecFrom :: Int -> Int -> Gen [Int]-vecFrom 0 _ = return []-vecFrom n x = moreThan x >>= liftM (x:) . vecFrom (n-1)--incVec :: Int -> Gen [Int]-incVec n = arbitrary >>= vecFrom n+lenRank3 :: Gen (Int, Integer, Integer, Integer)+lenRank3 = do (n, r1, r2) <- lenRank2+ r3 <- rank n+ return (n, r1, r2, r3) -- The sub-permutation determined by a set of indices. subperm :: Sym.Set -> Sym.StPerm -> Sym.StPerm@@ -55,20 +50,21 @@ arbitrary = uncurry Sym.unrankStPerm `liftM` lenRank shrink w = nub $ [0 .. Sym.size w - 1] >>= \k -> subperms k w +perm :: Gen [Int]+perm = liftM (\w -> w `Sym.act` [1..Sym.size w]) arbitrary+ perm2 :: Gen (Sym.StPerm, [Int])-perm2 = do u <- arbitrary- v <- incVec (Sym.size u)- return (u, v)+perm2 = do (n,r1,r2) <- lenRank2+ let u = Sym.unrankStPerm n r1+ let v = Sym.unrankStPerm n r2+ return (u, v `Sym.act` [1..n]) perm3 :: Gen (Sym.StPerm, Sym.StPerm, [Int])-perm3 = do (n,r1,r2) <- lenRank2+perm3 = do (n,r1,r2,r3) <- lenRank3 let u = Sym.unrankStPerm n r1 let v = Sym.unrankStPerm n r2- w <- incVec n- return (u, v, w)--perm :: Gen [Int]-perm = liftM (uncurry Sym.act) perm2+ let w = Sym.unrankStPerm n r3+ return (u, v, w `Sym.act` [1..n]) newtype Symmetry = Symmetry (Sym.StPerm -> Sym.StPerm, String) @@ -124,7 +120,7 @@ sym' n = map Sym.fromList $ Data.List.permutations [0..fromIntegral n - 1] prop_perm =- and [ sort (Sym.perms [1..n]) == sort (permutations [1..n]) | n<-[0..6] ]+ and [ sort (Sym.perms n) == sort (permutations [1..n]) | n<-[0..6::Int] ] prop_st = forAll perm2 $ \(u,v) -> Sym.st (u `Sym.act` v) == u `Sym.act` Sym.st v@@ -133,7 +129,7 @@ forAll perm2 $ \(u,v) -> u `Sym.act` v == map (v!!) (Sym.toList u) prop_act_id =- forAll perm2 $ \(u,v) -> Sym.idperm u `Sym.act` v == v+ forAll perm2 $ \(u,v) -> Sym.neutralize u `Sym.act` v == v prop_act_associative = forAll perm3 $ \(u,v,w) -> (u `Sym.act` v) `Sym.act` w == u `Sym.act` (v `Sym.act` w)@@ -141,28 +137,37 @@ prop_size = forAll perm $ \v -> Sym.size v == Sym.size (Sym.st v) -prop_idperm =- forAll perm2 $ \(u,v) -> Sym.idperm u == Sym.inverse (Sym.st u) `Sym.act` u+prop_neutralize =+ forAll perm2 $ \(u,v) -> Sym.neutralize u == Sym.inverse (Sym.st u) `Sym.act` u prop_inverse =- forAll perm $ \v -> Sym.inverse v == Sym.inverse (Sym.st v) `Sym.act` Sym.idperm v+ forAll perm $ \v -> Sym.inverse v == Sym.inverse (Sym.st v) `Sym.act` Sym.neutralize v prop_ordiso1 =- forAll perm2 $ \(u,v) -> u `Sym.ordiso` v == (u == Sym.st v)+ forAll perm2 $ \(u,v) -> u `Sym.ordiso` v == (u == Sym.st v) prop_ordiso2 =- forAll perm2 $ \(u,v) -> u `Sym.ordiso` v == (Sym.inverse u `Sym.act` v == Sym.idperm v)+ forAll perm2 $ \(u,v) -> u `Sym.ordiso` v == (Sym.inverse u `Sym.act` v == Sym.neutralize v) shadow :: Ord a => [a] -> [[a]] shadow w = nubSort . map normalize $ ptDeletions w where- normalize u = [ (sort w)!!i | i <- st u ]+ w' = sort w+ normalize u = [ w'!!i | i <- st u ] nubSort = map head . group . sort ptDeletions [] = [] ptDeletions xs@(x:xt) = xt : map (x:) (ptDeletions xt) -prop_shadow = forAll perm $ \w -> Sym.shadow w == shadow w+prop_shadow = forAll (resize 30 perm) $ \w -> Sym.shadow w == shadow w +coshadow :: (Enum a, Ord a) => [a] -> [[a]]+coshadow w = sort $ ptExtensions (succ $ maximum (toEnum 0 : w)) w+ where+ ptExtensions n [] = [[n]]+ ptExtensions n xs@(x:xt) = (n:xs) : map (x:) (ptExtensions n xt)++prop_coshadow = forAll (resize 50 perm) $ \w -> Sym.coshadow w == coshadow w+ segments :: [a] -> [[a]] segments [] = [[]] segments (x:xs) = segments xs ++ map (x:) (inits xs)@@ -182,24 +187,25 @@ simple :: Ord a => [a] -> Bool simple = null . properIntervals -prop_simple = forAll (resize 50 perm) $ \w -> Sym.simple w == simple w+prop_simple = forAll (resize 40 perm) $ \w -> Sym.simple w == simple w prop_unrankPerm = forAll perm $ \w ->- forAll (choose (0, product [1..fromIntegral (length w) - 1])) $ \r ->- Sym.st (Sym.unrankPerm (sort w) r) == Sym.unrankStPerm (length w) r+ let n = length w+ in forAll (choose (0, product [1..fromIntegral n - 1])) $ \r ->+ Sym.st (Sym.unrankPerm n r :: [Int]) == Sym.unrankStPerm n r prop_stackSort = forAll perm $ \v -> Sym.stackSort v == stack v prop_stackSort_231 = forAll perm $ \v ->- (Sym.stackSort v == Sym.idperm v) == (v `Sym.avoids` [Sym.st "231"])+ (Sym.stackSort v == Sym.neutralize v) == (v `Sym.avoids` [Sym.st "231"]) prop_bubbleSort = forAll perm $ \v -> Sym.bubbleSort v == bubble v prop_bubbleSort_231_321 = forAll perm $ \v ->- (Sym.bubbleSort v == Sym.idperm v) == (v `Sym.avoids` [Sym.st "231", Sym.st "321"])+ (Sym.bubbleSort v == Sym.neutralize v) == (v `Sym.avoids` [Sym.st "231", Sym.st "321"]) prop_subperm_copies p = forAll (resize 21 perm) $ \w -> and [ subperm m (Sym.st w) == p | m <- Sym.copiesOf p w ]@@ -295,7 +301,7 @@ prop_subsets_cardinality2 = forAll (choose (0,20)) $ \n -> forAll (choose (0,20)) $ \k ->- let cs = map (SV.length) (Sym.subsets n k) in ((k > n) && null cs) || ([k] == nub cs)+ let cs = map SV.length (Sym.subsets n k) in ((k > n) && null cs) || ([k] == nub cs) testsPerm = [ ("monoid/mempty/1", check prop_monoid_mempty1)@@ -313,11 +319,12 @@ , ("act/id", check prop_act_id) , ("act/associative", check prop_act_associative) , ("size", check prop_size)- , ("idperm", check prop_idperm)+ , ("neutralize", check prop_neutralize) , ("inverse", check prop_inverse) , ("ordiso/1", check prop_ordiso1) , ("ordiso/2", check prop_ordiso2) , ("shadow", check prop_shadow)+ , ("coshadow", check prop_coshadow) , ("simple", check prop_simple) , ("unrankPerm", check prop_unrankPerm) , ("stackSort", check prop_stackSort)@@ -480,10 +487,11 @@ des, asc, inv, lmin, lmax, rmin, rmax, peak, vall :: [Int] -> Int dasc, ddes, maj, comp, ep, dim :: [Int] -> Int -dim w = maximum $ 0 : [ i | (i,x) <- zip [0..] (st w), i /= x ]-maj w = sum [ i | (i,x,y) <- zip3 [1..] w (tail w), x > y ]-asc0 w = sum [ 1 | (x,y) <- ascents $ st w, y-x == 1 ]-des0 w = sum [ 1 | (x,y) <- descents $ st w, x-y == 1 ]+dim w = maximum $ 0 : [ i | (i,x) <- zip [0..] (st w), i /= x ]+maj w = sum [ i | (i,x,y) <- zip3 [1..] w (tail w), x > y ]+comaj w = sum [ n-i | (i,x,y) <- zip3 [1..] w (tail w), x > y ] where n = length w+asc0 w = sum [ 1 | (x,y) <- ascents $ st w, y-x == 1 ]+des0 w = sum [ 1 | (x,y) <- descents $ st w, x-y == 1 ] asc = length . ascents des = length . descents@@ -497,42 +505,43 @@ dasc = length . doubleAscents ddes = length . doubleDescents -prop_asc = forAll perm $ \w -> asc w == S.asc w-prop_des = forAll perm $ \w -> des w == S.des w-prop_exc = forAll perm $ \w -> exc w == S.exc w-prop_fp = forAll perm $ \w -> fp w == S.fp w-prop_cyc = forAll perm $ \w -> cyc w == S.cyc w-prop_inv = forAll perm $ \w -> inv w == S.inv w-prop_maj = forAll perm $ \w -> maj w == S.maj w-prop_lmin = forAll perm $ \w -> lmin w == S.lmin w-prop_lmax = forAll perm $ \w -> lmax w == S.lmax w-prop_rmin = forAll perm $ \w -> rmin w == S.rmin w-prop_rmax = forAll perm $ \w -> rmax w == S.rmax w-prop_head = forAll perm $ \w -> not (null w) ==> head (st w) == S.head w-prop_last = forAll perm $ \w -> not (null w) ==> last (st w) == S.last w-prop_peak = forAll perm $ \w -> peak w == S.peak w-prop_vall = forAll perm $ \w -> vall w == S.vall w-prop_dasc = forAll perm $ \w -> dasc w == S.dasc w-prop_ddes = forAll perm $ \w -> ddes w == S.ddes w-prop_ep = forAll perm $ \w -> ep w == S.ep w-prop_lir = forAll perm $ \w -> lir w == S.lir w-prop_ldr = forAll perm $ \w -> ldr w == S.ldr w-prop_rir = forAll perm $ \w -> rir w == S.rir w-prop_rdr = forAll perm $ \w -> rdr w == S.rdr w-prop_comp = forAll perm $ \w -> comp w == S.comp w-prop_dim = forAll perm $ \w -> dim w == S.dim w-prop_asc0 = forAll perm $ \w -> asc0 w == S.asc0 w-prop_des0 = forAll perm $ \w -> des0 w == S.des0 w+prop_asc = forAll perm $ \w -> asc w == S.asc w+prop_des = forAll perm $ \w -> des w == S.des w+prop_exc = forAll perm $ \w -> exc w == S.exc w+prop_fp = forAll perm $ \w -> fp w == S.fp w+prop_cyc = forAll perm $ \w -> cyc w == S.cyc w+prop_inv = forAll perm $ \w -> inv w == S.inv w+prop_maj = forAll perm $ \w -> maj w == S.maj w+prop_comaj = forAll perm $ \w -> comaj w == S.comaj w+prop_lmin = forAll perm $ \w -> lmin w == S.lmin w+prop_lmax = forAll perm $ \w -> lmax w == S.lmax w+prop_rmin = forAll perm $ \w -> rmin w == S.rmin w+prop_rmax = forAll perm $ \w -> rmax w == S.rmax w+prop_head = forAll perm $ \w -> not (null w) ==> head w == 1 + S.head w+prop_last = forAll perm $ \w -> not (null w) ==> last w == 1 + S.last w+prop_peak = forAll perm $ \w -> peak w == S.peak w+prop_vall = forAll perm $ \w -> vall w == S.vall w+prop_dasc = forAll perm $ \w -> dasc w == S.dasc w+prop_ddes = forAll perm $ \w -> ddes w == S.ddes w+prop_ep = forAll perm $ \w -> ep w == S.ep w+prop_lir = forAll perm $ \w -> lir w == S.lir w+prop_ldr = forAll perm $ \w -> ldr w == S.ldr w+prop_rir = forAll perm $ \w -> rir w == S.rir w+prop_rdr = forAll perm $ \w -> rdr w == S.rdr w+prop_comp = forAll perm $ \w -> comp w == S.comp w+prop_dim = forAll perm $ \w -> dim w == S.dim w+prop_asc0 = forAll perm $ \w -> asc0 w == S.asc0 w+prop_des0 = forAll perm $ \w -> des0 w == S.des0 w prop_inv_21 = forAll perm $ \w -> S.inv w == length (Sym.copiesOf (Sym.st "21") w) prop_lmin_values =- forAll perm $ \w -> lMinima (st w) == S.lminValues w+ forAll perm $ \w -> lMinima (st w) == S.lminValues w prop_lmin_indices =- forAll perm $ \w -> [ head $ elemIndices x w | x <- lMinima w ] == S.lminIndices w+ forAll perm $ \w -> [ head $ elemIndices x w | x <- lMinima w ] == S.lminIndices w prop_lmin_card =- forAll perm $ \w -> and [ S.lmin w == length (S.lminValues w)- , S.lmin w == length (S.lminIndices w)+ forAll perm $ \w -> and [ S.lmin w == length (S.lminValues w)+ , S.lmin w == length (S.lminIndices w) ] testsStat =@@ -543,6 +552,7 @@ , ("cyc", check prop_cyc) , ("inv", check prop_inv) , ("maj", check prop_maj)+ , ("comaj", check prop_comaj) , ("lmin", check prop_lmin) , ("lmax", check prop_lmax) , ("rmin", check prop_rmin)