protected boolean _findCanonicalLabelling(boolean tmpPreviouslyEqualToMin){
  boolean foundNewMinimum=false;
  IntArrayList underlyingVertexPosThatExtendTmp=getUnderlyingVertexPosThatExtendTmp();
  IntCursor underlyingVertexPosThatExtendTmpCursor=underlyingVertexPosThatExtendTmp.cursor();
  while (underlyingVertexPosThatExtendTmpCursor.moveNext()) {
    int underlyingVertexPosToAdd=underlyingVertexPosThatExtendTmpCursor.elem();
    int newTmpVertexPos=addTmpVertex(underlyingVertexPosToAdd);
    int newTmpVertexLabel=underlyingPosToLabel.getUnchecked(underlyingVertexPosToAdd);
    IntSet neighbourUnderlyingPositions=underlyingAdjacencyList.get(underlyingVertexPosToAdd);
    IntCursor neighbourUnderlyingPositionsCursor=neighbourUnderlyingPositions.cursor();
    PatternEdgeArrayList edgesToAdd=createPatternEdgeArrayList();
    while (neighbourUnderlyingPositionsCursor.moveNext()) {
      int neighbourUnderlyingPos=neighbourUnderlyingPositionsCursor.elem();
      int neighbourTmpPos=tmpLabelling.get(neighbourUnderlyingPos);
      if (neighbourTmpPos == -1) {
        continue;
      }
      addCandidatePatternEdges(edgesToAdd,neighbourUnderlyingPos,neighbourTmpPos,underlyingVertexPosToAdd,newTmpVertexPos);
    }
    if (edgesToAdd.size() > 0 || newTmpVertexPos == 0) {
      edgesToAdd.sort();
      boolean promisingTmpPattern=true;
      boolean equalToMinTmpPattern=tmpPreviouslyEqualToMin;
      if (foundMinimum) {
        int comparisonResult;
        if (newTmpVertexPos > 0) {
          PatternEdgeArrayList minEquivalentEdges=minEdges.get(newTmpVertexPos);
          comparisonResult=edgesToAdd.compareTo(minEquivalentEdges);
        }
 else {
          int minFirstUnderlyingVertexPos=minInverseLabelling.get(newTmpVertexPos);
          int minFirstUnderylingVertexLabel=underlyingPosToLabel.getUnchecked(minFirstUnderlyingVertexPos);
          comparisonResult=Integer.compare(newTmpVertexLabel,minFirstUnderylingVertexLabel);
        }
        equalToMinTmpPattern=equalToMinTmpPattern && comparisonResult == 0;
        if (tmpPreviouslyEqualToMin && !equalToMinTmpPattern) {
          if (comparisonResult > 0) {
            promisingTmpPattern=false;
          }
        }
      }
      if (promisingTmpPattern) {
        addTmpEdges(edgesToAdd);
        if (tmpLabelling.size() == getNumberOfVertices()) {
          if (!equalToMinTmpPattern || !foundMinimum) {
            copyTmpToMin();
            foundNewMinimum=true;
            vertexPositionEquivalences.clear();
          }
          IntIntCursor tmpLabellingCursor=tmpLabelling.cursor();
          while (tmpLabellingCursor.moveNext()) {
            int underlyingPos=tmpLabellingCursor.key();
            int tmpEquivalentPos=tmpLabellingCursor.value();
            int underlyingPosAccordingToMin=minInverseLabelling.get(tmpEquivalentPos);
            vertexPositionEquivalences.addEquivalence(underlyingPos,underlyingPosAccordingToMin);
          }
        }
 else {
          boolean foundNewMinimumInChild=_findCanonicalLabelling(equalToMinTmpPattern);
          if (foundNewMinimumInChild) {
            tmpPreviouslyEqualToMin=true;
            foundNewMinimum=true;
          }
        }
        removeLastTmpEdges();
      }
 else {
        edgesToAdd.reclaim();
      }
    }
    removeLastTmpVertex();
  }
  underlyingVertexPosThatExtendTmp.reclaim();
  return foundNewMinimum;
}

