001package de.learnlib.cache.sul; 002 003import net.automatalib.incremental.mealy.IncrementalMealyBuilder; 004import net.automatalib.incremental.mealy.State; 005import net.automatalib.incremental.mealy.TransitionRecord; 006import net.automatalib.words.Alphabet; 007import net.automatalib.words.WordBuilder; 008import de.learnlib.api.SUL; 009import de.learnlib.cache.mealy.MealyCacheConsistencyTest; 010 011public class SULCache<I, O> implements SUL<I, O> { 012 013 private final IncrementalMealyBuilder<I, O> incMealy; 014 private final SUL<I,O> delegate; 015 016 private State current; 017 private final WordBuilder<I> inputWord = new WordBuilder<>(); 018 private WordBuilder<O> outputWord; 019 020 public SULCache(Alphabet<I> alphabet, SUL<I,O> sul) { 021 this.incMealy = new IncrementalMealyBuilder<>(alphabet); 022 this.delegate = sul; 023 } 024 025 @Override 026 public void pre() { 027 if(outputWord != null) { 028 incMealy.insert(inputWord.toWord(), outputWord.toWord()); 029 } 030 031 inputWord.clear(); 032 outputWord = null; 033 current = incMealy.getInitialState(); 034 } 035 036 @Override 037 public O step(I in) { 038 O out = null; 039 040 if(current != null) { 041 TransitionRecord trans = incMealy.getTransition(current, in); 042 043 if(trans != null) { 044 out = incMealy.getTransitionOutput(trans); 045 current = incMealy.getSuccessor(trans); 046 assert current != null; 047 } 048 else { 049 current = null; 050 outputWord = new WordBuilder<>(); 051 delegate.pre(); 052 for(I prevSym : inputWord) { 053 outputWord.append(delegate.step(prevSym)); 054 } 055 } 056 } 057 058 inputWord.append(in); 059 060 if(current == null) { 061 out = delegate.step(in); 062 outputWord.add(out); 063 } 064 065 return out; 066 } 067 068 public MealyCacheConsistencyTest<I, O> createCacheConsistencyTest() { 069 return new MealyCacheConsistencyTest<>(incMealy); 070 } 071 072 @Override 073 public void post() { 074 delegate.post(); 075 } 076 077 078}