1 (***********************************************************************)
3 (* MLTk, Tcl/Tk interface of Objective Caml *)
5 (* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
6 (* projet Cristal, INRIA Rocquencourt *)
7 (* Jacques Garrigue, Kyoto University RIMS *)
9 (* Copyright 2002 Institut National de Recherche en Informatique et *)
10 (* en Automatique and Kyoto University. All rights reserved. *)
11 (* This file is distributed under the terms of the GNU Library *)
12 (* General Public License, with the special exception on linking *)
13 (* described in file LICENSE found in the Objective Caml source tree. *)
15 (***********************************************************************)
17 (* $Id: tsort.ml 4745 2002-04-26 12:16:26Z furuse $ *)
21 (* Topological Sort.list *)
22 (* d'apres More Programming Pearls *)
24 (* node * pred count * successors *)
28 mutable pred_count : int;
29 mutable successors : 'a entry list
32 type 'a porder = 'a entry list ref
36 let find_entry order node =
37 let rec search_entry =
40 | x::l -> if x.node = node then x else search_entry l
45 Not_found -> let entry = {node = node;
48 order := entry::!order;
51 let create () = ref []
53 (* Inverted args because Sort.list builds list in reverse order *)
54 let add_relation order (succ,pred) =
55 let pred_entry = find_entry order pred
56 and succ_entry = find_entry order succ in
57 succ_entry.pred_count <- succ_entry.pred_count + 1;
58 pred_entry.successors <- succ_entry::pred_entry.successors
61 let add_element order e =
62 ignore (find_entry order e)
65 let q = Queue.create ()
66 and result = ref [] in
68 ~f:(function {pred_count = n} as node ->
69 if n = 0 then Queue.add node q);
72 let t = Queue.take q in
73 result := t.node :: !result;
74 List.iter t.successors ~f:
76 let n = s.pred_count - 1 in
78 if n = 0 then Queue.add s q
84 ~f:(fun node -> if node.pred_count <> 0