Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
* The `OTUtils` class no longer provides the `displayHTMLInBrowser` methods in order to not depend on `java.desktop`. If you relied on this functionality, use the `writeHTMLToFile` methods instead and call `Desktop.getDesktop().open(file.toURI())` yourself.
* The classes in the `learnlib-learning-examples` artifact have their package renamed to `de.learnlib.testsupport.example`.
* Some other refactorings include:
* The `AbstractVisualizationTest` has been refactored into the `VisualizationUtils` factory.
* The `learnlib-datastructure-ot`, `learnlib-datastructure-dt`, `learnlib-datastructure-list`, and `learnlib-datastructure-pta` artifacts have been merged into a new `learnlib-datastructures` artifact.
* The `learnlib-oml` artifact (including its packages and class names) has been renamed to `learnlib-lambda`.
* Various counters (especially `*Counter*SUL`s) have been streamlined. In most cases there now exists a single counter that tracks multiple properties.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,15 @@ public boolean refineHypothesis(DefaultQuery<CI, D> query) {
final D outOld = oracle.answerQuery(testOld);
final D outNew = oracle.answerQuery(testNew);

if (!Objects.equals(outOld, outNew)) { // add new abstraction
if (Objects.equals(outOld, outNew)) {
prefix = prefix.append(r);
wb.append(r);
} else { // add new abstraction
final AI newA = tree.splitLeaf(r, cur, prefix, suffix, outOld);
abs.addSymbol(newA);
rep.addSymbol(cur);
learner.addAlphabetSymbol(cur);
return true;
} else {
prefix = prefix.append(r);
wb.append(r);
}
}

Expand Down Expand Up @@ -182,8 +182,8 @@ public L getLearner() {
return this.learner;
}

protected <S1, S2, SP, TP> void copyAbstract(UniversalDeterministicAutomaton<S1, CI, ?, SP, TP> src,
MutableDeterministic<S2, AI, ?, SP, TP> tgt) {
protected <S1, S2, T, SP, TP> void copyAbstract(UniversalDeterministicAutomaton<S1, CI, T, SP, TP> src,
MutableDeterministic<S2, AI, ?, SP, TP> tgt) {
// states
final Map<S2, S1> states = new HashMap<>();
final Map<S1, S2> statesRev = new HashMap<>();
Expand All @@ -200,12 +200,15 @@ protected <S1, S2, SP, TP> void copyAbstract(UniversalDeterministicAutomaton<S1,
// transitions
for (Entry<S2, S1> e : states.entrySet()) {
for (CI r : rep) {
final AbstractAbstractionTree<AI, CI, D> tree = getTreeForRepresentative(r);
final AI a = tree.getAbstractSymbol(r);
tgt.setTransition(e.getKey(),
a,
statesRev.get(src.getSuccessor(e.getValue(), r)),
src.getTransitionProperty(e.getValue(), r));
final T trans = src.getTransition(e.getValue(), r);
if (trans != null) {
final AbstractAbstractionTree<AI, CI, D> tree = getTreeForRepresentative(r);
final AI a = tree.getAbstractSymbol(r);
tgt.setTransition(e.getKey(),
a,
statesRev.get(src.getSuccessor(trans)),
src.getTransitionProperty(trans));
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion algorithms/active/aaar/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
requires net.automatalib.common.util;
requires net.automatalib.core;

// make non-static once https://github.com/typetools/checker-framework/issues/4559 is implemented
// annotations are 'provided'-scoped and do not need to be loaded at runtime
requires static org.checkerframework.checker.qual;

exports de.learnlib.algorithm.aaar;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,11 @@ private Optional<ADTNode<S, I, O>> compute(Map<S, S> mapping) {
final O nextOutput = automaton.getOutput(current, i);

final Map<S, S> nextMapping;
if (!successors.containsKey(nextOutput)) {
if (successors.containsKey(nextOutput)) {
nextMapping = successors.get(nextOutput);
} else {
nextMapping = new HashMap<>();
successors.put(nextOutput, nextMapping);
} else {
nextMapping = successors.get(nextOutput);
}

// invalid input
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,9 @@ public boolean refineHypothesis(DefaultQuery<I, Word<O>> ce) {
final DefaultQuery<I, Word<O>> currentCE = this.openCounterExamples.poll();
this.allCounterExamples.add(currentCE);

while (this.refineHypothesisInternal(currentCE)) {}
while (this.refineHypothesisInternal(currentCE)) {
// refine exhaustively
}
}

// subtree replacements may reactivate old CEs
Expand Down
2 changes: 1 addition & 1 deletion algorithms/active/adt/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
requires net.automatalib.util;
requires org.slf4j;

// annotations are 'provided'-scoped and do not need to be loaded at runtime
requires static de.learnlib.tooling.annotation;
// make non-static once https://github.com/typetools/checker-framework/issues/4559 is implemented
requires static org.checkerframework.checker.qual;

exports de.learnlib.algorithm.adt.ads;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,36 @@
package de.learnlib.algorithm.adt.learner;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;

import de.learnlib.oracle.membership.SULAdaptiveOracle;
import de.learnlib.sul.SUL;
import de.learnlib.testsupport.AbstractVisualizationTest;
import de.learnlib.testsupport.VisualizationUtils;
import de.learnlib.testsupport.example.mealy.ExampleCoffeeMachine.Input;
import net.automatalib.alphabet.Alphabet;
import net.automatalib.common.util.IOUtil;
import net.automatalib.serialization.dot.GraphDOT;
import org.checkerframework.checker.initialization.qual.UnderInitialization;
import org.testng.Assert;
import org.testng.annotations.Test;

public class ADTVisualizationTest extends AbstractVisualizationTest<ADTLearner<Input, String>> {
public class ADTVisualizationTest {

@Override
protected ADTLearner<Input, String> getLearnerBuilder(@UnderInitialization ADTVisualizationTest this,
Alphabet<Input> alphabet,
SUL<Input, String> sul) {
return new ADTLearnerBuilder<Input, String>().withAlphabet(alphabet)
.withOracle(new SULAdaptiveOracle<>(sul))
.create();
private final ADTLearner<Input, String> learner;

public ADTVisualizationTest() {
this.learner =
VisualizationUtils.runExperiment((alphabet, sul) -> new ADTLearnerBuilder<Input, String>().withAlphabet(
alphabet).withOracle(new SULAdaptiveOracle<>(sul)).create());
}

@Test
public void testVisualization() throws IOException {
final String expectedADT = resourceAsString("/adt.dot");
try (InputStream is = ADTVisualizationTest.class.getResourceAsStream("/adt.dot")) {
final String expectedADT = IOUtil.toString(IOUtil.asBufferedUTF8Reader(is));
final StringWriter actualADT = new StringWriter();

final StringWriter actualADT = new StringWriter();
GraphDOT.write(super.learner.getADT().getRoot(), actualADT);
GraphDOT.write(this.learner.getADT().getRoot(), actualADT);

Assert.assertEquals(actualADT.toString(), expectedADT);
Assert.assertEquals(actualADT.toString(), expectedADT);
}
}
}
2 changes: 1 addition & 1 deletion algorithms/active/dhc/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
requires net.automatalib.common.util;
requires net.automatalib.core;

// annotations are 'provided'-scoped and do not need to be loaded at runtime
requires static de.learnlib.tooling.annotation;
// make non-static once https://github.com/typetools/checker-framework/issues/4559 is implemented
requires static org.checkerframework.checker.qual;

exports de.learnlib.algorithm.dhc.mealy;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public void testMealyDHCGrid() {
dhc.startLearning();
MealyMachine<?, Character, ?, Integer> hypo = dhc.getHypothesisModel();

Assert.assertEquals(hypo.size(), (xsize * ysize), "Mismatch in size of learned hypothesis");
Assert.assertEquals(hypo.size(), xsize * ysize, "Mismatch in size of learned hypothesis");

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ public boolean refineHypothesis(DefaultQuery<I, Boolean> ceQuery) {
return false;
}
if (repeatedCounterexampleEvaluation) {
while (refineHypothesisSingle(input, output)) {}
while (refineHypothesisSingle(input, output)) {
// refine exhaustively
}
}
return true;
}
Expand Down Expand Up @@ -188,7 +190,7 @@ private void updateTransitions(List<Long> transList,
long encodedTrans = transList.get(i);

int sourceState = (int) (encodedTrans >> Integer.SIZE);
int transIdx = (int) (encodedTrans);
int transIdx = (int) encodedTrans;

StateInfo<I, Boolean> sourceInfo = stateInfos.get(sourceState);
I symbol = alphabet.getSymbol(transIdx);
Expand All @@ -202,7 +204,7 @@ private void updateTransitions(List<Long> transList,
long encodedTrans = transList.get(i);

int sourceState = (int) (encodedTrans >> Integer.SIZE);
int transIdx = (int) (encodedTrans);
int transIdx = (int) encodedTrans;

setTransition(sourceState, transIdx, succs.get(i));
}
Expand Down Expand Up @@ -309,8 +311,8 @@ public void addAlphabetSymbol(I symbol) {

// check if we already have information about the symbol (then the transition is defined) so we don't post
// redundant queries
if (this.hypothesis.getInitialState() != null &&
this.hypothesis.getSuccessor(this.hypothesis.getInitialState(), symbol) == null) {
final Integer init = this.hypothesis.getInitialState();
if (init != null && this.hypothesis.getSuccessor(init, symbol) == null) {
// use new list to prevent concurrent modification exception
final List<Word<I>> transAs = new ArrayList<>(this.stateInfos.size());
for (StateInfo<I, Boolean> si : this.stateInfos) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ public boolean refineHypothesis(DefaultQuery<I, Word<O>> ceQuery) {
return false;
}
if (repeatedCounterexampleEvaluation) {
while (refineHypothesisSingle(input, output)) {}
while (refineHypothesisSingle(input, output)) {
// refine exhaustively
}
}
return true;
}
Expand Down Expand Up @@ -200,7 +202,7 @@ private void updateTransitions(List<Long> transList,
long encodedTrans = transList.get(i);

int sourceState = (int) (encodedTrans >> Integer.SIZE);
int transIdx = (int) (encodedTrans);
int transIdx = (int) encodedTrans;

StateInfo<I, Word<O>> sourceInfo = stateInfos.get(sourceState);
I symbol = alphabet.getSymbol(transIdx);
Expand All @@ -214,7 +216,7 @@ private void updateTransitions(List<Long> transList,
long encodedTrans = transList.get(i);

int sourceState = (int) (encodedTrans >> Integer.SIZE);
int transIdx = (int) (encodedTrans);
int transIdx = (int) encodedTrans;

CompactTransition<O> trans = hypothesis.getTransition(sourceState, transIdx);
assert trans != null;
Expand Down Expand Up @@ -323,8 +325,8 @@ public void addAlphabetSymbol(I symbol) {

// check if we already have information about the symbol (then the transition is defined) so we don't post
// redundant queries
if (this.hypothesis.getInitialState() != null &&
this.hypothesis.getSuccessor(this.hypothesis.getInitialState(), symbol) == null) {
final Integer init = this.hypothesis.getInitialState();
if (init != null && this.hypothesis.getSuccessor(init, symbol) == null) {
// use new list to prevent concurrent modification exception
final List<Word<I>> transAs = new ArrayList<>(this.stateInfos.size());
final List<DefaultQuery<I, Word<O>>> outputQueries = new ArrayList<>(this.stateInfos.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
requires net.automatalib.core;
requires org.slf4j;

// annotations are 'provided'-scoped and do not need to be loaded at runtime
requires static de.learnlib.tooling.annotation;
// make non-static once https://github.com/typetools/checker-framework/issues/4559 is implemented
requires static org.checkerframework.checker.qual;

exports de.learnlib.algorithm.kv;
Expand Down
2 changes: 1 addition & 1 deletion algorithms/active/lambda/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
requires net.automatalib.common.util;
requires net.automatalib.core;

// make non-static once https://github.com/typetools/checker-framework/issues/4559 is implemented
// annotations are 'provided'-scoped and do not need to be loaded at runtime
requires static org.checkerframework.checker.qual;

exports de.learnlib.algorithm.lambda.lstar;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
*/
package de.learnlib.algorithm.lstar;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import de.learnlib.Resumable;
import de.learnlib.datastructure.observationtable.ObservationTable;
import de.learnlib.datastructure.observationtable.Row;
Expand All @@ -28,6 +24,7 @@
import net.automatalib.alphabet.Alphabet;
import net.automatalib.alphabet.SupportsGrowingAlphabet;
import net.automatalib.automaton.MutableDeterministic;
import net.automatalib.common.util.array.ResizingArrayStorage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -54,7 +51,7 @@ public abstract class AbstractAutomatonLStar<A, I, D, S, T, SP, TP, AI extends M
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractAutomatonLStar.class);

protected AI internalHyp;
protected List<StateInfo<S, I>> stateInfos = new ArrayList<>();
protected ResizingArrayStorage<StateInfo<S, I>> stateInfos = new ResizingArrayStorage<>(StateInfo.class);

/**
* Constructor.
Expand Down Expand Up @@ -83,40 +80,32 @@ public final void startLearning() {
* #stateProperty(ObservationTable, Row)} and {@link #transitionProperty(ObservationTable, Row, int)} methods are
* used to derive the respective properties.
*/
@SuppressWarnings("argument.type.incompatible")
// all added nulls to stateInfos will be correctly set to non-null values
protected void updateInternalHypothesis() {
if (!table.isInitialized()) {
throw new IllegalStateException("Cannot update internal hypothesis: not initialized");
}

int oldStates = internalHyp.size();
int numDistinct = table.numberOfDistinctRows();

int newStates = numDistinct - oldStates;

stateInfos.addAll(Collections.nCopies(newStates, null));
stateInfos.ensureCapacity(numDistinct);

// TODO: Is there a quicker way than iterating over *all* rows?
// FIRST PASS: Create new hypothesis states
for (Row<I> sp : table.getShortPrefixRows()) {
int id = sp.getRowContentId();
StateInfo<S, I> info = stateInfos.get(id);
if (info != null) {
// State from previous hypothesis, property might have changed
if (info.getRow() == sp) {
internalHyp.setStateProperty(info.getState(), stateProperty(table, sp));
}
continue;
}
StateInfo<S, I> info = stateInfos.array[id];

S state = createState(id == 0, sp);
if (info == null) {
S state = createState(id == 0, sp);
stateInfos.array[id] = new StateInfo<>(sp, state);
} else if (info.getRow() == sp) { // State from previous hypothesis, property might have changed
internalHyp.setStateProperty(info.getState(), stateProperty(table, sp));
}

stateInfos.set(id, new StateInfo<>(sp, state));
}

// SECOND PASS: Create hypothesis transitions
for (StateInfo<S, I> info : stateInfos) {
for (int r = 0; r < numDistinct; r++) {
StateInfo<S, I> info = stateInfos.array[r];
Row<I> sp = info.getRow();
S state = info.getState();

Expand All @@ -126,7 +115,7 @@ protected void updateInternalHypothesis() {
Row<I> succ = sp.getSuccessor(i);
int succId = succ.getRowContentId();

S succState = stateInfos.get(succId).getState();
S succState = stateInfos.array[succId].getState();

setTransition(state, input, succState, sp, i);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,7 @@ public Collection<Word<I>> getGlobalSuffixes() {
@Override
public boolean addGlobalSuffixes(Collection<? extends Word<I>> newGlobalSuffixes) {
List<List<Row<I>>> unclosed = table.addSuffixes(newGlobalSuffixes, oracle);
if (unclosed.isEmpty()) {
return false;
}
return completeConsistentTable(unclosed, false);
return !unclosed.isEmpty() && completeConsistentTable(unclosed, false);
}

@Override
Expand Down
Loading
Loading