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

LearnLib / automatalib / 13138848026

04 Feb 2025 02:53PM UTC coverage: 92.108% (+2.2%) from 89.877%
13138848026

push

github

mtf90
[maven-release-plugin] prepare release automatalib-0.12.0

16609 of 18032 relevant lines covered (92.11%)

1.7 hits per line

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

97.44
/serialization/saf/src/main/java/net/automatalib/serialization/saf/SAFOutput.java
1
/* Copyright (C) 2013-2025 TU Dortmund University
2
 * This file is part of AutomataLib <https://automatalib.net>.
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 net.automatalib.serialization.saf;
17

18
import java.io.DataOutput;
19
import java.io.DataOutputStream;
20
import java.io.IOException;
21
import java.io.OutputStream;
22
import java.util.ArrayList;
23
import java.util.Collection;
24
import java.util.List;
25
import java.util.Set;
26

27
import net.automatalib.alphabet.Alphabet;
28
import net.automatalib.automaton.UniversalAutomaton;
29
import net.automatalib.common.util.io.NonClosingOutputStream;
30
import net.automatalib.serialization.InputModelSerializer;
31

32
class SAFOutput<S, I, T, SP, TP, M extends UniversalAutomaton<S, I, T, SP, TP>> implements InputModelSerializer<I, M> {
2✔
33

34
    private final AutomatonType expectedType;
35
    private final BlockPropertyEncoder<? super SP> spEncoder;
36
    private final SinglePropertyEncoder<? super TP> tpEncoder;
37

38
    SAFOutput(AutomatonType expectedType,
39
              BlockPropertyEncoder<? super SP> spEncoder,
40
              SinglePropertyEncoder<? super TP> tpEncoder) {
2✔
41
        this.expectedType = expectedType;
2✔
42
        this.spEncoder = spEncoder;
2✔
43
        this.tpEncoder = tpEncoder;
2✔
44
    }
2✔
45

46
    @Override
47
    public void writeModel(OutputStream os, M model, Alphabet<I> alphabet) throws IOException {
48
        try (DataOutputStream out = new DataOutputStream(new NonClosingOutputStream(os))) {
2✔
49
            writeHeader(out, expectedType);
2✔
50
            out.writeInt(alphabet.size());
2✔
51
            writeAutomatonBody(out, model, alphabet, expectedType.isDeterministic(), spEncoder, tpEncoder);
2✔
52
        }
53
    }
2✔
54

55
    private void writeHeader(DataOutput out, AutomatonType type) throws IOException {
56
        out.writeByte('S');
2✔
57
        out.writeByte('A');
2✔
58
        out.writeByte('F');
2✔
59
        out.writeByte(type.ordinal());
2✔
60
    }
2✔
61

62
    private void writeAutomatonBody(DataOutput out,
63
                                    M automaton,
64
                                    Alphabet<I> alphabet,
65
                                    boolean deterministic,
66
                                    BlockPropertyEncoder<? super SP> spDecoder,
67
                                    SinglePropertyEncoder<? super TP> tpDecoder) throws IOException {
68

69
        final int numStates = automaton.size();
2✔
70
        out.writeInt(numStates);
2✔
71

72
        if (deterministic) {
2✔
73
            encodeBodyDet(out, automaton, alphabet, spDecoder, tpDecoder);
2✔
74
        } else {
75
            encodeBodyNondet(out, automaton, alphabet, spDecoder, tpDecoder);
2✔
76
        }
77
    }
2✔
78

79
    private void encodeBodyDet(DataOutput out,
80
                               M result,
81
                               Alphabet<I> alphabet,
82
                               BlockPropertyEncoder<? super SP> spEncoder,
83
                               SinglePropertyEncoder<? super TP> tpEncoder) throws IOException {
84

85
        final Set<S> initials = result.getInitialStates();
2✔
86

87
        if (initials.size() != 1) {
2✔
88
            throw new IllegalArgumentException();
×
89
        }
90

91
        final List<S> states = new ArrayList<>(result.getStates());
2✔
92
        final S init = initials.iterator().next();
2✔
93

94
        encodeStatesDet(out, result, init, states, spEncoder);
2✔
95
        encodeTransitionsDet(out, result, alphabet, states, tpEncoder);
2✔
96
    }
2✔
97

98
    private void encodeBodyNondet(DataOutput out,
99
                                  M source,
100
                                  Alphabet<I> alphabet,
101
                                  BlockPropertyEncoder<? super SP> spEncoder,
102
                                  SinglePropertyEncoder<? super TP> tpEncoder) throws IOException {
103

104
        final List<S> states = new ArrayList<>(source.getStates());
2✔
105
        final Set<S> initials = source.getInitialStates();
2✔
106

107
        encodeStatesNondet(out, source, initials, states, spEncoder);
2✔
108
        encodeTransitionsNondet(out, source, alphabet, states, tpEncoder);
2✔
109
    }
2✔
110

111
    private void encodeStatesDet(DataOutput out,
112
                                 M source,
113
                                 S init,
114
                                 List<S> states,
115
                                 BlockPropertyEncoder<? super SP> encoder) throws IOException {
116
        out.writeInt(states.indexOf(init));
2✔
117
        encodeStateProperties(out, source, states, encoder);
2✔
118
    }
2✔
119

120
    private void encodeTransitionsDet(DataOutput out,
121
                                      M source,
122
                                      Alphabet<I> alphabet,
123
                                      List<S> stateList,
124
                                      SinglePropertyEncoder<? super TP> tpEncoder) throws IOException {
125
        for (S state : stateList) {
2✔
126
            for (int j = 0; j < alphabet.size(); j++) {
2✔
127
                final I sym = alphabet.getSymbol(j);
2✔
128

129
                final Collection<T> succs = source.getTransitions(state, sym);
2✔
130

131
                if (succs.size() > 1) {
2✔
132
                    throw new IllegalArgumentException("Not deterministic");
×
133
                }
134

135
                // undefined succ
136
                if (succs.isEmpty()) {
2✔
137
                    out.writeInt(-1);
2✔
138
                } else {
139
                    final T succ = succs.iterator().next();
2✔
140
                    final S succState = source.getSuccessor(succ);
2✔
141

142
                    assert succState != null;
2✔
143

144
                    final int tgt = stateList.indexOf(succState);
2✔
145

146
                    out.writeInt(tgt);
2✔
147
                    tpEncoder.writeProperty(out, source.getTransitionProperty(succ));
2✔
148
                }
149
            }
150
        }
2✔
151
    }
2✔
152

153
    private void encodeStatesNondet(DataOutput out,
154
                                    M source,
155
                                    Collection<? extends S> initialStates,
156
                                    List<S> states,
157
                                    BlockPropertyEncoder<? super SP> encoder) throws IOException {
158
        // 'writeInts'
159
        out.writeInt(initialStates.size());
2✔
160

161
        for (S s : initialStates) {
2✔
162
            out.writeInt(states.indexOf(s));
2✔
163
        }
2✔
164
        // end 'writeInts'
165

166
        encodeStateProperties(out, source, states, encoder);
2✔
167
    }
2✔
168

169
    private void encodeTransitionsNondet(DataOutput out,
170
                                         M source,
171
                                         Alphabet<I> alphabet,
172
                                         List<S> stateList,
173
                                         SinglePropertyEncoder<? super TP> tpEncoder) throws IOException {
174
        for (S state : stateList) {
2✔
175
            for (int j = 0; j < alphabet.size(); j++) {
2✔
176
                final I sym = alphabet.getSymbol(j);
2✔
177

178
                final Collection<T> succs = source.getTransitions(state, sym);
2✔
179

180
                out.writeInt(succs.size());
2✔
181

182
                for (T t : succs) {
2✔
183
                    final S succState = source.getSuccessor(t);
2✔
184
                    out.writeInt(stateList.indexOf(succState));
2✔
185
                    tpEncoder.writeProperty(out, source.getTransitionProperty(t));
2✔
186
                }
2✔
187
            }
188
        }
2✔
189
    }
2✔
190

191
    private void encodeStateProperties(DataOutput out,
192
                                       M source,
193
                                       List<S> states,
194
                                       BlockPropertyEncoder<? super SP> encoder) throws IOException {
195
        encoder.start(out);
2✔
196

197
        for (S s : states) {
2✔
198
            encoder.encodeProperty(out, source.getStateProperty(s));
2✔
199
        }
2✔
200

201
        encoder.finish(out);
2✔
202
    }
2✔
203
}
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