src/main/java/de/dfki/lt/loot/fsa/algo/MinimizationBrzowski.java
private static <EdgeInfo> void propagate(AbstractAutomaton<EdgeInfo> graph,
    Graph<EdgeInfo> converse,
    Comparator<EdgeInfo> comp, int i, int j, BitSet notEquivalent) {

    int nodesLength = graph.getNumberOfVertices();

    if (converse.getOutEdges(i) == null || converse.getOutEdges(j) == null) return;

    // iterate over incoming edges of node i
    for (Edge<EdgeInfo> iEdge : converse.getOutEdges(i)) {

      // get transition char
      EdgeInfo iTrans = iEdge.getInfo();
      // get start node
      int iStartVertex = iEdge.getSource();

      // search for incoming edges of node j with the same transition char
      for (Edge<EdgeInfo> jEdge : converse.getOutEdges(j)) {

        // get transition char
        EdgeInfo jTrans = jEdge.getInfo();

        // we can skip the incoming edges with smaller edge info
        int compResult = comp.compare(jTrans, iTrans);
        // if (compResult < 0) { continue; }

        if (compResult == 0) {
          // get start node
          int jStartVertex = jEdge.getSource();
          // switch start node indices, so that iStartVertex always contains the
          // larger index; required because we use a LOWER triangular matrix
          if (iStartVertex < jStartVertex) {
            int temp = iStartVertex;
            iStartVertex = jStartVertex;
            jStartVertex = temp;
          }
          // check if the start nodes are marked as equivalen; if yes, mark them
          // as non-equivalent and propagate the change
          int index = jStartVertex * nodesLength + iStartVertex;
          if (! notEquivalent.get(index)) {
            notEquivalent.set(index);
            propagate(graph, converse, comp,
                iStartVertex, jStartVertex, notEquivalent);
          }
          continue;
        }

        // when we're here, this means that jTrans > iTrans; we can then stop
        // searching since the edges are sorted
        // break;
      }
    }
  }
/**
   * This propagates a non-equivalence between two nodes (identified by their
   * given indices in the given array) in the given matrix.
   *
   * @param nodes an array of <code>Vertex</code>s
   * @param i an <code>int</code> with the index of the first node
   * @param j an <code>int</code> with the index of the second node
   * @param equivalent a <code>boolean</code> matrix that contains a
   * <code>false</code> at matrix[i][j] (if i > j; vice versa otherwise)
   */
This propagates a non-equivalence between two nodes (identified by their
given indices in the given array) in the given matrix.

@param nodes an array of Vertexs
@param i an int with the index of the first node
@param j an int with the index of the second node
@param equivalent a boolean matrix that contains a
false at matrix[i][j] (if i > j; vice versa otherwise)
This propagates a non - equivalence between two nodes ( identified by their given indices in the given array ) in the given matrix . @param nodes an array of Vertexs @param i an int with the index of the first node @param j an int with the index of the second node @param equivalent a boolean matrix that contains a false at matrix [ i ] [ j ] ( if i > j ; vice versa otherwise )
private static <EdgeInfo> void propagate(AbstractAutomaton<EdgeInfo> graph,
    Graph<EdgeInfo> converse,
    Comparator<EdgeInfo> comp, int i, int j, BitSet notEquivalent) {
    int nodesLength = graph.getNumberOfVertices();
    if (converse.getOutEdges(i) == null || converse.getOutEdges(j) == null) return;
    for (Edge<EdgeInfo> iEdge : converse.getOutEdges(i)) {
      EdgeInfo iTrans = iEdge.getInfo();
      int iStartVertex = iEdge.getSource();
      for (Edge<EdgeInfo> jEdge : converse.getOutEdges(j)) {
        EdgeInfo jTrans = jEdge.getInfo();
        int compResult = comp.compare(jTrans, iTrans);
        if (compResult == 0) {
          int jStartVertex = jEdge.getSource();
          if (iStartVertex < jStartVertex) {
            int temp = iStartVertex;
            iStartVertex = jStartVertex;
            jStartVertex = temp;
          }
          int index = jStartVertex * nodesLength + iStartVertex;
          if (! notEquivalent.get(index)) {
            notEquivalent.set(index);
            propagate(graph, converse, comp,
                iStartVertex, jStartVertex, notEquivalent);
          }
          continue;
        }
      }
    }
  }
private static < EdgeInfo > void propagate ( AbstractAutomaton < EdgeInfo > graph , Graph < EdgeInfo > converse , Comparator < EdgeInfo > comp , int i , int j , BitSet notEquivalent ) { int nodesLength = graph . getNumberOfVertices ( ) ; if ( converse . getOutEdges ( i ) == null || converse . getOutEdges ( j ) == null ) return ; for ( Edge < EdgeInfo > iEdge : converse . getOutEdges ( i ) ) { EdgeInfo iTrans = iEdge . getInfo ( ) ; int iStartVertex = iEdge . getSource ( ) ; for ( Edge < EdgeInfo > jEdge : converse . getOutEdges ( j ) ) { EdgeInfo jTrans = jEdge . getInfo ( ) ; int compResult = comp . compare ( jTrans , iTrans ) ; if ( compResult == 0 ) { int jStartVertex = jEdge . getSource ( ) ; if ( iStartVertex < jStartVertex ) { int temp = iStartVertex ; iStartVertex = jStartVertex ; jStartVertex = temp ; } int index = jStartVertex * nodesLength + iStartVertex ; if ( ! notEquivalent . get ( index ) ) { notEquivalent . set ( index ) ; propagate ( graph , converse , comp , iStartVertex , jStartVertex , notEquivalent ) ; } continue ; } } } }
This propagates a non-equivalence between two nodes (identified by their
 given indices in the given array) in the given matrix.
This propagates a non - equivalence between two nodes ( identified by their given indices in the given array ) in the given matrix .
// iterate over incoming edges of node i // get transition char // get start node // search for incoming edges of node j with the same transition char // get transition char // we can skip the incoming edges with smaller edge info // if (compResult < 0) { continue; } // get start node // switch start node indices, so that iStartVertex always contains the // larger index; required because we use a LOWER triangular matrix // check if the start nodes are marked as equivalen; if yes, mark them // as non-equivalent and propagate the change // when we're here, this means that jTrans > iTrans; we can then stop // searching since the edges are sorted // break;