linear-maps-0.6: Data/Graph/IdMap.hs
module Data.Graph.IdMap where
import Data.IdMap
import qualified Data.List as List
------------------------------------
type Children a = a -> [a]
x .: ~(st, l) = (st, x: l)
depthFirstWalk' :: I m => Children (Id a) -> Set m a -> [Id a] -> (Set m a, [Id a])
depthFirstWalk' children s [] = (s, [])
depthFirstWalk' children s (h: t)
| h `member` s = depthFirstWalk' children s t
| otherwise = h .: depthFirstWalk' children (setInsert h s) (children h ++ t)
depthFirstWalk :: I m => Children (Id a) -> Set m a -> [Id a] -> [Id a]
depthFirstWalk children _s [] = []
depthFirstWalk children s (h: t)
| h `member` s = depthFirstWalk children s t
| otherwise = h : depthFirstWalk children (setInsert h s) (children h ++ t)
{-
postOrderWalk :: I m => Children (Id a) -> Set m a -> [Id a] -> [Id a]
postOrderWalk children _s [] = []
postOrderWalk children s (h: t)
| h `member` s = postOrderWalk children s t
| otherwise = postOrderWalk children (setInsert h s) (children h) ++ [h] : t
-}
data Task a = Return a | Visit a
postOrderWalk :: I m => Children (Id a) -> Set m a -> [Id a] -> [Id a]
postOrderWalk children s l = collect s $ map Visit l where
collect _s [] = []
collect s (Return h: t) = h: collect s t
collect s (Visit h: t)
| h `member` s = collect s t
| otherwise = collect (setInsert h s) $ map Visit (children h) ++ Return h: t
scc :: I m => Set m a -> Set m a -> Children (Id a) -> Children (Id a) -> [Id a] -> [[Id a]]
scc k k' children revChildren l
= reverse $ filter (not . null) $ mapWalk k revChildren l' where
l' = reverse (postOrderWalk children k' l)
mapWalk :: I m => Set m a -> Children (Id a) -> [Id a] -> [[Id a]]
mapWalk k children l = f k l
where
f _s [] = []
f s (h:t) = c : f s' t
where (s', c) = collect s [] [h]
-- collect :: Set a -> [a] -> [a] -> (Set a, [a])
collect s acc [] = (s, acc)
collect s acc (h:t)
| h `member` s = collect s acc t
| otherwise = collect (setInsert h s) (h: acc) (children h ++ t)
-----------------------------------------------------------
{-
-- megkeressük azokat a csúcsokat, amelyekre többen is hivatkoznak
findShared
:: k
=> Bool -- számoljuk-e még egyszer a gyökereket
-> Bool -- nézzük-e a gyerektelen csúcsokat
-> Children (Id a)
-> [Id a] -- roots
-> [Id a]
findShared countRoots countLeafs ch roots = filter double nodes where
nodes = walk k1 ch roots
inv = inverse ch nodes
double x
| countLeafs = numOfParents x > 1
| otherwise = length (ch x) > 0 && numOfParents x > 1
numOfParents x
| countRoots && isRoot x = 1 + length (inv x)
| otherwise = length (inv x)
isRoot = flipElem roots
-}
{-
data Task' a = Down a | Up a
downUp i = [Down i, Up i]
-- keresünk olyan csúcsokat, amelyeknek a kivétele megszünteti a ciklusokat
breakCycles :: Empty k -> Children (Id a) -> [Id a] -> [Id a]
breakCycles k children roots = collect (emptySet k) (emptySet k) $ concatMap downUp roots where
-- collect :: Set a -> [a] -> [a]
collect parents visited [] = []
collect parents visited (Up h:t)
= collect (delete h parents) visited t
collect parents visited (Down h:t)
| member h parents = h : collect parents visited t
| member h visited = collect parents visited t
| otherwise = collect (setInsert h parents) (setInsert h visited) $ concatMap downUp (children h) ++ t
cyclic, acyclic :: Empty k -> Children (Id a) -> [Id a] -> Bool
acyclic k ch r = List.null $ breakCycles k ch r
cyclic k ch r = not $ acyclic k ch r
---------
mapg :: Empty k1 -> Empty k2 -> Children (Id a) -> ((Id a->b) -> Id a -> b) -> [Id a] -> [b]
mapg k1 k2 ch h nodes = map f nodes where
f = memo k1 (h f) (walk k2 ch nodes)
{-
mapg' :: Empty k -> Children (Id a) -> ((a->b) -> a -> PreIds p -> b) -> [a] -> PreIds p -> [b]
mapg' ch h nodes ids = map f nodes where
f = memo' (h f) (walk ch nodes) ids
-}
-}