-- | -- Module : Control.Concurrent.ParallelTreeSearch -- Copyright : Fabian Reck, Sebastian Fischer -- License : PublicDomain -- -- Maintainer : Sebastian Fischer (sebf@informatik.uni-kiel.de) -- Stability : experimental -- Portability : portable -- -- This Haskell library provides an implementation of parallel search -- based on the search tree provided by the package tree-monad. -- module Control.Concurrent.ParallelTreeSearch ( parallelTreeSearch ) where import Control.Monad import Control.Monad.SearchTree import Control.Concurrent -- | Enumerate the leaves of a @SearchTree@ in parallel. parallelTreeSearch :: Int -- ^ number of threads to use -> SearchTree a -- ^ tree to search -> IO [a] -- ^ lazy list of leaves parallelTreeSearch threadCount tree = do ctr <- newMVar 1 res <- newChan queue <- newChan writeChan queue tree sequence (replicate threadCount (forkIO (search ctr res queue))) liftM (foldr (\mx xs -> maybe [] (:xs) mx) []) (getChanContents res) search :: MVar Int -> Chan (Maybe a) -> Chan (SearchTree a) -> IO () search ctr res queue = process =<< readChan queue where process None = finished process (One x) = do writeChan res (Just x); finished process (Choice l r) = do modifyMVar_ ctr (return.succ) writeChan queue l writeChan queue r search ctr res queue finished = do count <- modifyMVar ctr ((\n -> return (n,n)).pred) if count == 0 then writeChan res Nothing else search ctr res queue