{-# LANGUAGE UnicodeSyntax #-}
-- | Most of the functions for graph scrutinisation ('GraphRewriting.Graph.Read') and modification ('GraphRewriting.Graph.Write') are defined monadically. This module defines functions for extracting these monadic values and a few non-monadic graph scrutinisation/modification functions.
module GraphRewriting.Graph (module GraphRewriting.Graph, module GraphRewriting.Graph.Types, Graph (..)) where

import GraphRewriting.Graph.Types
import GraphRewriting.Graph.Internal
import Control.Monad.State
import qualified Data.IntMap as Map
import qualified Data.IntSet as Set
import Data.Maybe (fromJust)


emptyGraph  Graph n
emptyGraph :: forall n. Graph n
emptyGraph = Graph {nodeMap :: IntMap n
nodeMap = forall a. IntMap a
Map.empty, edgeMap :: IntMap IntSet
edgeMap = forall a. IntMap a
Map.empty, nextKey :: Int
nextKey = Int
0}

nodes  Graph n  [n]
nodes :: forall n. Graph n -> [n]
nodes = forall a. IntMap a -> [a]
Map.elems forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. Graph n -> IntMap n
nodeMap

-- | Each edge corresponds to the set of nodes it connects
edges  Graph n  [(Edge, [n])]
edges :: forall n. Graph n -> [(Edge, [n])]
edges Graph n
g = forall a b. (a -> b) -> [a] -> [b]
map (Int, IntSet) -> (Edge, [n])
lookupNodes forall a b. (a -> b) -> a -> b
$ forall a. IntMap a -> [(Int, a)]
Map.assocs (forall n. Graph n -> IntMap IntSet
edgeMap Graph n
g) where
	lookupNodes :: (Int, IntSet) -> (Edge, [n])
lookupNodes (Int
e,IntSet
ns) = (Int -> Edge
Edge Int
e, forall a b. (a -> b) -> [a] -> [b]
map (\Int
n  forall a. HasCallStack => Maybe a -> a
fromJust forall a b. (a -> b) -> a -> b
$ forall a. Int -> IntMap a -> Maybe a
Map.lookup Int
n forall a b. (a -> b) -> a -> b
$ forall n. Graph n -> IntMap n
nodeMap Graph n
g) forall a b. (a -> b) -> a -> b
$ IntSet -> [Int]
Set.elems IntSet
ns)

-- | unsafe, since no checks are performed to ensure that the invariants from
-- "GraphRewriting.Graph.Write" are preserved
unsafeMapNodes  (n  n')  Graph n  Graph n'
unsafeMapNodes :: forall n n'. (n -> n') -> Graph n -> Graph n'
unsafeMapNodes n -> n'
f Graph n
g = Graph n
g {nodeMap :: IntMap n'
nodeMap = forall a b. (a -> b) -> IntMap a -> IntMap b
Map.map n -> n'
f forall a b. (a -> b) -> a -> b
$ forall n. Graph n -> IntMap n
nodeMap Graph n
g}

-- | map that supplies an additional unique key to the mapping function; unsafe
-- in the same way as 'unsafeMapNodes'
unsafeMapNodesUnique  (Int  n  n')  Graph n  Graph n'
unsafeMapNodesUnique :: forall n n'. (Int -> n -> n') -> Graph n -> Graph n'
unsafeMapNodesUnique Int -> n -> n'
f Graph n
g = Graph n
g {nodeMap :: IntMap n'
nodeMap = forall a b. (Int -> a -> b) -> IntMap a -> IntMap b
Map.mapWithKey Int -> n -> n'
f forall a b. (a -> b) -> a -> b
$ forall n. Graph n -> IntMap n
nodeMap Graph n
g}

-- | apply a monadic graph modification to a graph
runGraph  Rewrite n a  Graph n  (a, Graph n)
runGraph :: forall n a. Rewrite n a -> Graph n -> (a, Graph n)
runGraph = forall s a. State s a -> s -> (a, s)
runState forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n a. Rewrite n a -> State (Graph n) a
rewrite

evalGraph  Rewrite n a  Graph n  a
evalGraph :: forall n a. Rewrite n a -> Graph n -> a
evalGraph = forall s a. State s a -> s -> a
evalState forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n a. Rewrite n a -> State (Graph n) a
rewrite

execGraph  Rewrite n a  Graph n  Graph n
execGraph :: forall n a. Rewrite n a -> Graph n -> Graph n
execGraph = forall s a. State s a -> s -> s
execState forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n a. Rewrite n a -> State (Graph n) a
rewrite