MetaGraphsNext.jl icon indicating copy to clipboard operation
MetaGraphsNext.jl copied to clipboard

voluntary Labels support

Open filchristou opened this issue 1 year ago • 12 comments

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.

filchristou avatar May 01 '23 13:05 filchristou

Maybe not a subtype, but at the very least an additional boolean attribute to store g.default_labeling?

gdalle avatar May 01 '23 15:05 gdalle

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.

filchristou avatar May 01 '23 15:05 filchristou

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?

gdalle avatar May 01 '23 15:05 gdalle

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.

filchristou avatar May 01 '23 16:05 filchristou

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.

bramtayl avatar May 05 '23 11:05 bramtayl

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

gdalle avatar May 05 '23 17:05 gdalle

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

gdalle avatar May 11 '23 08:05 gdalle

Drawing lots of inspiration from @filchristou

gdalle avatar May 11 '23 09:05 gdalle

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;

gdalle avatar May 11 '23 14:05 gdalle

@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

gdalle avatar Jul 02 '23 20:07 gdalle

Is the plan to migrate MetaGraphsNext.jl's code into GraphsBase.jl ?

filchristou avatar Jul 04 '23 09:07 filchristou

More like rewrite it from scratch

gdalle avatar Jul 04 '23 18:07 gdalle