Skip to content

Commit d90c8e1

Browse files
authored
Add convert_vertextype support for NamedGraphs, clean up constructors
2 parents fa74ea8 + f7539d3 commit d90c8e1

File tree

9 files changed

+95
-53
lines changed

9 files changed

+95
-53
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "NamedGraphs"
22
uuid = "678767b0-92e7-4007-89e4-4527a8725b19"
33
authors = ["Matthew Fishman <[email protected]> and contributors"]
4-
version = "0.1.0"
4+
version = "0.1.1"
55

66
[deps]
77
AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"

src/Dictionaries/dictionary.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Workaround for: https://github.com/andyferris/Dictionaries.jl/issues/98
2+
# TODO: Move to Dictionaries.jl file in NamedGraphs.jl
3+
copy_keys_values(d::Dictionary) = Dictionary(copy(d.indices), copy(d.values))
4+
5+
# Dictionaries.jl patch
6+
# TODO: delete once fixed in Dictionaries.jl
7+
# TODO: Move to Dictionaries.jl file in NamedGraphs.jl
8+
convert(::Type{Dictionary{I,T}}, dict::Dictionary{I,T}) where {I,T} = dict

src/Graphs/abstractgraph.jl

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ undirected_graph(::Type{<:AbstractGraph}) = error("Not implemented")
55

66
@traitfn directed_graph(graph::::IsDirected) = graph
77

8+
convert_vertextype(::Type{V}, graph::AbstractGraph{V}) where {V} = graph
9+
function convert_vertextype(V::Type, graph::AbstractGraph)
10+
return not_implemented()
11+
end
12+
813
# TODO: Handle metadata in a generic way
914
@traitfn function directed_graph(graph::::(!IsDirected))
1015
digraph = directed_graph(typeof(graph))()
@@ -48,6 +53,18 @@ function rename_vertices(g::AbstractGraph, name_map)
4853
return rename_vertices(v -> name_map[v], g)
4954
end
5055

56+
# Returns just the edges of a directed graph,
57+
# but both edge directions of an undirected graph.
58+
# TODO: Move to NamedGraphs.jl
59+
@traitfn function all_edges(g::::IsDirected)
60+
return edges(g)
61+
end
62+
63+
@traitfn function all_edges(g::::(!IsDirected))
64+
e = edges(g)
65+
return Iterators.flatten(zip(e, reverse.(e)))
66+
end
67+
5168
# Alternative syntax to `getindex` for getting a subgraph
5269
function subgraph(graph::AbstractGraph, subvertices::Vector)
5370
return induced_subgraph(graph, subvertices)[1]
@@ -250,17 +267,3 @@ end
250267
pop!(vertices)
251268
return [edgetype(graph)(vertex, parent_vertex(graph, vertex)) for vertex in vertices]
252269
end
253-
254-
########################################################################
255-
# Graphs.SimpleGraphs extensions
256-
257-
# TODO: Move to `SimpleGraph` file
258-
# TODO: Use trait dispatch to do no-ops when appropriate
259-
directed_graph(G::Type{<:SimpleGraph}) = SimpleDiGraph{vertextype(G)}
260-
undirected_graph(G::Type{<:SimpleGraph}) = G
261-
directed_graph(G::Type{<:SimpleDiGraph}) = G
262-
undirected_graph(G::Type{<:SimpleDiGraph}) = SimpleGraph{vertextype(G)}
263-
264-
function set_vertices(graph::AbstractSimpleGraph, vertices::Vector)
265-
return GenericNamedGraph(graph, vertices)
266-
end

src/Graphs/simplegraph.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
########################################################################
2+
# Graphs.SimpleGraphs extensions
3+
4+
# TODO: Move to `SimpleGraph` file
5+
# TODO: Use trait dispatch to do no-ops when appropriate
6+
directed_graph(G::Type{<:SimpleGraph}) = SimpleDiGraph{vertextype(G)}
7+
undirected_graph(G::Type{<:SimpleGraph}) = G
8+
directed_graph(G::Type{<:SimpleDiGraph}) = G
9+
undirected_graph(G::Type{<:SimpleDiGraph}) = SimpleGraph{vertextype(G)}
10+
11+
function set_vertices(graph::AbstractSimpleGraph, vertices::Vector)
12+
return GenericNamedGraph(graph, vertices)
13+
end

src/NamedGraphs.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,12 @@ import Graphs:
4646
import Base: show, eltype, copy, getindex, convert, hcat, vcat, hvncat, union
4747

4848
# abstractnamededge.jl
49-
import Base: Pair, Tuple, show, ==, hash, eltype
49+
import Base: Pair, Tuple, show, ==, hash, eltype, convert
5050
import Graphs: AbstractEdge, src, dst, reverse
5151

