From d561823168be7d042fcfac31162c6c2495f10ba4 Mon Sep 17 00:00:00 2001 From: Matt Fishman Date: Mon, 15 Apr 2024 10:28:36 -0400 Subject: [PATCH] Simplify `NamedGraph` constructors (#61) --- Project.toml | 2 +- README.md | 47 +++++++++++----------------- examples/README.jl | 8 ++--- examples/disjoint_union.jl | 4 +-- examples/multidimgraph_1d.jl | 4 +-- examples/multidimgraph_2d.jl | 4 +-- examples/namedgraph.jl | 2 +- src/generators/named_staticgraphs.jl | 8 ++--- src/namedgraph.jl | 36 +++++---------------- test/test_multidimgraph.jl | 10 +++--- test/test_namedgraph.jl | 4 ++- 11 files changed, 50 insertions(+), 79 deletions(-) diff --git a/Project.toml b/Project.toml index 0742256..7ff45d2 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "NamedGraphs" uuid = "678767b0-92e7-4007-89e4-4527a8725b19" authors = ["Matthew Fishman and contributors"] -version = "0.2.0" +version = "0.3.0" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" diff --git a/README.md b/README.md index eed2a84..cf2bd81 100644 --- a/README.md +++ b/README.md @@ -47,21 +47,7 @@ julia> using NamedGraphs julia> g = NamedGraph(grid((4,)), ["A", "B", "C", "D"]) NamedGraph{String} with 4 vertices: -4-element Dictionaries.Indices{String} - "A" - "B" - "C" - "D" - -and 3 edge(s): -"A" => "B" -"B" => "C" -"C" => "D" - - -julia> g = NamedGraph(grid((4,)); vertices=["A", "B", "C", "D"]) # Same as above -NamedGraph{String} with 4 vertices: -4-element Dictionaries.Indices{String} +4-element Indices{String} "A" "B" "C" @@ -94,7 +80,7 @@ julia> neighbors(g, "B") julia> subgraph(g, ["A", "B"]) NamedGraph{String} with 2 vertices: -2-element Dictionaries.Indices{String} +2-element Indices{String} "A" "B" @@ -116,9 +102,12 @@ It is natural to use tuples of integers as the names for the vertices of graphs For example: ```julia -julia> g = NamedGraph(grid((2, 2)); vertices=Tuple.(CartesianIndices((2, 2)))) +julia> dims = (2, 2) +(2, 2) + +julia> g = NamedGraph(grid(dims), Tuple.(CartesianIndices(dims))) NamedGraph{Tuple{Int64, Int64}} with 4 vertices: -4-element Dictionaries.Indices{Tuple{Int64, Int64}} +4-element Indices{Tuple{Int64, Int64}} (1, 1) (2, 1) (1, 2) @@ -162,7 +151,7 @@ You can use vertex names to get [induced subgraphs](https://juliagraphs.org/Grap ```julia julia> subgraph(v -> v[1] == 1, g) NamedGraph{Tuple{Int64, Int64}} with 2 vertices: -2-element Dictionaries.Indices{Tuple{Int64, Int64}} +2-element Indices{Tuple{Int64, Int64}} (1, 1) (1, 2) @@ -172,7 +161,7 @@ and 1 edge(s): julia> subgraph(v -> v[2] == 2, g) NamedGraph{Tuple{Int64, Int64}} with 2 vertices: -2-element Dictionaries.Indices{Tuple{Int64, Int64}} +2-element Indices{Tuple{Int64, Int64}} (1, 2) (2, 2) @@ -182,7 +171,7 @@ and 1 edge(s): julia> subgraph(g, [(1, 1), (2, 2)]) NamedGraph{Tuple{Int64, Int64}} with 2 vertices: -2-element Dictionaries.Indices{Tuple{Int64, Int64}} +2-element Indices{Tuple{Int64, Int64}} (1, 1) (2, 2) @@ -196,7 +185,7 @@ You can also take [disjoint unions](https://en.wikipedia.org/wiki/Disjoint_union ```julia julia> g₁ = g NamedGraph{Tuple{Int64, Int64}} with 4 vertices: -4-element Dictionaries.Indices{Tuple{Int64, Int64}} +4-element Indices{Tuple{Int64, Int64}} (1, 1) (2, 1) (1, 2) @@ -211,7 +200,7 @@ and 4 edge(s): julia> g₂ = g NamedGraph{Tuple{Int64, Int64}} with 4 vertices: -4-element Dictionaries.Indices{Tuple{Int64, Int64}} +4-element Indices{Tuple{Int64, Int64}} (1, 1) (2, 1) (1, 2) @@ -226,7 +215,7 @@ and 4 edge(s): julia> disjoint_union(g₁, g₂) NamedGraph{Tuple{Tuple{Int64, Int64}, Int64}} with 8 vertices: -8-element Dictionaries.Indices{Tuple{Tuple{Int64, Int64}, Int64}} +8-element Indices{Tuple{Tuple{Int64, Int64}, Int64}} ((1, 1), 1) ((2, 1), 1) ((1, 2), 1) @@ -249,7 +238,7 @@ and 8 edge(s): julia> g₁ ⊔ g₂ # Same as above NamedGraph{Tuple{Tuple{Int64, Int64}, Int64}} with 8 vertices: -8-element Dictionaries.Indices{Tuple{Tuple{Int64, Int64}, Int64}} +8-element Indices{Tuple{Tuple{Int64, Int64}, Int64}} ((1, 1), 1) ((2, 1), 1) ((1, 2), 1) @@ -287,9 +276,9 @@ be added manually. The original graphs can be obtained from subgraphs: ```julia -julia> rename_vertices(v -> v[1], subgraph(v -> v[2] == 1, g₁ ⊔ g₂)) +julia> rename_vertices(first, subgraph(v -> v[2] == 1, g₁ ⊔ g₂)) NamedGraph{Tuple{Int64, Int64}} with 4 vertices: -4-element Dictionaries.Indices{Tuple{Int64, Int64}} +4-element Indices{Tuple{Int64, Int64}} (1, 1) (2, 1) (1, 2) @@ -302,9 +291,9 @@ and 4 edge(s): (1, 2) => (2, 2) -julia> rename_vertices(v -> v[1], subgraph(v -> v[2] == 2, g₁ ⊔ g₂)) +julia> rename_vertices(first, subgraph(v -> v[2] == 2, g₁ ⊔ g₂)) NamedGraph{Tuple{Int64, Int64}} with 4 vertices: -4-element Dictionaries.Indices{Tuple{Int64, Int64}} +4-element Indices{Tuple{Int64, Int64}} (1, 1) (2, 1) (1, 2) diff --git a/examples/README.jl b/examples/README.jl index 2fa71d7..6382a55 100644 --- a/examples/README.jl +++ b/examples/README.jl @@ -28,7 +28,6 @@ using Graphs using NamedGraphs g = NamedGraph(grid((4,)), ["A", "B", "C", "D"]) -g = NamedGraph(grid((4,)); vertices=["A", "B", "C", "D"]) # Same as above #'Common operations are defined as you would expect: #+ term=true @@ -47,7 +46,8 @@ subgraph(g, ["A", "B"]) #' For example: #+ term=true -g = NamedGraph(grid((2, 2)); vertices=Tuple.(CartesianIndices((2, 2)))) +dims = (2, 2) +g = NamedGraph(grid(dims), Tuple.(CartesianIndices(dims))) #' In the future we will provide a shorthand notation for this, such as `cartesian_graph(grid((2, 2)), (2, 2))`. #' Internally the vertices are all stored as tuples with a label in each dimension. @@ -86,8 +86,8 @@ g₁ ⊔ g₂ # Same as above #' The original graphs can be obtained from subgraphs: #+ term=true -rename_vertices(v -> v[1], subgraph(v -> v[2] == 1, g₁ ⊔ g₂)) -rename_vertices(v -> v[1], subgraph(v -> v[2] == 2, g₁ ⊔ g₂)) +rename_vertices(first, subgraph(v -> v[2] == 1, g₁ ⊔ g₂)) +rename_vertices(first, subgraph(v -> v[2] == 2, g₁ ⊔ g₂)) #' ## Generating this README diff --git a/examples/disjoint_union.jl b/examples/disjoint_union.jl index fe6bb18..1a6a8d8 100644 --- a/examples/disjoint_union.jl +++ b/examples/disjoint_union.jl @@ -1,8 +1,8 @@ using Graphs using NamedGraphs -g1 = NamedGraph(grid((2, 2)); vertices=(2, 2)) -g2 = NamedGraph(grid((2, 2)); vertices=(2, 2)) +g1 = NamedGraph(grid((2, 2)), Tuple.(CartesianIndices((2, 2)))) +g2 = NamedGraph(grid((2, 2)), Tuple.(CartesianIndices((2, 2)))) g = ⊔("X" => g1, "Y" => g2) @show g1 diff --git a/examples/multidimgraph_1d.jl b/examples/multidimgraph_1d.jl index 5d2e412..3d0f94a 100644 --- a/examples/multidimgraph_1d.jl +++ b/examples/multidimgraph_1d.jl @@ -10,14 +10,14 @@ g = NamedGraph(parent_graph, vs) @show has_edge(g, "A" => "B") @show !has_edge(g, "A" => "C") -g_sub = g[["A"]] +g_sub = subgraph(g, ["A"]) @show has_vertex(g_sub, "A") @show !has_vertex(g_sub, "B") @show !has_vertex(g_sub, "C") @show !has_vertex(g_sub, "D") -g_sub = g[["A", "B"]] +g_sub = subgraph(g, ["A", "B"]) @show has_vertex(g_sub, "A") @show has_vertex(g_sub, "B") diff --git a/examples/multidimgraph_2d.jl b/examples/multidimgraph_2d.jl index 9f458a7..20923c1 100644 --- a/examples/multidimgraph_2d.jl +++ b/examples/multidimgraph_2d.jl @@ -42,8 +42,8 @@ g_sub = subgraph(v -> v[2] == 2, g) @show has_vertex(g_sub, ("Y", 2)) parent_graph = grid((2, 2)) -g1 = NamedGraph(parent_graph; vertices=(2, 2)) -g2 = NamedGraph(parent_graph; vertices=(2, 2)) +g1 = NamedGraph(parent_graph, Tuple.(CartesianIndices((2, 2)))) +g2 = NamedGraph(parent_graph, Tuple.(CartesianIndices((2, 2)))) g_disjoint_union = g1 ⊔ g2 diff --git a/examples/namedgraph.jl b/examples/namedgraph.jl index bf73359..3296d41 100644 --- a/examples/namedgraph.jl +++ b/examples/namedgraph.jl @@ -16,7 +16,7 @@ add_edge!(g, "A" => "C") @show issetequal(neighbors(g, "A"), ["B", "C"]) @show issetequal(neighbors(g, "B"), ["A", "C"]) -g_sub = g[["A", "B"]] +g_sub = subgraph(g, ["A", "B"]) @show has_vertex(g_sub, "A") @show has_vertex(g_sub, "B") diff --git a/src/generators/named_staticgraphs.jl b/src/generators/named_staticgraphs.jl index 872c24e..1a2365b 100644 --- a/src/generators/named_staticgraphs.jl +++ b/src/generators/named_staticgraphs.jl @@ -47,7 +47,7 @@ function named_bfs_tree( simple_graph::SimpleGraph, source::Integer=1; source_name=1, child_name=identity ) named_vertices = named_bfs_tree_vertices(simple_graph, source; source_name, child_name) - return NamedGraph(simple_graph; vertices=named_vertices) + return NamedGraph(simple_graph, named_vertices) end function named_binary_tree( @@ -72,12 +72,12 @@ end function named_grid(dims; kwargs...) simple_graph = grid(dims; kwargs...) - return NamedGraph(simple_graph; vertices=dims) + return NamedGraph(simple_graph, Tuple.(CartesianIndices(Tuple(dims)))) end function named_comb_tree(dims::Tuple) simple_graph = comb_tree(dims) - return NamedGraph(simple_graph; vertices=dims) + return NamedGraph(simple_graph, Tuple.(CartesianIndices(Tuple(dims)))) end function named_comb_tree(tooth_lengths::Vector{<:Integer}) @@ -88,5 +88,5 @@ function named_comb_tree(tooth_lengths::Vector{<:Integer}) vertices = filter(Tuple.(CartesianIndices((nx, ny)))) do (jx, jy) jy <= tooth_lengths[jx] end - return NamedGraph(simple_graph; vertices) + return NamedGraph(simple_graph, vertices) end diff --git a/src/namedgraph.jl b/src/namedgraph.jl index bf68953..f16b23a 100644 --- a/src/namedgraph.jl +++ b/src/namedgraph.jl @@ -107,6 +107,10 @@ function GenericNamedGraph{<:Any,G}(parent_graph::AbstractSimpleGraph, vertices) return GenericNamedGraph{<:Any,G}(parent_graph, to_vertices(vertices)) end +function GenericNamedGraph{<:Any,G}(parent_graph::AbstractSimpleGraph) where {G} + return GenericNamedGraph{<:Any,G}(parent_graph, vertices(parent_graph)) +end + function GenericNamedGraph(parent_graph::AbstractSimpleGraph, vertices::Vector) return GenericNamedGraph{eltype(vertices)}(parent_graph, vertices) end @@ -115,6 +119,10 @@ function GenericNamedGraph(parent_graph::AbstractSimpleGraph, vertices) return GenericNamedGraph(parent_graph, to_vertices(vertices)) end +function GenericNamedGraph(parent_graph::AbstractSimpleGraph) + return GenericNamedGraph(parent_graph, vertices(parent_graph)) +end + # # Tautological constructors # @@ -157,34 +165,6 @@ GenericNamedGraph{<:Any,G}() where {G} = GenericNamedGraph{<:Any,G}(Any[]) GenericNamedGraph() = GenericNamedGraph(Any[]) -# -# Keyword argument constructor syntax -# - -function GenericNamedGraph{V,G}( - parent_graph::AbstractSimpleGraph; vertices=vertices(parent_graph) -) where {V,G} - return GenericNamedGraph{V,G}(parent_graph, vertices) -end - -function GenericNamedGraph{V}( - parent_graph::AbstractSimpleGraph; vertices=vertices(parent_graph) -) where {V} - return GenericNamedGraph{V}(parent_graph, vertices) -end - -function GenericNamedGraph{<:Any,G}( - parent_graph::AbstractSimpleGraph; vertices=vertices(parent_graph) -) where {G} - return GenericNamedGraph{<:Any,G}(parent_graph, vertices) -end - -function GenericNamedGraph( - parent_graph::AbstractSimpleGraph; vertices=vertices(parent_graph) -) - return GenericNamedGraph(parent_graph, vertices) -end - # TODO: implement as: # graph = set_parent_graph(graph, copy(parent_graph(graph))) # graph = set_vertices(graph, copy(vertices(graph))) diff --git a/test/test_multidimgraph.jl b/test/test_multidimgraph.jl index 2d5bda1..d22b553 100644 --- a/test/test_multidimgraph.jl +++ b/test/test_multidimgraph.jl @@ -18,14 +18,14 @@ using Test show(io, "text/plain", g) @test String(take!(io)) isa String - g_sub = g[[("X", 1)]] + g_sub = subgraph(g, [("X", 1)]) @test has_vertex(g_sub, ("X", 1)) @test !has_vertex(g_sub, ("X", 2)) @test !has_vertex(g_sub, ("Y", 1)) @test !has_vertex(g_sub, ("Y", 2)) - g_sub = g[[("X", 1), ("X", 2)]] + g_sub = subgraph(g, [("X", 1), ("X", 2)]) @test has_vertex(g_sub, ("X", 1)) @test has_vertex(g_sub, ("X", 2)) @@ -50,7 +50,7 @@ using Test @test !has_vertex(g_sub, ("Y", 1)) @test has_edge(g_sub, ("X", 2) => ("Y", 2)) - g1 = NamedGraph(grid((2, 2)); vertices=(2, 2)) + g1 = NamedGraph(grid((2, 2)), Tuple.(CartesianIndices((2, 2)))) @test nv(g1) == 4 @test ne(g1) == 4 @@ -64,7 +64,7 @@ using Test @test has_edge(g1, (2, 1) => (2, 2)) @test !has_edge(g1, (1, 1) => (2, 2)) - g2 = NamedGraph(grid((2, 2)); vertices=(2, 2)) + g2 = NamedGraph(grid((2, 2)), Tuple.(CartesianIndices((2, 2)))) g = ("X" => g1) ⊔ ("Y" => g2) @@ -73,7 +73,7 @@ using Test @test has_vertex(g, ((1, 1), "X")) @test has_vertex(g, ((1, 1), "Y")) - g3 = NamedGraph(grid((2, 2)); vertices=(2, 2)) + g3 = NamedGraph(grid((2, 2)), Tuple.(CartesianIndices((2, 2)))) g = disjoint_union("X" => g1, "Y" => g2, "Z" => g3) @test nv(g) == 12 diff --git a/test/test_namedgraph.jl b/test/test_namedgraph.jl index 0055b33..dd4b97c 100644 --- a/test/test_namedgraph.jl +++ b/test/test_namedgraph.jl @@ -48,12 +48,14 @@ end @test issetequal(neighbors(g, "A"), ["B", "C"]) @test issetequal(neighbors(g, "B"), ["A", "C"]) - g_sub = g[["A", "B"]] + g_sub = subgraph(g, ["A", "B"]) @test has_vertex(g_sub, "A") @test has_vertex(g_sub, "B") @test !has_vertex(g_sub, "C") @test !has_vertex(g_sub, "D") + # Test Graphs.jl `getindex` syntax. + @test g_sub == g[["A", "B"]] g = NamedGraph(["A", "B", "C", "D", "E"]) add_edge!(g, "A" => "B")