9 sig |
9 sig |
10 type key |
10 type key |
11 type 'a T |
11 type 'a T |
12 exception UNDEFINED of key |
12 exception UNDEFINED of key |
13 val empty: 'a T |
13 val empty: 'a T |
14 val get_nodes: 'a T -> (key * 'a) list |
14 val keys: 'a T -> key list |
15 val map_nodes: ('a -> 'b) -> 'a T -> 'b T |
15 val map_nodes: ('a -> 'b) -> 'a T -> 'b T |
16 val get_node: 'a T -> key -> 'a |
16 val get_node: 'a T -> key -> 'a |
17 val map_node: key -> ('a -> 'a) -> 'a T -> 'a T |
17 val map_node: key -> ('a -> 'a) -> 'a T -> 'a T |
18 val imm_preds: 'a T -> key -> key list |
18 val imm_preds: 'a T -> key -> key list |
19 val imm_succs: 'a T -> key -> key list |
19 val imm_succs: 'a T -> key -> key list |
20 val all_preds: 'a T -> key list -> key list |
20 val all_preds: 'a T -> key list -> key list |
21 val all_succs: 'a T -> key list -> key list |
21 val all_succs: 'a T -> key list -> key list |
22 val find_paths: 'a T -> key * key -> key list list |
22 val find_paths: 'a T -> key * key -> key list list |
23 exception DUPLICATE of key |
23 exception DUPLICATE of key |
24 val new_node: key * 'a -> 'a T -> 'a T |
24 val new_node: key * 'a -> 'a T -> 'a T |
|
25 val del_nodes: key list -> 'a T -> 'a T |
25 val add_edge: key * key -> 'a T -> 'a T |
26 val add_edge: key * key -> 'a T -> 'a T |
26 val del_edge: key * key -> 'a T -> 'a T |
27 val del_edge: key * key -> 'a T -> 'a T |
27 exception CYCLES of key list list |
28 exception CYCLES of key list list |
28 val add_edge_acyclic: key * key -> 'a T -> 'a T |
29 val add_edge_acyclic: key * key -> 'a T -> 'a T |
29 end; |
30 end; |
45 val op ins_key = gen_ins eq_key; |
46 val op ins_key = gen_ins eq_key; |
46 |
47 |
47 infix del_key; |
48 infix del_key; |
48 fun xs del_key x = if x mem_key xs then gen_rem eq_key (xs, x) else xs; |
49 fun xs del_key x = if x mem_key xs then gen_rem eq_key (xs, x) else xs; |
49 |
50 |
|
51 infix del_keys; |
|
52 val op del_keys = foldl (op del_key); |
|
53 |
50 |
54 |
51 (* tables and sets of keys *) |
55 (* tables and sets of keys *) |
52 |
56 |
53 structure Table = TableFun(Key); |
57 structure Table = TableFun(Key); |
54 type keys = unit Table.table; |
58 type keys = unit Table.table; |
59 fun x mem_keys tab = is_some (Table.lookup (tab: keys, x)); |
63 fun x mem_keys tab = is_some (Table.lookup (tab: keys, x)); |
60 |
64 |
61 infix ins_keys; |
65 infix ins_keys; |
62 fun x ins_keys tab = if x mem_keys tab then tab else Table.update ((x, ()), tab); |
66 fun x ins_keys tab = if x mem_keys tab then tab else Table.update ((x, ()), tab); |
63 |
67 |
64 fun dest_keys tab = rev (Table.foldl (fn (xs, (x, ())) => x :: xs) ([], tab: keys)); |
|
65 |
|
66 |
68 |
67 (* graphs *) |
69 (* graphs *) |
68 |
70 |
69 datatype 'a T = Graph of ('a * (key list * key list)) Table.table; |
71 datatype 'a T = Graph of ('a * (key list * key list)) Table.table; |
70 |
72 |
71 exception UNDEFINED of key; |
73 exception UNDEFINED of key; |
72 |
74 |
73 val empty = Graph Table.empty; |
75 val empty = Graph Table.empty; |
|
76 fun keys (Graph tab) = Table.keys tab; |
74 |
77 |
75 fun get_entry (Graph tab) x = |
78 fun get_entry (Graph tab) x = |
76 (case Table.lookup (tab, x) of |
79 (case Table.lookup (tab, x) of |
77 Some entry => entry |
80 Some entry => entry |
78 | None => raise UNDEFINED x); |
81 | None => raise UNDEFINED x); |
80 fun map_entry x f (G as Graph tab) = Graph (Table.update ((x, f (get_entry G x)), tab)); |
83 fun map_entry x f (G as Graph tab) = Graph (Table.update ((x, f (get_entry G x)), tab)); |
81 |
84 |
82 |
85 |
83 (* nodes *) |
86 (* nodes *) |
84 |
87 |
85 fun get_nodes (Graph tab) = |
|
86 rev (Table.foldl (fn (nodes, (x, (i, _))) => (x, i) :: nodes) ([], tab)); |
|
87 |
|
88 fun map_nodes f (Graph tab) = Graph (Table.map (fn (i, ps) => (f i, ps)) tab); |
88 fun map_nodes f (Graph tab) = Graph (Table.map (fn (i, ps) => (f i, ps)) tab); |
89 |
89 |
90 fun get_node G = #1 o get_entry G; |
90 fun get_node G = #1 o get_entry G; |
91 fun map_node x f = map_entry x (fn (i, ps) => (f i, ps)); |
91 fun map_node x f = map_entry x (fn (i, ps) => (f i, ps)); |
92 |
92 |
93 |
93 |
94 (* reachability *) |
94 (* reachability *) |
95 |
95 |
|
96 (*nodes reachable from xs -- topologically sorted for acyclic graphs*) |
96 fun reachable next xs = |
97 fun reachable next xs = |
97 let |
98 let |
98 fun reach (R, x) = |
99 fun reach ((rs, R), x) = |
99 if x mem_keys R then R |
100 if x mem_keys R then (rs, R) |
100 else reachs (x ins_keys R, next x) |
101 else apfst (cons x) (reachs ((rs, x ins_keys R), next x)) |
101 and reachs R_xs = foldl reach R_xs; |
102 and reachs R_xs = foldl reach R_xs; |
102 in reachs (empty_keys, xs) end; |
103 in reachs (([], empty_keys), xs) end; |
103 |
104 |
104 (*immediate*) |
105 (*immediate*) |
105 fun imm_preds G = #1 o #2 o get_entry G; |
106 fun imm_preds G = #1 o #2 o get_entry G; |
106 fun imm_succs G = #2 o #2 o get_entry G; |
107 fun imm_succs G = #2 o #2 o get_entry G; |
107 |
108 |
108 (*transitive*) |
109 (*transitive*) |
109 fun all_preds G = dest_keys o reachable (imm_preds G); |
110 fun all_preds G = #1 o reachable (imm_preds G); |
110 fun all_succs G = dest_keys o reachable (imm_succs G); |
111 fun all_succs G = #1 o reachable (imm_succs G); |
111 |
112 |
112 |
113 |
113 (* paths *) |
114 (* paths *) |
114 |
115 |
115 fun find_paths G (x, y) = |
116 fun find_paths G (x, y) = |
116 let |
117 let |
117 val X = reachable (imm_succs G) [x]; |
118 val (_, X) = reachable (imm_succs G) [x]; |
118 fun paths ps p = |
119 fun paths ps p = |
119 if eq_key (p, x) then [p :: ps] |
120 if eq_key (p, x) then [p :: ps] |
120 else flat (map (paths (p :: ps)) |
121 else flat (map (paths (p :: ps)) |
121 (filter (fn pp => pp mem_keys X andalso not (pp mem_key ps)) (imm_preds G p))); |
122 (filter (fn pp => pp mem_keys X andalso not (pp mem_key ps)) (imm_preds G p))); |
122 in get_entry G y; if y mem_keys X then (paths [] y) else [] end; |
123 in get_entry G y; if y mem_keys X then (paths [] y) else [] end; |
127 exception DUPLICATE of key; |
128 exception DUPLICATE of key; |
128 |
129 |
129 fun new_node (x, info) (Graph tab) = |
130 fun new_node (x, info) (Graph tab) = |
130 Graph (Table.update_new ((x, (info, ([], []))), tab) |
131 Graph (Table.update_new ((x, (info, ([], []))), tab) |
131 handle Table.DUP key => raise DUPLICATE key); |
132 handle Table.DUP key => raise DUPLICATE key); |
|
133 |
|
134 fun del_nodes xs (Graph tab) = |
|
135 let |
|
136 fun del (x, (i, (preds, succs))) = |
|
137 if x mem_key xs then None |
|
138 else Some (x, (i, (preds del_keys xs, succs del_keys xs))); |
|
139 in Graph (Table.make (mapfilter del (Table.dest tab))) end; |
132 |
140 |
133 |
141 |
134 fun add_edge (x, y) = |
142 fun add_edge (x, y) = |
135 map_entry x (fn (i, (preds, succs)) => (i, (preds, y ins_key succs))) o |
143 map_entry x (fn (i, (preds, succs)) => (i, (preds, y ins_key succs))) o |
136 map_entry y (fn (i, (preds, succs)) => (i, (x ins_key preds, succs))); |
144 map_entry y (fn (i, (preds, succs)) => (i, (x ins_key preds, succs))); |