1{-# LANGUAGE CPP #-}
2#if __GLASGOW_HASKELL__
3{-# LANGUAGE Rank2Types #-}
4{-# LANGUAGE DeriveDataTypeable #-}
5{-# LANGUAGE StandaloneDeriving #-}
6#endif
7#if __GLASGOW_HASKELL__ >= 703
8{-# LANGUAGE Trustworthy #-}
9#endif
10#if __GLASGOW_HASKELL__ >= 702
11{-# LANGUAGE DeriveGeneric #-}
12{-# LANGUAGE StandaloneDeriving #-}
13#endif
14
15#include "containers.h"
16
17-----------------------------------------------------------------------------
18-- |
19-- Module      :  Data.Graph
20-- Copyright   :  (c) The University of Glasgow 2002
21-- License     :  BSD-style (see the file libraries/base/LICENSE)
22--
23-- Maintainer  :  libraries@haskell.org
24-- Portability :  portable
25--
26-- A version of the graph algorithms described in:
27--
28--   /Structuring Depth-First Search Algorithms in Haskell/,
29--   by David King and John Launchbury.
30--
31-----------------------------------------------------------------------------
32
33module Data.Graph(
34
35        -- * External interface
36
37        -- At present the only one with a "nice" external interface
38        stronglyConnComp, stronglyConnCompR, SCC(..), flattenSCC, flattenSCCs,
39
40        -- * Graphs
41
42        Graph, Table, Bounds, Edge, Vertex,
43
44        -- ** Building graphs
45
46        graphFromEdges, graphFromEdges', buildG, transposeG,
47        -- reverseE,
48
49        -- ** Graph properties
50
51        vertices, edges,
52        outdegree, indegree,
53
54        -- * Algorithms
55
56        dfs, dff,
57        topSort,
58        components,
59        scc,
60        bcc,
61        -- tree, back, cross, forward,
62        reachable, path,
63
64        module Data.Tree
65
66    ) where
67
68#if __GLASGOW_HASKELL__
69# define USE_ST_MONAD 1
70#endif
71
72-- Extensions
73#if USE_ST_MONAD
74import Control.Monad.ST
75import Data.Array.ST (STArray, newArray, readArray, writeArray)
76#else
77import Data.IntSet (IntSet)
78import qualified Data.IntSet as Set
79#endif
80import Data.Tree (Tree(Node), Forest)
81
82-- std interfaces
83import Control.Applicative
84#if !MIN_VERSION_base(4,8,0)
85import qualified Data.Foldable as F
86import Data.Traversable
87#else
88import Data.Foldable as F
89#endif
90import Control.DeepSeq (NFData(rnf))
91import Data.Maybe
92import Data.Array
93import Data.List
94#if MIN_VERSION_base(4,9,0)
95import Data.Functor.Classes
96import Data.Semigroup (Semigroup (..))
97#endif
98#if __GLASGOW_HASKELL__ >= 706
99import GHC.Generics (Generic, Generic1)
100#elif __GLASGOW_HASKELL__ >= 702
101import GHC.Generics (Generic)
102#endif
103#ifdef __GLASGOW_HASKELL__
104import Data.Data (Data)
105#endif
106import Data.Typeable
107
108
109-------------------------------------------------------------------------
110--                                                                      -
111--      External interface
112--                                                                      -
113-------------------------------------------------------------------------
114
115-- | Strongly connected component.
116data SCC vertex = AcyclicSCC vertex     -- ^ A single vertex that is not
117                                        -- in any cycle.
118                | CyclicSCC  [vertex]   -- ^ A maximal set of mutually
119                                        -- reachable vertices.
120#if __GLASGOW_HASKELL__ >= 802
121  deriving ( Eq   -- ^ @since 0.5.9
122           , Show -- ^ @since 0.5.9
123           , Read -- ^ @since 0.5.9
124           )
125#else
126  deriving (Eq, Show, Read)
127#endif
128
129INSTANCE_TYPEABLE1(SCC)
130
131#ifdef __GLASGOW_HASKELL__
132-- | @since 0.5.9
133deriving instance Data vertex => Data (SCC vertex)
134#endif
135
136#if __GLASGOW_HASKELL__ >= 706
137-- | @since 0.5.9
138deriving instance Generic1 SCC
139#endif
140
141#if __GLASGOW_HASKELL__ >= 702
142-- | @since 0.5.9
143deriving instance Generic (SCC vertex)
144#endif
145
146#if MIN_VERSION_base(4,9,0)
147-- | @since 0.5.9
148instance Eq1 SCC where
149  liftEq eq (AcyclicSCC v1) (AcyclicSCC v2) = eq v1 v2
150  liftEq eq (CyclicSCC vs1) (CyclicSCC vs2) = liftEq eq vs1 vs2
151  liftEq _ _ _ = False
152-- | @since 0.5.9
153instance Show1 SCC where
154  liftShowsPrec sp _sl d (AcyclicSCC v) = showsUnaryWith sp "AcyclicSCC" d v
155  liftShowsPrec _sp sl d (CyclicSCC vs) = showsUnaryWith (const sl) "CyclicSCC" d vs
156-- | @since 0.5.9
157instance Read1 SCC where
158  liftReadsPrec rp rl = readsData $
159    readsUnaryWith rp "AcyclicSCC" AcyclicSCC <>
160    readsUnaryWith (const rl) "CyclicSCC" CyclicSCC
161#endif
162
163-- | @since 0.5.9
164instance F.Foldable SCC where
165  foldr c n (AcyclicSCC v) = c v n
166  foldr c n (CyclicSCC vs) = foldr c n vs
167
168-- | @since 0.5.9
169instance Traversable SCC where
170  -- We treat the non-empty cyclic case specially to cut one
171  -- fmap application.
172  traverse f (AcyclicSCC vertex) = AcyclicSCC <$> f vertex
173  traverse _f (CyclicSCC []) = pure (CyclicSCC [])
174  traverse f (CyclicSCC (x : xs)) =
175    liftA2 (\x' xs' -> CyclicSCC (x' : xs')) (f x) (traverse f xs)
176
177instance NFData a => NFData (SCC a) where
178    rnf (AcyclicSCC v) = rnf v
179    rnf (CyclicSCC vs) = rnf vs
180
181-- | @since 0.5.4
182instance Functor SCC where
183    fmap f (AcyclicSCC v) = AcyclicSCC (f v)
184    fmap f (CyclicSCC vs) = CyclicSCC (fmap f vs)
185
186-- | The vertices of a list of strongly connected components.
187flattenSCCs :: [SCC a] -> [a]
188flattenSCCs = concatMap flattenSCC
189
190-- | The vertices of a strongly connected component.
191flattenSCC :: SCC vertex -> [vertex]
192flattenSCC (AcyclicSCC v) = [v]
193flattenSCC (CyclicSCC vs) = vs
194
195-- | The strongly connected components of a directed graph, topologically
196-- sorted.
197stronglyConnComp
198        :: Ord key
199        => [(node, key, [key])]
200                -- ^ The graph: a list of nodes uniquely identified by keys,
201                -- with a list of keys of nodes this node has edges to.
202                -- The out-list may contain keys that don't correspond to
203                -- nodes of the graph; such edges are ignored.
204        -> [SCC node]
205
206stronglyConnComp edges0
207  = map get_node (stronglyConnCompR edges0)
208  where
209    get_node (AcyclicSCC (n, _, _)) = AcyclicSCC n
210    get_node (CyclicSCC triples)     = CyclicSCC [n | (n,_,_) <- triples]
211
212-- | The strongly connected components of a directed graph, topologically
213-- sorted.  The function is the same as 'stronglyConnComp', except that
214-- all the information about each node retained.
215-- This interface is used when you expect to apply 'SCC' to
216-- (some of) the result of 'SCC', so you don't want to lose the
217-- dependency information.
218stronglyConnCompR
219        :: Ord key
220        => [(node, key, [key])]
221                -- ^ The graph: a list of nodes uniquely identified by keys,
222                -- with a list of keys of nodes this node has edges to.
223                -- The out-list may contain keys that don't correspond to
224                -- nodes of the graph; such edges are ignored.
225        -> [SCC (node, key, [key])]     -- ^ Topologically sorted
226
227stronglyConnCompR [] = []  -- added to avoid creating empty array in graphFromEdges -- SOF
228stronglyConnCompR edges0
229  = map decode forest
230  where
231    (graph, vertex_fn,_) = graphFromEdges edges0
232    forest             = scc graph
233    decode (Node v []) | mentions_itself v = CyclicSCC [vertex_fn v]
234                       | otherwise         = AcyclicSCC (vertex_fn v)
235    decode other = CyclicSCC (dec other [])
236                 where
237                   dec (Node v ts) vs = vertex_fn v : foldr dec vs ts
238    mentions_itself v = v `elem` (graph ! v)
239
240-------------------------------------------------------------------------
241--                                                                      -
242--      Graphs
243--                                                                      -
244-------------------------------------------------------------------------
245
246-- | Abstract representation of vertices.
247type Vertex  = Int
248-- | Table indexed by a contiguous set of vertices.
249type Table a = Array Vertex a
250-- | Adjacency list representation of a graph, mapping each vertex to its
251-- list of successors.
252type Graph   = Table [Vertex]
253-- | The bounds of a 'Table'.
254type Bounds  = (Vertex, Vertex)
255-- | An edge from the first vertex to the second.
256type Edge    = (Vertex, Vertex)
257
258-- | All vertices of a graph.
259vertices :: Graph -> [Vertex]
260vertices  = indices
261
262-- | All edges of a graph.
263edges    :: Graph -> [Edge]
264edges g   = [ (v, w) | v <- vertices g, w <- g!v ]
265
266mapT    :: (Vertex -> a -> b) -> Table a -> Table b
267mapT f t = array (bounds t) [ (,) v (f v (t!v)) | v <- indices t ]
268
269-- | Build a graph from a list of edges.
270buildG :: Bounds -> [Edge] -> Graph
271buildG bounds0 edges0 = accumArray (flip (:)) [] bounds0 edges0
272
273-- | The graph obtained by reversing all edges.
274transposeG  :: Graph -> Graph
275transposeG g = buildG (bounds g) (reverseE g)
276
277reverseE    :: Graph -> [Edge]
278reverseE g   = [ (w, v) | (v, w) <- edges g ]
279
280-- | A table of the count of edges from each node.
281outdegree :: Graph -> Table Int
282outdegree  = mapT numEdges
283             where numEdges _ ws = length ws
284
285-- | A table of the count of edges into each node.
286indegree :: Graph -> Table Int
287indegree  = outdegree . transposeG
288
289-- | Identical to 'graphFromEdges', except that the return value
290-- does not include the function which maps keys to vertices.  This
291-- version of 'graphFromEdges' is for backwards compatibility.
292graphFromEdges'
293        :: Ord key
294        => [(node, key, [key])]
295        -> (Graph, Vertex -> (node, key, [key]))
296graphFromEdges' x = (a,b) where
297    (a,b,_) = graphFromEdges x
298
299-- | Build a graph from a list of nodes uniquely identified by keys,
300-- with a list of keys of nodes this node should have edges to.
301-- The out-list may contain keys that don't correspond to
302-- nodes of the graph; they are ignored.
303graphFromEdges
304        :: Ord key
305        => [(node, key, [key])]
306        -> (Graph, Vertex -> (node, key, [key]), key -> Maybe Vertex)
307graphFromEdges edges0
308  = (graph, \v -> vertex_map ! v, key_vertex)
309  where
310    max_v           = length edges0 - 1
311    bounds0         = (0,max_v) :: (Vertex, Vertex)
312    sorted_edges    = sortBy lt edges0
313    edges1          = zipWith (,) [0..] sorted_edges
314
315    graph           = array bounds0 [(,) v (mapMaybe key_vertex ks) | (,) v (_,    _, ks) <- edges1]
316    key_map         = array bounds0 [(,) v k                       | (,) v (_,    k, _ ) <- edges1]
317    vertex_map      = array bounds0 edges1
318
319    (_,k1,_) `lt` (_,k2,_) = k1 `compare` k2
320
321    -- key_vertex :: key -> Maybe Vertex
322    --  returns Nothing for non-interesting vertices
323    key_vertex k   = findVertex 0 max_v
324                   where
325                     findVertex a b | a > b
326                              = Nothing
327                     findVertex a b = case compare k (key_map ! mid) of
328                                   LT -> findVertex a (mid-1)
329                                   EQ -> Just mid
330                                   GT -> findVertex (mid+1) b
331                              where
332                                mid = a + (b - a) `div` 2
333
334-------------------------------------------------------------------------
335--                                                                      -
336--      Depth first search
337--                                                                      -
338-------------------------------------------------------------------------
339
340-- | A spanning forest of the graph, obtained from a depth-first search of
341-- the graph starting from each vertex in an unspecified order.
342dff          :: Graph -> Forest Vertex
343dff g         = dfs g (vertices g)
344
345-- | A spanning forest of the part of the graph reachable from the listed
346-- vertices, obtained from a depth-first search of the graph starting at
347-- each of the listed vertices in order.
348dfs          :: Graph -> [Vertex] -> Forest Vertex
349dfs g vs      = prune (bounds g) (map (generate g) vs)
350
351generate     :: Graph -> Vertex -> Tree Vertex
352generate g v  = Node v (map (generate g) (g!v))
353
354prune        :: Bounds -> Forest Vertex -> Forest Vertex
355prune bnds ts = run bnds (chop ts)
356
357chop         :: Forest Vertex -> SetM s (Forest Vertex)
358chop []       = return []
359chop (Node v ts : us)
360              = do
361                visited <- contains v
362                if visited then
363                  chop us
364                 else do
365                  include v
366                  as <- chop ts
367                  bs <- chop us
368                  return (Node v as : bs)
369
370-- A monad holding a set of vertices visited so far.
371#if USE_ST_MONAD
372
373-- Use the ST monad if available, for constant-time primitives.
374
375newtype SetM s a = SetM { runSetM :: STArray s Vertex Bool -> ST s a }
376
377instance Monad (SetM s) where
378    return = pure
379    {-# INLINE return #-}
380    SetM v >>= f = SetM $ \s -> do { x <- v s; runSetM (f x) s }
381    {-# INLINE (>>=) #-}
382
383instance Functor (SetM s) where
384    f `fmap` SetM v = SetM $ \s -> f `fmap` v s
385    {-# INLINE fmap #-}
386
387instance Applicative (SetM s) where
388    pure x = SetM $ const (return x)
389    {-# INLINE pure #-}
390    SetM f <*> SetM v = SetM $ \s -> f s >>= (`fmap` v s)
391    -- We could also use the following definition
392    --   SetM f <*> SetM v = SetM $ \s -> f s <*> v s
393    -- but Applicative (ST s) instance is present only in GHC 7.2+
394    {-# INLINE (<*>) #-}
395
396run          :: Bounds -> (forall s. SetM s a) -> a
397run bnds act  = runST (newArray bnds False >>= runSetM act)
398
399contains     :: Vertex -> SetM s Bool
400contains v    = SetM $ \ m -> readArray m v
401
402include      :: Vertex -> SetM s ()
403include v     = SetM $ \ m -> writeArray m v True
404
405#else /* !USE_ST_MONAD */
406
407-- Portable implementation using IntSet.
408
409newtype SetM s a = SetM { runSetM :: IntSet -> (a, IntSet) }
410
411instance Monad (SetM s) where
412    return x     = SetM $ \s -> (x, s)
413    SetM v >>= f = SetM $ \s -> case v s of (x, s') -> runSetM (f x) s'
414
415instance Functor (SetM s) where
416    f `fmap` SetM v = SetM $ \s -> case v s of (x, s') -> (f x, s')
417    {-# INLINE fmap #-}
418
419instance Applicative (SetM s) where
420    pure x = SetM $ \s -> (x, s)
421    {-# INLINE pure #-}
422    SetM f <*> SetM v = SetM $ \s -> case f s of (k, s') -> case v s' of (x, s'') -> (k x, s'')
423    {-# INLINE (<*>) #-}
424
425run          :: Bounds -> SetM s a -> a
426run _ act     = fst (runSetM act Set.empty)
427
428contains     :: Vertex -> SetM s Bool
429contains v    = SetM $ \ m -> (Set.member v m, m)
430
431include      :: Vertex -> SetM s ()
432include v     = SetM $ \ m -> ((), Set.insert v m)
433
434#endif /* !USE_ST_MONAD */
435
436-------------------------------------------------------------------------
437--                                                                      -
438--      Algorithms
439--                                                                      -
440-------------------------------------------------------------------------
441
442------------------------------------------------------------
443-- Algorithm 1: depth first search numbering
444------------------------------------------------------------
445
446preorder' :: Tree a -> [a] -> [a]
447preorder' (Node a ts) = (a :) . preorderF' ts
448
449preorderF' :: Forest a -> [a] -> [a]
450preorderF' ts = foldr (.) id $ map preorder' ts
451
452preorderF :: Forest a -> [a]
453preorderF ts = preorderF' ts []
454
455tabulate        :: Bounds -> [Vertex] -> Table Int
456tabulate bnds vs = array bnds (zipWith (,) vs [1..])
457
458preArr          :: Bounds -> Forest Vertex -> Table Int
459preArr bnds      = tabulate bnds . preorderF
460
461------------------------------------------------------------
462-- Algorithm 2: topological sorting
463------------------------------------------------------------
464
465postorder :: Tree a -> [a] -> [a]
466postorder (Node a ts) = postorderF ts . (a :)
467
468postorderF   :: Forest a -> [a] -> [a]
469postorderF ts = foldr (.) id $ map postorder ts
470
471postOrd :: Graph -> [Vertex]
472postOrd g = postorderF (dff g) []
473
474-- | A topological sort of the graph.
475-- The order is partially specified by the condition that a vertex /i/
476-- precedes /j/ whenever /j/ is reachable from /i/ but not vice versa.
477topSort      :: Graph -> [Vertex]
478topSort       = reverse . postOrd
479
480------------------------------------------------------------
481-- Algorithm 3: connected components
482------------------------------------------------------------
483
484-- | The connected components of a graph.
485-- Two vertices are connected if there is a path between them, traversing
486-- edges in either direction.
487components   :: Graph -> Forest Vertex
488components    = dff . undirected
489
490undirected   :: Graph -> Graph
491undirected g  = buildG (bounds g) (edges g ++ reverseE g)
492
493-- Algorithm 4: strongly connected components
494
495-- | The strongly connected components of a graph.
496scc  :: Graph -> Forest Vertex
497scc g = dfs g (reverse (postOrd (transposeG g)))
498
499------------------------------------------------------------
500-- Algorithm 5: Classifying edges
501------------------------------------------------------------
502
503{-
504XXX unused code
505
506tree              :: Bounds -> Forest Vertex -> Graph
507tree bnds ts       = buildG bnds (concat (map flat ts))
508 where flat (Node v ts') = [ (v, w) | Node w _us <- ts' ]
509                        ++ concat (map flat ts')
510
511back              :: Graph -> Table Int -> Graph
512back g post        = mapT select g
513 where select v ws = [ w | w <- ws, post!v < post!w ]
514
515cross             :: Graph -> Table Int -> Table Int -> Graph
516cross g pre post   = mapT select g
517 where select v ws = [ w | w <- ws, post!v > post!w, pre!v > pre!w ]
518
519forward           :: Graph -> Graph -> Table Int -> Graph
520forward g tree' pre = mapT select g
521 where select v ws = [ w | w <- ws, pre!v < pre!w ] \\ tree' ! v
522-}
523
524------------------------------------------------------------
525-- Algorithm 6: Finding reachable vertices
526------------------------------------------------------------
527
528-- | A list of vertices reachable from a given vertex.
529reachable    :: Graph -> Vertex -> [Vertex]
530reachable g v = preorderF (dfs g [v])
531
532-- | Is the second vertex reachable from the first?
533path         :: Graph -> Vertex -> Vertex -> Bool
534path g v w    = w `elem` (reachable g v)
535
536------------------------------------------------------------
537-- Algorithm 7: Biconnected components
538------------------------------------------------------------
539
540-- | The biconnected components of a graph.
541-- An undirected graph is biconnected if the deletion of any vertex
542-- leaves it connected.
543bcc :: Graph -> Forest [Vertex]
544bcc g = (concat . map bicomps . map (do_label g dnum)) forest
545 where forest = dff g
546       dnum   = preArr (bounds g) forest
547
548do_label :: Graph -> Table Int -> Tree Vertex -> Tree (Vertex,Int,Int)
549do_label g dnum (Node v ts) = Node (v,dnum!v,lv) us
550 where us = map (do_label g dnum) ts
551       lv = minimum ([dnum!v] ++ [dnum!w | w <- g!v]
552                     ++ [lu | Node (_,_,lu) _ <- us])
553
554bicomps :: Tree (Vertex,Int,Int) -> Forest [Vertex]
555bicomps (Node (v,_,_) ts)
556      = [ Node (v:vs) us | (_,Node vs us) <- map collect ts]
557
558collect :: Tree (Vertex,Int,Int) -> (Int, Tree [Vertex])
559collect (Node (v,dv,lv) ts) = (lv, Node (v:vs) cs)
560 where collected = map collect ts
561       vs = concat [ ws | (lw, Node ws _) <- collected, lw<dv]
562       cs = concat [ if lw<dv then us else [Node (v:ws) us]
563                        | (lw, Node ws us) <- collected ]
564