{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE StrictData      #-}
module Language.Cimple.Graph
  ( Graph
  , fromEdges
  , edges
  ) where

import qualified Data.Graph as G

data Graph node key = Graph
    { forall node key. Graph node key -> Graph
graph          :: G.Graph
    , forall node key. Graph node key -> Vertex -> (node, key, [key])
nodeFromVertex :: G.Vertex -> (node, key, [key])
    , forall node key. Graph node key -> key -> Maybe Vertex
vertexFromKey  :: key -> Maybe G.Vertex
    }

fromEdges :: Ord key => [(node, key, [key])] -> Graph node key
fromEdges :: forall key node. Ord key => [(node, key, [key])] -> Graph node key
fromEdges [(node, key, [key])]
es = Graph{Graph
key -> Maybe Vertex
Vertex -> (node, key, [key])
vertexFromKey :: key -> Maybe Vertex
nodeFromVertex :: Vertex -> (node, key, [key])
graph :: Graph
vertexFromKey :: key -> Maybe Vertex
nodeFromVertex :: Vertex -> (node, key, [key])
graph :: Graph
..}
  where
    (Graph
graph, Vertex -> (node, key, [key])
nodeFromVertex, key -> Maybe Vertex
vertexFromKey) = [(node, key, [key])]
-> (Graph, Vertex -> (node, key, [key]), key -> Maybe Vertex)
forall key node.
Ord key =>
[(node, key, [key])]
-> (Graph, Vertex -> (node, key, [key]), key -> Maybe Vertex)
G.graphFromEdges [(node, key, [key])]
es

edges :: Graph node key -> [(key, key)]
edges :: forall node key. Graph node key -> [(key, key)]
edges Graph{Graph
key -> Maybe Vertex
Vertex -> (node, key, [key])
vertexFromKey :: key -> Maybe Vertex
nodeFromVertex :: Vertex -> (node, key, [key])
graph :: Graph
vertexFromKey :: forall node key. Graph node key -> key -> Maybe Vertex
nodeFromVertex :: forall node key. Graph node key -> Vertex -> (node, key, [key])
graph :: forall node key. Graph node key -> Graph
..} = ((Vertex, Vertex) -> (key, key))
-> [(Vertex, Vertex)] -> [(key, key)]
forall a b. (a -> b) -> [a] -> [b]
map (Vertex, Vertex) -> (key, key)
resolve ([(Vertex, Vertex)] -> [(key, key)])
-> (Graph -> [(Vertex, Vertex)]) -> Graph -> [(key, key)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Graph -> [(Vertex, Vertex)]
G.edges (Graph -> [(key, key)]) -> Graph -> [(key, key)]
forall a b. (a -> b) -> a -> b
$ Graph
graph
  where
    resolve :: (Vertex, Vertex) -> (key, key)
resolve (Vertex
from, Vertex
to) =
      let
          (node
_, key
from', [key]
_) = Vertex -> (node, key, [key])
nodeFromVertex Vertex
from
          (node
_, key
to', [key]
_) = Vertex -> (node, key, [key])
nodeFromVertex Vertex
to
      in
      (key
from', key
to')