----------------------------------------------------------------------------- -- A representation of "compositional" graphs ----------------------------------------------------------------------------- module Graph(Graph(..),Node(..),Edge(..),NodeId, joinGraphs,addNode,addEdge,isFinalizedGraph,showGraph) where import DaVinci -- A graph is a list of nodes and edges: data Graph = Graph [Node] [Edge] -- A node identifier is basically a natural number. -- However, this data type is abstract so that the user cannot -- explicitly construct node identifiers. data NodeId = NodeId Int -- A node is identified by a node identifier but more node infos -- could be added: data Node = Node NodeId -- An edge consists of a source and a target node which are -- identified by their node identifiers: data Edge = Edge NodeId NodeId -- Combine two graphs. joinGraphs (Graph ns1 es1) (Graph ns2 es2) = Graph (ns1++ns2) (es1++es2) -- Add a node two a graph. addNode n (Graph ns es) = Graph (Node n : ns) es -- Add a new edge between two nodes of a graph. addEdge n1 n2 (Graph ns es) = Graph ns (Edge n1 n2 : es) -- A graph is finalized for further processing if all nodes -- have uniquely assigned node identifiers: isFinalizedGraph :: Graph -> Success isFinalizedGraph (Graph nodes _) = numberNodes 1 nodes where numberNodes _ [] = success numberNodes n (Node ni : ns) | ni =:= NodeId n -- assign unique identifier = numberNodes (n+1) ns -- As an example, we convert this representation into the daVinci -- representation by grouping edges to their source node -- and displaying the graph: showGraph :: Graph -> IO () showGraph graph | isFinalizedGraph graph = (dvDisplay . graph2dv) graph graph2dv (Graph nodes edges) | nodes==nodes -- ensure that all nodeids are assigned = dvNewGraph (map (\(dvid,nodeid)-> dvNodeWithEdges dvid (make_label nodeid) (map (\(Edge _ n2)->createEdge n2) (filter (\(Edge n1 _)->n1==nodeid) edges)) dvEmptyH) idnodes) where idnodes = map node2idnode nodes createEdge nodeid = dvSimpleEdge e (fst (head (filter (\(_,n)->n==nodeid) idnodes))) dvEmptyH where e free -- transform node into a DvId/NodeId pair: node2idnode (Node nodeid) = (dvid,nodeid) where dvid free make_label (NodeId num) = "Node "++show num -- end of Graph library