Skip to content

Commit bf6c8bf

Browse files
committed
cleanup SUL cache impls
1 parent 604e4d5 commit bf6c8bf

File tree

4 files changed

+101
-118
lines changed

4 files changed

+101
-118
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1111
### Changed
1212

1313
* The `{DFA,Mealy,}W{p,}MethodEQOracle(MembershipOracle, int, int)` constructor no longer interprets its second `int` parameter as the batch size, but as an estimate for the expected SUL size. In order to explicitly set the batch size of the oracle, use the `{DFA,Mealy,}W{p,}MethodEQOracle(MembershipOracle, int, int, int)` constructor. Now, the two parameters `lookahead` and `expectedSize` will determine the length of the *middle part* via `Math.max(lookahead, expectedSize - hypothesis.size())`. This allows to dynamically adjust the length of the *middle part* throughout the learning process. See [LearnLib/automatalib#32](https://github.com/LearnLib/automatalib/issues/32).
14-
* Several DFA/Mealy specific (oracle) subclasses are now automatically generated. As a result they are no longer an inner class, but an indepentend top-level class. This requires to update the import statements.
14+
* Several DFA/Mealy specific (oracle) subclasses are now automatically generated. As a result they are no longer an inner class, but an independent top-level class. This requires to update the import statements.
1515
* JSR305 annotations have been replaced with checker-framework annotations.
1616
* LearnLib (incl. AutomataLib) now follows checker-framework's convention that (non-annotated) types are usually considered non-null unless explicitly annotated with `@Nullable`.
1717
* LearnLib (incl. AutomataLib) no longer has a (runtime-) dependency on JSR305 (and other `javax.*`) annotations or includes them in the distribution artifact. This now makes LearnLib (incl. AutomataLib) compliant with [Oracle's binary code license](https://www.oracle.com/downloads/licenses/binary-code-license.html) and allows LearnLib (incl. AutomataLib) artifacts as-is to be bundled in binary distributions with Oracle's JDKs/JREs.
1818
* A lot of code for inferring partial Mealy machines (esp. `PartialLStarMealy` and `PartialObservationTable`) has been removed/refactored. The concept of state local inputs is now implemented as a SUL filter and introduces a special `StateLocalInputSULOracle` which early-answers queries that would traverse unavailable inputs with a previously specified symbol. This way, queries that would traverse undefined input symbols still won't be executed on the SUL but the SUL appears as a 'total' Mealy system to the learner, allowing one to use every currently existing Mealy learner as-is. See the in-tree examples for more information.
19+
* `SULCache` no longer implements `MembershipOracle`.
1920

2021
### Removed
2122

oracles/filters/cache/src/main/java/de/learnlib/filter/cache/sul/AbstractSULCache.java

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,30 @@
1515
*/
1616
package de.learnlib.filter.cache.sul;
1717

18+
import java.io.Serializable;
19+
import java.util.List;
1820
import java.util.concurrent.locks.ReadWriteLock;
1921

22+
import de.learnlib.api.Resumable;
2023
import de.learnlib.api.SUL;
24+
import de.learnlib.api.oracle.EquivalenceOracle.MealyEquivalenceOracle;
2125
import de.learnlib.filter.cache.LearningCache.MealyLearningCache;
2226
import de.learnlib.filter.cache.mealy.MealyCacheConsistencyTest;
2327
import net.automatalib.SupportsGrowingAlphabet;
2428
import net.automatalib.incremental.mealy.IncrementalMealyBuilder;
2529
import net.automatalib.ts.output.MealyTransitionSystem;
2630
import net.automatalib.words.WordBuilder;
2731
import org.checkerframework.checker.nullness.qual.Nullable;
32+
import org.slf4j.Logger;
33+
import org.slf4j.LoggerFactory;
2834

2935
abstract class AbstractSULCache<I, O> implements SUL<I, O>, MealyLearningCache<I, O>, SupportsGrowingAlphabet<I> {
3036

31-
private final AbstractSULCacheImpl<?, I, ?, O> impl;
37+
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSULCache.class);
3238

33-
protected <S, T> AbstractSULCache(AbstractSULCacheImpl<S, I, T, O> cacheImpl) {
39+
private final AbstractSULCacheImpl<?, I, ?, O, ? extends AbstractSULCacheState<I, O>> impl;
40+
41+
protected <S, T> AbstractSULCache(AbstractSULCacheImpl<S, I, T, O, ? extends AbstractSULCacheState<I, O>> cacheImpl) {
3442
this.impl = cacheImpl;
3543
}
3644

@@ -60,7 +68,7 @@ public SUL<I, O> fork() {
6068
}
6169

6270
@Override
63-
public MealyCacheConsistencyTest<I, O> createCacheConsistencyTest() {
71+
public MealyEquivalenceOracle<I, O> createCacheConsistencyTest() {
6472
return impl.createCacheConsistencyTest();
6573
}
6674

@@ -85,18 +93,20 @@ public int size() {
8593
* transition system transition type
8694
* @param <O>
8795
* output symbol type
96+
* @param <C>
97+
* cache type
8898
*
8999
* @author Malte Isberner
90100
*/
91-
abstract static class AbstractSULCacheImpl<S, I, T, O>
92-
implements SUL<I, O>, MealyLearningCache<I, O>, SupportsGrowingAlphabet<I> {
101+
abstract static class AbstractSULCacheImpl<S, I, T, O, C extends AbstractSULCacheState<I, O>>
102+
implements SUL<I, O>, MealyLearningCache<I, O>, SupportsGrowingAlphabet<I>, Resumable<C> {
93103

94104
protected IncrementalMealyBuilder<I, O> incMealy;
95105
protected MealyTransitionSystem<S, I, T, O> mealyTs;
96106
protected final SUL<I, O> delegate;
97107
protected final ReadWriteLock incMealyLock;
98108

99-
protected final WordBuilder<I> inputWord = new WordBuilder<>();
109+
private final WordBuilder<I> inputWord = new WordBuilder<>();
100110
private final WordBuilder<O> outputWord = new WordBuilder<>();
101111

102112
private boolean delegatePreCalled;
@@ -143,6 +153,7 @@ public O step(I in) {
143153

144154
if (current == null) {
145155
out = delegate.step(in);
156+
postNewStepHook();
146157
outputWord.add(out);
147158
}
148159

@@ -161,7 +172,8 @@ public void post() {
161172
// otherwise acquire write-lock to update cache!
162173
incMealyLock.writeLock().lock();
163174
try {
164-
writeCache();
175+
incMealy.insert(inputWord.toWord(), outputWord.toWord());
176+
postCacheWriteHook(inputWord);
165177
} finally {
166178
incMealyLock.writeLock().unlock();
167179
}
@@ -182,7 +194,7 @@ public boolean canFork() {
182194
}
183195

184196
@Override
185-
public MealyCacheConsistencyTest<I, O> createCacheConsistencyTest() {
197+
public MealyEquivalenceOracle<I, O> createCacheConsistencyTest() {
186198
return new MealyCacheConsistencyTest<>(incMealy, incMealyLock);
187199
}
188200

@@ -191,15 +203,41 @@ public void addAlphabetSymbol(I symbol) {
191203
incMealy.addAlphabetSymbol(symbol);
192204
}
193205

206+
@Override
207+
@SuppressWarnings("unchecked")
208+
public void resume(C state) {
209+
final Class<?> thisClass = this.incMealy.getClass();
210+
final Class<?> stateClass = state.builder.getClass();
211+
212+
if (!thisClass.equals(stateClass)) {
213+
LOGGER.warn(
214+
"You currently plan to use a '{}', but the state contained a '{}'. This may yield unexpected behavior.",
215+
thisClass,
216+
stateClass);
217+
}
218+
219+
this.incMealy = state.builder;
220+
this.mealyTs = (MealyTransitionSystem<S, I, T, O>) this.incMealy.asTransitionSystem();
221+
}
222+
194223
protected void requiredInitializedDelegate() {
195224
if (!delegatePreCalled) {
196225
delegate.pre();
197226
}
198227
delegatePreCalled = true;
199228
}
200229

201-
protected void writeCache() {
202-
incMealy.insert(inputWord.toWord(), outputWord.toWord());
230+
protected void postNewStepHook() {}
231+
232+
protected void postCacheWriteHook(List<I> input) {}
233+
}
234+
235+
abstract static class AbstractSULCacheState<I, O> implements Serializable {
236+
237+
final IncrementalMealyBuilder<I, O> builder;
238+
239+
protected AbstractSULCacheState(IncrementalMealyBuilder<I, O> builder) {
240+
this.builder = builder;
203241
}
204242
}
205243
}

oracles/filters/cache/src/main/java/de/learnlib/filter/cache/sul/SULCache.java

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616
package de.learnlib.filter.cache.sul;
1717

18-
import java.io.Serializable;
1918
import java.util.concurrent.locks.ReadWriteLock;
2019
import java.util.concurrent.locks.ReentrantReadWriteLock;
2120

@@ -27,8 +26,6 @@
2726
import net.automatalib.incremental.mealy.tree.IncrementalMealyTreeBuilder;
2827
import net.automatalib.ts.output.MealyTransitionSystem;
2928
import net.automatalib.words.Alphabet;
30-
import org.slf4j.Logger;
31-
import org.slf4j.LoggerFactory;
3229

3330
/**
3431
* A cache to be used with a {@link SUL}.
@@ -49,8 +46,6 @@
4946
*/
5047
public class SULCache<I, O> extends AbstractSULCache<I, O> implements Resumable<SULCacheState<I, O>> {
5148

52-
private static final Logger LOGGER = LoggerFactory.getLogger(SULCache.class);
53-
5449
private final SULCacheImpl<?, I, ?, O> impl;
5550

5651
SULCache(IncrementalMealyBuilder<I, O> incMealy, SUL<I, O> sul) {
@@ -95,8 +90,7 @@ public void resume(SULCacheState<I, O> state) {
9590
*
9691
* @author Malte Isberner
9792
*/
98-
private static final class SULCacheImpl<S, I, T, O> extends AbstractSULCacheImpl<S, I, T, O>
99-
implements Resumable<SULCacheState<I, O>> {
93+
private static final class SULCacheImpl<S, I, T, O> extends AbstractSULCacheImpl<S, I, T, O, SULCacheState<I, O>> {
10094

10195
SULCacheImpl(IncrementalMealyBuilder<I, O> incMealy,
10296
ReadWriteLock lock,
@@ -114,31 +108,12 @@ public SUL<I, O> fork() {
114108
public SULCacheState<I, O> suspend() {
115109
return new SULCacheState<>(incMealy);
116110
}
117-
118-
@Override
119-
@SuppressWarnings("unchecked")
120-
public void resume(SULCacheState<I, O> state) {
121-
final Class<?> thisClass = this.incMealy.getClass();
122-
final Class<?> stateClass = state.builder.getClass();
123-
124-
if (!thisClass.equals(stateClass)) {
125-
LOGGER.warn(
126-
"You currently plan to use a '{}', but the state contained a '{}'. This may yield unexpected behavior.",
127-
thisClass,
128-
stateClass);
129-
}
130-
131-
super.incMealy = state.builder;
132-
super.mealyTs = (MealyTransitionSystem<S, I, T, O>) this.incMealy.asTransitionSystem();
133-
}
134111
}
135112

136-
public static class SULCacheState<I, O> implements Serializable {
137-
138-
final IncrementalMealyBuilder<I, O> builder;
113+
public static final class SULCacheState<I, O> extends AbstractSULCacheState<I, O> {
139114

140115
SULCacheState(IncrementalMealyBuilder<I, O> builder) {
141-
this.builder = builder;
116+
super(builder);
142117
}
143118
}
144119

0 commit comments

Comments
 (0)