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
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. 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)
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Int]
vs = String -> ShowS
showString String
"empty"
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Int, Int)]
es = Bool -> ShowS -> ShowS
showParen (Int
p forall a. Ord a => a -> a -> Bool
> Int
10) forall a b. (a -> b) -> a -> b
$ forall {a}. Show a => [a] -> ShowS
vshow [Int]
vs
| [Int]
vs forall a. Eq a => a -> a -> Bool
== [Int]
used = Bool -> ShowS -> ShowS
showParen (Int
p forall a. Ord a => a -> a -> Bool
> Int
10) forall a b. (a -> b) -> a -> b
$ forall {a} {a}. (Show a, Show a) => [(a, a)] -> ShowS
eshow [(Int, Int)]
es
| Bool
otherwise = Bool -> ShowS -> ShowS
showParen (Int
p forall a. Ord a => a -> a -> Bool
> Int
10) forall a b. (a -> b) -> a -> b
$
String -> ShowS
showString String
"overlay (" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {a}. Show a => [a] -> ShowS
vshow ([Int]
vs forall a. Eq a => [a] -> [a] -> [a]
\\ [Int]
used) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
String -> ShowS
showString String
") (" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {a} {a}. (Show a, Show a) => [(a, a)] -> ShowS
eshow [(Int, Int)]
es 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 " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 a
x
vshow [a]
xs = String -> ShowS
showString String
"vertices " forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 a
x forall b c a. (b -> c) -> (a -> b) -> a -> c
.
String -> ShowS
showString String
" " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 a
y
eshow [(a, a)]
xs = String -> ShowS
showString String
"edges " forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall a. Monoid a => [a] -> a
mconcat
[ forall a. Ord a => a -> a -> Ordering
compare (AdjacencyIntMap -> Int
vertexCount AdjacencyIntMap
x) (AdjacencyIntMap -> Int
vertexCount AdjacencyIntMap
y)
, forall a. Ord a => a -> a -> Ordering
compare (AdjacencyIntMap -> IntSet
vertexIntSet AdjacencyIntMap
x) (AdjacencyIntMap -> IntSet
vertexIntSet AdjacencyIntMap
y)
, forall a. Ord a => a -> a -> Ordering
compare (AdjacencyIntMap -> Int
edgeCount AdjacencyIntMap
x) (AdjacencyIntMap -> Int
edgeCount AdjacencyIntMap
y)
, 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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall a b. a -> b -> a
const AdjacencyIntMap
empty
abs :: AdjacencyIntMap -> AdjacencyIntMap
abs = forall a. a -> a
id
negate :: AdjacencyIntMap -> AdjacencyIntMap
negate = forall a. a -> a
id
instance NFData AdjacencyIntMap where
rnf :: AdjacencyIntMap -> ()
rnf (AM IntMap IntSet
a) = 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
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [(Int, a)] -> IntMap a
IntMap.fromAscList
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a -> b) -> a -> b
$ [Int] -> IntSet
IntSet.fromAscList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Set a -> [a]
Set.toAscList)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Map k a -> [(k, a)]
Map.toAscList
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. AdjacencyMap a -> Map a (Set a)
AM.adjacencyMap
empty :: AdjacencyIntMap
empty :: AdjacencyIntMap
empty = IntMap IntSet -> AdjacencyIntMap
AM forall a. IntMap a
IntMap.empty
{-# NOINLINE [1] empty #-}
vertex :: Int -> AdjacencyIntMap
vertex :: Int -> AdjacencyIntMap
vertex Int
x = IntMap IntSet -> AdjacencyIntMap
AM forall a b. (a -> b) -> a -> b
$ 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 forall a. Eq a => a -> a -> Bool
== Int
y = IntMap IntSet -> AdjacencyIntMap
AM forall a b. (a -> b) -> a -> b
$ forall a. Int -> a -> IntMap a
IntMap.singleton Int
x (Int -> IntSet
IntSet.singleton Int
y)
| Bool
otherwise = IntMap IntSet -> AdjacencyIntMap
AM forall a b. (a -> b) -> a -> b
$ 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 forall a b. (a -> b) -> a -> b
$ 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 forall a b. (a -> b) -> a -> b
$ 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, forall a. (Int -> a) -> IntSet -> IntMap a
IntMap.fromSet (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall a. IntMap a -> IntSet
IntMap.keysSet IntMap IntSet
y) (forall a. IntMap a -> IntSet
IntMap.keysSet IntMap IntSet
x) ]
{-# NOINLINE [1] connect #-}
vertices :: [Int] -> AdjacencyIntMap
vertices :: [Int] -> AdjacencyIntMap
vertices = IntMap IntSet -> AdjacencyIntMap
AM forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [(Int, a)] -> IntMap a
IntMap.fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a.
Foldable f =>
(a -> a -> a) -> f (IntMap a) -> IntMap a
IntMap.unionsWith IntSet -> IntSet -> IntSet
IntSet.union forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap
{-# NOINLINE [1] overlays #-}
connects :: [AdjacencyIntMap] -> AdjacencyIntMap
connects :: [AdjacencyIntMap] -> AdjacencyIntMap
connects = 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) = 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 = forall a. IntMap a -> Bool
IntMap.null 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 = forall a. Int -> IntMap a -> Bool
IntMap.member Int
x 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 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 = forall a. IntMap a -> Int
IntMap.size forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap
edgeCount :: AdjacencyIntMap -> Int
edgeCount :: AdjacencyIntMap -> Int
edgeCount = forall a. Sum a -> a
getSum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (forall a. a -> Sum a
Sum forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntSet -> Int
IntSet.size) forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> IntMap IntSet
adjacencyIntMap
vertexList :: AdjacencyIntMap -> [Int]
vertexList :: AdjacencyIntMap -> [Int]
vertexList = forall a. IntMap a -> [Int]
IntMap.keys 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) <- 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 = forall a. IntMap a -> IntSet
IntMap.keysSet 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 = forall a. Eq a => [a] -> Set a
Set.fromAscList forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyIntMap -> [(Int, Int)]
edgeList
adjacencyList :: AdjacencyIntMap -> [(Int, [Int])]
adjacencyList :: AdjacencyIntMap -> [(Int, [Int])]
adjacencyList = forall a b. (a -> b) -> [a] -> [b]
map (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap IntSet -> [Int]
IntSet.toAscList) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. IntMap a -> [(Int, a)]
IntMap.toAscList 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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter (Int, IntSet) -> Bool
p forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. IntMap a -> [(Int, a)]
IntMap.toAscList 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 = forall a. a -> Int -> IntMap a -> a
IntMap.findWithDefault IntSet
IntSet.empty Int
x 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 (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 forall a b. (a -> b) -> a -> b
$ [Int
x] forall a. [a] -> [a] -> [a]
++ [Int]
xs forall a. [a] -> [a] -> [a]
++ [Int
x]
clique :: [Int] -> AdjacencyIntMap
clique :: [Int] -> AdjacencyIntMap
clique = [(Int, IntSet)] -> AdjacencyIntMap
fromAdjacencyIntSets forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst 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) 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 forall a b. (a -> b) -> a -> b
$ 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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (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 forall a b. (a -> b) -> a -> b
$ 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 = forall a. (Int -> a) -> IntSet -> IntMap a
IntMap.fromSet (forall a b. a -> b -> a
const IntSet
IntSet.empty) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *). Foldable f => f IntSet -> IntSet
IntSet.unions forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd [(Int, IntSet)]
ss
es :: IntMap IntSet
es = 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 (forall a b. (a -> b) -> [a] -> [b]
map forall a. Tree a -> a
rootLabel [Tree Int]
f)
AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap
`overlay` [Tree Int] -> AdjacencyIntMap
forest (forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> Bool
null forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Tree a -> [Tree a]
subForest) [Tree Int]
f)
forest :: Forest Int -> AdjacencyIntMap
forest :: [Tree Int] -> AdjacencyIntMap
forest = [AdjacencyIntMap] -> AdjacencyIntMap
overlays forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> IntMap a -> IntMap b
IntMap.map (Int -> IntSet -> IntSet
IntSet.delete Int
x) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Int -> IntMap a -> IntMap a
IntMap.delete Int
x 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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> a) -> Int -> IntMap a -> IntMap a
IntMap.adjust (Int -> IntSet -> IntSet
IntSet.delete Int
y) Int
x 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 forall a b. (a -> b) -> a -> b
$ \Int
w -> if Int
w 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 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 forall a b. (a -> b) -> a -> b
$ 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 = forall a. (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
IntMap.unionWith IntSet -> IntSet -> IntSet
IntSet.union (forall a. (Int -> a) -> IntSet -> IntMap a
IntMap.fromSet (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ Int -> IntSet
IntSet.singleton Int
v) IntSet
es)
vs :: IntMap IntSet
vs = forall a. (Int -> a) -> IntSet -> IntMap a
IntMap.fromSet (forall a b. a -> b -> a
const IntSet
IntSet.empty) (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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> IntMap a -> IntMap b
IntMap.map ((Int -> Int) -> IntSet -> IntSet
IntSet.map Int -> Int
f) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> a -> a) -> (Int -> Int) -> IntMap a -> IntMap a
IntMap.mapKeysWith IntSet -> IntSet -> IntSet
IntSet.union Int -> Int
f 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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> IntMap a -> IntMap b
IntMap.map ((Int -> Bool) -> IntSet -> IntSet
IntSet.filter Int -> Bool
p) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (Int -> a -> Bool) -> IntMap a -> IntMap a
IntMap.filterWithKey (\Int
k IntSet
_ -> Int -> Bool
p Int
k) 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 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 forall a b. (a -> b) -> a -> b
$ 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 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` 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 forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [Int
x, Int
y] | (Int
x, IntSet
ys) <- forall a. IntMap a -> [(Int, a)]
IntMap.toAscList IntMap IntSet
m, Int
y <- IntSet -> [Int]
IntSet.toAscList IntSet
ys ]