
de.learnlib.algorithms.ttt.base.AbstractTTTHypothesis Maven / Gradle / Ivy
/* Copyright (C) 2013-2019 TU Dortmund
* This file is part of LearnLib, http://www.learnlib.de/.
*
* 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 de.learnlib.algorithms.ttt.base;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import net.automatalib.SupportsGrowingAlphabet;
import net.automatalib.automata.DeterministicAutomaton;
import net.automatalib.automata.FiniteAlphabetAutomaton;
import net.automatalib.automata.fsa.DFA;
import net.automatalib.graphs.Graph;
import net.automatalib.visualization.DefaultVisualizationHelper;
import net.automatalib.visualization.VisualizationHelper;
import net.automatalib.words.Alphabet;
import net.automatalib.words.GrowingAlphabet;
import net.automatalib.words.impl.Alphabets;
/**
* Hypothesis DFA for the {@link AbstractTTTLearner TTT algorithm}.
*
* @param
* input symbol type
*
* @author Malte Isberner
*/
public abstract class AbstractTTTHypothesis implements DeterministicAutomaton, I, T>,
FiniteAlphabetAutomaton, I, T>,
DeterministicAutomaton.FullIntAbstraction,
SupportsGrowingAlphabet,
Serializable {
protected final List> states = new ArrayList<>();
protected transient Alphabet alphabet;
private int alphabetSize;
private TTTState initialState;
/**
* Constructor.
*
* @param alphabet
* the input alphabet
*/
public AbstractTTTHypothesis(Alphabet alphabet) {
this.alphabet = alphabet;
this.alphabetSize = this.alphabet.size();
}
@Override
public TTTState getInitialState() {
return initialState;
}
@Override
public T getTransition(int stateId, int symIdx) {
TTTState state = states.get(stateId);
TTTTransition trans = getInternalTransition(state, symIdx);
return mapTransition(trans);
}
@Override
public T getTransition(TTTState state, I input) {
TTTTransition trans = getInternalTransition(state, input);
return trans == null ? null : mapTransition(trans);
}
/**
* Retrieves the internal transition (i.e., the {@link TTTTransition} object) for a given state and input.
* This method is required since the {@link DFA} interface requires the return value of {@link
* #getTransition(TTTState, Object)} to refer to the successor state directly.
*
* @param state
* the source state
* @param input
* the input symbol triggering the transition
*
* @return the transition object
*/
public TTTTransition getInternalTransition(TTTState state, I input) {
int inputIdx = alphabet.getSymbolIndex(input);
return getInternalTransition(state, inputIdx);
}
public TTTTransition getInternalTransition(TTTState state, int input) {
return state.getTransition(input);
}
protected abstract T mapTransition(TTTTransition internalTransition);
/**
* Initializes the automaton, adding an initial state. Whether or not the initial state is accepting needs to be
* known at this point.
*
* @return the initial state of this newly initialized automaton
*/
public TTTState initialize() {
assert !isInitialized();
initialState = createState(null);
return initialState;
}
/**
* Checks whether this automaton was initialized (i.e., {@link #initialize()} has been called).
*
* @return {@code true} if this automaton was initialized, {@code false} otherwise.
*/
public boolean isInitialized() {
return (initialState != null);
}
public TTTState createState(TTTTransition parent) {
TTTState state = newState(alphabet.size(), parent, states.size());
states.add(state);
if (parent != null) {
parent.makeTree(state);
}
return state;
}
protected TTTState newState(int alphabetSize, TTTTransition parent, int id) {
return new TTTState<>(alphabetSize, parent, id);
}
@Override
public Alphabet getInputAlphabet() {
return alphabet;
}
@Override
public GraphView graphView() {
return new GraphView();
}
@Override
public int getIntInitialState() {
return 0;
}
@Override
public int numInputs() {
return alphabet.size();
}
@Override
public int getIntSuccessor(T trans) {
return getSuccessor(trans).id;
}
@Override
public DeterministicAutomaton.FullIntAbstraction fullIntAbstraction(Alphabet alphabet) {
if (alphabet == this.alphabet) {
return this;
}
return DeterministicAutomaton.super.fullIntAbstraction(alphabet);
}
@Override
public void addAlphabetSymbol(I symbol) {
final GrowingAlphabet growingAlphabet = Alphabets.toGrowingAlphabetOrThrowException(this.alphabet);
if (!growingAlphabet.containsSymbol(symbol)) {
growingAlphabet.addSymbol(symbol);
}
final int newAlphabetSize = growingAlphabet.size();
if (alphabetSize < newAlphabetSize) {
for (final TTTState s : this.getStates()) {
s.ensureInputCapacity(newAlphabetSize);
}
alphabetSize = newAlphabetSize;
}
}
@Override
public Collection> getStates() {
return Collections.unmodifiableList(states);
}
@Override
public int size() {
return states.size();
}
void setAlphabet(Alphabet alphabet) {
this.alphabet = alphabet;
}
public static final class TTTEdge {
public final TTTTransition transition;
public final TTTState target;
public TTTEdge(TTTTransition transition, TTTState target) {
this.transition = transition;
this.target = target;
}
}
public class GraphView implements Graph, TTTEdge> {
@Override
public Collection> getNodes() {
return states;
}
@Override
public Collection> getOutgoingEdges(TTTState node) {
List> result = new ArrayList<>();
for (TTTTransition trans : node.getTransitions()) {
for (TTTState target : trans.getDTTarget().subtreeStates()) {
result.add(new TTTEdge<>(trans, target));
}
}
return result;
}
@Override
public TTTState getTarget(TTTEdge edge) {
return edge.target;
}
@Override
public VisualizationHelper, TTTEdge> getVisualizationHelper() {
return new DefaultVisualizationHelper, TTTEdge>() {
@Override
public boolean getEdgeProperties(TTTState src,
TTTEdge edge,
TTTState tgt,
Map properties) {
properties.put(EdgeAttrs.LABEL, String.valueOf(edge.transition.getInput()));
if (edge.transition.isTree()) {
properties.put(EdgeAttrs.STYLE, EdgeStyles.BOLD);
} else if (edge.transition.getDTTarget().isInner()) {
properties.put(EdgeAttrs.STYLE, EdgeStyles.DOTTED);
}
return true;
}
};
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy