 ### Simplify the implementation of graph numbering using [Numbering].

parent 56d72622
 ... ... @@ -17,58 +17,46 @@ module Make (G : GRAPH with type t = M.key) = struct type t = G.t (* Set up a facility for numbering vertices. *) let push frontier x = module N = Numbering.Make(M) (* Implement a depth-first search. The functions [N.has_been_encoded] and [N.encode] allow us not only to assign a unique number to each vertex, but also to mark a vertex and test whether a vertex has been marked. *) let frontier = Stack.create() let push x = Stack.push x frontier let rec visit gensym table frontier = let rec visit () = match Stack.pop frontier with | exception Stack.Empty -> (* The stack is empty: we are done. *) () | x -> match M.find x table with | _ -> (* [x] is known already: ignore it. *) visit gensym table frontier | exception Not_found -> (* Assign the number [i] to [x]. *) let i = gensym() in M.add x i table; G.foreach_successor x (push frontier); visit gensym table frontier let n, encode, decode = (* Perform a depth-first traversal of the graph. Assign a unique number [i] to every newly-discovered vertex [x]. *) let gensym = Gensym.make() in let table = M.create() in let frontier = Stack.create() in G.foreach_root (push frontier); visit gensym table frontier; let n = gensym() in (* We have discovered [n] graph vertices. [table] now contains a mapping of these vertices to integers in the range [0..n). We now build the reverse mapping in an array. This may seem a little clumsy (an array of options is allocated in an intermediate step), but requires only linear time. *) let vertex : G.t option array = Array.make n None in M.iter (fun x i -> vertex.(i) <- Some x ) table; let force = function Some x -> x | None -> assert false in let vertex : G.t array = Array.map force vertex in (* Return two conversions functions. *) let encode x = try M.find x table with Not_found -> let msg = Printf.sprintf "\n Fix.Number says: \ please check the argument passed to \"encode\".\n %s\n" __LOC__ in raise (Invalid_argument msg) and decode i = vertex.(i) in n, encode, decode if N.has_been_encoded x then (* [x] is known already: ignore it. *) visit() else (* Assign a number to [x]. *) let (_ : int) = N.encode x in G.foreach_successor x push; visit() (* Perform the depth-first search. *) let () = G.foreach_root push; visit() (* We are done! This defines [n], [encode], [decode]. *) include N.Done() end ... ...
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!