bitwalker / libgraph

A graph data structure library for Elixir projects
MIT License
524 stars 75 forks source link

Graph.delete_vertex/2 does not remove references in `in_edges` #17

Closed zyqxd closed 6 years ago

zyqxd commented 6 years ago

Given

graph =
  Graph.new
  |> Graph.add_vertices([1, 2, 4, 6])
  |> Graph.add_edge(1, 2)
  |> Graph.add_edge(2, 4)
  |> Graph.add_edge(4, 6)

graph_two = 
  graph
  |> Graph.add_vertices([3, 5, 7])
  |> Graph.add_edge(1, 3)
  |> Graph.add_edge(3, 4)
  |> Graph.add_edge(3, 5)
  |> Graph.add_edge(5, 6)
  |> Graph.add_edge(5, 7)

Test

assert graph == Graph.delete_vertices(graph_two, [3, 5, 7])
# The result is false

Inspect

Map.from_struct graph_two
%{
  edges: %{
    {539485162, 2577631668} => %{nil: 1},
    {1379807339, 3239926044} => %{nil: 1},
    {2577631668, 1379807339} => %{nil: 1}
  },
  in_edges: %{
    1379807339 => #MapSet<[1186525603, 2577631668]>,  #1186525603 dangling reference
    2577631668 => #MapSet<[539485162]>,
    3239926044 => #MapSet<[676967202, 1379807339]> #676967202 dangling reference
  },
  out_edges: %{
    539485162 => #MapSet<[2577631668]>,
    1379807339 => #MapSet<[3239926044]>,
    2577631668 => #MapSet<[1379807339]>
  },
  type: :directed,
  vertex_labels: %{
    539485162 => [],
    1379807339 => [],
    2577631668 => [],
    3239926044 => []
  },
  vertices: %{539485162 => 1, 1379807339 => 4, 2577631668 => 2, 3239926044 => 6}
}

These dangling references also raises nil enumeration errors when performing future operations.

Offending line

Graph.delete_vertex/2 is missing comprehension for in edges

Fix is to add

ie = for {id, ns} <- ie, do: {id, MapSet.delete(ns, v_id)}, into: %{}
aquarhead commented 6 years ago

Just encountered this as well... @itsdeezy can you make a PR? Confirmed your fix works for me :)

bitwalker commented 6 years ago

Fixed in master