net.automatalib.serialization.saf.SAFInput Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of automata-serialization-saf Show documentation
Show all versions of automata-serialization-saf Show documentation
(De-)Serializers for the Simple Automaton Format
/* Copyright (C) 2015 TU Dortmund
* This file is part of AutomataLib, http://www.automatalib.net/.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.automatalib.serialization.saf;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import net.automatalib.automata.AutomatonCreator;
import net.automatalib.automata.MutableAutomaton;
import net.automatalib.automata.fsa.impl.compact.CompactDFA;
import net.automatalib.automata.fsa.impl.compact.CompactNFA;
import net.automatalib.serialization.saf.SAFSerialization.AutomatonType;
import net.automatalib.words.Alphabet;
import net.automatalib.words.impl.Alphabets;
class SAFInput {
private static final AutomatonType[] types = SAFSerialization.AutomatonType.values();
private final DataInput in;
public SAFInput(DataInput in) {
this.in = in;
}
public SAFInput(InputStream is) {
this((DataInput)new DataInputStream(is));
}
public SAFInput(byte[] data) {
this(new ByteArrayInputStream(data));
}
public SAFInput(File file) throws FileNotFoundException {
this(new BufferedInputStream(new FileInputStream(file)));
}
public AutomatonType readHeader() throws IOException {
byte[] header = new byte[4];
in.readFully(header);
if (header[0] != 'S' || header[1] != 'A' || header[2] != 'F') {
throw new RuntimeException();
}
byte type = header[3];
if (type < 0 || type >= types.length) {
throw new RuntimeException();
}
return types[type];
}
private void decodeTransitionsDet(
MutableAutomaton result,
List stateList,
Alphabet alphabet,
SinglePropertyDecoder extends TP> tpDecoder) throws IOException {
int numStates = stateList.size();
assert result.size() == numStates;
int numInputs = alphabet.size();
for (S state : stateList) {
for (int j = 0; j < numInputs; j++) {
int tgt = in.readInt();
if (tgt != -1) {
I sym = alphabet.getSymbol(j);
S tgtState = stateList.get(tgt);
TP prop = tpDecoder.readProperty(in);
result.addTransition(state, sym, tgtState, prop);
}
}
}
}
private void decodeTransitionsNondet(
MutableAutomaton result,
List stateList,
Alphabet alphabet,
SinglePropertyDecoder extends TP> tpDecoder) throws IOException {
int numStates = stateList.size();
assert result.size() == numStates;
int numInputs = alphabet.size();
for (S state : stateList) {
for (int j = 0; j < numInputs; j++) {
int numTgts = in.readInt();
I sym = alphabet.getSymbol(j);
for (int k = 0; k < numTgts; k++) {
int tgt = in.readInt();
TP prop = tpDecoder.readProperty(in);
S tgtState = stateList.get(tgt);
result.addTransition(state, sym, tgtState, prop);
}
}
}
}
private List decodeStateProperties(
MutableAutomaton result,
int numStates,
BlockPropertyDecoder extends SP> decoder) throws IOException {
List stateList = new ArrayList<>(numStates);
decoder.start(in);
for (int i = 0; i < numStates; i++) {
SP prop = decoder.readProperty(in);
S state = result.addState(prop);
stateList.add(state);
}
return stateList;
}
private List decodeStatesDet(
MutableAutomaton result,
int numStates,
BlockPropertyDecoder extends SP> decoder) throws IOException {
int initStateId = in.readInt();
List stateList = decodeStateProperties(result, numStates, decoder);
S initState = stateList.get(initStateId);
result.setInitial(initState, true);
return stateList;
}
private List decodeStatesNondet(
MutableAutomaton result,
int numStates,
BlockPropertyDecoder extends SP> decoder) throws IOException {
int[] initStates = readInts(in);
List stateList = decodeStateProperties(result, numStates, decoder);
for (int initId : initStates) {
S initState = stateList.get(initId);
result.setInitial(initState, true);
}
return stateList;
}
private List decodeBodyDet(
MutableAutomaton result,
Alphabet alphabet,
int numStates,
BlockPropertyDecoder extends SP> spDecoder,
SinglePropertyDecoder extends TP> tpDecoder) throws IOException {
List stateList = decodeStatesDet(result, numStates, spDecoder);
decodeTransitionsDet(result, stateList, alphabet, tpDecoder);
return stateList;
}
private List decodeBodyNondet(
MutableAutomaton result,
Alphabet alphabet,
int numStates,
BlockPropertyDecoder extends SP> spDecoder,
SinglePropertyDecoder extends TP> tpDecoder) throws IOException {
List stateList = decodeStatesNondet(result, numStates, spDecoder);
decodeTransitionsNondet(result, stateList, alphabet, tpDecoder);
return stateList;
}
private static int[] readInts(DataInput in) throws IOException {
int n = in.readInt();
int[] result = new int[n];
for (int i = 0; i < n; i++) {
result[i] = in.readInt();
}
return result;
}
private > A readAutomatonBody(
Alphabet alphabet,
boolean deterministic,
AutomatonCreator extends A, I> creator,
BlockPropertyDecoder extends SP> spDecoder,
SinglePropertyDecoder extends TP> tpDecoder) throws IOException {
int numStates = in.readInt();
A result = creator.createAutomaton(alphabet, numStates);
// this cast is required ..
MutableAutomaton,I,?,SP,TP> result_ = (MutableAutomaton,I,?,SP,TP>)result;
if (deterministic) {
decodeBodyDet(result_, alphabet, numStates, spDecoder, tpDecoder);
}
else {
decodeBodyNondet(result_, alphabet, numStates, spDecoder, tpDecoder);
}
return result;
}
public > A readAutomaton(
AutomatonType expectedType,
Alphabet alphabet,
AutomatonCreator extends A, I> creator,
BlockPropertyDecoder extends SP> spDecoder,
SinglePropertyDecoder extends TP> tpDecoder) throws IOException {
AutomatonType type = readHeader();
if (type != expectedType) {
throw new RuntimeException();
}
int alphabetSize = in.readInt();
if (alphabetSize != alphabet.size()) {
throw new RuntimeException();
}
return readAutomatonBody(alphabet, type.isDeterministic(), creator, spDecoder, tpDecoder);
}
public > A readNativeAutomaton(
AutomatonType expectedType,
AutomatonCreator extends A, Integer> creator,
BlockPropertyDecoder extends SP> spDecoder,
SinglePropertyDecoder extends TP> tpDecoder) throws IOException {
AutomatonType type = readHeader();
if (type != expectedType) {
throw new RuntimeException();
}
int alphabetSize = in.readInt();
if (alphabetSize <= 0) {
throw new RuntimeException();
}
Alphabet alphabet = Alphabets.integers(0, alphabetSize - 1);
return readAutomatonBody(alphabet, type.isDeterministic(), creator, spDecoder, tpDecoder);
}
public CompactDFA readDFA(Alphabet alphabet) throws IOException {
return readAutomaton(
AutomatonType.DFA,
alphabet,
new CompactDFA.Creator<>(),
new AcceptanceDecoder(),
in -> null);
}
public CompactDFA readNativeDFA() throws IOException {
return readNativeAutomaton(
AutomatonType.DFA,
new CompactDFA.Creator<>(),
new AcceptanceDecoder(),
in -> null);
}
public CompactNFA readNFA(Alphabet alphabet) throws IOException {
return readAutomaton(
AutomatonType.NFA,
alphabet,
new CompactNFA.Creator<>(),
new AcceptanceDecoder(),
in -> null);
}
public CompactNFA readNativeNFA() throws IOException {
return readNativeAutomaton(
AutomatonType.NFA,
new CompactNFA.Creator<>(),
new AcceptanceDecoder(),
in -> null);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy