Skip to content

Commit a232386

Browse files
DonatoClunmtf90
andauthored
AbstractOneSEVPA: fixed issue in getOutgoingEdges(..) (LearnLib#39)
* AbstractOneSEVPA: fixed issue in getOutgoingEdges(..) * add test case * add changelog Co-authored-by: Markus Frohme <[email protected]>
1 parent 3322584 commit a232386

File tree

3 files changed

+99
-4
lines changed

3 files changed

+99
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1414
### Fixed
1515

1616
* Correctly enquote outputs containing whitespaces in `TAFWriter` ([#37](https://github.com/LearnLib/automatalib/issues/37), thanks to [Alexander Schieweck](https://github.com/aschieweck)).
17+
* Fixed a bug in the `Graph` representation of `AbstractOneSEVPA`s ([#39](https://github.com/LearnLib/automatalib/pull/39), thanks to [DonatoClun](https://github.com/DonatoClun)).
1718

1819

1920
## [0.9.0](https://github.com/LearnLib/automatalib/releases/tag/automatalib-0.9.0) - 2020-02-05

core/src/main/java/net/automatalib/automata/vpda/AbstractOneSEVPA.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public Collection<SevpaViewEdge<L, I>> getOutgoingEdges(final L location) {
125125
for (final L loc : getLocations()) {
126126
for (final I stackSymbol : alphabet.getCallAlphabet()) {
127127
final int sym = encodeStackSym(loc, stackSymbol);
128-
final L succ = getReturnSuccessor(loc, i, sym);
128+
final L succ = getReturnSuccessor(location, i, sym);
129129

130130
if (succ != null) {
131131
result.add(new SevpaViewEdge<>(i, sym, succ));
@@ -195,9 +195,9 @@ public I getCallSym(final int stackSym) {
195195

196196
static class SevpaViewEdge<S, I> {
197197

198-
private final I input;
199-
private final int stack;
200-
private final S target;
198+
final I input;
199+
final int stack;
200+
final S target;
201201

202202
SevpaViewEdge(I input, int stack, S target) {
203203
this.target = target;

core/src/test/java/net/automatalib/automata/vpda/VPDATest.java

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
package net.automatalib.automata.vpda;
1717

1818
import java.util.Collections;
19+
import java.util.HashSet;
1920

21+
import net.automatalib.automata.vpda.AbstractOneSEVPA.SevpaViewEdge;
22+
import net.automatalib.graphs.Graph;
2023
import net.automatalib.words.Alphabet;
2124
import net.automatalib.words.VPDAlphabet;
2225
import net.automatalib.words.Word;
@@ -61,4 +64,95 @@ public void testBracketLanguage() {
6164
Assert.assertFalse(vpda.accepts(Word.fromCharSequence(")(")));
6265
Assert.assertFalse(vpda.accepts(Word.fromCharSequence("()()")));
6366
}
67+
68+
/**
69+
* Test case for reported issue <a href="https://github.com/LearnLib/automatalib/pull/39">#39</a>.
70+
*/
71+
@Test
72+
public void testGraphRepresentation() {
73+
74+
final Alphabet<Integer> callAlphabet = Alphabets.integers(1, 10);
75+
final Alphabet<Integer> internalAlphabet = Alphabets.integers(11, 20);
76+
final Alphabet<Integer> returnAlphabet = Alphabets.integers(21, 30);
77+
final VPDAlphabet<Integer> alphabet = new DefaultVPDAlphabet<>(internalAlphabet, callAlphabet, returnAlphabet);
78+
79+
// create arbitrary VPA
80+
final DefaultOneSEVPA<Integer> vpa = new DefaultOneSEVPA<>(alphabet);
81+
final Location init = vpa.addInitialLocation(false);
82+
final Location accepting = vpa.addLocation(true);
83+
84+
// criss-cross internal successors
85+
for (final Integer i : internalAlphabet) {
86+
final Location initSucc;
87+
final Location accSucc;
88+
89+
if (i % 2 == 0) {
90+
initSucc = init;
91+
accSucc = accepting;
92+
} else {
93+
initSucc = accepting;
94+
accSucc = initSucc;
95+
}
96+
97+
vpa.setInternalSuccessor(init, i, initSucc);
98+
vpa.setInternalSuccessor(accepting, i, accSucc);
99+
}
100+
101+
// criss-cross return successors
102+
for (final Integer r : returnAlphabet) {
103+
104+
for (int i = 0; i < callAlphabet.size(); i++) {
105+
106+
final Location initSucc;
107+
final Location accSucc;
108+
109+
final int initSym = vpa.encodeStackSym(init, i);
110+
final int accSym = vpa.encodeStackSym(accepting, i);
111+
112+
if (i % 2 == 0) {
113+
initSucc = init;
114+
accSucc = accepting;
115+
} else {
116+
initSucc = accepting;
117+
accSucc = initSucc;
118+
}
119+
120+
vpa.setReturnSuccessor(init, r, initSym, initSucc);
121+
vpa.setReturnSuccessor(init, r, accSym, accSucc);
122+
vpa.setReturnSuccessor(accepting, r, initSym, accSucc);
123+
vpa.setReturnSuccessor(accepting, r, accSym, initSucc);
124+
}
125+
}
126+
127+
verifyGraphRepresentation(alphabet, vpa, vpa);
128+
}
129+
130+
private static <L, I> void verifyGraphRepresentation(VPDAlphabet<I> alphabet,
131+
OneSEVPA<L, I> vpa,
132+
Graph<L, SevpaViewEdge<L, I>> graph) {
133+
134+
Assert.assertEquals(new HashSet<>(vpa.getLocations()), new HashSet<>(graph.getNodes()));
135+
136+
for (final L loc : vpa.getLocations()) {
137+
for (SevpaViewEdge<L, I> edge : graph.getOutgoingEdges(loc)) {
138+
139+
final I input = edge.input;
140+
final int stack = edge.stack;
141+
final L target = edge.target;
142+
143+
switch (alphabet.getSymbolType(input)) {
144+
case CALL:
145+
throw new IllegalStateException("Call edges are implicit in a 1-SEVPA");
146+
case INTERNAL:
147+
Assert.assertEquals(vpa.getInternalSuccessor(loc, input), target);
148+
continue;
149+
case RETURN:
150+
Assert.assertEquals(vpa.getReturnSuccessor(loc, input, stack), target);
151+
continue;
152+
default:
153+
throw new IllegalStateException("Unknown symbol type: " + alphabet.getSymbolType(input));
154+
}
155+
}
156+
}
157+
}
64158
}

0 commit comments

Comments
 (0)