2015-12-23 02:59:18 -08:00
|
|
|
(**************************************************************************)
|
|
|
|
(* *)
|
2016-02-18 07:11:59 -08:00
|
|
|
(* OCaml *)
|
2015-12-23 02:59:18 -08:00
|
|
|
(* *)
|
|
|
|
(* Pierre Chambart, OCamlPro *)
|
2016-01-12 04:27:53 -08:00
|
|
|
(* Mark Shinwell and Leo White, Jane Street Europe *)
|
2015-12-23 02:59:18 -08:00
|
|
|
(* *)
|
2016-01-12 04:27:53 -08:00
|
|
|
(* Copyright 2013--2016 OCamlPro SAS *)
|
|
|
|
(* Copyright 2014--2016 Jane Street Group LLC *)
|
2015-12-23 02:59:18 -08:00
|
|
|
(* *)
|
2016-01-12 04:27:53 -08:00
|
|
|
(* All rights reserved. This file is distributed under the terms of *)
|
2016-01-12 04:32:30 -08:00
|
|
|
(* the GNU Lesser General Public License version 2.1, with the *)
|
2016-02-18 07:11:59 -08:00
|
|
|
(* special exception on linking described in the file LICENSE. *)
|
2016-01-12 04:27:53 -08:00
|
|
|
(* *)
|
|
|
|
(**************************************************************************)
|
2015-12-23 02:59:18 -08:00
|
|
|
|
2016-01-12 04:27:53 -08:00
|
|
|
(** Kosaraju's algorithm for strongly connected components. *)
|
2015-12-23 02:59:18 -08:00
|
|
|
|
|
|
|
module type S = sig
|
|
|
|
module Id : Identifiable.S
|
|
|
|
|
|
|
|
type directed_graph = Id.Set.t Id.Map.t
|
|
|
|
(** If (a -> set) belongs to the map, it means that there are edges
|
|
|
|
from [a] to every element of [set]. It is assumed that no edge
|
|
|
|
points to a vertex not represented in the map. *)
|
|
|
|
|
|
|
|
type component =
|
|
|
|
| Has_loop of Id.t list
|
|
|
|
| No_loop of Id.t
|
|
|
|
|
|
|
|
val connected_components_sorted_from_roots_to_leaf
|
|
|
|
: directed_graph
|
|
|
|
-> component array
|
|
|
|
|
|
|
|
val component_graph : directed_graph -> (component * int list) array
|
|
|
|
end
|
|
|
|
|
|
|
|
module Make (Id : Identifiable.S) : S with module Id := Id
|