Advertisement
Guest User

Untitled

a guest
Jul 2nd, 2016
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.68 KB | None | 0 0
  1. {-# LANGUAGE ScopedTypeVariables #-}
  2. {-# LANGUAGE TypeSynonymInstances #-}
  3. {-# LANGUAGE FlexibleInstances #-}
  4. {-# LANGUAGE TupleSections #-}
  5.  
  6. #include "vec_wrap.h"
  7.  
  8. module Main where
  9.  
  10. import Control.Exception.Base hiding (assert)
  11. import Control.Monad (forM, unless, foldM)
  12. import Data.Int
  13. import Data.List (delete)
  14. import Data.Maybe (fromMaybe)
  15. import Foreign.Marshal.Array
  16. import Foreign.Marshal.Utils
  17. import Foreign.Ptr
  18. import Foreign.Storable
  19. import Safe (lastMay, headMay)
  20. import Test.QuickCheck
  21. import Test.QuickCheck.Monadic
  22.  
  23.  
  24. data Cmd a = Push a
  25. | Init
  26. | Clear
  27. | Compact
  28. | Deinit
  29. | Extend [a]
  30. | First
  31. | Insert Int a
  32. | Last
  33. | Pop
  34. | Remove a
  35. | Reserve a
  36. | Reverse
  37. -- | Splice
  38. -- | SwapSplice
  39. -- | Swap
  40. -- | Truncate
  41. deriving (Show, Eq, Ord)
  42.  
  43. data Model a = Model [a] Int32 deriving (Show, Eq, Ord)
  44. type Model' = Model Int32
  45. type Cmd' = Cmd Int32
  46.  
  47.  
  48. insertAt :: a -> [a] -> Int -> Maybe [a]
  49. insertAt x ys 0 = Just (x:ys)
  50. insertAt x (y:ys) n = do xs <- insertAt x ys (n-1)
  51. return (y:xs)
  52. insertAt x [] n = Nothing
  53.  
  54.  
  55. runModel :: Eq a => Model a -> Cmd a -> (Model a, Maybe a)
  56. runModel (Model xs len) cmd =
  57. case cmd of
  58. Push x -> (Model (xs ++ [x]) (len + 1), Nothing)
  59. Init -> (Model [] 0, Nothing)
  60. Clear -> (Model [] 0, Nothing)
  61. Compact -> (Model xs len, Nothing)
  62. Deinit -> (Model [] 0, Nothing)
  63. Extend ys -> (Model (xs ++ ys) (len + fromIntegral (length ys)), Nothing)
  64. First -> (Model xs len, headMay xs)
  65. Insert ix x -> case insertAt x xs ix of
  66. Nothing -> (Model xs len, Nothing)
  67. Just xs -> (Model xs (len + 1), Nothing)
  68. Last -> (Model xs len, lastMay xs)
  69. Pop | len == 0 -> (Model xs len, Nothing)
  70. | otherwise -> (Model (init xs) (len - 1), lastMay xs)
  71. Reserve a -> (Model xs len, Nothing)
  72. Reverse -> (Model (reverse xs) len, Nothing)
  73. Remove a -> let deleted = delete a xs
  74. delLen = length deleted
  75. leng = length xs
  76. in (Model deleted (if delLen /= leng then len - 1 else len), Nothing)
  77.  
  78. runModelCmds :: [Cmd'] -> Model' -> Ptr Vec -> PropertyM IO (Model', Ptr Vec)
  79. runModelCmds cmds model pvec = foldM step (model, pvec) cmds
  80. where
  81. step (model, pvec) cmd =
  82. do let (pureM, pureRes) = runModel model cmd
  83. (pvec', ioRes) <- run (runVec pvec cmd)
  84. vec' <- run (peek pvec')
  85. let retsMatch = ioRes == pureRes
  86. if not retsMatch
  87. then do run $ putStrLn $ show ioRes ++ " != " ++ show pureRes
  88. assert retsMatch
  89. else assert retsMatch
  90. modelEquals <- run (modelEq pureM vec')
  91. modelAssert pureM vec' modelEquals
  92. return (pureM, pvec')
  93.  
  94. modelAssert m vec b =
  95. if b
  96. then assert True
  97. else run (printModels m vec) >> assert False
  98.  
  99. printModels m vec = do svec <- showVec vec
  100. putStrLn (show m ++ " != \n" ++ svec)
  101.  
  102. modelEq (Model xs len) vec = do
  103. xs' <- vdata vec
  104. return $ xs' == xs && len == vecLen vec
  105.  
  106. prop_api cmds = monadicIO $ do
  107. pvec <- run $ new (Vec nullPtr 0 0)
  108. runModelCmds cmds (Model [] 0) pvec
  109.  
  110.  
  111. runVec :: Ptr Vec -> Cmd Int32 -> IO (Ptr Vec, Maybe Int32)
  112. runVec pvec cmd =
  113. case cmd of
  114. Push x -> noret (vec_push pvec x)
  115. Init -> noret (vec_init pvec)
  116. Clear -> noret (vec_clear pvec)
  117. Compact -> noret (vec_compact pvec)
  118. Deinit -> noret (vec_deinit pvec)
  119. Extend ys -> noret $
  120. do let len_ys = length ys
  121. ys' <- newArray ys
  122. newVec <- new (Vec ys' (fromIntegral len_ys) (fromIntegral len_ys))
  123. vec_extend pvec newVec
  124. First -> doIfNonEmpty pvec vec_first
  125. Insert ix x -> do len <- vecLen <$> peek pvec
  126. if ix >= fromIntegral len
  127. then return (pvec, Nothing)
  128. else noret (vec_insert pvec (fromIntegral ix) x)
  129. Last -> doIfNonEmpty pvec vec_last
  130. Pop -> doIfNonEmpty pvec vec_pop
  131. Reserve a -> noret (vec_reserve pvec a)
  132. Remove a -> noret (vec_remove pvec a)
  133. where
  134. noret = fmap (, Nothing)
  135.  
  136. doIfNonEmpty pvec action = do
  137. len <- vecLen <$> peek pvec
  138. if len == 0
  139. then return (pvec, Nothing)
  140. else fmap (\ret -> (pvec, Just ret)) (action pvec)
  141.  
  142.  
  143. instance Arbitrary Cmd' where
  144. arbitrary = do Positive n <- arbitrary
  145. ys <- arbitrary
  146. Positive ix <- arbitrary
  147. x <- arbitrary
  148. elements [ Push n, Init, Clear, Compact, Deinit, Extend ys
  149. , First, Insert ix x, Last, Pop, Reserve n, Remove n
  150. ]
  151.  
  152.  
  153. data Vec = Vec { vecData :: {-# UNPACK #-} !(Ptr Int32)
  154. , vecLen :: {-# UNPACK #-} !Int32
  155. , vecCap :: {-# UNPACK #-} !Int32
  156. } deriving Show
  157.  
  158. showVec :: Vec -> IO String
  159. showVec v = do xs <- vdata v
  160. return $ "Vec " ++ show xs ++ " "
  161. ++ show (vecLen v) ++ " "
  162. ++ show (vecCap v)
  163.  
  164. instance Storable Vec where
  165. sizeOf _ = (#size struct test_vec)
  166. alignment = sizeOf
  167. peek ptr = do dat <- (#peek struct test_vec, data) ptr
  168. length <- (#peek struct test_vec, length) ptr
  169. cap <- (#peek struct test_vec, capacity) ptr
  170. return (Vec dat length cap)
  171. poke ptr (Vec dat len cap) = do (#poke struct test_vec, data) ptr dat
  172. (#poke struct test_vec, length) ptr len
  173. (#poke struct test_vec, capacity) ptr cap
  174.  
  175.  
  176. foreign import ccall "_vec_push" vec_push :: Ptr Vec -> Int32 -> IO (Ptr Vec)
  177. foreign import ccall "_vec_init" vec_init :: Ptr Vec -> IO (Ptr Vec)
  178. foreign import ccall "_vec_clear" vec_clear :: Ptr Vec -> IO (Ptr Vec)
  179. foreign import ccall "_vec_compact" vec_compact :: Ptr Vec -> IO (Ptr Vec)
  180. foreign import ccall "_vec_deinit" vec_deinit :: Ptr Vec -> IO (Ptr Vec)
  181. foreign import ccall "_vec_extend" vec_extend :: Ptr Vec -> Ptr Vec -> IO (Ptr Vec)
  182. foreign import ccall "_vec_first" vec_first :: Ptr Vec -> IO Int32
  183. foreign import ccall "_vec_insert" vec_insert :: Ptr Vec -> Int32 -> Int32 -> IO (Ptr Vec)
  184. foreign import ccall "_vec_last" vec_last :: Ptr Vec -> IO Int32
  185. foreign import ccall "_vec_pop" vec_pop :: Ptr Vec -> IO Int32
  186. foreign import ccall "_vec_pusharr" vec_pusharr :: Ptr Vec -> Ptr Int32 -> Int32 -> IO (Ptr Vec)
  187. foreign import ccall "_vec_remove" vec_remove :: Ptr Vec -> Int32 -> IO (Ptr Vec)
  188. foreign import ccall "_vec_reserve" vec_reserve :: Ptr Vec -> Int32 -> IO (Ptr Vec)
  189. foreign import ccall "_vec_reverse" vec_reverse :: Ptr Vec -> IO (Ptr Vec)
  190. -- foreign import ccall "_vec_sort" vec_sort :: Ptr Vec -> , int (*fn)(const void *, const void*)
  191. foreign import ccall "_vec_splice" vec_splice :: Ptr Vec -> Int32 -> Int32 -> IO (Ptr Vec)
  192. foreign import ccall "_vec_swapsplice" vec_swapsplice :: Ptr Vec -> Int32 -> Int32 -> IO (Ptr Vec)
  193. foreign import ccall "_vec_swap" vec_swap :: Ptr Vec -> Int32 -> Int32 -> IO (Ptr Vec)
  194. foreign import ccall "_vec_truncate" vec_truncate :: Ptr Vec -> Int32 -> IO (Ptr Vec)
  195.  
  196. main :: IO ()
  197. main = do
  198. quickCheck prop_api
  199.  
  200. -- pushShow p n = do
  201. -- p <- vec_push p n
  202. -- pv <- peek p
  203. -- print pv
  204. -- return p
  205.  
  206.  
  207. vdata :: Vec -> IO [Int32]
  208. vdata v = forM [0..fromIntegral (vecLen v) - 1] $ \n ->
  209. peekElemOff (vecData v) n
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement