Skip to content

Commit 9909fdd

Browse files
committed
make ADT configurable in its suffix finder
1 parent 9afd161 commit 9909fdd

3 files changed

Lines changed: 23 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1111
* LearnLib now supports JPMS modules. All artifacts now provide a `module-info` descriptor except of the distribution artifacts (for Maven-less environments) which only provide an `Automatic-Module-Name` due to non-modular dependencies. Note that while this is a Java 9+ feature, LearnLib still supports Java 8 byte code for the remaining class files.
1212
* Added the L# active learning algorithm (thanks to [Tiago Ferreira](https://github.com/tiferrei)).
1313
* The `ADTLearner` has been refactored to no longer use the (now-removed) `SymbolQueryOracle` but a new `AdaptiveMembershipOracle` instead which supports answering queries in parallel (thanks to [Leon Vitorovic](https://github.com/leonthalee)).
14+
* The `ADTLearner` can now be parameterized in its counterexample analysis method.
1415
* Added an `InterningMembershipOracle` (including refinements) to the `learnlib-cache` artifact that interns query responses to reduce memory consumption of large data structures. This exports the internal concepts of the DHC learner (which no longer interns query responses automatically).
1516
* `StaticParallelOracleBuilder` now supports custom executor services.
1617

algorithms/active/adt/src/main/java/de/learnlib/algorithm/adt/learner/ADTLearner.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import de.learnlib.algorithm.adt.model.ObservationTree;
5151
import de.learnlib.algorithm.adt.model.ReplacementResult;
5252
import de.learnlib.algorithm.adt.util.ADTUtil;
53+
import de.learnlib.counterexample.LocalSuffixFinder;
5354
import de.learnlib.counterexample.LocalSuffixFinders;
5455
import de.learnlib.logging.Category;
5556
import de.learnlib.oracle.AdaptiveMembershipOracle;
@@ -92,6 +93,7 @@ public class ADTLearner<I, O> implements LearningAlgorithm.MealyLearner<I, O>,
9293
private final Queue<DefaultQuery<I, Word<O>>> openCounterExamples;
9394
private final Set<DefaultQuery<I, Word<O>>> allCounterExamples;
9495
private final ObservationTree<ADTState<I, O>, I, O> observationTree;
96+
private final LocalSuffixFinder<? super I, ? super Word<O>> suffixFinder;
9597
private ADTHypothesis<I, O> hypothesis;
9698
private ADT<ADTState<I, O>, I, O> adt;
9799

@@ -100,7 +102,7 @@ public ADTLearner(Alphabet<I> alphabet,
100102
LeafSplitter leafSplitter,
101103
ADTExtender adtExtender,
102104
SubtreeReplacer subtreeReplacer) {
103-
this(alphabet, oracle, leafSplitter, adtExtender, subtreeReplacer, true);
105+
this(alphabet, oracle, leafSplitter, adtExtender, subtreeReplacer, true, LocalSuffixFinders.RIVEST_SCHAPIRE);
104106
}
105107

106108
@GenerateBuilder(defaults = BuilderDefaults.class)
@@ -109,7 +111,8 @@ public ADTLearner(Alphabet<I> alphabet,
109111
LeafSplitter leafSplitter,
110112
ADTExtender adtExtender,
111113
SubtreeReplacer subtreeReplacer,
112-
boolean useObservationTree) {
114+
boolean useObservationTree,
115+
LocalSuffixFinder<? super I, ? super Word<O>> suffixFinder) {
113116

114117
this.alphabet = alphabet;
115118
this.observationTree = new ObservationTree<>(this.alphabet, oracle, useObservationTree);
@@ -119,6 +122,7 @@ public ADTLearner(Alphabet<I> alphabet,
119122
this.leafSplitter = leafSplitter;
120123
this.adtExtender = adtExtender;
121124
this.subtreeReplacer = subtreeReplacer;
125+
this.suffixFinder = suffixFinder;
122126

123127
this.hypothesis = new ADTHypothesis<>(this.alphabet);
124128
this.openTransitions = new ArrayDeque<>();
@@ -188,8 +192,7 @@ public boolean refineHypothesisInternal(DefaultQuery<I, Word<O>> ceQuery) {
188192
}
189193

190194
// Determine a counterexample decomposition (u, a, v)
191-
final int suffixIdx =
192-
LocalSuffixFinders.RIVEST_SCHAPIRE.findSuffixIndex(ceQuery, this.hypothesis, this.hypothesis, this.mqo);
195+
final int suffixIdx = suffixFinder.findSuffixIndex(ceQuery, this.hypothesis, this.hypothesis, this.mqo);
193196

194197
if (suffixIdx == -1) {
195198
throw new IllegalStateException();
@@ -859,5 +862,10 @@ public static SubtreeReplacer subtreeReplacer() {
859862
public static boolean useObservationTree() {
860863
return true;
861864
}
865+
866+
@SuppressWarnings("unchecked")
867+
public static <I, D> LocalSuffixFinder<I, D> suffixFinder() {
868+
return (LocalSuffixFinder<I, D>) LocalSuffixFinders.RIVEST_SCHAPIRE;
869+
}
862870
}
863871
}

algorithms/active/adt/src/test/java/de/learnlib/algorithm/adt/it/ADTIT.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import de.learnlib.algorithm.adt.config.SubtreeReplacers;
3232
import de.learnlib.algorithm.adt.learner.ADTLearner;
3333
import de.learnlib.algorithm.adt.learner.ADTLearnerBuilder;
34+
import de.learnlib.counterexample.LocalSuffixFinder;
35+
import de.learnlib.counterexample.LocalSuffixFinders;
3436
import de.learnlib.driver.simulator.MealySimulatorSUL;
3537
import de.learnlib.filter.statistic.oracle.CounterAdaptiveQueryOracle;
3638
import de.learnlib.oracle.AdaptiveMembershipOracle;
@@ -49,6 +51,7 @@
4951
import net.automatalib.automaton.transducer.impl.CompactMealy;
5052
import net.automatalib.exception.FormatException;
5153
import net.automatalib.serialization.dot.DOTParsers;
54+
import org.checkerframework.checker.nullness.qual.Nullable;
5255
import org.testng.Assert;
5356
import org.testng.annotations.Test;
5457

@@ -88,9 +91,14 @@ protected <I, O> void addLearnerVariants(Alphabet<I> alphabet,
8891
for (int k = 0; k < SUBTREE_REPLACERS.size(); k++) {
8992
final SubtreeReplacer subtreeReplacer = SUBTREE_REPLACERS.get(k);
9093
builder.setSubtreeReplacer(subtreeReplacer);
91-
builder.setUseObservationTree(useCacheGenerator.nextBoolean());
9294

93-
variants.addLearnerVariant(i + "," + j + "," + k, builder.create());
95+
for (LocalSuffixFinder<@Nullable Object, @Nullable Object> suffixFinder : LocalSuffixFinders.values()) {
96+
builder.setSuffixFinder(suffixFinder);
97+
builder.setUseObservationTree(useCacheGenerator.nextBoolean());
98+
99+
variants.addLearnerVariant(i + "," + j + "," + k, builder.create());
100+
}
101+
94102
}
95103
}
96104
}

0 commit comments

Comments
 (0)