• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

LearnLib / learnlib / 6673301747

27 Oct 2023 11:46PM UTC coverage: 91.986% (-1.3%) from 93.327%
6673301747

push

github

mtf90
merge the release and sign-artifacts profiles

10984 of 11941 relevant lines covered (91.99%)

1.72 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.44
/commons/util/src/main/java/de/learnlib/util/Experiment.java
1
/* Copyright (C) 2013-2023 TU Dortmund
2
 * This file is part of LearnLib, http://www.learnlib.de/.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package de.learnlib.util;
17

18
import de.learnlib.api.algorithm.LearningAlgorithm;
19
import de.learnlib.api.logging.Category;
20
import de.learnlib.api.oracle.EquivalenceOracle;
21
import de.learnlib.api.query.DefaultQuery;
22
import de.learnlib.filter.statistic.Counter;
23
import de.learnlib.util.statistic.SimpleProfiler;
24
import net.automatalib.alphabet.Alphabet;
25
import net.automatalib.automaton.fsa.DFA;
26
import net.automatalib.automaton.transducer.MealyMachine;
27
import net.automatalib.automaton.transducer.MooreMachine;
28
import net.automatalib.word.Word;
29
import org.checkerframework.checker.nullness.qual.Nullable;
30
import org.slf4j.Logger;
31
import org.slf4j.LoggerFactory;
32

33
/**
34
 * runs a learning experiment.
35
 *
36
 * @param <A> the automaton type
37
 */
