| Copyright | (c) Andrey Mokhov 2016-2019 |
|---|---|
| License | MIT (see the file LICENSE) |
| Maintainer | andrey.mokhov@gmail.com |
| Stability | experimental |
| Safe Haskell | None |
| Language | Haskell2010 |
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 Relation a
- toSymmetric :: Ord a => Relation a -> Relation a
- fromSymmetric :: Relation a -> Relation a
- empty :: Relation a
- vertex :: a -> Relation a
- edge :: Ord a => a -> a -> Relation a
- overlay :: Ord a => Relation a -> Relation a -> Relation a
- connect :: Ord a => Relation a -> Relation a -> Relation a
- vertices :: Ord a => [a] -> Relation a
- edges :: Ord a => [(a, a)] -> Relation a
- overlays :: Ord a => [Relation a] -> Relation a
- connects :: Ord a => [Relation a] -> Relation a
- isSubgraphOf :: Ord a => Relation a -> Relation a -> Bool
- isEmpty :: Relation a -> Bool
- hasVertex :: Ord a => a -> Relation a -> Bool
- hasEdge :: Ord a => a -> a -> Relation a -> Bool
- vertexCount :: Relation a -> Int
- edgeCount :: Ord a => Relation a -> Int
- vertexList :: Relation a -> [a]
- edgeList :: Ord a => Relation a -> [(a, a)]
- adjacencyList :: Eq a => Relation a -> [(a, [a])]
- vertexSet :: Relation a -> Set a
- edgeSet :: Ord a => Relation a -> Set (a, a)
- neighbours :: Ord a => a -> Relation a -> Set a
- path :: Ord a => [a] -> Relation a
- circuit :: Ord a => [a] -> Relation a
- clique :: Ord a => [a] -> Relation a
- biclique :: Ord a => [a] -> [a] -> Relation a
- star :: Ord a => a -> [a] -> Relation a
- stars :: Ord a => [(a, [a])] -> Relation a
- tree :: Ord a => Tree a -> Relation a
- forest :: Ord a => Forest a -> Relation a
- removeVertex :: Ord a => a -> Relation a -> Relation a
- removeEdge :: Ord a => a -> a -> Relation a -> Relation a
- replaceVertex :: Ord a => a -> a -> Relation a -> Relation a
- mergeVertices :: Ord a => (a -> Bool) -> a -> Relation a -> Relation a
- gmap :: Ord b => (a -> b) -> Relation a -> Relation b
- induce :: (a -> Bool) -> Relation a -> Relation a
Data structure
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:
connectx y ==connecty 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:
vertex1 <vertex2vertex3 <edge1 2vertex1 <edge1 1edge1 1 <edge1 2edge1 2 <edge1 1 +edge2 2edge2 1 <edge1 3
edge1 2 ==edge2 1
Note that the resulting order refines the
isSubgraphOf relation and is compatible with
overlay and connect operations:
isSubgraphOf x y ==> x <= yempty <= x
x <= x + y
x + y <= x * yInstances
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 (edge1 2) ==edge1 2 toSymmetric .fromSymmetric== idfromSymmetric. toSymmetric ==symmetricClosurevertexCount. 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 (edge1 2) ==edges[(1,2), (2,1)]vertexCount. fromSymmetric ==vertexCountedgeCount. fromSymmetric <= (*2) .edgeCount
Basic graph construction primitives
Construct the empty graph. Complexity: O(1) time and memory.
isEmptyempty == TruehasVertexx empty == FalsevertexCountempty == 0edgeCountempty == 0
vertex :: a -> Relation a Source #
Construct the graph comprising a single isolated vertex. Complexity: O(1) time and memory.
isEmpty(vertex x) == FalsehasVertexx (vertex x) == TruevertexCount(vertex x) == 1edgeCount(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(vertexx) (vertexy) edge x y ==edgey x edge x y ==edges[(x,y), (y,x)]hasEdgex y (edge x y) == TrueedgeCount(edge x y) == 1vertexCount(edge 1 1) == 1vertexCount(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) ==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 +edgeCountyvertexCount(overlay 1 2) == 2edgeCount(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 xisEmpty(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) >=edgeCountyedgeCount(connect x y) >=vertexCountx *vertexCounty `div` 2vertexCount(connect 1 2) == 2edgeCount(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 [] ==emptyvertices [x] ==vertexxhasVertexx . vertices ==elemxvertexCount. vertices ==length.nubvertexSet. vertices == Set.fromList
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.
isSubgraphOfemptyx == True isSubgraphOf (vertexx)empty== False isSubgraphOf x (overlayx y) == True isSubgraphOf (overlayx y) (connectx y) == True isSubgraphOf (pathxs) (circuitxs) == True isSubgraphOf (edgex y) (edgey x) == True isSubgraphOf x y ==> x <= y
Graph properties
isEmpty :: Relation a -> Bool Source #
Check if a relation is empty. Complexity: O(1) time.
isEmptyempty== True isEmpty (overlayemptyempty) == True isEmpty (vertexx) == False isEmpty (removeVertexx $vertexx) == True isEmpty (removeEdgex y $edgex y) == False
hasVertex :: Ord a => a -> Relation a -> Bool Source #
Check if a graph contains a given vertex. Complexity: O(log(n)) time.
hasVertex xempty== False hasVertex x (vertexx) == True hasVertex 1 (vertex2) == False hasVertex x .removeVertexx ==constFalse
vertexCount :: Relation a -> Int Source #
The number of vertices in a graph. Complexity: O(1) time.
vertexCountempty== 0 vertexCount (vertexx) == 1 vertexCount ==length.vertexListvertexCount x < vertexCount y ==> x < y
vertexList :: Relation a -> [a] Source #
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
edgeListempty== [] edgeList (vertexx) == [] edgeList (edgex y) == [(min x y, max y x)] edgeList (star2 [3,1]) == [(1,2), (2,3)]
adjacencyList :: Eq a => Relation a -> [(a, [a])] Source #
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 . The latter is much
faster than this function, and takes only O(1) time and memory.relation . fromSymmetric
edgeSetempty== Set.emptyedgeSet (vertexx) == Set.emptyedgeSet (edgex 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 xempty== Set.emptyneighbours x (vertexx) == Set.emptyneighbours x (edgex y) == Set.fromList[y] neighbours y (edgex y) == Set.fromList[x]
Standard families of graphs
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 [] ==emptyclique [x] ==vertexx clique [x,y] ==edgex 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 [] [] ==emptybiclique [x] [] ==vertexx biclique [] [y] ==vertexy biclique [x1,x2] [y1,y2] ==edges[(x1,y1), (x1,y2), (x2,x2), (x2,y2)] biclique xs ys ==connect(verticesxs) (verticesys)
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 [] ==emptystars [(x, [])] ==vertexx stars [(x, [y])] ==edgex y stars [(x, ys)] ==starx ys stars ==overlays.map(uncurrystar) stars .adjacencyList== idoverlay(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 []) ==vertexx tree (Node x [Node y [Node z []]]) ==path[x,y,z] tree (Node x [Node y [], Node z []]) ==starx [y,z] tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) ==edges[(1,2), (1,3), (3,4), (3,5)]
Graph transformation
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 (edgex y) ==vertices[x,y] removeEdge x y . removeEdge x y == removeEdge x y removeEdge x y == removeEdge y x removeEdge x y .removeVertexx ==removeVertexx 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 replaces vertex replaceVertex x yx 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 (vertexx) ==vertexy 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 (constFalse) x == id mergeVertices (== x) y ==replaceVertexx y mergeVerticeseven1 (0 * 2) == 1 * 1 mergeVerticesodd1 (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 fempty==emptygmap f (vertexx) ==vertex(f x) gmap f (edgex 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 (constTrue ) x == x induce (constFalse) x ==emptyinduce (/= x) ==removeVertexx induce p . induce q == induce (\x -> p x && q x)isSubgraphOf(induce p x) x == True