de.learnlib.eqtests.basic.WpMethodEQOracle Maven / Gradle / Ivy
/* Copyright (C) 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
* .
*/
package de.learnlib.eqtests.basic;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import net.automatalib.automata.UniversalDeterministicAutomaton;
import net.automatalib.automata.concepts.Output;
import net.automatalib.automata.fsa.DFA;
import net.automatalib.automata.transout.MealyMachine;
import net.automatalib.commons.util.collections.CollectionsUtil;
import net.automatalib.commons.util.mappings.MutableMapping;
import net.automatalib.util.automata.Automata;
import net.automatalib.words.Word;
import net.automatalib.words.WordBuilder;
import de.learnlib.api.EquivalenceOracle;
import de.learnlib.api.MembershipOracle;
import de.learnlib.oracles.DefaultQuery;
/**
* Implements an equivalence test by applying the Wp-method test on the given hypothesis automaton,
* as described in "Test Selection Based on Finite State Models" by S. Fujiwara et al.
*
* @author Malte Isberner
*
* @param automaton type
* @param input symbol type
* @param output domain type
*/
public class WpMethodEQOracle & Output,I,D>
implements EquivalenceOracle {
public static class DFAWpMethodEQOracle extends WpMethodEQOracle,I,Boolean>
implements DFAEquivalenceOracle {
public DFAWpMethodEQOracle(int maxDepth,
MembershipOracle sulOracle) {
super(maxDepth, sulOracle);
}
}
public static class MealyWpMethodEQOracle extends WpMethodEQOracle,I,Word> {
public MealyWpMethodEQOracle(int maxDepth,
MembershipOracle> sulOracle) {
super(maxDepth, sulOracle);
}
}
private final int maxDepth;
private final MembershipOracle sulOracle;
/**
* Constructor.
* @param maxDepth the maximum length of the "middle" part of the test cases
* @param sulOracle interface to the system under learning
*/
public WpMethodEQOracle(int maxDepth, MembershipOracle sulOracle) {
this.maxDepth = maxDepth;
this.sulOracle = sulOracle;
}
/*
* (non-Javadoc)
* @see de.learnlib.api.EquivalenceOracle#findCounterExample(java.lang.Object, java.util.Collection)
*/
@Override
public DefaultQuery findCounterExample(A hypothesis,
Collection extends I> inputs) {
UniversalDeterministicAutomaton, I, ?, ?, ?> aut = hypothesis;
Output out = hypothesis;
return doFindCounterExample(aut, out, inputs);
}
/*
* Delegate target, used to bind the state-parameter of the automaton
*/
private DefaultQuery doFindCounterExample(UniversalDeterministicAutomaton hypothesis,
Output output, Collection extends I> inputs) {
List> stateCover = new ArrayList>(hypothesis.size());
List> transitions = new ArrayList>(hypothesis.size() * (inputs.size() - 1));
Automata.cover(hypothesis, inputs, stateCover, transitions);
List> globalSuffixes = Automata.characterizingSet(hypothesis, inputs);
if(globalSuffixes.isEmpty())
globalSuffixes = Collections.singletonList(Word.epsilon());
WordBuilder wb = new WordBuilder<>();
// Phase 1: state cover * middle part * global suffixes
for(List extends I> middle : CollectionsUtil.allTuples(inputs, 1, maxDepth)) {
for(Word as : stateCover) {
for(Word suffix : globalSuffixes) {
wb.append(as).append(middle).append(suffix);
Word queryWord = wb.toWord();
wb.clear();
DefaultQuery query = new DefaultQuery<>(queryWord);
D hypOutput = output.computeOutput(queryWord);
sulOracle.processQueries(Collections.singleton(query));
if(!Objects.equals(hypOutput, query.getOutput()))
return query;
}
}
}
// Phase 2: transitions (not in state cover) * middle part * local suffixes
MutableMapping>> localSuffixSets
= hypothesis.createStaticStateMapping();
for(List extends I> middle : CollectionsUtil.allTuples(inputs, 1, maxDepth)) {
for(Word trans : transitions) {
S state = hypothesis.getState(trans);
List> localSuffixes = localSuffixSets.get(state);
if(localSuffixes == null) {
localSuffixes = Automata.stateCharacterizingSet(hypothesis, inputs, state);
if(localSuffixes.isEmpty())
localSuffixes = Collections.singletonList(Word.epsilon());
localSuffixSets.put(state, localSuffixes);
}
for(Word suffix : localSuffixes) {
wb.append(trans).append(middle).append(suffix);
Word queryWord = wb.toWord();
wb.clear();
DefaultQuery query = new DefaultQuery<>(queryWord);
D hypOutput = output.computeOutput(queryWord);
sulOracle.processQueries(Collections.singleton(query));
if(!Objects.equals(hypOutput, query.getOutput()))
return query;
}
}
}
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy