module Data.Graph.Typed (
GraphKL(..), fromAdjacencyMap, fromAdjacencyIntMap,
dfsForest, dfsForestFrom, dfs, topSort, scc
) where
import Data.Tree
import Data.Maybe
import Data.Foldable
import qualified Data.Graph as KL
import qualified Algebra.Graph.AdjacencyMap as AM
import qualified Algebra.Graph.NonEmpty.AdjacencyMap as NonEmpty
import qualified Algebra.Graph.AdjacencyIntMap as AIM
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
data GraphKL a = GraphKL {
GraphKL a -> Graph
toGraphKL :: KL.Graph,
GraphKL a -> Vertex -> a
fromVertexKL :: KL.Vertex -> a,
GraphKL a -> a -> Maybe Vertex
toVertexKL :: a -> Maybe KL.Vertex }
fromAdjacencyMap :: Ord a => AM.AdjacencyMap a -> GraphKL a
fromAdjacencyMap :: AdjacencyMap a -> GraphKL a
fromAdjacencyMap AdjacencyMap a
am = GraphKL :: forall a.
Graph -> (Vertex -> a) -> (a -> Maybe Vertex) -> GraphKL a
GraphKL
{ toGraphKL :: Graph
toGraphKL = Graph
g
, fromVertexKL :: Vertex -> a
fromVertexKL = \Vertex
u -> case Vertex -> ((), a, [a])
r Vertex
u of (()
_, a
v, [a]
_) -> a
v
, toVertexKL :: a -> Maybe Vertex
toVertexKL = a -> Maybe Vertex
t }
where
(Graph
g, Vertex -> ((), a, [a])
r, a -> Maybe Vertex
t) = [((), a, [a])]
-> (Graph, Vertex -> ((), a, [a]), a -> Maybe Vertex)
forall key node.
Ord key =>
[(node, key, [key])]
-> (Graph, Vertex -> (node, key, [key]), key -> Maybe Vertex)
KL.graphFromEdges [ ((), a
x, [a]
ys) | (a
x, [a]
ys) <- AdjacencyMap a -> [(a, [a])]
forall a. AdjacencyMap a -> [(a, [a])]
AM.adjacencyList AdjacencyMap a
am ]
fromAdjacencyIntMap :: AIM.AdjacencyIntMap -> GraphKL Int
fromAdjacencyIntMap :: AdjacencyIntMap -> GraphKL Vertex
fromAdjacencyIntMap AdjacencyIntMap
aim = GraphKL :: forall a.
Graph -> (Vertex -> a) -> (a -> Maybe Vertex) -> GraphKL a
GraphKL
{ toGraphKL :: Graph
toGraphKL = Graph
g
, fromVertexKL :: Vertex -> Vertex
fromVertexKL = \Vertex
x -> case Vertex -> ((), Vertex, [Vertex])
r Vertex
x of (()
_, Vertex
v, [Vertex]
_) -> Vertex
v
, toVertexKL :: Vertex -> Maybe Vertex
toVertexKL = Vertex -> Maybe Vertex
t }
where
(Graph
g, Vertex -> ((), Vertex, [Vertex])
r, Vertex -> Maybe Vertex
t) = [((), Vertex, [Vertex])]
-> (Graph, Vertex -> ((), Vertex, [Vertex]),
Vertex -> Maybe Vertex)
forall key node.
Ord key =>
[(node, key, [key])]
-> (Graph, Vertex -> (node, key, [key]), key -> Maybe Vertex)
KL.graphFromEdges [ ((), Vertex
x, [Vertex]
ys) | (Vertex
x, [Vertex]
ys) <- AdjacencyIntMap -> [(Vertex, [Vertex])]
AIM.adjacencyList AdjacencyIntMap
aim ]
dfsForest :: GraphKL a -> Forest a
dfsForest :: GraphKL a -> Forest a
dfsForest (GraphKL Graph
g Vertex -> a
r a -> Maybe Vertex
_) = (Tree Vertex -> Tree a) -> [Tree Vertex] -> Forest a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Vertex -> a) -> Tree Vertex -> Tree a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vertex -> a
r) (Graph -> [Tree Vertex]
KL.dff Graph
g)
dfsForestFrom :: [a] -> GraphKL a -> Forest a
dfsForestFrom :: [a] -> GraphKL a -> Forest a
dfsForestFrom [a]
vs (GraphKL Graph
g Vertex -> a
r a -> Maybe Vertex
t) = (Tree Vertex -> Tree a) -> [Tree Vertex] -> Forest a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Vertex -> a) -> Tree Vertex -> Tree a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vertex -> a
r) (Graph -> [Vertex] -> [Tree Vertex]
KL.dfs Graph
g ((a -> Maybe Vertex) -> [a] -> [Vertex]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe a -> Maybe Vertex
t [a]
vs))
dfs :: [a] -> GraphKL a -> [a]
dfs :: [a] -> GraphKL a -> [a]
dfs [a]
vs = (Tree a -> [a]) -> [Tree a] -> [a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Tree a -> [a]
forall a. Tree a -> [a]
flatten ([Tree a] -> [a]) -> (GraphKL a -> [Tree a]) -> GraphKL a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> GraphKL a -> [Tree a]
forall a. [a] -> GraphKL a -> Forest a
dfsForestFrom [a]
vs
topSort :: GraphKL a -> [a]
topSort :: GraphKL a -> [a]
topSort (GraphKL Graph
g Vertex -> a
r a -> Maybe Vertex
_) = (Vertex -> a) -> [Vertex] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map Vertex -> a
r (Graph -> [Vertex]
KL.topSort Graph
g)
scc :: Ord a => AM.AdjacencyMap a -> AM.AdjacencyMap (NonEmpty.AdjacencyMap a)
scc :: AdjacencyMap a -> AdjacencyMap (AdjacencyMap a)
scc AdjacencyMap a
m = (Vertex -> AdjacencyMap a)
-> AdjacencyMap Vertex -> AdjacencyMap (AdjacencyMap a)
forall a b.
(Ord a, Ord b) =>
(a -> b) -> AdjacencyMap a -> AdjacencyMap b
AM.gmap (Map Vertex (AdjacencyMap a)
component Map Vertex (AdjacencyMap a) -> Vertex -> AdjacencyMap a
forall k a. Ord k => Map k a -> k -> a
Map.!) (AdjacencyMap Vertex -> AdjacencyMap (AdjacencyMap a))
-> AdjacencyMap Vertex -> AdjacencyMap (AdjacencyMap a)
forall a b. (a -> b) -> a -> b
$ AdjacencyMap Vertex -> AdjacencyMap Vertex
forall a. Ord a => AdjacencyMap a -> AdjacencyMap a
removeSelfLoops (AdjacencyMap Vertex -> AdjacencyMap Vertex)
-> AdjacencyMap Vertex -> AdjacencyMap Vertex
forall a b. (a -> b) -> a -> b
$ (a -> Vertex) -> AdjacencyMap a -> AdjacencyMap Vertex
forall a b.
(Ord a, Ord b) =>
(a -> b) -> AdjacencyMap a -> AdjacencyMap b
AM.gmap (Map a Vertex
leader Map a Vertex -> a -> Vertex
forall k a. Ord k => Map k a -> k -> a
Map.!) AdjacencyMap a
m
where
GraphKL Graph
g Vertex -> a
decode a -> Maybe Vertex
_ = AdjacencyMap a -> GraphKL a
forall a. Ord a => AdjacencyMap a -> GraphKL a
fromAdjacencyMap AdjacencyMap a
m
sccs :: [[Vertex]]
sccs = (Tree Vertex -> [Vertex]) -> [Tree Vertex] -> [[Vertex]]
forall a b. (a -> b) -> [a] -> [b]
map Tree Vertex -> [Vertex]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (Graph -> [Tree Vertex]
KL.scc Graph
g)
leader :: Map a Vertex
leader = [(a, Vertex)] -> Map a Vertex
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [ (Vertex -> a
decode Vertex
y, Vertex
x) | Vertex
x:[Vertex]
xs <- [[Vertex]]
sccs, Vertex
y <- Vertex
xVertex -> [Vertex] -> [Vertex]
forall a. a -> [a] -> [a]
:[Vertex]
xs ]
component :: Map Vertex (AdjacencyMap a)
component = [(Vertex, AdjacencyMap a)] -> Map Vertex (AdjacencyMap a)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [ (Vertex
x, [Vertex] -> AdjacencyMap a
expand (Vertex
xVertex -> [Vertex] -> [Vertex]
forall a. a -> [a] -> [a]
:[Vertex]
xs)) | Vertex
x:[Vertex]
xs <- [[Vertex]]
sccs ]
expand :: [Vertex] -> AdjacencyMap a
expand [Vertex]
xs = Maybe (AdjacencyMap a) -> AdjacencyMap a
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (AdjacencyMap a) -> AdjacencyMap a)
-> Maybe (AdjacencyMap a) -> AdjacencyMap a
forall a b. (a -> b) -> a -> b
$ AdjacencyMap a -> Maybe (AdjacencyMap a)
forall a. AdjacencyMap a -> Maybe (AdjacencyMap a)
NonEmpty.toNonEmpty (AdjacencyMap a -> Maybe (AdjacencyMap a))
-> AdjacencyMap a -> Maybe (AdjacencyMap a)
forall a b. (a -> b) -> a -> b
$ (a -> Bool) -> AdjacencyMap a -> AdjacencyMap a
forall a. (a -> Bool) -> AdjacencyMap a -> AdjacencyMap a
AM.induce (a -> Set a -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set a
s) AdjacencyMap a
m
where
s :: Set a
s = [a] -> Set a
forall a. Ord a => [a] -> Set a
Set.fromList ((Vertex -> a) -> [Vertex] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map Vertex -> a
decode [Vertex]
xs)
removeSelfLoops :: Ord a => AM.AdjacencyMap a -> AM.AdjacencyMap a
removeSelfLoops :: AdjacencyMap a -> AdjacencyMap a
removeSelfLoops AdjacencyMap a
m = (a -> AdjacencyMap a -> AdjacencyMap a)
-> AdjacencyMap a -> [a] -> AdjacencyMap a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\a
x -> a -> a -> AdjacencyMap a -> AdjacencyMap a
forall a. Ord a => a -> a -> AdjacencyMap a -> AdjacencyMap a
AM.removeEdge a
x a
x) AdjacencyMap a
m (AdjacencyMap a -> [a]
forall a. AdjacencyMap a -> [a]
AM.vertexList AdjacencyMap a
m)