+module OT =
+ struct
+ type t = int
+ let compare = Pervasives.compare
+ end
+
+module M = Map.Make(OT)
+
+let rec find_deps m i =
+ if M.mem i m then m
+ else
+ let p,_,_ = proof_of_id i in
+ match p with
+ | Exact _ -> M.add i [] m
+ | Step (_,(_,id1,(_,id2),_)) ->
+ let m = find_deps m id1 in
+ let m = find_deps m id2 in
+ M.add i (M.find id1 m @ M.find id2 m @ [id1;id2]) m
+;;
+
+let topological_sort l =
+ (* build the partial order relation *)
+ let m =
+ List.fold_left (fun m i -> find_deps m i)
+ M.empty l
+ in
+ let m = M.map (fun x -> Some x) m in
+ (* utils *)
+ let keys m = M.fold (fun i _ acc -> i::acc) m [] in
+ let split l m = List.filter (fun i -> M.find i m = Some []) l in
+ let purge l m =
+ M.mapi
+ (fun k v -> if List.mem k l then None else
+ match v with
+ | None -> None
+ | Some ll -> Some (List.filter (fun i -> not (List.mem i l)) ll))
+ m
+ in
+ let rec aux m =
+ let keys = keys m in
+ let ok = split keys m in
+ let m = purge ok m in
+ ok @ (if ok = [] then [] else aux m)
+ in
+ aux m
+;;
+
+