Fix CodingStyle#Warnings URLs
[ghc-hetmet.git] / compiler / utils / Digraph.lhs
index 8fda332..6617459 100644 (file)
@@ -1,68 +1,76 @@
+%
+% (c) The University of Glasgow 2006
+%
+
 \begin{code}
-module Digraph(
+{-# OPTIONS -w #-}
+-- The above warning supression flag is a temporary kludge.
+-- While working on this module you are encouraged to remove it and fix
+-- any warnings in the module. See
+--     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
+-- for details
 
-       -- At present the only one with a "nice" external interface
-       stronglyConnComp, stronglyConnCompR, SCC(..), flattenSCC, flattenSCCs,
+module Digraph(
 
-       Graph, Vertex, 
-       graphFromEdges, graphFromEdges', 
-       buildG, transposeG, reverseE, outdegree, indegree,
+        -- At present the only one with a "nice" external interface
+        stronglyConnComp, stronglyConnCompR, SCC(..), flattenSCC, flattenSCCs,
 
-       Tree(..), Forest,
-       showTree, showForest,
+        Graph, Vertex,
+        graphFromEdges, graphFromEdges',
+        buildG, transposeG, reverseE, outdegree, indegree,
 
-       dfs, dff,
-       topSort,
-       components,
-       scc,
-       back, cross, forward,
-       reachable, path,
-       bcc
+        Tree(..), Forest,
+        showTree, showForest,
 
+        dfs, dff,
+        topSort,
+        components,
+        scc,
+        back, cross, forward,
+        reachable, path,
+        bcc
     ) where
 
 # include "HsVersions.h"
 
 ------------------------------------------------------------------------------
 -- A version of the graph algorithms described in:
--- 
+--
 -- ``Lazy Depth-First Search and Linear Graph Algorithms in Haskell''
 --   by David King and John Launchbury
--- 
+--
 -- Also included is some additional code for printing tree structures ...
 ------------------------------------------------------------------------------
 
 
-import Util    ( sortLe )
+import Util        ( sortLe )
+import Outputable
 
 -- Extensions
-import MONAD_ST
+import Control.Monad.ST
 
 -- std interfaces
-import Maybe
-import Array
-import List
-import Outputable
+import Data.Maybe
+import Data.Array
+import Data.List
 
 #if __GLASGOW_HASKELL__ > 604
 import Data.Array.ST
-#elif __GLASGOW_HASKELL__ >= 504
-import Data.Array.ST  hiding ( indices, bounds )
 #else
-import ST
+import Data.Array.ST  hiding ( indices, bounds )
 #endif
 \end{code}
 
 
 %************************************************************************
-%*                                                                     *
-%*     External interface
-%*                                                                     *
+%*                                                                      *
+%*      External interface
+%*                                                                      *
 %************************************************************************
 
 \begin{code}
 data SCC vertex = AcyclicSCC vertex
-               | CyclicSCC  [vertex]
+                | CyclicSCC  [vertex]
 
 flattenSCCs :: [SCC a] -> [a]
 flattenSCCs = concatMap flattenSCC
@@ -77,12 +85,12 @@ instance Outputable a => Outputable (SCC a) where
 
 \begin{code}
 stronglyConnComp
-       :: Ord key
-       => [(node, key, [key])]         -- The graph; its ok for the
-                                       -- out-list to contain keys which arent
-                                       -- a vertex key, they are ignored
-       -> [SCC node]   -- Returned in topologically sorted order
-                       -- Later components depend on earlier ones, but not vice versa
+        :: Ord key
+        => [(node, key, [key])]         -- The graph; its ok for the
+                                        -- out-list to contain keys which arent
+                                        -- a vertex key, they are ignored
+        -> [SCC node]   -- Returned in topologically sorted order
+                        -- Later components depend on earlier ones, but not vice versa
 
 stronglyConnComp edges
   = map get_node (stronglyConnCompR edges)
@@ -93,30 +101,30 @@ stronglyConnComp edges
 -- The "R" interface is used when you expect to apply SCC to
 -- the (some of) the result of SCC, so you dont want to lose the dependency info
 stronglyConnCompR
-       :: Ord key
-       => [(node, key, [key])]         -- The graph; its ok for the
-                                       -- out-list to contain keys which arent
-                                       -- a vertex key, they are ignored
-       -> [SCC (node, key, [key])]     -- Topologically sorted
+        :: Ord key
+        => [(node, key, [key])]         -- The graph; its ok for the
+                                        -- out-list to contain keys which arent
+                                        -- a vertex key, they are ignored
+        -> [SCC (node, key, [key])]     -- Topologically sorted
 
 stronglyConnCompR [] = []  -- added to avoid creating empty array in graphFromEdges -- SOF
 stronglyConnCompR edges
   = map decode forest
   where
-    (graph, vertex_fn) = _scc_ "graphFromEdges" graphFromEdges edges
-    forest            = _scc_ "Digraph.scc" scc graph
+    (graph, vertex_fn) = {-# SCC "graphFromEdges" #-} graphFromEdges edges
+    forest             = {-# SCC "Digraph.scc" #-} scc graph
     decode (Node v []) | mentions_itself v = CyclicSCC [vertex_fn v]
-                      | otherwise         = AcyclicSCC (vertex_fn v)
+                       | otherwise         = AcyclicSCC (vertex_fn v)
     decode other = CyclicSCC (dec other [])
-                where
-                  dec (Node v ts) vs = vertex_fn v : foldr dec vs ts
+                 where
+                   dec (Node v ts) vs = vertex_fn v : foldr dec vs ts
     mentions_itself v = v `elem` (graph ! v)
 \end{code}
 
 %************************************************************************
-%*                                                                     *
-%*     Graphs
-%*                                                                     *
+%*                                                                      *
+%*      Graphs
+%*                                                                      *
 %************************************************************************
 
 
@@ -136,7 +144,7 @@ edges    :: Graph -> [Edge]
 edges g   = [ (v, w) | v <- vertices g, w <- g!v ]
 
 mapT    :: (Vertex -> a -> b) -> Table a -> Table b
-mapT f t = array (bounds t) [ (,) v (f v (t!v)) | v <- indices t ]
+mapT f t = array (bounds t) [ (v, f v (t ! v)) | v <- indices t ]
 
 buildG :: Bounds -> [Edge] -> Graph
 buildG bounds edges = accumArray (flip (:)) [] bounds edges
@@ -157,51 +165,53 @@ indegree  = outdegree . transposeG
 
 
 \begin{code}
-graphFromEdges 
-       :: Ord key
-       => [(node, key, [key])]
-       -> (Graph, Vertex -> (node, key, [key]))
-graphFromEdges edges = 
-  case graphFromEdges' edges of (graph, vertex_fn, _) -> (graph, vertex_fn) 
+graphFromEdges
+        :: Ord key
+        => [(node, key, [key])]
+        -> (Graph, Vertex -> (node, key, [key]))
+graphFromEdges edges =
+  case graphFromEdges' edges of (graph, vertex_fn, _) -> (graph, vertex_fn)
 
 graphFromEdges'
-       :: Ord key
-       => [(node, key, [key])]
-       -> (Graph, Vertex -> (node, key, [key]), key -> Maybe Vertex)
+        :: Ord key
+        => [(node, key, [key])]
+        -> (Graph, Vertex -> (node, key, [key]), key -> Maybe Vertex)
 graphFromEdges' edges
   = (graph, \v -> vertex_map ! v, key_vertex)
   where
-    max_v                  = length edges - 1
+    max_v           = length edges - 1
     bounds          = (0,max_v) :: (Vertex, Vertex)
     sorted_edges    = let
-                        (_,k1,_) `le` (_,k2,_) = case k1 `compare` k2 of { GT -> False; other -> True }
-                     in
-                       sortLe le edges
-    edges1         = zipWith (,) [0..] sorted_edges
+                         (_,k1,_) `le` (_,k2,_) = case k1 `compare` k2 of { GT -> False; other -> True }
+                      in
+                        sortLe le edges
+    edges1          = zipWith (,) [0..] sorted_edges
 
-    graph          = array bounds [(,) v (mapMaybe key_vertex ks) | (,) v (_,    _, ks) <- edges1]
-    key_map        = array bounds [(,) v k                        | (,) v (_,    k, _ ) <- edges1]
-    vertex_map     = array bounds edges1
+    graph           = array bounds [ (v, mapMaybe key_vertex ks)
+                               | (v, (_,    _, ks)) <- edges1]
+    key_map         = array bounds [ (v, k)
+                               | (v, (_,    k, _ )) <- edges1]
+    vertex_map      = array bounds edges1
 
 
     -- key_vertex :: key -> Maybe Vertex
-    --         returns Nothing for non-interesting vertices
-    key_vertex k   = find 0 max_v 
-                  where
-                    find a b | a > b 
-                             = Nothing
-                    find a b = case compare k (key_map ! mid) of
-                                  LT -> find a (mid-1)
-                                  EQ -> Just mid
-                                  GT -> find (mid+1) b
-                             where
-                               mid = (a + b) `div` 2
+    --  returns Nothing for non-interesting vertices
+    key_vertex k   = find 0 max_v
+                   where
+                     find a b | a > b
+                              = Nothing
+                     find a b = case compare k (key_map ! mid) of
+                                   LT -> find a (mid-1)
+                                   EQ -> Just mid
+                                   GT -> find (mid+1) b
+                              where
+                                mid = (a + b) `div` 2
 \end{code}
 
 %************************************************************************
-%*                                                                     *
-%*     Trees and forests
-%*                                                                     *
+%*                                                                      *
+%*      Trees and forests
+%*                                                                      *
 %************************************************************************
 
 \begin{code}
@@ -244,33 +254,22 @@ draw (Node x ts) = grp this (space (length this)) (stLoop ts)
 
 
 %************************************************************************
-%*                                                                     *
-%*     Depth first search
-%*                                                                     *
+%*                                                                      *
+%*      Depth first search
+%*                                                                      *
 %************************************************************************
 
 \begin{code}
-#if __GLASGOW_HASKELL__ >= 504
-newSTArray :: Ix i => (i,i) -> e -> ST s (STArray s i e)
-newSTArray = newArray
-
-readSTArray :: Ix i => STArray s i e -> i -> ST s e
-readSTArray = readArray
-
-writeSTArray :: Ix i => STArray s i e -> i -> e -> ST s ()
-writeSTArray = writeArray
-#endif
-
 type Set s    = STArray s Vertex Bool
 
 mkEmpty      :: Bounds -> ST s (Set s)
-mkEmpty bnds  = newSTArray bnds False
+mkEmpty bnds  = newArray bnds False
 
 contains     :: Set s -> Vertex -> ST s Bool
-contains m v  = readSTArray m v
+contains m v  = readArray m v
 
 include      :: Set s -> Vertex -> ST s ()
-include m v   = writeSTArray m v True
+include m v   = writeArray m v True
 \end{code}
 
 \begin{code}
@@ -302,9 +301,9 @@ chop m (Node v ts : us)
 
 
 %************************************************************************
-%*                                                                     *
-%*     Algorithms
-%*                                                                     *
+%*                                                                      *
+%*      Algorithms
+%*                                                                      *
 %************************************************************************
 
 ------------------------------------------------------------
@@ -331,17 +330,17 @@ preArr bnds      = tabulate bnds . preorderF
 ------------------------------------------------------------
 
 \begin{code}
---postorder :: Tree a -> [a]
-postorder (Node a ts) = postorderF ts ++ [a]
+postorder :: Tree a -> [a] -> [a]
+postorder (Node a ts) = postorderF ts . (a :)
 
-postorderF   :: Forest a -> [a]
-postorderF ts = concat (map postorder ts)
+postorderF   :: Forest a -> [a] -> [a]
+postorderF ts = foldr (.) id $ map postorder ts
 
-postOrd      :: Graph -> [Vertex]
-postOrd       = postorderF . dff
+postOrd :: Graph -> [Vertex]
+postOrd g = postorderF (dff g) []
 
-topSort      :: Graph -> [Vertex]
-topSort       = reverse . postOrd
+topSort :: Graph -> [Vertex]
+topSort = reverse . postOrd
 \end{code}