module Data.Graph.Inductive.Query.DFS (
CFun,
dfs, dfs', dff, dff',
dfsWith, dfsWith', dffWith, dffWith',
xdfsWith, xdfWith, xdffWith,
udfs, udfs', udff, udff',
udffWith, udffWith',
rdff, rdff', rdfs, rdfs',
rdffWith, rdffWith',
topsort, topsort', scc, reachable,
components, noComponents, isConnected, condensation
) where
import Data.Graph.Inductive.Basic
import Data.Graph.Inductive.Graph
import Data.Tree
import qualified Data.Map as Map
import Control.Monad (liftM2)
import Data.Tuple (swap)
fixNodes :: (Graph gr) => ([Node] -> gr a b -> c) -> gr a b -> c
fixNodes :: forall (gr :: * -> * -> *) a b c.
Graph gr =>
([Node] -> gr a b -> c) -> gr a b -> c
fixNodes [Node] -> gr a b -> c
f gr a b
g = [Node] -> gr a b -> c
f (forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> [Node]
nodes gr a b
g) gr a b
g
type CFun a b c = Context a b -> c
xdfsWith :: (Graph gr)
=> CFun a b [Node]
-> CFun a b c
-> [Node]
-> gr a b
-> [c]
xdfsWith :: forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b [Node] -> CFun a b c -> [Node] -> gr a b -> [c]
xdfsWith CFun a b [Node]
_ CFun a b c
_ [] gr a b
_ = []
xdfsWith CFun a b [Node]
_ CFun a b c
_ [Node]
_ gr a b
g | forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> Bool
isEmpty gr a b
g = []
xdfsWith CFun a b [Node]
d CFun a b c
f (Node
v:[Node]
vs) gr a b
g = case forall (gr :: * -> * -> *) a b.
Graph gr =>
Node -> gr a b -> Decomp gr a b
match Node
v gr a b
g of
(Just Context a b
c,gr a b
g') -> CFun a b c
f Context a b
cforall a. a -> [a] -> [a]
:forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b [Node] -> CFun a b c -> [Node] -> gr a b -> [c]
xdfsWith CFun a b [Node]
d CFun a b c
f (CFun a b [Node]
d Context a b
cforall a. [a] -> [a] -> [a]
++[Node]
vs) gr a b
g'
(MContext a b
Nothing,gr a b
g') -> forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b [Node] -> CFun a b c -> [Node] -> gr a b -> [c]
xdfsWith CFun a b [Node]
d CFun a b c
f [Node]
vs gr a b
g'
dfs :: (Graph gr) => [Node] -> gr a b -> [Node]
dfs :: forall (gr :: * -> * -> *) a b.
Graph gr =>
[Node] -> gr a b -> [Node]
dfs = forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> [Node] -> gr a b -> [c]
dfsWith forall a b. Context a b -> Node
node'
dfsWith :: (Graph gr) => CFun a b c -> [Node] -> gr a b -> [c]
dfsWith :: forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> [Node] -> gr a b -> [c]
dfsWith = forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b [Node] -> CFun a b c -> [Node] -> gr a b -> [c]
xdfsWith forall a b. Context a b -> [Node]
suc'
dfsWith' :: (Graph gr) => CFun a b c -> gr a b -> [c]
dfsWith' :: forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> gr a b -> [c]
dfsWith' CFun a b c
f = forall (gr :: * -> * -> *) a b c.
Graph gr =>
([Node] -> gr a b -> c) -> gr a b -> c
fixNodes (forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> [Node] -> gr a b -> [c]
dfsWith CFun a b c
f)
dfs' :: (Graph gr) => gr a b -> [Node]
dfs' :: forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> [Node]
dfs' = forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> gr a b -> [c]
dfsWith' forall a b. Context a b -> Node
node'
udfs :: (Graph gr) => [Node] -> gr a b -> [Node]
udfs :: forall (gr :: * -> * -> *) a b.
Graph gr =>
[Node] -> gr a b -> [Node]
udfs = forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b [Node] -> CFun a b c -> [Node] -> gr a b -> [c]
xdfsWith forall a b. Context a b -> [Node]
neighbors' forall a b. Context a b -> Node
node'
udfs' :: (Graph gr) => gr a b -> [Node]
udfs' :: forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> [Node]
udfs' = forall (gr :: * -> * -> *) a b c.
Graph gr =>
([Node] -> gr a b -> c) -> gr a b -> c
fixNodes forall (gr :: * -> * -> *) a b.
Graph gr =>
[Node] -> gr a b -> [Node]
udfs
rdfs :: (Graph gr) => [Node] -> gr a b -> [Node]
rdfs :: forall (gr :: * -> * -> *) a b.
Graph gr =>
[Node] -> gr a b -> [Node]
rdfs = forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b [Node] -> CFun a b c -> [Node] -> gr a b -> [c]
xdfsWith forall a b. Context a b -> [Node]
pre' forall a b. Context a b -> Node
node'
rdfs' :: (Graph gr) => gr a b -> [Node]
rdfs' :: forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> [Node]
rdfs' = forall (gr :: * -> * -> *) a b c.
Graph gr =>
([Node] -> gr a b -> c) -> gr a b -> c
fixNodes forall (gr :: * -> * -> *) a b.
Graph gr =>
[Node] -> gr a b -> [Node]
rdfs
xdfWith :: (Graph gr)
=> CFun a b [Node]
-> CFun a b c
-> [Node]
-> gr a b
-> ([Tree c],gr a b)
xdfWith :: forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b [Node]
-> CFun a b c -> [Node] -> gr a b -> ([Tree c], gr a b)
xdfWith CFun a b [Node]
_ CFun a b c
_ [] gr a b
g = ([],gr a b
g)
xdfWith CFun a b [Node]
_ CFun a b c
_ [Node]
_ gr a b
g | forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> Bool
isEmpty gr a b
g = ([],gr a b
g)
xdfWith CFun a b [Node]
d CFun a b c
f (Node
v:[Node]
vs) gr a b
g = case forall (gr :: * -> * -> *) a b.
Graph gr =>
Node -> gr a b -> Decomp gr a b
match Node
v gr a b
g of
(MContext a b
Nothing,gr a b
g1) -> forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b [Node]
-> CFun a b c -> [Node] -> gr a b -> ([Tree c], gr a b)
xdfWith CFun a b [Node]
d CFun a b c
f [Node]
vs gr a b
g1
(Just Context a b
c,gr a b
g1) -> (forall a. a -> [Tree a] -> Tree a
Node (CFun a b c
f Context a b
c) [Tree c]
tsforall a. a -> [a] -> [a]
:[Tree c]
ts',gr a b
g3)
where ([Tree c]
ts,gr a b
g2) = forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b [Node]
-> CFun a b c -> [Node] -> gr a b -> ([Tree c], gr a b)
xdfWith CFun a b [Node]
d CFun a b c
f (CFun a b [Node]
d Context a b
c) gr a b
g1
([Tree c]
ts',gr a b
g3) = forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b [Node]
-> CFun a b c -> [Node] -> gr a b -> ([Tree c], gr a b)
xdfWith CFun a b [Node]
d CFun a b c
f [Node]
vs gr a b
g2
xdffWith :: (Graph gr)
=> CFun a b [Node]
-> CFun a b c
-> [Node]
-> gr a b
-> [Tree c]
xdffWith :: forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b [Node] -> CFun a b c -> [Node] -> gr a b -> [Tree c]
xdffWith CFun a b [Node]
d CFun a b c
f [Node]
vs gr a b
g = forall a b. (a, b) -> a
fst (forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b [Node]
-> CFun a b c -> [Node] -> gr a b -> ([Tree c], gr a b)
xdfWith CFun a b [Node]
d CFun a b c
f [Node]
vs gr a b
g)
dff :: (Graph gr) => [Node] -> gr a b -> [Tree Node]
dff :: forall (gr :: * -> * -> *) a b.
Graph gr =>
[Node] -> gr a b -> [Tree Node]
dff = forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> [Node] -> gr a b -> [Tree c]
dffWith forall a b. Context a b -> Node
node'
dffWith :: (Graph gr) => CFun a b c -> [Node] -> gr a b -> [Tree c]
dffWith :: forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> [Node] -> gr a b -> [Tree c]
dffWith = forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b [Node] -> CFun a b c -> [Node] -> gr a b -> [Tree c]
xdffWith forall a b. Context a b -> [Node]
suc'
dffWith' :: (Graph gr) => CFun a b c -> gr a b -> [Tree c]
dffWith' :: forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> gr a b -> [Tree c]
dffWith' CFun a b c
f = forall (gr :: * -> * -> *) a b c.
Graph gr =>
([Node] -> gr a b -> c) -> gr a b -> c
fixNodes (forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> [Node] -> gr a b -> [Tree c]
dffWith CFun a b c
f)
dff' :: (Graph gr) => gr a b -> [Tree Node]
dff' :: forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> [Tree Node]
dff' = forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> gr a b -> [Tree c]
dffWith' forall a b. Context a b -> Node
node'
udff :: (Graph gr) => [Node] -> gr a b -> [Tree Node]
udff :: forall (gr :: * -> * -> *) a b.
Graph gr =>
[Node] -> gr a b -> [Tree Node]
udff = forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> [Node] -> gr a b -> [Tree c]
udffWith forall a b. Context a b -> Node
node'
udffWith :: (Graph gr) => CFun a b c -> [Node] -> gr a b -> [Tree c]
udffWith :: forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> [Node] -> gr a b -> [Tree c]
udffWith = forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b [Node] -> CFun a b c -> [Node] -> gr a b -> [Tree c]
xdffWith forall a b. Context a b -> [Node]
neighbors'
udffWith' :: (Graph gr) => CFun a b c -> gr a b -> [Tree c]
udffWith' :: forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> gr a b -> [Tree c]
udffWith' CFun a b c
f = forall (gr :: * -> * -> *) a b c.
Graph gr =>
([Node] -> gr a b -> c) -> gr a b -> c
fixNodes (forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> [Node] -> gr a b -> [Tree c]
udffWith CFun a b c
f)
udff' :: (Graph gr) => gr a b -> [Tree Node]
udff' :: forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> [Tree Node]
udff' = forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> gr a b -> [Tree c]
udffWith' forall a b. Context a b -> Node
node'
rdff :: (Graph gr) => [Node] -> gr a b -> [Tree Node]
rdff :: forall (gr :: * -> * -> *) a b.
Graph gr =>
[Node] -> gr a b -> [Tree Node]
rdff = forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> [Node] -> gr a b -> [Tree c]
rdffWith forall a b. Context a b -> Node
node'
rdffWith :: (Graph gr) => CFun a b c -> [Node] -> gr a b -> [Tree c]
rdffWith :: forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> [Node] -> gr a b -> [Tree c]
rdffWith = forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b [Node] -> CFun a b c -> [Node] -> gr a b -> [Tree c]
xdffWith forall a b. Context a b -> [Node]
pre'
rdffWith' :: (Graph gr) => CFun a b c -> gr a b -> [Tree c]
rdffWith' :: forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> gr a b -> [Tree c]
rdffWith' CFun a b c
f = forall (gr :: * -> * -> *) a b c.
Graph gr =>
([Node] -> gr a b -> c) -> gr a b -> c
fixNodes (forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> [Node] -> gr a b -> [Tree c]
rdffWith CFun a b c
f)
rdff' :: (Graph gr) => gr a b -> [Tree Node]
rdff' :: forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> [Tree Node]
rdff' = forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> gr a b -> [Tree c]
rdffWith' forall a b. Context a b -> Node
node'
components :: (Graph gr) => gr a b -> [[Node]]
components :: forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> [[Node]]
components = forall a b. (a -> b) -> [a] -> [b]
map forall a. Tree a -> [a]
preorder forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> [Tree Node]
udff'
noComponents :: (Graph gr) => gr a b -> Int
noComponents :: forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> Node
noComponents = forall (t :: * -> *) a. Foldable t => t a -> Node
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> [[Node]]
components
isConnected :: (Graph gr) => gr a b -> Bool
isConnected :: forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> Bool
isConnected = (forall a. Eq a => a -> a -> Bool
==Node
1) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> Node
noComponents
postflatten :: Tree a -> [a]
postflatten :: forall a. Tree a -> [a]
postflatten (Node a
v [Tree a]
ts) = forall a. [Tree a] -> [a]
postflattenF [Tree a]
ts forall a. [a] -> [a] -> [a]
++ [a
v]
postflattenF :: [Tree a] -> [a]
postflattenF :: forall a. [Tree a] -> [a]
postflattenF = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap forall a. Tree a -> [a]
postflatten
topsort :: (Graph gr) => gr a b -> [Node]
topsort :: forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> [Node]
topsort = forall a. [a] -> [a]
reverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [Tree a] -> [a]
postflattenF forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> [Tree Node]
dff'
topsort' :: (Graph gr) => gr a b -> [a]
topsort' :: forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> [a]
topsort' = forall a. [a] -> [a]
reverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [Tree a] -> [a]
postorderF forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (gr :: * -> * -> *) a b c.
Graph gr =>
CFun a b c -> gr a b -> [Tree c]
dffWith' forall a b. Context a b -> a
lab'
scc :: (Graph gr) => gr a b -> [[Node]]
scc :: forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> [[Node]]
scc gr a b
g = forall a b. (a -> b) -> [a] -> [b]
map forall a. Tree a -> [a]
preorder (forall (gr :: * -> * -> *) a b.
Graph gr =>
[Node] -> gr a b -> [Tree Node]
rdff (forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> [Node]
topsort gr a b
g) gr a b
g)
reachable :: (Graph gr) => Node -> gr a b -> [Node]
reachable :: forall (gr :: * -> * -> *) a b.
Graph gr =>
Node -> gr a b -> [Node]
reachable Node
v gr a b
g = forall a. [Tree a] -> [a]
preorderF (forall (gr :: * -> * -> *) a b.
Graph gr =>
[Node] -> gr a b -> [Tree Node]
dff [Node
v] gr a b
g)
condensation :: Graph gr => gr a b -> gr [Node] ()
condensation :: forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> gr [Node] ()
condensation gr a b
gr = forall (gr :: * -> * -> *) a b.
Graph gr =>
[LNode a] -> [LEdge b] -> gr a b
mkGraph [(Node, [Node])]
vs [(Node, Node, ())]
es
where
sccs :: [[Node]]
sccs = forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> [[Node]]
scc gr a b
gr
vs :: [(Node, [Node])]
vs = forall a b. [a] -> [b] -> [(a, b)]
zip [Node
1..] [[Node]]
sccs
vMap :: Map [Node] Node
vMap = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> (b, a)
swap [(Node, [Node])]
vs
getN :: [Node] -> Node
getN = (Map [Node] Node
vMap forall k a. Ord k => Map k a -> k -> a
Map.!)
es :: [(Node, Node, ())]
es = [ ([Node] -> Node
getN [Node]
c1, [Node] -> Node
getN [Node]
c2, ()) | [Node]
c1 <- [[Node]]
sccs, [Node]
c2 <- [[Node]]
sccs
, ([Node]
c1 forall a. Eq a => a -> a -> Bool
/= [Node]
c2) Bool -> Bool -> Bool
&& forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> Edge -> Bool
hasEdge gr a b
gr) (forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) [Node]
c1 [Node]
c2) ]