Skip to content

reachableGraph loops on cyclic input

GHC.Data.Graph.Directed.reachableGraph calculates a reachability map for its input graph: mapping a vertex to the set of vertices that are its transitive, directed neighbours.

For cyclic input, the current implementation returns a map where some of the values diverge. This can be demonstrated even in the simplest case of the one-vertex one-edge graph.

For reference, the current implementation is:

reachableGraph :: IntGraph -> IM.IntMap IS.IntSet
reachableGraph g = res
  where
    do_one v = IS.unions (IS.fromList (g ! v) : mapMaybe (flip IM.lookup res) (g ! v))
    res = IM.fromList [(v, do_one v) | v <- vertices g]

For g = {0 -> [0]}, this creates the map res = {0 -> mu r. IS.unions [IS.fromList [0], r]} since g ! 0 is [0] and thus mapMaybe (flip IM.lookup res) [0] is [r]. We're effectively creating the set IS.fromList (fix (0:)), which diverges.

Edited by sheaf
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information