alpha-0.9.9.5: src/My/Data/Graph.hs
module My.Data.Graph(
Graph,Node(..),
empty,
lookupContext,getContext,
insertNode,deleteNode,modifyNode,
insertEdge,deleteEdge,
modifyInEdges,modifyOutEdges,
tag,inEdges,outEdges,edges,
nextNodes,prevNodes,
nodeList,nodeListFull,
mapNodes
)
where
import qualified Data.Map as M
import Data.List
import Data.Maybe
type Node = Int
data Context e n = Context {
nodeTag :: n,
nodeInEdges :: M.Map Node e,
nodeOutEdges :: M.Map Node e
} deriving Show
data Graph e n = Graph {
nbNodes :: Int,
graphNodes :: M.Map Node (Context e n)
}
empty = Graph 0 M.empty
lookupContext n (Graph _ nds) = M.lookup n nds
getContext n g = fromMaybe (error $ "No node "++show n++" in graph "++show g) $ lookupContext n g
insertNode x (Graph n nds) = (n,Graph (n+1) (M.insert n (Context x M.empty M.empty) nds))
deleteNode nd (Graph n nds) = Graph n (M.delete nd nds)
modifyNode nd f (Graph n nds) = Graph n (M.adjust (\(Context t i o) -> Context (f t) i o) nd nds)
insertEdge x n1 n2 (Graph n nds) = Graph n (M.adjust (modifyInEdges (M.insert n1 x)) n2 $
M.adjust (modifyOutEdges (M.insert n2 x)) n1 nds)
deleteEdge n1 n2 (Graph n nds) = Graph n (M.adjust (modifyInEdges (M.delete n1)) n2 $
M.adjust (modifyOutEdges (M.delete n2)) n1 nds)
modifyInEdges f c = c { nodeInEdges = f $ nodeInEdges c }
modifyOutEdges f c = c { nodeOutEdges = f $ nodeOutEdges c }
tag = nodeTag
inEdges = M.toList . nodeInEdges
outEdges = M.toList . nodeOutEdges
edges c = (inEdges c,outEdges c)
nextNodes = map fst . outEdges
prevNodes = map fst . inEdges
nodeList = map fst . nodeListFull
nodeListFull = M.toList . graphNodes
mapNodes f (Graph n nds) = Graph n (M.mapWithKey (\n (Context t ie oe) -> Context (f n t) ie oe) nds)
instance (Show n,Show e) => Show (Graph e n) where
show (Graph _ nds) = intercalate "\n" showNodes
where showNodes = map showNode $ M.toList nds
showNode (n,Context nd ie oe) =
show n++": "++show nd++"\n "++
intercalate "\n " (map showNEdge (M.toList oe)
++ map showREdge (M.toList ie))
where showNEdge (n',e) = "--"++show e++"--> "++show n'
showREdge (n',e) = "<--"++show e++"-- "++show n'