{-# LANGUAGE CPP #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeFamilies #-}
module Data.Graph.Haggle.Classes (
Vertex, vertexId,
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
#if MIN_VERSION_base(4, 9, 0)
import Data.Kind ( Type )
#endif
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 m
g Vertex
src Vertex
dst = do
[Vertex]
succs <- g m -> Vertex -> m [Vertex]
forall (g :: (* -> *) -> *) (m :: * -> *).
(MGraph g, PrimMonad m, MonadRef m) =>
g m -> Vertex -> m [Vertex]
getSuccessors g m
g Vertex
src
Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> m Bool) -> Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ (Vertex -> Bool) -> [Vertex] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Vertex -> Vertex -> Bool
forall a. Eq a => a -> a -> Bool
==Vertex
dst) [Vertex]
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 m
g Edge
e = do
Int
nEs <- g m -> m Int
forall (g :: (* -> *) -> *) (m :: * -> *).
(MGraph g, PrimMonad m, MonadRef m) =>
g m -> m Int
countEdges g m
g
case Edge -> Int
edgeId Edge
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
nEs of
Bool
True -> Maybe (MEdgeLabel g) -> m (Maybe (MEdgeLabel g))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (MEdgeLabel g)
forall a. Maybe a
Nothing
Bool
False -> (MEdgeLabel g -> Maybe (MEdgeLabel g))
-> m (MEdgeLabel g) -> m (Maybe (MEdgeLabel g))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM MEdgeLabel g -> Maybe (MEdgeLabel g)
forall a. a -> Maybe a
Just (g m -> Edge -> m (MEdgeLabel g)
forall (g :: (* -> *) -> *) (m :: * -> *).
(MLabeledEdge g, PrimMonad m, MonadRef m) =>
g m -> Edge -> m (MEdgeLabel g)
unsafeGetEdgeLabel g m
g Edge
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 m
g = do
[Vertex]
vs <- g m -> m [Vertex]
forall (g :: (* -> *) -> *) (m :: * -> *).
(MGraph g, PrimMonad m, MonadRef m) =>
g m -> m [Vertex]
getVertices g m
g
[Vertex]
-> (Vertex -> m (Vertex, MVertexLabel g))
-> m [(Vertex, MVertexLabel g)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Vertex]
vs ((Vertex -> m (Vertex, MVertexLabel g))
-> m [(Vertex, MVertexLabel g)])
-> (Vertex -> m (Vertex, MVertexLabel g))
-> m [(Vertex, MVertexLabel g)]
forall a b. (a -> b) -> a -> b
$ \Vertex
v -> do
Maybe (MVertexLabel g)
ml <- g m -> Vertex -> m (Maybe (MVertexLabel g))
forall (g :: (* -> *) -> *) (m :: * -> *).
(MLabeledVertex g, PrimMonad m, MonadRef m) =>
g m -> Vertex -> m (Maybe (MVertexLabel g))
getVertexLabel g m
g Vertex
v
case Maybe (MVertexLabel g)
ml of
Just MVertexLabel g
l -> (Vertex, MVertexLabel g) -> m (Vertex, MVertexLabel g)
forall (m :: * -> *) a. Monad m => a -> m a
return (Vertex
v, MVertexLabel g
l)
Maybe (MVertexLabel g)
Nothing -> [Char] -> m (Vertex, MVertexLabel g)
forall a. HasCallStack => [Char] -> a
error ([Char]
"impossible (missing label for vertex" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Vertex -> [Char]
forall a. Show a => a -> [Char]
show Vertex
v [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
")")
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
g Vertex
src Vertex
dst = (Edge -> Bool) -> [Edge] -> [Edge]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Vertex
dst Vertex -> Vertex -> Bool
forall a. Eq a => a -> a -> Bool
==) (Vertex -> Bool) -> (Edge -> Vertex) -> Edge -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Edge -> Vertex
edgeDest) (g -> Vertex -> [Edge]
forall g. Graph g => g -> Vertex -> [Edge]
outEdges g
g Vertex
src)
edgeExists :: Graph g => g -> Vertex -> Vertex -> Bool
edgeExists :: g -> Vertex -> Vertex -> Bool
edgeExists g
g Vertex
v1 Vertex
v2 = Bool -> Bool
not (Bool -> Bool) -> ([Edge] -> Bool) -> [Edge] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Edge] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Edge] -> Bool) -> [Edge] -> Bool
forall a b. (a -> b) -> a -> b
$ g -> Vertex -> Vertex -> [Edge]
forall g. Graph g => g -> Vertex -> Vertex -> [Edge]
edgesBetween g
g Vertex
v1 Vertex
v2
class (Graph g) => Thawable g where
#if MIN_VERSION_base(4, 9, 0)
type MutableGraph g :: (Type -> Type) -> Type
#else
type MutableGraph g :: (* -> *) -> *
#endif
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
g Vertex
v = (Edge -> (Edge, EdgeLabel g)) -> [Edge] -> [(Edge, EdgeLabel g)]
forall a b. (a -> b) -> [a] -> [b]
map (g -> Edge -> (Edge, EdgeLabel g)
forall g. HasEdgeLabel g => g -> Edge -> (Edge, EdgeLabel g)
addEdgeLabel g
g) (g -> Vertex -> [Edge]
forall g. Graph g => g -> Vertex -> [Edge]
outEdges g
g Vertex
v)
class (HasEdgeLabel g, Bidirectional g) => BidirectionalEdgeLabel g where
labeledInEdges :: g -> Vertex -> [(Edge, EdgeLabel g)]
labeledInEdges g
g Vertex
v = (Edge -> (Edge, EdgeLabel g)) -> [Edge] -> [(Edge, EdgeLabel g)]
forall a b. (a -> b) -> [a] -> [b]
map (g -> Edge -> (Edge, EdgeLabel g)
forall g. HasEdgeLabel g => g -> Edge -> (Edge, EdgeLabel g)
addEdgeLabel g
g) (g -> Vertex -> [Edge]
forall g. Bidirectional g => g -> Vertex -> [Edge]
inEdges g
g Vertex
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
g Vertex
src Vertex
dst EdgeLabel g
lbl =
let g' :: g
g' = g -> Vertex -> Vertex -> g
forall g. InductiveGraph g => g -> Vertex -> Vertex -> g
deleteEdgesBetween g
g Vertex
src Vertex
dst
in g -> Vertex -> Vertex -> EdgeLabel g -> Maybe (Edge, g)
forall g.
InductiveGraph g =>
g -> Vertex -> Vertex -> EdgeLabel g -> Maybe (Edge, g)
insertLabeledEdge g
g' Vertex
src Vertex
dst EdgeLabel g
lbl
deleteVertex :: g -> Vertex -> g
deleteVertex g
g Vertex
v = g -> Maybe g -> g
forall a. a -> Maybe a -> a
fromMaybe g
g (Maybe g -> g) -> Maybe g -> g
forall a b. (a -> b) -> a -> b
$ do
(Context g
_, g
g') <- g -> Vertex -> Maybe (Context g, g)
forall g. InductiveGraph g => g -> Vertex -> Maybe (Context g, g)
match g
g Vertex
v
g -> Maybe g
forall (m :: * -> *) a. Monad m => a -> m a
return g
g'
addEdgeLabel :: (HasEdgeLabel g) => g -> Edge -> (Edge, EdgeLabel g)
addEdgeLabel :: g -> Edge -> (Edge, EdgeLabel g)
addEdgeLabel g
g Edge
e = (Edge
e, EdgeLabel g
el)
where
Just EdgeLabel g
el = g -> Edge -> Maybe (EdgeLabel g)
forall g. HasEdgeLabel g => g -> Edge -> Maybe (EdgeLabel g)
edgeLabel g
g Edge
e