module Graphs.GraphOps(
isAncestor,
isAncestorBy,
) where
import qualified Data.Set as Set
import Util.Queue
import Graphs.Graph
isAncestor :: Graph graph
=> graph nodeLabel nodeTypeLabel arcLabel arcTypeLabel
-> Node -> Node -> IO Bool
isAncestor graph node1 node2 =
let
getChildren :: Node -> IO [Node]
getChildren node =
do
arcs <- getArcsOut graph node
mapM (\ arc -> getTarget graph arc) arcs
in
isAncestorBy getChildren node1 node2
isAncestorBy :: Ord key => (key -> IO [key]) -> key -> key -> IO Bool
isAncestorBy getChildren (node1 :: node) node2 =
do
let
search :: Set.Set node -> Queue node -> IO Bool
search visited toDo0 = case removeQ toDo0 of
Nothing -> return False
Just (node,toDo1) ->
if Set.member node visited
then
search visited toDo1
else
if node == node2
then
return True
else
do
children <- getChildren node
let
toDo2 = foldl insertQ toDo1 children
visited1 = Set.insert node visited
search visited1 toDo2
search Set.empty (singletonQ node1)