Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,20 @@ julia> Networks.link!(g, :b, 1);
julia> Networks.link!(g, :c, 1);
```

In order to query the vertices connected by an edge, use `edge_incidents`:
In order to query the vertices connected by an edge, use `incident_vertices`:

```julia
julia> edge_incidents(g, 1)
julia> incident_vertices(g, 1)
Set{Symbol} with 3 elements:
:a
:b
:c
```

... and to query the edges connected to a vertex, use `vertex_incidents`:
... and to query the edges connected to a vertex, use `incident_edges`:

```julia
julia> vertex_incidents(g, :a)
julia> incident_edges(g, :a)
Set{Int64} with 1 element:
1
```
8 changes: 4 additions & 4 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ Networks.link!(g, :b, 1)
Networks.link!(g, :c, 1)
```

In order to query the vertices connected by an edge, use `edge_incidents`:
In order to query the vertices connected by an edge, use `incident_vertices`:

```@repl example
edge_incidents(g, 1)
incident_vertices(g, 1)
```

... and to query the edges connected to a vertex, use `edge_incidents`:
... and to query the edges connected to a vertex, use `incident_vertices`:

```@repl example
vertex_incidents(g, :a)
incident_edges(g, :a)
```
37 changes: 28 additions & 9 deletions docs/src/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,19 @@ Using [`DelegatorTraits.jl`](https://github.com/bsc-quantic/DelegatorTraits.jl)

## Network

The `Network` interface abstracts a network or graph as a bipartite graph whose sets are the vertices and the edges.
The `Network` interface abstracts a network or graph. Unlike other graph interfaces, `Network` considers edges as first-class objects and not just as
relations of vertices. This allows for a more relaxed abstraction where self-loops, open-edges, multi-edges and hyper-edges are allowed.
A type implementing the `Network` interface must implement the following methods:

| Required method | Description |
| :----------------------- | :------------------------------------------ |
| `all_vertices(g)` | Returns the list of vertices |
| `all_edges(g)` | Returns the list of edges |
| `edge_incidents(g, e)` | Returns the vertices connected by edge `e` |
| `vertex_incidents(g, v)` | Returns the edges conected to vertex `v` |
| `vertex_neighbors(g, v)` | Returns the vertices neighboring vertex `v` |
| `edge_neighbors(g, e)` | Returns the edges neighboring edge `e` |
| Required method | Description |
| :------------------------ | :----------------------------------------------- |
| `all_vertices(g)` | Returns the list of vertices |
| `all_edges(g)` | Returns the list of edges |
| `incident_vertices(g, e)` | Returns the vertices connected by edge `e` |
| `incident_edges(g, v)` | Returns the edges conected to vertex `v` |
| `neighbor_vertices(g, v)` | Returns the vertices neighboring vertex `v` |
| `neighbor_edges(g, e)` | Returns the edges neighboring edge `e` |
| `Directedness(::Type{G})` | Returns the directedness trait of graph type `G` |

### Optional methods

Expand All @@ -37,6 +39,23 @@ The following methods have a default implementation or their implementation is o
| `vertex_at(g, tag)` | If your type has some other way to refer to a vertex | _(undefined)_ | Returns the vertex related to `tag` |
| `edge_at(g, tag)` | If your type has some other way to refer to an edge | _(undefined)_ | Returns the edge related to `tag` |

### Directed methods

If your `Network` implementation represents a directed graph, the following methods are required:

!!! warning

Directedness on hypergraphs is not well-defined. It is such an edge case, that we have decide to don't support it explicitly for the time being.

| Required method | Description |
| :--------------------------- | :------------------------------------------------ |
| `incoming_edges(g, v)` | Returns the edges incoming to vertex `v` |
| `outgoing_edges(g, v)` | Returns the vertices outgoing from vertex `v` |
| `source_vertex(g, e)` | Returns the source vertex of edge `e` |
| `destination_vertex(g, e)` | Returns the destination vertex of edge `e` |
| `predecessor_vertices(g, v)` | Returns the vertices that are predecessors of `v` |
| `successor_vertices(g, v)` | Returns the vertices that are successors of `v` |

### Mutating methods

| Method | Brief description |
Expand Down
2 changes: 1 addition & 1 deletion src/Algorithms/cycles.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function cycle_basis(g, root=nothing)
while !isempty(stack)
z = pop!(stack)
zused = used[z]
for nbr in vertex_neighbors(g, z)
for nbr in neighbor_vertices(g, z)
if !in(nbr, keys_used)
pred[nbr] = z
push!(keys_pred, nbr)
Expand Down
24 changes: 12 additions & 12 deletions src/Components/IncidentNetwork.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ all_vertices(graph::IncidentNetwork) = keys(graph.vertexmap)
all_edges(graph::IncidentNetwork) = keys(graph.edgemap)

# TODO should we copy the sets to avoid accidental mutation?
edge_incidents(graph::IncidentNetwork, e) = graph.edgemap[e]
vertex_incidents(graph::IncidentNetwork, v) = graph.vertexmap[v]
incident_vertices(graph::IncidentNetwork, e) = graph.edgemap[e]
incident_edges(graph::IncidentNetwork, v) = graph.vertexmap[v]

function vertex_neighbors(graph::IncidentNetwork, v)
function neighbor_vertices(graph::IncidentNetwork, v)
neighbors = Set{typeof(v)}()
for edge in vertex_incidents(graph, v)
for neighbor in edge_incidents(graph, edge)
for edge in incident_edges(graph, v)
for neighbor in incident_vertices(graph, edge)
if neighbor != v
push!(neighbors, neighbor)
end
Expand All @@ -47,10 +47,10 @@ function vertex_neighbors(graph::IncidentNetwork, v)
return neighbors
end

function edge_neighbors(graph::IncidentNetwork, e)
function neighbor_edges(graph::IncidentNetwork, e)
neighbors = Set{typeof(e)}()
for vertex in edge_incidents(graph, e)
for neighbor in vertex_incidents(graph, vertex)
for vertex in incident_vertices(graph, e)
for neighbor in incident_edges(graph, vertex)
if neighbor != e
push!(neighbors, neighbor)
end
Expand Down Expand Up @@ -106,11 +106,11 @@ end

# TODO parameterize `EdgePersistence` to allow for different edge persistence strategies
function rmvertex!(graph::IncidentNetwork, vertex)
# isempty(vertex_incidents(graph, vertex)) || throw(ArgumentError("Vertex $vertex is incident to edges. Unlink edges first."))
# isempty(incident_edges(graph, vertex)) || throw(ArgumentError("Vertex $vertex is incident to edges. Unlink edges first."))
hasvertex(graph, vertex) || throw(ArgumentError("Vertex $vertex does not exist in the graph"))

# unlink vertex-edge pairs
for edge in vertex_incidents(graph, vertex)
for edge in incident_edges(graph, vertex)
unlink!(graph, vertex, edge)
end

Expand All @@ -127,11 +127,11 @@ function addedge!(graph::IncidentNetwork{V,E}, edge) where {V,E}
end

function rmedge!(graph::IncidentNetwork, edge)
# isempty(edge_incidents(graph, edge)) || throw(ArgumentError("Edge $edge is incident to vertices. Unlink vertices first."))
# isempty(incident_vertices(graph, edge)) || throw(ArgumentError("Edge $edge is incident to vertices. Unlink vertices first."))
hasedge(graph, edge) || throw(ArgumentError("Edge $edge does not exist in the graph"))

# unlink edge-vertex pairs
for vertex in edge_incidents(graph, edge)
for vertex in incident_vertices(graph, edge)
unlink!(graph, vertex, edge)
end

Expand Down
12 changes: 6 additions & 6 deletions src/Components/SimpleNetwork.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ edges(g::SimpleNetwork) = SimpleEdgeIter(g)
all_vertices(g::SimpleNetwork) = 1:length(g.fadjlist)
all_edges(g::SimpleNetwork) = SimpleEdgeIter(g)

edge_incidents(::SimpleNetwork, e::SimpleEdge) = [e.v1, e.v2]
vertex_incidents(g::SimpleNetwork, v) = map(dst -> SimpleEdge(v, dst), g.fadjlist[v])
incident_vertices(g::SimpleNetwork, e::SimpleEdge) = [e.v1, e.v2]
incident_edges(g::SimpleNetwork, v) = g.fadjlist[v]

vertex_neighbors(g::SimpleNetwork, v) = g.fadjlist[v]
function edge_neighbors(g::SimpleNetwork, e::SimpleEdge)
neigh_v1 = vertex_neighbors(g, e.v1)
neigh_v2 = vertex_neighbors(g, e.v2)
neighbor_vertices(g::SimpleNetwork, v) = g.fadjlist[v]
function neighbor_edges(g::SimpleNetwork, e::SimpleEdge)
neigh_v1 = neighbor_vertices(g, e.v1)
neigh_v2 = neighbor_vertices(g, e.v2)
neighbors = Set{edge_type(g)}()

for v in neigh_v1
Expand Down
Loading
Loading