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

LearnLib / learnlib / 6433387082

06 Oct 2023 03:10PM UTC coverage: 92.296% (-0.007%) from 92.303%
6433387082

push

github

mtf90
update Falk's developer id

11573 of 12539 relevant lines covered (92.3%)

1.67 hits per line

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

93.48
/commons/util/src/main/java/de/learnlib/util/mealy/MealyUtil.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.mealy;
17

18
import java.util.Iterator;
19
import java.util.Objects;
20

21
import de.learnlib.api.algorithm.LearningAlgorithm;
22
import de.learnlib.api.algorithm.LearningAlgorithm.MealyLearner;
23
import de.learnlib.api.oracle.MembershipOracle;
24
import de.learnlib.api.query.DefaultQuery;
25
import net.automatalib.automata.transducers.MealyMachine;
26
import net.automatalib.words.Word;
27
import org.checkerframework.checker.nullness.qual.Nullable;
28

29
/**
30
 * Utility class helping to unify various approaches to actively learning Mealy machines.
31
 */
32
public final class MealyUtil {
1✔
33

34
    public static final int NO_MISMATCH = -1;
35

36
    private MealyUtil() {
37
        // prevent instantiation
38
    }
39

40
    public static <I, O> int findMismatch(MealyMachine<?, I, ?, O> hypothesis, Word<I> input, Word<O> output) {
41
        return doFindMismatch(hypothesis, input, output);
1✔
42
    }
43

44
    public static <O> int findMismatch(Word<O> out1, Word<O> out2) {
45
        int len = out1.length();
1✔
46
        assert len == out2.length();
1✔
47

48
        for (int i = 0; i < len; i++) {
1✔
49
            O sym1 = out1.getSymbol(i);
1✔
50
            O sym2 = out2.getSymbol(i);
1✔
51

52
            if (!Objects.equals(sym1, sym2)) {
1✔
53
                return i;
1✔
54
            }
55
        }
56

57
        return NO_MISMATCH;
1✔
58
    }
59

60
    private static <S, I, T, O> int doFindMismatch(MealyMachine<S, I, T, O> hypothesis, Word<I> input, Word<O> output) {
61
        S state = hypothesis.getInitialState();
1✔
62

63
        if (state == null) {
1✔
64
            return NO_MISMATCH;
×
65
        }
66

67
        Iterator<I> inIt = input.iterator();
1✔
68
        Iterator<O> outIt = output.iterator();
1✔
69
        int i = 0;
1✔
70

71
        while (inIt.hasNext() && outIt.hasNext()) {
1✔
72
            final T trans = hypothesis.getTransition(state, inIt.next());
1✔
73
            if (trans == null) {
1✔
74
                return NO_MISMATCH;
×
75
            }
76
            final O ceOut = outIt.next();
1✔
77
            final O transOut = hypothesis.getTransitionOutput(trans);
1✔
78
            if (!Objects.equals(transOut, ceOut)) {
1✔
79
                return i;
1✔
80
            }
81
            state = hypothesis.getSuccessor(trans);
1✔
82
            i++;
1✔
83
        }
1✔
84

85
        return NO_MISMATCH;
1✔
86
    }
87

88
    public static <I, O> @Nullable DefaultQuery<I, Word<O>> shortenCounterExample(MealyMachine<?, I, ?, O> hypothesis,
89
                                                                                  DefaultQuery<I, Word<O>> ceQuery) {
90
        Word<I> cePrefix = ceQuery.getPrefix(), ceSuffix = ceQuery.getSuffix();
1✔
91
        Word<O> hypOut = hypothesis.computeSuffixOutput(cePrefix, ceSuffix);
1✔
92
        Word<O> ceOut = ceQuery.getOutput();
1✔
93
        assert ceOut.length() == hypOut.length();
1✔
94

95
        int mismatchIdx = findMismatch(hypOut, ceOut);
1✔
96
        if (mismatchIdx == NO_MISMATCH) {
1✔
97
            return null;
1✔
98
        }
99

100
        return new DefaultQuery<>(cePrefix, ceSuffix.prefix(mismatchIdx + 1), ceOut.prefix(mismatchIdx + 1));
1✔
101
    }
102

103
    public static <I, O> @Nullable DefaultQuery<I, O> reduceCounterExample(MealyMachine<?, I, ?, O> hypothesis,
104
                                                                           DefaultQuery<I, Word<O>> ceQuery) {
105
        Word<I> cePrefix = ceQuery.getPrefix(), ceSuffix = ceQuery.getSuffix();
1✔
106
        Word<O> hypOut = hypothesis.computeSuffixOutput(cePrefix, ceSuffix);
1✔
107
        Word<O> ceOut = ceQuery.getOutput();
1✔
108
        assert ceOut.length() == hypOut.length();
1✔
109

110
        int mismatchIdx = findMismatch(hypOut, ceOut);
1✔
111
        if (mismatchIdx == NO_MISMATCH) {
1✔
112
            return null;
×
113
        }
114

115
        return new DefaultQuery<>(cePrefix, ceSuffix.prefix(mismatchIdx + 1), ceOut.getSymbol(mismatchIdx));
1✔
116
    }
117

118
    public static <M extends MealyMachine<?, I, ?, O>, I, O> MealyLearner<I, O> wrapSymbolLearner(LearningAlgorithm<M, I, O> learner) {
119
        return new MealyLearnerWrapper<>(learner);
1✔
120
    }
121

122
    public static <I, O> MembershipOracle<I, @Nullable O> wrapWordOracle(MembershipOracle<I, Word<O>> oracle) {
123
        return new SymbolOracleWrapper<>(oracle);
1✔
124
    }
125

126
}
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

© 2026 Coveralls, Inc