ordered_scc

Function ordered_scc 

Source
pub fn ordered_scc<Id: NodeTrait + Debug, O: Ord>(
    graph: &DiGraphMap<Id, ()>,
    sort_by: impl Fn(&Id) -> O,
) -> Vec<Vec<Id>>
Expand description

Compute the SCCs (Strongly Connected Components) of a set of identifiers, where the order of the SCCs and the order of the identifiers inside the SCCs attempt to respect as much as possible the sort order given. The provided sort_by should be cheap.

This is used to generate the translated definitions in a consistent and stable manner. For instance, let’s say we extract 4 definitions f, g1, g2 and h, where:

  • g1 and g2 are mutually recursive
  • h calls g1

When translating those functions, we group together the mutually recursive functions, because they have to be extracted in one single group, and thus apply Tarjan’s algorithm on the call graph to find out which functions are mutually recursive. The implementation of Tarjan’s algorithm we use gives us the Strongly Connected SCCs of the call graph in an arbitrary order, so we can have: [[f], [g1, g2], [h]], but also [[h], [f], [g2, g1]], etc.

If the user defined those functions in the order: f, g1, h, g2, we want to reorder them into: f, g1, g2, h, so that we can translate the mutually recursive functions together, while performing a minimal amount of reordering. And if reordering is not needed, because the user defined those functions in the order f, g1, g2, h, or g1, g2, f, h or … then we want to translate them in this exact order.

The order in which Tarjan’s algorithm generates the SCCs is arbitrary, while we want to keep as much as possible the original order (the order in which the user generated the ids). For this, we iterate through the ordered ids and try to add the SCC containing the id to a new list of SCCs Of course, this SCC might have dependencies, so we need to add the dependencies first (in which case we have reordering to do). This is what this function does: we add an SCC and its dependencies to the list of reordered SCCs by doing a depth-first search.