52+
include(joinpath("Dictionaries", "dictionary.jl"))
5253
include(joinpath("Graphs", "abstractgraph.jl"))
54+
include(joinpath("Graphs", "simplegraph.jl"))
5355
include(joinpath("Graphs", "generators", "staticgraphs.jl"))
5456
include("abstractnamededge.jl")
5557
include("namededge.jl")

src/abstractnamededge.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
abstract type AbstractNamedEdge{V} <: AbstractEdge{V} end
22

3-
eltype(::Type{<:ET}) where {ET<:AbstractNamedEdge{T}} where {T} = T
3+
eltype(::Type{<:AbstractNamedEdge{V}}) where {V} = V
44

55
src(e::AbstractNamedEdge) = not_implemented()
66
dst(e::AbstractNamedEdge) = not_implemented()
77

8+
convert_vertextype(::Type{V}, E::Type{<:AbstractNamedEdge{V}}) where {V} = E
9+
convert_vertextype(::Type, E::Type{<:AbstractNamedEdge}) = not_implemented()
10+
811
function show(io::IO, mime::MIME"text/plain", e::AbstractNamedEdge)
912
show(io, src(e))
1013
print(io, " => ")
@@ -19,7 +22,7 @@ Pair(e::AbstractNamedEdge) = Pair(src(e), dst(e))
1922
Tuple(e::AbstractNamedEdge) = (src(e), dst(e))
2023

2124
# Convenience functions
22-
reverse(e::T) where {T<:AbstractNamedEdge} = T(dst(e), src(e))
25+
reverse(e::AbstractNamedEdge) = typeof(e)(dst(e), src(e))
2326
function ==(e1::AbstractNamedEdge, e2::AbstractNamedEdge)
2427
return (src(e1) == src(e2) && dst(e1) == dst(e2))
2528
end

src/abstractnamedgraph.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ undirected_graph(G::Type{<:AbstractNamedGraph}) = not_implemented()
2121
# In terms of `parent_graph_type`
2222
# is_directed(::Type{<:AbstractNamedGraph}) = not_implemented()
2323

24+
convert_vertextype(::Type, ::AbstractNamedGraph) = not_implemented()
25+
2426
# TODO: implement as:
2527
#
2628
# graph = set_parent_graph(graph, copy(parent_graph(graph)))
@@ -292,7 +294,7 @@ show(io::IO, graph::AbstractNamedGraph) = show(io, MIME"text/plain"(), graph)
292294
# Convenience functions
293295
#
294296

295-
function Base.:(==)(g1::AbstractNamedGraph, g2::AbstractNamedGraph)
297+
function (g1::AbstractNamedGraph == g2::AbstractNamedGraph)
296298
issetequal(vertices(g1), vertices(g2)) || return false
297299
for v in vertices(g1)
298300
issetequal(inneighbors(g1, v), inneighbors(g2, v)) || return false

src/namededge.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ end
66
NamedEdge(src::V, dst::V) where {V} = NamedEdge{V}(src, dst)
77
NamedEdge(src::S, dst::D) where {S,D} = NamedEdge{promote_type(S, D)}(src, dst)
88

9+
convert_vertextype(V::Type, ::Type{<:NamedEdge}) = NamedEdge{V}
10+
911
src(e::NamedEdge) = e.src
1012
dst(e::NamedEdge) = e.dst
1113

src/namedgraph.jl

Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,27 @@ struct GenericNamedGraph{V,G<:AbstractSimpleGraph{Int}} <: AbstractNamedGraph{V}
44
vertex_to_parent_vertex::Dictionary{V,Int}
55
end
66

7+
function convert_vertextype(V::Type, graph::GenericNamedGraph)
8+
return GenericNamedGraph(parent_graph(graph), convert(Vector{V}, vertices(graph)))
9+
end
10+
11+
#
12+
# Convert inputs to vertex list
13+
#
14+
15+
function to_vertices(vertices)
16+
return Vector(vertices)
17+
end
18+
to_vertices(vertices::Vector) = vertices
19+
to_vertices(vertices::Array) = vec(vertices)
20+
# Treat tuple inputs as cartesian grid sizes
21+
function to_vertices(vertices::Tuple{Vararg{Integer}})
22+
return vec(Tuple.(CartesianIndices(vertices)))
23+
end
24+
function to_vertices(V::Type, vertices)
25+
return convert(Vector{V}, to_vertices(vertices))
26+
end
27+
728
#
829
# Constructors from `AbstractSimpleGraph`
930
#
@@ -12,13 +33,20 @@ end
1233
function GenericNamedGraph{V,G}(
1334
parent_graph::AbstractSimpleGraph, vertices::Vector
1435
) where {V,G}
36+
@assert length(vertices) == nv(parent_graph)
1537
# Need to copy the vertices here, otherwise the Dictionary uses a view of the vertices
1638
return GenericNamedGraph{V,G}(
1739
parent_graph, vertices, Dictionary(copy(vertices), eachindex(vertices))
1840
)
1941
end
2042

