Skip to content

Commit 2e49865

Browse files
committed
refactor ObserverationTable implementation
move observation table implementation of lstar algorithm to corresponding datastructure module and cleanup code, such as - dropping duplicate interfaces, - dropping interfaces for DAOs and - splitting up existing OT functionality to read-only and mutable OT interface. fixes #47
1 parent 6462176 commit 2e49865

29 files changed

Lines changed: 722 additions & 914 deletions

algorithms/active/lstar/pom.xml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,6 @@ limitations under the License.
7676
<artifactId>automata-util</artifactId>
7777
</dependency>
7878

79-
<dependency>
80-
<groupId>com.google.guava</groupId>
81-
<artifactId>guava</artifactId>
82-
</dependency>
83-
8479
<!-- BuilderGen -->
8580
<dependency>
8681
<groupId>com.github.misberner.buildergen</groupId>

algorithms/active/lstar/src/main/java/de/learnlib/algorithms/lstar/AbstractAutomatonLStar.java

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@
1919
import java.util.ArrayList;
2020
import java.util.List;
2121

22-
import de.learnlib.algorithms.lstar.table.Row;
2322
import de.learnlib.api.algorithm.feature.ResumableLearner;
2423
import de.learnlib.api.oracle.MembershipOracle;
2524
import de.learnlib.api.query.DefaultQuery;
25+
import de.learnlib.datastructure.observationtable.ObservationTable;
26+
import de.learnlib.datastructure.observationtable.Row;
2627
import net.automatalib.automata.GrowableAlphabetAutomaton;
2728
import net.automatalib.automata.MutableDeterministic;
2829
import net.automatalib.commons.util.collections.CollectionsUtil;
@@ -61,7 +62,7 @@ public abstract class AbstractAutomatonLStar<A, I, D, S, T, SP, TP, AI extends M
6162
* @param oracle
6263
* the learning oracle
6364
*/
64-
public AbstractAutomatonLStar(Alphabet<I> alphabet, MembershipOracle<I, D> oracle, AI internalHyp) {
65+
protected AbstractAutomatonLStar(Alphabet<I> alphabet, MembershipOracle<I, D> oracle, AI internalHyp) {
6566
super(alphabet, oracle);
6667
this.internalHyp = internalHyp;
6768
internalHyp.clear();
@@ -82,16 +83,16 @@ public final void startLearning() {
8283

8384
/**
8485
* Performs the L*-style hypothesis construction. For creating states and transitions, the {@link
85-
* #stateProperty(Row)} and {@link #transitionProperty(Row, int)} methods are used to derive the respective
86-
* properties.
86+
* #stateProperty(ObservationTable, Row)} and {@link #transitionProperty(ObservationTable, Row, int)} methods are
87+
* used to derive the respective properties.
8788
*/
8889
protected void updateInternalHypothesis() {
8990
if (!table.isInitialized()) {
9091
throw new IllegalStateException("Cannot update internal hypothesis: not initialized");
9192
}
9293

9394
int oldStates = internalHyp.size();
94-
int numDistinct = table.numDistinctRows();
95+
int numDistinct = table.numberOfDistinctRows();
9596

9697
int newStates = numDistinct - oldStates;
9798

@@ -105,7 +106,7 @@ protected void updateInternalHypothesis() {
105106
if (info != null) {
106107
// State from previous hypothesis, property might have changed
107108
if (info.getRow() == sp) {
108-
internalHyp.setStateProperty(info.getState(), stateProperty(sp));
109+
internalHyp.setStateProperty(info.getState(), stateProperty(table, sp));
109110
}
110111
continue;
111112
}
@@ -128,31 +129,33 @@ protected void updateInternalHypothesis() {
128129

129130
S succState = stateInfos.get(succId).getState();
130131

131-
setTransition(state, input, succState, sp, i, succ);
132+
setTransition(state, input, succState, sp, i);
132133
}
133134
}
134135
}
135136

136137
/**
137138
* Derives a state property from the corresponding row.
138139
*
140+
* @param table
141+
* the current observation table
139142
* @param stateRow
140143
* the row for which the state is created
141144
*
142145
* @return the state property of the corresponding state
143146
*/
144-
protected abstract SP stateProperty(Row<I> stateRow);
147+
protected abstract SP stateProperty(ObservationTable<I, D> table, Row<I> stateRow);
145148

146149
protected S createState(boolean initial, Row<I> row) {
147-
SP prop = stateProperty(row);
150+
SP prop = stateProperty(table, row);
148151
if (initial) {
149152
return internalHyp.addInitialState(prop);
150153
}
151154
return internalHyp.addState(prop);
152155
}
153156

154-
protected void setTransition(S from, I input, S to, Row<I> fromRow, int inputIdx, Row<I> toRow) {
155-
TP prop = transitionProperty(fromRow, inputIdx);
157+
protected void setTransition(S from, I input, S to, Row<I> fromRow, int inputIdx) {
158+
TP prop = transitionProperty(table, fromRow, inputIdx);
156159
internalHyp.setTransition(from, input, to, prop);
157160
}
158161

@@ -169,7 +172,7 @@ protected void setTransition(S from, I input, S to, Row<I> fromRow, int inputIdx
169172
*
170173
* @return the transition property of the corresponding transition
171174
*/
172-
protected abstract TP transitionProperty(Row<I> stateRow, int inputIdx);
175+
protected abstract TP transitionProperty(ObservationTable<I, D> table, Row<I> stateRow, int inputIdx);
173176

174177
@Override
175178
protected final void doRefineHypothesis(DefaultQuery<I, D> ceQuery) {
@@ -201,7 +204,7 @@ public AutomatonLStarState<I, D, AI, S> suspend() {
201204
@Override
202205
public void resume(final AutomatonLStarState<I, D, AI, S> state) {
203206
this.table = state.getObservationTable();
204-
this.table.setAlphabet(alphabet);
207+
this.table.setInputAlphabet(alphabet);
205208
this.internalHyp = state.getHypothesis();
206209
this.stateInfos = state.getStateInfos();
207210
}

algorithms/active/lstar/src/main/java/de/learnlib/algorithms/lstar/AbstractExtensibleAutomatonLStar.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
import de.learnlib.algorithms.lstar.ce.ObservationTableCEXHandlers;
2323
import de.learnlib.algorithms.lstar.closing.ClosingStrategies;
2424
import de.learnlib.algorithms.lstar.closing.ClosingStrategy;
25-
import de.learnlib.algorithms.lstar.table.Row;
2625
import de.learnlib.api.oracle.MembershipOracle;
2726
import de.learnlib.api.query.DefaultQuery;
27+
import de.learnlib.datastructure.observationtable.Row;
2828
import net.automatalib.automata.GrowableAlphabetAutomaton;
2929
import net.automatalib.automata.MutableDeterministic;
3030
import net.automatalib.words.Alphabet;
@@ -38,13 +38,13 @@ public abstract class AbstractExtensibleAutomatonLStar<A, I, D, S, T, SP, TP, AI
3838
protected final List<Word<I>> initialPrefixes;
3939
protected final List<Word<I>> initialSuffixes;
4040

41-
public AbstractExtensibleAutomatonLStar(Alphabet<I> alphabet,
42-
MembershipOracle<I, D> oracle,
43-
AI internalHyp,
44-
List<Word<I>> initialPrefixes,
45-
List<Word<I>> initialSuffixes,
46-
ObservationTableCEXHandler<? super I, ? super D> cexHandler,
47-
ClosingStrategy<? super I, ? super D> closingStrategy) {
41+
protected AbstractExtensibleAutomatonLStar(Alphabet<I> alphabet,
42+
MembershipOracle<I, D> oracle,
43+
AI internalHyp,
44+
List<Word<I>> initialPrefixes,
45+
List<Word<I>> initialSuffixes,
46+
ObservationTableCEXHandler<? super I, ? super D> cexHandler,
47+
ClosingStrategy<? super I, ? super D> closingStrategy) {
4848
super(alphabet, oracle, internalHyp);
4949
this.initialPrefixes = initialPrefixes;
5050
this.initialSuffixes = initialSuffixes;
@@ -80,7 +80,6 @@ public static <I> List<Word<I>> initialPrefixes() {
8080
}
8181

8282
public static <I> List<Word<I>> initialSuffixes() {
83-
8483
return Collections.emptyList();
8584
}
8685

algorithms/active/lstar/src/main/java/de/learnlib/algorithms/lstar/AbstractLStar.java

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@
2222
import java.util.Objects;
2323

2424
import de.learnlib.algorithms.lstar.ce.ObservationTableCEXHandlers;
25-
import de.learnlib.algorithms.lstar.table.Inconsistency;
26-
import de.learnlib.algorithms.lstar.table.ObservationTable;
27-
import de.learnlib.algorithms.lstar.table.Row;
2825
import de.learnlib.api.algorithm.feature.GlobalSuffixLearner;
2926
import de.learnlib.api.algorithm.feature.SupportsGrowingAlphabet;
3027
import de.learnlib.api.oracle.MembershipOracle;
3128
import de.learnlib.api.query.DefaultQuery;
29+
import de.learnlib.datastructure.observationtable.GenericObservationTable;
30+
import de.learnlib.datastructure.observationtable.Inconsistency;
3231
import de.learnlib.datastructure.observationtable.OTLearner;
32+
import de.learnlib.datastructure.observationtable.ObservationTable;
33+
import de.learnlib.datastructure.observationtable.Row;
3334
import de.learnlib.util.MQUtil;
3435
import net.automatalib.automata.concepts.SuffixOutput;
3536
import net.automatalib.words.Alphabet;
@@ -57,7 +58,7 @@ public abstract class AbstractLStar<A, I, D>
5758

5859
protected Alphabet<I> alphabet;
5960
protected final MembershipOracle<I, D> oracle;
60-
protected ObservationTable<I, D> table;
61+
protected GenericObservationTable<I, D> table;
6162

6263
/**
6364
* Constructor.
@@ -67,10 +68,10 @@ public abstract class AbstractLStar<A, I, D>
6768
* @param oracle
6869
* the membership oracle.
6970
*/
70-
public AbstractLStar(Alphabet<I> alphabet, MembershipOracle<I, D> oracle) {
71+
protected AbstractLStar(Alphabet<I> alphabet, MembershipOracle<I, D> oracle) {
7172
this.alphabet = alphabet;
7273
this.oracle = oracle;
73-
this.table = new ObservationTable<>(alphabet);
74+
this.table = new GenericObservationTable<>(alphabet);
7475
}
7576

7677
@Override
@@ -87,9 +88,9 @@ public final boolean refineHypothesis(DefaultQuery<I, D> ceQuery) {
8788
if (!MQUtil.isCounterexample(ceQuery, hypothesisOutput())) {
8889
return false;
8990
}
90-
int oldDistinctRows = table.numDistinctRows();
91+
int oldDistinctRows = table.numberOfDistinctRows();
9192
doRefineHypothesis(ceQuery);
92-
assert (table.numDistinctRows() > oldDistinctRows);
93+
assert (table.numberOfDistinctRows() > oldDistinctRows);
9394
return true;
9495
}
9596

@@ -141,7 +142,7 @@ protected boolean completeConsistentTable(List<List<Row<I>>> unclosed, boolean c
141142
}
142143

143144
if (checkConsistency) {
144-
Inconsistency<I, D> incons;
145+
Inconsistency<I> incons;
145146

146147
do {
147148
incons = table.findInconsistency();
@@ -185,19 +186,16 @@ protected List<Row<I>> selectClosingRows(List<List<Row<I>>> unclosed) {
185186
*
186187
* @return the suffix to add in order to fix the inconsistency
187188
*/
188-
protected Word<I> analyzeInconsistency(Inconsistency<I, D> incons) {
189-
int inputIdx = incons.getInputIndex();
189+
protected Word<I> analyzeInconsistency(Inconsistency<I> incons) {
190+
int inputIdx = alphabet.getSymbolIndex(incons.getSymbol());
190191

191192
Row<I> succRow1 = incons.getFirstRow().getSuccessor(inputIdx);
192193
Row<I> succRow2 = incons.getSecondRow().getSuccessor(inputIdx);
193194

194-
int numSuffixes = table.numSuffixes();
195-
196-
List<D> contents1 = table.rowContents(succRow1);
197-
List<D> contents2 = table.rowContents(succRow2);
195+
int numSuffixes = table.getSuffixes().size();
198196

199197
for (int i = 0; i < numSuffixes; i++) {
200-
D val1 = contents1.get(i), val2 = contents2.get(i);
198+
D val1 = table.cellContents(succRow1, i), val2 = table.cellContents(succRow2, i);
201199
if (!Objects.equals(val1, val2)) {
202200
I sym = alphabet.getSymbol(inputIdx);
203201
Word<I> suffix = table.getSuffixes().get(i);
@@ -223,8 +221,8 @@ public boolean addGlobalSuffixes(Collection<? extends Word<I>> newGlobalSuffixes
223221
}
224222

225223
@Override
226-
public de.learnlib.datastructure.observationtable.ObservationTable<I, D> getObservationTable() {
227-
return table.asStandardTable();
224+
public ObservationTable<I, D> getObservationTable() {
225+
return table;
228226
}
229227

230228
@Override

algorithms/active/lstar/src/main/java/de/learnlib/algorithms/lstar/AbstractLStarState.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
import java.io.Serializable;
1919

20-
import de.learnlib.algorithms.lstar.table.ObservationTable;
20+
import de.learnlib.datastructure.observationtable.GenericObservationTable;
2121

2222
/**
2323
* Class that contains all data that represent the internal state of the {@link AbstractLStar} learner.
@@ -31,13 +31,13 @@
3131
*/
3232
public abstract class AbstractLStarState<I, D> implements Serializable {
3333

34-
private final ObservationTable<I, D> observationTable;
34+
private final GenericObservationTable<I, D> observationTable;
3535

36-
public AbstractLStarState(final ObservationTable<I, D> observationTable) {
36+
public AbstractLStarState(final GenericObservationTable<I, D> observationTable) {
3737
this.observationTable = observationTable;
3838
}
3939

40-
ObservationTable<I, D> getObservationTable() {
40+
GenericObservationTable<I, D> getObservationTable() {
4141
return observationTable;
4242
}
4343
}

algorithms/active/lstar/src/main/java/de/learnlib/algorithms/lstar/AutomatonLStarState.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import java.util.List;
1919

2020
import de.learnlib.algorithms.lstar.AbstractAutomatonLStar.StateInfo;
21-
import de.learnlib.algorithms.lstar.table.ObservationTable;
21+
import de.learnlib.datastructure.observationtable.GenericObservationTable;
2222

2323
/**
2424
* Class that contains all data that represent the internal state of the {@link AbstractAutomatonLStar} learner and its
@@ -38,9 +38,9 @@
3838
public class AutomatonLStarState<I, D, AI, S> extends AbstractLStarState<I, D> {
3939

4040
private final AI hypothesis;
41-
private final List<AbstractAutomatonLStar.StateInfo<S, I>> stateInfos;
41+
private final List<StateInfo<S, I>> stateInfos;
4242

43-
public AutomatonLStarState(final ObservationTable<I, D> observationTable,
43+
public AutomatonLStarState(final GenericObservationTable<I, D> observationTable,
4444
final AI hypothesis,
4545
final List<StateInfo<S, I>> stateInfos) {
4646
super(observationTable);

algorithms/active/lstar/src/main/java/de/learnlib/algorithms/lstar/ce/ObservationTableCEXHandler.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@
1717

1818
import java.util.List;
1919

20-
import de.learnlib.algorithms.lstar.table.ObservationTable;
21-
import de.learnlib.algorithms.lstar.table.Row;
2220
import de.learnlib.api.oracle.MembershipOracle;
2321
import de.learnlib.api.query.DefaultQuery;
22+
import de.learnlib.datastructure.observationtable.MutableObservationTable;
23+
import de.learnlib.datastructure.observationtable.Row;
2424
import net.automatalib.automata.concepts.SuffixOutput;
2525

2626
public interface ObservationTableCEXHandler<I, D> {
2727

2828
<RI extends I, RD extends D> List<List<Row<RI>>> handleCounterexample(DefaultQuery<RI, RD> ceQuery,
29-
ObservationTable<RI, RD> table,
29+
MutableObservationTable<RI, RD> table,
3030
SuffixOutput<RI, RD> hypOutput,
3131
MembershipOracle<RI, RD> oracle);
3232

0 commit comments

Comments
 (0)