anchor.diff:                      else
                           // Keep looping without modifying the set.
                           reachableFrom)))
  +
  +    (* TODO :   Copy the 'reachable' function, then modify it slightly
  +                so it computes the _reflexive_ transitive closure. *)
  +
  +    /// Computes the strongly-connected components of a graph using
  +    /// Tarjan's offline strongly-connected components algorithm.
  +    let stronglyConnectedComponents (graph : VertexLabeledSparseDigraph<'Vertex>) =
  +        // If the graph's vertex-set is empty, return immediately.
  +        if isEmpty graph then
  +            Set.empty
  +        else
  +            /// The successor sets of the graph vertices.
  +            let successorsOf = successors graph
  +
  +            //
  +            let rec scc (sccs : Set<Set<'Vertex>>,
  +                                            indices : Map<'Vertex, int>,
  +                                            lowlink : Map<'Vertex, int>,
  +                                            stack : 'Vertex list) (vertex : 'Vertex) =
  +                let index = indices.Count
  +                let indices = Map.add vertex index indices
  +                let lowlink = Map.add vertex index lowlink
  +                let stack = vertex :: stack
  +
  +                // Examine the successors of the current vertex.
  +                let successors = Map.find vertex successorsOf
  +                let sccs, indices, lowlink, stack =
  +                    ((sccs, indices, lowlink, stack), successors)
  +                    ||> Set.fold (fun ((sccs, indices, lowlink, stack) as state) successor ->
  +                        if not <| Map.containsKey successor indices then
  +                            // The successor has not been visited yet; do so now.
  +                            let sccs, indices, lowlink, stack =
  +                                scc state successor
  +                            let lowlink = Map.add vertex (min (Map.find vertex lowlink) (Map.find successor lowlink)) lowlink
  +                            sccs, indices, lowlink, stack
  +                        elif List.exists ((=) successor) stack then
  +                            // The successor is in the same SCC as the current vertex.
  +                            let lowlink = Map.add vertex (min (Map.find vertex lowlink) (Map.find successor indices)) lowlink
  +                            sccs, indices, lowlink, stack
  +                        else state)
  +
  +                // If v is a root node, pop the stack and generate an SCC
  +                if Map.find vertex lowlink = Map.find vertex indices then
  +                    let mutable scc = Set.empty
  +                    let mutable stack = stack
  +
  +                    while List.head stack <> vertex do
  +                        scc <- Set.add (List.head stack) scc
  +                        stack <- List.tail stack
  +
  +                    // The head of the stack should be this vertex itself.
  +                    // Remove it from the stack and add it to the SCC.
  +                    assert (List.head stack = vertex)
  +                    scc <- Set.add (List.head stack) scc
  +                    stack <- List.tail stack
  +
  +                    // Add the new SCC to the set of SCCs and continue processing.
  +                    (Set.add scc sccs), indices, lowlink, stack
  +                else
  +                    sccs, indices, lowlink, stack
  +
  +            // TODO : Modify this function to use CPS or re-implement
  +            // the algorithm so it's tail-recursive.
  +            ((Set.empty, Map.empty, Map.empty, List.empty), graph.Vertices)
  +            ||> Set.fold (fun ((_, indices, _, _) as state) vertex ->
  +                if Map.containsKey vertex indices then
  +                    state
  +                else
  +                    scc state vertex)
  +            // Return the set of strongly-connected components.
  +            |> fun (sccs,_,_,_) -> sccs
   
   //
   type internal ParserStatePositionGraphAction<'Nonterminal, 'Terminal
  
positive.code:     let inline isEmpty (graph : VertexLabeledSparseDigraph<'Vertex>) =
          graph.IsEmpty
  
      //
      let inline addVertex (vertex : 'Vertex) (graph : VertexLabeledSparseDigraph<'Vertex>) =
          graph.AddVertex vertex
  
negative.code: 
  
  /// An immutable implementation of a vertex-labeled sparse digraph.
  type internal VertexLabeledSparseDigraph<[<EqualityConditionalOn>]'Vertex when 'Vertex : comparison>
          private (vertices : Set<'Vertex>, edges : Set<'Vertex * 'Vertex>) =
      //
      static member internal Empty
  