28 val imm_succs: 'a T -> key -> key list |
28 val imm_succs: 'a T -> key -> key list |
29 val all_preds: 'a T -> key list -> key list |
29 val all_preds: 'a T -> key list -> key list |
30 val all_succs: 'a T -> key list -> key list |
30 val all_succs: 'a T -> key list -> key list |
31 val strong_conn: 'a T -> key list list |
31 val strong_conn: 'a T -> key list list |
32 val subgraph: key list -> 'a T -> 'a T |
32 val subgraph: key list -> 'a T -> 'a T |
33 val find_paths: 'a T -> key * key -> key list list |
|
34 val new_node: key * 'a -> 'a T -> 'a T (*exception DUP*) |
33 val new_node: key * 'a -> 'a T -> 'a T (*exception DUP*) |
35 val default_node: key * 'a -> 'a T -> 'a T |
34 val default_node: key * 'a -> 'a T -> 'a T |
36 val del_nodes: key list -> 'a T -> 'a T (*exception UNDEF*) |
35 val del_nodes: key list -> 'a T -> 'a T (*exception UNDEF*) |
37 val is_edge: 'a T -> key * key -> bool |
36 val is_edge: 'a T -> key * key -> bool |
38 val add_edge: key * key -> 'a T -> 'a T |
37 val add_edge: key * key -> 'a T -> 'a T |
39 val del_edge: key * key -> 'a T -> 'a T |
38 val del_edge: key * key -> 'a T -> 'a T |
40 val merge: ('a * 'a -> bool) -> 'a T * 'a T -> 'a T (*exception DUPS*) |
39 val merge: ('a * 'a -> bool) -> 'a T * 'a T -> 'a T (*exception DUPS*) |
41 val join: (key -> 'a * 'a -> 'a) (*exception DUP/SAME*) -> |
40 val join: (key -> 'a * 'a -> 'a) (*exception DUP/SAME*) -> |
42 'a T * 'a T -> 'a T (*exception DUPS*) |
41 'a T * 'a T -> 'a T (*exception DUPS*) |
|
42 val irreducible_paths: 'a T -> key * key -> key list list |
43 exception CYCLES of key list list |
43 exception CYCLES of key list list |
44 val add_edge_acyclic: key * key -> 'a T -> 'a T (*exception CYCLES*) |
44 val add_edge_acyclic: key * key -> 'a T -> 'a T (*exception CYCLES*) |
45 val add_deps_acyclic: key * key list -> 'a T -> 'a T (*exception CYCLES*) |
45 val add_deps_acyclic: key * key list -> 'a T -> 'a T (*exception CYCLES*) |
46 val merge_acyclic: ('a * 'a -> bool) -> 'a T * 'a T -> 'a T (*exception CYCLES*) |
46 val merge_acyclic: ('a * 'a -> bool) -> 'a T * 'a T -> 'a T (*exception CYCLES*) |
47 val add_edge_trans_acyclic: key * key -> 'a T -> 'a T (*exception CYCLES*) |
47 val add_edge_trans_acyclic: key * key -> 'a T -> 'a T (*exception CYCLES*) |
147 fun subg (k, (i, (preds, succs))) = |
147 fun subg (k, (i, (preds, succs))) = |
148 K (select k) ? Table.update (k, (i, (filter select preds, filter select succs))); |
148 K (select k) ? Table.update (k, (i, (filter select preds, filter select succs))); |
149 in Table.empty |> Table.fold subg tab |> Graph end; |
149 in Table.empty |> Table.fold subg tab |> Graph end; |
150 |
150 |
151 |
151 |
152 (* paths *) |
|
153 |
|
154 fun find_paths G (x, y) = |
|
155 let |
|
156 val (_, X) = reachable (imm_succs G) [x]; |
|
157 fun paths ps p = |
|
158 if not (null ps) andalso eq_key (p, x) then [p :: ps] |
|
159 else if member_keys X p andalso not (member_key ps p) |
|
160 then maps (paths (p :: ps)) (imm_preds G p) |
|
161 else []; |
|
162 in paths [] y end; |
|
163 |
|
164 |
|
165 (* nodes *) |
152 (* nodes *) |
166 |
153 |
167 fun new_node (x, info) (Graph tab) = |
154 fun new_node (x, info) (Graph tab) = |
168 Graph (Table.update_new (x, (info, ([], []))) tab); |
155 Graph (Table.update_new (x, (info, ([], []))) tab); |
169 |
156 |
213 in fold add (edges G2) (Graph (Table.merge eq_node (tab1, Table.map no_edges tab2))) end; |
200 in fold add (edges G2) (Graph (Table.merge eq_node (tab1, Table.map no_edges tab2))) end; |
214 |
201 |
215 fun merge eq GG = gen_merge add_edge eq GG; |
202 fun merge eq GG = gen_merge add_edge eq GG; |
216 |
203 |
217 |
204 |
|
205 (* irreducible paths -- Hasse diagram *) |
|
206 |
|
207 fun irreducible_preds G X path z = |
|
208 let |
|
209 fun red x x' = is_edge G (x, x') andalso not (eq_key (x', z)); |
|
210 fun irreds [] xs' = xs' |
|
211 | irreds (x :: xs) xs' = |
|
212 if not (member_keys X x) orelse eq_key (x, z) orelse member_key path x orelse |
|
213 exists (red x) xs orelse exists (red x) xs' |
|
214 then irreds xs xs' |
|
215 else irreds xs (x :: xs'); |
|
216 in irreds (imm_preds G z) [] end; |
|
217 |
|
218 fun irreducible_paths G (x, y) = |
|
219 let |
|
220 val (_, X) = reachable (imm_succs G) [x]; |
|
221 fun paths path z = |
|
222 if eq_key (x, z) then cons (z :: path) |
|
223 else fold (paths (z :: path)) (irreducible_preds G X path z); |
|
224 in if eq_key (x, y) andalso not (is_edge G (x, x)) then [[]] else paths [] y [] end; |
|
225 |
|
226 |
218 (* maintain acyclic graphs *) |
227 (* maintain acyclic graphs *) |
219 |
228 |
220 exception CYCLES of key list list; |
229 exception CYCLES of key list list; |
221 |
230 |
222 fun add_edge_acyclic (x, y) G = |
231 fun add_edge_acyclic (x, y) G = |
223 if is_edge G (x, y) then G |
232 if is_edge G (x, y) then G |
224 else |
233 else |
225 (case find_paths G (y, x) of |
234 (case irreducible_paths G (y, x) of |
226 [] => add_edge (x, y) G |
235 [] => add_edge (x, y) G |
227 | cycles => raise CYCLES (map (cons x) cycles)); |
236 | cycles => raise CYCLES (map (cons x) cycles)); |
228 |
237 |
229 fun add_deps_acyclic (y, xs) = fold (fn x => add_edge_acyclic (x, y)) xs; |
238 fun add_deps_acyclic (y, xs) = fold (fn x => add_edge_acyclic (x, y)) xs; |
230 |
239 |