module Algebra.Graph.AdjacencyIntMap (
AdjacencyIntMap, adjacencyIntMap, fromAdjacencyMap,
empty, vertex, edge, overlay, connect, vertices, edges, overlays, connects,
isSubgraphOf,
isEmpty, hasVertex, hasEdge, vertexCount, edgeCount, vertexList, edgeList,
adjacencyList, vertexIntSet, edgeSet, preIntSet, postIntSet,
path, circuit, clique, biclique, star, stars, fromAdjacencyIntSets, tree,
forest,
removeVertex, removeEdge, replaceVertex, mergeVertices, transpose, gmap,
induce,
compose, closure, reflexiveClosure, symmetricClosure, transitiveClosure,
consistent
) where
import Control.DeepSeq
import Data.IntMap.Strict (IntMap)
import Data.IntSet (IntSet)
import Data.List ((\\))
import Data.Monoid (Sum (..))
import Data.Set (Set)
import Data.Tree
import GHC.Generics
import qualified Data.IntMap.Strict as IntMap
import qualified Data.IntSet as IntSet
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import qualified Algebra.Graph.AdjacencyMap as AM
newtype AdjacencyIntMap = AM {
AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap :: IntMap IntSet } deriving (AdjacencyIntMap -> AdjacencyIntMap -> Bool
(AdjacencyIntMap -> AdjacencyIntMap -> Bool)
-> (AdjacencyIntMap -> AdjacencyIntMap -> Bool)
-> Eq AdjacencyIntMap
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AdjacencyIntMap -> AdjacencyIntMap -> Bool
$c/= :: AdjacencyIntMap -> AdjacencyIntMap -> Bool
== :: AdjacencyIntMap -> AdjacencyIntMap -> Bool
$c== :: AdjacencyIntMap -> AdjacencyIntMap -> Bool
Eq, (forall x. AdjacencyIntMap -> Rep AdjacencyIntMap x)
-> (forall x. Rep AdjacencyIntMap x -> AdjacencyIntMap)
-> Generic AdjacencyIntMap
forall x. Rep AdjacencyIntMap x -> AdjacencyIntMap
forall x. AdjacencyIntMap -> Rep AdjacencyIntMap x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep AdjacencyIntMap x -> AdjacencyIntMap
$cfrom :: forall x. AdjacencyIntMap -> Rep AdjacencyIntMap x
Generic)
instance Show AdjacencyIntMap where
showsPrec :: Int -> AdjacencyIntMap -> ShowS
showsPrec Int
p am :: AdjacencyIntMap
am@(AM IntMap IntSet
m)
| [Int] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Int]
vs = String -> ShowS
showString String
"empty"
| [(Int, Int)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Int, Int)]
es = Bool -> ShowS -> ShowS
showParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ [Int] -> ShowS
forall a. Show a => [a] -> ShowS
vshow [Int]
vs
| [Int]
vs [Int] -> [Int] -> Bool
forall a. Eq a => a -> a -> Bool
== [Int]
used = Bool -> ShowS -> ShowS
showParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ [(Int, Int)] -> ShowS
forall a a. (Show a, Show a) => [(a, a)] -> ShowS
eshow [(Int, Int)]
es
| Bool
otherwise = Bool -> ShowS -> ShowS
showParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
String -> ShowS
showString String
"overlay (" ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> ShowS
forall a. Show a => [a] -> ShowS
vshow ([Int]
vs [Int] -> [Int] -> [Int]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Int]
used) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
String -> ShowS
showString String
") (" ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Int, Int)] -> ShowS
forall a a. (Show a, Show a) => [(a, a)] -> ShowS
eshow [(Int, Int)]
es ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
")"
where
vs :: [Int]
vs = AdjacencyIntMap -> [Int]
vertexList AdjacencyIntMap
am
es :: [(Int, Int)]
es = AdjacencyIntMap -> [(Int, Int)]
edgeList AdjacencyIntMap
am
vshow :: [a] -> ShowS
vshow [a
x] = String -> ShowS
showString String
"vertex " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 a
x
vshow [a]
xs = String -> ShowS
showString String
"vertices " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [a] -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 [a]
xs
eshow :: [(a, a)] -> ShowS
eshow [(a
x, a
y)] = String -> ShowS
showString String
"edge " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 a
x ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
String -> ShowS
showString String
" " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 a
y
eshow [(a, a)]
xs = String -> ShowS
showString String
"edges " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [(a, a)] -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 [(a, a)]
xs
used :: [Int]
used = IntSet -> [Int]
IntSet.toAscList (IntMap IntSet -> IntSet
referredToVertexSet IntMap IntSet
m)
instance Ord AdjacencyIntMap where
compare :: AdjacencyIntMap -> AdjacencyIntMap -> Ordering
compare AdjacencyIntMap
x AdjacencyIntMap
y = [Ordering] -> Ordering
forall a. Monoid a => [a] -> a
mconcat
[ Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (AdjacencyIntMap -> Int
vertexCount AdjacencyIntMap
x) (AdjacencyIntMap -> Int
vertexCount AdjacencyIntMap
y)
, IntSet -> IntSet -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (AdjacencyIntMap -> IntSet
vertexIntSet AdjacencyIntMap
x) (AdjacencyIntMap -> IntSet
vertexIntSet AdjacencyIntMap
y)
, Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (AdjacencyIntMap -> Int
edgeCount AdjacencyIntMap
x) (AdjacencyIntMap -> Int
edgeCount AdjacencyIntMap
y)
, Set (Int, Int) -> Set (Int, Int) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (AdjacencyIntMap -> Set (Int, Int)
edgeSet AdjacencyIntMap
x) (AdjacencyIntMap -> Set (Int, Int)
edgeSet AdjacencyIntMap
y) ]
instance Num AdjacencyIntMap where
fromInteger :: Integer -> AdjacencyIntMap
fromInteger = Int -> AdjacencyIntMap
vertex (Int -> AdjacencyIntMap)
-> (Integer -> Int) -> Integer -> AdjacencyIntMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Int
forall a. Num a => Integer -> a
fromInteger
+ :: AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
(+) = AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
overlay
* :: AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
(*) = AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
connect
signum :: AdjacencyIntMap -> AdjacencyIntMap
signum = AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
forall a b. a -> b -> a
const AdjacencyIntMap
empty
abs :: AdjacencyIntMap -> AdjacencyIntMap
abs = AdjacencyIntMap -> AdjacencyIntMap
forall a. a -> a
id
negate :: AdjacencyIntMap -> AdjacencyIntMap
negate = AdjacencyIntMap -> AdjacencyIntMap
forall a. a -> a
id
instance NFData AdjacencyIntMap where
rnf :: AdjacencyIntMap -> ()
rnf (AM IntMap IntSet
a) = IntMap IntSet -> ()
forall a. NFData a => a -> ()
rnf IntMap IntSet
a
instance Semigroup AdjacencyIntMap where
<> :: AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
(<>) = AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
overlay
instance Monoid AdjacencyIntMap where
mempty :: AdjacencyIntMap
mempty = AdjacencyIntMap
empty
fromAdjacencyMap :: AM.AdjacencyMap Int -> AdjacencyIntMap
fromAdjacencyMap :: AdjacencyMap Int -> AdjacencyIntMap
fromAdjacencyMap = IntMap IntSet -> AdjacencyIntMap
AM
(IntMap IntSet -> AdjacencyIntMap)
-> (AdjacencyMap Int -> IntMap IntSet)
-> AdjacencyMap Int
-> AdjacencyIntMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Int, IntSet)] -> IntMap IntSet
forall a. [(Int, a)] -> IntMap a
IntMap.fromAscList
([(Int, IntSet)] -> IntMap IntSet)
-> (AdjacencyMap Int -> [(Int, IntSet)])
-> AdjacencyMap Int
-> IntMap IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, Set Int) -> (Int, IntSet))
-> [(Int, Set Int)] -> [(Int, IntSet)]
forall a b. (a -> b) -> [a] -> [b]
map ((Set Int -> IntSet) -> (Int, Set Int) -> (Int, IntSet)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Set Int -> IntSet) -> (Int, Set Int) -> (Int, IntSet))
-> (Set Int -> IntSet) -> (Int, Set Int) -> (Int, IntSet)
forall a b. (a -> b) -> a -> b
$ [Int] -> IntSet
IntSet.fromAscList ([Int] -> IntSet) -> (Set Int -> [Int]) -> Set Int -> IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set Int -> [Int]
forall a. Set a -> [a]
Set.toAscList)
([(Int, Set Int)] -> [(Int, IntSet)])
-> (AdjacencyMap Int -> [(Int, Set Int)])
-> AdjacencyMap Int
-> [(Int, IntSet)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map Int (Set Int) -> [(Int, Set Int)]
forall k a. Map k a -> [(k, a)]
Map.toAscList
(Map Int (Set Int) -> [(Int, Set Int)])
-> (AdjacencyMap Int -> Map Int (Set Int))
-> AdjacencyMap Int
-> [(Int, Set Int)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyMap Int -> Map Int (Set Int)
forall a. AdjacencyMap a -> Map a (Set a)
AM.adjacencyMap
empty :: AdjacencyIntMap
empty :: AdjacencyIntMap
empty = IntMap IntSet -> AdjacencyIntMap
AM IntMap IntSet
forall a. IntMap a
IntMap.empty
{-# NOINLINE [1] empty #-}
vertex :: Int -> AdjacencyIntMap
vertex :: Int -> AdjacencyIntMap
vertex Int
x = IntMap IntSet -> AdjacencyIntMap
AM (IntMap IntSet -> AdjacencyIntMap)
-> IntMap IntSet -> AdjacencyIntMap
forall a b. (a -> b) -> a -> b
$ Int -> IntSet -> IntMap IntSet
forall a. Int -> a -> IntMap a
IntMap.singleton Int
x IntSet
IntSet.empty
{-# NOINLINE [1] vertex #-}
edge :: Int -> Int -> AdjacencyIntMap
edge :: Int -> Int -> AdjacencyIntMap
edge Int
x Int
y | Int
x Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
y = IntMap IntSet -> AdjacencyIntMap
AM (IntMap IntSet -> AdjacencyIntMap)
-> IntMap IntSet -> AdjacencyIntMap
forall a b. (a -> b) -> a -> b
$ Int -> IntSet -> IntMap IntSet
forall a. Int -> a -> IntMap a
IntMap.singleton Int
x (Int -> IntSet
IntSet.singleton Int
y)
| Bool
otherwise = IntMap IntSet -> AdjacencyIntMap
AM (IntMap IntSet -> AdjacencyIntMap)
-> IntMap IntSet -> AdjacencyIntMap
forall a b. (a -> b) -> a -> b
$ [(Int, IntSet)] -> IntMap IntSet
forall a. [(Int, a)] -> IntMap a
IntMap.fromList [(Int
x, Int -> IntSet
IntSet.singleton Int
y), (Int
y, IntSet
IntSet.empty)]
overlay :: AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
overlay :: AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
overlay (AM IntMap IntSet
x) (AM IntMap IntSet
y) = IntMap IntSet -> AdjacencyIntMap
AM (IntMap IntSet -> AdjacencyIntMap)
-> IntMap IntSet -> AdjacencyIntMap
forall a b. (a -> b) -> a -> b
$ (IntSet -> IntSet -> IntSet)
-> IntMap IntSet -> IntMap IntSet -> IntMap IntSet
forall a. (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
IntMap.unionWith IntSet -> IntSet -> IntSet
IntSet.union IntMap IntSet
x IntMap IntSet
y
{-# NOINLINE [1] overlay #-}
connect :: AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
connect :: AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
connect (AM IntMap IntSet
x) (AM IntMap IntSet
y) = IntMap IntSet -> AdjacencyIntMap
AM (IntMap IntSet -> AdjacencyIntMap)
-> IntMap IntSet -> AdjacencyIntMap
forall a b. (a -> b) -> a -> b
$ (IntSet -> IntSet -> IntSet) -> [IntMap IntSet] -> IntMap IntSet
forall (f :: * -> *) a.
Foldable f =>
(a -> a -> a) -> f (IntMap a) -> IntMap a
IntMap.unionsWith IntSet -> IntSet -> IntSet
IntSet.union
[ IntMap IntSet
x, IntMap IntSet
y, (Int -> IntSet) -> IntSet -> IntMap IntSet
forall a. (Int -> a) -> IntSet -> IntMap a
IntMap.fromSet (IntSet -> Int -> IntSet
forall a b. a -> b -> a
const (IntSet -> Int -> IntSet) -> IntSet -> Int -> IntSet
forall a b. (a -> b) -> a -> b
$ IntMap IntSet -> IntSet
forall a. IntMap a -> IntSet
IntMap.keysSet IntMap IntSet
y) (IntMap IntSet -> IntSet
forall a. IntMap a -> IntSet
IntMap.keysSet IntMap IntSet
x) ]
{-# NOINLINE [1] connect #-}
vertices :: [Int] -> AdjacencyIntMap
vertices :: [Int] -> AdjacencyIntMap
vertices = IntMap IntSet -> AdjacencyIntMap
AM (IntMap IntSet -> AdjacencyIntMap)
-> ([Int] -> IntMap IntSet) -> [Int] -> AdjacencyIntMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Int, IntSet)] -> IntMap IntSet
forall a. [(Int, a)] -> IntMap a
IntMap.fromList ([(Int, IntSet)] -> IntMap IntSet)
-> ([Int] -> [(Int, IntSet)]) -> [Int] -> IntMap IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> (Int, IntSet)) -> [Int] -> [(Int, IntSet)]
forall a b. (a -> b) -> [a] -> [b]
map (, IntSet
IntSet.empty)
{-# NOINLINE [1] vertices #-}
edges :: [(Int, Int)] -> AdjacencyIntMap
edges :: [(Int, Int)] -> AdjacencyIntMap
edges = [(Int, IntSet)] -> AdjacencyIntMap
fromAdjacencyIntSets ([(Int, IntSet)] -> AdjacencyIntMap)
-> ([(Int, Int)] -> [(Int, IntSet)])
-> [(Int, Int)]
-> AdjacencyIntMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, Int) -> (Int, IntSet)) -> [(Int, Int)] -> [(Int, IntSet)]
forall a b. (a -> b) -> [a] -> [b]
map ((Int -> IntSet) -> (Int, Int) -> (Int, IntSet)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> IntSet
IntSet.singleton)
overlays :: [AdjacencyIntMap] -> AdjacencyIntMap
overlays :: [AdjacencyIntMap] -> AdjacencyIntMap
overlays = IntMap IntSet -> AdjacencyIntMap
AM (IntMap IntSet -> AdjacencyIntMap)
-> ([AdjacencyIntMap] -> IntMap IntSet)
-> [AdjacencyIntMap]
-> AdjacencyIntMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IntSet -> IntSet -> IntSet) -> [IntMap IntSet] -> IntMap IntSet
forall (f :: * -> *) a.
Foldable f =>
(a -> a -> a) -> f (IntMap a) -> IntMap a
IntMap.unionsWith IntSet -> IntSet -> IntSet
IntSet.union ([IntMap IntSet] -> IntMap IntSet)
-> ([AdjacencyIntMap] -> [IntMap IntSet])
-> [AdjacencyIntMap]
-> IntMap IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (AdjacencyIntMap -> IntMap IntSet)
-> [AdjacencyIntMap] -> [IntMap IntSet]
forall a b. (a -> b) -> [a] -> [b]
map AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap
{-# NOINLINE [1] overlays #-}
connects :: [AdjacencyIntMap] -> AdjacencyIntMap
connects :: [AdjacencyIntMap] -> AdjacencyIntMap
connects = (AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap)
-> AdjacencyIntMap -> [AdjacencyIntMap] -> AdjacencyIntMap
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
connect AdjacencyIntMap
empty
{-# NOINLINE [1] connects #-}
isSubgraphOf :: AdjacencyIntMap -> AdjacencyIntMap -> Bool
isSubgraphOf :: AdjacencyIntMap -> AdjacencyIntMap -> Bool
isSubgraphOf (AM IntMap IntSet
x) (AM IntMap IntSet
y) = (IntSet -> IntSet -> Bool)
-> IntMap IntSet -> IntMap IntSet -> Bool
forall a b. (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool
IntMap.isSubmapOfBy IntSet -> IntSet -> Bool
IntSet.isSubsetOf IntMap IntSet
x IntMap IntSet
y
isEmpty :: AdjacencyIntMap -> Bool
isEmpty :: AdjacencyIntMap -> Bool
isEmpty = IntMap IntSet -> Bool
forall a. IntMap a -> Bool
IntMap.null (IntMap IntSet -> Bool)
-> (AdjacencyIntMap -> IntMap IntSet) -> AdjacencyIntMap -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap
hasVertex :: Int -> AdjacencyIntMap -> Bool
hasVertex :: Int -> AdjacencyIntMap -> Bool
hasVertex Int
x = Int -> IntMap IntSet -> Bool
forall a. Int -> IntMap a -> Bool
IntMap.member Int
x (IntMap IntSet -> Bool)
-> (AdjacencyIntMap -> IntMap IntSet) -> AdjacencyIntMap -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap
hasEdge :: Int -> Int -> AdjacencyIntMap -> Bool
hasEdge :: Int -> Int -> AdjacencyIntMap -> Bool
hasEdge Int
u Int
v (AM IntMap IntSet
m) = case Int -> IntMap IntSet -> Maybe IntSet
forall a. Int -> IntMap a -> Maybe a
IntMap.lookup Int
u IntMap IntSet
m of
Maybe IntSet
Nothing -> Bool
False
Just IntSet
vs -> Int -> IntSet -> Bool
IntSet.member Int
v IntSet
vs
vertexCount :: AdjacencyIntMap -> Int
vertexCount :: AdjacencyIntMap -> Int
vertexCount = IntMap IntSet -> Int
forall a. IntMap a -> Int
IntMap.size (IntMap IntSet -> Int)
-> (AdjacencyIntMap -> IntMap IntSet) -> AdjacencyIntMap -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap
edgeCount :: AdjacencyIntMap -> Int
edgeCount :: AdjacencyIntMap -> Int
edgeCount = Sum Int -> Int
forall a. Sum a -> a
getSum (Sum Int -> Int)
-> (AdjacencyIntMap -> Sum Int) -> AdjacencyIntMap -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IntSet -> Sum Int) -> IntMap IntSet -> Sum Int
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (Int -> Sum Int
forall a. a -> Sum a
Sum (Int -> Sum Int) -> (IntSet -> Int) -> IntSet -> Sum Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntSet -> Int
IntSet.size) (IntMap IntSet -> Sum Int)
-> (AdjacencyIntMap -> IntMap IntSet) -> AdjacencyIntMap -> Sum Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap
vertexList :: AdjacencyIntMap -> [Int]
vertexList :: AdjacencyIntMap -> [Int]
vertexList = IntMap IntSet -> [Int]
forall a. IntMap a -> [Int]
IntMap.keys (IntMap IntSet -> [Int])
-> (AdjacencyIntMap -> IntMap IntSet) -> AdjacencyIntMap -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap
edgeList :: AdjacencyIntMap -> [(Int, Int)]
edgeList :: AdjacencyIntMap -> [(Int, Int)]
edgeList (AM IntMap IntSet
m) = [ (Int
x, Int
y) | (Int
x, IntSet
ys) <- IntMap IntSet -> [(Int, IntSet)]
forall a. IntMap a -> [(Int, a)]
IntMap.toAscList IntMap IntSet
m, Int
y <- IntSet -> [Int]
IntSet.toAscList IntSet
ys ]
{-# INLINE edgeList #-}
vertexIntSet :: AdjacencyIntMap -> IntSet
vertexIntSet :: AdjacencyIntMap -> IntSet
vertexIntSet = IntMap IntSet -> IntSet
forall a. IntMap a -> IntSet
IntMap.keysSet (IntMap IntSet -> IntSet)
-> (AdjacencyIntMap -> IntMap IntSet) -> AdjacencyIntMap -> IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap
edgeSet :: AdjacencyIntMap -> Set (Int, Int)
edgeSet :: AdjacencyIntMap -> Set (Int, Int)
edgeSet = [(Int, Int)] -> Set (Int, Int)
forall a. Eq a => [a] -> Set a
Set.fromAscList ([(Int, Int)] -> Set (Int, Int))
-> (AdjacencyIntMap -> [(Int, Int)])
-> AdjacencyIntMap
-> Set (Int, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> [(Int, Int)]
edgeList
adjacencyList :: AdjacencyIntMap -> [(Int, [Int])]
adjacencyList :: AdjacencyIntMap -> [(Int, [Int])]
adjacencyList = ((Int, IntSet) -> (Int, [Int]))
-> [(Int, IntSet)] -> [(Int, [Int])]
forall a b. (a -> b) -> [a] -> [b]
map ((IntSet -> [Int]) -> (Int, IntSet) -> (Int, [Int])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap IntSet -> [Int]
IntSet.toAscList) ([(Int, IntSet)] -> [(Int, [Int])])
-> (AdjacencyIntMap -> [(Int, IntSet)])
-> AdjacencyIntMap
-> [(Int, [Int])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntMap IntSet -> [(Int, IntSet)]
forall a. IntMap a -> [(Int, a)]
IntMap.toAscList (IntMap IntSet -> [(Int, IntSet)])
-> (AdjacencyIntMap -> IntMap IntSet)
-> AdjacencyIntMap
-> [(Int, IntSet)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap
preIntSet :: Int -> AdjacencyIntMap -> IntSet.IntSet
preIntSet :: Int -> AdjacencyIntMap -> IntSet
preIntSet Int
x = [Int] -> IntSet
IntSet.fromAscList ([Int] -> IntSet)
-> (AdjacencyIntMap -> [Int]) -> AdjacencyIntMap -> IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, IntSet) -> Int) -> [(Int, IntSet)] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (Int, IntSet) -> Int
forall a b. (a, b) -> a
fst ([(Int, IntSet)] -> [Int])
-> (AdjacencyIntMap -> [(Int, IntSet)]) -> AdjacencyIntMap -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, IntSet) -> Bool) -> [(Int, IntSet)] -> [(Int, IntSet)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Int, IntSet) -> Bool
p ([(Int, IntSet)] -> [(Int, IntSet)])
-> (AdjacencyIntMap -> [(Int, IntSet)])
-> AdjacencyIntMap
-> [(Int, IntSet)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntMap IntSet -> [(Int, IntSet)]
forall a. IntMap a -> [(Int, a)]
IntMap.toAscList (IntMap IntSet -> [(Int, IntSet)])
-> (AdjacencyIntMap -> IntMap IntSet)
-> AdjacencyIntMap
-> [(Int, IntSet)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap
where
p :: (Int, IntSet) -> Bool
p (Int
_, IntSet
set) = Int
x Int -> IntSet -> Bool
`IntSet.member` IntSet
set
postIntSet :: Int -> AdjacencyIntMap -> IntSet
postIntSet :: Int -> AdjacencyIntMap -> IntSet
postIntSet Int
x = IntSet -> Int -> IntMap IntSet -> IntSet
forall a. a -> Int -> IntMap a -> a
IntMap.findWithDefault IntSet
IntSet.empty Int
x (IntMap IntSet -> IntSet)
-> (AdjacencyIntMap -> IntMap IntSet) -> AdjacencyIntMap -> IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap
path :: [Int] -> AdjacencyIntMap
path :: [Int] -> AdjacencyIntMap
path [Int]
xs = case [Int]
xs of [] -> AdjacencyIntMap
empty
[Int
x] -> Int -> AdjacencyIntMap
vertex Int
x
(Int
_:[Int]
ys) -> [(Int, Int)] -> AdjacencyIntMap
edges ([Int] -> [Int] -> [(Int, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int]
xs [Int]
ys)
circuit :: [Int] -> AdjacencyIntMap
circuit :: [Int] -> AdjacencyIntMap
circuit [] = AdjacencyIntMap
empty
circuit (Int
x:[Int]
xs) = [Int] -> AdjacencyIntMap
path ([Int] -> AdjacencyIntMap) -> [Int] -> AdjacencyIntMap
forall a b. (a -> b) -> a -> b
$ [Int
x] [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ [Int]
xs [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ [Int
x]
clique :: [Int] -> AdjacencyIntMap
clique :: [Int] -> AdjacencyIntMap
clique = [(Int, IntSet)] -> AdjacencyIntMap
fromAdjacencyIntSets ([(Int, IntSet)] -> AdjacencyIntMap)
-> ([Int] -> [(Int, IntSet)]) -> [Int] -> AdjacencyIntMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([(Int, IntSet)], IntSet) -> [(Int, IntSet)]
forall a b. (a, b) -> a
fst (([(Int, IntSet)], IntSet) -> [(Int, IntSet)])
-> ([Int] -> ([(Int, IntSet)], IntSet)) -> [Int] -> [(Int, IntSet)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> ([(Int, IntSet)], IntSet)
go
where
go :: [Int] -> ([(Int, IntSet)], IntSet)
go [] = ([], IntSet
IntSet.empty)
go (Int
x:[Int]
xs) = let ([(Int, IntSet)]
res, IntSet
set) = [Int] -> ([(Int, IntSet)], IntSet)
go [Int]
xs in ((Int
x, IntSet
set) (Int, IntSet) -> [(Int, IntSet)] -> [(Int, IntSet)]
forall a. a -> [a] -> [a]
: [(Int, IntSet)]
res, Int -> IntSet -> IntSet
IntSet.insert Int
x IntSet
set)
{-# NOINLINE [1] clique #-}
biclique :: [Int] -> [Int] -> AdjacencyIntMap
biclique :: [Int] -> [Int] -> AdjacencyIntMap
biclique [Int]
xs [Int]
ys = IntMap IntSet -> AdjacencyIntMap
AM (IntMap IntSet -> AdjacencyIntMap)
-> IntMap IntSet -> AdjacencyIntMap
forall a b. (a -> b) -> a -> b
$ (Int -> IntSet) -> IntSet -> IntMap IntSet
forall a. (Int -> a) -> IntSet -> IntMap a
IntMap.fromSet Int -> IntSet
adjacent (IntSet
x IntSet -> IntSet -> IntSet
`IntSet.union` IntSet
y)
where
x :: IntSet
x = [Int] -> IntSet
IntSet.fromList [Int]
xs
y :: IntSet
y = [Int] -> IntSet
IntSet.fromList [Int]
ys
adjacent :: Int -> IntSet
adjacent Int
v = if Int
v Int -> IntSet -> Bool
`IntSet.member` IntSet
x then IntSet
y else IntSet
IntSet.empty
star :: Int -> [Int] -> AdjacencyIntMap
star :: Int -> [Int] -> AdjacencyIntMap
star Int
x [] = Int -> AdjacencyIntMap
vertex Int
x
star Int
x [Int]
ys = AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
connect (Int -> AdjacencyIntMap
vertex Int
x) ([Int] -> AdjacencyIntMap
vertices [Int]
ys)
{-# INLINE star #-}
stars :: [(Int, [Int])] -> AdjacencyIntMap
stars :: [(Int, [Int])] -> AdjacencyIntMap
stars = [(Int, IntSet)] -> AdjacencyIntMap
fromAdjacencyIntSets ([(Int, IntSet)] -> AdjacencyIntMap)
-> ([(Int, [Int])] -> [(Int, IntSet)])
-> [(Int, [Int])]
-> AdjacencyIntMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, [Int]) -> (Int, IntSet))
-> [(Int, [Int])] -> [(Int, IntSet)]
forall a b. (a -> b) -> [a] -> [b]
map (([Int] -> IntSet) -> (Int, [Int]) -> (Int, IntSet)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Int] -> IntSet
IntSet.fromList)
fromAdjacencyIntSets :: [(Int, IntSet)] -> AdjacencyIntMap
fromAdjacencyIntSets :: [(Int, IntSet)] -> AdjacencyIntMap
fromAdjacencyIntSets [(Int, IntSet)]
ss = IntMap IntSet -> AdjacencyIntMap
AM (IntMap IntSet -> AdjacencyIntMap)
-> IntMap IntSet -> AdjacencyIntMap
forall a b. (a -> b) -> a -> b
$ (IntSet -> IntSet -> IntSet)
-> IntMap IntSet -> IntMap IntSet -> IntMap IntSet
forall a. (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
IntMap.unionWith IntSet -> IntSet -> IntSet
IntSet.union IntMap IntSet
vs IntMap IntSet
es
where
vs :: IntMap IntSet
vs = (Int -> IntSet) -> IntSet -> IntMap IntSet
forall a. (Int -> a) -> IntSet -> IntMap a
IntMap.fromSet (IntSet -> Int -> IntSet
forall a b. a -> b -> a
const IntSet
IntSet.empty) (IntSet -> IntMap IntSet)
-> ([IntSet] -> IntSet) -> [IntSet] -> IntMap IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [IntSet] -> IntSet
forall (f :: * -> *). Foldable f => f IntSet -> IntSet
IntSet.unions ([IntSet] -> IntMap IntSet) -> [IntSet] -> IntMap IntSet
forall a b. (a -> b) -> a -> b
$ ((Int, IntSet) -> IntSet) -> [(Int, IntSet)] -> [IntSet]
forall a b. (a -> b) -> [a] -> [b]
map (Int, IntSet) -> IntSet
forall a b. (a, b) -> b
snd [(Int, IntSet)]
ss
es :: IntMap IntSet
es = (IntSet -> IntSet -> IntSet) -> [(Int, IntSet)] -> IntMap IntSet
forall a. (a -> a -> a) -> [(Int, a)] -> IntMap a
IntMap.fromListWith IntSet -> IntSet -> IntSet
IntSet.union [(Int, IntSet)]
ss
tree :: Tree Int -> AdjacencyIntMap
tree :: Tree Int -> AdjacencyIntMap
tree (Node Int
x []) = Int -> AdjacencyIntMap
vertex Int
x
tree (Node Int
x [Tree Int]
f ) = Int -> [Int] -> AdjacencyIntMap
star Int
x ((Tree Int -> Int) -> [Tree Int] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Tree Int -> Int
forall a. Tree a -> a
rootLabel [Tree Int]
f)
AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
`overlay` [Tree Int] -> AdjacencyIntMap
forest ((Tree Int -> Bool) -> [Tree Int] -> [Tree Int]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Tree Int -> Bool) -> Tree Int -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Tree Int] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Tree Int] -> Bool)
-> (Tree Int -> [Tree Int]) -> Tree Int -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tree Int -> [Tree Int]
forall a. Tree a -> [Tree a]
subForest) [Tree Int]
f)
forest :: Forest Int -> AdjacencyIntMap
forest :: [Tree Int] -> AdjacencyIntMap
forest = [AdjacencyIntMap] -> AdjacencyIntMap
overlays ([AdjacencyIntMap] -> AdjacencyIntMap)
-> ([Tree Int] -> [AdjacencyIntMap])
-> [Tree Int]
-> AdjacencyIntMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tree Int -> AdjacencyIntMap) -> [Tree Int] -> [AdjacencyIntMap]
forall a b. (a -> b) -> [a] -> [b]
map Tree Int -> AdjacencyIntMap
tree
removeVertex :: Int -> AdjacencyIntMap -> AdjacencyIntMap
removeVertex :: Int -> AdjacencyIntMap -> AdjacencyIntMap
removeVertex Int
x = IntMap IntSet -> AdjacencyIntMap
AM (IntMap IntSet -> AdjacencyIntMap)
-> (AdjacencyIntMap -> IntMap IntSet)
-> AdjacencyIntMap
-> AdjacencyIntMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IntSet -> IntSet) -> IntMap IntSet -> IntMap IntSet
forall a b. (a -> b) -> IntMap a -> IntMap b
IntMap.map (Int -> IntSet -> IntSet
IntSet.delete Int
x) (IntMap IntSet -> IntMap IntSet)
-> (AdjacencyIntMap -> IntMap IntSet)
-> AdjacencyIntMap
-> IntMap IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> IntMap IntSet -> IntMap IntSet
forall a. Int -> IntMap a -> IntMap a
IntMap.delete Int
x (IntMap IntSet -> IntMap IntSet)
-> (AdjacencyIntMap -> IntMap IntSet)
-> AdjacencyIntMap
-> IntMap IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap
removeEdge :: Int -> Int -> AdjacencyIntMap -> AdjacencyIntMap
removeEdge :: Int -> Int -> AdjacencyIntMap -> AdjacencyIntMap
removeEdge Int
x Int
y = IntMap IntSet -> AdjacencyIntMap
AM (IntMap IntSet -> AdjacencyIntMap)
-> (AdjacencyIntMap -> IntMap IntSet)
-> AdjacencyIntMap
-> AdjacencyIntMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IntSet -> IntSet) -> Int -> IntMap IntSet -> IntMap IntSet
forall a. (a -> a) -> Int -> IntMap a -> IntMap a
IntMap.adjust (Int -> IntSet -> IntSet
IntSet.delete Int
y) Int
x (IntMap IntSet -> IntMap IntSet)
-> (AdjacencyIntMap -> IntMap IntSet)
-> AdjacencyIntMap
-> IntMap IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap
replaceVertex :: Int -> Int -> AdjacencyIntMap -> AdjacencyIntMap
replaceVertex :: Int -> Int -> AdjacencyIntMap -> AdjacencyIntMap
replaceVertex Int
u Int
v = (Int -> Int) -> AdjacencyIntMap -> AdjacencyIntMap
gmap ((Int -> Int) -> AdjacencyIntMap -> AdjacencyIntMap)
-> (Int -> Int) -> AdjacencyIntMap -> AdjacencyIntMap
forall a b. (a -> b) -> a -> b
$ \Int
w -> if Int
w Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
u then Int
v else Int
w
mergeVertices :: (Int -> Bool) -> Int -> AdjacencyIntMap -> AdjacencyIntMap
mergeVertices :: (Int -> Bool) -> Int -> AdjacencyIntMap -> AdjacencyIntMap
mergeVertices Int -> Bool
p Int
v = (Int -> Int) -> AdjacencyIntMap -> AdjacencyIntMap
gmap ((Int -> Int) -> AdjacencyIntMap -> AdjacencyIntMap)
-> (Int -> Int) -> AdjacencyIntMap -> AdjacencyIntMap
forall a b. (a -> b) -> a -> b
$ \Int
u -> if Int -> Bool
p Int
u then Int
v else Int
u
transpose :: AdjacencyIntMap -> AdjacencyIntMap
transpose :: AdjacencyIntMap -> AdjacencyIntMap
transpose (AM IntMap IntSet
m) = IntMap IntSet -> AdjacencyIntMap
AM (IntMap IntSet -> AdjacencyIntMap)
-> IntMap IntSet -> AdjacencyIntMap
forall a b. (a -> b) -> a -> b
$ (Int -> IntSet -> IntMap IntSet -> IntMap IntSet)
-> IntMap IntSet -> IntMap IntSet -> IntMap IntSet
forall a b. (Int -> a -> b -> b) -> b -> IntMap a -> b
IntMap.foldrWithKey Int -> IntSet -> IntMap IntSet -> IntMap IntSet
combine IntMap IntSet
vs IntMap IntSet
m
where
combine :: Int -> IntSet -> IntMap IntSet -> IntMap IntSet
combine Int
v IntSet
es = (IntSet -> IntSet -> IntSet)
-> IntMap IntSet -> IntMap IntSet -> IntMap IntSet
forall a. (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
IntMap.unionWith IntSet -> IntSet -> IntSet
IntSet.union ((Int -> IntSet) -> IntSet -> IntMap IntSet
forall a. (Int -> a) -> IntSet -> IntMap a
IntMap.fromSet (IntSet -> Int -> IntSet
forall a b. a -> b -> a
const (IntSet -> Int -> IntSet) -> IntSet -> Int -> IntSet
forall a b. (a -> b) -> a -> b
$ Int -> IntSet
IntSet.singleton Int
v) IntSet
es)
vs :: IntMap IntSet
vs = (Int -> IntSet) -> IntSet -> IntMap IntSet
forall a. (Int -> a) -> IntSet -> IntMap a
IntMap.fromSet (IntSet -> Int -> IntSet
forall a b. a -> b -> a
const IntSet
IntSet.empty) (IntMap IntSet -> IntSet
forall a. IntMap a -> IntSet
IntMap.keysSet IntMap IntSet
m)
{-# NOINLINE [1] transpose #-}
{-# RULES
"transpose/empty" transpose empty = empty
"transpose/vertex" forall x. transpose (vertex x) = vertex x
"transpose/overlay" forall g1 g2. transpose (overlay g1 g2) = overlay (transpose g1) (transpose g2)
"transpose/connect" forall g1 g2. transpose (connect g1 g2) = connect (transpose g2) (transpose g1)
"transpose/overlays" forall xs. transpose (overlays xs) = overlays (map transpose xs)
"transpose/connects" forall xs. transpose (connects xs) = connects (reverse (map transpose xs))
"transpose/vertices" forall xs. transpose (vertices xs) = vertices xs
"transpose/clique" forall xs. transpose (clique xs) = clique (reverse xs)
#-}
gmap :: (Int -> Int) -> AdjacencyIntMap -> AdjacencyIntMap
gmap :: (Int -> Int) -> AdjacencyIntMap -> AdjacencyIntMap
gmap Int -> Int
f = IntMap IntSet -> AdjacencyIntMap
AM (IntMap IntSet -> AdjacencyIntMap)
-> (AdjacencyIntMap -> IntMap IntSet)
-> AdjacencyIntMap
-> AdjacencyIntMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IntSet -> IntSet) -> IntMap IntSet -> IntMap IntSet
forall a b. (a -> b) -> IntMap a -> IntMap b
IntMap.map ((Int -> Int) -> IntSet -> IntSet
IntSet.map Int -> Int
f) (IntMap IntSet -> IntMap IntSet)
-> (AdjacencyIntMap -> IntMap IntSet)
-> AdjacencyIntMap
-> IntMap IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IntSet -> IntSet -> IntSet)
-> (Int -> Int) -> IntMap IntSet -> IntMap IntSet
forall a. (a -> a -> a) -> (Int -> Int) -> IntMap a -> IntMap a
IntMap.mapKeysWith IntSet -> IntSet -> IntSet
IntSet.union Int -> Int
f (IntMap IntSet -> IntMap IntSet)
-> (AdjacencyIntMap -> IntMap IntSet)
-> AdjacencyIntMap
-> IntMap IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap
induce :: (Int -> Bool) -> AdjacencyIntMap -> AdjacencyIntMap
induce :: (Int -> Bool) -> AdjacencyIntMap -> AdjacencyIntMap
induce Int -> Bool
p = IntMap IntSet -> AdjacencyIntMap
AM (IntMap IntSet -> AdjacencyIntMap)
-> (AdjacencyIntMap -> IntMap IntSet)
-> AdjacencyIntMap
-> AdjacencyIntMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IntSet -> IntSet) -> IntMap IntSet -> IntMap IntSet
forall a b. (a -> b) -> IntMap a -> IntMap b
IntMap.map ((Int -> Bool) -> IntSet -> IntSet
IntSet.filter Int -> Bool
p) (IntMap IntSet -> IntMap IntSet)
-> (AdjacencyIntMap -> IntMap IntSet)
-> AdjacencyIntMap
-> IntMap IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> IntSet -> Bool) -> IntMap IntSet -> IntMap IntSet
forall a. (Int -> a -> Bool) -> IntMap a -> IntMap a
IntMap.filterWithKey (\Int
k IntSet
_ -> Int -> Bool
p Int
k) (IntMap IntSet -> IntMap IntSet)
-> (AdjacencyIntMap -> IntMap IntSet)
-> AdjacencyIntMap
-> IntMap IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap
compose :: AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
compose :: AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
compose AdjacencyIntMap
x AdjacencyIntMap
y = [(Int, IntSet)] -> AdjacencyIntMap
fromAdjacencyIntSets
[ (Int
t, IntSet
ys) | Int
v <- IntSet -> [Int]
IntSet.toList IntSet
vs, let ys :: IntSet
ys = Int -> AdjacencyIntMap -> IntSet
postIntSet Int
v AdjacencyIntMap
y
, Bool -> Bool
not (IntSet -> Bool
IntSet.null IntSet
ys), Int
t <- IntSet -> [Int]
IntSet.toList (Int -> AdjacencyIntMap -> IntSet
postIntSet Int
v AdjacencyIntMap
tx) ]
where
tx :: AdjacencyIntMap
tx = AdjacencyIntMap -> AdjacencyIntMap
transpose AdjacencyIntMap
x
vs :: IntSet
vs = AdjacencyIntMap -> IntSet
vertexIntSet AdjacencyIntMap
x IntSet -> IntSet -> IntSet
`IntSet.union` AdjacencyIntMap -> IntSet
vertexIntSet AdjacencyIntMap
y
closure :: AdjacencyIntMap -> AdjacencyIntMap
closure :: AdjacencyIntMap -> AdjacencyIntMap
closure = AdjacencyIntMap -> AdjacencyIntMap
reflexiveClosure (AdjacencyIntMap -> AdjacencyIntMap)
-> (AdjacencyIntMap -> AdjacencyIntMap)
-> AdjacencyIntMap
-> AdjacencyIntMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> AdjacencyIntMap
transitiveClosure
reflexiveClosure :: AdjacencyIntMap -> AdjacencyIntMap
reflexiveClosure :: AdjacencyIntMap -> AdjacencyIntMap
reflexiveClosure (AM IntMap IntSet
m) = IntMap IntSet -> AdjacencyIntMap
AM (IntMap IntSet -> AdjacencyIntMap)
-> IntMap IntSet -> AdjacencyIntMap
forall a b. (a -> b) -> a -> b
$ (Int -> IntSet -> IntSet) -> IntMap IntSet -> IntMap IntSet
forall a b. (Int -> a -> b) -> IntMap a -> IntMap b
IntMap.mapWithKey Int -> IntSet -> IntSet
IntSet.insert IntMap IntSet
m
symmetricClosure :: AdjacencyIntMap -> AdjacencyIntMap
symmetricClosure :: AdjacencyIntMap -> AdjacencyIntMap
symmetricClosure AdjacencyIntMap
m = AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
overlay AdjacencyIntMap
m (AdjacencyIntMap -> AdjacencyIntMap
transpose AdjacencyIntMap
m)
transitiveClosure :: AdjacencyIntMap -> AdjacencyIntMap
transitiveClosure :: AdjacencyIntMap -> AdjacencyIntMap
transitiveClosure AdjacencyIntMap
old
| AdjacencyIntMap
old AdjacencyIntMap -> AdjacencyIntMap -> Bool
forall a. Eq a => a -> a -> Bool
== AdjacencyIntMap
new = AdjacencyIntMap
old
| Bool
otherwise = AdjacencyIntMap -> AdjacencyIntMap
transitiveClosure AdjacencyIntMap
new
where
new :: AdjacencyIntMap
new = AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
overlay AdjacencyIntMap
old (AdjacencyIntMap
old AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
`compose` AdjacencyIntMap
old)
consistent :: AdjacencyIntMap -> Bool
consistent :: AdjacencyIntMap -> Bool
consistent (AM IntMap IntSet
m) = IntMap IntSet -> IntSet
referredToVertexSet IntMap IntSet
m IntSet -> IntSet -> Bool
`IntSet.isSubsetOf` IntMap IntSet -> IntSet
forall a. IntMap a -> IntSet
IntMap.keysSet IntMap IntSet
m
referredToVertexSet :: IntMap IntSet -> IntSet
referredToVertexSet :: IntMap IntSet -> IntSet
referredToVertexSet IntMap IntSet
m = [Int] -> IntSet
IntSet.fromList ([Int] -> IntSet) -> [Int] -> IntSet
forall a b. (a -> b) -> a -> b
$ [[Int]] -> [Int]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [Int
x, Int
y] | (Int
x, IntSet
ys) <- IntMap IntSet -> [(Int, IntSet)]
forall a. IntMap a -> [(Int, a)]
IntMap.toAscList IntMap IntSet
m, Int
y <- IntSet -> [Int]
IntSet.toAscList IntSet
ys ]