From 85eed7e4cc0b04a146fb8eaba81b6fe2af7eb824 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Tue, 16 Apr 2024 17:53:26 -0400 Subject: [PATCH 01/11] Update for latest NamedGraphs --- Project.toml | 4 +- examples/Project.toml | 4 + examples/multidimdatagraph_1d.jl | 12 +- examples/slicing.jl | 8 +- src/DataGraphs.jl | 44 +++--- src/abstractdatagraph.jl | 253 ++++++++++++++++--------------- src/datagraph.jl | 15 +- src/traits/isunderlyinggraph.jl | 4 + test/runtests.jl | 5 +- 9 files changed, 189 insertions(+), 160 deletions(-) create mode 100644 examples/Project.toml diff --git a/Project.toml b/Project.toml index 21035e4..b8b4676 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "DataGraphs" uuid = "b5a273c3-7e6c-41f6-98bd-8d7f1525a36a" authors = ["Matthew Fishman and contributors"] -version = "0.1.13" +version = "0.2.0" [deps] Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" @@ -14,7 +14,7 @@ SimpleTraits = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" Dictionaries = "0.4" Graphs = "1" GraphsFlows = "0.1.1" -NamedGraphs = "0.1.19" +NamedGraphs = "0.4" SimpleTraits = "0.9" julia = "1.7" diff --git a/examples/Project.toml b/examples/Project.toml new file mode 100644 index 0000000..6864eaa --- /dev/null +++ b/examples/Project.toml @@ -0,0 +1,4 @@ +[deps] +DataGraphs = "b5a273c3-7e6c-41f6-98bd-8d7f1525a36a" +Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" +NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19" diff --git a/examples/multidimdatagraph_1d.jl b/examples/multidimdatagraph_1d.jl index 81ef283..a5bf039 100644 --- a/examples/multidimdatagraph_1d.jl +++ b/examples/multidimdatagraph_1d.jl @@ -1,14 +1,16 @@ -using DataGraphs -using Graphs -using NamedGraphs +using DataGraphs: DataGraph +using Graphs: grid, has_edge, has_vertex +using NamedGraphs: NamedGraph, NamedEdge g = NamedGraph(grid((4,)), ["A", "B", "C", "D"]) dg = DataGraph(g, String, Symbol) @show has_vertex(dg, "A") @show has_vertex(dg, "D") -@show !has_vertex(dg, 0) -@show !has_vertex(dg, 5) + +# Broken, see https://github.com/andyferris/Dictionaries.jl/issues/143. +# @show !has_vertex(dg, 0) +# @show !has_vertex(dg, 5) @show has_edge(dg, "A", "B") @show has_edge(dg, "A" => "B") diff --git a/examples/slicing.jl b/examples/slicing.jl index 467acd4..bbfe877 100644 --- a/examples/slicing.jl +++ b/examples/slicing.jl @@ -1,7 +1,7 @@ -using DataGraphs -using NamedGraphs -using Dictionaries -using Graphs +using DataGraphs: DataGraph +using NamedGraphs.GraphsExtensions: subgraph +using NamedGraphs.NamedGraphGenerators: named_grid +using Graphs: ne, nv g = named_grid((2, 2)) dg = DataGraph(g, String, String) diff --git a/src/DataGraphs.jl b/src/DataGraphs.jl index 517a143..786392b 100644 --- a/src/DataGraphs.jl +++ b/src/DataGraphs.jl @@ -6,7 +6,7 @@ using GraphsFlows using NamedGraphs using SimpleTraits -using NamedGraphs: AbstractNamedGraph, all_edges +using NamedGraphs: AbstractNamedGraph # # imports @@ -86,27 +86,27 @@ import Graphs: vertices, yen_k_shortest_paths -# TODO: Can we remove the dependency on `NamedGraphs`? -# Maybe need a `GraphExtensions.jl` or -# `GraphInterfaces.jl` package. -import NamedGraphs: - ⊔, - boundary_edges, - boundary_vertices, - convert_vertextype, - directed_graph, - disjoint_union, - eccentricities, - incident_edges, - inner_boundary_vertices, - outer_boundary_vertices, - mincut_partitions, - rename_vertices, - symrcm, - symrcm_permute, - vertextype, - parent_graph, - parent_vertices_to_vertices +## # TODO: Can we remove the dependency on `NamedGraphs`? +## # Maybe need a `GraphExtensions.jl` or +## # `GraphInterfaces.jl` package. +## import NamedGraphs: +## ⊔, +## boundary_edges, +## boundary_vertices, +## convert_vertextype, +## directed_graph, +## disjoint_union, +## eccentricities, +## incident_edges, +## inner_boundary_vertices, +## outer_boundary_vertices, +## mincut_partitions, +## rename_vertices, +## symrcm, +## symrcm_permute, +## vertextype, +## parent_graph, +## parent_vertices_to_vertices # General functions not_implemented() = error("Not implemented") diff --git a/src/abstractdatagraph.jl b/src/abstractdatagraph.jl index ef80635..2068e10 100644 --- a/src/abstractdatagraph.jl +++ b/src/abstractdatagraph.jl @@ -1,5 +1,16 @@ +using Dictionaries: set!, unset! +using Graphs: Graphs, AbstractGraph, IsDirected, add_edge!, edges, vertices +using NamedGraphs: NamedGraphs +using NamedGraphs.GraphsExtensions: GraphsExtensions, incident_edges, vertextype + abstract type AbstractDataGraph{V,VD,ED} <: AbstractGraph{V} end +# TODO: Move to `DataGraphsGraphsFlowsExt`. +using GraphsFlows: GraphsFlows +function GraphsFlows.mincut(graph::AbstractDataGraph, args...; kwargs...) + return GraphsFlows.mincut(underlying_graph(graph), args...; kwargs...) +end + # Minimal interface underlying_graph(::AbstractDataGraph) = not_implemented() underlying_graph_type(::Type{<:AbstractDataGraph}) = not_implemented() @@ -9,80 +20,85 @@ edge_data(::AbstractDataGraph) = not_implemented() edge_data_type(::Type{<:AbstractDataGraph}) = not_implemented() # Derived interface -edgetype(G::Type{<:AbstractDataGraph}) = edgetype(underlying_graph_type(G)) -is_directed(G::Type{<:AbstractDataGraph}) = is_directed(underlying_graph_type(G)) +Graphs.edgetype(G::Type{<:AbstractDataGraph}) = Graphs.edgetype(underlying_graph_type(G)) +function Graphs.is_directed(G::Type{<:AbstractDataGraph}) + return Graphs.is_directed(underlying_graph_type(G)) +end underlying_graph_type(graph::AbstractDataGraph) = typeof(underlying_graph(graph)) vertex_data_type(graph::AbstractDataGraph) = vertex_data_type(typeof(graph)) edge_data_type(graph::AbstractDataGraph) = edge_data_type(typeof(graph)) # TODO: delete, defined for AbstractGraph{V}? -vertextype(G::Type{<:AbstractDataGraph}) = vertextype(underlying_graph_type(G)) -vertextype(graph::AbstractDataGraph) = vertextype(typeof(graph)) +function GraphsExtensions.vertextype(G::Type{<:AbstractDataGraph}) + return vertextype(underlying_graph_type(G)) +end +GraphsExtensions.vertextype(graph::AbstractDataGraph) = vertextype(typeof(graph)) -zero(G::Type{<:AbstractDataGraph}) = G() +Base.zero(G::Type{<:AbstractDataGraph}) = G() # Graphs overloads for f in [ - :a_star, - :add_edge!, - :add_vertex!, - :adjacency_matrix, - :bellman_ford_shortest_paths, - :bfs_parents, - :bfs_tree, - :boundary_edges, - :boundary_vertices, - :boruvka_mst, - :center, - :common_neighbors, - :connected_components, - :degree, - :degree_histogram, - :desopo_pape_shortest_paths, - :dfs_parents, - :dfs_tree, - :diameter, - :dijkstra_shortest_paths, - :eccentricity, - :eccentricities, - :edges, - :edgetype, - :eltype, - :enumerate_paths, - :floyd_warshall_shortest_paths, - :has_edge, - :has_path, - :has_vertex, - :inneighbors, - :inner_boundary_vertices, - :is_connected, - :is_cyclic, - :is_directed, - :is_strongly_connected, - :is_weakly_connected, - :mincut, - :(GraphsFlows.mincut), - :mincut_partitions, - :ne, - :neighbors, - :neighborhood, - :neighborhood_dists, - :outer_boundary_vertices, - :johnson_shortest_paths, - :spfa_shortest_paths, - :yen_k_shortest_paths, - :kruskal_mst, - :prim_mst, - :nv, - :outneighbors, - :periphery, - :radius, - :symrcm, - :symrcm_permute, - :steiner_tree, - :topological_sort_by_dfs, - :tree, - :vertices, + :(Graphs.a_star), + :(Graphs.add_edge!), + :(Graphs.add_vertex!), + :(Graphs.adjacency_matrix), + :(Graphs.bellman_ford_shortest_paths), + :(Graphs.bfs_parents), + :(Graphs.bfs_tree), + :(Graphs.boruvka_mst), + :(Graphs.center), + :(Graphs.common_neighbors), + :(Graphs.connected_components), + :(Graphs.degree), + :(Graphs.degree_histogram), + :(Graphs.desopo_pape_shortest_paths), + :(Graphs.dfs_parents), + :(Graphs.dfs_tree), + :(Graphs.diameter), + :(Graphs.dijkstra_shortest_paths), + :(Graphs.eccentricity), + :(Graphs.edges), + :(Graphs.edgetype), + :(Graphs.eltype), + :(Graphs.enumerate_paths), + :(Graphs.floyd_warshall_shortest_paths), + :(Graphs.has_edge), + :(Graphs.has_path), + :(Graphs.has_vertex), + :(Graphs.inneighbors), + :(Graphs.is_connected), + :(Graphs.is_cyclic), + :(Graphs.is_directed), + :(Graphs.is_strongly_connected), + :(Graphs.is_weakly_connected), + :(Graphs.mincut), + :(Graphs.ne), + :(Graphs.neighbors), + :(Graphs.neighborhood), + :(Graphs.neighborhood_dists), + :(Graphs.johnson_shortest_paths), + :(Graphs.spfa_shortest_paths), + :(Graphs.yen_k_shortest_paths), + :(Graphs.kruskal_mst), + :(Graphs.prim_mst), + :(Graphs.nv), + :(Graphs.outneighbors), + :(Graphs.periphery), + :(Graphs.radius), + :(Graphs.steiner_tree), + :(Graphs.topological_sort_by_dfs), + :(Graphs.tree), + :(Graphs.vertices), + :(GraphsExtensions.boundary_edges), + :(GraphsExtensions.boundary_vertices), + :(GraphsExtensions.eccentricities), + :(GraphsExtensions.inner_boundary_vertices), + :(GraphsExtensions.mincut_partitions), + :(GraphsExtensions.outer_boundary_vertices), + :(GraphsExtensions.symrcm_perm), + :(GraphsExtensions.symrcm_permute), + :(NamedGraphs.parent_graph), + :(NamedGraphs.parent_vertices_to_vertices), ] @eval begin function $f(graph::AbstractDataGraph, args...; kwargs...) @@ -91,28 +107,21 @@ for f in [ end end -# NamedGraphs overloads -for f in [:parent_graph, :parent_vertices_to_vertices] - @eval begin - function $f(graph::AbstractDataGraph, args...; kwargs...) - return $f(underlying_graph(graph), args...; kwargs...) - end - end -end - # Fix for ambiguity error with `AbstractGraph` version -function degree(graph::AbstractDataGraph, vertex::Integer) - return degree(underlying_graph(graph), vertex) +function Graphs.degree(graph::AbstractDataGraph, vertex::Integer) + return Graphs.degree(underlying_graph(graph), vertex) end # Fix for ambiguity error with `AbstractGraph` version -function dijkstra_shortest_paths(graph::AbstractDataGraph, vertices::Vector{<:Integer}) - return dijkstra_shortest_paths(underlying_graph(graph), vertices) +function Graphs.dijkstra_shortest_paths( + graph::AbstractDataGraph, vertices::Vector{<:Integer} +) + return Graphs.dijkstra_shortest_paths(underlying_graph(graph), vertices) end # Fix for ambiguity error with `AbstractGraph` version -function eccentricity(graph::AbstractDataGraph, distmx::AbstractMatrix) - return eccentricity(underlying_graph(graph), distmx) +function Graphs.eccentricity(graph::AbstractDataGraph, distmx::AbstractMatrix) + return Graphs.eccentricity(underlying_graph(graph), distmx) end # Fix for ambiguity error with `AbstractGraph` version @@ -125,9 +134,9 @@ function outdegree(graph::AbstractDataGraph, vertex::Integer) return outdegree(underlying_graph(graph), vertex) end -@traitfn directed_graph(graph::AbstractDataGraph::IsDirected) = graph +@traitfn GraphsExtensions.directed_graph(graph::AbstractDataGraph::IsDirected) = graph -@traitfn function directed_graph(graph::AbstractDataGraph::(!IsDirected)) +@traitfn function GraphsExtensions.directed_graph(graph::AbstractDataGraph::(!IsDirected)) digraph = directed_graph(typeof(graph))(directed_graph(underlying_graph(graph))) for v in vertices(graph) # TODO: Only loop over `keys(vertex_data(graph))` @@ -148,7 +157,7 @@ end return digraph end -function reverse(graph::AbstractDataGraph) +function Base.reverse(graph::AbstractDataGraph) reversed_graph = typeof(graph)(reverse(underlying_graph(graph))) for v in vertices(graph) if isassigned(graph, v) @@ -163,7 +172,7 @@ function reverse(graph::AbstractDataGraph) return reversed_graph end -function merge_vertices( +function Graphs.merge_vertices( graph::AbstractDataGraph, merge_vertices; merge_data=(x, y) -> y, @@ -171,11 +180,11 @@ function merge_vertices( merge_edge_data=merge_data, kwargs..., ) - underlying_merged_graph = merge_vertices(underlying_graph(graph); kwargs...) + underlying_merged_graph = Graphs.merge_vertices(underlying_graph(graph); kwargs...) return not_implemented() end -function merge_vertices!( +function Graphs.merge_vertices!( graph::AbstractDataGraph, merge_vertices; merge_data=(x, y) -> y, @@ -184,13 +193,13 @@ function merge_vertices!( kwargs..., ) underlying_merged_graph = copy(underlying_graph(graph)) - merge_vertices!(underlying_merged_graph; kwargs...) + Graphs.merge_vertices!(underlying_merged_graph; kwargs...) return not_implemented() end # Union the vertices and edges of the graphs and # merge the vertex and edge metadata. -function union( +function Base.union( graph1::AbstractDataGraph, graph2::AbstractDataGraph; merge_data=(x, y) -> y, @@ -204,7 +213,7 @@ function union( return DataGraph(underlying_graph_union, vertex_data_merge, edge_data_merge) end -function union( +function Base.union( graph1::AbstractDataGraph, graph2::AbstractDataGraph, graph3::AbstractDataGraph, @@ -214,8 +223,8 @@ function union( return union(union(graph1, graph2; kwargs...), graph3, graphs_tail...; kwargs...) end -function rename_vertices(f::Function, graph::AbstractDataGraph) - renamed_underlying_graph = rename_vertices(f, underlying_graph(graph)) +function GraphsExtensions.rename_vertices(f::Function, graph::AbstractDataGraph) + renamed_underlying_graph = GraphsExtensions.rename_vertices(f, underlying_graph(graph)) # TODO: Base the ouput type on `typeof(graph)`, for example: # convert_vertextype(eltype(renamed_vertices), typeof(graph))(renamed_underlying_graph) renamed_graph = DataGraph{ @@ -227,47 +236,49 @@ function rename_vertices(f::Function, graph::AbstractDataGraph) renamed_graph[f(v)] = graph[v] end for e in keys(edge_data(graph)) - renamed_graph[rename_vertices(f, e)] = graph[e] + renamed_graph[GraphsExtensions.rename_vertices(f, e)] = graph[e] end return renamed_graph end -function rem_vertex!(graph::AbstractDataGraph, vertex) +function Graphs.rem_vertex!(graph::AbstractDataGraph, vertex) neighbor_edges = incident_edges(graph, vertex) # unset!(vertex_data(graph), to_vertex(graph, vertex...)) unset!(vertex_data(graph), vertex) for neighbor_edge in neighbor_edges unset!(edge_data(graph), neighbor_edge) end - rem_vertex!(underlying_graph(graph), vertex) + Graphs.rem_vertex!(underlying_graph(graph), vertex) return graph end -function rem_edge!(graph::AbstractDataGraph, edge) +function Graphs.rem_edge!(graph::AbstractDataGraph, edge) unset!(edge_data(graph), edge) - rem_edge!(underlying_graph(graph), edge) + Graphs.rem_edge!(underlying_graph(graph), edge) return graph end # Fix ambiguity with: # Graphs.neighbors(graph::AbstractGraph, v::Integer) -neighbors(graph::AbstractDataGraph, v::Integer) = neighbors(underlying_graph(graph), v) +function Graphs.neighbors(graph::AbstractDataGraph, v::Integer) + return Graphs.neighbors(underlying_graph(graph), v) +end # Fix ambiguity with: # Graphs.bfs_tree(graph::AbstractGraph, s::Integer; dir) -function bfs_tree(graph::AbstractDataGraph, s::Integer; kwargs...) - return bfs_tree(underlying_graph(graph), s; kwargs...) +function Graphs.bfs_tree(graph::AbstractDataGraph, s::Integer; kwargs...) + return Graphs.bfs_tree(underlying_graph(graph), s; kwargs...) end # Fix ambiguity with: # Graphs.dfs_tree(graph::AbstractGraph, s::Integer; dir) -function dfs_tree(graph::AbstractDataGraph, s::Integer; kwargs...) - return dfs_tree(underlying_graph(graph), s; kwargs...) +function Graphs.dfs_tree(graph::AbstractDataGraph, s::Integer; kwargs...) + return Graphs.dfs_tree(underlying_graph(graph), s; kwargs...) end function map_vertex_data(f, graph::AbstractDataGraph; vertices=nothing) graph′ = copy(graph) - vs = isnothing(vertices) ? Graphs.vertices(graph) : vertices + vs = isnothing(vertices) ? vertices(graph) : vertices for v in vs graph′[v] = f(graph[v]) end @@ -276,7 +287,7 @@ end function map_edge_data(f, graph::AbstractDataGraph; edges=nothing) graph′ = copy(graph) - es = isnothing(edges) ? Graphs.edges(graph) : edges + es = isnothing(edges) ? edges(graph) : edges for e in es if isassigned(graph, e) graph′[e] = f(graph[e]) @@ -290,58 +301,58 @@ function map_data(f, graph::AbstractDataGraph; vertices=nothing, edges=nothing) return map_edge_data(f, graph; edges) end -function getindex(graph::AbstractDataGraph, vertex) +function Base.getindex(graph::AbstractDataGraph, vertex) return vertex_data(graph)[vertex] end -function get(graph::AbstractDataGraph, vertex, default) +function Base.get(graph::AbstractDataGraph, vertex, default) return get(vertex_data(graph), vertex, default) end -function getindex(graph::AbstractDataGraph, edge::AbstractEdge) +function Base.getindex(graph::AbstractDataGraph, edge::AbstractEdge) is_edge_arranged_ = is_edge_arranged(graph, edge) data = edge_data(graph)[arrange(is_edge_arranged_, edge)] return reverse_data_direction(is_edge_arranged_, graph, data) end # Support syntax `g[v1 => v2]` -function getindex(graph::AbstractDataGraph, edge::Pair) +function Base.getindex(graph::AbstractDataGraph, edge::Pair) return graph[edgetype(graph)(edge)] end -function get(graph::AbstractDataGraph, edge::AbstractEdge, default) +function Base.get(graph::AbstractDataGraph, edge::AbstractEdge, default) is_edge_arranged_ = is_edge_arranged(graph, edge) data = get(edge_data(graph), arrange(is_edge_arranged_, edge), default) return reverse_data_direction(is_edge_arranged_, graph, data) end -function get(graph::AbstractDataGraph, edge::Pair, default) +function Base.get(graph::AbstractDataGraph, edge::Pair, default) return get(graph, edgetype(graph)(edge), default) end # Support syntax `g[1, 2] = g[(1, 2)]` -function getindex(graph::AbstractDataGraph, i1, i2, i...) +function Base.getindex(graph::AbstractDataGraph, i1, i2, i...) return graph[(i1, i2, i...)] end -function isassigned(graph::AbstractDataGraph, vertex) +function Base.isassigned(graph::AbstractDataGraph, vertex) return isassigned(vertex_data(graph), vertex) end -function isassigned(graph::AbstractDataGraph, vertex::AbstractEdge) +function Base.isassigned(graph::AbstractDataGraph, vertex::AbstractEdge) return isassigned(edge_data(graph), arrange(graph, vertex)) end -function isassigned(graph::AbstractDataGraph, vertex::Pair) +function Base.isassigned(graph::AbstractDataGraph, vertex::Pair) return isassigned(graph, edgetype(graph)(vertex)) end -function setindex!(graph::AbstractDataGraph, data, vertex) +function Base.setindex!(graph::AbstractDataGraph, data, vertex) set!(vertex_data(graph), vertex, data) return graph end -function setindex!(graph::AbstractDataGraph, data, edge::AbstractEdge) +function Base.setindex!(graph::AbstractDataGraph, data, edge::AbstractEdge) is_edge_arranged_ = is_edge_arranged(graph, edge) arranged_edge = arrange(is_edge_arranged_, edge) arranged_data = reverse_data_direction(is_edge_arranged_, graph, data) @@ -349,19 +360,19 @@ function setindex!(graph::AbstractDataGraph, data, edge::AbstractEdge) return graph end -function setindex!(graph::AbstractDataGraph, data, edge::Pair) +function Base.setindex!(graph::AbstractDataGraph, data, edge::Pair) graph[edgetype(graph)(edge)] = data return graph end # Support syntax `g[1, 2] = g[(1, 2)]` -function setindex!(graph::AbstractDataGraph, x, i1, i2, i...) +function Base.setindex!(graph::AbstractDataGraph, x, i1, i2, i...) graph[(i1, i2, i...)] = x return graph end -function induced_subgraph(graph::AbstractDataGraph, subvertices::Vector) - underlying_subgraph, vlist = induced_subgraph(underlying_graph(graph), subvertices) +function Graphs.induced_subgraph(graph::AbstractDataGraph, subvertices) + underlying_subgraph, vlist = Graphs.induced_subgraph(underlying_graph(graph), subvertices) subgraph = typeof(graph)(underlying_subgraph) for v in vertices(subgraph) if isassigned(graph, v) @@ -380,7 +391,7 @@ end # Printing # -function show(io::IO, mime::MIME"text/plain", graph::AbstractDataGraph) +function Base.show(io::IO, mime::MIME"text/plain", graph::AbstractDataGraph) println(io, "$(typeof(graph)) with $(nv(graph)) vertices:") show(io, mime, vertices(graph)) println(io, "\n") @@ -399,4 +410,4 @@ function show(io::IO, mime::MIME"text/plain", graph::AbstractDataGraph) return nothing end -show(io::IO, graph::AbstractDataGraph) = show(io, MIME"text/plain"(), graph) +Base.show(io::IO, graph::AbstractDataGraph) = show(io, MIME"text/plain"(), graph) diff --git a/src/datagraph.jl b/src/datagraph.jl index b5feb62..f997899 100644 --- a/src/datagraph.jl +++ b/src/datagraph.jl @@ -1,3 +1,8 @@ +using Dictionaries: Dictionary +using Graphs: Graphs, edgetype +using Graphs.SimpleGraphs: SimpleGraph +using NamedGraphs.GraphsExtensions: directed_graph, vertextype + # TODO: define VertexDataGraph, a graph with only data on the # vertices, and EdgeDataGraph, a graph with only data on the edges. # TODO: Constrain `E<:AbstractEdge`. @@ -28,11 +33,11 @@ edge_data(graph::DataGraph) = getfield(graph, :edge_data) # TODO: Is this needed? underlying_graph_type(graph::DataGraph) = typeof(underlying_graph(graph)) # TODO: Is this needed? -is_directed(G::Type{<:DataGraph}) = is_directed(underlying_graph_type(G)) +Graphs.is_directed(G::Type{<:DataGraph}) = Graphs.is_directed(underlying_graph_type(G)) # TODO: Implement in terms of `set_underlying_graph`, `set_vertex_data`, etc. # TODO: Use `https://github.com/JuliaObjects/Accessors.jl`? -function copy(graph::DataGraph) +function Base.copy(graph::DataGraph) # Need to manually copy the keys of Dictionaries, see: # https://github.com/andyferris/Dictionaries.jl/issues/98 return DataGraph( @@ -172,13 +177,13 @@ function DataGraph{V}(graph::DataGraph) where {V} ) end -convert_vertextype(::Type{V}, graph::DataGraph{V}) where {V} = graph -function convert_vertextype(V::Type, graph::DataGraph) +GraphsExtensions.convert_vertextype(::Type{V}, graph::DataGraph{V}) where {V} = graph +function GraphsExtensions.convert_vertextype(V::Type, graph::DataGraph) return DataGraph{V}(graph) end # TODO: implement generic version in terms of `set_underlying_graph_type` -function directed_graph(G::Type{<:DataGraph}) +function GraphsExtensions.directed_graph(G::Type{<:DataGraph}) V = vertextype(G) VD = vertex_data_type(G) E = edgetype(G) diff --git a/src/traits/isunderlyinggraph.jl b/src/traits/isunderlyinggraph.jl index b3a985a..c63fb39 100644 --- a/src/traits/isunderlyinggraph.jl +++ b/src/traits/isunderlyinggraph.jl @@ -3,7 +3,11 @@ @traitimpl IsUnderlyingGraph{X} <- is_underlying_graph(X) #! format: on +using Graphs: AbstractGraph is_underlying_graph(::Type{<:AbstractGraph}) = false +using Graphs.SimpleGraphs: AbstractSimpleGraph is_underlying_graph(::Type{<:AbstractSimpleGraph}) = true + +using NamedGraphs: AbstractNamedGraph is_underlying_graph(::Type{<:AbstractNamedGraph}) = true diff --git a/test/runtests.jl b/test/runtests.jl index df6f655..18218a6 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,7 +1,9 @@ +@eval module $(gensym()) using DataGraphs using Dictionaries using Graphs -using NamedGraphs +using NamedGraphs.GraphsExtensions: ⊔, rename_vertices +using NamedGraphs.NamedGraphGenerators: named_grid, named_path_graph using Suppressor using Test @@ -314,3 +316,4 @@ using DataGraphs: is_arranged @test ps.pathcounts == dictionary([1 => 1.0, 2 => 1.0, 3 => 1.0, 4 => 1.0]) end end +end From ace82e56fdfe657a81ad871a533fcd17807c2884 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Tue, 16 Apr 2024 18:17:56 -0400 Subject: [PATCH 02/11] More namespace fixes --- examples/datagraph.jl | 6 +- examples/disjoint_union.jl | 8 +- examples/multidimdatagraph_1d.jl | 1 + examples/multidimdatagraph_2d.jl | 8 +- src/DataGraphs.jl | 131 +------------------------------ src/abstractdatagraph.jl | 3 +- src/arrange.jl | 3 + src/traits/isunderlyinggraph.jl | 2 + src/utils.jl | 1 + test/runtests.jl | 64 ++++++++++----- 10 files changed, 68 insertions(+), 159 deletions(-) create mode 100644 src/utils.jl diff --git a/examples/datagraph.jl b/examples/datagraph.jl index 4dbd176..c4f309c 100644 --- a/examples/datagraph.jl +++ b/examples/datagraph.jl @@ -1,8 +1,8 @@ -using DataGraphs -using Dictionaries -using Graphs +using DataGraphs: DataGraph +using Graphs: Edge, grid, has_edge, has_vertex g = grid((4,)) +# TODO: Change to `DataGraph(g; vertex_data_type=String, edge_data_type=String) dg = DataGraph(g, String, Symbol) @show !isassigned(dg, Edge(1, 2)) @show !isassigned(dg, 1 => 2) diff --git a/examples/disjoint_union.jl b/examples/disjoint_union.jl index 96af38e..2ddc415 100644 --- a/examples/disjoint_union.jl +++ b/examples/disjoint_union.jl @@ -1,7 +1,9 @@ -using Graphs -using NamedGraphs -using DataGraphs +using Graphs: edges, has_edge, has_vertex, ne, nv, vertices +using NamedGraphs.GraphsExtensions: ⊔ +using NamedGraphs.NamedGraphGenerators: named_grid +using DataGraphs: DataGraph +# TODO: Change to `DataGraph(g; vertex_data_type=String, edge_data_type=String) g = DataGraph(named_grid((2, 2)), String, String) for v in vertices(g) diff --git a/examples/multidimdatagraph_1d.jl b/examples/multidimdatagraph_1d.jl index a5bf039..408fada 100644 --- a/examples/multidimdatagraph_1d.jl +++ b/examples/multidimdatagraph_1d.jl @@ -3,6 +3,7 @@ using Graphs: grid, has_edge, has_vertex using NamedGraphs: NamedGraph, NamedEdge g = NamedGraph(grid((4,)), ["A", "B", "C", "D"]) +# TODO: Change to `DataGraph(g; vertex_data_type=String, edge_data_type=String) dg = DataGraph(g, String, Symbol) @show has_vertex(dg, "A") diff --git a/examples/multidimdatagraph_2d.jl b/examples/multidimdatagraph_2d.jl index 33f8d82..a4a2057 100644 --- a/examples/multidimdatagraph_2d.jl +++ b/examples/multidimdatagraph_2d.jl @@ -1,9 +1,9 @@ -using DataGraphs -using NamedGraphs -using Dictionaries -using Graphs +using DataGraphs: DataGraph +using NamedGraphs: NamedEdge +using NamedGraphs.NamedGraphGenerators: named_grid g = named_grid((2, 2)) +# TODO: Change to `DataGraph(g; vertex_data_type=String, edge_data_type=String) dg = DataGraph(g, String, String) dg[1, 1] = "X11" diff --git a/src/DataGraphs.jl b/src/DataGraphs.jl index 786392b..2d2a025 100644 --- a/src/DataGraphs.jl +++ b/src/DataGraphs.jl @@ -1,132 +1,9 @@ module DataGraphs -using Dictionaries -using Graphs -using Graphs.SimpleGraphs # AbstractSimpleGraph -using GraphsFlows -using NamedGraphs -using SimpleTraits - -using NamedGraphs: AbstractNamedGraph - -# -# imports -# - -import Base: - get, - getindex, - setindex!, - convert, - show, - isassigned, - eltype, - copy, - hvncat, - hcat, - vcat, - union, - zero - -import Graphs: - a_star, - adjacency_matrix, - add_edge!, - add_vertex!, - bellman_ford_shortest_paths, - bfs_parents, - bfs_tree, - boruvka_mst, - center, - common_neighbors, - connected_components, - connected_components!, - degree, - degree_histogram, - desopo_pape_shortest_paths, - dfs_parents, - dfs_tree, - diameter, - dijkstra_shortest_paths, - eccentricity, - edges, - edgetype, - enumerate_paths, - floyd_warshall_shortest_paths, - has_edge, - has_path, - has_vertex, - induced_subgraph, - inneighbors, - is_connected, - is_cyclic, - is_directed, - is_strongly_connected, - is_weakly_connected, - johnson_shortest_paths, - kruskal_mst, - merge_vertices, - merge_vertices!, - mincut, - ne, - neighbors, - neighborhood, - neighborhood_dists, - nv, - outneighbors, - periphery, - prim_mst, - radius, - rem_edge!, - rem_vertex!, - reverse, - spfa_shortest_paths, - steiner_tree, - topological_sort_by_dfs, - tree, - vertices, - yen_k_shortest_paths - -## # TODO: Can we remove the dependency on `NamedGraphs`? -## # Maybe need a `GraphExtensions.jl` or -## # `GraphInterfaces.jl` package. -## import NamedGraphs: -## ⊔, -## boundary_edges, -## boundary_vertices, -## convert_vertextype, -## directed_graph, -## disjoint_union, -## eccentricities, -## incident_edges, -## inner_boundary_vertices, -## outer_boundary_vertices, -## mincut_partitions, -## rename_vertices, -## symrcm, -## symrcm_permute, -## vertextype, -## parent_graph, -## parent_vertices_to_vertices - -# General functions -not_implemented() = error("Not implemented") - -include(joinpath("traits", "isunderlyinggraph.jl")) +include("utils.jl") +include("traits/isunderlyinggraph.jl") include("abstractdatagraph.jl") include("arrange.jl") include("datagraph.jl") -# -# exports -# - -export DataGraph, - AbstractDataGraph, - directed_graph, - disjoint_union, - map_vertex_data, - map_edge_data, - map_data, - ⊔ - -end # module DataGraphs +export AbstractDataGraph, DataGraph +end diff --git a/src/abstractdatagraph.jl b/src/abstractdatagraph.jl index 2068e10..2cb97e0 100644 --- a/src/abstractdatagraph.jl +++ b/src/abstractdatagraph.jl @@ -1,7 +1,8 @@ using Dictionaries: set!, unset! -using Graphs: Graphs, AbstractGraph, IsDirected, add_edge!, edges, vertices +using Graphs: Graphs, AbstractEdge, AbstractGraph, IsDirected, add_edge!, edges, vertices using NamedGraphs: NamedGraphs using NamedGraphs.GraphsExtensions: GraphsExtensions, incident_edges, vertextype +using SimpleTraits: SimpleTraits, @traitfn abstract type AbstractDataGraph{V,VD,ED} <: AbstractGraph{V} end diff --git a/src/arrange.jl b/src/arrange.jl index 1bf4330..8e861d1 100644 --- a/src/arrange.jl +++ b/src/arrange.jl @@ -1,3 +1,6 @@ +using Graphs: IsDirected, src, dst +using SimpleTraits: SimpleTraits, @traitfn + # TODO: Use a function `arrange` like in MetaGraphsNext: # https://github.com/JuliaGraphs/MetaGraphsNext.jl/blob/1539095ee6088aba0d5b1cb057c339ad92557889/src/metagraph.jl#L75-L80 # to sort the vertices, only directed graphs should store data diff --git a/src/traits/isunderlyinggraph.jl b/src/traits/isunderlyinggraph.jl index c63fb39..eae6029 100644 --- a/src/traits/isunderlyinggraph.jl +++ b/src/traits/isunderlyinggraph.jl @@ -1,3 +1,5 @@ +using SimpleTraits: SimpleTraits, @traitdef, @traitimpl + @traitdef IsUnderlyingGraph{X} #! format: off @traitimpl IsUnderlyingGraph{X} <- is_underlying_graph(X) diff --git a/src/utils.jl b/src/utils.jl new file mode 100644 index 0000000..d292515 --- /dev/null +++ b/src/utils.jl @@ -0,0 +1 @@ +not_implemented() = error("Not implemented") diff --git a/test/runtests.jl b/test/runtests.jl index 18218a6..b8b45df 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,20 +1,43 @@ @eval module $(gensym()) -using DataGraphs -using Dictionaries -using Graphs +using DataGraphs: DataGraph, is_arranged +using Dictionaries: Indices, dictionary +using Graphs: + add_edge!, + bfs_tree, + connected_components, + degree, + dfs_tree, + dijkstra_shortest_paths, + dst, + edges, + grid, + has_edge, + has_vertex, + indegree, + ne, + nv, + outdegree, + src, + vertices +using Graphs.SimpleGraphs: SimpleDiGraph, SimpleEdge, SimpleGraph +using NamedGraphs: NamedDiGraph, NamedGraph using NamedGraphs.GraphsExtensions: ⊔, rename_vertices using NamedGraphs.NamedGraphGenerators: named_grid, named_path_graph -using Suppressor -using Test +using Test: @test, @test_broken, @testset using DataGraphs: is_arranged @testset "DataGraphs.jl" begin - @testset "Examples" begin - examples_path = joinpath(pkgdir(DataGraphs), "examples") - @testset "Run examples: $filename" for filename in readdir(examples_path) - if endswith(filename, ".jl") - @suppress include(joinpath(examples_path, filename)) + @eval module $(gensym()) + using DataGraphs: DataGraphs + using Suppressor: @suppress + using Test: @testset + @testset "Examples" begin + examples_path = joinpath(pkgdir(DataGraphs), "examples") + @testset "Run examples: $filename" for filename in readdir(examples_path) + if endswith(filename, ".jl") + @suppress include(joinpath(examples_path, filename)) + end end end end @@ -41,9 +64,9 @@ using DataGraphs: is_arranged @testset "Basics" begin g = grid((4,)) dg = DataGraph{<:Any,String,Symbol}(g) - @test !isassigned(dg, Edge(1, 2)) + @test !isassigned(dg, SimpleEdge(1, 2)) @test !isassigned(dg, 1 => 2) - @test !isassigned(dg, Edge(1 => 2)) + @test !isassigned(dg, SimpleEdge(1 => 2)) @test !isassigned(dg, 1 => 3) @test !isassigned(dg, 1) @test !isassigned(dg, 2) @@ -78,11 +101,11 @@ using DataGraphs: is_arranged dg[1 => 2] = :E12 dg[2 => 3] = :E23 - dg[Edge(3, 4)] = :E34 + dg[SimpleEdge(3, 4)] = :E34 #@test isassigned(dg, (1, 2)) - @test isassigned(dg, Edge(2, 3)) + @test isassigned(dg, SimpleEdge(2, 3)) @test isassigned(dg, 3 => 4) - @test dg[Edge(1, 2)] == :E12 + @test dg[SimpleEdge(1, 2)] == :E12 @test dg[2 => 3] == :E23 @test dg[3 => 4] == :E34 @@ -93,7 +116,7 @@ using DataGraphs: is_arranged @test dg[(1, 1) => (1, (1, 1))] == "X" vdata = map(v -> "V$v", Indices(1:4)) - edata = map(e -> "E$(src(e))$(dst(e))", Indices([Edge(1, 2), Edge(2, 3), Edge(3, 4)])) + edata = map(e -> "E$(src(e))$(dst(e))", Indices(SimpleEdge.([1 => 2, 2 => 3, 3 => 4]))) dg = DataGraph(g, vdata, edata) @test dg[1] == "V1" @@ -105,12 +128,11 @@ using DataGraphs: is_arranged @test dg[2 => 3] == "E23" @test dg[3 => 4] == "E34" - @test DataGraph(g) isa - DataGraph{Int,Any,Any,SimpleGraph{Int},Graphs.SimpleGraphs.SimpleEdge{Int}} + @test DataGraph(g) isa DataGraph{Int,Any,Any,SimpleGraph{Int},SimpleEdge{Int}} @test DataGraph{<:Any,String}(g) isa - DataGraph{Int,String,Any,SimpleGraph{Int},Graphs.SimpleGraphs.SimpleEdge{Int}} + DataGraph{Int,String,Any,SimpleGraph{Int},SimpleEdge{Int}} @test DataGraph{<:Any,Any,String}(g) isa - DataGraph{Int,Any,String,SimpleGraph{Int},Graphs.SimpleGraphs.SimpleEdge{Int}} + DataGraph{Int,Any,String,SimpleGraph{Int},SimpleEdge{Int}} # TODO: is this needed? #@test DataGraph{<:Any,String}(g) isa DataGraph{Any,String} @@ -197,7 +219,7 @@ using DataGraphs: is_arranged g1[1] = ["A", "B", "C"] g1[1 => 2] = ["E", "F"] - g2 = DataGraph(Graph(5)) + g2 = DataGraph(SimpleGraph(5)) add_edge!(g2, 1 => 5) g2[1] = ["C", "D", "E"] From 31e29862f66a0a88e17fabe977dc465cf2602ae6 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Tue, 16 Apr 2024 18:29:30 -0400 Subject: [PATCH 03/11] Warn of future syntax change in examples --- examples/datagraph.jl | 3 ++- examples/disjoint_union.jl | 3 ++- examples/multidimdatagraph_1d.jl | 2 +- examples/multidimdatagraph_2d.jl | 3 ++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/examples/datagraph.jl b/examples/datagraph.jl index c4f309c..ae94ca6 100644 --- a/examples/datagraph.jl +++ b/examples/datagraph.jl @@ -2,7 +2,8 @@ using DataGraphs: DataGraph using Graphs: Edge, grid, has_edge, has_vertex g = grid((4,)) -# TODO: Change to `DataGraph(g; vertex_data_type=String, edge_data_type=String) +# TODO: Change to `DataGraph(g; vertex_data_eltype=String, edge_data_eltype=String) +# See: https://github.com/mtfishman/DataGraphs.jl/issues/26 dg = DataGraph(g, String, Symbol) @show !isassigned(dg, Edge(1, 2)) @show !isassigned(dg, 1 => 2) diff --git a/examples/disjoint_union.jl b/examples/disjoint_union.jl index 2ddc415..4d9640a 100644 --- a/examples/disjoint_union.jl +++ b/examples/disjoint_union.jl @@ -3,7 +3,8 @@ using NamedGraphs.GraphsExtensions: ⊔ using NamedGraphs.NamedGraphGenerators: named_grid using DataGraphs: DataGraph -# TODO: Change to `DataGraph(g; vertex_data_type=String, edge_data_type=String) +# TODO: Change to `DataGraph(g; vertex_data_eltype=String, edge_data_eltype=String) +# See: https://github.com/mtfishman/DataGraphs.jl/issues/26 g = DataGraph(named_grid((2, 2)), String, String) for v in vertices(g) diff --git a/examples/multidimdatagraph_1d.jl b/examples/multidimdatagraph_1d.jl index 408fada..9e1c48f 100644 --- a/examples/multidimdatagraph_1d.jl +++ b/examples/multidimdatagraph_1d.jl @@ -3,7 +3,7 @@ using Graphs: grid, has_edge, has_vertex using NamedGraphs: NamedGraph, NamedEdge g = NamedGraph(grid((4,)), ["A", "B", "C", "D"]) -# TODO: Change to `DataGraph(g; vertex_data_type=String, edge_data_type=String) +# TODO: Change to `DataGraph(g; vertex_data_eltype=String, edge_data_eltype=String) dg = DataGraph(g, String, Symbol) @show has_vertex(dg, "A") diff --git a/examples/multidimdatagraph_2d.jl b/examples/multidimdatagraph_2d.jl index a4a2057..8d8b45b 100644 --- a/examples/multidimdatagraph_2d.jl +++ b/examples/multidimdatagraph_2d.jl @@ -3,7 +3,8 @@ using NamedGraphs: NamedEdge using NamedGraphs.NamedGraphGenerators: named_grid g = named_grid((2, 2)) -# TODO: Change to `DataGraph(g; vertex_data_type=String, edge_data_type=String) +# TODO: Change to `DataGraph(g; vertex_data_eltype=String, edge_data_eltype=String) +# See: https://github.com/mtfishman/DataGraphs.jl/issues/26 dg = DataGraph(g, String, String) dg[1, 1] = "X11" From 32e0bfa15d51a48aef947c17f3cd08811fd962d2 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Tue, 16 Apr 2024 18:29:53 -0400 Subject: [PATCH 04/11] Comment --- examples/multidimdatagraph_1d.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/multidimdatagraph_1d.jl b/examples/multidimdatagraph_1d.jl index 9e1c48f..48de65b 100644 --- a/examples/multidimdatagraph_1d.jl +++ b/examples/multidimdatagraph_1d.jl @@ -4,6 +4,7 @@ using NamedGraphs: NamedGraph, NamedEdge g = NamedGraph(grid((4,)), ["A", "B", "C", "D"]) # TODO: Change to `DataGraph(g; vertex_data_eltype=String, edge_data_eltype=String) +# See: https://github.com/mtfishman/DataGraphs.jl/issues/26 dg = DataGraph(g, String, Symbol) @show has_vertex(dg, "A") From a04568556c4a53976edf0318d0646f9dddce4254 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Tue, 16 Apr 2024 19:29:35 -0400 Subject: [PATCH 05/11] Simplfy DataGraph constructors --- examples/datagraph.jl | 4 +- examples/disjoint_union.jl | 4 +- examples/multidimdatagraph_1d.jl | 4 +- examples/multidimdatagraph_2d.jl | 4 +- examples/slicing.jl | 2 +- src/abstractdatagraph.jl | 32 +++--- src/datagraph.jl | 184 ++++++++----------------------- test/runtests.jl | 24 ++-- 8 files changed, 80 insertions(+), 178 deletions(-) diff --git a/examples/datagraph.jl b/examples/datagraph.jl index ae94ca6..f46c305 100644 --- a/examples/datagraph.jl +++ b/examples/datagraph.jl @@ -2,9 +2,7 @@ using DataGraphs: DataGraph using Graphs: Edge, grid, has_edge, has_vertex g = grid((4,)) -# TODO: Change to `DataGraph(g; vertex_data_eltype=String, edge_data_eltype=String) -# See: https://github.com/mtfishman/DataGraphs.jl/issues/26 -dg = DataGraph(g, String, Symbol) +dg = DataGraph(g; vertex_data_eltype=String, edge_data_eltype=Symbol) @show !isassigned(dg, Edge(1, 2)) @show !isassigned(dg, 1 => 2) @show !isassigned(dg, Edge(1 => 2)) diff --git a/examples/disjoint_union.jl b/examples/disjoint_union.jl index 4d9640a..51685a7 100644 --- a/examples/disjoint_union.jl +++ b/examples/disjoint_union.jl @@ -3,9 +3,7 @@ using NamedGraphs.GraphsExtensions: ⊔ using NamedGraphs.NamedGraphGenerators: named_grid using DataGraphs: DataGraph -# TODO: Change to `DataGraph(g; vertex_data_eltype=String, edge_data_eltype=String) -# See: https://github.com/mtfishman/DataGraphs.jl/issues/26 -g = DataGraph(named_grid((2, 2)), String, String) +g = DataGraph(g; vertex_data_eltype=String, edge_data_eltype=String) for v in vertices(g) g[v] = "V$v" diff --git a/examples/multidimdatagraph_1d.jl b/examples/multidimdatagraph_1d.jl index 48de65b..2a06681 100644 --- a/examples/multidimdatagraph_1d.jl +++ b/examples/multidimdatagraph_1d.jl @@ -3,9 +3,7 @@ using Graphs: grid, has_edge, has_vertex using NamedGraphs: NamedGraph, NamedEdge g = NamedGraph(grid((4,)), ["A", "B", "C", "D"]) -# TODO: Change to `DataGraph(g; vertex_data_eltype=String, edge_data_eltype=String) -# See: https://github.com/mtfishman/DataGraphs.jl/issues/26 -dg = DataGraph(g, String, Symbol) +dg = DataGraph(g; vertex_data_eltype=String, edge_data_eltype=Symbol) @show has_vertex(dg, "A") @show has_vertex(dg, "D") diff --git a/examples/multidimdatagraph_2d.jl b/examples/multidimdatagraph_2d.jl index 8d8b45b..92ff83e 100644 --- a/examples/multidimdatagraph_2d.jl +++ b/examples/multidimdatagraph_2d.jl @@ -3,9 +3,7 @@ using NamedGraphs: NamedEdge using NamedGraphs.NamedGraphGenerators: named_grid g = named_grid((2, 2)) -# TODO: Change to `DataGraph(g; vertex_data_eltype=String, edge_data_eltype=String) -# See: https://github.com/mtfishman/DataGraphs.jl/issues/26 -dg = DataGraph(g, String, String) +dg = DataGraph(g; vertex_data_eltype=String, edge_data_eltype=String) dg[1, 1] = "X11" diff --git a/examples/slicing.jl b/examples/slicing.jl index bbfe877..85b0644 100644 --- a/examples/slicing.jl +++ b/examples/slicing.jl @@ -4,7 +4,7 @@ using NamedGraphs.NamedGraphGenerators: named_grid using Graphs: ne, nv g = named_grid((2, 2)) -dg = DataGraph(g, String, String) +dg = DataGraph(g; vertex_data_eltype=String, edge_data_eltype=String) dg[1, 1] = "V11" dg[1, 2] = "V12" diff --git a/src/abstractdatagraph.jl b/src/abstractdatagraph.jl index 2cb97e0..01e7807 100644 --- a/src/abstractdatagraph.jl +++ b/src/abstractdatagraph.jl @@ -16,26 +16,28 @@ end underlying_graph(::AbstractDataGraph) = not_implemented() underlying_graph_type(::Type{<:AbstractDataGraph}) = not_implemented() vertex_data(::AbstractDataGraph) = not_implemented() -vertex_data_type(::Type{<:AbstractDataGraph}) = not_implemented() +vertex_data_eltype(::Type{<:AbstractDataGraph}) = not_implemented() edge_data(::AbstractDataGraph) = not_implemented() -edge_data_type(::Type{<:AbstractDataGraph}) = not_implemented() +edge_data_eltype(::Type{<:AbstractDataGraph}) = not_implemented() # Derived interface -Graphs.edgetype(G::Type{<:AbstractDataGraph}) = Graphs.edgetype(underlying_graph_type(G)) -function Graphs.is_directed(G::Type{<:AbstractDataGraph}) - return Graphs.is_directed(underlying_graph_type(G)) +function Graphs.edgetype(graph_type::Type{<:AbstractDataGraph}) + return Graphs.edgetype(underlying_graph_type(graph_type)) +end +function Graphs.is_directed(graph_type::Type{<:AbstractDataGraph}) + return Graphs.is_directed(underlying_graph_type(graph_type)) end underlying_graph_type(graph::AbstractDataGraph) = typeof(underlying_graph(graph)) -vertex_data_type(graph::AbstractDataGraph) = vertex_data_type(typeof(graph)) -edge_data_type(graph::AbstractDataGraph) = edge_data_type(typeof(graph)) +vertex_data_eltype(graph::AbstractDataGraph) = eltype(vertex_data(graph)) +edge_data_eltype(graph::AbstractDataGraph) = eltype(edge_data(graph)) # TODO: delete, defined for AbstractGraph{V}? -function GraphsExtensions.vertextype(G::Type{<:AbstractDataGraph}) - return vertextype(underlying_graph_type(G)) +function GraphsExtensions.vertextype(graph_type::Type{<:AbstractDataGraph}) + return vertextype(underlying_graph_type(graph_type)) end GraphsExtensions.vertextype(graph::AbstractDataGraph) = vertextype(typeof(graph)) -Base.zero(G::Type{<:AbstractDataGraph}) = G() +Base.zero(graph_type::Type{<:AbstractDataGraph}) = graph_type() # Graphs overloads for f in [ @@ -211,7 +213,7 @@ function Base.union( vertex_data_merge = mergewith(merge_vertex_data, vertex_data(graph1), vertex_data(graph2)) edge_data_merge = mergewith(merge_edge_data, edge_data(graph1), edge_data(graph2)) # TODO: Convert to `promote_type(typeof(graph1), typeof(graph2))` - return DataGraph(underlying_graph_union, vertex_data_merge, edge_data_merge) + return _DataGraph(underlying_graph_union, vertex_data_merge, edge_data_merge) end function Base.union( @@ -228,10 +230,10 @@ function GraphsExtensions.rename_vertices(f::Function, graph::AbstractDataGraph) renamed_underlying_graph = GraphsExtensions.rename_vertices(f, underlying_graph(graph)) # TODO: Base the ouput type on `typeof(graph)`, for example: # convert_vertextype(eltype(renamed_vertices), typeof(graph))(renamed_underlying_graph) - renamed_graph = DataGraph{ - vertextype(renamed_underlying_graph),vertex_data_type(graph),edge_data_type(graph) - }( - renamed_underlying_graph + renamed_graph = DataGraph( + renamed_underlying_graph; + vertex_data_eltype=vertex_data_eltype(graph), + edge_data_eltype=edge_data_eltype(graph), ) for v in keys(vertex_data(graph)) renamed_graph[f(v)] = graph[v] diff --git a/src/datagraph.jl b/src/datagraph.jl index f997899..ec9ad42 100644 --- a/src/datagraph.jl +++ b/src/datagraph.jl @@ -5,7 +5,6 @@ using NamedGraphs.GraphsExtensions: directed_graph, vertextype # TODO: define VertexDataGraph, a graph with only data on the # vertices, and EdgeDataGraph, a graph with only data on the edges. -# TODO: Constrain `E<:AbstractEdge`. # TODO: Use https://github.com/vtjnash/ComputedFieldTypes.jl to # automatically determine `E` from `G` from `edgetype(G)` # and `V` from `G` as `vertextype(G)`. @@ -13,26 +12,28 @@ struct DataGraph{V,VD,ED,G<:AbstractGraph,E<:AbstractEdge} <: AbstractDataGraph{ underlying_graph::G vertex_data::Dictionary{V,VD} edge_data::Dictionary{E,ED} - function DataGraph{V,VD,ED,G,E}( - underlying_graph::G, vertex_data::Dictionary{V,VD}, edge_data::Dictionary{E,ED} - ) where {V,VD,ED,G<:AbstractGraph,E<:AbstractEdge} - @assert vertextype(underlying_graph) == V - @assert edgetype(underlying_graph) == E - return new{V,VD,ED,G,E}(underlying_graph, vertex_data, edge_data) + global function _DataGraph( + underlying_graph::AbstractGraph, vertex_data::Dictionary, edge_data::Dictionary + ) + return new{ + vertextype(underlying_graph), + eltype(vertex_data), + eltype(edge_data), + typeof(underlying_graph), + edgetype(underlying_graph), + }( + underlying_graph, vertex_data, edge_data + ) end end underlying_graph_type(G::Type{<:DataGraph}) = fieldtype(G, :underlying_graph) -# TODO: rename vertex_data_eltype -vertex_data_type(G::Type{<:DataGraph}) = eltype(fieldtype(G, :vertex_data)) -# TODO: rename edge_data_eltype -edge_data_type(G::Type{<:DataGraph}) = eltype(fieldtype(G, :edge_data)) +vertex_data_eltype(G::Type{<:DataGraph}) = eltype(fieldtype(G, :vertex_data)) +edge_data_eltype(G::Type{<:DataGraph}) = eltype(fieldtype(G, :edge_data)) underlying_graph(graph::DataGraph) = getfield(graph, :underlying_graph) vertex_data(graph::DataGraph) = getfield(graph, :vertex_data) edge_data(graph::DataGraph) = getfield(graph, :edge_data) -# TODO: Is this needed? -underlying_graph_type(graph::DataGraph) = typeof(underlying_graph(graph)) -# TODO: Is this needed? +# TODO: Is this needed? Maybe define a generic `AbstractDataGraph` version. Graphs.is_directed(G::Type{<:DataGraph}) = Graphs.is_directed(underlying_graph_type(G)) # TODO: Implement in terms of `set_underlying_graph`, `set_vertex_data`, etc. @@ -40,126 +41,29 @@ Graphs.is_directed(G::Type{<:DataGraph}) = Graphs.is_directed(underlying_graph_t function Base.copy(graph::DataGraph) # Need to manually copy the keys of Dictionaries, see: # https://github.com/andyferris/Dictionaries.jl/issues/98 - return DataGraph( + return _DataGraph( copy(underlying_graph(graph)), copy(vertex_data(graph)), copy(edge_data(graph)) ) end -# -# Constructors -# - -function DataGraph{V,VD,ED,G,E}( - underlying_graph::AbstractGraph=G(), - vertex_data::Dictionary=Dictionary{V,VD}(), - edge_data::Dictionary=Dictionary{E,ED}(), -) where {V,VD,ED,G,E} - return DataGraph{V,VD,ED,G,E}( - convert(G, underlying_graph), - convert(Dictionary{V,VD}, vertex_data), - convert(Dictionary{E,ED}, edge_data), - ) -end - -function DataGraph{V,VD,ED}( - underlying_graph::AbstractGraph{V}, - vertex_data::Dictionary=Dictionary{V,VD}(), - edge_data::Dictionary=Dictionary{edgetype(underlying_graph),ED}(), -) where {V,VD,ED} - G = typeof(underlying_graph) - E = edgetype(underlying_graph) - return DataGraph{V,VD,ED,G,E}(underlying_graph, vertex_data, edge_data) -end - -function DataGraph{V,VD,ED}( - underlying_graph::AbstractGraph=NamedGraph{V}(), - vertex_data::Dictionary=Dictionary{V,VD}(), - edge_data::Dictionary=Dictionary{edgetype(underlying_graph),ED}(), -) where {V,VD,ED} - return DataGraph{V,VD,ED}(convert_vertextype(V, underlying_graph), vertex_data, edge_data) -end - -function DataGraph{<:Any,VD,ED}( - underlying_graph::AbstractGraph, - vertex_data::Dictionary=Dictionary{vertextype(underlying_graph),VD}(), - edge_data::Dictionary=Dictionary{edgetype(underlying_graph),ED}(), -) where {VD,ED} - V = vertextype(underlying_graph) - return DataGraph{V,VD,ED}(underlying_graph, vertex_data, edge_data) -end - -function DataGraph{V,VD}( - underlying_graph::AbstractGraph=NamedGraph{V}(), - vertex_data::Dictionary=Dictionary{V,VD}(), - edge_data::Dictionary=Dictionary{edgetype(underlying_graph),Any}(), -) where {V,VD} - ED = eltype(edge_data) - return DataGraph{V,VD,ED}(underlying_graph, vertex_data, edge_data) -end - -function DataGraph{<:Any,VD}( - underlying_graph::AbstractGraph, - vertex_data::Dictionary=Dictionary{vertextype(underlying_graph),VD}(), - edge_data::Dictionary=Dictionary{edgetype(underlying_graph),Any}(), -) where {VD} - V = vertextype(underlying_graph) - ED = eltype(edge_data) - return DataGraph{V,VD,ED}(underlying_graph, vertex_data, edge_data) -end - -function DataGraph{V}( - underlying_graph::AbstractGraph=NamedGraph{V}(), - vertex_data::Dictionary=Dictionary{V,Any}(), - edge_data::Dictionary=Dictionary{edgetype(underlying_graph),Any}(), -) where {V} - VD = eltype(vertex_data) - ED = eltype(edge_data) - return DataGraph{V,VD,ED}(underlying_graph, vertex_data, edge_data) -end - function DataGraph( - underlying_graph::AbstractGraph=NamedGraph{Any}(), - vertex_data::Dictionary=Dictionary{vertextype(underlying_graph),Any}(), - edge_data::Dictionary=Dictionary{edgetype(underlying_graph),Any}(), + underlying_graph::AbstractGraph; vertex_data_eltype::Type=Any, edge_data_eltype::Type=Any ) - V = vertextype(underlying_graph) - return DataGraph{V}(underlying_graph, vertex_data, edge_data) -end - -# -# Type interface -# - -function DataGraph{V}(underlying_graph::AbstractGraph, VD::Type, ED::Type=Any) where {V} - return DataGraph{V,VD,ED}(underlying_graph) -end - -function DataGraph(underlying_graph::AbstractGraph, VD::Type, ED::Type=Any) - V = vertextype(underlying_graph) - return DataGraph{V,VD,ED}(underlying_graph) + return _DataGraph( + underlying_graph, + Dictionary{vertextype(underlying_graph),vertex_data_eltype}(), + Dictionary{edgetype(underlying_graph),edge_data_eltype}(), + ) end -# -# Convenience constructors for simple graphs -# - -function DataGraph{V,VD,ED,G,E}(nv::Integer, args...) where {V,VD,ED,G,E} - return DataGraph{V,VD,ED,G,E}(SimpleGraph(nv), args...) -end -function DataGraph{V,VD,ED}(nv::Integer, args...) where {V,VD,ED} - return DataGraph{V,VD,ED}(SimpleGraph(nv), args...) -end -function DataGraph{<:Any,VD,ED}(nv::Integer, args...) where {VD,ED} - return DataGraph{<:Any,VD,ED}(SimpleGraph(nv), args...) -end -function DataGraph{V,VD}(nv::Integer, args...) where {V,VD} - return DataGraph{V,VD}(SimpleGraph(nv), args...) -end -function DataGraph{<:Any,VD}(nv::Integer, args...) where {VD} - return DataGraph{<:Any,VD}(SimpleGraph(nv), args...) +function DataGraph{V,VD,ED,G,E}(underlying_graph::AbstractGraph) where {V,VD,ED,G,E} + @assert edgetype(underlying_graph) === E + return _DataGraph( + convert(G, underlying_graph), + Dictionary{V,VD}(), + Dictionary{E,ED}(), + ) end -DataGraph{V}(nv::Integer, args...) where {V} = DataGraph{V}(SimpleGraph(nv), args...) -DataGraph(nv::Integer, args...) = DataGraph(SimpleGraph(nv), args...) # Type conversions DataGraph{V,VD,ED,G}(graph::DataGraph{V,VD,ED,G}) where {V,VD,ED,G} = copy(graph) @@ -167,27 +71,29 @@ DataGraph{V,VD,ED}(graph::DataGraph{V,VD,ED}) where {V,VD,ED} = copy(graph) DataGraph{V,VD}(graph::DataGraph{V,VD}) where {V,VD} = copy(graph) DataGraph{V}(graph::DataGraph{V}) where {V} = copy(graph) function DataGraph{V}(graph::DataGraph) where {V} - E = convert_vertextype(V, edgetype(graph)) # TODO: Make sure this properly copies converted_underlying_graph = convert_vertextype(V, underlying_graph(graph)) converted_vertex_data = Dictionary{V}(vertex_data(graph)) - converted_edge_data = Dictionary{E}(edge_data(graph)) + converted_edge_data = Dictionary{edgetype(converted_underlying_graph)}(edge_data(graph)) return DataGraph{V}( converted_underlying_graph, converted_vertex_data, converted_edge_data ) end +# TODO: Move to `DataGraphsNamedGraphsExt`. GraphsExtensions.convert_vertextype(::Type{V}, graph::DataGraph{V}) where {V} = graph -function GraphsExtensions.convert_vertextype(V::Type, graph::DataGraph) - return DataGraph{V}(graph) -end - -# TODO: implement generic version in terms of `set_underlying_graph_type` -function GraphsExtensions.directed_graph(G::Type{<:DataGraph}) - V = vertextype(G) - VD = vertex_data_type(G) - E = edgetype(G) - ED = edge_data_type(G) - UG = underlying_graph_type(G) - return DataGraph{V,VD,ED,directed_graph(UG),E} +function GraphsExtensions.convert_vertextype(vertextype::Type, graph::DataGraph) + return DataGraph{vertextype}(graph) +end + +# TODO: Move to `DataGraphsNamedGraphsExt`. +# TODO: implement generic version in terms of `set_underlying_graph_type`. +function GraphsExtensions.directed_graph_type(graph_type::Type{<:DataGraph}) + return DataGraph{ + vertextype(graph_type), + vertex_data_eltype(graph_type), + edgetype(graph_type), + directed_graph_type(underlying_graph_type(graph_type)), + edgetype(graph_type), + } end diff --git a/test/runtests.jl b/test/runtests.jl index b8b45df..07b59e9 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,5 +1,5 @@ @eval module $(gensym()) -using DataGraphs: DataGraph, is_arranged +using DataGraphs: DataGraphs, DataGraph, is_arranged using Dictionaries: Indices, dictionary using Graphs: add_edge!, @@ -63,7 +63,7 @@ using DataGraphs: is_arranged @testset "Basics" begin g = grid((4,)) - dg = DataGraph{<:Any,String,Symbol}(g) + dg = DataGraph(g; vertex_data_eltype=String, edge_data_eltype=Symbol) @test !isassigned(dg, SimpleEdge(1, 2)) @test !isassigned(dg, 1 => 2) @test !isassigned(dg, SimpleEdge(1 => 2)) @@ -117,7 +117,16 @@ using DataGraphs: is_arranged vdata = map(v -> "V$v", Indices(1:4)) edata = map(e -> "E$(src(e))$(dst(e))", Indices(SimpleEdge.([1 => 2, 2 => 3, 3 => 4]))) - dg = DataGraph(g, vdata, edata) + # TODO: Make a more compact constructor that directly accepts + # vertex and edge data? Maybe `DataGraph(g; vertex_data=vdata, edge_data=edata)` + # or `DataGraph(g; vertex_data=v -> "V$v", edge_data=e -> "E$(src(e))$(dst(e))")`. + dg = DataGraph(g; vertex_data_eltype=eltype(vdata), edge_data_eltype=eltype(edata)) + for v in vertices(dg) + dg[v] = vdata[v] + end + for e in edges(dg) + dg[e] = edata[e] + end @test dg[1] == "V1" @test dg[2] == "V2" @@ -129,13 +138,6 @@ using DataGraphs: is_arranged @test dg[3 => 4] == "E34" @test DataGraph(g) isa DataGraph{Int,Any,Any,SimpleGraph{Int},SimpleEdge{Int}} - @test DataGraph{<:Any,String}(g) isa - DataGraph{Int,String,Any,SimpleGraph{Int},SimpleEdge{Int}} - @test DataGraph{<:Any,Any,String}(g) isa - DataGraph{Int,Any,String,SimpleGraph{Int},SimpleEdge{Int}} - - # TODO: is this needed? - #@test DataGraph{<:Any,String}(g) isa DataGraph{Any,String} # Vertices with mixed types dg = DataGraph(NamedGraph(grid((4,)), [1, "X", 2, "Y"])) @@ -172,7 +174,7 @@ using DataGraphs: is_arranged end @testset "Disjoint unions" begin - g = DataGraph{<:Any,String,String}(named_grid((2, 2))) + g = DataGraph(named_grid((2, 2)); vertex_data_eltype=String, edge_data_eltype=String) for v in vertices(g) g[v] = "V$v" From afb5bd614aca52e2b9af11bf205ee1175bf38048 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Tue, 16 Apr 2024 19:30:07 -0400 Subject: [PATCH 06/11] Format --- src/datagraph.jl | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/datagraph.jl b/src/datagraph.jl index ec9ad42..0ab561f 100644 --- a/src/datagraph.jl +++ b/src/datagraph.jl @@ -58,11 +58,7 @@ end function DataGraph{V,VD,ED,G,E}(underlying_graph::AbstractGraph) where {V,VD,ED,G,E} @assert edgetype(underlying_graph) === E - return _DataGraph( - convert(G, underlying_graph), - Dictionary{V,VD}(), - Dictionary{E,ED}(), - ) + return _DataGraph(convert(G, underlying_graph), Dictionary{V,VD}(), Dictionary{E,ED}()) end # Type conversions From ad322b6e37d4ebfe4eb7f75986350602e335953d Mon Sep 17 00:00:00 2001 From: mtfishman Date: Tue, 16 Apr 2024 19:59:23 -0400 Subject: [PATCH 07/11] Fix tests --- examples/disjoint_union.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/disjoint_union.jl b/examples/disjoint_union.jl index 51685a7..f06ea4d 100644 --- a/examples/disjoint_union.jl +++ b/examples/disjoint_union.jl @@ -3,7 +3,7 @@ using NamedGraphs.GraphsExtensions: ⊔ using NamedGraphs.NamedGraphGenerators: named_grid using DataGraphs: DataGraph -g = DataGraph(g; vertex_data_eltype=String, edge_data_eltype=String) +g = DataGraph(named_grid((2, 2)); vertex_data_eltype=String, edge_data_eltype=String) for v in vertices(g) g[v] = "V$v" From e829796bfc5526f72b0b3b9f39cbb2f4d174ccd3 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Tue, 16 Apr 2024 20:30:53 -0400 Subject: [PATCH 08/11] Package extensions --- Project.toml | 11 ++++++++++- .../DataGraphsGraphsFlowsExt.jl | 8 ++++++++ .../DataGraphsNamedGraphsExt.jl | 17 +++++++++++++++++ src/DataGraphs.jl | 3 +++ src/abstractdatagraph.jl | 9 --------- src/datagraph.jl | 2 -- src/traits/isunderlyinggraph.jl | 3 --- test/Project.toml | 1 + test/runtests.jl | 12 ++++++++++++ 9 files changed, 51 insertions(+), 15 deletions(-) create mode 100644 ext/DataGraphsGraphsFlowsExt/DataGraphsGraphsFlowsExt.jl create mode 100644 ext/DataGraphsNamedGraphsExt/DataGraphsNamedGraphsExt.jl diff --git a/Project.toml b/Project.toml index b8b4676..c9301fd 100644 --- a/Project.toml +++ b/Project.toml @@ -6,10 +6,17 @@ version = "0.2.0" [deps] Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" -GraphsFlows = "06909019-6f44-4949-96fc-b9d9aaa02889" NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19" SimpleTraits = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +[weakdeps] +GraphsFlows = "06909019-6f44-4949-96fc-b9d9aaa02889" +# NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19" + +[extensions] +DataGraphsGraphsFlowsExt = "GraphsFlows" +# DataGraphsNamedGraphsExt = "GraphsFlows" + [compat] Dictionaries = "0.4" Graphs = "1" @@ -19,6 +26,8 @@ SimpleTraits = "0.9" julia = "1.7" [extras] +GraphsFlows = "06909019-6f44-4949-96fc-b9d9aaa02889" +# NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] diff --git a/ext/DataGraphsGraphsFlowsExt/DataGraphsGraphsFlowsExt.jl b/ext/DataGraphsGraphsFlowsExt/DataGraphsGraphsFlowsExt.jl new file mode 100644 index 0000000..e6bf45c --- /dev/null +++ b/ext/DataGraphsGraphsFlowsExt/DataGraphsGraphsFlowsExt.jl @@ -0,0 +1,8 @@ +module DataGraphsGraphsFlowsExt +using DataGraphs: AbstractDataGraph, underlying_graph +using GraphsFlows: GraphsFlows + +function GraphsFlows.mincut(graph::AbstractDataGraph, args...; kwargs...) + return GraphsFlows.mincut(underlying_graph(graph), args...; kwargs...) +end +end diff --git a/ext/DataGraphsNamedGraphsExt/DataGraphsNamedGraphsExt.jl b/ext/DataGraphsNamedGraphsExt/DataGraphsNamedGraphsExt.jl new file mode 100644 index 0000000..b0048fe --- /dev/null +++ b/ext/DataGraphsNamedGraphsExt/DataGraphsNamedGraphsExt.jl @@ -0,0 +1,17 @@ +module DataGraphsNamedGraphsExt +using DataGraphs: DataGraphs, AbstractDataGraph, underlying_graph +using NamedGraphs: NamedGraphs, AbstractNamedGraph + +DataGraphs.is_underlying_graph(::Type{<:AbstractNamedGraph}) = true + +for f in [ + :(NamedGraphs.parent_graph), + :(NamedGraphs.parent_vertices_to_vertices), +] + @eval begin + function $f(graph::AbstractDataGraph, args...; kwargs...) + return $f(underlying_graph(graph), args...; kwargs...) + end + end +end +end diff --git a/src/DataGraphs.jl b/src/DataGraphs.jl index 2d2a025..6620304 100644 --- a/src/DataGraphs.jl +++ b/src/DataGraphs.jl @@ -4,6 +4,9 @@ include("traits/isunderlyinggraph.jl") include("abstractdatagraph.jl") include("arrange.jl") include("datagraph.jl") +# TODO: Turn into a weak dependency once `GraphsExtensions` +# is split off from `NamedGraphs`. +include("../ext/DataGraphsNamedGraphsExt/DataGraphsNamedGraphsExt.jl") export AbstractDataGraph, DataGraph end diff --git a/src/abstractdatagraph.jl b/src/abstractdatagraph.jl index 01e7807..d3f0c02 100644 --- a/src/abstractdatagraph.jl +++ b/src/abstractdatagraph.jl @@ -1,17 +1,10 @@ using Dictionaries: set!, unset! using Graphs: Graphs, AbstractEdge, AbstractGraph, IsDirected, add_edge!, edges, vertices -using NamedGraphs: NamedGraphs using NamedGraphs.GraphsExtensions: GraphsExtensions, incident_edges, vertextype using SimpleTraits: SimpleTraits, @traitfn abstract type AbstractDataGraph{V,VD,ED} <: AbstractGraph{V} end -# TODO: Move to `DataGraphsGraphsFlowsExt`. -using GraphsFlows: GraphsFlows -function GraphsFlows.mincut(graph::AbstractDataGraph, args...; kwargs...) - return GraphsFlows.mincut(underlying_graph(graph), args...; kwargs...) -end - # Minimal interface underlying_graph(::AbstractDataGraph) = not_implemented() underlying_graph_type(::Type{<:AbstractDataGraph}) = not_implemented() @@ -100,8 +93,6 @@ for f in [ :(GraphsExtensions.outer_boundary_vertices), :(GraphsExtensions.symrcm_perm), :(GraphsExtensions.symrcm_permute), - :(NamedGraphs.parent_graph), - :(NamedGraphs.parent_vertices_to_vertices), ] @eval begin function $f(graph::AbstractDataGraph, args...; kwargs...) diff --git a/src/datagraph.jl b/src/datagraph.jl index 0ab561f..718bf08 100644 --- a/src/datagraph.jl +++ b/src/datagraph.jl @@ -76,13 +76,11 @@ function DataGraph{V}(graph::DataGraph) where {V} ) end -# TODO: Move to `DataGraphsNamedGraphsExt`. GraphsExtensions.convert_vertextype(::Type{V}, graph::DataGraph{V}) where {V} = graph function GraphsExtensions.convert_vertextype(vertextype::Type, graph::DataGraph) return DataGraph{vertextype}(graph) end -# TODO: Move to `DataGraphsNamedGraphsExt`. # TODO: implement generic version in terms of `set_underlying_graph_type`. function GraphsExtensions.directed_graph_type(graph_type::Type{<:DataGraph}) return DataGraph{ diff --git a/src/traits/isunderlyinggraph.jl b/src/traits/isunderlyinggraph.jl index eae6029..6afb1dd 100644 --- a/src/traits/isunderlyinggraph.jl +++ b/src/traits/isunderlyinggraph.jl @@ -10,6 +10,3 @@ is_underlying_graph(::Type{<:AbstractGraph}) = false using Graphs.SimpleGraphs: AbstractSimpleGraph is_underlying_graph(::Type{<:AbstractSimpleGraph}) = true - -using NamedGraphs: AbstractNamedGraph -is_underlying_graph(::Type{<:AbstractNamedGraph}) = true diff --git a/test/Project.toml b/test/Project.toml index 9237873..7bbf4af 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -2,6 +2,7 @@ DataGraphs = "b5a273c3-7e6c-41f6-98bd-8d7f1525a36a" Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" +GraphsFlows = "06909019-6f44-4949-96fc-b9d9aaa02889" NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19" Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/test/runtests.jl b/test/runtests.jl index 07b59e9..31df4a3 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -17,9 +17,11 @@ using Graphs: ne, nv, outdegree, + path_graph, src, vertices using Graphs.SimpleGraphs: SimpleDiGraph, SimpleEdge, SimpleGraph +using GraphsFlows: GraphsFlows using NamedGraphs: NamedDiGraph, NamedGraph using NamedGraphs.GraphsExtensions: ⊔, rename_vertices using NamedGraphs.NamedGraphGenerators: named_grid, named_path_graph @@ -339,5 +341,15 @@ using DataGraphs: is_arranged @test ps.parents == dictionary([1 => 1, 2 => 1, 3 => 2, 4 => 3]) @test ps.pathcounts == dictionary([1 => 1.0, 2 => 1.0, 3 => 1.0, 4 => 1.0]) end + @testset "GraphsFlows.mincut (vertextype=$(eltype(verts))" for verts in ( + [1, 2, 3, 4], + ["A", "B", "C", "D"], + ) + g = DataGraph(NamedGraph(path_graph(4), verts)) + part1, part2, flow = GraphsFlows.mincut(g, verts[1], verts[4]) + @test verts[1] ∈ part1 + @test verts[4] ∈ part2 + @test flow == 1 + end end end From 0d6299f954e81fcf3e6d1c4d047e0866d21cfbf8 Mon Sep 17 00:00:00 2001 From: Matt Fishman Date: Tue, 16 Apr 2024 20:35:02 -0400 Subject: [PATCH 09/11] Format Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- ext/DataGraphsNamedGraphsExt/DataGraphsNamedGraphsExt.jl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ext/DataGraphsNamedGraphsExt/DataGraphsNamedGraphsExt.jl b/ext/DataGraphsNamedGraphsExt/DataGraphsNamedGraphsExt.jl index b0048fe..136db5e 100644 --- a/ext/DataGraphsNamedGraphsExt/DataGraphsNamedGraphsExt.jl +++ b/ext/DataGraphsNamedGraphsExt/DataGraphsNamedGraphsExt.jl @@ -4,10 +4,7 @@ using NamedGraphs: NamedGraphs, AbstractNamedGraph DataGraphs.is_underlying_graph(::Type{<:AbstractNamedGraph}) = true -for f in [ - :(NamedGraphs.parent_graph), - :(NamedGraphs.parent_vertices_to_vertices), -] +for f in [:(NamedGraphs.parent_graph), :(NamedGraphs.parent_vertices_to_vertices)] @eval begin function $f(graph::AbstractDataGraph, args...; kwargs...) return $f(underlying_graph(graph), args...; kwargs...) From ab1bc17ed8036c16e6e563106746f803776a4326 Mon Sep 17 00:00:00 2001 From: Matt Fishman Date: Tue, 16 Apr 2024 20:35:10 -0400 Subject: [PATCH 10/11] Format Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- test/runtests.jl | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 31df4a3..bb1f738 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -342,14 +342,13 @@ using DataGraphs: is_arranged @test ps.pathcounts == dictionary([1 => 1.0, 2 => 1.0, 3 => 1.0, 4 => 1.0]) end @testset "GraphsFlows.mincut (vertextype=$(eltype(verts))" for verts in ( - [1, 2, 3, 4], - ["A", "B", "C", "D"], - ) - g = DataGraph(NamedGraph(path_graph(4), verts)) - part1, part2, flow = GraphsFlows.mincut(g, verts[1], verts[4]) - @test verts[1] ∈ part1 - @test verts[4] ∈ part2 - @test flow == 1 + [1, 2, 3, 4], ["A", "B", "C", "D"] + ) + g = DataGraph(NamedGraph(path_graph(4), verts)) + part1, part2, flow = GraphsFlows.mincut(g, verts[1], verts[4]) + @test verts[1] ∈ part1 + @test verts[4] ∈ part2 + @test flow == 1 end end end From 063aa2f9cd253941db0b9123ee05bcbea958cbec Mon Sep 17 00:00:00 2001 From: mtfishman Date: Tue, 16 Apr 2024 20:54:01 -0400 Subject: [PATCH 11/11] PackageExtensionCompat --- Project.toml | 5 ++--- src/DataGraphs.jl | 5 +++++ src/abstractdatagraph.jl | 3 ++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Project.toml b/Project.toml index c9301fd..3864a4c 100644 --- a/Project.toml +++ b/Project.toml @@ -7,27 +7,26 @@ version = "0.2.0" Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19" +PackageExtensionCompat = "65ce6f38-6b18-4e1d-a461-8949797d7930" SimpleTraits = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" [weakdeps] GraphsFlows = "06909019-6f44-4949-96fc-b9d9aaa02889" -# NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19" [extensions] DataGraphsGraphsFlowsExt = "GraphsFlows" -# DataGraphsNamedGraphsExt = "GraphsFlows" [compat] Dictionaries = "0.4" Graphs = "1" GraphsFlows = "0.1.1" NamedGraphs = "0.4" +PackageExtensionCompat = "1" SimpleTraits = "0.9" julia = "1.7" [extras] GraphsFlows = "06909019-6f44-4949-96fc-b9d9aaa02889" -# NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] diff --git a/src/DataGraphs.jl b/src/DataGraphs.jl index 6620304..c603b91 100644 --- a/src/DataGraphs.jl +++ b/src/DataGraphs.jl @@ -9,4 +9,9 @@ include("datagraph.jl") include("../ext/DataGraphsNamedGraphsExt/DataGraphsNamedGraphsExt.jl") export AbstractDataGraph, DataGraph + +using PackageExtensionCompat: @require_extensions +function __init__() + @require_extensions +end end diff --git a/src/abstractdatagraph.jl b/src/abstractdatagraph.jl index d3f0c02..389fa95 100644 --- a/src/abstractdatagraph.jl +++ b/src/abstractdatagraph.jl @@ -1,5 +1,6 @@ using Dictionaries: set!, unset! -using Graphs: Graphs, AbstractEdge, AbstractGraph, IsDirected, add_edge!, edges, vertices +using Graphs: + Graphs, AbstractEdge, AbstractGraph, IsDirected, add_edge!, edges, ne, nv, vertices using NamedGraphs.GraphsExtensions: GraphsExtensions, incident_edges, vertextype using SimpleTraits: SimpleTraits, @traitfn