@@ -4,19 +4,18 @@ module Data.Graph (
44 Edge (..),
55 Graph (..),
66 SCC (..),
7-
7+
88 vertices ,
99
1010 scc ,
1111 scc' ,
12-
12+
1313 topSort ,
1414 topSort'
1515 ) where
1616
1717import Prelude
1818
19- import Data.Int
2019import Data.Maybe
2120import Data.List
2221import Data.Foldable
@@ -37,7 +36,7 @@ data Edge k = Edge k k
3736-- | Edges refer to vertices using keys of type `k`.
3837data Graph k v = Graph (List v ) (List (Edge k ))
3938
40- type Index = Int
39+ type Index = Int
4140
4241-- | A strongly-connected component of a graph.
4342-- |
@@ -47,7 +46,7 @@ type Index = Int
4746data SCC v = AcyclicSCC v | CyclicSCC (List v )
4847
4948instance showSCC :: (Show v ) => Show (SCC v ) where
50- show (AcyclicSCC v) = " AcyclicSCC (" ++ show v ++ " )"
49+ show (AcyclicSCC v) = " AcyclicSCC (" ++ show v ++ " )"
5150 show (CyclicSCC vs) = " CyclicSCC " ++ show vs
5251
5352instance eqSCC :: (Eq v ) => Eq (SCC v ) where
@@ -65,26 +64,26 @@ scc :: forall v. (Eq v, Ord v) => Graph v v -> List (SCC v)
6564scc = scc' id id
6665
6766-- | Compute the strongly connected components of a graph.
68- -- |
67+ -- |
6968-- | This function is a slight generalization of `scc` which allows key and value types
7069-- | to differ.
7170scc' :: forall k v . (Eq k , Ord k ) => (v -> k ) -> (k -> v ) -> Graph k v -> List (SCC v )
7271scc' makeKey makeVert (Graph vs es) = runPure (runST (do
73- index <- newSTRef zero
72+ index <- newSTRef zero
7473 path <- newSTRef Nil
7574 indexMap <- newSTRef M .empty
7675 lowlinkMap <- newSTRef M .empty
7776 components <- newSTRef Nil
7877
79- (let
78+ (let
8079 indexOf v = indexOfKey (makeKey v)
81-
80+
8281 indexOfKey k = do
8382 m <- readSTRef indexMap
8483 return $ M .lookup k m
85-
84+
8685 lowlinkOf v = lowlinkOfKey (makeKey v)
87-
86+
8887 lowlinkOfKey k = do
8988 m <- readSTRef lowlinkMap
9089 return $ M .lookup k m
@@ -97,7 +96,7 @@ scc' makeKey makeVert (Graph vs es) = runPure (runST (do
9796
9897 strongConnect k = do
9998 let v = makeVert k
100-
99+
101100 i <- readSTRef index
102101
103102 modifySTRef indexMap $ M .insert k i
@@ -123,23 +122,23 @@ scc' makeKey makeVert (Graph vs es) = runPure (runST (do
123122 modifySTRef lowlinkMap $ M .alter (maybeMin index) k
124123
125124 vIndex <- indexOfKey k
126- vLowlink <- lowlinkOfKey k
125+ vLowlink <- lowlinkOfKey k
127126
128127 when (vIndex == vLowlink) $ do
129128 currentPath <- readSTRef path
130129 let newPath = popUntil makeKey v currentPath Nil
131130 modifySTRef components $ flip (++) (singleton (makeComponent newPath.component))
132131 writeSTRef path newPath.path
133132 return unit
134-
133+
135134 makeComponent (Cons v Nil ) | not (isCycle (makeKey v)) = AcyclicSCC v
136135 makeComponent vs = CyclicSCC vs
137-
136+
138137 isCycle k = any (\(Edge k1 k2) -> k1 == k && k2 == k) es
139138 in go vs)))
140139
141140popUntil :: forall k v . (Eq k ) => (v -> k ) -> v -> List v -> List v -> { path :: List v , component :: List v }
142- popUntil _ _ Nil popped = { path: Nil , component: popped }
141+ popUntil _ _ Nil popped = { path: Nil , component: popped }
143142popUntil makeKey v (Cons w path) popped | makeKey v == makeKey w = { path: path, component: Cons w popped }
144143popUntil makeKey v (Cons w ws) popped = popUntil makeKey v ws (Cons w popped)
145144
@@ -154,7 +153,7 @@ topSort :: forall v. (Eq v, Ord v) => Graph v v -> List v
154153topSort = topSort' id id
155154
156155-- | Topologically sort the vertices of a graph
157- -- |
156+ -- |
158157-- | This function is a slight generalization of `scc` which allows key and value types
159158-- | to differ.
160159topSort' :: forall k v . (Eq k , Ord k ) => (v -> k ) -> (k -> v ) -> Graph k v -> List v
0 commit comments