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 -} -}