úÎSè<ÿ˜      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ                                  ! " # $ % &'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—(c) Andrey Mokhov 2016-2017MIT (see the file LICENSE)andrey.mokhov@gmail.com experimentalNone :DILRT&The o type class captures data types that can be converted to polymorphic graph expressions. The conversion method ƒ semantically acts as the identity on graph data structures, but allows to convert graphs between different data representations.  toGraph (g ::  a ) ::  a == g ˜ (toGraph (1 * 2 ::  Int) ::  Int) == "edge 1 2"  The class of preorder graphs( that are both reflexive and transitive. The class of transitive graphs- that satisfy the following additional axiom.The closure8 axiom: graphs with equal transitive closures are equal. 5y /= empty ==> x * y + x * z + y * z == x * y + y * zpBy repeated application of the axiom one can turn any graph into its transitive closure or transitive reduction. The class of reflexive graphs- that satisfy the following additional axiom.Each vertex has a  self-loop: vertex x == vertex x * vertex x'Or, alternatively, if we remember that   is an alias for ™: pure x == pure x * pure xoNote that by applying the axiom in the reverse direction, one can always remove all self-loops resulting in an irreflexive graphR. This type class can therefore be also used in the context of irreflexive graphs. The class of undirected graphs- that satisfy the following additional axiom. is commutative: x * y == y * xTThe core type class for constructing algebraic graphs is defined by introducing the  method to the standard š2 class and reusing the following existing methods:The  method comes from the  class and corresponds to the  empty graph#. This module simply re-exports it.The  . graph construction primitive is an alias for ™ of the › type class.Graph   is an alias for œ of the š type class.The Y type class is characterised by the following minimal set of axioms. In equations we use + and * as convenient shortcuts for   and , respectively.  is commutative and associative: / x + y == y + x x + (y + z) == (x + y) + z is associative and has  as the identity: < x * empty == x empty * x == x x * (y * z) == (x * y) * z distributes over  : 9x * (y + z) == x * y + x * z (x + y) * z == x * z + y * z can be decomposed: "x * y * z == x * y + x * z + y * zIThe following useful theorems can be proved from the above set of axioms.  has # as the identity and is idempotent: 2 x + empty == x empty + x == x x + x == xAbsorption and saturation of : -x * y + x + y == x * y x * x * x == x * xThe core type class , corresponds to unlabelled directed graphs. , ,  and ? graphs can be obtained by extending the minimal set of axioms.DWhen specifying the time and memory complexity of graph algorithms, n2 will denote the number of vertices in the graph, m3 will denote the number of edges in the graph, and s will denote the size of the corresponding  expression.Connect two graphs. FConstruct the graph comprising a single isolated vertex. An alias for ™. !Overlay two graphs. An alias for . ;Construct the graph comprising a single edge. Complexity: O(1) time, memory and size. edge x y ==  (  x) (  y)  (edge 1 1) == 1  (edge 1 2) == 2 OConstruct the graph comprising a given list of isolated vertices. Complexity: O(L) time, memory and size, where L" is the length of the given list. vertices [] ==  vertices [x] ==   x  x . vertices == ž x  . vertices == Ÿ .   . vertices == Set.  7Construct the graph from a list of edges. Complexity: O(L) time, memory and size, where L" is the length of the given list. edges [] ==  edges [(x,y)] ==   x y -Overlay a given list of graphs. Complexity: O(L) time and memory, and O(S) size, where L' is the length of the given list, and S/ is the sum of sizes of the graphs in the list. overlays [] == / overlays [x] == x overlays [x,y] ==   x y  . overlays == ¡  -Connect a given list of graphs. Complexity: O(L) time and memory, and O(S) size, where L' is the length of the given list, and S/ is the sum of sizes of the graphs in the list. connects [] == / connects [x] == x connects [x,y] ==  x y  . connects == ¡  1Construct the graph from given lists of vertices V and edges E-. The resulting graph contains the vertices V7 as well as all the vertices referred to by the edges E. Complexity:  O(|V| + |E|) time, memory and size. graph [] [] ==  graph [x] [] ==   x graph [] [(x,y)] ==   x y graph vs es ==   (  vs) (  es) The ' function takes two graphs and returns ¢ if the first graph is a subgraph3 of the second. Here is the current implementation: isSubgraphOf x y =   x y == y gThe complexity therefore depends on the complexity of equality testing of the specific graph instance.  isSubgraphOf - x == True isSubgraphOf (  x) . == False isSubgraphOf x (  x y) == True isSubgraphOf (  x y) ( x y) == True isSubgraphOf ( xs) ( xs) == True 2Check if a graph is empty. A convenient alias for £. Complexity: O(s) time. isEmpty ( == True isEmpty (   ) == True isEmpty ( ' x) == False isEmpty (# x $   x) == True ACheck if a graph contains a given vertex. A convenient alias for ž. Complexity: O(s) time.  hasVertex x " == False hasVertex x (  x) == True hasVertex x . # x == const False 0The number of vertices in a graph. Complexity:  O(s * log(n)) time.  vertexCount  == 0 vertexCount ( # x) == 1 vertexCount == Ÿ .  ;The sorted list of vertices of a given graph. Complexity:  O(s * log(n)) time and O(n) memory.  vertexList  == [] vertexList (  x) == [x] vertexList .   ==  .  3The set of vertices of a given graph. Complexity:  O(s * log(n)) time and O(n) memory.  vertexSet  == Set.¤ vertexSet .   == Set.¥ vertexSet .   == Set.  vertexSet .  == Set.  +The set of vertices of a given graph. Like 3 but specialised for graphs with vertices of type ¦. Complexity:  O(s * log(n)) time and O(n) memory.  vertexIntSet  == IntSet.§ vertexIntSet .   == IntSet.¨ vertexIntSet .   == IntSet.© vertexIntSet .  == IntSet.© The path% on a list of vertices. Complexity: O(L) time, memory and size, where L" is the length of the given list. path [] ==  path [x] ==   x path [x,y] ==   x y The circuit% on a list of vertices. Complexity: O(L) time, memory and size, where L" is the length of the given list. circuit [] ==  circuit [x] ==   x x circuit [x,y] ==   [(x,y), (y,x)] The clique% on a list of vertices. Complexity: O(L) time, memory and size, where L" is the length of the given list. clique [] ==  clique [x] ==   x clique [x,y] ==   x y clique [x,y,z] ==   [(x,y), (x,z), (y,z)] The biclique% on a list of vertices. Complexity:  O(L1 + L2) time, memory and size, where L1 and L2% are the lengths of the given lists. biclique [] [] ==  biclique [x] [] ==   x biclique [] [y] ==   y biclique [x1,x2] [y1,y2] ==  B [(x1,y1), (x1,y2), (x2,y1), (x2,y2)] biclique xs ys ==  (  xs) (  ys) The star> formed by a centre vertex and a list of leaves. Complexity: O(L) time, memory and size, where L" is the length of the given list. star x [] ==   x star x [y] ==   x y star x [y,z] ==   [(x,y), (x,z)] The  tree graph constructed from a given ª data structure. Complexity: O(T) time, memory and size, where TJ is the size of the given tree (i.e. the number of vertices in the tree). <tree (Node x []) ==  ? x tree (Node x [Node y [Node z []]]) == E [x,y,z] tree (Node x [Node y [], Node z []]) == E x [y,z] tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) ==   [(1,2), (1,3), (3,4), (3,5)] The  forest graph constructed from a given « data structure. Complexity: O(F) time, memory and size, where FN is the size of the given forest (i.e. the number of vertices in the forest). >forest [] == ? forest [x] == A x forest [Node 1 [Node 2 [], Node 3 []], Node 4 [Node 5 []]] ==  U [(1,2), (1,3), (4,5)] forest ==  . map   Construct a  mesh graph* from two lists of vertices. Complexity:  O(L1 * L2) time, memory and size, where L1 and L2% are the lengths of the given lists. mesh xs [] ==  mesh [] ys ==  mesh [x] [y] ==   (x, y) mesh xs ys == ' ( xs) ( ys) mesh [1..3] "ab" ==  ¤ [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(2,'b')), ((2,'a'),(2,'b')) , ((2,'a'),(3,'a')), ((2,'b'),(3,'b')), ((3,'a'),(3,'b')) ]  Construct a  torus graph* from two lists of vertices. Complexity:  O(L1 * L2) time, memory and size, where L1 and L2% are the lengths of the given lists. torus xs [] ==  torus [] ys ==  torus [x] [y] ==  # (x, y) (x, y) torus xs ys == ' ( xs) ( ys) torus [1,2] "ab" ==  · [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(1,'a')), ((1,'b'),(2,'b')) , ((2,'a'),(1,'a')), ((2,'a'),(2,'b')), ((2,'b'),(1,'b')), ((2,'b'),(2,'a')) ] ! Construct a De Bruijn graphV of a given non-negative dimension using symbols from a given alphabet. Complexity:  O(A^(D + 1)) time, memory and size, where A" is the size of the alphabet and D is the dimention of the graph. ) deBruijn 0 xs ==   [] [] n > 0  deBruijn n [] == * deBruijn 1 [0,1] ==  Y [ ([0],[0]), ([0],[1]), ([1],[0]), ([1],[1]) ] deBruijn 2 "0" ==  4 "00" "00" deBruijn 2 "01" ==  ¦ [ ("00","00"), ("00","01"), ("01","10"), ("01","11") , ("10","00"), ("10","01"), ("11","10"), ("11","11") ]  (deBruijn n xs) == (Ÿ $  xs)^n n > 0   edgeCount (deBruijn n xs) == (Ÿ $  xs)^(n + 1) "Construct the induced subgraph` of a given graph by removing the vertices that do not satisfy a given predicate. Complexity: O(s); time, memory and size, assuming that the predicate takes O(1) to be evaluated. @induce (const True) x == x induce (const False) x ==  induce (/= x) == #< x induce p . induce q == induce (\x -> p x && q x)  (induce p x) x == True #1Remove a vertex from a given graph. Complexity: O(s) time, memory and size. removeVertex x (  x) == 3 removeVertex x . removeVertex x == removeVertex x $ The function $ x y replaces vertex x with vertex y in a given . If y already exists, x and y will be merged. Complexity: O(s) time, memory and size. 6replaceVertex x x == id replaceVertex x y (  x) ==  # y replaceVertex x y == % (== x) y %NMerge vertices satisfying a given predicate with a given vertex. Complexity: O(s); time, memory and size, assuming that the predicate takes O(1) to be evaluated. KmergeVertices (const False) x == id mergeVertices (== x) y == $Y x y mergeVertices even 1 (0 * 2) == 1 * 1 mergeVertices odd 1 (3 + 4 * 5) == 4 * 1 &PSplit a vertex into a list of vertices with the same connectivity. Complexity:  O(s + k * L) time, memory and size, where kC is the number of occurrences of the vertex in the expression and L" is the length of the given list. %splitVertex x [] == #P x splitVertex x [x] == id splitVertex x [y] == $< x y splitVertex 1 [0,1] $ 1 * (2 + 3) == (0 + 1) * (2 + 3) ' Compute the Cartesian product of graphs. Complexity:  O(s1 * s2) time, memory and size, where s1 and s2$ are the sizes of the given graphs. box ( [0,1]) ( "ab") ==  É [ ((0,'a'), (0,'b')) , ((0,'a'), (1,'a')) , ((0,'b'), (1,'b')) , ((1,'a'), (1,'b')) ] LUp to an isomorphism between the resulting vertex types, this operation is  commutative,  associative,  distributes over  , has singleton graphs as  identities and  as the annihilating zero. Below ~~5 stands for the equality up to an isomorphism, e.g.  (x, ()) ~~ x. Qbox x y ~~ box y x box x (box y z) ~~ box (box x y) z box x (  y z) ==   (box x y) (box x z) box x (  ()) ~~ x box x  ~~   (box x y) ==  x *  y  edgeCount (box x y) <=  x *  edgeCount y +  edgeCount x *  y '  !"#$%&'(  !"#$%&'(   !#$%&"'%  !"#$%&'(c) Andrey Mokhov 2016-2017MIT (see the file LICENSE)andrey.mokhov@gmail.com experimentalNone :DILRT(The (o type class captures data types that can be converted to polymorphic graph expressions. The conversion method *ƒ semantically acts as the identity on graph data structures, but allows to convert graphs between different data representations.  toGraph (g ::  a ) ::  a == g ˜ (toGraph (1 * 2 ::  Int) ::  Int) == "edge 1 2" + The class of preorder graphs( that are both reflexive and transitive., The class of transitive graphs- that satisfy the following additional axiom.The closure8 axiom: graphs with equal transitive closures are equal. 5y /= empty ==> x * y + x * z + y * z == x * y + y * zpBy repeated application of the axiom one can turn any graph into its transitive closure or transitive reduction.- The class of reflexive graphs- that satisfy the following additional axiom.Each vertex has a  self-loop: vertex x == vertex x * vertex xoNote that by applying the axiom in the reverse direction, one can always remove all self-loops resulting in an irreflexive graphR. This type class can therefore be also used in the context of irreflexive graphs.. The class of undirected graphs- that satisfy the following additional axiom.4 is commutative: x * y == y * x/The core type class for constructing algebraic graphs, characterised by the following minimal set of axioms. In equations we use + and * as convenient shortcuts for 3 and 4, respectively.3 is commutative and associative: / x + y == y + x x + (y + z) == (x + y) + z4 is associative and has 1 as the identity: < x * empty == x empty * x == x x * (y * z) == (x * y) * z4 distributes over 3: 9x * (y + z) == x * y + x * z (x + y) * z == x * z + y * z4 can be decomposed: "x * y * z == x * y + x * z + y * zIThe following useful theorems can be proved from the above set of axioms.3 has 1# as the identity and is idempotent: 2 x + empty == x empty + x == x x + x == xAbsorption and saturation of 4: -x * y + x + y == x * y x * x * x == x * xThe core type class /, corresponds to unlabelled directed graphs. ., -, , and +? graphs can be obtained by extending the minimal set of axioms.DWhen specifying the time and memory complexity of graph algorithms, n2 will denote the number of vertices in the graph, m3 will denote the number of edges in the graph, and s will denote the size of the corresponding / expression.0The type of graph vertices.1Construct the empty graph.2)Construct the graph with a single vertex.3Overlay two graphs.4Connect two graphs.5;Construct the graph comprising a single edge. Complexity: O(1) time, memory and size.  edge x y == 4 (2 x) (2 y) 6OConstruct the graph comprising a given list of isolated vertices. Complexity: O(L) time, memory and size, where L" is the length of the given list. vertices [] == 1 vertices [x] == 2 x 77Construct the graph from a list of edges. Complexity: O(L) time, memory and size, where L" is the length of the given list. edges [] == 1 edges [(x,y)] == 5 x y 8-Overlay a given list of graphs. Complexity: O(L) time and memory, and O(S) size, where L' is the length of the given list, and S/ is the sum of sizes of the graphs in the list. overlays [] == 1' overlays [x] == x overlays [x,y] == 3 x y 9-Connect a given list of graphs. Complexity: O(L) time and memory, and O(S) size, where L' is the length of the given list, and S/ is the sum of sizes of the graphs in the list. connects [] == 1' connects [x] == x connects [x,y] == 4 x y :1Construct the graph from given lists of vertices V and edges E-. The resulting graph contains the vertices V7 as well as all the vertices referred to by the edges E. Complexity:  O(|V| + |E|) time, memory and size. graph [] [] == 1 graph [x] [] == 2 x graph [] [(x,y)] == 5 x y graph vs es == 3 (6 vs) (7 es) ;The ;' function takes two graphs and returns ¢ if the first graph is a subgraph3 of the second. Here is the current implementation: isSubgraphOf x y = 3 x y == y gThe complexity therefore depends on the complexity of equality testing of the specific graph instance.  isSubgraphOf 1- x == True isSubgraphOf (2 x) 1. == False isSubgraphOf x (3 x y) == True isSubgraphOf (3 x y) (4 x y) == True isSubgraphOf (< xs) (= xs) == True <The path% on a list of vertices. Complexity: O(L) time, memory and size, where L" is the length of the given list. path [] == 1 path [x] == 2 x path [x,y] == 5 x y =The circuit% on a list of vertices. Complexity: O(L) time, memory and size, where L" is the length of the given list. circuit [] == 1 circuit [x] == 5 x x circuit [x,y] == 7 [(x,y), (y,x)] >The clique% on a list of vertices. Complexity: O(L) time, memory and size, where L" is the length of the given list. clique [] == 1 clique [x] == 2 x clique [x,y] == 5 x y clique [x,y,z] == 7 [(x,y), (x,z), (y,z)] ?The biclique% on a list of vertices. Complexity:  O(L1 + L2) time, memory and size, where L1 and L2% are the lengths of the given lists. biclique [] [] == 1 biclique [x] [] == 2 x biclique [] [y] == 2 y biclique [x1,x2] [y1,y2] == 7B [(x1,y1), (x1,y2), (x2,y1), (x2,y2)] biclique xs ys == 4 (6 xs) (6 ys) @The star> formed by a centre vertex and a list of leaves. Complexity: O(L) time, memory and size, where L" is the length of the given list. star x [] == 2 x star x [y] == 5 x y star x [y,z] == 7 [(x,y), (x,z)] AThe  tree graph constructed from a given ª data structure. Complexity: O(T) time, memory and size, where TJ is the size of the given tree (i.e. the number of vertices in the tree). <tree (Node x []) == 2? x tree (Node x [Node y [Node z []]]) == <E [x,y,z] tree (Node x [Node y [], Node z []]) == @E x [y,z] tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) == 7 [(1,2), (1,3), (3,4), (3,5)] BThe  forest graph constructed from a given « data structure. Complexity: O(F) time, memory and size, where FN is the size of the given forest (i.e. the number of vertices in the forest). >forest [] == 1? forest [x] == AA x forest [Node 1 [Node 2 [], Node 3 []], Node 4 [Node 5 []]] == 7U [(1,2), (1,3), (4,5)] forest == 8 . map A 4()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[()*+,-./0123456789:;<=>?@AB/01234.-,+56897:;<=>?@AB()*-()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[(c) Andrey Mokhov 2016-2017MIT (see the file LICENSE)andrey.mokhov@gmail.comunstableNone :DILRT\The \X data type represents a graph by a map of vertices to their adjacency sets. We define a ¬; instance as a convenient notation for working with graphs: õ0 == vertex 0 1 + 2 == overlay (vertex 1) (vertex 2) 1 * 2 == connect (vertex 1) (vertex 2) 1 + 2 * 3 == overlay (vertex 1) (connect (vertex 2) (vertex 3)) 1 * (2 + 3) == connect (vertex 1) (overlay (vertex 2) (vertex 3))The ­? instance is defined using basic graph construction primitives: ÿdshow (empty :: IntAdjacencyMap Int) == "empty" show (1 :: IntAdjacencyMap Int) == "vertex 1" show (1 + 2 :: IntAdjacencyMap Int) == "vertices [1,2]" show (1 * 2 :: IntAdjacencyMap Int) == "edge 1 2" show (1 * 2 * 3 :: IntAdjacencyMap Int) == "edges [(1,2),(1,3),(2,3)]" show (1 * 2 + 3 :: IntAdjacencyMap Int) == "graph [1,2,3] [(1,2)]"The ®3 instance satisfies all axioms of algebraic graphs: is commutative and associative: / x + y == y + x x + (y + z) == (x + y) + z is associative and has  as the identity: < x * empty == x empty * x == x x * (y * z) == (x * y) * z distributes over : 9x * (y + z) == x * y + x * z (x + y) * z == x * z + y * z can be decomposed: "x * y * z == x * y + x * z + y * zIThe following useful theorems can be proved from the above set of axioms. has # as the identity and is idempotent: 2 x + empty == x empty + x == x x + x == xAbsorption and saturation of : -x * y + x + y == x * y x * x * x == x * xDWhen specifying the time and memory complexity of graph algorithms, n and mI will denote the number of vertices and edges in the graph, respectively.^The  adjacency mapN of the graph: each vertex is associated with a set of its direct successors._ÓCheck if the internal graph representation is consistent, i.e. that all edges refer to existing vertices. It should be impossible to create an inconsistent adjacency map, and we use this function in testing. ,Note: this function is for internal use only.  consistent & == True consistent ($ x) == True consistent (# x y) == True consistent (# x y) == True consistent (& x y) == True consistent (% xs) == True consistent ( % xs ys) == True consistent (! xs) == True \]^_¯°`ab\]^_\]^_\]^_¯°`ab(c) Andrey Mokhov 2016-2017MIT (see the file LICENSE)andrey.mokhov@gmail.com experimentalNone :DILRT,ddD encapsulates King-Launchbury graphs, which are implemented in the  Data.Graph module of the  containers library. If graphKL g == h then the following holds: map (f h) ("# $ e) h) == IntSet.± ({ g) map (\(x, y) -> (f h x, f h y)) (" $ e h) == y g e=Array-based graph representation (King and Launchbury, 1995).f A mapping of Data.Graph.Vertex to vertices of type a.gConstruct the  empty graph. Complexity: O(1) time and memory. s empty == True t x empty == False v empty == 0 w empty == 0 hConstruct the graph comprising a single isolated vertex. Complexity: O(1) time and memory. s (vertex x) == False t x (vertex x) == True t 1 (vertex 2) == False v (vertex x) == 1 w (vertex x) == 0 iConstruct the graph comprising  a single edge. Complexity: O(1) time, memory. edge x y == k (h x) (h y) u x y (edge x y) == True w (edge x y) == 1 v (edge 1 1) == 1 v (edge 1 2) == 2 jOverlay] two graphs. This is an idempotent, commutative and associative operation with the identity g. Complexity: O((n + m) * log(n)) time and O(n + m) memory. s (overlay x y) == s x && s y t z (overlay x y) == t z x || t z y v (overlay x y) >= v x v (overlay x y) <= v x + v y w (overlay x y) >= w x w (overlay x y) <= w x + w y v (overlay 1 2) == 2 w (overlay 1 2) == 0 kConnectA two graphs. This is an associative operation with the identity gU, which distributes over the 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). s (connect x y) == s x && s y t z (connect x y) == t z x || t z y v (connect x y) >= v x v (connect x y) <= v x + v y w (connect x y) >= w x w (connect x y) >= w y w (connect x y) >= v x * v y w (connect x y) <= v x * v y + w x + w y v (connect 1 2) == 2 w (connect 1 2) == 1 lOConstruct 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 [] == g vertices [x] == h x t x . vertices == ž x v . vertices == Ÿ .  { . vertices == IntSet.© m7Construct the graph from a list of edges. Complexity: O((n + m) * log(n)) time and O(n + m) memory. edges [] == g edges [(x, y)] == i x y w . edges == Ÿ .  y . edges ==  .  n-Overlay a given list of graphs. Complexity: O((n + m) * log(n)) time and O(n + m) memory. overlays [] == g/ overlays [x] == x overlays [x,y] == j x y s . overlays == ¡ s o-Connect a given list of graphs. Complexity: O((n + m) * log(n)) time and O(n + m) memory. connects [] == g/ connects [x] == x connects [x,y] == k x y s . connects == ¡ s p1Construct the graph from given lists of vertices V and edges E-. The resulting graph contains the vertices V7 as well as all the vertices referred to by the edges E. Complexity: O((n + m) * log(n)) time and O(n + m) memory. graph [] [] == g graph [x] [] == h x graph [] [(x,y)] == i x y graph vs es == j (l vs) (m es) q7Construct a graph from an adjacency list. Complexity: O((n + m) * log(n)) time and O(n + m) memory. 9fromAdjacencyList [] == g: fromAdjacencyList [(x, [])] == h< x fromAdjacencyList [(x, [y])] == i x y fromAdjacencyList . z == id jO (fromAdjacencyList xs) (fromAdjacencyList ys) == fromAdjacencyList (xs ++ ys) rThe r' function takes two graphs and returns ¢ if the first graph is a subgraph of the second. Complexity: O((n + m) * log(n)) time.  isSubgraphOf g- x == True isSubgraphOf (h x) g. == False isSubgraphOf x (j x y) == True isSubgraphOf (j x y) (k x y) == True isSubgraphOf (~ xs) ( xs) == True s(Check if a graph is empty. Complexity: O(1) time. isEmpty g( == True isEmpty (j g g) == True isEmpty (h' x) == False isEmpty (… x $ h x) == True isEmpty († x y $ i x y) == False t7Check if a graph contains a given vertex. Complexity:  O(log(n)) time.  hasVertex x g" == False hasVertex x (h x) == True hasVertex x . … x == const False u5Check if a graph contains a given edge. Complexity:  O(log(n)) time.  hasEdge x y g" == False hasEdge x y (h z) == False hasEdge x y (i" x y) == True hasEdge x y . † x y == const False v0The number of vertices in a graph. Complexity: O(1) time.  vertexCount g == 0 vertexCount (h# x) == 1 vertexCount == Ÿ . x w-The number of edges in a graph. Complexity: O(n) time.  edgeCount g == 0 edgeCount (h x) == 0 edgeCount (i# x y) == 1 edgeCount == Ÿ . y x;The sorted list of vertices of a given graph. Complexity: O(n) time and memory.  vertexList g == [] vertexList (h x) == [x] vertexList . l ==  .  y2The sorted list of edges of a graph. Complexity: O(n + m) time and O(m) memory.  edgeList g == [] edgeList (h x) == [] edgeList (i x y) == [(x,y)] edgeList (‚' 2 [3,1]) == [(2,1), (2,3)] edgeList . m ==  .  z The sorted adjacency list of a graph. Complexity: O(n + m) time and O(m) memory. adjacencyList g$ == [] adjacencyList (h) x) == [(x, [])] adjacencyList (i5 1 2) == [(1, [2]), (2, [])] adjacencyList (‚1 2 [3,1]) == [(1, []), (2, [1,3]), (3, [])] q . adjacencyList == id {3The set of vertices of a given graph. Complexity: O(n) time and memory.  vertexSet g == IntSet.§ vertexSet . h == IntSet.¨ vertexSet . l == IntSet.© vertexSet . € == IntSet.© |0The set of edges of a given graph. Complexity: O((n + m) * log(m)) time and O(m) memory. edgeSet g == Set.¤ edgeSet (h x) == Set.¤ edgeSet (i x y) == Set.¥ (x,y) edgeSet . m == Set.  }The postset of a vertex is the set of its direct successors.  postset x g == IntSet.§ postset x (h x) == IntSet.§ postset x (i x y) == IntSet.© [y] postset 2 (i 1 2) == IntSet.§ ~The path% on a list of vertices. Complexity: O((n + m) * log(n)) time and O(n + m) memory. path [] == g path [x] == h x path [x,y] == i x y The circuit% on a list of vertices. Complexity: O((n + m) * log(n)) time and O(n + m) memory. circuit [] == g circuit [x] == i x x circuit [x,y] == m [(x,y), (y,x)] €The clique% on a list of vertices. Complexity: O((n + m) * log(n)) time and O(n + m) memory. clique [] == g clique [x] == h x clique [x,y] == i x y clique [x,y,z] == m [(x,y), (x,z), (y,z)] The biclique% on a list of vertices. Complexity: O(n * log(n) + m) time and O(n + m) memory. biclique [] [] == g biclique [x] [] == h x biclique [] [y] == h y biclique [x1,x2] [y1,y2] == mB [(x1,y1), (x1,y2), (x2,y1), (x2,y2)] biclique xs ys == k (l xs) (l ys) ‚The star> formed by a centre vertex and a list of leaves. Complexity: O((n + m) * log(n)) time and O(n + m) memory. star x [] == h x star x [y] == i x y star x [y,z] == m [(x,y), (x,z)] ƒThe  tree graph constructed from a given ª data structure. Complexity: O((n + m) * log(n)) time and O(n + m) memory. <tree (Node x []) == h? x tree (Node x [Node y [Node z []]]) == ~E [x,y,z] tree (Node x [Node y [], Node z []]) == ‚E x [y,z] tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) == m [(1,2), (1,3), (3,4), (3,5)] „The  forest graph constructed from a given « data structure. Complexity: O((n + m) * log(n)) time and O(n + m) memory. >forest [] == g? forest [x] == ƒA x forest [Node 1 [Node 2 [], Node 3 []], Node 4 [Node 5 []]] == mU [(1,2), (1,3), (4,5)] forest == n . map ƒ …1Remove a vertex from a given graph. Complexity:  O(n*log(n)) time. removeVertex x (h x) == g3 removeVertex x . removeVertex x == removeVertex x †0Remove an edge from a given graph. Complexity:  O(log(n)) time. removeEdge x y (i x y) == lK [x, y] removeEdge x y . removeEdge x y == removeEdge x y removeEdge x y . … x == …a x removeEdge 1 1 (1 * 1 * 2 * 2) == 1 * 2 * 2 removeEdge 1 2 (1 * 1 * 2 * 2) == 1 * 1 + 2 * 2 ‡ The function ‡ x y replaces vertex x with vertex y in a given \. If y already exists, x and y will be merged. Complexity: O((n + m) * log(n)) time. 6replaceVertex x x == id replaceVertex x y (h x) == h# y replaceVertex x y == ˆ (== x) y ˆNMerge vertices satisfying a given predicate with a given vertex. Complexity: O((n + m) * log(n))* time, assuming that the predicate takes O(1) to be evaluated. KmergeVertices (const False) x == id mergeVertices (== x) y == ‡Y x y mergeVertices even 1 (0 * 2) == 1 * 1 mergeVertices odd 1 (3 + 4 * 5) == 4 * 1 ‰VTransform a graph by applying a function to each of its vertices. This is similar to Functor's ², but can be used with non-fully-parametric \. Complexity: O((n + m) * log(n)) time. gmap f g == g gmap f (h x) == h (f x) gmap f (i x y) == iG (f x) (f y) gmap id == id gmap f . gmap g == gmap (f . g) Š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 == g induce (/= x) == …< x induce p . induce q == induce (\x -> p x && q x) r (induce p x) x == True ‹ Compute the depth-first search forest of a graph. „ (dfsForest $ i 1 1) == h 1 „ (dfsForest $ i 1 2) == i 1 2 „ (dfsForest $ i 2 1) == l [1, 2] r („& $ dfsForest x) x == True dfsForest . „ÿ . dfsForest == dfsForest dfsForest $ 3 * (1 + 4) * (1 + 5) == [ Node { rootLabel = 1 , subForest = [ Node { rootLabel = 5 , subForest = [] }]} , Node { rootLabel = 3 , subForest = [ Node { rootLabel = 4 , subForest = [] }]}] Œ Compute the topological sort of a graph or return Nothing if the graph is cyclic. ntopSort (1 * 2 + 3 * 1) == Just [3,1,2] topSort (1 * 2 + 2 * 1) == Nothing fmap (flip  x) (topSort x) /= Just False -Check if a given list of vertices is a valid topological sort of a graph. šisTopSort [3, 1, 2] (1 * 2 + 3 * 1) == True isTopSort [1, 2, 3] (1 * 2 + 3 * 1) == False isTopSort [] (1 * 2 + 3 * 1) == False isTopSort [] g( == True isTopSort [x] (h& x) == True isTopSort [x] (i x x) == False ŽBuild d# from the adjacency map of a graph.  . graphKL == id 5Extract the adjacency map of a King-Launchbury graph. fromGraphKL . Ž == id -d³efghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ.\^dfeghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ1\^^ghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒdefefŽ*d³efghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ(c) Andrey Mokhov 2016-2017MIT (see the file LICENSE)andrey.mokhov@gmail.comunstableNone :DILRTThe # data type represents a graph as a binary relation. We define a ¬; instance as a convenient notation for working with graphs: õ0 == vertex 0 1 + 2 == overlay (vertex 1) (vertex 2) 1 * 2 == connect (vertex 1) (vertex 2) 1 + 2 * 3 == overlay (vertex 1) (connect (vertex 2) (vertex 3)) 1 * (2 + 3) == connect (vertex 1) (overlay (vertex 2) (vertex 3))The ­? instance is defined using basic graph construction primitives: ÿ: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 (1 * 2 * 3 :: Relation Int) == "edges [(1,2),(1,3),(2,3)]" show (1 * 2 + 3 :: Relation Int) == "graph [1,2,3] [(1,2)]"The ®3 instance satisfies all axioms of algebraic graphs: is commutative and associative: / x + y == y + x x + (y + z) == (x + y) + z is associative and has  as the identity: < x * empty == x empty * x == x x * (y * z) == (x * y) * z distributes over : 9x * (y + z) == x * y + x * z (x + y) * z == x * z + y * z can be decomposed: "x * y * z == x * y + x * z + y * zIThe following useful theorems can be proved from the above set of axioms. has ' as the identity and is idempotent: 2 x + empty == x empty + x == x x + x == xAbsorption and saturation of : -x * y + x + y == x * y x * x * x == x * xDWhen specifying the time and memory complexity of graph algorithms, n and mI will denote the number of vertices and edges in the graph, respectively.’The domain of the relation.“&The set of pairs of elements that are related<. It is guaranteed that each element belongs to the domain.”+Compute the Cartesian product of two sets. ,Note: this function is for internal use only.•hCheck if the internal representation of a relation is consistent, i.e. if all pairs of elements in the “# refer to existing elements in the ’5. It should be impossible to create an inconsistent ), and we use this function in testing. ,Note: this function is for internal use only.  consistent & == True consistent ($ x) == True consistent (# x y) == True consistent (# x y) == True consistent (& x y) == True consistent (% xs) == True consistent ( % xs ys) == True consistent (! xs) == True –:The set of elements that appear in a given set of pairs. ,Note: this function is for internal use only. ‘’“”•–—˜™‘’“”•–‘’“•”–‘’“”•–—˜™(c) Andrey Mokhov 2016-2017MIT (see the file LICENSE)andrey.mokhov@gmail.com experimentalNone :DILRT+›Construct the  empty graph. Complexity: O(1) time and memory. § empty == True ¨ x empty == False ª empty == 0 « empty == 0 œConstruct the graph comprising a single isolated vertex. Complexity: O(1) time and memory. § (vertex x) == False ¨ x (vertex x) == True ¨ 1 (vertex 2) == False ª (vertex x) == 1 « (vertex x) == 0 Construct the graph comprising  a single edge. Complexity: O(1) time, memory and size. edge x y == Ÿ (œ x) (œ y) © x y (edge x y) == True « (edge x y) == 1 ª (edge 1 1) == 1 ª (edge 1 2) == 2 žOverlay] two graphs. This is an idempotent, commutative and associative operation with the identity ›. Complexity: O((n + m) * log(n)) time and O(n + m) memory. § (overlay x y) == § x && § y ¨ z (overlay x y) == ¨ z x || ¨ z y ª (overlay x y) >= ª x ª (overlay x y) <= ª x + ª y « (overlay x y) >= « x « (overlay x y) <= « x + « y ª (overlay 1 2) == 2 « (overlay 1 2) == 0 ŸConnectA two graphs. This is an associative operation with the identity ›U, which distributes over the 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) == § x && § y ¨ z (connect x y) == ¨ z x || ¨ z y ª (connect x y) >= ª x ª (connect x y) <= ª x + ª y « (connect x y) >= « x « (connect x y) >= « y « (connect x y) >= ª x * ª y « (connect x y) <= ª x * ª y + « x + « y ª (connect 1 2) == 2 « (connect 1 2) == 1  OConstruct 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 [] == › vertices [x] == œ x ¨ x . vertices == ž x ª . vertices == Ÿ .  ® . vertices == Set.  ¡7Construct the graph from a list of edges. Complexity: O((n + m) * log(n)) time and O(n + m) memory. edges [] == › edges [(x,y)] ==  x y « . edges == Ÿ .  ¢-Overlay a given list of graphs. Complexity: O((n + m) * log(n)) time and O(n + m) memory. overlays [] == ›/ overlays [x] == x overlays [x,y] == ž x y § . overlays == ¡ § £-Connect a given list of graphs. Complexity: O((n + m) * log(n)) time and O(n + m) memory. connects [] == ›/ connects [x] == x connects [x,y] == Ÿ x y § . connects == ¡ § ¤1Construct the graph from given lists of vertices V and edges E-. The resulting graph contains the vertices V7 as well as all the vertices referred to by the edges E. Complexity: O((n + m) * log(n)) time and O(n + m) memory. graph [] [] == › graph [x] [] == œ x graph [] [(x,y)] ==  x y graph vs es == ž (  vs) (¡ es) ¥7Construct a graph from an adjacency list. Complexity: O((n + m) * log(n)) time and O(n + m) memory. 9fromAdjacencyList [] == ›: fromAdjacencyList [(x, [])] == œ< x fromAdjacencyList [(x, [y])] ==  x y žO (fromAdjacencyList xs) (fromAdjacencyList ys) == fromAdjacencyList (xs ++ ys) ¦The ¦' function takes two graphs and returns ¢ if the first graph is a subgraph of the second. Complexity: O((n + m) * log(n)) time.  isSubgraphOf ›- x == True isSubgraphOf (œ x) ›. == False isSubgraphOf x (ž x y) == True isSubgraphOf (ž x y) (Ÿ x y) == True isSubgraphOf (³ xs) (´ xs) == True §+Check if a relation is empty. Complexity: O(1) time. isEmpty ›( == True isEmpty (ž › ›) == True isEmpty (œ' x) == False isEmpty (º x $ œ x) == True isEmpty (» x y $  x y) == False ¨7Check if a graph contains a given vertex. Complexity:  O(log(n)) time.  hasVertex x ›" == False hasVertex x (œ x) == True hasVertex x . º x == const False ©5Check if a graph contains a given edge. Complexity:  O(log(n)) time.  hasEdge x y ›" == False hasEdge x y (œ z) == False hasEdge x y (" x y) == True hasEdge x y . » x y == const False ª0The number of vertices in a graph. Complexity: O(1) time.  vertexCount › == 0 vertexCount (œ# x) == 1 vertexCount == Ÿ . ¬ «-The number of edges in a graph. Complexity: O(1) time.  edgeCount › == 0 edgeCount (œ x) == 0 edgeCount (# x y) == 1 edgeCount == Ÿ . ­ ¬;The sorted list of vertices of a given graph. Complexity: O(n) time and memory.  vertexList › == [] vertexList (œ x) == [x] vertexList .   ==  .  ­2The sorted list of edges of a graph. Complexity: O(n + m) time and O(m) memory.  edgeList › == [] edgeList (œ x) == [] edgeList ( x y) == [(x,y)] edgeList (·' 2 [3,1]) == [(2,1), (2,3)] edgeList . ¡ ==  .  edgeList . ¾ ==  . map ´ . edgeList ®3The set of vertices of a given graph. Complexity: O(1) time.  vertexSet › == Set.¤ vertexSet . œ == Set.¥ vertexSet .   == Set.  vertexSet . µ == Set.  ¯+The set of vertices of a given graph. Like ®3 but specialised for graphs with vertices of type ¦. Complexity: O(n) time.  vertexIntSet › == IntSet.§ vertexIntSet . œ == IntSet.¨ vertexIntSet .   == IntSet.© vertexIntSet . µ == IntSet.© °0The set of edges of a given graph. Complexity: O(1) time. edgeSet › == Set.¤ edgeSet (œ x) == Set.¤ edgeSet ( x y) == Set.¥ (x,y) edgeSet . ¡ == Set.  ±The preset of an element x7 is the set of elements that are related to it on the left, i.e. preset x == { a | aRx }E. In the context of directed graphs, this corresponds to the set of direct predecessors of vertex x. Complexity: O(n + m) time and O(n) memory.  preset x › == Set.empty preset x (œ x) == Set.empty preset 1 ( 1 2) == Set.empty preset y ( x y) == Set.fromList [x] ²The postset of an element x7 is the set of elements that are related to it on the right, i.e. postset x == { a | xRa }E. In the context of directed graphs, this corresponds to the set of direct successors of vertex x. Complexity: O(n + m) time and O(n) memory.  postset x › == Set.empty postset x (œ x) == Set.empty postset x (% x y) == Set.fromList [y] postset 2 ( 1 2) == Set.empty ³The path% on a list of vertices. Complexity: O((n + m) * log(n)) time and O(n + m) memory. path [] == › path [x] == œ x path [x,y] ==  x y path . µ == ¾ . path ´The circuit% on a list of vertices. Complexity: O((n + m) * log(n)) time and O(n + m) memory. circuit [] == › circuit [x] ==  x x circuit [x,y] == ¡ [(x,y), (y,x)] circuit . µ == ¾ . circuit µThe clique% on a list of vertices. Complexity: O((n + m) * log(n)) time and O(n + m) memory. clique [] == › clique [x] == œ x clique [x,y] ==  x y clique [x,y,z] == ¡ [(x,y), (x,z), (y,z)] clique . µ == ¾ . clique ¶The biclique% on a list of vertices. Complexity: O(n * log(n) + m) time and O(n + m) memory. biclique [] [] == › biclique [x] [] == œ x biclique [] [y] == œ y biclique [x1,x2] [y1,y2] == ¡B [(x1,y1), (x1,y2), (x2,y1), (x2,y2)] biclique xs ys == Ÿ (  xs) (  ys) ·The star> formed by a centre vertex and a list of leaves. Complexity: O((n + m) * log(n)) time and O(n + m) memory. star x [] == œ x star x [y] ==  x y star x [y,z] == ¡ [(x,y), (x,z)] ¸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 []) == œ? x tree (Node x [Node y [Node z []]]) == ³E [x,y,z] tree (Node x [Node y [], Node z []]) == ·E x [y,z] tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) == ¡ [(1,2), (1,3), (3,4), (3,5)] ¹The  forest graph constructed from a given Forest data structure. Complexity: O((n + m) * log(n)) time and O(n + m) memory. >forest [] == ›? forest [x] == ¸A x forest [Node 1 [Node 2 [], Node 3 []], Node 4 [Node 5 []]] == ¡U [(1,2), (1,3), (4,5)] forest == ¢ . map ¸ º1Remove a vertex from a given graph. Complexity: O(n + m) time. removeVertex x (œ x) == ›3 removeVertex x . removeVertex x == removeVertex x »0Remove an edge from a given graph. Complexity:  O(log(m)) time. removeEdge x y ($ x y) ==  K [x, y] removeEdge x y . removeEdge x y == removeEdge x y removeEdge x y . º x == ºa x removeEdge 1 1 (1 * 1 * 2 * 2) == 1 * 2 * 2 removeEdge 1 2 (1 * 1 * 2 * 2) == 1 * 1 + 2 * 2 ¼ The function ¼ x y replaces vertex x with vertex y in a given  AdjacencyMap. If y already exists, x and y will be merged. Complexity: O((n + m) * log(n)) time. 6replaceVertex x x == id replaceVertex x y (œ x) == œ# y replaceVertex x y == ½ (== x) y ½NMerge vertices satisfying a given predicate with a given vertex. Complexity: O((n + m) * log(n))* time, assuming that the predicate takes O(1) to be evaluated. KmergeVertices (const False) x == id mergeVertices (== x) y == ¼Y x y mergeVertices even 1 (0 * 2) == 1 * 1 mergeVertices odd 1 (3 + 4 * 5) == 4 * 1 ¾&Transpose a given graph. Complexity:  O(m * log(m)) time.  transpose › == › transpose (œ x) == œ x transpose ( x y) == - y x transpose . transpose == id transpose . ³ == ³ . µ transpose . ´ == ´ . µ transpose . µ == µ . µ ­ . transpose ==  . map ´ . ­ ¿VTransform a graph by applying a function to each of its vertices. This is similar to Functor's ², but can be used with non-fully-parametric . Complexity: O((n + m) * log(n)) time. gmap f › == › gmap f (œ x) == œ (f x) gmap f ( x y) == G (f x) (f y) gmap id == id gmap f . gmap g == gmap (f . g) À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 == › induce (/= x) == º< x induce p . induce q == induce (\x -> p x && q x) ¦ (induce p x) x == True ÁCompose two relations: R = Á Q P. Two elements x and y. are related in the resulting relation, i.e. xRy, if there exists an element z , such that xPz and zQy-. This is an associative operation which has › as the annihilating zero. Complexity: O(n * m * log(m)) time and O(n + m) memory. compose › x == › compose x › == ›O compose x (compose y z) == compose (compose x y) z compose ( y z) ( x y) ==  x z compose (³ [1..5]) (³ [1..5]) == ¡ [(1,3),(2,4),(3,5)] compose (´ [1..5]) (´ [1..5]) == ´ [1,3,5,2,4]  Compute the reflexive closure of a . Complexity:  O(n * log(m)) time. reflexiveClosure › == › reflexiveClosure (œ x) ==  x x à Compute the symmetric closure of a . Complexity:  O(m * log(m)) time. symmetricClosure › == › symmetricClosure (œ x) == œ x symmetricClosure ( x y) == ¡ [(x, y), (y, x)] Ä Compute the transitive closure of a . Complexity: O(n * m * log(n) * log(m)) time. transitiveClosure › == › transitiveClosure (œ x) == œ x transitiveClosure (³ $  xs) == µ ( xs) Å Compute the preorder closure of a . Complexity: O(n * m * log(m)) time. preorderClosure › == › preorderClosure (œ x) ==  x x preorderClosure (³ $  xs) ==  (µ $  xs) +›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅ.“’›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅ0’“’“›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅ+›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅ(c) Andrey Mokhov 2016-2017MIT (see the file LICENSE)andrey.mokhov@gmail.comunstableNone :DILRTÆThe Æ data type represents a 5binary relation that is both reflexive and transitive$. Preorders satisfy all laws of the +$ type class and, in particular, the  self-loop axiom: 2 x == 2 x * 2 xand the closure axiom: y /= 1+ ==> x * y + x * z + y * z == x * y + y * z!For example, the following holds: < xs == (> xs :: PreorderRelation Int)The ­C instance produces reflexively and transitively closed expressions: äshow (1 :: PreorderRelation Int) == "edge 1 1" show (1 * 2 :: PreorderRelation Int) == "edges [(1,1),(1,2),(2,2)]" show (1 * 2 + 2 * 3 :: PreorderRelation Int) == "edges [(1,1),(1,2),(1,3),(2,2),(2,3),(3,3)]"ÉThe É data type represents a transitive binary relationF over a set of elements. Transitive relations satisfy all laws of the ,$ type class and, in particular, the closure axiom: y /= 1+ ==> x * y + x * z + y * z == x * y + y * z!For example, the following holds: < xs == (> xs :: TransitiveRelation Int)The ­3 instance produces transitively closed expressions: Šshow (1 * 2 :: TransitiveRelation Int) == "edge 1 2" show (1 * 2 + 2 * 3 :: TransitiveRelation Int) == "edges [(1,2),(1,3),(2,3)]"ÌThe Ì data type represents a symmetric binary relationE over a set of elements. Symmetric relations satisfy all laws of the .= type class and, in particular, the commutativity of connect: 4 x y == 4 y xThe ­4 instance produces symmetrically closed expressions: rshow (1 :: SymmetricRelation Int) == "vertex 1" show (1 * 2 :: SymmetricRelation Int) == "edges [(1,2),(2,1)]"ÏThe Ï data type represents a reflexive binary relationE over a set of elements. Reflexive relations satisfy all laws of the -$ type class and, in particular, the  self-loop axiom: 2 x == 2 x * 2 xThe ­2 instance produces reflexively closed expressions: xshow (1 :: ReflexiveRelation Int) == "edge 1 1" show (1 * 2 :: ReflexiveRelation Int) == "edges [(1,1),(1,2),(2,2)]"ÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâã ÆÇÈÉÊËÌÍÎÏÐÑ ÏÐÑÌÍÎÉÊËÆÇÈÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâã(c) Andrey Mokhov 2016-2017MIT (see the file LICENSE)andrey.mokhov@gmail.com experimentalNone :DILRTè%Construct a preorder relation from a . Complexity: O(1) time.é.Extract the underlying relation. Complexity: O(n * m * log(m)) time.èéÆèéÆèéèé (c) Andrey Mokhov 2016-2017MIT (see the file LICENSE)andrey.mokhov@gmail.com experimentalNone :DILRTê&Construct a reflexive relation from a . Complexity: O(1) time.ë.Extract the underlying relation. Complexity:  O(n*log(m)) time.êëÏêëÏêëêë (c) Andrey Mokhov 2016-2017MIT (see the file LICENSE)andrey.mokhov@gmail.com experimentalNone :DILRTì&Construct a symmetric relation from a . Complexity: O(1) time.í.Extract the underlying relation. Complexity:  O(m*log(m)) time.î The set of  neighbours of an element x6 is the set of elements that are related to it, i.e. neighbours x == { a | aRx }G. In the context of undirected graphs, this corresponds to the set of adjacent vertices of vertex x.  neighbours x  == Set.¤ neighbours x ( x) == Set.¤ neighbours x ( x y) == Set.  [y] neighbours y ( x y) == Set.  [x] ìíîÌìíîÌìíîìíî (c) Andrey Mokhov 2016-2017MIT (see the file LICENSE)andrey.mokhov@gmail.com experimentalNone :DILRTï'Construct a transitive relation from a . Complexity: O(1) time.ð.Extract the underlying relation. Complexity: O(n * m * log(m)) time.ïðÉïðÉïðïð (c) Andrey Mokhov 2016-2017MIT (see the file LICENSE)andrey.mokhov@gmail.comunstableNone :DILRTñThe ñX data type represents a graph by a map of vertices to their adjacency sets. We define a ¬; instance as a convenient notation for working with graphs: õ0 == vertex 0 1 + 2 == overlay (vertex 1) (vertex 2) 1 * 2 == connect (vertex 1) (vertex 2) 1 + 2 * 3 == overlay (vertex 1) (connect (vertex 2) (vertex 3)) 1 * (2 + 3) == connect (vertex 1) (overlay (vertex 2) (vertex 3))The ­? instance is defined using basic graph construction primitives: ÿRshow (empty :: AdjacencyMap Int) == "empty" show (1 :: AdjacencyMap Int) == "vertex 1" show (1 + 2 :: AdjacencyMap Int) == "vertices [1,2]" show (1 * 2 :: AdjacencyMap Int) == "edge 1 2" show (1 * 2 * 3 :: AdjacencyMap Int) == "edges [(1,2),(1,3),(2,3)]" show (1 * 2 + 3 :: AdjacencyMap Int) == "graph [1,2,3] [(1,2)]"The ®3 instance satisfies all axioms of algebraic graphs:  is commutative and associative: / x + y == y + x x + (y + z) == (x + y) + z  is associative and has   as the identity: < x * empty == x empty * x == x x * (y * z) == (x * y) * z  distributes over  : 9x * (y + z) == x * y + x * z (x + y) * z == x * z + y * z  can be decomposed: "x * y * z == x * y + x * z + y * zIThe following useful theorems can be proved from the above set of axioms.  has  ' as the identity and is idempotent: 2 x + empty == x empty + x == x x + x == xAbsorption and saturation of  : -x * y + x + y == x * y x * x * x == x * xDWhen specifying the time and memory complexity of graph algorithms, n and mI will denote the number of vertices and edges in the graph, respectively.óThe  adjacency mapN of the graph: each vertex is associated with a set of its direct successors.ôÓCheck if the internal graph representation is consistent, i.e. that all edges refer to existing vertices. It should be impossible to create an inconsistent adjacency map, and we use this function in testing. ,Note: this function is for internal use only.  consistent  & == True consistent ( $ x) == True consistent ( # x y) == True consistent ( # x y) == True consistent ( & x y) == True consistent ( % xs) == True consistent ( % xs ys) == True consistent ( ! xs) == True ñòóô¶·õö÷ñòóôñòóôñòóô¶·õö÷ (c) Andrey Mokhov 2016-2017MIT (see the file LICENSE)andrey.mokhov@gmail.com experimentalNone :DILRT-ùùD encapsulates King-Launchbury graphs, which are implemented in the  Data.Graph module of the  containers library. If graphKL g == h then the following holds: map (û h) ("# $ ú& h) == Set.¸ ( g) map (\(x, y) -> (û h x, û h y)) (" $ ú h) ==  g ú=Array-based graph representation (King and Launchbury, 1995).û A mapping of Data.Graph.Vertex to vertices of type a.üConstruct the  empty graph. Complexity: O(1) time and memory.  empty == True   x empty == False   empty == 0   empty == 0 ýConstruct the graph comprising a single isolated vertex. Complexity: O(1) time and memory.  (vertex x) == False   x (vertex x) == True   1 (vertex 2) == False   (vertex x) == 1   (vertex x) == 0 þConstruct the graph comprising  a single edge. Complexity: O(1) time, memory. edge x y ==  (ý x) (ý y)   x y (edge x y) == True   (edge x y) == 1   (edge 1 1) == 1   (edge 1 2) == 2 ÿOverlay] two graphs. This is an idempotent, commutative and associative operation with the identity ü. Complexity: O((n + m) * log(n)) time and O(n + m) memory.  (overlay x y) ==  x &&  y   z (overlay x y) ==   z x ||   z y   (overlay x y) >=   x   (overlay x y) <=   x +   y   (overlay x y) >=   x   (overlay x y) <=   x +   y   (overlay 1 2) == 2   (overlay 1 2) == 0 ConnectA two graphs. This is an associative operation with the identity üU, which distributes over the 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) ==  x &&  y   z (connect x y) ==   z x ||   z y   (connect x y) >=   x   (connect x y) <=   x +   y   (connect x y) >=   x   (connect x y) >=   y   (connect x y) >=   x *   y   (connect x y) <=   x *   y +   x +   y   (connect 1 2) == 2   (connect 1 2) == 1 OConstruct 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 [] == ü vertices [x] == ý x   x . vertices == ž x   . vertices == Ÿ .   . vertices == Set.  7Construct the graph from a list of edges. Complexity: O((n + m) * log(n)) time and O(n + m) memory. edges [] == ü edges [(x, y)] == þ x y   . edges == Ÿ .   . edges ==  .  -Overlay a given list of graphs. Complexity: O((n + m) * log(n)) time and O(n + m) memory. overlays [] == ü/ overlays [x] == x overlays [x,y] == ÿ x y  . overlays == ¡  -Connect a given list of graphs. Complexity: O((n + m) * log(n)) time and O(n + m) memory. connects [] == ü/ connects [x] == x connects [x,y] ==  x y  . connects == ¡  1Construct the graph from given lists of vertices V and edges E-. The resulting graph contains the vertices V7 as well as all the vertices referred to by the edges E. Complexity: O((n + m) * log(n)) time and O(n + m) memory. graph [] [] == ü graph [x] [] == ý x graph [] [(x,y)] == þ x y graph vs es == ÿ ( vs) ( es) 7Construct a graph from an adjacency list. Complexity: O((n + m) * log(n)) time and O(n + m) memory. 9fromAdjacencyList [] == ü: fromAdjacencyList [(x, [])] == ý< x fromAdjacencyList [(x, [y])] == þ x y fromAdjacencyList .  == id ÿO (fromAdjacencyList xs) (fromAdjacencyList ys) == fromAdjacencyList (xs ++ ys) The ' function takes two graphs and returns ¢ if the first graph is a subgraph of the second. Complexity: O((n + m) * log(n)) time.  isSubgraphOf ü- x == True isSubgraphOf (ý x) ü. == False isSubgraphOf x (ÿ x y) == True isSubgraphOf (ÿ x y) ( x y) == True isSubgraphOf ( xs) ( xs) == True (Check if a graph is empty. Complexity: O(1) time. isEmpty ü( == True isEmpty (ÿ ü ü) == True isEmpty (ý' x) == False isEmpty ( x $ ý x) == True isEmpty ( x y $ þ x y) == False  7Check if a graph contains a given vertex. Complexity:  O(log(n)) time.  hasVertex x ü" == False hasVertex x (ý x) == True hasVertex x .  x == const False  5Check if a graph contains a given edge. Complexity:  O(log(n)) time.  hasEdge x y ü" == False hasEdge x y (ý z) == False hasEdge x y (þ" x y) == True hasEdge x y .  x y == const False  0The number of vertices in a graph. Complexity: O(1) time.  vertexCount ü == 0 vertexCount (ý# x) == 1 vertexCount == Ÿ .    -The number of edges in a graph. Complexity: O(n) time.  edgeCount ü == 0 edgeCount (ý x) == 0 edgeCount (þ# x y) == 1 edgeCount == Ÿ .   ;The sorted list of vertices of a given graph. Complexity: O(n) time and memory.  vertexList ü == [] vertexList (ý x) == [x] vertexList .  ==  .  2The sorted list of edges of a graph. Complexity: O(n + m) time and O(m) memory.  edgeList ü == [] edgeList (ý x) == [] edgeList (þ x y) == [(x,y)] edgeList (' 2 [3,1]) == [(2,1), (2,3)] edgeList .  ==  .   The sorted adjacency list of a graph. Complexity: O(n + m) time and O(m) memory. adjacencyList ü$ == [] adjacencyList (ý) x) == [(x, [])] adjacencyList (þ5 1 2) == [(1, [2]), (2, [])] adjacencyList (1 2 [3,1]) == [(1, []), (2, [1,3]), (3, [])]  . adjacencyList == id 3The set of vertices of a given graph. Complexity: O(n) time and memory.  vertexSet ü == Set.¤ vertexSet . ý == Set.¥ vertexSet .  == Set.  vertexSet .  == Set.  0The set of edges of a given graph. Complexity: O((n + m) * log(m)) time and O(m) memory. edgeSet ü == Set.¤ edgeSet (ý x) == Set.¤ edgeSet (þ x y) == Set.¥ (x,y) edgeSet .  == Set.  The postset of a vertex is the set of its direct successors.  postset x ü == Set.¤ postset x (ý x) == Set.¤ postset x (þ x y) == Set.  [y] postset 2 (þ 1 2) == Set.¤ The path% on a list of vertices. Complexity: O((n + m) * log(n)) time and O(n + m) memory. path [] == ü path [x] == ý x path [x,y] == þ x y The circuit% on a list of vertices. Complexity: O((n + m) * log(n)) time and O(n + m) memory. circuit [] == ü circuit [x] == þ x x circuit [x,y] ==  [(x,y), (y,x)] The clique% on a list of vertices. Complexity: O((n + m) * log(n)) time and O(n + m) memory. clique [] == ü clique [x] == ý x clique [x,y] == þ x y clique [x,y,z] ==  [(x,y), (x,z), (y,z)] The biclique% on a list of vertices. Complexity: O(n * log(n) + m) time and O(n + m) memory. biclique [] [] == ü biclique [x] [] == ý x biclique [] [y] == ý y biclique [x1,x2] [y1,y2] == B [(x1,y1), (x1,y2), (x2,y1), (x2,y2)] biclique xs ys ==  ( xs) ( ys) The star> formed by a centre vertex and a list of leaves. Complexity: O((n + m) * log(n)) time and O(n + m) memory. star x [] == ý x star x [y] == þ x y star x [y,z] ==  [(x,y), (x,z)] The  tree graph constructed from a given ª data structure. Complexity: O((n + m) * log(n)) time and O(n + m) memory. <tree (Node x []) == ý? x tree (Node x [Node y [Node z []]]) == E [x,y,z] tree (Node x [Node y [], Node z []]) == E x [y,z] tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) ==  [(1,2), (1,3), (3,4), (3,5)] The  forest graph constructed from a given « data structure. Complexity: O((n + m) * log(n)) time and O(n + m) memory. >forest [] == ü? forest [x] == A x forest [Node 1 [Node 2 [], Node 3 []], Node 4 [Node 5 []]] == U [(1,2), (1,3), (4,5)] forest ==  . map  1Remove a vertex from a given graph. Complexity:  O(n*log(n)) time. removeVertex x (ý x) == ü3 removeVertex x . removeVertex x == removeVertex x 0Remove an edge from a given graph. Complexity:  O(log(n)) time. removeEdge x y (þ x y) == K [x, y] removeEdge x y . removeEdge x y == removeEdge x y removeEdge x y .  x == a x removeEdge 1 1 (1 * 1 * 2 * 2) == 1 * 2 * 2 removeEdge 1 2 (1 * 1 * 2 * 2) == 1 * 1 + 2 * 2  The function  x y replaces vertex x with vertex y in a given ñ. If y already exists, x and y will be merged. Complexity: O((n + m) * log(n)) time. 6replaceVertex x x == id replaceVertex x y (ý x) == ý# y replaceVertex x y ==  (== x) y NMerge vertices satisfying a given predicate with a given vertex. Complexity: O((n + m) * log(n))* time, assuming that the predicate takes O(1) to be evaluated. KmergeVertices (const False) x == id mergeVertices (== x) y == Y x y mergeVertices even 1 (0 * 2) == 1 * 1 mergeVertices odd 1 (3 + 4 * 5) == 4 * 1 VTransform a graph by applying a function to each of its vertices. This is similar to Functor's ², but can be used with non-fully-parametric ñ. Complexity: O((n + m) * log(n)) time. gmap f ü == ü gmap f (ý x) == ý (f x) gmap f (þ x y) == þG (f x) (f y) gmap id == id gmap f . gmap g == gmap (f . g) 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 == ü induce (/= x) == < x induce p . induce q == induce (\x -> p x && q x)  (induce p x) x == True   Compute the depth-first search forest of a graph.  (dfsForest $ þ 1 1) == ý 1  (dfsForest $ þ 1 2) == þ 1 2  (dfsForest $ þ 2 1) ==  [1, 2]  (& $ dfsForest x) x == True dfsForest . ÿ . dfsForest == dfsForest dfsForest $ 3 * (1 + 4) * (1 + 5) == [ Node { rootLabel = 1 , subForest = [ Node { rootLabel = 5 , subForest = [] }]} , Node { rootLabel = 3 , subForest = [ Node { rootLabel = 4 , subForest = [] }]}] ! Compute the topological sort of a graph or return Nothing if the graph is cyclic. ntopSort (1 * 2 + 3 * 1) == Just [3,1,2] topSort (1 * 2 + 2 * 1) == Nothing fmap (flip " x) (topSort x) /= Just False "-Check if a given list of vertices is a valid topological sort of a graph. šisTopSort [3, 1, 2] (1 * 2 + 3 * 1) == True isTopSort [1, 2, 3] (1 * 2 + 3 * 1) == False isTopSort [] (1 * 2 + 3 * 1) == False isTopSort [] ü( == True isTopSort [x] (ý& x) == True isTopSort [x] (þ x x) == False # Compute the  condensation1 of a graph, where each vertex corresponds to a strongly-connected component of the original graph. scc ü == ü scc (ý x) == ý (Set.¥ x) scc (þ x y) == þ (Set.¥ x) (Set.¥ y) scc ( (1:xs)) == þ (Set.  (1:xs)) (Set. $ (1:xs)) scc (3 * 1 * 4 * 1 * 5) ==  [ (Set.  [1,4], Set. 0 [1,4]) , (Set.  [1,4], Set. 0 [5] ) , (Set.  [3] , Set. 0 [1,4]) , (Set.  [3] , Set.  [5] )] $Build ù# from the adjacency map of a graph. % . graphKL == id %5Extract the adjacency map of a King-Launchbury graph. fromGraphKL . $ == id .ù¹úûüýþÿ      !"#$%/ñóùûúüýþÿ      !"#$%2ñóóüýþÿ      !"#ùúûúû$%+ù¹úûüýþÿ      !"#$%(c) Andrey Mokhov 2016-2017MIT (see the file LICENSE)andrey.mokhov@gmail.com experimentalNone :DILORT$&The &U datatype is the Boehm-Berarducci encoding of the core graph construction primitives ', (, * and +. We define a ¬; instance as a convenient notation for working with graphs: õ0 == vertex 0 1 + 2 == overlay (vertex 1) (vertex 2) 1 * 2 == connect (vertex 1) (vertex 2) 1 + 2 * 3 == overlay (vertex 1) (connect (vertex 2) (vertex 3)) 1 * (2 + 3) == connect (vertex 1) (overlay (vertex 2) (vertex 3))The ­? instance is defined using basic graph construction primitives: ÿ"show (empty :: Fold Int) == "empty" show (1 :: Fold Int) == "vertex 1" show (1 + 2 :: Fold Int) == "vertices [1,2]" show (1 * 2 :: Fold Int) == "edge 1 2" show (1 * 2 * 3 :: Fold Int) == "edges [(1,2),(1,3),(2,3)]" show (1 * 2 + 3 :: Fold Int) == "graph [1,2,3] [(1,2)]"The ®- instance is currently implemented using the ñ as the canonical graph representation. and satisfies all axioms of algebraic graphs:* is commutative and associative: / x + y == y + x x + (y + z) == (x + y) + z+ is associative and has ' as the identity: < x * empty == x empty * x == x x * (y * z) == (x * y) * z+ distributes over *: 9x * (y + z) == x * y + x * z (x + y) * z == x * z + y * z+ can be decomposed: "x * y * z == x * y + x * z + y * zIThe following useful theorems can be proved from the above set of axioms.* has '# as the identity and is idempotent: 2 x + empty == x empty + x == x x + x == xAbsorption and saturation of +: -x * y + x + y == x * y x * x * x == x * xDWhen specifying the time and memory complexity of graph algorithms, n2 will denote the number of vertices in the graph, m3 will denote the number of edges in the graph, and s will denote the size? of the corresponding graph expression. For example, if g is a & then n, m and s can be computed as follows: n == 5 g m == 6 g s == 2 g Note that 2 is slightly different from the Ÿ method of the º* type class, as the latter does not count ' leaves of the expression: Ÿ ' == 0 2 ' == 1 Ÿ (( x) == 1 2 (( x) == 1 Ÿ (' + ') == 0 2 (' + ') == 2The 2. of any graph is positive, and the difference (2 g - Ÿ g)- corresponds to the number of occurrences of ' in an expression g. Converting a & to the corresponding ñ takes O(s + m * log(m)) time and O(s + m)º memory. This is also the complexity of the graph equality test, because it is currently implemented by converting graph expressions to canonical representations based on adjacency maps.'Construct the  empty graph. Complexity: O(1) time, memory and size. 1 empty == True 3 x empty == False 5 empty == 0 6 empty == 0 2 empty == 1 (Construct the graph comprising a single isolated vertex. Complexity: O(1) time, memory and size. 1 (vertex x) == False 3 x (vertex x) == True 3 1 (vertex 2) == False 5 (vertex x) == 1 6 (vertex x) == 0 2 (vertex x) == 1 )Construct the graph comprising  a single edge. Complexity: O(1) time, memory and size. edge x y == + (( x) (( y) 4 x y (edge x y) == True 6 (edge x y) == 1 5 (edge 1 1) == 1 5 (edge 1 2) == 2 *Overlay] two graphs. This is an idempotent, commutative and associative operation with the identity '. Complexity: O(1) time and memory,  O(s1 + s2) size. 1 (overlay x y) == 1 x && 1 y 3 z (overlay x y) == 3 z x || 3 z y 5 (overlay x y) >= 5 x 5 (overlay x y) <= 5 x + 5 y 6 (overlay x y) >= 6 x 6 (overlay x y) <= 6 x + 6 y 2 (overlay x y) == 2 x + 2 y 5 (overlay 1 2) == 2 6 (overlay 1 2) == 0 +ConnectA two graphs. This is an associative operation with the identity 'U, which distributes over the overlay and obeys the decomposition axiom. Complexity: O(1) time and memory,  O(s1 + s2)„ size. 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). 1 (connect x y) == 1 x && 1 y 3 z (connect x y) == 3 z x || 3 z y 5 (connect x y) >= 5 x 5 (connect x y) <= 5 x + 5 y 6 (connect x y) >= 6 x 6 (connect x y) >= 6 y 6 (connect x y) >= 5 x * 5 y 6 (connect x y) <= 5 x * 5 y + 6 x + 6 y 2 (connect x y) == 2 x + 2 y 5 (connect 1 2) == 2 6 (connect 1 2) == 1 ,OConstruct the graph comprising a given list of isolated vertices. Complexity: O(L) time, memory and size, where L" is the length of the given list. vertices [] == ' vertices [x] == ( x 3 x . vertices == ž x 5 . vertices == Ÿ .  9 . vertices == Set.  -7Construct the graph from a list of edges. Complexity: O(L) time, memory and size, where L" is the length of the given list. edges [] == ' edges [(x,y)] == ) x y 6 . edges == Ÿ .  .-Overlay a given list of graphs. Complexity: O(L) time and memory, and O(S) size, where L' is the length of the given list, and S/ is the sum of sizes of the graphs in the list. overlays [] == '/ overlays [x] == x overlays [x,y] == * x y 1 . overlays == ¡ 1 /-Connect a given list of graphs. Complexity: O(L) time and memory, and O(S) size, where L' is the length of the given list, and S/ is the sum of sizes of the graphs in the list. connects [] == '/ connects [x] == x connects [x,y] == + x y 1 . connects == ¡ 1 02Generalised graph folding: recursively collapse a &¦ by applying the provided functions to the leaves and internal nodes of the expression. The order of arguments is: empty, vertex, overlay and connect. Complexity: O(s)D applications of given functions. As an example, the complexity of 2 is O(s) , since all functions have cost O(1). foldg ' ( * + == id foldg ' ( * (flip +) == D5 foldg [] return (++) (++) == »5 foldg 0 (const 1) (+) (+) == Ÿ5 foldg 1 (const 1) (+) (+) == 25 foldg True (const False) (&&) (&&) == 1 12Check if a graph is empty. A convenient alias for £. Complexity: O(s) time. isEmpty '( == True isEmpty (* ' ') == True isEmpty ((' x) == False isEmpty (? x $ ( x) == True isEmpty (@ x y $ ) x y) == False 2The sizeD of a graph, i.e. the number of leaves of the expression including ' leaves. Complexity: O(s) time. size ' == 1 size (( x) == 1 size (* x y) == size x + size y size (+G x y) == size x + size y size x >= 1 size x >= 5 x 3ACheck if a graph contains a given vertex. A convenient alias for ž. Complexity: O(s) time.  hasVertex x '" == False hasVertex x (( x) == True hasVertex x . ? x == const False 45Check if a graph contains a given edge. Complexity: O(s) time.  hasEdge x y '" == False hasEdge x y (( z) == False hasEdge x y ()" x y) == True hasEdge x y . @ x y == const False 50The number of vertices in a graph. Complexity:  O(s * log(n)) time.  vertexCount ' == 0 vertexCount ((# x) == 1 vertexCount == Ÿ . 7 6-The number of edges in a graph. Complexity: O(s + m * log(m))% time. Note that the number of edges mB of a graph can be quadratic with respect to the expression size s.  edgeCount ' == 0 edgeCount (( x) == 0 edgeCount ()# x y) == 1 edgeCount == Ÿ . 8 7;The sorted list of vertices of a given graph. Complexity:  O(s * log(n)) time and O(n) memory.  vertexList ' == [] vertexList (( x) == [x] vertexList . , ==  .  82The sorted list of edges of a graph. Complexity: O(s + m * log(m)) time and O(m)( memory. Note that the number of edges mA of a graph can be quadratic with respect to the expression size s.  edgeList ' == [] edgeList (( x) == [] edgeList () x y) == [(x,y)] edgeList (star' 2 [3,1]) == [(2,1), (2,3)] edgeList . - ==  .  edgeList . D ==  . map %& . edgeList 93The set of vertices of a given graph. Complexity:  O(s * log(n)) time and O(n) memory.  vertexSet ' == Set.¤ vertexSet . ( == Set.¥ vertexSet . , == Set.  vertexSet . clique == Set.  :+The set of vertices of a given graph. Like 93 but specialised for graphs with vertices of type ¦. Complexity:  O(s * log(n)) time and O(n) memory.  vertexIntSet ' == IntSet.§ vertexIntSet . ( == IntSet.¨ vertexIntSet . , == IntSet.© vertexIntSet . clique == IntSet.© ;0The set of edges of a given graph. Complexity:  O(s * log(m)) time and O(m) memory. edgeSet ' == Set.¤ edgeSet (( x) == Set.¤ edgeSet () x y) == Set.¥ (x,y) edgeSet . - == Set.  < Construct a  mesh graph* from two lists of vertices. Complexity:  O(L1 * L2) time, memory and size, where L1 and L2% are the lengths of the given lists. mesh xs [] == ' mesh [] ys == ' mesh [x] [y] == ( (x, y) mesh xs ys == I (path xs) (path ys) mesh [1..3] "ab" == -¤ [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(2,'b')), ((2,'a'),(2,'b')) , ((2,'a'),(3,'a')), ((2,'b'),(3,'b')), ((3,'a'),(3,'b')) ] = Construct a  torus graph* from two lists of vertices. Complexity:  O(L1 * L2) time, memory and size, where L1 and L2% are the lengths of the given lists. torus xs [] == ' torus [] ys == ' torus [x] [y] == )# (x, y) (x, y) torus xs ys == I (circuit xs) (circuit ys) torus [1,2] "ab" == -· [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(1,'a')), ((1,'b'),(2,'b')) , ((2,'a'),(1,'a')), ((2,'a'),(2,'b')), ((2,'b'),(1,'b')), ((2,'b'),(2,'a')) ] > Construct a De Bruijn graphV of a given non-negative dimension using symbols from a given alphabet. Complexity:  O(A^(D + 1)) time, memory and size, where A" is the size of the alphabet and D is the dimention of the graph. ) deBruijn 0 xs == ) [] [] n > 0  deBruijn n [] == '* deBruijn 1 [0,1] == -Y [ ([0],[0]), ([0],[1]), ([1],[0]), ([1],[1]) ] deBruijn 2 "0" == )4 "00" "00" deBruijn 2 "01" == -¦ [ ("00","00"), ("00","01"), ("01","10"), ("01","11") , ("10","00"), ("10","01"), ("11","10"), ("11","11") ] 5 (deBruijn n xs) == (Ÿ $  xs)^n n > 0  6 (deBruijn n xs) == (Ÿ $  xs)^(n + 1) ?1Remove a vertex from a given graph. Complexity: O(s) time, memory and size. removeVertex x (( x) == '3 removeVertex x . removeVertex x == removeVertex x @0Remove an edge from a given graph. Complexity: O(s) time and memory. removeEdge x y () x y) == ,K [x, y] removeEdge x y . removeEdge x y == removeEdge x y removeEdge x y . ? x == ?a x removeEdge 1 1 (1 * 1 * 2 * 2) == 1 * 2 * 2 removeEdge 1 2 (1 * 1 * 2 * 2) == 1 * 1 + 2 * 2 A The function A x y replaces vertex x with vertex y" in a given graph expression. If y already exists, x and y will be merged. Complexity: O(s) time, memory and size. 6replaceVertex x x == id replaceVertex x y (( x) == (# y replaceVertex x y == B (== x) y BNMerge vertices satisfying a given predicate with a given vertex. Complexity: O(s); time, memory and size, assuming that the predicate takes O(1) to be evaluated. KmergeVertices (const False) x == id mergeVertices (== x) y == AY x y mergeVertices even 1 (0 * 2) == 1 * 1 mergeVertices odd 1 (3 + 4 * 5) == 4 * 1 CPSplit a vertex into a list of vertices with the same connectivity. Complexity:  O(s + k * L) time, memory and size, where kC is the number of occurrences of the vertex in the expression and L" is the length of the given list. %splitVertex x [] == ?P x splitVertex x [x] == id splitVertex x [y] == A< x y splitVertex 1 [0,1] $ 1 * (2 + 3) == (0 + 1) * (2 + 3) D&Transpose a given graph. Complexity: O(s) time, memory and size.  transpose ' == ' transpose (( x) == ( x transpose () x y) == )- y x transpose . transpose == id transpose . < == < . µ transpose . = == = . µ transpose . > == > . µ transpose (I x y) == I (transpose x) (transpose y) 8 . transpose ==  . map %& . 8 E\Transform a given graph by applying a function to each of its vertices. This is similar to ²2 but can be used with non-fully-parametric graphs. gmap f ' == ' gmap f (( x) == ( (f x) gmap f () x y) == )G (f x) (f y) gmap id == id gmap f . gmap g == gmap (f . g) FoTransform a given graph by substituting each of its vertices with a subgraph. This is similar to Monad's bind ¼3 but can be used with non-fully-parametric graphs. bind ' f == ' bind (( x) f == f x bind () x y) f == + (f x) (f y) bind (, xs) f == . (½ f xs) bind x (const ') == ' bind x (A == x bind (bind x f) g == bind x (\y -> bind (f y) g) GConstruct the induced subgraph` of a given graph by removing the vertices that do not satisfy a given predicate. Complexity: O(s); time, memory and size, assuming that the predicate takes O(1) to be evaluated. @induce (const True) x == x induce (const False) x == ' induce (/= x) == ?< x induce p . induce q == induce (\x -> p x && q x)  isSubgraphOf (induce p x) x == True HÿVSimplify a graph expression. Semantically, this is the identity function, but it simplifies a given polymorphic graph expression according to the laws of the algebra. The function does not compute the simplest possible expression, but uses heuristics to obtain useful simplifications in reasonable time. Complexity: the function performs O(s)ˆ graph comparisons. It is guaranteed that the size of the result does not exceed the size of the given expression. Below the operator ~> denotes the is simplified to relation. simplify == id 2 (simplify x) <= 2 x simplify ' ~> 'q simplify 1 ~> 1 simplify (1 + 1) ~> 1 simplify (1 + 2 + 1) ~> 1 + 2 simplify (1 * 1 * 1) ~> 1 * 1 I Compute the Cartesian product of graphs. Complexity:  O(s1 * s2) time, memory and size, where s1 and s2$ are the sizes of the given graphs. box (path [0,1]) (path "ab") == -É [ ((0,'a'), (0,'b')) , ((0,'a'), (1,'a')) , ((0,'b'), (1,'b')) , ((1,'a'), (1,'b')) ] LUp to an isomorphism between the resulting vertex types, this operation is  commutative,  associative,  distributes over *, has singleton graphs as  identities and ' as the annihilating zero. Below ~~5 stands for the equality up to an isomorphism, e.g.  (x, ()) ~~ x. Qbox x y ~~ box y x box x (box y z) ~~ box (box x y) z box x (* y z) == * (box x y) (box x z) box x (( ()) ~~ x box x ' ~~ ' D (box x y) == box (D x) (D y) 5 (box x y) == 5 x * 5 y 6 (box x y) <= 5 x * 6 y + 6 x * 5 y @¾¿ÀÁÂÃ&ÄÅ'()*+,-./01234ÆÇÈÉ56789:;<=>?@ABCDEFGHÊIJKLMNOPQRSTUVWX-:;<=>?@AB&'()*+,-./0123456789:;<=>?@ABCDEFGHI-&'()*+,-./:0;123456789:;<=>?@AB<=>?@ABCDEFGHI:¾¿ÀÁÂÃ&ÄÅ'()*+,-./01234ÆÇÈÉ56789:;<=>?@ABCDEFGHÊIJKLMNOPQRSTUVWX(c) Andrey Mokhov 2016-2017MIT (see the file LICENSE)andrey.mokhov@gmail.com experimentalNone 234:DILRT,YThe YH datatype is a deep embedding of the core graph construction primitives ^, _, a and b. We define a ¬; instance as a convenient notation for working with graphs: õ0 == Vertex 0 1 + 2 == Overlay (Vertex 1) (Vertex 2) 1 * 2 == Connect (Vertex 1) (Vertex 2) 1 + 2 * 3 == Overlay (Vertex 1) (Connect (Vertex 2) (Vertex 3)) 1 * (2 + 3) == Connect (Vertex 1) (Overlay (Vertex 2) (Vertex 3))The ®- instance is currently implemented using the ñ as the canonical graph representation. and satisfies all axioms of algebraic graphs:a is commutative and associative: / x + y == y + x x + (y + z) == (x + y) + zb is associative and has ^ as the identity: < x * empty == x empty * x == x x * (y * z) == (x * y) * zb distributes over a: 9x * (y + z) == x * y + x * z (x + y) * z == x * z + y * zb can be decomposed: "x * y * z == x * y + x * z + y * zIThe following useful theorems can be proved from the above set of axioms.a has ^# as the identity and is idempotent: 2 x + empty == x empty + x == x x + x == xAbsorption and saturation of b: -x * y + x + y == x * y x * x * x == x * xDWhen specifying the time and memory complexity of graph algorithms, n2 will denote the number of vertices in the graph, m3 will denote the number of edges in the graph, and s will denote the size of the corresponding Y$ expression. For example, if g is a Y then n, m and s can be computed as follows: n == o g m == p g s == l g Note that l is slightly different from the Ÿ method of the º* type class, as the latter does not count ^ leaves of the expression: Ÿ ^ == 0 l ^ == 1 Ÿ (_ x) == 1 l (_ x) == 1 Ÿ (^ + ^) == 0 l (^ + ^) == 2The l. of any graph is positive, and the difference (l g - Ÿ g)- corresponds to the number of occurrences of ^ in an expression g. Converting a Y to the corresponding ñ takes O(s + m * log(m)) time and O(s + m)º memory. This is also the complexity of the graph equality test, because it is currently implemented by converting graph expressions to canonical representations based on adjacency maps.^Construct the  empty graph. An alias for the constructor Z. Complexity: O(1) time, memory and size. k empty == True m x empty == False o empty == 0 p empty == 0 l empty == 1 _Construct the graph comprising a single isolated vertex . An alias for the constructor [. Complexity: O(1) time, memory and size. k (vertex x) == False m x (vertex x) == True m 1 (vertex 2) == False o (vertex x) == 1 p (vertex x) == 0 l (vertex x) == 1 `Construct the graph comprising  a single edge. Complexity: O(1) time, memory and size. edge x y == b (_ x) (_ y) n x y (edge x y) == True p (edge x y) == 1 o (edge 1 1) == 1 o (edge 1 2) == 2 aOverlay* two graphs. An alias for the constructor \R. This is an idempotent, commutative and associative operation with the identity ^. Complexity: O(1) time and memory,  O(s1 + s2) size. k (overlay x y) == k x && k y m z (overlay x y) == m z x || m z y o (overlay x y) >= o x o (overlay x y) <= o x + o y p (overlay x y) >= p x p (overlay x y) <= p x + p y l (overlay x y) == l x + l y o (overlay 1 2) == 2 p (overlay 1 2) == 0 bConnect* two graphs. An alias for the constructor ]6. This is an associative operation with the identity ^V, which distributes over the overlay and obeys the decomposition axiom. Complexity: O(1) time and memory,  O(s1 + s2)„ size. 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). k (connect x y) == k x && k y m z (connect x y) == m z x || m z y o (connect x y) >= o x o (connect x y) <= o x + o y p (connect x y) >= p x p (connect x y) >= p y p (connect x y) >= o x * o y p (connect x y) <= o x * o y + p x + p y l (connect x y) == l x + l y o (connect 1 2) == 2 p (connect 1 2) == 1 cOConstruct the graph comprising a given list of isolated vertices. Complexity: O(L) time, memory and size, where L" is the length of the given list. vertices [] == ^ vertices [x] == _ x m x . vertices == ž x o . vertices == Ÿ .  s . vertices == Set.  d7Construct the graph from a list of edges. Complexity: O(L) time, memory and size, where L" is the length of the given list. edges [] == ^ edges [(x,y)] == ` x y p . edges == Ÿ .  e-Overlay a given list of graphs. Complexity: O(L) time and memory, and O(S) size, where L' is the length of the given list, and S/ is the sum of sizes of the graphs in the list. overlays [] == ^/ overlays [x] == x overlays [x,y] == a x y k . overlays == ¡ k f-Connect a given list of graphs. Complexity: O(L) time and memory, and O(S) size, where L' is the length of the given list, and S/ is the sum of sizes of the graphs in the list. connects [] == ^/ connects [x] == x connects [x,y] == b x y k . connects == ¡ k g1Construct the graph from given lists of vertices V and edges E-. The resulting graph contains the vertices V7 as well as all the vertices referred to by the edges E. Complexity:  O(|V| + |E|) time, memory and size. graph [] [] == ^ graph [x] [] == _ x graph [] [(x,y)] == ` x y graph vs es == a (c vs) (d es) h Generalised Y! folding: recursively collapse a Y¦ by applying the provided functions to the leaves and internal nodes of the expression. The order of arguments is: empty, vertex, overlay and connect. Complexity: O(s)D applications of given functions. As an example, the complexity of l is O(s) , since all functions have cost O(1). foldg ^ _ a b == id foldg ^ _ a (flip b) == …5 foldg [] return (++) (++) == '(5 foldg 0 (const 1) (+) (+) == ')5 foldg 1 (const 1) (+) (+) == l5 foldg True (const False) (&&) (&&) == k iThe i' function takes two graphs and returns ¢ if the first graph is a subgraph of the second. Complexity: O(s + m * log(m))% time. Note that the number of edges mB of a graph can be quadratic with respect to the expression size s.  isSubgraphOf ^- x == True isSubgraphOf (_ x) ^. == False isSubgraphOf x (a x y) == True isSubgraphOf (a x y) (b x y) == True isSubgraphOf (v xs) (w xs) == True j7Structural equality on graph expressions. Complexity: O(s) time. * x === x == True x === x + ^` == False x + y === x + y == True 1 + 2 === 2 + 1 == False x + y === x * y == False k2Check if a graph is empty. A convenient alias for £. Complexity: O(s) time. isEmpty ^( == True isEmpty (a ^ ^) == True isEmpty (_' x) == False isEmpty (€ x $ _ x) == True isEmpty ( x y $ ` x y) == False lThe sizeD of a graph, i.e. the number of leaves of the expression including ^ leaves. Complexity: O(s) time. size ^ == 1 size (_ x) == 1 size (a x y) == size x + size y size (bG x y) == size x + size y size x >= 1 size x >= o x mACheck if a graph contains a given vertex. A convenient alias for ž. Complexity: O(s) time.  hasVertex x ^" == False hasVertex x (_ x) == True hasVertex x . € x == const False n5Check if a graph contains a given edge. Complexity: O(s) time.  hasEdge x y ^" == False hasEdge x y (_ z) == False hasEdge x y (`" x y) == True hasEdge x y .  x y == const False o0The number of vertices in a graph. Complexity:  O(s * log(n)) time.  vertexCount ^ == 0 vertexCount (_# x) == 1 vertexCount == Ÿ . q p-The number of edges in a graph. Complexity: O(s + m * log(m))% time. Note that the number of edges mB of a graph can be quadratic with respect to the expression size s.  edgeCount ^ == 0 edgeCount (_ x) == 0 edgeCount (`# x y) == 1 edgeCount == Ÿ . r q;The sorted list of vertices of a given graph. Complexity:  O(s * log(n)) time and O(n) memory.  vertexList ^ == [] vertexList (_ x) == [x] vertexList . c ==  .  r2The sorted list of edges of a graph. Complexity: O(s + m * log(m)) time and O(m)( memory. Note that the number of edges mA of a graph can be quadratic with respect to the expression size s.  edgeList ^ == [] edgeList (_ x) == [] edgeList (` x y) == [(x,y)] edgeList (z' 2 [3,1]) == [(2,1), (2,3)] edgeList . d ==  .  edgeList . … ==  . map %& . edgeList s3The set of vertices of a given graph. Complexity:  O(s * log(n)) time and O(n) memory.  vertexSet ^ == Set.¤ vertexSet . _ == Set.¥ vertexSet . c == Set.  vertexSet . x == Set.  t+The set of vertices of a given graph. Like s3 but specialised for graphs with vertices of type ¦. Complexity:  O(s * log(n)) time and O(n) memory.  vertexIntSet ^ == IntSet.§ vertexIntSet . _ == IntSet.¨ vertexIntSet . c == IntSet.© vertexIntSet . x == IntSet.© u0The set of edges of a given graph. Complexity:  O(s * log(m)) time and O(m) memory. edgeSet ^ == Set.¤ edgeSet (_ x) == Set.¤ edgeSet (` x y) == Set.¥ (x,y) edgeSet . d == Set.  vThe path% on a list of vertices. Complexity: O(L) time, memory and size, where L" is the length of the given list. path [] == ^ path [x] == _ x path [x,y] == ` x y path . µ == … . path wThe circuit% on a list of vertices. Complexity: O(L) time, memory and size, where L" is the length of the given list. circuit [] == ^ circuit [x] == ` x x circuit [x,y] == d [(x,y), (y,x)] circuit . µ == … . circuit xThe clique% on a list of vertices. Complexity: O(L) time, memory and size, where L" is the length of the given list. clique [] == ^ clique [x] == _ x clique [x,y] == ` x y clique [x,y,z] == d [(x,y), (x,z), (y,z)] clique . µ == … . clique yThe biclique% on a list of vertices. Complexity:  O(L1 + L2) time, memory and size, where L1 and L2% are the lengths of the given lists. biclique [] [] == ^ biclique [x] [] == _ x biclique [] [y] == _ y biclique [x1,x2] [y1,y2] == dB [(x1,y1), (x1,y2), (x2,y1), (x2,y2)] biclique xs ys == b (c xs) (c ys) zThe star> formed by a centre vertex and a list of leaves. Complexity: O(L) time, memory and size, where L" is the length of the given list. star x [] == _ x star x [y] == ` x y star x [y,z] == d [(x,y), (x,z)] {The  tree graph constructed from a given Tree data structure. Complexity: O(T) time, memory and size, where TJ is the size of the given tree (i.e. the number of vertices in the tree). <tree (Node x []) == _? x tree (Node x [Node y [Node z []]]) == vE [x,y,z] tree (Node x [Node y [], Node z []]) == zE x [y,z] tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) == d [(1,2), (1,3), (3,4), (3,5)] |The  forest graph constructed from a given Forest data structure. Complexity: O(F) time, memory and size, where FN is the size of the given forest (i.e. the number of vertices in the forest). >forest [] == ^? forest [x] == {A x forest [Node 1 [Node 2 [], Node 3 []], Node 4 [Node 5 []]] == dU [(1,2), (1,3), (4,5)] forest == e . map { } Construct a  mesh graph* from two lists of vertices. Complexity:  O(L1 * L2) time, memory and size, where L1 and L2% are the lengths of the given lists. mesh xs [] == ^ mesh [] ys == ^ mesh [x] [y] == _ (x, y) mesh xs ys == ˆ (v xs) (v ys) mesh [1..3] "ab" == d¤ [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(2,'b')), ((2,'a'),(2,'b')) , ((2,'a'),(3,'a')), ((2,'b'),(3,'b')), ((3,'a'),(3,'b')) ] ~ Construct a  torus graph* from two lists of vertices. Complexity:  O(L1 * L2) time, memory and size, where L1 and L2% are the lengths of the given lists. torus xs [] == ^ torus [] ys == ^ torus [x] [y] == `# (x, y) (x, y) torus xs ys == ˆ (w xs) (w ys) torus [1,2] "ab" == d· [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(1,'a')), ((1,'b'),(2,'b')) , ((2,'a'),(1,'a')), ((2,'a'),(2,'b')), ((2,'b'),(1,'b')), ((2,'b'),(2,'a')) ]  Construct a De Bruijn graphV of a given non-negative dimension using symbols from a given alphabet. Complexity:  O(A^(D + 1)) time, memory and size, where A" is the size of the alphabet and D is the dimention of the graph. ) deBruijn 0 xs == ` [] [] n > 0  deBruijn n [] == ^* deBruijn 1 [0,1] == dY [ ([0],[0]), ([0],[1]), ([1],[0]), ([1],[1]) ] deBruijn 2 "0" == `4 "00" "00" deBruijn 2 "01" == d¦ [ ("00","00"), ("00","01"), ("01","10"), ("01","11") , ("10","00"), ("10","01"), ("11","10"), ("11","11") ] o (deBruijn n xs) == (Ÿ $  xs)^n n > 0  p (deBruijn n xs) == (Ÿ $  xs)^(n + 1) €1Remove a vertex from a given graph. Complexity: O(s) time, memory and size. removeVertex x (_ x) == ^3 removeVertex x . removeVertex x == removeVertex x 0Remove an edge from a given graph. Complexity: O(s) time and memory. removeEdge x y (` x y) == cK [x, y] removeEdge x y . removeEdge x y == removeEdge x y removeEdge x y . *+ x == *+a x removeEdge 1 1 (1 * 1 * 2 * 2) == 1 * 2 * 2 removeEdge 1 2 (1 * 1 * 2 * 2) == 1 * 1 + 2 * 2 ‚ The function ‚ x y replaces vertex x with vertex y in a given Y. If y already exists, x and y will be merged. Complexity: O(s) time, memory and size. 6replaceVertex x x == id replaceVertex x y (_ x) == _# y replaceVertex x y == ƒ (== x) y ƒNMerge vertices satisfying a given predicate with a given vertex. Complexity: O(s); time, memory and size, assuming that the predicate takes O(1) to be evaluated. KmergeVertices (const False) x == id mergeVertices (== x) y == ‚Y x y mergeVertices even 1 (0 * 2) == 1 * 1 mergeVertices odd 1 (3 + 4 * 5) == 4 * 1 „PSplit a vertex into a list of vertices with the same connectivity. Complexity:  O(s + k * L) time, memory and size, where kC is the number of occurrences of the vertex in the expression and L" is the length of the given list. %splitVertex x [] == €P x splitVertex x [x] == id splitVertex x [y] == ‚< x y splitVertex 1 [0,1] $ 1 * (2 + 3) == (0 + 1) * (2 + 3) …&Transpose a given graph. Complexity: O(s) time, memory and size.  transpose ^ == ^ transpose (_ x) == _ x transpose (` x y) == `- y x transpose . transpose == id transpose . v == v . µ transpose . w == w . µ transpose . x == x . µ transpose (ˆ x y) == ˆ (transpose x) (transpose y) r . transpose ==  . map %& . r †Construct the induced subgraph` of a given graph by removing the vertices that do not satisfy a given predicate. Complexity: O(s); time, memory and size, assuming that the predicate takes O(1) to be evaluated. @induce (const True) x == x induce (const False) x == ^ induce (/= x) == €< x induce p . induce q == induce (\x -> p x && q x) i (induce p x) x == True ‡ÿDSimplify a graph expression. Semantically, this is the identity function, but it simplifies a given expression according to the laws of the algebra. The function does not compute the simplest possible expression, but uses heuristics to obtain useful simplifications in reasonable time. Complexity: the function performs O(s)s graph comparisons. It is guaranteed that the size of the result does not exceed the size of the given expression. simplify == id l (simplify x) <= l x simplify ^ j ^ simplify 1 j 1 simplify (1 + 1) j 1 simplify (1 + 2 + 1) j 1 + 2 simplify (1 * 1 * 1) j 1 * 1 ˆ Compute the Cartesian product of graphs. Complexity:  O(s1 * s2) time, memory and size, where s1 and s2$ are the sizes of the given graphs. box (v [0,1]) (v "ab") == dÉ [ ((0,'a'), (0,'b')) , ((0,'a'), (1,'a')) , ((0,'b'), (1,'b')) , ((1,'a'), (1,'b')) ] LUp to an isomorphism between the resulting vertex types, this operation is  commutative,  associative,  distributes over a, has singleton graphs as  identities and ^ as the annihilating zero. Below ~~5 stands for the equality up to an isomorphism, e.g.  (x, ()) ~~ x. Qbox x y ~~ box y x box x (box y z) ~~ box (box x y) z box x (a y z) == a (box x y) (box x z) box x (_ ()) ~~ x box x ^ ~~ ^ … (box x y) == box (… x) (… y) o (box x y) == o x * o y p (box x y) <= o x * p y + p x * o y DËÌÍÎÏYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€ÐÑÒ‚ƒ„…†‡Óˆ‰Š‹ŒŽ‘’“0YZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ0YZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ=ËÌÍÎÏYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€ÐÑÒ‚ƒ„…†‡Óˆ‰Š‹ŒŽ‘’“j4Ô,-./0123#45 6789:;<=>?@ABCDEFG+HIJK.L/0123M#45 6=>?@ABCNOPQRSTUVWXYZ[\]^_`abcdefgghijklmnop#45 !678q9r:st;uv=>?@ABC+wHIxGyz{|}~€i‚ƒ„…#45 !678q9r:s;<u†v=>?@ABC+wHI‡xGˆ‰Š‹ŒŽ‘‘’““”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬ « ¬ « ¬ ­ « ¬ $ $ h i ® ¯ ° ± n o p      #  4 5 ! 6 7 8 q 9 r : s t ; u v = > ? @ A B C + w H I x G y z { ² | }#45³7´8q9r:s;<uDEF+wHIJ‡xµG¶K·¸¹º»¼½¾¿ÀÁÂÃÄÅÆMÇÈ#45 ³6É7´8q9r:s;<u=>?@ABCDEF+wHIJ‡G¶K·ÊËÌÍÎÏÐÑÒÓÔÕÖ×,ØÙ,-Ú,-Û,-Ü,-Ý,-Þ,'ß,')àáâ,'ãäåæ,'çàáàáèäåéàêàêèàêâàëìàëí,îï,Øðäñòóàêô,-õn,%&,ö÷ óàáô n,'ø,'(,-ù,-úûüüýþÿûüüýþ-algebraic-graphs-0.0.4-HPxUaAWnFkSGXAeISaVoNy Algebra.Graph.HigherKinded.ClassAlgebra.Graph.Class&Algebra.Graph.IntAdjacencyMap.InternalAlgebra.Graph.IntAdjacencyMapAlgebra.Graph.Relation.InternalAlgebra.Graph.Relation&Algebra.Graph.Relation.InternalDerivedAlgebra.Graph.Relation.Preorder Algebra.Graph.Relation.Reflexive Algebra.Graph.Relation.Symmetric!Algebra.Graph.Relation.Transitive#Algebra.Graph.AdjacencyMap.InternalAlgebra.Graph.AdjacencyMapAlgebra.Graph.Fold Algebra.GraphGraphFoldControl.Applicative Alternative Data.ListnubsortTest.QuickCheck==>RelationoverlayconnectemptyvertexedgeedgesgraphfromAdjacencyList Data.Graphvertices AdjacencyMap Data.Tupleswap Data.FoldabletoListlengthAlgebra.Graph.HigherKinded.Util removeVertexbaseGHC.BaseToGraphtoGraphPreorder Transitive Reflexive Undirectedoverlaysconnects isSubgraphOfisEmpty hasVertex vertexCount vertexList vertexSet vertexIntSetpathcircuitcliquebicliquestartreeforestmeshtorusdeBruijninduce replaceVertex mergeVertices splitVertexboxToVertexVertex$fPreorder(,,)$fTransitive(,,)$fReflexive(,,)$fUndirected(,,) $fGraph(,,) $fPreorder(,)$fTransitive(,)$fReflexive(,)$fUndirected(,) $fGraph(,)$fPreorder(->)$fTransitive(->)$fReflexive(->)$fUndirected(->) $fGraph(->)$fPreorderMaybe$fTransitiveMaybe$fReflexiveMaybe$fUndirectedMaybe $fGraphMaybe $fPreorder()$fTransitive() $fReflexive()$fUndirected() $fGraph()IntAdjacencyMap adjacencyMap consistent$fNumIntAdjacencyMap$fGraphIntAdjacencyMap$fShowIntAdjacencyMap$fEqIntAdjacencyMapGraphKLgetGraph getVertexhasEdge edgeCountedgeList adjacencyListedgeSetpostset removeEdgegmap dfsForesttopSort isTopSortgraphKL fromGraphKLdomainrelation setProductreferredToVertexSet $fNumRelation$fGraphRelation$fShowRelation $fEqRelationpreset transposecomposereflexiveClosuresymmetricClosuretransitiveClosurepreorderClosurePreorderRelation fromPreorderTransitiveRelationfromTransitiveSymmetricRelation fromSymmetricReflexiveRelation fromReflexive$fPreorderPreorderRelation$fTransitivePreorderRelation$fReflexivePreorderRelation$fGraphPreorderRelation$fEqPreorderRelation$fShowPreorderRelation$fTransitiveTransitiveRelation$fGraphTransitiveRelation$fShowTransitiveRelation$fEqTransitiveRelation$fUndirectedSymmetricRelation$fGraphSymmetricRelation$fShowSymmetricRelation$fEqSymmetricRelation$fReflexiveReflexiveRelation$fGraphReflexiveRelation$fShowReflexiveRelation$fEqReflexiveRelation$fNumReflexiveRelation$fNumSymmetricRelation$fNumTransitiveRelation$fNumPreorderRelation fromRelation toRelation neighbours$fNumAdjacencyMap$fGraphAdjacencyMap$fShowAdjacencyMap$fEqAdjacencyMapsccfoldgsizebindsimplify $fGraphPiece $fToGraphFold$fToGraphFold0$fTraversableFold$fFoldableFold $fGraphFold $fMonadFold$fMonadPlusFold$fAlternativeFold$fApplicativeFold $fFunctorFold $fNumFold $fGraphFold0$fEqFold $fShowFoldEmptyOverlayConnect===$fMonadPlusGraph$fAlternativeGraph $fMonadGraph$fApplicativeGraph $fEqGraph $fNumGraph $fGraphGraph$fToGraphGraph$fToGraphGraph0 $fGraphGraph0$fFoldableGraph$fFunctorGraph $fShowGraph$fTraversableGraphGHC.Showshowpure MonadPlus Applicativemplus<|>elemcontainers-0.5.7.1 Data.Set.BasefromListallghc-prim GHC.TypesTruenull singletonIntData.IntSet.Base Data.TreeTreeForestGHC.NumNumShow GHC.ClassesEqinternalEdgeList toAscListfmapGHC.ListreverseFoldable>>=mapPiecesPiecepieceintacttrivialrunFold edgelessPiecebreakIf nonTrivialsmashsimple