Current section
Files
Jump to
Current section
Files
lib/edge.ex
defmodule BitGraph.E do
alias BitGraph.V
defstruct from: nil,
to: nil,
opts: []
@type t :: %__MODULE__{
from: any(),
to: any(),
opts: Keyword.t()
}
alias BitGraph.Adjacency
alias Iter.Iterable
def init_edges(_opts) do
Map.new()
end
def new(from, to, opts \\ []) do
%__MODULE__{
from: from,
to: to,
opts: opts
}
end
def add_edge(graph, from, to) when is_integer(from) and is_integer(to) do
Adjacency.set(graph[:adjacency], from, to)
end
def edge?(graph, from, to) when is_integer(from) and is_integer(to) do
Adjacency.get(graph[:adjacency], from, to) == 1
end
def get_edge(%{edges: edges} = _graph, from, to) when is_integer(from) and is_integer(to) do
Map.get(edges, {from, to}, new(from, to))
end
def edges(graph) do
graph
|> BitGraph.vertices()
|> Enum.reduce(MapSet.new(), fn v, acc -> MapSet.union(acc, BitGraph.out_edges(graph, v)) end)
end
def in_edges(graph, to, opts \\ []) do
Iterable.map(V.in_neighbors(graph, to, opts),
fn neighbor -> get_edge(graph, neighbor, to) end
)
end
def out_edges(graph, from, opts \\ []) do
Iterable.map(V.out_neighbors(graph, from, opts),
fn neighbor -> get_edge(graph, from, neighbor) end
)
end
def edges(graph, vertex, opts \\ []) do
Iterable.concat(
[
in_edges(graph, vertex, opts),
out_edges(graph, vertex, opts)
]
)
end
def delete_edge(%{adjacency: %{bit_vector: false}} = graph, _from, _to) do
graph
end
def delete_edge(%{adjacency: adjacency, edges: edges} = graph, from, to) when is_integer(from) and is_integer(to) do
Adjacency.clear(adjacency, from, to)
edges
|> Map.delete({from, to})
|> then(fn updated_edges -> Map.put(graph, :edges, updated_edges) end)
end
def delete_edges(%{adjacency: %{bit_vector: false}} = graph, _vertex) do
graph
end
def delete_edges(%{adjacency: adjacency} = graph, vertex) when is_integer(vertex) do
Enum.reduce(Adjacency.row(adjacency, vertex), graph, fn out_neighbor, acc ->
delete_edge(acc, vertex, out_neighbor)
end)
|> then(fn graph ->
Enum.reduce(Adjacency.column(adjacency, vertex), graph, fn in_neighbor, acc ->
delete_edge(acc, in_neighbor, vertex)
end)
end)
end
end