anchor.diff:  
   is_edge_error(_) ->
       false.
  +
  +%% @doc Delete all edges between Src and Dst with the given label.
  +-spec delete_with_label(digraph:graph(), id(), id(), term()) -> digraph:graph().
  +delete_with_label(Graph, Src, Dst, Label) ->
  +  lists:filtermap(fun
  +                    ({E, _, _, L}) when L =:= Label -> {true, digraph:del_edge(Graph, E)};
  +                    (_) -> false
  +                  end, get_direct_edges(Graph, Src, Dst)),
  +  Graph.
  +
  +%% @doc Return all direct edges linking V1 and V2.
  +%%
  +%%      If V1 and V2 are not linked, return the empty list.
  +%%
  +%%      Otherwise, get all emanating edges from V1, and return
  +%%      only the ones linking to V2.
  +%%
  +-spec get_direct_edges(digraph:graph(),
  +    digraph:vertex(), digraph:vertex()) -> list(edge()).
  +
  +get_direct_edges(G, V1, V2) ->
  +  case directly_connected(G, V1, V2) of
  +    false -> [];
  +    true ->
  +      lists:flatmap(fun(Ed) ->
  +        case digraph:edge(G, Ed) of
  +          {_, _, To, _}=E when To =:= V2 -> [E];
  +          _ -> []
  +        end
  +                    end, digraph:out_edges(G, V1))
  +  end.
  +
  +%% @doc Are V1 and V2 linked directly?
  +%%
  +%%      digraph:get_short_path/3 returns a list of vertices if V1 and V2
  +%%      are connected, false otherwise.
  +%%
  +%%      If they are linked directly, this vertex list will only contain V1
  +%%      and V2.
  +%%
  +-spec directly_connected(digraph:graph(),
  +    digraph:vertex(), digraph:vertex()) -> boolean().
  +
  +directly_connected(G, V1, V2) ->
  +  case digraph:get_short_path(G, V1, V2) of
  +    [V1, V2] -> true;
  +    _        -> false
  +  end.
   
   to_dot(Graph) ->
       Start = ["digraph dag {\n"],
  
positive.code: %%% Type definitions
  %%%===================================================================
  
  -record(state, {dag :: digraph:graph()}).
  
  %%%===================================================================
  %%% API
  
negative.code:     {reply, Response, State};
  
  %% @doc For all V in Src, create an edge from V to Dst labelled with Pid.
  %%
  %%      We monitor all edge Pids to know when they die or get restarted.
  %%
  handle_call({add_edges, Src, Dst, Pid}, _From, #state{dag=Dag, process_map=Pm}=State) ->
      %% @todo Add metadata and duplicate checking.
      Status = [digraph:add_edge(Dag, V, Dst, Pid) || V <- Src],
      {R, St} = case lists:any(fun is_graph_error/1, Status) of
          true -> {error, State};
          false ->
              erlang:monitor(process, Pid),
              {ok, State#state{process_map=lists:foldl(fun(El, D) ->
                  dict:append(Pid, {El, Dst}, D)
              end, Pm, Src)}}
      end,
      {reply, R, St}.
  
  %% @private
  -spec handle_cast(term(), #state{}) -> {noreply, #state{}}.
  