protected boolean _findCanonicalLabelling ( boolean tmpPreviouslyEqualToMin ) { boolean foundNewMinimum = false ; IntArrayList underlyingVertexPosThatExtendTmp = getUnderlyingVertexPosThatExtendTmp ( ) ; IntCursor underlyingVertexPosThatExtendTmpCursor = underlyingVertexPosThatExtendTmp . cursor ( ) ; while ( underlyingVertexPosThatExtendTmpCursor . moveNext ( ) ) { int underlyingVertexPosToAdd = underlyingVertexPosThatExtendTmpCursor . elem ( ) ; int newTmpVertexPos = addTmpVertex ( underlyingVertexPosToAdd ) ; int newTmpVertexLabel = underlyingPosToLabel . getUnchecked ( underlyingVertexPosToAdd ) ; IntSet neighbourUnderlyingPositions = underlyingAdjacencyList . get ( underlyingVertexPosToAdd ) ; IntCursor neighbourUnderlyingPositionsCursor = neighbourUnderlyingPositions . cursor ( ) ; PatternEdgeArrayList edgesToAdd = createPatternEdgeArrayList ( ) ; while ( neighbourUnderlyingPositionsCursor . moveNext ( ) ) { int neighbourUnderlyingPos = neighbourUnderlyingPositionsCursor . elem ( ) ; int neighbourTmpPos = tmpLabelling . get ( neighbourUnderlyingPos ) ; if ( neighbourTmpPos == - 1 ) { continue ; } addCandidatePatternEdges ( edgesToAdd , neighbourUnderlyingPos , neighbourTmpPos , underlyingVertexPosToAdd , newTmpVertexPos ) ; } if ( edgesToAdd . size ( ) > 0 || newTmpVertexPos == 0 ) { edgesToAdd . sort ( ) ; boolean promisingTmpPattern = true ; boolean equalToMinTmpPattern = tmpPreviouslyEqualToMin ; if ( foundMinimum ) { int comparisonResult ; if ( newTmpVertexPos > 0 ) { PatternEdgeArrayList minEquivalentEdges = minEdges . get ( newTmpVertexPos ) ; comparisonResult = edgesToAdd . compareTo ( minEquivalentEdges ) ; } else { int minFirstUnderlyingVertexPos = minInverseLabelling . get ( newTmpVertexPos ) ; int minFirstUnderylingVertexLabel = underlyingPosToLabel . getUnchecked ( minFirstUnderlyingVertexPos ) ; comparisonResult = Integer . compare ( newTmpVertexLabel , minFirstUnderylingVertexLabel ) ; } equalToMinTmpPattern = equalToMinTmpPattern && comparisonResult == 0 ; if ( tmpPreviouslyEqualToMin && ! equalToMinTmpPattern ) { if ( comparisonResult > 0 ) { promisingTmpPattern = false ; } } } if ( promisingTmpPattern ) { addTmpEdges ( edgesToAdd ) ; if ( tmpLabelling . size ( ) == getNumberOfVertices ( ) ) { if ( ! equalToMinTmpPattern || ! foundMinimum ) { copyTmpToMin ( ) ; foundNewMinimum = true ; vertexPositionEquivalences . clear ( ) ; } IntIntCursor tmpLabellingCursor = tmpLabelling . cursor ( ) ; while ( tmpLabellingCursor . moveNext ( ) ) { int underlyingPos = tmpLabellingCursor . key ( ) ; int tmpEquivalentPos = tmpLabellingCursor . value ( ) ; int underlyingPosAccordingToMin = minInverseLabelling . get ( tmpEquivalentPos ) ; vertexPositionEquivalences . addEquivalence ( underlyingPos , underlyingPosAccordingToMin ) ; } } else { boolean foundNewMinimumInChild = _findCanonicalLabelling ( equalToMinTmpPattern ) ; if ( foundNewMinimumInChild ) { tmpPreviouslyEqualToMin = true ; foundNewMinimum = true ; } } removeLastTmpEdges ( ) ; } else { edgesToAdd . reclaim ( ) ; } } removeLastTmpVertex ( ) ; } underlyingVertexPosThatExtendTmp . reclaim ( ) ; return foundNewMinimum ; }
find the canonical labelling by increasing a tmppattern one vertex at a time and comparing it with the previous minimum .
