5 *) |
5 *) |
6 |
6 |
7 signature GRAPH = |
7 signature GRAPH = |
8 sig |
8 sig |
9 type key |
9 type key |
|
10 structure Keys: |
|
11 sig |
|
12 type T |
|
13 val is_empty: T -> bool |
|
14 val fold: (key -> 'a -> 'a) -> T -> 'a -> 'a |
|
15 val fold_rev: (key -> 'a -> 'a) -> T -> 'a -> 'a |
|
16 val dest: T -> key list |
|
17 end |
10 type 'a T |
18 type 'a T |
11 exception DUP of key |
19 exception DUP of key |
12 exception SAME |
20 exception SAME |
13 exception UNDEF of key |
21 exception UNDEF of key |
14 val empty: 'a T |
22 val empty: 'a T |
15 val is_empty: 'a T -> bool |
23 val is_empty: 'a T -> bool |
16 val keys: 'a T -> key list |
24 val keys: 'a T -> key list |
17 val dest: 'a T -> (key * key list) list |
25 val dest: 'a T -> (key * key list) list |
18 val get_first: (key * ('a * (key list * key list)) -> 'b option) -> 'a T -> 'b option |
26 val get_first: (key * ('a * (Keys.T * Keys.T)) -> 'b option) -> 'a T -> 'b option |
19 val fold: (key * ('a * (key list * key list)) -> 'b -> 'b) -> 'a T -> 'b -> 'b |
27 val fold: (key * ('a * (Keys.T * Keys.T)) -> 'b -> 'b) -> 'a T -> 'b -> 'b |
20 val minimals: 'a T -> key list |
|
21 val maximals: 'a T -> key list |
|
22 val subgraph: (key -> bool) -> 'a T -> 'a T |
28 val subgraph: (key -> bool) -> 'a T -> 'a T |
23 val get_entry: 'a T -> key -> key * ('a * (key list * key list)) (*exception UNDEF*) |
29 val get_entry: 'a T -> key -> key * ('a * (Keys.T * Keys.T)) (*exception UNDEF*) |
24 val map: (key -> 'a -> 'b) -> 'a T -> 'b T |
30 val map: (key -> 'a -> 'b) -> 'a T -> 'b T |
25 val get_node: 'a T -> key -> 'a (*exception UNDEF*) |
31 val get_node: 'a T -> key -> 'a (*exception UNDEF*) |
26 val map_node: key -> ('a -> 'a) -> 'a T -> 'a T |
32 val map_node: key -> ('a -> 'a) -> 'a T -> 'a T |
27 val map_node_yield: key -> ('a -> 'b * 'a) -> 'a T -> 'b * 'a T |
33 val map_node_yield: key -> ('a -> 'b * 'a) -> 'a T -> 'b * 'a T |
28 val imm_preds: 'a T -> key -> key list |
34 val imm_preds: 'a T -> key -> Keys.T |
29 val imm_succs: 'a T -> key -> key list |
35 val imm_succs: 'a T -> key -> Keys.T |
|
36 val immediate_preds: 'a T -> key -> key list |
|
37 val immediate_succs: 'a T -> key -> key list |
30 val all_preds: 'a T -> key list -> key list |
38 val all_preds: 'a T -> key list -> key list |
31 val all_succs: 'a T -> key list -> key list |
39 val all_succs: 'a T -> key list -> key list |
|
40 val minimals: 'a T -> key list |
|
41 val maximals: 'a T -> key list |
|
42 val is_minimal: 'a T -> key -> bool |
|
43 val is_maximal: 'a T -> key -> bool |
32 val strong_conn: 'a T -> key list list |
44 val strong_conn: 'a T -> key list list |
33 val new_node: key * 'a -> 'a T -> 'a T (*exception DUP*) |
45 val new_node: key * 'a -> 'a T -> 'a T (*exception DUP*) |
34 val default_node: key * 'a -> 'a T -> 'a T |
46 val default_node: key * 'a -> 'a T -> 'a T |
35 val del_nodes: key list -> 'a T -> 'a T (*exception UNDEF*) |
47 val del_nodes: key list -> 'a T -> 'a T (*exception UNDEF*) |
36 val del_node: key -> 'a T -> 'a T (*exception UNDEF*) |
48 val del_node: key -> 'a T -> 'a T (*exception UNDEF*) |
57 struct |
69 struct |
58 |
70 |
59 (* keys *) |
71 (* keys *) |
60 |
72 |
61 type key = Key.key; |
73 type key = Key.key; |
62 |
|
63 val eq_key = is_equal o Key.ord; |
74 val eq_key = is_equal o Key.ord; |
64 |
75 |
65 val member_key = member eq_key; |
|
66 val remove_key = remove eq_key; |
|
67 |
|
68 |
|
69 (* tables and sets of keys *) |
|
70 |
|
71 structure Table = Table(Key); |
76 structure Table = Table(Key); |
72 type keys = unit Table.table; |
77 |
73 |
78 structure Keys = |
74 val empty_keys = Table.empty: keys; |
79 struct |
75 |
80 |
76 fun member_keys tab = Table.defined (tab: keys); |
81 abstype T = Keys of unit Table.table |
77 fun insert_keys x tab = Table.insert (K true) (x, ()) (tab: keys); |
82 with |
|
83 |
|
84 val empty = Keys Table.empty; |
|
85 fun is_empty (Keys tab) = Table.is_empty tab; |
|
86 |
|
87 fun member (Keys tab) = Table.defined tab; |
|
88 fun insert x (Keys tab) = Keys (Table.insert (K true) (x, ()) tab); |
|
89 fun remove x (Keys tab) = Keys (Table.delete_safe x tab); |
|
90 |
|
91 fun fold f (Keys tab) = Table.fold (f o #1) tab; |
|
92 fun fold_rev f (Keys tab) = Table.fold_rev (f o #1) tab; |
|
93 |
|
94 fun make xs = Basics.fold insert xs empty; |
|
95 fun dest keys = fold_rev cons keys []; |
|
96 |
|
97 fun filter P keys = fold (fn x => P x ? insert x) keys empty; |
|
98 |
|
99 end; |
|
100 end; |
78 |
101 |
79 |
102 |
80 (* graphs *) |
103 (* graphs *) |
81 |
104 |
82 datatype 'a T = Graph of ('a * (key list * key list)) Table.table; |
105 datatype 'a T = Graph of ('a * (Keys.T * Keys.T)) Table.table; |
83 |
106 |
84 exception DUP = Table.DUP; |
107 exception DUP = Table.DUP; |
85 exception UNDEF = Table.UNDEF; |
108 exception UNDEF = Table.UNDEF; |
86 exception SAME = Table.SAME; |
109 exception SAME = Table.SAME; |
87 |
110 |
88 val empty = Graph Table.empty; |
111 val empty = Graph Table.empty; |
89 fun is_empty (Graph tab) = Table.is_empty tab; |
112 fun is_empty (Graph tab) = Table.is_empty tab; |
90 fun keys (Graph tab) = Table.keys tab; |
113 fun keys (Graph tab) = Table.keys tab; |
91 fun dest (Graph tab) = map (fn (x, (_, (_, succs))) => (x, succs)) (Table.dest tab); |
114 fun dest (Graph tab) = map (fn (x, (_, (_, succs))) => (x, Keys.dest succs)) (Table.dest tab); |
92 |
115 |
93 fun get_first f (Graph tab) = Table.get_first f tab; |
116 fun get_first f (Graph tab) = Table.get_first f tab; |
94 fun fold_graph f (Graph tab) = Table.fold f tab; |
117 fun fold_graph f (Graph tab) = Table.fold f tab; |
95 |
118 |
96 fun minimals G = fold_graph (fn (m, (_, ([], _))) => cons m | _ => I) G []; |
|
97 fun maximals G = fold_graph (fn (m, (_, (_, []))) => cons m | _ => I) G []; |
|
98 |
|
99 fun subgraph P G = |
119 fun subgraph P G = |
100 let |
120 let |
101 fun subg (k, (i, (preds, succs))) = |
121 fun subg (k, (i, (preds, succs))) = |
102 if P k then Table.update (k, (i, (filter P preds, filter P succs))) else I; |
122 if P k then Table.update (k, (i, (Keys.filter P preds, Keys.filter P succs))) |
|
123 else I; |
103 in Graph (fold_graph subg G Table.empty) end; |
124 in Graph (fold_graph subg G Table.empty) end; |
104 |
125 |
105 fun get_entry (Graph tab) x = |
126 fun get_entry (Graph tab) x = |
106 (case Table.lookup_key tab x of |
127 (case Table.lookup_key tab x of |
107 SOME entry => entry |
128 SOME entry => entry |
130 |
151 |
131 (*nodes reachable from xs -- topologically sorted for acyclic graphs*) |
152 (*nodes reachable from xs -- topologically sorted for acyclic graphs*) |
132 fun reachable next xs = |
153 fun reachable next xs = |
133 let |
154 let |
134 fun reach x (rs, R) = |
155 fun reach x (rs, R) = |
135 if member_keys R x then (rs, R) |
156 if Keys.member R x then (rs, R) |
136 else fold reach (next x) (rs, insert_keys x R) |>> cons x; |
157 else Keys.fold reach (next x) (rs, Keys.insert x R) |>> cons x; |
137 fun reachs x (rss, R) = |
158 fun reachs x (rss, R) = |
138 reach x ([], R) |>> (fn rs => rs :: rss); |
159 reach x ([], R) |>> (fn rs => rs :: rss); |
139 in fold reachs xs ([], empty_keys) end; |
160 in fold reachs xs ([], Keys.empty) end; |
140 |
161 |
141 (*immediate*) |
162 (*immediate*) |
142 fun imm_preds G = #1 o #2 o #2 o get_entry G; |
163 fun imm_preds G = #1 o #2 o #2 o get_entry G; |
143 fun imm_succs G = #2 o #2 o #2 o get_entry G; |
164 fun imm_succs G = #2 o #2 o #2 o get_entry G; |
144 |
165 |
|
166 fun immediate_preds G = Keys.dest o imm_preds G; |
|
167 fun immediate_succs G = Keys.dest o imm_succs G; |
|
168 |
145 (*transitive*) |
169 (*transitive*) |
146 fun all_preds G = flat o #1 o reachable (imm_preds G); |
170 fun all_preds G = flat o #1 o reachable (imm_preds G); |
147 fun all_succs G = flat o #1 o reachable (imm_succs G); |
171 fun all_succs G = flat o #1 o reachable (imm_succs G); |
|
172 |
|
173 (*minimal and maximal elements*) |
|
174 fun minimals G = fold_graph (fn (m, (_, (preds, _))) => Keys.is_empty preds ? cons m) G []; |
|
175 fun maximals G = fold_graph (fn (m, (_, (_, succs))) => Keys.is_empty succs ? cons m) G []; |
|
176 fun is_minimal G x = Keys.is_empty (imm_preds G x); |
|
177 fun is_maximal G x = Keys.is_empty (imm_succs G x); |
148 |
178 |
149 (*strongly connected components; see: David King and John Launchbury, |
179 (*strongly connected components; see: David King and John Launchbury, |
150 "Structuring Depth First Search Algorithms in Haskell"*) |
180 "Structuring Depth First Search Algorithms in Haskell"*) |
151 fun strong_conn G = |
181 fun strong_conn G = |
152 rev (filter_out null (#1 (reachable (imm_preds G) (all_succs G (keys G))))); |
182 rev (filter_out null (#1 (reachable (imm_preds G) (all_succs G (keys G))))); |
153 |
183 |
154 |
184 |
155 (* nodes *) |
185 (* nodes *) |
156 |
186 |
157 fun new_node (x, info) (Graph tab) = |
187 fun new_node (x, info) (Graph tab) = |
158 Graph (Table.update_new (x, (info, ([], []))) tab); |
188 Graph (Table.update_new (x, (info, (Keys.empty, Keys.empty))) tab); |
159 |
189 |
160 fun default_node (x, info) (Graph tab) = |
190 fun default_node (x, info) (Graph tab) = |
161 Graph (Table.default (x, (info, ([], []))) tab); |
191 Graph (Table.default (x, (info, (Keys.empty, Keys.empty))) tab); |
162 |
192 |
163 fun del_nodes xs (Graph tab) = |
193 fun del_nodes xs (Graph tab) = |
164 Graph (tab |
194 Graph (tab |
165 |> fold Table.delete xs |
195 |> fold Table.delete xs |
166 |> Table.map (fn _ => fn (i, (preds, succs)) => |
196 |> Table.map (fn _ => fn (i, (preds, succs)) => |
167 (i, (fold remove_key xs preds, fold remove_key xs succs)))); |
197 (i, (fold Keys.remove xs preds, fold Keys.remove xs succs)))); |
168 |
198 |
169 fun del_node x (G as Graph tab) = |
199 fun del_node x (G as Graph tab) = |
170 let |
200 let |
171 fun del_adjacent which y = Table.map_entry y (fn (i, ps) => (i, (which (remove_key x) ps))); |
201 fun del_adjacent which y = |
|
202 Table.map_entry y (fn (i, ps) => (i, (which (Keys.remove x) ps))); |
172 val (preds, succs) = #2 (#2 (get_entry G x)); |
203 val (preds, succs) = #2 (#2 (get_entry G x)); |
173 in |
204 in |
174 Graph (tab |
205 Graph (tab |
175 |> Table.delete x |
206 |> Table.delete x |
176 |> fold (del_adjacent apsnd) preds |
207 |> Keys.fold (del_adjacent apsnd) preds |
177 |> fold (del_adjacent apfst) succs) |
208 |> Keys.fold (del_adjacent apfst) succs) |
178 end; |
209 end; |
179 |
210 |
180 |
211 |
181 (* edges *) |
212 (* edges *) |
182 |
213 |
183 fun is_edge G (x, y) = member_key (imm_succs G x) y handle UNDEF _ => false; |
214 fun is_edge G (x, y) = Keys.member (imm_succs G x) y handle UNDEF _ => false; |
184 |
215 |
185 fun add_edge (x, y) G = |
216 fun add_edge (x, y) G = |
186 if is_edge G (x, y) then G |
217 if is_edge G (x, y) then G |
187 else |
218 else |
188 G |> map_entry y (fn (i, (preds, succs)) => (i, (x :: preds, succs))) |
219 G |> map_entry y (fn (i, (preds, succs)) => (i, (Keys.insert x preds, succs))) |
189 |> map_entry x (fn (i, (preds, succs)) => (i, (preds, y :: succs))); |
220 |> map_entry x (fn (i, (preds, succs)) => (i, (preds, Keys.insert y succs))); |
190 |
221 |
191 fun del_edge (x, y) G = |
222 fun del_edge (x, y) G = |
192 if is_edge G (x, y) then |
223 if is_edge G (x, y) then |
193 G |> map_entry y (fn (i, (preds, succs)) => (i, (remove_key x preds, succs))) |
224 G |> map_entry y (fn (i, (preds, succs)) => (i, (Keys.remove x preds, succs))) |
194 |> map_entry x (fn (i, (preds, succs)) => (i, (preds, remove_key y succs))) |
225 |> map_entry x (fn (i, (preds, succs)) => (i, (preds, Keys.remove y succs))) |
195 else G; |
226 else G; |
196 |
227 |
197 fun diff_edges G1 G2 = |
228 fun diff_edges G1 G2 = |
198 flat (dest G1 |> map (fn (x, ys) => ys |> map_filter (fn y => |
229 flat (dest G1 |> map (fn (x, ys) => ys |> map_filter (fn y => |
199 if is_edge G2 (x, y) then NONE else SOME (x, y)))); |
230 if is_edge G2 (x, y) then NONE else SOME (x, y)))); |