de.learnlib.mealy.MealyUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of learnlib-core Show documentation
Show all versions of learnlib-core Show documentation
Infrastructure and core functionalities of LearnLib
The newest version!
/* Copyright (C) 2013-2014 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.mealy;
import java.util.Iterator;
import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import net.automatalib.automata.transout.MealyMachine;
import net.automatalib.words.Word;
import de.learnlib.api.LearningAlgorithm;
import de.learnlib.api.MembershipOracle;
import de.learnlib.oracles.DefaultQuery;
/**
* Utility class helping to unify various approaches to actively learning
* Mealy machines.
*
* @author Malte Isberner
*
*/
@ParametersAreNonnullByDefault
public abstract class MealyUtil {
public static final int NO_MISMATCH = -1;
public static int findMismatch(MealyMachine, I, ?, O> hypothesis, Word input, Word output) {
return doFindMismatch(hypothesis, input, output);
}
private static int doFindMismatch(MealyMachine hypothesis, Word input, Word output) {
int i = 0;
S state = hypothesis.getInitialState();
Iterator inIt = input.iterator();
Iterator outIt = output.iterator();
while (inIt.hasNext() && outIt.hasNext()) {
T trans = hypothesis.getTransition(state, inIt.next());
O ceOut = outIt.next();
O transOut = hypothesis.getTransitionOutput(trans);
if (!Objects.equals(transOut, ceOut)) {
return i;
}
state = hypothesis.getSuccessor(trans);
i++;
}
return NO_MISMATCH;
}
public static int findMismatch(Word out1, Word out2) {
int len = out1.length();
assert len == out2.length();
for(int i = 0; i < len; i++) {
O sym1 = out1.getSymbol(i);
O sym2 = out2.getSymbol(i);
if(!Objects.equals(sym1, sym2))
return i;
}
return NO_MISMATCH;
}
@Nullable
public static DefaultQuery> shortenCounterExample(
MealyMachine,I,?,O> hypothesis,
DefaultQuery> ceQuery) {
Word cePrefix = ceQuery.getPrefix(), ceSuffix = ceQuery.getSuffix();
Word hypOut = hypothesis.computeSuffixOutput(cePrefix, ceSuffix);
Word ceOut = ceQuery.getOutput();
assert ceOut.length() == hypOut.length();
int mismatchIdx = findMismatch(hypOut, ceOut);
if(mismatchIdx == NO_MISMATCH)
return null;
return new DefaultQuery<>(cePrefix,
ceSuffix.prefix(mismatchIdx + 1),
ceOut.prefix(mismatchIdx + 1));
}
@Nullable
public static DefaultQuery reduceCounterExample(
MealyMachine,I,?,O> hypothesis,
DefaultQuery> ceQuery) {
Word cePrefix = ceQuery.getPrefix(), ceSuffix = ceQuery.getSuffix();
Word hypOut = hypothesis.computeSuffixOutput(cePrefix, ceSuffix);
Word ceOut = ceQuery.getOutput();
assert ceOut.length() == hypOut.length();
int mismatchIdx = findMismatch(hypOut, ceOut);
if(mismatchIdx == NO_MISMATCH)
return null;
return new DefaultQuery<>(cePrefix,
ceSuffix.prefix(mismatchIdx + 1),
ceOut.getSymbol(mismatchIdx));
}
@Nonnull
public static ,I,O>
LearningAlgorithm.MealyLearner wrapSymbolLearner(LearningAlgorithm learner) {
return new MealyLearnerWrapper<>(learner);
}
@Nonnull
public static MembershipOracle wrapWordOracle(MembershipOracle> oracle) {
return new SymbolOracleWrapper<>(oracle);
}
// Prevent inheritance
private MealyUtil() {
throw new IllegalStateException("Constructor should never be invoked");
}
}