combinat-0.2.8.2: test/Tests/LatticePaths.hs
-- | Tests for lattice paths
--
{-# LANGUAGE CPP, ScopedTypeVariables, GeneralizedNewtypeDeriving, FlexibleContexts #-}
module Tests.LatticePaths where
--------------------------------------------------------------------------------
import Math.Combinat.LatticePaths
import Test.Framework
import Test.Framework.Providers.QuickCheck2
import Test.QuickCheck
import System.Random
import Control.Monad
import Data.List
import Math.Combinat.Classes
import Math.Combinat.Helper
import Math.Combinat.Sign
import Math.Combinat.Numbers ( factorial , binomial )
--------------------------------------------------------------------------------
-- * instances
-- | Half-length of a Dyck path
newtype Half = Half Int deriving (Eq,Show)
-- | First number is (usually) less or equal than the second
data HalfPair = HalfPair Int Int deriving (Eq,Show)
maxHalfSize :: Int
maxHalfSize = 11 -- number of paths grow exponentially
instance Arbitrary Half where
arbitrary = liftM Half $ choose (0,maxHalfSize)
instance Arbitrary HalfPair where
arbitrary = do
n <- choose (0,maxHalfSize)
k <- choose (0,n+1)
return (HalfPair k n)
fi :: Int -> Integer
fi = fromIntegral
--------------------------------------------------------------------------------
-- * test group
testgroup_LatticePaths :: Test
testgroup_LatticePaths = testGroup "Lattice paths"
[ testProperty "dyck paths are in reverse lexicographic order" prop_revlex
, testProperty "naive Dyck path algorithm = less naive algorithm" prop_dyck_naive
, testProperty "counting Dyck paths" prop_count
, testProperty "counting Lattice paths" prop_count_lattice
, testProperty "bounded Dyck paths, def, v1" prop_bounded_1
, testProperty "bounded Dyck paths, def, v2" prop_bounded_2
, testProperty "bounded Dyck paths w/ high bound = all dyck paths" prop_not_bounded
, testProperty "zero-touching Dyck paths" prop_touching
, testProperty "Dyck paths w/ k peaks" prop_peaking
]
--------------------------------------------------------------------------------
-- * test properties
prop_revlex :: Bool
prop_revlex = and [ sort (dyckPaths m) == reverse (dyckPaths m) | m <- [0..maxHalfSize] ]
prop_dyck_naive :: Bool
prop_dyck_naive = and [ sort (dyckPathsNaive m) == sort (dyckPaths m) | m <- [0..maxHalfSize] ]
prop_count :: Bool
prop_count = and [ fi (length (dyckPaths m)) == countDyckPaths m | m <- [0..maxHalfSize] ]
prop_count_lattice :: HalfPair -> Bool
prop_count_lattice (HalfPair y x) = fi (length (latticePaths (x,y))) == countLatticePaths (x,y)
prop_bounded_1 :: HalfPair -> Bool
prop_bounded_1 (HalfPair h m) = (one == two) where
one = sort (boundedDyckPaths h m )
two = sort [ p | p <- dyckPaths m , pathHeight p <= h ]
prop_bounded_2 :: Half -> Half -> Bool
prop_bounded_2 (Half h) (Half m) = (one == two) where
one = sort (boundedDyckPaths h m )
two = sort [ p | p <- dyckPaths m , pathHeight p <= h ]
prop_not_bounded :: Bool
prop_not_bounded = and [ sort (boundedDyckPaths m m) == sort (dyckPaths m) | m <- [0..maxHalfSize] ]
prop_touching :: HalfPair -> Bool
prop_touching (HalfPair k m) = (one == two && fi (length one) == cnt) where
one = sort (touchingDyckPaths k m)
two = sort [ p | p <- dyckPaths m , pathNumberOfZeroTouches p == k ]
cnt = countTouchingDyckPaths k m
prop_peaking :: HalfPair -> Bool
prop_peaking (HalfPair k m) = (one == two && fi (length one) == cnt) where
one = sort (peakingDyckPaths k m)
two = sort [ p | p <- dyckPaths m , pathNumberOfPeaks p == k ]
cnt = countPeakingDyckPaths k m
--------------------------------------------------------------------------------