diff --git a/Project.toml b/Project.toml index 1ef0f7a..7afd5e7 100644 --- a/Project.toml +++ b/Project.toml @@ -8,9 +8,16 @@ JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" SimpleTraits = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" [compat] +Aqua = "0.8" +BenchmarkTools = "1" +Documenter = "1" Graphs = "1.4.1" +InteractiveUtils = "1" JLD2 = "0.1.11, 0.2, 0.3, 0.4" +JuliaFormatter = "1" +MetaGraphs = "0.7" SimpleTraits = "0.9" +Test = "1" julia = "1.6" [extras] diff --git a/src/graphs.jl b/src/graphs.jl index a4c098b..29696fc 100644 --- a/src/graphs.jl +++ b/src/graphs.jl @@ -44,6 +44,7 @@ function Graphs.outneighbors(meta_graph::MetaGraph, code::Integer) end function Base.issubset(meta_graph::MetaGraph, h::MetaGraph) + # no checking of: matching vertex label, or matching edge data return issubset(meta_graph.graph, h.graph) end @@ -267,10 +268,8 @@ function Base.zero(meta_graph::MetaGraph) ) end -function Graphs.induced_subgraph( - meta_graph::MetaGraph, vertex_codes::AbstractVector{<:Integer} -) - inducedgraph, code_map = induced_subgraph(meta_graph.graph, vertex_codes) +function meta_induced_subgraph(meta_graph::MetaGraph, selector) + inducedgraph, code_map = induced_subgraph(meta_graph.graph, selector) new_graph = MetaGraph( inducedgraph, empty(meta_graph.vertex_labels), @@ -284,6 +283,19 @@ function Graphs.induced_subgraph( return new_graph, code_map end +function Graphs.induced_subgraph( + meta_graph::MetaGraph, vertex_codes::AbstractVector{<:Integer} +) + return meta_induced_subgraph(meta_graph, vertex_codes) +end + +function Graphs.induced_subgraph( + meta_graph::MetaGraph, edges::AbstractVector{<:AbstractEdge} +) + # separate method to avoid dispatch ambiguity + return meta_induced_subgraph(meta_graph, edges) +end + @traitfn function Graphs.reverse(meta_graph::MG) where {MG <: MetaGraph; IsDirected{MG}} edge_data = meta_graph.edge_data reverse_edge_data = empty(edge_data) diff --git a/test/tutorial/2_graphs.jl b/test/tutorial/2_graphs.jl index 612fcf4..404c481 100644 --- a/test/tutorial/2_graphs.jl +++ b/test/tutorial/2_graphs.jl @@ -134,7 +134,7 @@ haskey(rock_paper_scissors, :scissors, :rock) haskey(reverse(rock_paper_scissors), :scissors, :rock) @test haskey(reverse(rock_paper_scissors), :scissors, :rock) #src -# Finally, let us take a subgraph: +# Let us take a subgraph induced by a subset of vertices: rock_paper, _ = induced_subgraph(rock_paper_scissors, [1, 2]) @test @inferred induced_subgraph(rock_paper_scissors, [1, 2])[1] == rock_paper #src @@ -147,3 +147,25 @@ haskey(rock_paper, :paper, :rock) #- haskey(rock_paper, :rock, :scissors) @test !haskey(rock_paper, :rock, :scissors) #src + +# Subgraphs can also be induced by a subset of edges. + +subtree_edges = collect(edges(rock_paper_scissors))[2:3] +rock_paper_scissors_subtree, _ = induced_subgraph(rock_paper_scissors, subtree_edges) +issubset(rock_paper_scissors_subtree, rock_paper_scissors) +ne(rock_paper_scissors_subtree) +@test ne(rock_paper_scissors_subtree) == 2 #src +#- +nv(rock_paper_scissors_subtree) +@test nv(rock_paper_scissors_subtree) == 3 #src +#- +[rock_paper_scissors_subtree[e...] for e in edge_labels(rock_paper_scissors_subtree)] + +# Checking that a graph is a subset of another is not supported yet. For example, an induced subgraph may appear as not a subset of the original graph, if vertex codes were modified. + +issubset(rock_paper_scissors_subtree, rock_paper_scissors) +@test_broken issubset(rock_paper_scissors_subtree, rock_paper_scissors) #src +#- +rock_scissors, _ = induced_subgraph(rock_paper_scissors, [1, 3]) +issubset(rock_scissors, rock_paper_scissors) +@test_broken issubset(rock_scissors, rock_paper_scissors) #src