module Data.Graph.Inductive.Basic
       (gsel, gfold, hasLoop,
        isSimple, postorder, postorderF, preorder, preorderF)
       where
{ import Data.Graph.Inductive.Graph;
  import Data.Graph.Inductive.Internal.Thread (threadMaybe,
                                               threadList);
  import Data.List (nub);
  import Data.Tree;
   
 
  gsel ::
       (Graph gr) => (Context a b -> Bool) -> gr a b -> [Context a b];
  gsel p = ufold (\ c cs -> if p c then c : cs else cs) [];
   
  hasLoop :: (Graph gr) => gr a b -> Bool;
  hasLoop = not . null . (gsel (\ c -> (node' c `elem` suc' c)));
   
  isSimple :: (Graph gr) => gr a b -> Bool;
  isSimple = not . hasLoop;
  threadGraph f c = threadMaybe f c match;
  gfold1 f d b = threadGraph d (\ c -> gfoldn f d b (f c));
  gfoldn f d b = threadList b (gfold1 f d b);
   
  gfold ::
        (Graph gr) =>
          (Context a b -> [Node]) ->
            (Context a b -> c -> d) ->
              (Maybe d -> c -> c, c) -> [Node] -> gr a b -> c;
  gfold f d b l g = fst (gfoldn f d b l g);
   
  postorder :: Tree a -> [a];
  postorder (Node v ts) = postorderF ts ++ [v];
   
  postorderF :: [Tree a] -> [a];
  postorderF = concatMap postorder;
   
  preorder :: Tree a -> [a];
  preorder = flatten;
   
  preorderF :: [Tree a] -> [a];
  preorderF = concatMap preorder}
