From a7e1dc0714ac5a829cc87de7dd9d09ec88eb2a31 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Wed, 29 Jun 2022 14:23:19 -0400 Subject: [PATCH 1/6] Parse states from AUT Header --- .../serialization/aut/InternalAUTParser.java | 7 ++--- .../aut/AUTSerializationTest.java | 26 +++++++++++++++++++ .../aut/src/test/resources/sinkStateTest.aut | 5 ++++ 3 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 serialization/aut/src/test/resources/sinkStateTest.aut diff --git a/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java b/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java index bb92fc5c72..ed2a540796 100644 --- a/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java +++ b/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java @@ -38,6 +38,7 @@ class InternalAUTParser { private int initialState; + private int numStates; private final Set alphabetSymbols = new HashSet<>(); private final Map> transitionMap = new HashMap<>(); @@ -65,7 +66,7 @@ public InputModelData> parse(Function result = new CompactNFA<>(alphabet, transitionMap.size()); - for (int i = 0; i < transitionMap.size(); i++) { + for (int i = 0; i < numStates; i++) { result.addState(); } @@ -98,9 +99,9 @@ private void parseHeader(BufferedReader reader) throws IOException { verifyLBracketAndShift(); initialState = parseNumberAndShift(); verifyCommaAndShift(); - parseNumberAndShift(); // ignore number of states - verifyCommaAndShift(); parseNumberAndShift(); // ignore number of transitions + verifyCommaAndShift(); + numStates = parseNumberAndShift(); // store number of states verifyRBracketAndShift(); } diff --git a/serialization/aut/src/test/java/net/automatalib/serialization/aut/AUTSerializationTest.java b/serialization/aut/src/test/java/net/automatalib/serialization/aut/AUTSerializationTest.java index 19d951d65c..989b3d7cfb 100644 --- a/serialization/aut/src/test/java/net/automatalib/serialization/aut/AUTSerializationTest.java +++ b/serialization/aut/src/test/java/net/automatalib/serialization/aut/AUTSerializationTest.java @@ -28,12 +28,15 @@ import com.google.common.io.ByteStreams; import net.automatalib.automata.fsa.DFA; import net.automatalib.automata.fsa.impl.compact.CompactDFA; +import net.automatalib.automata.fsa.impl.compact.CompactNFA; import net.automatalib.automata.simple.SimpleAutomaton; import net.automatalib.commons.util.io.UnclosableInputStream; import net.automatalib.commons.util.io.UnclosableOutputStream; +import net.automatalib.util.automata.builders.AutomatonBuilders; import net.automatalib.util.automata.random.RandomAutomata; import net.automatalib.words.Alphabet; import net.automatalib.words.impl.Alphabets; +import net.automatalib.words.impl.ArrayAlphabet; import org.testng.Assert; import org.testng.annotations.Test; @@ -65,6 +68,29 @@ public void quotationLabelTest() throws Exception { } } + @Test + public void sinkStateTest() throws Exception { + try (InputStream is = AUTSerializationTest.class.getResourceAsStream("/sinkStateTest.aut")) { + final SimpleAutomaton automaton = AUTParser.readAutomaton(is).model; + Assert.assertEquals(3, automaton.size()); + + final Alphabet alphabet = new ArrayAlphabet("input", "output"); + + final Set s0 = automaton.getInitialStates(); + final Set t1 = automaton.getSuccessors(s0, Collections.singletonList("input")); + final Set t2 = automaton.getSuccessors(s0, Collections.singletonList("output")); + final Set t3 = automaton.getSuccessors(s0, Arrays.asList("input", "output")); + final Set t4 = automaton.getSuccessors(s0, Arrays.asList("input", "output", "output")); + + Assert.assertEquals(Collections.singleton(0), s0); + Assert.assertEquals(Collections.singleton(1), t1); + Assert.assertEquals(Collections.singleton(2), t2); + Assert.assertEquals(Collections.singleton(0), t3); + Assert.assertEquals(Collections.singleton(2), t4); + } + } + + @Test public void serializationTest() throws Exception { final Alphabet alphabet = Alphabets.integers(0, 2); diff --git a/serialization/aut/src/test/resources/sinkStateTest.aut b/serialization/aut/src/test/resources/sinkStateTest.aut new file mode 100644 index 0000000000..15794c0505 --- /dev/null +++ b/serialization/aut/src/test/resources/sinkStateTest.aut @@ -0,0 +1,5 @@ +des(0,4,3) +(0,input,1) +(0,output,2) +(1,input,2) +(1,output,0) \ No newline at end of file From 02f23c7c73a38d30d2118b50df1d9864f20b9d03 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Wed, 29 Jun 2022 18:42:35 -0400 Subject: [PATCH 2/6] Use numStates for initial automaton size --- .../net/automatalib/serialization/aut/InternalAUTParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java b/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java index ed2a540796..a96f8167e1 100644 --- a/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java +++ b/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java @@ -64,7 +64,7 @@ public InputModelData> parse(Function inputMap = Maps.asMap(alphabetSymbols, inputTransformer::apply); final Alphabet alphabet = Alphabets.fromCollection(inputMap.values()); - final CompactNFA result = new CompactNFA<>(alphabet, transitionMap.size()); + final CompactNFA result = new CompactNFA<>(alphabet, numStates); for (int i = 0; i < numStates; i++) { result.addState(); From 162a78cd5bdb3d8eabb7080d928656a74e49ccaf Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Wed, 29 Jun 2022 20:40:19 -0400 Subject: [PATCH 3/6] Throw exception for invalid number of states and invalid state numbers --- .../automatalib/serialization/aut/InternalAUTParser.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java b/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java index a96f8167e1..3b3babd3d9 100644 --- a/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java +++ b/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java @@ -102,6 +102,9 @@ private void parseHeader(BufferedReader reader) throws IOException { parseNumberAndShift(); // ignore number of transitions verifyCommaAndShift(); numStates = parseNumberAndShift(); // store number of states + if(numStates == 0) { + throw new IllegalArgumentException("Number of states must be >= 1"); + } verifyRBracketAndShift(); } @@ -188,7 +191,9 @@ private int parseNumberAndShift() { final StringBuilder sb = new StringBuilder(); char sym = currentLineContent[currentPos]; - + if(sym == '-') { + throw new IllegalArgumentException(buildErrorMessage("Negative numbers not compatible with AUT format")); + } while (Character.isDigit(sym)) { sb.append(sym); currentPos++; From 927f7895cf790f3656531ec9dc2b1e47fb60b2e8 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Wed, 29 Jun 2022 21:24:35 -0400 Subject: [PATCH 4/6] Add assertions for testing incorrect state numbers --- .../automatalib/serialization/aut/InternalAUTParser.java | 7 ++++++- .../serialization/aut/AUTSerializationTest.java | 7 +++++-- serialization/aut/src/test/resources/error4.aut | 4 ++++ serialization/aut/src/test/resources/error5.aut | 2 ++ 4 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 serialization/aut/src/test/resources/error4.aut create mode 100644 serialization/aut/src/test/resources/error5.aut diff --git a/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java b/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java index 3b3babd3d9..26b747e6ec 100644 --- a/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java +++ b/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java @@ -102,7 +102,7 @@ private void parseHeader(BufferedReader reader) throws IOException { parseNumberAndShift(); // ignore number of transitions verifyCommaAndShift(); numStates = parseNumberAndShift(); // store number of states - if(numStates == 0) { + if(numStates < 1) { throw new IllegalArgumentException("Number of states must be >= 1"); } verifyRBracketAndShift(); @@ -194,12 +194,17 @@ private int parseNumberAndShift() { if(sym == '-') { throw new IllegalArgumentException(buildErrorMessage("Negative numbers not compatible with AUT format")); } + while (Character.isDigit(sym)) { sb.append(sym); currentPos++; sym = currentLineContent[currentPos]; } + if(sb.length() == 0){ + throw new IllegalArgumentException(buildErrorMessage("Expected number")); + } + // forward pointer shiftToNextNonWhitespace(); return Integer.parseInt(sb.toString()); diff --git a/serialization/aut/src/test/java/net/automatalib/serialization/aut/AUTSerializationTest.java b/serialization/aut/src/test/java/net/automatalib/serialization/aut/AUTSerializationTest.java index 989b3d7cfb..43e3a55fc1 100644 --- a/serialization/aut/src/test/java/net/automatalib/serialization/aut/AUTSerializationTest.java +++ b/serialization/aut/src/test/java/net/automatalib/serialization/aut/AUTSerializationTest.java @@ -90,7 +90,6 @@ public void sinkStateTest() throws Exception { } } - @Test public void serializationTest() throws Exception { final Alphabet alphabet = Alphabets.integers(0, 2); @@ -118,10 +117,14 @@ private void equalityTest(SimpleAutomaton src, SimpleAutomaton AUTParser.readAutomaton(e1)); Assert.assertThrows(() -> AUTParser.readAutomaton(e2)); Assert.assertThrows(() -> AUTParser.readAutomaton(e3)); + Assert.assertThrows(() -> AUTParser.readAutomaton(e4)); + Assert.assertThrows(() -> AUTParser.readAutomaton(e5)); } } diff --git a/serialization/aut/src/test/resources/error4.aut b/serialization/aut/src/test/resources/error4.aut new file mode 100644 index 0000000000..73898677ff --- /dev/null +++ b/serialization/aut/src/test/resources/error4.aut @@ -0,0 +1,4 @@ +des(0, 3, 0) +(0, a, 1) +(1, b, 0) +(1, c, 1) \ No newline at end of file diff --git a/serialization/aut/src/test/resources/error5.aut b/serialization/aut/src/test/resources/error5.aut new file mode 100644 index 0000000000..34be5ec16c --- /dev/null +++ b/serialization/aut/src/test/resources/error5.aut @@ -0,0 +1,2 @@ +des(0, 1, 1) +(1, z , -2) \ No newline at end of file From 851d1dddbb74f5cc6ef37e41f56285a0028dd6e4 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Thu, 30 Jun 2022 08:17:59 -0400 Subject: [PATCH 5/6] Generalize error message --- .../net/automatalib/serialization/aut/InternalAUTParser.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java b/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java index 26b747e6ec..7b49db6210 100644 --- a/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java +++ b/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java @@ -191,9 +191,6 @@ private int parseNumberAndShift() { final StringBuilder sb = new StringBuilder(); char sym = currentLineContent[currentPos]; - if(sym == '-') { - throw new IllegalArgumentException(buildErrorMessage("Negative numbers not compatible with AUT format")); - } while (Character.isDigit(sym)) { sb.append(sym); @@ -202,7 +199,7 @@ private int parseNumberAndShift() { } if(sb.length() == 0){ - throw new IllegalArgumentException(buildErrorMessage("Expected number")); + throw new IllegalArgumentException(buildErrorMessage("Expected a positive number")); } // forward pointer From cb3a2800f62949413f8b11b20c62d51fa228d31e Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Thu, 30 Jun 2022 22:51:08 -0400 Subject: [PATCH 6/6] Remove unused imports --- .../net/automatalib/serialization/aut/InternalAUTParser.java | 4 ++-- .../automatalib/serialization/aut/AUTSerializationTest.java | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java b/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java index 7b49db6210..c37bfea758 100644 --- a/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java +++ b/serialization/aut/src/main/java/net/automatalib/serialization/aut/InternalAUTParser.java @@ -102,7 +102,7 @@ private void parseHeader(BufferedReader reader) throws IOException { parseNumberAndShift(); // ignore number of transitions verifyCommaAndShift(); numStates = parseNumberAndShift(); // store number of states - if(numStates < 1) { + if (numStates < 1) { throw new IllegalArgumentException("Number of states must be >= 1"); } verifyRBracketAndShift(); @@ -198,7 +198,7 @@ private int parseNumberAndShift() { sym = currentLineContent[currentPos]; } - if(sb.length() == 0){ + if (sb.length() == 0){ throw new IllegalArgumentException(buildErrorMessage("Expected a positive number")); } diff --git a/serialization/aut/src/test/java/net/automatalib/serialization/aut/AUTSerializationTest.java b/serialization/aut/src/test/java/net/automatalib/serialization/aut/AUTSerializationTest.java index 43e3a55fc1..0f043b5ef1 100644 --- a/serialization/aut/src/test/java/net/automatalib/serialization/aut/AUTSerializationTest.java +++ b/serialization/aut/src/test/java/net/automatalib/serialization/aut/AUTSerializationTest.java @@ -28,11 +28,9 @@ import com.google.common.io.ByteStreams; import net.automatalib.automata.fsa.DFA; import net.automatalib.automata.fsa.impl.compact.CompactDFA; -import net.automatalib.automata.fsa.impl.compact.CompactNFA; import net.automatalib.automata.simple.SimpleAutomaton; import net.automatalib.commons.util.io.UnclosableInputStream; import net.automatalib.commons.util.io.UnclosableOutputStream; -import net.automatalib.util.automata.builders.AutomatonBuilders; import net.automatalib.util.automata.random.RandomAutomata; import net.automatalib.words.Alphabet; import net.automatalib.words.impl.Alphabets;