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
/* Copyright (C) 2013-2014 TU Dortmund
* This file is part of LearnLib, http://www.learnlib.de/.
*
* LearnLib is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 3.0 as published by the Free Software Foundation.
*
* LearnLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with LearnLib; if not, see
* http://www.gnu.de/documents/lgpl.en.html.
*/
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");
}
}