38
public class Experiment<A extends Object> {
39

40
    public static final String LEARNING_PROFILE_KEY = "Learning";
41
    public static final String COUNTEREXAMPLE_PROFILE_KEY = "Searching for counterexample";
42

43
    private static final Logger LOGGER = LoggerFactory.getLogger(Experiment.class);
2✔
44
    private final ExperimentImpl<?, ?> impl;
45
    private boolean logModels;
46
    private boolean profile;
47
    private final Counter rounds = new Counter("Learning rounds", "#");
2✔
48
    private @Nullable A finalHypothesis;
49

50
    public <I, D> Experiment(LearningAlgorithm<? extends A, I, D> learningAlgorithm,
51
                             EquivalenceOracle<? super A, I, D> equivalenceAlgorithm,
52
                             Alphabet<I> inputs) {
2✔
53
        this.impl = new ExperimentImpl<>(learningAlgorithm, equivalenceAlgorithm, inputs);
2✔
54
    }
2✔
55

56
    public A run() {
57
        if (this.finalHypothesis != null) {
2✔
58
            throw new IllegalStateException("Experiment has already been run");
2✔
59
        }
60

61
        finalHypothesis = impl.run();
2✔
62
        return finalHypothesis;
2✔
63
    }
64

65
    public A getFinalHypothesis() {
66
        if (finalHypothesis == null) {
2✔
67
            throw new IllegalStateException("Experiment has not yet been run");
2✔
68
        }
69

70
        return finalHypothesis;
2✔
71
    }
72

73
    private void profileStart(String taskname) {
74
        if (profile) {
2✔
75
            SimpleProfiler.start(taskname);
2✔
76
        }
77
    }
2✔
78

79
    private void profileStop(String taskname) {
80
        if (profile) {
2✔
81
            SimpleProfiler.stop(taskname);
2✔
82
        }
83
    }
2✔
84

85
    /**
86
     * @param logModels
87
     *         flag whether models should be logged
88
     */
89
    public void setLogModels(boolean logModels) {
90
        this.logModels = logModels;
×
91
    }
×
92

93
    /**
94
     * @param profile
95
     *         flag whether learning process should be profiled
96
     */
97
    public void setProfile(boolean profile) {
98
        this.profile = profile;
2✔
99
    }
2✔
100

101
    /**
102
     * @return the rounds
103
     */
104
    public Counter getRounds() {
105
        return rounds;
×
106
    }
107

108
    private final class ExperimentImpl<I, D> {
2✔
109

110
        private final LearningAlgorithm<? extends A, I, D> learningAlgorithm;
111
        private final EquivalenceOracle<? super A, I, D> equivalenceAlgorithm;
112
        private final Alphabet<I> inputs;
113

114
        ExperimentImpl(LearningAlgorithm<? extends A, I, D> learningAlgorithm,
115
                       EquivalenceOracle<? super A, I, D> equivalenceAlgorithm,
116
                       Alphabet<I> inputs) {
2✔
117
            this.learningAlgorithm = learningAlgorithm;
2✔
118
            this.equivalenceAlgorithm = equivalenceAlgorithm;
2✔
119
            this.inputs = inputs;
2✔
120
        }
2✔
121

122
        public A run() {
123
            rounds.increment();
2✔
124
            LOGGER.info(Category.PHASE, "Starting round {}", rounds.getCount());
2✔
125
            LOGGER.info(Category.PHASE, "Learning");
2✔
126

127
            profileStart(LEARNING_PROFILE_KEY);
2✔
128
            learningAlgorithm.startLearning();
2✔
129
            profileStop(LEARNING_PROFILE_KEY);
2✔
130

131
            while (true) {
132
                final A hyp = learningAlgorithm.getHypothesisModel();
2✔
133

134
                if (logModels) {
2✔
135
                    LOGGER.info(Category.MODEL, hyp.toString());
×
136
                }
137

138
                LOGGER.info(Category.PHASE, "Searching for counterexample");
2✔
139

140
                profileStart(COUNTEREXAMPLE_PROFILE_KEY);
2✔
141
                DefaultQuery<I, D> ce = equivalenceAlgorithm.findCounterExample(hyp, inputs);
2✔
142
                profileStop(COUNTEREXAMPLE_PROFILE_KEY);
2✔
143

144
                if (ce == null) {
2✔
145
                    return hyp;
2✔
146
                }
147

148
                LOGGER.info(Category.COUNTEREXAMPLE, ce.getInput().toString());
2✔
149

150
                // next round ...
151
                rounds.increment();
2✔
152
                LOGGER.info(Category.PHASE, "Starting round {}", rounds.getCount());
2✔
153
                LOGGER.info(Category.PHASE, "Learning");
2✔
154

155
                profileStart(LEARNING_PROFILE_KEY);
2✔
156
                final boolean refined = learningAlgorithm.refineHypothesis(ce);
2✔
157
                profileStop(LEARNING_PROFILE_KEY);
2✔
158

159
                assert refined;
2✔
160
            }
2✔
161
        }
162
    }
163

164
    public static class DFAExperiment<I> extends Experiment<DFA<?, I>> {
165
        public DFAExperiment(LearningAlgorithm<? extends DFA<?, I>, I, Boolean> learningAlgorithm,
166
                             EquivalenceOracle<? super DFA<?, I>, I, Boolean> equivalenceAlgorithm,
167
                             Alphabet<I> inputs) {
168
            super(learningAlgorithm, equivalenceAlgorithm, inputs);
2✔
169
        }
2✔
170

171
    }
172

173
    public static class MealyExperiment<I, O> extends Experiment<MealyMachine<?, I, ?, O>> {
174

175
        public MealyExperiment(LearningAlgorithm<? extends MealyMachine<?, I, ?, O>, I, Word<O>> learningAlgorithm,
176
                               EquivalenceOracle<? super MealyMachine<?, I, ?, O>, I, Word<O>> equivalenceAlgorithm,
177
                               Alphabet<I> inputs) {
178
            super(learningAlgorithm, equivalenceAlgorithm, inputs);
×
179
        }
×
180

181
    }
182

183
    public static class MooreExperiment<I, O> extends Experiment<MooreMachine<?, I, ?, O>> {
184

185
        public MooreExperiment(LearningAlgorithm<? extends MooreMachine<?, I, ?, O>, I, Word<O>> learningAlgorithm,
186
                               EquivalenceOracle<? super MooreMachine<?, I, ?, O>, I, Word<O>> equivalenceAlgorithm,
187
                               Alphabet<I> inputs) {
188
            super(learningAlgorithm, equivalenceAlgorithm, inputs);
×
189
        }
×
190

191
    }
192

193
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc