| Copyright | (c) Andrey Mokhov 2016-2022 |
|---|---|
| License | MIT (see the file LICENSE) |
| Maintainer | [email protected] |
| Stability | experimental |
| Safe Haskell | Safe-Inferred |
| Language | Haskell2010 |
Algebra.Graph.Bipartite.AdjacencyMap
Description
Alga is a library for algebraic construction and manipulation of graphs in Haskell. See this paper for the motivation behind the library, the underlying theory, and implementation details.
This module defines the AdjacencyMap data type for undirected bipartite
graphs and associated functions. See
Algebra.Graph.Bipartite.AdjacencyMap.Algorithm for basic bipartite graph
algorithms.
To avoid name clashes with Algebra.Graph.AdjacencyMap, this module can be imported qualified:
import qualified Algebra.Graph.Bipartite.AdjacencyMap as Bipartite
Synopsis
- data AdjacencyMap a b
- leftAdjacencyMap :: AdjacencyMap a b -> Map a (Set b)
- rightAdjacencyMap :: AdjacencyMap a b -> Map b (Set a)
- empty :: AdjacencyMap a b
- leftVertex :: a -> AdjacencyMap a b
- rightVertex :: b -> AdjacencyMap a b
- vertex :: Either a b -> AdjacencyMap a b
- edge :: a -> b -> AdjacencyMap a b
- overlay :: (Ord a, Ord b) => AdjacencyMap a b -> AdjacencyMap a b -> AdjacencyMap a b
- connect :: (Ord a, Ord b) => AdjacencyMap a b -> AdjacencyMap a b -> AdjacencyMap a b
- vertices :: (Ord a, Ord b) => [a] -> [b] -> AdjacencyMap a b
- edges :: (Ord a, Ord b) => [(a, b)] -> AdjacencyMap a b
- overlays :: (Ord a, Ord b) => [AdjacencyMap a b] -> AdjacencyMap a b
- connects :: (Ord a, Ord b) => [AdjacencyMap a b] -> AdjacencyMap a b
- swap :: AdjacencyMap a b -> AdjacencyMap b a
- toBipartite :: (Ord a, Ord b) => AdjacencyMap (Either a b) -> AdjacencyMap a b
- toBipartiteWith :: (Ord a, Ord b, Ord c) => (a -> Either b c) -> AdjacencyMap a -> AdjacencyMap b c
- fromBipartite :: (Ord a, Ord b) => AdjacencyMap a b -> AdjacencyMap (Either a b)
- fromBipartiteWith :: Ord c => (a -> c) -> (b -> c) -> AdjacencyMap a b -> AdjacencyMap c
- isEmpty :: AdjacencyMap a b -> Bool
- hasLeftVertex :: Ord a => a -> AdjacencyMap a b -> Bool
- hasRightVertex :: Ord b => b -> AdjacencyMap a b -> Bool
- hasVertex :: (Ord a, Ord b) => Either a b -> AdjacencyMap a b -> Bool
- hasEdge :: (Ord a, Ord b) => a -> b -> AdjacencyMap a b -> Bool
- leftVertexCount :: AdjacencyMap a b -> Int
- rightVertexCount :: AdjacencyMap a b -> Int
- vertexCount :: AdjacencyMap a b -> Int
- edgeCount :: AdjacencyMap a b -> Int
- leftVertexList :: AdjacencyMap a b -> [a]
- rightVertexList :: AdjacencyMap a b -> [b]
- vertexList :: AdjacencyMap a b -> [Either a b]
- edgeList :: AdjacencyMap a b -> [(a, b)]
- leftVertexSet :: AdjacencyMap a b -> Set a
- rightVertexSet :: AdjacencyMap a b -> Set b
- vertexSet :: (Ord a, Ord b) => AdjacencyMap a b -> Set (Either a b)
- edgeSet :: (Ord a, Ord b) => AdjacencyMap a b -> Set (a, b)
- leftAdjacencyList :: AdjacencyMap a b -> [(a, [b])]
- rightAdjacencyList :: AdjacencyMap a b -> [(b, [a])]
- data List a b
- evenList :: [(a, b)] -> List a b
- oddList :: a -> [(b, a)] -> List a b
- path :: (Ord a, Ord b) => List a b -> AdjacencyMap a b
- circuit :: (Ord a, Ord b) => [(a, b)] -> AdjacencyMap a b
- biclique :: (Ord a, Ord b) => [a] -> [b] -> AdjacencyMap a b
- star :: (Ord a, Ord b) => a -> [b] -> AdjacencyMap a b
- stars :: (Ord a, Ord b) => [(a, [b])] -> AdjacencyMap a b
- mesh :: (Ord a, Ord b) => [a] -> [b] -> AdjacencyMap (a, b) (a, b)
- removeLeftVertex :: Ord a => a -> AdjacencyMap a b -> AdjacencyMap a b
- removeRightVertex :: Ord b => b -> AdjacencyMap a b -> AdjacencyMap a b
- removeEdge :: (Ord a, Ord b) => a -> b -> AdjacencyMap a b -> AdjacencyMap a b
- bimap :: (Ord a, Ord b, Ord c, Ord d) => (a -> c) -> (b -> d) -> AdjacencyMap a b -> AdjacencyMap c d
- box :: (Ord a, Ord b) => AdjacencyMap a a -> AdjacencyMap b b -> AdjacencyMap (a, b) (a, b)
- boxWith :: (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f) => (a -> c -> e) -> (b -> d -> e) -> (a -> d -> f) -> (b -> c -> f) -> AdjacencyMap a b -> AdjacencyMap c d -> AdjacencyMap e f
- consistent :: (Ord a, Ord b) => AdjacencyMap a b -> Bool
Data structure
data AdjacencyMap a b Source #
The AdjacencyMap data type represents an undirected bipartite
graph. The two type parameters determine the types of vertices of each part. If
the types coincide, the vertices of the left part are still treated as disjoint
from the vertices of the right part. See examples for more details.
We define a Num instance as a convenient notation for working with bipartite
graphs:
0 ==rightVertex0swap1 ==leftVertex1swap1 + 2 ==vertices[1] [2]swap1 * 2 ==edge1 2swap1 + 2 *swap3 ==overlay(leftVertex1) (edge3 2)swap1 * (2 +swap3) ==connect(leftVertex1) (vertices[3] [2])
Note: the Num instance does not satisfy several "customary laws" of Num,
which dictate that fromInteger 0 and fromInteger 1 should act as
additive and multiplicative identities, and negate as additive inverse.
Nevertheless, overloading fromInteger, + and * is very convenient when
working with algebraic graphs; we hope that in future Haskell's Prelude will
provide a more fine-grained class hierarchy for algebraic structures, which we
would be able to utilise without violating any laws.
The Show instance is defined using basic graph construction primitives:
show empty == "empty" show 1 == "rightVertex 1" show (swap2) == "leftVertex 2" show (1 + 2) == "vertices [] [1,2]" show (swap(1 + 2)) == "vertices [1,2] []" show (swap1 * 2) == "edge 1 2" show (swap1 * 2 *swap3) == "edges [(1,2),(3,2)]" show (swap1 * 2 +swap3) == "overlay (leftVertex 3) (edge 1 2)"
The Eq instance satisfies all axioms of undirected bipartite algebraic graphs:
overlayis commutative and associative:x + y == y + x x + (y + z) == (x + y) + z
connectis commutative, associative and hasemptyas the identity:x * empty == x empty * x == x x * y == y * x x * (y * z) == (x * y) * zconnectdistributes overoverlay:x * (y + z) == x * y + x * z (x + y) * z == x * z + y * z
connectcan be decomposed:x * y * z == x * y + x * z + y * z
connecthas the same effect asoverlayon vertices of the same part:leftVertex x * leftVertex y == leftVertex x + leftVertex y rightVertex x * rightVertex y == rightVertex x + rightVertex y
The following useful theorems can be proved from the above set of axioms.
overlayhasemptyas the identity and is idempotent:x + empty == x empty + x == x x + x == xAbsorption and saturation of
connect:x * y + x + y == x * y x * x * x == x * x
When specifying the time and memory complexity of graph algorithms, n and m will denote the number of vertices and edges of the graph, respectively. In addition, l and r will denote the number of vertices in the left and right parts of the graph, respectively.
Instances
leftAdjacencyMap :: AdjacencyMap a b -> Map a (Set b) Source #
The adjacency map of the left part of the graph: each left vertex is associated with a set of its right neighbours. Complexity: O(1) time and memory.
leftAdjacencyMapempty== Map.emptyleftAdjacencyMap (leftVertexx) == Map.singletonx Set.emptyleftAdjacencyMap (rightVertexx) == Map.emptyleftAdjacencyMap (edgex y) == Map.singletonx (Set.singletony)
rightAdjacencyMap :: AdjacencyMap a b -> Map b (Set a) Source #
The adjacency map of the right part of the graph: each right vertex is associated with a set of its left neighbours. Complexity: O(1) time and memory.
rightAdjacencyMapempty== Map.emptyrightAdjacencyMap (leftVertexx) == Map.emptyrightAdjacencyMap (rightVertexx) == Map.singletonx Set.emptyrightAdjacencyMap (edgex y) == Map.singletony (Set.singletonx)
Basic graph construction primitives
empty :: AdjacencyMap a b Source #
Construct the empty graph.
isEmptyempty == TrueleftAdjacencyMapempty == Map.emptyrightAdjacencyMapempty == Map.emptyhasVertexx empty == False
leftVertex :: a -> AdjacencyMap a b Source #
Construct the graph comprising a single isolated vertex in the left part.
leftAdjacencyMap(leftVertex x) == Map.singletonx Set.emptyrightAdjacencyMap(leftVertex x) == Map.emptyhasLeftVertexx (leftVertex y) == (x == y)hasRightVertexx (leftVertex y) == FalsehasEdgex y (leftVertex z) == False
rightVertex :: b -> AdjacencyMap a b Source #
Construct the graph comprising a single isolated vertex in the right part.
leftAdjacencyMap(rightVertex x) == Map.emptyrightAdjacencyMap(rightVertex x) == Map.singletonx Set.emptyhasLeftVertexx (rightVertex y) == FalsehasRightVertexx (rightVertex y) == (x == y)hasEdgex y (rightVertex z) == False
vertex :: Either a b -> AdjacencyMap a b Source #
Construct the graph comprising a single isolated vertex.
vertex . Left ==leftVertexvertex . Right ==rightVertex
edge :: a -> b -> AdjacencyMap a b Source #
Construct the graph comprising a single edge.
edge x y ==connect(leftVertexx) (rightVertexy)leftAdjacencyMap(edge x y) == Map.singletonx (Set.singletony)rightAdjacencyMap(edge x y) == Map.singletony (Set.singletonx)hasEdgex y (edge x y) == TruehasEdge1 2 (edge 2 1) == False
overlay :: (Ord a, Ord b) => AdjacencyMap a b -> AdjacencyMap a b -> AdjacencyMap a b 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) ==isEmptyx &&isEmptyyhasVertexz (overlay x y) ==hasVertexz x ||hasVertexz yvertexCount(overlay x y) >=vertexCountxvertexCount(overlay x y) <=vertexCountx +vertexCountyedgeCount(overlay x y) >=edgeCountxedgeCount(overlay x y) <=edgeCountx +edgeCounty
connect :: (Ord a, Ord b) => AdjacencyMap a b -> AdjacencyMap a b -> AdjacencyMap a b Source #
Connect two graphs, filtering out the edges between vertices of the same
part. 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 in the arguments: O(m1 + m2 + l1 * r2 + l2 * r1).
connect (leftVertexx) (leftVertexy) ==vertices[x,y] [] connect (leftVertexx) (rightVertexy) ==edgex y connect (rightVertexx) (leftVertexy) ==edgey x connect (rightVertexx) (rightVertexy) ==vertices[] [x,y] connect (verticesxs1 ys1) (verticesxs2 ys2) ==overlay(bicliquexs1 ys2) (bicliquexs2 ys1)isEmpty(connect x y) ==isEmptyx &&isEmptyyhasVertexz (connect x y) ==hasVertexz x ||hasVertexz yvertexCount(connect x y) >=vertexCountxvertexCount(connect x y) <=vertexCountx +vertexCountyedgeCount(connect x y) >=edgeCountxedgeCount(connect x y) >=leftVertexCountx *rightVertexCountyedgeCount(connect x y) <=leftVertexCountx *rightVertexCounty +rightVertexCountx *leftVertexCounty +edgeCountx +edgeCounty
vertices :: (Ord a, Ord b) => [a] -> [b] -> AdjacencyMap a b Source #
Construct the graph comprising given lists of isolated vertices in each part. Complexity: O(L * log(L)) time and O(L) memory, where L is the total length of two lists.
vertices [] [] ==emptyvertices [x] [] ==leftVertexx vertices [] [x] ==rightVertexx vertices xs ys ==overlays(mapleftVertexxs ++maprightVertexys)hasLeftVertexx (vertices xs ys) ==elemx xshasRightVertexy (vertices xs ys) ==elemy ys
overlays :: (Ord a, Ord b) => [AdjacencyMap a b] -> AdjacencyMap a b Source #
connects :: (Ord a, Ord b) => [AdjacencyMap a b] -> AdjacencyMap a b Source #
swap :: AdjacencyMap a b -> AdjacencyMap b a Source #
Conversion functions
toBipartite :: (Ord a, Ord b) => AdjacencyMap (Either a b) -> AdjacencyMap a b Source #
Construct a bipartite AdjacencyMap from an Algebra.Graph.AdjacencyMap,
adding any missing edges to make the graph undirected and filtering out the
edges within the same parts.
Complexity: O(m * log(n)).
toBipartiteempty==emptytoBipartite (vertex(Left x)) ==leftVertexx toBipartite (vertex(Right x)) ==rightVertexx toBipartite (edge(Left x) (Left y)) ==vertices[x,y] [] toBipartite (edge(Left x) (Right y)) ==edgex y toBipartite (edge(Right x) (Left y)) ==edgey x toBipartite (edge(Right x) (Right y)) ==vertices[] [x,y] toBipartite .clique==uncurrybiclique.partitionEitherstoBipartite .fromBipartite==id
toBipartiteWith :: (Ord a, Ord b, Ord c) => (a -> Either b c) -> AdjacencyMap a -> AdjacencyMap b c Source #
Construct a bipartite AdjacencyMap from an Algebra.Graph.AdjacencyMap,
where the two parts are identified by a separate function, adding any missing
edges to make the graph undirected and filtering out the edges within the
same parts.
Complexity: O(m * log(n)).
toBipartiteWith fempty==emptytoBipartiteWith Left x ==vertices(vertexListx) [] toBipartiteWith Right x ==vertices[] (vertexListx) toBipartiteWith f ==toBipartite.gmapf toBipartiteWith id ==toBipartite
fromBipartite :: (Ord a, Ord b) => AdjacencyMap a b -> AdjacencyMap (Either a b) Source #
Construct an Algebra.Graph.AdjacencyMap from a bipartite AdjacencyMap.
Complexity: O(m * log(n)).
fromBipartiteempty==emptyfromBipartite (leftVertexx) ==vertex(Left x) fromBipartite (edgex y) ==edges[(Left x, Right y), (Right y, Left x)]toBipartite. fromBipartite ==id
fromBipartiteWith :: Ord c => (a -> c) -> (b -> c) -> AdjacencyMap a b -> AdjacencyMap c Source #
Construct an Algebra.Graph.AdjacencyMap from a bipartite AdjacencyMap
given a way to inject vertices of the two parts into the resulting vertex
type.
Complexity: O(m * log(n)).
fromBipartiteWith Left Right ==fromBipartitefromBipartiteWith id id (verticesxs ys) ==vertices(xs ++ ys) fromBipartiteWith id id .edges==symmetricClosure.edges
Graph properties
isEmpty :: AdjacencyMap a b -> Bool Source #
hasLeftVertex :: Ord a => a -> AdjacencyMap a b -> Bool Source #
Check if a graph contains a given vertex in the left part. Complexity: O(log(l)) time.
hasLeftVertex xempty== False hasLeftVertex x (leftVertexy) == (x == y) hasLeftVertex x (rightVertexy) == False
hasRightVertex :: Ord b => b -> AdjacencyMap a b -> Bool Source #
Check if a graph contains a given vertex in the right part. Complexity: O(log(r)) time.
hasRightVertex xempty== False hasRightVertex x (leftVertexy) == False hasRightVertex x (rightVertexy) == (x == y)
hasVertex :: (Ord a, Ord b) => Either a b -> AdjacencyMap a b -> Bool Source #
Check if a graph contains a given vertex. Complexity: O(log(n)) time.
hasVertex . Left ==hasLeftVertexhasVertex . Right ==hasRightVertex
leftVertexCount :: AdjacencyMap a b -> Int Source #
The number of vertices in the left part of a graph. Complexity: O(1) time.
leftVertexCountempty== 0 leftVertexCount (leftVertexx) == 1 leftVertexCount (rightVertexx) == 0 leftVertexCount (edgex y) == 1 leftVertexCount .edges==length.nub.mapfst
rightVertexCount :: AdjacencyMap a b -> Int Source #
The number of vertices in the right part of a graph. Complexity: O(1) time.
rightVertexCountempty== 0 rightVertexCount (leftVertexx) == 0 rightVertexCount (rightVertexx) == 1 rightVertexCount (edgex y) == 1 rightVertexCount .edges==length.nub.mapsnd
vertexCount :: AdjacencyMap a b -> Int Source #
The number of vertices in a graph. Complexity: O(1) time.
vertexCountempty== 0 vertexCount (vertexx) == 1 vertexCount (edgex y) == 2 vertexCount x ==leftVertexCountx +rightVertexCountx
edgeCount :: AdjacencyMap a b -> Int Source #
leftVertexList :: AdjacencyMap a b -> [a] Source #
The sorted list of vertices of the left part of a graph. Complexity: O(l) time and memory.
leftVertexListempty== [] leftVertexList (leftVertexx) == [x] leftVertexList (rightVertexx) == [] leftVertexList .flipvertices[] ==nub.sort
rightVertexList :: AdjacencyMap a b -> [b] Source #
The sorted list of vertices of the right part of a graph. Complexity: O(r) time and memory.
rightVertexListempty== [] rightVertexList (leftVertexx) == [] rightVertexList (rightVertexx) == [x] rightVertexList .vertices[] ==nub.sort
vertexList :: AdjacencyMap a b -> [Either a b] Source #
edgeList :: AdjacencyMap a b -> [(a, b)] Source #
leftVertexSet :: AdjacencyMap a b -> Set a Source #
The set of vertices of the left part of a graph. Complexity: O(l) time and memory.
leftVertexSetempty== Set.emptyleftVertexSet .leftVertex== Set.singletonleftVertexSet .rightVertex==constSet.emptyleftVertexSet .flipvertices[] == Set.fromList
rightVertexSet :: AdjacencyMap a b -> Set b Source #
The set of vertices of the right part of a graph. Complexity: O(r) time and memory.
rightVertexSetempty== Set.emptyrightVertexSet .leftVertex==constSet.emptyrightVertexSet .rightVertex== Set.singletonrightVertexSet .vertices[] == Set.fromList
leftAdjacencyList :: AdjacencyMap a b -> [(a, [b])] Source #
The sorted adjacency list of the left part of a graph. Complexity: O(n + m) time and memory.
leftAdjacencyListempty== [] leftAdjacencyList (vertices[] xs) == [] leftAdjacencyList (verticesxs []) == [(x, []) | x <-nub(sortxs)] leftAdjacencyList (edgex y) == [(x, [y])] leftAdjacencyList (starx ys) == [(x,nub(sortys))]
rightAdjacencyList :: AdjacencyMap a b -> [(b, [a])] Source #
The sorted adjacency list of the right part of a graph. Complexity: O(n + m) time and memory.
rightAdjacencyListempty== [] rightAdjacencyList (vertices[] xs) == [(x, []) | x <-nub(sortxs)] rightAdjacencyList (verticesxs []) == [] rightAdjacencyList (edgex y) == [(y, [x])] rightAdjacencyList (starx ys) == [(y, [x]) | y <-nub(sortys)]
Standard families of graphs
A list of values of two alternating types. The first type argument denotes the type of the value at the head.
With the OverloadedLists extension it is possible to use the standard list
notation to construct a List where the two types coincide, for example:
[1, 2, 3, 4, 5] :: List Int Int
We make use of this shorthand notation in the examples below.
Instances
| IsList (List a a) Source # | |
| Generic (List a b) Source # | |
| (Show a, Show b) => Show (List a b) Source # | |
| (Eq a, Eq b) => Eq (List a b) Source # | |
| (Ord a, Ord b) => Ord (List a b) Source # | |
Defined in Algebra.Graph.Bipartite.AdjacencyMap | |
| type Item (List a a) Source # | |
Defined in Algebra.Graph.Bipartite.AdjacencyMap | |
| type Rep (List a b) Source # | |
Defined in Algebra.Graph.Bipartite.AdjacencyMap type Rep (List a b) = D1 ('MetaData "List" "Algebra.Graph.Bipartite.AdjacencyMap" "algebraic-graphs-0.7-CoSSqC3utlQHXcd8nDsyLt" 'False) (C1 ('MetaCons "Nil" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Cons" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (List b a)))) | |
circuit :: (Ord a, Ord b) => [(a, b)] -> AdjacencyMap a b Source #
The circuit on a list of pairs of vertices. Complexity: O(L * log(L)) time, where L is the length of the given list.
circuit [] ==emptycircuit [(x,y)] ==edgex y circuit [(1,2), (3,4), (5,6)] ==edges[(1,2), (3,2), (3,4), (5,4), (5,6), (1,6)] circuit .reverse==swap. circuit .mapData.Tuple.swap
star :: (Ord a, Ord b) => a -> [b] -> AdjacencyMap a b Source #
The star formed by a center vertex connected to a list of leaves. Complexity: O(L * log(L)) time, where L is the length of the given list.
star x [] ==leftVertexx star x [y] ==edgex y star x [y,z] ==edges[(x,y), (x,z)] star x ys ==connect(leftVertexx) (vertices[] ys)
stars :: (Ord a, Ord b) => [(a, [b])] -> AdjacencyMap a b Source #
The stars formed by overlaying a list of stars.
Complexity: O(L * log(L)) time, where L is the total size of the input.
stars [] ==emptystars [(x, [])] ==leftVertexx stars [(x, [y])] ==edgex y stars [(x, ys)] ==starx ys stars ==overlays.map(uncurrystar)overlay(stars xs) (stars ys) == stars (xs ++ ys)
mesh :: (Ord a, Ord b) => [a] -> [b] -> AdjacencyMap (a, b) (a, b) Source #
Construct a mesh graph from two lists of vertices. Complexity: O(L1 * L2 * log(L1 * L2)) time, where L1 and L2 are the lengths of the given lists.
mesh xs [] ==emptymesh [] ys ==emptymesh [x] [y] ==leftVertex(x,y) mesh [1,1] ['a','b'] ==biclique[(1,'a'), (1,'b')] [(1,'a'), (1,'b')] mesh [1,2] ['a','b'] ==biclique[(1,'a'), (2,'b')] [(1,'b'), (2,'a')]
Graph transformation
removeLeftVertex :: Ord a => a -> AdjacencyMap a b -> AdjacencyMap a b Source #
Remove a vertex from the left part of a given graph. Complexity: O(r * log(l)) time.
removeLeftVertex x (leftVertexx) ==emptyremoveLeftVertex 1 (leftVertex2) ==leftVertex2 removeLeftVertex x (rightVertexy) ==rightVertexy removeLeftVertex x (edgex y) ==rightVertexy removeLeftVertex x . removeLeftVertex x == removeLeftVertex x
removeRightVertex :: Ord b => b -> AdjacencyMap a b -> AdjacencyMap a b Source #
Remove a vertex from the right part of a given graph. Complexity: O(l * log(r)) time.
removeRightVertex x (rightVertexx) ==emptyremoveRightVertex 1 (rightVertex2) ==rightVertex2 removeRightVertex x (leftVertexy) ==leftVertexy removeRightVertex y (edgex y) ==leftVertexx removeRightVertex x . removeRightVertex x == removeRightVertex x
removeEdge :: (Ord a, Ord b) => a -> b -> AdjacencyMap a b -> AdjacencyMap a b Source #
Remove an edge from a given graph. Complexity: O(log(l) + log(r)) time.
removeEdge x y (edgex y) ==vertices[x] [y] removeEdge x y . removeEdge x y == removeEdge x y removeEdge x y .removeLeftVertexx ==removeLeftVertexx removeEdge x y .removeRightVertexy ==removeRightVertexy
bimap :: (Ord a, Ord b, Ord c, Ord d) => (a -> c) -> (b -> d) -> AdjacencyMap a b -> AdjacencyMap c d Source #
Transform a graph by applying given functions to the vertices of each part. Complexity: O((n + m) * log(n)) time.
bimap f gempty==emptybimap f g .vertex==vertex. Data.Bifunctor.bimapf g bimap f g (edgex y) ==edge(f x) (g y) bimapidid==idbimap f1 g1 . bimap f2 g2 == bimap (f1 . f2) (g1 . g2)
Graph composition
box :: (Ord a, Ord b) => AdjacencyMap a a -> AdjacencyMap b b -> AdjacencyMap (a, b) (a, b) Source #
Compute the Cartesian product of two graphs. Complexity: O((n + m) * log(n)) time and O(n + m) memory.
box(path[0,1]) (path['a','b']) ==edges[ ((0,'a'), (0,'b')) , ((0,'a'), (1,'a')) , ((1,'b'), (0,'b')) , ((1,'b'), (1,'a')) ]
Up to isomorphism between the resulting vertex types, this operation is
commutative, associative, distributes over overlay, has singleton
graphs as identities and swapping identities, and empty as the
annihilating zero. Below ~~ stands for equality up to an isomorphism,
e.g. (x, ()) ~~ x.
box x y ~~ box y x box x (box y z) ~~ box (box x y) z box x (overlayy z) ==overlay(box x y) (box x z) box x (leftVertex()) ~~ x box x (rightVertex()) ~~swapx box xempty~~emptyvertexCount(box x y) ==vertexCountx *vertexCountyedgeCount(box x y) ==vertexCountx *edgeCounty +edgeCountx *vertexCounty
boxWith :: (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f) => (a -> c -> e) -> (b -> d -> e) -> (a -> d -> f) -> (b -> c -> f) -> AdjacencyMap a b -> AdjacencyMap c d -> AdjacencyMap e f Source #
Compute the generalised Cartesian product of two graphs. The resulting vertices are obtained using the given vertex combinators. Complexity: O((n + m) * log(n)) time and O(n + m) memory.
See box for some examples.
box == boxWith (,) (,) (,) (,)
Miscellaneous
consistent :: (Ord a, Ord b) => AdjacencyMap a b -> Bool Source #
Check that the internal graph representation is consistent, i.e. that all
edges that are present in the leftAdjacencyMap are also present in the
rightAdjacencyMap map. It should be impossible to create an inconsistent
adjacency map, and we use this function in testing.
consistentempty== True consistent (vertexx) == True consistent (edgex y) == True consistent (edgesx) == True consistent (toBipartitex) == True consistent (swapx) == True consistent (circuitx) == True consistent (bicliquex y) == True