let reverse_dependency_closure ?(maxdepth=max_int) reverse =
let h = Hashtbl.create (Array.length reverse) in
let cmp : int -> int -> bool = (=) in
fun idlist ->
try Hashtbl.find h (idlist,maxdepth)
with Not_found -> begin
let queue = Queue.create () in
let visited = Hashtbl.create (List.length idlist) in
List.iter (fun e -> Queue.add (e,0) queue) (List.unique ~cmp idlist);
while (Queue.length queue > 0) do
let (id,level) = Queue.take queue in
if not(Hashtbl.mem visited id) && level < maxdepth then begin
Hashtbl.add visited id ();
List.iter (fun i ->
if not(Hashtbl.mem visited i) then
Queue.add (i,level+1) queue
) reverse.(id)
end
done;
let result = Hashtbl.fold (fun k _ l -> k::l) visited [] in
Hashtbl.add h (idlist,maxdepth) result;
result
end