packages feed

speculate-0.3.5: bench/qs2/regexes.hs

import Regex
import Test.QuickCheck
import Test.QuickCheck.Gen
import Test.QuickCheck.Random
import Control.Monad
import QuickSpec hiding (None)
import Data.Ord

instance Arbitrary Symbol where
  arbitrary = elements $ map Symbol ['a','b','c']

instance Arbitrary a => Arbitrary (RE a) where
  arbitrary = sized re
    where
    re 0 = oneof 
         [ return Empty
         , return None
         , liftM Lit arbitrary
         ]
    re n = oneof
         [ re 0
         , liftM Star (re (n - 1))
         , liftM2 (:.) re2 re2
         , liftM2 (:+) re2 re2
         ] where re2 = re (n `div` 2)
  shrink Empty    = []
  shrink None     = []
  shrink (Lit _)  = [Empty, None]
  shrink (Star r) = [r] ++ [Star r' | r' <- shrink r]
  shrink (r :+ s) = [r, s] ++ [r' :+ s' | (r',s') <- shrink (r,s)]
  shrink (r :. s) = [r, s] ++ [r' :. s' | (r',s') <- shrink (r,s)]

class    Charable a      where toChar :: a -> Char
instance Charable Char   where toChar = id
instance Charable Symbol where toChar (Symbol c) = c

instance (Arbitrary a, Charable a, Ord a, Eq a) => Eq (RE a) where
  r1 == r2 = r1 `compare` r2 == EQ

instance (Arbitrary a, Charable a, Ord a) => Ord (RE a) where
  compare = comparing (\r -> map (\a -> match toChar a r) vals)
    where
  --vals :: Arbitrary a => [[a]] -- adapted from QuickSpec's own RE example
    vals = unGen (vector 100) (mkQCGen 12345) 10

main = quickSpec signature
  { maxTermSize = Just 2 -- TODO: fixme!
  , instances =
      [ baseType (undefined :: RE Symbol)
      ]
  , constants =
      [ constant "Empty" (Empty :: RE Symbol)
      , constant "None"  (None  :: RE Symbol)
      , constant "Star"  (Star  :: RE Symbol -> RE Symbol)
      , constant ":+"    ((:+)  :: RE Symbol -> RE Symbol -> RE Symbol)
      , constant ":."    ((:.)  :: RE Symbol -> RE Symbol -> RE Symbol)
    --, constant "=~"    (=~)
    --, constant "Lit"   (Lit   :: Symbol -> RE Symbol)
      ]
  }