21-
function GenericNamedGraph{V}(parent_graph::AbstractSimpleGraph, vertices::Vector) where {V}
43+
function GenericNamedGraph{V,G}(
44+
parent_graph::AbstractSimpleGraph, vertices
45+
) where {V,G}
46+
return GenericNamedGraph{V,G}(parent_graph, to_vertices(V, vertices))
47+
end
48+
49+
function GenericNamedGraph{V}(parent_graph::AbstractSimpleGraph, vertices) where {V}
2250
return GenericNamedGraph{V,typeof(parent_graph)}(parent_graph, vertices)
2351
end
2452

@@ -28,28 +56,37 @@ function GenericNamedGraph{<:Any,G}(
2856
return GenericNamedGraph{eltype(vertices),G}(parent_graph, vertices)
2957
end
3058

59+
function GenericNamedGraph{<:Any,G}(
60+
parent_graph::AbstractSimpleGraph, vertices
61+
) where {G}
62+
return GenericNamedGraph{<:Any,G}(parent_graph, to_vertices(vertices))
63+
end
64+
3165
function GenericNamedGraph(parent_graph::AbstractSimpleGraph, vertices::Vector)
32-
# Need to copy the vertices here, otherwise the Dictionary uses a view of the vertices
3366
return GenericNamedGraph{eltype(vertices)}(parent_graph, vertices)
3467
end
3568

69+
function GenericNamedGraph(parent_graph::AbstractSimpleGraph, vertices)
70+
return GenericNamedGraph(parent_graph, to_vertices(vertices))
71+
end
72+
3673
#
3774
# Constructors from vertex names
3875
#
3976

40-
function GenericNamedGraph{V,G}(vertices::Vector) where {V,G}
77+
function GenericNamedGraph{V,G}(vertices) where {V,G}
4178
return GenericNamedGraph(G(length(vertices)), vertices)
4279
end
4380

44-
function GenericNamedGraph{V}(vertices::Vector) where {V}
81+
function GenericNamedGraph{V}(vertices) where {V}
4582
return GenericNamedGraph{V,SimpleGraph{Int}}(vertices)
4683
end
4784

48-
function GenericNamedGraph{<:Any,G}(vertices::Vector) where {G}
85+
function GenericNamedGraph{<:Any,G}(vertices) where {G}
4986
return GenericNamedGraph{Any,G}(vertices)
5087
end
5188

52-
function GenericNamedGraph(vertices::Vector)
89+
function GenericNamedGraph(vertices)
5390
return GenericNamedGraph{eltype(vertices)}(vertices)
5491
end
5592

@@ -93,34 +130,6 @@ function GenericNamedGraph(
93130
return GenericNamedGraph(parent_graph, vertices)
94131
end
95132

96-
#
97-
# Convenient cartesian index constructor
98-
#
99-
100-
function GenericNamedGraph{V,G}(
101-
parent_graph::AbstractSimpleGraph, grid_size::Tuple{Vararg{Int}}
102-
) where {V,G}
103-
vertices = Tuple.(CartesianIndices(grid_size))
104-
@assert prod(grid_size) == nv(parent_graph)
105-
return GenericNamedGraph{V,G}(parent_graph, vec(vertices))
106-
end
107-
108-
function GenericNamedGraph{V}(
109-
parent_graph::AbstractSimpleGraph, grid_size::Tuple{Vararg{Int}}
110-
) where {V}
111-
return GenericNamedGraph{V,typeof(parent_graph)}(parent_graph, grid_size)
112-
end
113-
114-
function GenericNamedGraph{<:Any,G}(
115-
parent_graph::AbstractSimpleGraph, grid_size::Tuple{Vararg{Int}}
116-
) where {G}
117-
return GenericNamedGraph{typeof(grid_size),G}(parent_graph, grid_size)
118-
end
119-
120-
function GenericNamedGraph(parent_graph::AbstractSimpleGraph, grid_size::Tuple{Vararg{Int}})
121-
return GenericNamedGraph{typeof(grid_size),typeof(parent_graph)}(parent_graph, grid_size)
122-
end
123-
124133
# AbstractNamedGraph required interface.
125134
# TODO: rename `parent_graph` (type is implied by input)
126135
parent_graph_type(::Type{<:GenericNamedGraph{V,G}}) where {V,G} = G

0 commit comments

Comments
 (0)