{-# LANGUAGE LambdaCase #-}
module Algebra.Graph.AdjacencyMap.Algorithm (
bfsForest, bfs, dfsForest, dfsForestFrom, dfs, reachable,
topSort, isAcyclic, scc,
isDfsForestOf, isTopSortOf,
Cycle
) where
import Control.Monad
import Control.Monad.Trans.Cont
import Control.Monad.Trans.State.Strict
import Data.Foldable (for_)
import Data.Either
import Data.List.NonEmpty (NonEmpty(..), (<|))
import Data.Maybe
import Data.Tree
import Algebra.Graph.AdjacencyMap
import Algebra.Graph.Internal
import qualified Algebra.Graph.NonEmpty.AdjacencyMap as NonEmpty
import qualified Data.Array as Array
import qualified Data.List as List
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
bfsForest :: Ord a => AdjacencyMap a -> [a] -> Forest a
bfsForest :: forall a. Ord a => AdjacencyMap a -> [a] -> Forest a
bfsForest AdjacencyMap a
x [a]
vs = forall s a. State s a -> s -> a
evalState ([a] -> StateT (Set a) Identity [Tree a]
explore [ a
v | a
v <- [a]
vs, forall a. Ord a => a -> AdjacencyMap a -> Bool
hasVertex a
v AdjacencyMap a
x ]) forall a. Set a
Set.empty
where
explore :: [a] -> StateT (Set a) Identity [Tree a]
explore = forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM forall {m :: * -> *} {a}.
(Monad m, Ord a) =>
a -> StateT (Set a) m Bool
discovered forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> forall (m :: * -> *) b a.
Monad m =>
(b -> m (a, [b])) -> [b] -> m [Tree a]
unfoldForestM_BF a -> StateT (Set a) Identity (a, [a])
walk
walk :: a -> StateT (Set a) Identity (a, [a])
walk a
v = (a
v,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> StateT (Set a) Identity [a]
adjacentM a
v
adjacentM :: a -> StateT (Set a) Identity [a]
adjacentM a
v = forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM forall {m :: * -> *} {a}.
(Monad m, Ord a) =>
a -> StateT (Set a) m Bool
discovered forall a b. (a -> b) -> a -> b
$ forall a. Set a -> [a]
Set.toList (forall a. Ord a => a -> AdjacencyMap a -> Set a
postSet a
v AdjacencyMap a
x)
discovered :: a -> StateT (Set a) m Bool
discovered a
v = do Bool
new <- forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
gets (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => a -> Set a -> Bool
Set.member a
v)
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
new forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify' (forall a. Ord a => a -> Set a -> Set a
Set.insert a
v)
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
new
bfs :: Ord a => AdjacencyMap a -> [a] -> [[a]]
bfs :: forall a. Ord a => AdjacencyMap a -> [a] -> [[a]]
bfs AdjacencyMap a
x = forall a b. (a -> b) -> [a] -> [b]
map forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [[a]] -> [[a]]
List.transpose forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall a. Tree a -> [[a]]
levels forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => AdjacencyMap a -> [a] -> Forest a
bfsForest AdjacencyMap a
x
dfsForestFromImpl :: Ord a => AdjacencyMap a -> [a] -> Forest a
dfsForestFromImpl :: forall a. Ord a => AdjacencyMap a -> [a] -> Forest a
dfsForestFromImpl AdjacencyMap a
g [a]
vs = forall s a. State s a -> s -> a
evalState ([a] -> StateT (Set a) Identity [Tree a]
explore [a]
vs) forall a. Set a
Set.empty
where
explore :: [a] -> StateT (Set a) Identity [Tree a]
explore (a
v:[a]
vs) = forall {m :: * -> *} {a}.
(Monad m, Ord a) =>
a -> StateT (Set a) m Bool
discovered a
v forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Bool
True -> (:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> StateT (Set a) Identity (Tree a)
walk a
v forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [a] -> StateT (Set a) Identity [Tree a]
explore [a]
vs
Bool
False -> [a] -> StateT (Set a) Identity [Tree a]
explore [a]
vs
explore [] = forall (m :: * -> *) a. Monad m => a -> m a
return []
walk :: a -> StateT (Set a) Identity (Tree a)
walk a
v = forall a. a -> [Tree a] -> Tree a
Node a
v forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [a] -> StateT (Set a) Identity [Tree a]
explore (a -> [a]
adjacent a
v)
adjacent :: a -> [a]
adjacent a
v = forall a. Set a -> [a]
Set.toList (forall a. Ord a => a -> AdjacencyMap a -> Set a
postSet a
v AdjacencyMap a
g)
discovered :: a -> StateT (Set a) m Bool
discovered a
v = do Bool
new <- forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
gets (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => a -> Set a -> Bool
Set.member a
v)
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
new forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify' (forall a. Ord a => a -> Set a -> Set a
Set.insert a
v)
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
new
dfsForest :: Ord a => AdjacencyMap a -> Forest a
dfsForest :: forall a. Ord a => AdjacencyMap a -> Forest a
dfsForest AdjacencyMap a
g = forall a. Ord a => AdjacencyMap a -> [a] -> Forest a
dfsForestFromImpl AdjacencyMap a
g (forall a. AdjacencyMap a -> [a]
vertexList AdjacencyMap a
g)
dfsForestFrom :: Ord a => AdjacencyMap a -> [a] -> Forest a
dfsForestFrom :: forall a. Ord a => AdjacencyMap a -> [a] -> Forest a
dfsForestFrom AdjacencyMap a
g [a]
vs = forall a. Ord a => AdjacencyMap a -> [a] -> Forest a
dfsForestFromImpl AdjacencyMap a
g [ a
v | a
v <- [a]
vs, forall a. Ord a => a -> AdjacencyMap a -> Bool
hasVertex a
v AdjacencyMap a
g ]
dfs :: Ord a => AdjacencyMap a -> [a] -> [a]
dfs :: forall a. Ord a => AdjacencyMap a -> [a] -> [a]
dfs AdjacencyMap a
x = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap forall a. Tree a -> [a]
flatten forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => AdjacencyMap a -> [a] -> Forest a
dfsForestFrom AdjacencyMap a
x
reachable :: Ord a => AdjacencyMap a -> a -> [a]
reachable :: forall a. Ord a => AdjacencyMap a -> a -> [a]
reachable AdjacencyMap a
x a
y = forall a. Ord a => AdjacencyMap a -> [a] -> [a]
dfs AdjacencyMap a
x [a
y]
type Cycle = NonEmpty
type Result a = Either (Cycle a) [a]
data NodeState = Entered | Exited
data S a = S { forall a. S a -> Map a a
parent :: Map.Map a a
, forall a. S a -> Map a NodeState
entry :: Map.Map a NodeState
, forall a. S a -> [a]
order :: [a] }
topSortImpl :: Ord a => AdjacencyMap a -> StateT (S a) (Cont (Result a)) (Result a)
topSortImpl :: forall a.
Ord a =>
AdjacencyMap a -> StateT (S a) (Cont (Result a)) (Result a)
topSortImpl AdjacencyMap a
g = forall (m :: * -> *) a s b.
CallCC m (a, s) (b, s) -> CallCC (StateT s m) a b
liftCallCC' forall {k} a (r :: k) (m :: k -> *) b.
((a -> ContT r m b) -> ContT r m a) -> ContT r m a
callCC forall a b. (a -> b) -> a -> b
$ \Result a -> StateT (S a) (Cont (Result a)) ()
cyclic ->
do let vertices :: [a]
vertices = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ forall k a. Map k a -> [(k, a)]
Map.toDescList forall a b. (a -> b) -> a -> b
$ forall a. AdjacencyMap a -> Map a (Set a)
adjacencyMap AdjacencyMap a
g
adjacent :: a -> [a]
adjacent = forall a. Set a -> [a]
Set.toDescList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Ord a => a -> AdjacencyMap a -> Set a
postSet AdjacencyMap a
g
dfsRoot :: a -> StateT (S a) (Cont (Result a)) ()
dfsRoot a
x = forall {m :: * -> *} {k}.
(Monad m, Ord k) =>
k -> StateT (S k) m (Maybe NodeState)
nodeState a
x forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe NodeState
Nothing -> forall {m :: * -> *} {a}.
(Monad m, Ord a) =>
a -> StateT (S a) m ()
enterRoot a
x forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> a -> StateT (S a) (Cont (Result a)) ()
dfs a
x forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {m :: * -> *} {a}.
(Monad m, Ord a) =>
a -> StateT (S a) m ()
exit a
x
Maybe NodeState
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
dfs :: a -> StateT (S a) (Cont (Result a)) ()
dfs a
x = forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (a -> [a]
adjacent a
x) forall a b. (a -> b) -> a -> b
$ \a
y ->
forall {m :: * -> *} {k}.
(Monad m, Ord k) =>
k -> StateT (S k) m (Maybe NodeState)
nodeState a
y forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe NodeState
Nothing -> forall {m :: * -> *} {a}.
(Monad m, Ord a) =>
a -> a -> StateT (S a) m ()
enter a
x a
y forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> a -> StateT (S a) (Cont (Result a)) ()
dfs a
y forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {m :: * -> *} {a}.
(Monad m, Ord a) =>
a -> StateT (S a) m ()
exit a
y
Just NodeState
Exited -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just NodeState
Entered -> Result a -> StateT (S a) (Cont (Result a)) ()
cyclic forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {a}. Ord a => a -> a -> Map a a -> NonEmpty a
retrace a
x a
y forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
gets forall a. S a -> Map a a
parent
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [a]
vertices a -> StateT (S a) (Cont (Result a)) ()
dfsRoot
forall a b. b -> Either a b
Right forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
gets forall a. S a -> [a]
order
where
nodeState :: k -> StateT (S k) m (Maybe NodeState)
nodeState k
v = forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
gets (forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup k
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. S a -> Map a NodeState
entry)
enter :: a -> a -> StateT (S a) m ()
enter a
u a
v = forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify' (\(S Map a a
m Map a NodeState
n [a]
vs) -> forall a. Map a a -> Map a NodeState -> [a] -> S a
S (forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert a
v a
u Map a a
m)
(forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert a
v NodeState
Entered Map a NodeState
n)
[a]
vs)
enterRoot :: a -> StateT (S a) m ()
enterRoot a
v = forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify' (\(S Map a a
m Map a NodeState
n [a]
vs) -> forall a. Map a a -> Map a NodeState -> [a] -> S a
S Map a a
m (forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert a
v NodeState
Entered Map a NodeState
n) [a]
vs)
exit :: a -> StateT (S a) m ()
exit a
v = forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify' (\(S Map a a
m Map a NodeState
n [a]
vs) -> forall a. Map a a -> Map a NodeState -> [a] -> S a
S Map a a
m (forall k a.
Ord k =>
(Maybe a -> Maybe a) -> k -> Map k a -> Map k a
Map.alter (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap NodeState -> NodeState
leave) a
v Map a NodeState
n) (a
vforall a. a -> [a] -> [a]
:[a]
vs))
where leave :: NodeState -> NodeState
leave = \case
NodeState
Entered -> NodeState
Exited
NodeState
Exited -> forall a. HasCallStack => [Char] -> a
error [Char]
"Internal error: dfs search order violated"
retrace :: a -> a -> Map a a -> NonEmpty a
retrace a
curr a
head Map a a
parent = NonEmpty a -> NonEmpty a
aux (a
curr forall a. a -> [a] -> NonEmpty a
:| []) where
aux :: NonEmpty a -> NonEmpty a
aux xs :: NonEmpty a
xs@(a
curr :| [a]
_)
| a
head forall a. Eq a => a -> a -> Bool
== a
curr = NonEmpty a
xs
| Bool
otherwise = NonEmpty a -> NonEmpty a
aux (Map a a
parent forall k a. Ord k => Map k a -> k -> a
Map.! a
curr forall a. a -> NonEmpty a -> NonEmpty a
<| NonEmpty a
xs)
topSort :: Ord a => AdjacencyMap a -> Either (Cycle a) [a]
topSort :: forall a. Ord a => AdjacencyMap a -> Either (Cycle a) [a]
topSort AdjacencyMap a
g = forall r a. Cont r a -> (a -> r) -> r
runCont (forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT (forall a.
Ord a =>
AdjacencyMap a -> StateT (S a) (Cont (Result a)) (Result a)
topSortImpl AdjacencyMap a
g) forall {a}. S a
initialState) forall a. a -> a
id
where
initialState :: S a
initialState = forall a. Map a a -> Map a NodeState -> [a] -> S a
S forall k a. Map k a
Map.empty forall k a. Map k a
Map.empty []
isAcyclic :: Ord a => AdjacencyMap a -> Bool
isAcyclic :: forall a. Ord a => AdjacencyMap a -> Bool
isAcyclic = forall a b. Either a b -> Bool
isRight forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => AdjacencyMap a -> Either (Cycle a) [a]
topSort
scc :: Ord a => AdjacencyMap a -> AdjacencyMap (NonEmpty.AdjacencyMap a)
scc :: forall a. Ord a => AdjacencyMap a -> AdjacencyMap (AdjacencyMap a)
scc AdjacencyMap a
g = forall a.
Ord a =>
AdjacencyMap a -> StateSCC a -> AdjacencyMap (AdjacencyMap a)
condense AdjacencyMap a
g forall a b. (a -> b) -> a -> b
$ forall s a. State s a -> s -> s
execState (forall a. Ord a => AdjacencyMap a -> State (StateSCC a) ()
gabowSCC AdjacencyMap a
g) forall {a}. StateSCC a
initialState where
initialState :: StateSCC a
initialState = forall a.
Int
-> Int
-> [(Int, a)]
-> [a]
-> Map a Int
-> Map a Int
-> [AdjacencyMap a]
-> [(Int, (a, a))]
-> [(a, a)]
-> StateSCC a
SCC Int
0 Int
0 [] [] forall k a. Map k a
Map.empty forall k a. Map k a
Map.empty [] [] []
data StateSCC a
= SCC { forall a. StateSCC a -> Int
_preorder :: {-# unpack #-} !Int
, forall a. StateSCC a -> Int
_component :: {-# unpack #-} !Int
, forall a. StateSCC a -> [(Int, a)]
boundaryStack :: [(Int,a)]
, forall a. StateSCC a -> [a]
_pathStack :: [a]
, forall a. StateSCC a -> Map a Int
preorders :: Map.Map a Int
, forall a. StateSCC a -> Map a Int
components :: Map.Map a Int
, forall a. StateSCC a -> [AdjacencyMap a]
_innerGraphs :: [AdjacencyMap a]
, forall a. StateSCC a -> [(Int, (a, a))]
_innerEdges :: [(Int,(a,a))]
, forall a. StateSCC a -> [(a, a)]
_outerEdges :: [(a,a)]
} deriving (Int -> StateSCC a -> ShowS
forall a. (Show a, Ord a) => Int -> StateSCC a -> ShowS
forall a. (Show a, Ord a) => [StateSCC a] -> ShowS
forall a. (Show a, Ord a) => StateSCC a -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [StateSCC a] -> ShowS
$cshowList :: forall a. (Show a, Ord a) => [StateSCC a] -> ShowS
show :: StateSCC a -> [Char]
$cshow :: forall a. (Show a, Ord a) => StateSCC a -> [Char]
showsPrec :: Int -> StateSCC a -> ShowS
$cshowsPrec :: forall a. (Show a, Ord a) => Int -> StateSCC a -> ShowS
Show)
gabowSCC :: Ord a => AdjacencyMap a -> State (StateSCC a) ()
gabowSCC :: forall a. Ord a => AdjacencyMap a -> State (StateSCC a) ()
gabowSCC AdjacencyMap a
g =
do let dfs :: a -> StateT (StateSCC a) Identity Bool
dfs a
u = do Int
p_u <- forall {m :: * -> *} {b}.
(Monad m, Ord b) =>
b -> StateT (StateSCC b) m Int
enter a
u
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (forall a. Ord a => a -> AdjacencyMap a -> Set a
postSet a
u AdjacencyMap a
g) forall a b. (a -> b) -> a -> b
$ \a
v -> do
forall {m :: * -> *} {k}.
(Monad m, Ord k) =>
k -> StateT (StateSCC k) m (Maybe Int)
preorderId a
v forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe Int
Nothing -> do
Bool
updated <- a -> StateT (StateSCC a) Identity Bool
dfs a
v
if Bool
updated then forall {m :: * -> *} {a}.
Monad m =>
(a, a) -> StateT (StateSCC a) m ()
outedge (a
u,a
v) else forall {m :: * -> *} {a}.
Monad m =>
(Int, (a, a)) -> StateT (StateSCC a) m ()
inedge (Int
p_u,(a
u,a
v))
Just Int
p_v -> do
Bool
scc_v <- forall {m :: * -> *} {k}.
(Monad m, Ord k) =>
k -> StateT (StateSCC k) m Bool
hasComponent a
v
if Bool
scc_v
then forall {m :: * -> *} {a}.
Monad m =>
(a, a) -> StateT (StateSCC a) m ()
outedge (a
u,a
v)
else forall {m :: * -> *} {a}.
Monad m =>
Int -> StateT (StateSCC a) m ()
popBoundary Int
p_v forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {m :: * -> *} {a}.
Monad m =>
(Int, (a, a)) -> StateT (StateSCC a) m ()
inedge (Int
p_u,(a
u,a
v))
forall {m :: * -> *} {k}.
(Monad m, Ord k) =>
k -> StateT (StateSCC k) m Bool
exit a
u
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (forall a. AdjacencyMap a -> [a]
vertexList AdjacencyMap a
g) forall a b. (a -> b) -> a -> b
$ \a
v -> do
Bool
assigned <- forall {m :: * -> *} {k}.
(Monad m, Ord k) =>
k -> StateT (StateSCC k) m Bool
hasPreorderId a
v
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
assigned forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ a -> StateT (StateSCC a) Identity Bool
dfs a
v
where
enter :: b -> StateT (StateSCC b) m Int
enter b
v = do SCC Int
pre Int
scc [(Int, b)]
bnd [b]
pth Map b Int
pres Map b Int
sccs [AdjacencyMap b]
gs [(Int, (b, b))]
es_i [(b, b)]
es_o <- forall (m :: * -> *) s. Monad m => StateT s m s
get
let pre' :: Int
pre' = Int
preforall a. Num a => a -> a -> a
+Int
1
bnd' :: [(Int, b)]
bnd' = (Int
pre,b
v)forall a. a -> [a] -> [a]
:[(Int, b)]
bnd
pth' :: [b]
pth' = b
vforall a. a -> [a] -> [a]
:[b]
pth
pres' :: Map b Int
pres' = forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert b
v Int
pre Map b Int
pres
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
put forall a b. (a -> b) -> a -> b
$! forall a.
Int
-> Int
-> [(Int, a)]
-> [a]
-> Map a Int
-> Map a Int
-> [AdjacencyMap a]
-> [(Int, (a, a))]
-> [(a, a)]
-> StateSCC a
SCC Int
pre' Int
scc [(Int, b)]
bnd' [b]
pth' Map b Int
pres' Map b Int
sccs [AdjacencyMap b]
gs [(Int, (b, b))]
es_i [(b, b)]
es_o
forall (m :: * -> *) a. Monad m => a -> m a
return Int
pre
popBoundary :: Int -> StateT (StateSCC a) m ()
popBoundary Int
p_v = forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify'
(\(SCC Int
pre Int
scc [(Int, a)]
bnd [a]
pth Map a Int
pres Map a Int
sccs [AdjacencyMap a]
gs [(Int, (a, a))]
es_i [(a, a)]
es_o) ->
forall a.
Int
-> Int
-> [(Int, a)]
-> [a]
-> Map a Int
-> Map a Int
-> [AdjacencyMap a]
-> [(Int, (a, a))]
-> [(a, a)]
-> StateSCC a
SCC Int
pre Int
scc (forall a. (a -> Bool) -> [a] -> [a]
dropWhile ((forall a. Ord a => a -> a -> Bool
>Int
p_v)forall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a b. (a, b) -> a
fst) [(Int, a)]
bnd) [a]
pth Map a Int
pres Map a Int
sccs [AdjacencyMap a]
gs [(Int, (a, a))]
es_i [(a, a)]
es_o)
exit :: b -> StateT (StateSCC b) m Bool
exit b
v = do Bool
newComponent <- (b
vforall a. Eq a => a -> a -> Bool
==)forall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a b. (a, b) -> b
sndforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. [a] -> a
head forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
gets forall a. StateSCC a -> [(Int, a)]
boundaryStack
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
newComponent forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *} {k}.
(Monad m, Ord k) =>
k -> StateT (StateSCC k) m ()
insertComponent b
v
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
newComponent
insertComponent :: k -> StateT (StateSCC k) m ()
insertComponent k
v = forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify'
(\(SCC Int
pre Int
scc [(Int, k)]
bnd [k]
pth Map k Int
pres Map k Int
sccs [AdjacencyMap k]
gs [(Int, (k, k))]
es_i [(k, k)]
es_o) ->
let ([k]
curr,[k]
v_pth') = forall a. (a -> Bool) -> [a] -> ([a], [a])
span (forall a. Eq a => a -> a -> Bool
/=k
v) [k]
pth
pth' :: [k]
pth' = forall a. [a] -> [a]
tail [k]
v_pth'
([(Int, (k, k))]
es,[(Int, (k, k))]
es_i') = forall a. (a -> Bool) -> [a] -> ([a], [a])
span ((forall a. Ord a => a -> a -> Bool
>=Int
p_v)forall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a b. (a, b) -> a
fst) [(Int, (k, k))]
es_i
g_i :: AdjacencyMap k
g_i | forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Int, (k, k))]
es = forall a. a -> AdjacencyMap a
vertex k
v
| Bool
otherwise = forall a. Ord a => [(a, a)] -> AdjacencyMap a
edges (forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Int, (k, k))]
es)
p_v :: Int
p_v = forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
head [(Int, k)]
bnd
scc' :: Int
scc' = Int
scc forall a. Num a => a -> a -> a
+ Int
1
bnd' :: [(Int, k)]
bnd' = forall a. [a] -> [a]
tail [(Int, k)]
bnd
sccs' :: Map k Int
sccs' = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' (\Map k Int
sccs k
x -> forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert k
x Int
scc Map k Int
sccs) Map k Int
sccs (k
vforall a. a -> [a] -> [a]
:[k]
curr)
gs' :: [AdjacencyMap k]
gs' = AdjacencyMap k
g_iforall a. a -> [a] -> [a]
:[AdjacencyMap k]
gs
in forall a.
Int
-> Int
-> [(Int, a)]
-> [a]
-> Map a Int
-> Map a Int
-> [AdjacencyMap a]
-> [(Int, (a, a))]
-> [(a, a)]
-> StateSCC a
SCC Int
pre Int
scc' [(Int, k)]
bnd' [k]
pth' Map k Int
pres Map k Int
sccs' [AdjacencyMap k]
gs' [(Int, (k, k))]
es_i' [(k, k)]
es_o)
inedge :: (Int, (a, a)) -> StateT (StateSCC a) m ()
inedge (Int, (a, a))
uv = forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify'
(\(SCC Int
pre Int
scc [(Int, a)]
bnd [a]
pth Map a Int
pres Map a Int
sccs [AdjacencyMap a]
gs [(Int, (a, a))]
es_i [(a, a)]
es_o) ->
forall a.
Int
-> Int
-> [(Int, a)]
-> [a]
-> Map a Int
-> Map a Int
-> [AdjacencyMap a]
-> [(Int, (a, a))]
-> [(a, a)]
-> StateSCC a
SCC Int
pre Int
scc [(Int, a)]
bnd [a]
pth Map a Int
pres Map a Int
sccs [AdjacencyMap a]
gs ((Int, (a, a))
uvforall a. a -> [a] -> [a]
:[(Int, (a, a))]
es_i) [(a, a)]
es_o)
outedge :: (a, a) -> StateT (StateSCC a) m ()
outedge (a, a)
uv = forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify'
(\(SCC Int
pre Int
scc [(Int, a)]
bnd [a]
pth Map a Int
pres Map a Int
sccs [AdjacencyMap a]
gs [(Int, (a, a))]
es_i [(a, a)]
es_o) ->
forall a.
Int
-> Int
-> [(Int, a)]
-> [a]
-> Map a Int
-> Map a Int
-> [AdjacencyMap a]
-> [(Int, (a, a))]
-> [(a, a)]
-> StateSCC a
SCC Int
pre Int
scc [(Int, a)]
bnd [a]
pth Map a Int
pres Map a Int
sccs [AdjacencyMap a]
gs [(Int, (a, a))]
es_i ((a, a)
uvforall a. a -> [a] -> [a]
:[(a, a)]
es_o))
hasPreorderId :: k -> StateT (StateSCC k) m Bool
hasPreorderId k
v = forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
gets (forall k a. Ord k => k -> Map k a -> Bool
Map.member k
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. StateSCC a -> Map a Int
preorders)
preorderId :: k -> StateT (StateSCC k) m (Maybe Int)
preorderId k
v = forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
gets (forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup k
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. StateSCC a -> Map a Int
preorders)
hasComponent :: k -> StateT (StateSCC k) m Bool
hasComponent k
v = forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
gets (forall k a. Ord k => k -> Map k a -> Bool
Map.member k
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. StateSCC a -> Map a Int
components)
condense :: Ord a => AdjacencyMap a -> StateSCC a -> AdjacencyMap (NonEmpty.AdjacencyMap a)
condense :: forall a.
Ord a =>
AdjacencyMap a -> StateSCC a -> AdjacencyMap (AdjacencyMap a)
condense AdjacencyMap a
g (SCC Int
_ Int
n [(Int, a)]
_ [a]
_ Map a Int
_ Map a Int
assignment [AdjacencyMap a]
inner [(Int, (a, a))]
_ [(a, a)]
outer)
| Int
n forall a. Eq a => a -> a -> Bool
== Int
1 = forall a. a -> AdjacencyMap a
vertex forall a b. (a -> b) -> a -> b
$ forall {a}. AdjacencyMap a -> AdjacencyMap a
convert AdjacencyMap a
g
| Bool
otherwise = forall a b.
(Ord a, Ord b) =>
(a -> b) -> AdjacencyMap a -> AdjacencyMap b
gmap (\Int
c -> Array Int (AdjacencyMap a)
inner' forall i e. Ix i => Array i e -> i -> e
Array.! (Int
nforall a. Num a => a -> a -> a
-Int
1forall a. Num a => a -> a -> a
-Int
c)) AdjacencyMap Int
outer'
where inner' :: Array Int (AdjacencyMap a)
inner' = forall i e. Ix i => (i, i) -> [e] -> Array i e
Array.listArray (Int
0,Int
nforall a. Num a => a -> a -> a
-Int
1) (forall {a}. AdjacencyMap a -> AdjacencyMap a
convert forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [AdjacencyMap a]
inner)
outer' :: AdjacencyMap Int
outer' = AdjacencyMap Int
es forall a.
Ord a =>
AdjacencyMap a -> AdjacencyMap a -> AdjacencyMap a
`overlay` AdjacencyMap Int
vs
vs :: AdjacencyMap Int
vs = forall a. Ord a => [a] -> AdjacencyMap a
vertices [Int
0..Int
nforall a. Num a => a -> a -> a
-Int
1]
es :: AdjacencyMap Int
es = forall a. Ord a => [(a, a)] -> AdjacencyMap a
edges [ (a -> Int
sccid a
x, a -> Int
sccid a
y) | (a
x,a
y) <- [(a, a)]
outer ]
sccid :: a -> Int
sccid a
v = Map a Int
assignment forall k a. Ord k => Map k a -> k -> a
Map.! a
v
convert :: AdjacencyMap a -> AdjacencyMap a
convert = forall a. HasCallStack => Maybe a -> a
fromJust forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. AdjacencyMap a -> Maybe (AdjacencyMap a)
NonEmpty.toNonEmpty
isDfsForestOf :: Ord a => Forest a -> AdjacencyMap a -> Bool
isDfsForestOf :: forall a. Ord a => Forest a -> AdjacencyMap a -> Bool
isDfsForestOf Forest a
f AdjacencyMap a
am = case Set a -> Forest a -> Maybe (Set a)
go forall a. Set a
Set.empty Forest a
f of
Just Set a
seen -> Set a
seen forall a. Eq a => a -> a -> Bool
== forall a. AdjacencyMap a -> Set a
vertexSet AdjacencyMap a
am
Maybe (Set a)
Nothing -> Bool
False
where
go :: Set a -> Forest a -> Maybe (Set a)
go Set a
seen [] = forall a. a -> Maybe a
Just Set a
seen
go Set a
seen (Tree a
t:Forest a
ts) = do
let root :: a
root = forall a. Tree a -> a
rootLabel Tree a
t
forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ a
root forall a. Ord a => a -> Set a -> Bool
`Set.notMember` Set a
seen
forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *). Foldable t => t Bool -> Bool
and [ forall a. Ord a => a -> a -> AdjacencyMap a -> Bool
hasEdge a
root (forall a. Tree a -> a
rootLabel Tree a
subTree) AdjacencyMap a
am | Tree a
subTree <- forall a. Tree a -> [Tree a]
subForest Tree a
t ]
Set a
newSeen <- Set a -> Forest a -> Maybe (Set a)
go (forall a. Ord a => a -> Set a -> Set a
Set.insert a
root Set a
seen) (forall a. Tree a -> [Tree a]
subForest Tree a
t)
forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ forall a. Ord a => a -> AdjacencyMap a -> Set a
postSet a
root AdjacencyMap a
am forall a. Ord a => Set a -> Set a -> Bool
`Set.isSubsetOf` Set a
newSeen
Set a -> Forest a -> Maybe (Set a)
go Set a
newSeen Forest a
ts
isTopSortOf :: Ord a => [a] -> AdjacencyMap a -> Bool
isTopSortOf :: forall a. Ord a => [a] -> AdjacencyMap a -> Bool
isTopSortOf [a]
xs AdjacencyMap a
m = Set a -> [a] -> Bool
go forall a. Set a
Set.empty [a]
xs
where
go :: Set a -> [a] -> Bool
go Set a
seen [] = Set a
seen forall a. Eq a => a -> a -> Bool
== forall k a. Map k a -> Set k
Map.keysSet (forall a. AdjacencyMap a -> Map a (Set a)
adjacencyMap AdjacencyMap a
m)
go Set a
seen (a
v:[a]
vs) = forall a. Ord a => a -> AdjacencyMap a -> Set a
postSet a
v AdjacencyMap a
m forall a. Ord a => Set a -> Set a -> Set a
`Set.intersection` Set a
newSeen forall a. Eq a => a -> a -> Bool
== forall a. Set a
Set.empty
Bool -> Bool -> Bool
&& Set a -> [a] -> Bool
go Set a
newSeen [a]
vs
where
newSeen :: Set a
newSeen = forall a. Ord a => a -> Set a -> Set a
Set.insert a
v Set a
seen