MetaGraphsNext.jl
MetaGraphsNext.jl copied to clipboard
voluntary Labels support
It would be nice if there was a version of MetaGraphs that didn't need the explicit label definition from the user.
I guess something similar to AttributeGraphs.jl. OAttributeGraph
models the vertex properties as a Vector
and switches the elements for every vertex deletion, etc.
Here in MetaGraphsNext.jl the data structure is hardcored to be Dict{Label,Tuple{Code,VertexData}}
. Ofc the user could make a Label being an Int. But at the moment s/he will also need to maintain it, which is a bother.
@gdalle suggested a MetaGraph
subtype with automatic labeling. I am not sure why would you need a subtype ??
I was thinking something like interfacing a keyword in the constructor default_labeling=false
that when it's true, we take over and make it so that label::Int=code::Int
at any state.
Maybe not a subtype, but at the very least an additional boolean attribute to store g.default_labeling
?
hm. now that I am thinking about it, it would be good if we could statically dispatch, because probably some function will need different implementation (e.g. rem_vertex should update indices). I guess that's where you were going with the subtype thing.
Having g.default_labeling
is nice but we need to check during runtime on what to do.
Except if we don't make that field boolean but a parameterized type we can dispatch with:
abstract type AbstractMode
struct DefaultMode <: AbstractMode
struct NoLabelsMode <: AbstractMode
struct MetaGraph{...,Mode<:AbstractMode,...}
...
mode::Mode
...
end
Graphs.rem_vertex(mg::MetaGraphs{...,m::DefaultMode,...}) = ...
Graphs.rem_vertex(mg::MetaGraphs{...,m::NoLabelsMode,...}) = ...
this can also work nicely with traits.
I still think that the constructor should have something like default_labeling=false
to be more user-friendly.
I was also thinking we could statically dispatch on whether LabelType = Int
or not (a type we used to forbid). But maybe there are scenarios where you want integer labels that differ from the codes, for instance because they are non continuous?
I cannot imagine well about the use cases, but I can also not exclude that someone might want to do this. I am not sure whether we should take this for granted or not.
One option would be to split the package into two: LabeledGraphs
and PropertyGraphs
(names tbd). The features are fairly separable. It would require a lot of rewriting though, especially because we would have to attach metadata to codes instead of labels.
I think splitting is not the answer: it makes it harder for newcomers to understand which package they want, plus sometimes you need both. Ideally our package could provide both functionalities, combined or not. The question is how many structs / metaprogramming tricks we need to do that with minimal code duplication
Maybe we could do a rewrite where the default vertex id is the classic integer, and then we use a @labels
macro whenever we want to use labels as ids and/or get labels as outputs. I'll try and give it a shot
Drawing lots of inspiration from @filchristou
The draft implementation is on branch optional_labels
. It's a near complete rewrite which would allow using the following syntax:
using MetaGraphsNext, Graphs
cities = UnlabeledMetaGraph(Graph(); vertex_data_type=String, edge_data_type=Float64)
add_vertex!(cities, "Paris")
add_vertex!(cities, "Berlin")
cities[1, 2] = 1000.0;
capitals = LabeledMetaGraph(
Graph(), Symbol; vertex_data_type=String, edge_data_type=Float64
)
add_vertex!(capitals, :France, "Paris")
add_vertex!(capitals, :Germany, "Berlin")
add_vertex!(capitals, :Italy, "Rome")
capitals[1, 2] = 1000.0;
@labels capitals[:France, :Italy] = 2000.0;
@filchristou this will probably be made obsolete by the new GraphsBase.jl, but we can still discuss it if you need it in the meantime
Is the plan to migrate MetaGraphsNext.jl
's code into GraphsBase.jl
?
More like rewrite it from scratch