packages feed

hgraph-1.2.0.0: src/HGraph/Directed/AdjacencyMap.hs

module HGraph.Directed.AdjacencyMap
       ( Digraph
       , emptyDigraph
       , module HGraph.Directed
       )
where

import HGraph.Directed
import qualified Data.Map as M
import qualified Data.Set as S

type DirectedNeighborhood a = (S.Set a, S.Set a)
data Digraph a where
  Digraph :: Ord a => M.Map a (DirectedNeighborhood a) -> Digraph a

emptyDigraph :: Ord a => Digraph a
emptyDigraph = Digraph M.empty

instance DirectedGraph Digraph where
  empty (Digraph d) = Digraph M.empty
  numVertices (Digraph d) = fromIntegral $ M.size d
  vertices (Digraph d) = M.keys d
  arcs (Digraph d) = concatMap (\(v, (_,o)) -> [(v,u) | u <- S.toList o]) $ M.assocs d
  isVertex (Digraph d) v = v `M.member` d
  linearizeVertices g@(Digraph adj) = (g', assocs)
    where
      assocs = zip [0..] (M.keys adj)
      ltoi = M.fromList $ zip (M.keys adj) [0..]
      g' = foldr addArc (foldr addVertex emptyDigraph (map fst assocs)) $
            [ (ltoi M.! u, ltoi M.! v) | (u,v) <- arcs g ]

instance Adjacency Digraph where
  outneighbors (Digraph d) v = S.toList $ snd $ d M.! v
  inneighbors  (Digraph d) v = S.toList $ fst $ d M.! v
  arcExists (Digraph d) (v,u) = u `S.member` (snd $ d M.! v)

instance Mutable Digraph where
  addVertex v (Digraph d) =
    Digraph (M.insertWith (\_ o -> o) v (S.empty, S.empty) d)
  removeVertex v g@(Digraph d) = 
      let Digraph d' = foldr removeArc g
                     (  (map (\u -> (v,u)) $ outneighbors g v)
                     ++ (map (\u -> (u,v)) $ inneighbors  g v))
      in Digraph $ M.delete v d'
            
  addArc (v,u) (Digraph d) =
    Digraph ( M.adjust (\(i,o) -> (i, S.insert u o)) v
            $ M.adjust (\(i,o) -> (S.insert v i, o)) u d)
  removeArc (v,u) (Digraph d)  =
    Digraph ( M.adjust (\(i,o) -> (i, S.delete u o)) v
            $ M.adjust (\(i,o) -> (S.delete v i, o)) u d)