{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeFamilies #-}
module Data.Graph.Haggle.Classes (
Vertex,
Edge,
edgeSource,
edgeDest,
MGraph(..),
MAddEdge(..),
MAddVertex(..),
MRemovable(..),
MBidirectional(..),
MLabeledEdge(..),
MLabeledVertex(..),
Graph(..),
edgeExists,
Thawable(..),
Bidirectional(..),
HasEdgeLabel(..),
HasVertexLabel(..),
BidirectionalEdgeLabel(..),
InductiveGraph(..),
Context(..)
) where
import Control.Monad ( forM, liftM )
import qualified Control.Monad.Primitive as P
import qualified Control.Monad.Ref as R
import Data.Maybe ( fromMaybe )
import Data.Graph.Haggle.Internal.Basic
class MGraph g where
type ImmutableGraph g
getVertices :: (P.PrimMonad m, R.MonadRef m) => g m -> m [Vertex]
getSuccessors :: (P.PrimMonad m, R.MonadRef m) => g m -> Vertex -> m [Vertex]
getOutEdges :: (P.PrimMonad m, R.MonadRef m) => g m -> Vertex -> m [Edge]
countVertices :: (P.PrimMonad m, R.MonadRef m) => g m -> m Int
countEdges :: (P.PrimMonad m, R.MonadRef m) => g m -> m Int
checkEdgeExists :: (P.PrimMonad m, R.MonadRef m) => g m -> Vertex -> Vertex -> m Bool
checkEdgeExists g src dst = do
succs <- getSuccessors g src
return $ any (==dst) succs
freeze :: (P.PrimMonad m, R.MonadRef m) => g m -> m (ImmutableGraph g)
class (MGraph g) => MAddVertex g where
addVertex :: (P.PrimMonad m, R.MonadRef m) => g m -> m Vertex
class (MGraph g) => MAddEdge g where
addEdge :: (P.PrimMonad m, R.MonadRef m) => g m -> Vertex -> Vertex -> m (Maybe Edge)
class (MGraph g) => MLabeledEdge g where
type MEdgeLabel g
getEdgeLabel :: (P.PrimMonad m, R.MonadRef m) => g m -> Edge -> m (Maybe (MEdgeLabel g))
getEdgeLabel g e = do
nEs <- countEdges g
case edgeId e >= nEs of
True -> return Nothing
False -> liftM Just (unsafeGetEdgeLabel g e)
unsafeGetEdgeLabel :: (P.PrimMonad m, R.MonadRef m) => g m -> Edge -> m (MEdgeLabel g)
addLabeledEdge :: (P.PrimMonad m, R.MonadRef m) => g m -> Vertex -> Vertex -> MEdgeLabel g -> m (Maybe Edge)
class (MGraph g) => MLabeledVertex g where
type MVertexLabel g
getVertexLabel :: (P.PrimMonad m, R.MonadRef m) => g m -> Vertex -> m (Maybe (MVertexLabel g))
addLabeledVertex :: (P.PrimMonad m, R.MonadRef m) => g m -> MVertexLabel g -> m Vertex
getLabeledVertices :: (P.PrimMonad m, R.MonadRef m) => g m -> m [(Vertex, MVertexLabel g)]
getLabeledVertices g = do
vs <- getVertices g
forM vs $ \v -> do
ml <- getVertexLabel g v
case ml of
Just l -> return (v, l)
Nothing -> error ("impossible (missing label for vertex" ++ show v ++ ")")
class (MGraph g) => MRemovable g where
removeVertex :: (P.PrimMonad m, R.MonadRef m) => g m -> Vertex -> m ()
removeEdgesBetween :: (P.PrimMonad m, R.MonadRef m) => g m -> Vertex -> Vertex -> m ()
removeEdge :: (P.PrimMonad m, R.MonadRef m) => g m -> Edge -> m ()
class (MGraph g) => MBidirectional g where
getPredecessors :: (P.PrimMonad m, R.MonadRef m) => g m -> Vertex -> m [Vertex]
getInEdges :: (P.PrimMonad m, R.MonadRef m) => g m -> Vertex -> m [Edge]
class Graph g where
vertices :: g -> [Vertex]
edges :: g -> [Edge]
successors :: g -> Vertex -> [Vertex]
outEdges :: g -> Vertex -> [Edge]
maxVertexId :: g -> Int
isEmpty :: g -> Bool
edgesBetween :: g -> Vertex -> Vertex -> [Edge]
edgesBetween g src dst = filter ((dst ==) . edgeDest) (outEdges g src)
edgeExists :: Graph g => g -> Vertex -> Vertex -> Bool
edgeExists g v1 v2 = not . null $ edgesBetween g v1 v2
class (Graph g) => Thawable g where
type MutableGraph g :: (* -> *) -> *
thaw :: (P.PrimMonad m, R.MonadRef m) => g -> m (MutableGraph g m)
class (Graph g) => Bidirectional g where
predecessors :: g -> Vertex -> [Vertex]
inEdges :: g -> Vertex -> [Edge]
class (Graph g) => HasEdgeLabel g where
type EdgeLabel g
edgeLabel :: g -> Edge -> Maybe (EdgeLabel g)
labeledEdges :: g -> [(Edge, EdgeLabel g)]
labeledOutEdges :: g -> Vertex -> [(Edge, EdgeLabel g)]
labeledOutEdges g v = map (addEdgeLabel g) (outEdges g v)
class (HasEdgeLabel g, Bidirectional g) => BidirectionalEdgeLabel g where
labeledInEdges :: g -> Vertex -> [(Edge, EdgeLabel g)]
labeledInEdges g v = map (addEdgeLabel g) (inEdges g v)
class (Graph g) => HasVertexLabel g where
type VertexLabel g
vertexLabel :: g -> Vertex -> Maybe (VertexLabel g)
labeledVertices :: g -> [(Vertex, VertexLabel g)]
data Context g = Context [(EdgeLabel g, Vertex)] (VertexLabel g) [(EdgeLabel g, Vertex)]
class (Graph g, HasEdgeLabel g, HasVertexLabel g) => InductiveGraph g where
emptyGraph :: g
match :: g -> Vertex -> Maybe (Context g, g)
context :: g -> Vertex -> Maybe (Context g)
insertLabeledVertex :: g -> VertexLabel g -> (Vertex, g)
insertLabeledEdge :: g -> Vertex -> Vertex -> EdgeLabel g -> Maybe (Edge, g)
deleteEdge :: g -> Edge -> g
deleteEdgesBetween :: g -> Vertex -> Vertex -> g
replaceLabeledEdge :: g -> Vertex -> Vertex -> EdgeLabel g -> Maybe (Edge, g)
replaceLabeledEdge g src dst lbl =
let g' = deleteEdgesBetween g src dst
in insertLabeledEdge g' src dst lbl
deleteVertex :: g -> Vertex -> g
deleteVertex g v = fromMaybe g $ do
(_, g') <- match g v
return g'
addEdgeLabel :: (HasEdgeLabel g) => g -> Edge -> (Edge, EdgeLabel g)
addEdgeLabel g e = (e, el)
where
Just el = edgeLabel g e