1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
(*
* A generic directed graph data structure.
* Implemented in an ``object oriented style''
* All graphs are based on this interface.
*
* -- Allen
*)
structure Graph : GRAPH =
struct
exception Graph of string
exception Subgraph
exception NotFound
exception Unimplemented
exception Readonly
exception NotSingleEntry
exception NotSingleExit
fun unimplemented _ = raise Unimplemented
type node_id = int
type 'n node = node_id * 'n
type 'e edge = node_id * node_id * 'e
datatype ('n,'e,'g) graph = GRAPH of ('n,'e,'g) graph_methods
withtype ('n,'e,'g) graph_methods =
{ name : string,
graph_info : 'g,
(* inserting/removing nodes and edges *)
new_id : unit -> node_id,
add_node : 'n node -> unit,
add_edge : 'e edge -> unit,
remove_node : node_id -> unit,
set_out_edges : node_id * 'e edge list -> unit,
set_in_edges : node_id * 'e edge list -> unit,
set_entries : node_id list -> unit,
set_exits : node_id list -> unit,
garbage_collect : unit -> unit,
nodes : unit -> 'n node list,
edges : unit -> 'e edge list,
order : unit -> int,
size : unit -> int,
capacity : unit -> int,
succ : node_id -> node_id list,
pred : node_id -> node_id list,
out_edges : node_id -> 'e edge list,
in_edges : node_id -> 'e edge list,
has_edge : node_id * node_id -> bool,
has_node : node_id -> bool,
node_info : node_id -> 'n,
entries : unit -> node_id list,
exits : unit -> node_id list,
entry_edges : node_id -> 'e edge list,
exit_edges : node_id -> 'e edge list,
forall_nodes : ('n node -> unit) -> unit,
forall_edges : ('e edge -> unit) -> unit
}
fun remove_all_edges (GRAPH G) (i,j) =
#set_out_edges G (i,List.filter (fn (_,k,_) => k = j) (#out_edges G i))
fun remove_all_edges' (GRAPH G) (i,j,p) =
#set_out_edges G (i,List.filter (fn (_,k,e) => k = j andalso p e)
(#out_edges G i))
fun remove_edge (GRAPH G) (i,j) =
let fun filter [] = []
| filter((e as (_,k,_))::es) =
if j = k then es else e::filter es
in #set_out_edges G (i,filter(#out_edges G i)) end
fun remove_edge' (GRAPH G) (i,j,p) =
let fun filter [] = []
| filter((e as (_,k,e'))::es) =
if j = k andalso p e' then es else e::filter es
in #set_out_edges G (i,filter(#out_edges G i)) end
end
|