8 |
8 |
9 signature GRAPH = |
9 signature GRAPH = |
10 sig |
10 sig |
11 type key |
11 type key |
12 type 'a T |
12 type 'a T |
13 exception UNDEFINED of key |
13 exception UNDEF of key |
|
14 exception DUP of key |
|
15 exception DUPS of key list |
14 val empty: 'a T |
16 val empty: 'a T |
15 val keys: 'a T -> key list |
17 val keys: 'a T -> key list |
16 val map_nodes: ('a -> 'b) -> 'a T -> 'b T |
18 val map_nodes: ('a -> 'b) -> 'a T -> 'b T |
17 val get_node: 'a T -> key -> 'a |
19 val get_node: 'a T -> key -> 'a |
18 val map_node: key -> ('a -> 'a) -> 'a T -> 'a T |
20 val map_node: key -> ('a -> 'a) -> 'a T -> 'a T |
19 val imm_preds: 'a T -> key -> key list |
21 val imm_preds: 'a T -> key -> key list |
20 val imm_succs: 'a T -> key -> key list |
22 val imm_succs: 'a T -> key -> key list |
21 val all_preds: 'a T -> key list -> key list |
23 val all_preds: 'a T -> key list -> key list |
22 val all_succs: 'a T -> key list -> key list |
24 val all_succs: 'a T -> key list -> key list |
23 val find_paths: 'a T -> key * key -> key list list |
25 val find_paths: 'a T -> key * key -> key list list |
24 exception DUPLICATE of key |
|
25 val new_node: key * 'a -> 'a T -> 'a T |
26 val new_node: key * 'a -> 'a T -> 'a T |
26 val del_nodes: key list -> 'a T -> 'a T |
27 val del_nodes: key list -> 'a T -> 'a T |
|
28 val edges: 'a T -> (key * key) list |
27 val add_edge: key * key -> 'a T -> 'a T |
29 val add_edge: key * key -> 'a T -> 'a T |
28 val del_edge: key * key -> 'a T -> 'a T |
30 val del_edge: key * key -> 'a T -> 'a T |
29 exception CYCLES of key list list |
31 exception CYCLES of key list list |
30 val add_edge_acyclic: key * key -> 'a T -> 'a T |
32 val add_edge_acyclic: key * key -> 'a T -> 'a T |
|
33 val add_deps_acyclic: key * key list -> 'a T -> 'a T |
|
34 val merge_acyclic: ('a * 'a -> bool) -> 'a T * 'a T -> 'a T |
31 end; |
35 end; |
32 |
36 |
33 functor GraphFun(Key: KEY): GRAPH = |
37 functor GraphFun(Key: KEY): GRAPH = |
34 struct |
38 struct |
35 |
39 |
69 |
73 |
70 (* graphs *) |
74 (* graphs *) |
71 |
75 |
72 datatype 'a T = Graph of ('a * (key list * key list)) Table.table; |
76 datatype 'a T = Graph of ('a * (key list * key list)) Table.table; |
73 |
77 |
74 exception UNDEFINED of key; |
78 exception UNDEF of key; |
|
79 exception DUP = Table.DUP; |
|
80 exception DUPS = Table.DUPS; |
75 |
81 |
76 val empty = Graph Table.empty; |
82 val empty = Graph Table.empty; |
77 fun keys (Graph tab) = Table.keys tab; |
83 fun keys (Graph tab) = Table.keys tab; |
78 |
84 |
79 fun get_entry (Graph tab) x = |
85 fun get_entry (Graph tab) x = |
80 (case Table.lookup (tab, x) of |
86 (case Table.lookup (tab, x) of |
81 Some entry => entry |
87 Some entry => entry |
82 | None => raise UNDEFINED x); |
88 | None => raise UNDEF x); |
83 |
89 |
84 fun map_entry x f (G as Graph tab) = Graph (Table.update ((x, f (get_entry G x)), tab)); |
90 fun map_entry x f (G as Graph tab) = Graph (Table.update ((x, f (get_entry G x)), tab)); |
85 |
91 |
86 |
92 |
87 (* nodes *) |
93 (* nodes *) |
122 else flat (map (paths (p :: ps)) |
128 else flat (map (paths (p :: ps)) |
123 (filter (fn pp => pp mem_keys X andalso not (pp mem_key ps)) (imm_preds G p))); |
129 (filter (fn pp => pp mem_keys X andalso not (pp mem_key ps)) (imm_preds G p))); |
124 in get_entry G y; if y mem_keys X then (paths [] y) else [] end; |
130 in get_entry G y; if y mem_keys X then (paths [] y) else [] end; |
125 |
131 |
126 |
132 |
127 (* build graphs *) |
133 (* nodes *) |
128 |
134 |
129 exception DUPLICATE of key; |
135 exception DUPLICATE of key; |
130 |
136 |
131 fun new_node (x, info) (Graph tab) = |
137 fun new_node (x, info) (Graph tab) = |
132 Graph (Table.update_new ((x, (info, ([], []))), tab) |
138 Graph (Table.update_new ((x, (info, ([], []))), tab)); |
133 handle Table.DUP key => raise DUPLICATE key); |
|
134 |
139 |
135 fun del_nodes xs (Graph tab) = |
140 fun del_nodes xs (Graph tab) = |
136 let |
141 let |
137 fun del (x, (i, (preds, succs))) = |
142 fun del (x, (i, (preds, succs))) = |
138 if x mem_key xs then None |
143 if x mem_key xs then None |
139 else Some (x, (i, (preds del_keys xs, succs del_keys xs))); |
144 else Some (x, (i, (preds del_keys xs, succs del_keys xs))); |
140 in Graph (Table.make (mapfilter del (Table.dest tab))) end; |
145 in Graph (Table.make (mapfilter del (Table.dest tab))) end; |
141 |
146 |
|
147 |
|
148 (* edges *) |
|
149 |
|
150 fun edges (Graph tab) = |
|
151 flat (map (fn (x, (_, (_, succs))) => (map (pair x) succs)) (Table.dest tab)); |
142 |
152 |
143 fun add_edge (x, y) = |
153 fun add_edge (x, y) = |
144 map_entry x (fn (i, (preds, succs)) => (i, (preds, y ins_key succs))) o |
154 map_entry x (fn (i, (preds, succs)) => (i, (preds, y ins_key succs))) o |
145 map_entry y (fn (i, (preds, succs)) => (i, (x ins_key preds, succs))); |
155 map_entry y (fn (i, (preds, succs)) => (i, (x ins_key preds, succs))); |
146 |
156 |
154 fun add_edge_acyclic (x, y) G = |
164 fun add_edge_acyclic (x, y) G = |
155 (case find_paths G (y, x) of |
165 (case find_paths G (y, x) of |
156 [] => add_edge (x, y) G |
166 [] => add_edge (x, y) G |
157 | cycles => raise CYCLES (map (cons x) cycles)); |
167 | cycles => raise CYCLES (map (cons x) cycles)); |
158 |
168 |
|
169 fun add_deps_acyclic (y, xs) G = |
|
170 foldl (fn (H, x) => add_edge_acyclic (x, y) H) (G, xs); |
|
171 |
|
172 |
|
173 (* merge_acyclic *) |
|
174 |
|
175 fun merge_acyclic eq (Graph tab1, G2 as Graph tab2) = |
|
176 foldl (fn (G, xy) => add_edge_acyclic xy G) |
|
177 (Graph (Table.merge (fn ((i1, _), (i2, _)) => eq (i1, i2)) (tab1, tab2)), edges G2); |
|
178 |
159 |
179 |
160 end; |
180 end; |
161 |
181 |
162 |
182 |
163 (*graphs indexed by strings*) |
183 (*graphs indexed by strings*) |