001/* Copyright (C) 2013 TU Dortmund
002 * This file is part of LearnLib, http://www.learnlib.de/.
003 * 
004 * LearnLib is free software; you can redistribute it and/or
005 * modify it under the terms of the GNU Lesser General Public
006 * License version 3.0 as published by the Free Software Foundation.
007 * 
008 * LearnLib is distributed in the hope that it will be useful,
009 * but WITHOUT ANY WARRANTY; without even the implied warranty of
010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
011 * Lesser General Public License for more details.
012 * 
013 * You should have received a copy of the GNU Lesser General Public
014 * License along with LearnLib; if not, see
015 * <http://www.gnu.de/documents/lgpl.en.html>.
016 */
017package de.learnlib.eqtests.basic.mealy;
018
019import java.util.Collection;
020import java.util.Objects;
021
022import net.automatalib.automata.concepts.SODetOutputAutomaton;
023import net.automatalib.words.Word;
024import de.learnlib.api.EquivalenceOracle;
025import de.learnlib.oracles.DefaultQuery;
026
027public class SymbolEQOracleWrapper<A extends SODetOutputAutomaton<?,I,?,Word<O>>, I, O> implements
028                EquivalenceOracle<A, I, O> {
029        
030        private final EquivalenceOracle<? super A, I, Word<O>> wordEqOracle;
031
032        public SymbolEQOracleWrapper(EquivalenceOracle<? super A,I,Word<O>> wordEqOracle) {
033                this.wordEqOracle = wordEqOracle;
034        }
035        
036        /*
037         * (non-Javadoc)
038         * @see de.learnlib.api.EquivalenceOracle#findCounterExample(java.lang.Object, net.automatalib.words.Alphabet)
039         */
040        @Override
041        public DefaultQuery<I, O> findCounterExample(A hypothesis, Collection<? extends I> inputs) {
042                DefaultQuery<I,Word<O>> wordCeQry = wordEqOracle.findCounterExample(hypothesis, inputs);
043                if(wordCeQry == null)
044                        return null;
045                
046                Word<O> hypOut = hypothesis.computeSuffixOutput(wordCeQry.getPrefix(), wordCeQry.getSuffix());
047                Word<O> ceOut = wordCeQry.getOutput();
048                
049                
050                int len = hypOut.length();
051                if(len != ceOut.length())
052                        throw new IllegalStateException("Output word length does not align with suffix length, truncating CE will not work");
053                
054                
055
056                for(int i = 0; i < len; i++) {
057                        O hypSym = hypOut.getSymbol(i), ceSym = ceOut.getSymbol(i);
058                        
059                        if(!Objects.equals(hypSym, ceSym)) {
060                                DefaultQuery<I,O> result = new DefaultQuery<I,O>(wordCeQry.getPrefix(),
061                                                wordCeQry.getSuffix().prefix(i+1));
062                                result.answer(ceSym);
063                                return result;
064                        }
065                }
066                
067                throw new IllegalStateException("Counterexample returned by underlying EQ oracle was none");
068        }
069
070}