-
Notifications
You must be signed in to change notification settings - Fork 34
Fat Interfaces
Unlike in many other APIs, the AutomataLib interfaces were chosen to be rather "fat". For example, the DeterministicTransitionSystem
(source, javadoc) interface declares (among others) the following three methods:
-
T getTransition(S state, I input)
, retrieving the transition (if existent) for a given input -
S getSuccessor(T transition)
, retrieving the successor state from an existing transition -
S getSuccessor(S state, I input)
, retrieving the successor state (if existent) for a given input
It is pretty obvious that the last of the three methods is redundant, from a strict perspective. It could, for example, be realized as follows:
S getSuccessor(S state, I input) {
T transition = getTransition(state, input);
return (transition != null) ? getSuccessor(transition) : null;
}
Removing this method would save a few lines in DeterministicTransitionSystem
implementations. However, there are two reasons why we decided against that.
The default implementation should always work (provided that the other methods are correctly implemented), but might be unnecessary complicated for some cases. Consider the case of a DeterministicAcceptorTS
(source, javadoc): in an acceptor, a transition is fully characterized by its target state. The transition type parameter T
therefore is bound to be the same type as S
, as the difference between a transition and its target state disappears. The above method could therefore be optimized:
S getSuccessor(S state, I input) {
return getTransition(state, input); // getTransition(S,I) actually returns S!
}
We now turned a 2-line-method into a one-liner, which is not very impressive. However, one can think of arbitrarily more complex cases. Even though maximizing efficiency was not a [design goal](Design Goals) of AutomataLib, it should still allow such optimizations.
One of the main [design goals](Design Goals) of AutomataLib is to provide a very precise mapping between abstract (mathematical) concepts and Java classes and interfaces. This can only be accomplished by excessive use of multiple interface implementation. The interface DeterministicTransitionSystem
actually extends SimpleDTS
, which provides an abstraction on a level that hides transitions, i.e., only in terms of input symbols and succesor states. The getSuccessor(S, I)
is in fact declared in the SimpleDTS
interface, so we can get rid of it only by removing the extension of SimpleDTS
. This, on the other hand, would be a conceptual violation, as the latter is an abstraction of DeterministicTransitionSystem
.