diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d8c94267..2e35e25ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,10 +17,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * Statistics collection has received a major rework. Previously, classes would implement the `StatisticCollector` interface and return a `StatisticData` object which 1) only allows for describing a very limited amount of data, and 2) requires you to keep track of all the objects that collect data. This approach has been *replaced* by a new `StatisticsService`. Instances of this service can be obtained similar to a logger via `Statistics.getService()` and require you to provide an implementation of this service on the classpath (a default one is provided by the `learnlib-statistics` module). The new service allows arbitrary components to collect various data which can be conveniently extracted based on the new `StatisticsKey`s used by the components. For more details on advanced scenarios (such as multi-threaded benchmarking), see the documentation of the respective classes. While this may require you to adjust the way you are collecting statistics, all functionality from beforehand should still be available. * `SimpleProfiler` has been replaced by the new clock-based statistics. * The `generateTestWords` method of `AbstractTestWordEQOracle` now needs to be public. +* The classes of `de.learnlib.testsupport.it.learner` have been split into the packages `de.learnlib.testsupport.it{,testcase,util,variant}` in the same module (`de.learnlib.testsupport:learnlib-learner-it-support`). ### Fixed * The `de.learnlib.algorithm.adt` module now correctly `exports` the `de.learnlib.algorithm.adt.config.model.*` packages. +* The `TTTLambdaMealy` learner now returns stable hypotheses that no longer issue queries during traversal. ## [0.18.0] - 2025-02-06 diff --git a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerIdentityDFAIT.java b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerIdentityDFAIT.java index a45313088..05b366baa 100644 --- a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerIdentityDFAIT.java +++ b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerIdentityDFAIT.java @@ -23,13 +23,18 @@ import de.learnlib.algorithm.aaar.explicit.IdentityInitialAbstraction; import de.learnlib.algorithm.aaar.explicit.NoopIncrementor; import de.learnlib.oracle.MembershipOracle.DFAMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractDFALearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.DFALearnerVariantList; +import de.learnlib.testsupport.it.AbstractDFALearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.DFALearnerVariantList; import net.automatalib.alphabet.Alphabet; import net.automatalib.common.util.Pair; public class ExplicitAAARLearnerIdentityDFAIT extends AbstractDFALearnerIT { + @Override + protected boolean requiresQueriesDuringHypothesisTraversal() { + return true; + } + @Override protected void addLearnerVariants(Alphabet alphabet, int targetSize, diff --git a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerIdentityMealyIT.java b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerIdentityMealyIT.java index ad22940c7..10b609e7b 100644 --- a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerIdentityMealyIT.java +++ b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerIdentityMealyIT.java @@ -23,14 +23,19 @@ import de.learnlib.algorithm.aaar.explicit.IdentityInitialAbstraction; import de.learnlib.algorithm.aaar.explicit.NoopIncrementor; import de.learnlib.oracle.MembershipOracle.MealyMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractMealyLearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MealyLearnerVariantList; +import de.learnlib.testsupport.it.AbstractMealyLearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MealyLearnerVariantList; import net.automatalib.alphabet.Alphabet; import net.automatalib.common.util.Pair; import net.automatalib.word.Word; public class ExplicitAAARLearnerIdentityMealyIT extends AbstractMealyLearnerIT { + @Override + protected boolean requiresQueriesDuringHypothesisTraversal() { + return true; + } + @Override protected void addLearnerVariants(Alphabet alphabet, int targetSize, diff --git a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerIdentityMooreIT.java b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerIdentityMooreIT.java index 213b4ae84..b82c3ed04 100644 --- a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerIdentityMooreIT.java +++ b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerIdentityMooreIT.java @@ -23,14 +23,19 @@ import de.learnlib.algorithm.aaar.explicit.IdentityInitialAbstraction; import de.learnlib.algorithm.aaar.explicit.NoopIncrementor; import de.learnlib.oracle.MembershipOracle.MooreMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractMooreLearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MooreLearnerVariantList; +import de.learnlib.testsupport.it.AbstractMooreLearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MooreLearnerVariantList; import net.automatalib.alphabet.Alphabet; import net.automatalib.common.util.Pair; import net.automatalib.word.Word; public class ExplicitAAARLearnerIdentityMooreIT extends AbstractMooreLearnerIT { + @Override + protected boolean requiresQueriesDuringHypothesisTraversal() { + return true; + } + @Override protected void addLearnerVariants(Alphabet alphabet, int targetSize, diff --git a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerModuloDFAIT.java b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerModuloDFAIT.java index 7054acefd..716d5e56b 100644 --- a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerModuloDFAIT.java +++ b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerModuloDFAIT.java @@ -23,13 +23,18 @@ import de.learnlib.algorithm.aaar.explicit.Incrementor; import de.learnlib.algorithm.aaar.explicit.ModuloInitialAbstraction; import de.learnlib.oracle.MembershipOracle.DFAMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractDFALearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.DFALearnerVariantList; +import de.learnlib.testsupport.it.AbstractDFALearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.DFALearnerVariantList; import net.automatalib.alphabet.Alphabet; import net.automatalib.common.util.Pair; public class ExplicitAAARLearnerModuloDFAIT extends AbstractDFALearnerIT { + @Override + protected boolean requiresQueriesDuringHypothesisTraversal() { + return true; + } + @Override protected void addLearnerVariants(Alphabet alphabet, int targetSize, diff --git a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerModuloMealyIT.java b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerModuloMealyIT.java index e4f04c4db..e274e33df 100644 --- a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerModuloMealyIT.java +++ b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerModuloMealyIT.java @@ -23,14 +23,19 @@ import de.learnlib.algorithm.aaar.explicit.Incrementor; import de.learnlib.algorithm.aaar.explicit.ModuloInitialAbstraction; import de.learnlib.oracle.MembershipOracle.MealyMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractMealyLearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MealyLearnerVariantList; +import de.learnlib.testsupport.it.AbstractMealyLearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MealyLearnerVariantList; import net.automatalib.alphabet.Alphabet; import net.automatalib.common.util.Pair; import net.automatalib.word.Word; public class ExplicitAAARLearnerModuloMealyIT extends AbstractMealyLearnerIT { + @Override + protected boolean requiresQueriesDuringHypothesisTraversal() { + return true; + } + @Override protected void addLearnerVariants(Alphabet alphabet, int targetSize, diff --git a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerModuloMooreIT.java b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerModuloMooreIT.java index 84bda9298..448043ceb 100644 --- a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerModuloMooreIT.java +++ b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/explicit/it/ExplicitAAARLearnerModuloMooreIT.java @@ -23,14 +23,19 @@ import de.learnlib.algorithm.aaar.explicit.Incrementor; import de.learnlib.algorithm.aaar.explicit.ModuloInitialAbstraction; import de.learnlib.oracle.MembershipOracle.MooreMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractMooreLearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MooreLearnerVariantList; +import de.learnlib.testsupport.it.AbstractMooreLearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MooreLearnerVariantList; import net.automatalib.alphabet.Alphabet; import net.automatalib.common.util.Pair; import net.automatalib.word.Word; public class ExplicitAAARLearnerModuloMooreIT extends AbstractMooreLearnerIT { + @Override + protected boolean requiresQueriesDuringHypothesisTraversal() { + return true; + } + @Override protected void addLearnerVariants(Alphabet alphabet, int targetSize, diff --git a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/generic/it/GenericAAARLearnerDFAIT.java b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/generic/it/GenericAAARLearnerDFAIT.java index b02ede962..4cecdcade 100644 --- a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/generic/it/GenericAAARLearnerDFAIT.java +++ b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/generic/it/GenericAAARLearnerDFAIT.java @@ -23,13 +23,18 @@ import de.learnlib.algorithm.aaar.TranslatingLearnerWrapper; import de.learnlib.algorithm.aaar.generic.GenericAAARLearnerDFA; import de.learnlib.oracle.MembershipOracle.DFAMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractDFALearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.DFALearnerVariantList; +import de.learnlib.testsupport.it.AbstractDFALearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.DFALearnerVariantList; import net.automatalib.alphabet.Alphabet; import net.automatalib.common.util.Pair; public class GenericAAARLearnerDFAIT extends AbstractDFALearnerIT { + @Override + protected boolean requiresQueriesDuringHypothesisTraversal() { + return true; + } + @Override protected void addLearnerVariants(Alphabet alphabet, int targetSize, diff --git a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/generic/it/GenericAAARLearnerMealyIT.java b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/generic/it/GenericAAARLearnerMealyIT.java index 6fe93c698..a5a853d2e 100644 --- a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/generic/it/GenericAAARLearnerMealyIT.java +++ b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/generic/it/GenericAAARLearnerMealyIT.java @@ -23,14 +23,19 @@ import de.learnlib.algorithm.aaar.TranslatingLearnerWrapper; import de.learnlib.algorithm.aaar.generic.GenericAAARLearnerMealy; import de.learnlib.oracle.MembershipOracle.MealyMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractMealyLearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MealyLearnerVariantList; +import de.learnlib.testsupport.it.AbstractMealyLearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MealyLearnerVariantList; import net.automatalib.alphabet.Alphabet; import net.automatalib.common.util.Pair; import net.automatalib.word.Word; public class GenericAAARLearnerMealyIT extends AbstractMealyLearnerIT { + @Override + protected boolean requiresQueriesDuringHypothesisTraversal() { + return true; + } + @Override protected void addLearnerVariants(Alphabet alphabet, int targetSize, diff --git a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/generic/it/GenericAAARLearnerMooreIT.java b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/generic/it/GenericAAARLearnerMooreIT.java index 389f648ab..4e0201cbc 100644 --- a/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/generic/it/GenericAAARLearnerMooreIT.java +++ b/algorithms/active/aaar/src/test/java/de/learnlib/algorithm/aaar/generic/it/GenericAAARLearnerMooreIT.java @@ -23,14 +23,19 @@ import de.learnlib.algorithm.aaar.TranslatingLearnerWrapper; import de.learnlib.algorithm.aaar.generic.GenericAAARLearnerMoore; import de.learnlib.oracle.MembershipOracle.MooreMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractMooreLearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MooreLearnerVariantList; +import de.learnlib.testsupport.it.AbstractMooreLearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MooreLearnerVariantList; import net.automatalib.alphabet.Alphabet; import net.automatalib.common.util.Pair; import net.automatalib.word.Word; public class GenericAAARLearnerMooreIT extends AbstractMooreLearnerIT { + @Override + protected boolean requiresQueriesDuringHypothesisTraversal() { + return true; + } + @Override protected void addLearnerVariants(Alphabet alphabet, int targetSize, diff --git a/algorithms/active/adt/src/test/java/de/learnlib/algorithm/adt/it/ADTIT.java b/algorithms/active/adt/src/test/java/de/learnlib/algorithm/adt/it/ADTIT.java index 57b6b2fd2..a6089acd0 100644 --- a/algorithms/active/adt/src/test/java/de/learnlib/algorithm/adt/it/ADTIT.java +++ b/algorithms/active/adt/src/test/java/de/learnlib/algorithm/adt/it/ADTIT.java @@ -45,8 +45,8 @@ import de.learnlib.statistic.Statistics; import de.learnlib.sul.SUL; import de.learnlib.testsupport.MQ2AQWrapper; -import de.learnlib.testsupport.it.learner.AbstractMealyLearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList; +import de.learnlib.testsupport.it.AbstractMealyLearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList; import de.learnlib.util.Experiment.MealyExperiment; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.transducer.impl.CompactMealy; diff --git a/algorithms/active/dhc/src/test/java/de/learnlib/algorithm/dhc/mealy/it/MealyDHCIT.java b/algorithms/active/dhc/src/test/java/de/learnlib/algorithm/dhc/mealy/it/MealyDHCIT.java index 67ab7c56a..68278ead7 100644 --- a/algorithms/active/dhc/src/test/java/de/learnlib/algorithm/dhc/mealy/it/MealyDHCIT.java +++ b/algorithms/active/dhc/src/test/java/de/learnlib/algorithm/dhc/mealy/it/MealyDHCIT.java @@ -19,8 +19,8 @@ import de.learnlib.counterexample.GlobalSuffixFinder; import de.learnlib.counterexample.GlobalSuffixFinders; import de.learnlib.oracle.MembershipOracle.MealyMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractMealyLearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MealyLearnerVariantList; +import de.learnlib.testsupport.it.AbstractMealyLearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MealyLearnerVariantList; import net.automatalib.alphabet.Alphabet; import net.automatalib.word.Word; diff --git a/algorithms/active/kearns-vazirani/src/test/java/de/learnlib/algorithm/kv/dfa/KearnsVaziraniDFAIT.java b/algorithms/active/kearns-vazirani/src/test/java/de/learnlib/algorithm/kv/dfa/KearnsVaziraniDFAIT.java index ed530d35e..5aa8739a6 100644 --- a/algorithms/active/kearns-vazirani/src/test/java/de/learnlib/algorithm/kv/dfa/KearnsVaziraniDFAIT.java +++ b/algorithms/active/kearns-vazirani/src/test/java/de/learnlib/algorithm/kv/dfa/KearnsVaziraniDFAIT.java @@ -18,8 +18,8 @@ import de.learnlib.acex.AbstractNamedAcexAnalyzer; import de.learnlib.acex.AcexAnalyzers; import de.learnlib.oracle.MembershipOracle.DFAMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractDFALearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.DFALearnerVariantList; +import de.learnlib.testsupport.it.AbstractDFALearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.DFALearnerVariantList; import net.automatalib.alphabet.Alphabet; import org.testng.annotations.Test; diff --git a/algorithms/active/kearns-vazirani/src/test/java/de/learnlib/algorithm/kv/mealy/KearnsVaziraniMealyIT.java b/algorithms/active/kearns-vazirani/src/test/java/de/learnlib/algorithm/kv/mealy/KearnsVaziraniMealyIT.java index 066d0339d..b4a86ca09 100644 --- a/algorithms/active/kearns-vazirani/src/test/java/de/learnlib/algorithm/kv/mealy/KearnsVaziraniMealyIT.java +++ b/algorithms/active/kearns-vazirani/src/test/java/de/learnlib/algorithm/kv/mealy/KearnsVaziraniMealyIT.java @@ -18,8 +18,8 @@ import de.learnlib.acex.AbstractNamedAcexAnalyzer; import de.learnlib.acex.AcexAnalyzers; import de.learnlib.oracle.MembershipOracle.MealyMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractMealyLearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MealyLearnerVariantList; +import de.learnlib.testsupport.it.AbstractMealyLearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MealyLearnerVariantList; import net.automatalib.alphabet.Alphabet; import org.testng.annotations.Test; diff --git a/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/AbstractTTTLambda.java b/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/AbstractTTTLambda.java index c0c319f2d..70786e1c6 100644 --- a/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/AbstractTTTLambda.java +++ b/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/AbstractTTTLambda.java @@ -34,12 +34,13 @@ import net.automatalib.automaton.concept.FiniteRepresentation; import net.automatalib.automaton.concept.SuffixOutput; import net.automatalib.word.Word; +import org.checkerframework.checker.nullness.qual.Nullable; public abstract class AbstractTTTLambda, I, D> implements LearningAlgorithm, SupportsGrowingAlphabet, FiniteRepresentation { private final MembershipOracle ceqs; - private final Alphabet alphabet; + protected final Alphabet alphabet; protected final SuffixTrie strie; protected final PrefixTree ptree; @@ -53,7 +54,7 @@ protected AbstractTTTLambda(Alphabet alphabet, MembershipOracle ceqs) { protected abstract int maxSearchIndex(int ceLength); - protected abstract DTLeaf getState(Word prefix); + protected abstract @Nullable DTLeaf getState(Word prefix); protected abstract AbstractDecisionTree dtree(); @@ -115,7 +116,7 @@ public void addAlphabetSymbol(I symbol) { } } - private void makeConsistent() { + protected void makeConsistent() { while (dtree().makeConsistent()) { // do nothing ... } @@ -174,6 +175,7 @@ private void analyzeCounterexample(DefaultQuery counterexample, Deque sprime = ce.suffix(ce.length() - (mid + 1)); DTLeaf qnext = getState(ua.word()); + assert qnext != null; for (PTNode uprime : qnext.getShortPrefixes()) { witnesses.push(new DefaultQuery<>(uprime.word(), sprime)); } diff --git a/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/dfa/TTTLambdaDFA.java b/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/dfa/TTTLambdaDFA.java index 1084a8bc7..318b21afe 100644 --- a/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/dfa/TTTLambdaDFA.java +++ b/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/dfa/TTTLambdaDFA.java @@ -24,6 +24,7 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.fsa.DFA; import net.automatalib.word.Word; +import org.checkerframework.checker.nullness.qual.Nullable; public class TTTLambdaDFA extends AbstractTTTLambda, I, Boolean> implements DFALearner { @@ -48,7 +49,7 @@ protected int maxSearchIndex(int ceLength) { } @Override - protected DTLeaf getState(Word prefix) { + protected @Nullable DTLeaf getState(Word prefix) { return hypothesis.getState(prefix); } diff --git a/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/mealy/DecisionTreeMealy.java b/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/mealy/DecisionTreeMealy.java index f0bce016c..c9c4f59c1 100644 --- a/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/mealy/DecisionTreeMealy.java +++ b/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/mealy/DecisionTreeMealy.java @@ -19,6 +19,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Objects; import de.learnlib.algorithm.lambda.ttt.dt.AbstractDecisionTree; import de.learnlib.algorithm.lambda.ttt.dt.Children; @@ -31,7 +32,7 @@ class DecisionTreeMealy extends AbstractDecisionTree> { - private final Map, Word> outputs; + private final Map, O> outputs; DecisionTreeMealy(MembershipOracle> mqOracle, Alphabet sigma, STNode stRoot) { super(sigma, mqOracle, stRoot); @@ -45,11 +46,11 @@ protected Children> newChildren() { @Override protected Word query(PTNode> prefix, STNode suffix) { - return mqOracle.answerQuery(prefix.word(), suffix.word()).suffix(suffix.word().length()); + return mqOracle.answerQuery(prefix.word(), suffix.word()); } - Word getOutput(DTLeaf> leaf, I a) { - return lookupOrQuery(leaf.getShortPrefixes().get(0).word(), Word.fromLetter(a)); + O getOutput(DTLeaf> leaf, I a) { + return lookupOrQuery(leaf.getShortPrefixes().get(0).word(), a); } @Override @@ -59,13 +60,13 @@ public boolean makeConsistent() { continue; } for (I a : alphabet) { - Word refOut = null; + O refOut = null; List>> sp = new LinkedList<>(n.getShortPrefixes()); for (PTNode> u : sp) { - Word out = lookupOrQuery(u.word(), Word.fromLetter(a)); + O out = lookupOrQuery(u.word(), a); if (refOut == null) { refOut = out; - } else if (!refOut.equals(out)) { + } else if (!Objects.equals(refOut, out)) { n.split(sp.get(0), u, a); return true; } @@ -75,11 +76,11 @@ public boolean makeConsistent() { return super.makeConsistent(); } - private Word lookupOrQuery(Word prefix, Word suffix) { - Word lookup = prefix.concat(suffix); - Word out = this.outputs.get(lookup); + private O lookupOrQuery(Word prefix, I step) { + Word lookup = prefix.append(step); + O out = this.outputs.get(lookup); if (out == null) { - out = mqOracle.answerQuery(prefix, suffix).suffix(1); + out = mqOracle.answerQuery(prefix, Word.fromLetter(step)).lastSymbol(); this.outputs.put(lookup, out); } return out; diff --git a/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/mealy/HypothesisMealy.java b/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/mealy/HypothesisMealy.java index dc8e7d04b..8f368c0fb 100644 --- a/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/mealy/HypothesisMealy.java +++ b/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/mealy/HypothesisMealy.java @@ -20,6 +20,7 @@ import de.learnlib.algorithm.lambda.ttt.dt.DTLeaf; import de.learnlib.algorithm.lambda.ttt.pt.PTNode; import de.learnlib.algorithm.lambda.ttt.pt.PrefixTree; +import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.word.Word; @@ -40,7 +41,7 @@ public Collection>> getStates() { @Override public O getTransitionOutput(MealyTransition o) { - return dtree.getOutput(o.source, o.input).lastSymbol(); + return dtree.getOutput(o.source, o.input); } @Override @@ -63,4 +64,19 @@ public DTLeaf> getSuccessor(MealyTransition o) { public DTLeaf> getInitialState() { return ptree.root().state(); } + + /** + * Makes sure that all transition outputs have been fetched, so that no more queries are being posed (e.g., after + * refinement) when the hypothesis is traversed. + * + * @param alphabet + * the alphabet symbols for which outputs should be fetched + */ + void fetchAllPendingOutputs(Alphabet alphabet) { + for (DTLeaf> s : dtree.leaves()) { + for (I i : alphabet) { + dtree.getOutput(s, i); + } + } + } } diff --git a/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/mealy/TTTLambdaMealy.java b/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/mealy/TTTLambdaMealy.java index 1e9c92c9b..e83c0efe6 100644 --- a/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/mealy/TTTLambdaMealy.java +++ b/algorithms/active/lambda/src/main/java/de/learnlib/algorithm/lambda/ttt/mealy/TTTLambdaMealy.java @@ -23,6 +23,7 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.word.Word; +import org.checkerframework.checker.nullness.qual.Nullable; public class TTTLambdaMealy extends AbstractTTTLambda, I, Word> implements MealyLearner { @@ -52,7 +53,7 @@ protected int maxSearchIndex(int ceLength) { } @Override - protected DTLeaf> getState(Word prefix) { + protected @Nullable DTLeaf> getState(Word prefix) { return hypothesis.getState(prefix); } @@ -70,4 +71,10 @@ protected AbstractDecisionTree> dtree() { public int size() { return hypothesis.size(); } + + @Override + protected void makeConsistent() { + super.makeConsistent(); + hypothesis.fetchAllPendingOutputs(super.alphabet); + } } diff --git a/algorithms/active/lambda/src/test/java/de/learnlib/algorithm/lambda/lstar/dfa/it/LLambdaDFAIT.java b/algorithms/active/lambda/src/test/java/de/learnlib/algorithm/lambda/lstar/dfa/it/LLambdaDFAIT.java index 4248d83d5..4e057fa76 100644 --- a/algorithms/active/lambda/src/test/java/de/learnlib/algorithm/lambda/lstar/dfa/it/LLambdaDFAIT.java +++ b/algorithms/active/lambda/src/test/java/de/learnlib/algorithm/lambda/lstar/dfa/it/LLambdaDFAIT.java @@ -17,8 +17,8 @@ import de.learnlib.algorithm.lambda.lstar.LLambdaDFA; import de.learnlib.oracle.MembershipOracle.DFAMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractDFALearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.DFALearnerVariantList; +import de.learnlib.testsupport.it.AbstractDFALearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.DFALearnerVariantList; import net.automatalib.alphabet.Alphabet; import org.testng.annotations.Test; diff --git a/algorithms/active/lambda/src/test/java/de/learnlib/algorithm/lambda/lstar/mealy/it/LLambdaMealyIT.java b/algorithms/active/lambda/src/test/java/de/learnlib/algorithm/lambda/lstar/mealy/it/LLambdaMealyIT.java index f75f766e6..72a6c34af 100644 --- a/algorithms/active/lambda/src/test/java/de/learnlib/algorithm/lambda/lstar/mealy/it/LLambdaMealyIT.java +++ b/algorithms/active/lambda/src/test/java/de/learnlib/algorithm/lambda/lstar/mealy/it/LLambdaMealyIT.java @@ -28,8 +28,8 @@ import de.learnlib.oracle.equivalence.MealyRandomWpMethodEQOracle; import de.learnlib.oracle.membership.SULOracle; import de.learnlib.query.DefaultQuery; -import de.learnlib.testsupport.it.learner.AbstractMealyLearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MealyLearnerVariantList; +import de.learnlib.testsupport.it.AbstractMealyLearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MealyLearnerVariantList; import de.learnlib.util.Experiment.MealyExperiment; import de.learnlib.util.mealy.MealyUtil; import net.automatalib.alphabet.Alphabet; diff --git a/algorithms/active/lambda/src/test/java/de/learnlib/algorithm/lambda/ttt/dfa/it/TTTLambdaDFAIT.java b/algorithms/active/lambda/src/test/java/de/learnlib/algorithm/lambda/ttt/dfa/it/TTTLambdaDFAIT.java index 46417f713..a49aee97f 100644 --- a/algorithms/active/lambda/src/test/java/de/learnlib/algorithm/lambda/ttt/dfa/it/TTTLambdaDFAIT.java +++ b/algorithms/active/lambda/src/test/java/de/learnlib/algorithm/lambda/ttt/dfa/it/TTTLambdaDFAIT.java @@ -17,8 +17,8 @@ import de.learnlib.algorithm.lambda.ttt.dfa.TTTLambdaDFA; import de.learnlib.oracle.MembershipOracle.DFAMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractDFALearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.DFALearnerVariantList; +import de.learnlib.testsupport.it.AbstractDFALearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.DFALearnerVariantList; import net.automatalib.alphabet.Alphabet; import org.testng.annotations.Test; diff --git a/algorithms/active/lambda/src/test/java/de/learnlib/algorithm/lambda/ttt/mealy/it/TTTLambdaMealyIT.java b/algorithms/active/lambda/src/test/java/de/learnlib/algorithm/lambda/ttt/mealy/it/TTTLambdaMealyIT.java index b5f5eac09..3f857b48c 100644 --- a/algorithms/active/lambda/src/test/java/de/learnlib/algorithm/lambda/ttt/mealy/it/TTTLambdaMealyIT.java +++ b/algorithms/active/lambda/src/test/java/de/learnlib/algorithm/lambda/ttt/mealy/it/TTTLambdaMealyIT.java @@ -17,8 +17,8 @@ import de.learnlib.algorithm.lambda.ttt.mealy.TTTLambdaMealy; import de.learnlib.oracle.MembershipOracle.MealyMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractMealyLearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MealyLearnerVariantList; +import de.learnlib.testsupport.it.AbstractMealyLearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MealyLearnerVariantList; import net.automatalib.alphabet.Alphabet; import org.testng.annotations.Test; diff --git a/algorithms/active/lsharp/src/test/java/de/learnlib/algorithm/lsharp/it/LSharpMealyIT.java b/algorithms/active/lsharp/src/test/java/de/learnlib/algorithm/lsharp/it/LSharpMealyIT.java index 893a90d1a..e4e57faad 100644 --- a/algorithms/active/lsharp/src/test/java/de/learnlib/algorithm/lsharp/it/LSharpMealyIT.java +++ b/algorithms/active/lsharp/src/test/java/de/learnlib/algorithm/lsharp/it/LSharpMealyIT.java @@ -23,8 +23,8 @@ import de.learnlib.algorithm.lsharp.Rule3; import de.learnlib.oracle.MembershipOracle.MealyMembershipOracle; import de.learnlib.testsupport.MQ2AQWrapper; -import de.learnlib.testsupport.it.learner.AbstractMealyLearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MealyLearnerVariantList; +import de.learnlib.testsupport.it.AbstractMealyLearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MealyLearnerVariantList; import net.automatalib.alphabet.Alphabet; import org.testng.annotations.Test; diff --git a/algorithms/active/lstar/src/main/java/de/learnlib/algorithm/lstar/mmlt/ExtensibleLStarMMLT.java b/algorithms/active/lstar/src/main/java/de/learnlib/algorithm/lstar/mmlt/ExtensibleLStarMMLT.java index 031ce1ca3..5e2d0d040 100644 --- a/algorithms/active/lstar/src/main/java/de/learnlib/algorithm/lstar/mmlt/ExtensibleLStarMMLT.java +++ b/algorithms/active/lstar/src/main/java/de/learnlib/algorithm/lstar/mmlt/ExtensibleLStarMMLT.java @@ -267,7 +267,6 @@ public static int selectOneShotTimer(List> sortedT * @return the internal hypothesis */ private MMLTHypothesis getInternalHypothesisModel() { - this.updateOutputs(); return constructHypothesis(this.hypData); } @@ -325,6 +324,8 @@ public void startLearning() { // Ensure that closed: this.completeConsistentTable(initialUnclosed); + // Ensure that all outputs are fetched + this.updateOutputs(); } @Override @@ -371,7 +372,7 @@ public boolean refineHypothesis(DefaultQuery, Word> } private boolean refineHypothesisSingle(DefaultQuery, Word>> ceQuery) { - // 1. Update hypothesis (may have changed since last refinement): + // 1. Current hypothesis: MMLTHypothesis hypothesis = this.getInternalHypothesisModel(); // 2. Transform to output inconsistency: @@ -436,6 +437,9 @@ private boolean refineHypothesisSingle(DefaultQuery, Word alphabet, MembershipOracle or @Override public Word transformAccessSequence(Word word) { - final List> shortPrefixes = super.getState(word).getShortPrefixes(); + DTLeaf state = super.getState(word); + assert state != null; + final List> shortPrefixes = state.getShortPrefixes(); assert shortPrefixes.size() == 1; return shortPrefixes.get(0).word(); diff --git a/algorithms/active/procedural/src/main/java/de/learnlib/algorithm/procedural/adapter/mealy/TTTLambdaAdapterMealy.java b/algorithms/active/procedural/src/main/java/de/learnlib/algorithm/procedural/adapter/mealy/TTTLambdaAdapterMealy.java index e73652490..9984befbc 100644 --- a/algorithms/active/procedural/src/main/java/de/learnlib/algorithm/procedural/adapter/mealy/TTTLambdaAdapterMealy.java +++ b/algorithms/active/procedural/src/main/java/de/learnlib/algorithm/procedural/adapter/mealy/TTTLambdaAdapterMealy.java @@ -18,6 +18,7 @@ import java.util.List; import de.learnlib.AccessSequenceTransformer; +import de.learnlib.algorithm.lambda.ttt.dt.DTLeaf; import de.learnlib.algorithm.lambda.ttt.mealy.TTTLambdaMealy; import de.learnlib.algorithm.lambda.ttt.pt.PTNode; import de.learnlib.oracle.MembershipOracle; @@ -40,8 +41,10 @@ public TTTLambdaAdapterMealy(Alphabet alphabet, MembershipOracle> @Override public Word transformAccessSequence(Word word) { - final List>> shortPrefixes = super.getState(word).getShortPrefixes(); + DTLeaf> state = super.getState(word); + assert state != null; + final List>> shortPrefixes = state.getShortPrefixes(); assert shortPrefixes.size() == 1; return shortPrefixes.get(0).word(); diff --git a/algorithms/active/procedural/src/test/java/de/learnlib/algorithm/procedural/sba/it/SBAIT.java b/algorithms/active/procedural/src/test/java/de/learnlib/algorithm/procedural/sba/it/SBAIT.java index 88023622e..bd9004dfd 100644 --- a/algorithms/active/procedural/src/test/java/de/learnlib/algorithm/procedural/sba/it/SBAIT.java +++ b/algorithms/active/procedural/src/test/java/de/learnlib/algorithm/procedural/sba/it/SBAIT.java @@ -38,8 +38,8 @@ import de.learnlib.algorithm.procedural.sba.manager.OptimizingATManager; import de.learnlib.oracle.MembershipOracle; import de.learnlib.oracle.MembershipOracle.DFAMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractSBALearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.SBALearnerVariantList; +import de.learnlib.testsupport.it.AbstractSBALearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.SBALearnerVariantList; import net.automatalib.alphabet.ProceduralInputAlphabet; import net.automatalib.alphabet.SupportsGrowingAlphabet; diff --git a/algorithms/active/procedural/src/test/java/de/learnlib/algorithm/procedural/spa/it/SPAIT.java b/algorithms/active/procedural/src/test/java/de/learnlib/algorithm/procedural/spa/it/SPAIT.java index 77d7eafd1..02051c67f 100644 --- a/algorithms/active/procedural/src/test/java/de/learnlib/algorithm/procedural/spa/it/SPAIT.java +++ b/algorithms/active/procedural/src/test/java/de/learnlib/algorithm/procedural/spa/it/SPAIT.java @@ -37,8 +37,8 @@ import de.learnlib.algorithm.procedural.spa.manager.OptimizingATRManager; import de.learnlib.oracle.MembershipOracle; import de.learnlib.oracle.MembershipOracle.DFAMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractSPALearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.SPALearnerVariantList; +import de.learnlib.testsupport.it.AbstractSPALearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.SPALearnerVariantList; import net.automatalib.alphabet.ProceduralInputAlphabet; import net.automatalib.alphabet.SupportsGrowingAlphabet; diff --git a/algorithms/active/procedural/src/test/java/de/learnlib/algorithm/procedural/spmm/it/SPMMIT.java b/algorithms/active/procedural/src/test/java/de/learnlib/algorithm/procedural/spmm/it/SPMMIT.java index ac6ff0f3d..19d1478cf 100644 --- a/algorithms/active/procedural/src/test/java/de/learnlib/algorithm/procedural/spmm/it/SPMMIT.java +++ b/algorithms/active/procedural/src/test/java/de/learnlib/algorithm/procedural/spmm/it/SPMMIT.java @@ -37,8 +37,8 @@ import de.learnlib.algorithm.procedural.spmm.manager.OptimizingATManager; import de.learnlib.oracle.MembershipOracle; import de.learnlib.oracle.MembershipOracle.MealyMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractSPMMLearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.SPMMLearnerVariantList; +import de.learnlib.testsupport.it.AbstractSPMMLearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.SPMMLearnerVariantList; import net.automatalib.alphabet.ProceduralInputAlphabet; import net.automatalib.alphabet.SupportsGrowingAlphabet; import net.automatalib.word.Word; diff --git a/algorithms/active/ttt-vpa/src/test/java/de/learnlib/algorithm/ttt/dfa/it/TTTLearnerVPAIT.java b/algorithms/active/ttt-vpa/src/test/java/de/learnlib/algorithm/ttt/dfa/it/TTTLearnerVPAIT.java index a5a9afec2..e6fdbf499 100644 --- a/algorithms/active/ttt-vpa/src/test/java/de/learnlib/algorithm/ttt/dfa/it/TTTLearnerVPAIT.java +++ b/algorithms/active/ttt-vpa/src/test/java/de/learnlib/algorithm/ttt/dfa/it/TTTLearnerVPAIT.java @@ -19,8 +19,8 @@ import de.learnlib.acex.AcexAnalyzers; import de.learnlib.algorithm.ttt.vpa.TTTLearnerVPABuilder; import de.learnlib.oracle.MembershipOracle.DFAMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractOneSEVPALearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList; +import de.learnlib.testsupport.it.AbstractOneSEVPALearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList; import net.automatalib.alphabet.VPAlphabet; import org.testng.annotations.Test; diff --git a/algorithms/active/ttt/src/test/java/de/learnlib/algorithm/ttt/dfa/it/PrefixTTTLearnerDFAIT.java b/algorithms/active/ttt/src/test/java/de/learnlib/algorithm/ttt/dfa/it/PrefixTTTLearnerDFAIT.java index 3394f6108..466958b86 100644 --- a/algorithms/active/ttt/src/test/java/de/learnlib/algorithm/ttt/dfa/it/PrefixTTTLearnerDFAIT.java +++ b/algorithms/active/ttt/src/test/java/de/learnlib/algorithm/ttt/dfa/it/PrefixTTTLearnerDFAIT.java @@ -19,8 +19,8 @@ import de.learnlib.acex.AcexAnalyzers; import de.learnlib.algorithm.ttt.dfa.PrefixTTTLearnerDFA; import de.learnlib.oracle.MembershipOracle.DFAMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractDFALearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.DFALearnerVariantList; +import de.learnlib.testsupport.it.AbstractDFALearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.DFALearnerVariantList; import net.automatalib.alphabet.Alphabet; import org.testng.annotations.Test; diff --git a/algorithms/active/ttt/src/test/java/de/learnlib/algorithm/ttt/dfa/it/TTTLearnerDFAIT.java b/algorithms/active/ttt/src/test/java/de/learnlib/algorithm/ttt/dfa/it/TTTLearnerDFAIT.java index b2683d90f..4ea747606 100644 --- a/algorithms/active/ttt/src/test/java/de/learnlib/algorithm/ttt/dfa/it/TTTLearnerDFAIT.java +++ b/algorithms/active/ttt/src/test/java/de/learnlib/algorithm/ttt/dfa/it/TTTLearnerDFAIT.java @@ -19,8 +19,8 @@ import de.learnlib.acex.AcexAnalyzers; import de.learnlib.algorithm.ttt.dfa.TTTLearnerDFABuilder; import de.learnlib.oracle.MembershipOracle.DFAMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractDFALearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.DFALearnerVariantList; +import de.learnlib.testsupport.it.AbstractDFALearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.DFALearnerVariantList; import net.automatalib.alphabet.Alphabet; import org.testng.annotations.Test; diff --git a/algorithms/active/ttt/src/test/java/de/learnlib/algorithm/ttt/mealy/it/TTTLearnerMealyIT.java b/algorithms/active/ttt/src/test/java/de/learnlib/algorithm/ttt/mealy/it/TTTLearnerMealyIT.java index bfd030563..83db41b82 100644 --- a/algorithms/active/ttt/src/test/java/de/learnlib/algorithm/ttt/mealy/it/TTTLearnerMealyIT.java +++ b/algorithms/active/ttt/src/test/java/de/learnlib/algorithm/ttt/mealy/it/TTTLearnerMealyIT.java @@ -19,8 +19,8 @@ import de.learnlib.acex.AcexAnalyzers; import de.learnlib.algorithm.ttt.mealy.TTTLearnerMealyBuilder; import de.learnlib.oracle.MembershipOracle.MealyMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractMealyLearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MealyLearnerVariantList; +import de.learnlib.testsupport.it.AbstractMealyLearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MealyLearnerVariantList; import net.automatalib.alphabet.Alphabet; import org.testng.annotations.Test; diff --git a/algorithms/active/ttt/src/test/java/de/learnlib/algorithm/ttt/moore/it/TTTLearnerMooreIT.java b/algorithms/active/ttt/src/test/java/de/learnlib/algorithm/ttt/moore/it/TTTLearnerMooreIT.java index 450d9fbc5..5ca5189ac 100644 --- a/algorithms/active/ttt/src/test/java/de/learnlib/algorithm/ttt/moore/it/TTTLearnerMooreIT.java +++ b/algorithms/active/ttt/src/test/java/de/learnlib/algorithm/ttt/moore/it/TTTLearnerMooreIT.java @@ -19,8 +19,8 @@ import de.learnlib.acex.AcexAnalyzers; import de.learnlib.algorithm.ttt.moore.TTTLearnerMooreBuilder; import de.learnlib.oracle.MembershipOracle.MooreMembershipOracle; -import de.learnlib.testsupport.it.learner.AbstractMooreLearnerIT; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MooreLearnerVariantList; +import de.learnlib.testsupport.it.AbstractMooreLearnerIT; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MooreLearnerVariantList; import net.automatalib.alphabet.Alphabet; import org.testng.annotations.Test; diff --git a/algorithms/passive/ostia/src/test/java/de/learnlib/algorithm/ostia/OSTIAIT.java b/algorithms/passive/ostia/src/test/java/de/learnlib/algorithm/ostia/OSTIAIT.java index 620844141..24f736a40 100644 --- a/algorithms/passive/ostia/src/test/java/de/learnlib/algorithm/ostia/OSTIAIT.java +++ b/algorithms/passive/ostia/src/test/java/de/learnlib/algorithm/ostia/OSTIAIT.java @@ -15,8 +15,8 @@ */ package de.learnlib.algorithm.ostia; -import de.learnlib.testsupport.it.learner.AbstractSSTPassiveLearnerIT; -import de.learnlib.testsupport.it.learner.PassiveLearnerVariantList; +import de.learnlib.testsupport.it.AbstractSSTPassiveLearnerIT; +import de.learnlib.testsupport.it.variant.PassiveLearnerVariantList; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.transducer.SubsequentialTransducer; import net.automatalib.word.Word; diff --git a/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/EdsmDfaIT.java b/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/EdsmDfaIT.java index 5ef209dc5..d1f75de5d 100644 --- a/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/EdsmDfaIT.java +++ b/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/EdsmDfaIT.java @@ -18,8 +18,8 @@ import de.learnlib.algorithm.rpni.BlueFringeEDSMDFA; import de.learnlib.datastructure.pta.config.DefaultProcessingOrders; import de.learnlib.datastructure.pta.config.ProcessingOrder; -import de.learnlib.testsupport.it.learner.AbstractDFAPassiveLearnerIT; -import de.learnlib.testsupport.it.learner.PassiveLearnerVariantList; +import de.learnlib.testsupport.it.AbstractDFAPassiveLearnerIT; +import de.learnlib.testsupport.it.variant.PassiveLearnerVariantList; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.fsa.DFA; diff --git a/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/MdlDfaIT.java b/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/MdlDfaIT.java index fc68b7179..c305cf667 100644 --- a/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/MdlDfaIT.java +++ b/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/MdlDfaIT.java @@ -20,9 +20,9 @@ import de.learnlib.algorithm.rpni.BlueFringeMDLDFA; import de.learnlib.query.DefaultQuery; -import de.learnlib.testsupport.it.learner.AbstractDFAPassiveLearnerIT; -import de.learnlib.testsupport.it.learner.LearnerITUtil; -import de.learnlib.testsupport.it.learner.PassiveLearnerVariantList; +import de.learnlib.testsupport.it.AbstractDFAPassiveLearnerIT; +import de.learnlib.testsupport.it.util.LearnerITUtil; +import de.learnlib.testsupport.it.variant.PassiveLearnerVariantList; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.fsa.DFA; diff --git a/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/RpniDfaIT.java b/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/RpniDfaIT.java index a4483d89a..a9519a26f 100644 --- a/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/RpniDfaIT.java +++ b/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/RpniDfaIT.java @@ -18,8 +18,8 @@ import de.learnlib.algorithm.rpni.BlueFringeRPNIDFA; import de.learnlib.datastructure.pta.config.DefaultProcessingOrders; import de.learnlib.datastructure.pta.config.ProcessingOrder; -import de.learnlib.testsupport.it.learner.AbstractDFAPassiveLearnerIT; -import de.learnlib.testsupport.it.learner.PassiveLearnerVariantList; +import de.learnlib.testsupport.it.AbstractDFAPassiveLearnerIT; +import de.learnlib.testsupport.it.variant.PassiveLearnerVariantList; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.fsa.DFA; diff --git a/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/RpniMealyIT.java b/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/RpniMealyIT.java index 7b2bbd9e7..753bce1e6 100644 --- a/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/RpniMealyIT.java +++ b/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/RpniMealyIT.java @@ -18,8 +18,8 @@ import de.learnlib.algorithm.rpni.BlueFringeRPNIMealy; import de.learnlib.datastructure.pta.config.DefaultProcessingOrders; import de.learnlib.datastructure.pta.config.ProcessingOrder; -import de.learnlib.testsupport.it.learner.AbstractMealyPassiveLearnerIT; -import de.learnlib.testsupport.it.learner.PassiveLearnerVariantList; +import de.learnlib.testsupport.it.AbstractMealyPassiveLearnerIT; +import de.learnlib.testsupport.it.variant.PassiveLearnerVariantList; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.word.Word; diff --git a/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/RpniMooreIT.java b/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/RpniMooreIT.java index efa98eb0e..830d907c6 100644 --- a/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/RpniMooreIT.java +++ b/algorithms/passive/rpni/src/test/java/de/learnlib/algorithm/rpni/it/RpniMooreIT.java @@ -18,8 +18,8 @@ import de.learnlib.algorithm.rpni.BlueFringeRPNIMoore; import de.learnlib.datastructure.pta.config.DefaultProcessingOrders; import de.learnlib.datastructure.pta.config.ProcessingOrder; -import de.learnlib.testsupport.it.learner.AbstractMoorePassiveLearnerIT; -import de.learnlib.testsupport.it.learner.PassiveLearnerVariantList; +import de.learnlib.testsupport.it.AbstractMoorePassiveLearnerIT; +import de.learnlib.testsupport.it.variant.PassiveLearnerVariantList; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.transducer.MooreMachine; import net.automatalib.word.Word; diff --git a/test-support/learner-it-support/pom.xml b/test-support/learner-it-support/pom.xml index bda6c74f3..7c7f4382c 100644 --- a/test-support/learner-it-support/pom.xml +++ b/test-support/learner-it-support/pom.xml @@ -61,6 +61,10 @@ limitations under the License. + + de.learnlib.tooling + annotations + org.checkerframework checker-qual diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractDFALearnerIT.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractDFALearnerIT.java similarity index 70% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractDFALearnerIT.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractDFALearnerIT.java index f10ca99ad..4700363f8 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractDFALearnerIT.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractDFALearnerIT.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it; import java.util.ArrayList; import java.util.List; @@ -23,8 +23,12 @@ import de.learnlib.oracle.membership.DFASimulatorOracle; import de.learnlib.testsupport.example.LearningExample.DFALearningExample; import de.learnlib.testsupport.example.LearningExamples; -import de.learnlib.testsupport.it.learner.LearnerVariantList.DFALearnerVariantList; -import de.learnlib.testsupport.it.learner.LearnerVariantListImpl.DFALearnerVariantListImpl; +import de.learnlib.testsupport.it.testcase.UniversalDeterministicLearnerITCase; +import de.learnlib.testsupport.it.util.DFALockableOracle; +import de.learnlib.testsupport.it.util.LearnerITUtil; +import de.learnlib.testsupport.it.variant.LearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantList.DFALearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantListImpl.DFALearnerVariantListImpl; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.fsa.DFA; import org.testng.annotations.Factory; @@ -54,15 +58,37 @@ private List>> cre DFALearningExample example) { final Alphabet alphabet = example.getAlphabet(); - final DFAMembershipOracle mqOracle = new DFASimulatorOracle<>(example.getReferenceAutomaton()); + final DFAMembershipOracle simOracle = new DFASimulatorOracle<>(example.getReferenceAutomaton()); + final DFALockableOracle lockOracle = new DFALockableOracle<>(simOracle); + final DFAMembershipOracle mqOracle; + + if (requiresQueriesDuringHypothesisTraversal()) { + mqOracle = simOracle; + } else { + mqOracle = lockOracle; + } + final DFALearnerVariantListImpl variants = new DFALearnerVariantListImpl<>(); addLearnerVariants(alphabet, example.getReferenceAutomaton().size(), mqOracle, variants); return LearnerITUtil.createExampleITCases(example, variants, + lockOracle, new SimulatorEQOracle<>(example.getReferenceAutomaton())); } + /** + * Returns whether the hypotheses require access to the membership oracle during traversal. This typically should + * not be the case as it disables the check for stable hypothesis constructions but certain approaches (e.g., + * automated alphabet abstraction refinement) require this by design. + * + * @return {@code true} if the hypotheses require access to the membership oracle during traversal, {@code false} + * otherwise + */ + protected boolean requiresQueriesDuringHypothesisTraversal() { + return false; + } + /** * Adds, for a given setup, all the variants of the DFA learner to be tested to the specified * {@link LearnerVariantList variant list}. diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractDFAPassiveLearnerIT.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractDFAPassiveLearnerIT.java similarity index 93% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractDFAPassiveLearnerIT.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractDFAPassiveLearnerIT.java index ed932bc84..a0740b2c7 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractDFAPassiveLearnerIT.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractDFAPassiveLearnerIT.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it; import java.util.ArrayList; import java.util.Collection; @@ -24,7 +24,10 @@ import de.learnlib.testsupport.example.LearningExample.DFALearningExample; import de.learnlib.testsupport.example.LearningExamples; import de.learnlib.testsupport.example.PassiveLearningExample.DFAPassiveLearningExample; -import de.learnlib.testsupport.it.learner.PassiveLearnerVariantListImpl.DFAPassiveLearnerVariantListImpl; +import de.learnlib.testsupport.it.testcase.PassiveLearnerVariantITCase; +import de.learnlib.testsupport.it.util.LearnerITUtil; +import de.learnlib.testsupport.it.variant.PassiveLearnerVariantList; +import de.learnlib.testsupport.it.variant.PassiveLearnerVariantListImpl.DFAPassiveLearnerVariantListImpl; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.fsa.DFA; import org.testng.annotations.Factory; diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMMLTLearnerIT.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMMLTLearnerIT.java similarity index 82% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMMLTLearnerIT.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMMLTLearnerIT.java index b6cd49d80..d44c47ec8 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMMLTLearnerIT.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMMLTLearnerIT.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it; import java.util.ArrayList; import java.util.Collections; @@ -25,8 +25,13 @@ import de.learnlib.oracle.membership.TimedSULOracle; import de.learnlib.testsupport.example.LearningExample.MMLTLearningExample; import de.learnlib.testsupport.example.LearningExamples; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MMLTLearnerVariantList; -import de.learnlib.testsupport.it.learner.LearnerVariantListImpl.MMLTLearnerVariantListImpl; +import de.learnlib.testsupport.it.testcase.AbstractLearnerVariantITCase; +import de.learnlib.testsupport.it.testcase.MMLTLearnerITCase; +import de.learnlib.testsupport.it.util.LearnerITUtil; +import de.learnlib.testsupport.it.util.MMLTLockableOracle; +import de.learnlib.testsupport.it.variant.LearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MMLTLearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantListImpl.MMLTLearnerVariantListImpl; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.mmlt.MMLT; import org.testng.annotations.Factory; @@ -52,13 +57,14 @@ public Object[] createExampleITCases() { private List> createAllVariantsITCase(MMLTLearningExample example) { final Alphabet alphabet = example.getUntimedAlphabet(); - final TimedQueryOracle mqOracle = - new TimedSULOracle<>(new MMLTSimulatorSUL<>(example.getReferenceAutomaton()), example.getParams()); + final TimedQueryOracle simOracle = new TimedSULOracle<>(new MMLTSimulatorSUL<>(example.getReferenceAutomaton()), example.getParams()); + final MMLTLockableOracle mqOracle = new MMLTLockableOracle<>(simOracle); final MMLTLearnerVariantListImpl variants = new MMLTLearnerVariantListImpl<>(); addLearnerVariants(alphabet, mqOracle, example, variants); return LearnerITUtil.createExampleITCases(example, variants, + mqOracle, new SimulatorEQOracle<>(example.getReferenceAutomaton())); } diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMealyLearnerIT.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMealyLearnerIT.java similarity index 75% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMealyLearnerIT.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMealyLearnerIT.java index fcbad098a..0674314ec 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMealyLearnerIT.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMealyLearnerIT.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it; import java.util.ArrayList; import java.util.List; @@ -28,8 +28,12 @@ import de.learnlib.testsupport.example.LearningExample.MealyLearningExample; import de.learnlib.testsupport.example.LearningExample.StateLocalInputMealyLearningExample; import de.learnlib.testsupport.example.LearningExamples; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MealyLearnerVariantList; -import de.learnlib.testsupport.it.learner.LearnerVariantListImpl.MealyLearnerVariantListImpl; +import de.learnlib.testsupport.it.testcase.UniversalDeterministicLearnerITCase; +import de.learnlib.testsupport.it.util.LearnerITUtil; +import de.learnlib.testsupport.it.util.MealyLockableOracle; +import de.learnlib.testsupport.it.variant.LearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MealyLearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantListImpl.MealyLearnerVariantListImpl; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.StateLocalInputMealyMachine; @@ -67,12 +71,22 @@ public Object[] createExampleITCases() { final Alphabet alphabet = example.getAlphabet(); final MealyMachine reference = example.getReferenceAutomaton(); - final MealyMembershipOracle mqOracle = new MealySimulatorOracle<>(reference); + final MealyMembershipOracle simOracle = new MealySimulatorOracle<>(reference); + final MealyLockableOracle lockOracle = new MealyLockableOracle<>(simOracle); + final MealyMembershipOracle mqOracle; + + if (requiresQueriesDuringHypothesisTraversal()) { + mqOracle = simOracle; + } else { + mqOracle = lockOracle; + } + final MealyLearnerVariantListImpl variants = new MealyLearnerVariantListImpl<>(); addLearnerVariants(alphabet, reference.size(), mqOracle, variants); return LearnerITUtil.createExampleITCases(example, variants, + lockOracle, new MealySimulatorEQOracle<>(example.getReferenceAutomaton())); } @@ -87,15 +101,36 @@ public Object[] createExampleITCases() { final StateLocalInputMealyMachine partialRef = MealyFilter.pruneTransitionsWithOutput(reference, alphabet, undefinedOutput); - final MealyMembershipOracle mqOracle = + final MealyMembershipOracle simOracle = new StateLocalInputSULOracle<>(new StateLocalInputMealySimulatorSUL<>(partialRef), undefinedOutput); + final MealyLockableOracle lockOracle = new MealyLockableOracle<>(simOracle); + final MealyMembershipOracle mqOracle; + + if (requiresQueriesDuringHypothesisTraversal()) { + mqOracle = simOracle; + } else { + mqOracle = lockOracle; + } + final MealyLearnerVariantListImpl variants = new MealyLearnerVariantListImpl<>(); addLearnerVariants(alphabet, reference.size(), mqOracle, variants); final MealyEquivalenceOracle eqOracle = new StateLocalInputMealySimulatorEQOracle<>(partialRef, alphabet, undefinedOutput); - return LearnerITUtil.createExampleITCases(example, variants, eqOracle); + return LearnerITUtil.createExampleITCases(example, variants, lockOracle, eqOracle); + } + + /** + * Returns whether the hypotheses require access to the membership oracle during traversal. This typically should + * not be the case as it disables the check for stable hypothesis constructions but certain approaches (e.g., + * automated alphabet abstraction refinement) require this by design. + * + * @return {@code true} if the hypotheses require access to the membership oracle during traversal, {@code false} + * otherwise + */ + protected boolean requiresQueriesDuringHypothesisTraversal() { + return false; } /** diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMealyPassiveLearnerIT.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMealyPassiveLearnerIT.java similarity index 92% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMealyPassiveLearnerIT.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMealyPassiveLearnerIT.java index f41d4ebb5..38f70edff 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMealyPassiveLearnerIT.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMealyPassiveLearnerIT.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it; import java.util.ArrayList; import java.util.Collection; @@ -24,7 +24,10 @@ import de.learnlib.testsupport.example.LearningExample.MealyLearningExample; import de.learnlib.testsupport.example.LearningExamples; import de.learnlib.testsupport.example.PassiveLearningExample.MealyPassiveLearningExample; -import de.learnlib.testsupport.it.learner.PassiveLearnerVariantListImpl.MealyLearnerVariantListImpl; +import de.learnlib.testsupport.it.testcase.PassiveLearnerVariantITCase; +import de.learnlib.testsupport.it.util.LearnerITUtil; +import de.learnlib.testsupport.it.variant.PassiveLearnerVariantList; +import de.learnlib.testsupport.it.variant.PassiveLearnerVariantListImpl.MealyLearnerVariantListImpl; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.word.Word; diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMealySymLearnerIT.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMealySymLearnerIT.java similarity index 84% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMealySymLearnerIT.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMealySymLearnerIT.java index 9e356f0a6..ff3850836 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMealySymLearnerIT.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMealySymLearnerIT.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it; import java.util.ArrayList; import java.util.List; @@ -24,8 +24,12 @@ import de.learnlib.oracle.membership.MealySimulatorOracle; import de.learnlib.testsupport.example.LearningExample.MealyLearningExample; import de.learnlib.testsupport.example.LearningExamples; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MealySymLearnerVariantList; -import de.learnlib.testsupport.it.learner.LearnerVariantListImpl.MealySymLearnerVariantListImpl; +import de.learnlib.testsupport.it.testcase.UniversalDeterministicLearnerITCase; +import de.learnlib.testsupport.it.util.LearnerITUtil; +import de.learnlib.testsupport.it.util.MealyLockableOracle; +import de.learnlib.testsupport.it.variant.LearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MealySymLearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantListImpl.MealySymLearnerVariantListImpl; import de.learnlib.util.mealy.MealyUtil; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.transducer.MealyMachine; @@ -57,12 +61,14 @@ public Object[] createExampleITCases() { MealyLearningExample example) { final Alphabet alphabet = example.getAlphabet(); - final MealyMembershipOracle mqOracle = new MealySimulatorOracle<>(example.getReferenceAutomaton()); + final MealyMembershipOracle simOracle = new MealySimulatorOracle<>(example.getReferenceAutomaton()); + final MealyLockableOracle mqOracle = new MealyLockableOracle<>(simOracle); final MealySymLearnerVariantListImpl variants = new MealySymLearnerVariantListImpl<>(); addLearnerVariants(alphabet, MealyUtil.wrapWordOracle(mqOracle), variants); return LearnerITUtil.createExampleITCases(example, variants.getMealyLearnerVariants(), + mqOracle, new SimulatorEQOracle<>(example.getReferenceAutomaton())); } diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMooreLearnerIT.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMooreLearnerIT.java similarity index 72% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMooreLearnerIT.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMooreLearnerIT.java index 04f97295e..3c53c920b 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMooreLearnerIT.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMooreLearnerIT.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it; import java.util.ArrayList; import java.util.List; @@ -24,8 +24,12 @@ import de.learnlib.oracle.membership.MooreSimulatorOracle; import de.learnlib.testsupport.example.LearningExample.MooreLearningExample; import de.learnlib.testsupport.example.LearningExamples; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MooreLearnerVariantList; -import de.learnlib.testsupport.it.learner.LearnerVariantListImpl.MooreLearnerVariantListImpl; +import de.learnlib.testsupport.it.testcase.UniversalDeterministicLearnerITCase; +import de.learnlib.testsupport.it.util.LearnerITUtil; +import de.learnlib.testsupport.it.util.MooreLockableOracle; +import de.learnlib.testsupport.it.variant.LearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MooreLearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantListImpl.MooreLearnerVariantListImpl; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.transducer.MooreMachine; import net.automatalib.word.Word; @@ -56,12 +60,33 @@ public Object[] createExampleITCases() { final Alphabet alphabet = example.getAlphabet(); final MooreMachine reference = example.getReferenceAutomaton(); - final MooreMembershipOracle mqOracle = new MooreSimulatorOracle<>(reference); + final MooreMembershipOracle simOracle = new MooreSimulatorOracle<>(reference); + final MooreLockableOracle lockOracle = new MooreLockableOracle<>(simOracle); + final MooreMembershipOracle mqOracle; + + if (requiresQueriesDuringHypothesisTraversal()) { + mqOracle = simOracle; + } else { + mqOracle = lockOracle; + } + final MooreEquivalenceOracle eqOracle = new MooreSimulatorEQOracle<>(reference); final MooreLearnerVariantListImpl variants = new MooreLearnerVariantListImpl<>(); addLearnerVariants(alphabet, reference.size(), mqOracle, variants); - return LearnerITUtil.createExampleITCases(example, variants, eqOracle); + return LearnerITUtil.createExampleITCases(example, variants, lockOracle, eqOracle); + } + + /** + * Returns whether the hypotheses require access to the membership oracle during traversal. This typically should + * not be the case as it disables the check for stable hypothesis constructions but certain approaches (e.g., + * automated alphabet abstraction refinement) require this by design. + * + * @return {@code true} if the hypotheses require access to the membership oracle during traversal, {@code false} + * otherwise + */ + protected boolean requiresQueriesDuringHypothesisTraversal() { + return false; } /** diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMoorePassiveLearnerIT.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMoorePassiveLearnerIT.java similarity index 92% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMoorePassiveLearnerIT.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMoorePassiveLearnerIT.java index cdb1dca3b..acbc8e68f 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMoorePassiveLearnerIT.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMoorePassiveLearnerIT.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it; import java.util.ArrayList; import java.util.Collection; @@ -24,7 +24,10 @@ import de.learnlib.testsupport.example.LearningExample.MooreLearningExample; import de.learnlib.testsupport.example.LearningExamples; import de.learnlib.testsupport.example.PassiveLearningExample.MoorePassiveLearningExample; -import de.learnlib.testsupport.it.learner.PassiveLearnerVariantListImpl.MooreLearnerVariantListImpl; +import de.learnlib.testsupport.it.testcase.PassiveLearnerVariantITCase; +import de.learnlib.testsupport.it.util.LearnerITUtil; +import de.learnlib.testsupport.it.variant.PassiveLearnerVariantList; +import de.learnlib.testsupport.it.variant.PassiveLearnerVariantListImpl.MooreLearnerVariantListImpl; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.transducer.MooreMachine; import net.automatalib.word.Word; diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMooreSymLearnerIT.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMooreSymLearnerIT.java similarity index 84% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMooreSymLearnerIT.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMooreSymLearnerIT.java index bdf3b3c70..6765d7403 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractMooreSymLearnerIT.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractMooreSymLearnerIT.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it; import java.util.ArrayList; import java.util.List; @@ -24,8 +24,12 @@ import de.learnlib.oracle.membership.MooreSimulatorOracle; import de.learnlib.testsupport.example.LearningExample.MooreLearningExample; import de.learnlib.testsupport.example.LearningExamples; -import de.learnlib.testsupport.it.learner.LearnerVariantList.MooreSymLearnerVariantList; -import de.learnlib.testsupport.it.learner.LearnerVariantListImpl.MooreSymLearnerVariantListImpl; +import de.learnlib.testsupport.it.testcase.UniversalDeterministicLearnerITCase; +import de.learnlib.testsupport.it.util.LearnerITUtil; +import de.learnlib.testsupport.it.util.MooreLockableOracle; +import de.learnlib.testsupport.it.variant.LearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantList.MooreSymLearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantListImpl.MooreSymLearnerVariantListImpl; import de.learnlib.util.moore.MooreUtil; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.transducer.MooreMachine; @@ -57,12 +61,14 @@ public Object[] createExampleITCases() { MooreLearningExample example) { final Alphabet alphabet = example.getAlphabet(); - final MooreMembershipOracle mqOracle = new MooreSimulatorOracle<>(example.getReferenceAutomaton()); + final MooreMembershipOracle simOracle = new MooreSimulatorOracle<>(example.getReferenceAutomaton()); + final MooreLockableOracle mqOracle = new MooreLockableOracle<>(simOracle); final MooreSymLearnerVariantListImpl variants = new MooreSymLearnerVariantListImpl<>(); addLearnerVariants(alphabet, MooreUtil.wrapWordOracle(mqOracle), variants); return LearnerITUtil.createExampleITCases(example, variants.getMooreLearnerVariants(), + mqOracle, new SimulatorEQOracle<>(example.getReferenceAutomaton())); } diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractOneSEVPALearnerIT.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractOneSEVPALearnerIT.java similarity index 83% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractOneSEVPALearnerIT.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractOneSEVPALearnerIT.java index 2b2b0b8dc..f3f598191 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractOneSEVPALearnerIT.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractOneSEVPALearnerIT.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it; import java.util.ArrayList; import java.util.List; @@ -23,7 +23,11 @@ import de.learnlib.oracle.membership.SEVPASimulatorOracle; import de.learnlib.testsupport.example.LearningExample.OneSEVPALearningExample; import de.learnlib.testsupport.example.LearningExamples; -import de.learnlib.testsupport.it.learner.LearnerVariantListImpl.OneSEVPALearnerVariantListImpl; +import de.learnlib.testsupport.it.testcase.OneSEVPALearnerITCase; +import de.learnlib.testsupport.it.util.LearnerITUtil; +import de.learnlib.testsupport.it.util.SEVPALockableOracle; +import de.learnlib.testsupport.it.variant.LearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantListImpl.OneSEVPALearnerVariantListImpl; import net.automatalib.alphabet.VPAlphabet; import net.automatalib.automaton.vpa.OneSEVPA; import org.testng.annotations.Factory; @@ -48,12 +52,14 @@ public Object[] createExampleITCases() { private List> createAllVariantsITCase(OneSEVPALearningExample example) { final VPAlphabet alphabet = example.getAlphabet(); - final DFAMembershipOracle mqOracle = new SEVPASimulatorOracle<>(example.getReferenceAutomaton()); + final DFAMembershipOracle simOracle = new SEVPASimulatorOracle<>(example.getReferenceAutomaton()); + final SEVPALockableOracle mqOracle = new SEVPALockableOracle<>(simOracle); final OneSEVPALearnerVariantListImpl variants = new OneSEVPALearnerVariantListImpl<>(); addLearnerVariants(alphabet, mqOracle, variants); return LearnerITUtil.createExampleITCases(example, variants, + mqOracle, new SimulatorEQOracle<>(example.getReferenceAutomaton())); } diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractSBALearnerIT.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractSBALearnerIT.java similarity index 80% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractSBALearnerIT.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractSBALearnerIT.java index aa7a9a184..18a1b48a9 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractSBALearnerIT.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractSBALearnerIT.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it; import java.util.ArrayList; import java.util.List; @@ -23,8 +23,13 @@ import de.learnlib.oracle.membership.SBASimulatorOracle; import de.learnlib.testsupport.example.LearningExample.SBALearningExample; import de.learnlib.testsupport.example.LearningExamples; -import de.learnlib.testsupport.it.learner.LearnerVariantList.SBALearnerVariantList; -import de.learnlib.testsupport.it.learner.LearnerVariantListImpl.SBALearnerVariantListImpl; +import de.learnlib.testsupport.it.testcase.AbstractLearnerVariantITCase; +import de.learnlib.testsupport.it.testcase.SBALearnerITCase; +import de.learnlib.testsupport.it.util.LearnerITUtil; +import de.learnlib.testsupport.it.util.SBALockableOracle; +import de.learnlib.testsupport.it.variant.LearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantList.SBALearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantListImpl.SBALearnerVariantListImpl; import net.automatalib.alphabet.ProceduralInputAlphabet; import net.automatalib.automaton.procedural.SBA; import org.testng.annotations.Factory; @@ -49,12 +54,14 @@ public Object[] createExampleITCases() { private List> createAllVariantsITCase(SBALearningExample example) { final ProceduralInputAlphabet alphabet = example.getAlphabet(); - final DFAMembershipOracle mqOracle = new SBASimulatorOracle<>(example.getReferenceAutomaton()); + final DFAMembershipOracle simOracle = new SBASimulatorOracle<>(example.getReferenceAutomaton()); + final SBALockableOracle mqOracle = new SBALockableOracle<>(simOracle); final SBALearnerVariantListImpl variants = new SBALearnerVariantListImpl<>(); addLearnerVariants(alphabet, mqOracle, variants); return LearnerITUtil.createExampleITCases(example, variants, + mqOracle, new SimulatorEQOracle<>(example.getReferenceAutomaton())); } diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractSPALearnerIT.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractSPALearnerIT.java similarity index 80% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractSPALearnerIT.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractSPALearnerIT.java index 38a1664e1..162c42868 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractSPALearnerIT.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractSPALearnerIT.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it; import java.util.ArrayList; import java.util.List; @@ -23,8 +23,13 @@ import de.learnlib.oracle.membership.SPASimulatorOracle; import de.learnlib.testsupport.example.LearningExample.SPALearningExample; import de.learnlib.testsupport.example.LearningExamples; -import de.learnlib.testsupport.it.learner.LearnerVariantList.SPALearnerVariantList; -import de.learnlib.testsupport.it.learner.LearnerVariantListImpl.SPALearnerVariantListImpl; +import de.learnlib.testsupport.it.testcase.AbstractLearnerVariantITCase; +import de.learnlib.testsupport.it.testcase.SPALearnerITCase; +import de.learnlib.testsupport.it.util.LearnerITUtil; +import de.learnlib.testsupport.it.util.SPALockableOracle; +import de.learnlib.testsupport.it.variant.LearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantList.SPALearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantListImpl.SPALearnerVariantListImpl; import net.automatalib.alphabet.ProceduralInputAlphabet; import net.automatalib.automaton.procedural.SPA; import org.testng.annotations.Factory; @@ -49,12 +54,14 @@ public Object[] createExampleITCases() { private List> createAllVariantsITCase(SPALearningExample example) { final ProceduralInputAlphabet alphabet = example.getAlphabet(); - final DFAMembershipOracle mqOracle = new SPASimulatorOracle<>(example.getReferenceAutomaton()); + final DFAMembershipOracle simOracle = new SPASimulatorOracle<>(example.getReferenceAutomaton()); + final SPALockableOracle mqOracle = new SPALockableOracle<>(simOracle); final SPALearnerVariantListImpl variants = new SPALearnerVariantListImpl<>(); addLearnerVariants(alphabet, mqOracle, variants); return LearnerITUtil.createExampleITCases(example, variants, + mqOracle, new SimulatorEQOracle<>(example.getReferenceAutomaton())); } diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractSPMMLearnerIT.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractSPMMLearnerIT.java similarity index 81% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractSPMMLearnerIT.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractSPMMLearnerIT.java index d5cff24e1..df1d00199 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractSPMMLearnerIT.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractSPMMLearnerIT.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it; import java.util.ArrayList; import java.util.List; @@ -23,8 +23,13 @@ import de.learnlib.oracle.membership.SPMMSimulatorOracle; import de.learnlib.testsupport.example.LearningExample.SPMMLearningExample; import de.learnlib.testsupport.example.LearningExamples; -import de.learnlib.testsupport.it.learner.LearnerVariantList.SPMMLearnerVariantList; -import de.learnlib.testsupport.it.learner.LearnerVariantListImpl.SPMMLearnerVariantListImpl; +import de.learnlib.testsupport.it.testcase.AbstractLearnerVariantITCase; +import de.learnlib.testsupport.it.testcase.SPMMLearnerITCase; +import de.learnlib.testsupport.it.util.LearnerITUtil; +import de.learnlib.testsupport.it.util.SPMMLockableOracle; +import de.learnlib.testsupport.it.variant.LearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantList.SPMMLearnerVariantList; +import de.learnlib.testsupport.it.variant.LearnerVariantListImpl.SPMMLearnerVariantListImpl; import net.automatalib.alphabet.ProceduralInputAlphabet; import net.automatalib.automaton.procedural.SPMM; import org.testng.annotations.Factory; @@ -49,11 +54,12 @@ public Object[] createExampleITCases() { private List> createAllVariantsITCase(SPMMLearningExample example) { final SPMM reference = example.getReferenceAutomaton(); - final MealyMembershipOracle mqOracle = new SPMMSimulatorOracle<>(reference); + final MealyMembershipOracle simOracle = new SPMMSimulatorOracle<>(reference); + final SPMMLockableOracle mqOracle = new SPMMLockableOracle<>(simOracle); final SPMMLearnerVariantListImpl variants = new SPMMLearnerVariantListImpl<>(); addLearnerVariants(example.getAlphabet(), reference.getErrorOutput(), mqOracle, variants); - return LearnerITUtil.createExampleITCases(example, variants, new SimulatorEQOracle<>(reference)); + return LearnerITUtil.createExampleITCases(example, variants, mqOracle, new SimulatorEQOracle<>(reference)); } /** diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractSSTPassiveLearnerIT.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractSSTPassiveLearnerIT.java similarity index 92% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractSSTPassiveLearnerIT.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractSSTPassiveLearnerIT.java index 12a43b388..ea2a296c3 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractSSTPassiveLearnerIT.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/AbstractSSTPassiveLearnerIT.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it; import java.util.ArrayList; import java.util.Collection; @@ -26,7 +26,10 @@ import de.learnlib.testsupport.example.LearningExample.SSTLearningExample; import de.learnlib.testsupport.example.LearningExamples; import de.learnlib.testsupport.example.PassiveLearningExample.SSTPassiveLearningExample; -import de.learnlib.testsupport.it.learner.PassiveLearnerVariantListImpl.SSTLearnerVariantListImpl; +import de.learnlib.testsupport.it.testcase.PassiveLearnerVariantITCase; +import de.learnlib.testsupport.it.util.LearnerITUtil; +import de.learnlib.testsupport.it.variant.PassiveLearnerVariantList; +import de.learnlib.testsupport.it.variant.PassiveLearnerVariantListImpl.SSTLearnerVariantListImpl; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.concept.SuffixOutput; diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractLearnerVariantITCase.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/AbstractLearnerVariantITCase.java similarity index 84% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractLearnerVariantITCase.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/AbstractLearnerVariantITCase.java index be66a2e66..d2dc54f4c 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/AbstractLearnerVariantITCase.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/AbstractLearnerVariantITCase.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it.testcase; import java.util.ArrayList; import java.util.List; @@ -23,6 +23,8 @@ import de.learnlib.oracle.EquivalenceOracle; import de.learnlib.query.DefaultQuery; import de.learnlib.testsupport.example.LearningExample; +import de.learnlib.testsupport.it.util.LockableOracle; +import de.learnlib.testsupport.it.variant.LearnerVariant; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.concept.FiniteRepresentation; import org.slf4j.Logger; @@ -31,7 +33,7 @@ import org.testng.ITest; import org.testng.annotations.Test; -abstract class AbstractLearnerVariantITCase implements ITest { +public abstract class AbstractLearnerVariantITCase implements ITest { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractLearnerVariantITCase.class); @@ -40,18 +42,22 @@ abstract class AbstractLearnerVariantITCase variant; private final LearningExample example; + private final LockableOracle lockableOracle; private final EquivalenceOracle eqOracle; AbstractLearnerVariantITCase(LearnerVariant variant, LearningExample example, + LockableOracle lockableOracle, EquivalenceOracle eqOracle) { this.variant = variant; this.example = example; + this.lockableOracle = lockableOracle; this.eqOracle = eqOracle; } @Test public void testLearning() { + lockableOracle.lock(); LearningAlgorithm learner = variant.getLearner(); Alphabet alphabet = example.getAlphabet(); @@ -64,7 +70,9 @@ public void testLearning() { long start = System.nanoTime(); + lockableOracle.unlock(); learner.startLearning(); + lockableOracle.lock(); int roundCounter = 0; DefaultQuery ceQuery; @@ -76,7 +84,12 @@ public void testLearning() { Assert.fail("Learning took too many rounds (> " + maxRounds + ")"); } + // this currently assumes a white-box equivalence oracle which does not pose any queries + // for situations where this is not the case, the EQ may be given a non-lockable MQ + lockableOracle.unlock(); boolean refined = learner.refineHypothesis(ceQuery); + lockableOracle.lock(); + Assert.assertTrue(refined, "Real counterexample " + ceQuery.getInput() + " did not refine hypothesis"); ceQueries.add(ceQuery); } diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/MMLTLearnerITCase.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/MMLTLearnerITCase.java similarity index 73% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/MMLTLearnerITCase.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/MMLTLearnerITCase.java index 9f27ba839..ddf1aa783 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/MMLTLearnerITCase.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/MMLTLearnerITCase.java @@ -13,10 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it.testcase; import de.learnlib.oracle.EquivalenceOracle; import de.learnlib.testsupport.example.LearningExample.MMLTLearningExample; +import de.learnlib.testsupport.it.util.MMLTLockableOracle; +import de.learnlib.testsupport.it.variant.LearnerVariant; import net.automatalib.automaton.mmlt.MMLT; import net.automatalib.symbol.time.TimedInput; import net.automatalib.symbol.time.TimedOutput; @@ -28,10 +30,11 @@ public class MMLTLearnerITCase private final MMLTLearningExample example; - MMLTLearnerITCase(LearnerVariant, TimedInput, Word>> variant, - MMLTLearningExample example, - EquivalenceOracle, TimedInput, Word>> eqOracle) { - super(variant, example, eqOracle); + public MMLTLearnerITCase(LearnerVariant, TimedInput, Word>> variant, + MMLTLearningExample example, + MMLTLockableOracle lockableOracle, + EquivalenceOracle, TimedInput, Word>> eqOracle) { + super(variant, example, lockableOracle, eqOracle); this.example = example; } diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/OneSEVPALearnerITCase.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/OneSEVPALearnerITCase.java similarity index 70% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/OneSEVPALearnerITCase.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/OneSEVPALearnerITCase.java index 8d7fe1bbe..38a5a35f6 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/OneSEVPALearnerITCase.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/OneSEVPALearnerITCase.java @@ -13,10 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it.testcase; import de.learnlib.oracle.EquivalenceOracle; import de.learnlib.testsupport.example.LearningExample.OneSEVPALearningExample; +import de.learnlib.testsupport.it.util.SEVPALockableOracle; +import de.learnlib.testsupport.it.variant.LearnerVariant; import net.automatalib.automaton.vpa.OneSEVPA; import net.automatalib.util.automaton.vpa.OneSEVPAs; @@ -24,10 +26,11 @@ public class OneSEVPALearnerITCase extends AbstractLearnerVariantITCase example; - OneSEVPALearnerITCase(LearnerVariant, I, Boolean> variant, - OneSEVPALearningExample example, - EquivalenceOracle, I, Boolean> eqOracle) { - super(variant, example, eqOracle); + public OneSEVPALearnerITCase(LearnerVariant, I, Boolean> variant, + OneSEVPALearningExample example, + SEVPALockableOracle lockableOracle, + EquivalenceOracle, I, Boolean> eqOracle) { + super(variant, example, lockableOracle, eqOracle); this.example = example; } diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/PassiveLearnerVariantITCase.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/PassiveLearnerVariantITCase.java similarity index 91% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/PassiveLearnerVariantITCase.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/PassiveLearnerVariantITCase.java index 90a63f5b1..f200f8431 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/PassiveLearnerVariantITCase.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/PassiveLearnerVariantITCase.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it.testcase; import java.util.Collection; @@ -21,6 +21,7 @@ import de.learnlib.logging.Category; import de.learnlib.query.DefaultQuery; import de.learnlib.testsupport.example.PassiveLearningExample; +import de.learnlib.testsupport.it.variant.PassiveLearnerVariant; import net.automatalib.automaton.concept.SuffixOutput; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,8 +49,8 @@ public final class PassiveLearnerVariantITCase variant; private final PassiveLearningExample example; - PassiveLearnerVariantITCase(PassiveLearnerVariant variant, - PassiveLearningExample example) { + public PassiveLearnerVariantITCase(PassiveLearnerVariant variant, + PassiveLearningExample example) { this.variant = variant; this.example = example; } diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/SBALearnerITCase.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/SBALearnerITCase.java similarity index 71% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/SBALearnerITCase.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/SBALearnerITCase.java index 68812b1b2..d3dbfc2e0 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/SBALearnerITCase.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/SBALearnerITCase.java @@ -13,10 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it.testcase; import de.learnlib.oracle.EquivalenceOracle; import de.learnlib.testsupport.example.LearningExample.SBALearningExample; +import de.learnlib.testsupport.it.util.SBALockableOracle; +import de.learnlib.testsupport.it.variant.LearnerVariant; import net.automatalib.automaton.procedural.SBA; import net.automatalib.util.automaton.procedural.SBAs; @@ -24,10 +26,11 @@ public class SBALearnerITCase extends AbstractLearnerVariantITCase example; - SBALearnerITCase(LearnerVariant, I, Boolean> variant, - SBALearningExample example, - EquivalenceOracle, I, Boolean> eqOracle) { - super(variant, example, eqOracle); + public SBALearnerITCase(LearnerVariant, I, Boolean> variant, + SBALearningExample example, + SBALockableOracle lockableOracle, + EquivalenceOracle, I, Boolean> eqOracle) { + super(variant, example, lockableOracle, eqOracle); this.example = example; } diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/SPALearnerITCase.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/SPALearnerITCase.java similarity index 71% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/SPALearnerITCase.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/SPALearnerITCase.java index 315498a7a..45c99b0e3 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/SPALearnerITCase.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/SPALearnerITCase.java @@ -13,10 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it.testcase; import de.learnlib.oracle.EquivalenceOracle; import de.learnlib.testsupport.example.LearningExample.SPALearningExample; +import de.learnlib.testsupport.it.util.SPALockableOracle; +import de.learnlib.testsupport.it.variant.LearnerVariant; import net.automatalib.automaton.procedural.SPA; import net.automatalib.util.automaton.procedural.SPAs; @@ -24,10 +26,11 @@ public class SPALearnerITCase extends AbstractLearnerVariantITCase example; - SPALearnerITCase(LearnerVariant, I, Boolean> variant, - SPALearningExample example, - EquivalenceOracle, I, Boolean> eqOracle) { - super(variant, example, eqOracle); + public SPALearnerITCase(LearnerVariant, I, Boolean> variant, + SPALearningExample example, + SPALockableOracle lockableOracle, + EquivalenceOracle, I, Boolean> eqOracle) { + super(variant, example, lockableOracle, eqOracle); this.example = example; } diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/SPMMLearnerITCase.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/SPMMLearnerITCase.java similarity index 71% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/SPMMLearnerITCase.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/SPMMLearnerITCase.java index 79cc0c26f..f43dcce98 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/SPMMLearnerITCase.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/SPMMLearnerITCase.java @@ -13,10 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it.testcase; import de.learnlib.oracle.EquivalenceOracle; import de.learnlib.testsupport.example.LearningExample.SPMMLearningExample; +import de.learnlib.testsupport.it.util.SPMMLockableOracle; +import de.learnlib.testsupport.it.variant.LearnerVariant; import net.automatalib.automaton.procedural.SPMM; import net.automatalib.util.automaton.procedural.SPMMs; import net.automatalib.word.Word; @@ -25,10 +27,11 @@ public class SPMMLearnerITCase extends AbstractLearnerVariantITCase example; - SPMMLearnerITCase(LearnerVariant, I, Word> variant, - SPMMLearningExample example, - EquivalenceOracle, I, Word> eqOracle) { - super(variant, example, eqOracle); + public SPMMLearnerITCase(LearnerVariant, I, Word> variant, + SPMMLearningExample example, + SPMMLockableOracle lockableOracle, + EquivalenceOracle, I, Word> eqOracle) { + super(variant, example, lockableOracle, eqOracle); this.example = example; } diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/UniversalDeterministicLearnerITCase.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/UniversalDeterministicLearnerITCase.java similarity index 71% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/UniversalDeterministicLearnerITCase.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/UniversalDeterministicLearnerITCase.java index c541bcc50..247911fba 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/UniversalDeterministicLearnerITCase.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/testcase/UniversalDeterministicLearnerITCase.java @@ -13,10 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it.testcase; import de.learnlib.oracle.EquivalenceOracle; import de.learnlib.testsupport.example.LearningExample.UniversalDeterministicLearningExample; +import de.learnlib.testsupport.it.util.LockableOracle; +import de.learnlib.testsupport.it.variant.LearnerVariant; import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.concept.Output; import net.automatalib.util.automaton.Automata; @@ -26,10 +28,11 @@ public class UniversalDeterministicLearnerITCase example; - UniversalDeterministicLearnerITCase(LearnerVariant variant, - UniversalDeterministicLearningExample example, - EquivalenceOracle eqOracle) { - super(variant, example, eqOracle); + public UniversalDeterministicLearnerITCase(LearnerVariant variant, + UniversalDeterministicLearningExample example, + LockableOracle lockableOracle, + EquivalenceOracle eqOracle) { + super(variant, example, lockableOracle, eqOracle); this.example = example; } diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/LearnerITUtil.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/util/LearnerITUtil.java similarity index 77% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/LearnerITUtil.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/util/LearnerITUtil.java index 6af1ccad4..eb69c9d00 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/LearnerITUtil.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/util/LearnerITUtil.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it.util; import java.util.ArrayList; import java.util.Collection; @@ -30,11 +30,23 @@ import de.learnlib.testsupport.example.LearningExample.SPMMLearningExample; import de.learnlib.testsupport.example.LearningExample.UniversalDeterministicLearningExample; import de.learnlib.testsupport.example.PassiveLearningExample; -import de.learnlib.testsupport.it.learner.LearnerVariantListImpl.MMLTLearnerVariantListImpl; -import de.learnlib.testsupport.it.learner.LearnerVariantListImpl.OneSEVPALearnerVariantListImpl; -import de.learnlib.testsupport.it.learner.LearnerVariantListImpl.SBALearnerVariantListImpl; -import de.learnlib.testsupport.it.learner.LearnerVariantListImpl.SPALearnerVariantListImpl; -import de.learnlib.testsupport.it.learner.LearnerVariantListImpl.SPMMLearnerVariantListImpl; +import de.learnlib.testsupport.it.testcase.AbstractLearnerVariantITCase; +import de.learnlib.testsupport.it.testcase.MMLTLearnerITCase; +import de.learnlib.testsupport.it.testcase.OneSEVPALearnerITCase; +import de.learnlib.testsupport.it.testcase.PassiveLearnerVariantITCase; +import de.learnlib.testsupport.it.testcase.SBALearnerITCase; +import de.learnlib.testsupport.it.testcase.SPALearnerITCase; +import de.learnlib.testsupport.it.testcase.SPMMLearnerITCase; +import de.learnlib.testsupport.it.testcase.UniversalDeterministicLearnerITCase; +import de.learnlib.testsupport.it.variant.LearnerVariant; +import de.learnlib.testsupport.it.variant.LearnerVariantListImpl; +import de.learnlib.testsupport.it.variant.LearnerVariantListImpl.MMLTLearnerVariantListImpl; +import de.learnlib.testsupport.it.variant.LearnerVariantListImpl.OneSEVPALearnerVariantListImpl; +import de.learnlib.testsupport.it.variant.LearnerVariantListImpl.SBALearnerVariantListImpl; +import de.learnlib.testsupport.it.variant.LearnerVariantListImpl.SPALearnerVariantListImpl; +import de.learnlib.testsupport.it.variant.LearnerVariantListImpl.SPMMLearnerVariantListImpl; +import de.learnlib.testsupport.it.variant.PassiveLearnerVariant; +import de.learnlib.testsupport.it.variant.PassiveLearnerVariantListImpl; import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.UniversalAutomaton; import net.automatalib.automaton.UniversalDeterministicAutomaton; @@ -73,6 +85,8 @@ private LearnerITUtil() { * the example system * @param variants * the list containing the various learner variants + * @param lockableOracle + * the lockable oracle to check stable hypothesis construction * @param eqOracle * the equivalence oracle to use by the learning process * @param @@ -87,11 +101,13 @@ private LearnerITUtil() { public static & Output> List> createExampleITCases( UniversalDeterministicLearningExample example, LearnerVariantListImpl variants, + LockableOracle lockableOracle, EquivalenceOracle eqOracle) { // explicit generics are required for correct type-inference - return LearnerITUtil., UniversalDeterministicLearnerITCase>createExampleITCasesInternal( + return LearnerITUtil., UniversalDeterministicLearnerITCase, LockableOracle>createExampleITCasesInternal( example, variants, + lockableOracle, eqOracle, UniversalDeterministicLearnerITCase::new); } @@ -103,6 +119,8 @@ private LearnerITUtil() { * the example system * @param variants * the list containing the various learner variants + * @param lockableOracle + * the lockable oracle to check stable hypothesis construction * @param eqOracle * the equivalence oracle to use by the learning process * @param @@ -114,11 +132,13 @@ private LearnerITUtil() { */ public static List> createExampleITCases(MMLTLearningExample example, MMLTLearnerVariantListImpl variants, + MMLTLockableOracle lockableOracle, EquivalenceOracle, TimedInput, Word>> eqOracle) { // explicit generics are required for correct type-inference - return LearnerITUtil., Word>, MMLT, MMLTLearningExample, MMLTLearnerITCase>createExampleITCasesInternal( + return LearnerITUtil., Word>, MMLT, MMLTLearningExample, MMLTLearnerITCase, MMLTLockableOracle>createExampleITCasesInternal( example, variants, + lockableOracle, eqOracle, MMLTLearnerITCase::new); } @@ -130,6 +150,8 @@ public static List> createExampleITCases(MMLTLear * the example system * @param variants * the list containing the various learner variants + * @param lockableOracle + * the lockable oracle to check stable hypothesis construction * @param eqOracle * the equivalence oracle to use by the learning process * @param @@ -139,11 +161,13 @@ public static List> createExampleITCases(MMLTLear */ public static List> createExampleITCases(SPALearningExample example, SPALearnerVariantListImpl variants, + SPALockableOracle lockableOracle, EquivalenceOracle, I, Boolean> eqOracle) { // explicit generics are required for correct type-inference - return LearnerITUtil., SPALearningExample, SPALearnerITCase>createExampleITCasesInternal( + return LearnerITUtil., SPALearningExample, SPALearnerITCase, SPALockableOracle>createExampleITCasesInternal( example, variants, + lockableOracle, eqOracle, SPALearnerITCase::new); } @@ -155,6 +179,8 @@ public static List> createExampleITCases(SPALearningExam * the example system * @param variants * the list containing the various learner variants + * @param lockableOracle + * the lockable oracle to check stable hypothesis construction * @param eqOracle * the equivalence oracle to use by the learning process * @param @@ -164,11 +190,13 @@ public static List> createExampleITCases(SPALearningExam */ public static List> createExampleITCases(SBALearningExample example, SBALearnerVariantListImpl variants, + SBALockableOracle lockableOracle, EquivalenceOracle, I, Boolean> eqOracle) { // explicit generics are required for correct type-inference - return LearnerITUtil., SBALearningExample, SBALearnerITCase>createExampleITCasesInternal( + return LearnerITUtil., SBALearningExample, SBALearnerITCase, SBALockableOracle>createExampleITCasesInternal( example, variants, + lockableOracle, eqOracle, SBALearnerITCase::new); } @@ -180,6 +208,8 @@ public static List> createExampleITCases(SBALearningExam * the example system * @param variants * the list containing the various learner variants + * @param lockableOracle + * the lockable oracle to check stable hypothesis construction * @param eqOracle * the equivalence oracle to use by the learning process * @param @@ -191,11 +221,13 @@ public static List> createExampleITCases(SBALearningExam */ public static List> createExampleITCases(SPMMLearningExample example, SPMMLearnerVariantListImpl variants, + SPMMLockableOracle lockableOracle, EquivalenceOracle, I, Word> eqOracle) { // explicit generics are required for correct type-inference - return LearnerITUtil., SPMM, SPMMLearningExample, SPMMLearnerITCase>createExampleITCasesInternal( + return LearnerITUtil., SPMM, SPMMLearningExample, SPMMLearnerITCase, SPMMLockableOracle>createExampleITCasesInternal( example, variants, + lockableOracle, eqOracle, SPMMLearnerITCase::new); } @@ -207,6 +239,8 @@ public static List> createExampleITCases(SPMMLear * the example system * @param variants * the list containing the various learner variants + * @param lockableOracle + * the lockable oracle to check stable hypothesis construction * @param eqOracle * the equivalence oracle to use by the learning process * @param @@ -216,26 +250,29 @@ public static List> createExampleITCases(SPMMLear */ public static List> createExampleITCases(OneSEVPALearningExample example, OneSEVPALearnerVariantListImpl variants, + SEVPALockableOracle lockableOracle, EquivalenceOracle, I, Boolean> eqOracle) { // explicit generics are required for correct type-inference - return LearnerITUtil., OneSEVPALearningExample, OneSEVPALearnerITCase>createExampleITCasesInternal( + return LearnerITUtil., OneSEVPALearningExample, OneSEVPALearnerITCase, SEVPALockableOracle>createExampleITCasesInternal( example, variants, + lockableOracle, eqOracle, OneSEVPALearnerITCase::new); } - private static , C extends AbstractLearnerVariantITCase> List createExampleITCasesInternal( + private static , C extends AbstractLearnerVariantITCase, LOR extends LockableOracle> List createExampleITCasesInternal( L example, LearnerVariantListImpl variants, + LOR lockableOracle, EquivalenceOracle eqOracle, - ITCaseBuilder builder) { + ITCaseBuilder builder) { final List> variantList = variants.getLearnerVariants(); final List result = new ArrayList<>(variantList.size()); for (LearnerVariant variant : variantList) { - result.add(builder.build(variant, example, eqOracle)); + result.add(builder.build(variant, example, lockableOracle, eqOracle)); } return result; @@ -298,8 +335,11 @@ public static > List, C extends AbstractLearnerVariantITCase> { + private interface ITCaseBuilder, C extends AbstractLearnerVariantITCase, LOR extends LockableOracle> { - C build(LearnerVariant variant, L example, EquivalenceOracle eqOracle); + C build(LearnerVariant variant, + L example, + LOR lockableOracle, + EquivalenceOracle eqOracle); } } diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/util/LockableOracle.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/util/LockableOracle.java new file mode 100644 index 000000000..4b29c95e8 --- /dev/null +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/util/LockableOracle.java @@ -0,0 +1,144 @@ +/* Copyright (C) 2013-2025 TU Dortmund University + * This file is part of LearnLib . + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.learnlib.testsupport.it.util; + +import java.util.Collection; + +import de.learnlib.oracle.MembershipOracle; +import de.learnlib.oracle.SingleQueryOracle.SingleQueryOracleDFA; +import de.learnlib.oracle.SingleQueryOracle.SingleQueryOracleMealy; +import de.learnlib.oracle.SingleQueryOracle.SingleQueryOracleMoore; +import de.learnlib.query.Query; +import de.learnlib.tooling.annotation.refinement.GenerateRefinement; +import de.learnlib.tooling.annotation.refinement.Generic; +import de.learnlib.tooling.annotation.refinement.Interface; +import net.automatalib.word.Word; + +/** + * A lockable oracle is a {@link MembershipOracle} whose actions can be blocked by setting its {@link #lock() lock}. + * During testing, this can be helpful for detecting whether learning algorithms are posing queries beyond hypothesis + * construction (which they really should not). + * + * @param + * input symbol type + * @param + * output domain + */ +@GenerateRefinement(name = "DFALockableOracle", + generics = @Generic(value = "I", desc = "input symbol type"), + parentGenerics = {@Generic("I"), @Generic(clazz = Boolean.class)}, + interfaces = @Interface(clazz = SingleQueryOracleDFA.class, generics = @Generic("I"))) +@GenerateRefinement(name = "MealyLockableOracle", + generics = {@Generic(value = "I", desc = "input symbol type"), + @Generic(value = "O", desc = "output symbol type")}, + parentGenerics = {@Generic("I"), @Generic(clazz = Word.class, generics = "O")}, + interfaces = @Interface(clazz = SingleQueryOracleMealy.class, + generics = {@Generic("I"), @Generic("O")})) +@GenerateRefinement(name = "MooreLockableOracle", + generics = {@Generic(value = "I", desc = "input symbol type"), + @Generic(value = "O", desc = "output symbol type")}, + parentGenerics = {@Generic("I"), @Generic(clazz = Word.class, generics = "O")}, + interfaces = @Interface(clazz = SingleQueryOracleMoore.class, + generics = {@Generic("I"), @Generic("O")})) +@GenerateRefinement(name = "SBALockableOracle", + generics = @Generic(value = "I", desc = "input symbol type"), + parentGenerics = {@Generic("I"), @Generic(clazz = Boolean.class)}, + interfaces = @Interface(clazz = SingleQueryOracleDFA.class, generics = @Generic("I"))) +@GenerateRefinement(name = "SEVPALockableOracle", + generics = @Generic(value = "I", desc = "input symbol type"), + parentGenerics = {@Generic("I"), @Generic(clazz = Boolean.class)}, + interfaces = @Interface(clazz = SingleQueryOracleDFA.class, generics = @Generic("I"))) +@GenerateRefinement(name = "SPALockableOracle", + generics = @Generic(value = "I", desc = "input symbol type"), + parentGenerics = {@Generic("I"), @Generic(clazz = Boolean.class)}, + interfaces = @Interface(clazz = SingleQueryOracleDFA.class, generics = @Generic("I"))) +@GenerateRefinement(name = "SPMMLockableOracle", + generics = {@Generic(value = "I", desc = "input symbol type"), + @Generic(value = "O", desc = "output symbol type")}, + parentGenerics = {@Generic("I"), @Generic(clazz = Word.class, generics = "O")}, + interfaces = @Interface(clazz = SingleQueryOracleMealy.class, + generics = {@Generic("I"), @Generic("O")})) +public class LockableOracle implements MembershipOracle { + + private final MembershipOracle delegate; + private boolean lock; + + /** + * Constructor. + * + * @param delegate + * the oracle to which operations should be delegated + */ + public LockableOracle(MembershipOracle delegate) { + this.delegate = delegate; + } + + /** + * Locks this oracle. After this call, all operations will throw an {@link IllegalStateException}. + */ + public void lock() { + this.lock = true; + } + + /** + * Unlocks this oracle. After this call, all operations will the delegated as usual. + */ + public void unlock() { + this.lock = false; + } + + protected void requireLock() { + if (lock) { + throw new IllegalStateException("Membership oracle should not be queried"); + } + } + + @Override + public D answerQuery(Word input) { + requireLock(); + return this.delegate.answerQuery(input); + } + + @Override + public D answerQuery(Word prefix, Word suffix) { + requireLock(); + return this.delegate.answerQuery(prefix, suffix); + } + + @Override + public void processQuery(Query query) { + requireLock(); + this.delegate.processQuery(query); + } + + @Override + public void processQueries(Collection> queries) { + requireLock(); + this.delegate.processQueries(queries); + } + + @Override + public MembershipOracle asOracle() { + requireLock(); + return this.delegate.asOracle(); + } + + @Override + public void processBatch(Collection> batch) { + requireLock(); + this.delegate.processBatch(batch); + } +} diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/util/MMLTLockableOracle.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/util/MMLTLockableOracle.java new file mode 100644 index 000000000..055207cdc --- /dev/null +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/util/MMLTLockableOracle.java @@ -0,0 +1,46 @@ +/* Copyright (C) 2013-2025 TU Dortmund University + * This file is part of LearnLib . + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.learnlib.testsupport.it.util; + +import de.learnlib.oracle.TimedQueryOracle; +import net.automatalib.symbol.time.TimedInput; +import net.automatalib.symbol.time.TimedOutput; +import net.automatalib.word.Word; + +/** + * A type-specific refinement of {@link LockableOracle}. + * + * @param + * input symbol type (of non-delaying inputs) + * @param + * output symbol type + */ +public class MMLTLockableOracle extends LockableOracle, Word>> + implements TimedQueryOracle { + + private final TimedQueryOracle delegate; + + public MMLTLockableOracle(TimedQueryOracle delegate) { + super(delegate); + this.delegate = delegate; + } + + @Override + public TimerQueryResult queryTimers(Word> prefix, long maxTotalWaitingTime) { + requireLock(); + return this.delegate.queryTimers(prefix, maxTotalWaitingTime); + } +} diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/LearnerVariant.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/LearnerVariant.java similarity index 97% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/LearnerVariant.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/LearnerVariant.java index 01624598f..7e514e65d 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/LearnerVariant.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/LearnerVariant.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it.variant; import de.learnlib.algorithm.LearningAlgorithm; diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/LearnerVariantList.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/LearnerVariantList.java similarity index 98% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/LearnerVariantList.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/LearnerVariantList.java index b5404319a..4dcf84f16 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/LearnerVariantList.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/LearnerVariantList.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it.variant; import de.learnlib.algorithm.LearningAlgorithm; import net.automatalib.automaton.fsa.DFA; diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/LearnerVariantListImpl.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/LearnerVariantListImpl.java similarity index 99% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/LearnerVariantListImpl.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/LearnerVariantListImpl.java index 89149e98e..5b2ab0167 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/LearnerVariantListImpl.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/LearnerVariantListImpl.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it.variant; import java.util.ArrayList; import java.util.List; diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/PassiveLearnerVariant.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/PassiveLearnerVariant.java similarity index 97% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/PassiveLearnerVariant.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/PassiveLearnerVariant.java index 9e736d8b3..fc8a8cb41 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/PassiveLearnerVariant.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/PassiveLearnerVariant.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it.variant; import de.learnlib.algorithm.PassiveLearningAlgorithm; diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/PassiveLearnerVariantList.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/PassiveLearnerVariantList.java similarity index 97% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/PassiveLearnerVariantList.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/PassiveLearnerVariantList.java index 67c894dd2..d887180e7 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/PassiveLearnerVariantList.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/PassiveLearnerVariantList.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it.variant; import de.learnlib.algorithm.PassiveLearningAlgorithm; import net.automatalib.automaton.fsa.DFA; diff --git a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/PassiveLearnerVariantListImpl.java b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/PassiveLearnerVariantListImpl.java similarity index 98% rename from test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/PassiveLearnerVariantListImpl.java rename to test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/PassiveLearnerVariantListImpl.java index bf7202d06..3831f482b 100644 --- a/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/learner/PassiveLearnerVariantListImpl.java +++ b/test-support/learner-it-support/src/main/java/de/learnlib/testsupport/it/variant/PassiveLearnerVariantListImpl.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.learnlib.testsupport.it.learner; +package de.learnlib.testsupport.it.variant; import java.util.ArrayList; import java.util.List; diff --git a/test-support/learner-it-support/src/main/java/module-info.java b/test-support/learner-it-support/src/main/java/module-info.java index f98b1411f..cfb2b7a79 100644 --- a/test-support/learner-it-support/src/main/java/module-info.java +++ b/test-support/learner-it-support/src/main/java/module-info.java @@ -41,7 +41,12 @@ requires org.slf4j; requires org.testng; + // annotations are 'provided'-scoped and do not need to be loaded at runtime requires static org.checkerframework.checker.qual; + requires static de.learnlib.tooling.annotation; - exports de.learnlib.testsupport.it.learner; + exports de.learnlib.testsupport.it; + exports de.learnlib.testsupport.it.testcase; + exports de.learnlib.testsupport.it.util; + exports de.learnlib.testsupport.it.variant; }