-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | A library for algebraic graph construction and transformation
--   
--   <a>Alga</a> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory and implementation details.
--   
--   The top-level module <a>Algebra.Graph</a> defines the main data type
--   for <i>algebraic graphs</i> <a>Graph</a>, as well as associated
--   algorithms. For type-safe representation and manipulation of
--   <i>non-empty algebraic graphs</i>, see <a>Algebra.Graph.NonEmpty</a>.
--   Furthermore, <i>algebraic graphs with edge labels</i> are implemented
--   in <a>Algebra.Graph.Labelled</a>.
--   
--   The library also provides conventional graph data structures, such as
--   <a>Algebra.Graph.AdjacencyMap</a> along with its various flavours:
--   
--   <ul>
--   <li>adjacency maps specialised to graphs with vertices of type
--   <a>Int</a> (<a>Algebra.Graph.AdjacencyIntMap</a>),</li>
--   <li>non-empty adjacency maps
--   (<a>Algebra.Graph.NonEmpty.AdjacencyMap</a>),</li>
--   <li>adjacency maps for undirected bipartite graphs
--   (<a>Algebra.Graph.Bipartite.AdjacencyMap</a>),</li>
--   <li>adjacency maps with edge labels
--   (<a>Algebra.Graph.Labelled.AdjacencyMap</a>),</li>
--   <li>acyclic adjacency maps
--   (<a>Algebra.Graph.Acyclic.AdjacencyMap</a>),</li>
--   </ul>
--   
--   A large part of the API of algebraic graphs and adjacency maps is
--   available through the <a>Foldable</a>-like type class
--   <a>Algebra.Graph.ToGraph</a>.
--   
--   The type classes defined in <a>Algebra.Graph.Class</a> and
--   <a>Algebra.Graph.HigherKinded.Class</a> can be used for polymorphic
--   construction and manipulation of graphs.
--   
--   This is an experimental library and the API is expected to remain
--   unstable until version 1.0.0. Please consider contributing to the
--   on-going <a>discussions on the library API</a>.
@package algebraic-graphs
@version 0.6


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module defines the <a>AdjacencyMap</a> data type and associated
--   functions. See <a>Algebra.Graph.AdjacencyMap.Algorithm</a> for basic
--   graph algorithms. <a>AdjacencyMap</a> is an instance of the
--   <a>Graph</a> type class, which can be used for polymorphic graph
--   construction and manipulation. <a>Algebra.Graph.AdjacencyIntMap</a>
--   defines adjacency maps specialised to graphs with <tt>Int</tt>
--   vertices.
module Algebra.Graph.AdjacencyMap

-- | The <a>AdjacencyMap</a> data type represents a graph by a map of
--   vertices to their adjacency sets. We define a <a>Num</a> instance as a
--   convenient notation for working with graphs:
--   
--   <pre>
--   0           == <a>vertex</a> 0
--   1 + 2       == <a>overlay</a> (<a>vertex</a> 1) (<a>vertex</a> 2)
--   1 * 2       == <a>connect</a> (<a>vertex</a> 1) (<a>vertex</a> 2)
--   1 + 2 * 3   == <a>overlay</a> (<a>vertex</a> 1) (<a>connect</a> (<a>vertex</a> 2) (<a>vertex</a> 3))
--   1 * (2 + 3) == <a>connect</a> (<a>vertex</a> 1) (<a>overlay</a> (<a>vertex</a> 2) (<a>vertex</a> 3))
--   </pre>
--   
--   <b>Note:</b> the <a>Num</a> instance does not satisfy several
--   "customary laws" of <a>Num</a>, which dictate that <a>fromInteger</a>
--   <tt>0</tt> and <a>fromInteger</a> <tt>1</tt> should act as additive
--   and multiplicative identities, and <a>negate</a> as additive inverse.
--   Nevertheless, overloading <a>fromInteger</a>, <a>+</a> and <a>*</a> is
--   very convenient when working with algebraic graphs; we hope that in
--   future Haskell's Prelude will provide a more fine-grained class
--   hierarchy for algebraic structures, which we would be able to utilise
--   without violating any laws.
--   
--   The <a>Show</a> instance is defined using basic graph construction
--   primitives:
--   
--   <pre>
--   show (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) == "overlay (vertex 3) (edge 1 2)"
--   </pre>
--   
--   The <a>Eq</a> instance satisfies all axioms of algebraic graphs:
--   
--   <ul>
--   <li><a>overlay</a> is commutative and associative:<pre> x + y == y + x
--   x + (y + z) == (x + y) + z</pre></li>
--   <li><a>connect</a> is associative and has <a>empty</a> as the
--   identity:<pre> x * empty == x empty * x == x x * (y * z) == (x * y) *
--   z</pre></li>
--   <li><a>connect</a> distributes over <a>overlay</a>:<pre>x * (y + z) ==
--   x * y + x * z (x + y) * z == x * z + y * z</pre></li>
--   <li><a>connect</a> can be decomposed:<pre>x * y * z == x * y + x * z +
--   y * z</pre></li>
--   </ul>
--   
--   The following useful theorems can be proved from the above set of
--   axioms.
--   
--   <ul>
--   <li><a>overlay</a> has <a>empty</a> as the identity and is
--   idempotent:<pre> x + empty == x empty + x == x x + x == x</pre></li>
--   <li>Absorption and saturation of <a>connect</a>:<pre>x * y + x + y ==
--   x * y x * x * x == x * x</pre></li>
--   </ul>
--   
--   When specifying the time and memory complexity of graph algorithms,
--   <i>n</i> and <i>m</i> will denote the number of vertices and edges in
--   the graph, respectively.
--   
--   The total order on graphs is defined using <i>size-lexicographic</i>
--   comparison:
--   
--   <ul>
--   <li>Compare the number of vertices. In case of a tie, continue.</li>
--   <li>Compare the sets of vertices. In case of a tie, continue.</li>
--   <li>Compare the number of edges. In case of a tie, continue.</li>
--   <li>Compare the sets of edges.</li>
--   </ul>
--   
--   Here are a few examples:
--   
--   <pre>
--   <a>vertex</a> 1 &lt; <a>vertex</a> 2
--   <a>vertex</a> 3 &lt; <a>edge</a> 1 2
--   <a>vertex</a> 1 &lt; <a>edge</a> 1 1
--   <a>edge</a> 1 1 &lt; <a>edge</a> 1 2
--   <a>edge</a> 1 2 &lt; <a>edge</a> 1 1 + <a>edge</a> 2 2
--   <a>edge</a> 1 2 &lt; <a>edge</a> 1 3
--   </pre>
--   
--   Note that the resulting order refines the <a>isSubgraphOf</a> relation
--   and is compatible with <a>overlay</a> and <a>connect</a> operations:
--   
--   <pre>
--   <a>isSubgraphOf</a> x y ==&gt; x &lt;= y
--   </pre>
--   
--   <pre>
--   <a>empty</a> &lt;= x
--   x     &lt;= x + y
--   x + y &lt;= x * y
--   </pre>
data AdjacencyMap a

-- | The <i>adjacency map</i> of a graph: each vertex is associated with a
--   set of its direct successors. Complexity: <i>O(1)</i> time and memory.
--   
--   <pre>
--   adjacencyMap <a>empty</a>      == Map.<a>empty</a>
--   adjacencyMap (<a>vertex</a> x) == Map.<a>singleton</a> x Set.<a>empty</a>
--   adjacencyMap (<a>edge</a> 1 1) == Map.<a>singleton</a> 1 (Set.<a>singleton</a> 1)
--   adjacencyMap (<a>edge</a> 1 2) == Map.<a>fromList</a> [(1,Set.<a>singleton</a> 2), (2,Set.<a>empty</a>)]
--   </pre>
adjacencyMap :: AdjacencyMap a -> Map a (Set a)

-- | Construct the <i>empty graph</i>.
--   
--   <pre>
--   <a>isEmpty</a>     empty == True
--   <a>hasVertex</a> x empty == False
--   <a>vertexCount</a> empty == 0
--   <a>edgeCount</a>   empty == 0
--   </pre>
empty :: AdjacencyMap a

-- | Construct the graph comprising <i>a single isolated vertex</i>.
--   
--   <pre>
--   <a>isEmpty</a>     (vertex x) == False
--   <a>hasVertex</a> x (vertex y) == (x == y)
--   <a>vertexCount</a> (vertex x) == 1
--   <a>edgeCount</a>   (vertex x) == 0
--   </pre>
vertex :: a -> AdjacencyMap a

-- | Construct the graph comprising <i>a single edge</i>.
--   
--   <pre>
--   edge x y               == <a>connect</a> (<a>vertex</a> x) (<a>vertex</a> y)
--   <a>hasEdge</a> x y (edge x y) == True
--   <a>edgeCount</a>   (edge x y) == 1
--   <a>vertexCount</a> (edge 1 1) == 1
--   <a>vertexCount</a> (edge 1 2) == 2
--   </pre>
edge :: Ord a => a -> a -> AdjacencyMap a

-- | <i>Overlay</i> two graphs. This is a commutative, associative and
--   idempotent operation with the identity <a>empty</a>. Complexity:
--   <i>O((n + m) * log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   <a>isEmpty</a>     (overlay x y) == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (overlay x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (overlay x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (overlay x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (overlay x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (overlay x y) &lt;= <a>edgeCount</a> x   + <a>edgeCount</a> y
--   <a>vertexCount</a> (overlay 1 2) == 2
--   <a>edgeCount</a>   (overlay 1 2) == 0
--   </pre>
overlay :: Ord a => AdjacencyMap a -> AdjacencyMap a -> AdjacencyMap a

-- | <i>Connect</i> two graphs. This is an associative operation with the
--   identity <a>empty</a>, which distributes over <a>overlay</a> and obeys
--   the decomposition axiom. Complexity: <i>O((n + m) * log(n))</i> time
--   and <i>O(n + m)</i> memory. Note that the number of edges in the
--   resulting graph is quadratic with respect to the number of vertices of
--   the arguments: <i>m = O(m1 + m2 + n1 * n2)</i>.
--   
--   <pre>
--   <a>isEmpty</a>     (connect x y) == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (connect x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (connect x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (connect x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (connect x y) &gt;= <a>edgeCount</a> y
--   <a>edgeCount</a>   (connect x y) &gt;= <a>vertexCount</a> x * <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect x y) &lt;= <a>vertexCount</a> x * <a>vertexCount</a> y + <a>edgeCount</a> x + <a>edgeCount</a> y
--   <a>vertexCount</a> (connect 1 2) == 2
--   <a>edgeCount</a>   (connect 1 2) == 1
--   </pre>
connect :: Ord a => AdjacencyMap a -> AdjacencyMap a -> AdjacencyMap a

-- | Construct the graph comprising a given list of isolated vertices.
--   Complexity: <i>O(L * log(L))</i> time and <i>O(L)</i> memory, where
--   <i>L</i> is the length of the given list.
--   
--   <pre>
--   vertices []            == <a>empty</a>
--   vertices [x]           == <a>vertex</a> x
--   vertices               == <a>overlays</a> . map <a>vertex</a>
--   <a>hasVertex</a> x . vertices == <a>elem</a> x
--   <a>vertexCount</a> . vertices == <a>length</a> . <a>nub</a>
--   <a>vertexSet</a>   . vertices == Set.<a>fromList</a>
--   </pre>
vertices :: Ord a => [a] -> AdjacencyMap a

-- | Construct the graph from a list of edges. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   edges []          == <a>empty</a>
--   edges [(x,y)]     == <a>edge</a> x y
--   edges             == <a>overlays</a> . <a>map</a> (<a>uncurry</a> <a>edge</a>)
--   <a>edgeCount</a> . edges == <a>length</a> . <a>nub</a>
--   <a>edgeList</a> . edges  == <a>nub</a> . <a>sort</a>
--   </pre>
edges :: Ord a => [(a, a)] -> AdjacencyMap a

-- | Overlay a given list of graphs. Complexity: <i>O((n + m) * log(n))</i>
--   time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   overlays []        == <a>empty</a>
--   overlays [x]       == x
--   overlays [x,y]     == <a>overlay</a> x y
--   overlays           == <a>foldr</a> <a>overlay</a> <a>empty</a>
--   <a>isEmpty</a> . overlays == <a>all</a> <a>isEmpty</a>
--   </pre>
overlays :: Ord a => [AdjacencyMap a] -> AdjacencyMap a

-- | Connect a given list of graphs. Complexity: <i>O((n + m) * log(n))</i>
--   time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   connects []        == <a>empty</a>
--   connects [x]       == x
--   connects [x,y]     == <a>connect</a> x y
--   connects           == <a>foldr</a> <a>connect</a> <a>empty</a>
--   <a>isEmpty</a> . connects == <a>all</a> <a>isEmpty</a>
--   </pre>
connects :: Ord a => [AdjacencyMap a] -> AdjacencyMap a

-- | The <a>isSubgraphOf</a> function takes two graphs and returns
--   <a>True</a> if the first graph is a <i>subgraph</i> of the second.
--   Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   isSubgraphOf <a>empty</a>         x             ==  True
--   isSubgraphOf (<a>vertex</a> x)    <a>empty</a>         ==  False
--   isSubgraphOf x             (<a>overlay</a> x y) ==  True
--   isSubgraphOf (<a>overlay</a> x y) (<a>connect</a> x y) ==  True
--   isSubgraphOf (<a>path</a> xs)     (<a>circuit</a> xs)  ==  True
--   isSubgraphOf x y                         ==&gt; x &lt;= y
--   </pre>
isSubgraphOf :: Ord a => AdjacencyMap a -> AdjacencyMap a -> Bool

-- | Check if a graph is empty. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   isEmpty <a>empty</a>                       == True
--   isEmpty (<a>overlay</a> <a>empty</a> <a>empty</a>)       == True
--   isEmpty (<a>vertex</a> x)                  == False
--   isEmpty (<a>removeVertex</a> x $ <a>vertex</a> x) == True
--   isEmpty (<a>removeEdge</a> x y $ <a>edge</a> x y) == False
--   </pre>
isEmpty :: AdjacencyMap a -> Bool

-- | Check if a graph contains a given vertex. Complexity: <i>O(log(n))</i>
--   time.
--   
--   <pre>
--   hasVertex x <a>empty</a>            == False
--   hasVertex x (<a>vertex</a> y)       == (x == y)
--   hasVertex x . <a>removeVertex</a> x == <a>const</a> False
--   </pre>
hasVertex :: Ord a => a -> AdjacencyMap a -> Bool

-- | Check if a graph contains a given edge. Complexity: <i>O(log(n))</i>
--   time.
--   
--   <pre>
--   hasEdge x y <a>empty</a>            == False
--   hasEdge x y (<a>vertex</a> z)       == False
--   hasEdge x y (<a>edge</a> x y)       == True
--   hasEdge x y . <a>removeEdge</a> x y == <a>const</a> False
--   hasEdge x y                  == <a>elem</a> (x,y) . <a>edgeList</a>
--   </pre>
hasEdge :: Ord a => a -> a -> AdjacencyMap a -> Bool

-- | The number of vertices in a graph. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   vertexCount <a>empty</a>             ==  0
--   vertexCount (<a>vertex</a> x)        ==  1
--   vertexCount                   ==  <a>length</a> . <a>vertexList</a>
--   vertexCount x &lt; vertexCount y ==&gt; x &lt; y
--   </pre>
vertexCount :: AdjacencyMap a -> Int

-- | The number of edges in a graph. Complexity: <i>O(n)</i> time.
--   
--   <pre>
--   edgeCount <a>empty</a>      == 0
--   edgeCount (<a>vertex</a> x) == 0
--   edgeCount (<a>edge</a> x y) == 1
--   edgeCount            == <a>length</a> . <a>edgeList</a>
--   </pre>
edgeCount :: AdjacencyMap a -> Int

-- | The sorted list of vertices of a given graph. Complexity: <i>O(n)</i>
--   time and memory.
--   
--   <pre>
--   vertexList <a>empty</a>      == []
--   vertexList (<a>vertex</a> x) == [x]
--   vertexList . <a>vertices</a> == <a>nub</a> . <a>sort</a>
--   </pre>
vertexList :: AdjacencyMap a -> [a]

-- | The sorted list of edges of a graph. Complexity: <i>O(n + m)</i> time
--   and <i>O(m)</i> memory.
--   
--   <pre>
--   edgeList <a>empty</a>          == []
--   edgeList (<a>vertex</a> x)     == []
--   edgeList (<a>edge</a> x y)     == [(x,y)]
--   edgeList (<a>star</a> 2 [3,1]) == [(2,1), (2,3)]
--   edgeList . <a>edges</a>        == <a>nub</a> . <a>sort</a>
--   edgeList . <a>transpose</a>    == <a>sort</a> . <a>map</a> <a>swap</a> . edgeList
--   </pre>
edgeList :: AdjacencyMap a -> [(a, a)]

-- | The sorted <i>adjacency list</i> of a graph. Complexity: <i>O(n +
--   m)</i> time and memory.
--   
--   <pre>
--   adjacencyList <a>empty</a>          == []
--   adjacencyList (<a>vertex</a> x)     == [(x, [])]
--   adjacencyList (<a>edge</a> 1 2)     == [(1, [2]), (2, [])]
--   adjacencyList (<a>star</a> 2 [3,1]) == [(1, []), (2, [1,3]), (3, [])]
--   <a>stars</a> . adjacencyList        == id
--   </pre>
adjacencyList :: AdjacencyMap a -> [(a, [a])]

-- | The set of vertices of a given graph. Complexity: <i>O(n)</i> time and
--   memory.
--   
--   <pre>
--   vertexSet <a>empty</a>      == Set.<a>empty</a>
--   vertexSet . <a>vertex</a>   == Set.<a>singleton</a>
--   vertexSet . <a>vertices</a> == Set.<a>fromList</a>
--   </pre>
vertexSet :: AdjacencyMap a -> Set a

-- | The set of edges of a given graph. Complexity: <i>O((n + m) *
--   log(m))</i> time and <i>O(m)</i> memory.
--   
--   <pre>
--   edgeSet <a>empty</a>      == Set.<a>empty</a>
--   edgeSet (<a>vertex</a> x) == Set.<a>empty</a>
--   edgeSet (<a>edge</a> x y) == Set.<a>singleton</a> (x,y)
--   edgeSet . <a>edges</a>    == Set.<a>fromList</a>
--   </pre>
edgeSet :: Eq a => AdjacencyMap a -> Set (a, a)

-- | The <i>preset</i> of an element <tt>x</tt> is the set of its <i>direct
--   predecessors</i>. Complexity: <i>O(n * log(n))</i> time and
--   <i>O(n)</i> memory.
--   
--   <pre>
--   preSet x <a>empty</a>      == Set.<a>empty</a>
--   preSet x (<a>vertex</a> x) == Set.<a>empty</a>
--   preSet 1 (<a>edge</a> 1 2) == Set.<a>empty</a>
--   preSet y (<a>edge</a> x y) == Set.<a>fromList</a> [x]
--   </pre>
preSet :: Ord a => a -> AdjacencyMap a -> Set a

-- | The <i>postset</i> of a vertex is the set of its <i>direct
--   successors</i>. Complexity: <i>O(log(n))</i> time and <i>O(1)</i>
--   memory.
--   
--   <pre>
--   postSet x <a>empty</a>      == Set.<a>empty</a>
--   postSet x (<a>vertex</a> x) == Set.<a>empty</a>
--   postSet x (<a>edge</a> x y) == Set.<a>fromList</a> [y]
--   postSet 2 (<a>edge</a> 1 2) == Set.<a>empty</a>
--   </pre>
postSet :: Ord a => a -> AdjacencyMap a -> Set a

-- | The <i>path</i> on a list of vertices. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   path []        == <a>empty</a>
--   path [x]       == <a>vertex</a> x
--   path [x,y]     == <a>edge</a> x y
--   path . <a>reverse</a> == <a>transpose</a> . path
--   </pre>
path :: Ord a => [a] -> AdjacencyMap a

-- | The <i>circuit</i> on a list of vertices. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   circuit []        == <a>empty</a>
--   circuit [x]       == <a>edge</a> x x
--   circuit [x,y]     == <a>edges</a> [(x,y), (y,x)]
--   circuit . <a>reverse</a> == <a>transpose</a> . circuit
--   </pre>
circuit :: Ord a => [a] -> AdjacencyMap a

-- | The <i>clique</i> on a list of vertices. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   clique []         == <a>empty</a>
--   clique [x]        == <a>vertex</a> x
--   clique [x,y]      == <a>edge</a> x y
--   clique [x,y,z]    == <a>edges</a> [(x,y), (x,z), (y,z)]
--   clique (xs <a>++</a> ys) == <a>connect</a> (clique xs) (clique ys)
--   clique . <a>reverse</a>  == <a>transpose</a> . clique
--   </pre>
clique :: Ord a => [a] -> AdjacencyMap a

-- | The <i>biclique</i> on two lists of vertices. Complexity: <i>O(n *
--   log(n) + m)</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   biclique []      []      == <a>empty</a>
--   biclique [x]     []      == <a>vertex</a> x
--   biclique []      [y]     == <a>vertex</a> y
--   biclique [x1,x2] [y1,y2] == <a>edges</a> [(x1,y1), (x1,y2), (x2,y1), (x2,y2)]
--   biclique xs      ys      == <a>connect</a> (<a>vertices</a> xs) (<a>vertices</a> ys)
--   </pre>
biclique :: Ord a => [a] -> [a] -> AdjacencyMap a

-- | The <i>star</i> formed by a centre vertex connected to a list of
--   leaves. Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n +
--   m)</i> memory.
--   
--   <pre>
--   star x []    == <a>vertex</a> x
--   star x [y]   == <a>edge</a> x y
--   star x [y,z] == <a>edges</a> [(x,y), (x,z)]
--   star x ys    == <a>connect</a> (<a>vertex</a> x) (<a>vertices</a> ys)
--   </pre>
star :: Ord a => a -> [a] -> AdjacencyMap a

-- | The <i>stars</i> formed by overlaying a list of <a>star</a>s. An
--   inverse of <a>adjacencyList</a>. Complexity: <i>O(L * log(n))</i>
--   time, memory and size, where <i>L</i> is the total size of the input.
--   
--   <pre>
--   stars []                      == <a>empty</a>
--   stars [(x, [])]               == <a>vertex</a> x
--   stars [(x, [y])]              == <a>edge</a> x y
--   stars [(x, ys)]               == <a>star</a> x ys
--   stars                         == <a>overlays</a> . <a>map</a> (<a>uncurry</a> <a>star</a>)
--   stars . <a>adjacencyList</a>         == id
--   <a>overlay</a> (stars xs) (stars ys) == stars (xs <a>++</a> ys)
--   </pre>
stars :: Ord a => [(a, [a])] -> AdjacencyMap a

-- | Construct a graph from a list of adjacency sets; a variation of
--   <a>stars</a>. Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n +
--   m)</i> memory.
--   
--   <pre>
--   fromAdjacencySets []                                  == <a>empty</a>
--   fromAdjacencySets [(x, Set.<a>empty</a>)]                    == <a>vertex</a> x
--   fromAdjacencySets [(x, Set.<a>singleton</a> y)]              == <a>edge</a> x y
--   fromAdjacencySets . <a>map</a> (<a>fmap</a> Set.<a>fromList</a>)           == <a>stars</a>
--   <a>overlay</a> (fromAdjacencySets xs) (fromAdjacencySets ys) == fromAdjacencySets (xs <a>++</a> ys)
--   </pre>
fromAdjacencySets :: Ord a => [(a, Set a)] -> AdjacencyMap a

-- | The <i>tree graph</i> constructed from a given <a>Tree</a> data
--   structure. Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n +
--   m)</i> memory.
--   
--   <pre>
--   tree (Node x [])                                         == <a>vertex</a> x
--   tree (Node x [Node y [Node z []]])                       == <a>path</a> [x,y,z]
--   tree (Node x [Node y [], Node z []])                     == <a>star</a> x [y,z]
--   tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) == <a>edges</a> [(1,2), (1,3), (3,4), (3,5)]
--   </pre>
tree :: Ord a => Tree a -> AdjacencyMap a

-- | The <i>forest graph</i> constructed from a given <a>Forest</a> data
--   structure. Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n +
--   m)</i> memory.
--   
--   <pre>
--   forest []                                                  == <a>empty</a>
--   forest [x]                                                 == <a>tree</a> x
--   forest [Node 1 [Node 2 [], Node 3 []], Node 4 [Node 5 []]] == <a>edges</a> [(1,2), (1,3), (4,5)]
--   forest                                                     == <a>overlays</a> . <a>map</a> <a>tree</a>
--   </pre>
forest :: Ord a => Forest a -> AdjacencyMap a

-- | Remove a vertex from a given graph. Complexity: <i>O(n*log(n))</i>
--   time.
--   
--   <pre>
--   removeVertex x (<a>vertex</a> x)       == <a>empty</a>
--   removeVertex 1 (<a>vertex</a> 2)       == <a>vertex</a> 2
--   removeVertex x (<a>edge</a> x x)       == <a>empty</a>
--   removeVertex 1 (<a>edge</a> 1 2)       == <a>vertex</a> 2
--   removeVertex x . removeVertex x == removeVertex x
--   </pre>
removeVertex :: Ord a => a -> AdjacencyMap a -> AdjacencyMap a

-- | Remove an edge from a given graph. Complexity: <i>O(log(n))</i> time.
--   
--   <pre>
--   removeEdge x y (<a>edge</a> x y)       == <a>vertices</a> [x,y]
--   removeEdge x y . removeEdge x y == removeEdge x y
--   removeEdge x y . <a>removeVertex</a> x == <a>removeVertex</a> x
--   removeEdge 1 1 (1 * 1 * 2 * 2)  == 1 * 2 * 2
--   removeEdge 1 2 (1 * 1 * 2 * 2)  == 1 * 1 + 2 * 2
--   </pre>
removeEdge :: Ord a => a -> a -> AdjacencyMap a -> AdjacencyMap a

-- | The function <tt><a>replaceVertex</a> x y</tt> replaces vertex
--   <tt>x</tt> with vertex <tt>y</tt> in a given <a>AdjacencyMap</a>. If
--   <tt>y</tt> already exists, <tt>x</tt> and <tt>y</tt> will be merged.
--   Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   replaceVertex x x            == id
--   replaceVertex x y (<a>vertex</a> x) == <a>vertex</a> y
--   replaceVertex x y            == <a>mergeVertices</a> (== x) y
--   </pre>
replaceVertex :: Ord a => a -> a -> AdjacencyMap a -> AdjacencyMap a

-- | Merge vertices satisfying a given predicate into a given vertex.
--   Complexity: <i>O((n + m) * log(n))</i> time, assuming that the
--   predicate takes constant time.
--   
--   <pre>
--   mergeVertices (<a>const</a> False) x    == id
--   mergeVertices (== x) y           == <a>replaceVertex</a> x y
--   mergeVertices <a>even</a> 1 (0 * 2)     == 1 * 1
--   mergeVertices <a>odd</a>  1 (3 + 4 * 5) == 4 * 1
--   </pre>
mergeVertices :: Ord a => (a -> Bool) -> a -> AdjacencyMap a -> AdjacencyMap a

-- | Transpose a given graph. Complexity: <i>O(m * log(n))</i> time, <i>O(n
--   + m)</i> memory.
--   
--   <pre>
--   transpose <a>empty</a>       == <a>empty</a>
--   transpose (<a>vertex</a> x)  == <a>vertex</a> x
--   transpose (<a>edge</a> x y)  == <a>edge</a> y x
--   transpose . transpose == id
--   <a>edgeList</a> . transpose  == <a>sort</a> . <a>map</a> <a>swap</a> . <a>edgeList</a>
--   </pre>
transpose :: Ord a => AdjacencyMap a -> AdjacencyMap a

-- | Transform a graph by applying a function to each of its vertices. This
--   is similar to <tt>Functor</tt>'s <a>fmap</a> but can be used with
--   non-fully-parametric <a>AdjacencyMap</a>. Complexity: <i>O((n + m) *
--   log(n))</i> time.
--   
--   <pre>
--   gmap f <a>empty</a>      == <a>empty</a>
--   gmap f (<a>vertex</a> x) == <a>vertex</a> (f x)
--   gmap f (<a>edge</a> x y) == <a>edge</a> (f x) (f y)
--   gmap <a>id</a>           == <a>id</a>
--   gmap f . gmap g   == gmap (f . g)
--   </pre>
gmap :: (Ord a, Ord b) => (a -> b) -> AdjacencyMap a -> AdjacencyMap b

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that do not satisfy a given predicate. Complexity: <i>O(n +
--   m)</i> time, assuming that the predicate takes constant time.
--   
--   <pre>
--   induce (<a>const</a> True ) x      == x
--   induce (<a>const</a> False) x      == <a>empty</a>
--   induce (/= x)               == <a>removeVertex</a> x
--   induce p . induce q         == induce (\x -&gt; p x &amp;&amp; q x)
--   <a>isSubgraphOf</a> (induce p x) x == True
--   </pre>
induce :: (a -> Bool) -> AdjacencyMap a -> AdjacencyMap a

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that are <a>Nothing</a>. Complexity: <i>O(n + m)</i> time.
--   
--   <pre>
--   induceJust (<a>vertex</a> <a>Nothing</a>)                               == <a>empty</a>
--   induceJust (<a>edge</a> (<a>Just</a> x) <a>Nothing</a>)                        == <a>vertex</a> x
--   induceJust . <a>gmap</a> <a>Just</a>                                    == <a>id</a>
--   induceJust . <a>gmap</a> (\x -&gt; if p x then <a>Just</a> x else <a>Nothing</a>) == <a>induce</a> p
--   </pre>
induceJust :: Ord a => AdjacencyMap (Maybe a) -> AdjacencyMap a

-- | Left-to-right <i>relational composition</i> of graphs: vertices
--   <tt>x</tt> and <tt>z</tt> are connected in the resulting graph if
--   there is a vertex <tt>y</tt>, such that <tt>x</tt> is connected to
--   <tt>y</tt> in the first graph, and <tt>y</tt> is connected to
--   <tt>z</tt> in the second graph. There are no isolated vertices in the
--   result. This operation is associative, has <a>empty</a> and
--   single-<a>vertex</a> graphs as <i>annihilating zeroes</i>, and
--   distributes over <a>overlay</a>. Complexity: <i>O(n * m * log(n))</i>
--   time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   compose <a>empty</a>            x                == <a>empty</a>
--   compose x                <a>empty</a>            == <a>empty</a>
--   compose (<a>vertex</a> x)       y                == <a>empty</a>
--   compose x                (<a>vertex</a> y)       == <a>empty</a>
--   compose x                (compose y z)    == compose (compose x y) z
--   compose x                (<a>overlay</a> y z)    == <a>overlay</a> (compose x y) (compose x z)
--   compose (<a>overlay</a> x y)    z                == <a>overlay</a> (compose x z) (compose y z)
--   compose (<a>edge</a> x y)       (<a>edge</a> y z)       == <a>edge</a> x z
--   compose (<a>path</a>    [1..5]) (<a>path</a>    [1..5]) == <a>edges</a> [(1,3), (2,4), (3,5)]
--   compose (<a>circuit</a> [1..5]) (<a>circuit</a> [1..5]) == <a>circuit</a> [1,3,5,2,4]
--   </pre>
compose :: Ord a => AdjacencyMap a -> AdjacencyMap a -> AdjacencyMap a

-- | Compute the <i>Cartesian product</i> of graphs. Complexity: <i>O((n +
--   m) * log(n))</i> time and O(n + m) memory.
--   
--   <pre>
--   box (<a>path</a> [0,1]) (<a>path</a> "ab") == <a>edges</a> [ ((0,'a'), (0,'b'))
--                                         , ((0,'a'), (1,'a'))
--                                         , ((0,'b'), (1,'b'))
--                                         , ((1,'a'), (1,'b')) ]
--   </pre>
--   
--   Up to isomorphism between the resulting vertex types, this operation
--   is <i>commutative</i>, <i>associative</i>, <i>distributes</i> over
--   <a>overlay</a>, has singleton graphs as <i>identities</i> and
--   <a>empty</a> as the <i>annihilating zero</i>. Below <tt>~~</tt> stands
--   for equality up to an isomorphism, e.g. <tt>(x,</tt> <tt>()) ~~
--   x</tt>.
--   
--   <pre>
--   box x y               ~~ box y x
--   box x (box y z)       ~~ box (box x y) z
--   box x (<a>overlay</a> y z)   == <a>overlay</a> (box x y) (box x z)
--   box x (<a>vertex</a> ())     ~~ x
--   box x <a>empty</a>           ~~ <a>empty</a>
--   <a>transpose</a>   (box x y) == box (<a>transpose</a> x) (<a>transpose</a> y)
--   <a>vertexCount</a> (box x y) == <a>vertexCount</a> x * <a>vertexCount</a> y
--   <a>edgeCount</a>   (box x y) &lt;= <a>vertexCount</a> x * <a>edgeCount</a> y + <a>edgeCount</a> x * <a>vertexCount</a> y
--   </pre>
box :: (Ord a, Ord b) => AdjacencyMap a -> AdjacencyMap b -> AdjacencyMap (a, b)

-- | Compute the <i>reflexive and transitive closure</i> of a graph.
--   Complexity: <i>O(n * m * log(n)^2)</i> time.
--   
--   <pre>
--   closure <a>empty</a>           == <a>empty</a>
--   closure (<a>vertex</a> x)      == <a>edge</a> x x
--   closure (<a>edge</a> x x)      == <a>edge</a> x x
--   closure (<a>edge</a> x y)      == <a>edges</a> [(x,x), (x,y), (y,y)]
--   closure (<a>path</a> $ <a>nub</a> xs) == <a>reflexiveClosure</a> (<a>clique</a> $ <a>nub</a> xs)
--   closure                 == <a>reflexiveClosure</a> . <a>transitiveClosure</a>
--   closure                 == <a>transitiveClosure</a> . <a>reflexiveClosure</a>
--   closure . closure       == closure
--   <a>postSet</a> x (closure y)   == Set.<a>fromList</a> (<a>reachable</a> x y)
--   </pre>
closure :: Ord a => AdjacencyMap a -> AdjacencyMap a

-- | Compute the <i>reflexive closure</i> of a graph by adding a self-loop
--   to every vertex. Complexity: <i>O(n * log(n))</i> time.
--   
--   <pre>
--   reflexiveClosure <a>empty</a>              == <a>empty</a>
--   reflexiveClosure (<a>vertex</a> x)         == <a>edge</a> x x
--   reflexiveClosure (<a>edge</a> x x)         == <a>edge</a> x x
--   reflexiveClosure (<a>edge</a> x y)         == <a>edges</a> [(x,x), (x,y), (y,y)]
--   reflexiveClosure . reflexiveClosure == reflexiveClosure
--   </pre>
reflexiveClosure :: Ord a => AdjacencyMap a -> AdjacencyMap a

-- | Compute the <i>symmetric closure</i> of a graph by overlaying it with
--   its own transpose. Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   symmetricClosure <a>empty</a>              == <a>empty</a>
--   symmetricClosure (<a>vertex</a> x)         == <a>vertex</a> x
--   symmetricClosure (<a>edge</a> x y)         == <a>edges</a> [(x,y), (y,x)]
--   symmetricClosure x                  == <a>overlay</a> x (<a>transpose</a> x)
--   symmetricClosure . symmetricClosure == symmetricClosure
--   </pre>
symmetricClosure :: Ord a => AdjacencyMap a -> AdjacencyMap a

-- | Compute the <i>transitive closure</i> of a graph. Complexity: <i>O(n *
--   m * log(n)^2)</i> time.
--   
--   <pre>
--   transitiveClosure <a>empty</a>               == <a>empty</a>
--   transitiveClosure (<a>vertex</a> x)          == <a>vertex</a> x
--   transitiveClosure (<a>edge</a> x y)          == <a>edge</a> x y
--   transitiveClosure (<a>path</a> $ <a>nub</a> xs)     == <a>clique</a> (<a>nub</a> xs)
--   transitiveClosure . transitiveClosure == transitiveClosure
--   </pre>
transitiveClosure :: Ord a => AdjacencyMap a -> AdjacencyMap a

-- | Check that 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.
--   
--   <pre>
--   consistent <a>empty</a>         == True
--   consistent (<a>vertex</a> x)    == True
--   consistent (<a>overlay</a> x y) == True
--   consistent (<a>connect</a> x y) == True
--   consistent (<a>edge</a> x y)    == True
--   consistent (<a>edges</a> xs)    == True
--   consistent (<a>stars</a> xs)    == True
--   </pre>
consistent :: Ord a => AdjacencyMap a -> Bool
instance GHC.Generics.Generic (Algebra.Graph.AdjacencyMap.AdjacencyMap a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Algebra.Graph.AdjacencyMap.AdjacencyMap a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.AdjacencyMap.AdjacencyMap a)
instance (GHC.Classes.Ord a, GHC.Show.Show a) => GHC.Show.Show (Algebra.Graph.AdjacencyMap.AdjacencyMap a)
instance (GHC.Classes.Ord a, GHC.Num.Num a) => GHC.Num.Num (Algebra.Graph.AdjacencyMap.AdjacencyMap a)
instance Data.String.IsString a => Data.String.IsString (Algebra.Graph.AdjacencyMap.AdjacencyMap a)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Algebra.Graph.AdjacencyMap.AdjacencyMap a)
instance GHC.Classes.Ord a => GHC.Base.Semigroup (Algebra.Graph.AdjacencyMap.AdjacencyMap a)
instance GHC.Classes.Ord a => GHC.Base.Monoid (Algebra.Graph.AdjacencyMap.AdjacencyMap a)


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module defines the <a>AdjacencyIntMap</a> data type and
--   associated functions. See
--   <a>Algebra.Graph.AdjacencyIntMap.Algorithm</a> for implementations of
--   basic graph algorithms. <a>AdjacencyIntMap</a> is an instance of the
--   <a>Graph</a> type class, which can be used for polymorphic graph
--   construction and manipulation. See <a>Algebra.Graph.AdjacencyMap</a>
--   for graphs with non-<tt>Int</tt> vertices.
module Algebra.Graph.AdjacencyIntMap

-- | The <a>AdjacencyIntMap</a> data type represents a graph by a map of
--   vertices to their adjacency sets. We define a <a>Num</a> instance as a
--   convenient notation for working with graphs:
--   
--   <pre>
--   0           == <a>vertex</a> 0
--   1 + 2       == <a>overlay</a> (<a>vertex</a> 1) (<a>vertex</a> 2)
--   1 * 2       == <a>connect</a> (<a>vertex</a> 1) (<a>vertex</a> 2)
--   1 + 2 * 3   == <a>overlay</a> (<a>vertex</a> 1) (<a>connect</a> (<a>vertex</a> 2) (<a>vertex</a> 3))
--   1 * (2 + 3) == <a>connect</a> (<a>vertex</a> 1) (<a>overlay</a> (<a>vertex</a> 2) (<a>vertex</a> 3))
--   </pre>
--   
--   <b>Note:</b> the <a>Num</a> instance does not satisfy several
--   "customary laws" of <a>Num</a>, which dictate that <a>fromInteger</a>
--   <tt>0</tt> and <a>fromInteger</a> <tt>1</tt> should act as additive
--   and multiplicative identities, and <a>negate</a> as additive inverse.
--   Nevertheless, overloading <a>fromInteger</a>, <a>+</a> and <a>*</a> is
--   very convenient when working with algebraic graphs; we hope that in
--   future Haskell's Prelude will provide a more fine-grained class
--   hierarchy for algebraic structures, which we would be able to utilise
--   without violating any laws.
--   
--   The <a>Show</a> instance is defined using basic graph construction
--   primitives:
--   
--   <pre>
--   show (empty     :: AdjacencyIntMap Int) == "empty"
--   show (1         :: AdjacencyIntMap Int) == "vertex 1"
--   show (1 + 2     :: AdjacencyIntMap Int) == "vertices [1,2]"
--   show (1 * 2     :: AdjacencyIntMap Int) == "edge 1 2"
--   show (1 * 2 * 3 :: AdjacencyIntMap Int) == "edges [(1,2),(1,3),(2,3)]"
--   show (1 * 2 + 3 :: AdjacencyIntMap Int) == "overlay (vertex 3) (edge 1 2)"
--   </pre>
--   
--   The <a>Eq</a> instance satisfies all axioms of algebraic graphs:
--   
--   <ul>
--   <li><a>overlay</a> is commutative and associative:<pre> x + y == y + x
--   x + (y + z) == (x + y) + z</pre></li>
--   <li><a>connect</a> is associative and has <a>empty</a> as the
--   identity:<pre> x * empty == x empty * x == x x * (y * z) == (x * y) *
--   z</pre></li>
--   <li><a>connect</a> distributes over <a>overlay</a>:<pre>x * (y + z) ==
--   x * y + x * z (x + y) * z == x * z + y * z</pre></li>
--   <li><a>connect</a> can be decomposed:<pre>x * y * z == x * y + x * z +
--   y * z</pre></li>
--   </ul>
--   
--   The following useful theorems can be proved from the above set of
--   axioms.
--   
--   <ul>
--   <li><a>overlay</a> has <a>empty</a> as the identity and is
--   idempotent:<pre> x + empty == x empty + x == x x + x == x</pre></li>
--   <li>Absorption and saturation of <a>connect</a>:<pre>x * y + x + y ==
--   x * y x * x * x == x * x</pre></li>
--   </ul>
--   
--   When specifying the time and memory complexity of graph algorithms,
--   <i>n</i> and <i>m</i> will denote the number of vertices and edges in
--   the graph, respectively.
--   
--   The total order on graphs is defined using <i>size-lexicographic</i>
--   comparison:
--   
--   <ul>
--   <li>Compare the number of vertices. In case of a tie, continue.</li>
--   <li>Compare the sets of vertices. In case of a tie, continue.</li>
--   <li>Compare the number of edges. In case of a tie, continue.</li>
--   <li>Compare the sets of edges.</li>
--   </ul>
--   
--   Here are a few examples:
--   
--   <pre>
--   <a>vertex</a> 1 &lt; <a>vertex</a> 2
--   <a>vertex</a> 3 &lt; <a>edge</a> 1 2
--   <a>vertex</a> 1 &lt; <a>edge</a> 1 1
--   <a>edge</a> 1 1 &lt; <a>edge</a> 1 2
--   <a>edge</a> 1 2 &lt; <a>edge</a> 1 1 + <a>edge</a> 2 2
--   <a>edge</a> 1 2 &lt; <a>edge</a> 1 3
--   </pre>
--   
--   Note that the resulting order refines the <a>isSubgraphOf</a> relation
--   and is compatible with <a>overlay</a> and <a>connect</a> operations:
--   
--   <pre>
--   <a>isSubgraphOf</a> x y ==&gt; x &lt;= y
--   </pre>
--   
--   <pre>
--   <a>empty</a> &lt;= x
--   x     &lt;= x + y
--   x + y &lt;= x * y
--   </pre>
data AdjacencyIntMap

-- | The <i>adjacency map</i> of a graph: each vertex is associated with a
--   set of its direct successors. Complexity: <i>O(1)</i> time and memory.
--   
--   <pre>
--   adjacencyIntMap <a>empty</a>      == IntMap.<a>empty</a>
--   adjacencyIntMap (<a>vertex</a> x) == IntMap.<a>singleton</a> x IntSet.<a>empty</a>
--   adjacencyIntMap (<a>edge</a> 1 1) == IntMap.<a>singleton</a> 1 (IntSet.<a>singleton</a> 1)
--   adjacencyIntMap (<a>edge</a> 1 2) == IntMap.<a>fromList</a> [(1,IntSet.<a>singleton</a> 2), (2,IntSet.<a>empty</a>)]
--   </pre>
adjacencyIntMap :: AdjacencyIntMap -> IntMap IntSet

-- | Construct an <a>AdjacencyIntMap</a> from an <a>AdjacencyMap</a> with
--   vertices of type <a>Int</a>. Complexity: <i>O(n + m)</i> time and
--   memory.
--   
--   <pre>
--   fromAdjacencyMap == <a>stars</a> . AdjacencyMap.<a>adjacencyList</a>
--   </pre>
fromAdjacencyMap :: AdjacencyMap Int -> AdjacencyIntMap

-- | Construct the <i>empty graph</i>.
--   
--   <pre>
--   <a>isEmpty</a>     empty == True
--   <a>hasVertex</a> x empty == False
--   <a>vertexCount</a> empty == 0
--   <a>edgeCount</a>   empty == 0
--   </pre>
empty :: AdjacencyIntMap

-- | Construct the graph comprising <i>a single isolated vertex</i>.
--   
--   <pre>
--   <a>isEmpty</a>     (vertex x) == False
--   <a>hasVertex</a> x (vertex y) == (x == y)
--   <a>vertexCount</a> (vertex x) == 1
--   <a>edgeCount</a>   (vertex x) == 0
--   </pre>
vertex :: Int -> AdjacencyIntMap

-- | Construct the graph comprising <i>a single edge</i>.
--   
--   <pre>
--   edge x y               == <a>connect</a> (<a>vertex</a> x) (<a>vertex</a> y)
--   <a>hasEdge</a> x y (edge x y) == True
--   <a>edgeCount</a>   (edge x y) == 1
--   <a>vertexCount</a> (edge 1 1) == 1
--   <a>vertexCount</a> (edge 1 2) == 2
--   </pre>
edge :: Int -> Int -> AdjacencyIntMap

-- | <i>Overlay</i> two graphs. This is a commutative, associative and
--   idempotent operation with the identity <a>empty</a>. Complexity:
--   <i>O((n + m) * log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   <a>isEmpty</a>     (overlay x y) == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (overlay x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (overlay x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (overlay x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (overlay x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (overlay x y) &lt;= <a>edgeCount</a> x   + <a>edgeCount</a> y
--   <a>vertexCount</a> (overlay 1 2) == 2
--   <a>edgeCount</a>   (overlay 1 2) == 0
--   </pre>
overlay :: AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap

-- | <i>Connect</i> two graphs. This is an associative operation with the
--   identity <a>empty</a>, which distributes over <a>overlay</a> and obeys
--   the decomposition axiom. Complexity: <i>O((n + m) * log(n))</i> time
--   and <i>O(n + m)</i> memory. Note that the number of edges in the
--   resulting graph is quadratic with respect to the number of vertices of
--   the arguments: <i>m = O(m1 + m2 + n1 * n2)</i>.
--   
--   <pre>
--   <a>isEmpty</a>     (connect x y) == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (connect x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (connect x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (connect x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (connect x y) &gt;= <a>edgeCount</a> y
--   <a>edgeCount</a>   (connect x y) &gt;= <a>vertexCount</a> x * <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect x y) &lt;= <a>vertexCount</a> x * <a>vertexCount</a> y + <a>edgeCount</a> x + <a>edgeCount</a> y
--   <a>vertexCount</a> (connect 1 2) == 2
--   <a>edgeCount</a>   (connect 1 2) == 1
--   </pre>
connect :: AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap

-- | Construct the graph comprising a given list of isolated vertices.
--   Complexity: <i>O(L * log(L))</i> time and <i>O(L)</i> memory, where
--   <i>L</i> is the length of the given list.
--   
--   <pre>
--   vertices []             == <a>empty</a>
--   vertices [x]            == <a>vertex</a> x
--   vertices                == <a>overlays</a> . map <a>vertex</a>
--   <a>hasVertex</a> x  . vertices == <a>elem</a> x
--   <a>vertexCount</a>  . vertices == <a>length</a> . <a>nub</a>
--   <a>vertexIntSet</a> . vertices == IntSet.<a>fromList</a>
--   </pre>
vertices :: [Int] -> AdjacencyIntMap

-- | Construct the graph from a list of edges. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   edges []          == <a>empty</a>
--   edges [(x,y)]     == <a>edge</a> x y
--   edges             == <a>overlays</a> . <a>map</a> (<a>uncurry</a> <a>edge</a>)
--   <a>edgeCount</a> . edges == <a>length</a> . <a>nub</a>
--   <a>edgeList</a> . edges  == <a>nub</a> . <a>sort</a>
--   </pre>
edges :: [(Int, Int)] -> AdjacencyIntMap

-- | Overlay a given list of graphs. Complexity: <i>O((n + m) * log(n))</i>
--   time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   overlays []        == <a>empty</a>
--   overlays [x]       == x
--   overlays [x,y]     == <a>overlay</a> x y
--   overlays           == <a>foldr</a> <a>overlay</a> <a>empty</a>
--   <a>isEmpty</a> . overlays == <a>all</a> <a>isEmpty</a>
--   </pre>
overlays :: [AdjacencyIntMap] -> AdjacencyIntMap

-- | Connect a given list of graphs. Complexity: <i>O((n + m) * log(n))</i>
--   time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   connects []        == <a>empty</a>
--   connects [x]       == x
--   connects [x,y]     == <a>connect</a> x y
--   connects           == <a>foldr</a> <a>connect</a> <a>empty</a>
--   <a>isEmpty</a> . connects == <a>all</a> <a>isEmpty</a>
--   </pre>
connects :: [AdjacencyIntMap] -> AdjacencyIntMap

-- | The <a>isSubgraphOf</a> function takes two graphs and returns
--   <a>True</a> if the first graph is a <i>subgraph</i> of the second.
--   Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   isSubgraphOf <a>empty</a>         x             ==  True
--   isSubgraphOf (<a>vertex</a> x)    <a>empty</a>         ==  False
--   isSubgraphOf x             (<a>overlay</a> x y) ==  True
--   isSubgraphOf (<a>overlay</a> x y) (<a>connect</a> x y) ==  True
--   isSubgraphOf (<a>path</a> xs)     (<a>circuit</a> xs)  ==  True
--   isSubgraphOf x y                         ==&gt; x &lt;= y
--   </pre>
isSubgraphOf :: AdjacencyIntMap -> AdjacencyIntMap -> Bool

-- | Check if a graph is empty. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   isEmpty <a>empty</a>                       == True
--   isEmpty (<a>overlay</a> <a>empty</a> <a>empty</a>)       == True
--   isEmpty (<a>vertex</a> x)                  == False
--   isEmpty (<a>removeVertex</a> x $ <a>vertex</a> x) == True
--   isEmpty (<a>removeEdge</a> x y $ <a>edge</a> x y) == False
--   </pre>
isEmpty :: AdjacencyIntMap -> Bool

-- | Check if a graph contains a given vertex. Complexity: <i>O(log(n))</i>
--   time.
--   
--   <pre>
--   hasVertex x <a>empty</a>            == False
--   hasVertex x (<a>vertex</a> y)       == (x == y)
--   hasVertex x . <a>removeVertex</a> x == <a>const</a> False
--   </pre>
hasVertex :: Int -> AdjacencyIntMap -> Bool

-- | Check if a graph contains a given edge. Complexity: <i>O(log(n))</i>
--   time.
--   
--   <pre>
--   hasEdge x y <a>empty</a>            == False
--   hasEdge x y (<a>vertex</a> z)       == False
--   hasEdge x y (<a>edge</a> x y)       == True
--   hasEdge x y . <a>removeEdge</a> x y == <a>const</a> False
--   hasEdge x y                  == <a>elem</a> (x,y) . <a>edgeList</a>
--   </pre>
hasEdge :: Int -> Int -> AdjacencyIntMap -> Bool

-- | The number of vertices in a graph. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   vertexCount <a>empty</a>             ==  0
--   vertexCount (<a>vertex</a> x)        ==  1
--   vertexCount                   ==  <a>length</a> . <a>vertexList</a>
--   vertexCount x &lt; vertexCount y ==&gt; x &lt; y
--   </pre>
vertexCount :: AdjacencyIntMap -> Int

-- | The number of edges in a graph. Complexity: <i>O(n)</i> time.
--   
--   <pre>
--   edgeCount <a>empty</a>      == 0
--   edgeCount (<a>vertex</a> x) == 0
--   edgeCount (<a>edge</a> x y) == 1
--   edgeCount            == <a>length</a> . <a>edgeList</a>
--   </pre>
edgeCount :: AdjacencyIntMap -> Int

-- | The sorted list of vertices of a given graph. Complexity: <i>O(n)</i>
--   time and memory.
--   
--   <pre>
--   vertexList <a>empty</a>      == []
--   vertexList (<a>vertex</a> x) == [x]
--   vertexList . <a>vertices</a> == <a>nub</a> . <a>sort</a>
--   </pre>
vertexList :: AdjacencyIntMap -> [Int]

-- | The sorted list of edges of a graph. Complexity: <i>O(n + m)</i> time
--   and <i>O(m)</i> memory.
--   
--   <pre>
--   edgeList <a>empty</a>          == []
--   edgeList (<a>vertex</a> x)     == []
--   edgeList (<a>edge</a> x y)     == [(x,y)]
--   edgeList (<a>star</a> 2 [3,1]) == [(2,1), (2,3)]
--   edgeList . <a>edges</a>        == <a>nub</a> . <a>sort</a>
--   edgeList . <a>transpose</a>    == <a>sort</a> . <a>map</a> <a>swap</a> . edgeList
--   </pre>
edgeList :: AdjacencyIntMap -> [(Int, Int)]

-- | The sorted <i>adjacency list</i> of a graph. Complexity: <i>O(n +
--   m)</i> time and memory.
--   
--   <pre>
--   adjacencyList <a>empty</a>          == []
--   adjacencyList (<a>vertex</a> x)     == [(x, [])]
--   adjacencyList (<a>edge</a> 1 2)     == [(1, [2]), (2, [])]
--   adjacencyList (<a>star</a> 2 [3,1]) == [(1, []), (2, [1,3]), (3, [])]
--   <a>stars</a> . adjacencyList        == id
--   </pre>
adjacencyList :: AdjacencyIntMap -> [(Int, [Int])]

-- | The set of vertices of a given graph. Complexity: <i>O(n)</i> time and
--   memory.
--   
--   <pre>
--   vertexIntSet <a>empty</a>      == IntSet.<a>empty</a>
--   vertexIntSet . <a>vertex</a>   == IntSet.<a>singleton</a>
--   vertexIntSet . <a>vertices</a> == IntSet.<a>fromList</a>
--   vertexIntSet . <a>clique</a>   == IntSet.<a>fromList</a>
--   </pre>
vertexIntSet :: AdjacencyIntMap -> IntSet

-- | The set of edges of a given graph. Complexity: <i>O((n + m) *
--   log(m))</i> time and <i>O(m)</i> memory.
--   
--   <pre>
--   edgeSet <a>empty</a>      == Set.<a>empty</a>
--   edgeSet (<a>vertex</a> x) == Set.<a>empty</a>
--   edgeSet (<a>edge</a> x y) == Set.<a>singleton</a> (x,y)
--   edgeSet . <a>edges</a>    == Set.<a>fromList</a>
--   </pre>
edgeSet :: AdjacencyIntMap -> Set (Int, Int)

-- | The <i>preset</i> (here <tt>preIntSet</tt>) of an element <tt>x</tt>
--   is the set of its <i>direct predecessors</i>. Complexity: <i>O(n *
--   log(n))</i> time and <i>O(n)</i> memory.
--   
--   <pre>
--   preIntSet x <a>empty</a>      == Set.<a>empty</a>
--   preIntSet x (<a>vertex</a> x) == Set.<a>empty</a>
--   preIntSet 1 (<a>edge</a> 1 2) == Set.<a>empty</a>
--   preIntSet y (<a>edge</a> x y) == Set.<a>fromList</a> [x]
--   </pre>
preIntSet :: Int -> AdjacencyIntMap -> IntSet

-- | The <i>postset</i> (here <tt>postIntSet</tt>) of a vertex is the set
--   of its <i>direct successors</i>.
--   
--   <pre>
--   postIntSet x <a>empty</a>      == IntSet.<a>empty</a>
--   postIntSet x (<a>vertex</a> x) == IntSet.<a>empty</a>
--   postIntSet x (<a>edge</a> x y) == IntSet.<a>fromList</a> [y]
--   postIntSet 2 (<a>edge</a> 1 2) == IntSet.<a>empty</a>
--   </pre>
postIntSet :: Int -> AdjacencyIntMap -> IntSet

-- | The <i>path</i> on a list of vertices. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   path []        == <a>empty</a>
--   path [x]       == <a>vertex</a> x
--   path [x,y]     == <a>edge</a> x y
--   path . <a>reverse</a> == <a>transpose</a> . path
--   </pre>
path :: [Int] -> AdjacencyIntMap

-- | The <i>circuit</i> on a list of vertices. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   circuit []        == <a>empty</a>
--   circuit [x]       == <a>edge</a> x x
--   circuit [x,y]     == <a>edges</a> [(x,y), (y,x)]
--   circuit . <a>reverse</a> == <a>transpose</a> . circuit
--   </pre>
circuit :: [Int] -> AdjacencyIntMap

-- | The <i>clique</i> on a list of vertices. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   clique []         == <a>empty</a>
--   clique [x]        == <a>vertex</a> x
--   clique [x,y]      == <a>edge</a> x y
--   clique [x,y,z]    == <a>edges</a> [(x,y), (x,z), (y,z)]
--   clique (xs ++ ys) == <a>connect</a> (clique xs) (clique ys)
--   clique . <a>reverse</a>  == <a>transpose</a> . clique
--   </pre>
clique :: [Int] -> AdjacencyIntMap

-- | The <i>biclique</i> on two lists of vertices. Complexity: <i>O(n *
--   log(n) + m)</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   biclique []      []      == <a>empty</a>
--   biclique [x]     []      == <a>vertex</a> x
--   biclique []      [y]     == <a>vertex</a> y
--   biclique [x1,x2] [y1,y2] == <a>edges</a> [(x1,y1), (x1,y2), (x2,y1), (x2,y2)]
--   biclique xs      ys      == <a>connect</a> (<a>vertices</a> xs) (<a>vertices</a> ys)
--   </pre>
biclique :: [Int] -> [Int] -> AdjacencyIntMap

-- | The <i>star</i> formed by a centre vertex connected to a list of
--   leaves. Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n +
--   m)</i> memory.
--   
--   <pre>
--   star x []    == <a>vertex</a> x
--   star x [y]   == <a>edge</a> x y
--   star x [y,z] == <a>edges</a> [(x,y), (x,z)]
--   star x ys    == <a>connect</a> (<a>vertex</a> x) (<a>vertices</a> ys)
--   </pre>
star :: Int -> [Int] -> AdjacencyIntMap

-- | The <i>stars</i> formed by overlaying a list of <a>star</a>s. An
--   inverse of <a>adjacencyList</a>. Complexity: <i>O(L * log(n))</i>
--   time, memory and size, where <i>L</i> is the total size of the input.
--   
--   <pre>
--   stars []                      == <a>empty</a>
--   stars [(x, [])]               == <a>vertex</a> x
--   stars [(x, [y])]              == <a>edge</a> x y
--   stars [(x, ys)]               == <a>star</a> x ys
--   stars                         == <a>overlays</a> . <a>map</a> (<a>uncurry</a> <a>star</a>)
--   stars . <a>adjacencyList</a>         == id
--   <a>overlay</a> (stars xs) (stars ys) == stars (xs ++ ys)
--   </pre>
stars :: [(Int, [Int])] -> AdjacencyIntMap

-- | Construct a graph from a list of adjacency sets; a variation of
--   <a>stars</a>. Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n +
--   m)</i> memory.
--   
--   <pre>
--   fromAdjacencyIntSets []                                     == <a>empty</a>
--   fromAdjacencyIntSets [(x, IntSet.<a>empty</a>)]                    == <a>vertex</a> x
--   fromAdjacencyIntSets [(x, IntSet.<a>singleton</a> y)]              == <a>edge</a> x y
--   fromAdjacencyIntSets . <a>map</a> (<a>fmap</a> IntSet.<a>fromList</a>)           == <a>stars</a>
--   <a>overlay</a> (fromAdjacencyIntSets xs) (fromAdjacencyIntSets ys) == fromAdjacencyIntSets (xs ++ ys)
--   </pre>
fromAdjacencyIntSets :: [(Int, IntSet)] -> AdjacencyIntMap

-- | The <i>tree graph</i> constructed from a given <a>Tree</a> data
--   structure. Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n +
--   m)</i> memory.
--   
--   <pre>
--   tree (Node x [])                                         == <a>vertex</a> x
--   tree (Node x [Node y [Node z []]])                       == <a>path</a> [x,y,z]
--   tree (Node x [Node y [], Node z []])                     == <a>star</a> x [y,z]
--   tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) == <a>edges</a> [(1,2), (1,3), (3,4), (3,5)]
--   </pre>
tree :: Tree Int -> AdjacencyIntMap

-- | The <i>forest graph</i> constructed from a given <a>Forest</a> data
--   structure. Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n +
--   m)</i> memory.
--   
--   <pre>
--   forest []                                                  == <a>empty</a>
--   forest [x]                                                 == <a>tree</a> x
--   forest [Node 1 [Node 2 [], Node 3 []], Node 4 [Node 5 []]] == <a>edges</a> [(1,2), (1,3), (4,5)]
--   forest                                                     == <a>overlays</a> . <a>map</a> <a>tree</a>
--   </pre>
forest :: Forest Int -> AdjacencyIntMap

-- | Remove a vertex from a given graph. Complexity: <i>O(n*log(n))</i>
--   time.
--   
--   <pre>
--   removeVertex x (<a>vertex</a> x)       == <a>empty</a>
--   removeVertex 1 (<a>vertex</a> 2)       == <a>vertex</a> 2
--   removeVertex x (<a>edge</a> x x)       == <a>empty</a>
--   removeVertex 1 (<a>edge</a> 1 2)       == <a>vertex</a> 2
--   removeVertex x . removeVertex x == removeVertex x
--   </pre>
removeVertex :: Int -> AdjacencyIntMap -> AdjacencyIntMap

-- | Remove an edge from a given graph. Complexity: <i>O(log(n))</i> time.
--   
--   <pre>
--   removeEdge x y (<a>edge</a> x y)       == <a>vertices</a> [x,y]
--   removeEdge x y . removeEdge x y == removeEdge x y
--   removeEdge x y . <a>removeVertex</a> x == <a>removeVertex</a> x
--   removeEdge 1 1 (1 * 1 * 2 * 2)  == 1 * 2 * 2
--   removeEdge 1 2 (1 * 1 * 2 * 2)  == 1 * 1 + 2 * 2
--   </pre>
removeEdge :: Int -> Int -> AdjacencyIntMap -> AdjacencyIntMap

-- | The function <tt><a>replaceVertex</a> x y</tt> replaces vertex
--   <tt>x</tt> with vertex <tt>y</tt> in a given <a>AdjacencyIntMap</a>.
--   If <tt>y</tt> already exists, <tt>x</tt> and <tt>y</tt> will be
--   merged. Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   replaceVertex x x            == id
--   replaceVertex x y (<a>vertex</a> x) == <a>vertex</a> y
--   replaceVertex x y            == <a>mergeVertices</a> (== x) y
--   </pre>
replaceVertex :: Int -> Int -> AdjacencyIntMap -> AdjacencyIntMap

-- | Merge vertices satisfying a given predicate into a given vertex.
--   Complexity: <i>O((n + m) * log(n))</i> time, assuming that the
--   predicate takes constant time.
--   
--   <pre>
--   mergeVertices (<a>const</a> False) x    == id
--   mergeVertices (== x) y           == <a>replaceVertex</a> x y
--   mergeVertices <a>even</a> 1 (0 * 2)     == 1 * 1
--   mergeVertices <a>odd</a>  1 (3 + 4 * 5) == 4 * 1
--   </pre>
mergeVertices :: (Int -> Bool) -> Int -> AdjacencyIntMap -> AdjacencyIntMap

-- | Transpose a given graph. Complexity: <i>O(m * log(n))</i> time, <i>O(n
--   + m)</i> memory.
--   
--   <pre>
--   transpose <a>empty</a>       == <a>empty</a>
--   transpose (<a>vertex</a> x)  == <a>vertex</a> x
--   transpose (<a>edge</a> x y)  == <a>edge</a> y x
--   transpose . transpose == id
--   <a>edgeList</a> . transpose  == <a>sort</a> . <a>map</a> <a>swap</a> . <a>edgeList</a>
--   </pre>
transpose :: AdjacencyIntMap -> AdjacencyIntMap

-- | Transform a graph by applying a function to each of its vertices. This
--   is similar to <tt>Functor</tt>'s <a>fmap</a> but can be used with
--   non-fully-parametric <a>AdjacencyIntMap</a>. Complexity: <i>O((n + m)
--   * log(n))</i> time.
--   
--   <pre>
--   gmap f <a>empty</a>      == <a>empty</a>
--   gmap f (<a>vertex</a> x) == <a>vertex</a> (f x)
--   gmap f (<a>edge</a> x y) == <a>edge</a> (f x) (f y)
--   gmap id           == id
--   gmap f . gmap g   == gmap (f . g)
--   </pre>
gmap :: (Int -> Int) -> AdjacencyIntMap -> AdjacencyIntMap

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that do not satisfy a given predicate. Complexity: <i>O(n +
--   m)</i> time, assuming that the predicate takes constant time.
--   
--   <pre>
--   induce (<a>const</a> True ) x      == x
--   induce (<a>const</a> False) x      == <a>empty</a>
--   induce (/= x)               == <a>removeVertex</a> x
--   induce p . induce q         == induce (\x -&gt; p x &amp;&amp; q x)
--   <a>isSubgraphOf</a> (induce p x) x == True
--   </pre>
induce :: (Int -> Bool) -> AdjacencyIntMap -> AdjacencyIntMap

-- | Left-to-right <i>relational composition</i> of graphs: vertices
--   <tt>x</tt> and <tt>z</tt> are connected in the resulting graph if
--   there is a vertex <tt>y</tt>, such that <tt>x</tt> is connected to
--   <tt>y</tt> in the first graph, and <tt>y</tt> is connected to
--   <tt>z</tt> in the second graph. There are no isolated vertices in the
--   result. This operation is associative, has <a>empty</a> and
--   single-<a>vertex</a> graphs as <i>annihilating zeroes</i>, and
--   distributes over <a>overlay</a>. Complexity: <i>O(n * m * log(n))</i>
--   time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   compose <a>empty</a>            x                == <a>empty</a>
--   compose x                <a>empty</a>            == <a>empty</a>
--   compose (<a>vertex</a> x)       y                == <a>empty</a>
--   compose x                (<a>vertex</a> y)       == <a>empty</a>
--   compose x                (compose y z)    == compose (compose x y) z
--   compose x                (<a>overlay</a> y z)    == <a>overlay</a> (compose x y) (compose x z)
--   compose (<a>overlay</a> x y)    z                == <a>overlay</a> (compose x z) (compose y z)
--   compose (<a>edge</a> x y)       (<a>edge</a> y z)       == <a>edge</a> x z
--   compose (<a>path</a>    [1..5]) (<a>path</a>    [1..5]) == <a>edges</a> [(1,3), (2,4), (3,5)]
--   compose (<a>circuit</a> [1..5]) (<a>circuit</a> [1..5]) == <a>circuit</a> [1,3,5,2,4]
--   </pre>
compose :: AdjacencyIntMap -> AdjacencyIntMap -> AdjacencyIntMap

-- | Compute the <i>reflexive and transitive closure</i> of a graph.
--   Complexity: <i>O(n * m * log(n)^2)</i> time.
--   
--   <pre>
--   closure <a>empty</a>            == <a>empty</a>
--   closure (<a>vertex</a> x)       == <a>edge</a> x x
--   closure (<a>edge</a> x x)       == <a>edge</a> x x
--   closure (<a>edge</a> x y)       == <a>edges</a> [(x,x), (x,y), (y,y)]
--   closure (<a>path</a> $ <a>nub</a> xs) == <a>reflexiveClosure</a> (<a>clique</a> $ <a>nub</a> xs)
--   closure                  == <a>reflexiveClosure</a> . <a>transitiveClosure</a>
--   closure                  == <a>transitiveClosure</a> . <a>reflexiveClosure</a>
--   closure . closure        == closure
--   <a>postIntSet</a> x (closure y) == IntSet.<a>fromList</a> (<a>reachable</a> x y)
--   </pre>
closure :: AdjacencyIntMap -> AdjacencyIntMap

-- | Compute the <i>reflexive closure</i> of a graph by adding a self-loop
--   to every vertex. Complexity: <i>O(n * log(n))</i> time.
--   
--   <pre>
--   reflexiveClosure <a>empty</a>              == <a>empty</a>
--   reflexiveClosure (<a>vertex</a> x)         == <a>edge</a> x x
--   reflexiveClosure (<a>edge</a> x x)         == <a>edge</a> x x
--   reflexiveClosure (<a>edge</a> x y)         == <a>edges</a> [(x,x), (x,y), (y,y)]
--   reflexiveClosure . reflexiveClosure == reflexiveClosure
--   </pre>
reflexiveClosure :: AdjacencyIntMap -> AdjacencyIntMap

-- | Compute the <i>symmetric closure</i> of a graph by overlaying it with
--   its own transpose. Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   symmetricClosure <a>empty</a>              == <a>empty</a>
--   symmetricClosure (<a>vertex</a> x)         == <a>vertex</a> x
--   symmetricClosure (<a>edge</a> x y)         == <a>edges</a> [(x,y), (y,x)]
--   symmetricClosure x                  == <a>overlay</a> x (<a>transpose</a> x)
--   symmetricClosure . symmetricClosure == symmetricClosure
--   </pre>
symmetricClosure :: AdjacencyIntMap -> AdjacencyIntMap

-- | Compute the <i>transitive closure</i> of a graph. Complexity: <i>O(n *
--   m * log(n)^2)</i> time.
--   
--   <pre>
--   transitiveClosure <a>empty</a>               == <a>empty</a>
--   transitiveClosure (<a>vertex</a> x)          == <a>vertex</a> x
--   transitiveClosure (<a>edge</a> x y)          == <a>edge</a> x y
--   transitiveClosure (<a>path</a> $ <a>nub</a> xs)     == <a>clique</a> (<a>nub</a> xs)
--   transitiveClosure . transitiveClosure == transitiveClosure
--   </pre>
transitiveClosure :: AdjacencyIntMap -> AdjacencyIntMap

-- | Check that 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.
--   
--   <pre>
--   consistent <a>empty</a>         == True
--   consistent (<a>vertex</a> x)    == True
--   consistent (<a>overlay</a> x y) == True
--   consistent (<a>connect</a> x y) == True
--   consistent (<a>edge</a> x y)    == True
--   consistent (<a>edges</a> xs)    == True
--   consistent (<a>stars</a> xs)    == True
--   </pre>
consistent :: AdjacencyIntMap -> Bool
instance GHC.Generics.Generic Algebra.Graph.AdjacencyIntMap.AdjacencyIntMap
instance GHC.Classes.Eq Algebra.Graph.AdjacencyIntMap.AdjacencyIntMap
instance GHC.Show.Show Algebra.Graph.AdjacencyIntMap.AdjacencyIntMap
instance GHC.Classes.Ord Algebra.Graph.AdjacencyIntMap.AdjacencyIntMap
instance GHC.Num.Num Algebra.Graph.AdjacencyIntMap.AdjacencyIntMap
instance Control.DeepSeq.NFData Algebra.Graph.AdjacencyIntMap.AdjacencyIntMap
instance GHC.Base.Semigroup Algebra.Graph.AdjacencyIntMap.AdjacencyIntMap
instance GHC.Base.Monoid Algebra.Graph.AdjacencyIntMap.AdjacencyIntMap


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module provides basic graph algorithms, such as <i>depth-first
--   search</i>, implemented for the <a>Algebra.Graph.AdjacencyIntMap</a>
--   data type.
--   
--   Some of the worst-case complexities include the term <i>min(n,W)</i>.
--   Following <a>IntSet</a> and <a>IntMap</a>, the <i>W</i> stands for
--   word size (usually 32 or 64 bits).
module Algebra.Graph.AdjacencyIntMap.Algorithm

-- | Compute the <i>breadth-first search</i> forest of a graph, such that
--   adjacent vertices are explored in increasing order with respect to
--   their <a>Ord</a> instance. The search is seeded by a list of argument
--   vertices that will be the roots of the resulting forest. Duplicates in
--   the list will have their first occurrence expanded and subsequent ones
--   ignored. Argument vertices not in the graph are also ignored.
--   
--   Let <i>L</i> be the number of seed vertices. Complexity:
--   <i>O((L+m)*min(n,W))</i> time and <i>O(n)</i> space.
--   
--   <pre>
--   <a>forest</a> (bfsForest [1,2] $ <a>edge</a> 1 2)      == <a>vertices</a> [1,2]
--   <a>forest</a> (bfsForest [2]   $ <a>edge</a> 1 2)      == <a>vertex</a> 2
--   <a>forest</a> (bfsForest [3]   $ <a>edge</a> 1 2)      == <a>empty</a>
--   <a>forest</a> (bfsForest [2,1] $ <a>edge</a> 1 2)      == <a>vertices</a> [1,2]
--   <a>isSubgraphOf</a> (<a>forest</a> $ bfsForest vs x) x == True
--   bfsForest (<a>vertexList</a> g) g               == <a>map</a> (v -&gt; Node v []) (<tt>nub</tt> $ <a>vertexList</a> g)
--   bfsForest [] x                           == []
--   bfsForest [1,4] (3 * (1 + 4) * (1 + 5))  == [ Node { rootLabel = 1
--                                                      , subForest = [ Node { rootLabel = 5
--                                                                           , subForest = [] }]}
--                                               , Node { rootLabel = 4
--                                                      , subForest = [] }]
--   <a>forest</a> (bfsForest [3] (<a>circuit</a> [1..5] + <a>circuit</a> [5,4..1])) == <a>path</a> [3,2,1] + <a>path</a> [3,4,5]
--   </pre>
bfsForest :: [Int] -> AdjacencyIntMap -> Forest Int

-- | This is <a>bfsForest</a> with the resulting forest converted to a
--   level structure. Adjacent vertices are explored in increasing order
--   with respect to their <a>Ord</a> instance. Flattening the result via
--   <tt><a>concat</a> . <a>bfs</a> vs</tt> gives an enumeration of
--   vertices reachable from <tt>vs</tt> in breadth first order.
--   
--   Let <i>L</i> be the number of seed vertices. Complexity:
--   <i>O((L+m)*min(n,W))</i> time and <i>O(n)</i> space.
--   
--   <pre>
--   bfs vs <a>empty</a>                                         == []
--   bfs [] g                                             == []
--   bfs [1]   (<a>edge</a> 1 1)                                 == [[1]]
--   bfs [1]   (<a>edge</a> 1 2)                                 == [[1],[2]]
--   bfs [2]   (<a>edge</a> 1 2)                                 == [[2]]
--   bfs [1,2] (<a>edge</a> 1 2)                                 == [[1,2]]
--   bfs [2,1] (<a>edge</a> 1 2)                                 == [[2,1]]
--   bfs [3]   (<a>edge</a> 1 2)                                 == []
--   bfs [1,2] ( (1*2) + (3*4) + (5*6) )                  == [[1,2]]
--   bfs [1,3] ( (1*2) + (3*4) + (5*6) )                  == [[1,3],[2,4]]
--   bfs [3] (3 * (1 + 4) * (1 + 5))                      == [[3],[1,4,5]]
--   bfs [2] (<a>circuit</a> [1..5] + <a>circuit</a> [5,4..1])          == [[2],[1,3],[5,4]]
--   <a>concat</a> (bfs [3] $ <a>circuit</a> [1..5] + <a>circuit</a> [5,4..1]) == [3,2,4,1,5]
--   bfs vs == <a>map</a> <a>concat</a> . <a>transpose</a> . <a>map</a> <a>levels</a> . <a>bfsForest</a> vs
--   </pre>
bfs :: [Int] -> AdjacencyIntMap -> [[Int]]

-- | Compute the <i>depth-first search</i> forest of a graph, where
--   adjacent vertices are expanded in increasing order with respect to
--   their <a>Ord</a> instance.
--   
--   Complexity: <i>O((n+m)*min(n,W))</i> time and <i>O(n)</i> space.
--   
--   <pre>
--   dfsForest <a>empty</a>                       == []
--   <a>forest</a> (dfsForest $ <a>edge</a> 1 1)         == <a>vertex</a> 1
--   <a>forest</a> (dfsForest $ <a>edge</a> 1 2)         == <a>edge</a> 1 2
--   <a>forest</a> (dfsForest $ <a>edge</a> 2 1)         == <a>vertices</a> [1,2]
--   <a>isSubgraphOf</a> (<a>forest</a> $ dfsForest x) x == True
--   <a>isDfsForestOf</a> (dfsForest x) x         == True
--   dfsForest . <a>forest</a> . dfsForest        == dfsForest
--   dfsForest (<a>vertices</a> vs)               == <a>map</a> (\v -&gt; Node v []) (<a>nub</a> $ <a>sort</a> vs)
--   <a>dfsForestFrom</a> (<a>vertexList</a> x) x        == dfsForest x
--   dfsForest $ 3 * (1 + 4) * (1 + 5)     == [ Node { rootLabel = 1
--                                                   , subForest = [ Node { rootLabel = 5
--                                                                        , subForest = [] }]}
--                                            , Node { rootLabel = 3
--                                                   , subForest = [ Node { rootLabel = 4
--                                                                        , subForest = [] }]}]
--   <a>forest</a> (dfsForest $ <a>circuit</a> [1..5] + <a>circuit</a> [5,4..1]) == <a>path</a> [1,2,3,4,5]
--   </pre>
dfsForest :: AdjacencyIntMap -> Forest Int

-- | Compute the <i>depth-first search</i> forest of a graph from the given
--   vertices, where adjacent vertices are expanded in increasing order
--   with respect to to their <a>Ord</a> instance. Note that the resulting
--   forest does not necessarily span the whole graph, as some vertices may
--   be unreachable. Any of the given vertices which are not in the graph
--   are ignored.
--   
--   Let <i>L</i> be the number of seed vertices. Complexity:
--   <i>O((L+m)*min(n,W))</i> time and <i>O(n)</i> space.
--   
--   <pre>
--   dfsForestFrom vs <a>empty</a>                           == []
--   <a>forest</a> (dfsForestFrom [1]   $ <a>edge</a> 1 1)          == <a>vertex</a> 1
--   <a>forest</a> (dfsForestFrom [1]   $ <a>edge</a> 1 2)          == <a>edge</a> 1 2
--   <a>forest</a> (dfsForestFrom [2]   $ <a>edge</a> 1 2)          == <a>vertex</a> 2
--   <a>forest</a> (dfsForestFrom [3]   $ <a>edge</a> 1 2)          == <a>empty</a>
--   <a>forest</a> (dfsForestFrom [2,1] $ <a>edge</a> 1 2)          == <a>vertices</a> [1,2]
--   <a>isSubgraphOf</a> (<a>forest</a> $ dfsForestFrom vs x) x     == True
--   <a>isDfsForestOf</a> (dfsForestFrom (<a>vertexList</a> x) x) x == True
--   dfsForestFrom (<a>vertexList</a> x) x                   == <a>dfsForest</a> x
--   dfsForestFrom vs             (<a>vertices</a> vs)       == <a>map</a> (\v -&gt; Node v []) (<a>nub</a> vs)
--   dfsForestFrom []             x                   == []
--   dfsForestFrom [1,4] $ 3 * (1 + 4) * (1 + 5)      == [ Node { rootLabel = 1
--                                                              , subForest = [ Node { rootLabel = 5
--                                                                                   , subForest = [] }
--                                                       , Node { rootLabel = 4
--                                                              , subForest = [] }]
--   <a>forest</a> (dfsForestFrom [3] $ <a>circuit</a> [1..5] + <a>circuit</a> [5,4..1]) == <a>path</a> [3,2,1,5,4]
--   </pre>
dfsForestFrom :: [Int] -> AdjacencyIntMap -> Forest Int

-- | Compute the vertices visited by <i>depth-first search</i> in a graph
--   from the given vertices. Adjacent vertices are explored in increasing
--   order with respect to their <a>Ord</a> instance.
--   
--   Let <i>L</i> be the number of seed vertices. Complexity:
--   <i>O((L+m)*min(n,W))</i> time and <i>O(n)</i> space.
--   
--   <pre>
--   dfs vs    $ <a>empty</a>                    == []
--   dfs [1]   $ <a>edge</a> 1 1                 == [1]
--   dfs [1]   $ <a>edge</a> 1 2                 == [1,2]
--   dfs [2]   $ <a>edge</a> 1 2                 == [2]
--   dfs [3]   $ <a>edge</a> 1 2                 == []
--   dfs [1,2] $ <a>edge</a> 1 2                 == [1,2]
--   dfs [2,1] $ <a>edge</a> 1 2                 == [2,1]
--   dfs []    $ x                        == []
--   dfs [1,4] $ 3 * (1 + 4) * (1 + 5)    == [1,5,4]
--   <a>isSubgraphOf</a> (<a>vertices</a> $ dfs vs x) x == True
--   dfs [3] $ <a>circuit</a> [1..5] + <a>circuit</a> [5,4..1] == [3,2,1,5,4]
--   </pre>
dfs :: [Int] -> AdjacencyIntMap -> [Int]

-- | Compute the list of vertices that are <i>reachable</i> from a given
--   source vertex in a graph. The vertices in the resulting list appear in
--   <i>depth-first order</i>.
--   
--   Complexity: <i>O(m*min(n,W))</i> time and <i>O(n)</i> space.
--   
--   <pre>
--   reachable x $ <a>empty</a>                       == []
--   reachable 1 $ <a>vertex</a> 1                    == [1]
--   reachable 1 $ <a>vertex</a> 2                    == []
--   reachable 1 $ <a>edge</a> 1 1                    == [1]
--   reachable 1 $ <a>edge</a> 1 2                    == [1,2]
--   reachable 4 $ <a>path</a>    [1..8]              == [4..8]
--   reachable 4 $ <a>circuit</a> [1..8]              == [4..8] ++ [1..3]
--   reachable 8 $ <a>clique</a>  [8,7..1]            == [8] ++ [1..7]
--   <a>isSubgraphOf</a> (<a>vertices</a> $ reachable x y) y == True
--   </pre>
reachable :: Int -> AdjacencyIntMap -> [Int]

-- | Compute a topological sort of a DAG or discover a cycle.
--   
--   Vertices are expanded in decreasing order with respect to their
--   <a>Ord</a> instance. This gives the lexicographically smallest
--   topological ordering in the case of success. In the case of failure,
--   the cycle is characterized by being the lexicographically smallest up
--   to rotation with respect to <tt>Ord (Dual Int)</tt> in the first
--   connected component of the graph containing a cycle, where the
--   connected components are ordered by their largest vertex with respect
--   to <tt>Ord a</tt>.
--   
--   Complexity: <i>O((n+m)*min(n,W))</i> time and <i>O(n)</i> space.
--   
--   <pre>
--   topSort (1 * 2 + 3 * 1)                    == Right [3,1,2]
--   topSort (<a>path</a> [1..5])                      == Right [1..5]
--   topSort (3 * (1 * 4 + 2 * 5))              == Right [3,1,2,4,5]
--   topSort (1 * 2 + 2 * 1)                    == Left (2 <a>:|</a> [1])
--   topSort (<a>path</a> [5,4..1] + <a>edge</a> 2 4)         == Left (4 <a>:|</a> [3,2])
--   topSort (<a>circuit</a> [1..3])                   == Left (3 <a>:|</a> [1,2])
--   topSort (<a>circuit</a> [1..3] + <a>circuit</a> [3,2,1]) == Left (3 <a>:|</a> [2])
--   topSort (1*2 + 2*1 + 3*4 + 4*3 + 5*1)      == Left (1 <a>:|</a> [2])
--   fmap (<a>flip</a> <a>isTopSortOf</a> x) (topSort x)      /= Right False
--   topSort . <a>vertices</a>                         == Right . <tt>nub</tt> . <tt>sort</tt>
--   </pre>
topSort :: AdjacencyIntMap -> Either (Cycle Int) [Int]

-- | Check if a given graph is <i>acyclic</i>.
--   
--   Complexity: <i>O((n+m)*min(n,W))</i> time and <i>O(n)</i> space.
--   
--   <pre>
--   isAcyclic (1 * 2 + 3 * 1) == True
--   isAcyclic (1 * 2 + 2 * 1) == False
--   isAcyclic . <a>circuit</a>       == <a>null</a>
--   isAcyclic                 == <a>isRight</a> . <a>topSort</a>
--   </pre>
isAcyclic :: AdjacencyIntMap -> Bool

-- | Check if a given forest is a correct <i>depth-first search</i> forest
--   of a graph. The implementation is based on the paper "Depth-First
--   Search and Strong Connectivity in Coq" by François Pottier.
--   
--   <pre>
--   isDfsForestOf []                              <a>empty</a>            == True
--   isDfsForestOf []                              (<a>vertex</a> 1)       == False
--   isDfsForestOf [Node 1 []]                     (<a>vertex</a> 1)       == True
--   isDfsForestOf [Node 1 []]                     (<a>vertex</a> 2)       == False
--   isDfsForestOf [Node 1 [], Node 1 []]          (<a>vertex</a> 1)       == False
--   isDfsForestOf [Node 1 []]                     (<a>edge</a> 1 1)       == True
--   isDfsForestOf [Node 1 []]                     (<a>edge</a> 1 2)       == False
--   isDfsForestOf [Node 1 [], Node 2 []]          (<a>edge</a> 1 2)       == False
--   isDfsForestOf [Node 2 [], Node 1 []]          (<a>edge</a> 1 2)       == True
--   isDfsForestOf [Node 1 [Node 2 []]]            (<a>edge</a> 1 2)       == True
--   isDfsForestOf [Node 1 [], Node 2 []]          (<a>vertices</a> [1,2]) == True
--   isDfsForestOf [Node 2 [], Node 1 []]          (<a>vertices</a> [1,2]) == True
--   isDfsForestOf [Node 1 [Node 2 []]]            (<a>vertices</a> [1,2]) == False
--   isDfsForestOf [Node 1 [Node 2 [Node 3 []]]]   (<a>path</a> [1,2,3])   == True
--   isDfsForestOf [Node 1 [Node 3 [Node 2 []]]]   (<a>path</a> [1,2,3])   == False
--   isDfsForestOf [Node 3 [], Node 1 [Node 2 []]] (<a>path</a> [1,2,3])   == True
--   isDfsForestOf [Node 2 [Node 3 []], Node 1 []] (<a>path</a> [1,2,3])   == True
--   isDfsForestOf [Node 1 [], Node 2 [Node 3 []]] (<a>path</a> [1,2,3])   == False
--   </pre>
isDfsForestOf :: Forest Int -> AdjacencyIntMap -> Bool

-- | Check if a given list of vertices is a correct <i>topological sort</i>
--   of a graph.
--   
--   <pre>
--   isTopSortOf [3,1,2] (1 * 2 + 3 * 1) == True
--   isTopSortOf [1,2,3] (1 * 2 + 3 * 1) == False
--   isTopSortOf []      (1 * 2 + 3 * 1) == False
--   isTopSortOf []      <a>empty</a>           == True
--   isTopSortOf [x]     (<a>vertex</a> x)      == True
--   isTopSortOf [x]     (<a>edge</a> x x)      == False
--   </pre>
isTopSortOf :: [Int] -> AdjacencyIntMap -> Bool
type Cycle = NonEmpty


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module defines various internal utilities and data structures
--   used throughout the library, such as lists with fast concatenation.
--   The API is unstable and unsafe, and is exposed only for documentation.
module Algebra.Graph.Internal

-- | An abstract list data type with <i>O(1)</i> time concatenation (the
--   current implementation uses difference lists). Here <tt>a</tt> is the
--   type of list elements. <a>List</a> <tt>a</tt> is a <a>Monoid</a>:
--   <a>mempty</a> corresponds to the empty list and two lists can be
--   concatenated with <a>mappend</a> (or operator <a>&lt;&gt;</a>).
--   Singleton lists can be constructed using the function <a>pure</a> from
--   the <a>Applicative</a> instance. <a>List</a> <tt>a</tt> is also an
--   instance of <tt>IsList</tt>, therefore you can use list literals, e.g.
--   <tt>[1,4]</tt> <tt>::</tt> <a>List</a> <tt>Int</tt> is the same as
--   <a>pure</a> <tt>1</tt> <a>&lt;&gt;</a> <a>pure</a> <tt>4</tt>; note
--   that this requires the <tt>OverloadedLists</tt> GHC extension. To
--   extract plain Haskell lists you can use the <a>toList</a> function
--   from the <a>Foldable</a> instance.
data List a

-- | The <i>focus</i> of a graph expression is a flattened representation
--   of the subgraph under focus, its context, as well as the list of all
--   encountered vertices. See <a>removeEdge</a> for a use-case example.
data Focus a

-- | All vertices (leaves) of the graph expression.
Focus :: Bool -> List a -> List a -> List a -> Focus a

-- | True if focus on the specified subgraph is obtained.
[ok] :: Focus a -> Bool

-- | Inputs into the focused subgraph.
[is] :: Focus a -> List a

-- | Outputs out of the focused subgraph.
[os] :: Focus a -> List a
[vs] :: Focus a -> List a

-- | Focus on the empty graph.
emptyFocus :: Focus a

-- | Focus on the graph with a single vertex, given a predicate indicating
--   whether the vertex is of interest.
vertexFocus :: (a -> Bool) -> a -> Focus a

-- | Overlay two foci.
overlayFoci :: Focus a -> Focus a -> Focus a

-- | Connect two foci.
connectFoci :: Focus a -> Focus a -> Focus a

-- | A safe version of <a>foldr1</a>.
foldr1Safe :: (a -> a -> a) -> [a] -> Maybe a

-- | Auxiliary function that try to apply a function to a base case and a
--   <a>Maybe</a> value and return <a>Just</a> the result or <a>Just</a>
--   the base case.
maybeF :: (a -> b -> a) -> a -> Maybe b -> Maybe a

-- | Compute the Cartesian product of two sets, applying a function to each
--   resulting pair.
cartesianProductWith :: Ord c => (a -> b -> c) -> Set a -> Set b -> Set c

-- | Perform an applicative action for each element of a set.
forEach :: Applicative f => Set a -> (a -> f b) -> f ()

-- | Help GHC with type inference when direct use of <a>coerce</a> does not
--   compile.
coerce00 :: Coercible f g => f x -> g x

-- | Help GHC with type inference when direct use of <a>coerce</a> does not
--   compile.
coerce10 :: (Coercible a b, Coercible f g) => (a -> f x) -> b -> g x

-- | Help GHC with type inference when direct use of <a>coerce</a> does not
--   compile.
coerce20 :: (Coercible a b, Coercible c d, Coercible f g) => (a -> c -> f x) -> b -> d -> g x

-- | Help GHC with type inference when direct use of <a>coerce</a> does not
--   compile.
coerce01 :: (Coercible a b, Coercible f g) => (f x -> a) -> g x -> b

-- | Help GHC with type inference when direct use of <a>coerce</a> does not
--   compile.
coerce11 :: (Coercible a b, Coercible c d, Coercible f g) => (a -> f x -> c) -> b -> g x -> d

-- | Help GHC with type inference when direct use of <a>coerce</a> does not
--   compile.
coerce21 :: (Coercible a b, Coercible c d, Coercible p q, Coercible f g) => (a -> c -> f x -> p) -> b -> d -> g x -> q
instance GHC.Base.Semigroup (Algebra.Graph.Internal.List a)
instance GHC.Base.Monoid (Algebra.Graph.Internal.List a)
instance GHC.Show.Show a => GHC.Show.Show (Algebra.Graph.Internal.List a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Algebra.Graph.Internal.List a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.Internal.List a)
instance GHC.Exts.IsList (Algebra.Graph.Internal.List a)
instance Data.Foldable.Foldable Algebra.Graph.Internal.List
instance GHC.Base.Functor Algebra.Graph.Internal.List
instance GHC.Base.Applicative Algebra.Graph.Internal.List
instance GHC.Base.Monad Algebra.Graph.Internal.List


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module defines the core data type <a>Graph</a> and associated
--   algorithms. For graphs that are known to be <i>non-empty</i> at
--   compile time, see <a>Algebra.Graph.NonEmpty</a>. <a>Graph</a> is an
--   instance of type classes defined in modules <a>Algebra.Graph.Class</a>
--   and <a>Algebra.Graph.HigherKinded.Class</a>, which can be used for
--   polymorphic graph construction and manipulation.
module Algebra.Graph

-- | The <a>Graph</a> data type is a deep embedding of the core graph
--   construction primitives <a>empty</a>, <a>vertex</a>, <a>overlay</a>
--   and <a>connect</a>. We define a <a>Num</a> instance as a convenient
--   notation for working with graphs:
--   
--   <pre>
--   0           == <a>vertex</a> 0
--   1 + 2       == <a>overlay</a> (<a>vertex</a> 1) (<a>vertex</a> 2)
--   1 * 2       == <a>connect</a> (<a>vertex</a> 1) (<a>vertex</a> 2)
--   1 + 2 * 3   == <a>overlay</a> (<a>vertex</a> 1) (<a>connect</a> (<a>vertex</a> 2) (<a>vertex</a> 3))
--   1 * (2 + 3) == <a>connect</a> (<a>vertex</a> 1) (<a>overlay</a> (<a>vertex</a> 2) (<a>vertex</a> 3))
--   </pre>
--   
--   <b>Note:</b> the <a>Num</a> instance does not satisfy several
--   "customary laws" of <a>Num</a>, which dictate that <a>fromInteger</a>
--   <tt>0</tt> and <a>fromInteger</a> <tt>1</tt> should act as additive
--   and multiplicative identities, and <a>negate</a> as additive inverse.
--   Nevertheless, overloading <a>fromInteger</a>, <a>+</a> and <a>*</a> is
--   very convenient when working with algebraic graphs; we hope that in
--   future Haskell's Prelude will provide a more fine-grained class
--   hierarchy for algebraic structures, which we would be able to utilise
--   without violating any laws.
--   
--   The <a>Eq</a> instance is currently implemented using the
--   <a>AdjacencyMap</a> as the <i>canonical graph representation</i> and
--   satisfies all axioms of algebraic graphs:
--   
--   <ul>
--   <li><a>overlay</a> is commutative and associative:<pre> x + y == y + x
--   x + (y + z) == (x + y) + z</pre></li>
--   <li><a>connect</a> is associative and has <a>empty</a> as the
--   identity:<pre> x * empty == x empty * x == x x * (y * z) == (x * y) *
--   z</pre></li>
--   <li><a>connect</a> distributes over <a>overlay</a>:<pre>x * (y + z) ==
--   x * y + x * z (x + y) * z == x * z + y * z</pre></li>
--   <li><a>connect</a> can be decomposed:<pre>x * y * z == x * y + x * z +
--   y * z</pre></li>
--   </ul>
--   
--   The following useful theorems can be proved from the above set of
--   axioms.
--   
--   <ul>
--   <li><a>overlay</a> has <a>empty</a> as the identity and is
--   idempotent:<pre> x + empty == x empty + x == x x + x == x</pre></li>
--   <li>Absorption and saturation of <a>connect</a>:<pre>x * y + x + y ==
--   x * y x * x * x == x * x</pre></li>
--   </ul>
--   
--   When specifying the time and memory complexity of graph algorithms,
--   <i>n</i> will denote the number of vertices in the graph, <i>m</i>
--   will denote the number of edges in the graph, and <i>s</i> will denote
--   the <i>size</i> of the corresponding <a>Graph</a> expression. For
--   example, if <tt>g</tt> is a <a>Graph</a> then <i>n</i>, <i>m</i> and
--   <i>s</i> can be computed as follows:
--   
--   <pre>
--   n == <a>vertexCount</a> g
--   m == <a>edgeCount</a> g
--   s == <a>size</a> g
--   </pre>
--   
--   Note that <a>size</a> counts all leaves of the expression:
--   
--   <pre>
--   <a>vertexCount</a> <a>empty</a>           == 0
--   <a>size</a>        <a>empty</a>           == 1
--   <a>vertexCount</a> (<a>vertex</a> x)      == 1
--   <a>size</a>        (<a>vertex</a> x)      == 1
--   <a>vertexCount</a> (<a>empty</a> + <a>empty</a>) == 0
--   <a>size</a>        (<a>empty</a> + <a>empty</a>) == 2
--   </pre>
--   
--   Converting a <a>Graph</a> to the corresponding <a>AdjacencyMap</a>
--   takes <i>O(s + m * log(m))</i> time and <i>O(s + m)</i> 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.
--   
--   The total order on graphs is defined using <i>size-lexicographic</i>
--   comparison:
--   
--   <ul>
--   <li>Compare the number of vertices. In case of a tie, continue.</li>
--   <li>Compare the sets of vertices. In case of a tie, continue.</li>
--   <li>Compare the number of edges. In case of a tie, continue.</li>
--   <li>Compare the sets of edges.</li>
--   </ul>
--   
--   Here are a few examples:
--   
--   <pre>
--   <a>vertex</a> 1 &lt; <a>vertex</a> 2
--   <a>vertex</a> 3 &lt; <a>edge</a> 1 2
--   <a>vertex</a> 1 &lt; <a>edge</a> 1 1
--   <a>edge</a> 1 1 &lt; <a>edge</a> 1 2
--   <a>edge</a> 1 2 &lt; <a>edge</a> 1 1 + <a>edge</a> 2 2
--   <a>edge</a> 1 2 &lt; <a>edge</a> 1 3
--   </pre>
--   
--   Note that the resulting order refines the <a>isSubgraphOf</a> relation
--   and is compatible with <a>overlay</a> and <a>connect</a> operations:
--   
--   <pre>
--   <a>isSubgraphOf</a> x y ==&gt; x &lt;= y
--   </pre>
--   
--   <pre>
--   <a>empty</a> &lt;= x
--   x     &lt;= x + y
--   x + y &lt;= x * y
--   </pre>
--   
--   Deforestation (fusion) is implemented for some functions in this
--   module. This means that when a function tagged as a "good producer" is
--   composed with a function tagged as a "good consumer", the intermediate
--   structure will not be built.
data Graph a
Empty :: Graph a
Vertex :: a -> Graph a
Overlay :: Graph a -> Graph a -> Graph a
Connect :: Graph a -> Graph a -> Graph a

-- | Construct the <i>empty graph</i>. An alias for the constructor
--   <a>Empty</a>.
--   
--   <pre>
--   <a>isEmpty</a>     empty == True
--   <a>hasVertex</a> x empty == False
--   <a>vertexCount</a> empty == 0
--   <a>edgeCount</a>   empty == 0
--   <a>size</a>        empty == 1
--   </pre>
empty :: Graph a

-- | Construct the graph comprising <i>a single isolated vertex</i>. An
--   alias for the constructor <a>Vertex</a>.
--   
--   <pre>
--   <a>isEmpty</a>     (vertex x) == False
--   <a>hasVertex</a> x (vertex y) == (x == y)
--   <a>vertexCount</a> (vertex x) == 1
--   <a>edgeCount</a>   (vertex x) == 0
--   <a>size</a>        (vertex x) == 1
--   </pre>
vertex :: a -> Graph a

-- | Construct the graph comprising <i>a single edge</i>.
--   
--   <pre>
--   edge x y               == <a>connect</a> (<a>vertex</a> x) (<a>vertex</a> y)
--   <a>hasEdge</a> x y (edge x y) == True
--   <a>edgeCount</a>   (edge x y) == 1
--   <a>vertexCount</a> (edge 1 1) == 1
--   <a>vertexCount</a> (edge 1 2) == 2
--   </pre>
edge :: a -> a -> Graph a

-- | <i>Overlay</i> two graphs. An alias for the constructor
--   <a>Overlay</a>. This is a commutative, associative and idempotent
--   operation with the identity <a>empty</a>. Complexity: <i>O(1)</i> time
--   and memory, <i>O(s1 + s2)</i> size.
--   
--   <pre>
--   <a>isEmpty</a>     (overlay x y) == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (overlay x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (overlay x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (overlay x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (overlay x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (overlay x y) &lt;= <a>edgeCount</a> x   + <a>edgeCount</a> y
--   <a>size</a>        (overlay x y) == <a>size</a> x        + <a>size</a> y
--   <a>vertexCount</a> (overlay 1 2) == 2
--   <a>edgeCount</a>   (overlay 1 2) == 0
--   </pre>
overlay :: Graph a -> Graph a -> Graph a

-- | <i>Connect</i> two graphs. An alias for the constructor
--   <a>Connect</a>. This is an associative operation with the identity
--   <a>empty</a>, which distributes over <a>overlay</a> and obeys the
--   decomposition axiom. Complexity: <i>O(1)</i> time and memory, <i>O(s1
--   + s2)</i> size. Note that the number of edges in the resulting graph
--   is quadratic with respect to the number of vertices of the arguments:
--   <i>m = O(m1 + m2 + n1 * n2)</i>.
--   
--   <pre>
--   <a>isEmpty</a>     (connect x y) == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (connect x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (connect x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (connect x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (connect x y) &gt;= <a>edgeCount</a> y
--   <a>edgeCount</a>   (connect x y) &gt;= <a>vertexCount</a> x * <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect x y) &lt;= <a>vertexCount</a> x * <a>vertexCount</a> y + <a>edgeCount</a> x + <a>edgeCount</a> y
--   <a>size</a>        (connect x y) == <a>size</a> x        + <a>size</a> y
--   <a>vertexCount</a> (connect 1 2) == 2
--   <a>edgeCount</a>   (connect 1 2) == 1
--   </pre>
connect :: Graph a -> Graph a -> Graph a

-- | Construct the graph comprising a given list of isolated vertices.
--   Complexity: <i>O(L)</i> time, memory and size, where <i>L</i> is the
--   length of the given list.
--   
--   Good consumer of lists and producer of graphs.
--   
--   <pre>
--   vertices []            == <a>empty</a>
--   vertices [x]           == <a>vertex</a> x
--   vertices               == <a>overlays</a> . map <a>vertex</a>
--   <a>hasVertex</a> x . vertices == <a>elem</a> x
--   <a>vertexCount</a> . vertices == <a>length</a> . <a>nub</a>
--   <a>vertexSet</a>   . vertices == Set.<a>fromList</a>
--   </pre>
vertices :: [a] -> Graph a

-- | Construct the graph from a list of edges. Complexity: <i>O(L)</i>
--   time, memory and size, where <i>L</i> is the length of the given list.
--   
--   Good consumer of lists and producer of graphs.
--   
--   <pre>
--   edges []          == <a>empty</a>
--   edges [(x,y)]     == <a>edge</a> x y
--   edges             == <a>overlays</a> . <a>map</a> (<a>uncurry</a> <a>edge</a>)
--   <a>edgeCount</a> . edges == <a>length</a> . <a>nub</a>
--   </pre>
edges :: [(a, a)] -> Graph a

-- | Overlay a given list of graphs. Complexity: <i>O(L)</i> time and
--   memory, and <i>O(S)</i> size, where <i>L</i> is the length of the
--   given list, and <i>S</i> is the sum of sizes of the graphs in the
--   list.
--   
--   Good consumer of lists and producer of graphs.
--   
--   <pre>
--   overlays []        == <a>empty</a>
--   overlays [x]       == x
--   overlays [x,y]     == <a>overlay</a> x y
--   overlays           == <a>foldr</a> <a>overlay</a> <a>empty</a>
--   <a>isEmpty</a> . overlays == <a>all</a> <a>isEmpty</a>
--   </pre>
overlays :: [Graph a] -> Graph a

-- | Connect a given list of graphs. Complexity: <i>O(L)</i> time and
--   memory, and <i>O(S)</i> size, where <i>L</i> is the length of the
--   given list, and <i>S</i> is the sum of sizes of the graphs in the
--   list.
--   
--   Good consumer of lists and producer of graphs.
--   
--   <pre>
--   connects []        == <a>empty</a>
--   connects [x]       == x
--   connects [x,y]     == <a>connect</a> x y
--   connects           == <a>foldr</a> <a>connect</a> <a>empty</a>
--   <a>isEmpty</a> . connects == <a>all</a> <a>isEmpty</a>
--   </pre>
connects :: [Graph a] -> Graph a

-- | Generalised <a>Graph</a> folding: recursively collapse a <a>Graph</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: <i>O(s)</i> applications of the given functions.
--   As an example, the complexity of <a>size</a> is <i>O(s)</i>, since
--   <a>const</a> and <a>+</a> have constant costs.
--   
--   Good consumer.
--   
--   <pre>
--   foldg <a>empty</a> <a>vertex</a>        <a>overlay</a> <a>connect</a>        == id
--   foldg <a>empty</a> <a>vertex</a>        <a>overlay</a> (<a>flip</a> <a>connect</a>) == <a>transpose</a>
--   foldg 1     (<a>const</a> 1)     (+)     (+)            == <a>size</a>
--   foldg True  (<a>const</a> False) (&amp;&amp;)    (&amp;&amp;)           == <a>isEmpty</a>
--   foldg False (== x)        (||)    (||)           == <a>hasVertex</a> x
--   </pre>
foldg :: b -> (a -> b) -> (b -> b -> b) -> (b -> b -> b) -> Graph a -> b

-- | Build a graph given an interpretation of the four graph construction
--   primitives <a>empty</a>, <a>vertex</a>, <a>overlay</a> and
--   <a>connect</a>, in this order. See examples for further clarification.
--   
--   Functions expressed with <a>buildg</a> are good producers.
--   
--   <pre>
--   buildg f                                                   == f <a>empty</a> <a>vertex</a> <a>overlay</a> <a>connect</a>
--   buildg (\e _ _ _ -&gt; e)                                     == <a>empty</a>
--   buildg (\_ v _ _ -&gt; v x)                                   == <a>vertex</a> x
--   buildg (\e v o c -&gt; o (<a>foldg</a> e v o c x) (<a>foldg</a> e v o c y)) == <a>overlay</a> x y
--   buildg (\e v o c -&gt; c (<a>foldg</a> e v o c x) (<a>foldg</a> e v o c y)) == <a>connect</a> x y
--   buildg (\e v o _ -&gt; <a>foldr</a> o e (<a>map</a> v xs))                  == <a>vertices</a> xs
--   buildg (\e v o c -&gt; <a>foldg</a> e v o (<a>flip</a> c) g)                == <a>transpose</a> g
--   <a>foldg</a> e v o c (buildg f)                                   == f e v o c
--   </pre>
buildg :: (forall r. r -> (a -> r) -> (r -> r -> r) -> (r -> r -> r) -> r) -> Graph a

-- | The <a>isSubgraphOf</a> function takes two graphs and returns
--   <a>True</a> if the first graph is a <i>subgraph</i> of the second.
--   Complexity: <i>O(s + m * log(m))</i> time. Note that the number of
--   edges <i>m</i> of a graph can be quadratic with respect to the
--   expression size <i>s</i>.
--   
--   Good consumer of both arguments.
--   
--   <pre>
--   isSubgraphOf <a>empty</a>         x             ==  True
--   isSubgraphOf (<a>vertex</a> x)    <a>empty</a>         ==  False
--   isSubgraphOf x             (<a>overlay</a> x y) ==  True
--   isSubgraphOf (<a>overlay</a> x y) (<a>connect</a> x y) ==  True
--   isSubgraphOf (<a>path</a> xs)     (<a>circuit</a> xs)  ==  True
--   isSubgraphOf x y                         ==&gt; x &lt;= y
--   </pre>
isSubgraphOf :: Ord a => Graph a -> Graph a -> Bool

-- | Structural equality on graph expressions. Complexity: <i>O(s)</i>
--   time.
--   
--   <pre>
--       x === x         == True
--       x === x + <a>empty</a> == False
--   x + y === x + y     == True
--   1 + 2 === 2 + 1     == False
--   x + y === x * y     == False
--   </pre>
(===) :: Eq a => Graph a -> Graph a -> Bool
infix 4 ===

-- | Check if a graph is empty. Complexity: <i>O(s)</i> time.
--   
--   Good consumer.
--   
--   <pre>
--   isEmpty <a>empty</a>                       == True
--   isEmpty (<a>overlay</a> <a>empty</a> <a>empty</a>)       == True
--   isEmpty (<a>vertex</a> x)                  == False
--   isEmpty (<a>removeVertex</a> x $ <a>vertex</a> x) == True
--   isEmpty (<a>removeEdge</a> x y $ <a>edge</a> x y) == False
--   </pre>
isEmpty :: Graph a -> Bool

-- | The <i>size</i> of a graph, i.e. the number of leaves of the
--   expression including <a>empty</a> leaves. Complexity: <i>O(s)</i>
--   time.
--   
--   Good consumer.
--   
--   <pre>
--   size <a>empty</a>         == 1
--   size (<a>vertex</a> x)    == 1
--   size (<a>overlay</a> x y) == size x + size y
--   size (<a>connect</a> x y) == size x + size y
--   size x             &gt;= 1
--   size x             &gt;= <a>vertexCount</a> x
--   </pre>
size :: Graph a -> Int

-- | Check if a graph contains a given vertex. Complexity: <i>O(s)</i>
--   time.
--   
--   Good consumer.
--   
--   <pre>
--   hasVertex x <a>empty</a>            == False
--   hasVertex x (<a>vertex</a> y)       == (x == y)
--   hasVertex x . <a>removeVertex</a> x == <a>const</a> False
--   </pre>
hasVertex :: Eq a => a -> Graph a -> Bool

-- | Check if a graph contains a given edge. Complexity: <i>O(s)</i> time.
--   
--   Good consumer.
--   
--   <pre>
--   hasEdge x y <a>empty</a>            == False
--   hasEdge x y (<a>vertex</a> z)       == False
--   hasEdge x y (<a>edge</a> x y)       == True
--   hasEdge x y . <a>removeEdge</a> x y == <a>const</a> False
--   hasEdge x y                  == <a>elem</a> (x,y) . <a>edgeList</a>
--   </pre>
hasEdge :: Eq a => a -> a -> Graph a -> Bool

-- | The number of vertices in a graph. Complexity: <i>O(s * log(n))</i>
--   time.
--   
--   Good consumer.
--   
--   <pre>
--   vertexCount <a>empty</a>             ==  0
--   vertexCount (<a>vertex</a> x)        ==  1
--   vertexCount                   ==  <a>length</a> . <a>vertexList</a>
--   vertexCount x &lt; vertexCount y ==&gt; x &lt; y
--   </pre>
vertexCount :: Ord a => Graph a -> Int

-- | The number of edges in a graph. Complexity: <i>O(s + m * log(m))</i>
--   time. Note that the number of edges <i>m</i> of a graph can be
--   quadratic with respect to the expression size <i>s</i>.
--   
--   Good consumer.
--   
--   <pre>
--   edgeCount <a>empty</a>      == 0
--   edgeCount (<a>vertex</a> x) == 0
--   edgeCount (<a>edge</a> x y) == 1
--   edgeCount            == <a>length</a> . <a>edgeList</a>
--   </pre>
edgeCount :: Ord a => Graph a -> Int

-- | The sorted list of vertices of a given graph. Complexity: <i>O(s *
--   log(n))</i> time and <i>O(n)</i> memory.
--   
--   Good consumer of graphs and producer of lists.
--   
--   <pre>
--   vertexList <a>empty</a>      == []
--   vertexList (<a>vertex</a> x) == [x]
--   vertexList . <a>vertices</a> == <a>nub</a> . <a>sort</a>
--   </pre>
vertexList :: Ord a => Graph a -> [a]

-- | The sorted list of edges of a graph. Complexity: <i>O(s + m *
--   log(m))</i> time and <i>O(m)</i> memory. Note that the number of edges
--   <i>m</i> of a graph can be quadratic with respect to the expression
--   size <i>s</i>.
--   
--   Good consumer of graphs and producer of lists.
--   
--   <pre>
--   edgeList <a>empty</a>          == []
--   edgeList (<a>vertex</a> x)     == []
--   edgeList (<a>edge</a> x y)     == [(x,y)]
--   edgeList (<a>star</a> 2 [3,1]) == [(2,1), (2,3)]
--   edgeList . <a>edges</a>        == <a>nub</a> . <a>sort</a>
--   edgeList . <a>transpose</a>    == <a>sort</a> . <a>map</a> <a>swap</a> . edgeList
--   </pre>
edgeList :: Ord a => Graph a -> [(a, a)]

-- | The set of vertices of a given graph. Complexity: <i>O(s * log(n))</i>
--   time and <i>O(n)</i> memory.
--   
--   Good consumer.
--   
--   <pre>
--   vertexSet <a>empty</a>      == Set.<a>empty</a>
--   vertexSet . <a>vertex</a>   == Set.<a>singleton</a>
--   vertexSet . <a>vertices</a> == Set.<a>fromList</a>
--   </pre>
vertexSet :: Ord a => Graph a -> Set a

-- | The set of edges of a given graph. Complexity: <i>O(s * log(m))</i>
--   time and <i>O(m)</i> memory.
--   
--   Good consumer.
--   
--   <pre>
--   edgeSet <a>empty</a>      == Set.<a>empty</a>
--   edgeSet (<a>vertex</a> x) == Set.<a>empty</a>
--   edgeSet (<a>edge</a> x y) == Set.<a>singleton</a> (x,y)
--   edgeSet . <a>edges</a>    == Set.<a>fromList</a>
--   </pre>
edgeSet :: Ord a => Graph a -> Set (a, a)

-- | The sorted <i>adjacency list</i> of a graph. Complexity: <i>O(n +
--   m)</i> time and memory.
--   
--   Good consumer.
--   
--   <pre>
--   adjacencyList <a>empty</a>          == []
--   adjacencyList (<a>vertex</a> x)     == [(x, [])]
--   adjacencyList (<a>edge</a> 1 2)     == [(1, [2]), (2, [])]
--   adjacencyList (<a>star</a> 2 [3,1]) == [(1, []), (2, [1,3]), (3, [])]
--   <a>stars</a> . adjacencyList        == id
--   </pre>
adjacencyList :: Ord a => Graph a -> [(a, [a])]

-- | The <i>path</i> on a list of vertices. Complexity: <i>O(L)</i> time,
--   memory and size, where <i>L</i> is the length of the given list.
--   
--   Good producer.
--   
--   <pre>
--   path []        == <a>empty</a>
--   path [x]       == <a>vertex</a> x
--   path [x,y]     == <a>edge</a> x y
--   path . <a>reverse</a> == <a>transpose</a> . path
--   </pre>
path :: [a] -> Graph a

-- | The <i>circuit</i> on a list of vertices. Complexity: <i>O(L)</i>
--   time, memory and size, where <i>L</i> is the length of the given list.
--   
--   Good producer.
--   
--   <pre>
--   circuit []        == <a>empty</a>
--   circuit [x]       == <a>edge</a> x x
--   circuit [x,y]     == <a>edges</a> [(x,y), (y,x)]
--   circuit . <a>reverse</a> == <a>transpose</a> . circuit
--   </pre>
circuit :: [a] -> Graph a

-- | The <i>clique</i> on a list of vertices. Complexity: <i>O(L)</i> time,
--   memory and size, where <i>L</i> is the length of the given list.
--   
--   Good consumer of lists and producer of graphs.
--   
--   <pre>
--   clique []         == <a>empty</a>
--   clique [x]        == <a>vertex</a> x
--   clique [x,y]      == <a>edge</a> x y
--   clique [x,y,z]    == <a>edges</a> [(x,y), (x,z), (y,z)]
--   clique (xs ++ ys) == <a>connect</a> (clique xs) (clique ys)
--   clique . <a>reverse</a>  == <a>transpose</a> . clique
--   </pre>
clique :: [a] -> Graph a

-- | The <i>biclique</i> on two lists of vertices. Complexity: <i>O(L1 +
--   L2)</i> time, memory and size, where <i>L1</i> and <i>L2</i> are the
--   lengths of the given lists.
--   
--   Good consumer of both arguments and producer of graphs.
--   
--   <pre>
--   biclique []      []      == <a>empty</a>
--   biclique [x]     []      == <a>vertex</a> x
--   biclique []      [y]     == <a>vertex</a> y
--   biclique [x1,x2] [y1,y2] == <a>edges</a> [(x1,y1), (x1,y2), (x2,y1), (x2,y2)]
--   biclique xs      ys      == <a>connect</a> (<a>vertices</a> xs) (<a>vertices</a> ys)
--   </pre>
biclique :: [a] -> [a] -> Graph a

-- | The <i>star</i> formed by a centre vertex connected to a list of
--   leaves. Complexity: <i>O(L)</i> time, memory and size, where <i>L</i>
--   is the length of the given list.
--   
--   Good consumer of lists and good producer of graphs.
--   
--   <pre>
--   star x []    == <a>vertex</a> x
--   star x [y]   == <a>edge</a> x y
--   star x [y,z] == <a>edges</a> [(x,y), (x,z)]
--   star x ys    == <a>connect</a> (<a>vertex</a> x) (<a>vertices</a> ys)
--   </pre>
star :: a -> [a] -> Graph a

-- | The <i>stars</i> formed by overlaying a list of <a>star</a>s. An
--   inverse of <a>adjacencyList</a>. Complexity: <i>O(L)</i> time, memory
--   and size, where <i>L</i> is the total size of the input.
--   
--   Good consumer of lists and producer of graphs.
--   
--   <pre>
--   stars []                      == <a>empty</a>
--   stars [(x, [])]               == <a>vertex</a> x
--   stars [(x, [y])]              == <a>edge</a> x y
--   stars [(x, ys)]               == <a>star</a> x ys
--   stars                         == <a>overlays</a> . <a>map</a> (<a>uncurry</a> <a>star</a>)
--   stars . <a>adjacencyList</a>         == id
--   <a>overlay</a> (stars xs) (stars ys) == stars (xs ++ ys)
--   </pre>
stars :: [(a, [a])] -> Graph a

-- | The <i>tree graph</i> constructed from a given <a>Tree</a> data
--   structure. Complexity: <i>O(T)</i> time, memory and size, where
--   <i>T</i> is the size of the given tree (i.e. the number of vertices in
--   the tree).
--   
--   <pre>
--   tree (Node x [])                                         == <a>vertex</a> x
--   tree (Node x [Node y [Node z []]])                       == <a>path</a> [x,y,z]
--   tree (Node x [Node y [], Node z []])                     == <a>star</a> x [y,z]
--   tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) == <a>edges</a> [(1,2), (1,3), (3,4), (3,5)]
--   </pre>
tree :: Tree a -> Graph a

-- | The <i>forest graph</i> constructed from a given <a>Forest</a> data
--   structure. Complexity: <i>O(F)</i> time, memory and size, where
--   <i>F</i> is the size of the given forest (i.e. the number of vertices
--   in the forest).
--   
--   <pre>
--   forest []                                                  == <a>empty</a>
--   forest [x]                                                 == <a>tree</a> x
--   forest [Node 1 [Node 2 [], Node 3 []], Node 4 [Node 5 []]] == <a>edges</a> [(1,2), (1,3), (4,5)]
--   forest                                                     == <a>overlays</a> . <a>map</a> <a>tree</a>
--   </pre>
forest :: Forest a -> Graph a

-- | Construct a <i>mesh graph</i> from two lists of vertices. Complexity:
--   <i>O(L1 * L2)</i> time, memory and size, where <i>L1</i> and <i>L2</i>
--   are the lengths of the given lists.
--   
--   <pre>
--   mesh xs     []   == <a>empty</a>
--   mesh []     ys   == <a>empty</a>
--   mesh [x]    [y]  == <a>vertex</a> (x, y)
--   mesh xs     ys   == <a>box</a> (<a>path</a> xs) (<a>path</a> ys)
--   mesh [1..3] "ab" == <a>edges</a> [ ((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')) ]
--   </pre>
mesh :: [a] -> [b] -> Graph (a, b)

-- | Construct a <i>torus graph</i> from two lists of vertices. Complexity:
--   <i>O(L1 * L2)</i> time, memory and size, where <i>L1</i> and <i>L2</i>
--   are the lengths of the given lists.
--   
--   <pre>
--   torus xs    []   == <a>empty</a>
--   torus []    ys   == <a>empty</a>
--   torus [x]   [y]  == <a>edge</a> (x,y) (x,y)
--   torus xs    ys   == <a>box</a> (<a>circuit</a> xs) (<a>circuit</a> ys)
--   torus [1,2] "ab" == <a>edges</a> [ ((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')) ]
--   </pre>
torus :: [a] -> [b] -> Graph (a, b)

-- | Construct a <i>De Bruijn graph</i> of a given non-negative dimension
--   using symbols from a given alphabet. Complexity: <i>O(A^(D + 1))</i>
--   time, memory and size, where <i>A</i> is the size of the alphabet and
--   <i>D</i> is the dimension of the graph.
--   
--   <pre>
--             deBruijn 0 xs               == <a>edge</a> [] []
--   n &gt; 0 ==&gt; deBruijn n []               == <a>empty</a>
--             deBruijn 1 [0,1]            == <a>edges</a> [ ([0],[0]), ([0],[1]), ([1],[0]), ([1],[1]) ]
--             deBruijn 2 "0"              == <a>edge</a> "00" "00"
--             deBruijn 2 "01"             == <a>edges</a> [ ("00","00"), ("00","01"), ("01","10"), ("01","11")
--                                                  , ("10","00"), ("10","01"), ("11","10"), ("11","11") ]
--             <a>transpose</a>   (deBruijn n xs) == <a>fmap</a> <a>reverse</a> $ deBruijn n xs
--             <a>vertexCount</a> (deBruijn n xs) == (<a>length</a> $ <a>nub</a> xs)^n
--   n &gt; 0 ==&gt; <a>edgeCount</a>   (deBruijn n xs) == (<a>length</a> $ <a>nub</a> xs)^(n + 1)
--   </pre>
deBruijn :: Int -> [a] -> Graph [a]

-- | Remove a vertex from a given graph. Complexity: <i>O(s)</i> time,
--   memory and size.
--   
--   Good consumer and producer.
--   
--   <pre>
--   removeVertex x (<a>vertex</a> x)       == <a>empty</a>
--   removeVertex 1 (<a>vertex</a> 2)       == <a>vertex</a> 2
--   removeVertex x (<a>edge</a> x x)       == <a>empty</a>
--   removeVertex 1 (<a>edge</a> 1 2)       == <a>vertex</a> 2
--   removeVertex x . removeVertex x == removeVertex x
--   </pre>
removeVertex :: Eq a => a -> Graph a -> Graph a

-- | Remove an edge from a given graph. Complexity: <i>O(s)</i> time,
--   memory and size.
--   
--   <pre>
--   removeEdge x y (<a>edge</a> x y)       == <a>vertices</a> [x,y]
--   removeEdge x y . removeEdge x y == removeEdge x y
--   removeEdge x y . <a>removeVertex</a> x == <a>removeVertex</a> x
--   removeEdge 1 1 (1 * 1 * 2 * 2)  == 1 * 2 * 2
--   removeEdge 1 2 (1 * 1 * 2 * 2)  == 1 * 1 + 2 * 2
--   <a>size</a> (removeEdge x y z)         &lt;= 3 * <a>size</a> z
--   </pre>
removeEdge :: Eq a => a -> a -> Graph a -> Graph a

-- | The function <tt><a>replaceVertex</a> x y</tt> replaces vertex
--   <tt>x</tt> with vertex <tt>y</tt> in a given <a>Graph</a>. If
--   <tt>y</tt> already exists, <tt>x</tt> and <tt>y</tt> will be merged.
--   Complexity: <i>O(s)</i> time, memory and size.
--   
--   Good consumer and producer.
--   
--   <pre>
--   replaceVertex x x            == id
--   replaceVertex x y (<a>vertex</a> x) == <a>vertex</a> y
--   replaceVertex x y            == <a>mergeVertices</a> (== x) y
--   </pre>
replaceVertex :: Eq a => a -> a -> Graph a -> Graph a

-- | Merge vertices satisfying a given predicate into a given vertex.
--   Complexity: <i>O(s)</i> time, memory and size, assuming that the
--   predicate takes constant time.
--   
--   Good consumer and producer.
--   
--   <pre>
--   mergeVertices (<a>const</a> False) x    == id
--   mergeVertices (== x) y           == <a>replaceVertex</a> x y
--   mergeVertices <a>even</a> 1 (0 * 2)     == 1 * 1
--   mergeVertices <a>odd</a>  1 (3 + 4 * 5) == 4 * 1
--   </pre>
mergeVertices :: (a -> Bool) -> a -> Graph a -> Graph a

-- | Split a vertex into a list of vertices with the same connectivity.
--   Complexity: <i>O(s + k * L)</i> time, memory and size, where <i>k</i>
--   is the number of occurrences of the vertex in the expression and
--   <i>L</i> is the length of the given list.
--   
--   Good consumer of lists and producer of graphs.
--   
--   <pre>
--   splitVertex x []                  == <a>removeVertex</a> x
--   splitVertex x [x]                 == id
--   splitVertex x [y]                 == <a>replaceVertex</a> x y
--   splitVertex 1 [0,1] $ 1 * (2 + 3) == (0 + 1) * (2 + 3)
--   </pre>
splitVertex :: Eq a => a -> [a] -> Graph a -> Graph a

-- | Transpose a given graph. Complexity: <i>O(s)</i> time, memory and
--   size.
--   
--   Good consumer and producer.
--   
--   <pre>
--   transpose <a>empty</a>       == <a>empty</a>
--   transpose (<a>vertex</a> x)  == <a>vertex</a> x
--   transpose (<a>edge</a> x y)  == <a>edge</a> y x
--   transpose . transpose == id
--   transpose (<a>box</a> x y)   == <a>box</a> (transpose x) (transpose y)
--   <a>edgeList</a> . transpose  == <a>sort</a> . <a>map</a> <a>swap</a> . <a>edgeList</a>
--   </pre>
transpose :: Graph a -> Graph a

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that do not satisfy a given predicate. Complexity:
--   <i>O(s)</i> time, memory and size, assuming that the predicate takes
--   constant time.
--   
--   Good consumer and producer.
--   
--   <pre>
--   induce (<a>const</a> True ) x      == x
--   induce (<a>const</a> False) x      == <a>empty</a>
--   induce (/= x)               == <a>removeVertex</a> x
--   induce p . induce q         == induce (\x -&gt; p x &amp;&amp; q x)
--   <a>isSubgraphOf</a> (induce p x) x == True
--   </pre>
induce :: (a -> Bool) -> Graph a -> Graph a

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that are <a>Nothing</a>. Complexity: <i>O(s)</i> time, memory
--   and size.
--   
--   Good consumer and producer.
--   
--   <pre>
--   induceJust (<a>vertex</a> <a>Nothing</a>)                               == <a>empty</a>
--   induceJust (<a>edge</a> (<a>Just</a> x) <a>Nothing</a>)                        == <a>vertex</a> x
--   induceJust . <a>fmap</a> <a>Just</a>                                    == <a>id</a>
--   induceJust . <a>fmap</a> (\x -&gt; if p x then <a>Just</a> x else <a>Nothing</a>) == <a>induce</a> p
--   </pre>
induceJust :: Graph (Maybe a) -> Graph a

-- | Simplify 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 <i>O(s)</i> graph
--   comparisons. It is guaranteed that the size of the result does not
--   exceed the size of the given expression.
--   
--   Good consumer.
--   
--   <pre>
--   simplify              == id
--   <a>size</a> (simplify x)     &lt;= <a>size</a> x
--   simplify <a>empty</a>       <a>===</a> <a>empty</a>
--   simplify 1           <a>===</a> 1
--   simplify (1 + 1)     <a>===</a> 1
--   simplify (1 + 2 + 1) <a>===</a> 1 + 2
--   simplify (1 * 1 * 1) <a>===</a> 1 * 1
--   </pre>
simplify :: Ord a => Graph a -> Graph a

-- | <i>Sparsify</i> a graph by adding intermediate <a>Left</a>
--   <tt>Int</tt> vertices between the original vertices (wrapping the
--   latter in <a>Right</a>) such that the resulting graph is
--   <i>sparse</i>, i.e. contains only O(s) edges, but preserves the
--   reachability relation between the original vertices. Sparsification is
--   useful when working with dense graphs, as it can reduce the number of
--   edges from O(n^2) down to O(n) by replacing cliques, bicliques and
--   similar densely connected structures by sparse subgraphs built out of
--   intermediate vertices. Complexity: O(s) time, memory and size.
--   
--   <pre>
--   <a>sort</a> . <a>reachable</a> x       == <a>sort</a> . <a>rights</a> . <a>reachable</a> (<a>Right</a> x) . sparsify
--   <a>vertexCount</a> (sparsify x) &lt;= <a>vertexCount</a> x + <a>size</a> x + 1
--   <a>edgeCount</a>   (sparsify x) &lt;= 3 * <a>size</a> x
--   <a>size</a>        (sparsify x) &lt;= 3 * <a>size</a> x
--   </pre>
sparsify :: Graph a -> Graph (Either Int a)

-- | Sparsify a graph whose vertices are integers in the range
--   <tt>[1..n]</tt>, where <tt>n</tt> is the first argument of the
--   function, producing an array-based graph representation from
--   <a>Data.Graph</a> (introduced by King and Launchbury, hence the name
--   of the function). In the resulting graph, vertices <tt>[1..n]</tt>
--   correspond to the original vertices, and all vertices greater than
--   <tt>n</tt> are introduced by the sparsification procedure.
--   
--   Complexity: <i>O(s)</i> time and memory. Note that thanks to
--   sparsification, the resulting graph has a linear number of edges with
--   respect to the size of the original algebraic representation even
--   though the latter can potentially contain a quadratic <i>O(s^2)</i>
--   number of edges.
--   
--   <pre>
--   <a>sort</a> . <a>reachable</a> k                 == <a>sort</a> . <a>filter</a> (&lt;= n) . <a>flip</a> <a>reachable</a> k . sparsifyKL n
--   <a>length</a> (<a>vertices</a> $ sparsifyKL n x) &lt;= <a>vertexCount</a> x + <a>size</a> x + 1
--   <a>length</a> (<a>edges</a>    $ sparsifyKL n x) &lt;= 3 * <a>size</a> x
--   </pre>
sparsifyKL :: Int -> Graph Int -> Graph

-- | Left-to-right <i>relational composition</i> of graphs: vertices
--   <tt>x</tt> and <tt>z</tt> are connected in the resulting graph if
--   there is a vertex <tt>y</tt>, such that <tt>x</tt> is connected to
--   <tt>y</tt> in the first graph, and <tt>y</tt> is connected to
--   <tt>z</tt> in the second graph. There are no isolated vertices in the
--   result. This operation is associative, has <a>empty</a> and
--   single-<a>vertex</a> graphs as <i>annihilating zeroes</i>, and
--   distributes over <a>overlay</a>. Complexity: <i>O(n * m * log(n))</i>
--   time, <i>O(n + m)</i> memory, and <i>O(m1 + m2)</i> size, where
--   <i>n</i> and <i>m</i> stand for the number of vertices and edges in
--   the resulting graph, while <i>m1</i> and <i>m2</i> are the number of
--   edges in the original graphs. Note that the number of edges in the
--   resulting graph may be quadratic, i.e. <i>m = O(m1 * m2)</i>, but the
--   algebraic representation requires only <i>O(m1 + m2)</i> operations to
--   list them.
--   
--   Good consumer of both arguments and good producer.
--   
--   <pre>
--   compose <a>empty</a>            x                == <a>empty</a>
--   compose x                <a>empty</a>            == <a>empty</a>
--   compose (<a>vertex</a> x)       y                == <a>empty</a>
--   compose x                (<a>vertex</a> y)       == <a>empty</a>
--   compose x                (compose y z)    == compose (compose x y) z
--   compose x                (<a>overlay</a> y z)    == <a>overlay</a> (compose x y) (compose x z)
--   compose (<a>overlay</a> x y)    z                == <a>overlay</a> (compose x z) (compose y z)
--   compose (<a>edge</a> x y)       (<a>edge</a> y z)       == <a>edge</a> x z
--   compose (<a>path</a>    [1..5]) (<a>path</a>    [1..5]) == <a>edges</a> [(1,3), (2,4), (3,5)]
--   compose (<a>circuit</a> [1..5]) (<a>circuit</a> [1..5]) == <a>circuit</a> [1,3,5,2,4]
--   <a>size</a> (compose x y)                        &lt;= <a>edgeCount</a> x + <a>edgeCount</a> y + 1
--   </pre>
compose :: Ord a => Graph a -> Graph a -> Graph a

-- | Compute the <i>Cartesian product</i> of graphs. Complexity: <i>O(s1 *
--   s2)</i> time, memory and size, where <i>s1</i> and <i>s2</i> are the
--   sizes of the given graphs.
--   
--   <pre>
--   box (<a>path</a> [0,1]) (<a>path</a> "ab") == <a>edges</a> [ ((0,'a'), (0,'b'))
--                                         , ((0,'a'), (1,'a'))
--                                         , ((0,'b'), (1,'b'))
--                                         , ((1,'a'), (1,'b')) ]
--   </pre>
--   
--   Up to isomorphism between the resulting vertex types, this operation
--   is <i>commutative</i>, <i>associative</i>, <i>distributes</i> over
--   <a>overlay</a>, has singleton graphs as <i>identities</i> and
--   <a>empty</a> as the <i>annihilating zero</i>. Below <tt>~~</tt> stands
--   for equality up to an isomorphism, e.g. <tt>(x,</tt> <tt>()) ~~
--   x</tt>.
--   
--   <pre>
--   box x y               ~~ box y x
--   box x (box y z)       ~~ box (box x y) z
--   box x (<a>overlay</a> y z)   == <a>overlay</a> (box x y) (box x z)
--   box x (<a>vertex</a> ())     ~~ x
--   box x <a>empty</a>           ~~ <a>empty</a>
--   <a>transpose</a>   (box x y) == box (<a>transpose</a> x) (<a>transpose</a> y)
--   <a>vertexCount</a> (box x y) == <a>vertexCount</a> x * <a>vertexCount</a> y
--   <a>edgeCount</a>   (box x y) &lt;= <a>vertexCount</a> x * <a>edgeCount</a> y + <a>edgeCount</a> x * <a>vertexCount</a> y
--   </pre>
box :: Graph a -> Graph b -> Graph (a, b)

-- | The <a>Context</a> of a subgraph comprises its <a>inputs</a> and
--   <a>outputs</a>, i.e. all the vertices that are connected to the
--   subgraph's vertices. Note that inputs and outputs can belong to the
--   subgraph itself. In general, there are no guarantees on the order of
--   vertices in <a>inputs</a> and <a>outputs</a>; furthermore, there may
--   be repetitions.
data Context a
Context :: [a] -> [a] -> Context a
[inputs] :: Context a -> [a]
[outputs] :: Context a -> [a]

-- | Extract the <a>Context</a> of a subgraph specified by a given
--   predicate. Returns <tt>Nothing</tt> if the specified subgraph is
--   empty.
--   
--   Good consumer.
--   
--   <pre>
--   context (<a>const</a> False) x                   == Nothing
--   context (== 1)        (<a>edge</a> 1 2)          == Just (<a>Context</a> [   ] [2  ])
--   context (== 2)        (<a>edge</a> 1 2)          == Just (<a>Context</a> [1  ] [   ])
--   context (<a>const</a> True ) (<a>edge</a> 1 2)          == Just (<a>Context</a> [1  ] [2  ])
--   context (== 4)        (3 * 1 * 4 * 1 * 5) == Just (<a>Context</a> [3,1] [1,5])
--   </pre>
context :: (a -> Bool) -> Graph a -> Maybe (Context a)
instance GHC.Generics.Generic (Algebra.Graph.Graph a)
instance GHC.Show.Show a => GHC.Show.Show (Algebra.Graph.Graph a)
instance GHC.Show.Show a => GHC.Show.Show (Algebra.Graph.Context a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Algebra.Graph.Context a)
instance GHC.Base.Functor Algebra.Graph.Graph
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Algebra.Graph.Graph a)
instance GHC.Num.Num a => GHC.Num.Num (Algebra.Graph.Graph a)
instance Data.String.IsString a => Data.String.IsString (Algebra.Graph.Graph a)
instance GHC.Classes.Ord a => GHC.Classes.Eq (Algebra.Graph.Graph a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.Graph a)
instance GHC.Base.Applicative Algebra.Graph.Graph
instance GHC.Base.Monad Algebra.Graph.Graph
instance GHC.Base.Alternative Algebra.Graph.Graph
instance GHC.Base.MonadPlus Algebra.Graph.Graph
instance GHC.Base.Semigroup (Algebra.Graph.Graph a)
instance GHC.Base.Monoid (Algebra.Graph.Graph a)


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module defines the core type class <a>Graph</a>, a few graph
--   subclasses, and basic polymorphic graph construction primitives.
--   Functions that cannot be implemented fully polymorphically and require
--   the use of an intermediate data type are not included. For example, to
--   compute the size of a <a>Graph</a> expression you will need to use a
--   concrete data type, such as <a>Algebra.Graph</a>.
--   
--   See <a>Algebra.Graph.Class</a> for alternative definitions where the
--   core type class is not higher-kinded and permits more instances.
module Algebra.Graph.HigherKinded.Class

-- | The core type class for constructing algebraic graphs is defined by
--   introducing the <a>connect</a> method to the standard <a>MonadPlus</a>
--   class and reusing the following existing methods:
--   
--   <ul>
--   <li>The <a>empty</a> method comes from the <a>Alternative</a> class
--   and corresponds to the <i>empty graph</i>. This module simply
--   re-exports it.</li>
--   <li>The <a>vertex</a> graph construction primitive is an alias for
--   <a>pure</a> of the <a>Applicative</a> type class.</li>
--   <li>Graph <a>overlay</a> is an alias for <tt>mplus</tt> of the
--   <a>MonadPlus</a> type class.</li>
--   </ul>
--   
--   The <a>Graph</a> type class is characterised by the following minimal
--   set of axioms. In equations we use <tt>+</tt> and <tt>*</tt> as
--   convenient shortcuts for <a>overlay</a> and <a>connect</a>,
--   respectively.
--   
--   <ul>
--   <li><a>overlay</a> is commutative and associative:<pre> x + y == y + x
--   x + (y + z) == (x + y) + z</pre></li>
--   <li><a>connect</a> is associative and has <a>empty</a> as the
--   identity:<pre> x * empty == x empty * x == x x * (y * z) == (x * y) *
--   z</pre></li>
--   <li><a>connect</a> distributes over <a>overlay</a>:<pre>x * (y + z) ==
--   x * y + x * z (x + y) * z == x * z + y * z</pre></li>
--   <li><a>connect</a> can be decomposed:<pre>x * y * z == x * y + x * z +
--   y * z</pre></li>
--   </ul>
--   
--   The following useful theorems can be proved from the above set of
--   axioms.
--   
--   <ul>
--   <li><a>overlay</a> has <a>empty</a> as the identity and is
--   idempotent:<pre> x + empty == x empty + x == x x + x == x</pre></li>
--   <li>Absorption and saturation of <a>connect</a>:<pre>x * y + x + y ==
--   x * y x * x * x == x * x</pre></li>
--   </ul>
--   
--   The core type class <a>Graph</a> corresponds to unlabelled directed
--   graphs. <a>Undirected</a>, <a>Reflexive</a>, <a>Transitive</a> and
--   <a>Preorder</a> graphs can be obtained by extending the minimal set of
--   axioms.
--   
--   When specifying the time and memory complexity of graph algorithms,
--   <i>n</i> will denote the number of vertices in the graph, <i>m</i>
--   will denote the number of edges in the graph, and <i>s</i> will denote
--   the <i>size</i> of the corresponding <a>Graph</a> expression.
class MonadPlus g => Graph g

-- | Connect two graphs.
connect :: Graph g => g a -> g a -> g a

-- | The identity of <a>&lt;|&gt;</a>
empty :: Alternative f => f a

-- | Construct the graph comprising a single isolated vertex. An alias for
--   <a>pure</a>.
vertex :: Graph g => a -> g a

-- | Overlay two graphs. An alias for <a>&lt;|&gt;</a>.
overlay :: Graph g => g a -> g a -> g a

-- | The class of <i>undirected graphs</i> that satisfy the following
--   additional axiom.
--   
--   <ul>
--   <li><a>connect</a> is commutative:<pre>x * y == y * x</pre></li>
--   </ul>
class Graph g => Undirected g

-- | The class of <i>reflexive graphs</i> that satisfy the following
--   additional axiom.
--   
--   <ul>
--   <li>Each vertex has a <i>self-loop</i>:<pre>vertex x == vertex x *
--   vertex x</pre></li>
--   </ul>
--   
--   Or, alternatively, if we remember that <a>vertex</a> is an alias for
--   <a>pure</a>:
--   
--   <pre>
--   pure x == pure x * pure x
--   </pre>
--   
--   Note that by applying the axiom in the reverse direction, one can
--   always remove all self-loops resulting in an <i>irreflexive graph</i>.
--   This type class can therefore be also used in the context of
--   irreflexive graphs.
class Graph g => Reflexive g

-- | The class of <i>transitive graphs</i> that satisfy the following
--   additional axiom.
--   
--   <ul>
--   <li>The <i>closure</i> axiom: graphs with equal transitive closures
--   are equal.<pre>y /= empty ==&gt; x * y + x * z + y * z == x * y + y *
--   z</pre></li>
--   </ul>
--   
--   By repeated application of the axiom one can turn any graph into its
--   transitive closure or transitive reduction.
class Graph g => Transitive g

-- | The class of <i>preorder graphs</i> that are both reflexive and
--   transitive.
class (Reflexive g, Transitive g) => Preorder g

-- | Construct the graph comprising a single edge.
--   
--   <pre>
--   edge x y               == <a>connect</a> (<a>vertex</a> x) (<a>vertex</a> y)
--   <tt>vertexCount</tt> (edge 1 1) == 1
--   <tt>vertexCount</tt> (edge 1 2) == 2
--   </pre>
edge :: Graph g => a -> a -> g a

-- | Construct the graph comprising a given list of isolated vertices.
--   Complexity: <i>O(L)</i> time, memory and size, where <i>L</i> is the
--   length of the given list.
--   
--   <pre>
--   vertices []            == <a>empty</a>
--   vertices [x]           == <a>vertex</a> x
--   vertices               == <a>overlays</a> . map <a>vertex</a>
--   <tt>hasVertex</tt> x . vertices == <a>elem</a> x
--   <tt>vertexCount</tt> . vertices == <a>length</a> . <a>nub</a>
--   <tt>vertexSet</tt>   . vertices == Set.<a>fromList</a>
--   </pre>
vertices :: Graph g => [a] -> g a

-- | Construct the graph from a list of edges. Complexity: <i>O(L)</i>
--   time, memory and size, where <i>L</i> is the length of the given list.
--   
--   <pre>
--   edges []      == <a>empty</a>
--   edges [(x,y)] == <a>edge</a> x y
--   </pre>
edges :: Graph g => [(a, a)] -> g a

-- | Overlay a given list of graphs. Complexity: <i>O(L)</i> time and
--   memory, and <i>O(S)</i> size, where <i>L</i> is the length of the
--   given list, and <i>S</i> is the sum of sizes of the graphs in the
--   list.
--   
--   <pre>
--   overlays []        == <a>empty</a>
--   overlays [x]       == x
--   overlays [x,y]     == <a>overlay</a> x y
--   overlays           == <a>foldr</a> <a>overlay</a> <a>empty</a>
--   <tt>isEmpty</tt> . overlays == <a>all</a> <tt>isEmpty</tt>
--   </pre>
overlays :: Graph g => [g a] -> g a

-- | Connect a given list of graphs. Complexity: <i>O(L)</i> time and
--   memory, and <i>O(S)</i> size, where <i>L</i> is the length of the
--   given list, and <i>S</i> is the sum of sizes of the graphs in the
--   list.
--   
--   <pre>
--   connects []        == <a>empty</a>
--   connects [x]       == x
--   connects [x,y]     == <a>connect</a> x y
--   connects           == <a>foldr</a> <a>connect</a> <a>empty</a>
--   <tt>isEmpty</tt> . connects == <a>all</a> <tt>isEmpty</tt>
--   </pre>
connects :: Graph g => [g a] -> g a

-- | The <a>isSubgraphOf</a> function takes two graphs and returns
--   <a>True</a> if the first graph is a <i>subgraph</i> of the second.
--   Here is the current implementation:
--   
--   <pre>
--   isSubgraphOf x y = <a>overlay</a> x y == y
--   </pre>
--   
--   The complexity therefore depends on the complexity of equality testing
--   of the specific graph instance.
--   
--   <pre>
--   isSubgraphOf <a>empty</a>         x             == True
--   isSubgraphOf (<a>vertex</a> x)    <a>empty</a>         == False
--   isSubgraphOf x             (<a>overlay</a> x y) == True
--   isSubgraphOf (<a>overlay</a> x y) (<a>connect</a> x y) == True
--   isSubgraphOf (<a>path</a> xs)     (<a>circuit</a> xs)  == True
--   </pre>
isSubgraphOf :: (Graph g, Eq (g a)) => g a -> g a -> Bool

-- | Check if a graph contains a given edge. Complexity: <i>O(s)</i> time.
--   
--   <pre>
--   hasEdge x y <a>empty</a>            == False
--   hasEdge x y (<a>vertex</a> z)       == False
--   hasEdge x y (<a>edge</a> x y)       == True
--   hasEdge x y                  == <a>elem</a> (x,y) . <tt>edgeList</tt>
--   </pre>
hasEdge :: (Eq (g a), Graph g, Ord a) => a -> a -> g a -> Bool

-- | The <i>path</i> on a list of vertices. Complexity: <i>O(L)</i> time,
--   memory and size, where <i>L</i> is the length of the given list.
--   
--   <pre>
--   path []    == <a>empty</a>
--   path [x]   == <a>vertex</a> x
--   path [x,y] == <a>edge</a> x y
--   </pre>
path :: Graph g => [a] -> g a

-- | The <i>circuit</i> on a list of vertices. Complexity: <i>O(L)</i>
--   time, memory and size, where <i>L</i> is the length of the given list.
--   
--   <pre>
--   circuit []    == <a>empty</a>
--   circuit [x]   == <a>edge</a> x x
--   circuit [x,y] == <a>edges</a> [(x,y), (y,x)]
--   </pre>
circuit :: Graph g => [a] -> g a

-- | The <i>clique</i> on a list of vertices. Complexity: <i>O(L)</i> time,
--   memory and size, where <i>L</i> is the length of the given list.
--   
--   <pre>
--   clique []         == <a>empty</a>
--   clique [x]        == <a>vertex</a> x
--   clique [x,y]      == <a>edge</a> x y
--   clique [x,y,z]    == <a>edges</a> [(x,y), (x,z), (y,z)]
--   clique (xs ++ ys) == <a>connect</a> (clique xs) (clique ys)
--   </pre>
clique :: Graph g => [a] -> g a

-- | The <i>biclique</i> on two lists of vertices. Complexity: <i>O(L1 +
--   L2)</i> time, memory and size, where <i>L1</i> and <i>L2</i> are the
--   lengths of the given lists.
--   
--   <pre>
--   biclique []      []      == <a>empty</a>
--   biclique [x]     []      == <a>vertex</a> x
--   biclique []      [y]     == <a>vertex</a> y
--   biclique [x1,x2] [y1,y2] == <a>edges</a> [(x1,y1), (x1,y2), (x2,y1), (x2,y2)]
--   biclique xs      ys      == <a>connect</a> (<a>vertices</a> xs) (<a>vertices</a> ys)
--   </pre>
biclique :: Graph g => [a] -> [a] -> g a

-- | The <i>star</i> formed by a centre vertex connected to a list of
--   leaves. Complexity: <i>O(L)</i> time, memory and size, where <i>L</i>
--   is the length of the given list.
--   
--   <pre>
--   star x []    == <a>vertex</a> x
--   star x [y]   == <a>edge</a> x y
--   star x [y,z] == <a>edges</a> [(x,y), (x,z)]
--   star x ys    == <a>connect</a> (<a>vertex</a> x) (<a>vertices</a> ys)
--   </pre>
star :: Graph g => a -> [a] -> g a

-- | The <i>stars</i> formed by overlaying a list of <a>star</a>s. An
--   inverse of <tt>adjacencyList</tt>. Complexity: <i>O(L)</i> time,
--   memory and size, where <i>L</i> is the total size of the input.
--   
--   <pre>
--   stars []                      == <a>empty</a>
--   stars [(x, [])]               == <a>vertex</a> x
--   stars [(x, [y])]              == <a>edge</a> x y
--   stars [(x, ys)]               == <a>star</a> x ys
--   stars                         == <a>overlays</a> . <a>map</a> (<a>uncurry</a> <a>star</a>)
--   stars . <tt>adjacencyList</tt>         == id
--   <a>overlay</a> (stars xs) (stars ys) == stars (xs ++ ys)
--   </pre>
stars :: Graph g => [(a, [a])] -> g a

-- | The <i>tree graph</i> constructed from a given <a>Tree</a> data
--   structure. Complexity: <i>O(T)</i> time, memory and size, where
--   <i>T</i> is the size of the given tree (i.e. the number of vertices in
--   the tree).
--   
--   <pre>
--   tree (Node x [])                                         == <a>vertex</a> x
--   tree (Node x [Node y [Node z []]])                       == <a>path</a> [x,y,z]
--   tree (Node x [Node y [], Node z []])                     == <a>star</a> x [y,z]
--   tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) == <a>edges</a> [(1,2), (1,3), (3,4), (3,5)]
--   </pre>
tree :: Graph g => Tree a -> g a

-- | The <i>forest graph</i> constructed from a given <a>Forest</a> data
--   structure. Complexity: <i>O(F)</i> time, memory and size, where
--   <i>F</i> is the size of the given forest (i.e. the number of vertices
--   in the forest).
--   
--   <pre>
--   forest []                                                  == <a>empty</a>
--   forest [x]                                                 == <a>tree</a> x
--   forest [Node 1 [Node 2 [], Node 3 []], Node 4 [Node 5 []]] == <a>edges</a> [(1,2), (1,3), (4,5)]
--   forest                                                     == <a>overlays</a> . <a>map</a> <a>tree</a>
--   </pre>
forest :: Graph g => Forest a -> g a

-- | Construct a <i>mesh graph</i> from two lists of vertices. Complexity:
--   <i>O(L1 * L2)</i> time, memory and size, where <i>L1</i> and <i>L2</i>
--   are the lengths of the given lists.
--   
--   <pre>
--   mesh xs     []   == <a>empty</a>
--   mesh []     ys   == <a>empty</a>
--   mesh [x]    [y]  == <a>vertex</a> (x, y)
--   mesh xs     ys   == <tt>box</tt> (<a>path</a> xs) (<a>path</a> ys)
--   mesh [1..3] "ab" == <a>edges</a> [ ((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')) ]
--   </pre>
mesh :: Graph g => [a] -> [b] -> g (a, b)

-- | Construct a <i>torus graph</i> from two lists of vertices. Complexity:
--   <i>O(L1 * L2)</i> time, memory and size, where <i>L1</i> and <i>L2</i>
--   are the lengths of the given lists.
--   
--   <pre>
--   torus xs    []   == <a>empty</a>
--   torus []    ys   == <a>empty</a>
--   torus [x]   [y]  == <a>edge</a> (x,y) (x,y)
--   torus xs    ys   == <tt>box</tt> (<a>circuit</a> xs) (<a>circuit</a> ys)
--   torus [1,2] "ab" == <a>edges</a> [ ((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')) ]
--   </pre>
torus :: Graph g => [a] -> [b] -> g (a, b)

-- | Construct a <i>De Bruijn graph</i> of a given non-negative dimension
--   using symbols from a given alphabet. Complexity: <i>O(A^(D + 1))</i>
--   time, memory and size, where <i>A</i> is the size of the alphabet and
--   <i>D</i> is the dimension of the graph.
--   
--   <pre>
--             deBruijn 0 xs               == <a>edge</a> [] []
--   n &gt; 0 ==&gt; deBruijn n []               == <a>empty</a>
--             deBruijn 1 [0,1]            == <a>edges</a> [ ([0],[0]), ([0],[1]), ([1],[0]), ([1],[1]) ]
--             deBruijn 2 "0"              == <a>edge</a> "00" "00"
--             deBruijn 2 "01"             == <a>edges</a> [ ("00","00"), ("00","01"), ("01","10"), ("01","11")
--                                                  , ("10","00"), ("10","01"), ("11","10"), ("11","11") ]
--             transpose   (deBruijn n xs) == <a>fmap</a> <a>reverse</a> $ deBruijn n xs
--             <tt>vertexCount</tt> (deBruijn n xs) == (<a>length</a> $ <a>nub</a> xs)^n
--   n &gt; 0 ==&gt; <tt>edgeCount</tt>   (deBruijn n xs) == (<a>length</a> $ <a>nub</a> xs)^(n + 1)
--   </pre>
deBruijn :: Graph g => Int -> [a] -> g [a]

-- | Remove a vertex from a given graph. Complexity: <i>O(s)</i> time,
--   memory and size.
--   
--   <pre>
--   removeVertex x (<a>vertex</a> x)       == <a>empty</a>
--   removeVertex 1 (<a>vertex</a> 2)       == <a>vertex</a> 2
--   removeVertex x (<a>edge</a> x x)       == <a>empty</a>
--   removeVertex 1 (<a>edge</a> 1 2)       == <a>vertex</a> 2
--   removeVertex x . removeVertex x == removeVertex x
--   </pre>
removeVertex :: (Eq a, Graph g) => a -> g a -> g a

-- | The function <tt><a>replaceVertex</a> x y</tt> replaces vertex
--   <tt>x</tt> with vertex <tt>y</tt> in a given <a>Graph</a>. If
--   <tt>y</tt> already exists, <tt>x</tt> and <tt>y</tt> will be merged.
--   Complexity: <i>O(s)</i> time, memory and size.
--   
--   <pre>
--   replaceVertex x x            == id
--   replaceVertex x y (<a>vertex</a> x) == <a>vertex</a> y
--   replaceVertex x y            == <a>mergeVertices</a> (== x) y
--   </pre>
replaceVertex :: (Eq a, Graph g) => a -> a -> g a -> g a

-- | Merge vertices satisfying a given predicate into a given vertex.
--   Complexity: <i>O(s)</i> time, memory and size, assuming that the
--   predicate takes constant time.
--   
--   <pre>
--   mergeVertices (<a>const</a> False) x    == id
--   mergeVertices (== x) y           == <a>replaceVertex</a> x y
--   mergeVertices <a>even</a> 1 (0 * 2)     == 1 * 1
--   mergeVertices <a>odd</a>  1 (3 + 4 * 5) == 4 * 1
--   </pre>
mergeVertices :: Graph g => (a -> Bool) -> a -> g a -> g a

-- | Split a vertex into a list of vertices with the same connectivity.
--   Complexity: <i>O(s + k * L)</i> time, memory and size, where <i>k</i>
--   is the number of occurrences of the vertex in the expression and
--   <i>L</i> is the length of the given list.
--   
--   <pre>
--   splitVertex x []                  == <a>removeVertex</a> x
--   splitVertex x [x]                 == id
--   splitVertex x [y]                 == <a>replaceVertex</a> x y
--   splitVertex 1 [0,1] $ 1 * (2 + 3) == (0 + 1) * (2 + 3)
--   </pre>
splitVertex :: (Eq a, Graph g) => a -> [a] -> g a -> g a

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that do not satisfy a given predicate. Complexity:
--   <i>O(s)</i> time, memory and size, assuming that the predicate takes
--   constant time.
--   
--   <pre>
--   induce (<a>const</a> True ) x      == x
--   induce (<a>const</a> False) x      == <a>empty</a>
--   induce (/= x)               == <a>removeVertex</a> x
--   induce p . induce q         == induce (\x -&gt; p x &amp;&amp; q x)
--   <a>isSubgraphOf</a> (induce p x) x == True
--   </pre>
induce :: Graph g => (a -> Bool) -> g a -> g a
instance Algebra.Graph.HigherKinded.Class.Graph Algebra.Graph.Graph


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module defines the <a>AdjacencyMap</a> data type for undirected
--   bipartite graphs and associated functions. See
--   <a>Algebra.Graph.Bipartite.AdjacencyMap.Algorithm</a> for basic
--   bipartite graph algorithms.
--   
--   To avoid name clashes with <a>Algebra.Graph.AdjacencyMap</a>, this
--   module can be imported qualified:
--   
--   <pre>
--   import qualified Algebra.Graph.Bipartite.AdjacencyMap as Bipartite
--   </pre>
module Algebra.Graph.Bipartite.AdjacencyMap

-- | The <a>AdjacencyMap</a> data type represents an undirected bipartite
--   graph. The two type parameters determine the types of vertices of each
--   part. If the types coincide, the vertices of the left part are still
--   treated as disjoint from the vertices of the right part. See examples
--   for more details.
--   
--   We define a <a>Num</a> instance as a convenient notation for working
--   with bipartite graphs:
--   
--   <pre>
--   0                     == <a>rightVertex</a> 0
--   <a>swap</a> 1                == <a>leftVertex</a> 1
--   <a>swap</a> 1 + 2            == <a>vertices</a> [1] [2]
--   <a>swap</a> 1 * 2            == <a>edge</a> 1 2
--   <a>swap</a> 1 + 2 * <a>swap</a> 3   == <a>overlay</a> (<a>leftVertex</a> 1) (<a>edge</a> 3 2)
--   <a>swap</a> 1 * (2 + <a>swap</a> 3) == <a>connect</a> (<a>leftVertex</a> 1) (<a>vertices</a> [3] [2])
--   </pre>
--   
--   <b>Note:</b> the <a>Num</a> instance does not satisfy several
--   "customary laws" of <a>Num</a>, which dictate that <a>fromInteger</a>
--   <tt>0</tt> and <a>fromInteger</a> <tt>1</tt> should act as additive
--   and multiplicative identities, and <a>negate</a> as additive inverse.
--   Nevertheless, overloading <a>fromInteger</a>, <a>+</a> and <a>*</a> is
--   very convenient when working with algebraic graphs; we hope that in
--   future Haskell's Prelude will provide a more fine-grained class
--   hierarchy for algebraic structures, which we would be able to utilise
--   without violating any laws.
--   
--   The <a>Show</a> instance is defined using basic graph construction
--   primitives:
--   
--   <pre>
--   show empty                 == "empty"
--   show 1                     == "rightVertex 1"
--   show (<a>swap</a> 2)              == "leftVertex 2"
--   show (1 + 2)               == "vertices [] [1,2]"
--   show (<a>swap</a> (1 + 2))        == "vertices [1,2] []"
--   show (<a>swap</a> 1 * 2)          == "edge 1 2"
--   show (<a>swap</a> 1 * 2 * <a>swap</a> 3) == "edges [(1,2),(3,2)]"
--   show (<a>swap</a> 1 * 2 + <a>swap</a> 3) == "overlay (leftVertex 3) (edge 1 2)"
--   </pre>
--   
--   The <a>Eq</a> instance satisfies all axioms of undirected bipartite
--   algebraic graphs:
--   
--   <ul>
--   <li><a>overlay</a> is commutative and associative:<pre> x + y == y + x
--   x + (y + z) == (x + y) + z</pre></li>
--   <li><a>connect</a> is commutative, associative and has <a>empty</a> as
--   the identity:<pre> x * empty == x empty * x == x x * y == y * x x * (y
--   * z) == (x * y) * z</pre></li>
--   <li><a>connect</a> distributes over <a>overlay</a>:<pre>x * (y + z) ==
--   x * y + x * z (x + y) * z == x * z + y * z</pre></li>
--   <li><a>connect</a> can be decomposed:<pre>x * y * z == x * y + x * z +
--   y * z</pre></li>
--   <li><a>connect</a> has the same effect as <a>overlay</a> on vertices
--   of the same part:<pre> leftVertex x * leftVertex y == leftVertex x +
--   leftVertex y rightVertex x * rightVertex y == rightVertex x +
--   rightVertex y</pre></li>
--   </ul>
--   
--   The following useful theorems can be proved from the above set of
--   axioms.
--   
--   <ul>
--   <li><a>overlay</a> has <a>empty</a> as the identity and is
--   idempotent:<pre>x + empty == x empty + x == x x + x == x</pre></li>
--   <li>Absorption and saturation of <a>connect</a>:<pre>x * y + x + y ==
--   x * y x * x * x == x * x</pre></li>
--   </ul>
--   
--   When specifying the time and memory complexity of graph algorithms,
--   <i>n</i> and <i>m</i> will denote the number of vertices and edges of
--   the graph, respectively. In addition, <i>l</i> and <i>r</i> will
--   denote the number of vertices in the left and right parts of the
--   graph, respectively.
data AdjacencyMap a b

-- | The <i>adjacency map</i> of the left part of the graph: each left
--   vertex is associated with a set of its right neighbours. Complexity:
--   <i>O(1)</i> time and memory.
--   
--   <pre>
--   leftAdjacencyMap <a>empty</a>           == Map.<a>empty</a>
--   leftAdjacencyMap (<a>leftVertex</a> x)  == Map.<a>singleton</a> x Set.<a>empty</a>
--   leftAdjacencyMap (<a>rightVertex</a> x) == Map.<a>empty</a>
--   leftAdjacencyMap (<a>edge</a> x y)      == Map.<a>singleton</a> x (Set.<a>singleton</a> y)
--   </pre>
leftAdjacencyMap :: AdjacencyMap a b -> Map a (Set b)

-- | The <i>adjacency map</i> of the right part of the graph: each right
--   vertex is associated with a set of its left neighbours. Complexity:
--   <i>O(1)</i> time and memory.
--   
--   <pre>
--   rightAdjacencyMap <a>empty</a>           == Map.<a>empty</a>
--   rightAdjacencyMap (<a>leftVertex</a> x)  == Map.<a>empty</a>
--   rightAdjacencyMap (<a>rightVertex</a> x) == Map.<a>singleton</a> x Set.<a>empty</a>
--   rightAdjacencyMap (<a>edge</a> x y)      == Map.<a>singleton</a> y (Set.<a>singleton</a> x)
--   </pre>
rightAdjacencyMap :: AdjacencyMap a b -> Map b (Set a)

-- | Construct the <i>empty graph</i>.
--   
--   <pre>
--   <a>isEmpty</a> empty           == True
--   <a>leftAdjacencyMap</a> empty  == Map.<a>empty</a>
--   <a>rightAdjacencyMap</a> empty == Map.<a>empty</a>
--   <a>hasVertex</a> x empty       == False
--   </pre>
empty :: AdjacencyMap a b

-- | Construct the graph comprising <i>a single isolated vertex</i> in the
--   left part.
--   
--   <pre>
--   <a>leftAdjacencyMap</a> (leftVertex x)  == Map.<a>singleton</a> x Set.<a>empty</a>
--   <a>rightAdjacencyMap</a> (leftVertex x) == Map.<a>empty</a>
--   <a>hasLeftVertex</a> x (leftVertex y)   == (x == y)
--   <a>hasRightVertex</a> x (leftVertex y)  == False
--   <a>hasEdge</a> x y (leftVertex z)       == False
--   </pre>
leftVertex :: a -> AdjacencyMap a b

-- | Construct the graph comprising <i>a single isolated vertex</i> in the
--   right part.
--   
--   <pre>
--   <a>leftAdjacencyMap</a> (rightVertex x)  == Map.<a>empty</a>
--   <a>rightAdjacencyMap</a> (rightVertex x) == Map.<a>singleton</a> x Set.<a>empty</a>
--   <a>hasLeftVertex</a> x (rightVertex y)   == False
--   <a>hasRightVertex</a> x (rightVertex y)  == (x == y)
--   <a>hasEdge</a> x y (rightVertex z)       == False
--   </pre>
rightVertex :: b -> AdjacencyMap a b

-- | Construct the graph comprising <i>a single isolated vertex</i>.
--   
--   <pre>
--   vertex . Left  == <a>leftVertex</a>
--   vertex . Right == <a>rightVertex</a>
--   </pre>
vertex :: Either a b -> AdjacencyMap a b

-- | Construct the graph comprising <i>a single edge</i>.
--   
--   <pre>
--   edge x y                     == <a>connect</a> (<a>leftVertex</a> x) (<a>rightVertex</a> y)
--   <a>leftAdjacencyMap</a> (edge x y)  == Map.<a>singleton</a> x (Set.<a>singleton</a> y)
--   <a>rightAdjacencyMap</a> (edge x y) == Map.<a>singleton</a> y (Set.<a>singleton</a> x)
--   <a>hasEdge</a> x y (edge x y)       == True
--   <a>hasEdge</a> 1 2 (edge 2 1)       == False
--   </pre>
edge :: a -> b -> AdjacencyMap a b

-- | <i>Overlay</i> two graphs. This is a commutative, associative and
--   idempotent operation with the identity <a>empty</a>. Complexity:
--   <i>O((n + m) * log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   <a>isEmpty</a>     (overlay x y) == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (overlay x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (overlay x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (overlay x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (overlay x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (overlay x y) &lt;= <a>edgeCount</a> x   + <a>edgeCount</a> y
--   </pre>
overlay :: (Ord a, Ord b) => AdjacencyMap a b -> AdjacencyMap a b -> AdjacencyMap a b

-- | <i>Connect</i> two graphs, filtering out the edges between vertices of
--   the same part. This is a commutative and associative operation with
--   the identity <a>empty</a>, which distributes over <a>overlay</a> and
--   obeys the decomposition axiom. Complexity: <i>O((n + m) * log(n))</i>
--   time and <i>O(n + m)</i> memory. Note that the number of edges in the
--   resulting graph is quadratic with respect to the number of vertices in
--   the arguments: <i>O(m1 + m2 + l1 * r2 + l2 * r1)</i>.
--   
--   <pre>
--   connect (<a>leftVertex</a> x)     (<a>leftVertex</a> y)     == <a>vertices</a> [x,y] []
--   connect (<a>leftVertex</a> x)     (<a>rightVertex</a> y)    == <a>edge</a> x y
--   connect (<a>rightVertex</a> x)    (<a>leftVertex</a> y)     == <a>edge</a> y x
--   connect (<a>rightVertex</a> x)    (<a>rightVertex</a> y)    == <a>vertices</a> [] [x,y]
--   connect (<a>vertices</a> xs1 ys1) (<a>vertices</a> xs2 ys2) == <a>overlay</a> (<a>biclique</a> xs1 ys2) (<a>biclique</a> xs2 ys1)
--   <a>isEmpty</a>     (connect x y)                     == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (connect x y)                     == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (connect x y)                     &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (connect x y)                     &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect x y)                     &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (connect x y)                     &gt;= <a>leftVertexCount</a> x * <a>rightVertexCount</a> y
--   <a>edgeCount</a>   (connect x y)                     &lt;= <a>leftVertexCount</a> x * <a>rightVertexCount</a> y + <a>rightVertexCount</a> x * <a>leftVertexCount</a> y + <a>edgeCount</a> x + <a>edgeCount</a> y
--   </pre>
connect :: (Ord a, Ord b) => AdjacencyMap a b -> AdjacencyMap a b -> AdjacencyMap a b

-- | Construct the graph comprising given lists of isolated vertices in
--   each part. Complexity: <i>O(L * log(L))</i> time and <i>O(L)</i>
--   memory, where <i>L</i> is the total length of two lists.
--   
--   <pre>
--   vertices [] []                    == <a>empty</a>
--   vertices [x] []                   == <a>leftVertex</a> x
--   vertices [] [x]                   == <a>rightVertex</a> x
--   vertices xs ys                    == <a>overlays</a> (<a>map</a> <a>leftVertex</a> xs ++ <a>map</a> <a>rightVertex</a> ys)
--   <a>hasLeftVertex</a>  x (vertices xs ys) == <a>elem</a> x xs
--   <a>hasRightVertex</a> y (vertices xs ys) == <a>elem</a> y ys
--   </pre>
vertices :: (Ord a, Ord b) => [a] -> [b] -> AdjacencyMap a b

-- | Construct the graph from a list of edges. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   edges []            == <a>empty</a>
--   edges [(x,y)]       == <a>edge</a> x y
--   edges               == <a>overlays</a> . <a>map</a> (<a>uncurry</a> <a>edge</a>)
--   <a>hasEdge</a> x y . edges == <a>elem</a> (x,y)
--   <a>edgeCount</a>   . edges == <a>length</a> . <tt>nub</tt>
--   </pre>
edges :: (Ord a, Ord b) => [(a, b)] -> AdjacencyMap a b

-- | Overlay a given list of graphs. Complexity: <i>O((n + m) * log(n))</i>
--   time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   overlays []        == <a>empty</a>
--   overlays [x]       == x
--   overlays [x,y]     == <a>overlay</a> x y
--   overlays           == <a>foldr</a> <a>overlay</a> <a>empty</a>
--   <a>isEmpty</a> . overlays == <a>all</a> <a>isEmpty</a>
--   </pre>
overlays :: (Ord a, Ord b) => [AdjacencyMap a b] -> AdjacencyMap a b

-- | Connect a given list of graphs. Complexity: <i>O((n + m) * log(n))</i>
--   time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   connects []        == <a>empty</a>
--   connects [x]       == x
--   connects [x,y]     == connect x y
--   connects           == <a>foldr</a> <a>connect</a> <a>empty</a>
--   <a>isEmpty</a> . connects == <a>all</a> <a>isEmpty</a>
--   </pre>
connects :: (Ord a, Ord b) => [AdjacencyMap a b] -> AdjacencyMap a b

-- | Swap the parts of a given graph. Complexity: <i>O(1)</i> time and
--   memory.
--   
--   <pre>
--   swap <a>empty</a>            == <a>empty</a>
--   swap . <a>leftVertex</a>     == <a>rightVertex</a>
--   swap (<a>vertices</a> xs ys) == <a>vertices</a> ys xs
--   swap (<a>edge</a> x y)       == <a>edge</a> y x
--   swap . <a>edges</a>          == <a>edges</a> . <a>map</a> Data.Tuple.<a>swap</a>
--   swap . swap           == <a>id</a>
--   </pre>
swap :: AdjacencyMap a b -> AdjacencyMap b a

-- | Construct a bipartite <a>AdjacencyMap</a> from an
--   <a>Algebra.Graph.AdjacencyMap</a>, adding any missing edges to make
--   the graph undirected and filtering out the edges within the same
--   parts. Complexity: <i>O(m * log(n))</i>.
--   
--   <pre>
--   toBipartite <a>empty</a>                      == <a>empty</a>
--   toBipartite (<a>vertex</a> (Left x))          == <a>leftVertex</a> x
--   toBipartite (<a>vertex</a> (Right x))         == <a>rightVertex</a> x
--   toBipartite (<a>edge</a> (Left x) (Left y))   == <a>vertices</a> [x,y] []
--   toBipartite (<a>edge</a> (Left x) (Right y))  == <a>edge</a> x y
--   toBipartite (<a>edge</a> (Right x) (Left y))  == <a>edge</a> y x
--   toBipartite (<a>edge</a> (Right x) (Right y)) == <a>vertices</a> [] [x,y]
--   toBipartite . <a>clique</a>                   == <a>uncurry</a> <a>biclique</a> . <a>partitionEithers</a>
--   toBipartite . <a>fromBipartite</a>            == <a>id</a>
--   </pre>
toBipartite :: (Ord a, Ord b) => AdjacencyMap (Either a b) -> AdjacencyMap a b

-- | Construct a bipartite <a>AdjacencyMap</a> from an
--   <a>Algebra.Graph.AdjacencyMap</a>, where the two parts are identified
--   by a separate function, adding any missing edges to make the graph
--   undirected and filtering out the edges within the same parts.
--   Complexity: <i>O(m * log(n))</i>.
--   
--   <pre>
--   toBipartiteWith f <a>empty</a> == <a>empty</a>
--   toBipartiteWith Left x  == <a>vertices</a> (<a>vertexList</a> x) []
--   toBipartiteWith Right x == <a>vertices</a> [] (<a>vertexList</a> x)
--   toBipartiteWith f       == <a>toBipartite</a> . <a>gmap</a> f
--   toBipartiteWith id      == <a>toBipartite</a>
--   </pre>
toBipartiteWith :: (Ord a, Ord b, Ord c) => (a -> Either b c) -> AdjacencyMap a -> AdjacencyMap b c

-- | Construct an <a>Algebra.Graph.AdjacencyMap</a> from a bipartite
--   <a>AdjacencyMap</a>. Complexity: <i>O(m * log(n))</i>.
--   
--   <pre>
--   fromBipartite <a>empty</a>          == <a>empty</a>
--   fromBipartite (<a>leftVertex</a> x) == <a>vertex</a> (Left x)
--   fromBipartite (<a>edge</a> x y)     == <a>edges</a> [(Left x, Right y), (Right y, Left x)]
--   <a>toBipartite</a> . fromBipartite  == <a>id</a>
--   </pre>
fromBipartite :: (Ord a, Ord b) => AdjacencyMap a b -> AdjacencyMap (Either a b)

-- | Construct an <a>Algebra.Graph.AdjacencyMap</a> from a bipartite
--   <a>AdjacencyMap</a> given a way to inject vertices of the two parts
--   into the resulting vertex type. Complexity: <i>O(m * log(n))</i>.
--   
--   <pre>
--   fromBipartiteWith Left Right             == <a>fromBipartite</a>
--   fromBipartiteWith id id (<a>vertices</a> xs ys) == <a>vertices</a> (xs ++ ys)
--   fromBipartiteWith id id . <a>edges</a>          == <a>symmetricClosure</a> . <a>edges</a>
--   </pre>
fromBipartiteWith :: Ord c => (a -> c) -> (b -> c) -> AdjacencyMap a b -> AdjacencyMap c

-- | Check if a graph is empty. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   isEmpty <a>empty</a>                 == True
--   isEmpty (<a>overlay</a> <a>empty</a> <a>empty</a>) == True
--   isEmpty (<a>vertex</a> x)            == False
--   isEmpty                       == (==) <a>empty</a>
--   </pre>
isEmpty :: AdjacencyMap a b -> Bool

-- | Check if a graph contains a given vertex in the left part. Complexity:
--   <i>O(log(l))</i> time.
--   
--   <pre>
--   hasLeftVertex x <a>empty</a>           == False
--   hasLeftVertex x (<a>leftVertex</a> y)  == (x == y)
--   hasLeftVertex x (<a>rightVertex</a> y) == False
--   </pre>
hasLeftVertex :: Ord a => a -> AdjacencyMap a b -> Bool

-- | Check if a graph contains a given vertex in the right part.
--   Complexity: <i>O(log(r))</i> time.
--   
--   <pre>
--   hasRightVertex x <a>empty</a>           == False
--   hasRightVertex x (<a>leftVertex</a> y)  == False
--   hasRightVertex x (<a>rightVertex</a> y) == (x == y)
--   </pre>
hasRightVertex :: Ord b => b -> AdjacencyMap a b -> Bool

-- | Check if a graph contains a given vertex. Complexity: <i>O(log(n))</i>
--   time.
--   
--   <pre>
--   hasVertex . Left  == <a>hasLeftVertex</a>
--   hasVertex . Right == <a>hasRightVertex</a>
--   </pre>
hasVertex :: (Ord a, Ord b) => Either a b -> AdjacencyMap a b -> Bool

-- | Check if a graph contains a given edge. Complexity: <i>O(log(n))</i>
--   time.
--   
--   <pre>
--   hasEdge x y <a>empty</a>      == False
--   hasEdge x y (<a>vertex</a> z) == False
--   hasEdge x y (<a>edge</a> x y) == True
--   hasEdge x y            == <a>elem</a> (x,y) . <a>edgeList</a>
--   </pre>
hasEdge :: (Ord a, Ord b) => a -> b -> AdjacencyMap a b -> Bool

-- | The number of vertices in the left part of a graph. Complexity:
--   <i>O(1)</i> time.
--   
--   <pre>
--   leftVertexCount <a>empty</a>           == 0
--   leftVertexCount (<a>leftVertex</a> x)  == 1
--   leftVertexCount (<a>rightVertex</a> x) == 0
--   leftVertexCount (<a>edge</a> x y)      == 1
--   leftVertexCount . <a>edges</a>         == <a>length</a> . <tt>nub</tt> . <a>map</a> <a>fst</a>
--   </pre>
leftVertexCount :: AdjacencyMap a b -> Int

-- | The number of vertices in the right part of a graph. Complexity:
--   <i>O(1)</i> time.
--   
--   <pre>
--   rightVertexCount <a>empty</a>           == 0
--   rightVertexCount (<a>leftVertex</a> x)  == 0
--   rightVertexCount (<a>rightVertex</a> x) == 1
--   rightVertexCount (<a>edge</a> x y)      == 1
--   rightVertexCount . <a>edges</a>         == <a>length</a> . <tt>nub</tt> . <a>map</a> <a>snd</a>
--   </pre>
rightVertexCount :: AdjacencyMap a b -> Int

-- | The number of vertices in a graph. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   vertexCount <a>empty</a>      == 0
--   vertexCount (<a>vertex</a> x) == 1
--   vertexCount (<a>edge</a> x y) == 2
--   vertexCount x          == <a>leftVertexCount</a> x + <a>rightVertexCount</a> x
--   </pre>
vertexCount :: AdjacencyMap a b -> Int

-- | The number of edges in a graph. Complexity: <i>O(l)</i> time.
--   
--   <pre>
--   edgeCount <a>empty</a>      == 0
--   edgeCount (<a>vertex</a> x) == 0
--   edgeCount (<a>edge</a> x y) == 1
--   edgeCount . <a>edges</a>    == <a>length</a> . <tt>nub</tt>
--   </pre>
edgeCount :: AdjacencyMap a b -> Int

-- | The sorted list of vertices of the left part of a graph. Complexity:
--   <i>O(l)</i> time and memory.
--   
--   <pre>
--   leftVertexList <a>empty</a>              == []
--   leftVertexList (<a>leftVertex</a> x)     == [x]
--   leftVertexList (<a>rightVertex</a> x)    == []
--   leftVertexList . <a>flip</a> <a>vertices</a> [] == <tt>nub</tt> . <a>sort</a>
--   </pre>
leftVertexList :: AdjacencyMap a b -> [a]

-- | The sorted list of vertices of the right part of a graph. Complexity:
--   <i>O(r)</i> time and memory.
--   
--   <pre>
--   rightVertexList <a>empty</a>           == []
--   rightVertexList (<a>leftVertex</a> x)  == []
--   rightVertexList (<a>rightVertex</a> x) == [x]
--   rightVertexList . <a>vertices</a> []   == <tt>nub</tt> . <a>sort</a>
--   </pre>
rightVertexList :: AdjacencyMap a b -> [b]

-- | The sorted list of vertices of a graph. Complexity: <i>O(n)</i> time
--   and memory
--   
--   <pre>
--   vertexList <a>empty</a>                             == []
--   vertexList (<a>vertex</a> x)                        == [x]
--   vertexList (<a>edge</a> x y)                        == [Left x, Right y]
--   vertexList (<a>vertices</a> (<a>lefts</a> xs) (<a>rights</a> xs)) == <tt>nub</tt> (<a>sort</a> xs)
--   </pre>
vertexList :: AdjacencyMap a b -> [Either a b]

-- | The sorted list of edges of a graph. Complexity: <i>O(n + m)</i> time
--   and <i>O(m)</i> memory.
--   
--   <pre>
--   edgeList <a>empty</a>      == []
--   edgeList (<a>vertex</a> x) == []
--   edgeList (<a>edge</a> x y) == [(x,y)]
--   edgeList . <a>edges</a>    == <tt>nub</tt> . <a>sort</a>
--   </pre>
edgeList :: AdjacencyMap a b -> [(a, b)]

-- | The set of vertices of the left part of a graph. Complexity:
--   <i>O(l)</i> time and memory.
--   
--   <pre>
--   leftVertexSet <a>empty</a>              == Set.<a>empty</a>
--   leftVertexSet . <a>leftVertex</a>       == Set.<a>singleton</a>
--   leftVertexSet . <a>rightVertex</a>      == <a>const</a> Set.<a>empty</a>
--   leftVertexSet . <a>flip</a> <a>vertices</a> [] == Set.<a>fromList</a>
--   </pre>
leftVertexSet :: AdjacencyMap a b -> Set a

-- | The set of vertices of the right part of a graph. Complexity:
--   <i>O(r)</i> time and memory.
--   
--   <pre>
--   rightVertexSet <a>empty</a>         == Set.<a>empty</a>
--   rightVertexSet . <a>leftVertex</a>  == <a>const</a> Set.<a>empty</a>
--   rightVertexSet . <a>rightVertex</a> == Set.<a>singleton</a>
--   rightVertexSet . <a>vertices</a> [] == Set.<a>fromList</a>
--   </pre>
rightVertexSet :: AdjacencyMap a b -> Set b

-- | The set of vertices of a graph. Complexity: <i>O(n)</i> time and
--   memory.
--   
--   <pre>
--   vertexSet <a>empty</a>                             == Set.<a>empty</a>
--   vertexSet . <a>vertex</a>                          == Set.<a>singleton</a>
--   vertexSet (<a>edge</a> x y)                        == Set.<a>fromList</a> [Left x, Right y]
--   vertexSet (<a>vertices</a> (<a>lefts</a> xs) (<a>rights</a> xs)) == Set.<a>fromList</a> xs
--   </pre>
vertexSet :: (Ord a, Ord b) => AdjacencyMap a b -> Set (Either a b)

-- | The set of edges of a graph. Complexity: <i>O(n + m)</i> time and
--   <i>O(m)</i> memory.
--   
--   <pre>
--   edgeSet <a>empty</a>      == Set.<a>empty</a>
--   edgeSet (<a>vertex</a> x) == Set.<a>empty</a>
--   edgeSet (<a>edge</a> x y) == Set.<a>singleton</a> (x,y)
--   edgeSet . <a>edges</a>    == Set.<a>fromList</a>
--   </pre>
edgeSet :: (Ord a, Ord b) => AdjacencyMap a b -> Set (a, b)

-- | The sorted <i>adjacency list</i> of the left part of a graph.
--   Complexity: <i>O(n + m)</i> time and memory.
--   
--   <pre>
--   leftAdjacencyList <a>empty</a>            == []
--   leftAdjacencyList (<a>vertices</a> [] xs) == []
--   leftAdjacencyList (<a>vertices</a> xs []) == [(x, []) | x &lt;- <tt>nub</tt> (<a>sort</a> xs)]
--   leftAdjacencyList (<a>edge</a> x y)       == [(x, [y])]
--   leftAdjacencyList (<a>star</a> x ys)      == [(x, <tt>nub</tt> (<a>sort</a> ys))]
--   </pre>
leftAdjacencyList :: AdjacencyMap a b -> [(a, [b])]

-- | The sorted <i>adjacency list</i> of the right part of a graph.
--   Complexity: <i>O(n + m)</i> time and memory.
--   
--   <pre>
--   rightAdjacencyList <a>empty</a>            == []
--   rightAdjacencyList (<a>vertices</a> [] xs) == [(x, []) | x &lt;- <tt>nub</tt> (<a>sort</a> xs)]
--   rightAdjacencyList (<a>vertices</a> xs []) == []
--   rightAdjacencyList (<a>edge</a> x y)       == [(y, [x])]
--   rightAdjacencyList (<a>star</a> x ys)      == [(y, [x])  | y &lt;- <tt>nub</tt> (<a>sort</a> ys)]
--   </pre>
rightAdjacencyList :: AdjacencyMap a b -> [(b, [a])]

-- | A list of values of two alternating types. The first type argument
--   denotes the type of the value at the head.
--   
--   With the <tt>OverloadedLists</tt> extension it is possible to use the
--   standard list notation to construct a <a>List</a> where the two types
--   coincide, for example:
--   
--   <pre>
--   [1, 2, 3, 4, 5] :: List Int Int
--   </pre>
--   
--   We make use of this shorthand notation in the examples below.
data List a b
Nil :: List a b
Cons :: a -> List b a -> List a b

-- | Construct a <a>List</a> of even length from a list of pairs.
--   
--   <pre>
--   evenList []                 == <a>Nil</a>
--   evenList [(1,2), (3,4)]     == [1, 2, 3, 4] :: <a>List</a> Int Int
--   evenList [(1,'a'), (2,'b')] == <a>Cons</a> 1 (<a>Cons</a> 'a' (<a>Cons</a> 2 (<a>Cons</a> 'b' <a>Nil</a>)))
--   </pre>
evenList :: [(a, b)] -> List a b

-- | Construct a <a>List</a> of odd length given the first element and a
--   list of pairs.
--   
--   <pre>
--   oddList 1 []                 == <a>Cons</a> 1 <a>Nil</a>
--   oddList 1 [(2,3), (4,5)]     == [1, 2, 3, 4, 5] :: <a>List</a> Int Int
--   oddList 1 [('a',2), ('b',3)] == <a>Cons</a> 1 (<a>Cons</a> 'a' (<a>Cons</a> 2 (<a>Cons</a> 'b' (<a>Cons</a> 3 <a>Nil</a>))))
--   </pre>
oddList :: a -> [(b, a)] -> List a b

-- | The <i>path</i> on a <a>List</a> of vertices. Complexity: <i>O(L *
--   log(L))</i> time, where <i>L</i> is the length of the given list.
--   
--   <pre>
--   path <a>Nil</a>                   == <a>empty</a>
--   path (<a>Cons</a> x <a>Nil</a>)          == <a>leftVertex</a> x
--   path (<a>Cons</a> x (<a>Cons</a> y <a>Nil</a>)) == <a>edge</a> x y
--   path [1, 2, 3, 4, 5]       == <a>edges</a> [(1,2), (3,2), (3,4), (5,4)]
--   </pre>
path :: (Ord a, Ord b) => List a b -> AdjacencyMap a b

-- | The <i>circuit</i> on a list of pairs of vertices. Complexity: <i>O(L
--   * log(L))</i> time, where L is the length of the given list.
--   
--   <pre>
--   circuit []                    == <a>empty</a>
--   circuit [(x,y)]               == <a>edge</a> x y
--   circuit [(1,2), (3,4), (5,6)] == <a>edges</a> [(1,2), (3,2), (3,4), (5,4), (5,6), (1,6)]
--   circuit . <a>reverse</a>             == <a>swap</a> . circuit . <a>map</a> Data.Tuple.<a>swap</a>
--   </pre>
circuit :: (Ord a, Ord b) => [(a, b)] -> AdjacencyMap a b

-- | The <i>biclique</i> on two lists of vertices. Complexity: <i>O(n *
--   log(n) + m)</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   biclique [] [] == <a>empty</a>
--   biclique xs [] == <a>vertices</a> xs []
--   biclique [] ys == <a>vertices</a> [] ys
--   biclique xs ys == <a>connect</a> (<a>vertices</a> xs []) (<a>vertices</a> [] ys)
--   </pre>
biclique :: (Ord a, Ord b) => [a] -> [b] -> AdjacencyMap a b

-- | The <i>star</i> formed by a center vertex connected to a list of
--   leaves. Complexity: <i>O(L * log(L))</i> time, where <i>L</i> is the
--   length of the given list.
--   
--   <pre>
--   star x []    == <a>leftVertex</a> x
--   star x [y]   == <a>edge</a> x y
--   star x [y,z] == <a>edges</a> [(x,y), (x,z)]
--   star x ys    == <a>connect</a> (<a>leftVertex</a> x) (<a>vertices</a> [] ys)
--   </pre>
star :: (Ord a, Ord b) => a -> [b] -> AdjacencyMap a b

-- | The <i>stars</i> formed by overlaying a list of <a>star</a>s.
--   Complexity: <i>O(L * log(L))</i> time, where <i>L</i> is the total
--   size of the input.
--   
--   <pre>
--   stars []                      == <a>empty</a>
--   stars [(x, [])]               == <a>leftVertex</a> x
--   stars [(x, [y])]              == <a>edge</a> x y
--   stars [(x, ys)]               == <a>star</a> x ys
--   stars                         == <a>overlays</a> . <a>map</a> (<a>uncurry</a> <a>star</a>)
--   <a>overlay</a> (stars xs) (stars ys) == stars (xs ++ ys)
--   </pre>
stars :: (Ord a, Ord b) => [(a, [b])] -> AdjacencyMap a b

-- | Construct a <i>mesh</i> graph from two lists of vertices. Complexity:
--   <i>O(L1 * L2 * log(L1 * L2))</i> time, where <i>L1</i> and <i>L2</i>
--   are the lengths of the given lists.
--   
--   <pre>
--   mesh xs []           == <a>empty</a>
--   mesh [] ys           == <a>empty</a>
--   mesh [x] [y]         == <a>leftVertex</a> (x,y)
--   mesh [1,1] ['a','b'] == <a>biclique</a> [(1,'a'), (1,'b')] [(1,'a'), (1,'b')]
--   mesh [1,2] ['a','b'] == <a>biclique</a> [(1,'a'), (2,'b')] [(1,'b'), (2,'a')]
--   </pre>
mesh :: (Ord a, Ord b) => [a] -> [b] -> AdjacencyMap (a, b) (a, b)

-- | Remove a vertex from the left part of a given graph. Complexity:
--   <i>O(r * log(l))</i> time.
--   
--   <pre>
--   removeLeftVertex x (<a>leftVertex</a> x)       == <a>empty</a>
--   removeLeftVertex 1 (<a>leftVertex</a> 2)       == <a>leftVertex</a> 2
--   removeLeftVertex x (<a>rightVertex</a> y)      == <a>rightVertex</a> y
--   removeLeftVertex x (<a>edge</a> x y)           == <a>rightVertex</a> y
--   removeLeftVertex x . removeLeftVertex x == removeLeftVertex x
--   </pre>
removeLeftVertex :: Ord a => a -> AdjacencyMap a b -> AdjacencyMap a b

-- | Remove a vertex from the right part of a given graph. Complexity:
--   <i>O(l * log(r))</i> time.
--   
--   <pre>
--   removeRightVertex x (<a>rightVertex</a> x)       == <a>empty</a>
--   removeRightVertex 1 (<a>rightVertex</a> 2)       == <a>rightVertex</a> 2
--   removeRightVertex x (<a>leftVertex</a> y)        == <a>leftVertex</a> y
--   removeRightVertex y (<a>edge</a> x y)            == <a>leftVertex</a> x
--   removeRightVertex x . removeRightVertex x == removeRightVertex x
--   </pre>
removeRightVertex :: Ord b => b -> AdjacencyMap a b -> AdjacencyMap a b

-- | Remove an edge from a given graph. Complexity: <i>O(log(l) +
--   log(r))</i> time.
--   
--   <pre>
--   removeEdge x y (<a>edge</a> x y)            == <a>vertices</a> [x] [y]
--   removeEdge x y . removeEdge x y      == removeEdge x y
--   removeEdge x y . <a>removeLeftVertex</a> x  == <a>removeLeftVertex</a> x
--   removeEdge x y . <a>removeRightVertex</a> y == <a>removeRightVertex</a> y
--   </pre>
removeEdge :: (Ord a, Ord b) => a -> b -> AdjacencyMap a b -> AdjacencyMap a b

-- | Transform a graph by applying given functions to the vertices of each
--   part. Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   bimap f g <a>empty</a>           == <a>empty</a>
--   bimap f g . <a>vertex</a>        == <a>vertex</a> . Data.Bifunctor.<a>bimap</a> f g
--   bimap f g (<a>edge</a> x y)      == <a>edge</a> (f x) (g y)
--   bimap <a>id</a> <a>id</a>               == <a>id</a>
--   bimap f1 g1 . bimap f2 g2 == bimap (f1 . f2) (g1 . g2)
--   </pre>
bimap :: (Ord a, Ord b, Ord c, Ord d) => (a -> c) -> (b -> d) -> AdjacencyMap a b -> AdjacencyMap c d

-- | Compute the <i>Cartesian product</i> of two graphs. Complexity:
--   <i>O((n + m) * log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   <a>box</a> (<a>path</a> [0,1]) (<a>path</a> ['a','b']) == <a>edges</a> [ ((0,'a'), (0,'b'))
--                                              , ((0,'a'), (1,'a'))
--                                              , ((1,'b'), (0,'b'))
--                                              , ((1,'b'), (1,'a')) ]
--   </pre>
--   
--   Up to isomorphism between the resulting vertex types, this operation
--   is <i>commutative</i>, <i>associative</i>, <i>distributes</i> over
--   <a>overlay</a>, has singleton graphs as <i>identities</i> and
--   <i>swapping identities</i>, and <a>empty</a> as the <i>annihilating
--   zero</i>. Below <tt>~~</tt> stands for equality up to an isomorphism,
--   e.g. <tt>(x,</tt> <tt>()) ~~ x</tt>.
--   
--   <pre>
--   box x y                ~~ box y x
--   box x (box y z)        ~~ box (box x y) z
--   box x (<a>overlay</a> y z)    == <a>overlay</a> (box x y) (box x z)
--   box x (<a>leftVertex</a> ())  ~~ x
--   box x (<a>rightVertex</a> ()) ~~ <a>swap</a> x
--   box x <a>empty</a>            ~~ <a>empty</a>
--   <a>vertexCount</a> (box x y)  == <a>vertexCount</a> x * <a>vertexCount</a> y
--   <a>edgeCount</a>   (box x y)  == <a>vertexCount</a> x * <a>edgeCount</a> y + <a>edgeCount</a> x * <a>vertexCount</a> y
--   </pre>
box :: (Ord a, Ord b) => AdjacencyMap a a -> AdjacencyMap b b -> AdjacencyMap (a, b) (a, b)

-- | Compute the generalised <i>Cartesian product</i> of two graphs. The
--   resulting vertices are obtained using the given vertex combinators.
--   Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n + m)</i>
--   memory.
--   
--   See <a>box</a> for some examples.
--   
--   <pre>
--   box == boxWith (,) (,) (,) (,)
--   </pre>
boxWith :: (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f) => (a -> c -> e) -> (b -> d -> e) -> (a -> d -> f) -> (b -> c -> f) -> AdjacencyMap a b -> AdjacencyMap c d -> AdjacencyMap e f

-- | Check that the internal graph representation is consistent, i.e. that
--   all edges that are present in the <a>leftAdjacencyMap</a> are also
--   present in the <a>rightAdjacencyMap</a> map. It should be impossible
--   to create an inconsistent adjacency map, and we use this function in
--   testing.
--   
--   <pre>
--   consistent <a>empty</a>           == True
--   consistent (<a>vertex</a> x)      == True
--   consistent (<a>edge</a> x y)      == True
--   consistent (<a>edges</a> x)       == True
--   consistent (<a>toBipartite</a> x) == True
--   consistent (<a>swap</a> x)        == True
--   consistent (<a>circuit</a> x)     == True
--   consistent (<a>biclique</a> x y)  == True
--   </pre>
consistent :: (Ord a, Ord b) => AdjacencyMap a b -> Bool
instance GHC.Generics.Generic (Algebra.Graph.Bipartite.AdjacencyMap.AdjacencyMap a b)
instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Algebra.Graph.Bipartite.AdjacencyMap.List a b)
instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Algebra.Graph.Bipartite.AdjacencyMap.List a b)
instance GHC.Generics.Generic (Algebra.Graph.Bipartite.AdjacencyMap.List a b)
instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Algebra.Graph.Bipartite.AdjacencyMap.List a b)
instance GHC.Exts.IsList (Algebra.Graph.Bipartite.AdjacencyMap.List a a)
instance (GHC.Classes.Ord a, GHC.Classes.Ord b, GHC.Num.Num b) => GHC.Num.Num (Algebra.Graph.Bipartite.AdjacencyMap.AdjacencyMap a b)
instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Eq (Algebra.Graph.Bipartite.AdjacencyMap.AdjacencyMap a b)
instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Algebra.Graph.Bipartite.AdjacencyMap.AdjacencyMap a b)
instance (GHC.Classes.Ord a, GHC.Classes.Ord b, GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Algebra.Graph.Bipartite.AdjacencyMap.AdjacencyMap a b)
instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Base.Semigroup (Algebra.Graph.Bipartite.AdjacencyMap.AdjacencyMap a b)
instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Base.Monoid (Algebra.Graph.Bipartite.AdjacencyMap.AdjacencyMap a b)


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module provides several basic algorithms on undirected bipartite
--   graphs.
module Algebra.Graph.Bipartite.AdjacencyMap.Algorithm

-- | A cycle of odd length. For example, <tt>[1,2,3]</tt> represents the
--   cycle <tt>1</tt> <tt>-&gt;</tt> <tt>2</tt> <tt>-&gt;</tt> <tt>3</tt>
--   <tt>-&gt;</tt> <tt>1</tt>.
type OddCycle a = [a]

-- | Test the bipartiteness of a given <a>Algebra.Graph.AdjacencyMap</a>.
--   In case of success, return an <a>AdjacencyMap</a> with the same set of
--   edges and each vertex marked with the part it belongs to. In case of
--   failure, return any cycle of odd length in the graph.
--   
--   The returned partition is lexicographically smallest, assuming that
--   vertices of the left part precede all the vertices of the right part.
--   
--   The returned cycle is optimal in the following sense: there exists a
--   path that is either empty or ends in a vertex adjacent to the first
--   vertex in the cycle, such that all vertices in <tt>path</tt>
--   <tt>++</tt> <tt>cycle</tt> are distinct and <tt>path</tt> <tt>++</tt>
--   <tt>cycle</tt> is lexicographically smallest among all such pairs of
--   paths and cycles.
--   
--   <i>Note</i>: since <a>AdjacencyMap</a> represents <i>undirected</i>
--   bipartite graphs, all edges in the input graph are treated as
--   undirected. See the examples and the correctness property for a
--   clarification.
--   
--   Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n + m)</i>
--   memory.
--   
--   <pre>
--   detectParts <a>empty</a>                                       == Right <a>empty</a>
--   detectParts (<a>vertex</a> x)                                  == Right (<a>leftVertex</a> x)
--   detectParts (<a>edge</a> x x)                                  == Left [x]
--   detectParts (<a>edge</a> 1 2)                                  == Right (<a>edge</a> 1 2)
--   detectParts (1 * (2 + 3))                               == Right (<a>edges</a> [(1,2), (1,3)])
--   detectParts (1 * 2 * 3)                                 == Left [1, 2, 3]
--   detectParts ((1 + 3) * (2 + 4) + 6 * 5)                 == Right (<a>swap</a> (1 + 3) * (2 + 4) + <a>swap</a> 5 * 6)
--   detectParts ((1 * 3 * 4) + 2 * (1 + 2))                 == Left [2]
--   detectParts (<a>clique</a> [1..10])                            == Left [1, 2, 3]
--   detectParts (<a>circuit</a> [1..10])                           == Right (<a>circuit</a> [(x, x + 1) | x &lt;- [1,3,5,7,9]])
--   detectParts (<a>circuit</a> [1..11])                           == Left [1..11]
--   detectParts (<a>biclique</a> [] xs)                            == Right (<a>vertices</a> xs [])
--   detectParts (<a>biclique</a> (<a>map</a> Left (x:xs)) (<a>map</a> Right ys)) == Right (<a>biclique</a> (<a>map</a> Left (x:xs)) (<a>map</a> Right ys))
--   <tt>isRight</tt> (detectParts (<a>star</a> x ys))                       == <a>notElem</a> x ys
--   <tt>isRight</tt> (detectParts (<a>fromBipartite</a> (<a>toBipartite</a> x)))   == True
--   </pre>
--   
--   The correctness of <a>detectParts</a> can be expressed by the
--   following property:
--   
--   <pre>
--   let undirected = <a>symmetricClosure</a> input in
--   case detectParts input of
--       Left cycle -&gt; <a>mod</a> (length cycle) 2 == 1 &amp;&amp; <a>isSubgraphOf</a> (<a>circuit</a> cycle) undirected
--       Right result -&gt; <a>gmap</a> <a>fromEither</a> (<a>fromBipartite</a> result) == undirected
--   </pre>
detectParts :: Ord a => AdjacencyMap a -> Either (OddCycle a) (AdjacencyMap a a)

-- | A <i>matching</i> is a set of pairwise non-adjacent edges between the
--   two parts of a bipartite graph.
--   
--   The <a>Show</a> instance is defined using the <a>matching</a>
--   function, with the edges listed in the ascending order of left
--   vertices.
--   
--   <pre>
--   show (<a>matching</a> [])                 == "matching []"
--   show (<a>matching</a> [(2,'a'), (1,'b')]) == "matching [(1,'b'),(2,'a')]"
--   </pre>
data Matching a b

-- | The map of vertices covered by the matching in the left part to their
--   neighbours in the right part. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   pairOfLeft (<a>matching</a> [])                 == Map.<a>empty</a>
--   pairOfLeft (<a>matching</a> [(2,'a'), (1,'b')]) == Map.<a>fromList</a> [(1,'b'), (2,'a')]
--   Map.<a>size</a> . pairOfLeft                    == Map.<a>size</a> . pairOfRight
--   </pre>
pairOfLeft :: Matching a b -> Map a b

-- | The map of vertices covered by the matching in the right part to their
--   neighbours in the left part. Complexity: <i>O(1)</i>.
--   
--   <pre>
--   pairOfRight (<a>matching</a> [])                 == Map.<a>empty</a>
--   pairOfRight (<a>matching</a> [(2,'a'), (1,'b')]) == Map.<a>fromList</a> [('a',2), ('b',1)]
--   Map.<a>size</a> . pairOfRight                    == Map.<a>size</a> . pairOfLeft
--   </pre>
pairOfRight :: Matching a b -> Map b a

-- | Construct a <a>Matching</a> from a list of edges. Complexity: <i>O(L *
--   log(L))</i> time, where <i>L</i> is the length of the given list.
--   
--   Edges that appear closer to the end of the list supersede all previous
--   edges. That is, if two edges from the list share a vertex, the one
--   that appears closer to the beginning is ignored.
--   
--   <pre>
--   <a>pairOfLeft</a>  (matching [])                     == Map.<a>empty</a>
--   <a>pairOfRight</a> (matching [])                     == Map.<a>empty</a>
--   <a>pairOfLeft</a>  (matching [(2,'a'), (1,'b')])     == Map.<a>fromList</a> [(2,'a'), (1,'b')]
--   <a>pairOfLeft</a>  (matching [(1,'a'), (1,'b')])     == Map.<a>singleton</a> 1 'b'
--   matching [(1,'a'), (1,'b'), (2,'b'), (2,'a')] == matching [(2,'a')]
--   </pre>
matching :: (Ord a, Ord b) => [(a, b)] -> Matching a b

-- | Check if a given <a>Matching</a> is a valid <i>matching</i> of a
--   bipartite graph. Complexity: <i>O(S * log(n))</i>, where <i>S</i> is
--   the size of the matching.
--   
--   <pre>
--   isMatchingOf (<a>matching</a> []) x               == True
--   isMatchingOf (<a>matching</a> xs) <a>empty</a>           == <a>null</a> xs
--   isMatchingOf (<a>matching</a> [(x,y)]) (<a>edge</a> x y) == True
--   isMatchingOf (<a>matching</a> [(1,2)]) (<a>edge</a> 2 1) == False
--   </pre>
isMatchingOf :: (Ord a, Ord b) => Matching a b -> AdjacencyMap a b -> Bool

-- | The number of edges in a matching. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   matchingSize (<a>matching</a> [])                 == 0
--   matchingSize (<a>matching</a> [(2,'a'), (1,'b')]) == 2
--   matchingSize (<a>matching</a> [(1,'a'), (1,'b')]) == 1
--   matchingSize (<a>matching</a> xs)                 &lt;= <a>length</a> xs
--   matchingSize                               == Map.<a>size</a> . <a>pairOfLeft</a>
--   </pre>
matchingSize :: Matching a b -> Int

-- | Find a <i>maximum matching</i> in a bipartite graph. A matching is
--   maximum if it has the largest possible size. Complexity: <i>O(m *
--   sqrt(n) * log(n))</i> time.
--   
--   <pre>
--   maxMatching <a>empty</a>                                          == <a>matching</a> []
--   maxMatching (<a>vertices</a> xs ys)                               == <a>matching</a> []
--   maxMatching (<a>path</a> [1,2,3,4])                               == <a>matching</a> [(1,2), (3,4)]
--   <a>matchingSize</a> (maxMatching (<a>circuit</a> [(1,2), (3,4), (5,6)])) == 3
--   <a>matchingSize</a> (maxMatching (<a>star</a> x (y:ys)))                 == 1
--   <a>matchingSize</a> (maxMatching (<a>biclique</a> xs ys))                == <a>min</a> (<a>length</a> (<a>nub</a> xs)) (<a>length</a> (<a>nub</a> ys))
--   <a>isMatchingOf</a> (maxMatching x) x                             == True
--   </pre>
maxMatching :: (Ord a, Ord b) => AdjacencyMap a b -> Matching a b

-- | A <i>vertex cover</i> of a bipartite graph.
--   
--   A <i>vertex cover</i> is a subset of vertices such that every edge is
--   incident to some vertex in the subset. We represent vertex covers by
--   storing two sets of vertices, one for each part. An equivalent
--   representation, which is slightly less memory efficient, is
--   <tt>Set</tt> <tt>(Either</tt> <tt>a</tt> <tt>b)</tt>.
type VertexCover a b = (Set a, Set b)

-- | Check if a given pair of sets is a <i>vertex cover</i> of a bipartite
--   graph. Complexity: <i>O(m * log(n))</i>.
--   
--   <pre>
--   isVertexCoverOf (xs             , ys             ) <a>empty</a>          == Set.<a>null</a> xs &amp;&amp; Set.<a>null</a> ys
--   isVertexCoverOf (xs             , ys             ) (<a>leftVertex</a> x) == Set.<a>isSubsetOf</a> xs (Set.<a>singleton</a> x) &amp;&amp; Set.<a>null</a> ys
--   isVertexCoverOf (Set.<a>empty</a>      , Set.<a>empty</a>      ) (<a>edge</a> x y)     == False
--   isVertexCoverOf (Set.<a>singleton</a> x, ys             ) (<a>edge</a> x y)     == Set.<a>isSubsetOf</a> ys (Set.<a>singleton</a> y)
--   isVertexCoverOf (xs             , Set.<a>singleton</a> y) (<a>edge</a> x y)     == Set.<a>isSubsetOf</a> xs (Set.<a>singleton</a> x)
--   </pre>
isVertexCoverOf :: (Ord a, Ord b) => (Set a, Set b) -> AdjacencyMap a b -> Bool

-- | The number of vertices in a vertex cover. Complexity: <i>O(1)</i>
--   time.
vertexCoverSize :: VertexCover a b -> Int

-- | Find a <i>minimum vertex cover</i> in a bipartite graph. A vertex
--   cover is minimum if it has the smallest possible size. Complexity:
--   <i>O(m * sqrt(n) * log(n))</i>.
--   
--   <pre>
--   minVertexCover <a>empty</a>                              == (Set.<a>empty</a>, Set.<a>empty</a>)
--   minVertexCover (<a>vertices</a> xs ys)                   == (Set.<a>empty</a>, Set.<a>empty</a>)
--   minVertexCover (<a>path</a> [1,2,3])                     == (Set.<a>empty</a>, Set.<a>singleton</a> 2)
--   minVertexCover (<a>star</a> x (1:2:ys))                  == (Set.<a>singleton</a> x, Set.<a>empty</a>)
--   <a>vertexCoverSize</a> (minVertexCover (<a>biclique</a> xs ys)) == <a>min</a> (<a>length</a> (<a>nub</a> xs)) (<a>length</a> (<a>nub</a> ys))
--   <a>vertexCoverSize</a> . minVertexCover                  == <a>matchingSize</a> . <a>maxMatching</a>
--   <a>isVertexCoverOf</a> (minVertexCover x) x              == True
--   </pre>
minVertexCover :: (Ord a, Ord b) => AdjacencyMap a b -> VertexCover a b

-- | An <i>independent set</i> of a bipartite graph.
--   
--   An <i>independent set</i> is a subset of vertices such that no two of
--   them are adjacent. We represent independent sets by storing two sets
--   of vertices, one for each part. An equivalent representation, which is
--   slightly less memory efficient, is <tt>Set</tt> <tt>(Either</tt>
--   <tt>a</tt> <tt>b)</tt>.
type IndependentSet a b = (Set a, Set b)

-- | Check if a given pair of sets is an <i>independent set</i> of a
--   bipartite graph. Complexity: <i>O(m * log(n))</i>.
--   
--   <pre>
--   isIndependentSetOf (xs             , ys             ) <a>empty</a>          == Set.<a>null</a> xs &amp;&amp; Set.<a>null</a> ys
--   isIndependentSetOf (xs             , ys             ) (<a>leftVertex</a> x) == Set.<a>isSubsetOf</a> xs (Set.<a>singleton</a> x) &amp;&amp; Set.<a>null</a> ys
--   isIndependentSetOf (Set.<a>empty</a>      , Set.<a>empty</a>      ) (<a>edge</a> x y)     == True
--   isIndependentSetOf (Set.<a>singleton</a> x, ys             ) (<a>edge</a> x y)     == Set.<a>null</a> ys
--   isIndependentSetOf (xs             , Set.<a>singleton</a> y) (<a>edge</a> x y)     == Set.<a>null</a> xs
--   </pre>
isIndependentSetOf :: (Ord a, Ord b) => (Set a, Set b) -> AdjacencyMap a b -> Bool

-- | The number of vertices in an independent set. Complexity: <i>O(1)</i>
--   time.
independentSetSize :: IndependentSet a b -> Int

-- | Find a <i>maximum independent set</i> in a bipartite graph. An
--   independent set is maximum if it has the largest possible size.
--   Complexity: <i>O(m * sqrt(n) * log(n))</i>.
--   
--   <pre>
--   maxIndependentSet <a>empty</a>                                 == (Set.<a>empty</a>, Set.<a>empty</a>)
--   maxIndependentSet (<a>vertices</a> xs ys)                      == (Set.<a>fromList</a> xs, Set.<a>fromList</a> ys)
--   maxIndependentSet (<a>path</a> [1,2,3])                        == (Set.<a>fromList</a> [1,3], Set.<a>empty</a>)
--   maxIndependentSet (<a>star</a> x (1:2:ys))                     == (Set.<a>empty</a>, Set.<a>fromList</a> (1:2:ys))
--   <a>independentSetSize</a> (maxIndependentSet (<a>biclique</a> xs ys)) == <a>max</a> (<a>length</a> (<a>nub</a> xs)) (<a>length</a> (<a>nub</a> ys))
--   <a>independentSetSize</a> (maxIndependentSet x)                == <a>vertexCount</a> x - <a>vertexCoverSize</a> (<a>minVertexCover</a> x)
--   <a>isIndependentSetOf</a> (maxIndependentSet x) x              == True
--   </pre>
maxIndependentSet :: (Ord a, Ord b) => AdjacencyMap a b -> IndependentSet a b

-- | Given a matching in a bipartite graph, find either a <i>vertex
--   cover</i> of the same size or an <i>augmenting path</i> with respect
--   to the matching, thereby demonstrating that the matching is not
--   maximum. Complexity: <i>O((m + n) * log(n))</i>.
--   
--   An <i>alternating path</i> is a path whose edges belong alternately to
--   the matching and not to the matching. An <i>augmenting path</i> is an
--   alternating path that starts from and ends on the vertices that are
--   not covered by the matching. A matching is maximum if and only if
--   there is no augmenting path with respect to it.
--   
--   <pre>
--   augmentingPath (<a>matching</a> [])      <a>empty</a>            == Left (Set.<a>empty</a>, Set.<a>empty</a>)
--   augmentingPath (<a>matching</a> [])      (<a>edge</a> 1 2)       == Right [1,2]
--   augmentingPath (<a>matching</a> [(1,2)]) (<a>path</a> [1,2,3])   == Left (Set.<a>empty</a>, Set.<a>singleton</a> 2)
--   augmentingPath (<a>matching</a> [(3,2)]) (<a>path</a> [1,2,3,4]) == Right [1,2,3,4]
--   isLeft (augmentingPath (<a>maxMatching</a> x) x)          == True
--   </pre>
augmentingPath :: (Ord a, Ord b) => Matching a b -> AdjacencyMap a b -> Either (VertexCover a b) (List a b)

-- | Check if the internal representation of a matching is consistent, i.e.
--   that every edge that is present in <a>pairOfLeft</a> is also present
--   in <a>pairOfRight</a>. Complexity: <i>O(S * log(S))</i>, where
--   <i>S</i> is the size of the matching.
--   
--   <pre>
--   consistentMatching (<a>matching</a> xs)   == True
--   consistentMatching (<a>maxMatching</a> x) == True
--   </pre>
consistentMatching :: (Ord a, Ord b) => Matching a b -> Bool
instance GHC.Classes.Eq Algebra.Graph.Bipartite.AdjacencyMap.Algorithm.Part
instance GHC.Show.Show Algebra.Graph.Bipartite.AdjacencyMap.Algorithm.Part
instance GHC.Generics.Generic (Algebra.Graph.Bipartite.AdjacencyMap.Algorithm.Matching a b)
instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Algebra.Graph.Bipartite.AdjacencyMap.Algorithm.Matching a b)
instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Algebra.Graph.Bipartite.AdjacencyMap.Algorithm.Matching a b)
instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Algebra.Graph.Bipartite.AdjacencyMap.Algorithm.Matching a b)


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module provides basic data types and type classes for
--   representing edge labels in edge-labelled graphs, e.g. see
--   <a>Algebra.Graph.Labelled</a>.
module Algebra.Graph.Label

-- | A <i>semiring</i> extends a commutative <a>Monoid</a> with operation
--   <a>&lt;.&gt;</a> that acts similarly to multiplication over the
--   underlying (additive) monoid and has <a>one</a> as the identity. This
--   module also provides two convenient aliases: <a>zero</a> for
--   <a>mempty</a>, and <a>&lt;+&gt;</a> for <a>&lt;&gt;</a>, which makes
--   the interface more uniform.
--   
--   Instances of this type class must satisfy the following semiring laws:
--   
--   <ul>
--   <li>Associativity of <a>&lt;+&gt;</a> and <a>&lt;.&gt;</a>:<pre>x
--   &lt;+&gt; (y &lt;+&gt; z) == (x &lt;+&gt; y) &lt;+&gt; z x &lt;.&gt;
--   (y &lt;.&gt; z) == (x &lt;.&gt; y) &lt;.&gt; z</pre></li>
--   <li>Identities of <a>&lt;+&gt;</a> and <a>&lt;.&gt;</a>:<pre>zero
--   &lt;+&gt; x == x == x &lt;+&gt; zero one &lt;.&gt; x == x == x
--   &lt;.&gt; one</pre></li>
--   <li>Commutativity of <a>&lt;+&gt;</a>:<pre>x &lt;+&gt; y == y
--   &lt;+&gt; x</pre></li>
--   <li>Annihilating <a>zero</a>:<pre>x &lt;.&gt; zero == zero zero
--   &lt;.&gt; x == zero</pre></li>
--   <li>Distributivity:<pre>x &lt;.&gt; (y &lt;+&gt; z) == x &lt;.&gt; y
--   &lt;+&gt; x &lt;.&gt; z (x &lt;+&gt; y) &lt;.&gt; z == x &lt;.&gt; z
--   &lt;+&gt; y &lt;.&gt; z</pre></li>
--   </ul>
class (Monoid a, Semigroup a) => Semiring a
one :: Semiring a => a
(<.>) :: Semiring a => a -> a -> a
infixr 7 <.>

-- | An alias for <a>mempty</a>.
zero :: Monoid a => a

-- | An alias for <a>&lt;&gt;</a>.
(<+>) :: Semigroup a => a -> a -> a
infixr 6 <+>

-- | A <i>star semiring</i> is a <a>Semiring</a> with an additional unary
--   operator <a>star</a> satisfying the following two laws:
--   
--   <pre>
--   star a = one &lt;+&gt; a &lt;.&gt; star a
--   star a = one &lt;+&gt; star a &lt;.&gt; a
--   </pre>
class Semiring a => StarSemiring a
star :: StarSemiring a => a -> a

-- | A <i>dioid</i> is an <i>idempotent semiring</i>, i.e. it satisfies the
--   following <i>idempotence</i> law in addition to the <a>Semiring</a>
--   laws:
--   
--   <pre>
--   x &lt;+&gt; x == x
--   </pre>
class Semiring a => Dioid a

-- | A non-negative value that can be <a>finite</a> or <a>infinite</a>.
--   Note: the current implementation of the <a>Num</a> instance raises an
--   error on negative literals and on the <a>negate</a> method.
data NonNegative a

-- | A finite non-negative value or <tt>Nothing</tt> if the argument is
--   negative.
finite :: (Num a, Ord a) => a -> Maybe (NonNegative a)

-- | A finite <a>Word</a>.
finiteWord :: Word -> NonNegative Word

-- | A non-negative finite value, created <i>unsafely</i>: the argument is
--   not checked for being non-negative, so <tt>unsafeFinite (-1)</tt>
--   compiles just fine.
unsafeFinite :: a -> NonNegative a

-- | The (non-negative) infinite value.
infinite :: NonNegative a

-- | Get a finite value or <tt>Nothing</tt> if the value is infinite.
getFinite :: NonNegative a -> Maybe a

-- | A <i>distance</i> is a non-negative value that can be <a>finite</a> or
--   <a>infinite</a>. Distances form a <a>Dioid</a> as follows:
--   
--   <pre>
--   <a>zero</a>  = <a>distance</a> <a>infinite</a>
--   <a>one</a>   = 0
--   (<a>&lt;+&gt;</a>) = <a>min</a>
--   (<a>&lt;.&gt;</a>) = (<a>+</a>)
--   </pre>
data Distance a

-- | A non-negative distance.
distance :: NonNegative a -> Distance a

-- | Get the value of a distance.
getDistance :: Distance a -> NonNegative a

-- | A <i>capacity</i> is a non-negative value that can be <a>finite</a> or
--   <a>infinite</a>. Capacities form a <a>Dioid</a> as follows:
--   
--   <pre>
--   <a>zero</a>  = 0
--   <a>one</a>   = <a>capacity</a> <a>infinite</a>
--   (<a>&lt;+&gt;</a>) = <a>max</a>
--   (<a>&lt;.&gt;</a>) = <a>min</a>
--   </pre>
data Capacity a

-- | A non-negative capacity.
capacity :: NonNegative a -> Capacity a

-- | Get the value of a capacity.
getCapacity :: Capacity a -> NonNegative a

-- | A <i>count</i> is a non-negative value that can be <a>finite</a> or
--   <a>infinite</a>. Counts form a <a>Semiring</a> as follows:
--   
--   <pre>
--   <a>zero</a>  = 0
--   <a>one</a>   = 1
--   (<a>&lt;+&gt;</a>) = (<a>+</a>)
--   (<a>&lt;.&gt;</a>) = (<a>*</a>)
--   </pre>
data Count a

-- | A non-negative count.
count :: NonNegative a -> Count a

-- | Get the value of a count.
getCount :: Count a -> NonNegative a

-- | The <i>power set</i> over the underlying set of elements <tt>a</tt>.
--   If <tt>a</tt> is a monoid, then the power set forms a <a>Dioid</a> as
--   follows:
--   
--   <pre>
--   <a>zero</a>    = PowerSet Set.<a>empty</a>
--   <a>one</a>     = PowerSet $ Set.<a>singleton</a> <a>mempty</a>
--   x <a>&lt;+&gt;</a> y = PowerSet $ Set.<a>union</a> (getPowerSet x) (getPowerSet y)
--   x <a>&lt;.&gt;</a> y = PowerSet $ <a>cartesianProductWith</a> <a>mappend</a> (getPowerSet x) (getPowerSet y)
--   </pre>
newtype PowerSet a
PowerSet :: Set a -> PowerSet a
[getPowerSet] :: PowerSet a -> Set a

-- | If <tt>a</tt> is a monoid, <a>Minimum</a> <tt>a</tt> forms the
--   following <a>Dioid</a>:
--   
--   <pre>
--   <a>zero</a>  = <a>noMinimum</a>
--   <a>one</a>   = <a>pure</a> <a>mempty</a>
--   (<a>&lt;+&gt;</a>) = <a>liftA2</a> <a>min</a>
--   (<a>&lt;.&gt;</a>) = <a>liftA2</a> <a>mappend</a>
--   </pre>
--   
--   To create a singleton value of type <a>Minimum</a> <tt>a</tt> use the
--   <a>pure</a> function. For example:
--   
--   <pre>
--   getMinimum (<a>pure</a> "Hello, " <a>&lt;+&gt;</a> <a>pure</a> "World!") == Just "Hello, "
--   getMinimum (<a>pure</a> "Hello, " <a>&lt;.&gt;</a> <a>pure</a> "World!") == Just "Hello, World!"
--   </pre>
data Minimum a

-- | Extract the minimum or <tt>Nothing</tt> if it does not exist.
getMinimum :: Minimum a -> Maybe a

-- | The value corresponding to the lack of minimum, e.g. the minimum of
--   the empty set.
noMinimum :: Minimum a

-- | A <i>path</i> is a list of edges.
type Path a = [(a, a)]

-- | The type of <i>free labels</i> over the underlying set of symbols
--   <tt>a</tt>. This data type is an instance of classes
--   <a>StarSemiring</a> and <a>Dioid</a>.
data Label a

-- | Check if a <a>Label</a> is <a>zero</a>.
isZero :: Label a -> Bool

-- | A type synonym for <i>regular expressions</i>, built on top of <i>free
--   labels</i>.
type RegularExpression a = Label a

-- | An <i>optimum semiring</i> obtained by combining a semiring <tt>o</tt>
--   that defines an <i>optimisation criterion</i>, and a semiring
--   <tt>a</tt> that describes the <i>arguments</i> of an optimisation
--   problem. For example, by choosing <tt>o = <a>Distance</a> Int</tt> and
--   and <tt>a = <a>Minimum</a> (<a>Path</a> String)</tt>, we obtain the
--   <i>shortest path semiring</i> for computing the shortest path in an
--   <tt>Int</tt>-labelled graph with <tt>String</tt> vertices.
--   
--   We assume that the semiring <tt>o</tt> is <i>selective</i> i.e. for
--   all <tt>x</tt> and <tt>y</tt>:
--   
--   <pre>
--   x &lt;+&gt; y == x || x &lt;+&gt; y == y
--   </pre>
--   
--   In words, the operation <a>&lt;+&gt;</a> always simply selects one of
--   its arguments. For example, the <a>Capacity</a> and <a>Distance</a>
--   semirings are selective, whereas the the <a>Count</a> semiring is not.
data Optimum o a
Optimum :: o -> a -> Optimum o a
[getOptimum] :: Optimum o a -> o
[getArgument] :: Optimum o a -> a

-- | The <a>Optimum</a> semiring specialised to <i>finding the
--   lexicographically smallest shortest path</i>.
type ShortestPath e a = Optimum (Distance e) (Minimum (Path a))

-- | The <a>Optimum</a> semiring specialised to <i>finding all shortest
--   paths</i>.
type AllShortestPaths e a = Optimum (Distance e) (PowerSet (Path a))

-- | The <a>Optimum</a> semiring specialised to <i>counting all shortest
--   paths</i>.
type CountShortestPaths e = Optimum (Distance e) (Count Integer)

-- | The <a>Optimum</a> semiring specialised to <i>finding the
--   lexicographically smallest widest path</i>.
type WidestPath e a = Optimum (Capacity e) (Minimum (Path a))
instance GHC.Show.Show a => GHC.Show.Show (Algebra.Graph.Label.Extended a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.Label.Extended a)
instance GHC.Base.Functor Algebra.Graph.Label.Extended
instance GHC.Classes.Eq a => GHC.Classes.Eq (Algebra.Graph.Label.Extended a)
instance GHC.Base.Monad Algebra.Graph.Label.NonNegative
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.Label.NonNegative a)
instance GHC.Base.Functor Algebra.Graph.Label.NonNegative
instance GHC.Classes.Eq a => GHC.Classes.Eq (Algebra.Graph.Label.NonNegative a)
instance GHC.Base.Applicative Algebra.Graph.Label.NonNegative
instance GHC.Classes.Ord a => GHC.Base.Semigroup (Algebra.Graph.Label.Distance a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.Label.Distance a)
instance (GHC.Num.Num a, GHC.Classes.Ord a) => GHC.Num.Num (Algebra.Graph.Label.Distance a)
instance (GHC.Classes.Ord a, GHC.Num.Num a) => GHC.Base.Monoid (Algebra.Graph.Label.Distance a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Algebra.Graph.Label.Distance a)
instance GHC.Num.Num a => GHC.Enum.Bounded (Algebra.Graph.Label.Distance a)
instance (GHC.Num.Num a, GHC.Classes.Ord a) => GHC.Base.Semigroup (Algebra.Graph.Label.Count a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.Label.Count a)
instance (GHC.Num.Num a, GHC.Classes.Ord a) => GHC.Num.Num (Algebra.Graph.Label.Count a)
instance (GHC.Num.Num a, GHC.Classes.Ord a) => GHC.Base.Monoid (Algebra.Graph.Label.Count a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Algebra.Graph.Label.Count a)
instance GHC.Num.Num a => GHC.Enum.Bounded (Algebra.Graph.Label.Count a)
instance GHC.Classes.Ord a => GHC.Base.Semigroup (Algebra.Graph.Label.Capacity a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.Label.Capacity a)
instance (GHC.Num.Num a, GHC.Classes.Ord a) => GHC.Num.Num (Algebra.Graph.Label.Capacity a)
instance (GHC.Classes.Ord a, GHC.Num.Num a) => GHC.Base.Monoid (Algebra.Graph.Label.Capacity a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Algebra.Graph.Label.Capacity a)
instance GHC.Num.Num a => GHC.Enum.Bounded (Algebra.Graph.Label.Capacity a)
instance GHC.Base.Monad Algebra.Graph.Label.Minimum
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.Label.Minimum a)
instance GHC.Base.Functor Algebra.Graph.Label.Minimum
instance GHC.Classes.Eq a => GHC.Classes.Eq (Algebra.Graph.Label.Minimum a)
instance GHC.Base.Applicative Algebra.Graph.Label.Minimum
instance GHC.Show.Show a => GHC.Show.Show (Algebra.Graph.Label.PowerSet a)
instance GHC.Classes.Ord a => GHC.Base.Semigroup (Algebra.Graph.Label.PowerSet a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.Label.PowerSet a)
instance GHC.Classes.Ord a => GHC.Base.Monoid (Algebra.Graph.Label.PowerSet a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Algebra.Graph.Label.PowerSet a)
instance GHC.Base.Functor Algebra.Graph.Label.Label
instance (GHC.Show.Show o, GHC.Show.Show a) => GHC.Show.Show (Algebra.Graph.Label.Optimum o a)
instance (GHC.Classes.Ord o, GHC.Classes.Ord a) => GHC.Classes.Ord (Algebra.Graph.Label.Optimum o a)
instance (GHC.Classes.Eq o, GHC.Classes.Eq a) => GHC.Classes.Eq (Algebra.Graph.Label.Optimum o a)
instance (GHC.Classes.Eq o, GHC.Base.Monoid a, GHC.Base.Monoid o) => GHC.Base.Semigroup (Algebra.Graph.Label.Optimum o a)
instance (GHC.Classes.Eq o, GHC.Base.Monoid a, GHC.Base.Monoid o) => GHC.Base.Monoid (Algebra.Graph.Label.Optimum o a)
instance (GHC.Classes.Eq o, Algebra.Graph.Label.Semiring a, Algebra.Graph.Label.Semiring o) => Algebra.Graph.Label.Semiring (Algebra.Graph.Label.Optimum o a)
instance (GHC.Classes.Eq o, Algebra.Graph.Label.StarSemiring a, Algebra.Graph.Label.StarSemiring o) => Algebra.Graph.Label.StarSemiring (Algebra.Graph.Label.Optimum o a)
instance (GHC.Classes.Eq o, Algebra.Graph.Label.Dioid a, Algebra.Graph.Label.Dioid o) => Algebra.Graph.Label.Dioid (Algebra.Graph.Label.Optimum o a)
instance GHC.Exts.IsList (Algebra.Graph.Label.Label a)
instance GHC.Show.Show a => GHC.Show.Show (Algebra.Graph.Label.Label a)
instance GHC.Base.Semigroup (Algebra.Graph.Label.Label a)
instance GHC.Base.Monoid (Algebra.Graph.Label.Label a)
instance Algebra.Graph.Label.Semiring (Algebra.Graph.Label.Label a)
instance Algebra.Graph.Label.StarSemiring (Algebra.Graph.Label.Label a)
instance (GHC.Base.Monoid a, GHC.Classes.Ord a) => Algebra.Graph.Label.Semiring (Algebra.Graph.Label.PowerSet a)
instance (GHC.Base.Monoid a, GHC.Classes.Ord a) => Algebra.Graph.Label.Dioid (Algebra.Graph.Label.PowerSet a)
instance GHC.Classes.Ord a => GHC.Base.Semigroup (Algebra.Graph.Label.Minimum a)
instance (GHC.Base.Monoid a, GHC.Classes.Ord a) => GHC.Base.Monoid (Algebra.Graph.Label.Minimum a)
instance (GHC.Base.Monoid a, GHC.Classes.Ord a) => Algebra.Graph.Label.Semiring (Algebra.Graph.Label.Minimum a)
instance (GHC.Base.Monoid a, GHC.Classes.Ord a) => Algebra.Graph.Label.Dioid (Algebra.Graph.Label.Minimum a)
instance GHC.Show.Show a => GHC.Show.Show (Algebra.Graph.Label.Minimum a)
instance GHC.Exts.IsList a => GHC.Exts.IsList (Algebra.Graph.Label.Minimum a)
instance GHC.Show.Show a => GHC.Show.Show (Algebra.Graph.Label.Capacity a)
instance (GHC.Num.Num a, GHC.Classes.Ord a) => Algebra.Graph.Label.Semiring (Algebra.Graph.Label.Capacity a)
instance (GHC.Num.Num a, GHC.Classes.Ord a) => Algebra.Graph.Label.StarSemiring (Algebra.Graph.Label.Capacity a)
instance (GHC.Num.Num a, GHC.Classes.Ord a) => Algebra.Graph.Label.Dioid (Algebra.Graph.Label.Capacity a)
instance GHC.Show.Show a => GHC.Show.Show (Algebra.Graph.Label.Count a)
instance (GHC.Num.Num a, GHC.Classes.Ord a) => Algebra.Graph.Label.Semiring (Algebra.Graph.Label.Count a)
instance (GHC.Num.Num a, GHC.Classes.Ord a) => Algebra.Graph.Label.StarSemiring (Algebra.Graph.Label.Count a)
instance GHC.Show.Show a => GHC.Show.Show (Algebra.Graph.Label.Distance a)
instance (GHC.Num.Num a, GHC.Classes.Ord a) => Algebra.Graph.Label.Semiring (Algebra.Graph.Label.Distance a)
instance (GHC.Num.Num a, GHC.Classes.Ord a) => Algebra.Graph.Label.StarSemiring (Algebra.Graph.Label.Distance a)
instance (GHC.Num.Num a, GHC.Classes.Ord a) => Algebra.Graph.Label.Dioid (Algebra.Graph.Label.Distance a)
instance (GHC.Num.Num a, GHC.Show.Show a) => GHC.Show.Show (Algebra.Graph.Label.NonNegative a)
instance GHC.Num.Num a => GHC.Enum.Bounded (Algebra.Graph.Label.NonNegative a)
instance (GHC.Num.Num a, GHC.Classes.Ord a) => GHC.Num.Num (Algebra.Graph.Label.NonNegative a)
instance GHC.Base.Applicative Algebra.Graph.Label.Extended
instance GHC.Base.Monad Algebra.Graph.Label.Extended
instance (GHC.Num.Num a, GHC.Classes.Eq a) => GHC.Num.Num (Algebra.Graph.Label.Extended a)
instance Algebra.Graph.Label.Dioid Data.Semigroup.Internal.Any
instance Algebra.Graph.Label.StarSemiring Data.Semigroup.Internal.Any
instance Algebra.Graph.Label.Semiring Data.Semigroup.Internal.Any


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module defines the <a>AdjacencyMap</a> data type for
--   edge-labelled graphs, as well as associated operations and algorithms.
--   <a>AdjacencyMap</a> is an instance of the <a>Graph</a> type class,
--   which can be used for polymorphic graph construction and manipulation.
module Algebra.Graph.Labelled.AdjacencyMap

-- | Edge-labelled graphs, where the type variable <tt>e</tt> stands for
--   edge labels. For example, <a>AdjacencyMap</a> <tt>Bool</tt> <tt>a</tt>
--   is isomorphic to unlabelled graphs defined in the top-level module
--   <a>Algebra.Graph.AdjacencyMap</a>, where <tt>False</tt> and
--   <tt>True</tt> denote the lack of and the existence of an unlabelled
--   edge, respectively.
data AdjacencyMap e a

-- | The <i>adjacency map</i> of an edge-labelled graph: each vertex is
--   associated with a map from its direct successors to the corresponding
--   edge labels.
adjacencyMap :: AdjacencyMap e a -> Map a (Map a e)

-- | Construct the <i>empty graph</i>.
--   
--   <pre>
--   <a>isEmpty</a>     empty == True
--   <a>hasVertex</a> x empty == False
--   <a>vertexCount</a> empty == 0
--   <a>edgeCount</a>   empty == 0
--   </pre>
empty :: AdjacencyMap e a

-- | Construct the graph comprising <i>a single isolated vertex</i>.
--   
--   <pre>
--   <a>isEmpty</a>     (vertex x) == False
--   <a>hasVertex</a> x (vertex y) == (x == y)
--   <a>vertexCount</a> (vertex x) == 1
--   <a>edgeCount</a>   (vertex x) == 0
--   </pre>
vertex :: a -> AdjacencyMap e a

-- | Construct the graph comprising <i>a single edge</i>.
--   
--   <pre>
--   edge e    x y              == <a>connect</a> e (<a>vertex</a> x) (<a>vertex</a> y)
--   edge <a>zero</a> x y              == <a>vertices</a> [x,y]
--   <a>hasEdge</a>   x y (edge e x y) == (e /= <a>zero</a>)
--   <a>edgeLabel</a> x y (edge e x y) == e
--   <a>edgeCount</a>     (edge e x y) == if e == <a>zero</a> then 0 else 1
--   <a>vertexCount</a>   (edge e 1 1) == 1
--   <a>vertexCount</a>   (edge e 1 2) == 2
--   </pre>
edge :: (Eq e, Monoid e, Ord a) => e -> a -> a -> AdjacencyMap e a

-- | The left-hand part of a convenient ternary-ish operator
--   <tt>x-&lt;e&gt;-y</tt> for creating labelled edges.
--   
--   <pre>
--   x -&lt;e&gt;- y == <a>edge</a> e x y
--   </pre>
(-<) :: a -> e -> (a, e)
infixl 5 -<

-- | The right-hand part of a convenient ternary-ish operator
--   <tt>x-&lt;e&gt;-y</tt> for creating labelled edges.
--   
--   <pre>
--   x -&lt;e&gt;- y == <a>edge</a> e x y
--   </pre>
(>-) :: (Eq e, Monoid e, Ord a) => (a, e) -> a -> AdjacencyMap e a
infixl 5 >-

-- | <i>Overlay</i> two graphs. This is a commutative, associative and
--   idempotent operation with the identity <a>empty</a>. Complexity:
--   <i>O((n + m) * log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   <a>isEmpty</a>     (overlay x y) == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (overlay x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (overlay x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (overlay x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (overlay x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (overlay x y) &lt;= <a>edgeCount</a> x   + <a>edgeCount</a> y
--   <a>vertexCount</a> (overlay 1 2) == 2
--   <a>edgeCount</a>   (overlay 1 2) == 0
--   </pre>
--   
--   Note: <a>overlay</a> composes edges in parallel using the operator
--   <a>&lt;+&gt;</a> with <a>zero</a> acting as the identity:
--   
--   <pre>
--   <a>edgeLabel</a> x y $ overlay (<a>edge</a> e x y) (<a>edge</a> <a>zero</a> x y) == e
--   <a>edgeLabel</a> x y $ overlay (<a>edge</a> e x y) (<a>edge</a> f    x y) == e <a>&lt;+&gt;</a> f
--   </pre>
--   
--   Furthermore, when applied to transitive graphs, <a>overlay</a>
--   composes edges in sequence using the operator <a>&lt;.&gt;</a> with
--   <a>one</a> acting as the identity:
--   
--   <pre>
--   <a>edgeLabel</a> x z $ <a>transitiveClosure</a> (overlay (<a>edge</a> e x y) (<a>edge</a> <a>one</a> y z)) == e
--   <a>edgeLabel</a> x z $ <a>transitiveClosure</a> (overlay (<a>edge</a> e x y) (<a>edge</a> f   y z)) == e <a>&lt;.&gt;</a> f
--   </pre>
overlay :: (Eq e, Monoid e, Ord a) => AdjacencyMap e a -> AdjacencyMap e a -> AdjacencyMap e a

-- | <i>Connect</i> two graphs with edges labelled by a given label. When
--   applied to the same labels, this is an associative operation with the
--   identity <a>empty</a>, which distributes over <a>overlay</a> and obeys
--   the decomposition axiom. Complexity: <i>O((n + m) * log(n))</i> time
--   and <i>O(n + m)</i> memory. Note that the number of edges in the
--   resulting graph is quadratic with respect to the number of vertices of
--   the arguments: <i>m = O(m1 + m2 + n1 * n2)</i>.
--   
--   <pre>
--   <a>isEmpty</a>     (connect e x y) == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (connect e x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (connect e x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (connect e x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect e x y) &lt;= <a>vertexCount</a> x * <a>vertexCount</a> y + <a>edgeCount</a> x + <a>edgeCount</a> y
--   <a>vertexCount</a> (connect e 1 2) == 2
--   <a>edgeCount</a>   (connect e 1 2) == if e == <a>zero</a> then 0 else 1
--   </pre>
connect :: (Eq e, Monoid e, Ord a) => e -> AdjacencyMap e a -> AdjacencyMap e a -> AdjacencyMap e a

-- | Construct the graph comprising a given list of isolated vertices.
--   Complexity: <i>O(L * log(L))</i> time and <i>O(L)</i> memory, where
--   <i>L</i> is the length of the given list.
--   
--   <pre>
--   vertices []            == <a>empty</a>
--   vertices [x]           == <a>vertex</a> x
--   vertices               == <a>overlays</a> . map <a>vertex</a>
--   <a>hasVertex</a> x . vertices == <a>elem</a> x
--   <a>vertexCount</a> . vertices == <a>length</a> . <a>nub</a>
--   <a>vertexSet</a>   . vertices == Set.<a>fromList</a>
--   </pre>
vertices :: Ord a => [a] -> AdjacencyMap e a

-- | Construct the graph from a list of edges. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   edges []        == <a>empty</a>
--   edges [(e,x,y)] == <a>edge</a> e x y
--   edges           == <a>overlays</a> . <a>map</a> (\(e, x, y) -&gt; <a>edge</a> e x y)
--   </pre>
edges :: (Eq e, Monoid e, Ord a) => [(e, a, a)] -> AdjacencyMap e a

-- | Overlay a given list of graphs. Complexity: <i>O((n + m) * log(n))</i>
--   time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   overlays []        == <a>empty</a>
--   overlays [x]       == x
--   overlays [x,y]     == <a>overlay</a> x y
--   overlays           == <a>foldr</a> <a>overlay</a> <a>empty</a>
--   <a>isEmpty</a> . overlays == <a>all</a> <a>isEmpty</a>
--   </pre>
overlays :: (Eq e, Monoid e, Ord a) => [AdjacencyMap e a] -> AdjacencyMap e a

-- | Construct a graph from a list of adjacency sets. Complexity: <i>O((n +
--   m) * log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   fromAdjacencyMaps []                                  == <a>empty</a>
--   fromAdjacencyMaps [(x, Map.<a>empty</a>)]                    == <a>vertex</a> x
--   fromAdjacencyMaps [(x, Map.<a>singleton</a> y e)]            == if e == <a>zero</a> then <a>vertices</a> [x,y] else <a>edge</a> e x y
--   <a>overlay</a> (fromAdjacencyMaps xs) (fromAdjacencyMaps ys) == fromAdjacencyMaps (xs <a>++</a> ys)
--   </pre>
fromAdjacencyMaps :: (Eq e, Monoid e, Ord a) => [(a, Map a e)] -> AdjacencyMap e a

-- | The <a>isSubgraphOf</a> function takes two graphs and returns
--   <a>True</a> if the first graph is a <i>subgraph</i> of the second.
--   Complexity: <i>O(s + m * log(m))</i> time. Note that the number of
--   edges <i>m</i> of a graph can be quadratic with respect to the
--   expression size <i>s</i>.
--   
--   <pre>
--   isSubgraphOf <a>empty</a>      x     ==  True
--   isSubgraphOf (<a>vertex</a> x) <a>empty</a> ==  False
--   isSubgraphOf x y              ==&gt; x &lt;= y
--   </pre>
isSubgraphOf :: (Eq e, Monoid e, Ord a) => AdjacencyMap e a -> AdjacencyMap e a -> Bool

-- | Check if a graph is empty. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   isEmpty <a>empty</a>                         == True
--   isEmpty (<a>overlay</a> <a>empty</a> <a>empty</a>)         == True
--   isEmpty (<a>vertex</a> x)                    == False
--   isEmpty (<a>removeVertex</a> x $ <a>vertex</a> x)   == True
--   isEmpty (<a>removeEdge</a> x y $ <a>edge</a> e x y) == False
--   </pre>
isEmpty :: AdjacencyMap e a -> Bool

-- | Check if a graph contains a given vertex. Complexity: <i>O(log(n))</i>
--   time.
--   
--   <pre>
--   hasVertex x <a>empty</a>            == False
--   hasVertex x (<a>vertex</a> y)       == (x == y)
--   hasVertex x . <a>removeVertex</a> x == <a>const</a> False
--   </pre>
hasVertex :: Ord a => a -> AdjacencyMap e a -> Bool

-- | Check if a graph contains a given edge. Complexity: <i>O(log(n))</i>
--   time.
--   
--   <pre>
--   hasEdge x y <a>empty</a>            == False
--   hasEdge x y (<a>vertex</a> z)       == False
--   hasEdge x y (<a>edge</a> e x y)     == (e /= <a>zero</a>)
--   hasEdge x y . <a>removeEdge</a> x y == <a>const</a> False
--   hasEdge x y                  == <a>not</a> . <a>null</a> . <a>filter</a> (\(_,ex,ey) -&gt; ex == x &amp;&amp; ey == y) . <a>edgeList</a>
--   </pre>
hasEdge :: Ord a => a -> a -> AdjacencyMap e a -> Bool

-- | Extract the label of a specified edge in a graph. Complexity:
--   <i>O(log(n))</i> time.
--   
--   <pre>
--   edgeLabel x y <a>empty</a>         == <a>zero</a>
--   edgeLabel x y (<a>vertex</a> z)    == <a>zero</a>
--   edgeLabel x y (<a>edge</a> e x y)  == e
--   edgeLabel s t (<a>overlay</a> x y) == edgeLabel s t x <a>+</a> edgeLabel s t y
--   </pre>
edgeLabel :: (Monoid e, Ord a) => a -> a -> AdjacencyMap e a -> e

-- | The number of vertices in a graph. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   vertexCount <a>empty</a>             ==  0
--   vertexCount (<a>vertex</a> x)        ==  1
--   vertexCount                   ==  <a>length</a> . <a>vertexList</a>
--   vertexCount x &lt; vertexCount y ==&gt; x &lt; y
--   </pre>
vertexCount :: AdjacencyMap e a -> Int

-- | The number of (non-<a>zero</a>) edges in a graph. Complexity:
--   <i>O(n)</i> time.
--   
--   <pre>
--   edgeCount <a>empty</a>        == 0
--   edgeCount (<a>vertex</a> x)   == 0
--   edgeCount (<a>edge</a> e x y) == if e == <a>zero</a> then 0 else 1
--   edgeCount              == <a>length</a> . <a>edgeList</a>
--   </pre>
edgeCount :: AdjacencyMap e a -> Int

-- | The sorted list of vertices of a given graph. Complexity: <i>O(n)</i>
--   time and memory.
--   
--   <pre>
--   vertexList <a>empty</a>      == []
--   vertexList (<a>vertex</a> x) == [x]
--   vertexList . <a>vertices</a> == <a>nub</a> . <a>sort</a>
--   </pre>
vertexList :: AdjacencyMap e a -> [a]

-- | The list of edges of a graph, sorted lexicographically with respect to
--   pairs of connected vertices (i.e. edge-labels are ignored when
--   sorting). Complexity: <i>O(n + m)</i> time and <i>O(m)</i> memory.
--   
--   <pre>
--   edgeList <a>empty</a>        == []
--   edgeList (<a>vertex</a> x)   == []
--   edgeList (<a>edge</a> e x y) == if e == <a>zero</a> then [] else [(e,x,y)]
--   </pre>
edgeList :: AdjacencyMap e a -> [(e, a, a)]

-- | The set of vertices of a given graph. Complexity: <i>O(n)</i> time and
--   memory.
--   
--   <pre>
--   vertexSet <a>empty</a>      == Set.<a>empty</a>
--   vertexSet . <a>vertex</a>   == Set.<a>singleton</a>
--   vertexSet . <a>vertices</a> == Set.<a>fromList</a>
--   </pre>
vertexSet :: AdjacencyMap e a -> Set a

-- | The set of edges of a given graph. Complexity: <i>O(n + m)</i> time
--   and <i>O(m)</i> memory.
--   
--   <pre>
--   edgeSet <a>empty</a>        == Set.<a>empty</a>
--   edgeSet (<a>vertex</a> x)   == Set.<a>empty</a>
--   edgeSet (<a>edge</a> e x y) == if e == <a>zero</a> then Set.<a>empty</a> else Set.<a>singleton</a> (e,x,y)
--   </pre>
edgeSet :: (Eq a, Eq e) => AdjacencyMap e a -> Set (e, a, a)

-- | The <i>preset</i> of an element <tt>x</tt> is the set of its <i>direct
--   predecessors</i>. Complexity: <i>O(n * log(n))</i> time and
--   <i>O(n)</i> memory.
--   
--   <pre>
--   preSet x <a>empty</a>        == Set.<a>empty</a>
--   preSet x (<a>vertex</a> x)   == Set.<a>empty</a>
--   preSet 1 (<a>edge</a> e 1 2) == Set.<a>empty</a>
--   preSet y (<a>edge</a> e x y) == if e == <a>zero</a> then Set.<a>empty</a> else Set.<a>fromList</a> [x]
--   </pre>
preSet :: Ord a => a -> AdjacencyMap e a -> Set a

-- | The <i>postset</i> of a vertex is the set of its <i>direct
--   successors</i>. Complexity: <i>O(log(n))</i> time and <i>O(1)</i>
--   memory.
--   
--   <pre>
--   postSet x <a>empty</a>        == Set.<a>empty</a>
--   postSet x (<a>vertex</a> x)   == Set.<a>empty</a>
--   postSet x (<a>edge</a> e x y) == if e == <a>zero</a> then Set.<a>empty</a> else Set.<a>fromList</a> [y]
--   postSet 2 (<a>edge</a> e 1 2) == Set.<a>empty</a>
--   </pre>
postSet :: Ord a => a -> AdjacencyMap e a -> Set a

-- | Convert a graph to the corresponding unlabelled <a>AdjacencyMap</a> by
--   forgetting labels on all non-<a>zero</a> edges. Complexity: <i>O((n +
--   m) * log(n))</i> time and memory.
--   
--   <pre>
--   <a>hasEdge</a> x y == <a>hasEdge</a> x y . skeleton
--   </pre>
skeleton :: Ord a => AdjacencyMap e a -> AdjacencyMap a

-- | Remove a vertex from a given graph. Complexity: <i>O(n*log(n))</i>
--   time.
--   
--   <pre>
--   removeVertex x (<a>vertex</a> x)       == <a>empty</a>
--   removeVertex 1 (<a>vertex</a> 2)       == <a>vertex</a> 2
--   removeVertex x (<a>edge</a> e x x)     == <a>empty</a>
--   removeVertex 1 (<a>edge</a> e 1 2)     == <a>vertex</a> 2
--   removeVertex x . removeVertex x == removeVertex x
--   </pre>
removeVertex :: Ord a => a -> AdjacencyMap e a -> AdjacencyMap e a

-- | Remove an edge from a given graph. Complexity: <i>O(log(n))</i> time.
--   
--   <pre>
--   removeEdge x y (<a>edge</a> e x y)     == <a>vertices</a> [x,y]
--   removeEdge x y . removeEdge x y == removeEdge x y
--   removeEdge x y . <a>removeVertex</a> x == <a>removeVertex</a> x
--   removeEdge 1 1 (1 * 1 * 2 * 2)  == 1 * 2 * 2
--   removeEdge 1 2 (1 * 1 * 2 * 2)  == 1 * 1 + 2 * 2
--   </pre>
removeEdge :: Ord a => a -> a -> AdjacencyMap e a -> AdjacencyMap e a

-- | The function <tt><a>replaceVertex</a> x y</tt> replaces vertex
--   <tt>x</tt> with vertex <tt>y</tt> in a given <a>AdjacencyMap</a>. If
--   <tt>y</tt> already exists, <tt>x</tt> and <tt>y</tt> will be merged.
--   Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   replaceVertex x x            == id
--   replaceVertex x y (<a>vertex</a> x) == <a>vertex</a> y
--   replaceVertex x y            == <a>gmap</a> (\v -&gt; if v == x then y else v)
--   </pre>
replaceVertex :: (Eq e, Monoid e, Ord a) => a -> a -> AdjacencyMap e a -> AdjacencyMap e a

-- | Replace an edge from a given graph. If it doesn't exist, it will be
--   created. Complexity: <i>O(log(n))</i> time.
--   
--   <pre>
--   replaceEdge e x y z                 == <a>overlay</a> (removeEdge x y z) (<a>edge</a> e x y)
--   replaceEdge e x y (<a>edge</a> f x y)      == <a>edge</a> e x y
--   <a>edgeLabel</a> x y (replaceEdge e x y z) == e
--   </pre>
replaceEdge :: (Eq e, Monoid e, Ord a) => e -> a -> a -> AdjacencyMap e a -> AdjacencyMap e a

-- | Transpose a given graph. Complexity: <i>O(m * log(n))</i> time, <i>O(n
--   + m)</i> memory.
--   
--   <pre>
--   transpose <a>empty</a>        == <a>empty</a>
--   transpose (<a>vertex</a> x)   == <a>vertex</a> x
--   transpose (<a>edge</a> e x y) == <a>edge</a> e y x
--   transpose . transpose  == id
--   </pre>
transpose :: (Monoid e, Ord a) => AdjacencyMap e a -> AdjacencyMap e a

-- | Transform a graph by applying a function to each of its vertices. This
--   is similar to <tt>Functor</tt>'s <a>fmap</a> but can be used with
--   non-fully-parametric <a>AdjacencyMap</a>. Complexity: <i>O((n + m) *
--   log(n))</i> time.
--   
--   <pre>
--   gmap f <a>empty</a>        == <a>empty</a>
--   gmap f (<a>vertex</a> x)   == <a>vertex</a> (f x)
--   gmap f (<a>edge</a> e x y) == <a>edge</a> e (f x) (f y)
--   gmap <a>id</a>             == <a>id</a>
--   gmap f . gmap g     == gmap (f . g)
--   </pre>
gmap :: (Eq e, Monoid e, Ord a, Ord b) => (a -> b) -> AdjacencyMap e a -> AdjacencyMap e b

-- | Transform a graph by applying a function <tt>h</tt> to each of its
--   edge labels. Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   The function <tt>h</tt> is required to be a <i>homomorphism</i> on the
--   underlying type of labels <tt>e</tt>. At the very least it must
--   preserve <a>zero</a> and <a>&lt;+&gt;</a>:
--   
--   <pre>
--   h <a>zero</a>      == <a>zero</a>
--   h x <a>&lt;+&gt;</a> h y == h (x <a>&lt;+&gt;</a> y)
--   </pre>
--   
--   If <tt>e</tt> is also a semiring, then <tt>h</tt> must also preserve
--   the multiplicative structure:
--   
--   <pre>
--   h <a>one</a>       == <a>one</a>
--   h x <a>&lt;.&gt;</a> h y == h (x <a>&lt;.&gt;</a> y)
--   </pre>
--   
--   If the above requirements hold, then the implementation provides the
--   following guarantees.
--   
--   <pre>
--   emap h <a>empty</a>           == <a>empty</a>
--   emap h (<a>vertex</a> x)      == <a>vertex</a> x
--   emap h (<a>edge</a> e x y)    == <a>edge</a> (h e) x y
--   emap h (<a>overlay</a> x y)   == <a>overlay</a> (emap h x) (emap h y)
--   emap h (<a>connect</a> e x y) == <a>connect</a> (h e) (emap h x) (emap h y)
--   emap <a>id</a>                == <a>id</a>
--   emap g . emap h        == emap (g . h)
--   </pre>
emap :: (Eq f, Monoid f) => (e -> f) -> AdjacencyMap e a -> AdjacencyMap f a

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that do not satisfy a given predicate. Complexity: <i>O(n +
--   m)</i> time, assuming that the predicate takes constant time.
--   
--   <pre>
--   induce (<a>const</a> True ) x      == x
--   induce (<a>const</a> False) x      == <a>empty</a>
--   induce (/= x)               == <a>removeVertex</a> x
--   induce p . induce q         == induce (\x -&gt; p x &amp;&amp; q x)
--   <a>isSubgraphOf</a> (induce p x) x == True
--   </pre>
induce :: (a -> Bool) -> AdjacencyMap e a -> AdjacencyMap e a

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that are <a>Nothing</a>. Complexity: <i>O(n + m)</i> time.
--   
--   <pre>
--   induceJust (<a>vertex</a> <a>Nothing</a>)                               == <a>empty</a>
--   induceJust (<a>edge</a> (<a>Just</a> x) <a>Nothing</a>)                        == <a>vertex</a> x
--   induceJust . <a>gmap</a> <a>Just</a>                                    == <a>id</a>
--   induceJust . <a>gmap</a> (\x -&gt; if p x then <a>Just</a> x else <a>Nothing</a>) == <a>induce</a> p
--   </pre>
induceJust :: Ord a => AdjacencyMap e (Maybe a) -> AdjacencyMap e a

-- | Compute the <i>reflexive and transitive closure</i> of a graph over
--   the underlying star semiring using the Warshall-Floyd-Kleene
--   algorithm.
--   
--   <pre>
--   closure <a>empty</a>         == <a>empty</a>
--   closure (<a>vertex</a> x)    == <a>edge</a> <a>one</a> x x
--   closure (<a>edge</a> e x x)  == <a>edge</a> <a>one</a> x x
--   closure (<a>edge</a> e x y)  == <a>edges</a> [(<a>one</a>,x,x), (e,x,y), (<a>one</a>,y,y)]
--   closure               == <a>reflexiveClosure</a> . <a>transitiveClosure</a>
--   closure               == <a>transitiveClosure</a> . <a>reflexiveClosure</a>
--   closure . closure     == closure
--   <a>postSet</a> x (closure y) == Set.<a>fromList</a> (<a>reachable</a> x y)
--   </pre>
closure :: (Eq e, Ord a, StarSemiring e) => AdjacencyMap e a -> AdjacencyMap e a

-- | Compute the <i>reflexive closure</i> of a graph over the underlying
--   semiring by adding a self-loop of weight <a>one</a> to every vertex.
--   Complexity: <i>O(n * log(n))</i> time.
--   
--   <pre>
--   reflexiveClosure <a>empty</a>              == <a>empty</a>
--   reflexiveClosure (<a>vertex</a> x)         == <a>edge</a> <a>one</a> x x
--   reflexiveClosure (<a>edge</a> e x x)       == <a>edge</a> <a>one</a> x x
--   reflexiveClosure (<a>edge</a> e x y)       == <a>edges</a> [(<a>one</a>,x,x), (e,x,y), (<a>one</a>,y,y)]
--   reflexiveClosure . reflexiveClosure == reflexiveClosure
--   </pre>
reflexiveClosure :: (Ord a, Semiring e) => AdjacencyMap e a -> AdjacencyMap e a

-- | Compute the <i>symmetric closure</i> of a graph by overlaying it with
--   its own transpose. Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   symmetricClosure <a>empty</a>              == <a>empty</a>
--   symmetricClosure (<a>vertex</a> x)         == <a>vertex</a> x
--   symmetricClosure (<a>edge</a> e x y)       == <a>edges</a> [(e,x,y), (e,y,x)]
--   symmetricClosure x                  == <a>overlay</a> x (<a>transpose</a> x)
--   symmetricClosure . symmetricClosure == symmetricClosure
--   </pre>
symmetricClosure :: (Eq e, Monoid e, Ord a) => AdjacencyMap e a -> AdjacencyMap e a

-- | Compute the <i>transitive closure</i> of a graph over the underlying
--   star semiring using a modified version of the Warshall-Floyd-Kleene
--   algorithm, which omits the reflexivity step.
--   
--   <pre>
--   transitiveClosure <a>empty</a>               == <a>empty</a>
--   transitiveClosure (<a>vertex</a> x)          == <a>vertex</a> x
--   transitiveClosure (<a>edge</a> e x y)        == <a>edge</a> e x y
--   transitiveClosure . transitiveClosure == transitiveClosure
--   </pre>
transitiveClosure :: (Eq e, Ord a, StarSemiring e) => AdjacencyMap e a -> AdjacencyMap e a

-- | Check that the internal graph representation is consistent, i.e. that
--   all edges refer to existing vertices, and there are no
--   <a>zero</a>-labelled edges. It should be impossible to create an
--   inconsistent adjacency map, and we use this function in testing.
consistent :: (Ord a, Eq e, Monoid e) => AdjacencyMap e a -> Bool
instance (Control.DeepSeq.NFData a, Control.DeepSeq.NFData e) => Control.DeepSeq.NFData (Algebra.Graph.Labelled.AdjacencyMap.AdjacencyMap e a)
instance GHC.Generics.Generic (Algebra.Graph.Labelled.AdjacencyMap.AdjacencyMap e a)
instance (GHC.Classes.Eq a, GHC.Classes.Eq e) => GHC.Classes.Eq (Algebra.Graph.Labelled.AdjacencyMap.AdjacencyMap e a)
instance (GHC.Classes.Ord a, GHC.Show.Show a, GHC.Classes.Ord e, GHC.Show.Show e) => GHC.Show.Show (Algebra.Graph.Labelled.AdjacencyMap.AdjacencyMap e a)
instance (GHC.Classes.Ord e, GHC.Base.Monoid e, GHC.Classes.Ord a) => GHC.Classes.Ord (Algebra.Graph.Labelled.AdjacencyMap.AdjacencyMap e a)
instance (GHC.Classes.Eq e, Algebra.Graph.Label.Dioid e, GHC.Num.Num a, GHC.Classes.Ord a) => GHC.Num.Num (Algebra.Graph.Labelled.AdjacencyMap.AdjacencyMap e a)
instance Data.String.IsString a => Data.String.IsString (Algebra.Graph.Labelled.AdjacencyMap.AdjacencyMap e a)
instance (GHC.Classes.Ord a, GHC.Classes.Eq e, GHC.Base.Monoid e) => GHC.Base.Semigroup (Algebra.Graph.Labelled.AdjacencyMap.AdjacencyMap e a)
instance (GHC.Classes.Ord a, GHC.Classes.Eq e, GHC.Base.Monoid e) => GHC.Base.Monoid (Algebra.Graph.Labelled.AdjacencyMap.AdjacencyMap e a)


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module provides a minimal and experimental implementation of
--   algebraic graphs with edge labels. The API will be expanded in the
--   next release.
module Algebra.Graph.Labelled

-- | Edge-labelled graphs, where the type variable <tt>e</tt> stands for
--   edge labels. For example, <a>Graph</a> <tt>Bool</tt> <tt>a</tt> is
--   isomorphic to unlabelled graphs defined in the top-level module
--   <a>Algebra.Graph.Graph</a>, where <tt>False</tt> and <tt>True</tt>
--   denote the lack of and the existence of an unlabelled edge,
--   respectively.
data Graph e a
Empty :: Graph e a
Vertex :: a -> Graph e a
Connect :: e -> Graph e a -> Graph e a -> Graph e a

-- | Construct the <i>empty graph</i>. An alias for the constructor
--   <a>Empty</a>.
--   
--   <pre>
--   <a>isEmpty</a>     empty == True
--   <a>hasVertex</a> x empty == False
--   <a>vertexCount</a> empty == 0
--   <a>edgeCount</a>   empty == 0
--   </pre>
empty :: Graph e a

-- | Construct the graph comprising <i>a single isolated vertex</i>. An
--   alias for the constructor <a>Vertex</a>.
--   
--   <pre>
--   <a>isEmpty</a>     (vertex x) == False
--   <a>hasVertex</a> x (vertex y) == (x == y)
--   <a>vertexCount</a> (vertex x) == 1
--   <a>edgeCount</a>   (vertex x) == 0
--   </pre>
vertex :: a -> Graph e a

-- | Construct the graph comprising <i>a single labelled edge</i>.
--   
--   <pre>
--   edge e    x y              == <a>connect</a> e (<a>vertex</a> x) (<a>vertex</a> y)
--   edge <a>zero</a> x y              == <a>vertices</a> [x,y]
--   <a>hasEdge</a>   x y (edge e x y) == (e /= <a>zero</a>)
--   <a>edgeLabel</a> x y (edge e x y) == e
--   <a>edgeCount</a>     (edge e x y) == if e == <a>zero</a> then 0 else 1
--   <a>vertexCount</a>   (edge e 1 1) == 1
--   <a>vertexCount</a>   (edge e 1 2) == 2
--   </pre>
edge :: e -> a -> a -> Graph e a

-- | The left-hand part of a convenient ternary-ish operator
--   <tt>x-&lt;e&gt;-y</tt> for creating labelled edges.
--   
--   <pre>
--   x -&lt;e&gt;- y == <a>edge</a> e x y
--   </pre>
(-<) :: a -> e -> (a, e)
infixl 5 -<

-- | The right-hand part of a convenient ternary-ish operator
--   <tt>x-&lt;e&gt;-y</tt> for creating labelled edges.
--   
--   <pre>
--   x -&lt;e&gt;- y == <a>edge</a> e x y
--   </pre>
(>-) :: (a, e) -> a -> Graph e a
infixl 5 >-

-- | <i>Overlay</i> two graphs. An alias for <a>Connect</a> <a>zero</a>.
--   Complexity: <i>O(1)</i> time and memory, <i>O(s1 + s2)</i> size.
--   
--   <pre>
--   <a>isEmpty</a>     (overlay x y) == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (overlay x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (overlay x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (overlay x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (overlay x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (overlay x y) &lt;= <a>edgeCount</a> x   + <a>edgeCount</a> y
--   <a>vertexCount</a> (overlay 1 2) == 2
--   <a>edgeCount</a>   (overlay 1 2) == 0
--   </pre>
--   
--   Note: <a>overlay</a> composes edges in parallel using the operator
--   <a>&lt;+&gt;</a> with <a>zero</a> acting as the identity:
--   
--   <pre>
--   <a>edgeLabel</a> x y $ overlay (<a>edge</a> e x y) (<a>edge</a> <a>zero</a> x y) == e
--   <a>edgeLabel</a> x y $ overlay (<a>edge</a> e x y) (<a>edge</a> f    x y) == e <a>&lt;+&gt;</a> f
--   </pre>
--   
--   Furthermore, when applied to transitive graphs, <a>overlay</a>
--   composes edges in sequence using the operator <a>&lt;.&gt;</a> with
--   <a>one</a> acting as the identity:
--   
--   <pre>
--   <a>edgeLabel</a> x z $ <a>transitiveClosure</a> (overlay (<a>edge</a> e x y) (<a>edge</a> <a>one</a> y z)) == e
--   <a>edgeLabel</a> x z $ <a>transitiveClosure</a> (overlay (<a>edge</a> e x y) (<a>edge</a> f   y z)) == e <a>&lt;.&gt;</a> f
--   </pre>
overlay :: Monoid e => Graph e a -> Graph e a -> Graph e a

-- | <i>Connect</i> two graphs with edges labelled by a given label. An
--   alias for <a>Connect</a>. Complexity: <i>O(1)</i> time and memory,
--   <i>O(s1 + s2)</i> size. Note that the number of edges in the resulting
--   graph is quadratic with respect to the number of vertices of the
--   arguments: <i>m = O(m1 + m2 + n1 * n2)</i>.
--   
--   <pre>
--   <a>isEmpty</a>     (connect e x y) == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (connect e x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (connect e x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (connect e x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect e x y) &lt;= <a>vertexCount</a> x * <a>vertexCount</a> y + <a>edgeCount</a> x + <a>edgeCount</a> y
--   <a>vertexCount</a> (connect e 1 2) == 2
--   <a>edgeCount</a>   (connect e 1 2) == if e == <a>zero</a> then 0 else 1
--   </pre>
connect :: e -> Graph e a -> Graph e a -> Graph e a

-- | Construct the graph comprising a given list of isolated vertices.
--   Complexity: <i>O(L)</i> time, memory and size, where <i>L</i> is the
--   length of the given list.
--   
--   <pre>
--   vertices []            == <a>empty</a>
--   vertices [x]           == <a>vertex</a> x
--   vertices               == <a>overlays</a> . map <a>vertex</a>
--   <a>hasVertex</a> x . vertices == <a>elem</a> x
--   <a>vertexCount</a> . vertices == <a>length</a> . <a>nub</a>
--   <a>vertexSet</a>   . vertices == Set.<a>fromList</a>
--   </pre>
vertices :: Monoid e => [a] -> Graph e a

-- | Construct the graph from a list of labelled edges. Complexity:
--   <i>O(L)</i> time, memory and size, where <i>L</i> is the length of the
--   given list.
--   
--   <pre>
--   edges []        == <a>empty</a>
--   edges [(e,x,y)] == <a>edge</a> e x y
--   edges           == <a>overlays</a> . <a>map</a> (\(e, x, y) -&gt; <a>edge</a> e x y)
--   </pre>
edges :: Monoid e => [(e, a, a)] -> Graph e a

-- | Overlay a given list of graphs. Complexity: <i>O(L)</i> time and
--   memory, and <i>O(S)</i> size, where <i>L</i> is the length of the
--   given list, and <i>S</i> is the sum of sizes of the graphs in the
--   list.
--   
--   <pre>
--   overlays []        == <a>empty</a>
--   overlays [x]       == x
--   overlays [x,y]     == <a>overlay</a> x y
--   overlays           == <a>foldr</a> <a>overlay</a> <a>empty</a>
--   <a>isEmpty</a> . overlays == <a>all</a> <a>isEmpty</a>
--   </pre>
overlays :: Monoid e => [Graph e a] -> Graph e a

-- | Generalised <a>Graph</a> folding: recursively collapse a <a>Graph</a>
--   by applying the provided functions to the leaves and internal nodes of
--   the expression. The order of arguments is: empty, vertex and connect.
--   Complexity: <i>O(s)</i> applications of the given functions. As an
--   example, the complexity of <a>size</a> is <i>O(s)</i>, since
--   <a>const</a> and <a>+</a> have constant costs.
--   
--   <pre>
--   foldg <a>empty</a>     <a>vertex</a>        <a>connect</a>             == <a>id</a>
--   foldg <a>empty</a>     <a>vertex</a>        (<a>fmap</a> <a>flip</a> <a>connect</a>) == <a>transpose</a>
--   foldg 1         (<a>const</a> 1)     (<a>const</a> (+))         == <a>size</a>
--   foldg True      (<a>const</a> False) (<a>const</a> (&amp;&amp;))        == <a>isEmpty</a>
--   foldg False     (== x)        (<a>const</a> (||))        == <a>hasVertex</a> x
--   foldg Set.<a>empty</a> Set.<a>singleton</a> (<a>const</a> Set.<a>union</a>)   == <a>vertexSet</a>
--   </pre>
foldg :: b -> (a -> b) -> (e -> b -> b -> b) -> Graph e a -> b

-- | Build a graph given an interpretation of the three graph construction
--   primitives <a>empty</a>, <a>vertex</a> and <a>connect</a>, in this
--   order. See examples for further clarification.
--   
--   <pre>
--   buildg f                                               == f <a>empty</a> <a>vertex</a> <a>connect</a>
--   buildg (\e _ _ -&gt; e)                                   == <a>empty</a>
--   buildg (\_ v _ -&gt; v x)                                 == <a>vertex</a> x
--   buildg (\e v c -&gt; c l (<a>foldg</a> e v c x) (<a>foldg</a> e v c y)) == <a>connect</a> l x y
--   buildg (\e v c -&gt; <a>foldr</a> (c <a>zero</a>) e (<a>map</a> v xs))         == <a>vertices</a> xs
--   buildg (\e v c -&gt; <a>foldg</a> e v (<a>flip</a> . c) g)              == <a>transpose</a> g
--   <a>foldg</a> e v c (buildg f)                                 == f e v c
--   </pre>
buildg :: (forall r. r -> (a -> r) -> (e -> r -> r -> r) -> r) -> Graph e a

-- | The <a>isSubgraphOf</a> function takes two graphs and returns
--   <a>True</a> if the first graph is a <i>subgraph</i> of the second.
--   Complexity: <i>O(s + m * log(m))</i> time. Note that the number of
--   edges <i>m</i> of a graph can be quadratic with respect to the
--   expression size <i>s</i>.
--   
--   <pre>
--   isSubgraphOf <a>empty</a>         x             ==  True
--   isSubgraphOf (<a>vertex</a> x)    <a>empty</a>         ==  False
--   isSubgraphOf x             (<a>overlay</a> x y) ==  True
--   isSubgraphOf (<a>overlay</a> x y) (<a>connect</a> x y) ==  True
--   isSubgraphOf x y                         ==&gt; x &lt;= y
--   </pre>
isSubgraphOf :: (Eq e, Monoid e, Ord a) => Graph e a -> Graph e a -> Bool

-- | Check if a graph is empty. Complexity: <i>O(s)</i> time.
--   
--   <pre>
--   isEmpty <a>empty</a>                         == True
--   isEmpty (<a>overlay</a> <a>empty</a> <a>empty</a>)         == True
--   isEmpty (<a>vertex</a> x)                    == False
--   isEmpty (<a>removeVertex</a> x $ <a>vertex</a> x)   == True
--   isEmpty (<a>removeEdge</a> x y $ <a>edge</a> e x y) == False
--   </pre>
isEmpty :: Graph e a -> Bool

-- | The <i>size</i> of a graph, i.e. the number of leaves of the
--   expression including <a>empty</a> leaves. Complexity: <i>O(s)</i>
--   time.
--   
--   <pre>
--   size <a>empty</a>         == 1
--   size (<a>vertex</a> x)    == 1
--   size (<a>overlay</a> x y) == size x + size y
--   size (<a>connect</a> x y) == size x + size y
--   size x             &gt;= 1
--   size x             &gt;= <a>vertexCount</a> x
--   </pre>
size :: Graph e a -> Int

-- | Check if a graph contains a given vertex. Complexity: <i>O(s)</i>
--   time.
--   
--   <pre>
--   hasVertex x <a>empty</a>            == False
--   hasVertex x (<a>vertex</a> y)       == (x == y)
--   hasVertex x . <a>removeVertex</a> x == <a>const</a> False
--   </pre>
hasVertex :: Eq a => a -> Graph e a -> Bool

-- | Check if a graph contains a given edge. Complexity: <i>O(s)</i> time.
--   
--   <pre>
--   hasEdge x y <a>empty</a>            == False
--   hasEdge x y (<a>vertex</a> z)       == False
--   hasEdge x y (<a>edge</a> e x y)     == (e /= <a>zero</a>)
--   hasEdge x y . <a>removeEdge</a> x y == <a>const</a> False
--   hasEdge x y                  == <a>not</a> . <a>null</a> . <a>filter</a> (\(_,ex,ey) -&gt; ex == x &amp;&amp; ey == y) . <a>edgeList</a>
--   </pre>
hasEdge :: (Eq e, Monoid e, Ord a) => a -> a -> Graph e a -> Bool

-- | Extract the label of a specified edge from a graph.
edgeLabel :: (Eq a, Monoid e) => a -> a -> Graph e a -> e

-- | The sorted list of vertices of a given graph. Complexity: <i>O(s *
--   log(n))</i> time and <i>O(n)</i> memory.
--   
--   <pre>
--   vertexList <a>empty</a>      == []
--   vertexList (<a>vertex</a> x) == [x]
--   vertexList . <a>vertices</a> == <a>nub</a> . <a>sort</a>
--   </pre>
vertexList :: Ord a => Graph e a -> [a]

-- | The list of edges of a graph, sorted lexicographically with respect to
--   pairs of connected vertices (i.e. edge-labels are ignored when
--   sorting). Complexity: <i>O(n + m)</i> time and <i>O(m)</i> memory.
--   
--   <pre>
--   edgeList <a>empty</a>        == []
--   edgeList (<a>vertex</a> x)   == []
--   edgeList (<a>edge</a> e x y) == if e == <a>zero</a> then [] else [(e,x,y)]
--   </pre>
edgeList :: (Eq e, Monoid e, Ord a) => Graph e a -> [(e, a, a)]

-- | The set of vertices of a given graph. Complexity: <i>O(s * log(n))</i>
--   time and <i>O(n)</i> memory.
--   
--   <pre>
--   vertexSet <a>empty</a>      == Set.<a>empty</a>
--   vertexSet . <a>vertex</a>   == Set.<a>singleton</a>
--   vertexSet . <a>vertices</a> == Set.<a>fromList</a>
--   </pre>
vertexSet :: Ord a => Graph e a -> Set a

-- | The set of edges of a given graph. Complexity: <i>O(n + m)</i> time
--   and <i>O(m)</i> memory.
--   
--   <pre>
--   edgeSet <a>empty</a>        == Set.<a>empty</a>
--   edgeSet (<a>vertex</a> x)   == Set.<a>empty</a>
--   edgeSet (<a>edge</a> e x y) == if e == <a>zero</a> then Set.<a>empty</a> else Set.<a>singleton</a> (e,x,y)
--   </pre>
edgeSet :: (Eq e, Monoid e, Ord a) => Graph e a -> Set (e, a, a)

-- | Remove a vertex from a given graph. Complexity: <i>O(s)</i> time,
--   memory and size.
--   
--   <pre>
--   removeVertex x (<a>vertex</a> x)       == <a>empty</a>
--   removeVertex 1 (<a>vertex</a> 2)       == <a>vertex</a> 2
--   removeVertex x (<a>edge</a> e x x)     == <a>empty</a>
--   removeVertex 1 (<a>edge</a> e 1 2)     == <a>vertex</a> 2
--   removeVertex x . removeVertex x == removeVertex x
--   </pre>
removeVertex :: Eq a => a -> Graph e a -> Graph e a

-- | Remove an edge from a given graph. Complexity: <i>O(s)</i> time,
--   memory and size.
--   
--   <pre>
--   removeEdge x y (<a>edge</a> e x y)     == <a>vertices</a> [x,y]
--   removeEdge x y . removeEdge x y == removeEdge x y
--   removeEdge x y . <a>removeVertex</a> x == <a>removeVertex</a> x
--   removeEdge 1 1 (1 * 1 * 2 * 2)  == 1 * 2 * 2
--   removeEdge 1 2 (1 * 1 * 2 * 2)  == 1 * 1 + 2 * 2
--   </pre>
removeEdge :: (Eq a, Eq e, Monoid e) => a -> a -> Graph e a -> Graph e a

-- | The function <tt><a>replaceVertex</a> x y</tt> replaces vertex
--   <tt>x</tt> with vertex <tt>y</tt> in a given <a>Graph</a>. If
--   <tt>y</tt> already exists, <tt>x</tt> and <tt>y</tt> will be merged.
--   Complexity: <i>O(s)</i> time, memory and size.
--   
--   <pre>
--   replaceVertex x x            == id
--   replaceVertex x y (<a>vertex</a> x) == <a>vertex</a> y
--   replaceVertex x y            == <a>fmap</a> (\v -&gt; if v == x then y else v)
--   </pre>
replaceVertex :: Eq a => a -> a -> Graph e a -> Graph e a

-- | Replace an edge from a given graph. If it doesn't exist, it will be
--   created. Complexity: <i>O(log(n))</i> time.
--   
--   <pre>
--   replaceEdge e x y z                 == <a>overlay</a> (removeEdge x y z) (<a>edge</a> e x y)
--   replaceEdge e x y (<a>edge</a> f x y)      == <a>edge</a> e x y
--   <a>edgeLabel</a> x y (replaceEdge e x y z) == e
--   </pre>
replaceEdge :: (Eq e, Monoid e, Ord a) => e -> a -> a -> Graph e a -> Graph e a

-- | Transpose a given graph. Complexity: <i>O(s)</i> time, memory and
--   size.
--   
--   <pre>
--   transpose <a>empty</a>        == <a>empty</a>
--   transpose (<a>vertex</a> x)   == <a>vertex</a> x
--   transpose (<a>edge</a> e x y) == <a>edge</a> e y x
--   transpose . transpose  == id
--   </pre>
transpose :: Graph e a -> Graph e a

-- | Transform a graph by applying a function to each of its edge labels.
--   Complexity: <i>O(s)</i> time, memory and size.
--   
--   The function <tt>h</tt> is required to be a <i>homomorphism</i> on the
--   underlying type of labels <tt>e</tt>. At the very least it must
--   preserve <a>zero</a> and <a>&lt;+&gt;</a>:
--   
--   <pre>
--   h <a>zero</a>      == <a>zero</a>
--   h x <a>&lt;+&gt;</a> h y == h (x <a>&lt;+&gt;</a> y)
--   </pre>
--   
--   If <tt>e</tt> is also a semiring, then <tt>h</tt> must also preserve
--   the multiplicative structure:
--   
--   <pre>
--   h <a>one</a>       == <a>one</a>
--   h x <a>&lt;.&gt;</a> h y == h (x <a>&lt;.&gt;</a> y)
--   </pre>
--   
--   If the above requirements hold, then the implementation provides the
--   following guarantees.
--   
--   <pre>
--   emap h <a>empty</a>           == <a>empty</a>
--   emap h (<a>vertex</a> x)      == <a>vertex</a> x
--   emap h (<a>edge</a> e x y)    == <a>edge</a> (h e) x y
--   emap h (<a>overlay</a> x y)   == <a>overlay</a> (emap h x) (emap h y)
--   emap h (<a>connect</a> e x y) == <a>connect</a> (h e) (emap h x) (emap h y)
--   emap <a>id</a>                == <a>id</a>
--   emap g . emap h        == emap (g . h)
--   </pre>
emap :: (e -> f) -> Graph e a -> Graph f a

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that do not satisfy a given predicate. Complexity:
--   <i>O(s)</i> time, memory and size, assuming that the predicate takes
--   constant time.
--   
--   <pre>
--   induce (<a>const</a> True ) x      == x
--   induce (<a>const</a> False) x      == <a>empty</a>
--   induce (/= x)               == <a>removeVertex</a> x
--   induce p . induce q         == induce (\x -&gt; p x &amp;&amp; q x)
--   <a>isSubgraphOf</a> (induce p x) x == True
--   </pre>
induce :: (a -> Bool) -> Graph e a -> Graph e a

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that are <a>Nothing</a>. Complexity: <i>O(s)</i> time, memory
--   and size.
--   
--   <pre>
--   induceJust (<a>vertex</a> <a>Nothing</a>)                               == <a>empty</a>
--   induceJust (<a>edge</a> (<a>Just</a> x) <a>Nothing</a>)                        == <a>vertex</a> x
--   induceJust . <a>fmap</a> <a>Just</a>                                    == <a>id</a>
--   induceJust . <a>fmap</a> (\x -&gt; if p x then <a>Just</a> x else <a>Nothing</a>) == <a>induce</a> p
--   </pre>
induceJust :: Graph e (Maybe a) -> Graph e a

-- | Compute the <i>reflexive and transitive closure</i> of a graph over
--   the underlying star semiring using the Warshall-Floyd-Kleene
--   algorithm.
--   
--   <pre>
--   closure <a>empty</a>         == <a>empty</a>
--   closure (<a>vertex</a> x)    == <a>edge</a> <a>one</a> x x
--   closure (<a>edge</a> e x x)  == <a>edge</a> <a>one</a> x x
--   closure (<a>edge</a> e x y)  == <a>edges</a> [(<a>one</a>,x,x), (e,x,y), (<a>one</a>,y,y)]
--   closure               == <a>reflexiveClosure</a> . <a>transitiveClosure</a>
--   closure               == <a>transitiveClosure</a> . <a>reflexiveClosure</a>
--   closure . closure     == closure
--   <a>postSet</a> x (closure y) == Set.<a>fromList</a> (<a>reachable</a> x y)
--   </pre>
closure :: (Eq e, Ord a, StarSemiring e) => Graph e a -> Graph e a

-- | Compute the <i>reflexive closure</i> of a graph over the underlying
--   semiring by adding a self-loop of weight <a>one</a> to every vertex.
--   Complexity: <i>O(n * log(n))</i> time.
--   
--   <pre>
--   reflexiveClosure <a>empty</a>              == <a>empty</a>
--   reflexiveClosure (<a>vertex</a> x)         == <a>edge</a> <a>one</a> x x
--   reflexiveClosure (<a>edge</a> e x x)       == <a>edge</a> <a>one</a> x x
--   reflexiveClosure (<a>edge</a> e x y)       == <a>edges</a> [(<a>one</a>,x,x), (e,x,y), (<a>one</a>,y,y)]
--   reflexiveClosure . reflexiveClosure == reflexiveClosure
--   </pre>
reflexiveClosure :: (Ord a, Semiring e) => Graph e a -> Graph e a

-- | Compute the <i>symmetric closure</i> of a graph by overlaying it with
--   its own transpose. Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   symmetricClosure <a>empty</a>              == <a>empty</a>
--   symmetricClosure (<a>vertex</a> x)         == <a>vertex</a> x
--   symmetricClosure (<a>edge</a> e x y)       == <a>edges</a> [(e,x,y), (e,y,x)]
--   symmetricClosure x                  == <a>overlay</a> x (<a>transpose</a> x)
--   symmetricClosure . symmetricClosure == symmetricClosure
--   </pre>
symmetricClosure :: Monoid e => Graph e a -> Graph e a

-- | Compute the <i>transitive closure</i> of a graph over the underlying
--   star semiring using a modified version of the Warshall-Floyd-Kleene
--   algorithm, which omits the reflexivity step.
--   
--   <pre>
--   transitiveClosure <a>empty</a>               == <a>empty</a>
--   transitiveClosure (<a>vertex</a> x)          == <a>vertex</a> x
--   transitiveClosure (<a>edge</a> e x y)        == <a>edge</a> e x y
--   transitiveClosure . transitiveClosure == transitiveClosure
--   </pre>
transitiveClosure :: (Eq e, Ord a, StarSemiring e) => Graph e a -> Graph e a

-- | A type synonym for <i>unlabelled graphs</i>.
type UnlabelledGraph a = Graph Any a

-- | A type synonym for <i>automata</i> or <i>labelled transition
--   systems</i>.
type Automaton a s = Graph (RegularExpression a) s

-- | A <i>network</i> is a graph whose edges are labelled with distances.
type Network e a = Graph (Distance e) a

-- | The <a>Context</a> of a subgraph comprises its <a>inputs</a> and
--   <a>outputs</a>, i.e. all the vertices that are connected to the
--   subgraph's vertices (along with the corresponding edge labels). Note
--   that inputs and outputs can belong to the subgraph itself. In general,
--   there are no guarantees on the order of vertices in <a>inputs</a> and
--   <a>outputs</a>; furthermore, there may be repetitions.
data Context e a
Context :: [(e, a)] -> [(e, a)] -> Context e a
[inputs] :: Context e a -> [(e, a)]
[outputs] :: Context e a -> [(e, a)]

-- | Extract the <a>Context</a> of a subgraph specified by a given
--   predicate. Returns <tt>Nothing</tt> if the specified subgraph is
--   empty.
--   
--   <pre>
--   context (<a>const</a> False) x                   == Nothing
--   context (== 1)        (<a>edge</a> e 1 2)        == if e == <a>zero</a> then Just (<a>Context</a> [] []) else Just (<a>Context</a> [     ] [(e,2)])
--   context (== 2)        (<a>edge</a> e 1 2)        == if e == <a>zero</a> then Just (<a>Context</a> [] []) else Just (<a>Context</a> [(e,1)] [     ])
--   context (<a>const</a> True ) (<a>edge</a> e 1 2)        == if e == <a>zero</a> then Just (<a>Context</a> [] []) else Just (<a>Context</a> [(e,1)] [(e,2)])
--   context (== 4)        (3 * 1 * 4 * 1 * 5) == Just (<a>Context</a> [(<a>one</a>,3), (<a>one</a>,1)] [(<a>one</a>,1), (<a>one</a>,5)])
--   </pre>
context :: (Eq e, Monoid e) => (a -> Bool) -> Graph e a -> Maybe (Context e a)
instance GHC.Generics.Generic (Algebra.Graph.Labelled.Graph e a)
instance (GHC.Show.Show a, GHC.Show.Show e) => GHC.Show.Show (Algebra.Graph.Labelled.Graph e a)
instance GHC.Base.Functor (Algebra.Graph.Labelled.Graph e)
instance (GHC.Show.Show e, GHC.Show.Show a) => GHC.Show.Show (Algebra.Graph.Labelled.Context e a)
instance (GHC.Classes.Eq e, GHC.Classes.Eq a) => GHC.Classes.Eq (Algebra.Graph.Labelled.Context e a)
instance (GHC.Classes.Eq e, GHC.Base.Monoid e, GHC.Classes.Ord a) => GHC.Classes.Eq (Algebra.Graph.Labelled.Graph e a)
instance (GHC.Classes.Eq e, GHC.Base.Monoid e, GHC.Classes.Ord a, GHC.Classes.Ord e) => GHC.Classes.Ord (Algebra.Graph.Labelled.Graph e a)
instance (GHC.Classes.Ord a, GHC.Num.Num a, Algebra.Graph.Label.Dioid e) => GHC.Num.Num (Algebra.Graph.Labelled.Graph e a)
instance Data.String.IsString a => Data.String.IsString (Algebra.Graph.Labelled.Graph e a)
instance Data.Bifunctor.Bifunctor Algebra.Graph.Labelled.Graph
instance (Control.DeepSeq.NFData e, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Algebra.Graph.Labelled.Graph e a)
instance GHC.Base.Monoid e => GHC.Base.Semigroup (Algebra.Graph.Labelled.Graph e a)
instance GHC.Base.Monoid e => GHC.Base.Monoid (Algebra.Graph.Labelled.Graph e a)


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module contains a simple example of using edge-labelled graphs
--   defined in the module <a>Algebra.Graph.Labelled</a> for working with
--   networks, i.e. graphs whose edges are labelled with distances.
module Algebra.Graph.Labelled.Example.Network

-- | Our example networks have <i>cities</i> as vertices.
data City
Aberdeen :: City
Edinburgh :: City
Glasgow :: City
London :: City
Newcastle :: City

-- | For simplicity we measure <i>journey times</i> in integer number of
--   minutes.
type JourneyTime = Int

-- | A part of the EastCoast train network between <a>Aberdeen</a> and
--   <a>London</a>.
--   
--   <pre>
--   eastCoast = <a>overlays</a> [ <a>Aberdeen</a>  <a>-&lt;</a>150<a>&gt;-</a> <a>Edinburgh</a>
--                        , <a>Edinburgh</a> <a>-&lt;</a> 90<a>&gt;-</a> <a>Newcastle</a>
--                        , <a>Newcastle</a> <a>-&lt;</a>170<a>&gt;-</a> <a>London</a> ]
--   </pre>
eastCoast :: Network JourneyTime City

-- | A part of the ScotRail train network between <a>Aberdeen</a> and
--   <a>Glasgow</a>.
--   
--   <pre>
--   scotRail = <a>overlays</a> [ <a>Aberdeen</a>  <a>-&lt;</a>140<a>&gt;-</a> <a>Edinburgh</a>
--                       , <a>Edinburgh</a> <a>-&lt;</a> 50<a>&gt;-</a> <a>Glasgow</a>
--                       , <a>Edinburgh</a> <a>-&lt;</a> 70<a>&gt;-</a> <a>Glasgow</a> ]
--   </pre>
scotRail :: Network JourneyTime City

-- | An example train network.
--   
--   <pre>
--   network = <a>overlay</a> <a>scotRail</a> <a>eastCoast</a>
--   </pre>
network :: Network JourneyTime City
instance GHC.Show.Show Algebra.Graph.Labelled.Example.Network.City
instance GHC.Classes.Ord Algebra.Graph.Labelled.Example.Network.City
instance GHC.Classes.Eq Algebra.Graph.Labelled.Example.Network.City
instance GHC.Enum.Enum Algebra.Graph.Labelled.Example.Network.City
instance GHC.Enum.Bounded Algebra.Graph.Labelled.Example.Network.City


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module defines the data type <a>AdjacencyMap</a> for graphs that
--   are known to be non-empty at compile time. To avoid name clashes with
--   <a>Algebra.Graph.AdjacencyMap</a>, this module can be imported
--   qualified:
--   
--   <pre>
--   import qualified Algebra.Graph.NonEmpty.AdjacencyMap as NonEmpty
--   </pre>
--   
--   The naming convention generally follows that of
--   <a>Data.List.NonEmpty</a>: we use suffix <tt>1</tt> to indicate the
--   functions whose interface must be changed compared to
--   <a>Algebra.Graph.AdjacencyMap</a>, e.g. <a>vertices1</a>.
module Algebra.Graph.NonEmpty.AdjacencyMap

-- | The <a>AdjacencyMap</a> data type represents a graph by a map of
--   vertices to their adjacency sets. We define a <a>Num</a> instance as a
--   convenient notation for working with graphs:
--   
--   <pre>
--   0           == <a>vertex</a> 0
--   1 + 2       == <a>overlay</a> (<a>vertex</a> 1) (<a>vertex</a> 2)
--   1 * 2       == <a>connect</a> (<a>vertex</a> 1) (<a>vertex</a> 2)
--   1 + 2 * 3   == <a>overlay</a> (<a>vertex</a> 1) (<a>connect</a> (<a>vertex</a> 2) (<a>vertex</a> 3))
--   1 * (2 + 3) == <a>connect</a> (<a>vertex</a> 1) (<a>overlay</a> (<a>vertex</a> 2) (<a>vertex</a> 3))
--   </pre>
--   
--   <b>Note:</b> the <a>signum</a> method of the type class <a>Num</a>
--   cannot be implemented and will throw an error. Furthermore, the
--   <a>Num</a> instance does not satisfy several "customary laws" of
--   <a>Num</a>, which dictate that <a>fromInteger</a> <tt>0</tt> and
--   <a>fromInteger</a> <tt>1</tt> should act as additive and
--   multiplicative identities, and <a>negate</a> as additive inverse.
--   Nevertheless, overloading <a>fromInteger</a>, <a>+</a> and <a>*</a> is
--   very convenient when working with algebraic graphs; we hope that in
--   future Haskell's Prelude will provide a more fine-grained class
--   hierarchy for algebraic structures, which we would be able to utilise
--   without violating any laws.
--   
--   The <a>Show</a> instance is defined using basic graph construction
--   primitives:
--   
--   <pre>
--   show (1         :: AdjacencyMap Int) == "vertex 1"
--   show (1 + 2     :: AdjacencyMap Int) == "vertices1 [1,2]"
--   show (1 * 2     :: AdjacencyMap Int) == "edge 1 2"
--   show (1 * 2 * 3 :: AdjacencyMap Int) == "edges1 [(1,2),(1,3),(2,3)]"
--   show (1 * 2 + 3 :: AdjacencyMap Int) == "overlay (vertex 3) (edge 1 2)"
--   </pre>
--   
--   The <a>Eq</a> instance satisfies the following laws of algebraic
--   graphs:
--   
--   <ul>
--   <li><a>overlay</a> is commutative, associative and idempotent:<pre> x
--   + y == y + x x + (y + z) == (x + y) + z x + x == x</pre></li>
--   <li><a>connect</a> is associative:<pre>x * (y * z) == (x * y) *
--   z</pre></li>
--   <li><a>connect</a> distributes over <a>overlay</a>:<pre>x * (y + z) ==
--   x * y + x * z (x + y) * z == x * z + y * z</pre></li>
--   <li><a>connect</a> can be decomposed:<pre>x * y * z == x * y + x * z +
--   y * z</pre></li>
--   <li><a>connect</a> satisfies absorption and saturation:<pre>x * y + x
--   + y == x * y x * x * x == x * x</pre></li>
--   </ul>
--   
--   When specifying the time and memory complexity of graph algorithms,
--   <i>n</i> and <i>m</i> will denote the number of vertices and edges in
--   the graph, respectively.
--   
--   The total order on graphs is defined using <i>size-lexicographic</i>
--   comparison:
--   
--   <ul>
--   <li>Compare the number of vertices. In case of a tie, continue.</li>
--   <li>Compare the sets of vertices. In case of a tie, continue.</li>
--   <li>Compare the number of edges. In case of a tie, continue.</li>
--   <li>Compare the sets of edges.</li>
--   </ul>
--   
--   Here are a few examples:
--   
--   <pre>
--   <a>vertex</a> 1 &lt; <a>vertex</a> 2
--   <a>vertex</a> 3 &lt; <a>edge</a> 1 2
--   <a>vertex</a> 1 &lt; <a>edge</a> 1 1
--   <a>edge</a> 1 1 &lt; <a>edge</a> 1 2
--   <a>edge</a> 1 2 &lt; <a>edge</a> 1 1 + <a>edge</a> 2 2
--   <a>edge</a> 1 2 &lt; <a>edge</a> 1 3
--   </pre>
--   
--   Note that the resulting order refines the <a>isSubgraphOf</a> relation
--   and is compatible with <a>overlay</a> and <a>connect</a> operations:
--   
--   <pre>
--   <a>isSubgraphOf</a> x y ==&gt; x &lt;= y
--   </pre>
--   
--   <pre>
--   x     &lt;= x + y
--   x + y &lt;= x * y
--   </pre>
data AdjacencyMap a

-- | Convert a possibly empty <a>AdjacencyMap</a> into
--   NonEmpty.<a>AdjacencyMap</a>. Returns <a>Nothing</a> if the argument
--   is <a>empty</a>. Complexity: <i>O(1)</i> time, memory and size.
--   
--   <pre>
--   toNonEmpty <a>empty</a>          == <a>Nothing</a>
--   toNonEmpty . <a>fromNonEmpty</a> == <a>Just</a>
--   </pre>
toNonEmpty :: AdjacencyMap a -> Maybe (AdjacencyMap a)

-- | Convert a NonEmpty.<a>AdjacencyMap</a> into an <a>AdjacencyMap</a>.
--   The resulting graph is guaranteed to be non-empty. Complexity:
--   <i>O(1)</i> time, memory and size.
--   
--   <pre>
--   <tt>isEmpty</tt> . fromNonEmpty    == <a>const</a> <a>False</a>
--   <a>toNonEmpty</a> . fromNonEmpty == <a>Just</a>
--   </pre>
fromNonEmpty :: AdjacencyMap a -> AdjacencyMap a

-- | Construct the graph comprising <i>a single isolated vertex</i>.
--   
--   <pre>
--   <a>hasVertex</a> x (vertex y) == (x == y)
--   <a>vertexCount</a> (vertex x) == 1
--   <a>edgeCount</a>   (vertex x) == 0
--   </pre>
vertex :: a -> AdjacencyMap a

-- | Construct the graph comprising <i>a single edge</i>.
--   
--   <pre>
--   edge x y               == <a>connect</a> (<a>vertex</a> x) (<a>vertex</a> y)
--   <a>hasEdge</a> x y (edge x y) == True
--   <a>edgeCount</a>   (edge x y) == 1
--   <a>vertexCount</a> (edge 1 1) == 1
--   <a>vertexCount</a> (edge 1 2) == 2
--   </pre>
edge :: Ord a => a -> a -> AdjacencyMap a

-- | <i>Overlay</i> two graphs. This is a commutative, associative and
--   idempotent operation with the identity <tt>empty</tt>. Complexity:
--   <i>O((n + m) * log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   <a>hasVertex</a> z (overlay x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (overlay x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (overlay x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (overlay x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (overlay x y) &lt;= <a>edgeCount</a> x   + <a>edgeCount</a> y
--   <a>vertexCount</a> (overlay 1 2) == 2
--   <a>edgeCount</a>   (overlay 1 2) == 0
--   </pre>
overlay :: Ord a => AdjacencyMap a -> AdjacencyMap a -> AdjacencyMap a

-- | <i>Connect</i> two graphs. This is an associative operation with the
--   identity <tt>empty</tt>, which distributes over <a>overlay</a> and
--   obeys the decomposition axiom. Complexity: <i>O((n + m) * log(n))</i>
--   time and <i>O(n + m)</i> memory. Note that the number of edges in the
--   resulting graph is quadratic with respect to the number of vertices of
--   the arguments: <i>m = O(m1 + m2 + n1 * n2)</i>.
--   
--   <pre>
--   <a>hasVertex</a> z (connect x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (connect x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (connect x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (connect x y) &gt;= <a>edgeCount</a> y
--   <a>edgeCount</a>   (connect x y) &gt;= <a>vertexCount</a> x * <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect x y) &lt;= <a>vertexCount</a> x * <a>vertexCount</a> y + <a>edgeCount</a> x + <a>edgeCount</a> y
--   <a>vertexCount</a> (connect 1 2) == 2
--   <a>edgeCount</a>   (connect 1 2) == 1
--   </pre>
connect :: Ord a => AdjacencyMap a -> AdjacencyMap a -> AdjacencyMap a

-- | Construct the graph comprising a given list of isolated vertices.
--   Complexity: <i>O(L * log(L))</i> time and <i>O(L)</i> memory, where
--   <i>L</i> is the length of the given list.
--   
--   <pre>
--   vertices1 [x]           == <a>vertex</a> x
--   <a>hasVertex</a> x . vertices1 == <a>elem</a> x
--   <a>vertexCount</a> . vertices1 == <a>length</a> . <a>nub</a>
--   <a>vertexSet</a>   . vertices1 == Set.<a>fromList</a> . <a>toList</a>
--   </pre>
vertices1 :: Ord a => NonEmpty a -> AdjacencyMap a

-- | Construct the graph from a list of edges. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   edges1 [(x,y)]     == <a>edge</a> x y
--   edges1             == <a>overlays1</a> . <a>fmap</a> (<a>uncurry</a> <a>edge</a>)
--   <a>edgeCount</a> . edges1 == <a>length</a> . <a>nub</a>
--   </pre>
edges1 :: Ord a => NonEmpty (a, a) -> AdjacencyMap a

-- | Overlay a given list of graphs. Complexity: <i>O((n + m) * log(n))</i>
--   time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   overlays1 [x]   == x
--   overlays1 [x,y] == <a>overlay</a> x y
--   </pre>
overlays1 :: Ord a => NonEmpty (AdjacencyMap a) -> AdjacencyMap a

-- | Connect a given list of graphs. Complexity: <i>O((n + m) * log(n))</i>
--   time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   connects1 [x]   == x
--   connects1 [x,y] == <a>connect</a> x y
--   </pre>
connects1 :: Ord a => NonEmpty (AdjacencyMap a) -> AdjacencyMap a

-- | The <a>isSubgraphOf</a> function takes two graphs and returns
--   <a>True</a> if the first graph is a <i>subgraph</i> of the second.
--   Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   isSubgraphOf x             (<a>overlay</a> x y) ==  True
--   isSubgraphOf (<a>overlay</a> x y) (<a>connect</a> x y) ==  True
--   isSubgraphOf (<a>path1</a> xs)    (<a>circuit1</a> xs) ==  True
--   isSubgraphOf x y                         ==&gt; x &lt;= y
--   </pre>
isSubgraphOf :: Ord a => AdjacencyMap a -> AdjacencyMap a -> Bool

-- | Check if a graph contains a given vertex. Complexity: <i>O(log(n))</i>
--   time.
--   
--   <pre>
--   hasVertex x (<a>vertex</a> y) == (x == y)
--   </pre>
hasVertex :: Ord a => a -> AdjacencyMap a -> Bool

-- | Check if a graph contains a given edge. Complexity: <i>O(log(n))</i>
--   time.
--   
--   <pre>
--   hasEdge x y (<a>vertex</a> z)       == False
--   hasEdge x y (<a>edge</a> x y)       == True
--   hasEdge x y . <a>removeEdge</a> x y == <a>const</a> False
--   hasEdge x y                  == <a>elem</a> (x,y) . <a>edgeList</a>
--   </pre>
hasEdge :: Ord a => a -> a -> AdjacencyMap a -> Bool

-- | The number of vertices in a graph. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   vertexCount (<a>vertex</a> x)        ==  1
--   vertexCount                   ==  <a>length</a> . <tt>vertexList</tt>
--   vertexCount x &lt; vertexCount y ==&gt; x &lt; y
--   </pre>
vertexCount :: AdjacencyMap a -> Int

-- | The number of edges in a graph. Complexity: <i>O(n)</i> time.
--   
--   <pre>
--   edgeCount (<a>vertex</a> x) == 0
--   edgeCount (<a>edge</a> x y) == 1
--   edgeCount            == <a>length</a> . <a>edgeList</a>
--   </pre>
edgeCount :: AdjacencyMap a -> Int

-- | The sorted list of vertices of a given graph. Complexity: <i>O(n)</i>
--   time and memory.
--   
--   <pre>
--   vertexList1 (<a>vertex</a> x)  == [x]
--   vertexList1 . <a>vertices1</a> == <a>nub</a> . <a>sort</a>
--   </pre>
vertexList1 :: AdjacencyMap a -> NonEmpty a

-- | The sorted list of edges of a graph. Complexity: <i>O(n + m)</i> time
--   and <i>O(m)</i> memory.
--   
--   <pre>
--   edgeList (<a>vertex</a> x)     == []
--   edgeList (<a>edge</a> x y)     == [(x,y)]
--   edgeList (<a>star</a> 2 [3,1]) == [(2,1), (2,3)]
--   edgeList . <tt>edges</tt>        == <a>nub</a> . <a>sort</a>
--   edgeList . <a>transpose</a>    == <a>sort</a> . <a>map</a> <a>swap</a> . edgeList
--   </pre>
edgeList :: AdjacencyMap a -> [(a, a)]

-- | The set of vertices of a given graph. Complexity: <i>O(n)</i> time and
--   memory.
--   
--   <pre>
--   vertexSet . <a>vertex</a>    == Set.<a>singleton</a>
--   vertexSet . <a>vertices1</a> == Set.<a>fromList</a> . <a>toList</a>
--   vertexSet . <a>clique1</a>   == Set.<a>fromList</a> . <a>toList</a>
--   </pre>
vertexSet :: AdjacencyMap a -> Set a

-- | The set of edges of a given graph. Complexity: <i>O((n + m) *
--   log(m))</i> time and <i>O(m)</i> memory.
--   
--   <pre>
--   edgeSet (<a>vertex</a> x) == Set.<a>empty</a>
--   edgeSet (<a>edge</a> x y) == Set.<a>singleton</a> (x,y)
--   edgeSet . <tt>edges</tt>    == Set.<a>fromList</a>
--   </pre>
edgeSet :: Ord a => AdjacencyMap a -> Set (a, a)

-- | The <i>preset</i> of an element <tt>x</tt> is the set of its <i>direct
--   predecessors</i>. Complexity: <i>O(n * log(n))</i> time and
--   <i>O(n)</i> memory.
--   
--   <pre>
--   preSet x (<a>vertex</a> x) == Set.<a>empty</a>
--   preSet 1 (<a>edge</a> 1 2) == Set.<a>empty</a>
--   preSet y (<a>edge</a> x y) == Set.<a>fromList</a> [x]
--   </pre>
preSet :: Ord a => a -> AdjacencyMap a -> Set a

-- | The <i>postset</i> of a vertex is the set of its <i>direct
--   successors</i>. Complexity: <i>O(log(n))</i> time and <i>O(1)</i>
--   memory.
--   
--   <pre>
--   postSet x (<a>vertex</a> x) == Set.<a>empty</a>
--   postSet x (<a>edge</a> x y) == Set.<a>fromList</a> [y]
--   postSet 2 (<a>edge</a> 1 2) == Set.<a>empty</a>
--   </pre>
postSet :: Ord a => a -> AdjacencyMap a -> Set a

-- | The <i>path</i> on a list of vertices. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   path1 [x]       == <a>vertex</a> x
--   path1 [x,y]     == <a>edge</a> x y
--   path1 . <a>reverse</a> == <a>transpose</a> . path1
--   </pre>
path1 :: Ord a => NonEmpty a -> AdjacencyMap a

-- | The <i>circuit</i> on a list of vertices. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   circuit1 [x]       == <a>edge</a> x x
--   circuit1 [x,y]     == <a>edges1</a> [(x,y), (y,x)]
--   circuit1 . <a>reverse</a> == <a>transpose</a> . circuit1
--   </pre>
circuit1 :: Ord a => NonEmpty a -> AdjacencyMap a

-- | The <i>clique</i> on a list of vertices. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   clique1 [x]        == <a>vertex</a> x
--   clique1 [x,y]      == <a>edge</a> x y
--   clique1 [x,y,z]    == <a>edges1</a> [(x,y), (x,z), (y,z)]
--   clique1 (xs <a>&lt;&gt;</a> ys) == <a>connect</a> (clique1 xs) (clique1 ys)
--   clique1 . <a>reverse</a>  == <a>transpose</a> . clique1
--   </pre>
clique1 :: Ord a => NonEmpty a -> AdjacencyMap a

-- | The <i>biclique</i> on two lists of vertices. Complexity: <i>O(n *
--   log(n) + m)</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   biclique1 [x1,x2] [y1,y2] == <a>edges1</a> [(x1,y1), (x1,y2), (x2,y1), (x2,y2)]
--   biclique1 xs      ys      == <a>connect</a> (<a>vertices1</a> xs) (<a>vertices1</a> ys)
--   </pre>
biclique1 :: Ord a => NonEmpty a -> NonEmpty a -> AdjacencyMap a

-- | The <i>star</i> formed by a centre vertex connected to a list of
--   leaves. Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n +
--   m)</i> memory.
--   
--   <pre>
--   star x []    == <a>vertex</a> x
--   star x [y]   == <a>edge</a> x y
--   star x [y,z] == <a>edges1</a> [(x,y), (x,z)]
--   </pre>
star :: Ord a => a -> [a] -> AdjacencyMap a

-- | The <i>stars</i> formed by overlaying a list of <a>star</a>s. An
--   inverse of <tt>adjacencyList</tt>. Complexity: <i>O(L * log(n))</i>
--   time, memory and size, where <i>L</i> is the total size of the input.
--   
--   <pre>
--   stars1 [(x, [] )]               == <a>vertex</a> x
--   stars1 [(x, [y])]               == <a>edge</a> x y
--   stars1 [(x, ys )]               == <a>star</a> x ys
--   stars1                          == <a>overlays1</a> . <a>fmap</a> (<a>uncurry</a> <a>star</a>)
--   <a>overlay</a> (stars1 xs) (stars1 ys) == stars1 (xs <a>&lt;&gt;</a> ys)
--   </pre>
stars1 :: Ord a => NonEmpty (a, [a]) -> AdjacencyMap a

-- | The <i>tree graph</i> constructed from a given <a>Tree</a> data
--   structure. Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n +
--   m)</i> memory.
--   
--   <pre>
--   tree (Node x [])                                         == <a>vertex</a> x
--   tree (Node x [Node y [Node z []]])                       == <a>path1</a> [x,y,z]
--   tree (Node x [Node y [], Node z []])                     == <a>star</a> x [y,z]
--   tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) == <a>edges1</a> [(1,2), (1,3), (3,4), (3,5)]
--   </pre>
tree :: Ord a => Tree a -> AdjacencyMap a

-- | Remove a vertex from a given graph. Complexity: <i>O(n*log(n))</i>
--   time.
--   
--   <pre>
--   removeVertex1 x (<a>vertex</a> x)          == Nothing
--   removeVertex1 1 (<a>vertex</a> 2)          == Just (<a>vertex</a> 2)
--   removeVertex1 x (<a>edge</a> x x)          == Nothing
--   removeVertex1 1 (<a>edge</a> 1 2)          == Just (<a>vertex</a> 2)
--   removeVertex1 x <a>&gt;=&gt;</a> removeVertex1 x == removeVertex1 x
--   </pre>
removeVertex1 :: Ord a => a -> AdjacencyMap a -> Maybe (AdjacencyMap a)

-- | Remove an edge from a given graph. Complexity: <i>O(log(n))</i> time.
--   
--   <pre>
--   removeEdge x y (<a>edge</a> x y)       == <a>vertices1</a> [x,y]
--   removeEdge x y . removeEdge x y == removeEdge x y
--   removeEdge 1 1 (1 * 1 * 2 * 2)  == 1 * 2 * 2
--   removeEdge 1 2 (1 * 1 * 2 * 2)  == 1 * 1 + 2 * 2
--   </pre>
removeEdge :: Ord a => a -> a -> AdjacencyMap a -> AdjacencyMap a

-- | The function <tt><a>replaceVertex</a> x y</tt> replaces vertex
--   <tt>x</tt> with vertex <tt>y</tt> in a given <a>AdjacencyMap</a>. If
--   <tt>y</tt> already exists, <tt>x</tt> and <tt>y</tt> will be merged.
--   Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   replaceVertex x x            == id
--   replaceVertex x y (<a>vertex</a> x) == <a>vertex</a> y
--   replaceVertex x y            == <a>mergeVertices</a> (== x) y
--   </pre>
replaceVertex :: Ord a => a -> a -> AdjacencyMap a -> AdjacencyMap a

-- | Merge vertices satisfying a given predicate into a given vertex.
--   Complexity: <i>O((n + m) * log(n))</i> time, assuming that the
--   predicate takes constant time.
--   
--   <pre>
--   mergeVertices (<a>const</a> False) x    == id
--   mergeVertices (== x) y           == <a>replaceVertex</a> x y
--   mergeVertices <a>even</a> 1 (0 * 2)     == 1 * 1
--   mergeVertices <a>odd</a>  1 (3 + 4 * 5) == 4 * 1
--   </pre>
mergeVertices :: Ord a => (a -> Bool) -> a -> AdjacencyMap a -> AdjacencyMap a

-- | Transpose a given graph. Complexity: <i>O(m * log(n))</i> time, <i>O(n
--   + m)</i> memory.
--   
--   <pre>
--   transpose (<a>vertex</a> x)  == <a>vertex</a> x
--   transpose (<a>edge</a> x y)  == <a>edge</a> y x
--   transpose . transpose == id
--   <a>edgeList</a> . transpose  == <a>sort</a> . <a>map</a> <a>swap</a> . <a>edgeList</a>
--   </pre>
transpose :: Ord a => AdjacencyMap a -> AdjacencyMap a

-- | Transform a graph by applying a function to each of its vertices. This
--   is similar to <tt>Functor</tt>'s <a>fmap</a> but can be used with
--   non-fully-parametric <a>AdjacencyMap</a>. Complexity: <i>O((n + m) *
--   log(n))</i> time.
--   
--   <pre>
--   gmap f (<a>vertex</a> x) == <a>vertex</a> (f x)
--   gmap f (<a>edge</a> x y) == <a>edge</a> (f x) (f y)
--   gmap id           == id
--   gmap f . gmap g   == gmap (f . g)
--   </pre>
gmap :: (Ord a, Ord b) => (a -> b) -> AdjacencyMap a -> AdjacencyMap b

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that do not satisfy a given predicate. Complexity:
--   <i>O(m)</i> time, assuming that the predicate takes constant time.
--   
--   <pre>
--   induce1 (<a>const</a> True ) x == Just x
--   induce1 (<a>const</a> False) x == Nothing
--   induce1 (/= x)          == <a>removeVertex1</a> x
--   induce1 p <a>&gt;=&gt;</a> induce1 q == induce1 (\x -&gt; p x &amp;&amp; q x)
--   </pre>
induce1 :: (a -> Bool) -> AdjacencyMap a -> Maybe (AdjacencyMap a)

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that are <a>Nothing</a>. Returns <a>Nothing</a> if the
--   resulting graph is empty. Complexity: <i>O(n + m)</i> time.
--   
--   <pre>
--   induceJust1 (<a>vertex</a> <a>Nothing</a>)                               == <a>Nothing</a>
--   induceJust1 (<a>edge</a> (<a>Just</a> x) <a>Nothing</a>)                        == <a>Just</a> (<a>vertex</a> x)
--   induceJust1 . <a>gmap</a> <a>Just</a>                                    == <a>Just</a>
--   induceJust1 . <a>gmap</a> (\x -&gt; if p x then <a>Just</a> x else <a>Nothing</a>) == <a>induce1</a> p
--   </pre>
induceJust1 :: Ord a => AdjacencyMap (Maybe a) -> Maybe (AdjacencyMap a)

-- | Compute the <i>reflexive and transitive closure</i> of a graph.
--   Complexity: <i>O(n * m * log(n)^2)</i> time.
--   
--   <pre>
--   closure (<a>vertex</a> x)       == <a>edge</a> x x
--   closure (<a>edge</a> x x)       == <a>edge</a> x x
--   closure (<a>edge</a> x y)       == <a>edges1</a> [(x,x), (x,y), (y,y)]
--   closure (<a>path1</a> $ <a>nub</a> xs) == <a>reflexiveClosure</a> (<a>clique1</a> $ <a>nub</a> xs)
--   closure                  == <a>reflexiveClosure</a> . <a>transitiveClosure</a>
--   closure                  == <a>transitiveClosure</a> . <a>reflexiveClosure</a>
--   closure . closure        == closure
--   <a>postSet</a> x (closure y)    == Set.<a>fromList</a> (<a>reachable</a> x y)
--   </pre>
closure :: Ord a => AdjacencyMap a -> AdjacencyMap a

-- | Compute the <i>reflexive closure</i> of a graph by adding a self-loop
--   to every vertex. Complexity: <i>O(n * log(n))</i> time.
--   
--   <pre>
--   reflexiveClosure (<a>vertex</a> x)         == <a>edge</a> x x
--   reflexiveClosure (<a>edge</a> x x)         == <a>edge</a> x x
--   reflexiveClosure (<a>edge</a> x y)         == <a>edges1</a> [(x,x), (x,y), (y,y)]
--   reflexiveClosure . reflexiveClosure == reflexiveClosure
--   </pre>
reflexiveClosure :: Ord a => AdjacencyMap a -> AdjacencyMap a

-- | Compute the <i>symmetric closure</i> of a graph by overlaying it with
--   its own transpose. Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   symmetricClosure (<a>vertex</a> x)         == <a>vertex</a> x
--   symmetricClosure (<a>edge</a> x y)         == <a>edges1</a> [(x,y), (y,x)]
--   symmetricClosure x                  == <a>overlay</a> x (<a>transpose</a> x)
--   symmetricClosure . symmetricClosure == symmetricClosure
--   </pre>
symmetricClosure :: Ord a => AdjacencyMap a -> AdjacencyMap a

-- | Compute the <i>transitive closure</i> of a graph. Complexity: <i>O(n *
--   m * log(n)^2)</i> time.
--   
--   <pre>
--   transitiveClosure (<a>vertex</a> x)          == <a>vertex</a> x
--   transitiveClosure (<a>edge</a> x y)          == <a>edge</a> x y
--   transitiveClosure (<a>path1</a> $ <a>nub</a> xs)    == <a>clique1</a> (<a>nub</a> xs)
--   transitiveClosure . transitiveClosure == transitiveClosure
--   </pre>
transitiveClosure :: Ord a => AdjacencyMap a -> AdjacencyMap a

-- | Check that the internal graph representation is consistent, i.e. that
--   all edges refer to existing vertices, and the graph is non-empty. It
--   should be impossible to create an inconsistent adjacency map, and we
--   use this function in testing.
--   
--   <pre>
--   consistent (<a>vertex</a> x)    == True
--   consistent (<a>overlay</a> x y) == True
--   consistent (<a>connect</a> x y) == True
--   consistent (<a>edge</a> x y)    == True
--   consistent (<tt>edges</tt> xs)    == True
--   consistent (<tt>stars</tt> xs)    == True
--   </pre>
consistent :: Ord a => AdjacencyMap a -> Bool
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.NonEmpty.AdjacencyMap.AdjacencyMap a)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Algebra.Graph.NonEmpty.AdjacencyMap.AdjacencyMap a)
instance Data.String.IsString a => Data.String.IsString (Algebra.Graph.NonEmpty.AdjacencyMap.AdjacencyMap a)
instance GHC.Generics.Generic (Algebra.Graph.NonEmpty.AdjacencyMap.AdjacencyMap a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Algebra.Graph.NonEmpty.AdjacencyMap.AdjacencyMap a)
instance (GHC.Classes.Ord a, GHC.Num.Num a) => GHC.Num.Num (Algebra.Graph.NonEmpty.AdjacencyMap.AdjacencyMap a)
instance (GHC.Classes.Ord a, GHC.Show.Show a) => GHC.Show.Show (Algebra.Graph.NonEmpty.AdjacencyMap.AdjacencyMap a)
instance GHC.Classes.Ord a => GHC.Base.Semigroup (Algebra.Graph.NonEmpty.AdjacencyMap.AdjacencyMap a)


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module provides basic graph algorithms, such as <i>depth-first
--   search</i>, implemented for the <a>Algebra.Graph.AdjacencyMap</a> data
--   type.
module Algebra.Graph.AdjacencyMap.Algorithm

-- | Compute the <i>breadth-first search</i> forest of a graph, such that
--   adjacent vertices are explored in increasing order with respect to
--   their <a>Ord</a> instance. The search is seeded by a list of argument
--   vertices that will be the roots of the resulting forest. Duplicates in
--   the list will have their first occurrence expanded and subsequent ones
--   ignored. Argument vertices not in the graph are also ignored.
--   
--   Let <i>L</i> be the number of seed vertices. Complexity:
--   <i>O((L+m)*log n)</i> time and <i>O(n)</i> space.
--   
--   <pre>
--   <a>forest</a> (bfsForest [1,2] $ <a>edge</a> 1 2)      == <a>vertices</a> [1,2]
--   <a>forest</a> (bfsForest [2]   $ <a>edge</a> 1 2)      == <a>vertex</a> 2
--   <a>forest</a> (bfsForest [3]   $ <a>edge</a> 1 2)      == <a>empty</a>
--   <a>forest</a> (bfsForest [2,1] $ <a>edge</a> 1 2)      == <a>vertices</a> [1,2]
--   <a>isSubgraphOf</a> (<a>forest</a> $ bfsForest vs x) x == True
--   bfsForest (<a>vertexList</a> g) g               == <a>map</a> (v -&gt; Node v []) (<tt>nub</tt> $ <a>vertexList</a> g)
--   bfsForest [] x                           == []
--   bfsForest [1,4] (3 * (1 + 4) * (1 + 5))  == [ Node { rootLabel = 1
--                                                      , subForest = [ Node { rootLabel = 5
--                                                                           , subForest = [] }]}
--                                               , Node { rootLabel = 4
--                                                      , subForest = [] }]
--   <a>forest</a> (bfsForest [3] (<a>circuit</a> [1..5] + <a>circuit</a> [5,4..1])) == <a>path</a> [3,2,1] + <a>path</a> [3,4,5]
--   </pre>
bfsForest :: Ord a => [a] -> AdjacencyMap a -> Forest a

-- | This is <a>bfsForest</a> with the resulting forest converted to a
--   level structure. Adjacent vertices are explored in increasing order
--   with respect to their <a>Ord</a> instance. Flattening the result via
--   <tt><a>concat</a> . <a>bfs</a> vs</tt> gives an enumeration of
--   vertices reachable from <tt>vs</tt> in breadth first order.
--   
--   Let <i>L</i> be the number of seed vertices. Complexity:
--   <i>O((L+m)*log n)</i> time and <i>O(n)</i> space.
--   
--   <pre>
--   bfs vs <a>empty</a>                                         == []
--   bfs [] g                                             == []
--   bfs [1]   (<a>edge</a> 1 1)                                 == [[1]]
--   bfs [1]   (<a>edge</a> 1 2)                                 == [[1],[2]]
--   bfs [2]   (<a>edge</a> 1 2)                                 == [[2]]
--   bfs [1,2] (<a>edge</a> 1 2)                                 == [[1,2]]
--   bfs [2,1] (<a>edge</a> 1 2)                                 == [[2,1]]
--   bfs [3]   (<a>edge</a> 1 2)                                 == []
--   bfs [1,2] ( (1*2) + (3*4) + (5*6) )                  == [[1,2]]
--   bfs [1,3] ( (1*2) + (3*4) + (5*6) )                  == [[1,3],[2,4]]
--   bfs [3] (3 * (1 + 4) * (1 + 5))                      == [[3],[1,4,5]]
--   bfs [2] (<a>circuit</a> [1..5] + <a>circuit</a> [5,4..1])          == [[2],[1,3],[5,4]]
--   <a>concat</a> (bfs [3] $ <a>circuit</a> [1..5] + <a>circuit</a> [5,4..1]) == [3,2,4,1,5]
--   bfs vs == <a>map</a> <a>concat</a> . <a>transpose</a> . <a>map</a> <a>levels</a> . <a>bfsForest</a> vs
--   </pre>
bfs :: Ord a => [a] -> AdjacencyMap a -> [[a]]

-- | Compute the <i>depth-first search</i> forest of a graph, where
--   adjacent vertices are expanded in increasing order with respect to
--   their <a>Ord</a> instance.
--   
--   Complexity: <i>O((n+m)*log n)</i> time and <i>O(n)</i> space.
--   
--   <pre>
--   dfsForest <a>empty</a>                       == []
--   <a>forest</a> (dfsForest $ <a>edge</a> 1 1)         == <a>vertex</a> 1
--   <a>forest</a> (dfsForest $ <a>edge</a> 1 2)         == <a>edge</a> 1 2
--   <a>forest</a> (dfsForest $ <a>edge</a> 2 1)         == <a>vertices</a> [1,2]
--   <a>isSubgraphOf</a> (<a>forest</a> $ dfsForest x) x == True
--   <a>isDfsForestOf</a> (dfsForest x) x         == True
--   dfsForest . <a>forest</a> . dfsForest        == dfsForest
--   dfsForest (<a>vertices</a> vs)               == <a>map</a> (\v -&gt; Node v []) (<a>nub</a> $ <a>sort</a> vs)
--   <a>dfsForestFrom</a> (<a>vertexList</a> x) x        == dfsForest x
--   dfsForest $ 3 * (1 + 4) * (1 + 5)     == [ Node { rootLabel = 1
--                                                   , subForest = [ Node { rootLabel = 5
--                                                                        , subForest = [] }]}
--                                            , Node { rootLabel = 3
--                                                   , subForest = [ Node { rootLabel = 4
--                                                                        , subForest = [] }]}]
--   <a>forest</a> (dfsForest $ <a>circuit</a> [1..5] + <a>circuit</a> [5,4..1]) == <a>path</a> [1,2,3,4,5]
--   </pre>
dfsForest :: Ord a => AdjacencyMap a -> Forest a

-- | Compute the <i>depth-first search</i> forest of a graph from the given
--   vertices, where adjacent vertices are expanded in increasing order
--   with respect to their <a>Ord</a> instance. Note that the resulting
--   forest does not necessarily span the whole graph, as some vertices may
--   be unreachable. Any of the given vertices which are not in the graph
--   are ignored.
--   
--   Let <i>L</i> be the number of seed vertices. Complexity:
--   <i>O((L+m)*log n)</i> time and <i>O(n)</i> space.
--   
--   <pre>
--   dfsForestFrom vs <a>empty</a>                           == []
--   <a>forest</a> (dfsForestFrom [1]   $ <a>edge</a> 1 1)          == <a>vertex</a> 1
--   <a>forest</a> (dfsForestFrom [1]   $ <a>edge</a> 1 2)          == <a>edge</a> 1 2
--   <a>forest</a> (dfsForestFrom [2]   $ <a>edge</a> 1 2)          == <a>vertex</a> 2
--   <a>forest</a> (dfsForestFrom [3]   $ <a>edge</a> 1 2)          == <a>empty</a>
--   <a>forest</a> (dfsForestFrom [2,1] $ <a>edge</a> 1 2)          == <a>vertices</a> [1,2]
--   <a>isSubgraphOf</a> (<a>forest</a> $ dfsForestFrom vs x) x     == True
--   <a>isDfsForestOf</a> (dfsForestFrom (<a>vertexList</a> x) x) x == True
--   dfsForestFrom (<a>vertexList</a> x) x                   == <a>dfsForest</a> x
--   dfsForestFrom vs             (<a>vertices</a> vs)       == <a>map</a> (\v -&gt; Node v []) (<a>nub</a> vs)
--   dfsForestFrom []             x                   == []
--   dfsForestFrom [1,4] $ 3 * (1 + 4) * (1 + 5)      == [ Node { rootLabel = 1
--                                                              , subForest = [ Node { rootLabel = 5
--                                                                                   , subForest = [] }
--                                                       , Node { rootLabel = 4
--                                                              , subForest = [] }]
--    <a>forest</a> (dfsForestFrom [3] $ <a>circuit</a> [1..5] + <a>circuit</a> [5,4..1]) == <a>path</a> [3,2,1,5,4]
--   </pre>
dfsForestFrom :: Ord a => [a] -> AdjacencyMap a -> Forest a

-- | Compute the vertices visited by <i>depth-first search</i> in a graph
--   from the given vertices. Adjacent vertices are expanded in increasing
--   order with respect to their <a>Ord</a> instance.
--   
--   Let <i>L</i> be the number of seed vertices. Complexity:
--   <i>O((L+m)*log n)</i> time and <i>O(n)</i> space.
--   
--   <pre>
--   dfs vs    $ <a>empty</a>                    == []
--   dfs [1]   $ <a>edge</a> 1 1                 == [1]
--   dfs [1]   $ <a>edge</a> 1 2                 == [1,2]
--   dfs [2]   $ <a>edge</a> 1 2                 == [2]
--   dfs [3]   $ <a>edge</a> 1 2                 == []
--   dfs [1,2] $ <a>edge</a> 1 2                 == [1,2]
--   dfs [2,1] $ <a>edge</a> 1 2                 == [2,1]
--   dfs []    $ x                        == []
--   dfs [1,4] $ 3 * (1 + 4) * (1 + 5)    == [1,5,4]
--   <a>isSubgraphOf</a> (<a>vertices</a> $ dfs vs x) x == True
--   dfs [3] $ <a>circuit</a> [1..5] + <a>circuit</a> [5,4..1] == [3,2,1,5,4]
--   </pre>
dfs :: Ord a => [a] -> AdjacencyMap a -> [a]

-- | Compute the list of vertices that are <i>reachable</i> from a given
--   source vertex in a graph. The vertices in the resulting list appear in
--   <i>depth-first order</i>.
--   
--   Complexity: <i>O(m*log n)</i> time and <i>O(n)</i> space.
--   
--   <pre>
--   reachable x $ <a>empty</a>                       == []
--   reachable 1 $ <a>vertex</a> 1                    == [1]
--   reachable 1 $ <a>vertex</a> 2                    == []
--   reachable 1 $ <a>edge</a> 1 1                    == [1]
--   reachable 1 $ <a>edge</a> 1 2                    == [1,2]
--   reachable 4 $ <a>path</a>    [1..8]              == [4..8]
--   reachable 4 $ <a>circuit</a> [1..8]              == [4..8] ++ [1..3]
--   reachable 8 $ <a>clique</a>  [8,7..1]            == [8] ++ [1..7]
--   <a>isSubgraphOf</a> (<a>vertices</a> $ reachable x y) y == True
--   </pre>
reachable :: Ord a => a -> AdjacencyMap a -> [a]

-- | Compute a topological sort of a DAG or discover a cycle.
--   
--   Vertices are expanded in decreasing order with respect to their
--   <a>Ord</a> instance. This gives the lexicographically smallest
--   topological ordering in the case of success. In the case of failure,
--   the cycle is characterized by being the lexicographically smallest up
--   to rotation with respect to <tt>Ord (Dual a)</tt> in the first
--   connected component of the graph containing a cycle, where the
--   connected components are ordered by their largest vertex with respect
--   to <tt>Ord a</tt>.
--   
--   Complexity: <i>O((n+m)*log n)</i> time and <i>O(n)</i> space.
--   
--   <pre>
--   topSort (1 * 2 + 3 * 1)                    == Right [3,1,2]
--   topSort (<a>path</a> [1..5])                      == Right [1..5]
--   topSort (3 * (1 * 4 + 2 * 5))              == Right [3,1,2,4,5]
--   topSort (1 * 2 + 2 * 1)                    == Left (2 <a>:|</a> [1])
--   topSort (<a>path</a> [5,4..1] + <a>edge</a> 2 4)         == Left (4 <a>:|</a> [3,2])
--   topSort (<a>circuit</a> [1..3])                   == Left (3 <a>:|</a> [1,2])
--   topSort (<a>circuit</a> [1..3] + <a>circuit</a> [3,2,1]) == Left (3 <a>:|</a> [2])
--   topSort (1*2 + 2*1 + 3*4 + 4*3 + 5*1)      == Left (1 <a>:|</a> [2])
--   fmap (<a>flip</a> <a>isTopSortOf</a> x) (topSort x)      /= Right False
--   <a>isRight</a> . topSort                          == <a>isAcyclic</a>
--   topSort . <a>vertices</a>                         == Right . <tt>nub</tt> . <tt>sort</tt>
--   </pre>
topSort :: Ord a => AdjacencyMap a -> Either (Cycle a) [a]

-- | Check if a given graph is <i>acyclic</i>.
--   
--   Complexity: <i>O((n+m)*log n)</i> time and <i>O(n)</i> space.
--   
--   <pre>
--   isAcyclic (1 * 2 + 3 * 1) == True
--   isAcyclic (1 * 2 + 2 * 1) == False
--   isAcyclic . <a>circuit</a>       == <a>null</a>
--   isAcyclic                 == <a>isRight</a> . <a>topSort</a>
--   </pre>
isAcyclic :: Ord a => AdjacencyMap a -> Bool

-- | Compute the <i>condensation</i> of a graph, where each vertex
--   corresponds to a <i>strongly-connected component</i> of the original
--   graph. Note that component graphs are non-empty, and are therefore of
--   type <a>Algebra.Graph.NonEmpty.AdjacencyMap</a>.
--   
--   Details about the implementation can be found at <a>gabow-notes</a>.
--   
--   Complexity: <i>O((n+m)*log n)</i> time and <i>O(n+m)</i> space.
--   
--   <pre>
--   scc <a>empty</a>               == <a>empty</a>
--   scc (<a>vertex</a> x)          == <a>vertex</a> (NonEmpty.<a>vertex</a> x)
--   scc (<a>vertices</a> xs)       == <a>vertices</a> (<a>map</a> <a>vertex</a> xs)
--   scc (<a>edge</a> 1 1)          == <a>vertex</a> (NonEmpty.<a>edge</a> 1 1)
--   scc (<a>edge</a> 1 2)          == <a>edge</a>   (NonEmpty.<a>vertex</a> 1) (NonEmpty.<a>vertex</a> 2)
--   scc (<a>circuit</a> (1:xs))    == <a>vertex</a> (NonEmpty.<a>circuit1</a> (1 <a>:|</a> xs))
--   scc (3 * 1 * 4 * 1 * 5) == <a>edges</a>  [ (NonEmpty.<a>vertex</a>  3      , NonEmpty.<a>vertex</a>  5      )
--                                     , (NonEmpty.<a>vertex</a>  3      , NonEmpty.<a>clique1</a> [1,4,1])
--                                     , (NonEmpty.<a>clique1</a> [1,4,1], NonEmpty.<a>vertex</a>  5      ) ]
--   <a>isAcyclic</a> . scc == <a>const</a> True
--   <a>isAcyclic</a> x     == (scc x == <a>gmap</a> NonEmpty.<a>vertex</a> x)
--   </pre>
scc :: Ord a => AdjacencyMap a -> AdjacencyMap (AdjacencyMap a)

-- | Check if a given forest is a correct <i>depth-first search</i> forest
--   of a graph. The implementation is based on the paper "Depth-First
--   Search and Strong Connectivity in Coq" by François Pottier.
--   
--   <pre>
--   isDfsForestOf []                              <a>empty</a>            == True
--   isDfsForestOf []                              (<a>vertex</a> 1)       == False
--   isDfsForestOf [Node 1 []]                     (<a>vertex</a> 1)       == True
--   isDfsForestOf [Node 1 []]                     (<a>vertex</a> 2)       == False
--   isDfsForestOf [Node 1 [], Node 1 []]          (<a>vertex</a> 1)       == False
--   isDfsForestOf [Node 1 []]                     (<a>edge</a> 1 1)       == True
--   isDfsForestOf [Node 1 []]                     (<a>edge</a> 1 2)       == False
--   isDfsForestOf [Node 1 [], Node 2 []]          (<a>edge</a> 1 2)       == False
--   isDfsForestOf [Node 2 [], Node 1 []]          (<a>edge</a> 1 2)       == True
--   isDfsForestOf [Node 1 [Node 2 []]]            (<a>edge</a> 1 2)       == True
--   isDfsForestOf [Node 1 [], Node 2 []]          (<a>vertices</a> [1,2]) == True
--   isDfsForestOf [Node 2 [], Node 1 []]          (<a>vertices</a> [1,2]) == True
--   isDfsForestOf [Node 1 [Node 2 []]]            (<a>vertices</a> [1,2]) == False
--   isDfsForestOf [Node 1 [Node 2 [Node 3 []]]]   (<a>path</a> [1,2,3])   == True
--   isDfsForestOf [Node 1 [Node 3 [Node 2 []]]]   (<a>path</a> [1,2,3])   == False
--   isDfsForestOf [Node 3 [], Node 1 [Node 2 []]] (<a>path</a> [1,2,3])   == True
--   isDfsForestOf [Node 2 [Node 3 []], Node 1 []] (<a>path</a> [1,2,3])   == True
--   isDfsForestOf [Node 1 [], Node 2 [Node 3 []]] (<a>path</a> [1,2,3])   == False
--   </pre>
isDfsForestOf :: Ord a => Forest a -> AdjacencyMap a -> Bool

-- | Check if a given list of vertices is a correct <i>topological sort</i>
--   of a graph.
--   
--   <pre>
--   isTopSortOf [3,1,2] (1 * 2 + 3 * 1) == True
--   isTopSortOf [1,2,3] (1 * 2 + 3 * 1) == False
--   isTopSortOf []      (1 * 2 + 3 * 1) == False
--   isTopSortOf []      <a>empty</a>           == True
--   isTopSortOf [x]     (<a>vertex</a> x)      == True
--   isTopSortOf [x]     (<a>edge</a> x x)      == False
--   </pre>
isTopSortOf :: Ord a => [a] -> AdjacencyMap a -> Bool
type Cycle = NonEmpty
instance (GHC.Show.Show a, GHC.Classes.Ord a) => GHC.Show.Show (Algebra.Graph.AdjacencyMap.Algorithm.StateSCC a)


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module defines the <a>AdjacencyMap</a> data type and for acyclic
--   graphs, as well as associated operations and algorithms. To avoid name
--   clashes with <a>Algebra.Graph.AdjacencyMap</a>, this module can be
--   imported qualified:
--   
--   <pre>
--   import qualified Algebra.Graph.Acyclic.AdjacencyMap as Acyclic
--   </pre>
module Algebra.Graph.Acyclic.AdjacencyMap

-- | The <a>AdjacencyMap</a> data type represents an acyclic graph by a map
--   of vertices to their adjacency sets. Although the internal
--   representation allows for cycles, the methods provided by this module
--   cannot be used to construct a graph with cycles.
--   
--   The <a>Show</a> instance is defined using basic graph construction
--   primitives where possible, falling back to <a>toAcyclic</a> and
--   <a>Algebra.Graph.AdjacencyMap</a> otherwise:
--   
--   <pre>
--   show empty                == "empty"
--   show (shrink 1)           == "vertex 1"
--   show (shrink $ 1 + 2)     == "vertices [1,2]"
--   show (shrink $ 1 * 2)     == "(fromJust . toAcyclic) (edge 1 2)"
--   show (shrink $ 1 * 2 * 3) == "(fromJust . toAcyclic) (edges [(1,2),(1,3),(2,3)])"
--   show (shrink $ 1 * 2 + 3) == "(fromJust . toAcyclic) (overlay (vertex 3) (edge 1 2))"
--   </pre>
--   
--   The total order on graphs is defined using <i>size-lexicographic</i>
--   comparison:
--   
--   <ul>
--   <li>Compare the number of vertices. In case of a tie, continue.</li>
--   <li>Compare the sets of vertices. In case of a tie, continue.</li>
--   <li>Compare the number of edges. In case of a tie, continue.</li>
--   <li>Compare the sets of edges.</li>
--   </ul>
--   
--   Note that the resulting order refines the <a>isSubgraphOf</a>
--   relation:
--   
--   <pre>
--   <a>isSubgraphOf</a> x y ==&gt; x &lt;= y
--   </pre>
data AdjacencyMap a

-- | Extract the underlying acyclic <a>Algebra.Graph.AdjacencyMap</a>.
--   Complexity: <i>O(1)</i> time and memory.
--   
--   <pre>
--   fromAcyclic <a>empty</a>                == <a>empty</a>
--   fromAcyclic . <a>vertex</a>             == <a>vertex</a>
--   fromAcyclic (shrink $ 1 * 3 + 2) == 1 * 3 + 2
--   <a>vertexCount</a> . fromAcyclic        == <a>vertexCount</a>
--   <a>edgeCount</a>   . fromAcyclic        == <a>edgeCount</a>
--   <a>isAcyclic</a>   . fromAcyclic        == <a>const</a> True
--   </pre>
fromAcyclic :: AdjacencyMap a -> AdjacencyMap a

-- | Construct the <i>empty graph</i>.
--   
--   <pre>
--   <a>isEmpty</a>     empty == True
--   <a>hasVertex</a> x empty == False
--   <a>vertexCount</a> empty == 0
--   <a>edgeCount</a>   empty == 0
--   </pre>
empty :: AdjacencyMap a

-- | Construct the graph comprising <i>a single isolated vertex</i>.
--   
--   <pre>
--   <a>isEmpty</a>     (vertex x) == False
--   <a>hasVertex</a> x (vertex y) == (x == y)
--   <a>vertexCount</a> (vertex x) == 1
--   <a>edgeCount</a>   (vertex x) == 0
--   </pre>
vertex :: a -> AdjacencyMap a

-- | Construct the graph comprising a given list of isolated vertices.
--   Complexity: <i>O(L * log(L))</i> time and <i>O(L)</i> memory, where
--   <i>L</i> is the length of the given list.
--   
--   <pre>
--   vertices []            == <a>empty</a>
--   vertices [x]           == <a>vertex</a> x
--   <a>hasVertex</a> x . vertices == <a>elem</a> x
--   <a>vertexCount</a> . vertices == <a>length</a> . <a>nub</a>
--   <a>vertexSet</a>   . vertices == Set.<a>fromList</a>
--   </pre>
vertices :: Ord a => [a] -> AdjacencyMap a

-- | Construct the disjoint <i>union</i> of two graphs. Complexity: <i>O((n
--   + m) * log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   <a>vertexSet</a> (union x y) == Set.<a>unions</a> [ Set.<a>map</a> <a>Left</a>  (<a>vertexSet</a> x)
--                                       , Set.<a>map</a> <a>Right</a> (<a>vertexSet</a> y) ]
--   
--   <a>edgeSet</a>   (union x y) == Set.<a>unions</a> [ Set.<a>map</a> (<a>bimap</a> <a>Left</a>  <a>Left</a> ) (<a>edgeSet</a> x)
--                                       , Set.<a>map</a> (<a>bimap</a> <a>Right</a> <a>Right</a>) (<a>edgeSet</a> y) ]
--   </pre>
union :: (Ord a, Ord b) => AdjacencyMap a -> AdjacencyMap b -> AdjacencyMap (Either a b)

-- | Construct the <i>join</i> of two graphs. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   <a>vertexSet</a> (join x y) == Set.<a>unions</a> [ Set.<a>map</a> <a>Left</a>  (<a>vertexSet</a> x)
--                                      , Set.<a>map</a> <a>Right</a> (<a>vertexSet</a> y) ]
--   
--   <a>edgeSet</a>   (join x y) == Set.<a>unions</a> [ Set.<a>map</a> (<a>bimap</a> <a>Left</a>  <a>Left</a> ) (<a>edgeSet</a> x)
--                                      , Set.<a>map</a> (<a>bimap</a> <a>Right</a> <a>Right</a>) (<a>edgeSet</a> y)
--                                      , Set.<a>map</a> (<a>bimap</a> <a>Left</a>  <a>Right</a>) (Set.<a>cartesianProduct</a> (<a>vertexSet</a> x) (<a>vertexSet</a> y)) ]
--   </pre>
join :: (Ord a, Ord b) => AdjacencyMap a -> AdjacencyMap b -> AdjacencyMap (Either a b)

-- | The <a>isSubgraphOf</a> function takes two graphs and returns
--   <a>True</a> if the first graph is a <i>subgraph</i> of the second.
--   Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   isSubgraphOf <a>empty</a>        x                     ==  True
--   isSubgraphOf (<a>vertex</a> x)   <a>empty</a>                 ==  False
--   isSubgraphOf (<a>induce</a> p x) x                     ==  True
--   isSubgraphOf x            (<a>transitiveClosure</a> x) ==  True
--   isSubgraphOf x y                                ==&gt; x &lt;= y
--   </pre>
isSubgraphOf :: Ord a => AdjacencyMap a -> AdjacencyMap a -> Bool

-- | Check if a graph is empty. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   isEmpty <a>empty</a>                             == True
--   isEmpty (<a>vertex</a> x)                        == False
--   isEmpty (<a>removeVertex</a> x $ <a>vertex</a> x)       == True
--   isEmpty (<a>removeEdge</a> 1 2 $ shrink $ 1 * 2) == False
--   </pre>
isEmpty :: AdjacencyMap a -> Bool

-- | Check if a graph contains a given vertex. Complexity: <i>O(log(n))</i>
--   time.
--   
--   <pre>
--   hasVertex x <a>empty</a>            == False
--   hasVertex x (<a>vertex</a> y)       == (x == y)
--   hasVertex x . <a>removeVertex</a> x == <a>const</a> False
--   </pre>
hasVertex :: Ord a => a -> AdjacencyMap a -> Bool

-- | Check if a graph contains a given edge. Complexity: <i>O(log(n))</i>
--   time.
--   
--   <pre>
--   hasEdge x y <a>empty</a>            == False
--   hasEdge x y (<a>vertex</a> z)       == False
--   hasEdge 1 2 (shrink $ 1 * 2) == True
--   hasEdge x y . <a>removeEdge</a> x y == <a>const</a> False
--   hasEdge x y                  == <a>elem</a> (x,y) . <a>edgeList</a>
--   </pre>
hasEdge :: Ord a => a -> a -> AdjacencyMap a -> Bool

-- | The number of vertices in a graph. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   vertexCount <a>empty</a>             ==  0
--   vertexCount (<a>vertex</a> x)        ==  1
--   vertexCount                   ==  <a>length</a> . <a>vertexList</a>
--   vertexCount x &lt; vertexCount y ==&gt; x &lt; y
--   </pre>
vertexCount :: AdjacencyMap a -> Int

-- | The number of edges in a graph. Complexity: <i>O(n)</i> time.
--   
--   <pre>
--   edgeCount <a>empty</a>            == 0
--   edgeCount (<a>vertex</a> x)       == 0
--   edgeCount (shrink $ 1 * 2) == 1
--   edgeCount                  == <a>length</a> . <a>edgeList</a>
--   </pre>
edgeCount :: AdjacencyMap a -> Int

-- | The sorted list of vertices of a given graph. Complexity: <i>O(n)</i>
--   time and memory.
--   
--   <pre>
--   vertexList <a>empty</a>      == []
--   vertexList (<a>vertex</a> x) == [x]
--   vertexList . <a>vertices</a> == <a>nub</a> . <a>sort</a>
--   </pre>
vertexList :: AdjacencyMap a -> [a]

-- | The sorted list of edges of a graph. Complexity: <i>O(n + m)</i> time
--   and <i>O(m)</i> memory.
--   
--   <pre>
--   edgeList <a>empty</a>            == []
--   edgeList (<a>vertex</a> x)       == []
--   edgeList (shrink $ 2 * 1) == [(2,1)]
--   edgeList . <a>transpose</a>      == <a>sort</a> . <a>map</a> <a>swap</a> . edgeList
--   </pre>
edgeList :: AdjacencyMap a -> [(a, a)]

-- | The sorted <i>adjacency list</i> of a graph. Complexity: <i>O(n +
--   m)</i> time and memory.
--   
--   <pre>
--   adjacencyList <a>empty</a>            == []
--   adjacencyList (<a>vertex</a> x)       == [(x, [])]
--   adjacencyList (shrink $ 1 * 2) == [(1, [2]), (2, [])]
--   </pre>
adjacencyList :: AdjacencyMap a -> [(a, [a])]

-- | The set of vertices of a given graph. Complexity: <i>O(n)</i> time and
--   memory.
--   
--   <pre>
--   vertexSet <a>empty</a>      == Set.<a>empty</a>
--   vertexSet . <a>vertex</a>   == Set.<a>singleton</a>
--   vertexSet . <a>vertices</a> == Set.<a>fromList</a>
--   </pre>
vertexSet :: AdjacencyMap a -> Set a

-- | The set of edges of a given graph. Complexity: <i>O((n + m) *
--   log(m))</i> time and <i>O(m)</i> memory.
--   
--   <pre>
--   edgeSet <a>empty</a>            == Set.<a>empty</a>
--   edgeSet (<a>vertex</a> x)       == Set.<a>empty</a>
--   edgeSet (shrink $ 1 * 2) == Set.<a>singleton</a> (1,2)
--   </pre>
edgeSet :: Eq a => AdjacencyMap a -> Set (a, a)

-- | The <i>preset</i> of an element <tt>x</tt> is the set of its <i>direct
--   predecessors</i>. Complexity: <i>O(n * log(n))</i> time and
--   <i>O(n)</i> memory.
--   
--   <pre>
--   preSet x <a>empty</a>            == Set.<a>empty</a>
--   preSet x (<a>vertex</a> x)       == Set.<a>empty</a>
--   preSet 1 (shrink $ 1 * 2) == Set.<a>empty</a>
--   preSet 2 (shrink $ 1 * 2) == Set.<a>fromList</a> [1]
--   Set.<a>member</a> x . preSet x   == <a>const</a> False
--   </pre>
preSet :: Ord a => a -> AdjacencyMap a -> Set a

-- | The <i>postset</i> of a vertex is the set of its <i>direct
--   successors</i>. Complexity: <i>O(log(n))</i> time and <i>O(1)</i>
--   memory.
--   
--   <pre>
--   postSet x <a>empty</a>            == Set.<a>empty</a>
--   postSet x (<a>vertex</a> x)       == Set.<a>empty</a>
--   postSet 1 (shrink $ 1 * 2) == Set.<a>fromList</a> [2]
--   postSet 2 (shrink $ 1 * 2) == Set.<a>empty</a>
--   Set.<a>member</a> x . postSet x   == <a>const</a> False
--   </pre>
postSet :: Ord a => a -> AdjacencyMap a -> Set a

-- | Remove a vertex from a given acyclic graph. Complexity:
--   <i>O(n*log(n))</i> time.
--   
--   <pre>
--   removeVertex x (<a>vertex</a> x)       == <a>empty</a>
--   removeVertex 1 (<a>vertex</a> 2)       == <a>vertex</a> 2
--   removeVertex 1 (shrink $ 1 * 2) == <a>vertex</a> 2
--   removeVertex x . removeVertex x == removeVertex x
--   </pre>
removeVertex :: Ord a => a -> AdjacencyMap a -> AdjacencyMap a

-- | Remove an edge from a given acyclic graph. Complexity:
--   <i>O(log(n))</i> time.
--   
--   <pre>
--   removeEdge 1 2 (shrink $ 1 * 2)     == <a>vertices</a> [1,2]
--   removeEdge x y . removeEdge x y     == removeEdge x y
--   removeEdge x y . <a>removeVertex</a> x     == <a>removeVertex</a> x
--   removeEdge 1 2 (shrink $ 1 * 2 * 3) == shrink ((1 + 2) * 3)
--   </pre>
removeEdge :: Ord a => a -> a -> AdjacencyMap a -> AdjacencyMap a

-- | Transpose a given acyclic graph. Complexity: <i>O(m * log(n))</i>
--   time, <i>O(n + m)</i> memory.
--   
--   <pre>
--   transpose <a>empty</a>       == <a>empty</a>
--   transpose (<a>vertex</a> x)  == <a>vertex</a> x
--   transpose . transpose == id
--   <a>edgeList</a> . transpose  == <a>sort</a> . <a>map</a> <a>swap</a> . <a>edgeList</a>
--   </pre>
transpose :: Ord a => AdjacencyMap a -> AdjacencyMap a

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that do not satisfy a given predicate. Complexity: <i>O(n +
--   m)</i> time, assuming that the predicate takes constant time.
--   
--   <pre>
--   induce (<a>const</a> True ) x      == x
--   induce (<a>const</a> False) x      == <a>empty</a>
--   induce (/= x)               == <a>removeVertex</a> x
--   induce p . induce q         == induce (x -&gt; p x &amp;&amp; q x)
--   <a>isSubgraphOf</a> (induce p x) x == True
--   </pre>
induce :: (a -> Bool) -> AdjacencyMap a -> AdjacencyMap a

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that are <a>Nothing</a>. Complexity: <i>O(n + m)</i> time.
--   
--   <pre>
--   induceJust (<a>vertex</a> <a>Nothing</a>) == <a>empty</a>
--   induceJust . <a>vertex</a> . <a>Just</a>  == <a>vertex</a>
--   </pre>
induceJust :: Ord a => AdjacencyMap (Maybe a) -> AdjacencyMap a

-- | Compute the <i>Cartesian product</i> of graphs. Complexity: <i>O((n +
--   m) * log(n))</i> time and O(n + m) memory.
--   
--   <pre>
--   <a>edgeList</a> (box (<a>shrink</a> $ 1 * 2) (<a>shrink</a> $ 10 * 20)) == [ ((1,10), (1,20))
--                                                         , ((1,10), (2,10))
--                                                         , ((1,20), (2,20))
--                                                         , ((2,10), (2,20)) ]
--   </pre>
--   
--   Up to isomorphism between the resulting vertex types, this operation
--   is <i>commutative</i> and <i>associative</i>, has singleton graphs as
--   <i>identities</i> and <a>empty</a> as the <i>annihilating zero</i>.
--   Below <tt>~~</tt> stands for equality up to an isomorphism, e.g.
--   <tt>(x,</tt> <tt>()) ~~ x</tt>.
--   
--   <pre>
--   box x y               ~~ box y x
--   box x (box y z)       ~~ box (box x y) z
--   box x (<a>vertex</a> ())     ~~ x
--   box x <a>empty</a>           ~~ <a>empty</a>
--   <a>transpose</a>   (box x y) == box (<a>transpose</a> x) (<a>transpose</a> y)
--   <a>vertexCount</a> (box x y) == <a>vertexCount</a> x * <a>vertexCount</a> y
--   <a>edgeCount</a>   (box x y) &lt;= <a>vertexCount</a> x * <a>edgeCount</a> y + <a>edgeCount</a> x * <a>vertexCount</a> y
--   </pre>
box :: (Ord a, Ord b) => AdjacencyMap a -> AdjacencyMap b -> AdjacencyMap (a, b)

-- | Compute the <i>transitive closure</i> of a graph. Complexity: <i>O(n *
--   m * log(n)^2)</i> time.
--   
--   <pre>
--   transitiveClosure <a>empty</a>                    == <a>empty</a>
--   transitiveClosure (<a>vertex</a> x)               == <a>vertex</a> x
--   transitiveClosure (shrink $ 1 * 2 + 2 * 3) == shrink (1 * 2 + 1 * 3 + 2 * 3)
--   transitiveClosure . transitiveClosure      == transitiveClosure
--   </pre>
transitiveClosure :: Ord a => AdjacencyMap a -> AdjacencyMap a

-- | Compute a <i>topological sort</i> of an acyclic graph.
--   
--   <pre>
--   topSort <a>empty</a>                          == []
--   topSort (<a>vertex</a> x)                     == [x]
--   topSort (shrink $ 1 * (2 + 4) + 3 * 4) == [1, 2, 3, 4]
--   topSort (<a>join</a> x y)                     == <a>fmap</a> <a>Left</a> (topSort x) ++ <a>fmap</a> <a>Right</a> (topSort y)
--   <a>Right</a> . topSort                        == <a>topSort</a> . <a>fromAcyclic</a>
--   </pre>
topSort :: Ord a => AdjacencyMap a -> [a]

-- | Compute the acyclic <i>condensation</i> of a graph, where each vertex
--   corresponds to a <i>strongly-connected component</i> of the original
--   graph. Note that component graphs are non-empty, and are therefore of
--   type <a>Algebra.Graph.NonEmpty.AdjacencyMap</a>.
--   
--   <pre>
--              scc <a>empty</a>               == <a>empty</a>
--              scc (<a>vertex</a> x)          == <a>vertex</a> (NonEmpty.<a>vertex</a> x)
--              scc (<a>edge</a> 1 1)          == <a>vertex</a> (NonEmpty.<a>edge</a> 1 1)
--   <a>edgeList</a> $ scc (<a>edge</a> 1 2)          == [ (NonEmpty.<a>vertex</a> 1       , NonEmpty.<a>vertex</a> 2       ) ]
--   <a>edgeList</a> $ scc (3 * 1 * 4 * 1 * 5) == [ (NonEmpty.<a>vertex</a> 3       , NonEmpty.<a>vertex</a> 5       )
--                                         , (NonEmpty.<a>vertex</a> 3       , NonEmpty.<a>clique1</a> [1,4,1])
--                                         , (NonEmpty.<a>clique1</a> [1,4,1], NonEmpty.<a>vertex</a> 5       ) ]
--   </pre>
scc :: Ord a => AdjacencyMap a -> AdjacencyMap (AdjacencyMap a)

-- | Construct an acyclic graph from a given adjacency map, or return
--   <a>Nothing</a> if the input contains cycles.
--   
--   <pre>
--   toAcyclic (<a>path</a>    [1,2,3]) == <a>Just</a> (shrink $ 1 * 2 + 2 * 3)
--   toAcyclic (<a>clique</a>  [3,2,1]) == <a>Just</a> (<a>transpose</a> (shrink $ 1 * 2 * 3))
--   toAcyclic (<a>circuit</a> [1,2,3]) == <a>Nothing</a>
--   toAcyclic . <a>fromAcyclic</a>     == <a>Just</a>
--   </pre>
toAcyclic :: Ord a => AdjacencyMap a -> Maybe (AdjacencyMap a)

-- | Construct an acyclic graph from a given adjacency map, keeping only
--   edges <tt>(x,y)</tt> where <tt>x &lt; y</tt> according to the supplied
--   <a>Ord</a> <tt>a</tt> instance.
--   
--   <pre>
--   toAcyclicOrd <a>empty</a>       == <a>empty</a>
--   toAcyclicOrd . <a>vertex</a>    == <a>vertex</a>
--   toAcyclicOrd (1 + 2)     == shrink (1 + 2)
--   toAcyclicOrd (1 * 2)     == shrink (1 * 2)
--   toAcyclicOrd (2 * 1)     == shrink (1 + 2)
--   toAcyclicOrd (1 * 2 * 1) == shrink (1 * 2)
--   toAcyclicOrd (1 * 2 * 3) == shrink (1 * 2 * 3)
--   </pre>
toAcyclicOrd :: Ord a => AdjacencyMap a -> AdjacencyMap a

-- | Construct an acyclic graph from a given adjacency map using
--   <a>scc</a>. If the graph is acyclic, it is returned as is. If the
--   graph is cyclic, then a representative for every strongly connected
--   component in its condensation graph is chosen and these
--   representatives are used to build an acyclic graph.
--   
--   <pre>
--   shrink . <a>vertex</a>      == <a>vertex</a>
--   shrink . <a>vertices</a>    == <a>vertices</a>
--   shrink . <a>fromAcyclic</a> == <a>id</a>
--   </pre>
shrink :: Ord a => AdjacencyMap a -> AdjacencyMap a

-- | Check if the internal representation of an acyclic graph is
--   consistent, i.e. that all edges refer to existing vertices and the
--   graph is acyclic. It should be impossible to create an inconsistent
--   <a>AdjacencyMap</a>.
--   
--   <pre>
--   consistent <a>empty</a>                 == True
--   consistent (<a>vertex</a> x)            == True
--   consistent (<a>vertices</a> xs)         == True
--   consistent (<a>union</a> x y)           == True
--   consistent (<a>join</a> x y)            == True
--   consistent (<a>transpose</a> x)         == True
--   consistent (<a>box</a> x y)             == True
--   consistent (<a>transitiveClosure</a> x) == True
--   consistent (<a>scc</a> x)               == True
--   <a>fmap</a> consistent (<a>toAcyclic</a> x)    /= False
--   consistent (<a>toAcyclicOrd</a> x)      == True
--   </pre>
consistent :: Ord a => AdjacencyMap a -> Bool
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.Acyclic.AdjacencyMap.AdjacencyMap a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Algebra.Graph.Acyclic.AdjacencyMap.AdjacencyMap a)
instance (GHC.Classes.Ord a, GHC.Show.Show a) => GHC.Show.Show (Algebra.Graph.Acyclic.AdjacencyMap.AdjacencyMap a)


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module defines the <a>Relation</a> data type, as well as
--   associated operations and algorithms. <a>Relation</a> is an instance
--   of the <a>Graph</a> type class, which can be used for polymorphic
--   graph construction and manipulation.
module Algebra.Graph.Relation

-- | The <a>Relation</a> data type represents a graph as a <i>binary
--   relation</i>. We define a <a>Num</a> instance as a convenient notation
--   for working with graphs:
--   
--   <pre>
--   0           == <a>vertex</a> 0
--   1 + 2       == <a>overlay</a> (<a>vertex</a> 1) (<a>vertex</a> 2)
--   1 * 2       == <a>connect</a> (<a>vertex</a> 1) (<a>vertex</a> 2)
--   1 + 2 * 3   == <a>overlay</a> (<a>vertex</a> 1) (<a>connect</a> (<a>vertex</a> 2) (<a>vertex</a> 3))
--   1 * (2 + 3) == <a>connect</a> (<a>vertex</a> 1) (<a>overlay</a> (<a>vertex</a> 2) (<a>vertex</a> 3))
--   </pre>
--   
--   <b>Note:</b> the <a>Num</a> instance does not satisfy several
--   "customary laws" of <a>Num</a>, which dictate that <a>fromInteger</a>
--   <tt>0</tt> and <a>fromInteger</a> <tt>1</tt> should act as additive
--   and multiplicative identities, and <a>negate</a> as additive inverse.
--   Nevertheless, overloading <a>fromInteger</a>, <a>+</a> and <a>*</a> is
--   very convenient when working with algebraic graphs; we hope that in
--   future Haskell's Prelude will provide a more fine-grained class
--   hierarchy for algebraic structures, which we would be able to utilise
--   without violating any laws.
--   
--   The <a>Show</a> instance is defined using basic graph construction
--   primitives:
--   
--   <pre>
--   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) == "overlay (vertex 3) (edge 1 2)"
--   </pre>
--   
--   The <a>Eq</a> instance satisfies all axioms of algebraic graphs:
--   
--   <ul>
--   <li><a>overlay</a> is commutative and associative:<pre> x + y == y + x
--   x + (y + z) == (x + y) + z</pre></li>
--   <li><a>connect</a> is associative and has <a>empty</a> as the
--   identity:<pre> x * empty == x empty * x == x x * (y * z) == (x * y) *
--   z</pre></li>
--   <li><a>connect</a> distributes over <a>overlay</a>:<pre>x * (y + z) ==
--   x * y + x * z (x + y) * z == x * z + y * z</pre></li>
--   <li><a>connect</a> can be decomposed:<pre>x * y * z == x * y + x * z +
--   y * z</pre></li>
--   </ul>
--   
--   The following useful theorems can be proved from the above set of
--   axioms.
--   
--   <ul>
--   <li><a>overlay</a> has <a>empty</a> as the identity and is
--   idempotent:<pre> x + empty == x empty + x == x x + x == x</pre></li>
--   <li>Absorption and saturation of <a>connect</a>:<pre>x * y + x + y ==
--   x * y x * x * x == x * x</pre></li>
--   </ul>
--   
--   When specifying the time and memory complexity of graph algorithms,
--   <i>n</i> and <i>m</i> will denote the number of vertices and edges in
--   the graph, respectively.
--   
--   The total order on graphs is defined using <i>size-lexicographic</i>
--   comparison:
--   
--   <ul>
--   <li>Compare the number of vertices. In case of a tie, continue.</li>
--   <li>Compare the sets of vertices. In case of a tie, continue.</li>
--   <li>Compare the number of edges. In case of a tie, continue.</li>
--   <li>Compare the sets of edges.</li>
--   </ul>
--   
--   Here are a few examples:
--   
--   <pre>
--   <a>vertex</a> 1 &lt; <a>vertex</a> 2
--   <a>vertex</a> 3 &lt; <a>edge</a> 1 2
--   <a>vertex</a> 1 &lt; <a>edge</a> 1 1
--   <a>edge</a> 1 1 &lt; <a>edge</a> 1 2
--   <a>edge</a> 1 2 &lt; <a>edge</a> 1 1 + <a>edge</a> 2 2
--   <a>edge</a> 1 2 &lt; <a>edge</a> 1 3
--   </pre>
--   
--   Note that the resulting order refines the <a>isSubgraphOf</a> relation
--   and is compatible with <a>overlay</a> and <a>connect</a> operations:
--   
--   <pre>
--   <a>isSubgraphOf</a> x y ==&gt; x &lt;= y
--   </pre>
--   
--   <pre>
--   <a>empty</a> &lt;= x
--   x     &lt;= x + y
--   x + y &lt;= x * y
--   </pre>
data Relation a

-- | The <i>domain</i> of the relation. Complexity: <i>O(1)</i> time and
--   memory.
domain :: Relation a -> Set a

-- | The set of pairs of elements that are <i>related</i>. It is guaranteed
--   that each element belongs to the domain. Complexity: <i>O(1)</i> time
--   and memory.
relation :: Relation a -> Set (a, a)

-- | Construct the <i>empty graph</i>.
--   
--   <pre>
--   <a>isEmpty</a>     empty == True
--   <a>hasVertex</a> x empty == False
--   <a>vertexCount</a> empty == 0
--   <a>edgeCount</a>   empty == 0
--   </pre>
empty :: Relation a

-- | Construct the graph comprising <i>a single isolated vertex</i>.
--   
--   <pre>
--   <a>isEmpty</a>     (vertex x) == False
--   <a>hasVertex</a> x (vertex y) == (x == y)
--   <a>vertexCount</a> (vertex x) == 1
--   <a>edgeCount</a>   (vertex x) == 0
--   </pre>
vertex :: a -> Relation a

-- | Construct the graph comprising <i>a single edge</i>.
--   
--   <pre>
--   edge x y               == <a>connect</a> (<a>vertex</a> x) (<a>vertex</a> y)
--   <a>hasEdge</a> x y (edge x y) == True
--   <a>edgeCount</a>   (edge x y) == 1
--   <a>vertexCount</a> (edge 1 1) == 1
--   <a>vertexCount</a> (edge 1 2) == 2
--   </pre>
edge :: Ord a => a -> a -> Relation a

-- | <i>Overlay</i> two graphs. This is a commutative, associative and
--   idempotent operation with the identity <a>empty</a>. Complexity:
--   <i>O((n + m) * log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   <a>isEmpty</a>     (overlay x y) == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (overlay x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (overlay x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (overlay x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (overlay x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (overlay x y) &lt;= <a>edgeCount</a> x   + <a>edgeCount</a> y
--   <a>vertexCount</a> (overlay 1 2) == 2
--   <a>edgeCount</a>   (overlay 1 2) == 0
--   </pre>
overlay :: Ord a => Relation a -> Relation a -> Relation a

-- | <i>Connect</i> two graphs. This is an associative operation with the
--   identity <a>empty</a>, which distributes over <a>overlay</a> and obeys
--   the decomposition axiom. Complexity: <i>O((n + m) * log(n))</i> time
--   and <i>O(n + m)</i> memory. Note that the number of edges in the
--   resulting graph is quadratic with respect to the number of vertices of
--   the arguments: <i>m = O(m1 + m2 + n1 * n2)</i>.
--   
--   <pre>
--   <a>isEmpty</a>     (connect x y) == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (connect x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (connect x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (connect x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (connect x y) &gt;= <a>edgeCount</a> y
--   <a>edgeCount</a>   (connect x y) &gt;= <a>vertexCount</a> x * <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect x y) &lt;= <a>vertexCount</a> x * <a>vertexCount</a> y + <a>edgeCount</a> x + <a>edgeCount</a> y
--   <a>vertexCount</a> (connect 1 2) == 2
--   <a>edgeCount</a>   (connect 1 2) == 1
--   </pre>
connect :: Ord a => Relation a -> Relation a -> Relation a

-- | Construct the graph comprising a given list of isolated vertices.
--   Complexity: <i>O(L * log(L))</i> time and <i>O(L)</i> memory, where
--   <i>L</i> is the length of the given list.
--   
--   <pre>
--   vertices []            == <a>empty</a>
--   vertices [x]           == <a>vertex</a> x
--   vertices               == <a>overlays</a> . map <a>vertex</a>
--   <a>hasVertex</a> x . vertices == <a>elem</a> x
--   <a>vertexCount</a> . vertices == <a>length</a> . <a>nub</a>
--   <a>vertexSet</a>   . vertices == Set.<a>fromList</a>
--   </pre>
vertices :: Ord a => [a] -> Relation a

-- | Construct the graph from a list of edges. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   edges []          == <a>empty</a>
--   edges [(x,y)]     == <a>edge</a> x y
--   edges             == <a>overlays</a> . <a>map</a> (<a>uncurry</a> <a>edge</a>)
--   <a>edgeCount</a> . edges == <a>length</a> . <a>nub</a>
--   </pre>
edges :: Ord a => [(a, a)] -> Relation a

-- | Overlay a given list of graphs. Complexity: <i>O((n + m) * log(n))</i>
--   time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   overlays []        == <a>empty</a>
--   overlays [x]       == x
--   overlays [x,y]     == <a>overlay</a> x y
--   overlays           == <a>foldr</a> <a>overlay</a> <a>empty</a>
--   <a>isEmpty</a> . overlays == <a>all</a> <a>isEmpty</a>
--   </pre>
overlays :: Ord a => [Relation a] -> Relation a

-- | Connect a given list of graphs. Complexity: <i>O((n + m) * log(n))</i>
--   time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   connects []        == <a>empty</a>
--   connects [x]       == x
--   connects [x,y]     == <a>connect</a> x y
--   connects           == <a>foldr</a> <a>connect</a> <a>empty</a>
--   <a>isEmpty</a> . connects == <a>all</a> <a>isEmpty</a>
--   </pre>
connects :: Ord a => [Relation a] -> Relation a

-- | The <a>isSubgraphOf</a> function takes two graphs and returns
--   <a>True</a> if the first graph is a <i>subgraph</i> of the second.
--   Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   isSubgraphOf <a>empty</a>         x             ==  True
--   isSubgraphOf (<a>vertex</a> x)    <a>empty</a>         ==  False
--   isSubgraphOf x             (<a>overlay</a> x y) ==  True
--   isSubgraphOf (<a>overlay</a> x y) (<a>connect</a> x y) ==  True
--   isSubgraphOf (<a>path</a> xs)     (<a>circuit</a> xs)  ==  True
--   isSubgraphOf x y                         ==&gt; x &lt;= y
--   </pre>
isSubgraphOf :: Ord a => Relation a -> Relation a -> Bool

-- | Check if a relation is empty. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   isEmpty <a>empty</a>                       == True
--   isEmpty (<a>overlay</a> <a>empty</a> <a>empty</a>)       == True
--   isEmpty (<a>vertex</a> x)                  == False
--   isEmpty (<a>removeVertex</a> x $ <a>vertex</a> x) == True
--   isEmpty (<a>removeEdge</a> x y $ <a>edge</a> x y) == False
--   </pre>
isEmpty :: Relation a -> Bool

-- | Check if a graph contains a given vertex. Complexity: <i>O(log(n))</i>
--   time.
--   
--   <pre>
--   hasVertex x <a>empty</a>            == False
--   hasVertex x (<a>vertex</a> y)       == (x == y)
--   hasVertex x . <a>removeVertex</a> x == <a>const</a> False
--   </pre>
hasVertex :: Ord a => a -> Relation a -> Bool

-- | Check if a graph contains a given edge. Complexity: <i>O(log(n))</i>
--   time.
--   
--   <pre>
--   hasEdge x y <a>empty</a>            == False
--   hasEdge x y (<a>vertex</a> z)       == False
--   hasEdge x y (<a>edge</a> x y)       == True
--   hasEdge x y . <a>removeEdge</a> x y == <a>const</a> False
--   hasEdge x y                  == <a>elem</a> (x,y) . <a>edgeList</a>
--   </pre>
hasEdge :: Ord a => a -> a -> Relation a -> Bool

-- | The number of vertices in a graph. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   vertexCount <a>empty</a>             ==  0
--   vertexCount (<a>vertex</a> x)        ==  1
--   vertexCount                   ==  <a>length</a> . <a>vertexList</a>
--   vertexCount x &lt; vertexCount y ==&gt; x &lt; y
--   </pre>
vertexCount :: Relation a -> Int

-- | The number of edges in a graph. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   edgeCount <a>empty</a>      == 0
--   edgeCount (<a>vertex</a> x) == 0
--   edgeCount (<a>edge</a> x y) == 1
--   edgeCount            == <a>length</a> . <a>edgeList</a>
--   </pre>
edgeCount :: Relation a -> Int

-- | The sorted list of vertices of a given graph. Complexity: <i>O(n)</i>
--   time and memory.
--   
--   <pre>
--   vertexList <a>empty</a>      == []
--   vertexList (<a>vertex</a> x) == [x]
--   vertexList . <a>vertices</a> == <a>nub</a> . <a>sort</a>
--   </pre>
vertexList :: Relation a -> [a]

-- | The sorted list of edges of a graph. Complexity: <i>O(n + m)</i> time
--   and <i>O(m)</i> memory.
--   
--   <pre>
--   edgeList <a>empty</a>          == []
--   edgeList (<a>vertex</a> x)     == []
--   edgeList (<a>edge</a> x y)     == [(x,y)]
--   edgeList (<a>star</a> 2 [3,1]) == [(2,1), (2,3)]
--   edgeList . <a>edges</a>        == <a>nub</a> . <a>sort</a>
--   edgeList . <a>transpose</a>    == <a>sort</a> . <a>map</a> <a>swap</a> . edgeList
--   </pre>
edgeList :: Relation a -> [(a, a)]

-- | The sorted <i>adjacency list</i> of a graph. Complexity: <i>O(n +
--   m)</i> time and memory.
--   
--   <pre>
--   adjacencyList <a>empty</a>          == []
--   adjacencyList (<a>vertex</a> x)     == [(x, [])]
--   adjacencyList (<a>edge</a> 1 2)     == [(1, [2]), (2, [])]
--   adjacencyList (<a>star</a> 2 [3,1]) == [(1, []), (2, [1,3]), (3, [])]
--   <a>stars</a> . adjacencyList        == id
--   </pre>
adjacencyList :: Eq a => Relation a -> [(a, [a])]

-- | The set of vertices of a given graph. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   vertexSet <a>empty</a>      == Set.<a>empty</a>
--   vertexSet . <a>vertex</a>   == Set.<a>singleton</a>
--   vertexSet . <a>vertices</a> == Set.<a>fromList</a>
--   </pre>
vertexSet :: Relation a -> Set a

-- | The set of edges of a given graph. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   edgeSet <a>empty</a>      == Set.<a>empty</a>
--   edgeSet (<a>vertex</a> x) == Set.<a>empty</a>
--   edgeSet (<a>edge</a> x y) == Set.<a>singleton</a> (x,y)
--   edgeSet . <a>edges</a>    == Set.<a>fromList</a>
--   </pre>
edgeSet :: Relation a -> Set (a, a)

-- | The <i>preset</i> of an element <tt>x</tt> is the set of elements that
--   are related to it on the <i>left</i>, i.e. <tt>preSet x == { a | aRx
--   }</tt>. In the context of directed graphs, this corresponds to the set
--   of <i>direct predecessors</i> of vertex <tt>x</tt>. Complexity: <i>O(n
--   + m)</i> time and <i>O(n)</i> memory.
--   
--   <pre>
--   preSet x <a>empty</a>      == Set.<a>empty</a>
--   preSet x (<a>vertex</a> x) == Set.<a>empty</a>
--   preSet 1 (<a>edge</a> 1 2) == Set.<a>empty</a>
--   preSet y (<a>edge</a> x y) == Set.<a>fromList</a> [x]
--   </pre>
preSet :: Ord a => a -> Relation a -> Set a

-- | The <i>postset</i> of an element <tt>x</tt> is the set of elements
--   that are related to it on the <i>right</i>, i.e. <tt>postSet x == { a
--   | xRa }</tt>. In the context of directed graphs, this corresponds to
--   the set of <i>direct successors</i> of vertex <tt>x</tt>. Complexity:
--   <i>O(n + m)</i> time and <i>O(n)</i> memory.
--   
--   <pre>
--   postSet x <a>empty</a>      == Set.<a>empty</a>
--   postSet x (<a>vertex</a> x) == Set.<a>empty</a>
--   postSet x (<a>edge</a> x y) == Set.<a>fromList</a> [y]
--   postSet 2 (<a>edge</a> 1 2) == Set.<a>empty</a>
--   </pre>
postSet :: Ord a => a -> Relation a -> Set a

-- | The <i>path</i> on a list of vertices. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   path []        == <a>empty</a>
--   path [x]       == <a>vertex</a> x
--   path [x,y]     == <a>edge</a> x y
--   path . <a>reverse</a> == <a>transpose</a> . path
--   </pre>
path :: Ord a => [a] -> Relation a

-- | The <i>circuit</i> on a list of vertices. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   circuit []        == <a>empty</a>
--   circuit [x]       == <a>edge</a> x x
--   circuit [x,y]     == <a>edges</a> [(x,y), (y,x)]
--   circuit . <a>reverse</a> == <a>transpose</a> . circuit
--   </pre>
circuit :: Ord a => [a] -> Relation a

-- | The <i>clique</i> on a list of vertices. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   clique []         == <a>empty</a>
--   clique [x]        == <a>vertex</a> x
--   clique [x,y]      == <a>edge</a> x y
--   clique [x,y,z]    == <a>edges</a> [(x,y), (x,z), (y,z)]
--   clique (xs ++ ys) == <a>connect</a> (clique xs) (clique ys)
--   clique . <a>reverse</a>  == <a>transpose</a> . clique
--   </pre>
clique :: Ord a => [a] -> Relation a

-- | The <i>biclique</i> on two lists of vertices. Complexity: <i>O(n *
--   log(n) + m)</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   biclique []      []      == <a>empty</a>
--   biclique [x]     []      == <a>vertex</a> x
--   biclique []      [y]     == <a>vertex</a> y
--   biclique [x1,x2] [y1,y2] == <a>edges</a> [(x1,y1), (x1,y2), (x2,y1), (x2,y2)]
--   biclique xs      ys      == <a>connect</a> (<a>vertices</a> xs) (<a>vertices</a> ys)
--   </pre>
biclique :: Ord a => [a] -> [a] -> Relation a

-- | The <i>star</i> formed by a centre vertex connected to a list of
--   leaves. Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n +
--   m)</i> memory.
--   
--   <pre>
--   star x []    == <a>vertex</a> x
--   star x [y]   == <a>edge</a> x y
--   star x [y,z] == <a>edges</a> [(x,y), (x,z)]
--   star x ys    == <a>connect</a> (<a>vertex</a> x) (<a>vertices</a> ys)
--   </pre>
star :: Ord a => a -> [a] -> Relation a

-- | The <i>stars</i> formed by overlaying a list of <a>star</a>s. An
--   inverse of <a>adjacencyList</a>. Complexity: <i>O(L * log(n))</i>
--   time, memory and size, where <i>L</i> is the total size of the input.
--   
--   <pre>
--   stars []                      == <a>empty</a>
--   stars [(x, [])]               == <a>vertex</a> x
--   stars [(x, [y])]              == <a>edge</a> x y
--   stars [(x, ys)]               == <a>star</a> x ys
--   stars                         == <a>overlays</a> . <a>map</a> (<a>uncurry</a> <a>star</a>)
--   stars . <a>adjacencyList</a>         == id
--   <a>overlay</a> (stars xs) (stars ys) == stars (xs ++ ys)
--   </pre>
stars :: Ord a => [(a, [a])] -> Relation a

-- | The <i>tree graph</i> constructed from a given <a>Tree</a> data
--   structure. Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n +
--   m)</i> memory.
--   
--   <pre>
--   tree (Node x [])                                         == <a>vertex</a> x
--   tree (Node x [Node y [Node z []]])                       == <a>path</a> [x,y,z]
--   tree (Node x [Node y [], Node z []])                     == <a>star</a> x [y,z]
--   tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) == <a>edges</a> [(1,2), (1,3), (3,4), (3,5)]
--   </pre>
tree :: Ord a => Tree a -> Relation a

-- | The <i>forest graph</i> constructed from a given <a>Forest</a> data
--   structure. Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n +
--   m)</i> memory.
--   
--   <pre>
--   forest []                                                  == <a>empty</a>
--   forest [x]                                                 == <a>tree</a> x
--   forest [Node 1 [Node 2 [], Node 3 []], Node 4 [Node 5 []]] == <a>edges</a> [(1,2), (1,3), (4,5)]
--   forest                                                     == <a>overlays</a> . <a>map</a> <a>tree</a>
--   </pre>
forest :: Ord a => Forest a -> Relation a

-- | Remove a vertex from a given graph. Complexity: <i>O(n + m)</i> time.
--   
--   <pre>
--   removeVertex x (<a>vertex</a> x)       == <a>empty</a>
--   removeVertex 1 (<a>vertex</a> 2)       == <a>vertex</a> 2
--   removeVertex x (<a>edge</a> x x)       == <a>empty</a>
--   removeVertex 1 (<a>edge</a> 1 2)       == <a>vertex</a> 2
--   removeVertex x . removeVertex x == removeVertex x
--   </pre>
removeVertex :: Ord a => a -> Relation a -> Relation a

-- | Remove an edge from a given graph. Complexity: <i>O(log(m))</i> time.
--   
--   <pre>
--   removeEdge x y (<a>edge</a> x y)       == <a>vertices</a> [x,y]
--   removeEdge x y . removeEdge x y == removeEdge x y
--   removeEdge x y . <a>removeVertex</a> x == <a>removeVertex</a> x
--   removeEdge 1 1 (1 * 1 * 2 * 2)  == 1 * 2 * 2
--   removeEdge 1 2 (1 * 1 * 2 * 2)  == 1 * 1 + 2 * 2
--   </pre>
removeEdge :: Ord a => a -> a -> Relation a -> Relation a

-- | The function <tt><a>replaceVertex</a> x y</tt> replaces vertex
--   <tt>x</tt> with vertex <tt>y</tt> in a given <tt>AdjacencyMap</tt>. If
--   <tt>y</tt> already exists, <tt>x</tt> and <tt>y</tt> will be merged.
--   Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   replaceVertex x x            == id
--   replaceVertex x y (<a>vertex</a> x) == <a>vertex</a> y
--   replaceVertex x y            == <a>mergeVertices</a> (== x) y
--   </pre>
replaceVertex :: Ord a => a -> a -> Relation a -> Relation a

-- | Merge vertices satisfying a given predicate into a given vertex.
--   Complexity: <i>O((n + m) * log(n))</i> time, assuming that the
--   predicate takes constant time.
--   
--   <pre>
--   mergeVertices (<a>const</a> False) x    == id
--   mergeVertices (== x) y           == <a>replaceVertex</a> x y
--   mergeVertices <a>even</a> 1 (0 * 2)     == 1 * 1
--   mergeVertices <a>odd</a>  1 (3 + 4 * 5) == 4 * 1
--   </pre>
mergeVertices :: Ord a => (a -> Bool) -> a -> Relation a -> Relation a

-- | Transpose a given graph. Complexity: <i>O(m * log(m))</i> time.
--   
--   <pre>
--   transpose <a>empty</a>       == <a>empty</a>
--   transpose (<a>vertex</a> x)  == <a>vertex</a> x
--   transpose (<a>edge</a> x y)  == <a>edge</a> y x
--   transpose . transpose == id
--   <a>edgeList</a> . transpose  == <a>sort</a> . <a>map</a> <a>swap</a> . <a>edgeList</a>
--   </pre>
transpose :: Ord a => Relation a -> Relation a

-- | Transform a graph by applying a function to each of its vertices. This
--   is similar to <tt>Functor</tt>'s <a>fmap</a> but can be used with
--   non-fully-parametric <a>Relation</a>. Complexity: <i>O((n + m) *
--   log(n))</i> time.
--   
--   <pre>
--   gmap f <a>empty</a>      == <a>empty</a>
--   gmap f (<a>vertex</a> x) == <a>vertex</a> (f x)
--   gmap f (<a>edge</a> x y) == <a>edge</a> (f x) (f y)
--   gmap id           == id
--   gmap f . gmap g   == gmap (f . g)
--   </pre>
gmap :: Ord b => (a -> b) -> Relation a -> Relation b

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that do not satisfy a given predicate. Complexity: <i>O(n +
--   m)</i> time, assuming that the predicate takes constant time.
--   
--   <pre>
--   induce (<a>const</a> True ) x      == x
--   induce (<a>const</a> False) x      == <a>empty</a>
--   induce (/= x)               == <a>removeVertex</a> x
--   induce p . induce q         == induce (\x -&gt; p x &amp;&amp; q x)
--   <a>isSubgraphOf</a> (induce p x) x == True
--   </pre>
induce :: (a -> Bool) -> Relation a -> Relation a

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that are <a>Nothing</a>. Complexity: <i>O(n + m)</i> time.
--   
--   <pre>
--   induceJust (<a>vertex</a> <a>Nothing</a>)                               == <a>empty</a>
--   induceJust (<a>edge</a> (<a>Just</a> x) <a>Nothing</a>)                        == <a>vertex</a> x
--   induceJust . <a>gmap</a> <a>Just</a>                                    == <a>id</a>
--   induceJust . <a>gmap</a> (\x -&gt; if p x then <a>Just</a> x else <a>Nothing</a>) == <a>induce</a> p
--   </pre>
induceJust :: Ord a => Relation (Maybe a) -> Relation a

-- | Left-to-right <i>relational composition</i> of graphs: vertices
--   <tt>x</tt> and <tt>z</tt> are connected in the resulting graph if
--   there is a vertex <tt>y</tt>, such that <tt>x</tt> is connected to
--   <tt>y</tt> in the first graph, and <tt>y</tt> is connected to
--   <tt>z</tt> in the second graph. There are no isolated vertices in the
--   result. This operation is associative, has <a>empty</a> and
--   single-<a>vertex</a> graphs as <i>annihilating zeroes</i>, and
--   distributes over <a>overlay</a>. Complexity: <i>O(n * m * log(m))</i>
--   time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   compose <a>empty</a>            x                == <a>empty</a>
--   compose x                <a>empty</a>            == <a>empty</a>
--   compose (<a>vertex</a> x)       y                == <a>empty</a>
--   compose x                (<a>vertex</a> y)       == <a>empty</a>
--   compose x                (compose y z)    == compose (compose x y) z
--   compose x                (<a>overlay</a> y z)    == <a>overlay</a> (compose x y) (compose x z)
--   compose (<a>overlay</a> x y)    z                == <a>overlay</a> (compose x z) (compose y z)
--   compose (<a>edge</a> x y)       (<a>edge</a> y z)       == <a>edge</a> x z
--   compose (<a>path</a>    [1..5]) (<a>path</a>    [1..5]) == <a>edges</a> [(1,3), (2,4), (3,5)]
--   compose (<a>circuit</a> [1..5]) (<a>circuit</a> [1..5]) == <a>circuit</a> [1,3,5,2,4]
--   </pre>
compose :: Ord a => Relation a -> Relation a -> Relation a

-- | Compute the <i>reflexive and transitive closure</i> of a graph.
--   Complexity: <i>O(n * m * log(n) * log(m))</i> time.
--   
--   <pre>
--   closure <a>empty</a>           == <a>empty</a>
--   closure (<a>vertex</a> x)      == <a>edge</a> x x
--   closure (<a>edge</a> x x)      == <a>edge</a> x x
--   closure (<a>edge</a> x y)      == <a>edges</a> [(x,x), (x,y), (y,y)]
--   closure (<a>path</a> $ <a>nub</a> xs) == <a>reflexiveClosure</a> (<a>clique</a> $ <a>nub</a> xs)
--   closure                 == <a>reflexiveClosure</a> . <a>transitiveClosure</a>
--   closure                 == <a>transitiveClosure</a> . <a>reflexiveClosure</a>
--   closure . closure       == closure
--   <a>postSet</a> x (closure y)   == Set.<a>fromList</a> (<a>reachable</a> x y)
--   </pre>
closure :: Ord a => Relation a -> Relation a

-- | Compute the <i>reflexive closure</i> of a graph. Complexity: <i>O(n *
--   log(m))</i> time.
--   
--   <pre>
--   reflexiveClosure <a>empty</a>              == <a>empty</a>
--   reflexiveClosure (<a>vertex</a> x)         == <a>edge</a> x x
--   reflexiveClosure (<a>edge</a> x x)         == <a>edge</a> x x
--   reflexiveClosure (<a>edge</a> x y)         == <a>edges</a> [(x,x), (x,y), (y,y)]
--   reflexiveClosure . reflexiveClosure == reflexiveClosure
--   </pre>
reflexiveClosure :: Ord a => Relation a -> Relation a

-- | Compute the <i>symmetric closure</i> of a graph. Complexity: <i>O(m *
--   log(m))</i> time.
--   
--   <pre>
--   symmetricClosure <a>empty</a>              == <a>empty</a>
--   symmetricClosure (<a>vertex</a> x)         == <a>vertex</a> x
--   symmetricClosure (<a>edge</a> x y)         == <a>edges</a> [(x,y), (y,x)]
--   symmetricClosure x                  == <a>overlay</a> x (<a>transpose</a> x)
--   symmetricClosure . symmetricClosure == symmetricClosure
--   </pre>
symmetricClosure :: Ord a => Relation a -> Relation a

-- | Compute the <i>transitive closure</i> of a graph. Complexity: <i>O(n *
--   m * log(n) * log(m))</i> time.
--   
--   <pre>
--   transitiveClosure <a>empty</a>               == <a>empty</a>
--   transitiveClosure (<a>vertex</a> x)          == <a>vertex</a> x
--   transitiveClosure (<a>edge</a> x y)          == <a>edge</a> x y
--   transitiveClosure (<a>path</a> $ <a>nub</a> xs)     == <a>clique</a> (<a>nub</a> xs)
--   transitiveClosure . transitiveClosure == transitiveClosure
--   </pre>
transitiveClosure :: Ord a => Relation a -> Relation a

-- | Check that the internal representation of a relation is consistent,
--   i.e. if all pairs of elements in the <a>relation</a> refer to existing
--   elements in the <a>domain</a>. It should be impossible to create an
--   inconsistent <a>Relation</a>, and we use this function in testing.
--   
--   <pre>
--   consistent <a>empty</a>         == True
--   consistent (<a>vertex</a> x)    == True
--   consistent (<a>overlay</a> x y) == True
--   consistent (<a>connect</a> x y) == True
--   consistent (<a>edge</a> x y)    == True
--   consistent (<a>edges</a> xs)    == True
--   consistent (<a>stars</a> xs)    == True
--   </pre>
consistent :: Ord a => Relation a -> Bool
instance GHC.Classes.Eq a => GHC.Classes.Eq (Algebra.Graph.Relation.Relation a)
instance (GHC.Classes.Ord a, GHC.Show.Show a) => GHC.Show.Show (Algebra.Graph.Relation.Relation a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.Relation.Relation a)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Algebra.Graph.Relation.Relation a)
instance (GHC.Classes.Ord a, GHC.Num.Num a) => GHC.Num.Num (Algebra.Graph.Relation.Relation a)
instance Data.String.IsString a => Data.String.IsString (Algebra.Graph.Relation.Relation a)
instance GHC.Classes.Ord a => GHC.Base.Semigroup (Algebra.Graph.Relation.Relation a)
instance GHC.Classes.Ord a => GHC.Base.Monoid (Algebra.Graph.Relation.Relation a)


-- | An abstract implementation of symmetric binary relations. To avoid
--   name clashes with <a>Algebra.Graph.Relation</a>, this module can be
--   imported qualified:
--   
--   <pre>
--   import qualified Algebra.Graph.Relation.Symmetric as Symmetric
--   </pre>
--   
--   <a>Relation</a> is an instance of the <a>Graph</a> type class, which
--   can be used for polymorphic graph construction and manipulation.
module Algebra.Graph.Relation.Symmetric

-- | This data type represents a <i>symmetric binary relation</i> over a
--   set of elements of type <tt>a</tt>. Symmetric relations satisfy all
--   laws of the <a>Undirected</a> type class, including the commutativity
--   of <a>connect</a>:
--   
--   <pre>
--   <a>connect</a> x y == <a>connect</a> y x
--   </pre>
--   
--   The <a>Show</a> instance lists edge vertices in non-decreasing order:
--   
--   <pre>
--   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)"
--   </pre>
--   
--   The total order on graphs is defined using <i>size-lexicographic</i>
--   comparison:
--   
--   <ul>
--   <li>Compare the number of vertices. In case of a tie, continue.</li>
--   <li>Compare the sets of vertices. In case of a tie, continue.</li>
--   <li>Compare the number of edges. In case of a tie, continue.</li>
--   <li>Compare the sets of edges.</li>
--   </ul>
--   
--   Here are a few examples:
--   
--   <pre>
--   <a>vertex</a> 1 &lt; <a>vertex</a> 2
--   <a>vertex</a> 3 &lt; <a>edge</a> 1 2
--   <a>vertex</a> 1 &lt; <a>edge</a> 1 1
--   <a>edge</a> 1 1 &lt; <a>edge</a> 1 2
--   <a>edge</a> 1 2 &lt; <a>edge</a> 1 1 + <a>edge</a> 2 2
--   <a>edge</a> 2 1 &lt; <a>edge</a> 1 3
--   </pre>
--   
--   <pre>
--   <a>edge</a> 1 2 == <a>edge</a> 2 1
--   </pre>
--   
--   Note that the resulting order refines the <a>isSubgraphOf</a> relation
--   and is compatible with <a>overlay</a> and <a>connect</a> operations:
--   
--   <pre>
--   <a>isSubgraphOf</a> x y ==&gt; x &lt;= y
--   </pre>
--   
--   <pre>
--   <a>empty</a> &lt;= x
--   x     &lt;= x + y
--   x + y &lt;= x * y
--   </pre>
data Relation a

-- | Construct a symmetric relation from a given
--   <a>Algebra.Graph.Relation</a>. Complexity: <i>O(m*log(m))</i> time.
--   
--   <pre>
--   toSymmetric (<a>edge</a> 1 2)         == <a>edge</a> 1 2
--   toSymmetric . <a>fromSymmetric</a>    == id
--   <a>fromSymmetric</a>    . toSymmetric == <a>symmetricClosure</a>
--   <a>vertexCount</a>      . toSymmetric == <a>vertexCount</a>
--   (*2) . <a>edgeCount</a> . toSymmetric &gt;= <a>edgeCount</a>
--   </pre>
toSymmetric :: Ord a => Relation a -> Relation a

-- | Extract the underlying symmetric <a>Algebra.Graph.Relation</a>.
--   Complexity: <i>O(1)</i> time and memory.
--   
--   <pre>
--   fromSymmetric (<a>edge</a> 1 2)    == <a>edges</a> [(1,2), (2,1)]
--   <a>vertexCount</a> . fromSymmetric == <a>vertexCount</a>
--   <a>edgeCount</a>   . fromSymmetric &lt;= (*2) . <a>edgeCount</a>
--   </pre>
fromSymmetric :: Relation a -> Relation a

-- | Construct the <i>empty graph</i>.
--   
--   <pre>
--   <a>isEmpty</a>     empty == True
--   <a>hasVertex</a> x empty == False
--   <a>vertexCount</a> empty == 0
--   <a>edgeCount</a>   empty == 0
--   </pre>
empty :: Relation a

-- | Construct the graph comprising <i>a single isolated vertex</i>.
--   
--   <pre>
--   <a>isEmpty</a>     (vertex x) == False
--   <a>hasVertex</a> x (vertex y) == (x == y)
--   <a>vertexCount</a> (vertex x) == 1
--   <a>edgeCount</a>   (vertex x) == 0
--   </pre>
vertex :: a -> Relation a

-- | Construct the graph comprising <i>a single edge</i>.
--   
--   <pre>
--   edge x y               == <a>connect</a> (<a>vertex</a> x) (<a>vertex</a> y)
--   edge x y               == <a>edge</a> y x
--   edge x y               == <a>edges</a> [(x,y), (y,x)]
--   <a>hasEdge</a> x y (edge x y) == True
--   <a>edgeCount</a>   (edge x y) == 1
--   <a>vertexCount</a> (edge 1 1) == 1
--   <a>vertexCount</a> (edge 1 2) == 2
--   </pre>
edge :: Ord a => a -> a -> Relation a

-- | <i>Overlay</i> two graphs. This is a commutative, associative and
--   idempotent operation with the identity <a>empty</a>. Complexity:
--   <i>O((n + m) * log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   <a>isEmpty</a>     (overlay x y) == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (overlay x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (overlay x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (overlay x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (overlay x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (overlay x y) &lt;= <a>edgeCount</a> x   + <a>edgeCount</a> y
--   <a>vertexCount</a> (overlay 1 2) == 2
--   <a>edgeCount</a>   (overlay 1 2) == 0
--   </pre>
overlay :: Ord a => Relation a -> Relation a -> Relation a

-- | <i>Connect</i> two graphs. This is a commutative and associative
--   operation with the identity <a>empty</a>, which distributes over
--   <a>overlay</a> and obeys the decomposition axiom. Complexity: <i>O((n
--   + m) * log(n))</i> time and <i>O(n + m)</i> memory. Note that the
--   number of edges in the resulting graph is quadratic with respect to
--   the number of vertices of the arguments: <i>m = O(m1 + m2 + n1 *
--   n2)</i>.
--   
--   <pre>
--   connect x y               == connect y x
--   <a>isEmpty</a>     (connect x y) == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (connect x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (connect x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (connect x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (connect x y) &gt;= <a>edgeCount</a> y
--   <a>edgeCount</a>   (connect x y) &gt;= <a>vertexCount</a> x * <a>vertexCount</a> y `div` 2
--   <a>vertexCount</a> (connect 1 2) == 2
--   <a>edgeCount</a>   (connect 1 2) == 1
--   </pre>
connect :: Ord a => Relation a -> Relation a -> Relation a

-- | Construct the graph comprising a given list of isolated vertices.
--   Complexity: <i>O(L * log(L))</i> time and <i>O(L)</i> memory, where
--   <i>L</i> is the length of the given list.
--   
--   <pre>
--   vertices []            == <a>empty</a>
--   vertices [x]           == <a>vertex</a> x
--   vertices               == <a>overlays</a> . map <a>vertex</a>
--   <a>hasVertex</a> x . vertices == <a>elem</a> x
--   <a>vertexCount</a> . vertices == <a>length</a> . <a>nub</a>
--   <a>vertexSet</a>   . vertices == Set.<a>fromList</a>
--   </pre>
vertices :: Ord a => [a] -> Relation a

-- | Construct the graph from a list of edges. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   edges []             == <a>empty</a>
--   edges [(x,y)]        == <a>edge</a> x y
--   edges [(x,y), (y,x)] == <a>edge</a> x y
--   </pre>
edges :: Ord a => [(a, a)] -> Relation a

-- | Overlay a given list of graphs. Complexity: <i>O((n + m) * log(n))</i>
--   time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   overlays []        == <a>empty</a>
--   overlays [x]       == x
--   overlays [x,y]     == <a>overlay</a> x y
--   overlays           == <a>foldr</a> <a>overlay</a> <a>empty</a>
--   <a>isEmpty</a> . overlays == <a>all</a> <a>isEmpty</a>
--   </pre>
overlays :: Ord a => [Relation a] -> Relation a

-- | Connect a given list of graphs. Complexity: <i>O((n + m) * log(n))</i>
--   time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   connects []        == <a>empty</a>
--   connects [x]       == x
--   connects [x,y]     == <a>connect</a> x y
--   connects           == <a>foldr</a> <a>connect</a> <a>empty</a>
--   <a>isEmpty</a> . connects == <a>all</a> <a>isEmpty</a>
--   connects           == connects . <a>reverse</a>
--   </pre>
connects :: Ord a => [Relation a] -> Relation a

-- | The <a>isSubgraphOf</a> function takes two graphs and returns
--   <a>True</a> if the first graph is a <i>subgraph</i> of the second.
--   Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   isSubgraphOf <a>empty</a>         x             ==  True
--   isSubgraphOf (<a>vertex</a> x)    <a>empty</a>         ==  False
--   isSubgraphOf x             (<a>overlay</a> x y) ==  True
--   isSubgraphOf (<a>overlay</a> x y) (<a>connect</a> x y) ==  True
--   isSubgraphOf (<a>path</a> xs)     (<a>circuit</a> xs)  ==  True
--   isSubgraphOf (<a>edge</a> x y)    (<a>edge</a> y x)    ==  True
--   isSubgraphOf x y                         ==&gt; x &lt;= y
--   </pre>
isSubgraphOf :: Ord a => Relation a -> Relation a -> Bool

-- | Check if a relation is empty. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   isEmpty <a>empty</a>                       == True
--   isEmpty (<a>overlay</a> <a>empty</a> <a>empty</a>)       == True
--   isEmpty (<a>vertex</a> x)                  == False
--   isEmpty (<a>removeVertex</a> x $ <a>vertex</a> x) == True
--   isEmpty (<a>removeEdge</a> x y $ <a>edge</a> x y) == False
--   </pre>
isEmpty :: Relation a -> Bool

-- | Check if a graph contains a given vertex. Complexity: <i>O(log(n))</i>
--   time.
--   
--   <pre>
--   hasVertex x <a>empty</a>            == False
--   hasVertex x (<a>vertex</a> y)       == (x == y)
--   hasVertex x . <a>removeVertex</a> x == <a>const</a> False
--   </pre>
hasVertex :: Ord a => a -> Relation a -> Bool

-- | Check if a graph contains a given edge. Complexity: <i>O(log(n))</i>
--   time.
--   
--   <pre>
--   hasEdge x y <a>empty</a>            == False
--   hasEdge x y (<a>vertex</a> z)       == False
--   hasEdge x y (<a>edge</a> x y)       == True
--   hasEdge x y (<a>edge</a> y x)       == True
--   hasEdge x y . <a>removeEdge</a> x y == <a>const</a> False
--   hasEdge x y                  == <a>elem</a> (<a>min</a> x y, <a>max</a> x y) . <a>edgeList</a>
--   </pre>
hasEdge :: Ord a => a -> a -> Relation a -> Bool

-- | The number of vertices in a graph. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   vertexCount <a>empty</a>             ==  0
--   vertexCount (<a>vertex</a> x)        ==  1
--   vertexCount                   ==  <a>length</a> . <a>vertexList</a>
--   vertexCount x &lt; vertexCount y ==&gt; x &lt; y
--   </pre>
vertexCount :: Relation a -> Int

-- | The number of edges in a graph. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   edgeCount <a>empty</a>      == 0
--   edgeCount (<a>vertex</a> x) == 0
--   edgeCount (<a>edge</a> x y) == 1
--   edgeCount            == <a>length</a> . <a>edgeList</a>
--   </pre>
edgeCount :: Ord a => Relation a -> Int

-- | The sorted list of vertices of a given graph. Complexity: <i>O(n)</i>
--   time and memory.
--   
--   <pre>
--   vertexList <a>empty</a>      == []
--   vertexList (<a>vertex</a> x) == [x]
--   vertexList . <a>vertices</a> == <a>nub</a> . <a>sort</a>
--   </pre>
vertexList :: Relation a -> [a]

-- | The sorted list of edges of a graph, where edge vertices appear in the
--   non-decreasing order. Complexity: <i>O(n + m)</i> time and <i>O(m)</i>
--   memory.
--   
--   Note: If you need the sorted list of edges where an edge appears in
--   both directions, use <tt><a>edgeList</a> . <a>fromSymmetric</a></tt>.
--   
--   <pre>
--   edgeList <a>empty</a>          == []
--   edgeList (<a>vertex</a> x)     == []
--   edgeList (<a>edge</a> x y)     == [(<a>min</a> x y, <a>max</a> y x)]
--   edgeList (<a>star</a> 2 [3,1]) == [(1,2), (2,3)]
--   </pre>
edgeList :: Ord a => Relation a -> [(a, a)]

-- | The sorted <i>adjacency list</i> of a graph. Complexity: <i>O(n +
--   m)</i> time and memory.
--   
--   <pre>
--   adjacencyList <a>empty</a>          == []
--   adjacencyList (<a>vertex</a> x)     == [(x, [])]
--   adjacencyList (<a>edge</a> 1 2)     == [(1, [2]), (2, [1])]
--   adjacencyList (<a>star</a> 2 [3,1]) == [(1, [2]), (2, [1,3]), (3, [2])]
--   <a>stars</a> . adjacencyList        == id
--   </pre>
adjacencyList :: Eq a => Relation a -> [(a, [a])]

-- | The set of vertices of a given graph. Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   vertexSet <a>empty</a>      == Set.<a>empty</a>
--   vertexSet . <a>vertex</a>   == Set.<a>singleton</a>
--   vertexSet . <a>vertices</a> == Set.<a>fromList</a>
--   </pre>
vertexSet :: Relation a -> Set a

-- | The set of edges of a given graph, where edge vertices appear in the
--   non-decreasing order. Complexity: <i>O(m)</i> time.
--   
--   Note: If you need the set of edges where an edge appears in both
--   directions, use <tt><a>relation</a> . <a>fromSymmetric</a></tt>. The
--   latter is much faster than this function, and takes only <i>O(1)</i>
--   time and memory.
--   
--   <pre>
--   edgeSet <a>empty</a>      == Set.<a>empty</a>
--   edgeSet (<a>vertex</a> x) == Set.<a>empty</a>
--   edgeSet (<a>edge</a> x y) == Set.<a>singleton</a> (<a>min</a> x y, <a>max</a> x y)
--   </pre>
edgeSet :: Ord a => Relation a -> Set (a, a)

-- | The set of <i>neighbours</i> of an element <tt>x</tt> is the set of
--   elements that are related to it, i.e. <tt>neighbours x == { a | aRx
--   }</tt>. In the context of undirected graphs, this corresponds to the
--   set of <i>adjacent</i> vertices of vertex <tt>x</tt>.
--   
--   <pre>
--   neighbours x <a>empty</a>      == Set.<a>empty</a>
--   neighbours x (<a>vertex</a> x) == Set.<a>empty</a>
--   neighbours x (<a>edge</a> x y) == Set.<a>fromList</a> [y]
--   neighbours y (<a>edge</a> x y) == Set.<a>fromList</a> [x]
--   </pre>
neighbours :: Ord a => a -> Relation a -> Set a

-- | The <i>path</i> on a list of vertices. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   path []    == <a>empty</a>
--   path [x]   == <a>vertex</a> x
--   path [x,y] == <a>edge</a> x y
--   path       == path . <a>reverse</a>
--   </pre>
path :: Ord a => [a] -> Relation a

-- | The <i>circuit</i> on a list of vertices. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   circuit []    == <a>empty</a>
--   circuit [x]   == <a>edge</a> x x
--   circuit [x,y] == <a>edge</a> x y
--   circuit       == circuit . <a>reverse</a>
--   </pre>
circuit :: Ord a => [a] -> Relation a

-- | The <i>clique</i> on a list of vertices. Complexity: <i>O((n + m) *
--   log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   clique []         == <a>empty</a>
--   clique [x]        == <a>vertex</a> x
--   clique [x,y]      == <a>edge</a> x y
--   clique [x,y,z]    == <a>edges</a> [(x,y), (x,z), (y,z)]
--   clique (xs ++ ys) == <a>connect</a> (clique xs) (clique ys)
--   clique            == clique . <a>reverse</a>
--   </pre>
clique :: Ord a => [a] -> Relation a

-- | The <i>biclique</i> on two lists of vertices. Complexity: <i>O((n + m)
--   * log(n))</i> time and <i>O(n + m)</i> memory.
--   
--   <pre>
--   biclique []      []      == <a>empty</a>
--   biclique [x]     []      == <a>vertex</a> x
--   biclique []      [y]     == <a>vertex</a> y
--   biclique [x1,x2] [y1,y2] == <a>edges</a> [(x1,y1), (x1,y2), (x2,x2), (x2,y2)]
--   biclique xs      ys      == <a>connect</a> (<a>vertices</a> xs) (<a>vertices</a> ys)
--   </pre>
biclique :: Ord a => [a] -> [a] -> Relation a

-- | The <i>star</i> formed by a centre vertex connected to a list of
--   leaves. Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n +
--   m)</i> memory.
--   
--   <pre>
--   star x []    == <a>vertex</a> x
--   star x [y]   == <a>edge</a> x y
--   star x [y,z] == <a>edges</a> [(x,y), (x,z)]
--   star x ys    == <a>connect</a> (<a>vertex</a> x) (<a>vertices</a> ys)
--   </pre>
star :: Ord a => a -> [a] -> Relation a

-- | The <i>stars</i> formed by overlaying a list of <a>star</a>s. An
--   inverse of <a>adjacencyList</a>. Complexity: <i>O(L * log(n))</i>
--   time, memory and size, where <i>L</i> is the total size of the input.
--   
--   <pre>
--   stars []                      == <a>empty</a>
--   stars [(x, [])]               == <a>vertex</a> x
--   stars [(x, [y])]              == <a>edge</a> x y
--   stars [(x, ys)]               == <a>star</a> x ys
--   stars                         == <a>overlays</a> . <a>map</a> (<a>uncurry</a> <a>star</a>)
--   stars . <a>adjacencyList</a>         == id
--   <a>overlay</a> (stars xs) (stars ys) == stars (xs ++ ys)
--   </pre>
stars :: Ord a => [(a, [a])] -> Relation a

-- | The <i>tree graph</i> constructed from a given <a>Tree</a> data
--   structure. Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n +
--   m)</i> memory.
--   
--   <pre>
--   tree (Node x [])                                         == <a>vertex</a> x
--   tree (Node x [Node y [Node z []]])                       == <a>path</a> [x,y,z]
--   tree (Node x [Node y [], Node z []])                     == <a>star</a> x [y,z]
--   tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) == <a>edges</a> [(1,2), (1,3), (3,4), (3,5)]
--   </pre>
tree :: Ord a => Tree a -> Relation a

-- | The <i>forest graph</i> constructed from a given <a>Forest</a> data
--   structure. Complexity: <i>O((n + m) * log(n))</i> time and <i>O(n +
--   m)</i> memory.
--   
--   <pre>
--   forest []                                                  == <a>empty</a>
--   forest [x]                                                 == <a>tree</a> x
--   forest [Node 1 [Node 2 [], Node 3 []], Node 4 [Node 5 []]] == <a>edges</a> [(1,2), (1,3), (4,5)]
--   forest                                                     == <a>overlays</a> . <a>map</a> <a>tree</a>
--   </pre>
forest :: Ord a => Forest a -> Relation a

-- | Remove a vertex from a given graph. Complexity: <i>O(n + m)</i> time.
--   
--   <pre>
--   removeVertex x (<a>vertex</a> x)       == <a>empty</a>
--   removeVertex 1 (<a>vertex</a> 2)       == <a>vertex</a> 2
--   removeVertex x (<a>edge</a> x x)       == <a>empty</a>
--   removeVertex 1 (<a>edge</a> 1 2)       == <a>vertex</a> 2
--   removeVertex x . removeVertex x == removeVertex x
--   </pre>
removeVertex :: Ord a => a -> Relation a -> Relation a

-- | Remove an edge from a given graph. Complexity: <i>O(log(m))</i> time.
--   
--   <pre>
--   removeEdge x y (<a>edge</a> x y)       == <a>vertices</a> [x,y]
--   removeEdge x y . removeEdge x y == removeEdge x y
--   removeEdge x y                  == removeEdge y x
--   removeEdge x y . <a>removeVertex</a> x == <a>removeVertex</a> x
--   removeEdge 1 1 (1 * 1 * 2 * 2)  == 1 * 2 * 2
--   removeEdge 1 2 (1 * 1 * 2 * 2)  == 1 * 1 + 2 * 2
--   </pre>
removeEdge :: Ord a => a -> a -> Relation a -> Relation a

-- | The function <tt><a>replaceVertex</a> x y</tt> replaces vertex
--   <tt>x</tt> with vertex <tt>y</tt> in a given <a>Relation</a>. If
--   <tt>y</tt> already exists, <tt>x</tt> and <tt>y</tt> will be merged.
--   Complexity: <i>O((n + m) * log(n))</i> time.
--   
--   <pre>
--   replaceVertex x x            == id
--   replaceVertex x y (<a>vertex</a> x) == <a>vertex</a> y
--   replaceVertex x y            == <a>mergeVertices</a> (== x) y
--   </pre>
replaceVertex :: Ord a => a -> a -> Relation a -> Relation a

-- | Merge vertices satisfying a given predicate into a given vertex.
--   Complexity: <i>O((n + m) * log(n))</i> time, assuming that the
--   predicate takes constant time.
--   
--   <pre>
--   mergeVertices (<a>const</a> False) x    == id
--   mergeVertices (== x) y           == <a>replaceVertex</a> x y
--   mergeVertices <a>even</a> 1 (0 * 2)     == 1 * 1
--   mergeVertices <a>odd</a>  1 (3 + 4 * 5) == 4 * 1
--   </pre>
mergeVertices :: Ord a => (a -> Bool) -> a -> Relation a -> Relation a

-- | Transform a graph by applying a function to each of its vertices. This
--   is similar to <tt>Functor</tt>'s <a>fmap</a> but can be used with
--   non-fully-parametric <a>Relation</a>. Complexity: <i>O((n + m) *
--   log(n))</i> time.
--   
--   <pre>
--   gmap f <a>empty</a>      == <a>empty</a>
--   gmap f (<a>vertex</a> x) == <a>vertex</a> (f x)
--   gmap f (<a>edge</a> x y) == <a>edge</a> (f x) (f y)
--   gmap id           == id
--   gmap f . gmap g   == gmap (f . g)
--   </pre>
gmap :: Ord b => (a -> b) -> Relation a -> Relation b

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that do not satisfy a given predicate. Complexity: <i>O(n +
--   m)</i> time, assuming that the predicate takes constant time.
--   
--   <pre>
--   induce (<a>const</a> True ) x      == x
--   induce (<a>const</a> False) x      == <a>empty</a>
--   induce (/= x)               == <a>removeVertex</a> x
--   induce p . induce q         == induce (\x -&gt; p x &amp;&amp; q x)
--   <a>isSubgraphOf</a> (induce p x) x == True
--   </pre>
induce :: (a -> Bool) -> Relation a -> Relation a

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that are <a>Nothing</a>. Complexity: <i>O(n + m)</i> time.
--   
--   <pre>
--   induceJust (<a>vertex</a> <a>Nothing</a>)                               == <a>empty</a>
--   induceJust (<a>edge</a> (<a>Just</a> x) <a>Nothing</a>)                        == <a>vertex</a> x
--   induceJust . <a>gmap</a> <a>Just</a>                                    == <a>id</a>
--   induceJust . <a>gmap</a> (\x -&gt; if p x then <a>Just</a> x else <a>Nothing</a>) == <a>induce</a> p
--   </pre>
induceJust :: Ord a => Relation (Maybe a) -> Relation a

-- | Check that the internal representation of a symmetric relation is
--   consistent, i.e. that (i) that all edges refer to existing vertices,
--   and (ii) all edges have their symmetric counterparts. It should be
--   impossible to create an inconsistent <a>Relation</a>, and we use this
--   function in testing.
--   
--   <pre>
--   consistent <a>empty</a>         == True
--   consistent (<a>vertex</a> x)    == True
--   consistent (<a>overlay</a> x y) == True
--   consistent (<a>connect</a> x y) == True
--   consistent (<a>edge</a> x y)    == True
--   consistent (<a>edges</a> xs)    == True
--   consistent (<a>stars</a> xs)    == True
--   </pre>
consistent :: Ord a => Relation a -> Bool
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Algebra.Graph.Relation.Symmetric.Relation a)
instance Data.String.IsString a => Data.String.IsString (Algebra.Graph.Relation.Symmetric.Relation a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Algebra.Graph.Relation.Symmetric.Relation a)
instance (GHC.Classes.Ord a, GHC.Show.Show a) => GHC.Show.Show (Algebra.Graph.Relation.Symmetric.Relation a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.Relation.Symmetric.Relation a)
instance (GHC.Classes.Ord a, GHC.Num.Num a) => GHC.Num.Num (Algebra.Graph.Relation.Symmetric.Relation a)
instance GHC.Classes.Ord a => GHC.Base.Semigroup (Algebra.Graph.Relation.Symmetric.Relation a)
instance GHC.Classes.Ord a => GHC.Base.Monoid (Algebra.Graph.Relation.Symmetric.Relation a)


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module defines the type class <a>ToGraph</a> for capturing data
--   types that can be converted to algebraic graphs. To make an instance
--   of this class you need to define just a single method (<a>toGraph</a>
--   or <a>foldg</a>), which gives you access to many other useful methods
--   for free (although note that the default implementations may be
--   suboptimal performance-wise).
--   
--   This type class is similar to the standard type class <a>Foldable</a>
--   defined for lists. Furthermore, one can define <a>Foldable</a> methods
--   <a>foldMap</a> and <a>toList</a> using <tt>ToGraph</tt>.<a>foldg</a>:
--   
--   <pre>
--   <a>foldMap</a> f = <a>foldg</a> <a>mempty</a> f    (<a>&lt;&gt;</a>) (<a>&lt;&gt;</a>)
--   <a>toList</a>    = <a>foldg</a> []     <a>pure</a> (<a>++</a>) (<a>++</a>)
--   </pre>
--   
--   However, the resulting <a>Foldable</a> instance is problematic. For
--   example, folding equivalent algebraic graphs <tt>1</tt> and <tt>1</tt>
--   + <tt>1</tt> leads to different results:
--   
--   <pre>
--   <a>toList</a> (1    ) == [1]
--   <a>toList</a> (1 + 1) == [1, 1]
--   </pre>
--   
--   To avoid such cases, we do not provide <a>Foldable</a> instances for
--   algebraic graph datatypes. Furthermore, we require that the four
--   arguments passed to <a>foldg</a> satisfy the laws of the algebra of
--   graphs. The above definitions of <a>foldMap</a> and <a>toList</a>
--   violate this requirement, for example <tt>[1] ++ [1] /= [1]</tt>, and
--   are therefore disallowed.
module Algebra.Graph.ToGraph

-- | The <a>ToGraph</a> type class captures data types that can be
--   converted to algebraic graphs. Instances of this type class should
--   satisfy the laws specified by the default method definitions.
class ToGraph t where {
    
    -- | The type of vertices of the resulting graph.
    type family ToVertex t;
}

-- | Convert a value to the corresponding algebraic graph, see
--   <a>Algebra.Graph</a>.
--   
--   <pre>
--   toGraph == <a>foldg</a> <a>Empty</a> <a>Vertex</a> <a>Overlay</a> <a>Connect</a>
--   </pre>
toGraph :: ToGraph t => t -> Graph (ToVertex t)

-- | The method <a>foldg</a> is used for generalised graph folding. It
--   collapses a given value by applying the provided graph construction
--   primitives. The order of arguments is: empty, vertex, overlay and
--   connect, and it is assumed that the arguments satisfy the axioms of
--   the graph algebra.
--   
--   <pre>
--   foldg == Algebra.Graph.<a>foldg</a> . <a>toGraph</a>
--   </pre>
foldg :: ToGraph t => r -> (ToVertex t -> r) -> (r -> r -> r) -> (r -> r -> r) -> t -> r

-- | Check if a graph is empty.
--   
--   <pre>
--   isEmpty == <a>foldg</a> True (<a>const</a> False) (&amp;&amp;) (&amp;&amp;)
--   </pre>
isEmpty :: ToGraph t => t -> Bool

-- | Check if a graph contains a given vertex.
--   
--   <pre>
--   hasVertex x == <a>foldg</a> False (==x) (||) (||)
--   </pre>
hasVertex :: (ToGraph t, Eq (ToVertex t)) => ToVertex t -> t -> Bool

-- | Check if a graph contains a given edge.
--   
--   <pre>
--   hasEdge x y == Algebra.Graph.<a>hasEdge</a> x y . <a>toGraph</a>
--   </pre>
hasEdge :: (ToGraph t, Eq (ToVertex t)) => ToVertex t -> ToVertex t -> t -> Bool

-- | The number of vertices in a graph.
--   
--   <pre>
--   vertexCount == Set.<a>size</a> . <a>vertexSet</a>
--   </pre>
vertexCount :: (ToGraph t, Ord (ToVertex t)) => t -> Int

-- | The number of edges in a graph.
--   
--   <pre>
--   edgeCount == Set.<a>size</a> . <a>edgeSet</a>
--   </pre>
edgeCount :: (ToGraph t, Ord (ToVertex t)) => t -> Int

-- | The sorted list of vertices of a given graph.
--   
--   <pre>
--   vertexList == Set.<a>toAscList</a> . <a>vertexSet</a>
--   </pre>
vertexList :: (ToGraph t, Ord (ToVertex t)) => t -> [ToVertex t]

-- | The sorted list of edges of a graph.
--   
--   <pre>
--   edgeList == Set.<a>toAscList</a> . <a>edgeSet</a>
--   </pre>
edgeList :: (ToGraph t, Ord (ToVertex t)) => t -> [(ToVertex t, ToVertex t)]

-- | The set of vertices of a graph.
--   
--   <pre>
--   vertexSet == <a>foldg</a> Set.<a>empty</a> Set.<a>singleton</a> Set.<a>union</a> Set.<a>union</a>
--   </pre>
vertexSet :: (ToGraph t, Ord (ToVertex t)) => t -> Set (ToVertex t)

-- | The set of vertices of a graph. Like <a>vertexSet</a> but specialised
--   for graphs with vertices of type <a>Int</a>.
--   
--   <pre>
--   vertexIntSet == <a>foldg</a> IntSet.<a>empty</a> IntSet.<a>singleton</a> IntSet.<a>union</a> IntSet.<a>union</a>
--   </pre>
vertexIntSet :: (ToGraph t, ToVertex t ~ Int) => t -> IntSet

-- | The set of edges of a graph.
--   
--   <pre>
--   edgeSet == Algebra.Graph.AdjacencyMap.<a>edgeSet</a> . <a>toAdjacencyMap</a>
--   </pre>
edgeSet :: (ToGraph t, Ord (ToVertex t)) => t -> Set (ToVertex t, ToVertex t)

-- | The <i>preset</i> of a vertex is the set of its <i>direct
--   predecessors</i>.
--   
--   <pre>
--   preSet x == Algebra.Graph.AdjacencyMap.<a>preSet</a> x . <a>toAdjacencyMap</a>
--   </pre>
preSet :: (ToGraph t, Ord (ToVertex t)) => ToVertex t -> t -> Set (ToVertex t)

-- | The <i>preset</i> (here <tt>preIntSet</tt>) of a vertex is the set of
--   its <i>direct predecessors</i>. Like <a>preSet</a> but specialised for
--   graphs with vertices of type <a>Int</a>.
--   
--   <pre>
--   preIntSet x == Algebra.Graph.AdjacencyIntMap.<a>preIntSet</a> x . <a>toAdjacencyIntMap</a>
--   </pre>
preIntSet :: (ToGraph t, ToVertex t ~ Int) => Int -> t -> IntSet

-- | The <i>postset</i> of a vertex is the set of its <i>direct
--   successors</i>.
--   
--   <pre>
--   postSet x == Algebra.Graph.AdjacencyMap.<a>postSet</a> x . <a>toAdjacencyMap</a>
--   </pre>
postSet :: (ToGraph t, Ord (ToVertex t)) => ToVertex t -> t -> Set (ToVertex t)

-- | The <i>postset</i> (here <tt>postIntSet</tt>) of a vertex is the set
--   of its <i>direct successors</i>. Like <a>postSet</a> but specialised
--   for graphs with vertices of type <a>Int</a>.
--   
--   <pre>
--   postIntSet x == Algebra.Graph.AdjacencyIntMap.<a>postIntSet</a> x . <a>toAdjacencyIntMap</a>
--   </pre>
postIntSet :: (ToGraph t, ToVertex t ~ Int) => Int -> t -> IntSet

-- | The sorted <i>adjacency list</i> of a graph.
--   
--   <pre>
--   adjacencyList == Algebra.Graph.AdjacencyMap.<a>adjacencyList</a> . <a>toAdjacencyMap</a>
--   </pre>
adjacencyList :: (ToGraph t, Ord (ToVertex t)) => t -> [(ToVertex t, [ToVertex t])]

-- | Compute the <i>depth-first search</i> forest of a graph that
--   corresponds to searching from each of the graph vertices in the
--   <a>Ord</a> <tt>a</tt> order.
--   
--   <pre>
--   dfsForest == Algebra.Graph.AdjacencyMap.<a>dfsForest</a> . toAdjacencyMap
--   </pre>
dfsForest :: (ToGraph t, Ord (ToVertex t)) => t -> Forest (ToVertex t)

-- | Compute the <i>depth-first search</i> forest of a graph, searching
--   from each of the given vertices in order. Note that the resulting
--   forest does not necessarily span the whole graph, as some vertices may
--   be unreachable.
--   
--   <pre>
--   dfsForestFrom vs == Algebra.Graph.AdjacencyMap.<a>dfsForestFrom</a> vs . toAdjacencyMap
--   </pre>
dfsForestFrom :: (ToGraph t, Ord (ToVertex t)) => [ToVertex t] -> t -> Forest (ToVertex t)

-- | Compute the list of vertices visited by the <i>depth-first search</i>
--   in a graph, when searching from each of the given vertices in order.
--   
--   <pre>
--   dfs vs == Algebra.Graph.AdjacencyMap.<a>dfs</a> vs . toAdjacencyMap
--   </pre>
dfs :: (ToGraph t, Ord (ToVertex t)) => [ToVertex t] -> t -> [ToVertex t]

-- | Compute the list of vertices that are <i>reachable</i> from a given
--   source vertex in a graph. The vertices in the resulting list appear in
--   the <i>depth-first order</i>.
--   
--   <pre>
--   reachable x == Algebra.Graph.AdjacencyMap.<a>reachable</a> x . toAdjacencyMap
--   </pre>
reachable :: (ToGraph t, Ord (ToVertex t)) => ToVertex t -> t -> [ToVertex t]

-- | Compute the <i>topological sort</i> of a graph or a <tt>AM.Cycle</tt>
--   if the graph is cyclic.
--   
--   <pre>
--   topSort == Algebra.Graph.AdjacencyMap.<a>topSort</a> . toAdjacencyMap
--   </pre>
topSort :: (ToGraph t, Ord (ToVertex t)) => t -> Either (Cycle (ToVertex t)) [ToVertex t]

-- | Check if a given graph is <i>acyclic</i>.
--   
--   <pre>
--   isAcyclic == Algebra.Graph.AdjacencyMap.<a>isAcyclic</a> . toAdjacencyMap
--   </pre>
isAcyclic :: (ToGraph t, Ord (ToVertex t)) => t -> Bool

-- | Convert a value to the corresponding <a>AdjacencyMap</a>.
--   
--   <pre>
--   toAdjacencyMap == <a>foldg</a> <a>empty</a> <a>vertex</a> <a>overlay</a> <a>connect</a>
--   </pre>
toAdjacencyMap :: (ToGraph t, Ord (ToVertex t)) => t -> AdjacencyMap (ToVertex t)

-- | Convert a value to the corresponding <a>AdjacencyMap</a> and transpose
--   the result.
--   
--   <pre>
--   toAdjacencyMapTranspose == <a>foldg</a> <a>empty</a> <a>vertex</a> <a>overlay</a> (<a>flip</a> <a>connect</a>)
--   </pre>
toAdjacencyMapTranspose :: (ToGraph t, Ord (ToVertex t)) => t -> AdjacencyMap (ToVertex t)

-- | Convert a value to the corresponding <a>AdjacencyIntMap</a>.
--   
--   <pre>
--   toAdjacencyIntMap == <a>foldg</a> <a>empty</a> <a>vertex</a> <a>overlay</a> <a>connect</a>
--   </pre>
toAdjacencyIntMap :: (ToGraph t, ToVertex t ~ Int) => t -> AdjacencyIntMap

-- | Convert a value to the corresponding <a>AdjacencyIntMap</a> and
--   transpose the result.
--   
--   <pre>
--   toAdjacencyIntMapTranspose == <a>foldg</a> <a>empty</a> <a>vertex</a> <a>overlay</a> (<a>flip</a> <a>connect</a>)
--   </pre>
toAdjacencyIntMapTranspose :: (ToGraph t, ToVertex t ~ Int) => t -> AdjacencyIntMap

-- | Check if a given forest is a valid <i>depth-first search</i> forest of
--   a graph.
--   
--   <pre>
--   isDfsForestOf f == Algebra.Graph.AdjacencyMap.<a>isDfsForestOf</a> f . toAdjacencyMap
--   </pre>
isDfsForestOf :: (ToGraph t, Ord (ToVertex t)) => Forest (ToVertex t) -> t -> Bool

-- | Check if a given list of vertices is a valid <i>topological sort</i>
--   of a graph.
--   
--   <pre>
--   isTopSortOf vs == Algebra.Graph.AdjacencyMap.<a>isTopSortOf</a> vs . toAdjacencyMap
--   </pre>
isTopSortOf :: (ToGraph t, Ord (ToVertex t)) => [ToVertex t] -> t -> Bool

-- | The <i>adjacency map</i> of a graph: each vertex is associated with a
--   set of its <i>direct successors</i>.
--   
--   <pre>
--   adjacencyMap == Algebra.Graph.AdjacencyMap.<a>adjacencyMap</a> . <a>toAdjacencyMap</a>
--   </pre>
adjacencyMap :: ToGraph t => Ord (ToVertex t) => t -> Map (ToVertex t) (Set (ToVertex t))

-- | The <i>adjacency map</i> of a graph: each vertex is associated with a
--   set of its <i>direct successors</i>. Like <a>adjacencyMap</a> but
--   specialised for graphs with vertices of type <a>Int</a>.
--   
--   <pre>
--   adjacencyIntMap == Algebra.Graph.AdjacencyIntMap.<a>adjacencyIntMap</a> . <a>toAdjacencyIntMap</a>
--   </pre>
adjacencyIntMap :: (ToGraph t, ToVertex t ~ Int) => t -> IntMap IntSet

-- | The transposed <i>adjacency map</i> of a graph: each vertex is
--   associated with a set of its <i>direct predecessors</i>.
--   
--   <pre>
--   adjacencyMapTranspose == Algebra.Graph.AdjacencyMap.<a>adjacencyMap</a> . <a>toAdjacencyMapTranspose</a>
--   </pre>
adjacencyMapTranspose :: (ToGraph t, Ord (ToVertex t)) => t -> Map (ToVertex t) (Set (ToVertex t))

-- | The transposed <i>adjacency map</i> of a graph: each vertex is
--   associated with a set of its <i>direct predecessors</i>. Like
--   <a>adjacencyMapTranspose</a> but specialised for graphs with vertices
--   of type <a>Int</a>.
--   
--   <pre>
--   adjacencyIntMapTranspose == Algebra.Graph.AdjacencyIntMap.<a>adjacencyIntMap</a> . <a>toAdjacencyIntMapTranspose</a>
--   </pre>
adjacencyIntMapTranspose :: (ToGraph t, ToVertex t ~ Int) => t -> IntMap IntSet
instance GHC.Classes.Ord a => Algebra.Graph.ToGraph.ToGraph (Algebra.Graph.Graph a)
instance GHC.Classes.Ord a => Algebra.Graph.ToGraph.ToGraph (Algebra.Graph.AdjacencyMap.AdjacencyMap a)
instance Algebra.Graph.ToGraph.ToGraph Algebra.Graph.AdjacencyIntMap.AdjacencyIntMap
instance (GHC.Classes.Eq e, GHC.Base.Monoid e, GHC.Classes.Ord a) => Algebra.Graph.ToGraph.ToGraph (Algebra.Graph.Labelled.Graph e a)
instance (GHC.Classes.Eq e, GHC.Base.Monoid e, GHC.Classes.Ord a) => Algebra.Graph.ToGraph.ToGraph (Algebra.Graph.Labelled.AdjacencyMap.AdjacencyMap e a)
instance GHC.Classes.Ord a => Algebra.Graph.ToGraph.ToGraph (Algebra.Graph.NonEmpty.AdjacencyMap.AdjacencyMap a)
instance GHC.Classes.Ord a => Algebra.Graph.ToGraph.ToGraph (Algebra.Graph.Relation.Relation a)
instance GHC.Classes.Ord a => Algebra.Graph.ToGraph.ToGraph (Algebra.Graph.Relation.Symmetric.Relation a)


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module defines the data type <a>Graph</a> for algebraic graphs
--   that are known to be non-empty at compile time. To avoid name clashes
--   with <a>Algebra.Graph</a>, this module can be imported qualified:
--   
--   <pre>
--   import qualified Algebra.Graph.NonEmpty as NonEmpty
--   </pre>
--   
--   The naming convention generally follows that of
--   <a>Data.List.NonEmpty</a>: we use suffix <tt>1</tt> to indicate the
--   functions whose interface must be changed compared to
--   <a>Algebra.Graph</a>, e.g. <a>vertices1</a>.
module Algebra.Graph.NonEmpty

-- | Non-empty algebraic graphs, which are constructed using three
--   primitives: <a>vertex</a>, <a>overlay</a> and <a>connect</a>. See
--   module <a>Algebra.Graph</a> for algebraic graphs that can be empty.
--   
--   We define a <a>Num</a> instance as a convenient notation for working
--   with graphs:
--   
--   <pre>
--   0           == <a>vertex</a> 0
--   1 + 2       == <a>overlay</a> (<a>vertex</a> 1) (<a>vertex</a> 2)
--   1 * 2       == <a>connect</a> (<a>vertex</a> 1) (<a>vertex</a> 2)
--   1 + 2 * 3   == <a>overlay</a> (<a>vertex</a> 1) (<a>connect</a> (<a>vertex</a> 2) (<a>vertex</a> 3))
--   1 * (2 + 3) == <a>connect</a> (<a>vertex</a> 1) (<a>overlay</a> (<a>vertex</a> 2) (<a>vertex</a> 3))
--   </pre>
--   
--   <b>Note:</b> the <a>signum</a> method of the type class <a>Num</a>
--   cannot be implemented and will throw an error. Furthermore, the
--   <a>Num</a> instance does not satisfy several "customary laws" of
--   <a>Num</a>, which dictate that <a>fromInteger</a> <tt>0</tt> and
--   <a>fromInteger</a> <tt>1</tt> should act as additive and
--   multiplicative identities, and <a>negate</a> as additive inverse.
--   Nevertheless, overloading <a>fromInteger</a>, <a>+</a> and <a>*</a> is
--   very convenient when working with algebraic graphs; we hope that in
--   future Haskell's Prelude will provide a more fine-grained class
--   hierarchy for algebraic structures, which we would be able to utilise
--   without violating any laws.
--   
--   The <a>Eq</a> instance satisfies the following laws of non-empty
--   algebraic graphs.
--   
--   <ul>
--   <li><a>overlay</a> is commutative, associative and idempotent:<pre> x
--   + y == y + x x + (y + z) == (x + y) + z x + x == x</pre></li>
--   <li><a>connect</a> is associative:<pre>x * (y * z) == (x * y) *
--   z</pre></li>
--   <li><a>connect</a> distributes over <a>overlay</a>:<pre>x * (y + z) ==
--   x * y + x * z (x + y) * z == x * z + y * z</pre></li>
--   <li><a>connect</a> can be decomposed:<pre>x * y * z == x * y + x * z +
--   y * z</pre></li>
--   <li><a>connect</a> satisfies absorption and saturation:<pre>x * y + x
--   + y == x * y x * x * x == x * x</pre></li>
--   </ul>
--   
--   When specifying the time and memory complexity of graph algorithms,
--   <i>n</i> will denote the number of vertices in the graph, <i>m</i>
--   will denote the number of edges in the graph, and <i>s</i> will denote
--   the <i>size</i> of the corresponding <a>Graph</a> expression, defined
--   as the number of vertex leaves (note that <i>n</i> &lt;= <i>s</i>). If
--   <tt>g</tt> is a <a>Graph</a>, the corresponding <i>n</i>, <i>m</i> and
--   <i>s</i> can be computed as follows:
--   
--   <pre>
--   n == <a>vertexCount</a> g
--   m == <a>edgeCount</a> g
--   s == <a>size</a> g
--   </pre>
--   
--   Converting a <a>Graph</a> to the corresponding <a>AdjacencyMap</a>
--   takes <i>O(s + m * log(m))</i> time and <i>O(s + m)</i> 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.
--   
--   The total order <a>Ord</a> on graphs is defined using
--   <i>size-lexicographic</i> comparison:
--   
--   <ul>
--   <li>Compare the number of vertices. In case of a tie, continue.</li>
--   <li>Compare the sets of vertices. In case of a tie, continue.</li>
--   <li>Compare the number of edges. In case of a tie, continue.</li>
--   <li>Compare the sets of edges.</li>
--   </ul>
--   
--   Here are a few examples:
--   
--   <pre>
--   <a>vertex</a> 1 &lt; <a>vertex</a> 2
--   <a>vertex</a> 3 &lt; <a>edge</a> 1 2
--   <a>vertex</a> 1 &lt; <a>edge</a> 1 1
--   <a>edge</a> 1 1 &lt; <a>edge</a> 1 2
--   <a>edge</a> 1 2 &lt; <a>edge</a> 1 1 + <a>edge</a> 2 2
--   <a>edge</a> 1 2 &lt; <a>edge</a> 1 3
--   </pre>
--   
--   Note that the resulting order refines the <a>isSubgraphOf</a> relation
--   and is compatible with <a>overlay</a> and <a>connect</a> operations:
--   
--   <pre>
--   <a>isSubgraphOf</a> x y ==&gt; x &lt;= y
--   </pre>
--   
--   <pre>
--   x     &lt;= x + y
--   x + y &lt;= x * y
--   </pre>
data Graph a
Vertex :: a -> Graph a
Overlay :: Graph a -> Graph a -> Graph a
Connect :: Graph a -> Graph a -> Graph a

-- | Convert an algebraic graph (from <a>Algebra.Graph</a>) into a
--   non-empty algebraic graph. Returns <a>Nothing</a> if the argument is
--   <a>empty</a>. Complexity: <i>O(s)</i> time, memory and size.
--   
--   <pre>
--   toNonEmpty <a>empty</a>       == Nothing
--   toNonEmpty (<a>toGraph</a> x) == Just (x :: <a>Graph</a> a)
--   </pre>
toNonEmpty :: Graph a -> Maybe (Graph a)

-- | Construct the graph comprising <i>a single isolated vertex</i>. An
--   alias for the constructor <a>Vertex</a>.
--   
--   <pre>
--   <a>hasVertex</a> x (vertex y) == (x == y)
--   <a>vertexCount</a> (vertex x) == 1
--   <a>edgeCount</a>   (vertex x) == 0
--   <a>size</a>        (vertex x) == 1
--   </pre>
vertex :: a -> Graph a

-- | Construct the graph comprising <i>a single edge</i>.
--   
--   <pre>
--   edge x y               == <a>connect</a> (<a>vertex</a> x) (<a>vertex</a> y)
--   <a>hasEdge</a> x y (edge x y) == True
--   <a>edgeCount</a>   (edge x y) == 1
--   <a>vertexCount</a> (edge 1 1) == 1
--   <a>vertexCount</a> (edge 1 2) == 2
--   </pre>
edge :: a -> a -> Graph a

-- | <i>Overlay</i> two graphs. An alias for the constructor
--   <a>Overlay</a>. This is a commutative, associative and idempotent
--   operation. Complexity: <i>O(1)</i> time and memory, <i>O(s1 + s2)</i>
--   size.
--   
--   <pre>
--   <a>hasVertex</a> z (overlay x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (overlay x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (overlay x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (overlay x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (overlay x y) &lt;= <a>edgeCount</a> x   + <a>edgeCount</a> y
--   <a>size</a>        (overlay x y) == <a>size</a> x        + <a>size</a> y
--   <a>vertexCount</a> (overlay 1 2) == 2
--   <a>edgeCount</a>   (overlay 1 2) == 0
--   </pre>
overlay :: Graph a -> Graph a -> Graph a

-- | Overlay a possibly empty graph (from <a>Algebra.Graph</a>) with a
--   non-empty graph. If the first argument is <a>empty</a>, the function
--   returns the second argument; otherwise it is semantically the same as
--   <a>overlay</a>. Complexity: <i>O(s1)</i> time and memory, and <i>O(s1
--   + s2)</i> size.
--   
--   <pre>
--                  overlay1 <a>empty</a> x == x
--   x /= <a>empty</a> ==&gt; overlay1 x     y == overlay (fromJust $ toNonEmpty x) y
--   </pre>
overlay1 :: Graph a -> Graph a -> Graph a

-- | <i>Connect</i> two graphs. An alias for the constructor
--   <a>Connect</a>. This is an associative operation, which distributes
--   over <a>overlay</a> and obeys the decomposition axiom. Complexity:
--   <i>O(1)</i> time and memory, <i>O(s1 + s2)</i> size. Note that the
--   number of edges in the resulting graph is quadratic with respect to
--   the number of vertices of the arguments: <i>m = O(m1 + m2 + n1 *
--   n2)</i>.
--   
--   <pre>
--   <a>hasVertex</a> z (connect x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (connect x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (connect x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (connect x y) &gt;= <a>edgeCount</a> y
--   <a>edgeCount</a>   (connect x y) &gt;= <a>vertexCount</a> x * <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect x y) &lt;= <a>vertexCount</a> x * <a>vertexCount</a> y + <a>edgeCount</a> x + <a>edgeCount</a> y
--   <a>size</a>        (connect x y) == <a>size</a> x        + <a>size</a> y
--   <a>vertexCount</a> (connect 1 2) == 2
--   <a>edgeCount</a>   (connect 1 2) == 1
--   </pre>
connect :: Graph a -> Graph a -> Graph a

-- | Construct the graph comprising a given list of isolated vertices.
--   Complexity: <i>O(L)</i> time, memory and size, where <i>L</i> is the
--   length of the given list.
--   
--   <pre>
--   vertices1 [x]           == <a>vertex</a> x
--   <a>hasVertex</a> x . vertices1 == <a>elem</a> x
--   <a>vertexCount</a> . vertices1 == <a>length</a> . <a>nub</a>
--   <a>vertexSet</a>   . vertices1 == Set.<a>fromList</a> . <a>toList</a>
--   </pre>
vertices1 :: NonEmpty a -> Graph a

-- | Construct the graph from a list of edges. Complexity: <i>O(L)</i>
--   time, memory and size, where <i>L</i> is the length of the given list.
--   
--   <pre>
--   edges1 [(x,y)]     == <a>edge</a> x y
--   edges1             == <a>overlays1</a> . <a>fmap</a> (<a>uncurry</a> <a>edge</a>)
--   <a>edgeCount</a> . edges1 == <a>length</a> . <a>nub</a>
--   </pre>
edges1 :: NonEmpty (a, a) -> Graph a

-- | Overlay a given list of graphs. Complexity: <i>O(L)</i> time and
--   memory, and <i>O(S)</i> size, where <i>L</i> is the length of the
--   given list, and <i>S</i> is the sum of sizes of the graphs in the
--   list.
--   
--   <pre>
--   overlays1 [x]   == x
--   overlays1 [x,y] == <a>overlay</a> x y
--   </pre>
overlays1 :: NonEmpty (Graph a) -> Graph a

-- | Connect a given list of graphs. Complexity: <i>O(L)</i> time and
--   memory, and <i>O(S)</i> size, where <i>L</i> is the length of the
--   given list, and <i>S</i> is the sum of sizes of the graphs in the
--   list.
--   
--   <pre>
--   connects1 [x]   == x
--   connects1 [x,y] == <a>connect</a> x y
--   </pre>
connects1 :: NonEmpty (Graph a) -> Graph a

-- | Generalised graph folding: recursively collapse a <a>Graph</a> by
--   applying the provided functions to the leaves and internal nodes of
--   the expression. The order of arguments is: vertex, overlay and
--   connect. Complexity: <i>O(s)</i> applications of the given functions.
--   As an example, the complexity of <a>size</a> is <i>O(s)</i>, since
--   <a>const</a> and <a>+</a> have constant costs.
--   
--   <pre>
--   foldg1 <a>vertex</a>    <a>overlay</a> <a>connect</a>        == id
--   foldg1 <a>vertex</a>    <a>overlay</a> (<a>flip</a> <a>connect</a>) == <a>transpose</a>
--   foldg1 (<a>const</a> 1) (+)     (+)            == <a>size</a>
--   foldg1 (== x)    (||)    (||)           == <a>hasVertex</a> x
--   </pre>
foldg1 :: (a -> b) -> (b -> b -> b) -> (b -> b -> b) -> Graph a -> b

-- | The <a>isSubgraphOf</a> function takes two graphs and returns
--   <a>True</a> if the first graph is a <i>subgraph</i> of the second.
--   Complexity: <i>O(s + m * log(m))</i> time. Note that the number of
--   edges <i>m</i> of a graph can be quadratic with respect to the
--   expression size <i>s</i>.
--   
--   <pre>
--   isSubgraphOf x             (<a>overlay</a> x y) ==  True
--   isSubgraphOf (<a>overlay</a> x y) (<a>connect</a> x y) ==  True
--   isSubgraphOf (<a>path1</a> xs)    (<a>circuit1</a> xs) ==  True
--   isSubgraphOf x y                         ==&gt; x &lt;= y
--   </pre>
isSubgraphOf :: Ord a => Graph a -> Graph a -> Bool

-- | Structural equality on graph expressions. Complexity: <i>O(s)</i>
--   time.
--   
--   <pre>
--       x === x     == True
--   x + y === x + y == True
--   1 + 2 === 2 + 1 == False
--   x + y === x * y == False
--   </pre>
(===) :: Eq a => Graph a -> Graph a -> Bool
infix 4 ===

-- | The <i>size</i> of a graph, i.e. the number of leaves of the
--   expression. Complexity: <i>O(s)</i> time.
--   
--   <pre>
--   size (<a>vertex</a> x)    == 1
--   size (<a>overlay</a> x y) == size x + size y
--   size (<a>connect</a> x y) == size x + size y
--   size x             &gt;= 1
--   size x             &gt;= <a>vertexCount</a> x
--   </pre>
size :: Graph a -> Int

-- | Check if a graph contains a given vertex. Complexity: <i>O(s)</i>
--   time.
--   
--   <pre>
--   hasVertex x (<a>vertex</a> y) == (x == y)
--   </pre>
hasVertex :: Eq a => a -> Graph a -> Bool

-- | Check if a graph contains a given edge. Complexity: <i>O(s)</i> time.
--   
--   <pre>
--   hasEdge x y (<a>vertex</a> z)       == False
--   hasEdge x y (<a>edge</a> x y)       == True
--   hasEdge x y . <a>removeEdge</a> x y == <a>const</a> False
--   hasEdge x y                  == <a>elem</a> (x,y) . <a>edgeList</a>
--   </pre>
hasEdge :: Eq a => a -> a -> Graph a -> Bool

-- | The number of vertices in a graph. Complexity: <i>O(s * log(n))</i>
--   time.
--   
--   <pre>
--   vertexCount (<a>vertex</a> x)        ==  1
--   vertexCount                   ==  <a>length</a> . <tt>vertexList</tt>
--   vertexCount x &lt; vertexCount y ==&gt; x &lt; y
--   </pre>
vertexCount :: Ord a => Graph a -> Int

-- | The number of edges in a graph. Complexity: <i>O(s + m * log(m))</i>
--   time. Note that the number of edges <i>m</i> of a graph can be
--   quadratic with respect to the expression size <i>s</i>.
--   
--   <pre>
--   edgeCount (<a>vertex</a> x) == 0
--   edgeCount (<a>edge</a> x y) == 1
--   edgeCount            == <a>length</a> . <a>edgeList</a>
--   </pre>
edgeCount :: Ord a => Graph a -> Int

-- | The sorted list of vertices of a given graph. Complexity: <i>O(s *
--   log(n))</i> time and <i>O(n)</i> memory.
--   
--   <pre>
--   vertexList1 (<a>vertex</a> x)  == [x]
--   vertexList1 . <a>vertices1</a> == <a>nub</a> . <a>sort</a>
--   </pre>
vertexList1 :: Ord a => Graph a -> NonEmpty a

-- | The sorted list of edges of a graph. Complexity: <i>O(s + m *
--   log(m))</i> time and <i>O(m)</i> memory. Note that the number of edges
--   <i>m</i> of a graph can be quadratic with respect to the expression
--   size <i>s</i>.
--   
--   <pre>
--   edgeList (<a>vertex</a> x)     == []
--   edgeList (<a>edge</a> x y)     == [(x,y)]
--   edgeList (<a>star</a> 2 [3,1]) == [(2,1), (2,3)]
--   edgeList . <a>edges1</a>       == <a>nub</a> . <a>sort</a> . <a>toList</a>
--   edgeList . <a>transpose</a>    == <a>sort</a> . <a>map</a> <a>swap</a> . edgeList
--   </pre>
edgeList :: Ord a => Graph a -> [(a, a)]

-- | The set of vertices of a given graph. Complexity: <i>O(s * log(n))</i>
--   time and <i>O(n)</i> memory.
--   
--   <pre>
--   vertexSet . <a>vertex</a>    == Set.<a>singleton</a>
--   vertexSet . <a>vertices1</a> == Set.<a>fromList</a> . <a>toList</a>
--   vertexSet . <a>clique1</a>   == Set.<a>fromList</a> . <a>toList</a>
--   </pre>
vertexSet :: Ord a => Graph a -> Set a

-- | The set of edges of a given graph. Complexity: <i>O(s * log(m))</i>
--   time and <i>O(m)</i> memory.
--   
--   <pre>
--   edgeSet (<a>vertex</a> x) == Set.<a>empty</a>
--   edgeSet (<a>edge</a> x y) == Set.<a>singleton</a> (x,y)
--   edgeSet . <a>edges1</a>   == Set.<a>fromList</a> . <a>toList</a>
--   </pre>
edgeSet :: Ord a => Graph a -> Set (a, a)

-- | The <i>path</i> on a list of vertices. Complexity: <i>O(L)</i> time,
--   memory and size, where <i>L</i> is the length of the given list.
--   
--   <pre>
--   path1 [x]       == <a>vertex</a> x
--   path1 [x,y]     == <a>edge</a> x y
--   path1 . <a>reverse</a> == <a>transpose</a> . path1
--   </pre>
path1 :: NonEmpty a -> Graph a

-- | The <i>circuit</i> on a list of vertices. Complexity: <i>O(L)</i>
--   time, memory and size, where <i>L</i> is the length of the given list.
--   
--   <pre>
--   circuit1 [x]       == <a>edge</a> x x
--   circuit1 [x,y]     == <a>edges1</a> [(x,y), (y,x)]
--   circuit1 . <a>reverse</a> == <a>transpose</a> . circuit1
--   </pre>
circuit1 :: NonEmpty a -> Graph a

-- | The <i>clique</i> on a list of vertices. Complexity: <i>O(L)</i> time,
--   memory and size, where <i>L</i> is the length of the given list.
--   
--   <pre>
--   clique1 [x]        == <a>vertex</a> x
--   clique1 [x,y]      == <a>edge</a> x y
--   clique1 [x,y,z]    == <a>edges1</a> [(x,y), (x,z), (y,z)]
--   clique1 (xs <a>&lt;&gt;</a> ys) == <a>connect</a> (clique1 xs) (clique1 ys)
--   clique1 . <a>reverse</a>  == <a>transpose</a> . clique1
--   </pre>
clique1 :: NonEmpty a -> Graph a

-- | The <i>biclique</i> on two lists of vertices. Complexity: <i>O(L1 +
--   L2)</i> time, memory and size, where <i>L1</i> and <i>L2</i> are the
--   lengths of the given lists.
--   
--   <pre>
--   biclique1 [x1,x2] [y1,y2] == <a>edges1</a> [(x1,y1), (x1,y2), (x2,y1), (x2,y2)]
--   biclique1 xs      ys      == <a>connect</a> (<a>vertices1</a> xs) (<a>vertices1</a> ys)
--   </pre>
biclique1 :: NonEmpty a -> NonEmpty a -> Graph a

-- | The <i>star</i> formed by a centre vertex connected to a list of
--   leaves. Complexity: <i>O(L)</i> time, memory and size, where <i>L</i>
--   is the length of the given list.
--   
--   <pre>
--   star x []    == <a>vertex</a> x
--   star x [y]   == <a>edge</a> x y
--   star x [y,z] == <a>edges1</a> [(x,y), (x,z)]
--   </pre>
star :: a -> [a] -> Graph a

-- | The <i>stars</i> formed by overlaying a non-empty list of
--   <a>star</a>s. Complexity: <i>O(L)</i> time, memory and size, where
--   <i>L</i> is the total size of the input.
--   
--   <pre>
--   stars1 [(x, [] )]               == <a>vertex</a> x
--   stars1 [(x, [y])]               == <a>edge</a> x y
--   stars1 [(x, ys )]               == <a>star</a> x ys
--   stars1                          == <a>overlays1</a> . <a>fmap</a> (<a>uncurry</a> <a>star</a>)
--   <a>overlay</a> (stars1 xs) (stars1 ys) == stars1 (xs <a>&lt;&gt;</a> ys)
--   </pre>
stars1 :: NonEmpty (a, [a]) -> Graph a

-- | The <i>tree graph</i> constructed from a given <a>Tree</a> data
--   structure. Complexity: <i>O(T)</i> time, memory and size, where
--   <i>T</i> is the size of the given tree (i.e. the number of vertices in
--   the tree).
--   
--   <pre>
--   tree (Node x [])                                         == <a>vertex</a> x
--   tree (Node x [Node y [Node z []]])                       == <a>path1</a> [x,y,z]
--   tree (Node x [Node y [], Node z []])                     == <a>star</a> x [y,z]
--   tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) == <a>edges1</a> [(1,2), (1,3), (3,4), (3,5)]
--   </pre>
tree :: Tree a -> Graph a

-- | Construct a <i>mesh graph</i> from two lists of vertices. Complexity:
--   <i>O(L1 * L2)</i> time, memory and size, where <i>L1</i> and <i>L2</i>
--   are the lengths of the given lists.
--   
--   <pre>
--   mesh1 [x]     [y]        == <a>vertex</a> (x, y)
--   mesh1 xs      ys         == <a>box</a> (<a>path1</a> xs) (<a>path1</a> ys)
--   mesh1 [1,2,3] ['a', 'b'] == <a>edges1</a> [ ((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')) ]
--   </pre>
mesh1 :: NonEmpty a -> NonEmpty b -> Graph (a, b)

-- | Construct a <i>torus graph</i> from two lists of vertices. Complexity:
--   <i>O(L1 * L2)</i> time, memory and size, where <i>L1</i> and <i>L2</i>
--   are the lengths of the given lists.
--   
--   <pre>
--   torus1 [x]   [y]        == <a>edge</a> (x,y) (x,y)
--   torus1 xs    ys         == <a>box</a> (<a>circuit1</a> xs) (<a>circuit1</a> ys)
--   torus1 [1,2] ['a', 'b'] == <a>edges1</a> [ ((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')) ]
--   </pre>
torus1 :: NonEmpty a -> NonEmpty b -> Graph (a, b)

-- | Remove a vertex from a given graph. Returns <tt>Nothing</tt> if the
--   resulting graph is empty. Complexity: <i>O(s)</i> time, memory and
--   size.
--   
--   <pre>
--   removeVertex1 x (<a>vertex</a> x)          == Nothing
--   removeVertex1 1 (<a>vertex</a> 2)          == Just (<a>vertex</a> 2)
--   removeVertex1 x (<a>edge</a> x x)          == Nothing
--   removeVertex1 1 (<a>edge</a> 1 2)          == Just (<a>vertex</a> 2)
--   removeVertex1 x <a>&gt;=&gt;</a> removeVertex1 x == removeVertex1 x
--   </pre>
removeVertex1 :: Eq a => a -> Graph a -> Maybe (Graph a)

-- | Remove an edge from a given graph. Complexity: <i>O(s)</i> time,
--   memory and size.
--   
--   <pre>
--   removeEdge x y (<a>edge</a> x y)       == <a>vertices1</a> [x,y]
--   removeEdge x y . removeEdge x y == removeEdge x y
--   removeEdge 1 1 (1 * 1 * 2 * 2)  == 1 * 2 * 2
--   removeEdge 1 2 (1 * 1 * 2 * 2)  == 1 * 1 + 2 * 2
--   <a>size</a> (removeEdge x y z)         &lt;= 3 * <a>size</a> z
--   </pre>
removeEdge :: Eq a => a -> a -> Graph a -> Graph a

-- | The function <a>replaceVertex</a> <tt>x y</tt> replaces vertex
--   <tt>x</tt> with vertex <tt>y</tt> in a given <a>Graph</a>. If
--   <tt>y</tt> already exists, <tt>x</tt> and <tt>y</tt> will be merged.
--   Complexity: <i>O(s)</i> time, memory and size.
--   
--   <pre>
--   replaceVertex x x            == id
--   replaceVertex x y (<a>vertex</a> x) == <a>vertex</a> y
--   replaceVertex x y            == <a>mergeVertices</a> (== x) y
--   </pre>
replaceVertex :: Eq a => a -> a -> Graph a -> Graph a

-- | Merge vertices satisfying a given predicate into a given vertex.
--   Complexity: <i>O(s)</i> time, memory and size, assuming that the
--   predicate takes constant time.
--   
--   <pre>
--   mergeVertices (<a>const</a> False) x    == id
--   mergeVertices (== x) y           == <a>replaceVertex</a> x y
--   mergeVertices <a>even</a> 1 (0 * 2)     == 1 * 1
--   mergeVertices <a>odd</a>  1 (3 + 4 * 5) == 4 * 1
--   </pre>
mergeVertices :: (a -> Bool) -> a -> Graph a -> Graph a

-- | Split a vertex into a list of vertices with the same connectivity.
--   Complexity: <i>O(s + k * L)</i> time, memory and size, where <i>k</i>
--   is the number of occurrences of the vertex in the expression and
--   <i>L</i> is the length of the given list.
--   
--   <pre>
--   splitVertex1 x [x]                 == id
--   splitVertex1 x [y]                 == <a>replaceVertex</a> x y
--   splitVertex1 1 [0,1] $ 1 * (2 + 3) == (0 + 1) * (2 + 3)
--   </pre>
splitVertex1 :: Eq a => a -> NonEmpty a -> Graph a -> Graph a

-- | Transpose a given graph. Complexity: <i>O(s)</i> time, memory and
--   size.
--   
--   <pre>
--   transpose (<a>vertex</a> x)  == <a>vertex</a> x
--   transpose (<a>edge</a> x y)  == <a>edge</a> y x
--   transpose . transpose == id
--   transpose (<a>box</a> x y)   == <a>box</a> (transpose x) (transpose y)
--   <a>edgeList</a> . transpose  == <a>sort</a> . <a>map</a> <a>swap</a> . <a>edgeList</a>
--   </pre>
transpose :: Graph a -> Graph a

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that do not satisfy a given predicate. Returns
--   <tt>Nothing</tt> if the resulting graph is empty. Complexity:
--   <i>O(s)</i> time, memory and size, assuming that the predicate takes
--   constant time.
--   
--   <pre>
--   induce1 (<a>const</a> True ) x == Just x
--   induce1 (<a>const</a> False) x == Nothing
--   induce1 (/= x)          == <a>removeVertex1</a> x
--   induce1 p <a>&gt;=&gt;</a> induce1 q == induce1 (\x -&gt; p x &amp;&amp; q x)
--   </pre>
induce1 :: (a -> Bool) -> Graph a -> Maybe (Graph a)

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that are <a>Nothing</a>. Returns <a>Nothing</a> if the
--   resulting graph is empty. Complexity: <i>O(s)</i> time, memory and
--   size.
--   
--   <pre>
--   induceJust1 (<a>vertex</a> <a>Nothing</a>)                               == <a>Nothing</a>
--   induceJust1 (<a>edge</a> (<a>Just</a> x) <a>Nothing</a>)                        == <a>Just</a> (<a>vertex</a> x)
--   induceJust1 . <a>fmap</a> <a>Just</a>                                    == <a>Just</a>
--   induceJust1 . <a>fmap</a> (\x -&gt; if p x then <a>Just</a> x else <a>Nothing</a>) == <a>induce1</a> p
--   </pre>
induceJust1 :: Graph (Maybe a) -> Maybe (Graph a)

-- | Simplify 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 <i>O(s)</i> graph
--   comparisons. It is guaranteed that the size of the result does not
--   exceed the size of the given expression.
--   
--   <pre>
--   simplify             ==  id
--   <a>size</a> (simplify x)    &lt;=  <a>size</a> x
--   simplify 1           <a>===</a> 1
--   simplify (1 + 1)     <a>===</a> 1
--   simplify (1 + 2 + 1) <a>===</a> 1 + 2
--   simplify (1 * 1 * 1) <a>===</a> 1 * 1
--   </pre>
simplify :: Ord a => Graph a -> Graph a

-- | <i>Sparsify</i> a graph by adding intermediate <a>Left</a>
--   <tt>Int</tt> vertices between the original vertices (wrapping the
--   latter in <a>Right</a>) such that the resulting graph is
--   <i>sparse</i>, i.e. contains only O(s) edges, but preserves the
--   reachability relation between the original vertices. Sparsification is
--   useful when working with dense graphs, as it can reduce the number of
--   edges from O(n^2) down to O(n) by replacing cliques, bicliques and
--   similar densely connected structures by sparse subgraphs built out of
--   intermediate vertices. Complexity: O(s) time, memory and size.
--   
--   <pre>
--   <a>sort</a> . <a>reachable</a> x       == <a>sort</a> . <a>rights</a> . <a>reachable</a> (<a>Right</a> x) . sparsify
--   <a>vertexCount</a> (sparsify x) &lt;= <a>vertexCount</a> x + <a>size</a> x + 1
--   <a>edgeCount</a>   (sparsify x) &lt;= 3 * <a>size</a> x
--   <a>size</a>        (sparsify x) &lt;= 3 * <a>size</a> x
--   </pre>
sparsify :: Graph a -> Graph (Either Int a)

-- | Sparsify a graph whose vertices are integers in the range
--   <tt>[1..n]</tt>, where <tt>n</tt> is the first argument of the
--   function, producing an array-based graph representation from
--   <a>Data.Graph</a> (introduced by King and Launchbury, hence the name
--   of the function). In the resulting graph, vertices <tt>[1..n]</tt>
--   correspond to the original vertices, and all vertices greater than
--   <tt>n</tt> are introduced by the sparsification procedure.
--   
--   Complexity: <i>O(s)</i> time and memory. Note that thanks to
--   sparsification, the resulting graph has a linear number of edges with
--   respect to the size of the original algebraic representation even
--   though the latter can potentially contain a quadratic <i>O(s^2)</i>
--   number of edges.
--   
--   <pre>
--   <a>sort</a> . <a>reachable</a> k                 == <a>sort</a> . <a>filter</a> (&lt;= n) . <a>flip</a> <a>reachable</a> k . sparsifyKL n
--   <a>length</a> (<a>vertices</a> $ sparsifyKL n x) &lt;= <a>vertexCount</a> x + <a>size</a> x + 1
--   <a>length</a> (<a>edges</a>    $ sparsifyKL n x) &lt;= 3 * <a>size</a> x
--   </pre>
sparsifyKL :: Int -> Graph Int -> Graph

-- | Compute the <i>Cartesian product</i> of graphs. Complexity: <i>O(s1 *
--   s2)</i> time, memory and size, where <i>s1</i> and <i>s2</i> are the
--   sizes of the given graphs.
--   
--   <pre>
--   box (<a>path1</a> [0,1]) (<a>path1</a> ['a','b']) == <a>edges1</a> [ ((0,'a'), (0,'b'))
--                                                 , ((0,'a'), (1,'a'))
--                                                 , ((0,'b'), (1,'b'))
--                                                 , ((1,'a'), (1,'b')) ]
--   </pre>
--   
--   Up to isomorphism between the resulting vertex types, this operation
--   is <i>commutative</i>, <i>associative</i>, <i>distributes</i> over
--   <a>overlay</a>, and has singleton graphs as <i>identities</i>. Below
--   <tt>~~</tt> stands for equality up to an isomorphism, e.g.
--   <tt>(x,</tt> <tt>()) ~~ x</tt>.
--   
--   <pre>
--   box x y               ~~ box y x
--   box x (box y z)       ~~ box (box x y) z
--   box x (<a>overlay</a> y z)   == <a>overlay</a> (box x y) (box x z)
--   box x (<a>vertex</a> ())     ~~ x
--   <a>transpose</a>   (box x y) == box (<a>transpose</a> x) (<a>transpose</a> y)
--   <a>vertexCount</a> (box x y) == <a>vertexCount</a> x * <a>vertexCount</a> y
--   <a>edgeCount</a>   (box x y) &lt;= <a>vertexCount</a> x * <a>edgeCount</a> y + <a>edgeCount</a> x * <a>vertexCount</a> y
--   </pre>
box :: Graph a -> Graph b -> Graph (a, b)
instance GHC.Show.Show a => GHC.Show.Show (Algebra.Graph.NonEmpty.Graph a)
instance GHC.Base.Functor Algebra.Graph.NonEmpty.Graph
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Algebra.Graph.NonEmpty.Graph a)
instance Algebra.Graph.ToGraph.ToGraph (Algebra.Graph.NonEmpty.Graph a)
instance GHC.Num.Num a => GHC.Num.Num (Algebra.Graph.NonEmpty.Graph a)
instance Data.String.IsString a => Data.String.IsString (Algebra.Graph.NonEmpty.Graph a)
instance GHC.Classes.Ord a => GHC.Classes.Eq (Algebra.Graph.NonEmpty.Graph a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.NonEmpty.Graph a)
instance GHC.Base.Semigroup (Algebra.Graph.NonEmpty.Graph a)
instance GHC.Base.Applicative Algebra.Graph.NonEmpty.Graph
instance GHC.Base.Monad Algebra.Graph.NonEmpty.Graph


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module contains a simple example of using edge-labelled graphs
--   defined in the module <a>Algebra.Graph.Labelled</a> for working with
--   finite automata.
module Algebra.Graph.Labelled.Example.Automaton

-- | The alphabet of actions for ordering coffee or tea.
data Alphabet

-- | Order coffee
Coffee :: Alphabet

-- | Order tea
Tea :: Alphabet

-- | Cancel payment or order
Cancel :: Alphabet

-- | Pay for the order
Pay :: Alphabet

-- | The state of the order.
data State

-- | Choosing what to order
Choice :: State

-- | Making the payment
Payment :: State

-- | The order is complete
Complete :: State

-- | An example automaton for ordering coffee or tea.
--   
--   <pre>
--   order = <a>overlays</a> [ <a>Choice</a>  <a>-&lt;</a>[<a>Coffee</a>, <a>Tea</a>]<a>&gt;-</a> <a>Payment</a>
--                    , <a>Choice</a>  <a>-&lt;</a>[<a>Cancel</a>     ]<a>&gt;-</a> <a>Complete</a>
--                    , <a>Payment</a> <a>-&lt;</a>[<a>Cancel</a>     ]<a>&gt;-</a> <a>Choice</a>
--                    , <a>Payment</a> <a>-&lt;</a>[<a>Pay</a>        ]<a>&gt;-</a> <a>Complete</a> ]
--   </pre>
coffeeTeaAutomaton :: Automaton Alphabet State

-- | The map of <a>State</a> reachability.
--   
--   <pre>
--   reachability = Map.<a>fromList</a> $ map (s -&gt; (s, <a>reachable</a> s <tt>order</tt>)) [<a>Choice</a> ..]
--   </pre>
--   
--   Or, when evaluated:
--   
--   <pre>
--   reachability = Map.<a>fromList</a> [ (<a>Choice</a>  , [<a>Choice</a>  , <a>Payment</a>, <a>Complete</a>])
--                               , (<a>Payment</a> , [<a>Payment</a> , <a>Choice</a> , <a>Complete</a>])
--                               , (<a>Complete</a>, [<a>Complete</a>                   ]) ]
--   </pre>
reachability :: Map State [State]
instance GHC.Show.Show Algebra.Graph.Labelled.Example.Automaton.Alphabet
instance GHC.Classes.Ord Algebra.Graph.Labelled.Example.Automaton.Alphabet
instance GHC.Classes.Eq Algebra.Graph.Labelled.Example.Automaton.Alphabet
instance GHC.Enum.Enum Algebra.Graph.Labelled.Example.Automaton.Alphabet
instance GHC.Enum.Bounded Algebra.Graph.Labelled.Example.Automaton.Alphabet
instance GHC.Show.Show Algebra.Graph.Labelled.Example.Automaton.State
instance GHC.Classes.Ord Algebra.Graph.Labelled.Example.Automaton.State
instance GHC.Classes.Eq Algebra.Graph.Labelled.Example.Automaton.State
instance GHC.Enum.Enum Algebra.Graph.Labelled.Example.Automaton.State
instance GHC.Enum.Bounded Algebra.Graph.Labelled.Example.Automaton.State


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module defines basic functionality for exporting graphs in
--   textual and binary formats. <a>Algebra.Graph.Export.Dot</a> provides
--   DOT-specific functions.
module Algebra.Graph.Export

-- | An abstract document data type with <i>O(1)</i> time concatenation
--   (the current implementation uses difference lists). Here <tt>s</tt> is
--   the type of abstract symbols or strings (text or binary). <a>Doc</a>
--   <tt>s</tt> is a <a>Monoid</a>, therefore <a>mempty</a> corresponds to
--   the <i>empty document</i> and two documents can be concatenated with
--   <a>mappend</a> (or operator <a>&lt;&gt;</a>). Documents comprising a
--   single symbol or string can be constructed using the function
--   <a>literal</a>. Alternatively, you can construct documents as string
--   literals, e.g. simply as <tt>"alga"</tt>, by using the
--   <tt>OverloadedStrings</tt> GHC extension. To extract the document
--   contents use the function <a>render</a>.
--   
--   Note that the document comprising a single empty string is considered
--   to be different from the empty document. This design choice is
--   motivated by the desire to support string types <tt>s</tt> that have
--   no <a>Eq</a> instance, such as <a>Data.ByteString.Builder</a>, for
--   which there is no way to check whether a string is empty or not. As a
--   consequence, the <a>Eq</a> and <a>Ord</a> instances are defined as
--   follows:
--   
--   <pre>
--   <a>mempty</a> /= <a>literal</a> ""
--   <a>mempty</a> &lt;  <a>literal</a> ""
--   </pre>
data Doc s

-- | Check if a document is empty. The result is the same as when comparing
--   the given document to <a>mempty</a>, but this function does not
--   require the <a>Eq</a> <tt>s</tt> constraint. Note that the document
--   comprising a single empty string is considered to be different from
--   the empty document.
--   
--   <pre>
--   isEmpty <a>mempty</a>       == True
--   isEmpty (<a>literal</a> "") == False
--   isEmpty x            == (x == <a>mempty</a>)
--   </pre>
isEmpty :: Doc s -> Bool

-- | Construct a document comprising a single symbol or string. If
--   <tt>s</tt> is an instance of class <a>IsString</a>, then documents of
--   type <a>Doc</a> <tt>s</tt> can be constructed directly from string
--   literals (see the second example below).
--   
--   <pre>
--   literal "Hello, " <a>&lt;&gt;</a> literal "World!" == literal "Hello, World!"
--   literal "I am just a string literal"  == "I am just a string literal"
--   <a>render</a> . literal                      == <a>id</a>
--   </pre>
literal :: s -> Doc s

-- | Render the document as a single string. An inverse of the function
--   <a>literal</a>.
--   
--   <pre>
--   render (<a>literal</a> "al" <a>&lt;&gt;</a> <a>literal</a> "ga") :: (<a>IsString</a> s, <a>Monoid</a> s) =&gt; s
--   render (<a>literal</a> "al" <a>&lt;&gt;</a> <a>literal</a> "ga") == "alga"
--   render <a>mempty</a>                         == <a>mempty</a>
--   render . <a>literal</a>                      == <a>id</a>
--   </pre>
render :: Monoid s => Doc s -> s

-- | Concatenate two documents, separated by a single space, unless one of
--   the documents is empty. The operator &lt;+&gt; is associative with
--   identity <a>mempty</a>.
--   
--   <pre>
--   x &lt;+&gt; <a>mempty</a>         == x
--   <a>mempty</a> &lt;+&gt; x         == x
--   x &lt;+&gt; (y &lt;+&gt; z)      == (x &lt;+&gt; y) &lt;+&gt; z
--   "name" &lt;+&gt; "surname" == "name surname"
--   </pre>
(<+>) :: IsString s => Doc s -> Doc s -> Doc s
infixl 7 <+>

-- | Wrap a document in square brackets.
--   
--   <pre>
--   brackets "i"    == "[i]"
--   brackets <a>mempty</a> == "[]"
--   </pre>
brackets :: IsString s => Doc s -> Doc s

-- | Wrap a document into double quotes.
--   
--   <pre>
--   doubleQuotes "/path/with spaces"   == "\"/path/with spaces\""
--   doubleQuotes (doubleQuotes <a>mempty</a>) == "\"\"\"\""
--   </pre>
doubleQuotes :: IsString s => Doc s -> Doc s

-- | Prepend a given number of spaces to a document.
--   
--   <pre>
--   indent 0        == <a>id</a>
--   indent 1 <a>mempty</a> == " "
--   </pre>
indent :: IsString s => Int -> Doc s -> Doc s

-- | Concatenate documents after appending a terminating newline symbol to
--   each.
--   
--   <pre>
--   unlines []                    == <a>mempty</a>
--   unlines [<a>mempty</a>]              == "\n"
--   unlines ["title", "subtitle"] == "title\nsubtitle\n"
--   </pre>
unlines :: IsString s => [Doc s] -> Doc s

-- | Export a graph into a document given two functions that construct
--   documents for individual vertices and edges. The order of export is:
--   vertices, sorted by <a>Ord</a> <tt>a</tt>, and then edges, sorted by
--   <a>Ord</a> <tt>(a, a)</tt>.
--   
--   For example:
--   
--   <pre>
--   vDoc x   = <a>literal</a> (<a>show</a> x) &lt;&gt; "\n"
--   eDoc x y = <a>literal</a> (<a>show</a> x) &lt;&gt; " -&gt; " &lt;&gt; <a>literal</a> (<a>show</a> y) &lt;&gt; "\n"
--   &gt; putStrLn $ <a>render</a> $ export vDoc eDoc (1 + 2 * (3 + 4) :: <a>Graph</a> Int)
--   
--   1
--   2
--   3
--   4
--   2 -&gt; 3
--   2 -&gt; 4
--   </pre>
export :: (Ord a, ToGraph g, ToVertex g ~ a) => (a -> Doc s) -> (a -> a -> Doc s) -> g -> Doc s
instance GHC.Base.Semigroup (Algebra.Graph.Export.Doc s)
instance GHC.Base.Monoid (Algebra.Graph.Export.Doc s)
instance (GHC.Base.Monoid s, GHC.Show.Show s) => GHC.Show.Show (Algebra.Graph.Export.Doc s)
instance (GHC.Base.Monoid s, GHC.Classes.Eq s) => GHC.Classes.Eq (Algebra.Graph.Export.Doc s)
instance (GHC.Base.Monoid s, GHC.Classes.Ord s) => GHC.Classes.Ord (Algebra.Graph.Export.Doc s)
instance Data.String.IsString s => Data.String.IsString (Algebra.Graph.Export.Doc s)


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module defines functions for exporting graphs in the DOT file
--   format.
module Algebra.Graph.Export.Dot

-- | An attribute is just a key-value pair, for example <tt>"shape" :=
--   "box"</tt>. Attributes are used to specify the style of graph elements
--   during export.
data Attribute s
(:=) :: s -> s -> Attribute s

-- | The style of quoting used when exporting attributes;
--   <a>DoubleQuotes</a> is the default.
data Quoting
DoubleQuotes :: Quoting
NoQuotes :: Quoting

-- | The record <a>Style</a> <tt>a</tt> <tt>s</tt> specifies the style to
--   use when exporting a graph in the DOT format. Here <tt>a</tt> is the
--   type of the graph vertices, and <tt>s</tt> is the type of string to
--   represent the resulting DOT document (e.g. String, Text, etc.). The
--   only field that has no obvious default value is <a>vertexName</a>,
--   which holds a function of type <tt>a -&gt; s</tt> to compute vertex
--   names. See the function <a>export</a> for an example.
data Style a s
Style :: s -> [s] -> [Attribute s] -> [Attribute s] -> [Attribute s] -> (a -> s) -> (a -> [Attribute s]) -> (a -> a -> [Attribute s]) -> Quoting -> Style a s

-- | Name of the graph.
[graphName] :: Style a s -> s

-- | Preamble (a list of lines) is added at the beginning of the DOT file
--   body.
[preamble] :: Style a s -> [s]

-- | Graph style, e.g. <tt>["bgcolor" := "azure"]</tt>.
[graphAttributes] :: Style a s -> [Attribute s]

-- | Default vertex style, e.g. <tt>["shape" := "diamond"]</tt>.
[defaultVertexAttributes] :: Style a s -> [Attribute s]

-- | Default edge style, e.g. <tt>["style" := "dashed"]</tt>.
[defaultEdgeAttributes] :: Style a s -> [Attribute s]

-- | Compute a vertex name.
[vertexName] :: Style a s -> a -> s

-- | Attributes of a specific vertex.
[vertexAttributes] :: Style a s -> a -> [Attribute s]

-- | Attributes of a specific edge.
[edgeAttributes] :: Style a s -> a -> a -> [Attribute s]

-- | The quoting style used for attributes.
[attributeQuoting] :: Style a s -> Quoting

-- | Default style for exporting graphs. The <a>vertexName</a> field is
--   provided as the only argument; the other fields are set to trivial
--   defaults.
defaultStyle :: Monoid s => (a -> s) -> Style a s

-- | Default style for exporting graphs with <a>Show</a>-able vertices. The
--   <a>vertexName</a> field is computed using <a>show</a>; the other
--   fields are set to trivial defaults.
--   
--   <pre>
--   defaultStyleViaShow = <a>defaultStyle</a> (<a>fromString</a> . <a>show</a>)
--   </pre>
defaultStyleViaShow :: (Show a, IsString s, Monoid s) => Style a s

-- | Export a graph with a given style.
--   
--   For example:
--   
--   <pre>
--   style :: <a>Style</a> Int String
--   style = <a>Style</a>
--       { <a>graphName</a>               = "Example"
--       , <a>preamble</a>                = ["  // This is an example", ""]
--       , <a>graphAttributes</a>         = ["label" := "Example", "labelloc" := "top"]
--       , <a>defaultVertexAttributes</a> = ["shape" := "circle"]
--       , <a>defaultEdgeAttributes</a>   = <a>mempty</a>
--       , <a>vertexName</a>              = \x   -&gt; "v" ++ <a>show</a> x
--       , <a>vertexAttributes</a>        = \x   -&gt; ["color" := "blue"   | <a>odd</a> x      ]
--       , <a>edgeAttributes</a>          = \x y -&gt; ["style" := "dashed" | <a>odd</a> (x * y)]
--       , <a>attributeQuoting</a>        = <a>DoubleQuotes</a> }
--   
--   &gt; putStrLn $ export style (1 * 2 + 3 * 4 * 5 :: <tt>Graph</tt> Int)
--   
--   digraph Example
--   {
--     // This is an example
--   
--     graph [label="Example" labelloc="top"]
--     node [shape="circle"]
--     "v1" [color="blue"]
--     "v2"
--     "v3" [color="blue"]
--     "v4"
--     "v5" [color="blue"]
--     "v1" -&gt; "v2"
--     "v3" -&gt; "v4"
--     "v3" -&gt; "v5" [style="dashed"]
--     "v4" -&gt; "v5"
--   }
--   </pre>
export :: (IsString s, Monoid s, Ord a, ToGraph g, ToVertex g ~ a) => Style a s -> g -> s

-- | Export a graph whose vertices are represented simply by their names.
--   
--   For example:
--   
--   <pre>
--   &gt; Text.putStrLn $ exportAsIs (<a>circuit</a> ["a", "b", "c"] :: <a>AdjacencyMap</a> Text)
--   
--   digraph
--   {
--     "a"
--     "b"
--     "c"
--     "a" -&gt; "b"
--     "b" -&gt; "c"
--     "c" -&gt; "a"
--   }
--   </pre>
exportAsIs :: (IsString s, Monoid s, Ord (ToVertex g), ToGraph g, ToVertex g ~ s) => g -> s

-- | Export a graph using the <a>defaultStyleViaShow</a>.
--   
--   For example:
--   
--   <pre>
--   &gt; putStrLn $ exportViaShow (1 + 2 * (3 + 4) :: <a>Graph</a> Int)
--   
--   digraph
--   {
--     "1"
--     "2"
--     "3"
--     "4"
--     "2" -&gt; "3"
--     "2" -&gt; "4"
--   }
--   </pre>
exportViaShow :: (IsString s, Monoid s, Ord (ToVertex g), Show (ToVertex g), ToGraph g) => g -> s


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module defines an undirected version of algebraic graphs.
--   Undirected graphs satisfy all laws of the <a>Undirected</a> type
--   class, including the commutativity of <a>connect</a>.
--   
--   To avoid name clashes with <a>Algebra.Graph</a>, this module can be
--   imported qualified:
--   
--   <pre>
--   import qualified Algebra.Graph.Undirected as Undirected
--   </pre>
module Algebra.Graph.Undirected

-- | The <a>Graph</a> data type provides the four algebraic graph
--   construction primitives <a>empty</a>, <a>vertex</a>, <a>overlay</a>
--   and <a>connect</a>, as well as various derived functions. The only
--   difference compared to the <a>Graph</a> data type defined in
--   <a>Algebra.Graph</a> is that the <a>connect</a> operation is
--   <i>commutative</i>. We define a <a>Num</a> instance as a convenient
--   notation for working with undirected graphs:
--   
--   <pre>
--   0           == <a>vertex</a> 0
--   1 + 2       == <a>overlay</a> (<a>vertex</a> 1) (<a>vertex</a> 2)
--   1 * 2       == <a>connect</a> (<a>vertex</a> 1) (<a>vertex</a> 2)
--   1 + 2 * 3   == <a>overlay</a> (<a>vertex</a> 1) (<a>connect</a> (<a>vertex</a> 2) (<a>vertex</a> 3))
--   1 * (2 + 3) == <a>connect</a> (<a>vertex</a> 1) (<a>overlay</a> (<a>vertex</a> 2) (<a>vertex</a> 3))
--   </pre>
--   
--   <b>Note:</b> the <a>Num</a> instance does not satisfy several
--   "customary laws" of <a>Num</a>, which dictate that <a>fromInteger</a>
--   <tt>0</tt> and <a>fromInteger</a> <tt>1</tt> should act as additive
--   and multiplicative identities, and <a>negate</a> as additive inverse.
--   Nevertheless, overloading <a>fromInteger</a>, <a>+</a> and <a>*</a> is
--   very convenient when working with algebraic graphs; we hope that in
--   future Haskell's Prelude will provide a more fine-grained class
--   hierarchy for algebraic structures, which we would be able to utilise
--   without violating any laws.
--   
--   The <a>Eq</a> instance is currently implemented using the
--   <a>Relation</a> as the <i>canonical graph representation</i> and
--   satisfies all axioms of algebraic graphs:
--   
--   <ul>
--   <li><a>overlay</a> is commutative and associative:<pre> x + y == y + x
--   x + (y + z) == (x + y) + z</pre></li>
--   <li><a>connect</a> is associative, commutative and has <a>empty</a> as
--   the identity:<pre> x * empty == x empty * x == x x * y == y * x x * (y
--   * z) == (x * y) * z</pre></li>
--   <li><a>connect</a> distributes over <a>overlay</a>:<pre>x * (y + z) ==
--   x * y + x * z (x + y) * z == x * z + y * z</pre></li>
--   <li><a>connect</a> can be decomposed:<pre>x * y * z == x * y + x * z +
--   y * z</pre></li>
--   </ul>
--   
--   The following useful theorems can be proved from the above set of
--   axioms.
--   
--   <ul>
--   <li><a>overlay</a> has <a>empty</a> as the identity and is
--   idempotent:<pre> x + empty == x empty + x == x x + x == x</pre></li>
--   <li>Absorption and saturation of <a>connect</a>:<pre>x * y + x + y ==
--   x * y x * x * x == x * x</pre></li>
--   </ul>
--   
--   When specifying the time and memory complexity of graph algorithms,
--   <i>n</i> will denote the number of vertices in the graph, <i>m</i>
--   will denote the number of edges in the graph, and <i>s</i> will denote
--   the <i>size</i> of the corresponding <a>Graph</a> expression. For
--   example, if <tt>g</tt> is a <a>Graph</a> then <i>n</i>, <i>m</i> and
--   <i>s</i> can be computed as follows:
--   
--   <pre>
--   n == <a>vertexCount</a> g
--   m == <a>edgeCount</a> g
--   s == <a>size</a> g
--   </pre>
--   
--   Note that <a>size</a> counts all leaves of the expression:
--   
--   <pre>
--   <a>vertexCount</a> <a>empty</a>           == 0
--   <a>size</a>        <a>empty</a>           == 1
--   <a>vertexCount</a> (<a>vertex</a> x)      == 1
--   <a>size</a>        (<a>vertex</a> x)      == 1
--   <a>vertexCount</a> (<a>empty</a> + <a>empty</a>) == 0
--   <a>size</a>        (<a>empty</a> + <a>empty</a>) == 2
--   </pre>
--   
--   Converting an undirected <a>Graph</a> to the corresponding
--   <a>Relation</a> takes <i>O(s + m * log(m))</i> time and <i>O(s +
--   m)</i> 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.
--   
--   The total order on graphs is defined using <i>size-lexicographic</i>
--   comparison:
--   
--   <ul>
--   <li>Compare the number of vertices. In case of a tie, continue.</li>
--   <li>Compare the sets of vertices. In case of a tie, continue.</li>
--   <li>Compare the number of edges. In case of a tie, continue.</li>
--   <li>Compare the sets of edges.</li>
--   </ul>
--   
--   Here are a few examples:
--   
--   <pre>
--   <a>vertex</a> 1 &lt; <a>vertex</a> 2
--   <a>vertex</a> 3 &lt; <a>edge</a> 1 2
--   <a>vertex</a> 1 &lt; <a>edge</a> 1 1
--   <a>edge</a> 1 1 &lt; <a>edge</a> 1 2
--   <a>edge</a> 1 2 &lt; <a>edge</a> 1 1 + <a>edge</a> 2 2
--   <a>edge</a> 1 2 &lt; <a>edge</a> 1 3
--   <a>edge</a> 1 2 == <a>edge</a> 2 1
--   </pre>
--   
--   Note that the resulting order refines the <a>isSubgraphOf</a> relation
--   and is compatible with <a>overlay</a> and <a>connect</a> operations:
--   
--   <pre>
--   <a>isSubgraphOf</a> x y ==&gt; x &lt;= y
--   </pre>
--   
--   <pre>
--   <a>empty</a> &lt;= x
--   x     &lt;= x + y
--   x + y &lt;= x * y
--   </pre>
data Graph a

-- | Extract the underlying <a>Algebra.Graph</a>. Complexity: <i>O(n +
--   m)</i> time.
--   
--   <pre>
--   fromUndirected (<a>edge</a> 1 2)     == <a>edges</a> [(1,2),(2,1)]
--   <a>toUndirected</a> . <a>fromUndirected</a> == id
--   <a>vertexCount</a> . fromUndirected  == <a>vertexCount</a>
--   <a>edgeCount</a> . fromUndirected    &lt;= (*2) . <a>edgeCount</a>
--   </pre>
fromUndirected :: Ord a => Graph a -> Graph a

-- | Construct an undirected graph from a given <a>Algebra.Graph</a>.
--   Complexity: <i>O(1)</i> time.
--   
--   <pre>
--   toUndirected (<a>edge</a> 1 2)         == <a>edge</a> 1 2
--   toUndirected . <a>fromUndirected</a>   == id
--   <a>vertexCount</a> . toUndirected      == <a>vertexCount</a>
--   (*2) . <a>edgeCount</a> . toUndirected &gt;= <a>edgeCount</a>
--   </pre>
toUndirected :: Graph a -> Graph a

-- | Construct the <i>empty graph</i>.
--   
--   <pre>
--   <a>isEmpty</a>     empty == True
--   <a>hasVertex</a> x empty == False
--   <a>vertexCount</a> empty == 0
--   <a>edgeCount</a>   empty == 0
--   <a>size</a>        empty == 1
--   </pre>
empty :: Graph a

-- | Construct the graph comprising <i>a single isolated vertex</i>.
--   
--   <pre>
--   <a>isEmpty</a>     (vertex x) == False
--   <a>hasVertex</a> x (vertex y) == (x == y)
--   <a>vertexCount</a> (vertex x) == 1
--   <a>edgeCount</a>   (vertex x) == 0
--   <a>size</a>        (vertex x) == 1
--   </pre>
vertex :: a -> Graph a

-- | Construct the graph comprising <i>a single edge</i>.
--   
--   <pre>
--   edge x y               == <a>connect</a> (<a>vertex</a> x) (<a>vertex</a> y)
--   edge x y               == <a>edge</a> y x
--   edge x y               == <a>edges</a> [(x,y), (y,x)]
--   <a>hasEdge</a> x y (edge x y) == True
--   <a>edgeCount</a>   (edge x y) == 1
--   <a>vertexCount</a> (edge 1 1) == 1
--   <a>vertexCount</a> (edge 1 2) == 2
--   </pre>
edge :: a -> a -> Graph a

-- | <i>Overlay</i> two graphs. This is a commutative, associative and
--   idempotent operation with the identity <a>empty</a>. Complexity:
--   <i>O(1)</i> time and memory, <i>O(s1 + s2)</i> size.
--   
--   <pre>
--   <a>isEmpty</a>     (overlay x y) == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (overlay x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (overlay x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (overlay x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (overlay x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (overlay x y) &lt;= <a>edgeCount</a> x   + <a>edgeCount</a> y
--   <a>size</a>        (overlay x y) == <a>size</a> x        + <a>size</a> y
--   <a>vertexCount</a> (overlay 1 2) == 2
--   <a>edgeCount</a>   (overlay 1 2) == 0
--   </pre>
overlay :: Graph a -> Graph a -> Graph a

-- | <i>Connect</i> two graphs. This is a commutative and associative
--   operation with the identity <a>empty</a>, which distributes over
--   <a>overlay</a> and obeys the decomposition axiom. Complexity:
--   <i>O(1)</i> time and memory, <i>O(s1 + s2)</i> size. Note that the
--   number of edges in the resulting graph is quadratic with respect to
--   the number of vertices of the arguments: <i>m = O(m1 + m2 + n1 *
--   n2)</i>.
--   
--   <pre>
--   <a>connect</a> x y               == <a>connect</a> y x
--   <a>isEmpty</a>     (connect x y) == <a>isEmpty</a>   x   &amp;&amp; <a>isEmpty</a>   y
--   <a>hasVertex</a> z (connect x y) == <a>hasVertex</a> z x || <a>hasVertex</a> z y
--   <a>vertexCount</a> (connect x y) &gt;= <a>vertexCount</a> x
--   <a>vertexCount</a> (connect x y) &lt;= <a>vertexCount</a> x + <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect x y) &gt;= <a>edgeCount</a> x
--   <a>edgeCount</a>   (connect x y) &gt;= <a>edgeCount</a> y
--   <a>edgeCount</a>   (connect x y) &gt;= <a>vertexCount</a> x * <a>vertexCount</a> y
--   <a>edgeCount</a>   (connect x y) &gt;= <a>vertexCount</a> x * <a>vertexCount</a> y <a>div</a> 2
--   <a>size</a>        (connect x y) == <a>size</a> x        + <a>size</a> y
--   <a>vertexCount</a> (connect 1 2) == 2
--   <a>edgeCount</a>   (connect 1 2) == 1
--   </pre>
connect :: Graph a -> Graph a -> Graph a

-- | Construct the graph comprising a given list of isolated vertices.
--   Complexity: <i>O(L)</i> time, memory and size, where <i>L</i> is the
--   length of the given list.
--   
--   <pre>
--   vertices []            == <a>empty</a>
--   vertices [x]           == <a>vertex</a> x
--   vertices               == <a>overlays</a> . map <a>vertex</a>
--   <a>hasVertex</a> x . vertices == <a>elem</a> x
--   <a>vertexCount</a> . vertices == <a>length</a> . <a>nub</a>
--   <a>vertexSet</a>   . vertices == Set . <a>fromList</a>
--   </pre>
vertices :: [a] -> Graph a

-- | Construct the graph from a list of edges. Complexity: <i>O(L)</i>
--   time, memory and size, where <i>L</i> is the length of the given list.
--   
--   <pre>
--   edges []             == <a>empty</a>
--   edges [(x,y)]        == <a>edge</a> x y
--   edges [(x,y), (y,x)] == <a>edge</a> x y
--   </pre>
edges :: [(a, a)] -> Graph a

-- | Overlay a given list of graphs. Complexity: <i>O(L)</i> time and
--   memory, and <i>O(S)</i> size, where <i>L</i> is the length of the
--   given list, and <i>S</i> is the sum of sizes of the graphs in the
--   list.
--   
--   <pre>
--   overlays []        == <a>empty</a>
--   overlays [x]       == x
--   overlays [x,y]     == <a>overlay</a> x y
--   overlays           == <a>foldr</a> <a>overlay</a> <a>empty</a>
--   <a>isEmpty</a> . overlays == <a>all</a> <a>isEmpty</a>
--   </pre>
overlays :: [Graph a] -> Graph a

-- | Connect a given list of graphs. Complexity: <i>O(L)</i> time and
--   memory, and <i>O(S)</i> size, where <i>L</i> is the length of the
--   given list, and <i>S</i> is the sum of sizes of the graphs in the
--   list.
--   
--   <pre>
--   connects []        == <a>empty</a>
--   connects [x]       == x
--   connects [x,y]     == <a>connect</a> x y
--   connects           == <a>foldr</a> <a>connect</a> <a>empty</a>
--   <a>isEmpty</a> . connects == <a>all</a> <a>isEmpty</a>
--   connects           == connects . <a>reverse</a>
--   </pre>
connects :: [Graph a] -> Graph a

-- | Generalised <a>Graph</a> folding: recursively collapse a <a>Graph</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: <i>O(s)</i> applications of the given functions.
--   As an example, the complexity of <a>size</a> is <i>O(s)</i>, since
--   <a>const</a> and <a>+</a> have constant costs.
--   
--   <pre>
--   foldg <a>empty</a> <a>vertex</a>        <a>overlay</a> <a>connect</a>        == id
--   foldg <a>empty</a> <a>vertex</a>        <a>overlay</a> (<a>flip</a> <a>connect</a>) == id
--   foldg 1     (<a>const</a> 1)     (+)     (+)            == <a>size</a>
--   foldg True  (<a>const</a> False) (&amp;&amp;)    (&amp;&amp;)           == <a>isEmpty</a>
--   foldg False (== x)        (||)    (||)           == <a>hasVertex</a> x
--   </pre>
foldg :: b -> (a -> b) -> (b -> b -> b) -> (b -> b -> b) -> Graph a -> b

-- | The <a>isSubgraphOf</a> function takes two graphs and returns
--   <a>True</a> if the first graph is a <i>subgraph</i> of the second.
--   Complexity: <i>O(s + m * log(m))</i> time. Note that the number of
--   edges <i>m</i> of a graph can be quadratic with respect to the
--   expression size <i>s</i>.
--   
--   <pre>
--   isSubgraphOf <a>empty</a>         x             ==  True
--   isSubgraphOf (<a>vertex</a> x)    <a>empty</a>         ==  False
--   isSubgraphOf x             (<a>overlay</a> x y) ==  True
--   isSubgraphOf (<a>overlay</a> x y) (<a>connect</a> x y) ==  True
--   isSubgraphOf (<a>path</a> xs)     (<a>circuit</a> xs)  ==  True
--   isSubgraphOf (<a>edge</a> x y)    (<a>edge</a> y x)    ==  True
--   isSubgraphOf x y                         ==&gt; x &lt;= y
--   </pre>
isSubgraphOf :: Ord a => Graph a -> Graph a -> Bool

-- | Convert an undirected graph to a symmetric <a>Relation</a>.
toRelation :: Ord a => Graph a -> Relation a

-- | Check if a graph is empty. Complexity: <i>O(s)</i> time.
--   
--   <pre>
--   isEmpty <a>empty</a>                       == True
--   isEmpty (<a>overlay</a> <a>empty</a> <a>empty</a>)       == True
--   isEmpty (<a>vertex</a> x)                  == False
--   isEmpty (<a>removeVertex</a> x $ <a>vertex</a> x) == True
--   isEmpty (<a>removeEdge</a> x y $ <a>edge</a> x y) == False
--   </pre>
isEmpty :: Graph a -> Bool

-- | The <i>size</i> of a graph, i.e. the number of leaves of the
--   expression including <a>empty</a> leaves. Complexity: <i>O(s)</i>
--   time.
--   
--   <pre>
--   size <a>empty</a>         == 1
--   size (<a>vertex</a> x)    == 1
--   size (<a>overlay</a> x y) == size x + size y
--   size (<a>connect</a> x y) == size x + size y
--   size x             &gt;= 1
--   size x             &gt;= <a>vertexCount</a> x
--   </pre>
size :: Graph a -> Int

-- | Check if a graph contains a given vertex. Complexity: <i>O(s)</i>
--   time.
--   
--   <pre>
--   hasVertex x <a>empty</a>            == False
--   hasVertex x (<a>vertex</a> y)       == (x == y)
--   hasVertex x . <a>removeVertex</a> x == <a>const</a> False
--   </pre>
hasVertex :: Eq a => a -> Graph a -> Bool

-- | Check if a graph contains a given edge. Complexity: <i>O(s)</i> time.
--   
--   <pre>
--   hasEdge x y <a>empty</a>            == False
--   hasEdge x y (<a>vertex</a> z)       == False
--   hasEdge x y (<a>edge</a> x y)       == True
--   hasEdge x y (<a>edge</a> y x)       == True
--   hasEdge x y . <a>removeEdge</a> x y == <a>const</a> False
--   hasEdge x y                  == <a>elem</a> (min x y, max x y) . <a>edgeList</a>
--   </pre>
hasEdge :: Eq a => a -> a -> Graph a -> Bool

-- | The number of vertices in a graph. Complexity: <i>O(s * log(n))</i>
--   time.
--   
--   <pre>
--   vertexCount <a>empty</a>             ==  0
--   vertexCount (<a>vertex</a> x)        ==  1
--   vertexCount                   ==  <a>length</a> . <a>vertexList</a>
--   vertexCount x &lt; vertexCount y ==&gt; x &lt; y
--   </pre>
vertexCount :: Ord a => Graph a -> Int

-- | The number of edges in a graph. Complexity: <i>O(s + m * log(m))</i>
--   time. Note that the number of edges <i>m</i> of a graph can be
--   quadratic with respect to the expression size <i>s</i>.
--   
--   <pre>
--   edgeCount <a>empty</a>      == 0
--   edgeCount (<a>vertex</a> x) == 0
--   edgeCount (<a>edge</a> x y) == 1
--   edgeCount            == <a>length</a> . <a>edgeList</a>
--   </pre>
edgeCount :: Ord a => Graph a -> Int

-- | The sorted list of vertices of a given graph. Complexity: <i>O(s *
--   log(n))</i> time and <i>O(n)</i> memory.
--   
--   <pre>
--   vertexList <a>empty</a>      == []
--   vertexList (<a>vertex</a> x) == [x]
--   vertexList . <a>vertices</a> == <a>nub</a> . <a>sort</a>
--   </pre>
vertexList :: Ord a => Graph a -> [a]

-- | The sorted list of edges of a graph. Complexity: <i>O(s + m *
--   log(m))</i> time and <i>O(m)</i> memory. Note that the number of edges
--   <i>m</i> of a graph can be quadratic with respect to the expression
--   size <i>s</i>.
--   
--   <pre>
--   edgeList <a>empty</a>          == []
--   edgeList (<a>vertex</a> x)     == []
--   edgeList (<a>edge</a> x y)     == [(min x y, max y x)]
--   edgeList (<a>star</a> 2 [3,1]) == [(1,2), (2,3)]
--   </pre>
edgeList :: Ord a => Graph a -> [(a, a)]

-- | The set of vertices of a given graph. Complexity: <i>O(s * log(n))</i>
--   time and <i>O(n)</i> memory.
--   
--   <pre>
--   vertexSet <a>empty</a>      == Set.<a>empty</a>
--   vertexSet . <a>vertex</a>   == Set.<a>singleton</a>
--   vertexSet . <a>vertices</a> == Set.<a>fromList</a>
--   </pre>
vertexSet :: Ord a => Graph a -> Set a

-- | The set of edges of a given graph. Complexity: <i>O(s * log(m))</i>
--   time and <i>O(m)</i> memory.
--   
--   <pre>
--   edgeSet <a>empty</a>      == Set.<a>empty</a>
--   edgeSet (<a>vertex</a> x) == Set.<a>empty</a>
--   edgeSet (<a>edge</a> x y) == Set.<a>singleton</a> (<a>min</a> x y, <a>max</a> x y)
--   </pre>
edgeSet :: Ord a => Graph a -> Set (a, a)

-- | The sorted <i>adjacency list</i> of a graph. Complexity: <i>O(n +
--   m)</i> time and memory.
--   
--   <pre>
--   adjacencyList <a>empty</a>          == []
--   adjacencyList (<a>vertex</a> x)     == [(x, [])]
--   adjacencyList (<a>edge</a> 1 2)     == [(1, [2]), (2, [1])]
--   adjacencyList (<a>star</a> 2 [3,1]) == [(1, [2]), (2, [1,3]), (3, [2])]
--   <a>stars</a> . adjacencyList        == id
--   </pre>
adjacencyList :: Ord a => Graph a -> [(a, [a])]

-- | The set of vertices <i>adjacent</i> to a given vertex.
--   
--   <pre>
--   neighbours x <a>empty</a>      == Set.<a>empty</a>
--   neighbours x (<a>vertex</a> x) == Set.<a>empty</a>
--   neighbours x (<a>edge</a> x y) == Set.<a>fromList</a> [y]
--   neighbours y (<a>edge</a> x y) == Set.<a>fromList</a> [x]
--   </pre>
neighbours :: Ord a => a -> Graph a -> Set a

-- | The <i>path</i> on a list of vertices. Complexity: <i>O(L)</i> time,
--   memory and size, where <i>L</i> is the length of the given list.
--   
--   <pre>
--   path []        == <a>empty</a>
--   path [x]       == <a>vertex</a> x
--   path [x,y]     == <a>edge</a> x y
--   path . <a>reverse</a> == path
--   </pre>
path :: [a] -> Graph a

-- | The <i>circuit</i> on a list of vertices. Complexity: <i>O(L)</i>
--   time, memory and size, where <i>L</i> is the length of the given list.
--   
--   <pre>
--   circuit []        == <a>empty</a>
--   circuit [x]       == <a>edge</a> x x
--   circuit [x,y]     == <a>edge</a> (x,y)
--   circuit . <a>reverse</a> == circuit
--   </pre>
circuit :: [a] -> Graph a

-- | The <i>clique</i> on a list of vertices. Complexity: <i>O(L)</i> time,
--   memory and size, where <i>L</i> is the length of the given list.
--   
--   <pre>
--   clique []         == <a>empty</a>
--   clique [x]        == <a>vertex</a> x
--   clique [x,y]      == <a>edge</a> x y
--   clique [x,y,z]    == <a>edges</a> [(x,y), (x,z), (y,z)]
--   clique (xs ++ ys) == <a>connect</a> (clique xs) (clique ys)
--   clique . <a>reverse</a>  == clique
--   </pre>
clique :: [a] -> Graph a

-- | The <i>biclique</i> on two lists of vertices. Complexity: <i>O(L1 +
--   L2)</i> time, memory and size, where <i>L1</i> and <i>L2</i> are the
--   lengths of the given lists.
--   
--   <pre>
--   biclique []      []      == <a>empty</a>
--   biclique [x]     []      == <a>vertex</a> x
--   biclique []      [y]     == <a>vertex</a> y
--   biclique [x1,x2] [y1,y2] == <a>edges</a> [(x1,y1), (x1,y2), (x2,x2), (x2,y2)]
--   biclique xs      ys      == <a>connect</a> (<a>vertices</a> xs) (<a>vertices</a> ys)
--   </pre>
biclique :: [a] -> [a] -> Graph a

-- | The <i>star</i> formed by a centre vertex connected to a list of
--   leaves. Complexity: <i>O(L)</i> time, memory and size, where <i>L</i>
--   is the length of the given list.
--   
--   <pre>
--   star x []    == <a>vertex</a> x
--   star x [y]   == <a>edge</a> x y
--   star x [y,z] == <a>edges</a> [(x,y), (x,z)]
--   star x ys    == <a>connect</a> (<a>vertex</a> x) (<a>vertices</a> ys)
--   </pre>
star :: a -> [a] -> Graph a

-- | The <i>stars</i> formed by overlaying a list of <a>star</a>s. An
--   inverse of <a>adjacencyList</a>. Complexity: <i>O(L)</i> time, memory
--   and size, where <i>L</i> is the total size of the input.
--   
--   <pre>
--   stars []                      == <a>empty</a>
--   stars [(x, [])]               == <a>vertex</a> x
--   stars [(x, [y])]              == <a>edge</a> x y
--   stars [(x, ys)]               == <a>star</a> x ys
--   stars                         == <a>overlays</a> . <a>map</a> (<a>uncurry</a> <a>star</a>)
--   stars . <a>adjacencyList</a>         == id
--   <a>overlay</a> (stars xs) (stars ys) == stars (xs ++ ys)
--   </pre>
stars :: [(a, [a])] -> Graph a

-- | The <i>tree graph</i> constructed from a given <a>Tree</a> data
--   structure. Complexity: <i>O(T)</i> time, memory and size, where
--   <i>T</i> is the size of the given tree (i.e. the number of vertices in
--   the tree).
--   
--   <pre>
--   tree (Node x [])                                         == <a>vertex</a> x
--   tree (Node x [Node y [Node z []]])                       == <a>path</a> [x,y,z]
--   tree (Node x [Node y [], Node z []])                     == <a>star</a> x [y,z]
--   tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) == <a>edges</a> [(1,2), (1,3), (3,4), (3,5)]
--   </pre>
tree :: Tree a -> Graph a

-- | The <i>forest graph</i> constructed from a given <a>Forest</a> data
--   structure. Complexity: <i>O(F)</i> time, memory and size, where
--   <i>F</i> is the size of the given forest (i.e. the number of vertices
--   in the forest).
--   
--   <pre>
--   forest []                                                  == <a>empty</a>
--   forest [x]                                                 == <a>tree</a> x
--   forest [Node 1 [Node 2 [], Node 3 []], Node 4 [Node 5 []]] == <a>edges</a> [(1,2), (1,3), (4,5)]
--   forest                                                     == <a>overlays</a> . <a>map</a> <a>tree</a>
--   </pre>
forest :: Forest a -> Graph a

-- | Remove a vertex from a given graph. Complexity: <i>O(s)</i> time,
--   memory and size.
--   
--   <pre>
--   removeVertex x (<a>vertex</a> x)       == <a>empty</a>
--   removeVertex 1 (<a>vertex</a> 2)       == <a>vertex</a> 2
--   removeVertex x (<a>edge</a> x x)       == <a>empty</a>
--   removeVertex 1 (<a>edge</a> 1 2)       == <a>vertex</a> 2
--   removeVertex x . removeVertex x == removeVertex x
--   </pre>
removeVertex :: Eq a => a -> Graph a -> Graph a

-- | Remove an edge from a given graph. Complexity: <i>O(s)</i> time,
--   memory and size.
--   
--   <pre>
--   removeEdge x y (<a>edge</a> x y)       == <a>vertices</a> [x,y]
--   removeEdge x y . removeEdge x y == removeEdge x y
--   removeEdge x y                  == removeEdge y x
--   removeEdge x y . <a>removeVertex</a> x == <a>removeVertex</a> x
--   removeEdge 1 1 (1 * 1 * 2 * 2)  == 1 * 2 * 2
--   removeEdge 1 2 (1 * 1 * 2 * 2)  == 1 * 1 + 2 * 2
--   </pre>
removeEdge :: Eq a => a -> a -> Graph a -> Graph a

-- | The function <tt><a>replaceVertex</a> x y</tt> replaces vertex
--   <tt>x</tt> with vertex <tt>y</tt> in a given <a>Graph</a>. If
--   <tt>y</tt> already exists, <tt>x</tt> and <tt>y</tt> will be merged.
--   Complexity: <i>O(s)</i> time, memory and size.
--   
--   <pre>
--   replaceVertex x x            == id
--   replaceVertex x y (<a>vertex</a> x) == <a>vertex</a> y
--   replaceVertex x y            == <a>mergeVertices</a> (== x) y
--   </pre>
replaceVertex :: Eq a => a -> a -> Graph a -> Graph a

-- | Merge vertices satisfying a given predicate into a given vertex.
--   Complexity: <i>O(s)</i> time, memory and size, assuming that the
--   predicate takes constant time.
--   
--   <pre>
--   mergeVertices (<a>const</a> False) x    == id
--   mergeVertices (== x) y           == <a>replaceVertex</a> x y
--   mergeVertices <a>even</a> 1 (0 * 2)     == 1 * 1
--   mergeVertices <a>odd</a>  1 (3 + 4 * 5) == 4 * 1
--   </pre>
mergeVertices :: (a -> Bool) -> a -> Graph a -> Graph a

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that do not satisfy a given predicate. Complexity:
--   <i>O(s)</i> time, memory and size, assuming that the predicate takes
--   constant time.
--   
--   <pre>
--   induce (<a>const</a> True ) x      == x
--   induce (<a>const</a> False) x      == <a>empty</a>
--   induce (/= x)               == <a>removeVertex</a> x
--   induce p . induce q         == induce (\x -&gt; p x &amp;&amp; q x)
--   <a>isSubgraphOf</a> (induce p x) x == True
--   </pre>
induce :: (a -> Bool) -> Graph a -> Graph a

-- | Construct the <i>induced subgraph</i> of a given graph by removing the
--   vertices that are <a>Nothing</a>. Complexity: <i>O(s)</i> time, memory
--   and size.
--   
--   <pre>
--   induceJust (<a>vertex</a> <a>Nothing</a>)                               == <a>empty</a>
--   induceJust (<a>edge</a> (<a>Just</a> x) <a>Nothing</a>)                        == <a>vertex</a> x
--   induceJust . <a>fmap</a> <a>Just</a>                                    == <a>id</a>
--   induceJust . <a>fmap</a> (\x -&gt; if p x then <a>Just</a> x else <a>Nothing</a>) == <a>induce</a> p
--   </pre>
induceJust :: Graph (Maybe a) -> Graph a

-- | The edge complement of a graph. Note that, as can be seen from the
--   examples below, this operation ignores self-loops. Complexity:
--   <i>O(n^2 * log n)</i> time, <i>O(n^2)</i> memory.
--   
--   <pre>
--   complement <a>empty</a>           == <a>empty</a>
--   complement (<a>vertex</a> x)      == (<a>vertex</a> x)
--   complement (<a>edge</a> 1 2)      == (<a>vertices</a> [1, 2])
--   complement (<a>edge</a> 0 0)      == (<a>edge</a> 0 0)
--   complement (<a>star</a> 1 [2, 3]) == (<a>overlay</a> (<a>vertex</a> 1) (<a>edge</a> 2 3))
--   complement . complement    == id
--   </pre>
complement :: Ord a => Graph a -> Graph a
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Algebra.Graph.Undirected.Graph a)
instance GHC.Base.MonadPlus Algebra.Graph.Undirected.Graph
instance GHC.Base.Monad Algebra.Graph.Undirected.Graph
instance Data.String.IsString a => Data.String.IsString (Algebra.Graph.Undirected.Graph a)
instance GHC.Generics.Generic (Algebra.Graph.Undirected.Graph a)
instance GHC.Base.Functor Algebra.Graph.Undirected.Graph
instance GHC.Base.Applicative Algebra.Graph.Undirected.Graph
instance GHC.Base.Alternative Algebra.Graph.Undirected.Graph
instance (GHC.Show.Show a, GHC.Classes.Ord a) => GHC.Show.Show (Algebra.Graph.Undirected.Graph a)
instance GHC.Num.Num a => GHC.Num.Num (Algebra.Graph.Undirected.Graph a)
instance GHC.Classes.Ord a => GHC.Classes.Eq (Algebra.Graph.Undirected.Graph a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.Undirected.Graph a)
instance GHC.Base.Semigroup (Algebra.Graph.Undirected.Graph a)
instance GHC.Base.Monoid (Algebra.Graph.Undirected.Graph a)


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module defines the core type class <a>Graph</a>, a few graph
--   subclasses, and basic polymorphic graph construction primitives.
--   Functions that cannot be implemented fully polymorphically and require
--   the use of an intermediate data type are not included. For example, to
--   compute the number of vertices in a <a>Graph</a> expression you will
--   need to use a concrete data type, such as <a>Algebra.Graph.Graph</a>
--   or <a>Algebra.Graph.AdjacencyMap</a>.
--   
--   See <a>Algebra.Graph.HigherKinded.Class</a> for the higher-kinded
--   version of the core graph type class.
module Algebra.Graph.Class

-- | The core type class for constructing algebraic graphs, characterised
--   by the following minimal set of axioms. In equations we use <tt>+</tt>
--   and <tt>*</tt> as convenient shortcuts for <a>overlay</a> and
--   <a>connect</a>, respectively.
--   
--   <ul>
--   <li><a>overlay</a> is commutative and associative:<pre> x + y == y + x
--   x + (y + z) == (x + y) + z</pre></li>
--   <li><a>connect</a> is associative and has <a>empty</a> as the
--   identity:<pre> x * empty == x empty * x == x x * (y * z) == (x * y) *
--   z</pre></li>
--   <li><a>connect</a> distributes over <a>overlay</a>:<pre>x * (y + z) ==
--   x * y + x * z (x + y) * z == x * z + y * z</pre></li>
--   <li><a>connect</a> can be decomposed:<pre>x * y * z == x * y + x * z +
--   y * z</pre></li>
--   </ul>
--   
--   The following useful theorems can be proved from the above set of
--   axioms.
--   
--   <ul>
--   <li><a>overlay</a> has <a>empty</a> as the identity and is
--   idempotent:<pre> x + empty == x empty + x == x x + x == x</pre></li>
--   <li>Absorption and saturation of <a>connect</a>:<pre>x * y + x + y ==
--   x * y x * x * x == x * x</pre></li>
--   </ul>
--   
--   The core type class <a>Graph</a> corresponds to unlabelled directed
--   graphs. <a>Undirected</a>, <a>Reflexive</a>, <a>Transitive</a> and
--   <a>Preorder</a> graphs can be obtained by extending the minimal set of
--   axioms.
--   
--   When specifying the time and memory complexity of graph algorithms,
--   <i>n</i> will denote the number of vertices in the graph, <i>m</i>
--   will denote the number of edges in the graph, and <i>s</i> will denote
--   the <i>size</i> of the corresponding <a>Graph</a> expression.
class Graph g where {
    
    -- | The type of graph vertices.
    type family Vertex g;
}

-- | Construct the empty graph.
empty :: Graph g => g

-- | Construct the graph with a single vertex.
vertex :: Graph g => Vertex g -> g

-- | Overlay two graphs.
overlay :: Graph g => g -> g -> g

-- | Connect two graphs.
connect :: Graph g => g -> g -> g

-- | The class of <i>undirected graphs</i> that satisfy the following
--   additional axiom.
--   
--   <ul>
--   <li><a>connect</a> is commutative:<pre>x * y == y * x</pre></li>
--   </ul>
class Graph g => Undirected g

-- | The class of <i>reflexive graphs</i> that satisfy the following
--   additional axiom.
--   
--   <ul>
--   <li>Each vertex has a <i>self-loop</i>:<pre>vertex x == vertex x *
--   vertex x</pre></li>
--   </ul>
--   
--   Note that by applying the axiom in the reverse direction, one can
--   always remove all self-loops resulting in an <i>irreflexive graph</i>.
--   This type class can therefore be also used in the context of
--   irreflexive graphs.
class Graph g => Reflexive g

-- | The class of <i>transitive graphs</i> that satisfy the following
--   additional axiom.
--   
--   <ul>
--   <li>The <i>closure</i> axiom: graphs with equal transitive closures
--   are equal.<pre>y /= empty ==&gt; x * y + x * z + y * z == x * y + y *
--   z</pre></li>
--   </ul>
--   
--   By repeated application of the axiom one can turn any graph into its
--   transitive closure or transitive reduction.
class Graph g => Transitive g

-- | The class of <i>preorder graphs</i> that are both reflexive and
--   transitive.
class (Reflexive g, Transitive g) => Preorder g

-- | Construct the graph comprising a single edge.
--   
--   <pre>
--   edge x y == <a>connect</a> (<a>vertex</a> x) (<a>vertex</a> y)
--   </pre>
edge :: Graph g => Vertex g -> Vertex g -> g

-- | Construct the graph comprising a given list of isolated vertices.
--   Complexity: <i>O(L)</i> time, memory and size, where <i>L</i> is the
--   length of the given list.
--   
--   <pre>
--   vertices []  == <a>empty</a>
--   vertices [x] == <a>vertex</a> x
--   vertices     == <a>overlays</a> . map <a>vertex</a>
--   </pre>
vertices :: Graph g => [Vertex g] -> g

-- | Overlay a given list of graphs. Complexity: <i>O(L)</i> time and
--   memory, and <i>O(S)</i> size, where <i>L</i> is the length of the
--   given list, and <i>S</i> is the sum of sizes of the graphs in the
--   list.
--   
--   <pre>
--   overlays []    == <a>empty</a>
--   overlays [x]   == x
--   overlays [x,y] == <a>overlay</a> x y
--   overlays       == <a>foldr</a> <a>overlay</a> <a>empty</a>
--   </pre>
overlays :: Graph g => [g] -> g

-- | Connect a given list of graphs. Complexity: <i>O(L)</i> time and
--   memory, and <i>O(S)</i> size, where <i>L</i> is the length of the
--   given list, and <i>S</i> is the sum of sizes of the graphs in the
--   list.
--   
--   <pre>
--   connects []    == <a>empty</a>
--   connects [x]   == x
--   connects [x,y] == <a>connect</a> x y
--   connects       == <a>foldr</a> <a>connect</a> <a>empty</a>
--   </pre>
connects :: Graph g => [g] -> g

-- | Construct the graph from a list of edges. Complexity: <i>O(L)</i>
--   time, memory and size, where <i>L</i> is the length of the given list.
--   
--   <pre>
--   edges []      == <a>empty</a>
--   edges [(x,y)] == <a>edge</a> x y
--   </pre>
edges :: Graph g => [(Vertex g, Vertex g)] -> g

-- | The <a>isSubgraphOf</a> function takes two graphs and returns
--   <a>True</a> if the first graph is a <i>subgraph</i> of the second.
--   Here is the current implementation:
--   
--   <pre>
--   isSubgraphOf x y = <a>overlay</a> x y == y
--   </pre>
--   
--   The complexity therefore depends on the complexity of equality testing
--   of the specific graph instance.
--   
--   <pre>
--   isSubgraphOf <a>empty</a>         x             == True
--   isSubgraphOf (<a>vertex</a> x)    <a>empty</a>         == False
--   isSubgraphOf x             (<a>overlay</a> x y) == True
--   isSubgraphOf (<a>overlay</a> x y) (<a>connect</a> x y) == True
--   isSubgraphOf (<a>path</a> xs)     (<a>circuit</a> xs)  == True
--   </pre>
isSubgraphOf :: (Graph g, Eq g) => g -> g -> Bool

-- | The <i>path</i> on a list of vertices. Complexity: <i>O(L)</i> time,
--   memory and size, where <i>L</i> is the length of the given list.
--   
--   <pre>
--   path []    == <a>empty</a>
--   path [x]   == <a>vertex</a> x
--   path [x,y] == <a>edge</a> x y
--   </pre>
path :: Graph g => [Vertex g] -> g

-- | The <i>circuit</i> on a list of vertices. Complexity: <i>O(L)</i>
--   time, memory and size, where <i>L</i> is the length of the given list.
--   
--   <pre>
--   circuit []    == <a>empty</a>
--   circuit [x]   == <a>edge</a> x x
--   circuit [x,y] == <a>edges</a> [(x,y), (y,x)]
--   </pre>
circuit :: Graph g => [Vertex g] -> g

-- | The <i>clique</i> on a list of vertices. Complexity: <i>O(L)</i> time,
--   memory and size, where <i>L</i> is the length of the given list.
--   
--   <pre>
--   clique []         == <a>empty</a>
--   clique [x]        == <a>vertex</a> x
--   clique [x,y]      == <a>edge</a> x y
--   clique [x,y,z]    == <a>edges</a> [(x,y), (x,z), (y,z)]
--   clique (xs ++ ys) == <a>connect</a> (clique xs) (clique ys)
--   </pre>
clique :: Graph g => [Vertex g] -> g

-- | The <i>biclique</i> on two lists of vertices. Complexity: <i>O(L1 +
--   L2)</i> time, memory and size, where <i>L1</i> and <i>L2</i> are the
--   lengths of the given lists.
--   
--   <pre>
--   biclique []      []      == <a>empty</a>
--   biclique [x]     []      == <a>vertex</a> x
--   biclique []      [y]     == <a>vertex</a> y
--   biclique [x1,x2] [y1,y2] == <a>edges</a> [(x1,y1), (x1,y2), (x2,y1), (x2,y2)]
--   biclique xs      ys      == <a>connect</a> (<a>vertices</a> xs) (<a>vertices</a> ys)
--   </pre>
biclique :: Graph g => [Vertex g] -> [Vertex g] -> g

-- | The <i>star</i> formed by a centre vertex connected to a list of
--   leaves. Complexity: <i>O(L)</i> time, memory and size, where <i>L</i>
--   is the length of the given list.
--   
--   <pre>
--   star x []    == <a>vertex</a> x
--   star x [y]   == <a>edge</a> x y
--   star x [y,z] == <a>edges</a> [(x,y), (x,z)]
--   star x ys    == <a>connect</a> (<a>vertex</a> x) (<a>vertices</a> ys)
--   </pre>
star :: Graph g => Vertex g -> [Vertex g] -> g

-- | The <i>tree graph</i> constructed from a given <a>Tree</a> data
--   structure. Complexity: <i>O(T)</i> time, memory and size, where
--   <i>T</i> is the size of the given tree (i.e. the number of vertices in
--   the tree).
--   
--   <pre>
--   tree (Node x [])                                         == <a>vertex</a> x
--   tree (Node x [Node y [Node z []]])                       == <a>path</a> [x,y,z]
--   tree (Node x [Node y [], Node z []])                     == <a>star</a> x [y,z]
--   tree (Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]) == <a>edges</a> [(1,2), (1,3), (3,4), (3,5)]
--   </pre>
tree :: Graph g => Tree (Vertex g) -> g

-- | The <i>forest graph</i> constructed from a given <a>Forest</a> data
--   structure. Complexity: <i>O(F)</i> time, memory and size, where
--   <i>F</i> is the size of the given forest (i.e. the number of vertices
--   in the forest).
--   
--   <pre>
--   forest []                                                  == <a>empty</a>
--   forest [x]                                                 == <a>tree</a> x
--   forest [Node 1 [Node 2 [], Node 3 []], Node 4 [Node 5 []]] == <a>edges</a> [(1,2), (1,3), (4,5)]
--   forest                                                     == <a>overlays</a> . <a>map</a> <a>tree</a>
--   </pre>
forest :: Graph g => Forest (Vertex g) -> g
instance Algebra.Graph.Class.Preorder ()
instance Algebra.Graph.Class.Preorder g => Algebra.Graph.Class.Preorder (GHC.Maybe.Maybe g)
instance Algebra.Graph.Class.Preorder g => Algebra.Graph.Class.Preorder (a -> g)
instance (Algebra.Graph.Class.Preorder g, Algebra.Graph.Class.Preorder h) => Algebra.Graph.Class.Preorder (g, h)
instance (Algebra.Graph.Class.Preorder g, Algebra.Graph.Class.Preorder h, Algebra.Graph.Class.Preorder i) => Algebra.Graph.Class.Preorder (g, h, i)
instance Algebra.Graph.Class.Transitive ()
instance Algebra.Graph.Class.Transitive g => Algebra.Graph.Class.Transitive (GHC.Maybe.Maybe g)
instance Algebra.Graph.Class.Transitive g => Algebra.Graph.Class.Transitive (a -> g)
instance (Algebra.Graph.Class.Transitive g, Algebra.Graph.Class.Transitive h) => Algebra.Graph.Class.Transitive (g, h)
instance (Algebra.Graph.Class.Transitive g, Algebra.Graph.Class.Transitive h, Algebra.Graph.Class.Transitive i) => Algebra.Graph.Class.Transitive (g, h, i)
instance Algebra.Graph.Class.Reflexive ()
instance Algebra.Graph.Class.Reflexive g => Algebra.Graph.Class.Reflexive (GHC.Maybe.Maybe g)
instance Algebra.Graph.Class.Reflexive g => Algebra.Graph.Class.Reflexive (a -> g)
instance (Algebra.Graph.Class.Reflexive g, Algebra.Graph.Class.Reflexive h) => Algebra.Graph.Class.Reflexive (g, h)
instance (Algebra.Graph.Class.Reflexive g, Algebra.Graph.Class.Reflexive h, Algebra.Graph.Class.Reflexive i) => Algebra.Graph.Class.Reflexive (g, h, i)
instance Algebra.Graph.Class.Undirected (Algebra.Graph.Undirected.Graph a)
instance GHC.Classes.Ord a => Algebra.Graph.Class.Undirected (Algebra.Graph.Relation.Symmetric.Relation a)
instance Algebra.Graph.Class.Undirected ()
instance Algebra.Graph.Class.Undirected g => Algebra.Graph.Class.Undirected (GHC.Maybe.Maybe g)
instance Algebra.Graph.Class.Undirected g => Algebra.Graph.Class.Undirected (a -> g)
instance (Algebra.Graph.Class.Undirected g, Algebra.Graph.Class.Undirected h) => Algebra.Graph.Class.Undirected (g, h)
instance (Algebra.Graph.Class.Undirected g, Algebra.Graph.Class.Undirected h, Algebra.Graph.Class.Undirected i) => Algebra.Graph.Class.Undirected (g, h, i)
instance Algebra.Graph.Class.Graph (Algebra.Graph.Graph a)
instance Algebra.Graph.Class.Graph (Algebra.Graph.Undirected.Graph a)
instance GHC.Classes.Ord a => Algebra.Graph.Class.Graph (Algebra.Graph.AdjacencyMap.AdjacencyMap a)
instance Algebra.Graph.Class.Graph Algebra.Graph.AdjacencyIntMap.AdjacencyIntMap
instance Algebra.Graph.Label.Dioid e => Algebra.Graph.Class.Graph (Algebra.Graph.Labelled.Graph e a)
instance (Algebra.Graph.Label.Dioid e, GHC.Classes.Eq e, GHC.Classes.Ord a) => Algebra.Graph.Class.Graph (Algebra.Graph.Labelled.AdjacencyMap.AdjacencyMap e a)
instance GHC.Classes.Ord a => Algebra.Graph.Class.Graph (Algebra.Graph.Relation.Relation a)
instance GHC.Classes.Ord a => Algebra.Graph.Class.Graph (Algebra.Graph.Relation.Symmetric.Relation a)
instance Algebra.Graph.Class.Graph ()
instance Algebra.Graph.Class.Graph g => Algebra.Graph.Class.Graph (GHC.Maybe.Maybe g)
instance Algebra.Graph.Class.Graph g => Algebra.Graph.Class.Graph (a -> g)
instance (Algebra.Graph.Class.Graph g, Algebra.Graph.Class.Graph h) => Algebra.Graph.Class.Graph (g, h)
instance (Algebra.Graph.Class.Graph g, Algebra.Graph.Class.Graph h, Algebra.Graph.Class.Graph i) => Algebra.Graph.Class.Graph (g, h, i)


-- | An abstract implementation of transitive binary relations. Use
--   <a>Algebra.Graph.Class</a> for polymorphic construction and
--   manipulation.
module Algebra.Graph.Relation.Transitive

-- | The <a>TransitiveRelation</a> data type represents a <i>transitive
--   binary relation</i> over a set of elements. Transitive relations
--   satisfy all laws of the <tt>Transitive</tt> type class and, in
--   particular, the <i>closure</i> axiom:
--   
--   <pre>
--   y /= <a>empty</a> ==&gt; x * y + x * z + y * z == x * y + y * z
--   </pre>
--   
--   For example, the following holds:
--   
--   <pre>
--   <a>path</a> xs == (<a>clique</a> xs :: TransitiveRelation Int)
--   </pre>
--   
--   The <a>Show</a> instance produces transitively closed expressions:
--   
--   <pre>
--   show (1 * 2         :: TransitiveRelation Int) == "edge 1 2"
--   show (1 * 2 + 2 * 3 :: TransitiveRelation Int) == "edges [(1,2),(1,3),(2,3)]"
--   </pre>
data TransitiveRelation a

-- | Construct a transitive relation from a <a>Relation</a>. Complexity:
--   <i>O(1)</i> time.
fromRelation :: Relation a -> TransitiveRelation a

-- | Extract the underlying relation. Complexity: <i>O(n * m * log(m))</i>
--   time.
toRelation :: Ord a => TransitiveRelation a -> Relation a
instance (GHC.Classes.Ord a, GHC.Num.Num a) => GHC.Num.Num (Algebra.Graph.Relation.Transitive.TransitiveRelation a)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Algebra.Graph.Relation.Transitive.TransitiveRelation a)
instance Data.String.IsString a => Data.String.IsString (Algebra.Graph.Relation.Transitive.TransitiveRelation a)
instance GHC.Classes.Ord a => GHC.Classes.Eq (Algebra.Graph.Relation.Transitive.TransitiveRelation a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.Relation.Transitive.TransitiveRelation a)
instance (GHC.Classes.Ord a, GHC.Show.Show a) => GHC.Show.Show (Algebra.Graph.Relation.Transitive.TransitiveRelation a)
instance GHC.Classes.Ord a => Algebra.Graph.Class.Graph (Algebra.Graph.Relation.Transitive.TransitiveRelation a)
instance GHC.Classes.Ord a => Algebra.Graph.Class.Transitive (Algebra.Graph.Relation.Transitive.TransitiveRelation a)


-- | An abstract implementation of reflexive binary relations. Use
--   <a>Algebra.Graph.Class</a> for polymorphic construction and
--   manipulation.
module Algebra.Graph.Relation.Reflexive

-- | The <a>ReflexiveRelation</a> data type represents a <i>reflexive
--   binary relation</i> over a set of elements. Reflexive relations
--   satisfy all laws of the <tt>Reflexive</tt> type class and, in
--   particular, the <i>self-loop</i> axiom:
--   
--   <pre>
--   <a>vertex</a> x == <a>vertex</a> x * <a>vertex</a> x
--   </pre>
--   
--   The <a>Show</a> instance produces reflexively closed expressions:
--   
--   <pre>
--   show (1     :: ReflexiveRelation Int) == "edge 1 1"
--   show (1 * 2 :: ReflexiveRelation Int) == "edges [(1,1),(1,2),(2,2)]"
--   </pre>
data ReflexiveRelation a

-- | Construct a reflexive relation from a <a>Relation</a>. Complexity:
--   <i>O(1)</i> time.
fromRelation :: Relation a -> ReflexiveRelation a

-- | Extract the underlying relation. Complexity: <i>O(n*log(m))</i> time.
toRelation :: Ord a => ReflexiveRelation a -> Relation a
instance (GHC.Classes.Ord a, GHC.Num.Num a) => GHC.Num.Num (Algebra.Graph.Relation.Reflexive.ReflexiveRelation a)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Algebra.Graph.Relation.Reflexive.ReflexiveRelation a)
instance Data.String.IsString a => Data.String.IsString (Algebra.Graph.Relation.Reflexive.ReflexiveRelation a)
instance GHC.Classes.Ord a => GHC.Classes.Eq (Algebra.Graph.Relation.Reflexive.ReflexiveRelation a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.Relation.Reflexive.ReflexiveRelation a)
instance (GHC.Classes.Ord a, GHC.Show.Show a) => GHC.Show.Show (Algebra.Graph.Relation.Reflexive.ReflexiveRelation a)
instance GHC.Classes.Ord a => Algebra.Graph.Class.Graph (Algebra.Graph.Relation.Reflexive.ReflexiveRelation a)
instance GHC.Classes.Ord a => Algebra.Graph.Class.Reflexive (Algebra.Graph.Relation.Reflexive.ReflexiveRelation a)


-- | An abstract implementation of preorder relations. Use
--   <a>Algebra.Graph.Class</a> for polymorphic construction and
--   manipulation.
module Algebra.Graph.Relation.Preorder

-- | The <a>PreorderRelation</a> data type represents a <i>binary relation
--   that is both reflexive and transitive</i>. Preorders satisfy all laws
--   of the <tt>Preorder</tt> type class and, in particular, the
--   <i>self-loop</i> axiom:
--   
--   <pre>
--   <a>vertex</a> x == <a>vertex</a> x * <a>vertex</a> x
--   </pre>
--   
--   and the <i>closure</i> axiom:
--   
--   <pre>
--   y /= <a>empty</a> ==&gt; x * y + x * z + y * z == x * y + y * z
--   </pre>
--   
--   For example, the following holds:
--   
--   <pre>
--   <a>path</a> xs == (<a>clique</a> xs :: PreorderRelation Int)
--   </pre>
--   
--   The <a>Show</a> instance produces reflexively and transitively closed
--   expressions:
--   
--   <pre>
--   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)]"
--   </pre>
data PreorderRelation a

-- | Construct a preorder relation from a <a>Relation</a>. Complexity:
--   <i>O(1)</i> time.
fromRelation :: Relation a -> PreorderRelation a

-- | Extract the underlying relation. Complexity: <i>O(n * m * log(m))</i>
--   time.
toRelation :: Ord a => PreorderRelation a -> Relation a
instance (GHC.Classes.Ord a, GHC.Num.Num a) => GHC.Num.Num (Algebra.Graph.Relation.Preorder.PreorderRelation a)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Algebra.Graph.Relation.Preorder.PreorderRelation a)
instance Data.String.IsString a => Data.String.IsString (Algebra.Graph.Relation.Preorder.PreorderRelation a)
instance (GHC.Classes.Ord a, GHC.Show.Show a) => GHC.Show.Show (Algebra.Graph.Relation.Preorder.PreorderRelation a)
instance GHC.Classes.Ord a => GHC.Classes.Eq (Algebra.Graph.Relation.Preorder.PreorderRelation a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Algebra.Graph.Relation.Preorder.PreorderRelation a)
instance GHC.Classes.Ord a => Algebra.Graph.Class.Graph (Algebra.Graph.Relation.Preorder.PreorderRelation a)
instance GHC.Classes.Ord a => Algebra.Graph.Class.Reflexive (Algebra.Graph.Relation.Preorder.PreorderRelation a)
instance GHC.Classes.Ord a => Algebra.Graph.Class.Transitive (Algebra.Graph.Relation.Preorder.PreorderRelation a)
instance GHC.Classes.Ord a => Algebra.Graph.Class.Preorder (Algebra.Graph.Relation.Preorder.PreorderRelation a)


-- | <b>Alga</b> is a library for algebraic construction and manipulation
--   of graphs in Haskell. See <a>this paper</a> for the motivation behind
--   the library, the underlying theory, and implementation details.
--   
--   This module provides primitives for interoperability between this
--   library and the <a>Data.Graph</a> module of the containers library. It
--   is for internal use only and may be removed without notice at any
--   point.
module Data.Graph.Typed

-- | <a>GraphKL</a> encapsulates King-Launchbury graphs, which are
--   implemented in the <a>Data.Graph</a> module of the <tt>containers</tt>
--   library.
data GraphKL a
GraphKL :: Graph -> (Vertex -> a) -> (a -> Maybe Vertex) -> GraphKL a

-- | Array-based graph representation (King and Launchbury, 1995).
[toGraphKL] :: GraphKL a -> Graph

-- | A mapping of <a>Data.Graph.Vertex</a> to vertices of type <tt>a</tt>.
--   This is partial and may fail if the vertex is out of bounds.
[fromVertexKL] :: GraphKL a -> Vertex -> a

-- | A mapping from vertices of type <tt>a</tt> to
--   <a>Data.Graph.Vertex</a>. Returns <a>Nothing</a> if the argument is
--   not in the graph.
[toVertexKL] :: GraphKL a -> a -> Maybe Vertex

-- | Build <a>GraphKL</a> from an <a>AdjacencyMap</a>. If
--   <tt>fromAdjacencyMap g == h</tt> then the following holds:
--   
--   <pre>
--   map (<a>fromVertexKL</a> h) (<a>vertices</a> $ <a>toGraphKL</a> h)                               == <a>vertexList</a> g
--   map (\(x, y) -&gt; (<a>fromVertexKL</a> h x, <a>fromVertexKL</a> h y)) (<a>edges</a> $ <a>toGraphKL</a> h) == <a>edgeList</a> g
--   <a>toGraphKL</a> (fromAdjacencyMap (1 * 2 + 3 * 1))                                == <tt>array</tt> (0,2) [(0,[1]), (1,[]), (2,[0])]
--   <a>toGraphKL</a> (fromAdjacencyMap (1 * 2 + 2 * 1))                                == <tt>array</tt> (0,1) [(0,[1]), (1,[0])]
--   </pre>
fromAdjacencyMap :: Ord a => AdjacencyMap a -> GraphKL a

-- | Build <a>GraphKL</a> from an <a>AdjacencyIntMap</a>. If
--   <tt>fromAdjacencyIntMap g == h</tt> then the following holds:
--   
--   <pre>
--   map (<a>fromVertexKL</a> h) (<a>vertices</a> $ <a>toGraphKL</a> h)                               == <a>toAscList</a> (<a>vertexIntSet</a> g)
--   map (\(x, y) -&gt; (<a>fromVertexKL</a> h x, <a>fromVertexKL</a> h y)) (<a>edges</a> $ <a>toGraphKL</a> h) == <a>edgeList</a> g
--   <a>toGraphKL</a> (fromAdjacencyIntMap (1 * 2 + 3 * 1))                             == <tt>array</tt> (0,2) [(0,[1]), (1,[]), (2,[0])]
--   <a>toGraphKL</a> (fromAdjacencyIntMap (1 * 2 + 2 * 1))                             == <tt>array</tt> (0,1) [(0,[1]), (1,[0])]
--   </pre>
fromAdjacencyIntMap :: AdjacencyIntMap -> GraphKL Int

-- | Compute the <i>depth-first search</i> forest of a graph.
--   
--   In the following examples we will use the helper function:
--   
--   <pre>
--   (%) :: (GraphKL Int -&gt; a) -&gt; <a>AdjacencyMap</a> Int -&gt; a
--   a % g = a $ <a>fromAdjacencyMap</a> g
--   </pre>
--   
--   for greater clarity.
--   
--   <pre>
--   <a>forest</a> (dfsForest % <a>edge</a> 1 1)           == <a>vertex</a> 1
--   <a>forest</a> (dfsForest % <a>edge</a> 1 2)           == <a>edge</a> 1 2
--   <a>forest</a> (dfsForest % <a>edge</a> 2 1)           == <a>vertices</a> [1, 2]
--   <a>isSubgraphOf</a> (<a>forest</a> $ dfsForest % x) x == True
--   dfsForest % <a>forest</a> (dfsForest % x)      == dfsForest % x
--   dfsForest % <a>vertices</a> vs                 == <a>map</a> (\v -&gt; Node v []) (<a>nub</a> $ <a>sort</a> vs)
--   <a>dfsForestFrom</a> (<a>vertexList</a> x) % x        == dfsForest % x
--   dfsForest % (3 * (1 + 4) * (1 + 5))     == [ Node { rootLabel = 1
--                                                     , subForest = [ Node { rootLabel = 5
--                                                                          , subForest = [] }]}
--                                              , Node { rootLabel = 3
--                                                     , subForest = [ Node { rootLabel = 4
--                                                                          , subForest = [] }]}]
--   </pre>
dfsForest :: GraphKL a -> Forest a

-- | Compute the <i>depth-first search</i> forest of a graph, searching
--   from each of the given vertices in order. Note that the resulting
--   forest does not necessarily span the whole graph, as some vertices may
--   be unreachable.
--   
--   In the following examples we will use the helper function:
--   
--   <pre>
--   (%) :: (GraphKL Int -&gt; a) -&gt; <a>AdjacencyMap</a> Int -&gt; a
--   a % g = a $ <a>fromAdjacencyMap</a> g
--   </pre>
--   
--   for greater clarity.
--   
--   <pre>
--   <a>forest</a> (dfsForestFrom [1]    % <a>edge</a> 1 1)       == <a>vertex</a> 1
--   <a>forest</a> (dfsForestFrom [1]    % <a>edge</a> 1 2)       == <a>edge</a> 1 2
--   <a>forest</a> (dfsForestFrom [2]    % <a>edge</a> 1 2)       == <a>vertex</a> 2
--   <a>forest</a> (dfsForestFrom [3]    % <a>edge</a> 1 2)       == <a>empty</a>
--   <a>forest</a> (dfsForestFrom [2, 1] % <a>edge</a> 1 2)       == <a>vertices</a> [1, 2]
--   <a>isSubgraphOf</a> (<a>forest</a> $ dfsForestFrom vs % x) x == True
--   dfsForestFrom (<a>vertexList</a> x) % x               == <a>dfsForest</a> % x
--   dfsForestFrom vs               % <a>vertices</a> vs   == <a>map</a> (\v -&gt; Node v []) (<a>nub</a> vs)
--   dfsForestFrom []               % x             == []
--   dfsForestFrom [1, 4] % (3 * (1 + 4) * (1 + 5)) == [ Node { rootLabel = 1
--                                                            , subForest = [ Node { rootLabel = 5
--                                                                                 , subForest = [] }
--                                                     , Node { rootLabel = 4
--                                                            , subForest = [] }]
--   </pre>
dfsForestFrom :: [a] -> GraphKL a -> Forest a

-- | Compute the list of vertices visited by the <i>depth-first search</i>
--   in a graph, when searching from each of the given vertices in order.
--   
--   In the following examples we will use the helper function:
--   
--   <pre>
--   (%) :: (GraphKL Int -&gt; a) -&gt; <a>AdjacencyMap</a> Int -&gt; a
--   a % g = a $ <a>fromAdjacencyMap</a> g
--   </pre>
--   
--   for greater clarity.
--   
--   <pre>
--   dfs [1]   % <a>edge</a> 1 1                 == [1]
--   dfs [1]   % <a>edge</a> 1 2                 == [1,2]
--   dfs [2]   % <a>edge</a> 1 2                 == [2]
--   dfs [3]   % <a>edge</a> 1 2                 == []
--   dfs [1,2] % <a>edge</a> 1 2                 == [1,2]
--   dfs [2,1] % <a>edge</a> 1 2                 == [2,1]
--   dfs []    % x                        == []
--   dfs [1,4] % (3 * (1 + 4) * (1 + 5))  == [1,5,4]
--   <a>isSubgraphOf</a> (<a>vertices</a> $ dfs vs x) x == True
--   </pre>
dfs :: [a] -> GraphKL a -> [a]

-- | Compute the <i>topological sort</i> of a graph. Note that this
--   function returns a result even if the graph is cyclic.
--   
--   In the following examples we will use the helper function:
--   
--   <pre>
--   (%) :: (GraphKL Int -&gt; a) -&gt; <a>AdjacencyMap</a> Int -&gt; a
--   a % g = a $ <a>fromAdjacencyMap</a> g
--   </pre>
--   
--   for greater clarity.
--   
--   <pre>
--   topSort % (1 * 2 + 3 * 1) == [3,1,2]
--   topSort % (1 * 2 + 2 * 1) == [1,2]
--   </pre>
topSort :: GraphKL a -> [a]
scc :: Ord a => AdjacencyMap a -> AdjacencyMap (AdjacencyMap a)
