-----------------------------------------------------------------------------
-- |
-- Module : Order
-- Copyright : Thomas Hallgren? Lennart Augustsson?
--
-- Maintainer : Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk>
-- Stability : Stable
-- Portability : All
--
-- Provides a strongly connected component topological sort.
-----------------------------------------------------------------------------
module Order (closegraph, decorate, scctsort) where
import Compat(assocFail)
import Graph(scceq)
import ListUtil(lconcatMap)
import Tsort
import Utils(apair, asnd, pairwith)
-- unused in hmake
decorate :: (Eq a) => [(a, b)]
-> (t, [[a]])
-> (t, [[(a, b)]])
decorate g = asnd (map (map (\f -> (f, assocFail f g))))
-- | Topological sort of strongly connected components.
-- Nodes within a scc will appear in an arbitrary order.
scctsort g =
let sccg = scceq (==) g
sccs = map (map fst) sccg
cg = map collapse_node sccg
sortg = (ptsort . rmreflx . closegraph . collapse_graph sccs) cg
in sccs
closegraph g =
let nodes = map fst g
isnode f = f `elem` nodes
in map (asnd (filter isnode)) g
rmreflx xs = map (\(f, fs) -> (f, filter (/= f) fs)) xs
collapse_node ((f, fs) : ms) = (f, fs ++ concat (map snd ms))
collapse_graph eq = map (apair (pairwith map (reprnode eq)))
reconstruct sccg f =
assocFail f (map (\((f', _) : fs) -> (f', f' : map fst fs)) sccg)
reprnode eq a = (head . head . filter (a `elem`)) eq
|