private void evaluateSubtreeReplacement() {

        if (this.hypothesis.size() == 1) {
            // skip replacement if only one node is discovered
            return;
        }

        final Set<ReplacementResult<ADTState<I, O>, I, O>> potentialReplacements =
                this.subtreeReplacer.computeReplacements(this.hypothesis, this.alphabet, this.adt);
        final List<ReplacementResult<ADTState<I, O>, I, O>> validReplacements =
                new ArrayList<>(potentialReplacements.size());
        final Set<ADTNode<ADTState<I, O>, I, O>> cachedLeaves =
                potentialReplacements.isEmpty() ? Collections.emptySet() : ADTUtil.collectLeaves(this.adt.getRoot());

        for (final ReplacementResult<ADTState<I, O>, I, O> potentialReplacement : potentialReplacements) {
            final ADTNode<ADTState<I, O>, I, O> proposedReplacement = potentialReplacement.getReplacement();
            final ADTNode<ADTState<I, O>, I, O> nodeToReplace = potentialReplacement.getNodeToReplace();

            assert this.validateADS(nodeToReplace, proposedReplacement, potentialReplacement.getCutoutNodes());

            final ADTNode<ADTState<I, O>, I, O> replacement = this.verifyADS(nodeToReplace,
                                                                             proposedReplacement,
                                                                             cachedLeaves,
                                                                             potentialReplacement.getCutoutNodes());

            // verification may have introduced reset nodes
            final int oldCosts = ADTUtil.computeEffectiveResets(nodeToReplace);
            final int newCosts = ADTUtil.computeEffectiveResets(replacement);

            if (newCosts >= oldCosts) {
                continue;
            }

            validReplacements.add(new ReplacementResult<>(nodeToReplace, replacement));
        }

        for (final ReplacementResult<ADTState<I, O>, I, O> potentialReplacement : validReplacements) {
            final ADTNode<ADTState<I, O>, I, O> replacement = potentialReplacement.getReplacement();
            final ADTNode<ADTState<I, O>, I, O> nodeToReplace = potentialReplacement.getNodeToReplace();

            this.adt.replaceNode(nodeToReplace, replacement);

            this.resiftAffectedTransitions(ADTUtil.collectLeaves(replacement), ADTUtil.getStartOfADS(replacement));
        }

        this.closeTransitions();
    }
private void evaluateSubtreeReplacement ( ) { if ( this . hypothesis . size ( ) == 1 ) { return ; } final Set < ReplacementResult < ADTState < I , O > , I , O > > potentialReplacements = this . subtreeReplacer . computeReplacements ( this . hypothesis , this . alphabet , this . adt ) ; final List < ReplacementResult < ADTState < I , O > , I , O > > validReplacements = new ArrayList < > ( potentialReplacements . size ( ) ) ; final Set < ADTNode < ADTState < I , O > , I , O > > cachedLeaves = potentialReplacements . isEmpty ( ) ? Collections . emptySet ( ) : ADTUtil . collectLeaves ( this . adt . getRoot ( ) ) ; for ( final ReplacementResult < ADTState < I , O > , I , O > potentialReplacement : potentialReplacements ) { final ADTNode < ADTState < I , O > , I , O > proposedReplacement = potentialReplacement . getReplacement ( ) ; final ADTNode < ADTState < I , O > , I , O > nodeToReplace = potentialReplacement . getNodeToReplace ( ) ; assert this . validateADS ( nodeToReplace , proposedReplacement , potentialReplacement . getCutoutNodes ( ) ) ; final ADTNode < ADTState < I , O > , I , O > replacement = this . verifyADS ( nodeToReplace , proposedReplacement , cachedLeaves , potentialReplacement . getCutoutNodes ( ) ) ; final int oldCosts = ADTUtil . computeEffectiveResets ( nodeToReplace ) ; final int newCosts = ADTUtil . computeEffectiveResets ( replacement ) ; if ( newCosts >= oldCosts ) { continue ; } validReplacements . add ( new ReplacementResult < > ( nodeToReplace , replacement ) ) ; } for ( final ReplacementResult < ADTState < I , O > , I , O > potentialReplacement : validReplacements ) { final ADTNode < ADTState < I , O > , I , O > replacement = potentialReplacement . getReplacement ( ) ; final ADTNode < ADTState < I , O > , I , O > nodeToReplace = potentialReplacement . getNodeToReplace ( ) ; this . adt . replaceNode ( nodeToReplace , replacement ) ; this . resiftAffectedTransitions ( ADTUtil . collectLeaves ( replacement ) , ADTUtil . getStartOfADS ( replacement ) ) ; } this . closeTransitions ( ) ; }
Ask the {@link #subtreeReplacer} for any replacements.