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 {
forall a. GraphKL a -> Graph
toGraphKL :: KL.Graph,
forall a. GraphKL a -> Int -> a
fromVertexKL :: KL.Vertex -> a,
forall a. GraphKL a -> a -> Maybe Int
toVertexKL :: a -> Maybe KL.Vertex }
fromAdjacencyMap :: Ord a => AM.AdjacencyMap a -> GraphKL a
fromAdjacencyMap :: forall a. Ord a => AdjacencyMap a -> GraphKL a
fromAdjacencyMap AdjacencyMap a
am = GraphKL
{ toGraphKL :: Graph
toGraphKL = Graph
g
, fromVertexKL :: Int -> a
fromVertexKL = \Int
u -> case Int -> ((), a, [a])
r Int
u of (()
_, a
v, [a]
_) -> a
v
, toVertexKL :: a -> Maybe Int
toVertexKL = a -> Maybe Int
t }
where
(Graph
g, Int -> ((), a, [a])
r, a -> Maybe Int
t) = [((), a, [a])] -> (Graph, Int -> ((), a, [a]), a -> Maybe Int)
forall key node.
Ord key =>
[(node, key, [key])]
-> (Graph, Int -> (node, key, [key]), key -> Maybe Int)
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 Int
fromAdjacencyIntMap AdjacencyIntMap
aim = GraphKL
{ toGraphKL :: Graph
toGraphKL = Graph
g
, fromVertexKL :: Int -> Int
fromVertexKL = \Int
x -> case Int -> ((), Int, [Int])
r Int
x of (()
_, Int
v, [Int]
_) -> Int
v
, toVertexKL :: Int -> Maybe Int
toVertexKL = Int -> Maybe Int
t }
where
(Graph
g, Int -> ((), Int, [Int])
r, Int -> Maybe Int
t) = [((), Int, [Int])]
-> (Graph, Int -> ((), Int, [Int]), Int -> Maybe Int)
forall key node.
Ord key =>
[(node, key, [key])]
-> (Graph, Int -> (node, key, [key]), key -> Maybe Int)
KL.graphFromEdges [ ((), Int
x, [Int]
ys) | (Int
x, [Int]
ys) <- AdjacencyIntMap -> [(Int, [Int])]
AIM.adjacencyList AdjacencyIntMap
aim ]
dfsForest :: GraphKL a -> Forest a
dfsForest :: forall a. GraphKL a -> Forest a
dfsForest (GraphKL Graph
g Int -> a
r a -> Maybe Int
_) = (Tree Int -> Tree a) -> [Tree Int] -> [Tree a]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Int -> a) -> Tree Int -> Tree a
forall a b. (a -> b) -> Tree a -> Tree b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> a
r) (Graph -> [Tree Int]
KL.dff Graph
g)
dfsForestFrom :: GraphKL a -> [a] -> Forest a
dfsForestFrom :: forall a. GraphKL a -> [a] -> Forest a
dfsForestFrom (GraphKL Graph
g Int -> a
r a -> Maybe Int
t) = (Tree Int -> Tree a) -> [Tree Int] -> [Tree a]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Int -> a) -> Tree Int -> Tree a
forall a b. (a -> b) -> Tree a -> Tree b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> a
r) ([Tree Int] -> [Tree a]) -> ([a] -> [Tree Int]) -> [a] -> [Tree a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Graph -> [Int] -> [Tree Int]
KL.dfs Graph
g ([Int] -> [Tree Int]) -> ([a] -> [Int]) -> [a] -> [Tree Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Maybe Int) -> [a] -> [Int]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe a -> Maybe Int
t
dfs :: GraphKL a -> [a] -> [a]
dfs :: forall a. GraphKL a -> [a] -> [a]
dfs GraphKL a
x = (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]) -> ([a] -> [Tree a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GraphKL a -> [a] -> [Tree a]
forall a. GraphKL a -> [a] -> Forest a
dfsForestFrom GraphKL a
x
topSort :: GraphKL a -> [a]
topSort :: forall a. GraphKL a -> [a]
topSort (GraphKL Graph
g Int -> a
r a -> Maybe Int
_) = (Int -> a) -> [Int] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map Int -> a
r (Graph -> [Int]
KL.topSort Graph
g)
scc :: Ord a => AM.AdjacencyMap a -> AM.AdjacencyMap (NonEmpty.AdjacencyMap a)
scc :: forall a. Ord a => AdjacencyMap a -> AdjacencyMap (AdjacencyMap a)
scc AdjacencyMap a
m = (Int -> AdjacencyMap a)
-> AdjacencyMap Int -> AdjacencyMap (AdjacencyMap a)
forall a b.
(Ord a, Ord b) =>
(a -> b) -> AdjacencyMap a -> AdjacencyMap b
AM.gmap (Map Int (AdjacencyMap a)
component Map Int (AdjacencyMap a) -> Int -> AdjacencyMap a
forall k a. Ord k => Map k a -> k -> a
Map.!) (AdjacencyMap Int -> AdjacencyMap (AdjacencyMap a))
-> AdjacencyMap Int -> AdjacencyMap (AdjacencyMap a)
forall a b. (a -> b) -> a -> b
$ AdjacencyMap Int -> AdjacencyMap Int
forall a. Ord a => AdjacencyMap a -> AdjacencyMap a
removeSelfLoops (AdjacencyMap Int -> AdjacencyMap Int)
-> AdjacencyMap Int -> AdjacencyMap Int
forall a b. (a -> b) -> a -> b
$ (a -> Int) -> AdjacencyMap a -> AdjacencyMap Int
forall a b.
(Ord a, Ord b) =>
(a -> b) -> AdjacencyMap a -> AdjacencyMap b
AM.gmap (Map a Int
leader Map a Int -> a -> Int
forall k a. Ord k => Map k a -> k -> a
Map.!) AdjacencyMap a
m
where
GraphKL Graph
g Int -> a
decode a -> Maybe Int
_ = AdjacencyMap a -> GraphKL a
forall a. Ord a => AdjacencyMap a -> GraphKL a
fromAdjacencyMap AdjacencyMap a
m
sccs :: [[Int]]
sccs = (Tree Int -> [Int]) -> [Tree Int] -> [[Int]]
forall a b. (a -> b) -> [a] -> [b]
map Tree Int -> [Int]
forall a. Tree a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (Graph -> [Tree Int]
KL.scc Graph
g)
leader :: Map a Int
leader = [(a, Int)] -> Map a Int
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [ (Int -> a
decode Int
y, Int
x) | Int
x:[Int]
xs <- [[Int]]
sccs, Int
y <- Int
xInt -> [Int] -> [Int]
forall a. a -> [a] -> [a]
:[Int]
xs ]
component :: Map Int (AdjacencyMap a)
component = [(Int, AdjacencyMap a)] -> Map Int (AdjacencyMap a)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [ (Int
x, [Int] -> AdjacencyMap a
expand (Int
xInt -> [Int] -> [Int]
forall a. a -> [a] -> [a]
:[Int]
xs)) | Int
x:[Int]
xs <- [[Int]]
sccs ]
expand :: [Int] -> AdjacencyMap a
expand [Int]
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 ((Int -> a) -> [Int] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map Int -> a
decode [Int]
xs)
removeSelfLoops :: Ord a => AM.AdjacencyMap a -> AM.AdjacencyMap a
removeSelfLoops :: forall a. Ord a => AdjacencyMap a -> AdjacencyMap a
removeSelfLoops AdjacencyMap a
m = (a -> AdjacencyMap a -> AdjacencyMap a)
-> AdjacencyMap a -> [a] -> AdjacencyMap a
forall a b. (a -> b -> b) -> b -> [a] -> b
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)