SimpleGraphs.hs

-- Graphs, with minimal assumptions about the nodes
module SimpleGraphs where

import List(nub)
import Maybe(fromMaybe)
import MUtils(collectByFst,swap)



type Graph a = [(a,[a])]
type Reachable a = [a]

graph         ::          [(a,[a])] -> Graph a
reachable     :: Eq a  => Graph a -> [a] -> Reachable a
isReachable   :: Eq a  => Reachable a -> a -> Bool
listReachable ::          Reachable a -> [a]
neighbours    :: Eq a  => Graph a ->  a  -> [a]
nodes         ::          Graph a -> [a] -- may exclude nodes without edges
edges         ::          Graph a ->        [(a,a)]
reverseGraph  :: Ord a => Graph a ->        Graph a

graph = id

-- The set of reachable nodes from a given node in a graph:
reachable graph = r []
  where
    r reached [] = reached
    r reached (s:ss) =
      if s `elem` reached
      then r reached ss
      else r (s:reached) (push (neighbours graph s) ss)

    push [] ss = ss
    push (x:xs) ss = push xs (x:ss)

-- nonreflexive:
reachable' g = reachable g . nub . concatMap (neighbours g)

isReachable xs x = x `elem` xs
listReachable = id

neighbours g n = fromMaybe [] (lookup n g)

reverseGraph g = collectByFst . map swap . edges $ g

edges g = [(from,to)|(from,ns)<-g,to<-ns]
nodes = map fst

Plain-text version of SimpleGraphs.hs | Valid HTML?