Skip to content

Commit b42343e

Browse files
committed
Provide an ST-based GraphM instance
Closes #25
1 parent 0e089a9 commit b42343e

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

Data/Graph/Inductive/Monad/STArray.hs

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses #-}
2+
3+
-- (c) 2002 by Martin Erwig [see file COPYRIGHT]
4+
-- | Static IOArray-based Graphs
5+
module Data.Graph.Inductive.Monad.STArray(
6+
-- * Graph Representation
7+
SGr(..), GraphRep, Context', USGr,
8+
defaultGraphSize, emptyN,
9+
-- * Utilities
10+
removeDel,
11+
) where
12+
13+
import Data.Graph.Inductive.Graph
14+
import Data.Graph.Inductive.Monad
15+
16+
import Control.Monad
17+
import Control.Monad.ST
18+
import Data.Array
19+
import Data.Array.ST
20+
import System.IO.Unsafe
21+
22+
23+
24+
----------------------------------------------------------------------
25+
-- GRAPH REPRESENTATION
26+
----------------------------------------------------------------------
27+
28+
newtype SGr s a b = SGr (GraphRep s a b)
29+
30+
type GraphRep s a b = (Int,Array Node (Context' a b),STArray s Node Bool)
31+
type Context' a b = Maybe (Adj b,a,Adj b)
32+
33+
type USGr s = SGr s () ()
34+
35+
36+
----------------------------------------------------------------------
37+
-- CLASS INSTANCES
38+
----------------------------------------------------------------------
39+
40+
-- Show
41+
--
42+
showGraph :: (Show a,Show b) => GraphRep RealWorld a b -> String
43+
showGraph (_,a,m) = concatMap showAdj (indices a)
44+
where showAdj v | unsafeST (readArray m v) = ""
45+
| otherwise = case a!v of
46+
Nothing -> ""
47+
Just (_,l,s) -> '\n':show v++":"++show l++"->"++show s'
48+
where s' = unsafeST (removeDel m s)
49+
50+
unsafeST :: ST RealWorld a -> a
51+
unsafeST = unsafePerformIO . stToIO
52+
53+
instance (Show a,Show b) => Show (SGr RealWorld a b) where
54+
show (SGr g) = showGraph g
55+
56+
instance (Show a,Show b) => Show (ST RealWorld (SGr RealWorld a b)) where
57+
show g = unsafeST (do {(SGr g') <- g; return (showGraph g')})
58+
59+
{-
60+
run :: Show (IO a) => IO a -> IO ()
61+
run x = seq x (print x)
62+
-}
63+
64+
-- GraphM
65+
--
66+
instance GraphM (ST s) (SGr s) where
67+
emptyM = emptyN defaultGraphSize
68+
isEmptyM g = do {SGr (n,_,_) <- g; return (n==0)}
69+
matchM v g = do g'@(SGr (n,a,m)) <- g
70+
case a!v of
71+
Nothing -> return (Nothing,g')
72+
Just (pr,l,su) ->
73+
do b <- readArray m v
74+
if b then return (Nothing,g') else
75+
do s <- removeDel m su
76+
p' <- removeDel m pr
77+
let p = filter ((/=v).snd) p'
78+
writeArray m v True
79+
return (Just (p,v,l,s),SGr (n-1,a,m))
80+
mkGraphM vs es = do m <- newArray (1,n) False
81+
return (SGr (n,pr,m))
82+
where nod = array bnds (map (\(v,l)->(v,Just ([],l,[]))) vs)
83+
su = accum addSuc nod (map (\(v,w,l)->(v,(l,w))) es)
84+
pr = accum addPre su (map (\(v,w,l)->(w,(l,v))) es)
85+
bnds = (minimum vs',maximum vs')
86+
vs' = map fst vs
87+
n = length vs
88+
addSuc (Just (p,l',s)) (l,w) = Just (p,l',(l,w):s)
89+
addSuc Nothing _ = error "mkGraphM (SGr): addSuc Nothing"
90+
addPre (Just (p,l',s)) (l,w) = Just ((l,w):p,l',s)
91+
addPre Nothing _ = error "mkGraphM (SGr): addPre Nothing"
92+
labNodesM g = do (SGr (_,a,m)) <- g
93+
let getLNode vs (_,Nothing) = return vs
94+
getLNode vs (v,Just (_,l,_)) =
95+
do b <- readArray m v
96+
return (if b then vs else (v,l):vs)
97+
foldM getLNode [] (assocs a)
98+
99+
defaultGraphSize :: Int
100+
defaultGraphSize = 100
101+
102+
emptyN :: Int -> ST s (SGr s a b)
103+
emptyN n = do m <- newArray (1,n) False
104+
return (SGr (0,array (1,n) [(i,Nothing) | i <- [1..n]],m))
105+
106+
----------------------------------------------------------------------
107+
-- UTILITIES
108+
----------------------------------------------------------------------
109+
110+
111+
112+
-- | filter list (of successors\/predecessors) through a boolean ST array
113+
-- representing deleted marks
114+
removeDel :: STArray s Node Bool -> Adj b -> ST s (Adj b)
115+
removeDel m = filterM (\(_,v)->do {b<-readArray m v;return (not b)})

fgl.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ library {
4646
Data.Graph.Inductive.Query,
4747
Data.Graph.Inductive.Tree,
4848
Data.Graph.Inductive.Monad.IOArray,
49+
Data.Graph.Inductive.Monad.STArray,
4950
Data.Graph.Inductive.Query.ArtPoint,
5051
Data.Graph.Inductive.Query.BCC,
5152
Data.Graph.Inductive.Query.BFS,

0 commit comments

Comments
 (0)