Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <I> void addLearnerVariants(Alphabet<I> alphabet,
int targetSize,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <I, O> void addLearnerVariants(Alphabet<I> alphabet,
int targetSize,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <I, O> void addLearnerVariants(Alphabet<I> alphabet,
int targetSize,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <I> void addLearnerVariants(Alphabet<I> alphabet,
int targetSize,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <I, O> void addLearnerVariants(Alphabet<I> alphabet,
int targetSize,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <I, O> void addLearnerVariants(Alphabet<I> alphabet,
int targetSize,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <I> void addLearnerVariants(Alphabet<I> alphabet,
int targetSize,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <I, O> void addLearnerVariants(Alphabet<I> alphabet,
int targetSize,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <I, O> void addLearnerVariants(Alphabet<I> alphabet,
int targetSize,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<M extends SuffixOutput<I, D>, I, D>
implements LearningAlgorithm<M, I, D>, SupportsGrowingAlphabet<I>, FiniteRepresentation {

private final MembershipOracle<I, D> ceqs;
private final Alphabet<I> alphabet;
protected final Alphabet<I> alphabet;
protected final SuffixTrie<I> strie;
protected final PrefixTree<I, D> ptree;

Expand All @@ -53,7 +54,7 @@ protected AbstractTTTLambda(Alphabet<I> alphabet, MembershipOracle<I, D> ceqs) {

protected abstract int maxSearchIndex(int ceLength);

protected abstract DTLeaf<I, D> getState(Word<I> prefix);
protected abstract @Nullable DTLeaf<I, D> getState(Word<I> prefix);

protected abstract AbstractDecisionTree<I, D> dtree();

Expand Down Expand Up @@ -115,7 +116,7 @@ public void addAlphabetSymbol(I symbol) {
}
}

private void makeConsistent() {
protected void makeConsistent() {
while (dtree().makeConsistent()) {
// do nothing ...
}
Expand Down Expand Up @@ -174,6 +175,7 @@ private void analyzeCounterexample(DefaultQuery<I, D> counterexample, Deque<Defa
int mid = (upper + lower) / 2;
Word<I> sprime = ce.suffix(ce.length() - (mid + 1));
DTLeaf<I, D> qnext = getState(ua.word());
assert qnext != null;
for (PTNode<I, D> uprime : qnext.getShortPrefixes()) {
witnesses.push(new DefaultQuery<>(uprime.word(), sprime));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<I> extends AbstractTTTLambda<DFA<?, I>, I, Boolean> implements DFALearner<I> {

Expand All @@ -48,7 +49,7 @@ protected int maxSearchIndex(int ceLength) {
}

@Override
protected DTLeaf<I, Boolean> getState(Word<I> prefix) {
protected @Nullable DTLeaf<I, Boolean> getState(Word<I> prefix) {
return hypothesis.getState(prefix);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -31,7 +32,7 @@

class DecisionTreeMealy<I, O> extends AbstractDecisionTree<I, Word<O>> {

private final Map<Word<I>, Word<O>> outputs;
private final Map<Word<I>, O> outputs;

DecisionTreeMealy(MembershipOracle<I, Word<O>> mqOracle, Alphabet<I> sigma, STNode<I> stRoot) {
super(sigma, mqOracle, stRoot);
Expand All @@ -45,11 +46,11 @@ protected Children<I, Word<O>> newChildren() {

@Override
protected Word<O> query(PTNode<I, Word<O>> prefix, STNode<I> suffix) {
return mqOracle.answerQuery(prefix.word(), suffix.word()).suffix(suffix.word().length());
return mqOracle.answerQuery(prefix.word(), suffix.word());
}

Word<O> getOutput(DTLeaf<I, Word<O>> leaf, I a) {
return lookupOrQuery(leaf.getShortPrefixes().get(0).word(), Word.fromLetter(a));
O getOutput(DTLeaf<I, Word<O>> leaf, I a) {
return lookupOrQuery(leaf.getShortPrefixes().get(0).word(), a);
}

@Override
Expand All @@ -59,13 +60,13 @@ public boolean makeConsistent() {
continue;
}
for (I a : alphabet) {
Word<O> refOut = null;
O refOut = null;
List<PTNode<I, Word<O>>> sp = new LinkedList<>(n.getShortPrefixes());
for (PTNode<I, Word<O>> u : sp) {
Word<O> 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;
}
Expand All @@ -75,11 +76,11 @@ public boolean makeConsistent() {
return super.makeConsistent();
}

private Word<O> lookupOrQuery(Word<I> prefix, Word<I> suffix) {
Word<I> lookup = prefix.concat(suffix);
Word<O> out = this.outputs.get(lookup);
private O lookupOrQuery(Word<I> prefix, I step) {
Word<I> 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;
Expand Down
Loading