{-# LANGUAGE ViewPatterns #-}
import Text.Regex.Applicative
import Text.Regex.Applicative.Reference
import Control.Applicative
import Control.Monad
import Test.SmallCheck
import Data.Traversable
import Text.Printf
-- Small alphabets as SmallCheck's series
newtype A = A { a :: Char } deriving Show
instance Serial A where
series = cons0 $ A 'a'
coseries = error "No coseries, sorry"
newtype AB = AB { ab :: Char } deriving Show
instance Serial AB where
series = cons0 (AB 'a') \/ cons0 (AB 'b')
coseries = error "No coseries, sorry"
newtype ABC = ABC { abc :: Char } deriving Show
instance Serial ABC where
series = cons0 (ABC 'a') \/ cons0 (ABC 'b') \/ cons0 (ABC 'c')
coseries = error "No coseries, sorry"
re1 =
let one = pure 1 <* sym 'a'
two = pure 2 <* sym 'a' <* sym 'a'
in (,) <$> (one <|> two) <*> (two <|> one)
re2 = sequenceA $
[ pure 1 <* sym 'a' <* sym 'a' <|>
pure 2 <* sym 'a'
, pure 3 <* sym 'b'
, pure 4 <* sym 'b' <|>
pure 5 <* sym 'a' ]
re3 = sequenceA $
[ pure 0 <|> pure 1
, pure 1 <* sym 'a' <* sym 'a' <|>
pure 2 <* sym 'a'
, pure 3 <* sym 'b' <|> pure 6
, fmap (+1) $
pure 4 <* sym 'b' <|>
pure 7 <|>
pure 5 <* sym 'a' ]
re4 = sym 'a' *> many (sym 'b') <* sym 'a'
re5 = (sym 'a' <|> sym 'a' *> sym 'a') *> many (sym 'a')
re6 = many (pure 3 <* sym 'a' <* sym 'a' <* sym 'a' <|> pure 1 <* sym 'a')
-- Regular expression from the weighted regexp paper.
re7 =
let many_A_or_B = many (sym 'a' <|> sym 'b')
in (,) <$>
many ((,,,) <$> many_A_or_B <*> sym 'c' <*> many_A_or_B <*> sym 'c') <*>
many_A_or_B
re8 = (,) <$> many (sym 'a' <|> sym 'b') <*> many (sym 'b' <|> sym 'c')
prop re f (map f -> s) = reference re s == (s =~ re)
tests =
[ depthCheck 10 $ prop re1 a
, depthCheck 10 $ prop re2 ab
, depthCheck 10 $ prop re3 ab
, depthCheck 10 $ prop re4 ab
, depthCheck 10 $ prop re5 a
, depthCheck 10 $ prop re6 a
, depthCheck 7 $ prop re7 abc
, depthCheck 7 $ prop re8 abc
]
main = do
foldM runTest (1 :: Int) tests
return ()
where
runTest n test = do
printf "Running test case %d...\n" n
test
printf "\n"
return $ n+1