Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* Copyright (C) 2013-2018 TU Dortmund
* This file is part of LearnLib, http://www.learnlib.de/.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.learnlib.algorithms.adt.config;
import java.util.Iterator;
import java.util.Map;
import de.learnlib.algorithms.adt.adt.ADTLeafNode;
import de.learnlib.algorithms.adt.adt.ADTNode;
import de.learnlib.algorithms.adt.adt.ADTResetNode;
import de.learnlib.algorithms.adt.adt.ADTSymbolNode;
import de.learnlib.algorithms.adt.api.LeafSplitter;
import de.learnlib.algorithms.adt.util.ADTUtil;
import net.automatalib.commons.util.Pair;
import net.automatalib.words.Word;
/**
* A collection of default {@link LeafSplitter} configurations.
*
* @author frohme
*/
public final class LeafSplitters {
public static final LeafSplitter DEFAULT_SPLITTER = LeafSplitters::splitIntoNewADS;
public static final LeafSplitter EXTEND_PARENT = new LeafSplitter() {
@Override
public ADTNode split(ADTNode nodeToSplit,
Word distinguishingSuffix,
Word oldOutput,
Word newOutput) {
if (canSplitParent(nodeToSplit, distinguishingSuffix, oldOutput, newOutput)) {
return splitParent(nodeToSplit, distinguishingSuffix, oldOutput, newOutput);
}
return splitIntoNewADS(nodeToSplit, distinguishingSuffix, oldOutput, newOutput);
}
};
private LeafSplitters() {
// prevent instantiation
}
private static boolean canSplitParent(final ADTNode nodeToSplit,
final Word distinguishingSuffix,
final Word hypothesisOutput,
final Word newOutput) {
// initial split
if (nodeToSplit.getParent() == null) {
return false;
}
final Pair, Word> trace = ADTUtil.buildTraceForNode(nodeToSplit);
final Word traceInput = trace.getFirst();
final Word traceOutput = trace.getSecond();
return traceInput.isPrefixOf(distinguishingSuffix) && traceOutput.isPrefixOf(newOutput) &&
traceOutput.isPrefixOf(hypothesisOutput);
}
private static ADTNode splitIntoNewADS(final ADTNode nodeToSplit,
final Word distinguishingSuffix,
final Word oldOutput,
final Word newOutput) {
final Iterator suffixIter = distinguishingSuffix.iterator();
// Replace old final state
final ADTNode parent = nodeToSplit.getParent();
final ADTNode newADS = new ADTSymbolNode<>(null, suffixIter.next());
if (parent != null) { // if parent == null, we split the initial node
boolean foundSuccessor = false;
for (Map.Entry> entry : parent.getChildren().entrySet()) {
if (entry.getValue().equals(nodeToSplit)) {
final ADTNode reset = new ADTResetNode<>(newADS);
reset.setParent(parent);
parent.getChildren().put(entry.getKey(), reset);
newADS.setParent(reset);
foundSuccessor = true;
break;
}
}
if (!foundSuccessor) {
throw new IllegalStateException();
}
}
return finalizeSplit(nodeToSplit, newADS, suffixIter, oldOutput.iterator(), newOutput.iterator());
}
private static ADTNode finalizeSplit(final ADTNode nodeToSplit,
final ADTNode adtRoot,
final Iterator suffixIter,
final Iterator oldIter,
final Iterator newIter) {
ADTNode previous = adtRoot;
O oldOut = oldIter.next();
O newOut = newIter.next();
while (oldOut.equals(newOut)) {
final ADTNode next = new ADTSymbolNode<>(previous, suffixIter.next());
previous.getChildren().put(oldOut, next);
oldOut = oldIter.next();
newOut = newIter.next();
previous = next;
}
final ADTNode oldFinalNode = nodeToSplit;
final ADTNode newFinalNode = new ADTLeafNode<>(previous, null);
oldFinalNode.setParent(previous);
newFinalNode.setParent(previous);
previous.getChildren().put(oldOut, oldFinalNode);
previous.getChildren().put(newOut, newFinalNode);
return newFinalNode;
}
public static ADTNode splitParent(final ADTNode nodeToSplit,
final Word distinguishingSuffix,
final Word oldOutput,
final Word newOutput) {
final ADTNode previousADS = ADTUtil.getStartOfADS(nodeToSplit);
final Iterator suffixIter = distinguishingSuffix.iterator();
final Iterator oldIter = oldOutput.iterator();
final Iterator newIter = newOutput.iterator();
ADTNode adsIter = previousADS;
O newSuffixOutput = null;
while (!ADTUtil.isLeafNode(adsIter)) {
// Forward other iterators
suffixIter.next();
newIter.next();
newSuffixOutput = oldIter.next();
adsIter = adsIter.getChildren().get(newSuffixOutput);
}
final ADTNode continuedADS = new ADTSymbolNode<>(adsIter.getParent(), suffixIter.next());
adsIter.getParent().getChildren().put(newSuffixOutput, continuedADS);
return finalizeSplit(nodeToSplit, continuedADS, suffixIter, oldIter, newIter);
}
}