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.algorithms.lstargeneric.mealy; 018 019import java.util.ArrayList; 020import java.util.List; 021 022import net.automatalib.automata.concepts.SuffixOutput; 023import net.automatalib.automata.transout.MealyMachine; 024import net.automatalib.automata.transout.impl.compact.CompactMealy; 025import net.automatalib.automata.transout.impl.compact.CompactMealyTransition; 026import net.automatalib.words.Alphabet; 027import net.automatalib.words.Word; 028import de.learnlib.algorithms.lstargeneric.ExtensibleAutomatonLStar; 029import de.learnlib.algorithms.lstargeneric.ce.ObservationTableCEXHandler; 030import de.learnlib.algorithms.lstargeneric.closing.ClosingStrategy; 031import de.learnlib.algorithms.lstargeneric.table.Row; 032import de.learnlib.api.LearningAlgorithm.MealyLearner; 033import de.learnlib.api.MembershipOracle; 034import de.learnlib.oracles.DefaultQuery; 035 036public class ExtensibleLStarMealy<I, O> extends 037 ExtensibleAutomatonLStar<MealyMachine<?,I,?,O>, I, Word<O>, Integer, CompactMealyTransition<O>, Void, O, CompactMealy<I,O>> 038 implements MealyLearner<I,O> { 039 040 private final List<O> outputTable 041 = new ArrayList<O>(); 042 043 044 public ExtensibleLStarMealy(Alphabet<I> alphabet, 045 MembershipOracle<I, Word<O>> oracle, 046 List<Word<I>> initialSuffixes, 047 ObservationTableCEXHandler<? super I, ? super Word<O>> cexHandler, 048 ClosingStrategy<? super I, ? super Word<O>> closingStrategy) { 049 super(alphabet, oracle, new CompactMealy<I,O>(alphabet), 050 LStarMealyUtil.ensureSuffixCompliancy(initialSuffixes, alphabet, cexHandler.needsConsistencyCheck()), 051 cexHandler, 052 closingStrategy); 053 } 054 055 @Override 056 protected Void stateProperty(Row<I> stateRow) { 057 return null; 058 } 059 060 @Override 061 protected O transitionProperty(Row<I> stateRow, int inputIdx) { 062 updateOutputs(); 063 Row<I> transRow = stateRow.getSuccessor(inputIdx); 064 return outputTable.get(transRow.getRowId() - 1); 065 } 066 067 @Override 068 protected List<Word<I>> initialSuffixes() { 069 return initialSuffixes; 070 } 071 072 protected void updateOutputs() { 073 int numOutputs = outputTable.size(); 074 int numTransRows = table.numTotalRows() - 1; 075 076 int newOutputs = numTransRows - numOutputs; 077 if(newOutputs == 0) 078 return; 079 080 List<DefaultQuery<I,Word<O>>> outputQueries 081 = new ArrayList<DefaultQuery<I,Word<O>>>(numOutputs); 082 083 for(int i = numOutputs+1; i <= numTransRows; i++) { 084 Row<I> row = table.getRow(i); 085 Word<I> rowPrefix = row.getPrefix(); 086 int prefixLen = rowPrefix.size(); 087 outputQueries.add(new DefaultQuery<I,Word<O>>(rowPrefix.prefix(prefixLen - 1), 088 rowPrefix.suffix(1))); 089 } 090 091 oracle.processQueries(outputQueries); 092 093 for(int i = 0; i < newOutputs; i++) { 094 DefaultQuery<I,Word<O>> query = outputQueries.get(i); 095 O outSym = query.getOutput().getSymbol(0); 096 outputTable.add(outSym); 097 } 098 } 099 100 @Override 101 protected MealyMachine<?, I, ?, O> exposeInternalHypothesis() { 102 return internalHyp; 103 } 104 105 @Override 106 protected SuffixOutput<I,Word<O>> hypothesisOutput() { 107 return internalHyp; 108 } 109 110}