algebraic-graphs-0.4: A library for algebraic graph construction and transformation

Copyright(c) Andrey Mokhov 2016-2019
LicenseMIT (see the file LICENSE)
Maintainerandrey.mokhov@gmail.com
Stabilityexperimental
Safe HaskellNone
LanguageHaskell2010

Algebra.Graph.Relation.Symmetric

Contents

Description

An abstract implementation of symmetric binary relations. To avoid name clashes with Algebra.Graph.Relation, this module can be imported qualified:

import qualified Algebra.Graph.Relation.Symmetric as Symmetric

Relation is an instance of the Graph type class, which can be used for polymorphic graph construction and manipulation.

Synopsis

Data structure

data Relation a Source #

This data type represents a symmetric binary relation over a set of elements of type a. Symmetric relations satisfy all laws of the Undirected type class, including the commutativity of connect:

connect x y == connect y x

The Show instance lists edge vertices in non-decreasing order:

show (empty     :: Relation Int) == "empty"
show (1         :: Relation Int) == "vertex 1"
show (1 + 2     :: Relation Int) == "vertices [1,2]"
show (1 * 2     :: Relation Int) == "edge 1 2"
show (2 * 1     :: Relation Int) == "edge 1 2"
show (1 * 2 * 1 :: Relation Int) == "edges [(1,1),(1,2)]"
show (3 * 2 * 1 :: Relation Int) == "edges [(1,2),(1,3),(2,3)]"
show (1 * 2 + 3 :: Relation Int) == "overlay (vertex 3) (edge 1 2)"

The total order on graphs is defined using size-lexicographic comparison:

  • Compare the number of vertices. In case of a tie, continue.
  • Compare the sets of vertices. In case of a tie, continue.
  • Compare the number of edges. In case of a tie, continue.
  • Compare the sets of edges.

Here are a few examples:

vertex 1 < vertex 2
vertex 3 < edge 1 2
vertex 1 < edge 1 1
edge 1 1 < edge 1 2
edge 1 2 < edge 1 1 + edge 2 2
edge 2 1 < edge 1 3
edge 1 2 == edge 2 1

Note that the resulting order refines the isSubgraphOf relation and is compatible with overlay and connect operations:

isSubgraphOf x y ==> x <= y
empty <= x
x     <= x + y
x + y <= x * y
Instances
Ord a => Eq (Relation a) Source # 
Instance details

Defined in Algebra.Graph.Relation.Symmetric.Internal

Methods

(==) :: Relation a -> Relation a -> Bool #

(/=) :: Relation a -> Relation a -> Bool #

(Ord a, Num a) => Num (Relation a) Source # 
Instance details

Defined in Algebra.Graph.Relation.Symmetric.Internal

Ord a => Ord (Relation a) Source # 
Instance details

Defined in Algebra.Graph.Relation.Symmetric.Internal

Methods

compare :: Relation a -> Relation a -> Ordering #

(<) :: Relation a -> Relation a -> Bool #

(<=) :: Relation a -> Relation a -> Bool #

(>) :: Relation a -> Relation a -> Bool #

(>=) :: Relation a -> Relation a -> Bool #

max :: Relation a -> Relation a -> Relation a #

min :: Relation a -> Relation a -> Relation a #

(Ord a, Show a) => Show (Relation a) Source # 
Instance details

Defined in Algebra.Graph.Relation.Symmetric.Internal

Methods

showsPrec :: Int -> Relation a -> ShowS #

show :: Relation a -> String #

showList :: [Relation a] -> ShowS #

NFData a => NFData (Relation a) Source # 
Instance details

Defined in Algebra.Graph.Relation.Symmetric.Internal

Methods

rnf :: Relation a -> () #

Ord a => ToGraph (Relation a) Source #

See Algebra.Graph.Symmetric.Relation. Warning: this instance is likely to be modified or removed in future.

Instance details

Defined in Algebra.Graph.ToGraph

Associated Types

type ToVertex (Relation a) :: Type Source #

Methods

toGraph :: Relation a -> Graph (ToVertex (Relation a)) Source #

foldg :: r -> (ToVertex (Relation a) -> r) -> (r -> r -> r) -> (r -> r -> r) -> Relation a -> r Source #

isEmpty :: Relation a -> Bool Source #

size :: Relation a -> Int Source #

hasVertex :: ToVertex (Relation a) -> Relation a -> Bool Source #

hasEdge :: ToVertex (Relation a) -> ToVertex (Relation a) -> Relation a -> Bool Source #

vertexCount :: Relation a -> Int Source #

edgeCount :: Relation a -> Int Source #

vertexList :: Relation a -> [ToVertex (Relation a)] Source #

edgeList :: Relation a -> [(ToVertex (Relation a), ToVertex (Relation a))] Source #

vertexSet :: Relation a -> Set (ToVertex (Relation a)) Source #

vertexIntSet :: Relation a -> IntSet Source #

edgeSet :: Relation a -> Set (ToVertex (Relation a), ToVertex (Relation a)) Source #

preSet :: ToVertex (Relation a) -> Relation a -> Set (ToVertex (Relation a)) Source #

preIntSet :: Int -> Relation a -> IntSet Source #

postSet :: ToVertex (Relation a) -> Relation a -> Set (ToVertex (Relation a)) Source #

postIntSet :: Int -> Relation a -> IntSet Source #

adjacencyList :: Relation a -> [(ToVertex (Relation a), [ToVertex (Relation a)])] Source #

adjacencyMap :: Relation a -> Map (ToVertex (Relation a)) (Set (ToVertex (Relation a))) Source #

adjacencyIntMap :: Relation a -> IntMap IntSet Source #

adjacencyMapTranspose :: Relation a -> Map (ToVertex (Relation a)) (Set (ToVertex (Relation a))) Source #

adjacencyIntMapTranspose :: Relation a -> IntMap IntSet Source #

dfsForest :: Relation a -> Forest (ToVertex (Relation a)) Source #

dfsForestFrom :: [ToVertex (Relation a)] -> Relation a -> Forest (ToVertex (Relation a)) Source #

dfs :: [ToVertex (Relation a)] -> Relation a -> [ToVertex (Relation a)] Source #

reachable :: ToVertex (Relation a) -> Relation a -> [ToVertex (Relation a)] Source #

topSort :: Relation a -> Maybe [ToVertex (Relation a)] Source #

isAcyclic :: Relation a -> Bool Source #

toAdjacencyMap :: Relation a -> AdjacencyMap (ToVertex (Relation a)) Source #

toAdjacencyMapTranspose :: Relation a -> AdjacencyMap (ToVertex (Relation a)) Source #

toAdjacencyIntMap :: Relation a -> AdjacencyIntMap Source #

toAdjacencyIntMapTranspose :: Relation a -> AdjacencyIntMap Source #

isDfsForestOf :: Forest (ToVertex (Relation a)) -> Relation a -> Bool Source #

isTopSortOf :: [ToVertex (Relation a)] -> Relation a -> Bool Source #

Ord a => Undirected (Relation a) Source # 
Instance details

Defined in Algebra.Graph.Class

Ord a => Graph (Relation a) Source # 
Instance details

Defined in Algebra.Graph.Class

Associated Types

type Vertex (Relation a) :: Type Source #

type ToVertex (Relation a) Source # 
Instance details

Defined in Algebra.Graph.ToGraph

type ToVertex (Relation a) = a
type Vertex (Relation a) Source # 
Instance details

Defined in Algebra.Graph.Class

type Vertex (Relation a) = a

toSymmetric :: Ord a => Relation a -> Relation a Source #

Construct a symmetric relation from a given Algebra.Graph.Relation. Complexity: O(m*log(m)) time.

toSymmetric (edge 1 2)         == edge 1 2
toSymmetric . fromSymmetric    == id
fromSymmetric    . toSymmetric == symmetricClosure
vertexCount      . toSymmetric == vertexCount
(*2) . edgeCount . toSymmetric >= edgeCount

fromSymmetric :: Relation a -> Relation a Source #

Extract the underlying symmetric Algebra.Graph.Relation. Complexity: O(1) time and memory.

fromSymmetric (edge 1 2)    == edges [(1,2), (2,1)]
vertexCount . fromSymmetric == vertexCount
edgeCount   . fromSymmetric <= (*2) . edgeCount

Basic graph construction primitives

empty :: Relation a Source #

Construct the empty graph. Complexity: O(1) time and memory.

isEmpty     empty == True
hasVertex x empty == False
vertexCount empty == 0
edgeCount   empty == 0

vertex :: a -> Relation a Source #

Construct the graph comprising a single isolated vertex. Complexity: O(1) time and memory.

isEmpty     (vertex x) == False
hasVertex x (vertex x) == True
vertexCount (vertex x) == 1
edgeCount   (vertex x) == 0

edge :: Ord a => a -> a -> Relation a Source #

Construct the graph comprising a single edge. Complexity: O(1) time, memory and size.

edge x y               == connect (vertex x) (vertex y)
edge x y               == edge y x
edge x y               == edges [(x,y), (y,x)]
hasEdge x y (edge x y) == True
edgeCount   (edge x y) == 1
vertexCount (edge 1 1) == 1
vertexCount (edge 1 2) == 2

overlay :: Ord a => Relation a -> Relation a -> Relation a Source #

Overlay two graphs. This is a commutative, associative and idempotent operation with the identity empty. Complexity: O((n + m) * log(n)) time and O(n + m) memory.

isEmpty     (overlay x y) == isEmpty   x   && isEmpty   y
hasVertex z (overlay x y) == hasVertex z x || hasVertex z y
vertexCount (overlay x y) >= vertexCount x
vertexCount (overlay x y) <= vertexCount x + vertexCount y
edgeCount   (overlay x y) >= edgeCount x
edgeCount   (overlay x y) <= edgeCount x   + edgeCount y
vertexCount (overlay 1 2) == 2
edgeCount   (overlay 1 2) == 0

connect :: Ord a => Relation a -> Relation a -> Relation a Source #

Connect two graphs. This is a commutative and associative operation with the identity empty, which distributes over overlay and obeys the decomposition axiom. Complexity: O((n + m) * log(n)) time and O(n + m) memory. Note that the number of edges in the resulting graph is quadratic with respect to the number of vertices of the arguments: m = O(m1 + m2 + n1 * n2).

connect x y               == connect y x
isEmpty     (connect x y) == isEmpty   x   && isEmpty   y
hasVertex z (connect x y) == hasVertex z x || hasVertex z y
vertexCount (connect x y) >= vertexCount x
vertexCount (connect x y) <= vertexCount x + vertexCount y
edgeCount   (connect x y) >= edgeCount x
edgeCount   (connect x y) >= edgeCount y
edgeCount   (connect x y) >= vertexCount x * vertexCount y `div` 2
vertexCount (connect 1 2) == 2
edgeCount   (connect 1 2) == 1

vertices :: Ord a => [a] -> Relation a Source #

Construct the graph comprising a given list of isolated vertices. Complexity: O(L * log(L)) time and O(L) memory, where L is the length of the given list.

vertices []            == empty
vertices [x]           == vertex x
hasVertex x . vertices == elem x
vertexCount . vertices == length . nub
vertexSet   . vertices == Set.fromList

edges :: Ord a => [(a, a)] -> Relation a Source #

Construct the graph from a list of edges. Complexity: O((n + m) * log(n)) time and O(n + m) memory.

edges []             == empty
edges [(x,y)]        == edge x y
edges [(x,y), (y,x)] == edge x y

overlays :: Ord a => [Relation a] -> Relation a Source #

Overlay a given list of graphs. Complexity: O((n + m) * log(n)) time and O(n + m) memory.

overlays []        == empty
overlays [x]       == x
overlays [x,y]     == overlay x y
overlays           == foldr overlay empty
isEmpty . overlays == all isEmpty

connects :: Ord a => [Relation a] -> Relation a Source #

Connect a given list of graphs. Complexity: O((n + m) * log(n)) time and O(n + m) memory.

connects []        == empty
connects [x]       == x
connects [x,y]     == connect x y
connects           == foldr connect empty
isEmpty . connects == all isEmpty
connects           == connects . reverse

Relations on graphs

isSubgraphOf :: Ord a => Relation a -> Relation a -> Bool Source #

The isSubgraphOf function takes two graphs and returns True if the first graph is a subgraph of the second. Complexity: O((n + m) * log(n)) time.

isSubgraphOf empty         x             ==  True
isSubgraphOf (vertex x)    empty         ==  False
isSubgraphOf x             (overlay x y) ==  True
isSubgraphOf (overlay x y) (connect x y) ==  True
isSubgraphOf (path xs)     (circuit xs)  ==  True
isSubgraphOf (edge x y)    (edge y x)    ==  True
isSubgraphOf x y                         ==> x <= y

Graph properties

isEmpty :: Relation a -> Bool Source #

Check if a relation is empty. Complexity: O(1) time.

isEmpty empty                       == True
isEmpty (overlay empty empty)       == True
isEmpty (vertex x)                  == False
isEmpty (removeVertex x $ vertex x) == True
isEmpty (removeEdge x y $ edge x y) == False

hasVertex :: Ord a => a -> Relation a -> Bool Source #

Check if a graph contains a given vertex. Complexity: O(log(n)) time.

hasVertex x empty            == False
hasVertex x (vertex x)       == True
hasVertex 1 (vertex 2)       == False
hasVertex x . removeVertex x == const False

hasEdge :: Ord a => a -> a -> Relation a -> Bool Source #

Check if a graph contains a given edge. Complexity: O(log(n)) time.

hasEdge x y empty            == False
hasEdge x y (vertex z)       == False
hasEdge x y (edge x y)       == True
hasEdge x y (edge y x)       == True
hasEdge x y . removeEdge x y == const False
hasEdge x y                  == elem (min x y, max x y) . edgeList

vertexCount :: Relation a -> Int Source #

The number of vertices in a graph. Complexity: O(1) time.

vertexCount empty             ==  0
vertexCount (vertex x)        ==  1
vertexCount                   ==  length . vertexList
vertexCount x < vertexCount y ==> x < y

edgeCount :: Ord a => Relation a -> Int Source #

The number of edges in a graph. Complexity: O(1) time.

edgeCount empty      == 0
edgeCount (vertex x) == 0
edgeCount (edge x y) == 1
edgeCount            == length . edgeList

vertexList :: Relation a -> [a] Source #

The sorted list of vertices of a given graph. Complexity: O(n) time and memory.

vertexList empty      == []
vertexList (vertex x) == [x]
vertexList . vertices == nub . sort

edgeList :: Ord a => Relation a -> [(a, a)] Source #

The sorted list of edges of a graph, where edge vertices appear in the non-decreasing order. Complexity: O(n + m) time and O(m) memory.

Note: If you need the sorted list of edges where an edge appears in both directions, use edgeList . fromSymmetric.

edgeList empty          == []
edgeList (vertex x)     == []
edgeList (edge x y)     == [(min x y, max y x)]
edgeList (star 2 [3,1]) == [(1,2), (2,3)]

adjacencyList :: Eq a => Relation a -> [(a, [a])] Source #

The sorted adjacency list of a graph. Complexity: O(n + m) time and O(m) memory.

adjacencyList empty          == []
adjacencyList (vertex x)     == [(x, [])]
adjacencyList (edge 1 2)     == [(1, [2]), (2, [1])]
adjacencyList (star 2 [3,1]) == [(1, [2]), (2, [1,3]), (3, [2])]
stars . adjacencyList        == id

vertexSet :: Relation a -> Set a Source #

The set of vertices of a given graph. Complexity: O(1) time.

vertexSet empty      == Set.empty
vertexSet . vertex   == Set.singleton
vertexSet . vertices == Set.fromList

edgeSet :: Ord a => Relation a -> Set (a, a) Source #

The set of edges of a given graph, where edge vertices appear in the non-decreasing order. Complexity: O(m) time.

Note: If you need the set of edges where an edge appears in both directions, use relation . fromSymmetric. The latter is much faster than this function, and takes only O(1) time and memory.

edgeSet empty      == Set.empty
edgeSet (vertex x) == Set.empty
edgeSet (edge x y) == Set.singleton (min x y, max x y)

neighbours :: Ord a => a -> Relation a -> Set a Source #

The set of neighbours of an element x is the set of elements that are related to it, i.e. neighbours x == { a | aRx }. In the context of undirected graphs, this corresponds to the set of adjacent vertices of vertex x.

neighbours x empty      == Set.empty
neighbours x (vertex x) == Set.empty
neighbours x (edge x y) == Set.fromList [y]
neighbours y (edge x y) == Set.fromList [x]

Standard families of graphs

path :: Ord a => [a] -> Relation a Source #

The path on a list of vertices. Complexity: O((n + m) * log(n)) time and O(n + m) memory.

path []    == empty
path [x]   == vertex x
path [x,y] == edge x y
path       == path . reverse

circuit :: Ord a => [a] -> Relation a Source #

The circuit on a list of vertices. Complexity: O((n + m) * log(n)) time and O(n + m) memory.

circuit []    == empty
circuit [x]   == edge x x
circuit [x,y] == edge x y
circuit       == circuit . reverse

clique :: Ord a => [a] -> Relation a Source #

The clique on a list of vertices. Complexity: O((n + m) * log(n)) time + O(m*log(m)) time from computing the symmetricClosure and O(n + m)/ memory.

clique []         == empty
clique [x]        == vertex x
clique [x,y]      == edge x y
clique [x,y,z]    == edges [(x,y), (x,z), (y,z)]
clique (xs ++ ys) == connect (clique xs) (clique ys)
clique            == clique . reverse

biclique :: Ord a => [a] -> [a] -> Relation a Source #

The biclique on two lists of vertices. Complexity: O(n * log(n) + m) time + O(m*log(m)) time from computing the symmetricClosure and O(n + m)/ memory.

biclique []      []      == empty
biclique [x]     []      == vertex x
biclique []      [y]     == vertex y
biclique [x1,x2] [y1,y2] == edges [(x1,y1), (x1,y2), (x2,x2), (x2,y2)]
biclique xs      ys      == connect (vertices xs) (vertices ys)

star :: Ord a => a -> [a] -> Relation a Source #

The star formed by a centre vertex connected to a list of leaves. Complexity: O((n + m) * log(n)) time and O(n + m) memory.

star x []    == vertex x
star x [y]   == edge x y
star x [y,z] == edges [(x,y), (x,z)]
star x ys    == connect (vertex x) (vertices ys)

stars :: Ord a => [(a, [a])] -> Relation a Source #

The stars formed by overlaying a list of stars. An inverse of adjacencyList. Complexity: O(L * log(n)) time, memory and size, where L is the total size of the input.

stars []                      == empty
stars [(x, [])]               == vertex x
stars [(x, [y])]              == edge x y
stars [(x, ys)]               == star x ys
stars                         == overlays . map (uncurry star)
stars . adjacencyList         == id
overlay (stars xs) (stars ys) == stars (xs ++ ys)

tree :: Ord a => Tree a -> Relation a Source #

The tree graph constructed from a given Tree data structure. Complexity: O((n + m) * log(n)) time and O(n + m) memory.

tree (Node x [])                                         == vertex x
tree (Node x [Node y [Node z []]])                       == path [x,y,z]
tree (Node x [Node y [], Node z []])                     == star x [y,z]
tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) == edges [(1,2), (1,3), (3,4), (3,5)]

forest :: Ord a => Forest a -> Relation a Source #

The forest graph constructed from a given Forest data structure. Complexity: O((n + m) * log(n)) time and O(n + m) memory.

forest []                                                  == empty
forest [x]                                                 == tree x
forest [Node 1 [Node 2 [], Node 3 []], Node 4 [Node 5 []]] == edges [(1,2), (1,3), (4,5)]
forest                                                     == overlays . map tree

Graph transformation

removeVertex :: Ord a => a -> Relation a -> Relation a Source #

Remove a vertex from a given graph. Complexity: O(n + m) time.

removeVertex x (vertex x)       == empty
removeVertex 1 (vertex 2)       == vertex 2
removeVertex x (edge x x)       == empty
removeVertex 1 (edge 1 2)       == vertex 2
removeVertex x . removeVertex x == removeVertex x

removeEdge :: Ord a => a -> a -> Relation a -> Relation a Source #

Remove an edge from a given graph. Complexity: O(log(m)) time.

removeEdge x y (edge x y)       == vertices [x,y]
removeEdge x y . removeEdge x y == removeEdge x y
removeEdge x y                  == removeEdge y x
removeEdge x y . removeVertex x == removeVertex x
removeEdge 1 1 (1 * 1 * 2 * 2)  == 1 * 2 * 2
removeEdge 1 2 (1 * 1 * 2 * 2)  == 1 * 1 + 2 * 2

replaceVertex :: Ord a => a -> a -> Relation a -> Relation a Source #

The function replaceVertex x y replaces vertex x with vertex y in a given Relation. If y already exists, x and y will be merged. Complexity: O((n + m) * log(n)) time.

replaceVertex x x            == id
replaceVertex x y (vertex x) == vertex y
replaceVertex x y            == mergeVertices (== x) y

mergeVertices :: Ord a => (a -> Bool) -> a -> Relation a -> Relation a Source #

Merge vertices satisfying a given predicate into a given vertex. Complexity: O((n + m) * log(n)) time, assuming that the predicate takes O(1) to be evaluated.

mergeVertices (const False) x    == id
mergeVertices (== x) y           == replaceVertex x y
mergeVertices even 1 (0 * 2)     == 1 * 1
mergeVertices odd  1 (3 + 4 * 5) == 4 * 1

gmap :: Ord b => (a -> b) -> Relation a -> Relation b Source #

Transform a graph by applying a function to each of its vertices. This is similar to Functor's fmap but can be used with non-fully-parametric Relation. Complexity: O((n + m) * log(n)) time.

gmap f empty      == empty
gmap f (vertex x) == vertex (f x)
gmap f (edge x y) == edge (f x) (f y)
gmap id           == id
gmap f . gmap g   == gmap (f . g)

induce :: (a -> Bool) -> Relation a -> Relation a Source #

Construct the induced subgraph of a given graph by removing the vertices that do not satisfy a given predicate. Complexity: O(m) time, assuming that the predicate takes O(1) to be evaluated.

induce (const True ) x      == x
induce (const False) x      == empty
induce (/= x)               == removeVertex x
induce p . induce q         == induce (\x -> p x && q x)
isSubgraphOf (induce p x) x == True