package.lisp @ 884333cfb6fb v1.3.2

Detect *all* cycles during topological sort

Previously the cycle detection was limited to detecting when we hit
a currently-being-visited node during a traversal.  So something like this would
be correctly found:

    A --> B --> C
          ^     |
          |     |
          +-----+

We start at the root (A), go to B, then to C, then to B, and detect that we're
still working on B and signal the error.

But this doesn't find all cycles, because we *start* at the root nodes, and if
a cycle doesn't have any outcropping branches we'll never reach it at all.  For
example:

    A --> B
    ^     |
    |     |
    +-----+

This graph has no roots, so we incorrectly ignore the cycle.

This patch fixes the problem by keeping a count of visited nodes and and making
sure it matches the digraph's size at the end.

Fixes https://github.com/sjl/cl-digraph/issues/4
author Steve Losh <steve@stevelosh.com>
date Mon, 14 Dec 2020 20:13:51 -0500
parents 0434eb58dde3
children 7e80eda84170
(defpackage :digraph
  (:use :cl :digraph.quickutils)
  (:export
    :digraph
    :make-digraph

    :emptyp

    :vertices
    :edges

    :arbitrary-vertex

    :roots
    :leafs

    :rootp
    :leafp

    :predecessors
    :successors
    :neighbors

    :contains-vertex-p
    :contains-edge-p

    :insert-vertex
    :insert-edge

    :remove-edge
    :remove-vertex

    :degree
    :degree-in
    :degree-out

    :count-vertices
    :count-edges

    :mapc-vertices
    :mapc-edges
    :map-vertices
    :map-edges

    :map-depth-first
    :map-breadth-first
    :mapc-depth-first
    :mapc-breadth-first

    :topological-sort

    :reachablep

    :copy-digraph))