Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Synopsis
- data Graph edge node edgeLabel nodeLabel
- type LabeledNode n label = (n, label)
- type LabeledEdge edge node label = (edge node, label)
- class (Foldable edge, Ord1 edge) => Edge edge where
- defaultEdgeFoldMap :: (Edge edge, Monoid a) => edge a -> a
- data DirEdge node = DirEdge node node
- data UndirEdge node = UndirEdge node node
- undirEdge :: Ord node => node -> node -> UndirEdge node
- data EitherEdge node
- = EDirEdge (DirEdge node)
- | EUndirEdge (UndirEdge node)
- empty :: Graph edge node edgeLabel nodeLabel
- fromList :: (Edge e, Ord n) => [LabeledNode n nl] -> [LabeledEdge e n el] -> Graph e n el nl
- fromMap :: (Edge e, Ord n) => Map n nl -> Map (e n) el -> Graph e n el nl
- graphMap :: Graph edge node edgeLabel nodeLabel -> Map node (InOutMap edge node edgeLabel nodeLabel)
- nodeLabels :: (Edge e, Ord n) => Graph e n el nl -> Map n nl
- nodeSet :: Graph e n el nl -> Set n
- nodes :: (Edge edge, Ord node) => Graph edge node edgeLabel nodeLabel -> [node]
- nodeEdges :: (Edge edge, Ord node) => Graph edge node edgeLabel nodeLabel -> Map node (Set (edge node), nodeLabel, Set (edge node))
- edgeLabels :: (Edge edge, Ord node) => Graph edge node edgeLabel nodeLabel -> Map (edge node) edgeLabel
- edgeSet :: (Edge edge, Ord node) => Graph edge node edgeLabel nodeLabel -> Set (edge node)
- edges :: (Edge edge, Ord node) => Graph edge node edgeLabel nodeLabel -> [edge node]
- isEmpty :: Graph e n el nl -> Bool
- lookupNode :: Ord n => n -> Graph e n el nl -> Maybe nl
- lookupEdge :: (Edge e, Ord n) => e n -> Graph e n el nl -> Maybe el
- predecessors :: (Edge e, Ord n) => Graph e n el nl -> n -> [n]
- successors :: (Edge e, Ord n) => Graph e n el nl -> n -> [n]
- adjacentEdgeSet :: (Edge e, Ord n) => Graph e n el nl -> n -> Set (e n)
- adjacentEdges :: (Edge e, Ord n) => Graph e n el nl -> n -> Set (e n)
- isLoop :: (Edge edge, Eq node) => edge node -> Bool
- pathExists :: (Edge edge, Ord node) => node -> node -> Graph edge node edgeLabel nodeLabel -> Bool
- isConsistent :: (Ord n, Eq el) => Graph DirEdge n el nl -> Bool
- mapNode :: (nl0 -> nl1) -> Graph e n el nl0 -> Graph e n el nl1
- mapNodeWithKey :: (n -> nl0 -> nl1) -> Graph e n el nl0 -> Graph e n el nl1
- mapEdge :: (el0 -> el1) -> Graph e n el0 nl -> Graph e n el1 nl
- mapEdgeWithKey :: (e n -> el0 -> el1) -> Graph e n el0 nl -> Graph e n el1 nl
- mapNodeWithInOut :: (Edge e, Ord n) => (InOut e n el nl0 -> nl1) -> Graph e n el nl0 -> Graph e n el nl1
- type InOut e n el nl = ([LabeledEdge e n el], LabeledNode n nl, [LabeledEdge e n el])
- filterEdgeWithKey :: (Edge e, Ord n) => (e n -> el -> Bool) -> Graph e n el nl -> Graph e n el nl
- traverseNode :: (Applicative f, Edge e, Ord n) => (nl0 -> f nl1) -> Graph e n el nl0 -> f (Graph e n el nl1)
- traverseEdge :: (Applicative f, Edge e, Ord n) => (el0 -> f el1) -> Graph e n el0 nl -> f (Graph e n el1 nl)
- traverse :: (Applicative f, Edge e, Ord n) => (nl0 -> f nl1) -> (el0 -> f el1) -> Graph e n el0 nl0 -> f (Graph e n el1 nl1)
- checkedZipWith :: (Edge edge, Ord node) => Caller -> (nodeLabel0 -> nodeLabel1 -> nodeLabel2) -> (edgeLabel0 -> edgeLabel1 -> edgeLabel2) -> Graph edge node edgeLabel0 nodeLabel0 -> Graph edge node edgeLabel1 nodeLabel1 -> Graph edge node edgeLabel2 nodeLabel2
- union :: (Edge edge, Ord node) => Graph edge node edgeLabel nodeLabel -> Graph edge node edgeLabel nodeLabel -> Graph edge node edgeLabel nodeLabel
- class Edge edge => Reverse edge
- reverse :: (Reverse e, Ord n) => Graph e n el nl -> Graph e n el nl
- reverseEdge :: Reverse edge => edge node -> edge node
- mapKeys :: (Edge edge1, Ord node0, Ord node1) => (node0 -> node1) -> (edge0 node0 -> edge1 node1) -> Graph edge0 node0 edgeLabel nodeLabel -> Graph edge1 node1 edgeLabel nodeLabel
- mapMaybeEdgeKeys :: (Edge e1, Ord n) => (e0 n -> Maybe (e1 n)) -> Graph e0 n el nl -> Graph e1 n el nl
- mapEdgeKeys :: (Edge e1, Ord n) => (e0 n -> e1 n) -> Graph e0 n el nl -> Graph e1 n el nl
- deleteNode :: (Edge e, Ord n) => n -> Graph e n el nl -> Graph e n el nl
- deleteNodeSet :: (Edge e, Ord n) => Set n -> Graph e n el nl -> Graph e n el nl
- deleteEdge :: (Edge e, Ord n) => e n -> Graph e n el nl -> Graph e n el nl
- insertNode :: Ord n => n -> nl -> Graph e n el nl -> Graph e n el nl
- insertEdge :: (Edge e, Ord n) => e n -> el -> Graph e n el nl -> Graph e n el nl
- insertEdgeSet :: (Edge e, Ord n) => Map (e n) el -> Graph e n el nl -> Graph e n el nl
Types
data Graph edge node edgeLabel nodeLabel Source #
Instances
(Eq1 edge, Eq node, Eq edgeLabel, Eq nodeLabel) => Eq (Graph edge node edgeLabel nodeLabel) Source # | |
(Ord1 edge, Ord node, Ord edgeLabel, Ord nodeLabel) => Ord (Graph edge node edgeLabel nodeLabel) Source # | |
Defined in Data.Graph.Comfort compare :: Graph edge node edgeLabel nodeLabel -> Graph edge node edgeLabel nodeLabel -> Ordering # (<) :: Graph edge node edgeLabel nodeLabel -> Graph edge node edgeLabel nodeLabel -> Bool # (<=) :: Graph edge node edgeLabel nodeLabel -> Graph edge node edgeLabel nodeLabel -> Bool # (>) :: Graph edge node edgeLabel nodeLabel -> Graph edge node edgeLabel nodeLabel -> Bool # (>=) :: Graph edge node edgeLabel nodeLabel -> Graph edge node edgeLabel nodeLabel -> Bool # max :: Graph edge node edgeLabel nodeLabel -> Graph edge node edgeLabel nodeLabel -> Graph edge node edgeLabel nodeLabel # min :: Graph edge node edgeLabel nodeLabel -> Graph edge node edgeLabel nodeLabel -> Graph edge node edgeLabel nodeLabel # | |
(Edge e, Ord n, Show1 e, Show n, Show el, Show nl) => Show (Graph e n el nl) Source # | |
(Edge edge, Ord node) => Semigroup (Graph edge node edgeLabel nodeLabel) Source # | |
Defined in Data.Graph.Comfort (<>) :: Graph edge node edgeLabel nodeLabel -> Graph edge node edgeLabel nodeLabel -> Graph edge node edgeLabel nodeLabel # sconcat :: NonEmpty (Graph edge node edgeLabel nodeLabel) -> Graph edge node edgeLabel nodeLabel # stimes :: Integral b => b -> Graph edge node edgeLabel nodeLabel -> Graph edge node edgeLabel nodeLabel # | |
(Edge edge, Ord node) => Monoid (Graph edge node edgeLabel nodeLabel) Source # | |
type LabeledNode n label = (n, label) Source #
type LabeledEdge edge node label = (edge node, label) Source #
class (Foldable edge, Ord1 edge) => Edge edge where Source #
defaultEdgeFoldMap :: (Edge edge, Monoid a) => edge a -> a Source #
DirEdge node node |
Instances
UndirEdge node node |
Instances
data EitherEdge node Source #
EDirEdge (DirEdge node) | |
EUndirEdge (UndirEdge node) |
Instances
Construction
empty :: Graph edge node edgeLabel nodeLabel Source #
Graph.isEmpty (Graph.empty :: MonoGraph)
Graph.isConsistent (Graph.empty :: MonoGraph)
fromList :: (Edge e, Ord n) => [LabeledNode n nl] -> [LabeledEdge e n el] -> Graph e n el nl Source #
fromMap :: (Edge e, Ord n) => Map n nl -> Map (e n) el -> Graph e n el nl Source #
\(TestGraph gr) -> gr == Graph.fromMap (Graph.nodeLabels gr) (Graph.edgeLabels gr)
Extract large portions of the graph
graphMap :: Graph edge node edgeLabel nodeLabel -> Map node (InOutMap edge node edgeLabel nodeLabel) Source #
nodeEdges :: (Edge edge, Ord node) => Graph edge node edgeLabel nodeLabel -> Map node (Set (edge node), nodeLabel, Set (edge node)) Source #
edgeLabels :: (Edge edge, Ord node) => Graph edge node edgeLabel nodeLabel -> Map (edge node) edgeLabel Source #
Queries
lookupNode :: Ord n => n -> Graph e n el nl -> Maybe nl Source #
\(TestGraph gr) n -> Graph.lookupNode n gr == Map.lookup n (Graph.nodeLabels gr)
lookupEdge :: (Edge e, Ord n) => e n -> Graph e n el nl -> Maybe el Source #
\(GraphAndEdge gr e) -> Graph.lookupEdge e gr == Map.lookup e (Graph.edgeLabels gr)
predecessors :: (Edge e, Ord n) => Graph e n el nl -> n -> [n] Source #
Direct predecessors of a node, i.e. nodes with an outgoing edge to the queried node.
successors :: (Edge e, Ord n) => Graph e n el nl -> n -> [n] Source #
Direct successors of a node, i.e. nodes with an incoming edge from the queried node.
adjacentEdges :: (Edge e, Ord n) => Graph e n el nl -> n -> Set (e n) Source #
Deprecated: Use adjacentEdgeSet instead.
pathExists :: (Edge edge, Ord node) => node -> node -> Graph edge node edgeLabel nodeLabel -> Bool Source #
Manipulate labels
mapNode :: (nl0 -> nl1) -> Graph e n el nl0 -> Graph e n el nl1 Source #
\(TestGraph gr) -> Graph.mapNode id gr == gr
mapNodeWithKey :: (n -> nl0 -> nl1) -> Graph e n el nl0 -> Graph e n el nl1 Source #
mapEdge :: (el0 -> el1) -> Graph e n el0 nl -> Graph e n el1 nl Source #
\(TestGraph gr) -> Graph.mapEdge id gr == gr
mapEdgeWithKey :: (e n -> el0 -> el1) -> Graph e n el0 nl -> Graph e n el1 nl Source #
mapNodeWithInOut :: (Edge e, Ord n) => (InOut e n el nl0 -> nl1) -> Graph e n el nl0 -> Graph e n el nl1 Source #
type InOut e n el nl = ([LabeledEdge e n el], LabeledNode n nl, [LabeledEdge e n el]) Source #
filterEdgeWithKey :: (Edge e, Ord n) => (e n -> el -> Bool) -> Graph e n el nl -> Graph e n el nl Source #
\(GraphAndEdge gr e) -> Graph.filterEdgeWithKey (\ei _ -> e/=ei) gr == Graph.deleteEdge e gr
traverseNode :: (Applicative f, Edge e, Ord n) => (nl0 -> f nl1) -> Graph e n el nl0 -> f (Graph e n el nl1) Source #
Same restrictions as in traverse
.
\(TestGraph gr) nl -> Graph.isConsistent $ evalTraverseNode nl gr
\(TestGraph gr) -> runIdentity (Graph.traverseNode (Identity . Char.toUpper) gr) == Graph.mapNode Char.toUpper gr
traverseEdge :: (Applicative f, Edge e, Ord n) => (el0 -> f el1) -> Graph e n el0 nl -> f (Graph e n el1 nl) Source #
Same restrictions as in traverse
.
\(TestGraph gr) el -> Graph.isConsistent $ evalTraverseEdge el gr
\(TestGraph gr) el -> runIdentity (Graph.traverseEdge (Identity . (el+)) gr) == Graph.mapEdge (el+) gr
traverse :: (Applicative f, Edge e, Ord n) => (nl0 -> f nl1) -> (el0 -> f el1) -> Graph e n el0 nl0 -> f (Graph e n el1 nl1) Source #
Don't rely on a particular order of traversal!
\(TestGraph gr) nl el -> Graph.isConsistent $ evalTraverse nl el gr
\(TestGraph gr) nl el -> evalTraverse nl el gr == evalTraverseNode nl (evalTraverseEdge el gr)
\(TestGraph gr) nl el -> evalTraverse nl el gr == evalTraverseEdge el (evalTraverseNode nl gr)
\(TestGraph gr) nl -> flip MS.evalState nl (Graph.traverseNode nodeAction gr) == flip MS.evalState nl (Graph.traverse nodeAction pure gr)
\(TestGraph gr) el -> flip MS.evalState el (Graph.traverseEdge edgeAction gr) == flip MS.evalState el (Graph.traverse pure edgeAction gr)
Combine graphs
checkedZipWith :: (Edge edge, Ord node) => Caller -> (nodeLabel0 -> nodeLabel1 -> nodeLabel2) -> (edgeLabel0 -> edgeLabel1 -> edgeLabel2) -> Graph edge node edgeLabel0 nodeLabel0 -> Graph edge node edgeLabel1 nodeLabel1 -> Graph edge node edgeLabel2 nodeLabel2 Source #
Node and edge sets must be equal.
union :: (Edge edge, Ord node) => Graph edge node edgeLabel nodeLabel -> Graph edge node edgeLabel nodeLabel -> Graph edge node edgeLabel nodeLabel Source #
The node sets must be disjoint.
Manipulate indices
class Edge edge => Reverse edge Source #
Instances
Reverse DirEdge Source # | |
Defined in Data.Graph.Comfort reverseEdge :: DirEdge node -> DirEdge node Source # |
reverse :: (Reverse e, Ord n) => Graph e n el nl -> Graph e n el nl Source #
\(TestGraph gr) -> Graph.isConsistent (Graph.reverse gr)
\(TestGraph gr) -> Graph.reverse (Graph.reverse gr) == gr
reverseEdge :: Reverse edge => edge node -> edge node Source #
mapKeys :: (Edge edge1, Ord node0, Ord node1) => (node0 -> node1) -> (edge0 node0 -> edge1 node1) -> Graph edge0 node0 edgeLabel nodeLabel -> Graph edge1 node1 edgeLabel nodeLabel Source #
The index map must be an injection, that is, nodes must not collaps. Also the node and edge index maps must be consistent, i.e.
from (edgeMap e) == nodeMap (from e) to (edgeMap e) == nodeMap (to e)
Strictly spoken, we would need the node map only for isolated nodes, but we use it for all nodes for simplicity.
mapMaybeEdgeKeys :: (Edge e1, Ord n) => (e0 n -> Maybe (e1 n)) -> Graph e0 n el nl -> Graph e1 n el nl Source #
You may only use this for filtering edges and use more specialised types as a result. You must not alter source and target nodes of edges.
mapEdgeKeys :: (Edge e1, Ord n) => (e0 n -> e1 n) -> Graph e0 n el nl -> Graph e1 n el nl Source #
Same restrictions as in mapMaybeEdgeKeys
.
Insertion and removal
deleteNode :: (Edge e, Ord n) => n -> Graph e n el nl -> Graph e n el nl Source #
Node to be deleted must be contained in the graph.
\(TestGraph gr) n -> Graph.isConsistent $ deleteNodeIfExists n gr
\(TestGraph gr) n nl -> Graph.deleteNode n (Graph.insertNode n nl gr) == deleteNodeIfExists n gr
\(TestGraph gr) -> let isolatedNodes = filter (isolated gr) $ Graph.nodes gr in not (null isolatedNodes) ==> QC.forAll (QC.elements isolatedNodes) $ \n nl -> Graph.insertNode n nl gr == Graph.insertNode n nl (Graph.deleteNode n gr)
deleteNodeSet :: (Edge e, Ord n) => Set n -> Graph e n el nl -> Graph e n el nl Source #
Could be implemented more efficiently.
deleteEdge :: (Edge e, Ord n) => e n -> Graph e n el nl -> Graph e n el nl Source #
\(GraphAndEdge gr e) -> Graph.isConsistent $ Graph.deleteEdge e gr
\(GraphAndEdge gr e) el -> Graph.deleteEdge e (Graph.insertEdge e el gr) == Graph.deleteEdge e gr
\(GraphAndEdge gr e) el -> Graph.insertEdge e el gr == Graph.insertEdge e el (Graph.deleteEdge e gr)
insertNode :: Ord n => n -> nl -> Graph e n el nl -> Graph e n el nl Source #
In the current implementation existing nodes are replaced with new labels and existing edges are maintained. However, I think we should better have an extra function for this purpose and you should not rely on this behavior.
\(TestGraph gr) n nl -> Graph.isConsistent $ Graph.insertNode n nl gr
\(TestGraph gr) n nl -> Graph.lookupNode n (Graph.insertNode n nl gr) == Just nl
insertEdge :: (Edge e, Ord n) => e n -> el -> Graph e n el nl -> Graph e n el nl Source #
\(GraphAndEdge gr e) el -> Graph.isConsistent $ Graph.insertEdge e el gr
\(GraphAndEdge gr e) el -> Graph.lookupEdge e (Graph.insertEdge e el gr) == Just el
insertEdgeSet :: (Edge e, Ord n) => Map (e n) el -> Graph e n el nl -> Graph e n el nl Source #
In the current implementation existing edges are replaced with new labels. However, I think we should better have an extra function for this purpose and you should not rely on this behavior. It is an unchecked error if edges between non-existing nodes are inserted.