question: public static Grammar doTheMerges ( Grammar grammar , Lexicon lexicon , boolean [ ] [ ] [ ] mergeThesePairs , double [ ] [ ] mergeWeights ) { short [ ] numSubStatesArray = grammar . numSubStates ; short [ ] newNumSubStatesArray = grammar . numSubStates ; Grammar newGrammar = null ; while ( true ) { boolean somethingToMerge = false ; for ( int tag = 0 ; tag < numSubStatesArray . length ; tag ++ ) { for ( int i = 0 ; i < newNumSubStatesArray [ tag ] ; i ++ ) { for ( int j = 0 ; j < newNumSubStatesArray [ tag ] ; j ++ ) { somethingToMerge = somethingToMerge || mergeThesePairs [ tag ] [ i ] [ j ] ; } } } if ( ! somethingToMerge ) break ; boolean [ ] [ ] [ ] mergeThisIteration = new boolean [ newNumSubStatesArray . length ] [ ] [ ] ; for ( int tag = 0 ; tag < numSubStatesArray . length ; tag ++ ) { mergeThisIteration [ tag ] = new boolean [ mergeThesePairs [ tag ] . length ] [ mergeThesePairs [ tag ] . length ] ; for ( int i = 0 ; i < mergeThesePairs [ tag ] . length ; i ++ ) { for ( int j = 0 ; j < mergeThesePairs [ tag ] . length ; j ++ ) { mergeThisIteration [ tag ] [ i ] [ j ] = mergeThesePairs [ tag ] [ i ] [ j ] ; } } } for ( int tag = 0 ; tag < numSubStatesArray . length ; tag ++ ) { boolean [ ] alreadyDecidedToMerge = new boolean [ mergeThesePairs [ tag ] . length ] ; for ( int i = 0 ; i < mergeThesePairs [ tag ] . length ; i ++ ) { for ( int j = 0 ; j < mergeThesePairs [ tag ] . length ; j ++ ) { if ( alreadyDecidedToMerge [ i ] || alreadyDecidedToMerge [ j ] ) mergeThisIteration [ tag ] [ i ] [ j ] = false ; alreadyDecidedToMerge [ i ] = alreadyDecidedToMerge [ i ] || mergeThesePairs [ tag ] [ i ] [ j ] ; alreadyDecidedToMerge [ j ] = alreadyDecidedToMerge [ j ] || mergeThesePairs [ tag ] [ i ] [ j ] ; } } } for ( int tag = 0 ; tag < numSubStatesArray . length ; tag ++ ) { for ( int i = 0 ; i < mergeThesePairs [ tag ] . length ; i ++ ) { for ( int j = 0 ; j < mergeThesePairs [ tag ] . length ; j ++ ) { mergeThesePairs [ tag ] [ i ] [ j ] = mergeThesePairs [ tag ] [ i ] [ j ] && ! mergeThisIteration [ tag ] [ i ] [ j ] ; } } } newGrammar = grammar . mergeStates ( mergeThisIteration , mergeWeights ) ; lexicon . mergeStates ( mergeThisIteration , mergeWeights ) ; grammar . fixMergeWeightsEtc ( mergeThesePairs , mergeWeights , mergeThisIteration ) ; grammar = newGrammar ; newNumSubStatesArray = grammar . numSubStates ; } grammar . makeCRArrays ( ) ; return grammar ; }
target:  This function was written to have the ability to also merge non-sibling pairs, however this functionality is not used anymore since it seemed tricky to determine an appropriate threshold for merging non-siblings. The function returns a new grammar object and changes the lexicon in place!