Browse Source

Added detour/3 and reroute/2 to flow_graph.

Paul Downen 14 years ago
parent
commit
135ba56809
1 changed files with 24 additions and 8 deletions
  1. 24 8
      src/flow_graph.erl

+ 24 - 8
src/flow_graph.erl

@@ -10,6 +10,8 @@
 -export([append/2, append/1, get_in/1, get_out/1, out_edges/2]).
 % Checks for validity
 -export([valid_edge/1, valid_edge_list/1, valid_graph/1]).
+% Branching
+-export([detour/3, reroute/2]).
 
 % Use the orddict module for clarity, and the dict module for speed.
 -define(DICT, orddict).
@@ -106,17 +108,16 @@ from_list(In = #vertex{}, Out = #vertex{}, Edges) ->
     FG = lists:foldl(fun(E, G) -> add_edge(G, E) end,
 		     #flow_graph{in=In, out=Out, graph=?DICT:new()},
 		     Edges),
-    G2 = ?DICT:update(Out, fun(X)->X end, [], FG#flow_graph.graph),
-    FG#flow_graph{graph=G2}.
+    FG#flow_graph{graph=add_vertex(FG#flow_graph.graph, Out)}.
 
 %% Graph manipulation
 
-append(FG1 = #flow_graph{in=In1, out=Out1},
-       FG2 = #flow_graph{in=In2, out=Out2}) ->
-    G = ?DICT:merge(fun(_, E1, E2) -> lists:append(E1,E2) end,
-		      FG1#flow_graph.graph,
-		      FG2#flow_graph.graph),
-    add_edge(#flow_graph{in=In1, out=Out2, graph=G},
+merge_graphs(G1, G2) ->
+    ?DICT:merge(fun(_, E1, E2) -> lists:append(E1,E2) end, G1, G2).
+
+append(#flow_graph{in=In1, out=Out1, graph=G1},
+       #flow_graph{in=In2, out=Out2, graph=G2}) ->
+    add_edge(#flow_graph{in=In1, out=Out2, graph=merge_graphs(G1,G2)},
 	     flow(Out1, In2)).
 
 append([FG1|FGs]) ->
@@ -133,6 +134,9 @@ add_edge(FG = #flow_graph{graph=G}, E = #edge{from=From}) ->
     Add = fun(Edges) -> [E|Edges] end,
     FG#flow_graph{graph=?DICT:update(From, Add, [E], G)}.
 
+add_vertex(FG = #flow_graph{graph=G}, V = #vertex{}) ->
+    FG#flow_graph{graph=?DICT:update(V, fun(Es)->Es end, [], G)}.
+
 % Checks for validity
 valid_edge(#edge{from=From, to=To, through=Through}) ->
     IsNeutral = fun(flow)       -> true;
@@ -178,3 +182,15 @@ valid_edge_list(Edges) ->
 valid_graph(#flow_graph{graph=G}) ->
     lists:all(fun({_, Es}) -> valid_edge_list(Es) end,
 	      ?DICT:to_list(G)).
+
+% Branching
+detour(From = #flow_graph{out=FOut, graph=FG},
+       _Between = #flow_graph{in=BIn, out=BOut, graph=BG},
+       _To = #flow_graph{in=TIn}) ->
+    G = add_edge(add_edge(merge_graphs(FG,BG), flow(FOut, BIn)),
+		 flow(BOut, TIn)),
+    From#flow_graph{graph=G}.
+
+reroute(#flow_graph{in=In1, graph=G1},
+	#flow_graph{out=Out2, graph=G2}) ->
+    #flow_graph{in=In1, out=Out2, graph=merge_graphs(G1, G2)}.