123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134(**************************************************************************)(* *)(* Ocamlgraph: a generic graph library for OCaml *)(* Copyright (C) 2004-2010 *)(* Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles *)(* *)(* This software is free software; you can redistribute it and/or *)(* modify it under the terms of the GNU Library General Public *)(* License version 2.1, with the special exception on linking *)(* described in file LICENSE. *)(* *)(* This software is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *)(* *)(**************************************************************************)moduletypeG=sigtypetmoduleV:Sig.COMPARABLEvalsucc:t->V.t->V.tlistvaliter_succ:(V.t->unit)->t->V.t->unitvalfold_succ:(V.t->'a->'a)->t->V.t->'a->'avaliter_vertex:(V.t->unit)->t->unitvalfold_vertex:(V.t->'a->'a)->t->'a->'aendmoduletypeMINSEP=sigmoduleG:GmoduleVertex_Set:Set.Swithtypeelt=G.V.tmoduleVSetset:Set.Swithtypeelt=Vertex_Set.tvalallminsep:G.t->Vertex_Set.tlistvallist_of_allminsep:G.t->G.V.tlistlistvalset_of_allminsep:G.t->VSetset.tendmoduleMake(G:sigincludeGvalcc:t->V.tlist->V.tlistlist(** compute the set of connected components of G(V \ l) *)end)=structmoduleN=Oper.Neighbourhood(G)moduleVertex_Set:Set.Swithtypet=N.Vertex_Set.tandtypeelt=G.V.t=N.Vertex_SetmoduleVSetset=Set.Make(N.Vertex_Set)(* Use [N.Vertex_Set] instead of [Vertex_Set] in order to avoid an error with
ocamldoc 4.02. However this change requires to add extra type annotations
to module [Vertex_Set] above in order to prevent compilation error with
OCaml <= 4.0 :-(. *)letinitialisationg=letcc=G.ccginletneighbourhood=N.list_from_vertexginletneighbourhoods=N.set_from_verticesginG.fold_vertex(funvs->List.fold_left(funsl->neighbourhoodsl::s)s(cc(v::neighbourhoodv)))g[]letgenerationg=letneighbourhood=N.list_from_vertexginletneighbourhoods=N.set_from_verticesginletcc=G.ccginletrecgen_auxseenbigs=function|[]->bigs|s::tl->letl=Vertex_Set.elementssinletseen=VSetset.addsseeninletbigs,tl=Vertex_Set.fold(funv_->letadd_neighbourhoods(bigs,tl)l=lets=neighbourhoodslins::bigs,ifVSetset.memsseenthentlelses::tlinList.fold_leftadd_neighbourhoods(bigs,tl)(cc(l@neighbourhoodv)))s(bigs,tl)ingen_auxseenbigstlinfunbigs->gen_auxVSetset.emptybigsbigsletallminsepg=generationg(initialisationg)letset_of_allminsepg=List.fold_left(funbigss->VSetset.addsbigs)VSetset.empty(allminsepg)letlist_of_allminsepg=List.mapVertex_Set.elements(allminsepg)endmoduleP(G:sigincludeGvalremove_vertex:t->V.t->tend)=structmoduleG=GincludeMake(structincludeGletcc=letmoduleCC=Components.Make(G)infungl->letg=List.fold_leftremove_vertexglinCC.scc_listgend)endmoduleI(G:sigincludeGmoduleMark:Sig.MARKwithtypegraph=tandtypevertex=V.tend)=structmoduleG=GincludeMake(structincludeGletcc=letmoduleCC=Components.Make(structincludeGletiter_vertexf=iter_vertex(funv->ifMark.getv=0thenfv)end)infungl->G.Mark.clearg;List.iter(funv->G.Mark.setv1)l;CC.scc_listgend)end