sbromberger/LightGraphs.jl

[BUG] Infinite recursion when using UnitRange for target vertices in enumerate_paths

mattwigway opened this issue · 2 comments

Description of bug
When you call enumerate_paths(path_state, target_vertices) with target_vertices being a UnitRange (e.g. 1:4), infinite recursion occurs.

How to reproduce
Call enumerate_paths with targets being a UnitRange.

Expected behavior
Ideally it would return paths to the vertices specified by the UnitRange. Alternately, a MethodError would be acceptable.

Actual behavior
Infinite recursion. The issue is that enumerate_paths(state, ::UnitRange) does not match the signature of enumerate_paths(state::AbstractPathState, vs::Vector{<:Integer}), however it does match the signature of enumerate_paths(state::AbstractPathState, v) which is the convenience function to pass a vertex into enumerate_paths directly without wrapping it in an array. The issue is that that function then calls enumerate_paths(state, [v]), which still does not match the signature of the main enumerate_paths function but does match the signature of the convenience function, so it calls itself with enumerate_paths(state, [[v]]) ad infinitum.

I think the solution is that the v parameter to the convenience function should be annotated ::Integer, which should lead to a MethodError. Changing the main function to have the signature enumerate_paths(state::AbstractPathState, vs::AbstractVector{<:Integer}) would additionally allow UnitRanges to be used as targets. In any case the v parameter to the convenience function should be annotated so we can't get an infinite recursion situation even if someone passes some other type of incorrect input.

I'm happy to put together a pull request if this seems like a good course of action. I don't fully understand the Julia typing system yet, so I am not completely positive this change won't introduce type instability, but I think it shouldn't.

Code demonstrating bug

using LightGraphs

G = random_regular_digraph(10, 2)

@info "running Dijkstra"
djstate = dijkstra_shortest_paths(G, [1], allpaths=true)

@info "enumerating paths"
paths = enumerate_paths(djstate, 3:4)
# this next line will never be reached
@info "done"

Version information

  • output from versioninfo() surrounded by backticks (``)

Commit 788b2c77c1 (2020-11-09 13:37 UTC)
Platform Info:
OS: macOS (x86_64-apple-darwin18.7.0)
CPU: Intel(R) Core(TM) i7-5557U CPU @ 3.10GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-9.0.1 (ORCJIT, broadwell)

 - output from `] status LightGraphs` surrounded by backticks (``)
  ```Status `~/lightgraph_test/Project.toml`
  [093fc24a] LightGraphs v1.3.5```


**Additional context**
Add any other context about the problem here.

Thanks for this report. I think the best course of action is to change the enumerate_paths(state::AbstractPathState, vs::Vector{<:Integer}) signature to enumerate_paths(state::AbstractPathState, vs::AbstractVector{<:Integer}), and to change enumerate_paths(state::AbstractPathState, v) to enumerate_paths(state::AbstractPathState, v::Integer). Could you try a PR with that? (Also include a test with a unit range.)

Will do, thanks!