31 |
31 |
32 def make[Key, A](entries: List[((Key, A), List[Key])], |
32 def make[Key, A](entries: List[((Key, A), List[Key])], |
33 symmetric: Boolean = false)(implicit ord: Ordering[Key]): Graph[Key, A] = |
33 symmetric: Boolean = false)(implicit ord: Ordering[Key]): Graph[Key, A] = |
34 { |
34 { |
35 val graph1 = |
35 val graph1 = |
36 (empty[Key, A](ord) /: entries) { case (graph, ((x, info), _)) => graph.new_node(x, info) } |
36 entries.foldLeft(empty[Key, A](ord)) { |
|
37 case (graph, ((x, info), _)) => graph.new_node(x, info) |
|
38 } |
37 val graph2 = |
39 val graph2 = |
38 (graph1 /: entries) { case (graph, ((x, _), ys)) => |
40 entries.foldLeft(graph1) { |
39 (graph /: ys)({ case (g, y) => if (symmetric) g.add_edge(y, x) else g.add_edge(x, y) }) } |
41 case (graph, ((x, _), ys)) => |
|
42 ys.foldLeft(graph) { |
|
43 case (g, y) => if (symmetric) g.add_edge(y, x) else g.add_edge(x, y) |
|
44 } |
|
45 } |
40 graph2 |
46 graph2 |
41 } |
47 } |
42 |
48 |
43 def string[A]: Graph[String, A] = empty(Ordering.String) |
49 def string[A]: Graph[String, A] = empty(Ordering.String) |
44 def int[A]: Graph[Int, A] = empty(Ordering.Int) |
50 def int[A]: Graph[Int, A] = empty(Ordering.Int) |
117 next: Key => Keys, |
123 next: Key => Keys, |
118 xs: List[Key]): Map[Key, Long] = |
124 xs: List[Key]): Map[Key, Long] = |
119 { |
125 { |
120 def reach(length: Long)(rs: Map[Key, Long], x: Key): Map[Key, Long] = |
126 def reach(length: Long)(rs: Map[Key, Long], x: Key): Map[Key, Long] = |
121 if (rs.get(x) match { case Some(n) => n >= length case None => false }) rs |
127 if (rs.get(x) match { case Some(n) => n >= length case None => false }) rs |
122 else ((rs + (x -> length)) /: next(x))(reach(length + count(x))) |
128 else next(x).foldLeft(rs + (x -> length))(reach(length + count(x))) |
123 (Map.empty[Key, Long] /: xs)(reach(0)) |
129 xs.foldLeft(Map.empty[Key, Long])(reach(0)) |
124 } |
130 } |
125 def node_height(count: Key => Long): Map[Key, Long] = |
131 def node_height(count: Key => Long): Map[Key, Long] = |
126 reachable_length(count, imm_preds, maximals) |
132 reachable_length(count, imm_preds, maximals) |
127 def node_depth(count: Key => Long): Map[Key, Long] = |
133 def node_depth(count: Key => Long): Map[Key, Long] = |
128 reachable_length(count, imm_succs, minimals) |
134 reachable_length(count, imm_succs, minimals) |
136 { |
142 { |
137 def reach(res: (Long, Keys), x: Key): (Long, Keys) = |
143 def reach(res: (Long, Keys), x: Key): (Long, Keys) = |
138 { |
144 { |
139 val (n, rs) = res |
145 val (n, rs) = res |
140 if (rs.contains(x)) res |
146 if (rs.contains(x)) res |
141 else ((n + count(x), rs + x) /: next(x))(reach) |
147 else next(x).foldLeft((n + count(x), rs + x))(reach) |
142 } |
148 } |
143 |
149 |
144 @tailrec def reachs(size: Long, rs: Keys, rest: List[Key]): Keys = |
150 @tailrec def reachs(size: Long, rs: Keys, rest: List[Key]): Keys = |
145 rest match { |
151 rest match { |
146 case Nil => rs |
152 case Nil => rs |
160 { |
166 { |
161 val (rs, r_set) = reached |
167 val (rs, r_set) = reached |
162 if (r_set(x)) reached |
168 if (r_set(x)) reached |
163 else { |
169 else { |
164 val (rs1, r_set1) = |
170 val (rs1, r_set1) = |
165 if (rev) ((rs, r_set + x) /: next(x))({ case (b, a) => reach(a, b) }) |
171 if (rev) next(x).foldLeft((rs, r_set + x)) { case (b, a) => reach(a, b) } |
166 else (next(x) :\ (rs, r_set + x))(reach) |
172 else (next(x) :\ (rs, r_set + x))(reach) |
167 (x :: rs1, r_set1) |
173 (x :: rs1, r_set1) |
168 } |
174 } |
169 } |
175 } |
170 def reachs(reached: (List[List[Key]], Keys), x: Key): (List[List[Key]], Keys) = |
176 def reachs(reached: (List[List[Key]], Keys), x: Key): (List[List[Key]], Keys) = |
171 { |
177 { |
172 val (rss, r_set) = reached |
178 val (rss, r_set) = reached |
173 val (rs, r_set1) = reach(x, (Nil, r_set)) |
179 val (rs, r_set1) = reach(x, (Nil, r_set)) |
174 (rs :: rss, r_set1) |
180 (rs :: rss, r_set1) |
175 } |
181 } |
176 ((List.empty[List[Key]], empty_keys) /: xs)(reachs) |
182 xs.foldLeft((List.empty[List[Key]], empty_keys))(reachs) |
177 } |
183 } |
178 |
184 |
179 /*immediate*/ |
185 /*immediate*/ |
180 def imm_preds(x: Key): Keys = get_entry(x)._2._1 |
186 def imm_preds(x: Key): Keys = get_entry(x)._2._1 |
181 def imm_succs(x: Key): Keys = get_entry(x)._2._2 |
187 def imm_succs(x: Key): Keys = get_entry(x)._2._2 |
193 |
199 |
194 |
200 |
195 /* minimal and maximal elements */ |
201 /* minimal and maximal elements */ |
196 |
202 |
197 def minimals: List[Key] = |
203 def minimals: List[Key] = |
198 (List.empty[Key] /: rep) { |
204 rep.foldLeft(List.empty[Key]) { |
199 case (ms, (m, (_, (preds, _)))) => if (preds.isEmpty) m :: ms else ms } |
205 case (ms, (m, (_, (preds, _)))) => if (preds.isEmpty) m :: ms else ms |
|
206 } |
200 |
207 |
201 def maximals: List[Key] = |
208 def maximals: List[Key] = |
202 (List.empty[Key] /: rep) { |
209 rep.foldLeft(List.empty[Key]) { |
203 case (ms, (m, (_, (_, succs)))) => if (succs.isEmpty) m :: ms else ms } |
210 case (ms, (m, (_, (_, succs)))) => if (succs.isEmpty) m :: ms else ms |
|
211 } |
204 |
212 |
205 def is_minimal(x: Key): Boolean = imm_preds(x).isEmpty |
213 def is_minimal(x: Key): Boolean = imm_preds(x).isEmpty |
206 def is_maximal(x: Key): Boolean = imm_succs(x).isEmpty |
214 def is_maximal(x: Key): Boolean = imm_succs(x).isEmpty |
207 |
215 |
208 def is_isolated(x: Key): Boolean = is_minimal(x) && is_maximal(x) |
216 def is_isolated(x: Key): Boolean = is_minimal(x) && is_maximal(x) |
229 |
237 |
230 def del_node(x: Key): Graph[Key, A] = |
238 def del_node(x: Key): Graph[Key, A] = |
231 { |
239 { |
232 val (preds, succs) = get_entry(x)._2 |
240 val (preds, succs) = get_entry(x)._2 |
233 new Graph[Key, A]( |
241 new Graph[Key, A]( |
234 (((rep - x) /: preds)(del_adjacent(false, x)) /: succs)(del_adjacent(true, x))) |
242 succs.foldLeft(preds.foldLeft(rep - x)(del_adjacent(false, x)))(del_adjacent(true, x))) |
235 } |
243 } |
236 |
244 |
237 def restrict(pred: Key => Boolean): Graph[Key, A] = |
245 def restrict(pred: Key => Boolean): Graph[Key, A] = |
238 (this /: iterator){ case (graph, (x, _)) => if (!pred(x)) graph.del_node(x) else graph } |
246 iterator.foldLeft(this) { case (graph, (x, _)) => if (!pred(x)) graph.del_node(x) else graph } |
239 |
247 |
240 def exclude(pred: Key => Boolean): Graph[Key, A] = restrict(name => !pred(name)) |
248 def exclude(pred: Key => Boolean): Graph[Key, A] = restrict(name => !pred(name)) |
241 |
249 |
242 |
250 |
243 /* edge operations */ |
251 /* edge operations */ |
281 def irreducible_paths(x: Key, y: Key): List[List[Key]] = |
289 def irreducible_paths(x: Key, y: Key): List[List[Key]] = |
282 { |
290 { |
283 val (_, x_set) = reachable(imm_succs, List(x)) |
291 val (_, x_set) = reachable(imm_succs, List(x)) |
284 def paths(path: List[Key])(ps: List[List[Key]], z: Key): List[List[Key]] = |
292 def paths(path: List[Key])(ps: List[List[Key]], z: Key): List[List[Key]] = |
285 if (x == z) (z :: path) :: ps |
293 if (x == z) (z :: path) :: ps |
286 else (ps /: irreducible_preds(x_set, path, z))(paths(z :: path)) |
294 else irreducible_preds(x_set, path, z).foldLeft(ps)(paths(z :: path)) |
287 if ((x == y) && !is_edge(x, x)) List(Nil) else paths(Nil)(Nil, y) |
295 if ((x == y) && !is_edge(x, x)) List(Nil) else paths(Nil)(Nil, y) |
288 } |
296 } |
289 |
297 |
290 |
298 |
291 /* transitive closure and reduction */ |
299 /* transitive closure and reduction */ |
296 var graph = this |
304 var graph = this |
297 for (x <- preds; y <- succs) graph = graph.add_edge(x, y) |
305 for (x <- preds; y <- succs) graph = graph.add_edge(x, y) |
298 graph |
306 graph |
299 } |
307 } |
300 |
308 |
301 def transitive_closure: Graph[Key, A] = (this /: keys_iterator)(_.transitive_step(_)) |
309 def transitive_closure: Graph[Key, A] = keys_iterator.foldLeft(this)(_.transitive_step(_)) |
302 |
310 |
303 def transitive_reduction_acyclic: Graph[Key, A] = |
311 def transitive_reduction_acyclic: Graph[Key, A] = |
304 { |
312 { |
305 val trans = this.transitive_closure |
313 val trans = this.transitive_closure |
306 if (trans.iterator.exists({ case (x, (_, (_, succs))) => succs.contains(x) })) |
314 if (trans.iterator.exists({ case (x, (_, (_, succs))) => succs.contains(x) })) |
326 case cycles => throw new Graph.Cycles(cycles.map(x :: _)) |
334 case cycles => throw new Graph.Cycles(cycles.map(x :: _)) |
327 } |
335 } |
328 } |
336 } |
329 |
337 |
330 def add_deps_acyclic(y: Key, xs: List[Key]): Graph[Key, A] = |
338 def add_deps_acyclic(y: Key, xs: List[Key]): Graph[Key, A] = |
331 (this /: xs)(_.add_edge_acyclic(_, y)) |
339 xs.foldLeft(this)(_.add_edge_acyclic(_, y)) |
332 |
340 |
333 def topological_order: List[Key] = all_succs(minimals) |
341 def topological_order: List[Key] = all_succs(minimals) |
334 } |
342 } |