Skip to content

Commit da1b987

Browse files
committed
replace explicit StatsContainer with ServiceLoader-based approach
1 parent db81612 commit da1b987

28 files changed

Lines changed: 242 additions & 263 deletions

File tree

algorithms/active/lstar/src/main/java/de/learnlib/algorithm/lstar/mmlt/ExtensibleLStarMMLT.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@
2323
import de.learnlib.datastructure.observationtable.Row;
2424
import de.learnlib.oracle.TimedQueryOracle;
2525
import de.learnlib.query.DefaultQuery;
26-
import de.learnlib.statistic.container.DummyStatsContainer;
27-
import de.learnlib.statistic.container.LearnerStatsProvider;
28-
import de.learnlib.statistic.container.StatsContainer;
26+
import de.learnlib.statistic.Statistics;
27+
import de.learnlib.statistic.StatsContainer;
2928
import de.learnlib.symbol_filter.SymbolFilter;
3029
import de.learnlib.symbol_filter.SymbolFilterResponse;
3130
import de.learnlib.util.mealy.MealyUtil;
@@ -50,10 +49,10 @@
5049
* @param <I> Input type for non-delaying inputs
5150
* @param <O> Output symbol type
5251
*/
53-
public class ExtensibleLStarMMLT<I, O> implements OTLearner<MMLT<Integer, I, ?, O>, TimedInput<I>, Word<TimedOutput<O>>>, LearnerStatsProvider {
52+
public class ExtensibleLStarMMLT<I, O> implements OTLearner<MMLT<Integer, I, ?, O>, TimedInput<I>, Word<TimedOutput<O>>> {
5453

5554
private static final Logger logger = LoggerFactory.getLogger(ExtensibleLStarMMLT.class);
56-
private StatsContainer stats = new DummyStatsContainer();
55+
private final StatsContainer stats;
5756

5857
private final ClosingStrategy<? super TimedInput<I>, ? super Word<TimedOutput<O>>> closingStrategy;
5958

@@ -109,6 +108,7 @@ public ExtensibleLStarMMLT(Alphabet<I> alphabet,
109108
this.closingStrategy = closingStrategy;
110109
this.timeOracle = timeOracle;
111110
this.initialSuffixes = initialSuffixes;
111+
this.stats = Statistics.getContainer();
112112

113113
// Prepare hyp data:
114114

@@ -424,12 +424,6 @@ protected void completeConsistentTable(List<List<Row<TimedInput<I>>>> unclosed)
424424

425425
}
426426

427-
@Override
428-
public void setStatsContainer(StatsContainer container) {
429-
this.stats = container;
430-
this.cexAnalyzer.setStatsContainer(container);
431-
}
432-
433427
/**
434428
* Constructs a hypothesis MMLT from an observation table, inferred local resets, and inferred local timers.
435429
*/

algorithms/active/lstar/src/main/java/de/learnlib/algorithm/lstar/mmlt/cex/MMLTCounterexampleHandler.java

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,13 @@
44

55
import de.learnlib.acex.AcexAnalyzer;
66
import de.learnlib.algorithm.lstar.mmlt.ExtensibleLStarMMLT;
7+
import de.learnlib.algorithm.lstar.mmlt.MMLTHypothesis;
78
import de.learnlib.algorithm.lstar.mmlt.cex.results.CexAnalysisResult;
89
import de.learnlib.algorithm.lstar.mmlt.cex.results.FalseIgnoreResult;
910
import de.learnlib.algorithm.lstar.mmlt.cex.results.MissingDiscriminatorResult;
1011
import de.learnlib.algorithm.lstar.mmlt.cex.results.MissingOneShotResult;
1112
import de.learnlib.algorithm.lstar.mmlt.cex.results.MissingResetResult;
12-
import de.learnlib.algorithm.lstar.mmlt.MMLTHypothesis;
1313
import de.learnlib.oracle.TimedQueryOracle;
14-
import de.learnlib.statistic.container.DummyStatsContainer;
15-
import de.learnlib.statistic.container.LearnerStatsProvider;
16-
import de.learnlib.statistic.container.StatsContainer;
1714
import de.learnlib.symbol_filter.SymbolFilter;
1815
import de.learnlib.symbol_filter.SymbolFilterResponse;
1916
import net.automatalib.automaton.mmlt.MealyTimerInfo;
@@ -34,10 +31,9 @@
3431
* @param <I> Input type for non-delaying inputs
3532
* @param <O> Output symbol type
3633
*/
37-
public class MMLTCounterexampleHandler<S, I, O> implements LearnerStatsProvider {
34+
public class MMLTCounterexampleHandler<S, I, O> {
3835
private static final Logger logger = LoggerFactory.getLogger(MMLTCounterexampleHandler.class);
3936
private final SymbolFilter<TimedInput<I>, InputSymbol<I>> symbolFilter;
40-
private StatsContainer stats = new DummyStatsContainer();
4137

4238
protected final TimedQueryOracle<I, O> timeOracle;
4339
private final MMLTCounterexampleDecompositor<S, I, O> decompositor;
@@ -48,13 +44,8 @@ public MMLTCounterexampleHandler(TimedQueryOracle<I, O> timeOracle, AcexAnalyzer
4844
this.symbolFilter = symbolFilter;
4945
}
5046

51-
@Override
52-
public void setStatsContainer(StatsContainer container) {
53-
this.stats = container;
54-
}
55-
56-
public <T> CexAnalysisResult<I, O> analyzeInconsistency(MMLTOutputInconsistency<I, O> outIncons,
57-
MMLTHypothesis<I, O> hypothesis) {
47+
public CexAnalysisResult<I, O> analyzeInconsistency(MMLTOutputInconsistency<I, O> outIncons,
48+
MMLTHypothesis<I, O> hypothesis) {
5849

5950
// Search for an extended decomposition:
6051
var decomposition = decompositor.findExtendedDecomposition(outIncons, hypothesis);

api/src/main/java/de/learnlib/statistic/container/DummyStatsContainer.java renamed to api/src/main/java/de/learnlib/statistic/DummyStatsContainer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package de.learnlib.statistic.container;
1+
package de.learnlib.statistic;
22

33
import org.checkerframework.checker.nullness.qual.Nullable;
44

@@ -8,7 +8,7 @@
88
/**
99
* A dummy implementation of {@link StatsContainer} that does nothing.
1010
*/
11-
public class DummyStatsContainer implements StatsContainer {
11+
class DummyStatsContainer implements StatsContainer {
1212
@Override
1313
public void addTextInfo(String id, @Nullable String description, String text) {
1414

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package de.learnlib.statistic;
2+
3+
import java.util.ServiceLoader;
4+
5+
public class Statistics {
6+
7+
private static final StatisticsProvider PROVIDER;
8+
9+
static {
10+
final ServiceLoader<StatisticsProvider> loader = ServiceLoader.load(StatisticsProvider.class);
11+
12+
StatisticsProvider bestProvider = new DummyProvider();
13+
for (StatisticsProvider sp : loader) {
14+
if (sp.getPriority() > bestProvider.getPriority()) {
15+
bestProvider = sp;
16+
}
17+
}
18+
19+
PROVIDER = bestProvider;
20+
}
21+
22+
public static StatsContainer getContainer() {
23+
return PROVIDER.getContainer();
24+
}
25+
26+
private static class DummyProvider implements StatisticsProvider {
27+
28+
private static final StatsContainer CONTAINER = new DummyStatsContainer();
29+
30+
@Override
31+
public int getPriority() {
32+
return Integer.MIN_VALUE;
33+
}
34+
35+
@Override
36+
public StatsContainer getContainer() {
37+
return CONTAINER;
38+
}
39+
}
40+
41+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package de.learnlib.statistic;
2+
3+
public interface StatisticsProvider {
4+
5+
int getPriority();
6+
7+
StatsContainer getContainer();
8+
}

api/src/main/java/de/learnlib/statistic/container/StatsContainer.java renamed to api/src/main/java/de/learnlib/statistic/StatsContainer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package de.learnlib.statistic.container;
1+
package de.learnlib.statistic;
22

33

44
import org.checkerframework.checker.nullness.qual.Nullable;

api/src/main/java/de/learnlib/statistic/container/LearnerStatsProvider.java

Lines changed: 0 additions & 13 deletions
This file was deleted.

api/src/main/java/module-info.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
* limitations under the License.
1515
*/
1616

17+
import de.learnlib.statistic.StatisticsProvider;
18+
1719
/**
1820
* This module provides the core interfaces of LearnLib.
1921
* <p>
@@ -43,6 +45,7 @@
4345
exports de.learnlib.query;
4446
exports de.learnlib.statistic;
4547
exports de.learnlib.sul;
46-
exports de.learnlib.statistic.container;
4748
exports de.learnlib.symbol_filter;
49+
50+
uses StatisticsProvider;
4851
}

commons/util/src/main/java/module-info.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,4 @@
4343
exports de.learnlib.util.moore;
4444
exports de.learnlib.util.nfa;
4545
exports de.learnlib.util.statistic;
46-
exports de.learnlib.util.statistic.container;
4746
}

examples/src/main/java/de/learnlib/example/mmlt/Example1.java

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,22 @@
99
import de.learnlib.driver.simulator.MMLTSimulatorSUL;
1010
import de.learnlib.filter.cache.mmlt.TimedSULTreeCache;
1111
import de.learnlib.filter.cache.mmlt.TimeoutReducerSUL;
12+
import de.learnlib.filter.statistic.oracle.CounterEQOracle;
1213
import de.learnlib.filter.statistic.sul.CounterTimedSUL;
1314
import de.learnlib.oracle.EquivalenceOracle.MMLTEquivalenceOracle;
14-
import de.learnlib.oracle.equivalence.mmlt.EQOracleChain;
15-
import de.learnlib.oracle.equivalence.mmlt.RandomWpOracle;
16-
import de.learnlib.oracle.equivalence.mmlt.ResetSearchOracle;
15+
import de.learnlib.oracle.equivalence.MMLTEQOracleChain;
16+
import de.learnlib.oracle.equivalence.mmlt.RandomWpEQOracle;
17+
import de.learnlib.oracle.equivalence.mmlt.ResetSearchEQOracle;
1718
import de.learnlib.oracle.equivalence.mmlt.SimulatorEQOracle;
1819
import de.learnlib.oracle.membership.TimedSULOracle;
1920
import de.learnlib.oracle.symbol_filters.CachedSymbolFilter;
2021
import de.learnlib.oracle.symbol_filters.mmlt.MMLTRandomSymbolFilter;
2122
import de.learnlib.oracle.symbol_filters.mmlt.MMLTStatisticsSymbolFilter;
2223
import de.learnlib.query.DefaultQuery;
23-
import de.learnlib.statistic.container.StatsContainer;
24+
import de.learnlib.statistic.Statistics;
25+
import de.learnlib.statistic.StatsContainer;
2426
import de.learnlib.symbol_filter.SymbolFilter;
2527
import de.learnlib.testsupport.example.mmlt.MMLTExamples;
26-
import de.learnlib.util.statistic.container.MapStatsContainer;
2728
import net.automatalib.automaton.visualization.MMLTVisualizationHelper;
2829
import net.automatalib.symbol.time.InputSymbol;
2930
import net.automatalib.symbol.time.TimedInput;
@@ -43,7 +44,7 @@ public static void main(String[] args) {
4344

4445
// We first create a statistics container.
4546
// This container will store various statistical data during learning:
46-
var stats = new MapStatsContainer();
47+
var stats = Statistics.getContainer();
4748
stats.addTextInfo("LocalTimerMealyModel", null, model.toString());
4849
stats.setCounter("original_locs", "Locations in original", model.getReferenceAutomaton().getStates().size());
4950
stats.setCounter("original_inputs", "Untimed alphabet size in original", model.getReferenceAutomaton().getInputAlphabet().size());
@@ -54,23 +55,21 @@ public static void main(String[] args) {
5455
var sul = new MMLTSimulatorSUL<>(model.getReferenceAutomaton().getSemantics());
5556

5657
// We count all operations that are performed on the SUL with a stats-SUL:
57-
var statsAfterCache = new CounterTimedSUL<>(sul, stats);
58+
var statsAfterCache = new CounterTimedSUL<>(sul);
5859

5960
// We use a cache to avoid redundant operations:
6061
var cacheSUL = new TimedSULTreeCache<>(statsAfterCache, model.getParams());
61-
cacheSUL.setStatsContainer(stats);
62-
var toReducerSul = new TimeoutReducerSUL<>(cacheSUL, model.getParams().maxTimeoutWaitingTime(), stats);
62+
var toReducerSul = new TimeoutReducerSUL<>(cacheSUL, model.getParams().maxTimeoutWaitingTime());
6363

6464
// We use a query oracle to answer queries from the learner:
6565
var timeOracle = new TimedSULOracle<>(toReducerSul, model.getParams());
6666

6767
// We use a chain of different equivalence oracles:
68-
EQOracleChain<String, String> chainOracle = new EQOracleChain<>();
69-
chainOracle.addOracle(cacheSUL.createCacheConsistencyTest());
70-
chainOracle.addOracle(new ResetSearchOracle<>(timeOracle, 100, 1.0, 1.0));
71-
chainOracle.addOracle(new RandomWpOracle<>(timeOracle, 100, 16, 0, 100));
72-
chainOracle.addOracle(new SimulatorEQOracle<>(model.getReferenceAutomaton())); // ensure that we eventually find an accurate model
73-
chainOracle.setStatsContainer(stats);
68+
MMLTEQOracleChain<String, String> chainOracle = new MMLTEQOracleChain<>();
69+
chainOracle.addOracle(new CounterEQOracle<>(cacheSUL.createCacheConsistencyTest(), "cache"));
70+
chainOracle.addOracle(new CounterEQOracle<>(new ResetSearchEQOracle<>(timeOracle, 100, 1.0, 1.0), "reset"));
71+
chainOracle.addOracle(new CounterEQOracle<>(new RandomWpEQOracle<>(timeOracle, 100, 16, 0, 100), "wp"));
72+
chainOracle.addOracle(new CounterEQOracle<>(new SimulatorEQOracle<>(model.getReferenceAutomaton()), "sim")); // ensure that we eventually find an accurate model
7473

7574
// Set up our L* learner:
7675
List<Word<TimedInput<String>>> suffixes = new ArrayList<>();
@@ -87,7 +86,6 @@ public static void main(String[] args) {
8786
filter = new CachedSymbolFilter<>(filter); // need to wrap to enable updates to responses
8887

8988
var learner = new ExtensibleLStarMMLT<>(model.getReferenceAutomaton().getInputAlphabet(), model.getParams(), suffixes, timeOracle, filter);
90-
learner.setStatsContainer(stats);
9189

9290
// Start learning:
9391
runExperiment(learner, chainOracle, stats, 100);

0 commit comments

Comments
 (0)