packages feed

sym 0.2.3 → 0.3

raw patch · 7 files changed

+198/−120 lines, 7 files

Files

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)