From ae3c25ff0cb81489db473e495ce9bf5dca215b7e Mon Sep 17 00:00:00 2001 From: Markus Frohme Date: Wed, 10 Jun 2026 19:03:19 +0200 Subject: [PATCH 1/8] initial experimentation --- api/src/main/java/module-info.java | 1 + .../automaton/DeterministicAutomaton.java | 97 +-------- .../automaton/MutableDeterministic.java | 84 +------- .../automaton/ShrinkableDeterministic.java | 36 ---- .../automaton/UniversalAutomaton.java | 3 +- .../UniversalDeterministicAutomaton.java | 95 +-------- .../UniversalFiniteAlphabetAutomaton.java | 3 +- .../DeterministicAbstractions.java | 108 +++++++++- ... => MutableDeterministicAbstractions.java} | 96 ++++++++- .../SimpleDeterministicAbstractions.java | 111 +++++++++-- .../UniversalDeterministicAbstractions.java | 102 +++++++++- .../automatalib/automaton/concept/FinSem.java | 3 + .../Shrinkable.java} | 24 +-- .../net/automatalib/automaton/fsa/DFA.java | 8 + .../automaton/fsa/FiniteStateAcceptor.java | 12 +- .../net/automatalib/automaton/mmlt/MMLT.java | 10 +- .../automatalib/automaton/procedural/SBA.java | 9 +- .../automatalib/automaton/procedural/SPA.java | 9 +- .../automaton/procedural/SPMM.java | 11 +- .../simple/SimpleDeterministicAutomaton.java | 90 +-------- .../automaton/transducer/MealyMachine.java | 10 +- .../automaton/transducer/MooreMachine.java | 9 +- .../transducer/SubsequentialTransducer.java | 9 +- .../DeterministicFiniteSemantics.java | 40 ++++ .../semantics/DeterministicSemantics.java | 28 +++ .../semantics/FiniteSemantics.java | 37 ++++ .../net/automatalib/semantics/Semantics.java | 26 +++ .../ts/modal/ModalTransitionSystem.java | 8 +- .../automaton/base/AbstractCompact.java | 8 +- .../base/AbstractCompactDeterministic.java | 10 +- .../AbstractCompactSimpleDeterministic.java | 1 + .../automaton/base/AbstractFastMutable.java | 8 +- .../base/AbstractFastMutableDet.java | 4 +- .../impl/CompactTransitionOutput.java | 185 ++++++++++++++++++ .../impl/UniversalCompactDetAutomaton.java | 59 ++++++ .../automaton/mmlt/impl/CompactMMLT.java | 4 +- .../transducer/impl/CompactMealy.java | 140 +------------ ...DeterministicAutomatonAbstractionTest.java | 4 +- .../impl/MutableFullIntAbstractionTest.java | 9 +- .../impl/MutableStateIntAbstractionTest.java | 15 +- .../impl/SimpleAutomatonAbstractionTest.java | 4 +- .../UniversalAutomatonAbstractionTest.java | 4 +- .../impl/DynamicStateMappingTest.java | 5 +- .../java/net/automatalib/example/Example.java | 32 +++ .../automatalib/util/automaton/Automata.java | 64 +++--- .../IncrementalWMethodTestsIterator.java | 3 +- .../KWayStateCoverTestsIterator.java | 3 +- .../KWayTransitionCoverTestsIterator.java | 9 +- .../ProceduralWMethodTestsIterator.java | 4 +- .../conformance/WMethodTestsIterator.java | 5 +- .../conformance/WpMethodTestsIterator.java | 20 +- .../automaton/copy/PlainAutomatonCopy.java | 14 +- .../util/automaton/cover/Covers.java | 101 +++++----- .../cover/IncrementalStateCoverIterator.java | 4 +- .../automaton/equivalence/Bisimulation.java | 13 +- .../equivalence/CharacterizingSets.java | 48 +++-- .../DeterministicEquivalenceTest.java | 9 +- .../NearLinearEquivalenceTest.java | 57 ++++-- .../minimizer/HopcroftMinimizer.java | 55 +++--- .../automaton/procedural/ProceduralUtil.java | 34 ++-- .../random/RandomICAutomatonGenerator.java | 3 +- .../AutomatonInitialPartitioning.java | 10 +- .../HopcroftExtractors.java | 13 +- .../HopcroftInitializers.java | 20 +- .../partitionrefinement/StateSignature.java | 7 +- .../util/automaton/CopyConstructorTest.java | 8 +- .../WpMethodTestsIteratorTest.java | 10 +- .../copy/AbstractAutomatonCopyTest.java | 13 +- .../equivalence/BisimulationTest.java | 8 +- .../DeterministicEquivalenceTestTest.java | 22 ++- .../NearLinearEquivalenceTestTest.java | 32 +-- .../minimizer/AbstractMinimizationTest.java | 16 +- .../automaton/minimizer/MinimizerTest.java | 5 +- 73 files changed, 1309 insertions(+), 872 deletions(-) delete mode 100644 api/src/main/java/net/automatalib/automaton/ShrinkableDeterministic.java rename api/src/main/java/net/automatalib/automaton/abstraction/{MutableDeterministicAbstraction.java => MutableDeterministicAbstractions.java} (59%) create mode 100644 api/src/main/java/net/automatalib/automaton/concept/FinSem.java rename api/src/main/java/net/automatalib/automaton/{ShrinkableAutomaton.java => concept/Shrinkable.java} (79%) create mode 100644 api/src/main/java/net/automatalib/semantics/DeterministicFiniteSemantics.java create mode 100644 api/src/main/java/net/automatalib/semantics/DeterministicSemantics.java create mode 100644 api/src/main/java/net/automatalib/semantics/FiniteSemantics.java create mode 100644 api/src/main/java/net/automatalib/semantics/Semantics.java create mode 100644 core/src/main/java/net/automatalib/automaton/impl/CompactTransitionOutput.java create mode 100644 core/src/main/java/net/automatalib/automaton/impl/UniversalCompactDetAutomaton.java create mode 100644 examples/src/main/java/net/automatalib/example/Example.java diff --git a/api/src/main/java/module-info.java b/api/src/main/java/module-info.java index 116a88eed..3518088f0 100644 --- a/api/src/main/java/module-info.java +++ b/api/src/main/java/module-info.java @@ -62,6 +62,7 @@ exports net.automatalib.graph.visualization; exports net.automatalib.modelchecking; exports net.automatalib.serialization; + exports net.automatalib.semantics; exports net.automatalib.symbol.time; exports net.automatalib.ts; exports net.automatalib.ts.acceptor; diff --git a/api/src/main/java/net/automatalib/automaton/DeterministicAutomaton.java b/api/src/main/java/net/automatalib/automaton/DeterministicAutomaton.java index 6c5c8cdef..081e2647e 100644 --- a/api/src/main/java/net/automatalib/automaton/DeterministicAutomaton.java +++ b/api/src/main/java/net/automatalib/automaton/DeterministicAutomaton.java @@ -18,10 +18,12 @@ import java.util.function.IntFunction; import net.automatalib.alphabet.Alphabet; -import net.automatalib.automaton.abstraction.DeterministicAbstractions; +import net.automatalib.automaton.abstraction.DeterministicAbstractions.FullIntAbstraction; +import net.automatalib.automaton.abstraction.DeterministicAbstractions.FullIntAbstractionImpl; +import net.automatalib.automaton.abstraction.DeterministicAbstractions.StateIntAbstraction; +import net.automatalib.automaton.abstraction.DeterministicAbstractions.StateIntAbstractionImpl; import net.automatalib.automaton.simple.SimpleDeterministicAutomaton; import net.automatalib.ts.DeterministicTransitionSystem; -import org.checkerframework.checker.nullness.qual.Nullable; /** * Basic interface for a deterministic automaton. A deterministic automaton is a {@link DeterministicTransitionSystem} @@ -44,99 +46,12 @@ default FullIntAbstraction fullIntAbstraction(Alphabet alphabet) { @Override default FullIntAbstraction fullIntAbstraction(int numInputs, IntFunction symMapping) { - return new DeterministicAbstractions.FullIntAbstraction<>(stateIntAbstraction(), numInputs, symMapping); + return new FullIntAbstractionImpl<>(stateIntAbstraction(), numInputs, symMapping); } @Override default StateIntAbstraction stateIntAbstraction() { - return new DeterministicAbstractions.StateIntAbstraction<>(this); + return new StateIntAbstractionImpl<>(this); } - /** - * Base interface for {@link SimpleDeterministicAutomaton.IntAbstraction integer abstractions} of a {@link - * DeterministicAutomaton}. - * - * @param - * transition type - */ - interface IntAbstraction extends SimpleDeterministicAutomaton.IntAbstraction { - - /** - * Retrieves the (abstracted) successor of a transition object. - * - * @param transition - * the transition object - * - * @return the integer representing the successor of the given transition - */ - int getIntSuccessor(T transition); - } - - /** - * Interface for {@link SimpleDeterministicAutomaton.StateIntAbstraction state integer abstractions} of a {@link - * DeterministicAutomaton}. - * - * @param - * input symbol type - * @param - * transition type - */ - interface StateIntAbstraction extends IntAbstraction, SimpleDeterministicAutomaton.StateIntAbstraction { - - @Override - default int getSuccessor(int state, I input) { - T trans = getTransition(state, input); - if (trans == null) { - return INVALID_STATE; - } - return getIntSuccessor(trans); - } - - /** - * Retrieves the outgoing transition for an (abstracted) source state and input symbol, or returns {@code null} - * if the automaton has no transition for this state and input. - * - * @param state - * the integer representing the source state - * @param input - * the input symbol - * - * @return the outgoing transition, or {@code null} - */ - @Nullable T getTransition(int state, I input); - - } - - /** - * Interface for {@link SimpleDeterministicAutomaton.FullIntAbstraction full integer abstractions} of a {@link - * DeterministicAutomaton}. - * - * @param - * transition type - */ - interface FullIntAbstraction extends IntAbstraction, SimpleDeterministicAutomaton.FullIntAbstraction { - - @Override - default int getSuccessor(int state, int input) { - T trans = getTransition(state, input); - if (trans == null) { - return INVALID_STATE; - } - return getIntSuccessor(trans); - } - - /** - * Retrieves the outgoing transition for an (abstracted) source state and (abstracted) input symbol, or returns - * {@code null} if the automaton has no transition for this state and input. - * - * @param state - * the integer representing the source state - * @param input - * the integer representing the input symbol - * - * @return the outgoing transition, or {@code null} - */ - @Nullable T getTransition(int state, int input); - - } } diff --git a/api/src/main/java/net/automatalib/automaton/MutableDeterministic.java b/api/src/main/java/net/automatalib/automaton/MutableDeterministic.java index 53b9e1fdd..8b9cf95d7 100644 --- a/api/src/main/java/net/automatalib/automaton/MutableDeterministic.java +++ b/api/src/main/java/net/automatalib/automaton/MutableDeterministic.java @@ -20,7 +20,10 @@ import java.util.function.IntFunction; import net.automatalib.alphabet.Alphabet; -import net.automatalib.automaton.abstraction.MutableDeterministicAbstraction; +import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions.FullIntAbstraction; +import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions.FullIntAbstractionImpl; +import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions.StateIntAbstraction; +import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions.StateIntAbstractionImpl; import org.checkerframework.checker.nullness.qual.Nullable; /** @@ -148,87 +151,12 @@ default FullIntAbstraction fullIntAbstraction(Alphabet alphabet) { @Override default FullIntAbstraction fullIntAbstraction(int numInputs, IntFunction symMapping) { - return new MutableDeterministicAbstraction.FullIntAbstraction<>(stateIntAbstraction(), numInputs, symMapping); + return new FullIntAbstractionImpl<>(stateIntAbstraction(), numInputs, symMapping); } @Override default StateIntAbstraction stateIntAbstraction() { - return new MutableDeterministicAbstraction.StateIntAbstraction<>(this); + return new StateIntAbstractionImpl<>(this); } - /** - * Base interface for {@link UniversalDeterministicAutomaton.IntAbstraction integer abstractions} of a {@link - * MutableDeterministic}. - * - * @param - * transition type - * @param - * state property type - * @param - * transition property type - */ - interface IntAbstraction extends UniversalDeterministicAutomaton.IntAbstraction { - - void setStateProperty(int state, SP property); - - void setTransitionProperty(T transition, TP property); - - void setInitialState(int state); - - T createTransition(int successor, TP property); - - default int addIntState() { - return addIntState(null); - } - - int addIntState(@Nullable SP property); - - default int addIntInitialState() { - return addIntInitialState(null); - } - - int addIntInitialState(@Nullable SP property); - } - - /** - * Interface for {@link UniversalDeterministicAutomaton.StateIntAbstraction state integer abstractions} of a {@link - * MutableDeterministic}. - * - * @param - * input symbol type - * @param - * transition type - * @param - * state property type - * @param - * transition property type - */ - interface StateIntAbstraction - extends IntAbstraction, UniversalDeterministicAutomaton.StateIntAbstraction { - - void setTransition(int state, I input, @Nullable T transition); - - void setTransition(int state, I input, int successor, TP property); - - } - - /** - * Interface for {@link UniversalDeterministicAutomaton.FullIntAbstraction full integer abstractions} of a {@link - * MutableDeterministic}. - * - * @param - * transition type - * @param - * state property type - * @param - * transition property type - */ - interface FullIntAbstraction - extends IntAbstraction, UniversalDeterministicAutomaton.FullIntAbstraction { - - void setTransition(int state, int input, @Nullable T transition); - - void setTransition(int state, int input, int successor, TP property); - - } } diff --git a/api/src/main/java/net/automatalib/automaton/ShrinkableDeterministic.java b/api/src/main/java/net/automatalib/automaton/ShrinkableDeterministic.java deleted file mode 100644 index 7345f4a33..000000000 --- a/api/src/main/java/net/automatalib/automaton/ShrinkableDeterministic.java +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2013-2026 TU Dortmund University - * This file is part of AutomataLib . - * - * 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 net.automatalib.automaton; - -/** - * A mutable deterministic automaton that also supports destructive operations, i.e., removal of states and - * transitions. - * - * @param - * state class - * @param - * input symbol class - * @param - * transition class - * @param - * state property class - * @param - * transition property class - */ -public interface ShrinkableDeterministic - extends MutableDeterministic, ShrinkableAutomaton { - -} diff --git a/api/src/main/java/net/automatalib/automaton/UniversalAutomaton.java b/api/src/main/java/net/automatalib/automaton/UniversalAutomaton.java index d29c38279..de29f2d61 100644 --- a/api/src/main/java/net/automatalib/automaton/UniversalAutomaton.java +++ b/api/src/main/java/net/automatalib/automaton/UniversalAutomaton.java @@ -18,6 +18,7 @@ import java.util.Collection; import net.automatalib.automaton.graph.TransitionEdge; +import net.automatalib.automaton.graph.TransitionEdge.Property; import net.automatalib.automaton.graph.UniversalAutomatonGraphView; import net.automatalib.graph.UniversalGraph; import net.automatalib.ts.UniversalTransitionSystem; @@ -41,7 +42,7 @@ public interface UniversalAutomaton extends Automaton, UniversalTransitionSystem { @Override - default UniversalGraph, SP, TransitionEdge.Property> transitionGraphView(Collection inputs) { + default UniversalGraph, SP, Property> transitionGraphView(Collection inputs) { return new UniversalAutomatonGraphView<>(this, inputs); } diff --git a/api/src/main/java/net/automatalib/automaton/UniversalDeterministicAutomaton.java b/api/src/main/java/net/automatalib/automaton/UniversalDeterministicAutomaton.java index 76bc8435e..a10c1b669 100644 --- a/api/src/main/java/net/automatalib/automaton/UniversalDeterministicAutomaton.java +++ b/api/src/main/java/net/automatalib/automaton/UniversalDeterministicAutomaton.java @@ -18,9 +18,11 @@ import java.util.function.IntFunction; import net.automatalib.alphabet.Alphabet; -import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions; +import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.FullIntAbstraction; +import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.FullIntAbstractionImpl; +import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.StateIntAbstraction; +import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.StateIntAbstractionImpl; import net.automatalib.ts.UniversalDTS; -import org.checkerframework.checker.nullness.qual.Nullable; /** * A {@link DeterministicAutomaton} with state and transition properties. @@ -48,98 +50,13 @@ default FullIntAbstraction fullIntAbstraction(Alphabet alphabet) { @Override default FullIntAbstraction fullIntAbstraction(int numInputs, IntFunction symMapping) { - return new UniversalDeterministicAbstractions.FullIntAbstraction<>(stateIntAbstraction(), - numInputs, - symMapping); + return new FullIntAbstractionImpl<>(stateIntAbstraction(), numInputs, symMapping); } @Override default StateIntAbstraction stateIntAbstraction() { - return new UniversalDeterministicAbstractions.StateIntAbstraction<>(this); + return new StateIntAbstractionImpl<>(this); } - /** - * Base interface for {@link DeterministicAutomaton.IntAbstraction integer abstractions} of a {@link - * UniversalDeterministicAutomaton}. - * - * @param - * transition type - * @param - * state property type - * @param - * transition property type - */ - interface IntAbstraction extends DeterministicAutomaton.IntAbstraction { - - /** - * Retrieves the state property of a given (abstracted) state. - * - * @param state - * the integer representing the state of which to retrieve the property - * - * @return the property for the given state - */ - SP getStateProperty(int state); - - /** - * Retrieves the transition property of a given transition. - * - * @param transition - * the transition of which to retrieve the property - * - * @return the property for the given transition - */ - TP getTransitionProperty(T transition); - } - - /** - * Interface for {@link DeterministicAutomaton.StateIntAbstraction state integer abstractions} of a {@link - * UniversalDeterministicAutomaton}. - * - * @param - * input symbol type - * @param - * transition type - * @param - * state property type - * @param - * transition property type - */ - interface StateIntAbstraction - extends IntAbstraction, DeterministicAutomaton.StateIntAbstraction { - - default @Nullable TP getTransitionProperty(int state, I input) { - T trans = getTransition(state, input); - if (trans != null) { - return getTransitionProperty(trans); - } - return null; - } - - } - - /** - * Interface for {@link DeterministicAutomaton.FullIntAbstraction full integer abstractions} of a {@link - * UniversalDeterministicAutomaton}. - * - * @param - * transition type - * @param - * state property type - * @param - * transition property type - */ - interface FullIntAbstraction - extends IntAbstraction, DeterministicAutomaton.FullIntAbstraction { - - default @Nullable TP getTransitionProperty(int state, int input) { - T trans = getTransition(state, input); - if (trans != null) { - return getTransitionProperty(trans); - } - return null; - } - - } } diff --git a/api/src/main/java/net/automatalib/automaton/UniversalFiniteAlphabetAutomaton.java b/api/src/main/java/net/automatalib/automaton/UniversalFiniteAlphabetAutomaton.java index 11ef13408..50c613987 100644 --- a/api/src/main/java/net/automatalib/automaton/UniversalFiniteAlphabetAutomaton.java +++ b/api/src/main/java/net/automatalib/automaton/UniversalFiniteAlphabetAutomaton.java @@ -16,13 +16,14 @@ package net.automatalib.automaton; import net.automatalib.automaton.graph.TransitionEdge; +import net.automatalib.automaton.graph.TransitionEdge.Property; import net.automatalib.graph.UniversalGraph; public interface UniversalFiniteAlphabetAutomaton extends UniversalAutomaton, FiniteAlphabetAutomaton { @Override - default UniversalGraph, SP, TransitionEdge.Property> transitionGraphView() { + default UniversalGraph, SP, Property> transitionGraphView() { return transitionGraphView(getInputAlphabet()); } } diff --git a/api/src/main/java/net/automatalib/automaton/abstraction/DeterministicAbstractions.java b/api/src/main/java/net/automatalib/automaton/abstraction/DeterministicAbstractions.java index e3db5ce7c..fca136065 100644 --- a/api/src/main/java/net/automatalib/automaton/abstraction/DeterministicAbstractions.java +++ b/api/src/main/java/net/automatalib/automaton/abstraction/DeterministicAbstractions.java @@ -21,15 +21,106 @@ import org.checkerframework.checker.nullness.qual.Nullable; /** - * Default implementations for {@link DeterministicAutomaton} abstractions. + * Abstractions for {@link DeterministicAutomaton}s. */ public interface DeterministicAbstractions { - class StateIntAbstraction> - extends SimpleDeterministicAbstractions.StateIntAbstraction - implements DeterministicAutomaton.StateIntAbstraction { + /** + * Base interface for {@link SimpleDeterministicAbstractions.IntAbstraction integer abstractions} of a + * {@link DeterministicAutomaton}. + * + * @param + * transition type + */ + interface IntAbstraction extends SimpleDeterministicAbstractions.IntAbstraction { - public StateIntAbstraction(A automaton) { + /** + * Retrieves the (abstracted) successor of a transition object. + * + * @param transition + * the transition object + * + * @return the integer representing the successor of the given transition + */ + int getIntSuccessor(T transition); + } + + /** + * Interface for {@link SimpleDeterministicAbstractions.StateIntAbstraction state integer abstractions} of a + * {@link DeterministicAutomaton}. + * + * @param + * input symbol type + * @param + * transition type + */ + interface StateIntAbstraction + extends IntAbstraction, SimpleDeterministicAbstractions.StateIntAbstraction { + + @Override + default int getSuccessor(int state, I input) { + T trans = getTransition(state, input); + if (trans == null) { + return INVALID_STATE; + } + return getIntSuccessor(trans); + } + + /** + * Retrieves the outgoing transition for an (abstracted) source state and input symbol, or returns {@code null} + * if the automaton has no transition for this state and input. + * + * @param state + * the integer representing the source state + * @param input + * the input symbol + * + * @return the outgoing transition, or {@code null} + */ + @Nullable + T getTransition(int state, I input); + + } + + /** + * Interface for {@link SimpleDeterministicAbstractions.FullIntAbstraction full integer abstractions} of a + * {@link DeterministicAutomaton}. + * + * @param + * transition type + */ + interface FullIntAbstraction extends IntAbstraction, SimpleDeterministicAbstractions.FullIntAbstraction { + + @Override + default int getSuccessor(int state, int input) { + T trans = getTransition(state, input); + if (trans == null) { + return INVALID_STATE; + } + return getIntSuccessor(trans); + } + + /** + * Retrieves the outgoing transition for an (abstracted) source state and (abstracted) input symbol, or returns + * {@code null} if the automaton has no transition for this state and input. + * + * @param state + * the integer representing the source state + * @param input + * the integer representing the input symbol + * + * @return the outgoing transition, or {@code null} + */ + @Nullable + T getTransition(int state, int input); + + } + + class StateIntAbstractionImpl> + extends SimpleDeterministicAbstractions.StateIntAbstractionImpl + implements StateIntAbstraction { + + public StateIntAbstractionImpl(A automaton) { super(automaton); } @@ -44,11 +135,10 @@ public int getIntSuccessor(T transition) { } } - class FullIntAbstraction> - extends SimpleDeterministicAbstractions.FullIntAbstraction - implements DeterministicAutomaton.FullIntAbstraction { + class FullIntAbstractionImpl> + extends SimpleDeterministicAbstractions.FullIntAbstractionImpl implements FullIntAbstraction { - public FullIntAbstraction(A stateAbstraction, int numInputs, IntFunction symMapping) { + public FullIntAbstractionImpl(A stateAbstraction, int numInputs, IntFunction symMapping) { super(stateAbstraction, numInputs, symMapping); } diff --git a/api/src/main/java/net/automatalib/automaton/abstraction/MutableDeterministicAbstraction.java b/api/src/main/java/net/automatalib/automaton/abstraction/MutableDeterministicAbstractions.java similarity index 59% rename from api/src/main/java/net/automatalib/automaton/abstraction/MutableDeterministicAbstraction.java rename to api/src/main/java/net/automatalib/automaton/abstraction/MutableDeterministicAbstractions.java index 1a3103eb2..84834f855 100644 --- a/api/src/main/java/net/automatalib/automaton/abstraction/MutableDeterministicAbstraction.java +++ b/api/src/main/java/net/automatalib/automaton/abstraction/MutableDeterministicAbstractions.java @@ -21,15 +21,91 @@ import org.checkerframework.checker.nullness.qual.Nullable; /** - * Default implementations for {@link MutableDeterministic} abstractions. + * Abstractions for {@link MutableDeterministic}s. */ -public interface MutableDeterministicAbstraction { +public interface MutableDeterministicAbstractions { - class StateIntAbstraction> - extends UniversalDeterministicAbstractions.StateIntAbstraction - implements MutableDeterministic.StateIntAbstraction { + /** + * Base interface for {@link UniversalDeterministicAbstractions.IntAbstraction integer abstractions} of a + * {@link MutableDeterministic}. + * + * @param + * transition type + * @param + * state property type + * @param + * transition property type + */ + interface IntAbstraction extends UniversalDeterministicAbstractions.IntAbstraction { - public StateIntAbstraction(A automaton) { + void setStateProperty(int state, SP property); + + void setTransitionProperty(T transition, TP property); + + void setInitialState(int state); + + T createTransition(int successor, TP property); + + default int addIntState() { + return addIntState(null); + } + + int addIntState(@Nullable SP property); + + default int addIntInitialState() { + return addIntInitialState(null); + } + + int addIntInitialState(@Nullable SP property); + } + + /** + * Interface for {@link UniversalDeterministicAbstractions.StateIntAbstraction state integer abstractions} of a + * {@link MutableDeterministic}. + * + * @param + * input symbol type + * @param + * transition type + * @param + * state property type + * @param + * transition property type + */ + interface StateIntAbstraction + extends IntAbstraction, UniversalDeterministicAbstractions.StateIntAbstraction { + + void setTransition(int state, I input, @Nullable T transition); + + void setTransition(int state, I input, int successor, TP property); + + } + + /** + * Interface for {@link UniversalDeterministicAbstractions.FullIntAbstraction full integer abstractions} of a + * {@link MutableDeterministic}. + * + * @param + * transition type + * @param + * state property type + * @param + * transition property type + */ + interface FullIntAbstraction + extends IntAbstraction, UniversalDeterministicAbstractions.FullIntAbstraction { + + void setTransition(int state, int input, @Nullable T transition); + + void setTransition(int state, int input, int successor, TP property); + + } + + class StateIntAbstractionImpl> + extends UniversalDeterministicAbstractions.StateIntAbstractionImpl + implements StateIntAbstraction { + + public StateIntAbstractionImpl(A automaton) { super(automaton); } @@ -84,11 +160,11 @@ public int addIntInitialState(@Nullable SP property) { } } - class FullIntAbstraction> - extends UniversalDeterministicAbstractions.FullIntAbstraction - implements MutableDeterministic.FullIntAbstraction { + class FullIntAbstractionImpl> + extends UniversalDeterministicAbstractions.FullIntAbstractionImpl + implements FullIntAbstraction { - public FullIntAbstraction(A stateAbstraction, int numInputs, IntFunction symMapping) { + public FullIntAbstractionImpl(A stateAbstraction, int numInputs, IntFunction symMapping) { super(stateAbstraction, numInputs, symMapping); } diff --git a/api/src/main/java/net/automatalib/automaton/abstraction/SimpleDeterministicAbstractions.java b/api/src/main/java/net/automatalib/automaton/abstraction/SimpleDeterministicAbstractions.java index 37d4b9c97..d583e4e13 100644 --- a/api/src/main/java/net/automatalib/automaton/abstraction/SimpleDeterministicAbstractions.java +++ b/api/src/main/java/net/automatalib/automaton/abstraction/SimpleDeterministicAbstractions.java @@ -17,32 +17,112 @@ import java.util.function.IntFunction; +import net.automatalib.automaton.concept.FiniteRepresentation; import net.automatalib.automaton.concept.StateIDs; import net.automatalib.automaton.simple.SimpleDeterministicAutomaton; import org.checkerframework.checker.nullness.qual.Nullable; /** - * Default implementations for {@link SimpleDeterministicAutomaton} abstractions. + * Abstractions for {@link SimpleDeterministicAutomaton}s. */ public interface SimpleDeterministicAbstractions { + /** + * Basic interface for integer abstractions of automata. In an integer abstraction, each state of an automaton is + * identified with an integer in the range {@code [0, size() - 1]}. A similar abstraction may be imposed on the + * input symbols, this is however not prescribed by this interface (see {@link StateIntAbstraction} and + * {@link FullIntAbstraction}). + */ + interface IntAbstraction extends FiniteRepresentation { + + /** + * Representative for an invalid state. This is the value being returned by methods that would return + * {@code null} in their non-abstracted version. However, for determining whether a state is valid or not, code + * should never rely on the corresponding integer being equal to this value, since any integer outside the range + * {@code [0, size() - 1]} is invalid, in particular all negative integers. + */ + int INVALID_STATE = -1; + + /** + * Retrieves the initial state of the (abstracted) automaton as an integer. If the automaton has no initial + * state, {@link #INVALID_STATE} is returned. + * + * @return the integer representing the initial state, or {@link #INVALID_STATE}. + */ + int getIntInitialState(); + + } + + /** + * Interface for {@link IntAbstraction integer abstractions} of an automaton that operate on non-abstracted input + * symbols (i.e., input symbols are of type {@code I}). + * + * @param + * input symbol type + */ + interface StateIntAbstraction extends IntAbstraction { + + /** + * Retrieves the (abstracted) successor state for a given (abstracted) source state and input symbol. + * + * @param state + * the integer representing the source state + * @param input + * the input symbol + * + * @return the integer representing the successor state, or {@link IntAbstraction#INVALID_STATE} if there is no + * successor state. + */ + int getSuccessor(int state, I input); + + } + + /** + * Interface for an {@link IntAbstraction integer abstraction} that abstracts both states and input symbols to + * integers. In addition to the modalities specified in {@link IntAbstraction}, this interface prescribes that input + * symbols are abstracted to integers in the range {@code [0, numInputs() - 1]}. + */ + interface FullIntAbstraction extends IntAbstraction { + + /** + * Retrieves the (abstracted) successor for a given (abstracted) source state and (abstracted) input. + * + * @param state + * the integer representing the source state + * @param input + * the integer representing the input symbol + * + * @return the integer representing the target state, or {@link IntAbstraction#INVALID_STATE} if there is no + * successor state. + */ + int getSuccessor(int state, int input); + + /** + * Retrieves the number of input symbols. This determines the valid range of input symbols, which is + * {@code [0, numInputs() - 1]}. + * + * @return the number of input symbols + */ + int numInputs(); + + } + /** * Base class implementing the default way of obtaining an integer abstraction from an automaton, i.e., by mapping - * states to integers and vice versa using the {@link StateIDs} mapping obtained via {@link - * SimpleDeterministicAutomaton#stateIDs()}. + * states to integers and vice versa using the {@link StateIDs} mapping obtained via + * {@link SimpleDeterministicAutomaton#stateIDs()}. * * @param * state type * @param * automaton type */ - class IntAbstraction> - implements SimpleDeterministicAutomaton.IntAbstraction { + class IntAbstractionImpl> implements IntAbstraction { protected final A automaton; protected final StateIDs stateIds; - public IntAbstraction(A automaton) { + public IntAbstractionImpl(A automaton) { this.automaton = automaton; this.stateIds = automaton.stateIDs(); } @@ -75,7 +155,7 @@ protected final int safeStateToInt(@Nullable S state) { } /** - * Base class implementing the default way of obtaining a {@link SimpleDeterministicAutomaton.StateIntAbstraction}. + * Base class implementing the default way of obtaining a {@link StateIntAbstraction}. * * @param * state type @@ -84,12 +164,12 @@ protected final int safeStateToInt(@Nullable S state) { * @param * automaton type * - * @see IntAbstraction + * @see IntAbstractionImpl */ - class StateIntAbstraction> extends IntAbstraction - implements SimpleDeterministicAutomaton.StateIntAbstraction { + class StateIntAbstractionImpl> + extends IntAbstractionImpl implements StateIntAbstraction { - public StateIntAbstraction(A automaton) { + public StateIntAbstractionImpl(A automaton) { super(automaton); } @@ -100,22 +180,21 @@ public int getSuccessor(int state, I input) { } /** - * Base class implementing the default way of obtaining a {@link FullIntAbstraction}, i.e., building on top of a - * {@link StateIntAbstraction} and a mapping from integers to (concrete) input symbols. + * Base class implementing the default way of obtaining a {@link FullIntAbstractionImpl}, i.e., building on top of a + * {@link StateIntAbstractionImpl} and a mapping from integers to (concrete) input symbols. * * @param * input symbol type * @param * state abstraction type */ - class FullIntAbstraction> - implements SimpleDeterministicAutomaton.FullIntAbstraction { + class FullIntAbstractionImpl> implements FullIntAbstraction { protected final A stateAbstraction; protected final int numInputs; protected final IntFunction symMapping; - public FullIntAbstraction(A stateAbstraction, int numInputs, IntFunction symMapping) { + public FullIntAbstractionImpl(A stateAbstraction, int numInputs, IntFunction symMapping) { this.stateAbstraction = stateAbstraction; this.numInputs = numInputs; this.symMapping = symMapping; diff --git a/api/src/main/java/net/automatalib/automaton/abstraction/UniversalDeterministicAbstractions.java b/api/src/main/java/net/automatalib/automaton/abstraction/UniversalDeterministicAbstractions.java index 918befc99..66e38000c 100644 --- a/api/src/main/java/net/automatalib/automaton/abstraction/UniversalDeterministicAbstractions.java +++ b/api/src/main/java/net/automatalib/automaton/abstraction/UniversalDeterministicAbstractions.java @@ -18,17 +18,102 @@ import java.util.function.IntFunction; import net.automatalib.automaton.UniversalDeterministicAutomaton; +import org.checkerframework.checker.nullness.qual.Nullable; /** - * Default implementations for {@link UniversalDeterministicAutomaton} abstractions. + * Abstractions for {@link UniversalDeterministicAutomaton}s. */ public interface UniversalDeterministicAbstractions { - class StateIntAbstraction> - extends DeterministicAbstractions.StateIntAbstraction - implements UniversalDeterministicAutomaton.StateIntAbstraction { + /** + * Base interface for {@link DeterministicAbstractions.IntAbstraction integer abstractions} of a + * {@link UniversalDeterministicAutomaton}. + * + * @param + * transition type + * @param + * state property type + * @param + * transition property type + */ + interface IntAbstraction extends DeterministicAbstractions.IntAbstraction { - public StateIntAbstraction(A automaton) { + /** + * Retrieves the state property of a given (abstracted) state. + * + * @param state + * the integer representing the state of which to retrieve the property + * + * @return the property for the given state + */ + SP getStateProperty(int state); + + /** + * Retrieves the transition property of a given transition. + * + * @param transition + * the transition of which to retrieve the property + * + * @return the property for the given transition + */ + TP getTransitionProperty(T transition); + } + + /** + * Interface for {@link DeterministicAbstractions.StateIntAbstraction state integer abstractions} of a + * {@link UniversalDeterministicAutomaton}. + * + * @param + * input symbol type + * @param + * transition type + * @param + * state property type + * @param + * transition property type + */ + interface StateIntAbstraction + extends IntAbstraction, DeterministicAbstractions.StateIntAbstraction { + + default @Nullable TP getTransitionProperty(int state, I input) { + T trans = getTransition(state, input); + if (trans != null) { + return getTransitionProperty(trans); + } + return null; + } + + } + + /** + * Interface for {@link DeterministicAbstractions.FullIntAbstraction full integer abstractions} of a + * {@link UniversalDeterministicAutomaton}. + * + * @param + * transition type + * @param + * state property type + * @param + * transition property type + */ + interface FullIntAbstraction + extends IntAbstraction, DeterministicAbstractions.FullIntAbstraction { + + default @Nullable TP getTransitionProperty(int state, int input) { + T trans = getTransition(state, input); + if (trans != null) { + return getTransitionProperty(trans); + } + return null; + } + + } + + class StateIntAbstractionImpl> + extends DeterministicAbstractions.StateIntAbstractionImpl + implements StateIntAbstraction { + + public StateIntAbstractionImpl(A automaton) { super(automaton); } @@ -43,11 +128,10 @@ public TP getTransitionProperty(T transition) { } } - class FullIntAbstraction> - extends DeterministicAbstractions.FullIntAbstraction - implements UniversalDeterministicAutomaton.FullIntAbstraction { + class FullIntAbstractionImpl> + extends DeterministicAbstractions.FullIntAbstractionImpl implements FullIntAbstraction { - public FullIntAbstraction(A stateAbstraction, int numInputs, IntFunction symMapping) { + public FullIntAbstractionImpl(A stateAbstraction, int numInputs, IntFunction symMapping) { super(stateAbstraction, numInputs, symMapping); } diff --git a/api/src/main/java/net/automatalib/automaton/concept/FinSem.java b/api/src/main/java/net/automatalib/automaton/concept/FinSem.java new file mode 100644 index 000000000..30d269a63 --- /dev/null +++ b/api/src/main/java/net/automatalib/automaton/concept/FinSem.java @@ -0,0 +1,3 @@ +package net.automatalib.automaton.concept; + +public interface FinSem {} diff --git a/api/src/main/java/net/automatalib/automaton/ShrinkableAutomaton.java b/api/src/main/java/net/automatalib/automaton/concept/Shrinkable.java similarity index 79% rename from api/src/main/java/net/automatalib/automaton/ShrinkableAutomaton.java rename to api/src/main/java/net/automatalib/automaton/concept/Shrinkable.java index e8937cb42..c18e3e313 100644 --- a/api/src/main/java/net/automatalib/automaton/ShrinkableAutomaton.java +++ b/api/src/main/java/net/automatalib/automaton/concept/Shrinkable.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package net.automatalib.automaton; +package net.automatalib.automaton.concept; import java.util.ArrayList; import java.util.Collection; @@ -21,28 +21,22 @@ import java.util.ListIterator; import java.util.Objects; +import net.automatalib.automaton.MutableAutomaton; import org.checkerframework.checker.nullness.qual.Nullable; /** - * A mutable automaton that also supports destructive modifications, i.e., removal of states and transitions. + * A concept for supporting destructive modifications, e.g., removal of states. * * @param * state class - * @param - * input symbol class - * @param - * transition class - * @param - * state property class - * @param - * transition property class */ -public interface ShrinkableAutomaton extends MutableAutomaton { +@FunctionalInterface +public interface Shrinkable { - static void unlinkState(MutableAutomaton automaton, - S state, - @Nullable S replacement, - Collection inputs) { + static void unlinkState(MutableAutomaton automaton, + S state, + @Nullable S replacement, + Collection inputs) { for (S curr : automaton) { if (Objects.equals(state, curr)) { diff --git a/api/src/main/java/net/automatalib/automaton/fsa/DFA.java b/api/src/main/java/net/automatalib/automaton/fsa/DFA.java index ed5f71e9f..49aeebd63 100644 --- a/api/src/main/java/net/automatalib/automaton/fsa/DFA.java +++ b/api/src/main/java/net/automatalib/automaton/fsa/DFA.java @@ -19,6 +19,8 @@ import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.concept.DeterministicSuffixOutputAutomaton; +import net.automatalib.automaton.concept.FinSem; +import net.automatalib.semantics.DeterministicFiniteSemantics.FullSemantics; import net.automatalib.ts.acceptor.DeterministicAcceptorTS; /** @@ -27,8 +29,14 @@ public interface DFA extends UniversalDeterministicAutomaton, DeterministicAcceptorTS, DeterministicSuffixOutputAutomaton, + FullSemantics, FinSem, NFA { + @Override + default DFA getSemantics() { + return this; + } + @Override default boolean isAccepting(Collection states) { return DeterministicAcceptorTS.super.isAccepting(states); diff --git a/api/src/main/java/net/automatalib/automaton/fsa/FiniteStateAcceptor.java b/api/src/main/java/net/automatalib/automaton/fsa/FiniteStateAcceptor.java index e25e6c370..3cc01f3d6 100644 --- a/api/src/main/java/net/automatalib/automaton/fsa/FiniteStateAcceptor.java +++ b/api/src/main/java/net/automatalib/automaton/fsa/FiniteStateAcceptor.java @@ -26,18 +26,26 @@ import net.automatalib.automaton.graph.UniversalAutomatonGraphView; import net.automatalib.automaton.visualization.FSAVisualizationHelper; import net.automatalib.graph.UniversalGraph; +import net.automatalib.semantics.FiniteSemantics.FullSemantics; import net.automatalib.ts.acceptor.AcceptorTS; import net.automatalib.visualization.VisualizationHelper; /** * {@code FiniteStateAcceptor}s accept regular languages. */ -public interface FiniteStateAcceptor - extends AcceptorTS, UniversalAutomaton, OutputAutomaton { +public interface FiniteStateAcceptor extends AcceptorTS, + UniversalAutomaton, + OutputAutomaton, + FullSemantics { List STATE_PROPERTIES = Arrays.asList(Boolean.FALSE, Boolean.TRUE); List TRANSITION_PROPERTIES = Collections.singletonList(null); + @Override + default FiniteStateAcceptor getSemantics() { + return this; + } + @Override default UniversalGraph, Boolean, TransitionEdge.Property> transitionGraphView( Collection inputs) { diff --git a/api/src/main/java/net/automatalib/automaton/mmlt/MMLT.java b/api/src/main/java/net/automatalib/automaton/mmlt/MMLT.java index 52a5c8bf7..4d927a12b 100644 --- a/api/src/main/java/net/automatalib/automaton/mmlt/MMLT.java +++ b/api/src/main/java/net/automatalib/automaton/mmlt/MMLT.java @@ -22,7 +22,10 @@ import net.automatalib.common.util.Triple; import net.automatalib.graph.Graph; import net.automatalib.graph.concept.GraphViewable; +import net.automatalib.semantics.DeterministicSemantics.UniversalSemantics; import net.automatalib.symbol.time.SymbolicInput; +import net.automatalib.symbol.time.TimedInput; +import net.automatalib.symbol.time.TimedOutput; /** * Base type for a Mealy Machine with Local Timers (MMLT). @@ -50,8 +53,10 @@ * @param * output symbol type */ -public interface MMLT - extends UniversalDeterministicAutomaton, InputAlphabetHolder, GraphViewable { +public interface MMLT extends UniversalDeterministicAutomaton, + InputAlphabetHolder, + UniversalSemantics, TimedInput, Void, TimedOutput>, + GraphViewable { /** * Returns the symbol used for silent outputs. @@ -94,6 +99,7 @@ public interface MMLT * * @return a semantic view of this MMLT */ + @Override MMLTSemantics getSemantics(); @Override diff --git a/api/src/main/java/net/automatalib/automaton/procedural/SBA.java b/api/src/main/java/net/automatalib/automaton/procedural/SBA.java index 5e5720a1c..24dafb698 100644 --- a/api/src/main/java/net/automatalib/automaton/procedural/SBA.java +++ b/api/src/main/java/net/automatalib/automaton/procedural/SBA.java @@ -22,6 +22,7 @@ import net.automatalib.alphabet.ProceduralInputAlphabet; import net.automatalib.automaton.fsa.DFA; +import net.automatalib.semantics.DeterministicSemantics.FullSemantics; import net.automatalib.ts.acceptor.DeterministicAcceptorTS; /** @@ -35,7 +36,13 @@ * @param * input symbol type */ -public interface SBA extends ProceduralSystem>, DeterministicAcceptorTS { +public interface SBA extends ProceduralSystem>, DeterministicAcceptorTS, + FullSemantics { + + @Override + default SBA getSemantics() { + return this; + } @Override default Collection getProceduralInputs(Collection constraints) { diff --git a/api/src/main/java/net/automatalib/automaton/procedural/SPA.java b/api/src/main/java/net/automatalib/automaton/procedural/SPA.java index 59d787efa..c9422dec6 100644 --- a/api/src/main/java/net/automatalib/automaton/procedural/SPA.java +++ b/api/src/main/java/net/automatalib/automaton/procedural/SPA.java @@ -22,6 +22,7 @@ import net.automatalib.alphabet.ProceduralInputAlphabet; import net.automatalib.automaton.fsa.DFA; +import net.automatalib.semantics.DeterministicSemantics.FullSemantics; import net.automatalib.ts.acceptor.DeterministicAcceptorTS; /** @@ -56,7 +57,13 @@ * @param * input symbol type */ -public interface SPA extends ProceduralSystem>, DeterministicAcceptorTS { +public interface SPA + extends ProceduralSystem>, DeterministicAcceptorTS, FullSemantics { + + @Override + default SPA getSemantics() { + return this; + } @Override default Collection getProceduralInputs(Collection constraints) { diff --git a/api/src/main/java/net/automatalib/automaton/procedural/SPMM.java b/api/src/main/java/net/automatalib/automaton/procedural/SPMM.java index 3150241dc..bdd37d591 100644 --- a/api/src/main/java/net/automatalib/automaton/procedural/SPMM.java +++ b/api/src/main/java/net/automatalib/automaton/procedural/SPMM.java @@ -24,6 +24,7 @@ import net.automatalib.alphabet.ProceduralInputAlphabet; import net.automatalib.automaton.concept.Output; import net.automatalib.automaton.transducer.MealyMachine; +import net.automatalib.semantics.DeterministicSemantics.FullSemantics; import net.automatalib.ts.concept.DeterministicSuffixOutputTS; import net.automatalib.ts.output.MealyTransitionSystem; import net.automatalib.word.Word; @@ -45,8 +46,14 @@ * @param * output symbol type */ -public interface SPMM - extends ProceduralSystem>, MealyTransitionSystem { +public interface SPMM extends ProceduralSystem>, + MealyTransitionSystem, + FullSemantics { + + @Override + default SPMM getSemantics() { + return this; + } /** * Returns the output symbol that identifies erroneous transitions. Note that for the validity of this {@link SPMM}, diff --git a/api/src/main/java/net/automatalib/automaton/simple/SimpleDeterministicAutomaton.java b/api/src/main/java/net/automatalib/automaton/simple/SimpleDeterministicAutomaton.java index f6506f616..706bd49db 100644 --- a/api/src/main/java/net/automatalib/automaton/simple/SimpleDeterministicAutomaton.java +++ b/api/src/main/java/net/automatalib/automaton/simple/SimpleDeterministicAutomaton.java @@ -18,8 +18,10 @@ import java.util.function.IntFunction; import net.automatalib.alphabet.Alphabet; -import net.automatalib.automaton.abstraction.SimpleDeterministicAbstractions; -import net.automatalib.automaton.concept.FiniteRepresentation; +import net.automatalib.automaton.abstraction.SimpleDeterministicAbstractions.FullIntAbstraction; +import net.automatalib.automaton.abstraction.SimpleDeterministicAbstractions.FullIntAbstractionImpl; +import net.automatalib.automaton.abstraction.SimpleDeterministicAbstractions.StateIntAbstraction; +import net.automatalib.automaton.abstraction.SimpleDeterministicAbstractions.StateIntAbstractionImpl; import net.automatalib.ts.simple.SimpleDTS; /** @@ -60,7 +62,7 @@ default FullIntAbstraction fullIntAbstraction(Alphabet alphabet) { * @return a {@link FullIntAbstraction} */ default FullIntAbstraction fullIntAbstraction(int numInputs, IntFunction symMapping) { - return new SimpleDeterministicAbstractions.FullIntAbstraction<>(stateIntAbstraction(), numInputs, symMapping); + return new FullIntAbstractionImpl<>(stateIntAbstraction(), numInputs, symMapping); } /** @@ -69,87 +71,7 @@ default FullIntAbstraction fullIntAbstraction(int numInputs, IntFunction stateIntAbstraction() { - return new SimpleDeterministicAbstractions.StateIntAbstraction<>(this); - } - - /** - * Basic interface for integer abstractions of automata. In an integer abstraction, each state of an automaton is - * identified with an integer in the range {@code [0, size() - 1]}. A similar abstraction may be imposed on the - * input symbols, this is however not prescribed by this interface (see {@link StateIntAbstraction} and {@link - * FullIntAbstraction}). - */ - interface IntAbstraction extends FiniteRepresentation { - - /** - * Representative for an invalid state. This is the value being returned by methods that would return {@code - * null} in their non-abstracted version. However, for determining whether a state is valid or not, code should - * never rely on the corresponding integer being equal to this value, since any integer outside the range - * {@code [0, size() - 1]} is invalid, in particular all negative integers. - */ - int INVALID_STATE = -1; - - /** - * Retrieves the initial state of the (abstracted) automaton as an integer. If the automaton has no initial - * state, {@link #INVALID_STATE} is returned. - * - * @return the integer representing the initial state, or {@link #INVALID_STATE}. - */ - int getIntInitialState(); - - } - - /** - * Interface for {@link IntAbstraction integer abstractions} of an automaton that operate on non-abstracted input - * symbols (i.e., input symbols are of type {@code I}). - * - * @param - * input symbol type - */ - interface StateIntAbstraction extends IntAbstraction { - - /** - * Retrieves the (abstracted) successor state for a given (abstracted) source state and input symbol. - * - * @param state - * the integer representing the source state - * @param input - * the input symbol - * - * @return the integer representing the successor state, or {@link IntAbstraction#INVALID_STATE} if there is no - * successor state. - */ - int getSuccessor(int state, I input); - - } - - /** - * Interface for an {@link IntAbstraction integer abstraction} that abstracts both states and input symbols to - * integers. In addition to the modalities specified in {@link IntAbstraction}, this interface prescribes that input - * symbols are abstracted to integers in the range {@code [0, numInputs() - 1]}. - */ - interface FullIntAbstraction extends IntAbstraction { - - /** - * Retrieves the (abstracted) successor for a given (abstracted) source state and (abstracted) input. - * - * @param state - * the integer representing the source state - * @param input - * the integer representing the input symbol - * - * @return the integer representing the target state, or {@link IntAbstraction#INVALID_STATE} if there is no - * successor state. - */ - int getSuccessor(int state, int input); - - /** - * Retrieves the number of input symbols. This determines the valid range of input symbols, which is {@code [0, - * numInputs() - 1]}. - * - * @return the number of input symbols - */ - int numInputs(); - + return new StateIntAbstractionImpl<>(this); } } diff --git a/api/src/main/java/net/automatalib/automaton/transducer/MealyMachine.java b/api/src/main/java/net/automatalib/automaton/transducer/MealyMachine.java index 225598446..d351c40e4 100644 --- a/api/src/main/java/net/automatalib/automaton/transducer/MealyMachine.java +++ b/api/src/main/java/net/automatalib/automaton/transducer/MealyMachine.java @@ -18,16 +18,24 @@ import java.util.Collection; import net.automatalib.automaton.UniversalDeterministicAutomaton; +import net.automatalib.automaton.concept.FinSem; import net.automatalib.automaton.graph.TransitionEdge; import net.automatalib.automaton.graph.UniversalAutomatonGraphView; import net.automatalib.automaton.visualization.MealyVisualizationHelper; import net.automatalib.graph.UniversalGraph; +import net.automatalib.semantics.DeterministicFiniteSemantics.FullSemantics; import net.automatalib.ts.output.MealyTransitionSystem; import net.automatalib.visualization.VisualizationHelper; public interface MealyMachine extends UniversalDeterministicAutomaton, TransitionOutputAutomaton, - MealyTransitionSystem { + MealyTransitionSystem, FinSem, + FullSemantics { + + @Override + default MealyMachine getSemantics() { + return this; + } @Override default UniversalGraph, Void, TransitionEdge.Property> transitionGraphView(Collection inputs) { diff --git a/api/src/main/java/net/automatalib/automaton/transducer/MooreMachine.java b/api/src/main/java/net/automatalib/automaton/transducer/MooreMachine.java index c8511bb4d..8a1476654 100644 --- a/api/src/main/java/net/automatalib/automaton/transducer/MooreMachine.java +++ b/api/src/main/java/net/automatalib/automaton/transducer/MooreMachine.java @@ -23,12 +23,19 @@ import net.automatalib.automaton.graph.UniversalAutomatonGraphView; import net.automatalib.automaton.visualization.MooreVisualizationHelper; import net.automatalib.graph.UniversalGraph; +import net.automatalib.semantics.DeterministicFiniteSemantics.FullSemantics; import net.automatalib.ts.output.MooreTransitionSystem; import net.automatalib.visualization.VisualizationHelper; public interface MooreMachine extends UniversalDeterministicAutomaton, StateOutputAutomaton, - MooreTransitionSystem { + MooreTransitionSystem, + FullSemantics { + + @Override + default MooreMachine getSemantics() { + return this; + } @Override default UniversalGraph, O, Property> transitionGraphView(Collection inputs) { diff --git a/api/src/main/java/net/automatalib/automaton/transducer/SubsequentialTransducer.java b/api/src/main/java/net/automatalib/automaton/transducer/SubsequentialTransducer.java index 720605634..d3e411545 100644 --- a/api/src/main/java/net/automatalib/automaton/transducer/SubsequentialTransducer.java +++ b/api/src/main/java/net/automatalib/automaton/transducer/SubsequentialTransducer.java @@ -26,6 +26,7 @@ import net.automatalib.automaton.graph.UniversalAutomatonGraphView; import net.automatalib.automaton.visualization.SSTVisualizationHelper; import net.automatalib.graph.UniversalGraph; +import net.automatalib.semantics.DeterministicFiniteSemantics.FullSemantics; import net.automatalib.ts.concept.DeterministicOutputTS; import net.automatalib.ts.output.DeterministicTraceableTS; import net.automatalib.visualization.VisualizationHelper; @@ -53,7 +54,13 @@ */ public interface SubsequentialTransducer extends DeterministicTraceableTS, DeterministicSuffixOutputAutomaton>, - UniversalDeterministicAutomaton, Word> { + UniversalDeterministicAutomaton, Word>, + FullSemantics, Word> { + + @Override + default SubsequentialTransducer getSemantics() { + return this; + } @Override default boolean trace(S state, Iterable input, List output) { diff --git a/api/src/main/java/net/automatalib/semantics/DeterministicFiniteSemantics.java b/api/src/main/java/net/automatalib/semantics/DeterministicFiniteSemantics.java new file mode 100644 index 000000000..e310818b7 --- /dev/null +++ b/api/src/main/java/net/automatalib/semantics/DeterministicFiniteSemantics.java @@ -0,0 +1,40 @@ +package net.automatalib.semantics; + +import net.automatalib.automaton.DeterministicAutomaton; +import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.UniversalDeterministicAutomaton; + +public interface DeterministicFiniteSemantics { + + interface SimpleSemantics { + + DeterministicAutomaton getSemantics(); + + } + + interface UniversalSemantics extends SimpleSemantics, + FiniteSemantics.UniversalSemantics, + DeterministicSemantics.UniversalSemantics { + + @Override + UniversalDeterministicAutomaton getSemantics(); + } + + interface FullSemantics extends UniversalSemantics, + FiniteSemantics.FullSemantics, + DeterministicSemantics.FullSemantics { + + @Override + UniversalDeterministicAutomaton getSemantics(); + } + + interface MutableSemantics extends FullSemantics, FiniteSemantics.MutableSemantics { + @Override + MutableDeterministic getSemantics(); + + } + + static FullSemantics fromAutomaton(UniversalDeterministicAutomaton automaton) { + return () -> automaton; + } +} diff --git a/api/src/main/java/net/automatalib/semantics/DeterministicSemantics.java b/api/src/main/java/net/automatalib/semantics/DeterministicSemantics.java new file mode 100644 index 000000000..acc1f92f8 --- /dev/null +++ b/api/src/main/java/net/automatalib/semantics/DeterministicSemantics.java @@ -0,0 +1,28 @@ +package net.automatalib.semantics; + +import net.automatalib.ts.DeterministicTransitionSystem; +import net.automatalib.ts.UniversalDTS; + +public interface DeterministicSemantics { + + interface SimpleSemantics { + + DeterministicTransitionSystem getSemantics(); + + } + + interface UniversalSemantics + extends SimpleSemantics, Semantics.UniversalSemantics { + + @Override + UniversalDTS getSemantics(); + } + + interface FullSemantics + extends UniversalSemantics, Semantics.FullSemantics { + + @Override + UniversalDTS getSemantics(); + } + +} diff --git a/api/src/main/java/net/automatalib/semantics/FiniteSemantics.java b/api/src/main/java/net/automatalib/semantics/FiniteSemantics.java new file mode 100644 index 000000000..ed0312178 --- /dev/null +++ b/api/src/main/java/net/automatalib/semantics/FiniteSemantics.java @@ -0,0 +1,37 @@ +package net.automatalib.semantics; + +import net.automatalib.automaton.Automaton; +import net.automatalib.automaton.MutableAutomaton; +import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.UniversalAutomaton; + +public interface FiniteSemantics { + + interface SimpleSemantics extends Semantics.SimpleSemantics { + + Automaton getSemantics(); + + } + + interface UniversalSemantics + extends SimpleSemantics, Semantics.UniversalSemantics { + + @Override + UniversalAutomaton getSemantics(); + } + + interface FullSemantics + extends UniversalSemantics, Semantics.FullSemantics { + + @Override + UniversalAutomaton getSemantics(); + } + + interface MutableSemantics extends FullSemantics { + + @Override + MutableAutomaton getSemantics(); + + } + +} diff --git a/api/src/main/java/net/automatalib/semantics/Semantics.java b/api/src/main/java/net/automatalib/semantics/Semantics.java new file mode 100644 index 000000000..e35a275b1 --- /dev/null +++ b/api/src/main/java/net/automatalib/semantics/Semantics.java @@ -0,0 +1,26 @@ +package net.automatalib.semantics; + +import net.automatalib.ts.TransitionSystem; +import net.automatalib.ts.UniversalTransitionSystem; + +public interface Semantics { + + interface SimpleSemantics { + + TransitionSystem getSemantics(); + + } + + interface UniversalSemantics extends SimpleSemantics { + + @Override + UniversalTransitionSystem getSemantics(); + } + + interface FullSemantics extends UniversalSemantics { + + @Override + UniversalTransitionSystem getSemantics(); + } + +} diff --git a/api/src/main/java/net/automatalib/ts/modal/ModalTransitionSystem.java b/api/src/main/java/net/automatalib/ts/modal/ModalTransitionSystem.java index 0c54ede1d..a2dbfc265 100644 --- a/api/src/main/java/net/automatalib/ts/modal/ModalTransitionSystem.java +++ b/api/src/main/java/net/automatalib/ts/modal/ModalTransitionSystem.java @@ -24,6 +24,7 @@ import net.automatalib.automaton.graph.UniversalAutomatonGraphView; import net.automatalib.automaton.visualization.MTSVisualizationHelper; import net.automatalib.graph.UniversalGraph; +import net.automatalib.semantics.FiniteSemantics.FullSemantics; import net.automatalib.ts.modal.transition.ModalEdgeProperty; import net.automatalib.visualization.VisualizationHelper; @@ -44,7 +45,12 @@ * (specific) transition property type */ public interface ModalTransitionSystem - extends UniversalFiniteAlphabetAutomaton { + extends UniversalFiniteAlphabetAutomaton, FullSemantics { + + @Override + default ModalTransitionSystem getSemantics() { + return this; + } @Override default UniversalGraph, Void, Property> transitionGraphView(Collection inputs) { diff --git a/core/src/main/java/net/automatalib/automaton/base/AbstractCompact.java b/core/src/main/java/net/automatalib/automaton/base/AbstractCompact.java index 1d0ce75b1..cdbc8303c 100644 --- a/core/src/main/java/net/automatalib/automaton/base/AbstractCompact.java +++ b/core/src/main/java/net/automatalib/automaton/base/AbstractCompact.java @@ -24,8 +24,8 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.SupportsGrowingAlphabet; import net.automatalib.automaton.MutableAutomaton; -import net.automatalib.automaton.MutableDeterministic.FullIntAbstraction; import net.automatalib.automaton.UniversalFiniteAlphabetAutomaton; +import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions; import net.automatalib.automaton.concept.StateIDs; import net.automatalib.automaton.concept.StateLocalInput; import net.automatalib.common.util.collection.CollectionUtil; @@ -57,7 +57,7 @@ public abstract class AbstractCompact implements MutableAutomaton< protected static final float DEFAULT_RESIZE_FACTOR = 1.5f; protected static final int DEFAULT_INIT_CAPACITY = 11; - protected static final int INVALID_STATE = FullIntAbstraction.INVALID_STATE; + protected static final int INVALID_STATE = MutableDeterministicAbstractions.FullIntAbstraction.INVALID_STATE; private final Alphabet alphabet; private final float resizeFactor; @@ -341,8 +341,8 @@ public final int numInputs(@UnknownInitialization(AbstractCompact.class) Abstrac } /** - * An enum containing the different kind of update operations. Each enum constant implements the required {@link - * TransitionUpdateOperation#updateStorage(Object, Payload, IntFunction, ArrayInitializer)} method. + * An enum containing the different kind of update operations. Each enum constant implements the required + * {@link TransitionUpdateOperation#updateStorage(Object, Payload, IntFunction, ArrayInitializer)} method. */ private enum TransitionUpdateOperation { /** diff --git a/core/src/main/java/net/automatalib/automaton/base/AbstractCompactDeterministic.java b/core/src/main/java/net/automatalib/automaton/base/AbstractCompactDeterministic.java index fe0de81ff..6d4249b90 100644 --- a/core/src/main/java/net/automatalib/automaton/base/AbstractCompactDeterministic.java +++ b/core/src/main/java/net/automatalib/automaton/base/AbstractCompactDeterministic.java @@ -22,12 +22,14 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions.FullIntAbstraction; +import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions.StateIntAbstraction; import org.checkerframework.checker.nullness.qual.Nullable; /** * Abstract super class that refines {@link AbstractCompact} for deterministic automata. This class provides default - * implementations for several of the {@link MutableDeterministic.FullIntAbstraction} concepts, such that subclasses - * only need to care about the primitive-based implementations. + * implementations for several of the {@link FullIntAbstraction} concepts, such that subclasses only need to care about + * the primitive-based implementations. * * @param * input symbol type @@ -40,8 +42,8 @@ */ public abstract class AbstractCompactDeterministic extends AbstractCompact implements MutableDeterministic, - MutableDeterministic.StateIntAbstraction, - MutableDeterministic.FullIntAbstraction { + StateIntAbstraction, + FullIntAbstraction { private int initial = AbstractCompact.INVALID_STATE; diff --git a/core/src/main/java/net/automatalib/automaton/base/AbstractCompactSimpleDeterministic.java b/core/src/main/java/net/automatalib/automaton/base/AbstractCompactSimpleDeterministic.java index 3d9b32e38..8666a1ffb 100644 --- a/core/src/main/java/net/automatalib/automaton/base/AbstractCompactSimpleDeterministic.java +++ b/core/src/main/java/net/automatalib/automaton/base/AbstractCompactSimpleDeterministic.java @@ -19,6 +19,7 @@ import java.util.Iterator; import net.automatalib.alphabet.Alphabet; +import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions.FullIntAbstraction; import org.checkerframework.checker.nullness.qual.Nullable; /** diff --git a/core/src/main/java/net/automatalib/automaton/base/AbstractFastMutable.java b/core/src/main/java/net/automatalib/automaton/base/AbstractFastMutable.java index b557f755a..2e44e251d 100644 --- a/core/src/main/java/net/automatalib/automaton/base/AbstractFastMutable.java +++ b/core/src/main/java/net/automatalib/automaton/base/AbstractFastMutable.java @@ -19,8 +19,9 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.SupportsGrowingAlphabet; -import net.automatalib.automaton.ShrinkableAutomaton; +import net.automatalib.automaton.MutableAutomaton; import net.automatalib.automaton.UniversalFiniteAlphabetAutomaton; +import net.automatalib.automaton.concept.Shrinkable; import net.automatalib.automaton.concept.StateIDs; import net.automatalib.automaton.concept.StateLocalInput; import net.automatalib.common.util.mapping.ArrayMapping; @@ -33,7 +34,8 @@ * Shared functionality for (non-) deterministic mutable automata. */ public abstract class AbstractFastMutable, I, T, SP, TP> - implements ShrinkableAutomaton, + implements MutableAutomaton, + Shrinkable, UniversalFiniteAlphabetAutomaton, StateIDs, SupportsGrowingAlphabet, @@ -73,7 +75,7 @@ public void removeAllTransitions(S state) { @Override public void removeState(S state, @Nullable S replacement) { - ShrinkableAutomaton.unlinkState(this, state, replacement, inputAlphabet); + Shrinkable.unlinkState(this, state, replacement, inputAlphabet); states.remove(state, tracker); } diff --git a/core/src/main/java/net/automatalib/automaton/base/AbstractFastMutableDet.java b/core/src/main/java/net/automatalib/automaton/base/AbstractFastMutableDet.java index dbb46310d..db2f1e2f8 100644 --- a/core/src/main/java/net/automatalib/automaton/base/AbstractFastMutableDet.java +++ b/core/src/main/java/net/automatalib/automaton/base/AbstractFastMutableDet.java @@ -20,11 +20,11 @@ import java.util.List; import net.automatalib.alphabet.Alphabet; -import net.automatalib.automaton.ShrinkableDeterministic; +import net.automatalib.automaton.MutableDeterministic; import org.checkerframework.checker.nullness.qual.Nullable; public abstract class AbstractFastMutableDet, I, T, SP, TP> - extends AbstractFastMutable implements ShrinkableDeterministic { + extends AbstractFastMutable implements MutableDeterministic { private @Nullable S initialState; diff --git a/core/src/main/java/net/automatalib/automaton/impl/CompactTransitionOutput.java b/core/src/main/java/net/automatalib/automaton/impl/CompactTransitionOutput.java new file mode 100644 index 000000000..a183687a2 --- /dev/null +++ b/core/src/main/java/net/automatalib/automaton/impl/CompactTransitionOutput.java @@ -0,0 +1,185 @@ +/* Copyright (C) 2013-2026 TU Dortmund University + * This file is part of AutomataLib . + * + * 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 net.automatalib.automaton.impl; + +import java.util.Arrays; + +import net.automatalib.alphabet.Alphabet; +import net.automatalib.automaton.AutomatonCreator; +import net.automatalib.automaton.base.AbstractCompact; +import net.automatalib.automaton.base.AbstractCompactDeterministic; +import net.automatalib.automaton.concept.MutableTransitionOutput; +import org.checkerframework.checker.nullness.qual.Nullable; + +public class CompactTransitionOutput extends AbstractCompactDeterministic, Void, O> + implements MutableTransitionOutput, O> { + + private int[] transitions; + private @Nullable Object[] outputs; + + public CompactTransitionOutput(Alphabet alphabet, int stateCapacity, float resizeFactor) { + super(alphabet, stateCapacity, resizeFactor); + + final int size = stateCapacity * numInputs(); + + this.transitions = new int[size]; + this.outputs = new Object[size]; + + Arrays.fill(transitions, AbstractCompact.INVALID_STATE); + } + + public CompactTransitionOutput(Alphabet alphabet, int stateCapacity) { + this(alphabet, stateCapacity, DEFAULT_RESIZE_FACTOR); + } + + public CompactTransitionOutput(Alphabet alphabet) { + this(alphabet, DEFAULT_INIT_CAPACITY, DEFAULT_RESIZE_FACTOR); + } + + public CompactTransitionOutput(CompactTransitionOutput other) { + this(other.getInputAlphabet(), other); + } + + protected CompactTransitionOutput(Alphabet alphabet, CompactTransitionOutput other) { + super(alphabet, other); + this.transitions = other.transitions.clone(); + this.outputs = other.outputs.clone(); + } + + @Override + protected void updateTransitionStorage(Payload payload) { + this.transitions = updateTransitionStorage(this.transitions, AbstractCompact.INVALID_STATE, payload); + this.outputs = updateTransitionStorage(this.outputs, null, payload); + } + + @Override + public O getTransitionOutput(CompactTransition transition) { + return transition.getProperty(); + } + + @Override + public O getTransitionProperty(CompactTransition transition) { + return transition.getProperty(); + } + + @Override + @SuppressWarnings("unchecked") + // Overridden for performance reasons (to prevent object instantiation of default implementation) + public O getTransitionProperty(int state, int input) { + return (O) outputs[toMemoryIndex(state, input)]; + } + + @Override + public void setTransitionProperty(CompactTransition transition, O property) { + transition.setProperty(property); + + if (transition.isAutomatonTransition()) { + outputs[transition.getMemoryIdx()] = property; + } + } + + @Override + public void setTransitionOutput(CompactTransition transition, O output) { + setTransitionProperty(transition, output); + } + + @Override + public void removeAllTransitions(Integer state) { + final int lower = state * numInputs(); + final int upper = lower + numInputs(); + Arrays.fill(transitions, lower, upper, AbstractCompact.INVALID_STATE); + Arrays.fill(outputs, lower, upper, null); + } + + @Override + // Overridden for performance reasons (to prevent object instantiation of default implementation) + public int getSuccessor(int state, int input) { + return transitions[toMemoryIndex(state, input)]; + } + + @Override + public int getIntSuccessor(CompactTransition transition) { + return transition.getSuccId(); + } + + @Override + public CompactTransition createTransition(int succId, O property) { + return new CompactTransition<>(succId, property); + } + + @Override + public void setStateProperty(int state, Void property) {} + + @Override + public Void getStateProperty(int stateId) { + return null; + } + + @Override + public void setTransition(int state, int input, @Nullable CompactTransition transition) { + if (transition == null) { + setTransition(state, input, AbstractCompact.INVALID_STATE, null); + } else { + setTransition(state, input, transition.getSuccId(), transition.getProperty()); + transition.setMemoryIdx(toMemoryIndex(state, input)); + } + } + + @Override + public void setTransition(int state, int input, int successor, @Nullable O property) { + final int idx = toMemoryIndex(state, input); + transitions[idx] = successor; + outputs[idx] = property; + } + + @Override + public void clear() { + int endIdx = size() * numInputs(); + Arrays.fill(transitions, 0, endIdx, AbstractCompact.INVALID_STATE); + Arrays.fill(outputs, 0, endIdx, null); + + super.clear(); + } + + @Override + public @Nullable CompactTransition getTransition(int state, int input) { + final int idx = toMemoryIndex(state, input); + final int succ = transitions[idx]; + + if (succ == AbstractCompact.INVALID_STATE) { + return null; + } + + @SuppressWarnings("unchecked") + final O output = (O) outputs[idx]; + + return new CompactTransition<>(idx, succ, output); + } + + public static final class Creator implements AutomatonCreator, I> { + + @Override + public CompactTransitionOutput createAutomaton(Alphabet alphabet, int sizeHint) { + return new CompactTransitionOutput<>(alphabet, sizeHint); + } + + @Override + public CompactTransitionOutput createAutomaton(Alphabet alphabet) { + return new CompactTransitionOutput<>(alphabet); + } + } + +} diff --git a/core/src/main/java/net/automatalib/automaton/impl/UniversalCompactDetAutomaton.java b/core/src/main/java/net/automatalib/automaton/impl/UniversalCompactDetAutomaton.java new file mode 100644 index 000000000..7063453cb --- /dev/null +++ b/core/src/main/java/net/automatalib/automaton/impl/UniversalCompactDetAutomaton.java @@ -0,0 +1,59 @@ +/* Copyright (C) 2013-2026 TU Dortmund University + * This file is part of AutomataLib . + * + * 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 net.automatalib.automaton.impl; + +import net.automatalib.alphabet.Alphabet; +import net.automatalib.automaton.AutomatonCreator; +import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.UniversalFiniteAlphabetAutomaton; +import net.automatalib.automaton.base.AbstractCompactDeterministic; + +/** + * A default implementation for {@link AbstractCompactDeterministic} that uses {@link CompactTransition} as transition + * type and supports various types of state and transition properties. + * + * @param + * input symbol type + * @param + * state property type + * @param + * transition property type + */ +public class UniversalCompactDetAutomaton extends UniversalCompactDet + implements MutableDeterministic, SP, TP>, + UniversalFiniteAlphabetAutomaton, SP, TP> { + + public UniversalCompactDetAutomaton(Alphabet alphabet) { + super(alphabet); + } + + public UniversalCompactDetAutomaton(Alphabet alphabet, int stateCapacity) { + super(alphabet, stateCapacity); + } + + public static final class Creator implements AutomatonCreator, I> { + + @Override + public UniversalCompactDetAutomaton createAutomaton(Alphabet alphabet, int numStates) { + return new UniversalCompactDetAutomaton<>(alphabet, numStates); + } + + @Override + public UniversalCompactDetAutomaton createAutomaton(Alphabet alphabet) { + return new UniversalCompactDetAutomaton<>(alphabet); + } + } +} diff --git a/core/src/main/java/net/automatalib/automaton/mmlt/impl/CompactMMLT.java b/core/src/main/java/net/automatalib/automaton/mmlt/impl/CompactMMLT.java index e727aa318..c5ac37be2 100644 --- a/core/src/main/java/net/automatalib/automaton/mmlt/impl/CompactMMLT.java +++ b/core/src/main/java/net/automatalib/automaton/mmlt/impl/CompactMMLT.java @@ -27,11 +27,11 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.AutomatonCreator; import net.automatalib.automaton.impl.CompactTransition; +import net.automatalib.automaton.impl.CompactTransitionOutput; import net.automatalib.automaton.mmlt.MMLTSemantics; import net.automatalib.automaton.mmlt.MutableMMLT; import net.automatalib.automaton.mmlt.SymbolCombiner; import net.automatalib.automaton.mmlt.TimerInfo; -import net.automatalib.automaton.transducer.impl.CompactMealy; import net.automatalib.common.util.Triple; import net.automatalib.graph.Graph; import net.automatalib.symbol.time.SymbolicInput; @@ -44,7 +44,7 @@ * @param * output symbol type */ -public class CompactMMLT extends CompactMealy implements MutableMMLT, O> { +public class CompactMMLT extends CompactTransitionOutput implements MutableMMLT, O> { private final Map>> sortedTimers; // location -> (sorted timers) private final Map> resets; // location -> inputs (that reset all timers) diff --git a/core/src/main/java/net/automatalib/automaton/transducer/impl/CompactMealy.java b/core/src/main/java/net/automatalib/automaton/transducer/impl/CompactMealy.java index 3a3281afd..cf10fdf50 100644 --- a/core/src/main/java/net/automatalib/automaton/transducer/impl/CompactMealy.java +++ b/core/src/main/java/net/automatalib/automaton/transducer/impl/CompactMealy.java @@ -15,51 +15,35 @@ */ package net.automatalib.automaton.transducer.impl; -import java.util.Arrays; - import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.AutomatonCreator; -import net.automatalib.automaton.base.AbstractCompact; -import net.automatalib.automaton.base.AbstractCompactDeterministic; import net.automatalib.automaton.impl.CompactTransition; +import net.automatalib.automaton.impl.CompactTransitionOutput; import net.automatalib.automaton.transducer.MutableMealyMachine; import net.automatalib.automaton.transducer.StateLocalInputMealyMachine; -import org.checkerframework.checker.nullness.qual.Nullable; - -public class CompactMealy extends AbstractCompactDeterministic, Void, O> implements - MutableMealyMachine, O>, - StateLocalInputMealyMachine, O> { - private int[] transitions; - private @Nullable Object[] outputs; +public class CompactMealy extends CompactTransitionOutput + implements MutableMealyMachine, O>, + StateLocalInputMealyMachine, O> { public CompactMealy(Alphabet alphabet, int stateCapacity, float resizeFactor) { super(alphabet, stateCapacity, resizeFactor); - - final int size = stateCapacity * numInputs(); - - this.transitions = new int[size]; - this.outputs = new Object[size]; - - Arrays.fill(transitions, AbstractCompact.INVALID_STATE); } public CompactMealy(Alphabet alphabet, int stateCapacity) { - this(alphabet, stateCapacity, DEFAULT_RESIZE_FACTOR); + super(alphabet, stateCapacity); } public CompactMealy(Alphabet alphabet) { - this(alphabet, DEFAULT_INIT_CAPACITY, DEFAULT_RESIZE_FACTOR); + super(alphabet); } public CompactMealy(CompactMealy other) { - this(other.getInputAlphabet(), other); + super(other); } protected CompactMealy(Alphabet alphabet, CompactMealy other) { super(alphabet, other); - this.transitions = other.transitions.clone(); - this.outputs = other.outputs.clone(); } public CompactMealy translate(Alphabet newAlphabet) { @@ -71,116 +55,6 @@ public CompactMealy translate(Alphabet newAlphabet) { return new CompactMealy<>(newAlphabet, this); } - @Override - protected void updateTransitionStorage(Payload payload) { - this.transitions = updateTransitionStorage(this.transitions, AbstractCompact.INVALID_STATE, payload); - this.outputs = updateTransitionStorage(this.outputs, null, payload); - } - - @Override - public O getTransitionOutput(CompactTransition transition) { - return transition.getProperty(); - } - - @Override - public O getTransitionProperty(CompactTransition transition) { - return transition.getProperty(); - } - - @Override - @SuppressWarnings("unchecked") - // Overridden for performance reasons (to prevent object instantiation of default implementation) - public O getTransitionProperty(int state, int input) { - return (O) outputs[toMemoryIndex(state, input)]; - } - - @Override - public void setTransitionProperty(CompactTransition transition, O property) { - transition.setProperty(property); - - if (transition.isAutomatonTransition()) { - outputs[transition.getMemoryIdx()] = property; - } - } - - @Override - public void setTransitionOutput(CompactTransition transition, O output) { - setTransitionProperty(transition, output); - } - - @Override - public void removeAllTransitions(Integer state) { - final int lower = state * numInputs(); - final int upper = lower + numInputs(); - Arrays.fill(transitions, lower, upper, AbstractCompact.INVALID_STATE); - Arrays.fill(outputs, lower, upper, null); - } - - @Override - // Overridden for performance reasons (to prevent object instantiation of default implementation) - public int getSuccessor(int state, int input) { - return transitions[toMemoryIndex(state, input)]; - } - - @Override - public int getIntSuccessor(CompactTransition transition) { - return transition.getSuccId(); - } - - @Override - public CompactTransition createTransition(int succId, O property) { - return new CompactTransition<>(succId, property); - } - - @Override - public void setStateProperty(int state, Void property) {} - - @Override - public Void getStateProperty(int stateId) { - return null; - } - - @Override - public void setTransition(int state, int input, @Nullable CompactTransition transition) { - if (transition == null) { - setTransition(state, input, AbstractCompact.INVALID_STATE, null); - } else { - setTransition(state, input, transition.getSuccId(), transition.getProperty()); - transition.setMemoryIdx(toMemoryIndex(state, input)); - } - } - - @Override - public void setTransition(int state, int input, int successor, @Nullable O property) { - final int idx = toMemoryIndex(state, input); - transitions[idx] = successor; - outputs[idx] = property; - } - - @Override - public void clear() { - int endIdx = size() * numInputs(); - Arrays.fill(transitions, 0, endIdx, AbstractCompact.INVALID_STATE); - Arrays.fill(outputs, 0, endIdx, null); - - super.clear(); - } - - @Override - public @Nullable CompactTransition getTransition(int state, int input) { - final int idx = toMemoryIndex(state, input); - final int succ = transitions[idx]; - - if (succ == AbstractCompact.INVALID_STATE) { - return null; - } - - @SuppressWarnings("unchecked") - final O output = (O) outputs[idx]; - - return new CompactTransition<>(idx, succ, output); - } - public static final class Creator implements AutomatonCreator, I> { @Override diff --git a/core/src/test/java/net/automatalib/automaton/abstraction/impl/DeterministicAutomatonAbstractionTest.java b/core/src/test/java/net/automatalib/automaton/abstraction/impl/DeterministicAutomatonAbstractionTest.java index e7096f9e7..c1966411c 100644 --- a/core/src/test/java/net/automatalib/automaton/abstraction/impl/DeterministicAutomatonAbstractionTest.java +++ b/core/src/test/java/net/automatalib/automaton/abstraction/impl/DeterministicAutomatonAbstractionTest.java @@ -20,8 +20,8 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Symbol; import net.automatalib.automaton.DeterministicAutomaton; -import net.automatalib.automaton.DeterministicAutomaton.FullIntAbstraction; -import net.automatalib.automaton.DeterministicAutomaton.StateIntAbstraction; +import net.automatalib.automaton.abstraction.DeterministicAbstractions.FullIntAbstraction; +import net.automatalib.automaton.abstraction.DeterministicAbstractions.StateIntAbstraction; import net.automatalib.automaton.impl.CompactTransition; import net.automatalib.automaton.transducer.impl.CompactMealy; import net.automatalib.automaton.util.TestUtil; diff --git a/core/src/test/java/net/automatalib/automaton/abstraction/impl/MutableFullIntAbstractionTest.java b/core/src/test/java/net/automatalib/automaton/abstraction/impl/MutableFullIntAbstractionTest.java index 226aa2b36..6567492d3 100644 --- a/core/src/test/java/net/automatalib/automaton/abstraction/impl/MutableFullIntAbstractionTest.java +++ b/core/src/test/java/net/automatalib/automaton/abstraction/impl/MutableFullIntAbstractionTest.java @@ -23,6 +23,7 @@ import net.automatalib.automaton.AutomatonCreator; import net.automatalib.automaton.MutableAutomaton; import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions; import net.automatalib.automaton.concept.StateIDs; import net.automatalib.automaton.impl.MutableAutomatonTest; import org.checkerframework.checker.nullness.qual.Nullable; @@ -79,7 +80,7 @@ protected , S, I, T, SP, TP> M creat private static class MockUp implements MutableDeterministic { final MutableDeterministic delegate; - final MutableDeterministic.FullIntAbstraction abstraction; + final MutableDeterministicAbstractions.FullIntAbstraction abstraction; final StateIDs stateIDs; final Alphabet alphabet; @@ -123,18 +124,18 @@ public S getSuccessor(T transition) { @Override public @Nullable S getSuccessor(S state, I input) { int succ = abstraction.getSuccessor(stateIDs.getStateId(state), alphabet.getSymbolIndex(input)); - return succ == FullIntAbstraction.INVALID_STATE ? null : stateIDs.getState(succ); + return succ == MutableDeterministicAbstractions.FullIntAbstraction.INVALID_STATE ? null : stateIDs.getState(succ); } @Override public @Nullable S getInitialState() { final int intInitial = abstraction.getIntInitialState(); - return intInitial == FullIntAbstraction.INVALID_STATE ? null : stateIDs.getState(intInitial); + return intInitial == MutableDeterministicAbstractions.FullIntAbstraction.INVALID_STATE ? null : stateIDs.getState(intInitial); } @Override public void setInitialState(@Nullable S state) { - abstraction.setInitialState(state == null ? FullIntAbstraction.INVALID_STATE : stateIDs.getStateId(state)); + abstraction.setInitialState(state == null ? MutableDeterministicAbstractions.FullIntAbstraction.INVALID_STATE : stateIDs.getStateId(state)); } @Override diff --git a/core/src/test/java/net/automatalib/automaton/abstraction/impl/MutableStateIntAbstractionTest.java b/core/src/test/java/net/automatalib/automaton/abstraction/impl/MutableStateIntAbstractionTest.java index b0c4530a5..f379313ed 100644 --- a/core/src/test/java/net/automatalib/automaton/abstraction/impl/MutableStateIntAbstractionTest.java +++ b/core/src/test/java/net/automatalib/automaton/abstraction/impl/MutableStateIntAbstractionTest.java @@ -23,6 +23,7 @@ import net.automatalib.automaton.AutomatonCreator; import net.automatalib.automaton.MutableAutomaton; import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions; import net.automatalib.automaton.concept.StateIDs; import net.automatalib.automaton.impl.MutableAutomatonTest; import org.checkerframework.checker.nullness.qual.Nullable; @@ -80,7 +81,7 @@ protected , S, I, T, SP, TP> M creat private static class MockUp implements MutableDeterministic { final MutableDeterministic delegate; - final MutableDeterministic.StateIntAbstraction abstraction; + final MutableDeterministicAbstractions.StateIntAbstraction abstraction; final StateIDs stateIDs; final Alphabet alphabet; @@ -124,18 +125,24 @@ public S getSuccessor(T transition) { @Override public @Nullable S getSuccessor(S state, I input) { int succ = abstraction.getSuccessor(stateIDs.getStateId(state), input); - return succ == StateIntAbstraction.INVALID_STATE ? null : stateIDs.getState(succ); + return succ == MutableDeterministicAbstractions.StateIntAbstraction.INVALID_STATE ? + null : + stateIDs.getState(succ); } @Override public @Nullable S getInitialState() { final int intInitial = abstraction.getIntInitialState(); - return intInitial == StateIntAbstraction.INVALID_STATE ? null : stateIDs.getState(intInitial); + return intInitial == MutableDeterministicAbstractions.StateIntAbstraction.INVALID_STATE ? + null : + stateIDs.getState(intInitial); } @Override public void setInitialState(@Nullable S state) { - abstraction.setInitialState(state == null ? StateIntAbstraction.INVALID_STATE : stateIDs.getStateId(state)); + abstraction.setInitialState(state == null ? + MutableDeterministicAbstractions.StateIntAbstraction.INVALID_STATE : + stateIDs.getStateId(state)); } @Override diff --git a/core/src/test/java/net/automatalib/automaton/abstraction/impl/SimpleAutomatonAbstractionTest.java b/core/src/test/java/net/automatalib/automaton/abstraction/impl/SimpleAutomatonAbstractionTest.java index 237c4e747..e8ef44e98 100644 --- a/core/src/test/java/net/automatalib/automaton/abstraction/impl/SimpleAutomatonAbstractionTest.java +++ b/core/src/test/java/net/automatalib/automaton/abstraction/impl/SimpleAutomatonAbstractionTest.java @@ -19,9 +19,9 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Symbol; +import net.automatalib.automaton.abstraction.SimpleDeterministicAbstractions.FullIntAbstraction; +import net.automatalib.automaton.abstraction.SimpleDeterministicAbstractions.StateIntAbstraction; import net.automatalib.automaton.simple.SimpleDeterministicAutomaton; -import net.automatalib.automaton.simple.SimpleDeterministicAutomaton.FullIntAbstraction; -import net.automatalib.automaton.simple.SimpleDeterministicAutomaton.StateIntAbstraction; import net.automatalib.automaton.transducer.impl.CompactMealy; import net.automatalib.automaton.util.TestUtil; import org.checkerframework.checker.nullness.qual.Nullable; diff --git a/core/src/test/java/net/automatalib/automaton/abstraction/impl/UniversalAutomatonAbstractionTest.java b/core/src/test/java/net/automatalib/automaton/abstraction/impl/UniversalAutomatonAbstractionTest.java index 1b7a14968..a6da56bd3 100644 --- a/core/src/test/java/net/automatalib/automaton/abstraction/impl/UniversalAutomatonAbstractionTest.java +++ b/core/src/test/java/net/automatalib/automaton/abstraction/impl/UniversalAutomatonAbstractionTest.java @@ -20,8 +20,8 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Symbol; import net.automatalib.automaton.UniversalDeterministicAutomaton; -import net.automatalib.automaton.UniversalDeterministicAutomaton.FullIntAbstraction; -import net.automatalib.automaton.UniversalDeterministicAutomaton.StateIntAbstraction; +import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.FullIntAbstraction; +import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.StateIntAbstraction; import net.automatalib.automaton.impl.CompactTransition; import net.automatalib.automaton.transducer.impl.CompactMealy; import net.automatalib.automaton.util.TestUtil; diff --git a/core/src/test/java/net/automatalib/automaton/impl/DynamicStateMappingTest.java b/core/src/test/java/net/automatalib/automaton/impl/DynamicStateMappingTest.java index c021f8427..0f5a8a6df 100644 --- a/core/src/test/java/net/automatalib/automaton/impl/DynamicStateMappingTest.java +++ b/core/src/test/java/net/automatalib/automaton/impl/DynamicStateMappingTest.java @@ -18,8 +18,9 @@ import java.util.ArrayList; import java.util.List; +import net.automatalib.automaton.MutableAutomaton; import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.automaton.ShrinkableAutomaton; +import net.automatalib.automaton.concept.Shrinkable; import net.automatalib.automaton.transducer.impl.CompactMealy; import net.automatalib.automaton.util.TestUtil; import net.automatalib.common.util.mapping.MutableMapping; @@ -43,7 +44,7 @@ public void testDeterministic() { testAutomaton(TestUtil.constructMealy(CompactMealy::new)); } - private static void testShrinkableAutomaton(ShrinkableAutomaton automaton) { + private static & MutableAutomaton> void testShrinkableAutomaton(M automaton) { final List states = new ArrayList<>(automaton.getStates()); diff --git a/examples/src/main/java/net/automatalib/example/Example.java b/examples/src/main/java/net/automatalib/example/Example.java new file mode 100644 index 000000000..5c2a70515 --- /dev/null +++ b/examples/src/main/java/net/automatalib/example/Example.java @@ -0,0 +1,32 @@ +package net.automatalib.example; + +import net.automatalib.alphabet.impl.Alphabets; +import net.automatalib.automaton.fsa.impl.CompactDFA; +import net.automatalib.automaton.fsa.impl.CompactNFA; +import net.automatalib.automaton.mmlt.impl.CompactMMLT; +import net.automatalib.automaton.mmlt.impl.StringSymbolCombiner; +import net.automatalib.automaton.transducer.impl.CompactMealy; +import net.automatalib.semantics.DeterministicFiniteSemantics; +import net.automatalib.util.automaton.Automata; + +public class Example { + + public static void main(String[] args) { + + var alphabet = Alphabets.integers(1,3); + + var dfa = new CompactDFA<>(alphabet); + var nfa = new CompactNFA<>(alphabet); + var mealy = new CompactMealy<>(alphabet); + var mmlt = new CompactMMLT<>(alphabet, "", StringSymbolCombiner.getInstance()); + + Automata.findSeparatingWord(nfa, nfa, alphabet); + Automata.findSeparatingWord(nfa, dfa, alphabet); + Automata.findSeparatingWord(dfa, dfa, alphabet); + Automata.findSeparatingWord(dfa, mealy, alphabet); + Automata.findSeparatingWord(mealy, mealy, alphabet); + Automata.findSeparatingWord(mealy, mmlt, alphabet); + Automata.findSeparatingWord(mealy, DeterministicFiniteSemantics.fromAutomaton(mmlt), alphabet); + } + +} diff --git a/util/src/main/java/net/automatalib/util/automaton/Automata.java b/util/src/main/java/net/automatalib/util/automaton/Automata.java index 0b0f87f8b..aa011b1df 100644 --- a/util/src/main/java/net/automatalib/util/automaton/Automata.java +++ b/util/src/main/java/net/automatalib/util/automaton/Automata.java @@ -24,11 +24,15 @@ import net.automatalib.automaton.DeterministicAutomaton; import net.automatalib.automaton.MutableDeterministic; import net.automatalib.automaton.UniversalDeterministicAutomaton; +import net.automatalib.automaton.concept.FinSem; import net.automatalib.automaton.graph.TransitionEdge; import net.automatalib.common.util.array.ArrayStorage; import net.automatalib.common.util.collection.CollectionUtil; import net.automatalib.graph.Graph; import net.automatalib.graph.UniversalGraph; +import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; +import net.automatalib.semantics.DeterministicFiniteSemantics.SimpleSemantics; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.util.automaton.equivalence.CharacterizingSets; import net.automatalib.util.automaton.equivalence.DeterministicEquivalenceTest; @@ -152,8 +156,10 @@ public static Graph> asGraph(Automaton> A invasiveMinimize(A automaton, - Collection inputs) { + public static > A invasiveMinimize(A semantics, + Collection inputs) { + + MutableDeterministic automaton = semantics.getSemantics(); final List inputList = CollectionUtil.randomAccessList(inputs); @@ -225,13 +231,13 @@ public static > automaton.addTransition(state, input, succ, transRec.property); } } - return automaton; + return semantics; } /** * Tests whether two automata are equivalent, i.e. whether there exists a - * {@link #findSeparatingWord(UniversalDeterministicAutomaton, UniversalDeterministicAutomaton, Collection) - * separating word} for the two given automata. + * {@link #findSeparatingWord(UniversalSemantics, UniversalSemantics, Collection) separating word} for the two given + * automata. * * @param * input symbol type @@ -244,10 +250,10 @@ public static > * * @return {@code true} if the automata are equivalent, {@code false} otherwise. * - * @see #findSeparatingWord(UniversalDeterministicAutomaton, UniversalDeterministicAutomaton, Collection) + * @see #findSeparatingWord(UniversalSemantics, UniversalSemantics, Collection) */ - public static boolean testEquivalence(UniversalDeterministicAutomaton reference, - UniversalDeterministicAutomaton other, + public static boolean testEquivalence(UniversalSemantics reference, + UniversalSemantics other, Collection inputs) { return findSeparatingWord(reference, other, inputs) == null; } @@ -267,9 +273,9 @@ public static boolean testEquivalence(UniversalDeterministicAutomaton @Nullable Word findSeparatingWord(UniversalDeterministicAutomaton reference, - UniversalDeterministicAutomaton other, - Collection inputs) { + public static & FinSem> @Nullable Word findSeparatingWord(A reference, + A other, + Collection inputs) { return NearLinearEquivalenceTest.findSeparatingWord(reference, other, inputs); } @@ -293,7 +299,7 @@ public static boolean testEquivalence(UniversalDeterministicAutomaton @Nullable Word findSeparatingWord(UniversalDeterministicAutomaton automaton, + public static @Nullable Word findSeparatingWord(UniversalSemantics automaton, S state1, S state2, Collection inputs) { @@ -316,8 +322,8 @@ public static boolean testEquivalence(UniversalDeterministicAutomaton @Nullable Word findShortestSeparatingWord(UniversalDeterministicAutomaton reference, - UniversalDeterministicAutomaton other, + public static @Nullable Word findShortestSeparatingWord(UniversalSemantics reference, + UniversalSemantics other, Collection inputs) { return DeterministicEquivalenceTest.findSeparatingWord(reference, other, inputs); } @@ -336,7 +342,7 @@ public static boolean testEquivalence(UniversalDeterministicAutomaton List> characterizingSet(UniversalDeterministicAutomaton automaton, + public static List> characterizingSet(UniversalSemantics automaton, Collection inputs) { List> result = new ArrayList<>(); characterizingSet(automaton, inputs, result); @@ -347,7 +353,7 @@ public static List> characterizingSet(UniversalDeterministicAutomato * Computes a characterizing set for the given automaton. *

* This is a convenience method acting as a shortcut to - * {@link CharacterizingSets#findCharacterizingSet(UniversalDeterministicAutomaton, Collection, Collection)}. + * {@link CharacterizingSets#findCharacterizingSet(UniversalSemantics, Collection, Collection)}. * * @param * input symbol type @@ -360,13 +366,13 @@ public static List> characterizingSet(UniversalDeterministicAutomato * * @see CharacterizingSets */ - public static void characterizingSet(UniversalDeterministicAutomaton automaton, + public static void characterizingSet(UniversalSemantics automaton, Collection inputs, Collection> result) { CharacterizingSets.findCharacterizingSet(automaton, inputs, result); } - public static boolean incrementalCharacterizingSet(UniversalDeterministicAutomaton automaton, + public static boolean incrementalCharacterizingSet(UniversalSemantics automaton, Collection inputs, Collection> oldSuffixes, Collection> newSuffixes) { @@ -391,7 +397,7 @@ public static boolean incrementalCharacterizingSet(UniversalDeterministicAut * * @see CharacterizingSets */ - public static List> stateCharacterizingSet(UniversalDeterministicAutomaton automaton, + public static List> stateCharacterizingSet(UniversalSemantics automaton, Collection inputs, S state) { List> result = new ArrayList<>(); @@ -403,8 +409,7 @@ public static List> stateCharacterizingSet(UniversalDeterministic * Computes a characterizing set for a single state. *

* Supports incremental computation, i.e. given a set of cover traces, only sequences for states not covered by these * traces are returned. diff --git a/util/src/main/java/net/automatalib/util/automaton/equivalence/Bisimulation.java b/util/src/main/java/net/automatalib/util/automaton/equivalence/Bisimulation.java index afa07e05e..1331bd87f 100644 --- a/util/src/main/java/net/automatalib/util/automaton/equivalence/Bisimulation.java +++ b/util/src/main/java/net/automatalib/util/automaton/equivalence/Bisimulation.java @@ -24,6 +24,7 @@ import net.automatalib.automaton.concept.StateIDs; import net.automatalib.common.util.Pair; import net.automatalib.common.util.collection.CollectionUtil; +import net.automatalib.semantics.FiniteSemantics.SimpleSemantics; import net.automatalib.util.partitionrefinement.Valmari; import net.automatalib.util.partitionrefinement.Valmari.RefinablePartition; @@ -33,9 +34,15 @@ private Bisimulation() { // prevent instantiation } - public static Set> bisimulationEquivalenceRelation(Automaton a, - Automaton b, - Collection inputs) { + public static Set> bisimulationEquivalenceRelation(SimpleSemantics a, + SimpleSemantics b, + Collection inputs) { + return bisimulationEquivalenceRelation(a.getSemantics(), b.getSemantics(), inputs); + } + + private static Set> bisimulationEquivalenceRelation(Automaton a, + Automaton b, + Collection inputs) { final List alphabet = CollectionUtil.randomAccessList(inputs); final StateIDs aIDs = a.stateIDs(); diff --git a/util/src/main/java/net/automatalib/util/automaton/equivalence/CharacterizingSets.java b/util/src/main/java/net/automatalib/util/automaton/equivalence/CharacterizingSets.java index 6f214d6de..64af4cabc 100644 --- a/util/src/main/java/net/automatalib/util/automaton/equivalence/CharacterizingSets.java +++ b/util/src/main/java/net/automatalib/util/automaton/equivalence/CharacterizingSets.java @@ -30,6 +30,7 @@ import net.automatalib.automaton.fsa.FiniteStateAcceptor; import net.automatalib.common.util.collection.AbstractSimplifiedIterator; import net.automatalib.common.util.collection.CollectionUtil; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.Automata; import net.automatalib.word.Word; import org.checkerframework.checker.nullness.qual.NonNull; @@ -55,7 +56,7 @@ private CharacterizingSets() {} /** * Computes a characterizing set for the given automaton. * - * @param automaton + * @param semantics * the automaton for which to determine the characterizing set. * @param inputs * the input alphabets to consider @@ -64,16 +65,16 @@ private CharacterizingSets() {} * @param * input symbol type */ - public static void findCharacterizingSet(UniversalDeterministicAutomaton automaton, + public static void findCharacterizingSet(UniversalSemantics semantics, Collection inputs, Collection> result) { - findIncrementalCharacterizingSet(automaton, inputs, Collections.emptyList(), result); + findIncrementalCharacterizingSet(semantics, inputs, Collections.emptyList(), result); } /** * Computes a characterizing set for a specified state in the given automaton. * - * @param automaton + * @param semantics * the automaton containing the state * @param inputs * the input alphabets to consider @@ -86,11 +87,13 @@ public static void findCharacterizingSet(UniversalDeterministicAutomaton * input symbol type */ - public static void findCharacterizingSet(UniversalDeterministicAutomaton automaton, + public static void findCharacterizingSet(UniversalSemantics semantics, Collection inputs, S state, Collection> result) { + UniversalDeterministicAutomaton automaton = semantics.getSemantics(); + Object prop = automaton.getStateProperty(state); List currentBlock = new ArrayList<>(); @@ -120,7 +123,7 @@ public static void findCharacterizingSet(UniversalDeterministicAutomaton< Word suffix = null; while (it.hasNext() && suffix == null) { S s = it.next(); - suffix = Automata.findSeparatingWord(automaton, state, s, inputs); + suffix = Automata.findSeparatingWord(semantics, state, s, inputs); } if (suffix == null) { @@ -143,9 +146,9 @@ public static void findCharacterizingSet(UniversalDeterministicAutomaton< } } - public static Iterator> characterizingSetIterator(UniversalDeterministicAutomaton automaton, - Collection inputs) { - return new IncrementalCharacterizingSetIterator<>(automaton, inputs, Collections.emptyList()); + public static Iterator> characterizingSetIterator(UniversalSemantics semantics, + Collection inputs) { + return new IncrementalCharacterizingSetIterator<>(semantics, inputs, Collections.emptyList()); } private static List buildTrace(UniversalDeterministicAutomaton automaton, @@ -216,11 +219,13 @@ private static boolean checkTrace(UniversalDeterministicAut return true; } - public static boolean findIncrementalCharacterizingSet(UniversalDeterministicAutomaton automaton, + public static boolean findIncrementalCharacterizingSet(UniversalSemantics semantics, Collection inputs, Collection> oldSuffixes, Collection> newSuffixes) { + UniversalDeterministicAutomaton automaton = semantics.getSemantics(); + boolean refined = false; // We need a list to ensure a stable iteration order @@ -235,7 +240,7 @@ public static boolean findIncrementalCharacterizingSet(UniversalDetermini Word suffix; - while ((suffix = refine(automaton, inputs, blocks)) != null) { + while ((suffix = refine(semantics, automaton, inputs, blocks)) != null) { newSuffixes.add(suffix); refined = true; } @@ -243,10 +248,10 @@ public static boolean findIncrementalCharacterizingSet(UniversalDetermini return refined; } - public static Iterator> incrementalCharacterizingSetIterator(UniversalDeterministicAutomaton automaton, - Collection inputs, - Collection> oldSuffixes) { - return new IncrementalCharacterizingSetIterator<>(automaton, inputs, oldSuffixes); + public static Iterator> incrementalCharacterizingSetIterator(UniversalSemantics semantics, + Collection inputs, + Collection> oldSuffixes) { + return new IncrementalCharacterizingSetIterator<>(semantics, inputs, oldSuffixes); } private static Queue> buildInitialBlocks(UniversalDeterministicAutomaton automaton, @@ -303,7 +308,8 @@ private static boolean epsilonRefine(UniversalDeterministicAutomaton @Nullable Word refine(UniversalDeterministicAutomaton automaton, + private static @Nullable Word refine(UniversalSemantics semantics, + UniversalDeterministicAutomaton automaton, Collection inputs, Queue> blockQueue) { @@ -321,7 +327,7 @@ private static boolean epsilonRefine(UniversalDeterministicAutomaton void cluster(UniversalDeterministicAutomaton extends AbstractSimplifiedIterator> { + private final UniversalSemantics semantics; private final UniversalDeterministicAutomaton automaton; private final Collection inputs; private final List> oldSuffixes; private Queue> blocks; - IncrementalCharacterizingSetIterator(UniversalDeterministicAutomaton automaton, + IncrementalCharacterizingSetIterator(UniversalSemantics semantics, Collection inputs, Collection> oldSuffixes) { - this.automaton = automaton; + this.semantics = semantics; + this.automaton = semantics.getSemantics(); this.inputs = inputs; this.oldSuffixes = CollectionUtil.randomAccessList(oldSuffixes); } @@ -409,7 +417,7 @@ protected boolean calculateNext() { } } - final Word suffix = refine(automaton, inputs, blocks); + final Word suffix = refine(semantics, automaton, inputs, blocks); if (suffix != null) { super.nextValue = suffix; diff --git a/util/src/main/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTest.java b/util/src/main/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTest.java index 6ff7d6998..00e09f423 100644 --- a/util/src/main/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTest.java +++ b/util/src/main/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTest.java @@ -24,6 +24,7 @@ import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.concept.StateIDs; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.word.Word; import net.automatalib.word.WordBuilder; import org.checkerframework.checker.nullness.qual.NonNull; @@ -38,8 +39,14 @@ private DeterministicEquivalenceTest() { // prevent instantiation } + public static @Nullable Word findSeparatingWord(UniversalSemantics reference, + UniversalSemantics other, + Collection inputs) { + return findSeparatingWord(reference.getSemantics(), other.getSemantics(), inputs); + } + @SuppressWarnings("PMD.UnnecessaryCast") // we want to cast to long, to prevent overflows - public static @Nullable Word findSeparatingWord( + private static @Nullable Word findSeparatingWord( UniversalDeterministicAutomaton reference, UniversalDeterministicAutomaton other, Collection inputs) { diff --git a/util/src/main/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTest.java b/util/src/main/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTest.java index 1b59e26b4..65748dac9 100644 --- a/util/src/main/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTest.java +++ b/util/src/main/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTest.java @@ -22,10 +22,13 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.UniversalDeterministicAutomaton; +import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.FullIntAbstraction; +import net.automatalib.automaton.concept.FinSem; import net.automatalib.automaton.concept.InputAlphabetHolder; import net.automatalib.automaton.concept.StateIDs; import net.automatalib.common.util.IntDisjointSets; import net.automatalib.common.util.UnionFindRemSP; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.word.Word; import net.automatalib.word.WordBuilder; import org.checkerframework.checker.nullness.qual.Nullable; @@ -41,10 +44,11 @@ private NearLinearEquivalenceTest() { // prevent instantiation } - public static @Nullable Word findSeparatingWord(UniversalDeterministicAutomaton target, - S init1, - S init2, - Collection inputs) { + public static & FinSem> @Nullable Word findSeparatingWord( + A target, + S init1, + S init2, + Collection inputs) { return findSeparatingWord(target, init1, init2, inputs, false); } @@ -71,11 +75,12 @@ private NearLinearEquivalenceTest() { * * @return A word separating the two states, {@code null} if no such word can be found */ - public static @Nullable Word findSeparatingWord(UniversalDeterministicAutomaton target, - S init1, - S init2, - Collection inputs, - boolean ignoreUndefinedTransitions) { + public static & FinSem> @Nullable Word findSeparatingWord( + A target, + S init1, + S init2, + Collection inputs, + boolean ignoreUndefinedTransitions) { Object sprop1 = target.getStateProperty(init1); Object sprop2 = target.getStateProperty(init2); @@ -173,13 +178,20 @@ private NearLinearEquivalenceTest() { return wb.toWord(); } - public static @Nullable Word findSeparatingWord(UniversalDeterministicAutomaton target, - UniversalDeterministicAutomaton other, + public static @Nullable Word findSeparatingWord(UniversalSemantics target, + UniversalSemantics other, Collection inputs) { return findSeparatingWord(target, other, inputs, false); } - public static @Nullable Word findSeparatingWord( + public static @Nullable Word findSeparatingWord(UniversalSemantics target, + UniversalSemantics other, + Collection inputs, + boolean ignoreUndefinedTransitions) { + return findSeparatingWord(target.getSemantics(), other.getSemantics(), inputs, ignoreUndefinedTransitions); + } + + private static @Nullable Word findSeparatingWord( UniversalDeterministicAutomaton target, UniversalDeterministicAutomaton other, Collection inputs, @@ -305,19 +317,27 @@ private NearLinearEquivalenceTest() { return wb.toWord(); } - public static @Nullable Word findSeparatingWord(UniversalDeterministicAutomaton target, - UniversalDeterministicAutomaton other, + public static @Nullable Word findSeparatingWord(UniversalSemantics target, + UniversalSemantics other, Alphabet inputs) { return findSeparatingWord(target, other, inputs, false); } - public static @Nullable Word findSeparatingWord( + public static @Nullable Word findSeparatingWord(UniversalSemantics target, + UniversalSemantics other, + Alphabet inputs, + boolean ignoreUndefinedTransitions) { + return findSeparatingWord(target.getSemantics(), other.getSemantics(), inputs, ignoreUndefinedTransitions); + } + + private static @Nullable Word findSeparatingWord( UniversalDeterministicAutomaton target, UniversalDeterministicAutomaton other, Alphabet inputs, boolean ignoreUndefinedTransitions) { - UniversalDeterministicAutomaton.FullIntAbstraction absTarget = target.fullIntAbstraction(inputs); - UniversalDeterministicAutomaton.FullIntAbstraction absOther = other.fullIntAbstraction(inputs); + + FullIntAbstraction absTarget = target.fullIntAbstraction(inputs); + FullIntAbstraction absOther = other.fullIntAbstraction(inputs); int init1 = absTarget.getIntInitialState(); int init2 = absOther.getIntInitialState(); @@ -430,7 +450,8 @@ private static final class Record { private final @Nullable Record reachedFrom; private final int depth; - @SuppressWarnings("nullness") // we will only access reachedBy after checking reachedFrom for null + @SuppressWarnings("nullness") + // we will only access reachedBy after checking reachedFrom for null Record(S state1, S2 state2) { this(state1, state2, null, null); } diff --git a/util/src/main/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizer.java b/util/src/main/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizer.java index c2673baed..ef7119288 100644 --- a/util/src/main/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizer.java +++ b/util/src/main/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizer.java @@ -21,14 +21,14 @@ import net.automatalib.alphabet.impl.Alphabets; import net.automatalib.automaton.AutomatonCreator; import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.automaton.MutableDeterministic.IntAbstraction; import net.automatalib.automaton.UniversalDeterministicAutomaton; -import net.automatalib.automaton.UniversalDeterministicAutomaton.FullIntAbstraction; +import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions; +import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.FullIntAbstraction; import net.automatalib.automaton.concept.InputAlphabetHolder; import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.fsa.MutableDFA; import net.automatalib.automaton.fsa.impl.CompactDFA; -import net.automatalib.automaton.impl.UniversalCompactDet; +import net.automatalib.automaton.impl.UniversalCompactDetAutomaton; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.MutableMealyMachine; import net.automatalib.automaton.transducer.impl.CompactMealy; @@ -486,8 +486,8 @@ public static CompactMealy minimizePartialMealy(MealyMachine UniversalCompactDet minimizeUniversal(UniversalDeterministicAutomaton automaton, - Alphabet alphabet) { + public static UniversalCompactDetAutomaton minimizeUniversal(UniversalDeterministicAutomaton automaton, + Alphabet alphabet) { return minimizeUniversal(automaton, alphabet, PruningMode.PRUNE_AFTER); } @@ -509,9 +509,9 @@ public static UniversalCompactDet minimizeUniversal(Unive * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static UniversalCompactDet minimizeUniversal(UniversalDeterministicAutomaton automaton, - Alphabet alphabet, - PruningMode pruningMode) { + public static UniversalCompactDetAutomaton minimizeUniversal(UniversalDeterministicAutomaton automaton, + Alphabet alphabet, + PruningMode pruningMode) { return minimizeUniversal(automaton, alphabet, pruningMode, AutomatonInitialPartitioning.BY_FULL_SIGNATURE); } @@ -535,11 +535,11 @@ public static UniversalCompactDet minimizeUniversal(Unive * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static UniversalCompactDet minimizeUniversal(UniversalDeterministicAutomaton automaton, - Alphabet alphabet, - PruningMode pruningMode, - AutomatonInitialPartitioning ip) { - return minimizeUniversal(automaton, alphabet, pruningMode, ip, new UniversalCompactDet.Creator<>()); + public static UniversalCompactDetAutomaton minimizeUniversal(UniversalDeterministicAutomaton automaton, + Alphabet alphabet, + PruningMode pruningMode, + AutomatonInitialPartitioning ip) { + return minimizeUniversal(automaton, alphabet, pruningMode, ip, new UniversalCompactDetAutomaton.Creator<>()); } /** @@ -658,8 +658,9 @@ public static UniversalCompactDet minimizeUniversal(Unive * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static UniversalCompactDet minimizePartialUniversal(UniversalDeterministicAutomaton automaton, - Alphabet alphabet) { + public static UniversalCompactDetAutomaton minimizePartialUniversal( + UniversalDeterministicAutomaton automaton, + Alphabet alphabet) { return minimizePartialUniversal(automaton, alphabet, PruningMode.PRUNE_AFTER); } @@ -681,9 +682,10 @@ public static UniversalCompactDet minimizePartialUniversa * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static UniversalCompactDet minimizePartialUniversal(UniversalDeterministicAutomaton automaton, - Alphabet alphabet, - PruningMode pruningMode) { + public static UniversalCompactDetAutomaton minimizePartialUniversal( + UniversalDeterministicAutomaton automaton, + Alphabet alphabet, + PruningMode pruningMode) { return minimizePartialUniversal(automaton, alphabet, @@ -714,18 +716,19 @@ public static UniversalCompactDet minimizePartialUniversa * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static UniversalCompactDet minimizePartialUniversal(UniversalDeterministicAutomaton automaton, - Alphabet alphabet, - PruningMode pruningMode, - AutomatonInitialPartitioning ip, - Object sinkClassification) { + public static UniversalCompactDetAutomaton minimizePartialUniversal( + UniversalDeterministicAutomaton automaton, + Alphabet alphabet, + PruningMode pruningMode, + AutomatonInitialPartitioning ip, + Object sinkClassification) { return minimizePartialUniversal(automaton, alphabet, pruningMode, ip, sinkClassification, - new UniversalCompactDet.Creator<>()); + new UniversalCompactDetAutomaton.Creator<>()); } /** @@ -787,11 +790,11 @@ public static UniversalCompactDet minimizePartialUniversa Storage spStorage, Storage tpStorage) { - final MutableDeterministic.FullIntAbstraction abs = + final MutableDeterministicAbstractions.FullIntAbstraction abs = automaton.fullIntAbstraction(Alphabets.fromCollection(alphabet)); final int init = abs.getIntInitialState(); - if (init == IntAbstraction.INVALID_STATE) { + if (init == MutableDeterministicAbstractions.IntAbstraction.INVALID_STATE) { automaton.clear(); return automaton; } diff --git a/util/src/main/java/net/automatalib/util/automaton/procedural/ProceduralUtil.java b/util/src/main/java/net/automatalib/util/automaton/procedural/ProceduralUtil.java index a6c340d0b..0daaf548e 100644 --- a/util/src/main/java/net/automatalib/util/automaton/procedural/ProceduralUtil.java +++ b/util/src/main/java/net/automatalib/util/automaton/procedural/ProceduralUtil.java @@ -29,8 +29,8 @@ import java.util.function.BiPredicate; import net.automatalib.alphabet.ProceduralInputAlphabet; -import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.common.util.HashUtil; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.Automata; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.word.Word; @@ -43,9 +43,9 @@ private ProceduralUtil() { // prevent instantiation } - static > Map> computeTerminatingSequences(Map procedures, - ProceduralInputAlphabet alphabet, - BiPredicate> tracePredicate) { + static > Map> computeTerminatingSequences(Map procedures, + ProceduralInputAlphabet alphabet, + BiPredicate> tracePredicate) { final Map> terminatingSequences = new HashMap<>(HashUtil.capacity(alphabet.getNumCalls())); @@ -103,12 +103,12 @@ private ProceduralUtil() { return terminatingSequences; } - static > Map> computeAccessSequences(Map procedures, - ProceduralInputAlphabet alphabet, - Collection proceduralInputs, - @Nullable I initialProcedure, - Map> terminatingSequences, - BiPredicate> transitionPredicate) { + static > Map> computeAccessSequences(Map procedures, + ProceduralInputAlphabet alphabet, + Collection proceduralInputs, + @Nullable I initialProcedure, + Map> terminatingSequences, + BiPredicate> transitionPredicate) { if (initialProcedure == null) { return Collections.emptyMap(); @@ -116,7 +116,7 @@ private ProceduralUtil() { final M initialP = procedures.get(initialProcedure); - if (initialP == null || initialP.getInitialState() == null) { + if (initialP == null || initialP.getSemantics().getInitialState() == null) { return Collections.emptyMap(); } @@ -150,7 +150,7 @@ private ProceduralUtil() { return accessSequences; } - private static > Collection discoverAccessSequences( + private static > Collection discoverAccessSequences( ProceduralInputAlphabet alphabet, Collection proceduralInputs, I procedure, @@ -193,11 +193,11 @@ private ProceduralUtil() { return newAS; } - static > @Nullable Word findSeparatingWord(Map sys1, - ATSequences at1, - Map sys2, - ATSequences at2, - ProceduralInputAlphabet alphabet) { + static > @Nullable Word findSeparatingWord(Map sys1, + ATSequences at1, + Map sys2, + ATSequences at2, + ProceduralInputAlphabet alphabet) { for (I procedure : alphabet.getCallAlphabet()) { final M p1 = sys1.get(procedure); final M p2 = sys2.get(procedure); diff --git a/util/src/main/java/net/automatalib/util/automaton/random/RandomICAutomatonGenerator.java b/util/src/main/java/net/automatalib/util/automaton/random/RandomICAutomatonGenerator.java index 542178d16..fb34a82ee 100644 --- a/util/src/main/java/net/automatalib/util/automaton/random/RandomICAutomatonGenerator.java +++ b/util/src/main/java/net/automatalib/util/automaton/random/RandomICAutomatonGenerator.java @@ -27,6 +27,7 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.AutomatonCreator; import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions.StateIntAbstraction; import net.automatalib.common.util.collection.CollectionUtil; import net.automatalib.common.util.random.RandomUtil; import org.checkerframework.checker.nullness.qual.Nullable; @@ -261,7 +262,7 @@ public RandomICAutomatonGenerator withTransitionProperties(Collection inputs, A result, Random r) { - MutableDeterministic.StateIntAbstraction resultAbs = result.stateIntAbstraction(); + StateIntAbstraction resultAbs = result.stateIntAbstraction(); List inputsList = CollectionUtil.randomAccessList(inputs); diff --git a/util/src/main/java/net/automatalib/util/partitionrefinement/AutomatonInitialPartitioning.java b/util/src/main/java/net/automatalib/util/partitionrefinement/AutomatonInitialPartitioning.java index 52e9f8ef8..1ef23bc39 100644 --- a/util/src/main/java/net/automatalib/util/partitionrefinement/AutomatonInitialPartitioning.java +++ b/util/src/main/java/net/automatalib/util/partitionrefinement/AutomatonInitialPartitioning.java @@ -19,7 +19,7 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.UniversalDeterministicAutomaton; -import net.automatalib.automaton.UniversalDeterministicAutomaton.FullIntAbstraction; +import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.FullIntAbstraction; /** * This enum allows to conveniently specify how the states of a deterministic automaton are initially partitioned when @@ -32,7 +32,7 @@ public enum AutomatonInitialPartitioning { */ BY_STATE_PROPERTY { @Override - public IntFunction initialClassifier(UniversalDeterministicAutomaton.FullIntAbstraction automaton) { + public IntFunction initialClassifier(FullIntAbstraction automaton) { return automaton::getStateProperty; } }, @@ -51,7 +51,7 @@ public IntFunction initialClassifier(UniversalDeterministicAutomaton.FullIntA */ BY_TRANSITION_PROPERTIES { @Override - public IntFunction initialClassifier(UniversalDeterministicAutomaton.FullIntAbstraction automaton) { + public IntFunction initialClassifier(FullIntAbstraction automaton) { return s -> StateSignature.byTransitionProperties(automaton, s); } }, @@ -70,11 +70,11 @@ public IntFunction initialClassifier(UniversalDeterministicAutomaton.FullIntA */ BY_FULL_SIGNATURE { @Override - public IntFunction initialClassifier(UniversalDeterministicAutomaton.FullIntAbstraction automaton) { + public IntFunction initialClassifier(FullIntAbstraction automaton) { return s -> StateSignature.byFullSignature(automaton, s); } }; - public abstract IntFunction initialClassifier(UniversalDeterministicAutomaton.FullIntAbstraction automaton); + public abstract IntFunction initialClassifier(FullIntAbstraction automaton); } diff --git a/util/src/main/java/net/automatalib/util/partitionrefinement/HopcroftExtractors.java b/util/src/main/java/net/automatalib/util/partitionrefinement/HopcroftExtractors.java index 956c07d45..c244d4f4b 100644 --- a/util/src/main/java/net/automatalib/util/partitionrefinement/HopcroftExtractors.java +++ b/util/src/main/java/net/automatalib/util/partitionrefinement/HopcroftExtractors.java @@ -21,7 +21,8 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.AutomatonCreator; import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.automaton.simple.SimpleDeterministicAutomaton; +import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions.FullIntAbstraction; +import net.automatalib.automaton.abstraction.SimpleDeterministicAbstractions; import net.automatalib.common.util.function.BiIntFunction; /** @@ -67,7 +68,7 @@ private HopcroftExtractors() {} public static > A toDeterministic(Hopcroft hopcroft, AutomatonCreator creator, Alphabet inputs, - SimpleDeterministicAutomaton.FullIntAbstraction abs, + SimpleDeterministicAbstractions.FullIntAbstraction abs, IntFunction spExtractor, BiIntFunction tpExtractor, boolean pruneUnreachable) { @@ -79,7 +80,7 @@ private HopcroftExtractors() {} private static > A toDeterministicPruned(Hopcroft hopcroft, AutomatonCreator creator, Alphabet inputs, - SimpleDeterministicAutomaton.FullIntAbstraction abs, + SimpleDeterministicAbstractions.FullIntAbstraction abs, IntFunction spExtractor, BiIntFunction tpExtractor) { @@ -90,7 +91,7 @@ private HopcroftExtractors() {} Arrays.fill(stateMap, -1); A result = creator.createAutomaton(inputs, numBlocks); - MutableDeterministic.FullIntAbstraction resultAbs = result.fullIntAbstraction(inputs); + FullIntAbstraction resultAbs = result.fullIntAbstraction(inputs); int origInit = abs.getIntInitialState(); SP initSp = spExtractor.apply(origInit); @@ -130,7 +131,7 @@ private HopcroftExtractors() {} private static > A toDeterministicUnpruned(Hopcroft hopcroft, AutomatonCreator creator, Alphabet inputs, - SimpleDeterministicAutomaton.FullIntAbstraction abs, + SimpleDeterministicAbstractions.FullIntAbstraction abs, IntFunction spExtractor, BiIntFunction tpExtractor) { @@ -138,7 +139,7 @@ private HopcroftExtractors() {} int numInputs = inputs.size(); A result = creator.createAutomaton(inputs, numBlocks); - MutableDeterministic.FullIntAbstraction resultAbs = result.fullIntAbstraction(inputs); + FullIntAbstraction resultAbs = result.fullIntAbstraction(inputs); for (int i = 0; i < numBlocks; i++) { resultAbs.addIntState(); diff --git a/util/src/main/java/net/automatalib/util/partitionrefinement/HopcroftInitializers.java b/util/src/main/java/net/automatalib/util/partitionrefinement/HopcroftInitializers.java index 0f2cc1654..1b244f769 100644 --- a/util/src/main/java/net/automatalib/util/partitionrefinement/HopcroftInitializers.java +++ b/util/src/main/java/net/automatalib/util/partitionrefinement/HopcroftInitializers.java @@ -20,8 +20,8 @@ import java.util.Objects; import java.util.function.IntFunction; -import net.automatalib.automaton.UniversalDeterministicAutomaton; -import net.automatalib.automaton.simple.SimpleDeterministicAutomaton; +import net.automatalib.automaton.abstraction.SimpleDeterministicAbstractions; +import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.FullIntAbstraction; import net.automatalib.common.util.array.ArrayUtil; import org.checkerframework.checker.nullness.qual.Nullable; @@ -49,7 +49,7 @@ private HopcroftInitializers() {} * * @return the initialized partition refinement data structure */ - public static Hopcroft initializeComplete(UniversalDeterministicAutomaton.FullIntAbstraction abs, + public static Hopcroft initializeComplete(FullIntAbstraction abs, AutomatonInitialPartitioning ip, boolean pruneUnreachable) { return initializeComplete(abs, ip.initialClassifier(abs), pruneUnreachable); @@ -73,7 +73,7 @@ public static Hopcroft initializeComplete(UniversalDeterministicAutomaton.FullIn * * @return the initialized partition refinement data structure */ - public static Hopcroft initializeComplete(SimpleDeterministicAutomaton.FullIntAbstraction abs, + public static Hopcroft initializeComplete(SimpleDeterministicAbstractions.FullIntAbstraction abs, IntFunction initialClassification, boolean pruneUnreachable) { @@ -82,7 +82,7 @@ public static Hopcroft initializeComplete(SimpleDeterministicAutomaton.FullIntAb initializeCompleteNoPrune(abs, initialClassification); } - private static Hopcroft initializeCompletePrune(SimpleDeterministicAutomaton.FullIntAbstraction abs, + private static Hopcroft initializeCompletePrune(SimpleDeterministicAbstractions.FullIntAbstraction abs, IntFunction initialClassification) { Hopcroft pt = new Hopcroft(); @@ -157,7 +157,7 @@ private static Hopcroft initializeCompletePrune(SimpleDeterministicAutomaton.Ful return pt; } - private static Hopcroft initializeCompleteNoPrune(SimpleDeterministicAutomaton.FullIntAbstraction abs, + private static Hopcroft initializeCompleteNoPrune(SimpleDeterministicAbstractions.FullIntAbstraction abs, IntFunction initialClassification) { Hopcroft pt = new Hopcroft(); int numStates = abs.size(); @@ -214,7 +214,7 @@ private static Hopcroft initializeCompleteNoPrune(SimpleDeterministicAutomaton.F return pt; } - public static Hopcroft initializePartial(UniversalDeterministicAutomaton.FullIntAbstraction abs, + public static Hopcroft initializePartial(FullIntAbstraction abs, AutomatonInitialPartitioning ip, Object sinkClassification, boolean pruneUnreachable) { @@ -238,7 +238,7 @@ public static Hopcroft initializePartial(UniversalDeterministicAutomaton.FullInt * * @return the initialized partition refinement data structure */ - public static Hopcroft initializePartial(SimpleDeterministicAutomaton.FullIntAbstraction abs, + public static Hopcroft initializePartial(SimpleDeterministicAbstractions.FullIntAbstraction abs, IntFunction initialClassification, Object sinkClassification, boolean pruneUnreachable) { @@ -247,7 +247,7 @@ public static Hopcroft initializePartial(SimpleDeterministicAutomaton.FullIntAbs initializePartialNoPrune(abs, initialClassification, sinkClassification); } - private static Hopcroft initializePartialPrune(SimpleDeterministicAutomaton.FullIntAbstraction abs, + private static Hopcroft initializePartialPrune(SimpleDeterministicAbstractions.FullIntAbstraction abs, IntFunction initialClassification, Object sinkClassification) { @@ -366,7 +366,7 @@ private static Hopcroft initializePartialPrune(SimpleDeterministicAutomaton.Full return pt; } - private static Hopcroft initializePartialNoPrune(SimpleDeterministicAutomaton.FullIntAbstraction abs, + private static Hopcroft initializePartialNoPrune(SimpleDeterministicAbstractions.FullIntAbstraction abs, IntFunction initialClassification, Object sinkClassification) { diff --git a/util/src/main/java/net/automatalib/util/partitionrefinement/StateSignature.java b/util/src/main/java/net/automatalib/util/partitionrefinement/StateSignature.java index 6618ffd7a..633450803 100644 --- a/util/src/main/java/net/automatalib/util/partitionrefinement/StateSignature.java +++ b/util/src/main/java/net/automatalib/util/partitionrefinement/StateSignature.java @@ -19,6 +19,7 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.UniversalDeterministicAutomaton; +import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.FullIntAbstraction; import org.checkerframework.checker.nullness.qual.Nullable; /** @@ -40,7 +41,7 @@ public static StateSignature byFullSignature(SP stateProperty, TP... tr return new StateSignature(properties); } - public static StateSignature byFullSignature(UniversalDeterministicAutomaton.FullIntAbstraction automaton, + public static StateSignature byFullSignature(FullIntAbstraction automaton, int state) { int numInputs = automaton.numInputs(); @Nullable Object[] properties = new Object[numInputs + 1]; @@ -64,7 +65,7 @@ public static StateSignature byTransitionProperties(TP... properties) { return new StateSignature(properties); } - public static StateSignature byTransitionProperties(UniversalDeterministicAutomaton.FullIntAbstraction automaton, + public static StateSignature byTransitionProperties(FullIntAbstraction automaton, int state) { int numInputs = automaton.numInputs(); @Nullable Object[] properties = new Object[numInputs]; @@ -81,7 +82,7 @@ public static StateSignature byTransitionProperties(UniversalDeterministi return new StateSignature(properties); } - private static void fillTransitionProperties(UniversalDeterministicAutomaton.FullIntAbstraction automaton, + private static void fillTransitionProperties(FullIntAbstraction automaton, int state, @Nullable Object[] properties) { int numInputs = automaton.numInputs(); diff --git a/util/src/test/java/net/automatalib/util/automaton/CopyConstructorTest.java b/util/src/test/java/net/automatalib/util/automaton/CopyConstructorTest.java index 19b6dd520..2fa22fb97 100644 --- a/util/src/test/java/net/automatalib/util/automaton/CopyConstructorTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/CopyConstructorTest.java @@ -23,13 +23,13 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Alphabets; -import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.fsa.NFA; import net.automatalib.automaton.fsa.impl.CompactDFA; import net.automatalib.automaton.fsa.impl.CompactNFA; import net.automatalib.automaton.transducer.impl.CompactMealy; import net.automatalib.automaton.transducer.impl.CompactMoore; import net.automatalib.automaton.transducer.impl.CompactSST; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.copy.AutomatonCopyMethod; import net.automatalib.util.automaton.copy.AutomatonLowLevelCopy; import net.automatalib.util.automaton.fsa.NFAs; @@ -90,9 +90,9 @@ public void testSST() { testCopyConstructor(sst, INPUT_ALPHABET, CompactSST::new); } - private > void testCopyConstructor(A automaton, - Alphabet alphabet, - Function copyConstructor) { + private > void testCopyConstructor(A automaton, + Alphabet alphabet, + Function copyConstructor) { final A copy = copyConstructor.apply(automaton); Assert.assertTrue(Automata.testEquivalence(automaton, copy, alphabet)); } diff --git a/util/src/test/java/net/automatalib/util/automaton/conformance/WpMethodTestsIteratorTest.java b/util/src/test/java/net/automatalib/util/automaton/conformance/WpMethodTestsIteratorTest.java index fcbeff67d..d6c59aada 100644 --- a/util/src/test/java/net/automatalib/util/automaton/conformance/WpMethodTestsIteratorTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/conformance/WpMethodTestsIteratorTest.java @@ -29,6 +29,7 @@ import net.automatalib.common.util.collection.IterableUtil; import net.automatalib.common.util.collection.IteratorUtil; import net.automatalib.common.util.comparison.CmpUtil; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.util.automaton.equivalence.CharacterizingSets; import net.automatalib.util.automaton.random.RandomAutomata; @@ -100,16 +101,17 @@ private > void checkTestWords(List> actual, List } - private List> generateWpMethodTest(UniversalDeterministicAutomaton automaton, + private List> generateWpMethodTest(UniversalSemantics semantics, Collection inputs, List> middleParts) { + final UniversalDeterministicAutomaton automaton = semantics.getSemantics(); final List> stateCover = new ArrayList<>(automaton.size()); final List> transitionCover = new ArrayList<>(automaton.size() * inputs.size()); final List> characterizingSet = new ArrayList<>(); - Covers.cover(automaton, inputs, stateCover, transitionCover); - CharacterizingSets.findCharacterizingSet(automaton, inputs, characterizingSet); + Covers.cover(semantics, inputs, stateCover, transitionCover); + CharacterizingSets.findCharacterizingSet(semantics, inputs, characterizingSet); Assert.assertFalse(stateCover.isEmpty()); Assert.assertFalse(transitionCover.isEmpty()); @@ -135,7 +137,7 @@ private List> generateWpMethodTest(UniversalDeterministicAutomato final S s = automaton.getState(prefixWithMiddle); final List> suffixes = new ArrayList<>(); - CharacterizingSets.findCharacterizingSet(automaton, inputs, s, suffixes); + CharacterizingSets.findCharacterizingSet(semantics, inputs, s, suffixes); assert !suffixes.isEmpty(); for (Word suffix : suffixes) { diff --git a/util/src/test/java/net/automatalib/util/automaton/copy/AbstractAutomatonCopyTest.java b/util/src/test/java/net/automatalib/util/automaton/copy/AbstractAutomatonCopyTest.java index d8acb19da..2ca6e1af0 100644 --- a/util/src/test/java/net/automatalib/util/automaton/copy/AbstractAutomatonCopyTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/copy/AbstractAutomatonCopyTest.java @@ -22,10 +22,11 @@ import net.automatalib.alphabet.impl.Alphabets; import net.automatalib.automaton.AutomatonCreator; import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.automaton.ShrinkableAutomaton; import net.automatalib.automaton.UniversalDeterministicAutomaton; +import net.automatalib.automaton.concept.Shrinkable; import net.automatalib.automaton.fsa.impl.CompactDFA; import net.automatalib.automaton.transducer.impl.CompactMealy; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.ts.TransitionPredicate; import net.automatalib.util.automaton.Automata; import net.automatalib.util.automaton.predicate.TransitionPredicates; @@ -142,21 +143,21 @@ private void makePartial(MutableDeterministic automaton for (S s : automaton) { if (stateFilterForRemoval.test(s)) { - ShrinkableAutomaton.unlinkState(automaton, s, null, alphabet); + Shrinkable.unlinkState(automaton, s, null, alphabet); } } } - private , S, I, T, SP, TP> void checkEquivalence(A source, - Alphabet alphabet, - AutomatonCreator targetCreator) { + private & UniversalSemantics, S, I, T, SP, TP> void checkEquivalence(A source, + Alphabet alphabet, + AutomatonCreator targetCreator) { final A target = targetCreator.createAutomaton(alphabet); AutomatonLowLevelCopy.copy(getCopyMethod(), source, alphabet, target); Assert.assertTrue(Automata.testEquivalence(source, target, alphabet)); } - private , S, I, T, SP, TP> void checkFilteredEquivalence(A source, + private & UniversalSemantics, S, I, T, SP, TP> void checkFilteredEquivalence(A source, Alphabet alphabet, AutomatonCreator targetCreator, Predicate sPred, diff --git a/util/src/test/java/net/automatalib/util/automaton/equivalence/BisimulationTest.java b/util/src/test/java/net/automatalib/util/automaton/equivalence/BisimulationTest.java index 4f9d21281..ff1af3ceb 100644 --- a/util/src/test/java/net/automatalib/util/automaton/equivalence/BisimulationTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/equivalence/BisimulationTest.java @@ -22,9 +22,9 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Alphabets; -import net.automatalib.automaton.Automaton; import net.automatalib.automaton.fsa.impl.CompactNFA; import net.automatalib.common.util.Pair; +import net.automatalib.semantics.FiniteSemantics.SimpleSemantics; import net.automatalib.ts.modal.impl.CompactMTS; import net.automatalib.util.automaton.random.TabakovVardiRandomAutomata; import org.testng.Assert; @@ -95,15 +95,15 @@ public void bisimTestLoop() { Assert.assertTrue(testBisimulationEquivalence(a, b, alphabet)); } - private static , BS, BT, B extends Automaton> boolean testBisimulationEquivalence( + private static , BS, B extends SimpleSemantics> boolean testBisimulationEquivalence( A a, B b, Collection inputs) { Set> bisim = Bisimulation.bisimulationEquivalenceRelation(a, b, inputs); - Set statesA = new HashSet<>(a.getStates()); - Set statesB = new HashSet<>(b.getStates()); + Set statesA = new HashSet<>(a.getSemantics().getStates()); + Set statesB = new HashSet<>(b.getSemantics().getStates()); for (Pair p : bisim) { statesA.remove(p.getFirst()); diff --git a/util/src/test/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTestTest.java b/util/src/test/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTestTest.java index 8151a1712..6572575fe 100644 --- a/util/src/test/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTestTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTestTest.java @@ -27,6 +27,7 @@ import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.impl.CompactMealy; import net.automatalib.common.util.function.BiIntFunction; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.equivalence.DeterministicEquivalenceTest.ArrayRegistry; import net.automatalib.util.automaton.equivalence.DeterministicEquivalenceTest.MapRegistry; import net.automatalib.util.automaton.equivalence.DeterministicEquivalenceTest.Pred; @@ -158,29 +159,32 @@ private static void testIndexComputation(BiIntFunction> constr } } - private static void testForEmptySepWord(UniversalDeterministicAutomaton a1, - UniversalDeterministicAutomaton a2, + private static void testForEmptySepWord(UniversalSemantics s1, + UniversalSemantics s2, Collection inputs) { - Assert.assertNull(DeterministicEquivalenceTest.findSeparatingWord(a1, a1, inputs)); - Assert.assertNull(DeterministicEquivalenceTest.findSeparatingWord(a2, a2, inputs)); + Assert.assertNull(DeterministicEquivalenceTest.findSeparatingWord(s1, s1, inputs)); + Assert.assertNull(DeterministicEquivalenceTest.findSeparatingWord(s2, s2, inputs)); - final Word sepWord1 = DeterministicEquivalenceTest.findSeparatingWord(a1, a2, inputs); + final UniversalDeterministicAutomaton a1 = s1.getSemantics(); + final UniversalDeterministicAutomaton a2 = s1.getSemantics(); + + final Word sepWord1 = DeterministicEquivalenceTest.findSeparatingWord(s1, s2, inputs); Assert.assertEquals(sepWord1, Word.epsilon()); Assert.assertNotEquals(a1.getState(sepWord1), a2.getState(sepWord1)); - final Word sepWord2 = DeterministicEquivalenceTest.findSeparatingWord(a2, a1, inputs); + final Word sepWord2 = DeterministicEquivalenceTest.findSeparatingWord(s2, s1, inputs); Assert.assertEquals(sepWord2, Word.epsilon()); Assert.assertNotEquals(a1.getState(sepWord2), a2.getState(sepWord2)); } - private & Output> void testEquivalenceInternal(M a1, + private & Output> void testEquivalenceInternal(M a1, M a2, Alphabet alphabet, boolean equivalent) { // explicitly assign type to (redundant) variables, otherwise javac complains - final UniversalDeterministicAutomaton m1 = a1; - final UniversalDeterministicAutomaton m2 = a2; + final UniversalSemantics m1 = a1; + final UniversalSemantics m2 = a2; final Word separatingWord = DeterministicEquivalenceTest.findSeparatingWord(m1, m2, alphabet); diff --git a/util/src/test/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTestTest.java b/util/src/test/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTestTest.java index 0b677efe5..e72f5687c 100644 --- a/util/src/test/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTestTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTestTest.java @@ -25,6 +25,7 @@ import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.fsa.impl.CompactDFA; import net.automatalib.automaton.transducer.impl.CompactMealy; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.random.RandomAutomata; import net.automatalib.word.Word; import org.testng.Assert; @@ -192,34 +193,37 @@ public void testIssue84() { Assert.assertEquals(sepWord.length(), TestUtil.LARGE_AUTOMATON_A.size() - 1); } - private static void testForEmptySepWord(UniversalDeterministicAutomaton a1, - UniversalDeterministicAutomaton a2, + private static void testForEmptySepWord(UniversalSemantics s1, + UniversalSemantics s2, Collection inputs) { - Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a1, a1, inputs)); - Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a2, a2, inputs)); + Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(s1, s1, inputs)); + Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(s2, s2, inputs)); - Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a1, a2, inputs, true)); - final Word sepWord1 = NearLinearEquivalenceTest.findSeparatingWord(a1, a2, inputs); + UniversalDeterministicAutomaton a1 = s1.getSemantics(); + UniversalDeterministicAutomaton a2 = s2.getSemantics(); + + Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(s1, s2, inputs, true)); + final Word sepWord1 = NearLinearEquivalenceTest.findSeparatingWord(s1, s2, inputs); Assert.assertEquals(sepWord1, Word.epsilon()); Assert.assertNotEquals(a1.getState(sepWord1), a2.getState(sepWord1)); - Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a2, a1, inputs, true)); - final Word sepWord2 = NearLinearEquivalenceTest.findSeparatingWord(a2, a1, inputs); + Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(s2, s1, inputs, true)); + final Word sepWord2 = NearLinearEquivalenceTest.findSeparatingWord(s2, s1, inputs); Assert.assertEquals(sepWord2, Word.epsilon()); Assert.assertNotEquals(a1.getState(sepWord2), a2.getState(sepWord2)); // Non-alphabet (non-integer-abstraction) version final Set inputsAsSet = new HashSet<>(inputs); - Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a1, a1, inputsAsSet)); - Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a2, a2, inputsAsSet)); + Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(s1, s1, inputsAsSet)); + Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(s2, s2, inputsAsSet)); - Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a1, a2, inputsAsSet, true)); - final Word sepWord3 = NearLinearEquivalenceTest.findSeparatingWord(a1, a2, inputsAsSet); + Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(s1, s2, inputsAsSet, true)); + final Word sepWord3 = NearLinearEquivalenceTest.findSeparatingWord(s1, s2, inputsAsSet); Assert.assertEquals(sepWord3, Word.epsilon()); Assert.assertNotEquals(a1.getState(sepWord3), a2.getState(sepWord3)); - Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a2, a1, inputsAsSet, true)); - final Word sepWord4 = NearLinearEquivalenceTest.findSeparatingWord(a2, a1, inputsAsSet); + Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(s2, s1, inputsAsSet, true)); + final Word sepWord4 = NearLinearEquivalenceTest.findSeparatingWord(s2, s1, inputsAsSet); Assert.assertEquals(sepWord4, Word.epsilon()); Assert.assertNotEquals(a1.getState(sepWord4), a2.getState(sepWord4)); } diff --git a/util/src/test/java/net/automatalib/util/automaton/minimizer/AbstractMinimizationTest.java b/util/src/test/java/net/automatalib/util/automaton/minimizer/AbstractMinimizationTest.java index baafecddb..33fbf5b0a 100644 --- a/util/src/test/java/net/automatalib/util/automaton/minimizer/AbstractMinimizationTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/minimizer/AbstractMinimizationTest.java @@ -25,10 +25,11 @@ import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.fsa.MutableDFA; import net.automatalib.automaton.fsa.impl.CompactDFA; -import net.automatalib.automaton.impl.UniversalCompactDet; +import net.automatalib.automaton.impl.UniversalCompactDetAutomaton; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.MutableMealyMachine; import net.automatalib.automaton.transducer.impl.CompactMealy; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.Automata; import net.automatalib.util.automaton.builder.AutomatonBuilders; import org.testng.Assert; @@ -156,7 +157,8 @@ public void createTestUniversal1() { final char input3 = 'c'; final char input4 = 'd'; - final UniversalCompactDet automaton = new UniversalCompactDet<>(alphabet); + final UniversalCompactDetAutomaton automaton = + new UniversalCompactDetAutomaton<>(alphabet); // @formatter:off AutomatonBuilders.forAutomaton(automaton) @@ -184,7 +186,7 @@ public void createTestUniversal1() { .create(); // @formatter:on - final TestConfig> config = + final TestConfig> config = new TestConfig<>(alphabet, automaton, 5, 6); if (supportsPartial()) { @@ -220,7 +222,7 @@ private > void testMinimizeDFA(TestConfig te } } - private > void testMinimizeUniversal(TestConfig test) { + private & UniversalSemantics> void testMinimizeUniversal(TestConfig test) { final UniversalDeterministicAutomaton result = minimizeUniversal(test.automaton, test.alphabet); @@ -247,15 +249,17 @@ private > void testMinimizeDFA(TestConfig te protected abstract boolean supportsPartial(); - private static void assertAllInequivalent(UniversalDeterministicAutomaton automaton, + private static void assertAllInequivalent(UniversalSemantics semantics, Collection inputs) { + + UniversalDeterministicAutomaton automaton = semantics.getSemantics(); StateIDs ids = automaton.stateIDs(); int size = automaton.size(); for (int i = 0; i < size - 1; i++) { S s1 = ids.getState(i); for (int j = i + 1; j < size; j++) { S s2 = ids.getState(j); - Assert.assertNotNull(Automata.findSeparatingWord(automaton, s1, s2, inputs)); + Assert.assertNotNull(Automata.findSeparatingWord(semantics, s1, s2, inputs)); } } } diff --git a/util/src/test/java/net/automatalib/util/automaton/minimizer/MinimizerTest.java b/util/src/test/java/net/automatalib/util/automaton/minimizer/MinimizerTest.java index c5a414f2b..9eb362960 100644 --- a/util/src/test/java/net/automatalib/util/automaton/minimizer/MinimizerTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/minimizer/MinimizerTest.java @@ -25,7 +25,7 @@ import net.automatalib.automaton.fsa.MutableDFA; import net.automatalib.automaton.fsa.impl.CompactDFA; import net.automatalib.automaton.graph.TransitionEdge.Property; -import net.automatalib.automaton.impl.UniversalCompactDet; +import net.automatalib.automaton.impl.UniversalCompactDetAutomaton; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.MutableMealyMachine; import net.automatalib.automaton.transducer.impl.CompactMealy; @@ -56,7 +56,8 @@ protected DFA minimizeDFA(MutableDFA dfa, Alphabet alphabet) @Override protected UniversalDeterministicAutomaton minimizeUniversal(MutableDeterministic automaton, Alphabet alphabet) { - final UniversalCompactDet result = new UniversalCompactDet<>(alphabet, automaton.size()); + final UniversalCompactDetAutomaton result = + new UniversalCompactDetAutomaton<>(alphabet, automaton.size()); Automata.minimize(automaton, alphabet, result); return result; } From 141b10a665d50d21e25e2e9138a1f2e78884265e Mon Sep 17 00:00:00 2001 From: Markus Frohme Date: Tue, 16 Jun 2026 21:15:12 +0200 Subject: [PATCH 2/8] cleanups --- .../automaton/MutableAutomaton.java | 3 +- .../automatalib/automaton/concept/FinSem.java | 3 - .../net/automatalib/automaton/fsa/DFA.java | 5 +- .../automaton/fsa/FiniteStateAcceptor.java | 9 +- .../automatalib/automaton/fsa/MutableDFA.java | 6 +- .../automatalib/automaton/fsa/MutableNFA.java | 4 +- .../net/automatalib/automaton/mmlt/MMLT.java | 4 +- .../automatalib/automaton/procedural/SBA.java | 4 +- .../automatalib/automaton/procedural/SPA.java | 5 +- .../automaton/procedural/SPMM.java | 5 +- .../automaton/transducer/MealyMachine.java | 7 +- .../automaton/transducer/MooreMachine.java | 4 +- .../transducer/MutableMealyMachine.java | 7 +- .../transducer/MutableMooreMachine.java | 7 +- .../MutableSubsequentialTransducer.java | 6 +- .../transducer/SubsequentialTransducer.java | 4 +- .../DeterministicFiniteSemantics.java | 45 +++--- .../semantics/DeterministicSemantics.java | 28 +++- .../semantics/FiniteSemantics.java | 32 +++-- .../net/automatalib/semantics/Semantics.java | 19 ++- .../ts/modal/ModalTransitionSystem.java | 4 +- .../impl/UniversalCompactDetAutomaton.java | 18 ++- .../java/net/automatalib/example/Example.java | 8 +- .../AbstractAut2ETF2FSM2AutTest.java | 4 +- .../automatalib/util/automaton/Automata.java | 69 ++++----- .../IncrementalWMethodTestsIterator.java | 8 +- .../KWayStateCoverTestsIterator.java | 22 ++- .../KWayTransitionCoverTestsIterator.java | 40 +++--- .../ProceduralWMethodTestsIterator.java | 4 +- .../conformance/WMethodTestsIterator.java | 10 +- .../conformance/WpMethodTestsIterator.java | 30 ++-- .../util/automaton/cover/Covers.java | 133 ++++++++---------- .../cover/IncrementalStateCoverIterator.java | 8 +- .../IncrementalTransitionCoverIterator.java | 10 +- .../automaton/equivalence/Bisimulation.java | 16 +-- .../equivalence/CharacterizingSets.java | 51 +++---- .../DeterministicEquivalenceTest.java | 14 +- .../NearLinearEquivalenceTest.java | 62 +++----- .../minimizer/HopcroftMinimizer.java | 69 +++++---- .../automaton/procedural/ProceduralUtil.java | 30 ++-- .../util/automaton/random/RandomAutomata.java | 29 ++-- ...RandomDeterministicAutomatonGenerator.java | 3 +- .../util/automaton/CopyConstructorTest.java | 6 +- .../WpMethodTestsIteratorTest.java | 10 +- .../copy/AbstractAutomatonCopyTest.java | 20 +-- .../equivalence/BisimulationTest.java | 9 +- .../DeterministicEquivalenceTestTest.java | 28 ++-- .../NearLinearEquivalenceTestTest.java | 34 ++--- .../minimizer/AbstractMinimizationTest.java | 18 +-- .../minimizer/AutomataMinimizationTest.java | 7 +- .../minimizer/HopcroftMinimizerTest.java | 7 +- .../minimizer/InvasiveHopcroftTest.java | 7 +- .../automaton/minimizer/MinimizerTest.java | 10 +- .../PartialHopcroftMinimizerTest.java | 7 +- 54 files changed, 494 insertions(+), 518 deletions(-) delete mode 100644 api/src/main/java/net/automatalib/automaton/concept/FinSem.java diff --git a/api/src/main/java/net/automatalib/automaton/MutableAutomaton.java b/api/src/main/java/net/automatalib/automaton/MutableAutomaton.java index 70dec62b9..34daba099 100644 --- a/api/src/main/java/net/automatalib/automaton/MutableAutomaton.java +++ b/api/src/main/java/net/automatalib/automaton/MutableAutomaton.java @@ -20,12 +20,13 @@ import java.util.HashSet; import java.util.Set; +import net.automatalib.automaton.concept.Shrinkable; import org.checkerframework.checker.nullness.qual.Nullable; /** * A mutable automaton. This interface adds support for non-destructive modifications, i.e., adding and modifying states * and transitions. If also removal of states and single transitions (from the set of outgoing transitions) should be - * removed, then {@link ShrinkableAutomaton} is the adequate interface. + * removed, then {@link Shrinkable} is the adequate interface. * * @param * state class. diff --git a/api/src/main/java/net/automatalib/automaton/concept/FinSem.java b/api/src/main/java/net/automatalib/automaton/concept/FinSem.java deleted file mode 100644 index 30d269a63..000000000 --- a/api/src/main/java/net/automatalib/automaton/concept/FinSem.java +++ /dev/null @@ -1,3 +0,0 @@ -package net.automatalib.automaton.concept; - -public interface FinSem {} diff --git a/api/src/main/java/net/automatalib/automaton/fsa/DFA.java b/api/src/main/java/net/automatalib/automaton/fsa/DFA.java index 49aeebd63..e31c09672 100644 --- a/api/src/main/java/net/automatalib/automaton/fsa/DFA.java +++ b/api/src/main/java/net/automatalib/automaton/fsa/DFA.java @@ -19,8 +19,7 @@ import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.concept.DeterministicSuffixOutputAutomaton; -import net.automatalib.automaton.concept.FinSem; -import net.automatalib.semantics.DeterministicFiniteSemantics.FullSemantics; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.ts.acceptor.DeterministicAcceptorTS; /** @@ -29,7 +28,7 @@ public interface DFA extends UniversalDeterministicAutomaton, DeterministicAcceptorTS, DeterministicSuffixOutputAutomaton, - FullSemantics, FinSem, + UniversalSemantics, NFA { @Override diff --git a/api/src/main/java/net/automatalib/automaton/fsa/FiniteStateAcceptor.java b/api/src/main/java/net/automatalib/automaton/fsa/FiniteStateAcceptor.java index 3cc01f3d6..1804192f6 100644 --- a/api/src/main/java/net/automatalib/automaton/fsa/FiniteStateAcceptor.java +++ b/api/src/main/java/net/automatalib/automaton/fsa/FiniteStateAcceptor.java @@ -26,7 +26,7 @@ import net.automatalib.automaton.graph.UniversalAutomatonGraphView; import net.automatalib.automaton.visualization.FSAVisualizationHelper; import net.automatalib.graph.UniversalGraph; -import net.automatalib.semantics.FiniteSemantics.FullSemantics; +import net.automatalib.semantics.FiniteSemantics.UniversalSemantics; import net.automatalib.ts.acceptor.AcceptorTS; import net.automatalib.visualization.VisualizationHelper; @@ -36,16 +36,11 @@ public interface FiniteStateAcceptor extends AcceptorTS, UniversalAutomaton, OutputAutomaton, - FullSemantics { + UniversalSemantics { List STATE_PROPERTIES = Arrays.asList(Boolean.FALSE, Boolean.TRUE); List TRANSITION_PROPERTIES = Collections.singletonList(null); - @Override - default FiniteStateAcceptor getSemantics() { - return this; - } - @Override default UniversalGraph, Boolean, TransitionEdge.Property> transitionGraphView( Collection inputs) { diff --git a/api/src/main/java/net/automatalib/automaton/fsa/MutableDFA.java b/api/src/main/java/net/automatalib/automaton/fsa/MutableDFA.java index b7b6332ea..4b9219fb3 100644 --- a/api/src/main/java/net/automatalib/automaton/fsa/MutableDFA.java +++ b/api/src/main/java/net/automatalib/automaton/fsa/MutableDFA.java @@ -16,9 +16,13 @@ package net.automatalib.automaton.fsa; import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; import org.checkerframework.checker.nullness.qual.Nullable; -public interface MutableDFA extends DFA, MutableDeterministic, MutableFSA { +public interface MutableDFA extends DFA, + MutableDeterministic, + MutableFSA, + MutableSemantics { @Override // Overridden for performance reasons (to prevent creating redundant transition objects) diff --git a/api/src/main/java/net/automatalib/automaton/fsa/MutableNFA.java b/api/src/main/java/net/automatalib/automaton/fsa/MutableNFA.java index 538385940..70c8f7f4a 100644 --- a/api/src/main/java/net/automatalib/automaton/fsa/MutableNFA.java +++ b/api/src/main/java/net/automatalib/automaton/fsa/MutableNFA.java @@ -15,6 +15,8 @@ */ package net.automatalib.automaton.fsa; -public interface MutableNFA extends NFA, MutableFSA { +import net.automatalib.semantics.FiniteSemantics.MutableSemantics; + +public interface MutableNFA extends NFA, MutableFSA, MutableSemantics { } diff --git a/api/src/main/java/net/automatalib/automaton/mmlt/MMLT.java b/api/src/main/java/net/automatalib/automaton/mmlt/MMLT.java index 4d927a12b..000a9cb74 100644 --- a/api/src/main/java/net/automatalib/automaton/mmlt/MMLT.java +++ b/api/src/main/java/net/automatalib/automaton/mmlt/MMLT.java @@ -22,7 +22,7 @@ import net.automatalib.common.util.Triple; import net.automatalib.graph.Graph; import net.automatalib.graph.concept.GraphViewable; -import net.automatalib.semantics.DeterministicSemantics.UniversalSemantics; +import net.automatalib.semantics.DeterministicSemantics.WildcardUniversalSemantics; import net.automatalib.symbol.time.SymbolicInput; import net.automatalib.symbol.time.TimedInput; import net.automatalib.symbol.time.TimedOutput; @@ -55,7 +55,7 @@ */ public interface MMLT extends UniversalDeterministicAutomaton, InputAlphabetHolder, - UniversalSemantics, TimedInput, Void, TimedOutput>, + WildcardUniversalSemantics, TimedInput, Void, TimedOutput>, GraphViewable { /** diff --git a/api/src/main/java/net/automatalib/automaton/procedural/SBA.java b/api/src/main/java/net/automatalib/automaton/procedural/SBA.java index 24dafb698..7bbd117ae 100644 --- a/api/src/main/java/net/automatalib/automaton/procedural/SBA.java +++ b/api/src/main/java/net/automatalib/automaton/procedural/SBA.java @@ -22,7 +22,7 @@ import net.automatalib.alphabet.ProceduralInputAlphabet; import net.automatalib.automaton.fsa.DFA; -import net.automatalib.semantics.DeterministicSemantics.FullSemantics; +import net.automatalib.semantics.DeterministicSemantics.UniversalSemantics; import net.automatalib.ts.acceptor.DeterministicAcceptorTS; /** @@ -37,7 +37,7 @@ * input symbol type */ public interface SBA extends ProceduralSystem>, DeterministicAcceptorTS, - FullSemantics { + UniversalSemantics { @Override default SBA getSemantics() { diff --git a/api/src/main/java/net/automatalib/automaton/procedural/SPA.java b/api/src/main/java/net/automatalib/automaton/procedural/SPA.java index c9422dec6..de2321d2d 100644 --- a/api/src/main/java/net/automatalib/automaton/procedural/SPA.java +++ b/api/src/main/java/net/automatalib/automaton/procedural/SPA.java @@ -22,7 +22,7 @@ import net.automatalib.alphabet.ProceduralInputAlphabet; import net.automatalib.automaton.fsa.DFA; -import net.automatalib.semantics.DeterministicSemantics.FullSemantics; +import net.automatalib.semantics.DeterministicSemantics.UniversalSemantics; import net.automatalib.ts.acceptor.DeterministicAcceptorTS; /** @@ -58,7 +58,8 @@ * input symbol type */ public interface SPA - extends ProceduralSystem>, DeterministicAcceptorTS, FullSemantics { + extends ProceduralSystem>, DeterministicAcceptorTS, + UniversalSemantics { @Override default SPA getSemantics() { diff --git a/api/src/main/java/net/automatalib/automaton/procedural/SPMM.java b/api/src/main/java/net/automatalib/automaton/procedural/SPMM.java index bdd37d591..b24f4a173 100644 --- a/api/src/main/java/net/automatalib/automaton/procedural/SPMM.java +++ b/api/src/main/java/net/automatalib/automaton/procedural/SPMM.java @@ -24,7 +24,7 @@ import net.automatalib.alphabet.ProceduralInputAlphabet; import net.automatalib.automaton.concept.Output; import net.automatalib.automaton.transducer.MealyMachine; -import net.automatalib.semantics.DeterministicSemantics.FullSemantics; +import net.automatalib.semantics.DeterministicSemantics.UniversalSemantics; import net.automatalib.ts.concept.DeterministicSuffixOutputTS; import net.automatalib.ts.output.MealyTransitionSystem; import net.automatalib.word.Word; @@ -47,8 +47,7 @@ * output symbol type */ public interface SPMM extends ProceduralSystem>, - MealyTransitionSystem, - FullSemantics { + MealyTransitionSystem, UniversalSemantics { @Override default SPMM getSemantics() { diff --git a/api/src/main/java/net/automatalib/automaton/transducer/MealyMachine.java b/api/src/main/java/net/automatalib/automaton/transducer/MealyMachine.java index d351c40e4..61bb21e7b 100644 --- a/api/src/main/java/net/automatalib/automaton/transducer/MealyMachine.java +++ b/api/src/main/java/net/automatalib/automaton/transducer/MealyMachine.java @@ -18,19 +18,18 @@ import java.util.Collection; import net.automatalib.automaton.UniversalDeterministicAutomaton; -import net.automatalib.automaton.concept.FinSem; import net.automatalib.automaton.graph.TransitionEdge; import net.automatalib.automaton.graph.UniversalAutomatonGraphView; import net.automatalib.automaton.visualization.MealyVisualizationHelper; import net.automatalib.graph.UniversalGraph; -import net.automatalib.semantics.DeterministicFiniteSemantics.FullSemantics; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.ts.output.MealyTransitionSystem; import net.automatalib.visualization.VisualizationHelper; public interface MealyMachine extends UniversalDeterministicAutomaton, TransitionOutputAutomaton, - MealyTransitionSystem, FinSem, - FullSemantics { + MealyTransitionSystem, + UniversalSemantics { @Override default MealyMachine getSemantics() { diff --git a/api/src/main/java/net/automatalib/automaton/transducer/MooreMachine.java b/api/src/main/java/net/automatalib/automaton/transducer/MooreMachine.java index 8a1476654..628d43130 100644 --- a/api/src/main/java/net/automatalib/automaton/transducer/MooreMachine.java +++ b/api/src/main/java/net/automatalib/automaton/transducer/MooreMachine.java @@ -23,14 +23,14 @@ import net.automatalib.automaton.graph.UniversalAutomatonGraphView; import net.automatalib.automaton.visualization.MooreVisualizationHelper; import net.automatalib.graph.UniversalGraph; -import net.automatalib.semantics.DeterministicFiniteSemantics.FullSemantics; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.ts.output.MooreTransitionSystem; import net.automatalib.visualization.VisualizationHelper; public interface MooreMachine extends UniversalDeterministicAutomaton, StateOutputAutomaton, MooreTransitionSystem, - FullSemantics { + UniversalSemantics { @Override default MooreMachine getSemantics() { diff --git a/api/src/main/java/net/automatalib/automaton/transducer/MutableMealyMachine.java b/api/src/main/java/net/automatalib/automaton/transducer/MutableMealyMachine.java index de201d318..d6a5ba186 100644 --- a/api/src/main/java/net/automatalib/automaton/transducer/MutableMealyMachine.java +++ b/api/src/main/java/net/automatalib/automaton/transducer/MutableMealyMachine.java @@ -17,9 +17,12 @@ import net.automatalib.automaton.MutableDeterministic; import net.automatalib.automaton.concept.MutableTransitionOutput; +import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; -public interface MutableMealyMachine - extends MealyMachine, MutableDeterministic, MutableTransitionOutput { +public interface MutableMealyMachine extends MealyMachine, + MutableDeterministic, + MutableTransitionOutput, + MutableSemantics { @Override default void setStateProperty(S state, Void property) {} diff --git a/api/src/main/java/net/automatalib/automaton/transducer/MutableMooreMachine.java b/api/src/main/java/net/automatalib/automaton/transducer/MutableMooreMachine.java index a6019707f..2db961fd6 100644 --- a/api/src/main/java/net/automatalib/automaton/transducer/MutableMooreMachine.java +++ b/api/src/main/java/net/automatalib/automaton/transducer/MutableMooreMachine.java @@ -17,9 +17,12 @@ import net.automatalib.automaton.MutableDeterministic; import net.automatalib.automaton.concept.MutableStateOutput; +import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; -public interface MutableMooreMachine - extends MooreMachine, MutableDeterministic, MutableStateOutput { +public interface MutableMooreMachine extends MooreMachine, + MutableDeterministic, + MutableStateOutput, + MutableSemantics { @Override default void setStateProperty(S state, O property) { diff --git a/api/src/main/java/net/automatalib/automaton/transducer/MutableSubsequentialTransducer.java b/api/src/main/java/net/automatalib/automaton/transducer/MutableSubsequentialTransducer.java index 761924976..91aad8efa 100644 --- a/api/src/main/java/net/automatalib/automaton/transducer/MutableSubsequentialTransducer.java +++ b/api/src/main/java/net/automatalib/automaton/transducer/MutableSubsequentialTransducer.java @@ -16,6 +16,7 @@ package net.automatalib.automaton.transducer; import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; import net.automatalib.word.Word; /** @@ -30,5 +31,6 @@ * @param * output symbol type */ -public interface MutableSubsequentialTransducer - extends SubsequentialTransducer, MutableDeterministic, Word> {} +public interface MutableSubsequentialTransducer extends SubsequentialTransducer, + MutableDeterministic, Word>, + MutableSemantics, Word> {} diff --git a/api/src/main/java/net/automatalib/automaton/transducer/SubsequentialTransducer.java b/api/src/main/java/net/automatalib/automaton/transducer/SubsequentialTransducer.java index d3e411545..0979f47ba 100644 --- a/api/src/main/java/net/automatalib/automaton/transducer/SubsequentialTransducer.java +++ b/api/src/main/java/net/automatalib/automaton/transducer/SubsequentialTransducer.java @@ -26,7 +26,7 @@ import net.automatalib.automaton.graph.UniversalAutomatonGraphView; import net.automatalib.automaton.visualization.SSTVisualizationHelper; import net.automatalib.graph.UniversalGraph; -import net.automatalib.semantics.DeterministicFiniteSemantics.FullSemantics; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.ts.concept.DeterministicOutputTS; import net.automatalib.ts.output.DeterministicTraceableTS; import net.automatalib.visualization.VisualizationHelper; @@ -55,7 +55,7 @@ public interface SubsequentialTransducer extends DeterministicTraceableTS, DeterministicSuffixOutputAutomaton>, UniversalDeterministicAutomaton, Word>, - FullSemantics, Word> { + UniversalSemantics, Word> { @Override default SubsequentialTransducer getSemantics() { diff --git a/api/src/main/java/net/automatalib/semantics/DeterministicFiniteSemantics.java b/api/src/main/java/net/automatalib/semantics/DeterministicFiniteSemantics.java index e310818b7..03db21873 100644 --- a/api/src/main/java/net/automatalib/semantics/DeterministicFiniteSemantics.java +++ b/api/src/main/java/net/automatalib/semantics/DeterministicFiniteSemantics.java @@ -4,37 +4,48 @@ import net.automatalib.automaton.MutableDeterministic; import net.automatalib.automaton.UniversalDeterministicAutomaton; -public interface DeterministicFiniteSemantics { +public interface DeterministicFiniteSemantics extends DeterministicSemantics, FiniteSemantics { - interface SimpleSemantics { + interface WildcardPlainSemantics extends DeterministicFiniteSemantics, + DeterministicSemantics.WildcardPlainSemantics, + FiniteSemantics.WildcardPlainSemantics { DeterministicAutomaton getSemantics(); - } - interface UniversalSemantics extends SimpleSemantics, - FiniteSemantics.UniversalSemantics, - DeterministicSemantics.UniversalSemantics { + interface PlainSemantics extends WildcardPlainSemantics, + DeterministicSemantics.PlainSemantics, + FiniteSemantics.PlainSemantics, + DeterministicAutomaton { @Override - UniversalDeterministicAutomaton getSemantics(); + default DeterministicAutomaton getSemantics() { + return this; + } } - interface FullSemantics extends UniversalSemantics, - FiniteSemantics.FullSemantics, - DeterministicSemantics.FullSemantics { + interface WildcardUniversalSemantics extends WildcardPlainSemantics, + DeterministicSemantics.WildcardUniversalSemantics, + FiniteSemantics.WildcardUniversalSemantics { @Override - UniversalDeterministicAutomaton getSemantics(); + UniversalDeterministicAutomaton getSemantics(); } - interface MutableSemantics extends FullSemantics, FiniteSemantics.MutableSemantics { - @Override - MutableDeterministic getSemantics(); + interface UniversalSemantics extends PlainSemantics, + WildcardUniversalSemantics, + FiniteSemantics.UniversalSemantics, + DeterministicSemantics.UniversalSemantics, + UniversalDeterministicAutomaton { + @Override + default UniversalDeterministicAutomaton getSemantics() { + return this; + } } - static FullSemantics fromAutomaton(UniversalDeterministicAutomaton automaton) { - return () -> automaton; - } + interface MutableSemantics extends UniversalSemantics, + FiniteSemantics.MutableSemantics, + MutableDeterministic {} + } diff --git a/api/src/main/java/net/automatalib/semantics/DeterministicSemantics.java b/api/src/main/java/net/automatalib/semantics/DeterministicSemantics.java index acc1f92f8..c90fa20de 100644 --- a/api/src/main/java/net/automatalib/semantics/DeterministicSemantics.java +++ b/api/src/main/java/net/automatalib/semantics/DeterministicSemantics.java @@ -3,26 +3,40 @@ import net.automatalib.ts.DeterministicTransitionSystem; import net.automatalib.ts.UniversalDTS; -public interface DeterministicSemantics { +public interface DeterministicSemantics extends Semantics { - interface SimpleSemantics { + interface WildcardPlainSemantics extends DeterministicSemantics, Semantics.WildcardPlainSemantics { DeterministicTransitionSystem getSemantics(); } - interface UniversalSemantics - extends SimpleSemantics, Semantics.UniversalSemantics { + interface PlainSemantics extends WildcardPlainSemantics, + Semantics.PlainSemantics, + DeterministicTransitionSystem { + + @Override + default DeterministicTransitionSystem getSemantics() { + return this; + } + } + + interface WildcardUniversalSemantics + extends WildcardPlainSemantics, Semantics.WildcardUniversalSemantics { @Override UniversalDTS getSemantics(); } - interface FullSemantics - extends UniversalSemantics, Semantics.FullSemantics { + interface UniversalSemantics extends PlainSemantics, + WildcardUniversalSemantics, + Semantics.UniversalSemantics, + UniversalDTS { @Override - UniversalDTS getSemantics(); + default UniversalDTS getSemantics() { + return this; + } } } diff --git a/api/src/main/java/net/automatalib/semantics/FiniteSemantics.java b/api/src/main/java/net/automatalib/semantics/FiniteSemantics.java index ed0312178..1efef2d4b 100644 --- a/api/src/main/java/net/automatalib/semantics/FiniteSemantics.java +++ b/api/src/main/java/net/automatalib/semantics/FiniteSemantics.java @@ -2,36 +2,44 @@ import net.automatalib.automaton.Automaton; import net.automatalib.automaton.MutableAutomaton; -import net.automatalib.automaton.MutableDeterministic; import net.automatalib.automaton.UniversalAutomaton; -public interface FiniteSemantics { +public interface FiniteSemantics extends Semantics { - interface SimpleSemantics extends Semantics.SimpleSemantics { + interface WildcardPlainSemantics extends FiniteSemantics, Semantics.WildcardPlainSemantics { Automaton getSemantics(); } - interface UniversalSemantics - extends SimpleSemantics, Semantics.UniversalSemantics { + interface PlainSemantics + extends WildcardPlainSemantics, Semantics.PlainSemantics, Automaton { @Override - UniversalAutomaton getSemantics(); + default Automaton getSemantics() { + return this; + } } - interface FullSemantics - extends UniversalSemantics, Semantics.FullSemantics { + interface WildcardUniversalSemantics + extends WildcardPlainSemantics, Semantics.WildcardUniversalSemantics { @Override - UniversalAutomaton getSemantics(); + UniversalAutomaton getSemantics(); } - interface MutableSemantics extends FullSemantics { + interface UniversalSemantics extends PlainSemantics, + WildcardUniversalSemantics, + Semantics.UniversalSemantics, + UniversalAutomaton { @Override - MutableAutomaton getSemantics(); - + default UniversalAutomaton getSemantics() { + return this; + } } + interface MutableSemantics + extends UniversalSemantics, MutableAutomaton {} + } diff --git a/api/src/main/java/net/automatalib/semantics/Semantics.java b/api/src/main/java/net/automatalib/semantics/Semantics.java index e35a275b1..41e621520 100644 --- a/api/src/main/java/net/automatalib/semantics/Semantics.java +++ b/api/src/main/java/net/automatalib/semantics/Semantics.java @@ -5,22 +5,33 @@ public interface Semantics { - interface SimpleSemantics { + interface WildcardPlainSemantics extends Semantics { TransitionSystem getSemantics(); + } + + interface PlainSemantics extends WildcardPlainSemantics, TransitionSystem { + @Override + default TransitionSystem getSemantics() { + return this; + } } - interface UniversalSemantics extends SimpleSemantics { + interface WildcardUniversalSemantics extends WildcardPlainSemantics { @Override UniversalTransitionSystem getSemantics(); } - interface FullSemantics extends UniversalSemantics { + interface UniversalSemantics extends PlainSemantics, + WildcardUniversalSemantics, + UniversalTransitionSystem { @Override - UniversalTransitionSystem getSemantics(); + default UniversalTransitionSystem getSemantics() { + return this; + } } } diff --git a/api/src/main/java/net/automatalib/ts/modal/ModalTransitionSystem.java b/api/src/main/java/net/automatalib/ts/modal/ModalTransitionSystem.java index a2dbfc265..b17a1fd5c 100644 --- a/api/src/main/java/net/automatalib/ts/modal/ModalTransitionSystem.java +++ b/api/src/main/java/net/automatalib/ts/modal/ModalTransitionSystem.java @@ -24,7 +24,7 @@ import net.automatalib.automaton.graph.UniversalAutomatonGraphView; import net.automatalib.automaton.visualization.MTSVisualizationHelper; import net.automatalib.graph.UniversalGraph; -import net.automatalib.semantics.FiniteSemantics.FullSemantics; +import net.automatalib.semantics.FiniteSemantics.UniversalSemantics; import net.automatalib.ts.modal.transition.ModalEdgeProperty; import net.automatalib.visualization.VisualizationHelper; @@ -45,7 +45,7 @@ * (specific) transition property type */ public interface ModalTransitionSystem - extends UniversalFiniteAlphabetAutomaton, FullSemantics { + extends UniversalFiniteAlphabetAutomaton, UniversalSemantics { @Override default ModalTransitionSystem getSemantics() { diff --git a/core/src/main/java/net/automatalib/automaton/impl/UniversalCompactDetAutomaton.java b/core/src/main/java/net/automatalib/automaton/impl/UniversalCompactDetAutomaton.java index 7063453cb..59de55003 100644 --- a/core/src/main/java/net/automatalib/automaton/impl/UniversalCompactDetAutomaton.java +++ b/core/src/main/java/net/automatalib/automaton/impl/UniversalCompactDetAutomaton.java @@ -20,6 +20,8 @@ import net.automatalib.automaton.MutableDeterministic; import net.automatalib.automaton.UniversalFiniteAlphabetAutomaton; import net.automatalib.automaton.base.AbstractCompactDeterministic; +import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; /** * A default implementation for {@link AbstractCompactDeterministic} that uses {@link CompactTransition} as transition @@ -32,9 +34,11 @@ * @param * transition property type */ -public class UniversalCompactDetAutomaton extends UniversalCompactDet - implements MutableDeterministic, SP, TP>, - UniversalFiniteAlphabetAutomaton, SP, TP> { +public class UniversalCompactDetAutomaton extends UniversalCompactDet implements + MutableDeterministic, SP, TP>, + UniversalFiniteAlphabetAutomaton, SP, TP>, + UniversalSemantics, SP, TP>, + MutableSemantics, SP, TP> { public UniversalCompactDetAutomaton(Alphabet alphabet) { super(alphabet); @@ -44,7 +48,13 @@ public UniversalCompactDetAutomaton(Alphabet alphabet, int stateCapacity) { super(alphabet, stateCapacity); } - public static final class Creator implements AutomatonCreator, I> { + @Override + public UniversalCompactDetAutomaton getSemantics() { + return this; + } + + public static final class Creator + implements AutomatonCreator, I> { @Override public UniversalCompactDetAutomaton createAutomaton(Alphabet alphabet, int numStates) { diff --git a/examples/src/main/java/net/automatalib/example/Example.java b/examples/src/main/java/net/automatalib/example/Example.java index 5c2a70515..53a60f8d8 100644 --- a/examples/src/main/java/net/automatalib/example/Example.java +++ b/examples/src/main/java/net/automatalib/example/Example.java @@ -8,6 +8,8 @@ import net.automatalib.automaton.transducer.impl.CompactMealy; import net.automatalib.semantics.DeterministicFiniteSemantics; import net.automatalib.util.automaton.Automata; +import net.automatalib.util.automaton.copy.AutomatonCopyMethod; +import net.automatalib.util.automaton.copy.AutomatonLowLevelCopy; public class Example { @@ -26,7 +28,11 @@ public static void main(String[] args) { Automata.findSeparatingWord(dfa, mealy, alphabet); Automata.findSeparatingWord(mealy, mealy, alphabet); Automata.findSeparatingWord(mealy, mmlt, alphabet); - Automata.findSeparatingWord(mealy, DeterministicFiniteSemantics.fromAutomaton(mmlt), alphabet); +// Automata.findSeparatingWord(mealy, DeterministicFiniteSemantics.fromAutomaton(mmlt), alphabet); + + var newMealy = new CompactMealy<>(alphabet); + AutomatonLowLevelCopy.copy(AutomatonCopyMethod.STATE_BY_STATE, mmlt, alphabet, newMealy); + Automata.findSeparatingWord(mealy, newMealy, alphabet); } } diff --git a/modelchecking/ltsmin/src/test/java/net/automatalib/modelchecker/ltsmin/integration/AbstractAut2ETF2FSM2AutTest.java b/modelchecking/ltsmin/src/test/java/net/automatalib/modelchecker/ltsmin/integration/AbstractAut2ETF2FSM2AutTest.java index 02da1ec9c..fad914e33 100644 --- a/modelchecking/ltsmin/src/test/java/net/automatalib/modelchecker/ltsmin/integration/AbstractAut2ETF2FSM2AutTest.java +++ b/modelchecking/ltsmin/src/test/java/net/automatalib/modelchecker/ltsmin/integration/AbstractAut2ETF2FSM2AutTest.java @@ -20,11 +20,11 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Alphabets; -import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.concept.InputAlphabetHolder; import net.automatalib.common.util.process.ProcessUtil; import net.automatalib.modelchecker.ltsmin.LTSminUtil; import net.automatalib.modelchecker.ltsmin.LTSminVersion; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.Automata; import org.testng.Assert; import org.testng.SkipException; @@ -44,7 +44,7 @@ * @param the automaton type. */ public abstract class AbstractAut2ETF2FSM2AutTest< - A extends UniversalDeterministicAutomaton & InputAlphabetHolder> { + A extends UniversalSemantics & InputAlphabetHolder> { @BeforeClass public void setupBeforeClass() { diff --git a/util/src/main/java/net/automatalib/util/automaton/Automata.java b/util/src/main/java/net/automatalib/util/automaton/Automata.java index aa011b1df..456f5b4f5 100644 --- a/util/src/main/java/net/automatalib/util/automaton/Automata.java +++ b/util/src/main/java/net/automatalib/util/automaton/Automata.java @@ -21,18 +21,16 @@ import java.util.List; import net.automatalib.automaton.Automaton; -import net.automatalib.automaton.DeterministicAutomaton; import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.automaton.UniversalDeterministicAutomaton; -import net.automatalib.automaton.concept.FinSem; import net.automatalib.automaton.graph.TransitionEdge; import net.automatalib.common.util.array.ArrayStorage; import net.automatalib.common.util.collection.CollectionUtil; import net.automatalib.graph.Graph; import net.automatalib.graph.UniversalGraph; import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; -import net.automatalib.semantics.DeterministicFiniteSemantics.SimpleSemantics; +import net.automatalib.semantics.DeterministicFiniteSemantics.PlainSemantics; import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; +import net.automatalib.semantics.FiniteSemantics; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.util.automaton.equivalence.CharacterizingSets; import net.automatalib.util.automaton.equivalence.DeterministicEquivalenceTest; @@ -87,8 +85,8 @@ public static Graph> asGraph(Automaton> A minimize( - UniversalDeterministicAutomaton automaton, + public static & FiniteSemantics> A minimize( + UniversalSemantics automaton, Collection inputs, A output) { @@ -156,11 +154,9 @@ public static Graph> asGraph(Automaton> A invasiveMinimize(A semantics, + public static > A invasiveMinimize(A automaton, Collection inputs) { - MutableDeterministic automaton = semantics.getSemantics(); - final List inputList = CollectionUtil.randomAccessList(inputs); int numInputs = inputs.size(); @@ -201,7 +197,8 @@ public static > A i automaton.clear(); // Add states from records - @Nullable Object[] states = new Object[records.length]; + @Nullable + Object[] states = new Object[records.length]; for (int i = 0; i < records.length; i++) { ResultStateRecord rec = records[i]; SP prop = rec.property; @@ -231,7 +228,7 @@ public static > A i automaton.addTransition(state, input, succ, transRec.property); } } - return semantics; + return automaton; } /** @@ -252,8 +249,8 @@ public static > A i * * @see #findSeparatingWord(UniversalSemantics, UniversalSemantics, Collection) */ - public static boolean testEquivalence(UniversalSemantics reference, - UniversalSemantics other, + public static boolean testEquivalence(UniversalSemantics reference, + UniversalSemantics other, Collection inputs) { return findSeparatingWord(reference, other, inputs) == null; } @@ -273,9 +270,9 @@ public static boolean testEquivalence(UniversalSemantics referen * * @return a separating word, or {@code null} if no such word could be found. */ - public static & FinSem> @Nullable Word findSeparatingWord(A reference, - A other, - Collection inputs) { + public static @Nullable Word findSeparatingWord(UniversalSemantics reference, + UniversalSemantics other, + Collection inputs) { return NearLinearEquivalenceTest.findSeparatingWord(reference, other, inputs); } @@ -299,7 +296,7 @@ public static boolean testEquivalence(UniversalSemantics referen * * @return a separating word, or {@code null} if no such word could be found */ - public static @Nullable Word findSeparatingWord(UniversalSemantics automaton, + public static @Nullable Word findSeparatingWord(UniversalSemantics automaton, S state1, S state2, Collection inputs) { @@ -322,8 +319,8 @@ public static boolean testEquivalence(UniversalSemantics referen * * @return a separating word, or {@code null} if no such word could be found. */ - public static @Nullable Word findShortestSeparatingWord(UniversalSemantics reference, - UniversalSemantics other, + public static @Nullable Word findShortestSeparatingWord(UniversalSemantics reference, + UniversalSemantics other, Collection inputs) { return DeterministicEquivalenceTest.findSeparatingWord(reference, other, inputs); } @@ -342,7 +339,7 @@ public static boolean testEquivalence(UniversalSemantics referen * * @see CharacterizingSets */ - public static List> characterizingSet(UniversalSemantics automaton, + public static List> characterizingSet(UniversalSemantics automaton, Collection inputs) { List> result = new ArrayList<>(); characterizingSet(automaton, inputs, result); @@ -366,13 +363,13 @@ public static List> characterizingSet(UniversalSemantics * * @see CharacterizingSets */ - public static void characterizingSet(UniversalSemantics automaton, + public static void characterizingSet(UniversalSemantics automaton, Collection inputs, Collection> result) { CharacterizingSets.findCharacterizingSet(automaton, inputs, result); } - public static boolean incrementalCharacterizingSet(UniversalSemantics automaton, + public static boolean incrementalCharacterizingSet(UniversalSemantics automaton, Collection inputs, Collection> oldSuffixes, Collection> newSuffixes) { @@ -397,7 +394,7 @@ public static boolean incrementalCharacterizingSet(UniversalSemantics List> stateCharacterizingSet(UniversalSemantics automaton, + public static List> stateCharacterizingSet(UniversalSemantics automaton, Collection inputs, S state) { List> result = new ArrayList<>(); @@ -426,7 +423,7 @@ public static List> stateCharacterizingSet(UniversalSemantics void stateCharacterizingSet(UniversalSemantics automaton, + public static void stateCharacterizingSet(UniversalSemantics automaton, Collection inputs, S state, Collection> result) { @@ -445,13 +442,11 @@ public static void stateCharacterizingSet(UniversalSemantics * * @return the state cover for the given automaton * - * @see Covers#stateCover(DeterministicAutomaton, Collection, Collection) + * @see Covers#stateCover(PlainSemantics, Collection, Collection) */ - public static List> stateCover(SimpleSemantics semantics, - Collection inputs) { - DeterministicAutomaton automaton = semantics.getSemantics(); + public static List> stateCover(PlainSemantics automaton, Collection inputs) { final List> result = new ArrayList<>(automaton.size()); - Covers.stateCover(semantics, inputs, result); + Covers.stateCover(automaton, inputs, result); return result; } @@ -467,13 +462,11 @@ public static List> stateCover(SimpleSemantics semantics, * * @return the transition cover for the given automaton * - * @see Covers#transitionCover(DeterministicAutomaton, Collection, Collection) + * @see Covers#transitionCover(PlainSemantics, Collection, Collection) */ - public static List> transitionCover(SimpleSemantics semantics, - Collection inputs) { - DeterministicAutomaton automaton = semantics.getSemantics(); + public static List> transitionCover(PlainSemantics automaton, Collection inputs) { final List> result = new ArrayList<>(automaton.size() * inputs.size()); - Covers.transitionCover(semantics, inputs, result); + Covers.transitionCover(automaton, inputs, result); return result; } @@ -489,13 +482,11 @@ public static List> transitionCover(SimpleSemantics semantics, * * @return the structural cover for the given automaton * - * @see Covers#structuralCover(DeterministicAutomaton, Collection, Collection) + * @see Covers#structuralCover(PlainSemantics, Collection, Collection) */ - public static List> structuralCover(SimpleSemantics semantics, - Collection inputs) { - DeterministicAutomaton automaton = semantics.getSemantics(); + public static List> structuralCover(PlainSemantics automaton, Collection inputs) { final List> result = new ArrayList<>(automaton.size() * (inputs.size() + 1)); - Covers.structuralCover(semantics, inputs, result); + Covers.structuralCover(automaton, inputs, result); return result; } diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/IncrementalWMethodTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/IncrementalWMethodTestsIterator.java index 02f783844..10dd63139 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/IncrementalWMethodTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/IncrementalWMethodTestsIterator.java @@ -21,8 +21,7 @@ import java.util.List; import net.automatalib.alphabet.Alphabet; -import net.automatalib.automaton.UniversalDeterministicAutomaton; -import net.automatalib.automaton.concept.FinSem; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.Automata; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.word.Word; @@ -56,7 +55,7 @@ public void setMaxDepth(int maxDepth) { this.maxDepth = maxDepth; } - public & FinSem> void update(A automaton) { + public void update(UniversalSemantics automaton) { int oldNumPrefixes = prefixes.size(); boolean newPrefixes = Covers.incrementalTransitionCover(automaton, alphabet, prefixes, prefixes); @@ -97,7 +96,8 @@ public Word next() { Item nextItem = itemQueue.remove(); Word result = assembleWord(nextItem); - @Nullable Item inc = increment(nextItem); + @Nullable + Item inc = increment(nextItem); if (inc != null) { itemQueue.offer(inc); } diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/KWayStateCoverTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/KWayStateCoverTestsIterator.java index 8d06c7018..9ba19da24 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/KWayStateCoverTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/KWayStateCoverTestsIterator.java @@ -27,8 +27,6 @@ import java.util.Set; import java.util.stream.Stream; -import net.automatalib.automaton.DeterministicAutomaton; -import net.automatalib.automaton.concept.FinSem; import net.automatalib.common.util.HashUtil; import net.automatalib.common.util.collection.AbstractSimplifiedIterator; import net.automatalib.common.util.collection.CollectionUtil; @@ -36,6 +34,7 @@ import net.automatalib.common.util.mapping.Mapping; import net.automatalib.common.util.mapping.Mappings; import net.automatalib.common.util.random.RandomUtil; +import net.automatalib.semantics.DeterministicFiniteSemantics.PlainSemantics; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.word.Word; import net.automatalib.word.WordBuilder; @@ -58,11 +57,8 @@ * automaton state type * @param * input symbol type - * @param - * automaton type */ -public class KWayStateCoverTestsIterator & FinSem> - extends AbstractSimplifiedIterator> { +public class KWayStateCoverTestsIterator extends AbstractSimplifiedIterator> { /** * The default value of k used in the k-way combinations/permutations. @@ -74,7 +70,7 @@ public class KWayStateCoverTestsIterator automaton; private final List alphabet; private final Random random; private final int randomWalkLen; @@ -92,9 +88,9 @@ public class KWayStateCoverTestsIterator inputs) { + public KWayStateCoverTestsIterator(PlainSemantics automaton, Collection inputs) { this(automaton, inputs, new Random()); } @@ -110,9 +106,11 @@ public KWayStateCoverTestsIterator(A automaton, Collection inputs) * @param random * the random number generator to use * - * @see #KWayStateCoverTestsIterator(DeterministicAutomaton, Collection, Random, int, int, CombinationMethod) + * @see #KWayStateCoverTestsIterator(PlainSemantics, Collection, Random, int, int, CombinationMethod) */ - public KWayStateCoverTestsIterator(A automaton, Collection inputs, Random random) { + public KWayStateCoverTestsIterator(PlainSemantics automaton, + Collection inputs, + Random random) { this(automaton, inputs, random, DEFAULT_R_WALK_LEN, DEFAULT_K, CombinationMethod.PERMUTATIONS); } @@ -132,7 +130,7 @@ public KWayStateCoverTestsIterator(A automaton, Collection inputs, * @param method * the method for computing combinations */ - public KWayStateCoverTestsIterator(A automaton, + public KWayStateCoverTestsIterator(PlainSemantics automaton, Collection inputs, Random random, int randomWalkLen, diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/KWayTransitionCoverTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/KWayTransitionCoverTestsIterator.java index 1c6893289..dd3d9a763 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/KWayTransitionCoverTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/KWayTransitionCoverTestsIterator.java @@ -27,8 +27,6 @@ import java.util.Set; import java.util.stream.Stream; -import net.automatalib.automaton.DeterministicAutomaton; -import net.automatalib.automaton.concept.FinSem; import net.automatalib.common.util.HashUtil; import net.automatalib.common.util.collection.AbstractSimplifiedIterator; import net.automatalib.common.util.collection.AbstractTwoLevelIterator; @@ -37,6 +35,7 @@ import net.automatalib.common.util.collection.IteratorUtil; import net.automatalib.common.util.mapping.Mapping; import net.automatalib.common.util.random.RandomUtil; +import net.automatalib.semantics.DeterministicFiniteSemantics.PlainSemantics; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.word.Word; import net.automatalib.word.WordBuilder; @@ -60,11 +59,8 @@ * automaton state type * @param * input symbol type - * @param - * automaton type */ -public class KWayTransitionCoverTestsIterator & FinSem> - implements Iterator> { +public class KWayTransitionCoverTestsIterator implements Iterator> { /** * The default value of k used in the k-way computations. @@ -91,7 +87,7 @@ public class KWayTransitionCoverTestsIterator automaton; private final List alphabet; private final Random random; private final int randomWalkLen; @@ -111,9 +107,9 @@ public class KWayTransitionCoverTestsIterator inputs) { + public KWayTransitionCoverTestsIterator(PlainSemantics automaton, Collection inputs) { this(automaton, inputs, new Random()); } @@ -131,10 +127,12 @@ public KWayTransitionCoverTestsIterator(A automaton, Collection inp * @param random * the random number generator to use * - * @see #KWayTransitionCoverTestsIterator(DeterministicAutomaton, Collection, Random, int, int, int, int, int, + * @see #KWayTransitionCoverTestsIterator(PlainSemantics, Collection, Random, int, int, int, int, int, * OptimizationMetric, GenerationMethod) */ - public KWayTransitionCoverTestsIterator(A automaton, Collection inputs, Random random) { + public KWayTransitionCoverTestsIterator(PlainSemantics automaton, + Collection inputs, + Random random) { this(automaton, inputs, random, @@ -173,7 +171,7 @@ public KWayTransitionCoverTestsIterator(A automaton, Collection inp * @param generationMethod * defines how the tests are generated */ - public KWayTransitionCoverTestsIterator(A automaton, + public KWayTransitionCoverTestsIterator(PlainSemantics automaton, Collection inputs, Random random, int randomWalkLen, @@ -214,7 +212,7 @@ public Word next() { return iterator.next(); } - private Set> generateRandomPaths(A hypothesis, S initial) { + private Set> generateRandomPaths(PlainSemantics hypothesis, S initial) { final Set> result = new HashSet<>(HashUtil.capacity(numGeneratePaths)); for (int i = 0; i < numGeneratePaths; i++) { @@ -227,7 +225,7 @@ private Set> generateRandomPaths(A hypothesis, S initial) { return result; } - private Path createPath(A hypothesis, S initial, Word steps) { + private Path createPath(PlainSemantics hypothesis, S initial, Word steps) { final Set> transitions = new HashSet<>(); final List<@Nullable S> prevStates = new ArrayList<>(steps.size()); @@ -254,7 +252,7 @@ private Path createPath(A hypothesis, S initial, Word steps) { return new Path<>(steps, transitions); } - private Iterator> generatePrefixSteps(A hypothesis, S initial) { + private Iterator> generatePrefixSteps(PlainSemantics hypothesis, S initial) { final List states = new ArrayList<>(hypothesis.getStates()); Collections.reverse(states); return new PrefixStepsIterator(states.iterator(), initial); @@ -424,9 +422,7 @@ public enum GenerationMethod { */ RANDOM { @Override - & FinSem> Iterator> getIterator( - KWayTransitionCoverTestsIterator self, - S initial) { + Iterator> getIterator(KWayTransitionCoverTestsIterator self, S initial) { return self.new GreedySetCoverIterator(initial); } }, @@ -435,16 +431,12 @@ public enum GenerationMethod { */ PREFIX { @Override - & FinSem> Iterator> getIterator( - KWayTransitionCoverTestsIterator self, - S initial) { + Iterator> getIterator(KWayTransitionCoverTestsIterator self, S initial) { return self.generatePrefixSteps(self.automaton, initial); } }; - abstract & FinSem> Iterator> getIterator( - KWayTransitionCoverTestsIterator self, - S initial); + abstract Iterator> getIterator(KWayTransitionCoverTestsIterator self, S initial); } /** diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/ProceduralWMethodTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/ProceduralWMethodTestsIterator.java index 56e136724..6aa808afd 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/ProceduralWMethodTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/ProceduralWMethodTestsIterator.java @@ -23,8 +23,6 @@ import java.util.Map; import net.automatalib.alphabet.ProceduralInputAlphabet; -import net.automatalib.automaton.UniversalDeterministicAutomaton; -import net.automatalib.automaton.concept.FinSem; import net.automatalib.common.util.collection.AbstractThreeLevelIterator; import net.automatalib.common.util.collection.AbstractTwoLevelIterator; import net.automatalib.common.util.collection.IterableUtil; @@ -38,7 +36,7 @@ import net.automatalib.word.WordBuilder; import org.checkerframework.checker.nullness.qual.NonNull; -class ProceduralWMethodTestsIterator & FinSem> +class ProceduralWMethodTestsIterator> extends AbstractTwoLevelIterator, Word> { private static final List>> EPSILON = diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/WMethodTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/WMethodTestsIterator.java index 1c53ed244..9f1cd0a7a 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/WMethodTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/WMethodTestsIterator.java @@ -20,7 +20,6 @@ import java.util.Iterator; import java.util.List; -import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.common.util.collection.AbstractThreeLevelIterator; import net.automatalib.common.util.collection.IterableUtil; import net.automatalib.common.util.collection.IteratorUtil; @@ -48,16 +47,15 @@ public class WMethodTestsIterator extends AbstractThreeLevelIterator, private final Iterable> suffixes; /** - * Convenience-constructor for {@link #WMethodTestsIterator(UniversalDeterministicAutomaton, Collection, int)} that - * selects {@code 0} as {@code maxDepth}. + * Convenience-constructor for {@link #WMethodTestsIterator(UniversalSemantics, Collection, int)} that selects + * {@code 0} as {@code maxDepth}. * * @param automaton * the automaton for which the testing sequences should be generated * @param inputs * the input symbols that should be considered for test sequence generation */ - public WMethodTestsIterator(UniversalSemantics automaton, - Collection inputs) { + public WMethodTestsIterator(UniversalSemantics automaton, Collection inputs) { this(automaton, inputs, 0); } @@ -71,7 +69,7 @@ public WMethodTestsIterator(UniversalSemantics automaton, * @param maxDepth * the maximum number of symbols that are appended to the transition-cover part of the test sequences */ - public WMethodTestsIterator(UniversalSemantics automaton, + public WMethodTestsIterator(UniversalSemantics automaton, Collection inputs, int maxDepth) { super(IteratorUtil.concat(IteratorUtil.singleton(Word.epsilon()), diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/WpMethodTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/WpMethodTestsIterator.java index ede304087..55b444a62 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/WpMethodTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/WpMethodTestsIterator.java @@ -22,7 +22,6 @@ import java.util.List; import java.util.Set; -import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.common.util.HashUtil; import net.automatalib.common.util.collection.AbstractThreeLevelIterator; import net.automatalib.common.util.collection.IterableUtil; @@ -50,16 +49,15 @@ public class WpMethodTestsIterator implements Iterator> { private final Iterator> wpIterator; /** - * Convenience-constructor for {@link #WpMethodTestsIterator(UniversalDeterministicAutomaton, Collection, int)} that - * selects {@code 0} as {@code maxDepth}. + * Convenience-constructor for {@link #WpMethodTestsIterator(UniversalSemantics, Collection, int)} that selects + * {@code 0} as {@code maxDepth}. * * @param automaton * the automaton for which the testing sequences should be generated * @param inputs * the input symbols that should be considered for test sequence generation */ - public WpMethodTestsIterator(UniversalSemantics automaton, - Collection inputs) { + public WpMethodTestsIterator(UniversalSemantics automaton, Collection inputs) { this(automaton, inputs, 0); } @@ -73,17 +71,16 @@ public WpMethodTestsIterator(UniversalSemantics automaton, * @param maxDepth * the maximum number of symbols that are appended to the transition-cover part of the test sequences */ - public WpMethodTestsIterator(UniversalSemantics semantics, + public WpMethodTestsIterator(UniversalSemantics automaton, Collection inputs, int maxDepth) { - final UniversalDeterministicAutomaton automaton = semantics.getSemantics(); final Set> stateCover = new HashSet<>(HashUtil.capacity(automaton.size())); final Set> transitionCover = new HashSet<>(HashUtil.capacity(automaton.size() * inputs.size())); - Covers.cover(semantics, inputs, stateCover, transitionCover); + Covers.cover(automaton, inputs, stateCover, transitionCover); - Iterator> characterizingIter = CharacterizingSets.characterizingSetIterator(semantics, inputs); + Iterator> characterizingIter = CharacterizingSets.characterizingSetIterator(automaton, inputs); // Special case: List of characterizing suffixes may be empty, // but in this case we still need to iterate over the prefixes! @@ -97,7 +94,7 @@ public WpMethodTestsIterator(UniversalSemantics semantics, // Phase 2: transitions (not in state cover) * middle part * local suffixes transitionCover.removeAll(stateCover); - final Iterator> secondIterator = new SecondPhaseIterator<>(semantics, + final Iterator> secondIterator = new SecondPhaseIterator<>(automaton, inputs, transitionCover, IterableUtil.allTuples(inputs, 0, maxDepth)); @@ -147,21 +144,19 @@ protected Word combine(Word suffix, List middle, Word prefix) { private static class SecondPhaseIterator extends AbstractThreeLevelIterator, List, Word, Word> { - private final UniversalSemantics semantics; - private final UniversalDeterministicAutomaton automaton; + private final UniversalSemantics automaton; private final Collection inputs; private final MutableMapping>> localSuffixSets; private final Iterable> middleParts; - SecondPhaseIterator(UniversalSemantics semantics, + SecondPhaseIterator(UniversalSemantics automaton, Collection inputs, Iterable> prefixes, Iterable> middleParts) { super(prefixes.iterator()); - this.semantics = semantics; - this.automaton = semantics.getSemantics(); + this.automaton = automaton; this.inputs = inputs; this.localSuffixSets = automaton.createStaticStateMapping(); this.middleParts = middleParts; @@ -180,10 +175,11 @@ protected Iterator> l3Iterator(Word prefix, List middle) { @SuppressWarnings("nullness") // input sequences have been computed on defined transitions final @NonNull S state = automaton.getSuccessor(tmp, middle); - @Nullable List> localSuffixes = localSuffixSets.get(state); + @Nullable + List> localSuffixes = localSuffixSets.get(state); if (localSuffixes == null) { - localSuffixes = Automata.stateCharacterizingSet(semantics, inputs, state); + localSuffixes = Automata.stateCharacterizingSet(automaton, inputs, state); if (localSuffixes.isEmpty()) { localSuffixes = Collections.singletonList(Word.epsilon()); } diff --git a/util/src/main/java/net/automatalib/util/automaton/cover/Covers.java b/util/src/main/java/net/automatalib/util/automaton/cover/Covers.java index bf1d077a4..99f69b70e 100644 --- a/util/src/main/java/net/automatalib/util/automaton/cover/Covers.java +++ b/util/src/main/java/net/automatalib/util/automaton/cover/Covers.java @@ -24,11 +24,10 @@ import java.util.function.BiFunction; import java.util.function.Consumer; -import net.automatalib.automaton.DeterministicAutomaton; -import net.automatalib.automaton.concept.FinSem; import net.automatalib.common.util.HashUtil; import net.automatalib.common.util.mapping.Mapping; import net.automatalib.common.util.mapping.MutableMapping; +import net.automatalib.semantics.DeterministicFiniteSemantics.PlainSemantics; import net.automatalib.word.Word; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -57,9 +56,9 @@ private Covers() {} * @param * input symbol type */ - public static & FinSem> void stateCover(A automaton, - Collection inputs, - Collection> states) { + public static void stateCover(PlainSemantics automaton, + Collection inputs, + Collection> states) { cover(automaton, inputs, automaton.getInitialState(), states::add, w -> {}); } @@ -76,10 +75,10 @@ private Covers() {} * * @return an iterator for the input sequences of the cover. * - * @see #stateCover(DeterministicAutomaton, Collection, Collection) + * @see #stateCover(PlainSemantics, Collection, Collection) */ - public static & FinSem> Iterator> stateCoverIterator(A automaton, - Collection inputs) { + public static Iterator> stateCoverIterator(PlainSemantics automaton, + Collection inputs) { return new IncrementalStateCoverIterator<>(automaton, inputs, Collections.emptyList()); } @@ -104,9 +103,9 @@ private Covers() {} * @param * input symbol type */ - public static & FinSem> void transitionCover(A automaton, - Collection inputs, - Collection> transitions) { + public static void transitionCover(PlainSemantics automaton, + Collection inputs, + Collection> transitions) { cover(automaton, inputs, automaton.getInitialState(), w -> {}, transitions::add); } @@ -123,10 +122,10 @@ private Covers() {} * * @return an iterator for the input sequences of the cover. * - * @see #transitionCover(DeterministicAutomaton, Collection, Collection) + * @see #transitionCover(PlainSemantics, Collection, Collection) */ - public static & FinSem> Iterator> transitionCoverIterator(A automaton, - Collection inputs) { + public static Iterator> transitionCoverIterator(PlainSemantics automaton, + Collection inputs) { return new IncrementalTransitionCoverIterator<>(automaton, inputs, Collections.emptyList()); } @@ -146,12 +145,12 @@ private Covers() {} * @param * input symbol type * - * @see #stateCover(DeterministicAutomaton, Collection, Collection) - * @see #transitionCover(DeterministicAutomaton, Collection, Collection) + * @see #stateCover(PlainSemantics, Collection, Collection) + * @see #transitionCover(PlainSemantics, Collection, Collection) */ - public static & FinSem> void structuralCover(A automaton, - Collection inputs, - Collection> cover) { + public static void structuralCover(PlainSemantics automaton, + Collection inputs, + Collection> cover) { cover(automaton, inputs, automaton.getInitialState(), cover::add, cover::add); } @@ -171,13 +170,13 @@ private Covers() {} * @param * input symbol type * - * @see #stateCover(DeterministicAutomaton, Collection, Collection) - * @see #transitionCover(DeterministicAutomaton, Collection, Collection) + * @see #stateCover(PlainSemantics, Collection, Collection) + * @see #transitionCover(PlainSemantics, Collection, Collection) */ - public static & FinSem> void cover(A automaton, - Collection inputs, - Collection> states, - Collection> transitions) { + public static void cover(PlainSemantics automaton, + Collection inputs, + Collection> states, + Collection> transitions) { cover(automaton, inputs, automaton.getInitialState(), states::add, transitions::add); } @@ -211,7 +210,7 @@ private Covers() {} * * @return a mapping from automaton states to their access sequences */ - public static Mapping> cover(DeterministicAutomaton automaton, + public static Mapping> cover(PlainSemantics automaton, Collection inputs, @Nullable S start, Consumer> states, @@ -234,8 +233,7 @@ private Covers() {} while ((curr = bfsQueue.poll()) != null) { @SuppressWarnings("nullness") // in a breadth-first traversal the predecessors are always defined - @NonNull - Word as = reach.get(curr); + @NonNull Word as = reach.get(curr); for (I in : inputs) { S succ = automaton.getSuccessor(curr, in); @@ -276,12 +274,12 @@ private Covers() {} * * @return {@code true} if new sequences have been added to the state cover, {@code false} otherwise. * - * @see #stateCover(DeterministicAutomaton, Collection, Collection) + * @see #stateCover(PlainSemantics, Collection, Collection) */ - public static & FinSem> boolean incrementalStateCover(A automaton, - Collection inputs, - Collection> oldStates, - Collection> newStates) { + public static boolean incrementalStateCover(PlainSemantics automaton, + Collection inputs, + Collection> oldStates, + Collection> newStates) { S init = automaton.getInitialState(); if (init == null) { @@ -345,12 +343,11 @@ private Covers() {} * * @return an iterator for the remaining input sequences of the cover. * - * @see #incrementalStateCover(DeterministicAutomaton, Collection, Collection, Collection) + * @see #incrementalStateCover(PlainSemantics, Collection, Collection, Collection) */ - public static & FinSem> Iterator> incrementalStateCoverIterator( - A automaton, - Collection inputs, - Collection> stateCover) { + public static Iterator> incrementalStateCoverIterator(PlainSemantics automaton, + Collection inputs, + Collection> stateCover) { return new IncrementalStateCoverIterator<>(automaton, inputs, stateCover); } @@ -371,12 +368,12 @@ private Covers() {} * * @return {@code true} if new sequences have been added to the state cover, {@code false} otherwise. * - * @see #transitionCover(DeterministicAutomaton, Collection, Collection) + * @see #transitionCover(PlainSemantics, Collection, Collection) */ - public static & FinSem> boolean incrementalTransitionCover(A automaton, - Collection inputs, - Collection> oldTransCover, - Collection> newTransCover) { + public static boolean incrementalTransitionCover(PlainSemantics automaton, + Collection inputs, + Collection> oldTransCover, + Collection> newTransCover) { final int oldTransSize = newTransCover.size(); incrementalCover(automaton, inputs, Collections.emptySet(), oldTransCover, w -> {}, newTransCover::add); @@ -399,12 +396,11 @@ private Covers() {} * * @return an iterator for the remaining input sequences of the cover. * - * @see #incrementalStateCover(DeterministicAutomaton, Collection, Collection, Collection) + * @see #incrementalStateCover(PlainSemantics, Collection, Collection, Collection) */ - public static & FinSem> Iterator> incrementalTransitionCoverIterator( - A automaton, - Collection inputs, - Collection> transitionCover) { + public static Iterator> incrementalTransitionCoverIterator(PlainSemantics automaton, + Collection inputs, + Collection> transitionCover) { return new IncrementalTransitionCoverIterator<>(automaton, inputs, transitionCover); } @@ -428,15 +424,15 @@ private Covers() {} * * @return {@code true} if new sequences have been added to the structural cover, {@code false} otherwise. * - * @see #incrementalStateCover(DeterministicAutomaton, Collection, Collection, Collection) - * @see #incrementalStateCover(DeterministicAutomaton, Collection, Collection, Collection) + * @see #incrementalStateCover(PlainSemantics, Collection, Collection, Collection) + * @see #incrementalStateCover(PlainSemantics, Collection, Collection, Collection) */ - public static & FinSem> boolean incrementalCover(A automaton, - Collection inputs, - Collection> oldStateCover, - Collection> oldTransCover, - Collection> newStateCover, - Collection> newTransCover) { + public static boolean incrementalCover(PlainSemantics automaton, + Collection inputs, + Collection> oldStateCover, + Collection> oldTransCover, + Collection> newStateCover, + Collection> newTransCover) { final int oldStateSize = newStateCover.size(); final int oldTransSize = newTransCover.size(); @@ -445,21 +441,12 @@ private Covers() {} return oldStateSize < newStateCover.size() || oldTransSize < newTransCover.size(); } - private static void incrementalCover(DeterministicAutomaton automaton, - Collection inputs, - Collection> oldStateCover, - Collection> oldTransCover, - Consumer> newStateCover, - Consumer> newTransCover) { - incrementalCover2(automaton, inputs, oldStateCover, oldTransCover, newStateCover, newTransCover); - } - - private static void incrementalCover2(DeterministicAutomaton automaton, - Collection inputs, - Collection> oldStateCover, - Collection> oldTransCover, - Consumer> newStateCover, - Consumer> newTransCover) { + private static void incrementalCover(PlainSemantics automaton, + Collection inputs, + Collection> oldStateCover, + Collection> oldTransCover, + Consumer> newStateCover, + Consumer> newTransCover) { S init = automaton.getInitialState(); @@ -521,7 +508,7 @@ private static void incrementalCover2(DeterministicAutomaton aut static boolean buildReachFromStateCover(MutableMapping> reach, Queue> bfsQueue, - DeterministicAutomaton automaton, + PlainSemantics automaton, Collection> oldStateCover, BiFunction, Record> recordBuilder) { @@ -546,7 +533,7 @@ static boolean buildReachFromStateCover(MutableMapping> r static void buildReachFromTransitionCover(MutableMapping> reach, Queue> bfsQueue, - DeterministicAutomaton automaton, + PlainSemantics automaton, Collection> oldTransCover, BiFunction, Record> recordBuilder, Consumer> newStateCallback) { diff --git a/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalStateCoverIterator.java b/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalStateCoverIterator.java index 37f330169..2d5c6cbd2 100644 --- a/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalStateCoverIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalStateCoverIterator.java @@ -20,9 +20,9 @@ import java.util.Iterator; import java.util.Queue; -import net.automatalib.automaton.DeterministicAutomaton; import net.automatalib.common.util.collection.AbstractSimplifiedIterator; import net.automatalib.common.util.mapping.MutableMapping; +import net.automatalib.semantics.DeterministicFiniteSemantics.PlainSemantics; import net.automatalib.word.Word; import org.checkerframework.checker.nullness.qual.Nullable; @@ -38,11 +38,11 @@ * @param * input symbol type * - * @see Covers#stateCover(DeterministicAutomaton, Collection, Collection) + * @see Covers#stateCover(PlainSemantics, Collection, Collection) */ class IncrementalStateCoverIterator extends AbstractSimplifiedIterator> { - private final DeterministicAutomaton automaton; + private final PlainSemantics automaton; private final Collection inputs; private final Collection> oldCover; @@ -52,7 +52,7 @@ class IncrementalStateCoverIterator extends AbstractSimplifiedIterator inputIterator; private @Nullable Record curr; - IncrementalStateCoverIterator(DeterministicAutomaton automaton, + IncrementalStateCoverIterator(PlainSemantics automaton, Collection inputs, Collection> oldCover) { this.automaton = automaton; diff --git a/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalTransitionCoverIterator.java b/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalTransitionCoverIterator.java index f24a93bbb..2b0ce6b2b 100644 --- a/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalTransitionCoverIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalTransitionCoverIterator.java @@ -21,10 +21,10 @@ import java.util.Iterator; import java.util.Queue; -import net.automatalib.automaton.DeterministicAutomaton; import net.automatalib.common.util.HashUtil; import net.automatalib.common.util.collection.AbstractSimplifiedIterator; import net.automatalib.common.util.mapping.MutableMapping; +import net.automatalib.semantics.DeterministicFiniteSemantics.PlainSemantics; import net.automatalib.word.Word; /** @@ -39,11 +39,11 @@ * @param * input symbol type * - * @see Covers#transitionCover(DeterministicAutomaton, Collection, Collection) + * @see Covers#transitionCover(PlainSemantics, Collection, Collection) */ class IncrementalTransitionCoverIterator extends AbstractSimplifiedIterator> { - private final DeterministicAutomaton automaton; + private final PlainSemantics automaton; private final Collection inputs; private final Collection> oldCover; @@ -53,13 +53,13 @@ class IncrementalTransitionCoverIterator extends AbstractSimplifiedIterato private Iterator inputIterator; private Record curr; - IncrementalTransitionCoverIterator(DeterministicAutomaton automaton, + IncrementalTransitionCoverIterator(PlainSemantics automaton, Collection inputs, Collection> oldCover) { this.automaton = automaton; this.inputs = inputs; this.oldCover = oldCover; - this.reach = automaton.createStaticStateMapping(); + this.reach = this.automaton.createStaticStateMapping(); this.bfsQueue = new ArrayDeque<>(); } diff --git a/util/src/main/java/net/automatalib/util/automaton/equivalence/Bisimulation.java b/util/src/main/java/net/automatalib/util/automaton/equivalence/Bisimulation.java index 1331bd87f..713547b18 100644 --- a/util/src/main/java/net/automatalib/util/automaton/equivalence/Bisimulation.java +++ b/util/src/main/java/net/automatalib/util/automaton/equivalence/Bisimulation.java @@ -20,11 +20,10 @@ import java.util.List; import java.util.Set; -import net.automatalib.automaton.Automaton; import net.automatalib.automaton.concept.StateIDs; import net.automatalib.common.util.Pair; import net.automatalib.common.util.collection.CollectionUtil; -import net.automatalib.semantics.FiniteSemantics.SimpleSemantics; +import net.automatalib.semantics.FiniteSemantics.PlainSemantics; import net.automatalib.util.partitionrefinement.Valmari; import net.automatalib.util.partitionrefinement.Valmari.RefinablePartition; @@ -34,16 +33,9 @@ private Bisimulation() { // prevent instantiation } - public static Set> bisimulationEquivalenceRelation(SimpleSemantics a, - SimpleSemantics b, - Collection inputs) { - return bisimulationEquivalenceRelation(a.getSemantics(), b.getSemantics(), inputs); - } - - private static Set> bisimulationEquivalenceRelation(Automaton a, - Automaton b, - Collection inputs) { - + public static Set> bisimulationEquivalenceRelation(PlainSemantics a, + PlainSemantics b, + Collection inputs) { final List alphabet = CollectionUtil.randomAccessList(inputs); final StateIDs aIDs = a.stateIDs(); final StateIDs bIDs = b.stateIDs(); diff --git a/util/src/main/java/net/automatalib/util/automaton/equivalence/CharacterizingSets.java b/util/src/main/java/net/automatalib/util/automaton/equivalence/CharacterizingSets.java index 64af4cabc..e81c94e6e 100644 --- a/util/src/main/java/net/automatalib/util/automaton/equivalence/CharacterizingSets.java +++ b/util/src/main/java/net/automatalib/util/automaton/equivalence/CharacterizingSets.java @@ -56,7 +56,7 @@ private CharacterizingSets() {} /** * Computes a characterizing set for the given automaton. * - * @param semantics + * @param automaton * the automaton for which to determine the characterizing set. * @param inputs * the input alphabets to consider @@ -65,16 +65,16 @@ private CharacterizingSets() {} * @param * input symbol type */ - public static void findCharacterizingSet(UniversalSemantics semantics, + public static void findCharacterizingSet(UniversalSemantics automaton, Collection inputs, Collection> result) { - findIncrementalCharacterizingSet(semantics, inputs, Collections.emptyList(), result); + findIncrementalCharacterizingSet(automaton, inputs, Collections.emptyList(), result); } /** * Computes a characterizing set for a specified state in the given automaton. * - * @param semantics + * @param automaton * the automaton containing the state * @param inputs * the input alphabets to consider @@ -87,13 +87,11 @@ public static void findCharacterizingSet(UniversalSemantics sema * @param * input symbol type */ - public static void findCharacterizingSet(UniversalSemantics semantics, + public static void findCharacterizingSet(UniversalSemantics automaton, Collection inputs, S state, Collection> result) { - UniversalDeterministicAutomaton automaton = semantics.getSemantics(); - Object prop = automaton.getStateProperty(state); List currentBlock = new ArrayList<>(); @@ -123,7 +121,7 @@ public static void findCharacterizingSet(UniversalSemantics s Word suffix = null; while (it.hasNext() && suffix == null) { S s = it.next(); - suffix = Automata.findSeparatingWord(semantics, state, s, inputs); + suffix = Automata.findSeparatingWord(automaton, state, s, inputs); } if (suffix == null) { @@ -146,9 +144,9 @@ public static void findCharacterizingSet(UniversalSemantics s } } - public static Iterator> characterizingSetIterator(UniversalSemantics semantics, - Collection inputs) { - return new IncrementalCharacterizingSetIterator<>(semantics, inputs, Collections.emptyList()); + public static Iterator> characterizingSetIterator(UniversalSemantics automaton, + Collection inputs) { + return new IncrementalCharacterizingSetIterator<>(automaton, inputs, Collections.emptyList()); } private static List buildTrace(UniversalDeterministicAutomaton automaton, @@ -219,13 +217,11 @@ private static boolean checkTrace(UniversalDeterministicAut return true; } - public static boolean findIncrementalCharacterizingSet(UniversalSemantics semantics, + public static boolean findIncrementalCharacterizingSet(UniversalSemantics automaton, Collection inputs, Collection> oldSuffixes, Collection> newSuffixes) { - UniversalDeterministicAutomaton automaton = semantics.getSemantics(); - boolean refined = false; // We need a list to ensure a stable iteration order @@ -240,7 +236,7 @@ public static boolean findIncrementalCharacterizingSet(UniversalSemantics Word suffix; - while ((suffix = refine(semantics, automaton, inputs, blocks)) != null) { + while ((suffix = refine(automaton, inputs, blocks)) != null) { newSuffixes.add(suffix); refined = true; } @@ -248,13 +244,13 @@ public static boolean findIncrementalCharacterizingSet(UniversalSemantics return refined; } - public static Iterator> incrementalCharacterizingSetIterator(UniversalSemantics semantics, - Collection inputs, - Collection> oldSuffixes) { - return new IncrementalCharacterizingSetIterator<>(semantics, inputs, oldSuffixes); + public static Iterator> incrementalCharacterizingSetIterator(UniversalSemantics automaton, + Collection inputs, + Collection> oldSuffixes) { + return new IncrementalCharacterizingSetIterator<>(automaton, inputs, oldSuffixes); } - private static Queue> buildInitialBlocks(UniversalDeterministicAutomaton automaton, + private static Queue> buildInitialBlocks(UniversalSemantics automaton, List> oldSuffixes) { Map>, List> initialPartitioning = new HashMap<>(); Queue> blocks = new ArrayDeque<>(); @@ -308,8 +304,7 @@ private static boolean epsilonRefine(UniversalDeterministicAutomaton @Nullable Word refine(UniversalSemantics semantics, - UniversalDeterministicAutomaton automaton, + private static @Nullable Word refine(UniversalSemantics automaton, Collection inputs, Queue> blockQueue) { @@ -327,7 +322,7 @@ private static boolean epsilonRefine(UniversalDeterministicAutomaton void cluster(UniversalDeterministicAutomaton extends AbstractSimplifiedIterator> { - private final UniversalSemantics semantics; - private final UniversalDeterministicAutomaton automaton; + private final UniversalSemantics automaton; private final Collection inputs; private final List> oldSuffixes; private Queue> blocks; - IncrementalCharacterizingSetIterator(UniversalSemantics semantics, + IncrementalCharacterizingSetIterator(UniversalSemantics automaton, Collection inputs, Collection> oldSuffixes) { - this.semantics = semantics; - this.automaton = semantics.getSemantics(); + this.automaton = automaton; this.inputs = inputs; this.oldSuffixes = CollectionUtil.randomAccessList(oldSuffixes); } @@ -417,7 +410,7 @@ protected boolean calculateNext() { } } - final Word suffix = refine(semantics, automaton, inputs, blocks); + final Word suffix = refine(automaton, inputs, blocks); if (suffix != null) { super.nextValue = suffix; diff --git a/util/src/main/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTest.java b/util/src/main/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTest.java index 00e09f423..080b11c77 100644 --- a/util/src/main/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTest.java +++ b/util/src/main/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTest.java @@ -22,7 +22,6 @@ import java.util.Objects; import java.util.Queue; -import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.concept.StateIDs; import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.word.Word; @@ -39,17 +38,10 @@ private DeterministicEquivalenceTest() { // prevent instantiation } - public static @Nullable Word findSeparatingWord(UniversalSemantics reference, - UniversalSemantics other, - Collection inputs) { - return findSeparatingWord(reference.getSemantics(), other.getSemantics(), inputs); - } - @SuppressWarnings("PMD.UnnecessaryCast") // we want to cast to long, to prevent overflows - private static @Nullable Word findSeparatingWord( - UniversalDeterministicAutomaton reference, - UniversalDeterministicAutomaton other, - Collection inputs) { + public static @Nullable Word findSeparatingWord(UniversalSemantics reference, + UniversalSemantics other, + Collection inputs) { int refSize = reference.size(); int otherSize = other.size(); diff --git a/util/src/main/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTest.java b/util/src/main/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTest.java index 65748dac9..a27f7917a 100644 --- a/util/src/main/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTest.java +++ b/util/src/main/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTest.java @@ -21,9 +21,7 @@ import java.util.Queue; import net.automatalib.alphabet.Alphabet; -import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.FullIntAbstraction; -import net.automatalib.automaton.concept.FinSem; import net.automatalib.automaton.concept.InputAlphabetHolder; import net.automatalib.automaton.concept.StateIDs; import net.automatalib.common.util.IntDisjointSets; @@ -44,11 +42,10 @@ private NearLinearEquivalenceTest() { // prevent instantiation } - public static & FinSem> @Nullable Word findSeparatingWord( - A target, - S init1, - S init2, - Collection inputs) { + public static @Nullable Word findSeparatingWord(UniversalSemantics target, + S init1, + S init2, + Collection inputs) { return findSeparatingWord(target, init1, init2, inputs, false); } @@ -75,12 +72,11 @@ private NearLinearEquivalenceTest() { * * @return A word separating the two states, {@code null} if no such word can be found */ - public static & FinSem> @Nullable Word findSeparatingWord( - A target, - S init1, - S init2, - Collection inputs, - boolean ignoreUndefinedTransitions) { + public static @Nullable Word findSeparatingWord(UniversalSemantics target, + S init1, + S init2, + Collection inputs, + boolean ignoreUndefinedTransitions) { Object sprop1 = target.getStateProperty(init1); Object sprop2 = target.getStateProperty(init2); @@ -178,24 +174,16 @@ private NearLinearEquivalenceTest() { return wb.toWord(); } - public static @Nullable Word findSeparatingWord(UniversalSemantics target, - UniversalSemantics other, + public static @Nullable Word findSeparatingWord(UniversalSemantics target, + UniversalSemantics other, Collection inputs) { return findSeparatingWord(target, other, inputs, false); } - public static @Nullable Word findSeparatingWord(UniversalSemantics target, - UniversalSemantics other, - Collection inputs, - boolean ignoreUndefinedTransitions) { - return findSeparatingWord(target.getSemantics(), other.getSemantics(), inputs, ignoreUndefinedTransitions); - } - - private static @Nullable Word findSeparatingWord( - UniversalDeterministicAutomaton target, - UniversalDeterministicAutomaton other, - Collection inputs, - boolean ignoreUndefinedTransitions) { + public static @Nullable Word findSeparatingWord(UniversalSemantics target, + UniversalSemantics other, + Collection inputs, + boolean ignoreUndefinedTransitions) { if (inputs instanceof Alphabet && target instanceof InputAlphabetHolder && other instanceof InputAlphabetHolder) { @@ -317,24 +305,16 @@ private NearLinearEquivalenceTest() { return wb.toWord(); } - public static @Nullable Word findSeparatingWord(UniversalSemantics target, - UniversalSemantics other, + public static @Nullable Word findSeparatingWord(UniversalSemantics target, + UniversalSemantics other, Alphabet inputs) { return findSeparatingWord(target, other, inputs, false); } - public static @Nullable Word findSeparatingWord(UniversalSemantics target, - UniversalSemantics other, - Alphabet inputs, - boolean ignoreUndefinedTransitions) { - return findSeparatingWord(target.getSemantics(), other.getSemantics(), inputs, ignoreUndefinedTransitions); - } - - private static @Nullable Word findSeparatingWord( - UniversalDeterministicAutomaton target, - UniversalDeterministicAutomaton other, - Alphabet inputs, - boolean ignoreUndefinedTransitions) { + public static @Nullable Word findSeparatingWord(UniversalSemantics target, + UniversalSemantics other, + Alphabet inputs, + boolean ignoreUndefinedTransitions) { FullIntAbstraction absTarget = target.fullIntAbstraction(inputs); FullIntAbstraction absOther = other.fullIntAbstraction(inputs); diff --git a/util/src/main/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizer.java b/util/src/main/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizer.java index ef7119288..77820c151 100644 --- a/util/src/main/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizer.java +++ b/util/src/main/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizer.java @@ -21,7 +21,6 @@ import net.automatalib.alphabet.impl.Alphabets; import net.automatalib.automaton.AutomatonCreator; import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions; import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.FullIntAbstraction; import net.automatalib.automaton.concept.InputAlphabetHolder; @@ -32,6 +31,8 @@ import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.MutableMealyMachine; import net.automatalib.automaton.transducer.impl.CompactMealy; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; +import net.automatalib.semantics.FiniteSemantics; import net.automatalib.util.automaton.minimizer.Storage.BooleanStorage; import net.automatalib.util.automaton.minimizer.Storage.GenericStorage; import net.automatalib.util.automaton.minimizer.Storage.VoidStorage; @@ -486,7 +487,7 @@ public static CompactMealy minimizePartialMealy(MealyMachine UniversalCompactDetAutomaton minimizeUniversal(UniversalDeterministicAutomaton automaton, + public static UniversalCompactDetAutomaton minimizeUniversal(UniversalSemantics automaton, Alphabet alphabet) { return minimizeUniversal(automaton, alphabet, PruningMode.PRUNE_AFTER); } @@ -509,7 +510,7 @@ public static UniversalCompactDetAutomaton minimizeUniver * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static UniversalCompactDetAutomaton minimizeUniversal(UniversalDeterministicAutomaton automaton, + public static UniversalCompactDetAutomaton minimizeUniversal(UniversalSemantics automaton, Alphabet alphabet, PruningMode pruningMode) { return minimizeUniversal(automaton, alphabet, pruningMode, AutomatonInitialPartitioning.BY_FULL_SIGNATURE); @@ -535,7 +536,7 @@ public static UniversalCompactDetAutomaton minimizeUniver * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static UniversalCompactDetAutomaton minimizeUniversal(UniversalDeterministicAutomaton automaton, + public static UniversalCompactDetAutomaton minimizeUniversal(UniversalSemantics automaton, Alphabet alphabet, PruningMode pruningMode, AutomatonInitialPartitioning ip) { @@ -567,12 +568,11 @@ public static UniversalCompactDetAutomaton minimizeUniver * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static > A minimizeUniversal( - UniversalDeterministicAutomaton automaton, - Alphabet alphabet, - PruningMode pruningMode, - AutomatonInitialPartitioning ip, - AutomatonCreator creator) { + public static > A minimizeUniversal(UniversalSemantics automaton, + Alphabet alphabet, + PruningMode pruningMode, + AutomatonInitialPartitioning ip, + AutomatonCreator creator) { final FullIntAbstraction abs = automaton.fullIntAbstraction(alphabet); final Hopcroft hopcroft = @@ -609,8 +609,9 @@ public static UniversalCompactDetAutomaton minimizeUniver * * @return {@code automaton} for convenience */ - public static > A minimizeUniversalInvasive(A automaton, - Collection inputs) { + public static & FiniteSemantics> A minimizeUniversalInvasive( + A automaton, + Collection inputs) { return minimizeUniversalInvasive(automaton, inputs, AutomatonInitialPartitioning.BY_FULL_SIGNATURE); } @@ -635,9 +636,10 @@ public static UniversalCompactDetAutomaton minimizeUniver * * @return {@code automaton} for convenience */ - public static > A minimizeUniversalInvasive(A automaton, - Collection inputs, - AutomatonInitialPartitioning ip) { + public static & FiniteSemantics> A minimizeUniversalInvasive( + A automaton, + Collection inputs, + AutomatonInitialPartitioning ip) { return minimizeInvasive(automaton, inputs, ip, new GenericStorage<>(), new GenericStorage<>()); } @@ -658,9 +660,8 @@ public static UniversalCompactDetAutomaton minimizeUniver * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static UniversalCompactDetAutomaton minimizePartialUniversal( - UniversalDeterministicAutomaton automaton, - Alphabet alphabet) { + public static UniversalCompactDetAutomaton minimizePartialUniversal(UniversalSemantics automaton, + Alphabet alphabet) { return minimizePartialUniversal(automaton, alphabet, PruningMode.PRUNE_AFTER); } @@ -682,10 +683,9 @@ public static UniversalCompactDetAutomaton minimizePartia * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static UniversalCompactDetAutomaton minimizePartialUniversal( - UniversalDeterministicAutomaton automaton, - Alphabet alphabet, - PruningMode pruningMode) { + public static UniversalCompactDetAutomaton minimizePartialUniversal(UniversalSemantics automaton, + Alphabet alphabet, + PruningMode pruningMode) { return minimizePartialUniversal(automaton, alphabet, @@ -716,12 +716,11 @@ public static UniversalCompactDetAutomaton minimizePartia * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static UniversalCompactDetAutomaton minimizePartialUniversal( - UniversalDeterministicAutomaton automaton, - Alphabet alphabet, - PruningMode pruningMode, - AutomatonInitialPartitioning ip, - Object sinkClassification) { + public static UniversalCompactDetAutomaton minimizePartialUniversal(UniversalSemantics automaton, + Alphabet alphabet, + PruningMode pruningMode, + AutomatonInitialPartitioning ip, + Object sinkClassification) { return minimizePartialUniversal(automaton, alphabet, @@ -758,8 +757,8 @@ public static UniversalCompactDetAutomaton minimizePartia * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static > A minimizePartialUniversal( - UniversalDeterministicAutomaton automaton, + public static & FiniteSemantics> A minimizePartialUniversal( + UniversalSemantics automaton, Alphabet alphabet, PruningMode pruningMode, AutomatonInitialPartitioning ip, @@ -784,11 +783,11 @@ public static UniversalCompactDetAutomaton minimizePartia } - private static > A minimizeInvasive(A automaton, - Collection alphabet, - AutomatonInitialPartitioning ip, - Storage spStorage, - Storage tpStorage) { + private static & FiniteSemantics> A minimizeInvasive(A automaton, + Collection alphabet, + AutomatonInitialPartitioning ip, + Storage spStorage, + Storage tpStorage) { final MutableDeterministicAbstractions.FullIntAbstraction abs = automaton.fullIntAbstraction(Alphabets.fromCollection(alphabet)); diff --git a/util/src/main/java/net/automatalib/util/automaton/procedural/ProceduralUtil.java b/util/src/main/java/net/automatalib/util/automaton/procedural/ProceduralUtil.java index 0daaf548e..ac60106a2 100644 --- a/util/src/main/java/net/automatalib/util/automaton/procedural/ProceduralUtil.java +++ b/util/src/main/java/net/automatalib/util/automaton/procedural/ProceduralUtil.java @@ -43,9 +43,9 @@ private ProceduralUtil() { // prevent instantiation } - static > Map> computeTerminatingSequences(Map procedures, - ProceduralInputAlphabet alphabet, - BiPredicate> tracePredicate) { + static > Map> computeTerminatingSequences(Map procedures, + ProceduralInputAlphabet alphabet, + BiPredicate> tracePredicate) { final Map> terminatingSequences = new HashMap<>(HashUtil.capacity(alphabet.getNumCalls())); @@ -103,12 +103,12 @@ private ProceduralUtil() { return terminatingSequences; } - static > Map> computeAccessSequences(Map procedures, - ProceduralInputAlphabet alphabet, - Collection proceduralInputs, - @Nullable I initialProcedure, - Map> terminatingSequences, - BiPredicate> transitionPredicate) { + static > Map> computeAccessSequences(Map procedures, + ProceduralInputAlphabet alphabet, + Collection proceduralInputs, + @Nullable I initialProcedure, + Map> terminatingSequences, + BiPredicate> transitionPredicate) { if (initialProcedure == null) { return Collections.emptyMap(); @@ -150,7 +150,7 @@ private ProceduralUtil() { return accessSequences; } - private static > Collection discoverAccessSequences( + private static > Collection discoverAccessSequences( ProceduralInputAlphabet alphabet, Collection proceduralInputs, I procedure, @@ -193,11 +193,11 @@ private ProceduralUtil() { return newAS; } - static > @Nullable Word findSeparatingWord(Map sys1, - ATSequences at1, - Map sys2, - ATSequences at2, - ProceduralInputAlphabet alphabet) { + static > @Nullable Word findSeparatingWord(Map sys1, + ATSequences at1, + Map sys2, + ATSequences at2, + ProceduralInputAlphabet alphabet) { for (I procedure : alphabet.getCallAlphabet()) { final M p1 = sys1.get(procedure); final M p2 = sys2.get(procedure); diff --git a/util/src/main/java/net/automatalib/util/automaton/random/RandomAutomata.java b/util/src/main/java/net/automatalib/util/automaton/random/RandomAutomata.java index d4605bc1f..906a803e1 100644 --- a/util/src/main/java/net/automatalib/util/automaton/random/RandomAutomata.java +++ b/util/src/main/java/net/automatalib/util/automaton/random/RandomAutomata.java @@ -45,6 +45,7 @@ import net.automatalib.automaton.vpa.impl.DefaultOneSEVPA; import net.automatalib.automaton.vpa.impl.Location; import net.automatalib.common.util.HashUtil; +import net.automatalib.semantics.FiniteSemantics; import net.automatalib.util.automaton.fsa.DFAs; import net.automatalib.util.automaton.minimizer.HopcroftMinimizer; import net.automatalib.util.automaton.minimizer.OneSEVPAMinimizer; @@ -337,22 +338,24 @@ public static SBA randomSBA(Random random, mealies); } - public static > A randomDeterministic(Random rand, - @NonNegative int numStates, - Collection inputs, - Collection stateProps, - Collection transProps, - A out) { + public static & FiniteSemantics> A randomDeterministic( + Random rand, + @NonNegative int numStates, + Collection inputs, + Collection stateProps, + Collection transProps, + A out) { return randomDeterministic(rand, numStates, inputs, stateProps, transProps, out, true); } - public static > A randomDeterministic(Random rand, - @NonNegative int numStates, - Collection inputs, - Collection stateProps, - Collection transProps, - A out, - boolean minimize) { + public static & FiniteSemantics> A randomDeterministic( + Random rand, + @NonNegative int numStates, + Collection inputs, + Collection stateProps, + Collection transProps, + A out, + boolean minimize) { RandomDeterministicAutomatonGenerator gen = new RandomDeterministicAutomatonGenerator<>(rand, inputs, stateProps, transProps, out); diff --git a/util/src/main/java/net/automatalib/util/automaton/random/RandomDeterministicAutomatonGenerator.java b/util/src/main/java/net/automatalib/util/automaton/random/RandomDeterministicAutomatonGenerator.java index d58b8a955..d12d8c1a1 100644 --- a/util/src/main/java/net/automatalib/util/automaton/random/RandomDeterministicAutomatonGenerator.java +++ b/util/src/main/java/net/automatalib/util/automaton/random/RandomDeterministicAutomatonGenerator.java @@ -19,8 +19,9 @@ import java.util.Random; import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.semantics.FiniteSemantics; -public class RandomDeterministicAutomatonGenerator> +public class RandomDeterministicAutomatonGenerator & FiniteSemantics> extends RandomAutomatonGenerator { public RandomDeterministicAutomatonGenerator(Random random, diff --git a/util/src/test/java/net/automatalib/util/automaton/CopyConstructorTest.java b/util/src/test/java/net/automatalib/util/automaton/CopyConstructorTest.java index 2fa22fb97..524d1dd1c 100644 --- a/util/src/test/java/net/automatalib/util/automaton/CopyConstructorTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/CopyConstructorTest.java @@ -90,9 +90,9 @@ public void testSST() { testCopyConstructor(sst, INPUT_ALPHABET, CompactSST::new); } - private > void testCopyConstructor(A automaton, - Alphabet alphabet, - Function copyConstructor) { + private > void testCopyConstructor(A automaton, + Alphabet alphabet, + Function copyConstructor) { final A copy = copyConstructor.apply(automaton); Assert.assertTrue(Automata.testEquivalence(automaton, copy, alphabet)); } diff --git a/util/src/test/java/net/automatalib/util/automaton/conformance/WpMethodTestsIteratorTest.java b/util/src/test/java/net/automatalib/util/automaton/conformance/WpMethodTestsIteratorTest.java index d6c59aada..dc95640ed 100644 --- a/util/src/test/java/net/automatalib/util/automaton/conformance/WpMethodTestsIteratorTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/conformance/WpMethodTestsIteratorTest.java @@ -24,7 +24,6 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Alphabets; -import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.fsa.impl.CompactDFA; import net.automatalib.common.util.collection.IterableUtil; import net.automatalib.common.util.collection.IteratorUtil; @@ -101,17 +100,16 @@ private > void checkTestWords(List> actual, List } - private List> generateWpMethodTest(UniversalSemantics semantics, + private List> generateWpMethodTest(UniversalSemantics automaton, Collection inputs, List> middleParts) { - final UniversalDeterministicAutomaton automaton = semantics.getSemantics(); final List> stateCover = new ArrayList<>(automaton.size()); final List> transitionCover = new ArrayList<>(automaton.size() * inputs.size()); final List> characterizingSet = new ArrayList<>(); - Covers.cover(semantics, inputs, stateCover, transitionCover); - CharacterizingSets.findCharacterizingSet(semantics, inputs, characterizingSet); + Covers.cover(automaton, inputs, stateCover, transitionCover); + CharacterizingSets.findCharacterizingSet(automaton, inputs, characterizingSet); Assert.assertFalse(stateCover.isEmpty()); Assert.assertFalse(transitionCover.isEmpty()); @@ -137,7 +135,7 @@ private List> generateWpMethodTest(UniversalSemantics final S s = automaton.getState(prefixWithMiddle); final List> suffixes = new ArrayList<>(); - CharacterizingSets.findCharacterizingSet(semantics, inputs, s, suffixes); + CharacterizingSets.findCharacterizingSet(automaton, inputs, s, suffixes); assert !suffixes.isEmpty(); for (Word suffix : suffixes) { diff --git a/util/src/test/java/net/automatalib/util/automaton/copy/AbstractAutomatonCopyTest.java b/util/src/test/java/net/automatalib/util/automaton/copy/AbstractAutomatonCopyTest.java index 2ca6e1af0..4d14b2d73 100644 --- a/util/src/test/java/net/automatalib/util/automaton/copy/AbstractAutomatonCopyTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/copy/AbstractAutomatonCopyTest.java @@ -148,21 +148,23 @@ private void makePartial(MutableDeterministic automaton } } - private & UniversalSemantics, S, I, T, SP, TP> void checkEquivalence(A source, - Alphabet alphabet, - AutomatonCreator targetCreator) { + private & UniversalSemantics, S, I, T, SP, TP> void checkEquivalence( + A source, + Alphabet alphabet, + AutomatonCreator targetCreator) { final A target = targetCreator.createAutomaton(alphabet); AutomatonLowLevelCopy.copy(getCopyMethod(), source, alphabet, target); Assert.assertTrue(Automata.testEquivalence(source, target, alphabet)); } - private & UniversalSemantics, S, I, T, SP, TP> void checkFilteredEquivalence(A source, - Alphabet alphabet, - AutomatonCreator targetCreator, - Predicate sPred, - TransitionPredicate tPred, - A expectedTarget) { + private & UniversalSemantics, S, I, T, SP, TP> void checkFilteredEquivalence( + A source, + Alphabet alphabet, + AutomatonCreator targetCreator, + Predicate sPred, + TransitionPredicate tPred, + A expectedTarget) { final A target = targetCreator.createAutomaton(alphabet); AutomatonLowLevelCopy.copy(getCopyMethod(), source, alphabet, target, sPred, tPred); diff --git a/util/src/test/java/net/automatalib/util/automaton/equivalence/BisimulationTest.java b/util/src/test/java/net/automatalib/util/automaton/equivalence/BisimulationTest.java index ff1af3ceb..92c9975a0 100644 --- a/util/src/test/java/net/automatalib/util/automaton/equivalence/BisimulationTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/equivalence/BisimulationTest.java @@ -24,7 +24,7 @@ import net.automatalib.alphabet.impl.Alphabets; import net.automatalib.automaton.fsa.impl.CompactNFA; import net.automatalib.common.util.Pair; -import net.automatalib.semantics.FiniteSemantics.SimpleSemantics; +import net.automatalib.semantics.FiniteSemantics.PlainSemantics; import net.automatalib.ts.modal.impl.CompactMTS; import net.automatalib.util.automaton.random.TabakovVardiRandomAutomata; import org.testng.Assert; @@ -95,10 +95,9 @@ public void bisimTestLoop() { Assert.assertTrue(testBisimulationEquivalence(a, b, alphabet)); } - private static , BS, B extends SimpleSemantics> boolean testBisimulationEquivalence( - A a, - B b, - Collection inputs) { + private static boolean testBisimulationEquivalence(PlainSemantics a, + PlainSemantics b, + Collection inputs) { Set> bisim = Bisimulation.bisimulationEquivalenceRelation(a, b, inputs); diff --git a/util/src/test/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTestTest.java b/util/src/test/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTestTest.java index 6572575fe..3a9649ac4 100644 --- a/util/src/test/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTestTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTestTest.java @@ -20,7 +20,6 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Alphabets; -import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.concept.Output; import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.fsa.impl.CompactDFA; @@ -159,32 +158,29 @@ private static void testIndexComputation(BiIntFunction> constr } } - private static void testForEmptySepWord(UniversalSemantics s1, - UniversalSemantics s2, + private static void testForEmptySepWord(UniversalSemantics a1, + UniversalSemantics a2, Collection inputs) { - Assert.assertNull(DeterministicEquivalenceTest.findSeparatingWord(s1, s1, inputs)); - Assert.assertNull(DeterministicEquivalenceTest.findSeparatingWord(s2, s2, inputs)); + Assert.assertNull(DeterministicEquivalenceTest.findSeparatingWord(a1, a1, inputs)); + Assert.assertNull(DeterministicEquivalenceTest.findSeparatingWord(a2, a2, inputs)); - final UniversalDeterministicAutomaton a1 = s1.getSemantics(); - final UniversalDeterministicAutomaton a2 = s1.getSemantics(); - - final Word sepWord1 = DeterministicEquivalenceTest.findSeparatingWord(s1, s2, inputs); + final Word sepWord1 = DeterministicEquivalenceTest.findSeparatingWord(a1, a2, inputs); Assert.assertEquals(sepWord1, Word.epsilon()); Assert.assertNotEquals(a1.getState(sepWord1), a2.getState(sepWord1)); - final Word sepWord2 = DeterministicEquivalenceTest.findSeparatingWord(s2, s1, inputs); + final Word sepWord2 = DeterministicEquivalenceTest.findSeparatingWord(a2, a1, inputs); Assert.assertEquals(sepWord2, Word.epsilon()); Assert.assertNotEquals(a1.getState(sepWord2), a2.getState(sepWord2)); } - private & Output> void testEquivalenceInternal(M a1, - M a2, - Alphabet alphabet, - boolean equivalent) { + private & Output> void testEquivalenceInternal(M a1, + M a2, + Alphabet alphabet, + boolean equivalent) { // explicitly assign type to (redundant) variables, otherwise javac complains - final UniversalSemantics m1 = a1; - final UniversalSemantics m2 = a2; + final UniversalSemantics m1 = a1; + final UniversalSemantics m2 = a2; final Word separatingWord = DeterministicEquivalenceTest.findSeparatingWord(m1, m2, alphabet); diff --git a/util/src/test/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTestTest.java b/util/src/test/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTestTest.java index e72f5687c..8e4bae8a8 100644 --- a/util/src/test/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTestTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTestTest.java @@ -22,10 +22,9 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Alphabets; -import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.fsa.impl.CompactDFA; import net.automatalib.automaton.transducer.impl.CompactMealy; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; +import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; import net.automatalib.util.automaton.random.RandomAutomata; import net.automatalib.word.Word; import org.testng.Assert; @@ -193,37 +192,34 @@ public void testIssue84() { Assert.assertEquals(sepWord.length(), TestUtil.LARGE_AUTOMATON_A.size() - 1); } - private static void testForEmptySepWord(UniversalSemantics s1, - UniversalSemantics s2, + private static void testForEmptySepWord(MutableSemantics a1, + MutableSemantics a2, Collection inputs) { - Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(s1, s1, inputs)); - Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(s2, s2, inputs)); + Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a1, a1, inputs)); + Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a2, a2, inputs)); - UniversalDeterministicAutomaton a1 = s1.getSemantics(); - UniversalDeterministicAutomaton a2 = s2.getSemantics(); - - Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(s1, s2, inputs, true)); - final Word sepWord1 = NearLinearEquivalenceTest.findSeparatingWord(s1, s2, inputs); + Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a1, a2, inputs, true)); + final Word sepWord1 = NearLinearEquivalenceTest.findSeparatingWord(a1, a2, inputs); Assert.assertEquals(sepWord1, Word.epsilon()); Assert.assertNotEquals(a1.getState(sepWord1), a2.getState(sepWord1)); - Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(s2, s1, inputs, true)); - final Word sepWord2 = NearLinearEquivalenceTest.findSeparatingWord(s2, s1, inputs); + Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a2, a1, inputs, true)); + final Word sepWord2 = NearLinearEquivalenceTest.findSeparatingWord(a2, a1, inputs); Assert.assertEquals(sepWord2, Word.epsilon()); Assert.assertNotEquals(a1.getState(sepWord2), a2.getState(sepWord2)); // Non-alphabet (non-integer-abstraction) version final Set inputsAsSet = new HashSet<>(inputs); - Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(s1, s1, inputsAsSet)); - Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(s2, s2, inputsAsSet)); + Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a1, a1, inputsAsSet)); + Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a2, a2, inputsAsSet)); - Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(s1, s2, inputsAsSet, true)); - final Word sepWord3 = NearLinearEquivalenceTest.findSeparatingWord(s1, s2, inputsAsSet); + Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a1, a2, inputsAsSet, true)); + final Word sepWord3 = NearLinearEquivalenceTest.findSeparatingWord(a1, a2, inputsAsSet); Assert.assertEquals(sepWord3, Word.epsilon()); Assert.assertNotEquals(a1.getState(sepWord3), a2.getState(sepWord3)); - Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(s2, s1, inputsAsSet, true)); - final Word sepWord4 = NearLinearEquivalenceTest.findSeparatingWord(s2, s1, inputsAsSet); + Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a2, a1, inputsAsSet, true)); + final Word sepWord4 = NearLinearEquivalenceTest.findSeparatingWord(a2, a1, inputsAsSet); Assert.assertEquals(sepWord4, Word.epsilon()); Assert.assertNotEquals(a1.getState(sepWord4), a2.getState(sepWord4)); } diff --git a/util/src/test/java/net/automatalib/util/automaton/minimizer/AbstractMinimizationTest.java b/util/src/test/java/net/automatalib/util/automaton/minimizer/AbstractMinimizationTest.java index 33fbf5b0a..c4d37ad3d 100644 --- a/util/src/test/java/net/automatalib/util/automaton/minimizer/AbstractMinimizationTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/minimizer/AbstractMinimizationTest.java @@ -19,8 +19,6 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Alphabets; -import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.concept.StateIDs; import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.fsa.MutableDFA; @@ -29,6 +27,7 @@ import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.MutableMealyMachine; import net.automatalib.automaton.transducer.impl.CompactMealy; +import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.Automata; import net.automatalib.util.automaton.builder.AutomatonBuilders; @@ -222,10 +221,9 @@ private > void testMinimizeDFA(TestConfig te } } - private & UniversalSemantics> void testMinimizeUniversal(TestConfig test) { + private > void testMinimizeUniversal(TestConfig test) { - final UniversalDeterministicAutomaton result = - minimizeUniversal(test.automaton, test.alphabet); + final UniversalSemantics result = minimizeUniversal(test.automaton, test.alphabet); if (isPruned()) { Assert.assertEquals(result.size(), test.prunedSize); @@ -241,25 +239,23 @@ private > void testMinimizeDFA(TestConfig te protected abstract MealyMachine minimizeMealy(MutableMealyMachine mealy, Alphabet alphabet); - protected abstract UniversalDeterministicAutomaton minimizeUniversal( - MutableDeterministic automaton, - Alphabet alphabet); + protected abstract UniversalSemantics minimizeUniversal(MutableSemantics automaton, + Alphabet alphabet); protected abstract boolean isPruned(); protected abstract boolean supportsPartial(); - private static void assertAllInequivalent(UniversalSemantics semantics, + private static void assertAllInequivalent(UniversalSemantics automaton, Collection inputs) { - UniversalDeterministicAutomaton automaton = semantics.getSemantics(); StateIDs ids = automaton.stateIDs(); int size = automaton.size(); for (int i = 0; i < size - 1; i++) { S s1 = ids.getState(i); for (int j = i + 1; j < size; j++) { S s2 = ids.getState(j); - Assert.assertNotNull(Automata.findSeparatingWord(semantics, s1, s2, inputs)); + Assert.assertNotNull(Automata.findSeparatingWord(automaton, s1, s2, inputs)); } } } diff --git a/util/src/test/java/net/automatalib/util/automaton/minimizer/AutomataMinimizationTest.java b/util/src/test/java/net/automatalib/util/automaton/minimizer/AutomataMinimizationTest.java index 1490bb296..bd5f4c196 100644 --- a/util/src/test/java/net/automatalib/util/automaton/minimizer/AutomataMinimizationTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/minimizer/AutomataMinimizationTest.java @@ -17,11 +17,12 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.fsa.MutableDFA; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.MutableMealyMachine; +import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.Automata; public class AutomataMinimizationTest extends AbstractMinimizationTest { @@ -38,8 +39,8 @@ protected DFA minimizeDFA(MutableDFA dfa, Alphabet alphabet) } @Override - protected UniversalDeterministicAutomaton minimizeUniversal(MutableDeterministic automaton, - Alphabet alphabet) { + protected UniversalSemantics minimizeUniversal(MutableSemantics automaton, + Alphabet alphabet) { return Automata.invasiveMinimize(automaton, alphabet); } diff --git a/util/src/test/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizerTest.java b/util/src/test/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizerTest.java index fae2d8e81..332b4c6ca 100644 --- a/util/src/test/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizerTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizerTest.java @@ -17,11 +17,12 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.fsa.MutableDFA; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.MutableMealyMachine; +import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.partitionrefinement.PruningMode; import org.testng.annotations.DataProvider; import org.testng.annotations.Factory; @@ -52,8 +53,8 @@ protected DFA minimizeDFA(MutableDFA dfa, Alphabet alphabet) } @Override - protected UniversalDeterministicAutomaton minimizeUniversal(MutableDeterministic automaton, - Alphabet alphabet) { + protected UniversalSemantics minimizeUniversal(MutableSemantics automaton, + Alphabet alphabet) { return HopcroftMinimizer.minimizeUniversal(automaton, alphabet, this.pruningMode); } diff --git a/util/src/test/java/net/automatalib/util/automaton/minimizer/InvasiveHopcroftTest.java b/util/src/test/java/net/automatalib/util/automaton/minimizer/InvasiveHopcroftTest.java index 8dc6b2806..b4c7f622d 100644 --- a/util/src/test/java/net/automatalib/util/automaton/minimizer/InvasiveHopcroftTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/minimizer/InvasiveHopcroftTest.java @@ -17,11 +17,12 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.fsa.MutableDFA; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.MutableMealyMachine; +import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; public class InvasiveHopcroftTest extends AbstractMinimizationTest { @@ -37,8 +38,8 @@ protected DFA minimizeDFA(MutableDFA dfa, Alphabet alphabet) } @Override - protected UniversalDeterministicAutomaton minimizeUniversal(MutableDeterministic automaton, - Alphabet alphabet) { + protected UniversalSemantics minimizeUniversal(MutableSemantics automaton, + Alphabet alphabet) { return HopcroftMinimizer.minimizeUniversalInvasive(automaton, alphabet); } diff --git a/util/src/test/java/net/automatalib/util/automaton/minimizer/MinimizerTest.java b/util/src/test/java/net/automatalib/util/automaton/minimizer/MinimizerTest.java index 9eb362960..8b8a48ae9 100644 --- a/util/src/test/java/net/automatalib/util/automaton/minimizer/MinimizerTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/minimizer/MinimizerTest.java @@ -20,7 +20,6 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Alphabets; import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.fsa.MutableDFA; import net.automatalib.automaton.fsa.impl.CompactDFA; @@ -29,6 +28,8 @@ import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.MutableMealyMachine; import net.automatalib.automaton.transducer.impl.CompactMealy; +import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.Automata; import net.automatalib.util.minimizer.Block; import net.automatalib.util.minimizer.MinimizationResult; @@ -54,10 +55,9 @@ protected DFA minimizeDFA(MutableDFA dfa, Alphabet alphabet) } @Override - protected UniversalDeterministicAutomaton minimizeUniversal(MutableDeterministic automaton, - Alphabet alphabet) { - final UniversalCompactDetAutomaton result = - new UniversalCompactDetAutomaton<>(alphabet, automaton.size()); + protected UniversalSemantics minimizeUniversal(MutableSemantics automaton, + Alphabet alphabet) { + final UniversalCompactDetAutomaton result = new UniversalCompactDetAutomaton<>(alphabet); Automata.minimize(automaton, alphabet, result); return result; } diff --git a/util/src/test/java/net/automatalib/util/automaton/minimizer/PartialHopcroftMinimizerTest.java b/util/src/test/java/net/automatalib/util/automaton/minimizer/PartialHopcroftMinimizerTest.java index a639874dd..d10660d76 100644 --- a/util/src/test/java/net/automatalib/util/automaton/minimizer/PartialHopcroftMinimizerTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/minimizer/PartialHopcroftMinimizerTest.java @@ -17,11 +17,12 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.fsa.MutableDFA; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.MutableMealyMachine; +import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.partitionrefinement.PruningMode; import org.testng.annotations.DataProvider; import org.testng.annotations.Factory; @@ -52,8 +53,8 @@ protected DFA minimizeDFA(MutableDFA dfa, Alphabet alphabet) } @Override - protected UniversalDeterministicAutomaton minimizeUniversal(MutableDeterministic automaton, - Alphabet alphabet) { + protected UniversalSemantics minimizeUniversal(MutableSemantics automaton, + Alphabet alphabet) { return HopcroftMinimizer.minimizePartialUniversal(automaton, alphabet, this.pruningMode); } From fb26415262232cfae3f50931c1f4982369aab899 Mon Sep 17 00:00:00 2001 From: Markus Frohme Date: Sat, 20 Jun 2026 17:24:23 +0200 Subject: [PATCH 3/8] integrate VPAs in new semantics + cleanup concepts --- api/src/main/java/module-info.java | 2 +- .../net/automatalib/automaton/Automaton.java | 8 ++ .../automaton/DeterministicAutomaton.java | 10 ++ .../automaton/MutableAutomaton.java | 4 + .../automaton/MutableDeterministic.java | 4 + .../automaton/UniversalAutomaton.java | 9 ++ .../UniversalDeterministicAutomaton.java | 10 ++ .../net/automatalib/automaton/fsa/DFA.java | 6 +- .../automaton/fsa/FiniteStateAcceptor.java | 14 +-- .../automatalib/automaton/fsa/MutableDFA.java | 8 +- .../automatalib/automaton/fsa/MutableFSA.java | 4 +- .../automatalib/automaton/fsa/MutableNFA.java | 6 +- .../net/automatalib/automaton/mmlt/MMLT.java | 6 +- .../automatalib/automaton/procedural/SBA.java | 6 +- .../automatalib/automaton/procedural/SPA.java | 5 +- .../automaton/procedural/SPMM.java | 5 +- .../automaton/transducer/MealyMachine.java | 8 +- .../automaton/transducer/MooreMachine.java | 9 +- .../transducer/MutableMealyMachine.java | 9 +- .../transducer/MutableMooreMachine.java | 9 +- .../MutableSubsequentialTransducer.java | 7 +- .../transducer/SubsequentialTransducer.java | 6 +- .../automatalib/automaton/vpa/OneSEVPA.java | 2 +- .../net/automatalib/automaton/vpa/SEVPA.java | 76 ++++++++++----- .../automaton/vpa/SEVPAGraphView.java | 26 +++--- .../automaton/vpa/SEVPASemantics.java | 71 ++++++++++++++ .../DeterministicFiniteSemantics.java | 26 ++++++ .../semantic/DeterministicSemantics.java | 26 ++++++ .../automatalib/semantic/FiniteSemantics.java | 26 ++++++ .../net/automatalib/semantic/Semantics.java | 25 +++++ .../DeterministicFiniteSemantics.java | 51 ---------- .../semantics/DeterministicSemantics.java | 42 --------- .../semantics/FiniteSemantics.java | 45 --------- .../net/automatalib/semantics/Semantics.java | 37 -------- .../ts/modal/ModalTransitionSystem.java | 4 +- .../modal/MutableModalTransitionSystem.java | 4 +- .../impl/UniversalCompactDetAutomaton.java | 12 +-- .../vpa/impl/AbstractDefaultSEVPA.java | 38 ++++---- .../automaton/vpa/impl/AbstractSEVPA.java | 40 +------- .../automaton/vpa/impl/DefaultVPATest.java | 30 +++--- .../java/net/automatalib/example/Example.java | 1 - .../AbstractAut2ETF2FSM2AutTest.java | 16 ++-- .../automatalib/util/automaton/Automata.java | 67 ++++++------- .../IncrementalWMethodTestsIterator.java | 4 +- .../KWayStateCoverTestsIterator.java | 14 +-- .../KWayTransitionCoverTestsIterator.java | 20 ++-- .../ProceduralWMethodTestsIterator.java | 4 +- .../conformance/WMethodTestsIterator.java | 8 +- .../conformance/WpMethodTestsIterator.java | 12 +-- .../util/automaton/cover/Covers.java | 61 ++++++------ .../cover/IncrementalStateCoverIterator.java | 8 +- .../IncrementalTransitionCoverIterator.java | 8 +- .../automaton/equivalence/Bisimulation.java | 6 +- .../equivalence/CharacterizingSets.java | 34 ++++--- .../DeterministicEquivalenceTest.java | 6 +- .../NearLinearEquivalenceTest.java | 25 +++-- .../minimizer/HopcroftMinimizer.java | 61 ++++++------ .../minimizer/OneSEVPAMinimizer.java | 37 ++++---- .../automaton/procedural/ProceduralUtil.java | 32 +++---- .../util/automaton/random/RandomAutomata.java | 45 +++++---- ...RandomDeterministicAutomatonGenerator.java | 3 +- .../util/automaton/vpa/OneSEVPAs.java | 93 +++++++++---------- .../util/automaton/vpa/ProductOneSEVPA.java | 59 +++++++++--- .../util/automaton/vpa/SPAConverter.java | 32 ++++--- .../util/automaton/CopyConstructorTest.java | 8 +- .../WpMethodTestsIteratorTest.java | 4 +- .../copy/AbstractAutomatonCopyTest.java | 22 ++--- .../equivalence/BisimulationTest.java | 6 +- .../DeterministicEquivalenceTestTest.java | 18 ++-- .../NearLinearEquivalenceTestTest.java | 6 +- .../minimizer/AbstractMinimizationTest.java | 16 ++-- .../minimizer/AutomataMinimizationTest.java | 10 +- .../minimizer/HopcroftMinimizerTest.java | 10 +- .../minimizer/InvasiveHopcroftTest.java | 10 +- .../automaton/minimizer/MinimizerTest.java | 10 +- .../PartialHopcroftMinimizerTest.java | 10 +- .../util/automaton/procedural/SPAsTest.java | 10 +- .../util/automaton/vpa/OneSEVPAsTest.java | 55 ++++++----- 78 files changed, 832 insertions(+), 755 deletions(-) create mode 100644 api/src/main/java/net/automatalib/automaton/vpa/SEVPASemantics.java create mode 100644 api/src/main/java/net/automatalib/semantic/DeterministicFiniteSemantics.java create mode 100644 api/src/main/java/net/automatalib/semantic/DeterministicSemantics.java create mode 100644 api/src/main/java/net/automatalib/semantic/FiniteSemantics.java create mode 100644 api/src/main/java/net/automatalib/semantic/Semantics.java delete mode 100644 api/src/main/java/net/automatalib/semantics/DeterministicFiniteSemantics.java delete mode 100644 api/src/main/java/net/automatalib/semantics/DeterministicSemantics.java delete mode 100644 api/src/main/java/net/automatalib/semantics/FiniteSemantics.java delete mode 100644 api/src/main/java/net/automatalib/semantics/Semantics.java diff --git a/api/src/main/java/module-info.java b/api/src/main/java/module-info.java index 3518088f0..8e68179b9 100644 --- a/api/src/main/java/module-info.java +++ b/api/src/main/java/module-info.java @@ -62,7 +62,7 @@ exports net.automatalib.graph.visualization; exports net.automatalib.modelchecking; exports net.automatalib.serialization; - exports net.automatalib.semantics; + exports net.automatalib.semantic; exports net.automatalib.symbol.time; exports net.automatalib.ts; exports net.automatalib.ts.acceptor; diff --git a/api/src/main/java/net/automatalib/automaton/Automaton.java b/api/src/main/java/net/automatalib/automaton/Automaton.java index ad0b077a7..9791228cb 100644 --- a/api/src/main/java/net/automatalib/automaton/Automaton.java +++ b/api/src/main/java/net/automatalib/automaton/Automaton.java @@ -47,4 +47,12 @@ public interface Automaton extends TransitionSystem, SimpleAut default Graph> transitionGraphView(Collection inputs) { return new AutomatonGraphView<>(this, inputs); } + + interface FiniteSemantics extends Automaton, net.automatalib.semantic.FiniteSemantics { + + @Override + default Automaton getSemantics() { + return this; + } + } } diff --git a/api/src/main/java/net/automatalib/automaton/DeterministicAutomaton.java b/api/src/main/java/net/automatalib/automaton/DeterministicAutomaton.java index 081e2647e..98b4fb01e 100644 --- a/api/src/main/java/net/automatalib/automaton/DeterministicAutomaton.java +++ b/api/src/main/java/net/automatalib/automaton/DeterministicAutomaton.java @@ -23,6 +23,7 @@ import net.automatalib.automaton.abstraction.DeterministicAbstractions.StateIntAbstraction; import net.automatalib.automaton.abstraction.DeterministicAbstractions.StateIntAbstractionImpl; import net.automatalib.automaton.simple.SimpleDeterministicAutomaton; +import net.automatalib.semantic.DeterministicSemantics; import net.automatalib.ts.DeterministicTransitionSystem; /** @@ -54,4 +55,13 @@ default StateIntAbstraction stateIntAbstraction() { return new StateIntAbstractionImpl<>(this); } + interface FiniteSemantics + extends DeterministicAutomaton, Automaton.FiniteSemantics, DeterministicSemantics { + + @Override + default DeterministicAutomaton getSemantics() { + return this; + } + } + } diff --git a/api/src/main/java/net/automatalib/automaton/MutableAutomaton.java b/api/src/main/java/net/automatalib/automaton/MutableAutomaton.java index 34daba099..1af047605 100644 --- a/api/src/main/java/net/automatalib/automaton/MutableAutomaton.java +++ b/api/src/main/java/net/automatalib/automaton/MutableAutomaton.java @@ -138,4 +138,8 @@ default T copyTransition(T trans, S succ) { TP property = getTransitionProperty(trans); return createTransition(succ, property); } + + interface FiniteSemantics + extends MutableAutomaton, UniversalAutomaton.FiniteSemantics {} + } diff --git a/api/src/main/java/net/automatalib/automaton/MutableDeterministic.java b/api/src/main/java/net/automatalib/automaton/MutableDeterministic.java index 8b9cf95d7..8ef7a243d 100644 --- a/api/src/main/java/net/automatalib/automaton/MutableDeterministic.java +++ b/api/src/main/java/net/automatalib/automaton/MutableDeterministic.java @@ -159,4 +159,8 @@ default StateIntAbstraction stateIntAbstraction() { return new StateIntAbstractionImpl<>(this); } + interface FiniteSemantics extends MutableDeterministic, + MutableAutomaton.FiniteSemantics, + UniversalDeterministicAutomaton.FiniteSemantics {} + } diff --git a/api/src/main/java/net/automatalib/automaton/UniversalAutomaton.java b/api/src/main/java/net/automatalib/automaton/UniversalAutomaton.java index de29f2d61..7c0e6fa9d 100644 --- a/api/src/main/java/net/automatalib/automaton/UniversalAutomaton.java +++ b/api/src/main/java/net/automatalib/automaton/UniversalAutomaton.java @@ -46,4 +46,13 @@ default UniversalGraph, SP, Property> transitionG return new UniversalAutomatonGraphView<>(this, inputs); } + interface FiniteSemantics + extends UniversalAutomaton, Automaton.FiniteSemantics { + + @Override + default UniversalAutomaton getSemantics() { + return this; + } + } + } diff --git a/api/src/main/java/net/automatalib/automaton/UniversalDeterministicAutomaton.java b/api/src/main/java/net/automatalib/automaton/UniversalDeterministicAutomaton.java index a10c1b669..fc2621db6 100644 --- a/api/src/main/java/net/automatalib/automaton/UniversalDeterministicAutomaton.java +++ b/api/src/main/java/net/automatalib/automaton/UniversalDeterministicAutomaton.java @@ -58,5 +58,15 @@ default StateIntAbstraction stateIntAbstraction() { return new StateIntAbstractionImpl<>(this); } + interface FiniteSemantics extends UniversalDeterministicAutomaton, + DeterministicAutomaton.FiniteSemantics, + UniversalAutomaton.FiniteSemantics { + + @Override + default UniversalDeterministicAutomaton getSemantics() { + return this; + } + } + } diff --git a/api/src/main/java/net/automatalib/automaton/fsa/DFA.java b/api/src/main/java/net/automatalib/automaton/fsa/DFA.java index e31c09672..02c18240e 100644 --- a/api/src/main/java/net/automatalib/automaton/fsa/DFA.java +++ b/api/src/main/java/net/automatalib/automaton/fsa/DFA.java @@ -17,18 +17,16 @@ import java.util.Collection; -import net.automatalib.automaton.UniversalDeterministicAutomaton; +import net.automatalib.automaton.UniversalDeterministicAutomaton.FiniteSemantics; import net.automatalib.automaton.concept.DeterministicSuffixOutputAutomaton; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.ts.acceptor.DeterministicAcceptorTS; /** * Deterministic finite state acceptor. */ -public interface DFA extends UniversalDeterministicAutomaton, +public interface DFA extends FiniteSemantics, DeterministicAcceptorTS, DeterministicSuffixOutputAutomaton, - UniversalSemantics, NFA { @Override diff --git a/api/src/main/java/net/automatalib/automaton/fsa/FiniteStateAcceptor.java b/api/src/main/java/net/automatalib/automaton/fsa/FiniteStateAcceptor.java index 1804192f6..edc4c2ee0 100644 --- a/api/src/main/java/net/automatalib/automaton/fsa/FiniteStateAcceptor.java +++ b/api/src/main/java/net/automatalib/automaton/fsa/FiniteStateAcceptor.java @@ -20,27 +20,29 @@ import java.util.Collections; import java.util.List; -import net.automatalib.automaton.UniversalAutomaton; +import net.automatalib.automaton.UniversalAutomaton.FiniteSemantics; import net.automatalib.automaton.concept.OutputAutomaton; import net.automatalib.automaton.graph.TransitionEdge; import net.automatalib.automaton.graph.UniversalAutomatonGraphView; import net.automatalib.automaton.visualization.FSAVisualizationHelper; import net.automatalib.graph.UniversalGraph; -import net.automatalib.semantics.FiniteSemantics.UniversalSemantics; import net.automatalib.ts.acceptor.AcceptorTS; import net.automatalib.visualization.VisualizationHelper; /** * {@code FiniteStateAcceptor}s accept regular languages. */ -public interface FiniteStateAcceptor extends AcceptorTS, - UniversalAutomaton, - OutputAutomaton, - UniversalSemantics { +public interface FiniteStateAcceptor + extends AcceptorTS, FiniteSemantics, OutputAutomaton { List STATE_PROPERTIES = Arrays.asList(Boolean.FALSE, Boolean.TRUE); List TRANSITION_PROPERTIES = Collections.singletonList(null); + @Override + default FiniteStateAcceptor getSemantics() { + return this; + } + @Override default UniversalGraph, Boolean, TransitionEdge.Property> transitionGraphView( Collection inputs) { diff --git a/api/src/main/java/net/automatalib/automaton/fsa/MutableDFA.java b/api/src/main/java/net/automatalib/automaton/fsa/MutableDFA.java index 4b9219fb3..a22666ada 100644 --- a/api/src/main/java/net/automatalib/automaton/fsa/MutableDFA.java +++ b/api/src/main/java/net/automatalib/automaton/fsa/MutableDFA.java @@ -15,14 +15,10 @@ */ package net.automatalib.automaton.fsa; -import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; +import net.automatalib.automaton.MutableDeterministic.FiniteSemantics; import org.checkerframework.checker.nullness.qual.Nullable; -public interface MutableDFA extends DFA, - MutableDeterministic, - MutableFSA, - MutableSemantics { +public interface MutableDFA extends DFA, FiniteSemantics, MutableFSA { @Override // Overridden for performance reasons (to prevent creating redundant transition objects) diff --git a/api/src/main/java/net/automatalib/automaton/fsa/MutableFSA.java b/api/src/main/java/net/automatalib/automaton/fsa/MutableFSA.java index c49949a81..ae775cd63 100644 --- a/api/src/main/java/net/automatalib/automaton/fsa/MutableFSA.java +++ b/api/src/main/java/net/automatalib/automaton/fsa/MutableFSA.java @@ -15,11 +15,11 @@ */ package net.automatalib.automaton.fsa; -import net.automatalib.automaton.MutableAutomaton; +import net.automatalib.automaton.MutableAutomaton.FiniteSemantics; import net.automatalib.common.util.WrapperUtil; import org.checkerframework.checker.nullness.qual.Nullable; -public interface MutableFSA extends FiniteStateAcceptor, MutableAutomaton { +public interface MutableFSA extends FiniteStateAcceptor, FiniteSemantics { default void flipAcceptance() { for (S state : this) { diff --git a/api/src/main/java/net/automatalib/automaton/fsa/MutableNFA.java b/api/src/main/java/net/automatalib/automaton/fsa/MutableNFA.java index 70c8f7f4a..11ae09ee2 100644 --- a/api/src/main/java/net/automatalib/automaton/fsa/MutableNFA.java +++ b/api/src/main/java/net/automatalib/automaton/fsa/MutableNFA.java @@ -15,8 +15,4 @@ */ package net.automatalib.automaton.fsa; -import net.automatalib.semantics.FiniteSemantics.MutableSemantics; - -public interface MutableNFA extends NFA, MutableFSA, MutableSemantics { - -} +public interface MutableNFA extends NFA, MutableFSA {} diff --git a/api/src/main/java/net/automatalib/automaton/mmlt/MMLT.java b/api/src/main/java/net/automatalib/automaton/mmlt/MMLT.java index 000a9cb74..289952271 100644 --- a/api/src/main/java/net/automatalib/automaton/mmlt/MMLT.java +++ b/api/src/main/java/net/automatalib/automaton/mmlt/MMLT.java @@ -22,10 +22,8 @@ import net.automatalib.common.util.Triple; import net.automatalib.graph.Graph; import net.automatalib.graph.concept.GraphViewable; -import net.automatalib.semantics.DeterministicSemantics.WildcardUniversalSemantics; +import net.automatalib.semantic.DeterministicSemantics; import net.automatalib.symbol.time.SymbolicInput; -import net.automatalib.symbol.time.TimedInput; -import net.automatalib.symbol.time.TimedOutput; /** * Base type for a Mealy Machine with Local Timers (MMLT). @@ -55,7 +53,7 @@ */ public interface MMLT extends UniversalDeterministicAutomaton, InputAlphabetHolder, - WildcardUniversalSemantics, TimedInput, Void, TimedOutput>, + DeterministicSemantics, GraphViewable { /** diff --git a/api/src/main/java/net/automatalib/automaton/procedural/SBA.java b/api/src/main/java/net/automatalib/automaton/procedural/SBA.java index 7bbd117ae..af120ea93 100644 --- a/api/src/main/java/net/automatalib/automaton/procedural/SBA.java +++ b/api/src/main/java/net/automatalib/automaton/procedural/SBA.java @@ -22,7 +22,7 @@ import net.automatalib.alphabet.ProceduralInputAlphabet; import net.automatalib.automaton.fsa.DFA; -import net.automatalib.semantics.DeterministicSemantics.UniversalSemantics; +import net.automatalib.semantic.DeterministicSemantics; import net.automatalib.ts.acceptor.DeterministicAcceptorTS; /** @@ -36,8 +36,8 @@ * @param * input symbol type */ -public interface SBA extends ProceduralSystem>, DeterministicAcceptorTS, - UniversalSemantics { +public interface SBA + extends ProceduralSystem>, DeterministicAcceptorTS, DeterministicSemantics { @Override default SBA getSemantics() { diff --git a/api/src/main/java/net/automatalib/automaton/procedural/SPA.java b/api/src/main/java/net/automatalib/automaton/procedural/SPA.java index de2321d2d..9ac6f3dd4 100644 --- a/api/src/main/java/net/automatalib/automaton/procedural/SPA.java +++ b/api/src/main/java/net/automatalib/automaton/procedural/SPA.java @@ -22,7 +22,7 @@ import net.automatalib.alphabet.ProceduralInputAlphabet; import net.automatalib.automaton.fsa.DFA; -import net.automatalib.semantics.DeterministicSemantics.UniversalSemantics; +import net.automatalib.semantic.DeterministicSemantics; import net.automatalib.ts.acceptor.DeterministicAcceptorTS; /** @@ -58,8 +58,7 @@ * input symbol type */ public interface SPA - extends ProceduralSystem>, DeterministicAcceptorTS, - UniversalSemantics { + extends ProceduralSystem>, DeterministicAcceptorTS, DeterministicSemantics { @Override default SPA getSemantics() { diff --git a/api/src/main/java/net/automatalib/automaton/procedural/SPMM.java b/api/src/main/java/net/automatalib/automaton/procedural/SPMM.java index b24f4a173..18fc94631 100644 --- a/api/src/main/java/net/automatalib/automaton/procedural/SPMM.java +++ b/api/src/main/java/net/automatalib/automaton/procedural/SPMM.java @@ -24,7 +24,7 @@ import net.automatalib.alphabet.ProceduralInputAlphabet; import net.automatalib.automaton.concept.Output; import net.automatalib.automaton.transducer.MealyMachine; -import net.automatalib.semantics.DeterministicSemantics.UniversalSemantics; +import net.automatalib.semantic.DeterministicSemantics; import net.automatalib.ts.concept.DeterministicSuffixOutputTS; import net.automatalib.ts.output.MealyTransitionSystem; import net.automatalib.word.Word; @@ -47,7 +47,8 @@ * output symbol type */ public interface SPMM extends ProceduralSystem>, - MealyTransitionSystem, UniversalSemantics { + MealyTransitionSystem, + DeterministicSemantics { @Override default SPMM getSemantics() { diff --git a/api/src/main/java/net/automatalib/automaton/transducer/MealyMachine.java b/api/src/main/java/net/automatalib/automaton/transducer/MealyMachine.java index 61bb21e7b..a9486f51f 100644 --- a/api/src/main/java/net/automatalib/automaton/transducer/MealyMachine.java +++ b/api/src/main/java/net/automatalib/automaton/transducer/MealyMachine.java @@ -17,19 +17,17 @@ import java.util.Collection; -import net.automatalib.automaton.UniversalDeterministicAutomaton; +import net.automatalib.automaton.UniversalDeterministicAutomaton.FiniteSemantics; import net.automatalib.automaton.graph.TransitionEdge; import net.automatalib.automaton.graph.UniversalAutomatonGraphView; import net.automatalib.automaton.visualization.MealyVisualizationHelper; import net.automatalib.graph.UniversalGraph; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.ts.output.MealyTransitionSystem; import net.automatalib.visualization.VisualizationHelper; -public interface MealyMachine extends UniversalDeterministicAutomaton, +public interface MealyMachine extends FiniteSemantics, TransitionOutputAutomaton, - MealyTransitionSystem, - UniversalSemantics { + MealyTransitionSystem { @Override default MealyMachine getSemantics() { diff --git a/api/src/main/java/net/automatalib/automaton/transducer/MooreMachine.java b/api/src/main/java/net/automatalib/automaton/transducer/MooreMachine.java index 628d43130..58c441dd7 100644 --- a/api/src/main/java/net/automatalib/automaton/transducer/MooreMachine.java +++ b/api/src/main/java/net/automatalib/automaton/transducer/MooreMachine.java @@ -17,20 +17,17 @@ import java.util.Collection; -import net.automatalib.automaton.UniversalDeterministicAutomaton; +import net.automatalib.automaton.UniversalDeterministicAutomaton.FiniteSemantics; import net.automatalib.automaton.graph.TransitionEdge; import net.automatalib.automaton.graph.TransitionEdge.Property; import net.automatalib.automaton.graph.UniversalAutomatonGraphView; import net.automatalib.automaton.visualization.MooreVisualizationHelper; import net.automatalib.graph.UniversalGraph; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.ts.output.MooreTransitionSystem; import net.automatalib.visualization.VisualizationHelper; -public interface MooreMachine extends UniversalDeterministicAutomaton, - StateOutputAutomaton, - MooreTransitionSystem, - UniversalSemantics { +public interface MooreMachine + extends FiniteSemantics, StateOutputAutomaton, MooreTransitionSystem { @Override default MooreMachine getSemantics() { diff --git a/api/src/main/java/net/automatalib/automaton/transducer/MutableMealyMachine.java b/api/src/main/java/net/automatalib/automaton/transducer/MutableMealyMachine.java index d6a5ba186..1c8c36011 100644 --- a/api/src/main/java/net/automatalib/automaton/transducer/MutableMealyMachine.java +++ b/api/src/main/java/net/automatalib/automaton/transducer/MutableMealyMachine.java @@ -15,14 +15,11 @@ */ package net.automatalib.automaton.transducer; -import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.MutableDeterministic.FiniteSemantics; import net.automatalib.automaton.concept.MutableTransitionOutput; -import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; -public interface MutableMealyMachine extends MealyMachine, - MutableDeterministic, - MutableTransitionOutput, - MutableSemantics { +public interface MutableMealyMachine + extends MealyMachine, FiniteSemantics, MutableTransitionOutput { @Override default void setStateProperty(S state, Void property) {} diff --git a/api/src/main/java/net/automatalib/automaton/transducer/MutableMooreMachine.java b/api/src/main/java/net/automatalib/automaton/transducer/MutableMooreMachine.java index 2db961fd6..0c0337677 100644 --- a/api/src/main/java/net/automatalib/automaton/transducer/MutableMooreMachine.java +++ b/api/src/main/java/net/automatalib/automaton/transducer/MutableMooreMachine.java @@ -15,14 +15,11 @@ */ package net.automatalib.automaton.transducer; -import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.MutableDeterministic.FiniteSemantics; import net.automatalib.automaton.concept.MutableStateOutput; -import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; -public interface MutableMooreMachine extends MooreMachine, - MutableDeterministic, - MutableStateOutput, - MutableSemantics { +public interface MutableMooreMachine + extends MooreMachine, FiniteSemantics, MutableStateOutput { @Override default void setStateProperty(S state, O property) { diff --git a/api/src/main/java/net/automatalib/automaton/transducer/MutableSubsequentialTransducer.java b/api/src/main/java/net/automatalib/automaton/transducer/MutableSubsequentialTransducer.java index 91aad8efa..7a1af98ff 100644 --- a/api/src/main/java/net/automatalib/automaton/transducer/MutableSubsequentialTransducer.java +++ b/api/src/main/java/net/automatalib/automaton/transducer/MutableSubsequentialTransducer.java @@ -16,7 +16,7 @@ package net.automatalib.automaton.transducer; import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; +import net.automatalib.automaton.MutableDeterministic.FiniteSemantics; import net.automatalib.word.Word; /** @@ -31,6 +31,5 @@ * @param * output symbol type */ -public interface MutableSubsequentialTransducer extends SubsequentialTransducer, - MutableDeterministic, Word>, - MutableSemantics, Word> {} +public interface MutableSubsequentialTransducer + extends SubsequentialTransducer, FiniteSemantics, Word> {} diff --git a/api/src/main/java/net/automatalib/automaton/transducer/SubsequentialTransducer.java b/api/src/main/java/net/automatalib/automaton/transducer/SubsequentialTransducer.java index 0979f47ba..5eb3c0153 100644 --- a/api/src/main/java/net/automatalib/automaton/transducer/SubsequentialTransducer.java +++ b/api/src/main/java/net/automatalib/automaton/transducer/SubsequentialTransducer.java @@ -18,7 +18,7 @@ import java.util.Collection; import java.util.List; -import net.automatalib.automaton.UniversalDeterministicAutomaton; +import net.automatalib.automaton.UniversalDeterministicAutomaton.FiniteSemantics; import net.automatalib.automaton.concept.DeterministicSuffixOutputAutomaton; import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.graph.TransitionEdge; @@ -26,7 +26,6 @@ import net.automatalib.automaton.graph.UniversalAutomatonGraphView; import net.automatalib.automaton.visualization.SSTVisualizationHelper; import net.automatalib.graph.UniversalGraph; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.ts.concept.DeterministicOutputTS; import net.automatalib.ts.output.DeterministicTraceableTS; import net.automatalib.visualization.VisualizationHelper; @@ -54,8 +53,7 @@ */ public interface SubsequentialTransducer extends DeterministicTraceableTS, DeterministicSuffixOutputAutomaton>, - UniversalDeterministicAutomaton, Word>, - UniversalSemantics, Word> { + FiniteSemantics, Word> { @Override default SubsequentialTransducer getSemantics() { diff --git a/api/src/main/java/net/automatalib/automaton/vpa/OneSEVPA.java b/api/src/main/java/net/automatalib/automaton/vpa/OneSEVPA.java index 98edb318b..332b2e27f 100644 --- a/api/src/main/java/net/automatalib/automaton/vpa/OneSEVPA.java +++ b/api/src/main/java/net/automatalib/automaton/vpa/OneSEVPA.java @@ -30,7 +30,7 @@ public interface OneSEVPA extends SEVPA { @Override default L getModuleEntry(I callSym) { - return getInitialLocation(); + return getInitialState(); } } diff --git a/api/src/main/java/net/automatalib/automaton/vpa/SEVPA.java b/api/src/main/java/net/automatalib/automaton/vpa/SEVPA.java index 1fa307b40..362859c9f 100644 --- a/api/src/main/java/net/automatalib/automaton/vpa/SEVPA.java +++ b/api/src/main/java/net/automatalib/automaton/vpa/SEVPA.java @@ -15,14 +15,19 @@ */ package net.automatalib.automaton.vpa; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; +import java.util.Set; import net.automatalib.alphabet.VPAlphabet; -import net.automatalib.automaton.concept.FiniteRepresentation; +import net.automatalib.automaton.UniversalAutomaton; import net.automatalib.automaton.concept.InputAlphabetHolder; import net.automatalib.automaton.vpa.SEVPAGraphView.SevpaViewEdge; import net.automatalib.graph.Graph; import net.automatalib.graph.concept.GraphViewable; +import net.automatalib.semantic.DeterministicSemantics; import net.automatalib.ts.acceptor.DeterministicAcceptorTS; import org.checkerframework.checker.nullness.qual.Nullable; @@ -34,50 +39,79 @@ * For more information on the semantics of VPAs see e.g. Congruences for * Visibly Pushdown Languages by Alur, Kumar, Madhusudan and Viswanathan. * - * @param + * @param * location type * @param * input alphabet type */ -public interface SEVPA - extends DeterministicAcceptorTS, I>, InputAlphabetHolder, GraphViewable, FiniteRepresentation { +public interface SEVPA extends UniversalAutomaton, + DeterministicSemantics, + GraphViewable, + InputAlphabetHolder { @Override VPAlphabet getInputAlphabet(); - int encodeStackSym(L srcLoc, I callSym); + S getModuleEntry(I callSym); - @Nullable L getInternalSuccessor(L loc, I intSym); - - L getLocation(int id); + int getNumStackSymbols(); - int getLocationId(L loc); + int encodeStackSym(S srcLoc, I callSym); - List getLocations(); + @Nullable + S getInternalSuccessor(S loc, I intSym); - int getNumStackSymbols(); + @Nullable + S getReturnSuccessor(S loc, I retSym, int stackSym); - L getModuleEntry(I callSym); + @Nullable + S getInitialState(); - @Nullable L getReturnSuccessor(L loc, I retSym, int stackSym); + @Override + default Set getInitialStates() { + final S init = getInitialState(); + return init == null ? Collections.emptySet() : Collections.singleton(init); + } @Override - default boolean isAccepting(State state) { - return state.getLocation() != null && isAcceptingLocation(state.getLocation()) && - state.getStackContents() == null; + default Void getTransitionProperty(S transition) { + return null; } - boolean isAcceptingLocation(L loc); + @Override + default Collection getTransitions(S state, I input) { + final VPAlphabet alphabet = getInputAlphabet(); + return switch (alphabet.getSymbolType(input)) { + case CALL: + yield Collections.singleton(getModuleEntry(input)); + case INTERNAL: + final S iSucc = getInternalSuccessor(state, input); + yield iSucc == null ? Collections.emptyList() : Collections.singleton(iSucc); + case RETURN: + final int symbols = getNumStackSymbols(); + final List result = new ArrayList<>(symbols); + for (int i = 0; i < symbols; i++) { + final S rSucc = getReturnSuccessor(state, input, i); + if (rSucc != null) { + result.add(rSucc); + } + } + yield result; + }; + } @Override - default State getInitialState() { - return new State<>(getInitialLocation(), null); + default S getSuccessor(S transition) { + return transition; } - L getInitialLocation(); + @Override + default DeterministicAcceptorTS, I> getSemantics() { + return new SEVPASemantics<>(this); + } @Override - default Graph> graphView() { + default Graph> graphView() { return new SEVPAGraphView<>(this); } } diff --git a/api/src/main/java/net/automatalib/automaton/vpa/SEVPAGraphView.java b/api/src/main/java/net/automatalib/automaton/vpa/SEVPAGraphView.java index 886c6f879..18fa64d6e 100644 --- a/api/src/main/java/net/automatalib/automaton/vpa/SEVPAGraphView.java +++ b/api/src/main/java/net/automatalib/automaton/vpa/SEVPAGraphView.java @@ -22,6 +22,7 @@ import java.util.Map; import net.automatalib.alphabet.VPAlphabet; +import net.automatalib.automaton.concept.StateIDs; import net.automatalib.automaton.vpa.SEVPAGraphView.SevpaViewEdge; import net.automatalib.graph.Graph; import net.automatalib.visualization.DefaultVisualizationHelper; @@ -32,15 +33,17 @@ public class SEVPAGraphView implements Graph> { private final SEVPA sevpa; private final VPAlphabet alphabet; + private final StateIDs stateIDs; public SEVPAGraphView(SEVPA sevpa) { this.sevpa = sevpa; this.alphabet = sevpa.getInputAlphabet(); + this.stateIDs = sevpa.stateIDs(); } @Override public Collection getNodes() { - return Collections.unmodifiableCollection(sevpa.getLocations()); + return Collections.unmodifiableCollection(sevpa.getStates()); } @Override @@ -66,13 +69,13 @@ public Collection> getOutgoingEdges(L location) { // all return transitions for every possible stack contents for (I i : alphabet.getReturnAlphabet()) { - for (L loc : sevpa.getLocations()) { + for (L loc : sevpa.getStates()) { for (I stackSymbol : alphabet.getCallAlphabet()) { final int sym = sevpa.encodeStackSym(loc, stackSymbol); final L succ = sevpa.getReturnSuccessor(location, i, sym); if (succ != null) { - result.add(new SevpaViewEdge<>(i, succ, sevpa.getLocationId(loc), stackSymbol)); + result.add(new SevpaViewEdge<>(i, succ, loc, stackSymbol)); } } } @@ -92,17 +95,17 @@ public VisualizationHelper> getVisualizationHelper() { @Override protected Collection initialNodes() { - return Collections.singleton(sevpa.getInitialLocation()); + return Collections.singleton(sevpa.getInitialState()); } @Override public boolean getNodeProperties(L node, Map properties) { super.getNodeProperties(node, properties); - if (sevpa.isAcceptingLocation(node)) { + if (sevpa.getStateProperty(node)) { properties.put(NodeAttrs.SHAPE, NodeShapes.DOUBLECIRCLE); } - properties.put(NodeAttrs.LABEL, "L" + sevpa.getLocationId(node)); + properties.put(NodeAttrs.LABEL, "L" + stateIDs.getStateId(node)); return true; } @@ -113,7 +116,8 @@ public boolean getEdgeProperties(L src, SevpaViewEdge edge, L tgt, Map { public final I input; public final S target; - public final int callLocId; + public final S callLoc; public final @Nullable I callSymbol; SevpaViewEdge(I internalAction, S target) { - this(internalAction, target, -1, null); + this(internalAction, target, null, null); } - SevpaViewEdge(I returnAction, S target, int callLocId, @Nullable I callSymbol) { + SevpaViewEdge(I returnAction, S target, S callLoc, @Nullable I callSymbol) { this.input = returnAction; this.target = target; - this.callLocId = callLocId; + this.callLoc = callLoc; this.callSymbol = callSymbol; } diff --git a/api/src/main/java/net/automatalib/automaton/vpa/SEVPASemantics.java b/api/src/main/java/net/automatalib/automaton/vpa/SEVPASemantics.java new file mode 100644 index 000000000..8ea097226 --- /dev/null +++ b/api/src/main/java/net/automatalib/automaton/vpa/SEVPASemantics.java @@ -0,0 +1,71 @@ +/* Copyright (C) 2013-2026 TU Dortmund University + * This file is part of AutomataLib . + * + * 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 net.automatalib.automaton.vpa; + +import net.automatalib.alphabet.VPAlphabet; +import net.automatalib.ts.acceptor.DeterministicAcceptorTS; +import org.checkerframework.checker.nullness.qual.Nullable; + +public class SEVPASemantics implements DeterministicAcceptorTS, I> { + + private final SEVPA sevpa; + private final VPAlphabet alphabet; + + public SEVPASemantics(SEVPA sevpa) { + this.sevpa = sevpa; + this.alphabet = sevpa.getInputAlphabet(); + } + + @Override + public @Nullable State getTransition(State state, I input) { + final S loc = state.getLocation(); + return switch (alphabet.getSymbolType(input)) { + case CALL: + final int newStackElem = sevpa.encodeStackSym(loc, input); + yield new State<>(sevpa.getModuleEntry(input), + StackContents.push(newStackElem, state.getStackContents())); + case RETURN: { + final StackContents contents = state.getStackContents(); + if (contents == null) { + yield null; + } + final int stackElem = contents.peek(); + final S succ = sevpa.getReturnSuccessor(loc, input, stackElem); + if (succ == null) { + yield null; + } + yield new State<>(succ, contents.pop()); + } + case INTERNAL: { + final S succ = sevpa.getInternalSuccessor(loc, input); + if (succ == null) { + yield null; + } + yield new State<>(succ, state.getStackContents()); + } + }; + } + + @Override + public boolean isAccepting(State state) { + return sevpa.getStateProperty(state.getLocation()) && state.getStackContents() == null; + } + + @Override + public State getInitialState() { + return new State<>(sevpa.getInitialState(), null); + } +} diff --git a/api/src/main/java/net/automatalib/semantic/DeterministicFiniteSemantics.java b/api/src/main/java/net/automatalib/semantic/DeterministicFiniteSemantics.java new file mode 100644 index 000000000..e0b6ed46b --- /dev/null +++ b/api/src/main/java/net/automatalib/semantic/DeterministicFiniteSemantics.java @@ -0,0 +1,26 @@ +/* Copyright (C) 2013-2026 TU Dortmund University + * This file is part of AutomataLib . + * + * 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 net.automatalib.semantic; + +import net.automatalib.automaton.DeterministicAutomaton; + +@FunctionalInterface +public interface DeterministicFiniteSemantics extends DeterministicSemantics, FiniteSemantics { + + @Override + DeterministicAutomaton getSemantics(); + +} diff --git a/api/src/main/java/net/automatalib/semantic/DeterministicSemantics.java b/api/src/main/java/net/automatalib/semantic/DeterministicSemantics.java new file mode 100644 index 000000000..8fee5e0ae --- /dev/null +++ b/api/src/main/java/net/automatalib/semantic/DeterministicSemantics.java @@ -0,0 +1,26 @@ +/* Copyright (C) 2013-2026 TU Dortmund University + * This file is part of AutomataLib . + * + * 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 net.automatalib.semantic; + +import net.automatalib.ts.DeterministicTransitionSystem; + +@FunctionalInterface +public interface DeterministicSemantics extends Semantics { + + @Override + DeterministicTransitionSystem getSemantics(); + +} diff --git a/api/src/main/java/net/automatalib/semantic/FiniteSemantics.java b/api/src/main/java/net/automatalib/semantic/FiniteSemantics.java new file mode 100644 index 000000000..b036f67f4 --- /dev/null +++ b/api/src/main/java/net/automatalib/semantic/FiniteSemantics.java @@ -0,0 +1,26 @@ +/* Copyright (C) 2013-2026 TU Dortmund University + * This file is part of AutomataLib . + * + * 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 net.automatalib.semantic; + +import net.automatalib.automaton.Automaton; + +@FunctionalInterface +public interface FiniteSemantics extends Semantics { + + @Override + Automaton getSemantics(); + +} diff --git a/api/src/main/java/net/automatalib/semantic/Semantics.java b/api/src/main/java/net/automatalib/semantic/Semantics.java new file mode 100644 index 000000000..48db7d019 --- /dev/null +++ b/api/src/main/java/net/automatalib/semantic/Semantics.java @@ -0,0 +1,25 @@ +/* Copyright (C) 2013-2026 TU Dortmund University + * This file is part of AutomataLib . + * + * 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 net.automatalib.semantic; + +import net.automatalib.ts.TransitionSystem; + +@FunctionalInterface +public interface Semantics { + + TransitionSystem getSemantics(); + +} diff --git a/api/src/main/java/net/automatalib/semantics/DeterministicFiniteSemantics.java b/api/src/main/java/net/automatalib/semantics/DeterministicFiniteSemantics.java deleted file mode 100644 index 03db21873..000000000 --- a/api/src/main/java/net/automatalib/semantics/DeterministicFiniteSemantics.java +++ /dev/null @@ -1,51 +0,0 @@ -package net.automatalib.semantics; - -import net.automatalib.automaton.DeterministicAutomaton; -import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.automaton.UniversalDeterministicAutomaton; - -public interface DeterministicFiniteSemantics extends DeterministicSemantics, FiniteSemantics { - - interface WildcardPlainSemantics extends DeterministicFiniteSemantics, - DeterministicSemantics.WildcardPlainSemantics, - FiniteSemantics.WildcardPlainSemantics { - - DeterministicAutomaton getSemantics(); - } - - interface PlainSemantics extends WildcardPlainSemantics, - DeterministicSemantics.PlainSemantics, - FiniteSemantics.PlainSemantics, - DeterministicAutomaton { - - @Override - default DeterministicAutomaton getSemantics() { - return this; - } - } - - interface WildcardUniversalSemantics extends WildcardPlainSemantics, - DeterministicSemantics.WildcardUniversalSemantics, - FiniteSemantics.WildcardUniversalSemantics { - - @Override - UniversalDeterministicAutomaton getSemantics(); - } - - interface UniversalSemantics extends PlainSemantics, - WildcardUniversalSemantics, - FiniteSemantics.UniversalSemantics, - DeterministicSemantics.UniversalSemantics, - UniversalDeterministicAutomaton { - - @Override - default UniversalDeterministicAutomaton getSemantics() { - return this; - } - } - - interface MutableSemantics extends UniversalSemantics, - FiniteSemantics.MutableSemantics, - MutableDeterministic {} - -} diff --git a/api/src/main/java/net/automatalib/semantics/DeterministicSemantics.java b/api/src/main/java/net/automatalib/semantics/DeterministicSemantics.java deleted file mode 100644 index c90fa20de..000000000 --- a/api/src/main/java/net/automatalib/semantics/DeterministicSemantics.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.automatalib.semantics; - -import net.automatalib.ts.DeterministicTransitionSystem; -import net.automatalib.ts.UniversalDTS; - -public interface DeterministicSemantics extends Semantics { - - interface WildcardPlainSemantics extends DeterministicSemantics, Semantics.WildcardPlainSemantics { - - DeterministicTransitionSystem getSemantics(); - - } - - interface PlainSemantics extends WildcardPlainSemantics, - Semantics.PlainSemantics, - DeterministicTransitionSystem { - - @Override - default DeterministicTransitionSystem getSemantics() { - return this; - } - } - - interface WildcardUniversalSemantics - extends WildcardPlainSemantics, Semantics.WildcardUniversalSemantics { - - @Override - UniversalDTS getSemantics(); - } - - interface UniversalSemantics extends PlainSemantics, - WildcardUniversalSemantics, - Semantics.UniversalSemantics, - UniversalDTS { - - @Override - default UniversalDTS getSemantics() { - return this; - } - } - -} diff --git a/api/src/main/java/net/automatalib/semantics/FiniteSemantics.java b/api/src/main/java/net/automatalib/semantics/FiniteSemantics.java deleted file mode 100644 index 1efef2d4b..000000000 --- a/api/src/main/java/net/automatalib/semantics/FiniteSemantics.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.automatalib.semantics; - -import net.automatalib.automaton.Automaton; -import net.automatalib.automaton.MutableAutomaton; -import net.automatalib.automaton.UniversalAutomaton; - -public interface FiniteSemantics extends Semantics { - - interface WildcardPlainSemantics extends FiniteSemantics, Semantics.WildcardPlainSemantics { - - Automaton getSemantics(); - - } - - interface PlainSemantics - extends WildcardPlainSemantics, Semantics.PlainSemantics, Automaton { - - @Override - default Automaton getSemantics() { - return this; - } - } - - interface WildcardUniversalSemantics - extends WildcardPlainSemantics, Semantics.WildcardUniversalSemantics { - - @Override - UniversalAutomaton getSemantics(); - } - - interface UniversalSemantics extends PlainSemantics, - WildcardUniversalSemantics, - Semantics.UniversalSemantics, - UniversalAutomaton { - - @Override - default UniversalAutomaton getSemantics() { - return this; - } - } - - interface MutableSemantics - extends UniversalSemantics, MutableAutomaton {} - -} diff --git a/api/src/main/java/net/automatalib/semantics/Semantics.java b/api/src/main/java/net/automatalib/semantics/Semantics.java deleted file mode 100644 index 41e621520..000000000 --- a/api/src/main/java/net/automatalib/semantics/Semantics.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.automatalib.semantics; - -import net.automatalib.ts.TransitionSystem; -import net.automatalib.ts.UniversalTransitionSystem; - -public interface Semantics { - - interface WildcardPlainSemantics extends Semantics { - - TransitionSystem getSemantics(); - } - - interface PlainSemantics extends WildcardPlainSemantics, TransitionSystem { - - @Override - default TransitionSystem getSemantics() { - return this; - } - } - - interface WildcardUniversalSemantics extends WildcardPlainSemantics { - - @Override - UniversalTransitionSystem getSemantics(); - } - - interface UniversalSemantics extends PlainSemantics, - WildcardUniversalSemantics, - UniversalTransitionSystem { - - @Override - default UniversalTransitionSystem getSemantics() { - return this; - } - } - -} diff --git a/api/src/main/java/net/automatalib/ts/modal/ModalTransitionSystem.java b/api/src/main/java/net/automatalib/ts/modal/ModalTransitionSystem.java index b17a1fd5c..35218b6e1 100644 --- a/api/src/main/java/net/automatalib/ts/modal/ModalTransitionSystem.java +++ b/api/src/main/java/net/automatalib/ts/modal/ModalTransitionSystem.java @@ -18,13 +18,13 @@ import java.util.Collection; import net.automatalib.automaton.UniversalAutomaton; +import net.automatalib.automaton.UniversalAutomaton.FiniteSemantics; import net.automatalib.automaton.UniversalFiniteAlphabetAutomaton; import net.automatalib.automaton.graph.TransitionEdge; import net.automatalib.automaton.graph.TransitionEdge.Property; import net.automatalib.automaton.graph.UniversalAutomatonGraphView; import net.automatalib.automaton.visualization.MTSVisualizationHelper; import net.automatalib.graph.UniversalGraph; -import net.automatalib.semantics.FiniteSemantics.UniversalSemantics; import net.automatalib.ts.modal.transition.ModalEdgeProperty; import net.automatalib.visualization.VisualizationHelper; @@ -45,7 +45,7 @@ * (specific) transition property type */ public interface ModalTransitionSystem - extends UniversalFiniteAlphabetAutomaton, UniversalSemantics { + extends UniversalFiniteAlphabetAutomaton, FiniteSemantics { @Override default ModalTransitionSystem getSemantics() { diff --git a/api/src/main/java/net/automatalib/ts/modal/MutableModalTransitionSystem.java b/api/src/main/java/net/automatalib/ts/modal/MutableModalTransitionSystem.java index 21cf43ba6..e9c566cc9 100644 --- a/api/src/main/java/net/automatalib/ts/modal/MutableModalTransitionSystem.java +++ b/api/src/main/java/net/automatalib/ts/modal/MutableModalTransitionSystem.java @@ -15,7 +15,7 @@ */ package net.automatalib.ts.modal; -import net.automatalib.automaton.MutableAutomaton; +import net.automatalib.automaton.MutableAutomaton.FiniteSemantics; import net.automatalib.ts.modal.transition.ModalEdgeProperty.ModalType; import net.automatalib.ts.modal.transition.MutableModalEdgeProperty; @@ -32,7 +32,7 @@ * (specific) transition property type */ public interface MutableModalTransitionSystem - extends ModalTransitionSystem, MutableAutomaton { + extends ModalTransitionSystem, FiniteSemantics { T addModalTransition(S src, I input, S tgt, ModalType modalType); diff --git a/core/src/main/java/net/automatalib/automaton/impl/UniversalCompactDetAutomaton.java b/core/src/main/java/net/automatalib/automaton/impl/UniversalCompactDetAutomaton.java index 59de55003..3da0b8bb2 100644 --- a/core/src/main/java/net/automatalib/automaton/impl/UniversalCompactDetAutomaton.java +++ b/core/src/main/java/net/automatalib/automaton/impl/UniversalCompactDetAutomaton.java @@ -17,11 +17,8 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.AutomatonCreator; -import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.automaton.UniversalFiniteAlphabetAutomaton; +import net.automatalib.automaton.MutableDeterministic.FiniteSemantics; import net.automatalib.automaton.base.AbstractCompactDeterministic; -import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; /** * A default implementation for {@link AbstractCompactDeterministic} that uses {@link CompactTransition} as transition @@ -34,11 +31,8 @@ * @param * transition property type */ -public class UniversalCompactDetAutomaton extends UniversalCompactDet implements - MutableDeterministic, SP, TP>, - UniversalFiniteAlphabetAutomaton, SP, TP>, - UniversalSemantics, SP, TP>, - MutableSemantics, SP, TP> { +public class UniversalCompactDetAutomaton extends UniversalCompactDet + implements FiniteSemantics, SP, TP> { public UniversalCompactDetAutomaton(Alphabet alphabet) { super(alphabet); diff --git a/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractDefaultSEVPA.java b/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractDefaultSEVPA.java index 65aa210b8..aabc1cc86 100644 --- a/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractDefaultSEVPA.java +++ b/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractDefaultSEVPA.java @@ -19,6 +19,7 @@ import java.util.List; import net.automatalib.alphabet.VPAlphabet; +import net.automatalib.automaton.concept.StateIDs; import org.checkerframework.checker.nullness.qual.Nullable; /** @@ -56,32 +57,38 @@ public int size() { return locations.size(); } - public void setInternalSuccessor(Location loc, I intSym, Location succ) { - loc.setInternalSuccessor(alphabet.getInternalSymbolIndex(intSym), succ); + @Override + public StateIDs stateIDs() { + return this; } - public void setReturnSuccessor(Location loc, I retSym, int stackSym, Location succ) { - loc.setReturnSuccessor(alphabet.getReturnSymbolIndex(retSym), stackSym, succ); + @Override + public int getStateId(Location state) { + return state.getIndex(); } @Override - public Location getInternalSuccessor(Location loc, I intSym) { - return loc.getInternalSuccessor(alphabet.getInternalSymbolIndex(intSym)); + public Location getState(int id) { + return this.locations.get(id); } @Override - public Location getLocation(int id) { - return locations.get(id); + public List getStates() { + return locations; } @Override - public int getLocationId(Location loc) { - return loc.getIndex(); + public Boolean getStateProperty(Location state) { + return state.isAccepting(); } @Override - public List getLocations() { - return locations; + public Location getInternalSuccessor(Location loc, I intSym) { + return loc.getInternalSuccessor(alphabet.getInternalSymbolIndex(intSym)); + } + + public void setInternalSuccessor(Location loc, I intSym, Location succ) { + loc.setInternalSuccessor(alphabet.getInternalSymbolIndex(intSym), succ); } @Override @@ -89,13 +96,12 @@ public List getLocations() { return loc.getReturnSuccessor(alphabet.getReturnSymbolIndex(retSym), stackSym); } - @Override - public boolean isAcceptingLocation(Location loc) { - return loc.isAccepting(); + public void setReturnSuccessor(Location loc, I retSym, int stackSym, Location succ) { + loc.setReturnSuccessor(alphabet.getReturnSymbolIndex(retSym), stackSym, succ); } @Override - public Location getInitialLocation() { + public Location getInitialState() { return initLoc; } diff --git a/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractSEVPA.java b/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractSEVPA.java index 267110e53..5ea439845 100644 --- a/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractSEVPA.java +++ b/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractSEVPA.java @@ -16,10 +16,8 @@ package net.automatalib.automaton.vpa.impl; import net.automatalib.alphabet.VPAlphabet; +import net.automatalib.automaton.concept.StateIDs; import net.automatalib.automaton.vpa.SEVPA; -import net.automatalib.automaton.vpa.StackContents; -import net.automatalib.automaton.vpa.State; -import org.checkerframework.checker.nullness.qual.Nullable; /** * Abstract class for k-SEVPAs that implements functionality shared across different subtypes. @@ -29,7 +27,7 @@ * @param * input alphabet type */ -public abstract class AbstractSEVPA implements SEVPA { +public abstract class AbstractSEVPA implements SEVPA, StateIDs { protected final VPAlphabet alphabet; @@ -42,43 +40,13 @@ public VPAlphabet getInputAlphabet() { return alphabet; } - @Override - public @Nullable State getTransition(State state, I input) { - final L loc = state.getLocation(); - final VPAlphabet.SymbolType type = alphabet.getSymbolType(input); - return switch (type) { - case CALL: - final int newStackElem = encodeStackSym(loc, input); - yield new State<>(getModuleEntry(input), StackContents.push(newStackElem, state.getStackContents())); - case RETURN: { - final StackContents contents = state.getStackContents(); - if (contents == null) { - yield null; - } - final int stackElem = contents.peek(); - final L succ = getReturnSuccessor(loc, input, stackElem); - if (succ == null) { - yield null; - } - yield new State<>(succ, contents.pop()); - } - case INTERNAL: { - final L succ = getInternalSuccessor(loc, input); - if (succ == null) { - yield null; - } - yield new State<>(succ, state.getStackContents()); - } - }; - } - @Override public int encodeStackSym(L srcLoc, I callSym) { return encodeStackSym(srcLoc, alphabet.getCallSymbolIndex(callSym)); } public int encodeStackSym(L srcLoc, int callSymIdx) { - return alphabet.getNumCalls() * getLocationId(srcLoc) + callSymIdx; + return alphabet.getNumCalls() * getStateId(srcLoc) + callSymIdx; } @Override @@ -87,7 +55,7 @@ public int getNumStackSymbols() { } public L getStackLoc(int stackSym) { - return getLocation(stackSym / alphabet.getNumCalls()); + return getState(stackSym / alphabet.getNumCalls()); } public I getCallSym(int stackSym) { diff --git a/core/src/test/java/net/automatalib/automaton/vpa/impl/DefaultVPATest.java b/core/src/test/java/net/automatalib/automaton/vpa/impl/DefaultVPATest.java index ab9ed13fc..5f3482d73 100644 --- a/core/src/test/java/net/automatalib/automaton/vpa/impl/DefaultVPATest.java +++ b/core/src/test/java/net/automatalib/automaton/vpa/impl/DefaultVPATest.java @@ -96,17 +96,17 @@ public void testBracketLanguageNSevpa() { } private void checkBracketWord(SEVPA sevpa) { - Assert.assertTrue(sevpa.accepts(Word.fromString("()"))); - Assert.assertTrue(sevpa.accepts(Word.fromString("[]"))); - Assert.assertTrue(sevpa.accepts(Word.fromString("(([[]]))"))); - Assert.assertTrue(sevpa.accepts(Word.fromString("([([])])"))); - Assert.assertTrue(sevpa.accepts(Word.fromString("[(())]"))); - - Assert.assertFalse(sevpa.accepts(Word.fromString(""))); - Assert.assertFalse(sevpa.accepts(Word.fromString("([(["))); - Assert.assertFalse(sevpa.accepts(Word.fromString("(((]]]"))); - Assert.assertFalse(sevpa.accepts(Word.fromString(")("))); - Assert.assertFalse(sevpa.accepts(Word.fromString("()()"))); + Assert.assertTrue(sevpa.getSemantics().accepts(Word.fromString("()"))); + Assert.assertTrue(sevpa.getSemantics().accepts(Word.fromString("[]"))); + Assert.assertTrue(sevpa.getSemantics().accepts(Word.fromString("(([[]]))"))); + Assert.assertTrue(sevpa.getSemantics().accepts(Word.fromString("([([])])"))); + Assert.assertTrue(sevpa.getSemantics().accepts(Word.fromString("[(())]"))); + + Assert.assertFalse(sevpa.getSemantics().accepts(Word.fromString(""))); + Assert.assertFalse(sevpa.getSemantics().accepts(Word.fromString("([(["))); + Assert.assertFalse(sevpa.getSemantics().accepts(Word.fromString("(((]]]"))); + Assert.assertFalse(sevpa.getSemantics().accepts(Word.fromString(")("))); + Assert.assertFalse(sevpa.getSemantics().accepts(Word.fromString("()()"))); } /** @@ -175,14 +175,14 @@ private static void verifyGraphRepresentation(VPAlphabet alphabet, OneSEVPA vpa, Graph> graph) { - Assert.assertEquals(new HashSet<>(vpa.getLocations()), new HashSet<>(graph.getNodes())); + Assert.assertEquals(new HashSet<>(vpa.getStates()), new HashSet<>(graph.getNodes())); - for (L loc : vpa.getLocations()) { + for (L loc : vpa.getStates()) { for (SevpaViewEdge edge : graph.getOutgoingEdges(loc)) { final I input = edge.input; final L target = edge.target; - final int callLocId = edge.callLocId; + final L callLoc = edge.callLoc; final I callSymbol = edge.callSymbol; switch (alphabet.getSymbolType(input)) { @@ -193,7 +193,7 @@ private static void verifyGraphRepresentation(VPAlphabet alphabet, Assert.assertEquals(vpa.getInternalSuccessor(loc, input), target); break; case RETURN: - final int stackSym = vpa.encodeStackSym(vpa.getLocation(callLocId), callSymbol); + final int stackSym = vpa.encodeStackSym(callLoc, callSymbol); Assert.assertEquals(vpa.getReturnSuccessor(loc, input, stackSym), target); break; default: diff --git a/examples/src/main/java/net/automatalib/example/Example.java b/examples/src/main/java/net/automatalib/example/Example.java index 53a60f8d8..cca4ba35e 100644 --- a/examples/src/main/java/net/automatalib/example/Example.java +++ b/examples/src/main/java/net/automatalib/example/Example.java @@ -6,7 +6,6 @@ import net.automatalib.automaton.mmlt.impl.CompactMMLT; import net.automatalib.automaton.mmlt.impl.StringSymbolCombiner; import net.automatalib.automaton.transducer.impl.CompactMealy; -import net.automatalib.semantics.DeterministicFiniteSemantics; import net.automatalib.util.automaton.Automata; import net.automatalib.util.automaton.copy.AutomatonCopyMethod; import net.automatalib.util.automaton.copy.AutomatonLowLevelCopy; diff --git a/modelchecking/ltsmin/src/test/java/net/automatalib/modelchecker/ltsmin/integration/AbstractAut2ETF2FSM2AutTest.java b/modelchecking/ltsmin/src/test/java/net/automatalib/modelchecker/ltsmin/integration/AbstractAut2ETF2FSM2AutTest.java index fad914e33..e226c4fc7 100644 --- a/modelchecking/ltsmin/src/test/java/net/automatalib/modelchecker/ltsmin/integration/AbstractAut2ETF2FSM2AutTest.java +++ b/modelchecking/ltsmin/src/test/java/net/automatalib/modelchecker/ltsmin/integration/AbstractAut2ETF2FSM2AutTest.java @@ -20,11 +20,11 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Alphabets; +import net.automatalib.automaton.UniversalDeterministicAutomaton.FiniteSemantics; import net.automatalib.automaton.concept.InputAlphabetHolder; import net.automatalib.common.util.process.ProcessUtil; import net.automatalib.modelchecker.ltsmin.LTSminUtil; import net.automatalib.modelchecker.ltsmin.LTSminVersion; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.Automata; import org.testng.Assert; import org.testng.SkipException; @@ -43,8 +43,7 @@ * * @param the automaton type. */ -public abstract class AbstractAut2ETF2FSM2AutTest< - A extends UniversalSemantics & InputAlphabetHolder> { +public abstract class AbstractAut2ETF2FSM2AutTest & InputAlphabetHolder> { @BeforeClass public void setupBeforeClass() { @@ -97,9 +96,14 @@ public void test() throws Exception { final A automatonIn = fsm2Automaton(fsm); // find the inputs that are actually used - final Alphabet inputAlphabet = automatonOut.getInputAlphabet().stream().filter( - i -> automatonOut.getStates().stream().anyMatch( - s -> automatonOut.getSuccessor(s, i) != null)).collect(Alphabets.collector()); + final Alphabet inputAlphabet = automatonOut.getInputAlphabet() + .stream() + .filter(i -> automatonOut.getStates() + .stream() + .anyMatch(s -> automatonOut.getSuccessor( + s, + i) != null)) + .collect(Alphabets.collector()); // test we have the same alphabet ignoring order Assert.assertEquals(new HashSet<>(inputAlphabet), new HashSet<>(automatonIn.getInputAlphabet())); diff --git a/util/src/main/java/net/automatalib/util/automaton/Automata.java b/util/src/main/java/net/automatalib/util/automaton/Automata.java index 456f5b4f5..405fcc2ca 100644 --- a/util/src/main/java/net/automatalib/util/automaton/Automata.java +++ b/util/src/main/java/net/automatalib/util/automaton/Automata.java @@ -21,16 +21,14 @@ import java.util.List; import net.automatalib.automaton.Automaton; +import net.automatalib.automaton.DeterministicAutomaton; import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.graph.TransitionEdge; import net.automatalib.common.util.array.ArrayStorage; import net.automatalib.common.util.collection.CollectionUtil; import net.automatalib.graph.Graph; import net.automatalib.graph.UniversalGraph; -import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; -import net.automatalib.semantics.DeterministicFiniteSemantics.PlainSemantics; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; -import net.automatalib.semantics.FiniteSemantics; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.util.automaton.equivalence.CharacterizingSets; import net.automatalib.util.automaton.equivalence.DeterministicEquivalenceTest; @@ -85,8 +83,8 @@ public static Graph> asGraph(Automaton & FiniteSemantics> A minimize( - UniversalSemantics automaton, + public static > A minimize( + UniversalDeterministicAutomaton.FiniteSemantics automaton, Collection inputs, A output) { @@ -154,8 +152,9 @@ public static Graph> asGraph(Automaton> A invasiveMinimize(A automaton, - Collection inputs) { + public static > A invasiveMinimize( + A automaton, + Collection inputs) { final List inputList = CollectionUtil.randomAccessList(inputs); @@ -233,8 +232,8 @@ public static > A i /** * Tests whether two automata are equivalent, i.e. whether there exists a - * {@link #findSeparatingWord(UniversalSemantics, UniversalSemantics, Collection) separating word} for the two given - * automata. + * {@link #findSeparatingWord(UniversalDeterministicAutomaton.FiniteSemantics, + * UniversalDeterministicAutomaton.FiniteSemantics, Collection) separating word} for the two given automata. * * @param * input symbol type @@ -247,10 +246,11 @@ public static > A i * * @return {@code true} if the automata are equivalent, {@code false} otherwise. * - * @see #findSeparatingWord(UniversalSemantics, UniversalSemantics, Collection) + * @see #findSeparatingWord(UniversalDeterministicAutomaton.FiniteSemantics, + * UniversalDeterministicAutomaton.FiniteSemantics, Collection) */ - public static boolean testEquivalence(UniversalSemantics reference, - UniversalSemantics other, + public static boolean testEquivalence(UniversalDeterministicAutomaton.FiniteSemantics reference, + UniversalDeterministicAutomaton.FiniteSemantics other, Collection inputs) { return findSeparatingWord(reference, other, inputs) == null; } @@ -270,8 +270,8 @@ public static boolean testEquivalence(UniversalSemantics refe * * @return a separating word, or {@code null} if no such word could be found. */ - public static @Nullable Word findSeparatingWord(UniversalSemantics reference, - UniversalSemantics other, + public static @Nullable Word findSeparatingWord(UniversalDeterministicAutomaton.FiniteSemantics reference, + UniversalDeterministicAutomaton.FiniteSemantics other, Collection inputs) { return NearLinearEquivalenceTest.findSeparatingWord(reference, other, inputs); } @@ -296,7 +296,7 @@ public static boolean testEquivalence(UniversalSemantics refe * * @return a separating word, or {@code null} if no such word could be found */ - public static @Nullable Word findSeparatingWord(UniversalSemantics automaton, + public static @Nullable Word findSeparatingWord(UniversalDeterministicAutomaton.FiniteSemantics automaton, S state1, S state2, Collection inputs) { @@ -319,8 +319,8 @@ public static boolean testEquivalence(UniversalSemantics refe * * @return a separating word, or {@code null} if no such word could be found. */ - public static @Nullable Word findShortestSeparatingWord(UniversalSemantics reference, - UniversalSemantics other, + public static @Nullable Word findShortestSeparatingWord(UniversalDeterministicAutomaton.FiniteSemantics reference, + UniversalDeterministicAutomaton.FiniteSemantics other, Collection inputs) { return DeterministicEquivalenceTest.findSeparatingWord(reference, other, inputs); } @@ -339,7 +339,7 @@ public static boolean testEquivalence(UniversalSemantics refe * * @see CharacterizingSets */ - public static List> characterizingSet(UniversalSemantics automaton, + public static List> characterizingSet(UniversalDeterministicAutomaton.FiniteSemantics automaton, Collection inputs) { List> result = new ArrayList<>(); characterizingSet(automaton, inputs, result); @@ -350,7 +350,8 @@ public static List> characterizingSet(UniversalSemantics * This is a convenience method acting as a shortcut to - * {@link CharacterizingSets#findCharacterizingSet(UniversalSemantics, Collection, Collection)}. + * {@link CharacterizingSets#findCharacterizingSet(UniversalDeterministicAutomaton.FiniteSemantics, Collection, + * Collection)}. * * @param * input symbol type @@ -363,13 +364,13 @@ public static List> characterizingSet(UniversalSemantics void characterizingSet(UniversalSemantics automaton, + public static void characterizingSet(UniversalDeterministicAutomaton.FiniteSemantics automaton, Collection inputs, Collection> result) { CharacterizingSets.findCharacterizingSet(automaton, inputs, result); } - public static boolean incrementalCharacterizingSet(UniversalSemantics automaton, + public static boolean incrementalCharacterizingSet(UniversalDeterministicAutomaton.FiniteSemantics automaton, Collection inputs, Collection> oldSuffixes, Collection> newSuffixes) { @@ -394,7 +395,7 @@ public static boolean incrementalCharacterizingSet(UniversalSemantics List> stateCharacterizingSet(UniversalSemantics automaton, + public static List> stateCharacterizingSet(UniversalDeterministicAutomaton.FiniteSemantics automaton, Collection inputs, S state) { List> result = new ArrayList<>(); @@ -406,7 +407,8 @@ public static List> stateCharacterizingSet(UniversalSemantics * This is a convenience method acting as a shortcut to - * {@link CharacterizingSets#findCharacterizingSet(UniversalSemantics, Collection, Object, Collection)}. + * {@link CharacterizingSets#findCharacterizingSet(UniversalDeterministicAutomaton.FiniteSemantics, Collection, + * Object, Collection)}. * * @param * state type @@ -423,7 +425,7 @@ public static List> stateCharacterizingSet(UniversalSemantics void stateCharacterizingSet(UniversalSemantics automaton, + public static void stateCharacterizingSet(UniversalDeterministicAutomaton.FiniteSemantics automaton, Collection inputs, S state, Collection> result) { @@ -442,9 +444,10 @@ public static void stateCharacterizingSet(UniversalSemantics List> stateCover(PlainSemantics automaton, Collection inputs) { + public static List> stateCover(DeterministicAutomaton.FiniteSemantics automaton, + Collection inputs) { final List> result = new ArrayList<>(automaton.size()); Covers.stateCover(automaton, inputs, result); return result; @@ -462,9 +465,10 @@ public static List> stateCover(PlainSemantics automaton, Co * * @return the transition cover for the given automaton * - * @see Covers#transitionCover(PlainSemantics, Collection, Collection) + * @see Covers#transitionCover(DeterministicAutomaton.FiniteSemantics, Collection, Collection) */ - public static List> transitionCover(PlainSemantics automaton, Collection inputs) { + public static List> transitionCover(DeterministicAutomaton.FiniteSemantics automaton, + Collection inputs) { final List> result = new ArrayList<>(automaton.size() * inputs.size()); Covers.transitionCover(automaton, inputs, result); return result; @@ -482,9 +486,10 @@ public static List> transitionCover(PlainSemantics automato * * @return the structural cover for the given automaton * - * @see Covers#structuralCover(PlainSemantics, Collection, Collection) + * @see Covers#structuralCover(DeterministicAutomaton.FiniteSemantics, Collection, Collection) */ - public static List> structuralCover(PlainSemantics automaton, Collection inputs) { + public static List> structuralCover(DeterministicAutomaton.FiniteSemantics automaton, + Collection inputs) { final List> result = new ArrayList<>(automaton.size() * (inputs.size() + 1)); Covers.structuralCover(automaton, inputs, result); return result; diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/IncrementalWMethodTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/IncrementalWMethodTestsIterator.java index 10dd63139..a4b0fc805 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/IncrementalWMethodTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/IncrementalWMethodTestsIterator.java @@ -21,7 +21,7 @@ import java.util.List; import net.automatalib.alphabet.Alphabet; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; +import net.automatalib.automaton.UniversalDeterministicAutomaton.FiniteSemantics; import net.automatalib.util.automaton.Automata; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.word.Word; @@ -55,7 +55,7 @@ public void setMaxDepth(int maxDepth) { this.maxDepth = maxDepth; } - public void update(UniversalSemantics automaton) { + public void update(FiniteSemantics automaton) { int oldNumPrefixes = prefixes.size(); boolean newPrefixes = Covers.incrementalTransitionCover(automaton, alphabet, prefixes, prefixes); diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/KWayStateCoverTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/KWayStateCoverTestsIterator.java index 9ba19da24..4aecbf4c3 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/KWayStateCoverTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/KWayStateCoverTestsIterator.java @@ -27,6 +27,7 @@ import java.util.Set; import java.util.stream.Stream; +import net.automatalib.automaton.DeterministicAutomaton.FiniteSemantics; import net.automatalib.common.util.HashUtil; import net.automatalib.common.util.collection.AbstractSimplifiedIterator; import net.automatalib.common.util.collection.CollectionUtil; @@ -34,7 +35,6 @@ import net.automatalib.common.util.mapping.Mapping; import net.automatalib.common.util.mapping.Mappings; import net.automatalib.common.util.random.RandomUtil; -import net.automatalib.semantics.DeterministicFiniteSemantics.PlainSemantics; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.word.Word; import net.automatalib.word.WordBuilder; @@ -70,7 +70,7 @@ public class KWayStateCoverTestsIterator extends AbstractSimplifiedIterato */ public static final int DEFAULT_R_WALK_LEN = 20; - private final PlainSemantics automaton; + private final FiniteSemantics automaton; private final List alphabet; private final Random random; private final int randomWalkLen; @@ -88,9 +88,9 @@ public class KWayStateCoverTestsIterator extends AbstractSimplifiedIterato * @param inputs * the inputs to consider for test case generation * - * @see #KWayStateCoverTestsIterator(PlainSemantics, Collection, Random) + * @see #KWayStateCoverTestsIterator(FiniteSemantics, Collection, Random) */ - public KWayStateCoverTestsIterator(PlainSemantics automaton, Collection inputs) { + public KWayStateCoverTestsIterator(FiniteSemantics automaton, Collection inputs) { this(automaton, inputs, new Random()); } @@ -106,9 +106,9 @@ public KWayStateCoverTestsIterator(PlainSemantics automaton, Collection * @param random * the random number generator to use * - * @see #KWayStateCoverTestsIterator(PlainSemantics, Collection, Random, int, int, CombinationMethod) + * @see #KWayStateCoverTestsIterator(FiniteSemantics, Collection, Random, int, int, CombinationMethod) */ - public KWayStateCoverTestsIterator(PlainSemantics automaton, + public KWayStateCoverTestsIterator(FiniteSemantics automaton, Collection inputs, Random random) { this(automaton, inputs, random, DEFAULT_R_WALK_LEN, DEFAULT_K, CombinationMethod.PERMUTATIONS); @@ -130,7 +130,7 @@ public KWayStateCoverTestsIterator(PlainSemantics automaton, * @param method * the method for computing combinations */ - public KWayStateCoverTestsIterator(PlainSemantics automaton, + public KWayStateCoverTestsIterator(FiniteSemantics automaton, Collection inputs, Random random, int randomWalkLen, diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/KWayTransitionCoverTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/KWayTransitionCoverTestsIterator.java index dd3d9a763..3d2e68836 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/KWayTransitionCoverTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/KWayTransitionCoverTestsIterator.java @@ -27,6 +27,7 @@ import java.util.Set; import java.util.stream.Stream; +import net.automatalib.automaton.DeterministicAutomaton.FiniteSemantics; import net.automatalib.common.util.HashUtil; import net.automatalib.common.util.collection.AbstractSimplifiedIterator; import net.automatalib.common.util.collection.AbstractTwoLevelIterator; @@ -35,7 +36,6 @@ import net.automatalib.common.util.collection.IteratorUtil; import net.automatalib.common.util.mapping.Mapping; import net.automatalib.common.util.random.RandomUtil; -import net.automatalib.semantics.DeterministicFiniteSemantics.PlainSemantics; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.word.Word; import net.automatalib.word.WordBuilder; @@ -87,7 +87,7 @@ public class KWayTransitionCoverTestsIterator implements Iterator> */ public static final int DEFAULT_R_WALK_LEN = 10; - private final PlainSemantics automaton; + private final FiniteSemantics automaton; private final List alphabet; private final Random random; private final int randomWalkLen; @@ -107,9 +107,9 @@ public class KWayTransitionCoverTestsIterator implements Iterator> * @param inputs * the inputs to consider for test case generation * - * @see #KWayTransitionCoverTestsIterator(PlainSemantics, Collection, Random) + * @see #KWayTransitionCoverTestsIterator(FiniteSemantics, Collection, Random) */ - public KWayTransitionCoverTestsIterator(PlainSemantics automaton, Collection inputs) { + public KWayTransitionCoverTestsIterator(FiniteSemantics automaton, Collection inputs) { this(automaton, inputs, new Random()); } @@ -127,10 +127,10 @@ public KWayTransitionCoverTestsIterator(PlainSemantics automaton, Colle * @param random * the random number generator to use * - * @see #KWayTransitionCoverTestsIterator(PlainSemantics, Collection, Random, int, int, int, int, int, + * @see #KWayTransitionCoverTestsIterator(FiniteSemantics, Collection, Random, int, int, int, int, int, * OptimizationMetric, GenerationMethod) */ - public KWayTransitionCoverTestsIterator(PlainSemantics automaton, + public KWayTransitionCoverTestsIterator(FiniteSemantics automaton, Collection inputs, Random random) { this(automaton, @@ -171,7 +171,7 @@ public KWayTransitionCoverTestsIterator(PlainSemantics automaton, * @param generationMethod * defines how the tests are generated */ - public KWayTransitionCoverTestsIterator(PlainSemantics automaton, + public KWayTransitionCoverTestsIterator(FiniteSemantics automaton, Collection inputs, Random random, int randomWalkLen, @@ -212,7 +212,7 @@ public Word next() { return iterator.next(); } - private Set> generateRandomPaths(PlainSemantics hypothesis, S initial) { + private Set> generateRandomPaths(FiniteSemantics hypothesis, S initial) { final Set> result = new HashSet<>(HashUtil.capacity(numGeneratePaths)); for (int i = 0; i < numGeneratePaths; i++) { @@ -225,7 +225,7 @@ private Set> generateRandomPaths(PlainSemantics hypothesis, return result; } - private Path createPath(PlainSemantics hypothesis, S initial, Word steps) { + private Path createPath(FiniteSemantics hypothesis, S initial, Word steps) { final Set> transitions = new HashSet<>(); final List<@Nullable S> prevStates = new ArrayList<>(steps.size()); @@ -252,7 +252,7 @@ private Path createPath(PlainSemantics hypothesis, S initial, Wor return new Path<>(steps, transitions); } - private Iterator> generatePrefixSteps(PlainSemantics hypothesis, S initial) { + private Iterator> generatePrefixSteps(FiniteSemantics hypothesis, S initial) { final List states = new ArrayList<>(hypothesis.getStates()); Collections.reverse(states); return new PrefixStepsIterator(states.iterator(), initial); diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/ProceduralWMethodTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/ProceduralWMethodTestsIterator.java index 6aa808afd..f78f1fffa 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/ProceduralWMethodTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/ProceduralWMethodTestsIterator.java @@ -23,12 +23,12 @@ import java.util.Map; import net.automatalib.alphabet.ProceduralInputAlphabet; +import net.automatalib.automaton.UniversalDeterministicAutomaton.FiniteSemantics; import net.automatalib.common.util.collection.AbstractThreeLevelIterator; import net.automatalib.common.util.collection.AbstractTwoLevelIterator; import net.automatalib.common.util.collection.IterableUtil; import net.automatalib.common.util.collection.IteratorUtil; import net.automatalib.common.util.collection.ReusableIterator; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.util.automaton.equivalence.CharacterizingSets; import net.automatalib.util.automaton.procedural.ATSequences; @@ -36,7 +36,7 @@ import net.automatalib.word.WordBuilder; import org.checkerframework.checker.nullness.qual.NonNull; -class ProceduralWMethodTestsIterator> +class ProceduralWMethodTestsIterator> extends AbstractTwoLevelIterator, Word> { private static final List>> EPSILON = diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/WMethodTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/WMethodTestsIterator.java index 9f1cd0a7a..17f15e430 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/WMethodTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/WMethodTestsIterator.java @@ -20,11 +20,11 @@ import java.util.Iterator; import java.util.List; +import net.automatalib.automaton.UniversalDeterministicAutomaton.FiniteSemantics; import net.automatalib.common.util.collection.AbstractThreeLevelIterator; import net.automatalib.common.util.collection.IterableUtil; import net.automatalib.common.util.collection.IteratorUtil; import net.automatalib.common.util.collection.ReusableIterator; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.util.automaton.equivalence.CharacterizingSets; import net.automatalib.word.Word; @@ -47,7 +47,7 @@ public class WMethodTestsIterator extends AbstractThreeLevelIterator, private final Iterable> suffixes; /** - * Convenience-constructor for {@link #WMethodTestsIterator(UniversalSemantics, Collection, int)} that selects + * Convenience-constructor for {@link #WMethodTestsIterator(FiniteSemantics, Collection, int)} that selects * {@code 0} as {@code maxDepth}. * * @param automaton @@ -55,7 +55,7 @@ public class WMethodTestsIterator extends AbstractThreeLevelIterator, * @param inputs * the input symbols that should be considered for test sequence generation */ - public WMethodTestsIterator(UniversalSemantics automaton, Collection inputs) { + public WMethodTestsIterator(FiniteSemantics automaton, Collection inputs) { this(automaton, inputs, 0); } @@ -69,7 +69,7 @@ public WMethodTestsIterator(UniversalSemantics automaton, Collect * @param maxDepth * the maximum number of symbols that are appended to the transition-cover part of the test sequences */ - public WMethodTestsIterator(UniversalSemantics automaton, + public WMethodTestsIterator(FiniteSemantics automaton, Collection inputs, int maxDepth) { super(IteratorUtil.concat(IteratorUtil.singleton(Word.epsilon()), diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/WpMethodTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/WpMethodTestsIterator.java index 55b444a62..644baa9c0 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/WpMethodTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/WpMethodTestsIterator.java @@ -22,12 +22,12 @@ import java.util.List; import java.util.Set; +import net.automatalib.automaton.UniversalDeterministicAutomaton.FiniteSemantics; import net.automatalib.common.util.HashUtil; import net.automatalib.common.util.collection.AbstractThreeLevelIterator; import net.automatalib.common.util.collection.IterableUtil; import net.automatalib.common.util.collection.IteratorUtil; import net.automatalib.common.util.mapping.MutableMapping; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.Automata; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.util.automaton.equivalence.CharacterizingSets; @@ -49,7 +49,7 @@ public class WpMethodTestsIterator implements Iterator> { private final Iterator> wpIterator; /** - * Convenience-constructor for {@link #WpMethodTestsIterator(UniversalSemantics, Collection, int)} that selects + * Convenience-constructor for {@link #WpMethodTestsIterator(FiniteSemantics, Collection, int)} that selects * {@code 0} as {@code maxDepth}. * * @param automaton @@ -57,7 +57,7 @@ public class WpMethodTestsIterator implements Iterator> { * @param inputs * the input symbols that should be considered for test sequence generation */ - public WpMethodTestsIterator(UniversalSemantics automaton, Collection inputs) { + public WpMethodTestsIterator(FiniteSemantics automaton, Collection inputs) { this(automaton, inputs, 0); } @@ -71,7 +71,7 @@ public WpMethodTestsIterator(UniversalSemantics automaton, Collec * @param maxDepth * the maximum number of symbols that are appended to the transition-cover part of the test sequences */ - public WpMethodTestsIterator(UniversalSemantics automaton, + public WpMethodTestsIterator(FiniteSemantics automaton, Collection inputs, int maxDepth) { @@ -144,13 +144,13 @@ protected Word combine(Word suffix, List middle, Word prefix) { private static class SecondPhaseIterator extends AbstractThreeLevelIterator, List, Word, Word> { - private final UniversalSemantics automaton; + private final FiniteSemantics automaton; private final Collection inputs; private final MutableMapping>> localSuffixSets; private final Iterable> middleParts; - SecondPhaseIterator(UniversalSemantics automaton, + SecondPhaseIterator(FiniteSemantics automaton, Collection inputs, Iterable> prefixes, Iterable> middleParts) { diff --git a/util/src/main/java/net/automatalib/util/automaton/cover/Covers.java b/util/src/main/java/net/automatalib/util/automaton/cover/Covers.java index 99f69b70e..28c43d81c 100644 --- a/util/src/main/java/net/automatalib/util/automaton/cover/Covers.java +++ b/util/src/main/java/net/automatalib/util/automaton/cover/Covers.java @@ -24,10 +24,10 @@ import java.util.function.BiFunction; import java.util.function.Consumer; +import net.automatalib.automaton.DeterministicAutomaton.FiniteSemantics; import net.automatalib.common.util.HashUtil; import net.automatalib.common.util.mapping.Mapping; import net.automatalib.common.util.mapping.MutableMapping; -import net.automatalib.semantics.DeterministicFiniteSemantics.PlainSemantics; import net.automatalib.word.Word; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -56,7 +56,7 @@ private Covers() {} * @param * input symbol type */ - public static void stateCover(PlainSemantics automaton, + public static void stateCover(FiniteSemantics automaton, Collection inputs, Collection> states) { cover(automaton, inputs, automaton.getInitialState(), states::add, w -> {}); @@ -75,9 +75,9 @@ public static void stateCover(PlainSemantics automaton, * * @return an iterator for the input sequences of the cover. * - * @see #stateCover(PlainSemantics, Collection, Collection) + * @see #stateCover(FiniteSemantics, Collection, Collection) */ - public static Iterator> stateCoverIterator(PlainSemantics automaton, + public static Iterator> stateCoverIterator(FiniteSemantics automaton, Collection inputs) { return new IncrementalStateCoverIterator<>(automaton, inputs, Collections.emptyList()); } @@ -103,7 +103,7 @@ public static Iterator> stateCoverIterator(PlainSemantics a * @param * input symbol type */ - public static void transitionCover(PlainSemantics automaton, + public static void transitionCover(FiniteSemantics automaton, Collection inputs, Collection> transitions) { cover(automaton, inputs, automaton.getInitialState(), w -> {}, transitions::add); @@ -122,9 +122,9 @@ public static void transitionCover(PlainSemantics automaton, * * @return an iterator for the input sequences of the cover. * - * @see #transitionCover(PlainSemantics, Collection, Collection) + * @see #transitionCover(FiniteSemantics, Collection, Collection) */ - public static Iterator> transitionCoverIterator(PlainSemantics automaton, + public static Iterator> transitionCoverIterator(FiniteSemantics automaton, Collection inputs) { return new IncrementalTransitionCoverIterator<>(automaton, inputs, Collections.emptyList()); } @@ -145,10 +145,10 @@ public static Iterator> transitionCoverIterator(PlainSemantics * input symbol type * - * @see #stateCover(PlainSemantics, Collection, Collection) - * @see #transitionCover(PlainSemantics, Collection, Collection) + * @see #stateCover(FiniteSemantics, Collection, Collection) + * @see #transitionCover(FiniteSemantics, Collection, Collection) */ - public static void structuralCover(PlainSemantics automaton, + public static void structuralCover(FiniteSemantics automaton, Collection inputs, Collection> cover) { cover(automaton, inputs, automaton.getInitialState(), cover::add, cover::add); @@ -170,10 +170,10 @@ public static void structuralCover(PlainSemantics automaton, * @param * input symbol type * - * @see #stateCover(PlainSemantics, Collection, Collection) - * @see #transitionCover(PlainSemantics, Collection, Collection) + * @see #stateCover(FiniteSemantics, Collection, Collection) + * @see #transitionCover(FiniteSemantics, Collection, Collection) */ - public static void cover(PlainSemantics automaton, + public static void cover(FiniteSemantics automaton, Collection inputs, Collection> states, Collection> transitions) { @@ -210,7 +210,7 @@ public static void cover(PlainSemantics automaton, * * @return a mapping from automaton states to their access sequences */ - public static Mapping> cover(PlainSemantics automaton, + public static Mapping> cover(FiniteSemantics automaton, Collection inputs, @Nullable S start, Consumer> states, @@ -233,7 +233,8 @@ public static void cover(PlainSemantics automaton, while ((curr = bfsQueue.poll()) != null) { @SuppressWarnings("nullness") // in a breadth-first traversal the predecessors are always defined - @NonNull Word as = reach.get(curr); + @NonNull + Word as = reach.get(curr); for (I in : inputs) { S succ = automaton.getSuccessor(curr, in); @@ -274,9 +275,9 @@ public static void cover(PlainSemantics automaton, * * @return {@code true} if new sequences have been added to the state cover, {@code false} otherwise. * - * @see #stateCover(PlainSemantics, Collection, Collection) + * @see #stateCover(FiniteSemantics, Collection, Collection) */ - public static boolean incrementalStateCover(PlainSemantics automaton, + public static boolean incrementalStateCover(FiniteSemantics automaton, Collection inputs, Collection> oldStates, Collection> newStates) { @@ -343,9 +344,9 @@ public static boolean incrementalStateCover(PlainSemantics autom * * @return an iterator for the remaining input sequences of the cover. * - * @see #incrementalStateCover(PlainSemantics, Collection, Collection, Collection) + * @see #incrementalStateCover(FiniteSemantics, Collection, Collection, Collection) */ - public static Iterator> incrementalStateCoverIterator(PlainSemantics automaton, + public static Iterator> incrementalStateCoverIterator(FiniteSemantics automaton, Collection inputs, Collection> stateCover) { return new IncrementalStateCoverIterator<>(automaton, inputs, stateCover); @@ -368,12 +369,12 @@ public static Iterator> incrementalStateCoverIterator(PlainSemantics * * @return {@code true} if new sequences have been added to the state cover, {@code false} otherwise. * - * @see #transitionCover(PlainSemantics, Collection, Collection) + * @see #transitionCover(FiniteSemantics, Collection, Collection) */ - public static boolean incrementalTransitionCover(PlainSemantics automaton, + public static boolean incrementalTransitionCover(FiniteSemantics automaton, Collection inputs, Collection> oldTransCover, - Collection> newTransCover) { + Collection> newTransCover) { final int oldTransSize = newTransCover.size(); incrementalCover(automaton, inputs, Collections.emptySet(), oldTransCover, w -> {}, newTransCover::add); @@ -396,9 +397,9 @@ public static boolean incrementalTransitionCover(PlainSemantics aut * * @return an iterator for the remaining input sequences of the cover. * - * @see #incrementalStateCover(PlainSemantics, Collection, Collection, Collection) + * @see #incrementalStateCover(FiniteSemantics, Collection, Collection, Collection) */ - public static Iterator> incrementalTransitionCoverIterator(PlainSemantics automaton, + public static Iterator> incrementalTransitionCoverIterator(FiniteSemantics automaton, Collection inputs, Collection> transitionCover) { return new IncrementalTransitionCoverIterator<>(automaton, inputs, transitionCover); @@ -424,10 +425,10 @@ public static Iterator> incrementalTransitionCoverIterator(PlainSema * * @return {@code true} if new sequences have been added to the structural cover, {@code false} otherwise. * - * @see #incrementalStateCover(PlainSemantics, Collection, Collection, Collection) - * @see #incrementalStateCover(PlainSemantics, Collection, Collection, Collection) + * @see #incrementalStateCover(FiniteSemantics, Collection, Collection, Collection) + * @see #incrementalStateCover(FiniteSemantics, Collection, Collection, Collection) */ - public static boolean incrementalCover(PlainSemantics automaton, + public static boolean incrementalCover(FiniteSemantics automaton, Collection inputs, Collection> oldStateCover, Collection> oldTransCover, @@ -441,7 +442,7 @@ public static boolean incrementalCover(PlainSemantics automaton, return oldStateSize < newStateCover.size() || oldTransSize < newTransCover.size(); } - private static void incrementalCover(PlainSemantics automaton, + private static void incrementalCover(FiniteSemantics automaton, Collection inputs, Collection> oldStateCover, Collection> oldTransCover, @@ -508,7 +509,7 @@ private static void incrementalCover(PlainSemantics automaton, static boolean buildReachFromStateCover(MutableMapping> reach, Queue> bfsQueue, - PlainSemantics automaton, + FiniteSemantics automaton, Collection> oldStateCover, BiFunction, Record> recordBuilder) { @@ -533,7 +534,7 @@ static boolean buildReachFromStateCover(MutableMapping> r static void buildReachFromTransitionCover(MutableMapping> reach, Queue> bfsQueue, - PlainSemantics automaton, + FiniteSemantics automaton, Collection> oldTransCover, BiFunction, Record> recordBuilder, Consumer> newStateCallback) { diff --git a/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalStateCoverIterator.java b/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalStateCoverIterator.java index 2d5c6cbd2..f75408b3b 100644 --- a/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalStateCoverIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalStateCoverIterator.java @@ -20,9 +20,9 @@ import java.util.Iterator; import java.util.Queue; +import net.automatalib.automaton.DeterministicAutomaton.FiniteSemantics; import net.automatalib.common.util.collection.AbstractSimplifiedIterator; import net.automatalib.common.util.mapping.MutableMapping; -import net.automatalib.semantics.DeterministicFiniteSemantics.PlainSemantics; import net.automatalib.word.Word; import org.checkerframework.checker.nullness.qual.Nullable; @@ -38,11 +38,11 @@ * @param * input symbol type * - * @see Covers#stateCover(PlainSemantics, Collection, Collection) + * @see Covers#stateCover(FiniteSemantics, Collection, Collection) */ class IncrementalStateCoverIterator extends AbstractSimplifiedIterator> { - private final PlainSemantics automaton; + private final FiniteSemantics automaton; private final Collection inputs; private final Collection> oldCover; @@ -52,7 +52,7 @@ class IncrementalStateCoverIterator extends AbstractSimplifiedIterator inputIterator; private @Nullable Record curr; - IncrementalStateCoverIterator(PlainSemantics automaton, + IncrementalStateCoverIterator(FiniteSemantics automaton, Collection inputs, Collection> oldCover) { this.automaton = automaton; diff --git a/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalTransitionCoverIterator.java b/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalTransitionCoverIterator.java index 2b0ce6b2b..67365fe61 100644 --- a/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalTransitionCoverIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalTransitionCoverIterator.java @@ -21,10 +21,10 @@ import java.util.Iterator; import java.util.Queue; +import net.automatalib.automaton.DeterministicAutomaton.FiniteSemantics; import net.automatalib.common.util.HashUtil; import net.automatalib.common.util.collection.AbstractSimplifiedIterator; import net.automatalib.common.util.mapping.MutableMapping; -import net.automatalib.semantics.DeterministicFiniteSemantics.PlainSemantics; import net.automatalib.word.Word; /** @@ -39,11 +39,11 @@ * @param * input symbol type * - * @see Covers#transitionCover(PlainSemantics, Collection, Collection) + * @see Covers#transitionCover(FiniteSemantics, Collection, Collection) */ class IncrementalTransitionCoverIterator extends AbstractSimplifiedIterator> { - private final PlainSemantics automaton; + private final FiniteSemantics automaton; private final Collection inputs; private final Collection> oldCover; @@ -53,7 +53,7 @@ class IncrementalTransitionCoverIterator extends AbstractSimplifiedIterato private Iterator inputIterator; private Record curr; - IncrementalTransitionCoverIterator(PlainSemantics automaton, + IncrementalTransitionCoverIterator(FiniteSemantics automaton, Collection inputs, Collection> oldCover) { this.automaton = automaton; diff --git a/util/src/main/java/net/automatalib/util/automaton/equivalence/Bisimulation.java b/util/src/main/java/net/automatalib/util/automaton/equivalence/Bisimulation.java index 713547b18..3f21e0b1d 100644 --- a/util/src/main/java/net/automatalib/util/automaton/equivalence/Bisimulation.java +++ b/util/src/main/java/net/automatalib/util/automaton/equivalence/Bisimulation.java @@ -20,10 +20,10 @@ import java.util.List; import java.util.Set; +import net.automatalib.automaton.Automaton.FiniteSemantics; import net.automatalib.automaton.concept.StateIDs; import net.automatalib.common.util.Pair; import net.automatalib.common.util.collection.CollectionUtil; -import net.automatalib.semantics.FiniteSemantics.PlainSemantics; import net.automatalib.util.partitionrefinement.Valmari; import net.automatalib.util.partitionrefinement.Valmari.RefinablePartition; @@ -33,8 +33,8 @@ private Bisimulation() { // prevent instantiation } - public static Set> bisimulationEquivalenceRelation(PlainSemantics a, - PlainSemantics b, + public static Set> bisimulationEquivalenceRelation(FiniteSemantics a, + FiniteSemantics b, Collection inputs) { final List alphabet = CollectionUtil.randomAccessList(inputs); final StateIDs aIDs = a.stateIDs(); diff --git a/util/src/main/java/net/automatalib/util/automaton/equivalence/CharacterizingSets.java b/util/src/main/java/net/automatalib/util/automaton/equivalence/CharacterizingSets.java index e81c94e6e..20d18b117 100644 --- a/util/src/main/java/net/automatalib/util/automaton/equivalence/CharacterizingSets.java +++ b/util/src/main/java/net/automatalib/util/automaton/equivalence/CharacterizingSets.java @@ -26,11 +26,10 @@ import java.util.Objects; import java.util.Queue; -import net.automatalib.automaton.UniversalDeterministicAutomaton; +import net.automatalib.automaton.UniversalDeterministicAutomaton.FiniteSemantics; import net.automatalib.automaton.fsa.FiniteStateAcceptor; import net.automatalib.common.util.collection.AbstractSimplifiedIterator; import net.automatalib.common.util.collection.CollectionUtil; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.Automata; import net.automatalib.word.Word; import org.checkerframework.checker.nullness.qual.NonNull; @@ -65,7 +64,7 @@ private CharacterizingSets() {} * @param * input symbol type */ - public static void findCharacterizingSet(UniversalSemantics automaton, + public static void findCharacterizingSet(FiniteSemantics automaton, Collection inputs, Collection> result) { findIncrementalCharacterizingSet(automaton, inputs, Collections.emptyList(), result); @@ -87,7 +86,7 @@ public static void findCharacterizingSet(UniversalSemantics a * @param * input symbol type */ - public static void findCharacterizingSet(UniversalSemantics automaton, + public static void findCharacterizingSet(FiniteSemantics automaton, Collection inputs, S state, Collection> result) { @@ -144,12 +143,12 @@ public static void findCharacterizingSet(UniversalSemantics Iterator> characterizingSetIterator(UniversalSemantics automaton, + public static Iterator> characterizingSetIterator(FiniteSemantics automaton, Collection inputs) { return new IncrementalCharacterizingSetIterator<>(automaton, inputs, Collections.emptyList()); } - private static List buildTrace(UniversalDeterministicAutomaton automaton, + private static List buildTrace(FiniteSemantics automaton, S state, Word suffix) { if (suffix.isEmpty()) { @@ -183,7 +182,7 @@ private static List buildTrace(UniversalDeterministicAutoma return trace; } - private static boolean checkTrace(UniversalDeterministicAutomaton automaton, + private static boolean checkTrace(FiniteSemantics automaton, S state, Word suffix, List

trace) { @@ -217,7 +216,7 @@ private static boolean checkTrace(UniversalDeterministicAut return true; } - public static boolean findIncrementalCharacterizingSet(UniversalSemantics automaton, + public static boolean findIncrementalCharacterizingSet(FiniteSemantics automaton, Collection inputs, Collection> oldSuffixes, Collection> newSuffixes) { @@ -244,13 +243,13 @@ public static boolean findIncrementalCharacterizingSet(UniversalSemantics return refined; } - public static Iterator> incrementalCharacterizingSetIterator(UniversalSemantics automaton, + public static Iterator> incrementalCharacterizingSetIterator(FiniteSemantics automaton, Collection inputs, Collection> oldSuffixes) { return new IncrementalCharacterizingSetIterator<>(automaton, inputs, oldSuffixes); } - private static Queue> buildInitialBlocks(UniversalSemantics automaton, + private static Queue> buildInitialBlocks(FiniteSemantics automaton, List> oldSuffixes) { Map>, List> initialPartitioning = new HashMap<>(); Queue> blocks = new ArrayDeque<>(); @@ -268,7 +267,7 @@ private static Queue> buildInitialBlocks(UniversalSemantics List> buildSignature(UniversalDeterministicAutomaton automaton, + private static List> buildSignature(FiniteSemantics automaton, List> suffixes, S state) { List> signature = new ArrayList<>(suffixes.size()); @@ -281,8 +280,7 @@ private static List> buildSignature(UniversalDeterministicAutomat return signature; } - private static boolean epsilonRefine(UniversalDeterministicAutomaton automaton, - Queue> blockQueue) { + private static boolean epsilonRefine(FiniteSemantics automaton, Queue> blockQueue) { int initialSize = blockQueue.size(); @@ -304,7 +302,7 @@ private static boolean epsilonRefine(UniversalDeterministicAutomaton @Nullable Word refine(UniversalSemantics automaton, + private static @Nullable Word refine(FiniteSemantics automaton, Collection inputs, Queue> blockQueue) { @@ -358,7 +356,7 @@ private static boolean epsilonRefine(UniversalDeterministicAutomaton Map> clusterByProperty(UniversalDeterministicAutomaton automaton, + private static Map> clusterByProperty(FiniteSemantics automaton, List states) { Map> result = new HashMap<>(); @@ -371,7 +369,7 @@ private static Map> clusterByProperty(UniversalDeterminist return result; } - private static void cluster(UniversalDeterministicAutomaton automaton, + private static void cluster(FiniteSemantics automaton, Word suffix, Iterator stateIt, Map, List> bucketMap) { @@ -386,12 +384,12 @@ private static void cluster(UniversalDeterministicAutomaton extends AbstractSimplifiedIterator> { - private final UniversalSemantics automaton; + private final FiniteSemantics automaton; private final Collection inputs; private final List> oldSuffixes; private Queue> blocks; - IncrementalCharacterizingSetIterator(UniversalSemantics automaton, + IncrementalCharacterizingSetIterator(FiniteSemantics automaton, Collection inputs, Collection> oldSuffixes) { this.automaton = automaton; diff --git a/util/src/main/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTest.java b/util/src/main/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTest.java index 080b11c77..a974c70d4 100644 --- a/util/src/main/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTest.java +++ b/util/src/main/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTest.java @@ -22,8 +22,8 @@ import java.util.Objects; import java.util.Queue; +import net.automatalib.automaton.UniversalDeterministicAutomaton.FiniteSemantics; import net.automatalib.automaton.concept.StateIDs; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.word.Word; import net.automatalib.word.WordBuilder; import org.checkerframework.checker.nullness.qual.NonNull; @@ -39,8 +39,8 @@ private DeterministicEquivalenceTest() { } @SuppressWarnings("PMD.UnnecessaryCast") // we want to cast to long, to prevent overflows - public static @Nullable Word findSeparatingWord(UniversalSemantics reference, - UniversalSemantics other, + public static @Nullable Word findSeparatingWord(FiniteSemantics reference, + FiniteSemantics other, Collection inputs) { int refSize = reference.size(); int otherSize = other.size(); diff --git a/util/src/main/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTest.java b/util/src/main/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTest.java index a27f7917a..1515906a3 100644 --- a/util/src/main/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTest.java +++ b/util/src/main/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTest.java @@ -21,12 +21,12 @@ import java.util.Queue; import net.automatalib.alphabet.Alphabet; +import net.automatalib.automaton.UniversalDeterministicAutomaton.FiniteSemantics; import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.FullIntAbstraction; import net.automatalib.automaton.concept.InputAlphabetHolder; import net.automatalib.automaton.concept.StateIDs; import net.automatalib.common.util.IntDisjointSets; import net.automatalib.common.util.UnionFindRemSP; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.word.Word; import net.automatalib.word.WordBuilder; import org.checkerframework.checker.nullness.qual.Nullable; @@ -42,7 +42,7 @@ private NearLinearEquivalenceTest() { // prevent instantiation } - public static @Nullable Word findSeparatingWord(UniversalSemantics target, + public static @Nullable Word findSeparatingWord(FiniteSemantics target, S init1, S init2, Collection inputs) { @@ -72,7 +72,7 @@ private NearLinearEquivalenceTest() { * * @return A word separating the two states, {@code null} if no such word can be found */ - public static @Nullable Word findSeparatingWord(UniversalSemantics target, + public static @Nullable Word findSeparatingWord(FiniteSemantics target, S init1, S init2, Collection inputs, @@ -174,14 +174,14 @@ private NearLinearEquivalenceTest() { return wb.toWord(); } - public static @Nullable Word findSeparatingWord(UniversalSemantics target, - UniversalSemantics other, + public static @Nullable Word findSeparatingWord(FiniteSemantics target, + FiniteSemantics other, Collection inputs) { return findSeparatingWord(target, other, inputs, false); } - public static @Nullable Word findSeparatingWord(UniversalSemantics target, - UniversalSemantics other, + public static @Nullable Word findSeparatingWord(FiniteSemantics target, + FiniteSemantics other, Collection inputs, boolean ignoreUndefinedTransitions) { @@ -305,14 +305,14 @@ private NearLinearEquivalenceTest() { return wb.toWord(); } - public static @Nullable Word findSeparatingWord(UniversalSemantics target, - UniversalSemantics other, + public static @Nullable Word findSeparatingWord(FiniteSemantics target, + FiniteSemantics other, Alphabet inputs) { return findSeparatingWord(target, other, inputs, false); } - public static @Nullable Word findSeparatingWord(UniversalSemantics target, - UniversalSemantics other, + public static @Nullable Word findSeparatingWord(FiniteSemantics target, + FiniteSemantics other, Alphabet inputs, boolean ignoreUndefinedTransitions) { @@ -430,8 +430,7 @@ private static final class Record { private final @Nullable Record reachedFrom; private final int depth; - @SuppressWarnings("nullness") - // we will only access reachedBy after checking reachedFrom for null + @SuppressWarnings("nullness") // we will only access reachedBy after checking reachedFrom for null Record(S state1, S2 state2) { this(state1, state2, null, null); } diff --git a/util/src/main/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizer.java b/util/src/main/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizer.java index 77820c151..7310cded4 100644 --- a/util/src/main/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizer.java +++ b/util/src/main/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizer.java @@ -21,6 +21,7 @@ import net.automatalib.alphabet.impl.Alphabets; import net.automatalib.automaton.AutomatonCreator; import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions; import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.FullIntAbstraction; import net.automatalib.automaton.concept.InputAlphabetHolder; @@ -31,8 +32,6 @@ import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.MutableMealyMachine; import net.automatalib.automaton.transducer.impl.CompactMealy; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; -import net.automatalib.semantics.FiniteSemantics; import net.automatalib.util.automaton.minimizer.Storage.BooleanStorage; import net.automatalib.util.automaton.minimizer.Storage.GenericStorage; import net.automatalib.util.automaton.minimizer.Storage.VoidStorage; @@ -487,7 +486,7 @@ public static CompactMealy minimizePartialMealy(MealyMachine UniversalCompactDetAutomaton minimizeUniversal(UniversalSemantics automaton, + public static UniversalCompactDetAutomaton minimizeUniversal(UniversalDeterministicAutomaton.FiniteSemantics automaton, Alphabet alphabet) { return minimizeUniversal(automaton, alphabet, PruningMode.PRUNE_AFTER); } @@ -510,7 +509,7 @@ public static UniversalCompactDetAutomaton minimizeUniver * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static UniversalCompactDetAutomaton minimizeUniversal(UniversalSemantics automaton, + public static UniversalCompactDetAutomaton minimizeUniversal(UniversalDeterministicAutomaton.FiniteSemantics automaton, Alphabet alphabet, PruningMode pruningMode) { return minimizeUniversal(automaton, alphabet, pruningMode, AutomatonInitialPartitioning.BY_FULL_SIGNATURE); @@ -536,7 +535,7 @@ public static UniversalCompactDetAutomaton minimizeUniver * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static UniversalCompactDetAutomaton minimizeUniversal(UniversalSemantics automaton, + public static UniversalCompactDetAutomaton minimizeUniversal(UniversalDeterministicAutomaton.FiniteSemantics automaton, Alphabet alphabet, PruningMode pruningMode, AutomatonInitialPartitioning ip) { @@ -568,11 +567,12 @@ public static UniversalCompactDetAutomaton minimizeUniver * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static > A minimizeUniversal(UniversalSemantics automaton, - Alphabet alphabet, - PruningMode pruningMode, - AutomatonInitialPartitioning ip, - AutomatonCreator creator) { + public static > A minimizeUniversal( + UniversalDeterministicAutomaton.FiniteSemantics automaton, + Alphabet alphabet, + PruningMode pruningMode, + AutomatonInitialPartitioning ip, + AutomatonCreator creator) { final FullIntAbstraction abs = automaton.fullIntAbstraction(alphabet); final Hopcroft hopcroft = @@ -609,7 +609,7 @@ public static UniversalCompactDetAutomaton minimizeUniver * * @return {@code automaton} for convenience */ - public static & FiniteSemantics> A minimizeUniversalInvasive( + public static > A minimizeUniversalInvasive( A automaton, Collection inputs) { return minimizeUniversalInvasive(automaton, inputs, AutomatonInitialPartitioning.BY_FULL_SIGNATURE); @@ -636,7 +636,7 @@ public static UniversalCompactDetAutomaton minimizeUniver * * @return {@code automaton} for convenience */ - public static & FiniteSemantics> A minimizeUniversalInvasive( + public static > A minimizeUniversalInvasive( A automaton, Collection inputs, AutomatonInitialPartitioning ip) { @@ -660,8 +660,9 @@ public static UniversalCompactDetAutomaton minimizeUniver * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static UniversalCompactDetAutomaton minimizePartialUniversal(UniversalSemantics automaton, - Alphabet alphabet) { + public static UniversalCompactDetAutomaton minimizePartialUniversal( + UniversalDeterministicAutomaton.FiniteSemantics automaton, + Alphabet alphabet) { return minimizePartialUniversal(automaton, alphabet, PruningMode.PRUNE_AFTER); } @@ -683,9 +684,10 @@ public static UniversalCompactDetAutomaton minimizePartia * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static UniversalCompactDetAutomaton minimizePartialUniversal(UniversalSemantics automaton, - Alphabet alphabet, - PruningMode pruningMode) { + public static UniversalCompactDetAutomaton minimizePartialUniversal( + UniversalDeterministicAutomaton.FiniteSemantics automaton, + Alphabet alphabet, + PruningMode pruningMode) { return minimizePartialUniversal(automaton, alphabet, @@ -716,11 +718,12 @@ public static UniversalCompactDetAutomaton minimizePartia * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static UniversalCompactDetAutomaton minimizePartialUniversal(UniversalSemantics automaton, - Alphabet alphabet, - PruningMode pruningMode, - AutomatonInitialPartitioning ip, - Object sinkClassification) { + public static UniversalCompactDetAutomaton minimizePartialUniversal( + UniversalDeterministicAutomaton.FiniteSemantics automaton, + Alphabet alphabet, + PruningMode pruningMode, + AutomatonInitialPartitioning ip, + Object sinkClassification) { return minimizePartialUniversal(automaton, alphabet, @@ -757,8 +760,8 @@ public static UniversalCompactDetAutomaton minimizePartia * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static & FiniteSemantics> A minimizePartialUniversal( - UniversalSemantics automaton, + public static > A minimizePartialUniversal( + UniversalDeterministicAutomaton.FiniteSemantics automaton, Alphabet alphabet, PruningMode pruningMode, AutomatonInitialPartitioning ip, @@ -783,11 +786,11 @@ public static UniversalCompactDetAutomaton minimizePartia } - private static & FiniteSemantics> A minimizeInvasive(A automaton, - Collection alphabet, - AutomatonInitialPartitioning ip, - Storage spStorage, - Storage tpStorage) { + private static > A minimizeInvasive(A automaton, + Collection alphabet, + AutomatonInitialPartitioning ip, + Storage spStorage, + Storage tpStorage) { final MutableDeterministicAbstractions.FullIntAbstraction abs = automaton.fullIntAbstraction(Alphabets.fromCollection(alphabet)); diff --git a/util/src/main/java/net/automatalib/util/automaton/minimizer/OneSEVPAMinimizer.java b/util/src/main/java/net/automatalib/util/automaton/minimizer/OneSEVPAMinimizer.java index 65f5df1b1..0eef56184 100644 --- a/util/src/main/java/net/automatalib/util/automaton/minimizer/OneSEVPAMinimizer.java +++ b/util/src/main/java/net/automatalib/util/automaton/minimizer/OneSEVPAMinimizer.java @@ -16,6 +16,7 @@ package net.automatalib.util.automaton.minimizer; import net.automatalib.alphabet.VPAlphabet; +import net.automatalib.automaton.concept.StateIDs; import net.automatalib.automaton.vpa.OneSEVPA; import net.automatalib.automaton.vpa.impl.DefaultOneSEVPA; import net.automatalib.automaton.vpa.impl.Location; @@ -39,6 +40,7 @@ public static DefaultOneSEVPA minimize(OneSEVPA sevpa, VPAlphabet void initHopcroft(Hopcroft hopcroft, OneSEVPA sevpa, VPAlphabet alphabet) { + final StateIDs stateIDs = sevpa.stateIDs(); final int numStates = sevpa.size(); final int numInputs = alphabet.getNumInternals() + alphabet.getNumCalls() * alphabet.getNumReturns() * sevpa.size() * 2; @@ -55,8 +57,8 @@ private static void initHopcroft(Hopcroft hopcroft, OneSEVPA sevpa, final Block[] initBlocks = new Block[2]; for (int i = 0; i < numStates; i++) { - final L loc = sevpa.getLocation(i); - final int initBlockIdx = sevpa.isAcceptingLocation(loc) ? 1 : 0; + final L loc = stateIDs.getState(i); + final int initBlockIdx = sevpa.getStateProperty(loc) ? 1 : 0; Block block = initBlocks[initBlockIdx]; if (block == null) { block = hopcroft.createBlock(); @@ -74,19 +76,19 @@ private static void initHopcroft(Hopcroft hopcroft, OneSEVPA sevpa, throw new IllegalArgumentException("Partial OneSEVPAs are not supported"); } - final int succId = sevpa.getLocationId(succ); + final int succId = stateIDs.getStateId(succ); data[predCountBase + succId]++; predCountBase += numStates; } for (I callSym : alphabet.getCallAlphabet()) { for (I retSym : alphabet.getReturnAlphabet()) { - for (L src : sevpa.getLocations()) { + for (L src : sevpa.getStates()) { int stackSym = sevpa.encodeStackSym(src, callSym); L succ = sevpa.getReturnSuccessor(loc, retSym, stackSym); if (succ == null) { throw new IllegalArgumentException("Partial OneSEVPAs are not supported"); } - int succId = sevpa.getLocationId(succ); + int succId = stateIDs.getStateId(succ); data[predCountBase + succId]++; predCountBase += numStates; @@ -95,7 +97,7 @@ private static void initHopcroft(Hopcroft hopcroft, OneSEVPA sevpa, if (succ == null) { throw new IllegalArgumentException("Partial OneSEVPAs are not supported"); } - succId = sevpa.getLocationId(succ); + succId = stateIDs.getStateId(succ); data[predCountBase + succId]++; predCountBase += numStates; } @@ -115,26 +117,26 @@ private static void initHopcroft(Hopcroft hopcroft, OneSEVPA sevpa, data[posDataLow + i] = pos; int predOfsBase = predOfsDataLow; - final L loc = sevpa.getLocation(i); + final L loc = stateIDs.getState(i); for (I intSym : alphabet.getInternalAlphabet()) { final L succ = sevpa.getInternalSuccessor(loc, intSym); if (succ == null) { throw new IllegalArgumentException("Partial OneSEVPAs are not supported"); } - final int succId = sevpa.getLocationId(succ); + final int succId = stateIDs.getStateId(succ); data[--data[predOfsBase + succId]] = i; predOfsBase += numStates; } for (I callSym : alphabet.getCallAlphabet()) { for (I retSym : alphabet.getReturnAlphabet()) { - for (L src : sevpa.getLocations()) { + for (L src : sevpa.getStates()) { int stackSym = sevpa.encodeStackSym(src, callSym); L succ = sevpa.getReturnSuccessor(loc, retSym, stackSym); if (succ == null) { throw new IllegalArgumentException("Partial OneSEVPAs are not supported"); } - int succId = sevpa.getLocationId(succ); + int succId = stateIDs.getStateId(succ); data[--data[predOfsBase + succId]] = i; predOfsBase += numStates; @@ -143,7 +145,7 @@ private static void initHopcroft(Hopcroft hopcroft, OneSEVPA sevpa, if (succ == null) { throw new IllegalArgumentException("Partial OneSEVPAs are not supported"); } - succId = sevpa.getLocationId(succ); + succId = stateIDs.getStateId(succ); data[--data[predOfsBase + succId]] = i; predOfsBase += numStates; } @@ -163,6 +165,7 @@ private static DefaultOneSEVPA fromHopcroft(Hopcroft pt, OneSEVPA original, VPAlphabet alphabet) { + final StateIDs stateIDs = original.stateIDs(); final int numBlocks = pt.getNumBlocks(); final DefaultOneSEVPA result = new DefaultOneSEVPA<>(alphabet, numBlocks); @@ -174,15 +177,15 @@ private static DefaultOneSEVPA fromHopcroft(Hopcroft pt, for (Block curr : pt.blockList()) { final int blockId = curr.id; final int rep = pt.getRepresentative(curr); - final L repLoc = original.getLocation(rep); + final L repLoc = stateIDs.getState(rep); final Location resultLoc = resultLocs[blockId]; - resultLoc.setAccepting(original.isAcceptingLocation(repLoc)); + resultLoc.setAccepting(original.getStateProperty(repLoc)); for (I intSym : alphabet.getInternalAlphabet()) { @SuppressWarnings("nullness") // partiality is handled during initialization final @NonNull L origSucc = original.getInternalSuccessor(repLoc, intSym); - final int origSuccId = original.getLocationId(origSucc); + final int origSuccId = stateIDs.getStateId(origSucc); final int resSuccId = pt.getBlockForState(origSuccId).id; final Location resSucc = resultLocs[resSuccId]; result.setInternalSuccessor(resultLoc, intSym, resSucc); @@ -191,13 +194,13 @@ private static DefaultOneSEVPA fromHopcroft(Hopcroft pt, for (I retSym : alphabet.getReturnAlphabet()) { for (Block b : pt.blockList()) { final int stackRepId = pt.getRepresentative(b); - final L stackRep = original.getLocation(stackRepId); + final L stackRep = stateIDs.getState(stackRepId); final Location resultStackRep = resultLocs[b.id]; final int origStackSym = original.encodeStackSym(stackRep, callSym); @SuppressWarnings("nullness") // partiality is handled during initialization final @NonNull L origSucc = original.getReturnSuccessor(repLoc, retSym, origStackSym); - final int origSuccId = original.getLocationId(origSucc); + final int origSuccId = stateIDs.getStateId(origSucc); final int resSuccId = pt.getBlockForState(origSuccId).id; final Location resSucc = resultLocs[resSuccId]; @@ -208,7 +211,7 @@ private static DefaultOneSEVPA fromHopcroft(Hopcroft pt, } } - final int origInit = original.getLocationId(original.getInitialLocation()); + final int origInit = stateIDs.getStateId(original.getInitialState()); result.setInitialLocation(resultLocs[pt.getBlockForState(origInit).id]); return result; diff --git a/util/src/main/java/net/automatalib/util/automaton/procedural/ProceduralUtil.java b/util/src/main/java/net/automatalib/util/automaton/procedural/ProceduralUtil.java index ac60106a2..123c05bea 100644 --- a/util/src/main/java/net/automatalib/util/automaton/procedural/ProceduralUtil.java +++ b/util/src/main/java/net/automatalib/util/automaton/procedural/ProceduralUtil.java @@ -29,8 +29,8 @@ import java.util.function.BiPredicate; import net.automatalib.alphabet.ProceduralInputAlphabet; +import net.automatalib.automaton.UniversalDeterministicAutomaton.FiniteSemantics; import net.automatalib.common.util.HashUtil; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.Automata; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.word.Word; @@ -43,9 +43,9 @@ private ProceduralUtil() { // prevent instantiation } - static > Map> computeTerminatingSequences(Map procedures, - ProceduralInputAlphabet alphabet, - BiPredicate> tracePredicate) { + static > Map> computeTerminatingSequences(Map procedures, + ProceduralInputAlphabet alphabet, + BiPredicate> tracePredicate) { final Map> terminatingSequences = new HashMap<>(HashUtil.capacity(alphabet.getNumCalls())); @@ -103,12 +103,12 @@ private ProceduralUtil() { return terminatingSequences; } - static > Map> computeAccessSequences(Map procedures, - ProceduralInputAlphabet alphabet, - Collection proceduralInputs, - @Nullable I initialProcedure, - Map> terminatingSequences, - BiPredicate> transitionPredicate) { + static > Map> computeAccessSequences(Map procedures, + ProceduralInputAlphabet alphabet, + Collection proceduralInputs, + @Nullable I initialProcedure, + Map> terminatingSequences, + BiPredicate> transitionPredicate) { if (initialProcedure == null) { return Collections.emptyMap(); @@ -150,7 +150,7 @@ private ProceduralUtil() { return accessSequences; } - private static > Collection discoverAccessSequences( + private static > Collection discoverAccessSequences( ProceduralInputAlphabet alphabet, Collection proceduralInputs, I procedure, @@ -193,11 +193,11 @@ private ProceduralUtil() { return newAS; } - static > @Nullable Word findSeparatingWord(Map sys1, - ATSequences at1, - Map sys2, - ATSequences at2, - ProceduralInputAlphabet alphabet) { + static > @Nullable Word findSeparatingWord(Map sys1, + ATSequences at1, + Map sys2, + ATSequences at2, + ProceduralInputAlphabet alphabet) { for (I procedure : alphabet.getCallAlphabet()) { final M p1 = sys1.get(procedure); final M p2 = sys2.get(procedure); diff --git a/util/src/main/java/net/automatalib/util/automaton/random/RandomAutomata.java b/util/src/main/java/net/automatalib/util/automaton/random/RandomAutomata.java index 906a803e1..923d8f507 100644 --- a/util/src/main/java/net/automatalib/util/automaton/random/RandomAutomata.java +++ b/util/src/main/java/net/automatalib/util/automaton/random/RandomAutomata.java @@ -30,7 +30,7 @@ import net.automatalib.alphabet.ProceduralOutputAlphabet; import net.automatalib.alphabet.VPAlphabet; import net.automatalib.automaton.Automaton; -import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.MutableDeterministic.FiniteSemantics; import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.fsa.impl.CompactDFA; import net.automatalib.automaton.procedural.SBA; @@ -45,7 +45,6 @@ import net.automatalib.automaton.vpa.impl.DefaultOneSEVPA; import net.automatalib.automaton.vpa.impl.Location; import net.automatalib.common.util.HashUtil; -import net.automatalib.semantics.FiniteSemantics; import net.automatalib.util.automaton.fsa.DFAs; import net.automatalib.util.automaton.minimizer.HopcroftMinimizer; import net.automatalib.util.automaton.minimizer.OneSEVPAMinimizer; @@ -123,10 +122,10 @@ public static DefaultOneSEVPA randomOneSEVPA(Random r, do { retSym = alphabet.getReturnSymbol(r.nextInt(alphabet.getNumReturns())); - srcLoc = result.getLocation(r.nextInt(result.size())); + srcLoc = result.getState(r.nextInt(result.size())); I callSym = alphabet.getCallSymbol(r.nextInt(alphabet.getNumCalls())); - final Location stackLoc = result.getLocation(r.nextInt(result.size())); + final Location stackLoc = result.getState(r.nextInt(result.size())); stackSym = result.encodeStackSym(stackLoc, callSym); } while (result.getReturnSuccessor(srcLoc, retSym, stackSym) != null); @@ -138,7 +137,7 @@ public static DefaultOneSEVPA randomOneSEVPA(Random r, do { intSym = alphabet.getInternalSymbol(r.nextInt(alphabet.getNumInternals())); - srcLoc = result.getLocation(r.nextInt(result.size())); + srcLoc = result.getState(r.nextInt(result.size())); } while (result.getInternalSuccessor(srcLoc, intSym) != null); final Location newLoc = result.addLocation(r.nextDouble() < acceptanceProb); @@ -146,20 +145,20 @@ public static DefaultOneSEVPA randomOneSEVPA(Random r, } } - for (Location loc : result.getLocations()) { + for (Location loc : result.getStates()) { for (I intSym : alphabet.getInternalAlphabet()) { if (result.getInternalSuccessor(loc, intSym) == null) { - final Location tgtLoc = result.getLocation(r.nextInt(result.size())); + final Location tgtLoc = result.getState(r.nextInt(result.size())); result.setInternalSuccessor(loc, intSym, tgtLoc); } } for (I callSym : alphabet.getCallAlphabet()) { - for (Location stackLoc : result.getLocations()) { + for (Location stackLoc : result.getStates()) { int stackSym = result.encodeStackSym(stackLoc, callSym); for (I retSym : alphabet.getReturnAlphabet()) { if (result.getReturnSuccessor(loc, retSym, stackSym) == null) { - final Location tgtLoc = result.getLocation(r.nextInt(result.size())); + final Location tgtLoc = result.getState(r.nextInt(result.size())); result.setReturnSuccessor(loc, retSym, stackSym, tgtLoc); } } @@ -338,24 +337,22 @@ public static SBA randomSBA(Random random, mealies); } - public static & FiniteSemantics> A randomDeterministic( - Random rand, - @NonNegative int numStates, - Collection inputs, - Collection stateProps, - Collection transProps, - A out) { + public static > A randomDeterministic(Random rand, + @NonNegative int numStates, + Collection inputs, + Collection stateProps, + Collection transProps, + A out) { return randomDeterministic(rand, numStates, inputs, stateProps, transProps, out, true); } - public static & FiniteSemantics> A randomDeterministic( - Random rand, - @NonNegative int numStates, - Collection inputs, - Collection stateProps, - Collection transProps, - A out, - boolean minimize) { + public static > A randomDeterministic(Random rand, + @NonNegative int numStates, + Collection inputs, + Collection stateProps, + Collection transProps, + A out, + boolean minimize) { RandomDeterministicAutomatonGenerator gen = new RandomDeterministicAutomatonGenerator<>(rand, inputs, stateProps, transProps, out); diff --git a/util/src/main/java/net/automatalib/util/automaton/random/RandomDeterministicAutomatonGenerator.java b/util/src/main/java/net/automatalib/util/automaton/random/RandomDeterministicAutomatonGenerator.java index d12d8c1a1..d58b8a955 100644 --- a/util/src/main/java/net/automatalib/util/automaton/random/RandomDeterministicAutomatonGenerator.java +++ b/util/src/main/java/net/automatalib/util/automaton/random/RandomDeterministicAutomatonGenerator.java @@ -19,9 +19,8 @@ import java.util.Random; import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.semantics.FiniteSemantics; -public class RandomDeterministicAutomatonGenerator & FiniteSemantics> +public class RandomDeterministicAutomatonGenerator> extends RandomAutomatonGenerator { public RandomDeterministicAutomatonGenerator(Random random, diff --git a/util/src/main/java/net/automatalib/util/automaton/vpa/OneSEVPAs.java b/util/src/main/java/net/automatalib/util/automaton/vpa/OneSEVPAs.java index 4d781accd..5a94dcdca 100644 --- a/util/src/main/java/net/automatalib/util/automaton/vpa/OneSEVPAs.java +++ b/util/src/main/java/net/automatalib/util/automaton/vpa/OneSEVPAs.java @@ -27,13 +27,17 @@ import java.util.function.Predicate; import net.automatalib.alphabet.VPAlphabet; +import net.automatalib.automaton.concept.StateIDs; import net.automatalib.automaton.vpa.OneSEVPA; +import net.automatalib.automaton.vpa.State; import net.automatalib.automaton.vpa.impl.DefaultOneSEVPA; import net.automatalib.common.util.HashUtil; import net.automatalib.common.util.IntDisjointSets; import net.automatalib.common.util.Pair; import net.automatalib.common.util.UnionFindRemSP; -import net.automatalib.common.util.array.ArrayStorage; +import net.automatalib.common.util.mapping.Mapping; +import net.automatalib.common.util.mapping.MutableMapping; +import net.automatalib.ts.acceptor.DeterministicAcceptorTS; import net.automatalib.util.automaton.minimizer.OneSEVPAMinimizer; import net.automatalib.util.automaton.vpa.SPAConverter.ConversionResult; import net.automatalib.util.ts.acceptor.AcceptanceCombiner; @@ -244,7 +248,7 @@ public static DefaultOneSEVPA minimize(OneSEVPA sevpa, VPAlphabet result = computeAccessSequences(sevpa, alphabet, true, predicate); L resultLoc = result.terminateLoc; if (resultLoc != null) { - return result.accessSequences.get(sevpa.getLocationId(resultLoc)); + return result.accessSequences.get(resultLoc); } return null; } @@ -261,9 +265,9 @@ public static DefaultOneSEVPA minimize(OneSEVPA sevpa, VPAlphabet * input symbol type * - * @return a list of access sequences, indexed by their respective {@link OneSEVPA#getLocationId(Object) id}. + * @return a mapping of states to their respective access sequences. */ - public static ArrayStorage> computeAccessSequences(OneSEVPA sevpa, VPAlphabet alphabet) { + public static Mapping> computeAccessSequences(OneSEVPA sevpa, VPAlphabet alphabet) { return computeAccessSequences(sevpa, alphabet, true, l -> false).accessSequences; } @@ -271,12 +275,12 @@ private static ReachResult computeAccessSequences(OneSEVPA se VPAlphabet alphabet, boolean computeAs, Predicate terminatePred) { - final ArrayStorage> result = new ArrayStorage<>(sevpa.size()); + final MutableMapping> result = sevpa.createStaticStateMapping(); - final L initLoc = sevpa.getInitialLocation(); + final L initLoc = sevpa.getInitialState(); final List reachable = new ArrayList<>(); reachable.add(initLoc); - result.set(sevpa.getLocationId(initLoc), Word.epsilon()); + result.put(initLoc, Word.epsilon()); if (terminatePred.test(initLoc)) { return new ReachResult<>(initLoc, reachable, result); @@ -285,19 +289,18 @@ private static ReachResult computeAccessSequences(OneSEVPA se int queuePtr = 0; while (queuePtr < reachable.size()) { final L curr = reachable.get(queuePtr++); - final Word currAs = result.get(sevpa.getLocationId(curr)); + final Word currAs = result.get(curr); for (I intSym : alphabet.getInternalAlphabet()) { final L succ = sevpa.getInternalSuccessor(curr, intSym); if (succ == null) { continue; } - final int succIdx = sevpa.getLocationId(succ); - if (result.get(succIdx) != null) { + if (result.get(succ) != null) { continue; } final Word succAs = computeAs ? currAs.append(intSym) : Word.epsilon(); - result.set(succIdx, succAs); + result.put(succ, succAs); if (terminatePred.test(succ)) { return new ReachResult<>(succ, reachable, result); } @@ -313,14 +316,11 @@ private static ReachResult computeAccessSequences(OneSEVPA se if (succ == null) { continue; } - int succIdx = sevpa.getLocationId(succ); - if (result.get(succIdx) == null) { + if (result.get(succ) == null) { Word succAs = computeAs ? - result.get(sevpa.getLocationId(src)) - .append(callSym) - .concat(currAs.append(returnSym)) : + result.get(src).append(callSym).concat(currAs.append(returnSym)) : Word.epsilon(); - result.set(succIdx, succAs); + result.put(succ, succAs); if (terminatePred.test(succ)) { return new ReachResult<>(succ, reachable, result); } @@ -333,13 +333,11 @@ private static ReachResult computeAccessSequences(OneSEVPA se if (succ == null) { continue; } - succIdx = sevpa.getLocationId(succ); - if (result.get(succIdx) == null) { + if (result.get(succ) == null) { final Word succAs = computeAs ? - currAs.append(callSym) - .concat(result.get(sevpa.getLocationId(src)).append(returnSym)) : + currAs.append(callSym).concat(result.get(src).append(returnSym)) : Word.epsilon(); - result.set(succIdx, succAs); + result.put(succ, succAs); if (terminatePred.test(succ)) { return new ReachResult<>(succ, reachable, result); } @@ -391,7 +389,7 @@ public static boolean testEquivalence(OneSEVPA sevpa1, OneSEVPA * {@code sevpa.accepts(w) == true}, {@code null} if such a word does not exist. */ public static @Nullable Word findAcceptedWord(OneSEVPA sevpa, VPAlphabet alphabet) { - return computeAccessSequence(sevpa, alphabet, sevpa::isAcceptingLocation); + return computeAccessSequence(sevpa, alphabet, sevpa::getStateProperty); } /** @@ -410,7 +408,7 @@ public static boolean testEquivalence(OneSEVPA sevpa1, OneSEVPA * {@code sevpa.accepts(w) == false}, {@code null} if such a word does not exist. */ public static @Nullable Word findRejectedWord(OneSEVPA sevpa, VPAlphabet alphabet) { - return computeAccessSequence(sevpa, alphabet, l -> !sevpa.isAcceptingLocation(l)); + return computeAccessSequence(sevpa, alphabet, Predicate.not(sevpa::getStateProperty)); } /** @@ -479,13 +477,14 @@ public static List findReachableLocations(OneSEVPA sevpa, VPAlph L init1, L init2, VPAlphabet alphabet) { - if (sevpa.isAcceptingLocation(init1) != sevpa.isAcceptingLocation(init2)) { + if (sevpa.getStateProperty(init1) != sevpa.getStateProperty(init2)) { return Pair.of(Word.epsilon(), Word.epsilon()); } - final ArrayStorage> as = computeAccessSequences(sevpa, alphabet); + final Mapping> as = computeAccessSequences(sevpa, alphabet); + final StateIDs stateIDs = sevpa.stateIDs(); final IntDisjointSets uf = new UnionFindRemSP(sevpa.size()); - uf.link(sevpa.getLocationId(init1), sevpa.getLocationId(init2)); + uf.link(stateIDs.getStateId(init1), stateIDs.getStateId(init2)); final Queue> queue = new ArrayDeque<>(); queue.add(new Record<>(init1, init2)); @@ -508,12 +507,12 @@ public static List findReachableLocations(OneSEVPA sevpa, VPAlph throw new IllegalArgumentException("Only total models are supported"); } - if (sevpa.isAcceptingLocation(succ1) != sevpa.isAcceptingLocation(succ2)) { + if (sevpa.getStateProperty(succ1) != sevpa.getStateProperty(succ2)) { lastPair = pair; break explore; } - final int r1 = uf.find(sevpa.getLocationId(succ1)), r2 = uf.find(sevpa.getLocationId(succ2)); + final int r1 = uf.find(stateIDs.getStateId(succ1)), r2 = uf.find(stateIDs.getStateId(succ2)); if (r1 == r2) { continue; @@ -531,7 +530,7 @@ public static List findReachableLocations(OneSEVPA sevpa, VPAlph final Word rWord = Word.fromLetter(r); // check l as source location for l1/l2 - for (L l : sevpa.getLocations()) { + for (L l : sevpa.getStates()) { final int sym = sevpa.encodeStackSym(l, c); final L rSucc1 = sevpa.getReturnSuccessor(l1, r, sym); final L rSucc2 = sevpa.getReturnSuccessor(l2, r, sym); @@ -540,15 +539,14 @@ public static List findReachableLocations(OneSEVPA sevpa, VPAlph throw new IllegalArgumentException("Only total models are supported"); } - final Pair, Word> pair = - Pair.of(Word.fromWords(as.get(sevpa.getLocationId(l)), cWord), rWord); + final Pair, Word> pair = Pair.of(Word.fromWords(as.get(l), cWord), rWord); - if (sevpa.isAcceptingLocation(rSucc1) != sevpa.isAcceptingLocation(rSucc2)) { + if (sevpa.getStateProperty(rSucc1) != sevpa.getStateProperty(rSucc2)) { lastPair = pair; break explore; } - final int r1 = uf.find(sevpa.getLocationId(rSucc1)), r2 = uf.find(sevpa.getLocationId(rSucc2)); + final int r1 = uf.find(stateIDs.getStateId(rSucc1)), r2 = uf.find(stateIDs.getStateId(rSucc2)); if (r1 == r2) { continue; @@ -560,7 +558,7 @@ public static List findReachableLocations(OneSEVPA sevpa, VPAlph } // check l1/l2 as source location for l - for (L l : sevpa.getLocations()) { + for (L l : sevpa.getStates()) { final int sym1 = sevpa.encodeStackSym(l1, c); final int sym2 = sevpa.encodeStackSym(l2, c); final L rSucc1 = sevpa.getReturnSuccessor(l, r, sym1); @@ -571,14 +569,14 @@ public static List findReachableLocations(OneSEVPA sevpa, VPAlph } final Pair, Word> pair = - Pair.of(Word.epsilon(), Word.fromWords(cWord, as.get(sevpa.getLocationId(l)), rWord)); + Pair.of(Word.epsilon(), Word.fromWords(cWord, as.get(l), rWord)); - if (sevpa.isAcceptingLocation(rSucc1) != sevpa.isAcceptingLocation(rSucc2)) { + if (sevpa.getStateProperty(rSucc1) != sevpa.getStateProperty(rSucc2)) { lastPair = pair; break explore; } - final int r1 = uf.find(sevpa.getLocationId(rSucc1)), r2 = uf.find(sevpa.getLocationId(rSucc2)); + final int r1 = uf.find(stateIDs.getStateId(rSucc1)), r2 = uf.find(stateIDs.getStateId(rSucc2)); if (r1 == r2) { continue; @@ -630,12 +628,13 @@ public static List findReachableLocations(OneSEVPA sevpa, VPAlph public static Collection, Word>> findCharacterizingSet(OneSEVPA sevpa, VPAlphabet alphabet) { - final ArrayStorage> as = computeAccessSequences(sevpa, alphabet); + final DeterministicAcceptorTS, I> semantics = sevpa.getSemantics(); + final Mapping> as = computeAccessSequences(sevpa, alphabet); final List acceptingLocations = new ArrayList<>(sevpa.size()); final List rejectionLocations = new ArrayList<>(sevpa.size()); - for (L l : sevpa.getLocations()) { - if (sevpa.isAcceptingLocation(l)) { + for (L l : sevpa.getStates()) { + if (sevpa.getStateProperty(l)) { acceptingLocations.add(l); } else { rejectionLocations.add(l); @@ -672,9 +671,7 @@ public static Collection, Word>> findCharacterizingSet(On final List acceptingBucket = new ArrayList<>(block.size()); final List rejectingBucket = new ArrayList<>(block.size()); - if (sevpa.accepts(Word.fromWords(sepWord.getFirst(), - as.get(sevpa.getLocationId(l1)), - sepWord.getSecond()))) { + if (semantics.accepts(Word.fromWords(sepWord.getFirst(), as.get(l1), sepWord.getSecond()))) { acceptingBucket.add(l1); rejectingBucket.add(l2); } else { @@ -684,9 +681,7 @@ public static Collection, Word>> findCharacterizingSet(On while (blockIter.hasNext()) { final L next = blockIter.next(); - if (sevpa.accepts(Word.fromWords(sepWord.getFirst(), - as.get(sevpa.getLocationId(next)), - sepWord.getSecond()))) { + if (semantics.accepts(Word.fromWords(sepWord.getFirst(), as.get(next), sepWord.getSecond()))) { acceptingBucket.add(next); } else { rejectingBucket.add(next); @@ -733,9 +728,9 @@ private static class ReachResult { final @Nullable L terminateLoc; final List reachableLocs; - final ArrayStorage> accessSequences; + final Mapping> accessSequences; - ReachResult(@Nullable L terminateLoc, List reachableLocs, ArrayStorage> accessSequences) { + ReachResult(@Nullable L terminateLoc, List reachableLocs, Mapping> accessSequences) { this.terminateLoc = terminateLoc; this.reachableLocs = reachableLocs; this.accessSequences = accessSequences; diff --git a/util/src/main/java/net/automatalib/util/automaton/vpa/ProductOneSEVPA.java b/util/src/main/java/net/automatalib/util/automaton/vpa/ProductOneSEVPA.java index 5890d6a2f..b7d41ee7a 100644 --- a/util/src/main/java/net/automatalib/util/automaton/vpa/ProductOneSEVPA.java +++ b/util/src/main/java/net/automatalib/util/automaton/vpa/ProductOneSEVPA.java @@ -16,9 +16,11 @@ package net.automatalib.util.automaton.vpa; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import net.automatalib.alphabet.VPAlphabet; +import net.automatalib.automaton.concept.StateIDs; import net.automatalib.automaton.vpa.OneSEVPA; import net.automatalib.automaton.vpa.impl.AbstractSEVPA; import net.automatalib.common.util.Pair; @@ -43,6 +45,9 @@ public class ProductOneSEVPA extends AbstractSEVPA, I> i private final AcceptanceCombiner accCombiner; + private final StateIDs stateIDs1; + private final StateIDs stateIDs2; + public ProductOneSEVPA(VPAlphabet alphabet, OneSEVPA sevpa1, OneSEVPA sevpa2, @@ -51,6 +56,8 @@ public ProductOneSEVPA(VPAlphabet alphabet, this.sevpa1 = sevpa1; this.sevpa2 = sevpa2; this.accCombiner = combiner; + this.stateIDs1 = sevpa1.stateIDs(); + this.stateIDs2 = sevpa2.stateIDs(); } @Override @@ -67,23 +74,32 @@ public ProductOneSEVPA(VPAlphabet alphabet, } @Override - public Pair getLocation(int id) { - final int l1Id = id / sevpa2.size(); - final int l2Id = id % sevpa2.size(); - return Pair.of(sevpa1.getLocation(l1Id), sevpa2.getLocation(l2Id)); + public Collection> getTransitions(Pair state, I input) { + final Collection t1 = sevpa1.getTransitions(state.getFirst(), input); + final Collection t2 = sevpa2.getTransitions(state.getSecond(), input); + + final List> result = new ArrayList<>(t1.size() * t2.size()); + + for (L1 l1 : t1) { + for (L2 l2 : t2) { + result.add(Pair.of(l1, l2)); + } + } + + return result; } @Override - public int getLocationId(Pair loc) { - return sevpa1.getLocationId(loc.getFirst()) * sevpa2.size() + sevpa2.getLocationId(loc.getSecond()); + public Pair getSuccessor(Pair transition) { + return transition; } @Override - public List> getLocations() { + public List> getStates() { final List> locations = new ArrayList<>(sevpa1.size() * sevpa2.size()); - for (L1 l1 : sevpa1.getLocations()) { - for (L2 l2 : sevpa2.getLocations()) { + for (L1 l1 : sevpa1.getStates()) { + for (L2 l2 : sevpa2.getStates()) { locations.add(Pair.of(l1, l2)); } } @@ -107,14 +123,18 @@ public List> getLocations() { } @Override - public boolean isAcceptingLocation(Pair loc) { - return accCombiner.combine(sevpa1.isAcceptingLocation(loc.getFirst()), - sevpa2.isAcceptingLocation(loc.getSecond())); + public Boolean getStateProperty(Pair loc) { + return accCombiner.combine(sevpa1.getStateProperty(loc.getFirst()), sevpa2.getStateProperty(loc.getSecond())); + } + + @Override + public Void getTransitionProperty(Pair transition) { + return null; } @Override - public Pair getInitialLocation() { - return Pair.of(sevpa1.getInitialLocation(), sevpa2.getInitialLocation()); + public Pair getInitialState() { + return Pair.of(sevpa1.getInitialState(), sevpa2.getInitialState()); } @Override @@ -134,4 +154,15 @@ public int size() { return sevpa1.size() * sevpa2.size(); } + @Override + public int getStateId(Pair state) { + return stateIDs1.getStateId(state.getFirst()) * sevpa2.size() + stateIDs2.getStateId(state.getSecond()); + } + + @Override + public Pair getState(int id) { + final int l1Id = id / sevpa2.size(); + final int l2Id = id % sevpa2.size(); + return Pair.of(stateIDs1.getState(l1Id), stateIDs2.getState(l2Id)); + } } diff --git a/util/src/main/java/net/automatalib/util/automaton/vpa/SPAConverter.java b/util/src/main/java/net/automatalib/util/automaton/vpa/SPAConverter.java index 8f14c558e..5cce2fbb5 100644 --- a/util/src/main/java/net/automatalib/util/automaton/vpa/SPAConverter.java +++ b/util/src/main/java/net/automatalib/util/automaton/vpa/SPAConverter.java @@ -40,7 +40,8 @@ import net.automatalib.automaton.vpa.OneSEVPA; import net.automatalib.common.util.HashUtil; import net.automatalib.common.util.Pair; -import net.automatalib.common.util.array.ArrayStorage; +import net.automatalib.common.util.mapping.Mapping; +import net.automatalib.ts.acceptor.DeterministicAcceptorTS; import net.automatalib.util.automaton.fsa.MutableDFAs; import net.automatalib.util.automaton.minimizer.HopcroftMinimizer; import net.automatalib.util.automaton.procedural.ATRSequences; @@ -74,7 +75,7 @@ static ConversionResult convert(OneSEVPA sevpa, for (AI ai : alphabet.getCallAlphabet()) { final Map locationMap = new HashMap<>(HashUtil.capacity(sevpa.size())); - for (L l : sevpa.getLocations()) { + for (L l : sevpa.getStates()) { final CI cc = symbolMapper.mapCallSymbol(ai); locationMap.put(l, cc); callAlphabet.addSymbol(cc); @@ -100,7 +101,7 @@ static ConversionResult convert(OneSEVPA sevpa, final Map l2sMap = new HashMap<>(HashUtil.capacity(sevpa.size())); final CompactDFA template = buildTemplate(sevpa, alphabet, spaAlphabet, symbolMapper, procedureMap, l2sMap); - for (L l : sevpa.getLocations()) { + for (L l : sevpa.getStates()) { final CompactDFA lCopy = new CompactDFA<>(template); lCopy.setAccepting(l2sMap.get(l), true); for (AI ai : alphabet.getCallAlphabet()) { @@ -111,8 +112,8 @@ static ConversionResult convert(OneSEVPA sevpa, // build main procedure final CompactDFA mCopy = new CompactDFA<>(template); - for (L l : sevpa.getLocations()) { - if (sevpa.isAcceptingLocation(l)) { + for (L l : sevpa.getStates()) { + if (sevpa.getStateProperty(l)) { mCopy.setAccepting(l2sMap.get(l), true); } } @@ -121,7 +122,7 @@ static ConversionResult convert(OneSEVPA sevpa, // prepare DTs final Map> dts = new HashMap<>(HashUtil.capacity(alphabet.getNumCalls())); final Collection, Word>> cs = OneSEVPAs.findCharacterizingSet(sevpa, alphabet); - final ArrayStorage> as = OneSEVPAs.computeAccessSequences(sevpa, alphabet); + final Mapping> as = OneSEVPAs.computeAccessSequences(sevpa, alphabet); // build SPA StackSPA spa = new StackSPA<>(spaAlphabet, mainProcedure, procedures); @@ -169,15 +170,16 @@ static ConversionResult convert(OneSEVPA sevpa, } else { // build (regular) dts for (AI ai : alphabet.getCallAlphabet()) { - final Node dt = buildDT(sevpa, sevpa.getLocations(), procedureMap.get(ai), cs, as); + final Node dt = buildDT(sevpa, sevpa.getStates(), procedureMap.get(ai), cs, as); dts.put(ai, dt); } } + final DeterministicAcceptorTS semantics = sevpa.getSemantics(); return new ConversionResult<>(spa, dts, reverseMapping, - new Mapper<>(alphabet, mainProcedure, dts, symbolMapper, sevpa::computeOutput)); + new Mapper<>(alphabet, mainProcedure, dts, symbolMapper, semantics::accepts)); } private static CompactDFA buildTemplate(OneSEVPA sevpa, @@ -191,14 +193,14 @@ private static CompactDFA buildTemplate(OneSEVPA sevpa, final CompactDFA dfa = new CompactDFA<>(proceduralAlphabet, sevpa.size()); final AI r = alphabet.getReturnSymbol(0); - final L initLoc = sevpa.getInitialLocation(); - for (L l : sevpa.getLocations()) { + final L initLoc = sevpa.getInitialState(); + for (L l : sevpa.getStates()) { final Integer s = dfa.addState(); map.put(l, s); dfa.setInitial(s, Objects.equals(l, initLoc)); } - for (L l : sevpa.getLocations()) { + for (L l : sevpa.getStates()) { final Integer s = map.get(l); for (AI ai : alphabet.getInternalAlphabet()) { final CI ci = symbolMapper.mapInternalSymbol(ai); @@ -208,7 +210,7 @@ private static CompactDFA buildTemplate(OneSEVPA sevpa, } for (AI ai : alphabet.getCallAlphabet()) { - for (L l2 : sevpa.getLocations()) { + for (L l2 : sevpa.getStates()) { final int sym = sevpa.encodeStackSym(l, ai); final L succ = sevpa.getReturnSuccessor(l2, r, sym); final Integer sSucc = map.get(succ); @@ -227,17 +229,19 @@ private static Node buildDT(OneSEVPA sevpa, Collection nodes, Map l2ciMap, Collection, Word>> cSet, - ArrayStorage> as) { + Mapping> as) { if (nodes.size() == 1) { return new Node<>(l2ciMap.get(nodes.iterator().next())); } + final DeterministicAcceptorTS semantics = sevpa.getSemantics(); + for (Pair, Word> cs : cSet) { final List acc = new ArrayList<>(nodes.size()); final List rej = new ArrayList<>(nodes.size()); for (L l : nodes) { - if (sevpa.accepts(Word.fromWords(cs.getFirst(), as.get(sevpa.getLocationId(l)), cs.getSecond()))) { + if (semantics.accepts(Word.fromWords(cs.getFirst(), as.get(l), cs.getSecond()))) { acc.add(l); } else { rej.add(l); diff --git a/util/src/test/java/net/automatalib/util/automaton/CopyConstructorTest.java b/util/src/test/java/net/automatalib/util/automaton/CopyConstructorTest.java index 524d1dd1c..4e40f117f 100644 --- a/util/src/test/java/net/automatalib/util/automaton/CopyConstructorTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/CopyConstructorTest.java @@ -23,13 +23,13 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Alphabets; +import net.automatalib.automaton.UniversalDeterministicAutomaton.FiniteSemantics; import net.automatalib.automaton.fsa.NFA; import net.automatalib.automaton.fsa.impl.CompactDFA; import net.automatalib.automaton.fsa.impl.CompactNFA; import net.automatalib.automaton.transducer.impl.CompactMealy; import net.automatalib.automaton.transducer.impl.CompactMoore; import net.automatalib.automaton.transducer.impl.CompactSST; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.copy.AutomatonCopyMethod; import net.automatalib.util.automaton.copy.AutomatonLowLevelCopy; import net.automatalib.util.automaton.fsa.NFAs; @@ -90,9 +90,9 @@ public void testSST() { testCopyConstructor(sst, INPUT_ALPHABET, CompactSST::new); } - private > void testCopyConstructor(A automaton, - Alphabet alphabet, - Function copyConstructor) { + private > void testCopyConstructor(A automaton, + Alphabet alphabet, + Function copyConstructor) { final A copy = copyConstructor.apply(automaton); Assert.assertTrue(Automata.testEquivalence(automaton, copy, alphabet)); } diff --git a/util/src/test/java/net/automatalib/util/automaton/conformance/WpMethodTestsIteratorTest.java b/util/src/test/java/net/automatalib/util/automaton/conformance/WpMethodTestsIteratorTest.java index dc95640ed..f438453b7 100644 --- a/util/src/test/java/net/automatalib/util/automaton/conformance/WpMethodTestsIteratorTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/conformance/WpMethodTestsIteratorTest.java @@ -24,11 +24,11 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Alphabets; +import net.automatalib.automaton.UniversalDeterministicAutomaton.FiniteSemantics; import net.automatalib.automaton.fsa.impl.CompactDFA; import net.automatalib.common.util.collection.IterableUtil; import net.automatalib.common.util.collection.IteratorUtil; import net.automatalib.common.util.comparison.CmpUtil; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.util.automaton.equivalence.CharacterizingSets; import net.automatalib.util.automaton.random.RandomAutomata; @@ -100,7 +100,7 @@ private > void checkTestWords(List> actual, List } - private List> generateWpMethodTest(UniversalSemantics automaton, + private List> generateWpMethodTest(FiniteSemantics automaton, Collection inputs, List> middleParts) { diff --git a/util/src/test/java/net/automatalib/util/automaton/copy/AbstractAutomatonCopyTest.java b/util/src/test/java/net/automatalib/util/automaton/copy/AbstractAutomatonCopyTest.java index 4d14b2d73..ecab3fe65 100644 --- a/util/src/test/java/net/automatalib/util/automaton/copy/AbstractAutomatonCopyTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/copy/AbstractAutomatonCopyTest.java @@ -22,11 +22,11 @@ import net.automatalib.alphabet.impl.Alphabets; import net.automatalib.automaton.AutomatonCreator; import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.MutableDeterministic.FiniteSemantics; import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.concept.Shrinkable; import net.automatalib.automaton.fsa.impl.CompactDFA; import net.automatalib.automaton.transducer.impl.CompactMealy; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.ts.TransitionPredicate; import net.automatalib.util.automaton.Automata; import net.automatalib.util.automaton.predicate.TransitionPredicates; @@ -148,23 +148,21 @@ private void makePartial(MutableDeterministic automaton } } - private & UniversalSemantics, S, I, T, SP, TP> void checkEquivalence( - A source, - Alphabet alphabet, - AutomatonCreator targetCreator) { + private , S, I, T, SP, TP> void checkEquivalence(A source, + Alphabet alphabet, + AutomatonCreator targetCreator) { final A target = targetCreator.createAutomaton(alphabet); AutomatonLowLevelCopy.copy(getCopyMethod(), source, alphabet, target); Assert.assertTrue(Automata.testEquivalence(source, target, alphabet)); } - private & UniversalSemantics, S, I, T, SP, TP> void checkFilteredEquivalence( - A source, - Alphabet alphabet, - AutomatonCreator targetCreator, - Predicate sPred, - TransitionPredicate tPred, - A expectedTarget) { + private , S, I, T, SP, TP> void checkFilteredEquivalence(A source, + Alphabet alphabet, + AutomatonCreator targetCreator, + Predicate sPred, + TransitionPredicate tPred, + A expectedTarget) { final A target = targetCreator.createAutomaton(alphabet); AutomatonLowLevelCopy.copy(getCopyMethod(), source, alphabet, target, sPred, tPred); diff --git a/util/src/test/java/net/automatalib/util/automaton/equivalence/BisimulationTest.java b/util/src/test/java/net/automatalib/util/automaton/equivalence/BisimulationTest.java index 92c9975a0..ff39b0970 100644 --- a/util/src/test/java/net/automatalib/util/automaton/equivalence/BisimulationTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/equivalence/BisimulationTest.java @@ -22,9 +22,9 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Alphabets; +import net.automatalib.automaton.Automaton.FiniteSemantics; import net.automatalib.automaton.fsa.impl.CompactNFA; import net.automatalib.common.util.Pair; -import net.automatalib.semantics.FiniteSemantics.PlainSemantics; import net.automatalib.ts.modal.impl.CompactMTS; import net.automatalib.util.automaton.random.TabakovVardiRandomAutomata; import org.testng.Assert; @@ -95,8 +95,8 @@ public void bisimTestLoop() { Assert.assertTrue(testBisimulationEquivalence(a, b, alphabet)); } - private static boolean testBisimulationEquivalence(PlainSemantics a, - PlainSemantics b, + private static boolean testBisimulationEquivalence(FiniteSemantics a, + FiniteSemantics b, Collection inputs) { Set> bisim = Bisimulation.bisimulationEquivalenceRelation(a, b, inputs); diff --git a/util/src/test/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTestTest.java b/util/src/test/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTestTest.java index 3a9649ac4..f63e839a8 100644 --- a/util/src/test/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTestTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/equivalence/DeterministicEquivalenceTestTest.java @@ -20,13 +20,13 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Alphabets; +import net.automatalib.automaton.UniversalDeterministicAutomaton.FiniteSemantics; import net.automatalib.automaton.concept.Output; import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.fsa.impl.CompactDFA; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.impl.CompactMealy; import net.automatalib.common.util.function.BiIntFunction; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.equivalence.DeterministicEquivalenceTest.ArrayRegistry; import net.automatalib.util.automaton.equivalence.DeterministicEquivalenceTest.MapRegistry; import net.automatalib.util.automaton.equivalence.DeterministicEquivalenceTest.Pred; @@ -158,8 +158,8 @@ private static void testIndexComputation(BiIntFunction> constr } } - private static void testForEmptySepWord(UniversalSemantics a1, - UniversalSemantics a2, + private static void testForEmptySepWord(FiniteSemantics a1, + FiniteSemantics a2, Collection inputs) { Assert.assertNull(DeterministicEquivalenceTest.findSeparatingWord(a1, a1, inputs)); @@ -174,13 +174,13 @@ private static void testForEmptySepWord(UniversalSemantics a1 Assert.assertNotEquals(a1.getState(sepWord2), a2.getState(sepWord2)); } - private & Output> void testEquivalenceInternal(M a1, - M a2, - Alphabet alphabet, - boolean equivalent) { + private & Output> void testEquivalenceInternal(M a1, + M a2, + Alphabet alphabet, + boolean equivalent) { // explicitly assign type to (redundant) variables, otherwise javac complains - final UniversalSemantics m1 = a1; - final UniversalSemantics m2 = a2; + final FiniteSemantics m1 = a1; + final FiniteSemantics m2 = a2; final Word separatingWord = DeterministicEquivalenceTest.findSeparatingWord(m1, m2, alphabet); diff --git a/util/src/test/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTestTest.java b/util/src/test/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTestTest.java index 8e4bae8a8..2835a909f 100644 --- a/util/src/test/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTestTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/equivalence/NearLinearEquivalenceTestTest.java @@ -22,9 +22,9 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Alphabets; +import net.automatalib.automaton.MutableDeterministic.FiniteSemantics; import net.automatalib.automaton.fsa.impl.CompactDFA; import net.automatalib.automaton.transducer.impl.CompactMealy; -import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; import net.automatalib.util.automaton.random.RandomAutomata; import net.automatalib.word.Word; import org.testng.Assert; @@ -192,8 +192,8 @@ public void testIssue84() { Assert.assertEquals(sepWord.length(), TestUtil.LARGE_AUTOMATON_A.size() - 1); } - private static void testForEmptySepWord(MutableSemantics a1, - MutableSemantics a2, + private static void testForEmptySepWord(FiniteSemantics a1, + FiniteSemantics a2, Collection inputs) { Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a1, a1, inputs)); Assert.assertNull(NearLinearEquivalenceTest.findSeparatingWord(a2, a2, inputs)); diff --git a/util/src/test/java/net/automatalib/util/automaton/minimizer/AbstractMinimizationTest.java b/util/src/test/java/net/automatalib/util/automaton/minimizer/AbstractMinimizationTest.java index c4d37ad3d..97cfbc96a 100644 --- a/util/src/test/java/net/automatalib/util/automaton/minimizer/AbstractMinimizationTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/minimizer/AbstractMinimizationTest.java @@ -19,6 +19,8 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Alphabets; +import net.automatalib.automaton.MutableDeterministic.FiniteSemantics; +import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.concept.StateIDs; import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.fsa.MutableDFA; @@ -27,8 +29,6 @@ import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.MutableMealyMachine; import net.automatalib.automaton.transducer.impl.CompactMealy; -import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.Automata; import net.automatalib.util.automaton.builder.AutomatonBuilders; import org.testng.Assert; @@ -221,9 +221,10 @@ private > void testMinimizeDFA(TestConfig te } } - private > void testMinimizeUniversal(TestConfig test) { + private > void testMinimizeUniversal(TestConfig test) { - final UniversalSemantics result = minimizeUniversal(test.automaton, test.alphabet); + final UniversalDeterministicAutomaton.FiniteSemantics result = + minimizeUniversal(test.automaton, test.alphabet); if (isPruned()) { Assert.assertEquals(result.size(), test.prunedSize); @@ -239,14 +240,15 @@ private > void testMinimizeDFA(TestConfig te protected abstract MealyMachine minimizeMealy(MutableMealyMachine mealy, Alphabet alphabet); - protected abstract UniversalSemantics minimizeUniversal(MutableSemantics automaton, - Alphabet alphabet); + protected abstract UniversalDeterministicAutomaton.FiniteSemantics minimizeUniversal( + FiniteSemantics automaton, + Alphabet alphabet); protected abstract boolean isPruned(); protected abstract boolean supportsPartial(); - private static void assertAllInequivalent(UniversalSemantics automaton, + private static void assertAllInequivalent(UniversalDeterministicAutomaton.FiniteSemantics automaton, Collection inputs) { StateIDs ids = automaton.stateIDs(); diff --git a/util/src/test/java/net/automatalib/util/automaton/minimizer/AutomataMinimizationTest.java b/util/src/test/java/net/automatalib/util/automaton/minimizer/AutomataMinimizationTest.java index bd5f4c196..13b823391 100644 --- a/util/src/test/java/net/automatalib/util/automaton/minimizer/AutomataMinimizationTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/minimizer/AutomataMinimizationTest.java @@ -16,13 +16,12 @@ package net.automatalib.util.automaton.minimizer; import net.automatalib.alphabet.Alphabet; -import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.MutableDeterministic.FiniteSemantics; +import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.fsa.MutableDFA; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.MutableMealyMachine; -import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.Automata; public class AutomataMinimizationTest extends AbstractMinimizationTest { @@ -39,8 +38,9 @@ protected DFA minimizeDFA(MutableDFA dfa, Alphabet alphabet) } @Override - protected UniversalSemantics minimizeUniversal(MutableSemantics automaton, - Alphabet alphabet) { + protected UniversalDeterministicAutomaton.FiniteSemantics minimizeUniversal( + FiniteSemantics automaton, + Alphabet alphabet) { return Automata.invasiveMinimize(automaton, alphabet); } diff --git a/util/src/test/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizerTest.java b/util/src/test/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizerTest.java index 332b4c6ca..2d65db679 100644 --- a/util/src/test/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizerTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizerTest.java @@ -16,13 +16,12 @@ package net.automatalib.util.automaton.minimizer; import net.automatalib.alphabet.Alphabet; -import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.MutableDeterministic.FiniteSemantics; +import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.fsa.MutableDFA; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.MutableMealyMachine; -import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.partitionrefinement.PruningMode; import org.testng.annotations.DataProvider; import org.testng.annotations.Factory; @@ -53,8 +52,9 @@ protected DFA minimizeDFA(MutableDFA dfa, Alphabet alphabet) } @Override - protected UniversalSemantics minimizeUniversal(MutableSemantics automaton, - Alphabet alphabet) { + protected UniversalDeterministicAutomaton.FiniteSemantics minimizeUniversal( + FiniteSemantics automaton, + Alphabet alphabet) { return HopcroftMinimizer.minimizeUniversal(automaton, alphabet, this.pruningMode); } diff --git a/util/src/test/java/net/automatalib/util/automaton/minimizer/InvasiveHopcroftTest.java b/util/src/test/java/net/automatalib/util/automaton/minimizer/InvasiveHopcroftTest.java index b4c7f622d..8188e18ad 100644 --- a/util/src/test/java/net/automatalib/util/automaton/minimizer/InvasiveHopcroftTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/minimizer/InvasiveHopcroftTest.java @@ -16,13 +16,12 @@ package net.automatalib.util.automaton.minimizer; import net.automatalib.alphabet.Alphabet; -import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.MutableDeterministic.FiniteSemantics; +import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.fsa.MutableDFA; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.MutableMealyMachine; -import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; public class InvasiveHopcroftTest extends AbstractMinimizationTest { @@ -38,8 +37,9 @@ protected DFA minimizeDFA(MutableDFA dfa, Alphabet alphabet) } @Override - protected UniversalSemantics minimizeUniversal(MutableSemantics automaton, - Alphabet alphabet) { + protected UniversalDeterministicAutomaton.FiniteSemantics minimizeUniversal( + FiniteSemantics automaton, + Alphabet alphabet) { return HopcroftMinimizer.minimizeUniversalInvasive(automaton, alphabet); } diff --git a/util/src/test/java/net/automatalib/util/automaton/minimizer/MinimizerTest.java b/util/src/test/java/net/automatalib/util/automaton/minimizer/MinimizerTest.java index 8b8a48ae9..4d341195e 100644 --- a/util/src/test/java/net/automatalib/util/automaton/minimizer/MinimizerTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/minimizer/MinimizerTest.java @@ -19,7 +19,8 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.alphabet.impl.Alphabets; -import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.MutableDeterministic.FiniteSemantics; +import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.fsa.MutableDFA; import net.automatalib.automaton.fsa.impl.CompactDFA; @@ -28,8 +29,6 @@ import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.MutableMealyMachine; import net.automatalib.automaton.transducer.impl.CompactMealy; -import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.Automata; import net.automatalib.util.minimizer.Block; import net.automatalib.util.minimizer.MinimizationResult; @@ -55,8 +54,9 @@ protected DFA minimizeDFA(MutableDFA dfa, Alphabet alphabet) } @Override - protected UniversalSemantics minimizeUniversal(MutableSemantics automaton, - Alphabet alphabet) { + protected UniversalDeterministicAutomaton.FiniteSemantics minimizeUniversal( + FiniteSemantics automaton, + Alphabet alphabet) { final UniversalCompactDetAutomaton result = new UniversalCompactDetAutomaton<>(alphabet); Automata.minimize(automaton, alphabet, result); return result; diff --git a/util/src/test/java/net/automatalib/util/automaton/minimizer/PartialHopcroftMinimizerTest.java b/util/src/test/java/net/automatalib/util/automaton/minimizer/PartialHopcroftMinimizerTest.java index d10660d76..f495f8fb6 100644 --- a/util/src/test/java/net/automatalib/util/automaton/minimizer/PartialHopcroftMinimizerTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/minimizer/PartialHopcroftMinimizerTest.java @@ -16,13 +16,12 @@ package net.automatalib.util.automaton.minimizer; import net.automatalib.alphabet.Alphabet; -import net.automatalib.automaton.MutableDeterministic; +import net.automatalib.automaton.MutableDeterministic.FiniteSemantics; +import net.automatalib.automaton.UniversalDeterministicAutomaton; import net.automatalib.automaton.fsa.DFA; import net.automatalib.automaton.fsa.MutableDFA; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.automaton.transducer.MutableMealyMachine; -import net.automatalib.semantics.DeterministicFiniteSemantics.MutableSemantics; -import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.partitionrefinement.PruningMode; import org.testng.annotations.DataProvider; import org.testng.annotations.Factory; @@ -53,8 +52,9 @@ protected DFA minimizeDFA(MutableDFA dfa, Alphabet alphabet) } @Override - protected UniversalSemantics minimizeUniversal(MutableSemantics automaton, - Alphabet alphabet) { + protected UniversalDeterministicAutomaton.FiniteSemantics minimizeUniversal( + FiniteSemantics automaton, + Alphabet alphabet) { return HopcroftMinimizer.minimizePartialUniversal(automaton, alphabet, this.pruningMode); } diff --git a/util/src/test/java/net/automatalib/util/automaton/procedural/SPAsTest.java b/util/src/test/java/net/automatalib/util/automaton/procedural/SPAsTest.java index bdcdc0dac..610065563 100644 --- a/util/src/test/java/net/automatalib/util/automaton/procedural/SPAsTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/procedural/SPAsTest.java @@ -40,11 +40,13 @@ import net.automatalib.automaton.procedural.impl.StackSPA; import net.automatalib.automaton.vpa.OneSEVPA; import net.automatalib.automaton.vpa.SEVPA; +import net.automatalib.automaton.vpa.State; import net.automatalib.common.util.IOUtil; import net.automatalib.common.util.collection.IteratorUtil; import net.automatalib.graph.ContextFreeModalProcessSystem; import net.automatalib.graph.ProceduralModalProcessGraph; import net.automatalib.serialization.dot.GraphDOT; +import net.automatalib.ts.acceptor.DeterministicAcceptorTS; import net.automatalib.util.automaton.builder.AutomatonBuilders; import net.automatalib.util.automaton.conformance.SPATestsIterator; import net.automatalib.util.automaton.conformance.WMethodTestsIterator; @@ -559,23 +561,25 @@ public void testEquivalence() { @Test(dataProvider = "systems") public void testOneSEVPAConversion(SPA spa) { - final OneSEVPA oneSEVPA = SPAs.toOneSEVPA(spa); + final OneSEVPA sevpa = SPAs.toOneSEVPA(spa); + final DeterministicAcceptorTS, I> semantics = sevpa.getSemantics(); final List> tests = IteratorUtil.list(new SPATestsIterator<>(spa, WMethodTestsIterator::new)); for (Word t : tests) { - Assert.assertEquals(spa.accepts(t), oneSEVPA.accepts(t)); + Assert.assertEquals(spa.accepts(t), semantics.accepts(t)); } } @Test(dataProvider = "systems") public void testNSEVPAConversion(SPA spa) { final SEVPA sevpa = SPAs.toNSEVPA(spa); + final DeterministicAcceptorTS, I> semantics = sevpa.getSemantics(); final List> tests = IteratorUtil.list(new SPATestsIterator<>(spa, WMethodTestsIterator::new)); for (Word t : tests) { - Assert.assertEquals(spa.accepts(t), sevpa.accepts(t)); + Assert.assertEquals(spa.accepts(t), semantics.accepts(t)); } } diff --git a/util/src/test/java/net/automatalib/util/automaton/vpa/OneSEVPAsTest.java b/util/src/test/java/net/automatalib/util/automaton/vpa/OneSEVPAsTest.java index f8df6d395..30ee052eb 100644 --- a/util/src/test/java/net/automatalib/util/automaton/vpa/OneSEVPAsTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/vpa/OneSEVPAsTest.java @@ -33,7 +33,8 @@ import net.automatalib.automaton.vpa.impl.Location; import net.automatalib.common.util.HashUtil; import net.automatalib.common.util.Pair; -import net.automatalib.common.util.array.ArrayStorage; +import net.automatalib.common.util.mapping.Mapping; +import net.automatalib.ts.acceptor.DeterministicAcceptorTS; import net.automatalib.util.automaton.conformance.SPATestsIterator; import net.automatalib.util.automaton.conformance.WpMethodTestsIterator; import net.automatalib.util.automaton.random.RandomAutomata; @@ -67,12 +68,14 @@ public static Object[][] getSPASystems() { @Test(dataProvider = "systems") public void testAccessSequenceSet(OneSEVPA sevpa) { final VPAlphabet alphabet = sevpa.getInputAlphabet(); + final DeterministicAcceptorTS, I> semantics = sevpa.getSemantics(); - final ArrayStorage> accessSequences = OneSEVPAs.computeAccessSequences(sevpa, alphabet); + final Mapping> accessSequences = OneSEVPAs.computeAccessSequences(sevpa, alphabet); final Set locations = new HashSet<>(HashUtil.capacity(sevpa.size())); - for (Word as : accessSequences) { - final State s = sevpa.getState(as); + for (L loc : sevpa.getStates()) { + final Word as = accessSequences.get(loc); + final State s = semantics.getState(as); Assert.assertNotNull(s); Assert.assertTrue(locations.add(s.getLocation())); } @@ -86,16 +89,17 @@ public void testReachableLocations(OneSEVPA sevpa) { final List reachableLocations = OneSEVPAs.findReachableLocations(sevpa, alphabet); - Assert.assertEquals(new HashSet<>(reachableLocations), new HashSet<>(sevpa.getLocations())); + Assert.assertEquals(new HashSet<>(reachableLocations), new HashSet<>(sevpa.getStates())); } @Test(dataProvider = "systems") public void testFindSeparatingWord(OneSEVPA sevpa) { final VPAlphabet alphabet = sevpa.getInputAlphabet(); - final ArrayStorage> as = OneSEVPAs.computeAccessSequences(sevpa, alphabet); + final DeterministicAcceptorTS, I> semantics = sevpa.getSemantics(); + final Mapping> as = OneSEVPAs.computeAccessSequences(sevpa, alphabet); - for (L l1 : sevpa.getLocations()) { - for (L l2 : sevpa.getLocations()) { + for (L l1 : sevpa.getStates()) { + for (L l2 : sevpa.getStates()) { final Pair, Word> sepWord = OneSEVPAs.findSeparatingWord(sevpa, l1, l2, alphabet); if (Objects.equals(l1, l2)) { @@ -104,8 +108,8 @@ public void testFindSeparatingWord(OneSEVPA sevpa) { Assert.assertNotNull(sepWord); final Word pref = sepWord.getFirst(); final Word suff = sepWord.getSecond(); - Assert.assertNotEquals(sevpa.accepts(Word.fromWords(pref, as.get(sevpa.getLocationId(l1)), suff)), - sevpa.accepts(Word.fromWords(pref, as.get(sevpa.getLocationId(l2)), suff))); + Assert.assertNotEquals(semantics.accepts(Word.fromWords(pref, as.get(l1), suff)), + semantics.accepts(Word.fromWords(pref, as.get(l2), suff))); } } } @@ -114,20 +118,21 @@ public void testFindSeparatingWord(OneSEVPA sevpa) { @Test(dataProvider = "systems") public void testCharacterizingSet(OneSEVPA sevpa) { final VPAlphabet alphabet = sevpa.getInputAlphabet(); - final ArrayStorage> accessSequences = OneSEVPAs.computeAccessSequences(sevpa, alphabet); + final DeterministicAcceptorTS, I> semantics = sevpa.getSemantics(); + final Mapping> accessSequences = OneSEVPAs.computeAccessSequences(sevpa, alphabet); final List, Word>> cSet = new ArrayList<>(OneSEVPAs.findCharacterizingSet(sevpa, alphabet)); final Set signatures = new HashSet<>(HashUtil.capacity(sevpa.size())); - for (L l : sevpa.getLocations()) { - final Word as = accessSequences.get(sevpa.getLocationId(l)); + for (L l : sevpa.getStates()) { + final Word as = accessSequences.get(l); final boolean[] signature = new boolean[cSet.size()]; int idx = 0; for (Pair, Word> p : cSet) { final Word w = Word.fromWords(p.getFirst(), as, p.getSecond()); Assert.assertTrue(alphabet.isWellMatched(w)); - signature[idx++] = sevpa.accepts(w); + signature[idx++] = semantics.accepts(w); } Assert.assertTrue(signatures.add(signature)); @@ -139,19 +144,21 @@ public void testCharacterizingSet(OneSEVPA sevpa) { @Test(dataProvider = "spaSystems") public void testToSPA(OneSEVPA sevpa, boolean minimize) { final VPAlphabet alphabet = sevpa.getInputAlphabet(); + final DeterministicAcceptorTS, I> semantics = sevpa.getSemantics(); final String mainProcedure = "main"; - final ArrayStorage> accessSequences = OneSEVPAs.computeAccessSequences(sevpa, alphabet); + final Mapping> accessSequences = OneSEVPAs.computeAccessSequences(sevpa, alphabet); final List, Word>> cSet = new ArrayList<>(OneSEVPAs.findCharacterizingSet(sevpa, alphabet)); final ConversionResult conversionResult = OneSEVPAs.toSPA(sevpa, alphabet, mainProcedure, new StringSymbolMapper<>(), minimize); - for (Word as : accessSequences) { + for (L loc : sevpa.getStates()) { + final Word as = accessSequences.get(loc); for (Pair, Word> cs : cSet) { final Word w = Word.fromWords(cs.getFirst(), as, cs.getSecond()); final Word mapped = conversionResult.mapper.apply(w); - Assert.assertEquals(conversionResult.spa.accepts(mapped), sevpa.accepts(w), w + " -> " + mapped); + Assert.assertEquals(conversionResult.spa.accepts(mapped), semantics.accepts(w), w + " -> " + mapped); } } @@ -167,7 +174,9 @@ public void testToSPA(OneSEVPA sevpa, boolean minimize) { final Word w = cropped.transform(conversionResult.reverseMapping::get); final Word mapped = conversionResult.mapper.apply(w); - Assert.assertEquals(conversionResult.spa.accepts(mapped), sevpa.accepts(w), w + " -> " + mapped); + Assert.assertEquals(conversionResult.spa.accepts(mapped), + semantics.accepts(w), + w + " -> " + mapped); } } } @@ -214,7 +223,7 @@ private static void addRedundantState(DefaultOneSEVPA automaton, VPAlphab Location locToCopy = null; outer: - for (Location l : automaton.getLocations()) { + for (Location l : automaton.getStates()) { for (I i : alphabet.getInternalAlphabet()) { final Location succ = automaton.getInternalSuccessor(l, i); if (!locationCache.add(succ)) { @@ -230,8 +239,8 @@ private static void addRedundantState(DefaultOneSEVPA automaton, VPAlphab Assert.assertNotNull(incomingInput); Assert.assertNotNull(locToCopy); - final Set oldStates = new HashSet<>(automaton.getLocations()); - final Location locCopy = automaton.addLocation(automaton.isAcceptingLocation(locToCopy)); + final Set oldStates = new HashSet<>(automaton.getStates()); + final Location locCopy = automaton.addLocation(automaton.getStateProperty(locToCopy)); // make return transitions of old states behave identical for the new stack symbol for (I callSym : alphabet.getCallAlphabet()) { @@ -310,14 +319,14 @@ private static DefaultOneSEVPA getCCARCBRRSystem() { result.setReturnSuccessor(l3, 'r', s2, l4); result.setReturnSuccessor(l4, 'r', s0, l5); - for (Location l : result.getLocations()) { + for (Location l : result.getStates()) { for (Character i : internalAlphabet) { final Location succ = result.getInternalSuccessor(l, i); if (succ == null) { result.setInternalSuccessor(l, i, l6); } } - for (Location s : result.getLocations()) { + for (Location s : result.getStates()) { final int sym = result.encodeStackSym(s, (Character) 'c'); final Location succ = result.getReturnSuccessor(l, 'r', sym); if (succ == null) { From 5afa949a67fa6a856b0885ac6e857f113f9a35d7 Mon Sep 17 00:00:00 2001 From: Markus Frohme Date: Mon, 22 Jun 2026 23:55:50 +0200 Subject: [PATCH 4/8] consolidations --- CHANGELOG.md | 20 +++-- api/pom.xml | 5 ++ api/src/main/java/module-info.java | 2 +- .../net/automatalib/automaton/Automaton.java | 10 +++ .../automaton/DeterministicAutomaton.java | 14 +++- .../automaton/MutableAutomaton.java | 25 ++++-- .../automaton/MutableDeterministic.java | 25 ++++-- .../automaton/UniversalAutomaton.java | 25 ++++-- .../UniversalDeterministicAutomaton.java | 26 ++++-- .../automaton/concept/InitialState.java | 52 ++++++++++++ .../automaton/concept/InitialStates.java | 37 +++++++++ .../automatalib/automaton/package-info.java | 8 +- .../MutableProbabilisticMealy.java | 8 +- .../ProbabilisticMealyMachine.java | 9 +-- .../automatalib/automaton/vpa/OneSEVPA.java | 10 +-- .../net/automatalib/automaton/vpa/SEVPA.java | 51 ++++++------ .../automaton/vpa/SEVPAGraphView.java | 36 +++++---- .../automaton/vpa/SEVPASemantics.java | 18 ++--- .../net/automatalib/graph/CFMPSGraphView.java | 6 +- .../CFMPSVisualizationHelper.java | 3 +- .../DeterministicFiniteSemantics.java | 3 + .../semantic/DeterministicSemantics.java | 3 + .../automatalib/semantic/FiniteSemantics.java | 3 + .../net/automatalib/semantic/Semantics.java | 8 ++ .../automatalib/semantic/package-info.java | 25 ++++++ .../net/automatalib/ts/simple/SimpleDTS.java | 28 +------ .../net/automatalib/ts/simple/SimpleTS.java | 10 +-- .../automatalib/automaton/SemanticsTest.java | 80 +++++++++++++++++++ .../automaton/base/AbstractCompact.java | 4 +- .../impl/UniversalCompactDetAutomaton.java | 11 +-- .../vpa/impl/AbstractDefaultSEVPA.java | 15 ++-- .../automaton/vpa/impl/DefaultNSEVPA.java | 6 +- .../automaton/vpa/impl/Location.java | 2 +- .../impl/MutableFullIntAbstractionTest.java | 10 +-- .../impl/MutableStateIntAbstractionTest.java | 16 ++-- .../automaton/impl/MutableAutomatonTest.java | 10 +++ .../automaton/vpa/impl/DefaultVPATest.java | 14 ++-- .../java/net/automatalib/example/Example.java | 37 --------- .../example/vpa/OneSEVPAExample.java | 6 +- .../automatalib/util/automaton/Automata.java | 3 +- .../IncrementalWMethodTestsIterator.java | 3 +- .../conformance/WpMethodTestsIterator.java | 3 +- .../util/automaton/cover/Covers.java | 3 +- .../IncrementalTransitionCoverIterator.java | 2 +- .../minimizer/HopcroftMinimizer.java | 2 +- .../minimizer/OneSEVPAMinimizer.java | 4 +- .../automaton/procedural/NSEVPAConverter.java | 8 +- .../procedural/OneSEVPAConverter.java | 8 +- .../automaton/procedural/ProceduralUtil.java | 2 +- .../util/automaton/random/RandomAutomata.java | 6 +- .../HopcroftExtractors.java | 41 +++++----- .../ValmariExtractors.java | 31 +++---- .../ValmariInitializers.java | 4 +- .../equivalence/BisimulationTest.java | 4 +- .../util/automaton/vpa/OneSEVPAsTest.java | 16 ++-- 55 files changed, 531 insertions(+), 290 deletions(-) create mode 100644 api/src/main/java/net/automatalib/automaton/concept/InitialState.java create mode 100644 api/src/main/java/net/automatalib/automaton/concept/InitialStates.java create mode 100644 api/src/main/java/net/automatalib/semantic/package-info.java create mode 100644 api/src/test/java/net/automatalib/automaton/SemanticsTest.java delete mode 100644 examples/src/main/java/net/automatalib/example/Example.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e0594b41..2087d1163 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added * A new formalism for *Mealy machines with local timers* (MMLTs) including means for conformance testing and equivalence checking has been added (thanks to [Paul Kogel](https://github.com/pdev55)). +* With the introduction of `MMLT`s which are finite-state systems structurally but infinite-state systems semantically, AutomataLib now more rigorously distinguishes between these two concepts by introducing (and at some points requiring) specific `{Finite,}Semantics` types. For automaton types that are inherently finite-state (e.g., `DFA`s, `MealyMachine`s, etc.), this should not require any refactoring. * Added a new `automata-serialization-mata` module for serializing (explicit) NFAs in the `.mata` format as used by the [mata library](https://github.com/VeriFIT/mata). * `automata-modelchecking-m3c` now supports ARM-based macOS systems. * `automata-modelchecking-m3c` can now be included in jlink images. @@ -21,14 +22,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Changed * AutomataLib now requires Java 17 at runtime. -* The following classes have been refactored to `record`s: - * `BricsTransitionProperty` - * `TransitionEdge{,.Property}` - * `ProbabilisticOutput` - * `LTSminVersion` -* The following class hierarchies have been made `sealed`: - * `CommonAttrs` - * `CommonStyles` + * The following classes have been refactored to `record`s: + * `BricsTransitionProperty` + * `TransitionEdge{,.Property}` + * `ProbabilisticOutput` + * `LTSminVersion` + * The following class hierarchies have been made `sealed`: + * `CommonAttrs` + * `CommonStyles` +* `SEVPA`s have been adjusted to the new structure/semantics split, by now implementing `UniversalAutomaton` and `DeterministicSemantics`. +* The `IntAbstraction` interfaces have been moved to their respective implementations in the `net.automatalib.automaton.abstraction` package. +* The `ShrinkableAutomaton` interface has been replaced with the `Shrinkable` concept. * The `compute{State,Suffix,}Output` concepts from `Det{Suffix,}OutputAutomaton` have been lifted to infinite-state transition systems. As part of this refactoring, some inconsistencies have been addressed. Previously, for `Word`-output systems, `computeSuffixOutput` threw an `UndefinedPropertyAccessException` if the prefix traversed an undefined transition but not if the suffix did (here, the output would only be cut short). Now, both methods simply early-exit output computation. Furthermore, these changes also include the following renamings: * `DetOutputAutomaton` -> `DeterministicOutputAutomaton` * `DetSuffixOutputAutomaton` -> `DeterministicSuffixOutputAutomaton` diff --git a/api/pom.xml b/api/pom.xml index a8f5a3d00..c9f7fa126 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -64,6 +64,11 @@ limitations under the License. + + org.mockito + mockito-core + + org.testng testng diff --git a/api/src/main/java/module-info.java b/api/src/main/java/module-info.java index 8e68179b9..1702b7416 100644 --- a/api/src/main/java/module-info.java +++ b/api/src/main/java/module-info.java @@ -61,8 +61,8 @@ exports net.automatalib.graph.helper; exports net.automatalib.graph.visualization; exports net.automatalib.modelchecking; - exports net.automatalib.serialization; exports net.automatalib.semantic; + exports net.automatalib.serialization; exports net.automatalib.symbol.time; exports net.automatalib.ts; exports net.automatalib.ts.acceptor; diff --git a/api/src/main/java/net/automatalib/automaton/Automaton.java b/api/src/main/java/net/automatalib/automaton/Automaton.java index 9791228cb..fed76b522 100644 --- a/api/src/main/java/net/automatalib/automaton/Automaton.java +++ b/api/src/main/java/net/automatalib/automaton/Automaton.java @@ -48,6 +48,16 @@ default Graph> transitionGraphView(Collection(this, inputs); } + /** + * Convenience interface that links an {@link Automaton} with {@link net.automatalib.semantic.FiniteSemantics}. + * + * @param + * state type + * @param + * input symbol type + * @param + * transition type + */ interface FiniteSemantics extends Automaton, net.automatalib.semantic.FiniteSemantics { @Override diff --git a/api/src/main/java/net/automatalib/automaton/DeterministicAutomaton.java b/api/src/main/java/net/automatalib/automaton/DeterministicAutomaton.java index 98b4fb01e..554cdf08a 100644 --- a/api/src/main/java/net/automatalib/automaton/DeterministicAutomaton.java +++ b/api/src/main/java/net/automatalib/automaton/DeterministicAutomaton.java @@ -23,7 +23,7 @@ import net.automatalib.automaton.abstraction.DeterministicAbstractions.StateIntAbstraction; import net.automatalib.automaton.abstraction.DeterministicAbstractions.StateIntAbstractionImpl; import net.automatalib.automaton.simple.SimpleDeterministicAutomaton; -import net.automatalib.semantic.DeterministicSemantics; +import net.automatalib.semantic.DeterministicFiniteSemantics; import net.automatalib.ts.DeterministicTransitionSystem; /** @@ -55,8 +55,18 @@ default StateIntAbstraction stateIntAbstraction() { return new StateIntAbstractionImpl<>(this); } + /** + * Convenience interface that links a {@link DeterministicAutomaton} with {@link DeterministicFiniteSemantics}. + * + * @param + * state type + * @param + * input symbol type + * @param + * transition type + */ interface FiniteSemantics - extends DeterministicAutomaton, Automaton.FiniteSemantics, DeterministicSemantics { + extends DeterministicAutomaton, Automaton.FiniteSemantics, DeterministicFiniteSemantics { @Override default DeterministicAutomaton getSemantics() { diff --git a/api/src/main/java/net/automatalib/automaton/MutableAutomaton.java b/api/src/main/java/net/automatalib/automaton/MutableAutomaton.java index 1af047605..69566df6b 100644 --- a/api/src/main/java/net/automatalib/automaton/MutableAutomaton.java +++ b/api/src/main/java/net/automatalib/automaton/MutableAutomaton.java @@ -29,15 +29,15 @@ * removed, then {@link Shrinkable} is the adequate interface. * * @param - * state class. + * state type * @param - * input symbol class. + * input symbol type * @param - * transition class. + * transition type * @param - * state property. + * state property type * @param - * transition property. + * transition property type */ public interface MutableAutomaton extends UniversalAutomaton { @@ -139,6 +139,21 @@ default T copyTransition(T trans, S succ) { return createTransition(succ, property); } + /** + * Convenience interface that links a {@link MutableAutomaton} with + * {@link net.automatalib.semantic.FiniteSemantics}. + * + * @param + * state type + * @param + * input symbol type + * @param + * transition type + * @param + * state property type + * @param + * transition property type + */ interface FiniteSemantics extends MutableAutomaton, UniversalAutomaton.FiniteSemantics {} diff --git a/api/src/main/java/net/automatalib/automaton/MutableDeterministic.java b/api/src/main/java/net/automatalib/automaton/MutableDeterministic.java index 8ef7a243d..962147b43 100644 --- a/api/src/main/java/net/automatalib/automaton/MutableDeterministic.java +++ b/api/src/main/java/net/automatalib/automaton/MutableDeterministic.java @@ -24,21 +24,22 @@ import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions.FullIntAbstractionImpl; import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions.StateIntAbstraction; import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions.StateIntAbstractionImpl; +import net.automatalib.semantic.DeterministicFiniteSemantics; import org.checkerframework.checker.nullness.qual.Nullable; /** * Interface for a mutable deterministic automaton. * * @param - * state class. + * state type * @param - * input symbol class. + * input symbol type * @param - * transition class. + * transition type * @param - * state property. + * state property type * @param - * transition property. + * transition property type */ public interface MutableDeterministic extends UniversalDeterministicAutomaton, MutableAutomaton { @@ -159,6 +160,20 @@ default StateIntAbstraction stateIntAbstraction() { return new StateIntAbstractionImpl<>(this); } + /** + * Convenience interface that links a {@link MutableDeterministic} with {@link DeterministicFiniteSemantics}. + * + * @param + * state type + * @param + * input symbol type + * @param + * transition type + * @param + * state property type + * @param + * transition property type + */ interface FiniteSemantics extends MutableDeterministic, MutableAutomaton.FiniteSemantics, UniversalDeterministicAutomaton.FiniteSemantics {} diff --git a/api/src/main/java/net/automatalib/automaton/UniversalAutomaton.java b/api/src/main/java/net/automatalib/automaton/UniversalAutomaton.java index 7c0e6fa9d..ea7b1bbac 100644 --- a/api/src/main/java/net/automatalib/automaton/UniversalAutomaton.java +++ b/api/src/main/java/net/automatalib/automaton/UniversalAutomaton.java @@ -28,15 +28,15 @@ * and transitions. See {@link UniversalTransitionSystem} for a further explanation of this concept. * * @param - * state class + * state type * @param - * input symbol class + * input symbol type * @param - * transition class + * transition type * @param - * state property class + * state property type * @param - * transition property class + * transition property type */ public interface UniversalAutomaton extends Automaton, UniversalTransitionSystem { @@ -46,6 +46,21 @@ default UniversalGraph, SP, Property> transitionG return new UniversalAutomatonGraphView<>(this, inputs); } + /** + * Convenience interface that links a {@link UniversalAutomaton} with + * {@link net.automatalib.semantic.FiniteSemantics}. + * + * @param + * state type + * @param + * input symbol type + * @param + * transition type + * @param + * state property type + * @param + * transition property type + */ interface FiniteSemantics extends UniversalAutomaton, Automaton.FiniteSemantics { diff --git a/api/src/main/java/net/automatalib/automaton/UniversalDeterministicAutomaton.java b/api/src/main/java/net/automatalib/automaton/UniversalDeterministicAutomaton.java index fc2621db6..e6e5bfa6c 100644 --- a/api/src/main/java/net/automatalib/automaton/UniversalDeterministicAutomaton.java +++ b/api/src/main/java/net/automatalib/automaton/UniversalDeterministicAutomaton.java @@ -22,21 +22,22 @@ import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.FullIntAbstractionImpl; import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.StateIntAbstraction; import net.automatalib.automaton.abstraction.UniversalDeterministicAbstractions.StateIntAbstractionImpl; +import net.automatalib.semantic.DeterministicFiniteSemantics; import net.automatalib.ts.UniversalDTS; /** * A {@link DeterministicAutomaton} with state and transition properties. * * @param - * state class + * state type * @param - * input symbol class + * input symbol type * @param - * transition class + * transition type * @param - * state property class + * state property type * @param - * transition property class + * transition property type * * @see UniversalAutomaton */ @@ -58,6 +59,21 @@ default StateIntAbstraction stateIntAbstraction() { return new StateIntAbstractionImpl<>(this); } + /** + * Convenience interface that links a {@link UniversalDeterministicAutomaton} with + * {@link DeterministicFiniteSemantics}. + * + * @param + * state type + * @param + * input symbol type + * @param + * transition type + * @param + * state property type + * @param + * transition property type + */ interface FiniteSemantics extends UniversalDeterministicAutomaton, DeterministicAutomaton.FiniteSemantics, UniversalAutomaton.FiniteSemantics { diff --git a/api/src/main/java/net/automatalib/automaton/concept/InitialState.java b/api/src/main/java/net/automatalib/automaton/concept/InitialState.java new file mode 100644 index 000000000..5ffcd2200 --- /dev/null +++ b/api/src/main/java/net/automatalib/automaton/concept/InitialState.java @@ -0,0 +1,52 @@ +/* Copyright (C) 2013-2026 TU Dortmund University + * This file is part of AutomataLib . + * + * 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 net.automatalib.automaton.concept; + +import java.util.Collections; +import java.util.Set; + +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * The concept of providing a single (potentially undefined) initial state. + * + * @param + * state type + */ +@FunctionalInterface +public interface InitialState extends InitialStates { + + /** + * Retrieves the initial state of a transition system. + * + * @return the initial state. + * + * @see InitialStates#getInitialStates() + */ + @Nullable S getInitialState(); + + @Override + default Set getInitialStates() { + return stateToSet(getInitialState()); + } + + static Set stateToSet(@Nullable S state) { + if (state == null) { + return Collections.emptySet(); + } + return Collections.singleton(state); + } +} diff --git a/api/src/main/java/net/automatalib/automaton/concept/InitialStates.java b/api/src/main/java/net/automatalib/automaton/concept/InitialStates.java new file mode 100644 index 000000000..e321e959e --- /dev/null +++ b/api/src/main/java/net/automatalib/automaton/concept/InitialStates.java @@ -0,0 +1,37 @@ +/* Copyright (C) 2013-2026 TU Dortmund University + * This file is part of AutomataLib . + * + * 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 net.automatalib.automaton.concept; + +import java.util.Set; + +/** + * The concept of providing (potentially multiple) initial states. + * + * @param + * state type + */ +@FunctionalInterface +public interface InitialStates { + + /** + * Retrieves the set of initial states of a transition system. + * + * @return the initial states. + */ + Set getInitialStates(); + +} + diff --git a/api/src/main/java/net/automatalib/automaton/package-info.java b/api/src/main/java/net/automatalib/automaton/package-info.java index fcb4eb2fb..a209d75c0 100644 --- a/api/src/main/java/net/automatalib/automaton/package-info.java +++ b/api/src/main/java/net/automatalib/automaton/package-info.java @@ -22,8 +22,10 @@ * nondeterministic, but can be specialized to be * {@link net.automatalib.automaton.DeterministicAutomaton deterministic}. *

- * The {@link net.automatalib.automaton.Automaton Automaton} interface has no inherent semantics. Special types of - * automata, such as {@link net.automatalib.automaton.fsa.DFA DFAs} or - * {@link net.automatalib.automaton.transducer.MealyMachine Mealy machines} can be found in the respective subpackages. + * The general automaton types mostly describe structural properties whereas semantic interpretations are defined in the + * {@link net.automatalib.semantic semantic package}. However, specific types such as + * {@link net.automatalib.automaton.fsa.DFA DFAs} or + * {@link net.automatalib.automaton.transducer.MealyMachine Mealy machines} often provide default implementations for + * convenience. */ package net.automatalib.automaton; diff --git a/api/src/main/java/net/automatalib/automaton/transducer/probabilistic/MutableProbabilisticMealy.java b/api/src/main/java/net/automatalib/automaton/transducer/probabilistic/MutableProbabilisticMealy.java index 476f62e2e..729e643a3 100644 --- a/api/src/main/java/net/automatalib/automaton/transducer/probabilistic/MutableProbabilisticMealy.java +++ b/api/src/main/java/net/automatalib/automaton/transducer/probabilistic/MutableProbabilisticMealy.java @@ -15,14 +15,14 @@ */ package net.automatalib.automaton.transducer.probabilistic; -import net.automatalib.automaton.MutableAutomaton; +import net.automatalib.automaton.MutableAutomaton.FiniteSemantics; import net.automatalib.automaton.concept.MutableProbabilistic; import net.automatalib.automaton.concept.MutableTransitionOutput; -public interface MutableProbabilisticMealy extends ProbabilisticMealyMachine, +public interface MutableProbabilisticMealy extends FiniteSemantics>, + ProbabilisticMealyMachine, MutableTransitionOutput, - MutableProbabilistic, - MutableAutomaton> { + MutableProbabilistic { @Override default void setStateProperty(S state, Void property) {} diff --git a/api/src/main/java/net/automatalib/automaton/transducer/probabilistic/ProbabilisticMealyMachine.java b/api/src/main/java/net/automatalib/automaton/transducer/probabilistic/ProbabilisticMealyMachine.java index 99e0f010b..3bbb3628e 100644 --- a/api/src/main/java/net/automatalib/automaton/transducer/probabilistic/ProbabilisticMealyMachine.java +++ b/api/src/main/java/net/automatalib/automaton/transducer/probabilistic/ProbabilisticMealyMachine.java @@ -15,15 +15,12 @@ */ package net.automatalib.automaton.transducer.probabilistic; -import net.automatalib.automaton.Automaton; +import net.automatalib.automaton.UniversalAutomaton.FiniteSemantics; import net.automatalib.automaton.concept.Probabilistic; import net.automatalib.automaton.concept.TransitionOutput; -import net.automatalib.ts.UniversalTransitionSystem; -public interface ProbabilisticMealyMachine extends Automaton, - TransitionOutput, - UniversalTransitionSystem>, - Probabilistic { +public interface ProbabilisticMealyMachine + extends FiniteSemantics>, TransitionOutput, Probabilistic { @Override default Void getStateProperty(S state) { diff --git a/api/src/main/java/net/automatalib/automaton/vpa/OneSEVPA.java b/api/src/main/java/net/automatalib/automaton/vpa/OneSEVPA.java index 332b2e27f..ab7f0caae 100644 --- a/api/src/main/java/net/automatalib/automaton/vpa/OneSEVPA.java +++ b/api/src/main/java/net/automatalib/automaton/vpa/OneSEVPA.java @@ -16,15 +16,15 @@ package net.automatalib.automaton.vpa; /** - * A specialized interface for 1-SEVPAs (1-module single entry visibly push-down automata). Note that contrary to the - * original definition of Alur et al. where 1-SEVPAs consist of one (separate) "main" module and one module for all call - * symbols, this implementation assumes a single module for both the "main" procedure and all call symbols, i.e., the - * initial location and all module entries coincide. + * A specialized interface for 1-{@link SEVPA}s. Contrary to the original definition of Alur et al. where 1-SEVPAs + * consist of one (separate) "main" module and one module for all call symbols, this implementation assumes a single + * module for both the "main" procedure and all call symbols, i.e., the initial location and all module entries + * coincide. * * @param * location type * @param - * input alphabet type + * input symbol type */ public interface OneSEVPA extends SEVPA { diff --git a/api/src/main/java/net/automatalib/automaton/vpa/SEVPA.java b/api/src/main/java/net/automatalib/automaton/vpa/SEVPA.java index 362859c9f..3aad9c73b 100644 --- a/api/src/main/java/net/automatalib/automaton/vpa/SEVPA.java +++ b/api/src/main/java/net/automatalib/automaton/vpa/SEVPA.java @@ -19,10 +19,10 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.Set; import net.automatalib.alphabet.VPAlphabet; import net.automatalib.automaton.UniversalAutomaton; +import net.automatalib.automaton.concept.InitialState; import net.automatalib.automaton.concept.InputAlphabetHolder; import net.automatalib.automaton.vpa.SEVPAGraphView.SevpaViewEdge; import net.automatalib.graph.Graph; @@ -38,13 +38,20 @@ *

* For more information on the semantics of VPAs see e.g. Congruences for * Visibly Pushdown Languages by Alur, Kumar, Madhusudan and Viswanathan. + *

+ * Note that this formalism integrates into the hierarchy of a non-deterministic {@link UniversalAutomaton} because a + * single return symbol may identify multiple transitions depending on the current top-of-stack symbol. Via + * {@link #getInternalSuccessor(Object, Object)} and {@link #getReturnSuccessor(Object, Object, int)}, these + * information can be accessed deterministically. As a result, its states act more like locations than actual + * states. A (deterministic, infinite-state) semantics view can be obtained via the {@link #getSemantics()} method. * - * @param + * @param * location type * @param - * input alphabet type + * input symbol type */ -public interface SEVPA extends UniversalAutomaton, +public interface SEVPA extends UniversalAutomaton, + InitialState, DeterministicSemantics, GraphViewable, InputAlphabetHolder { @@ -52,46 +59,38 @@ public interface SEVPA extends UniversalAutomaton, @Override VPAlphabet getInputAlphabet(); - S getModuleEntry(I callSym); + L getModuleEntry(I callSym); int getNumStackSymbols(); - int encodeStackSym(S srcLoc, I callSym); - - @Nullable - S getInternalSuccessor(S loc, I intSym); + int encodeStackSym(L srcLoc, I callSym); - @Nullable - S getReturnSuccessor(S loc, I retSym, int stackSym); + @Nullable L getInternalSuccessor(L loc, I intSym); - @Nullable - S getInitialState(); + @Nullable L getReturnSuccessor(L loc, I retSym, int stackSym); - @Override - default Set getInitialStates() { - final S init = getInitialState(); - return init == null ? Collections.emptySet() : Collections.singleton(init); - } + @Override // do not allow nullable initial state + L getInitialState(); @Override - default Void getTransitionProperty(S transition) { + default Void getTransitionProperty(L transition) { return null; } @Override - default Collection getTransitions(S state, I input) { + default Collection getTransitions(L state, I input) { final VPAlphabet alphabet = getInputAlphabet(); return switch (alphabet.getSymbolType(input)) { case CALL: yield Collections.singleton(getModuleEntry(input)); case INTERNAL: - final S iSucc = getInternalSuccessor(state, input); + final L iSucc = getInternalSuccessor(state, input); yield iSucc == null ? Collections.emptyList() : Collections.singleton(iSucc); case RETURN: final int symbols = getNumStackSymbols(); - final List result = new ArrayList<>(symbols); + final List result = new ArrayList<>(symbols); for (int i = 0; i < symbols; i++) { - final S rSucc = getReturnSuccessor(state, input, i); + final L rSucc = getReturnSuccessor(state, input, i); if (rSucc != null) { result.add(rSucc); } @@ -101,17 +100,17 @@ default Collection getTransitions(S state, I input) { } @Override - default S getSuccessor(S transition) { + default L getSuccessor(L transition) { return transition; } @Override - default DeterministicAcceptorTS, I> getSemantics() { + default DeterministicAcceptorTS, I> getSemantics() { return new SEVPASemantics<>(this); } @Override - default Graph> graphView() { + default Graph> graphView() { return new SEVPAGraphView<>(this); } } diff --git a/api/src/main/java/net/automatalib/automaton/vpa/SEVPAGraphView.java b/api/src/main/java/net/automatalib/automaton/vpa/SEVPAGraphView.java index 18fa64d6e..3a990d8bc 100644 --- a/api/src/main/java/net/automatalib/automaton/vpa/SEVPAGraphView.java +++ b/api/src/main/java/net/automatalib/automaton/vpa/SEVPAGraphView.java @@ -75,7 +75,7 @@ public Collection> getOutgoingEdges(L location) { final L succ = sevpa.getReturnSuccessor(location, i, sym); if (succ != null) { - result.add(new SevpaViewEdge<>(i, succ, loc, stackSymbol)); + result.add(new SevpaViewEdge<>(i, succ, loc, stackSymbol, stateIDs)); } } } @@ -95,7 +95,7 @@ public VisualizationHelper> getVisualizationHelper() { @Override protected Collection initialNodes() { - return Collections.singleton(sevpa.getInitialState()); + return Collections.unmodifiableCollection(sevpa.getInitialStates()); } @Override @@ -114,13 +114,7 @@ public boolean getNodeProperties(L node, Map properties) { public boolean getEdgeProperties(L src, SevpaViewEdge edge, L tgt, Map properties) { super.getEdgeProperties(src, edge, tgt, properties); - final I input = edge.input; - if (alphabet.isReturnSymbol(input)) { - properties.put(EdgeAttrs.LABEL, - input + "/(L" + stateIDs.getStateId(edge.callLoc) + ',' + edge.callSymbol + ')'); - } else { - properties.put(EdgeAttrs.LABEL, String.valueOf(input)); - } + properties.put(EdgeAttrs.LABEL, edge.label); return true; } @@ -131,19 +125,29 @@ public static class SevpaViewEdge { public final I input; public final S target; + public final String label; - public final S callLoc; + public final @Nullable S callLoc; public final @Nullable I callSymbol; - SevpaViewEdge(I internalAction, S target) { - this(internalAction, target, null, null); - } - - SevpaViewEdge(I returnAction, S target, S callLoc, @Nullable I callSymbol) { - this.input = returnAction; + private SevpaViewEdge(I input, S target, @Nullable S callLoc, @Nullable I callSymbol, String label) { + this.input = input; this.target = target; this.callLoc = callLoc; this.callSymbol = callSymbol; + this.label = label; + } + + SevpaViewEdge(I internalAction, S target) { + this(internalAction, target, null, null, String.valueOf(internalAction)); + } + + SevpaViewEdge(I returnAction, S target, S callLoc, I callSymbol, StateIDs stateIDs) { + this(returnAction, + target, + callLoc, + callSymbol, + returnAction + "/(L" + stateIDs.getStateId(callLoc) + ',' + callSymbol + ')'); } } diff --git a/api/src/main/java/net/automatalib/automaton/vpa/SEVPASemantics.java b/api/src/main/java/net/automatalib/automaton/vpa/SEVPASemantics.java index 8ea097226..99a882950 100644 --- a/api/src/main/java/net/automatalib/automaton/vpa/SEVPASemantics.java +++ b/api/src/main/java/net/automatalib/automaton/vpa/SEVPASemantics.java @@ -19,19 +19,19 @@ import net.automatalib.ts.acceptor.DeterministicAcceptorTS; import org.checkerframework.checker.nullness.qual.Nullable; -public class SEVPASemantics implements DeterministicAcceptorTS, I> { +public class SEVPASemantics implements DeterministicAcceptorTS, I> { - private final SEVPA sevpa; + private final SEVPA sevpa; private final VPAlphabet alphabet; - public SEVPASemantics(SEVPA sevpa) { + public SEVPASemantics(SEVPA sevpa) { this.sevpa = sevpa; this.alphabet = sevpa.getInputAlphabet(); } @Override - public @Nullable State getTransition(State state, I input) { - final S loc = state.getLocation(); + public @Nullable State getTransition(State state, I input) { + final L loc = state.getLocation(); return switch (alphabet.getSymbolType(input)) { case CALL: final int newStackElem = sevpa.encodeStackSym(loc, input); @@ -43,14 +43,14 @@ public SEVPASemantics(SEVPA sevpa) { yield null; } final int stackElem = contents.peek(); - final S succ = sevpa.getReturnSuccessor(loc, input, stackElem); + final L succ = sevpa.getReturnSuccessor(loc, input, stackElem); if (succ == null) { yield null; } yield new State<>(succ, contents.pop()); } case INTERNAL: { - final S succ = sevpa.getInternalSuccessor(loc, input); + final L succ = sevpa.getInternalSuccessor(loc, input); if (succ == null) { yield null; } @@ -60,12 +60,12 @@ public SEVPASemantics(SEVPA sevpa) { } @Override - public boolean isAccepting(State state) { + public boolean isAccepting(State state) { return sevpa.getStateProperty(state.getLocation()) && state.getStackContents() == null; } @Override - public State getInitialState() { + public State getInitialState() { return new State<>(sevpa.getInitialState(), null); } } diff --git a/api/src/main/java/net/automatalib/graph/CFMPSGraphView.java b/api/src/main/java/net/automatalib/graph/CFMPSGraphView.java index f5829b426..d51fd1d74 100644 --- a/api/src/main/java/net/automatalib/graph/CFMPSGraphView.java +++ b/api/src/main/java/net/automatalib/graph/CFMPSGraphView.java @@ -25,6 +25,7 @@ import net.automatalib.graph.visualization.CFMPSVisualizationHelper; import net.automatalib.visualization.VisualizationHelper; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; /** * Graph representation of a {@link ContextFreeModalProcessSystem} that displays all nodes of its sub-procedures once, @@ -41,12 +42,13 @@ */ public class CFMPSGraphView implements Graph, Pair> { - private final L mainProcedure; + private final @Nullable L mainProcedure; private final Map> pmpgs; // cast is fine, because we make sure to only query nodes/edges belonging to the respective procedures @SuppressWarnings("unchecked") - public CFMPSGraphView(L mainProcedure, Map> pmpgs) { + public CFMPSGraphView(@Nullable L mainProcedure, + Map> pmpgs) { this.mainProcedure = mainProcedure; this.pmpgs = (Map>) pmpgs; } diff --git a/api/src/main/java/net/automatalib/graph/visualization/CFMPSVisualizationHelper.java b/api/src/main/java/net/automatalib/graph/visualization/CFMPSVisualizationHelper.java index 5b11e4af6..8721a0eb0 100644 --- a/api/src/main/java/net/automatalib/graph/visualization/CFMPSVisualizationHelper.java +++ b/api/src/main/java/net/automatalib/graph/visualization/CFMPSVisualizationHelper.java @@ -28,6 +28,7 @@ import net.automatalib.graph.ProceduralModalProcessGraph; import net.automatalib.visualization.DefaultVisualizationHelper; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; public class CFMPSVisualizationHelper extends DefaultVisualizationHelper, Pair> { @@ -36,7 +37,7 @@ public class CFMPSVisualizationHelper extends DefaultVisualizationHelpe // cast is fine, because we make sure to only query nodes/edges belonging to the respective procedures @SuppressWarnings("unchecked") - public CFMPSVisualizationHelper(L mainProcedure, + public CFMPSVisualizationHelper(@Nullable L mainProcedure, Map> pmpgs) { this.visualizers = new HashMap<>(HashUtil.capacity(pmpgs.size())); this.initialNodes = new ArrayList<>(pmpgs.size()); diff --git a/api/src/main/java/net/automatalib/semantic/DeterministicFiniteSemantics.java b/api/src/main/java/net/automatalib/semantic/DeterministicFiniteSemantics.java index e0b6ed46b..9e639724d 100644 --- a/api/src/main/java/net/automatalib/semantic/DeterministicFiniteSemantics.java +++ b/api/src/main/java/net/automatalib/semantic/DeterministicFiniteSemantics.java @@ -17,6 +17,9 @@ import net.automatalib.automaton.DeterministicAutomaton; +/** + * An interface for providing deterministic, finite-state semantics. + */ @FunctionalInterface public interface DeterministicFiniteSemantics extends DeterministicSemantics, FiniteSemantics { diff --git a/api/src/main/java/net/automatalib/semantic/DeterministicSemantics.java b/api/src/main/java/net/automatalib/semantic/DeterministicSemantics.java index 8fee5e0ae..f6878ac34 100644 --- a/api/src/main/java/net/automatalib/semantic/DeterministicSemantics.java +++ b/api/src/main/java/net/automatalib/semantic/DeterministicSemantics.java @@ -17,6 +17,9 @@ import net.automatalib.ts.DeterministicTransitionSystem; +/** + * An interface for providing deterministic, infinite-state semantics. + */ @FunctionalInterface public interface DeterministicSemantics extends Semantics { diff --git a/api/src/main/java/net/automatalib/semantic/FiniteSemantics.java b/api/src/main/java/net/automatalib/semantic/FiniteSemantics.java index b036f67f4..32f7f5b49 100644 --- a/api/src/main/java/net/automatalib/semantic/FiniteSemantics.java +++ b/api/src/main/java/net/automatalib/semantic/FiniteSemantics.java @@ -17,6 +17,9 @@ import net.automatalib.automaton.Automaton; +/** + * An interface for providing non-deterministic, finite-state semantics. + */ @FunctionalInterface public interface FiniteSemantics extends Semantics { diff --git a/api/src/main/java/net/automatalib/semantic/Semantics.java b/api/src/main/java/net/automatalib/semantic/Semantics.java index 48db7d019..4daba17d3 100644 --- a/api/src/main/java/net/automatalib/semantic/Semantics.java +++ b/api/src/main/java/net/automatalib/semantic/Semantics.java @@ -17,9 +17,17 @@ import net.automatalib.ts.TransitionSystem; +/** + * An interface for providing non-deterministic, infinite-state semantics. + */ @FunctionalInterface public interface Semantics { + /** + * Returns a view on the semantic transition systems induced by the implementing structure. + * + * @return a view on the semantic transition systems induced by the implementing structure + */ TransitionSystem getSemantics(); } diff --git a/api/src/main/java/net/automatalib/semantic/package-info.java b/api/src/main/java/net/automatalib/semantic/package-info.java new file mode 100644 index 000000000..3dc7e7f5c --- /dev/null +++ b/api/src/main/java/net/automatalib/semantic/package-info.java @@ -0,0 +1,25 @@ +/* Copyright (C) 2013-2026 TU Dortmund University + * This file is part of AutomataLib . + * + * 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. + */ + +/** + * This package introduces the concept of semantics which allow one to distinguish between the structural and + * semantic interpretations of transition systems and automata using the same type definitions. + *

+ * The classes in this package act as semantic providers allowing, for example, structurally finite-state systems such + * as {@link net.automatalib.automaton.vpa.SEVPA}s or {@link net.automatalib.automaton.mmlt.MMLT}s to provide a view on + * their semantically infinite-state systems. + */ +package net.automatalib.semantic; diff --git a/api/src/main/java/net/automatalib/ts/simple/SimpleDTS.java b/api/src/main/java/net/automatalib/ts/simple/SimpleDTS.java index 377c771ce..bebec060c 100644 --- a/api/src/main/java/net/automatalib/ts/simple/SimpleDTS.java +++ b/api/src/main/java/net/automatalib/ts/simple/SimpleDTS.java @@ -16,10 +16,10 @@ package net.automatalib.ts.simple; import java.util.Collection; -import java.util.Collections; import java.util.Iterator; import java.util.Set; +import net.automatalib.automaton.concept.InitialState; import net.automatalib.ts.TransitionSystem; import org.checkerframework.checker.nullness.qual.Nullable; @@ -36,21 +36,16 @@ * @param * input symbol class */ -public interface SimpleDTS extends SimpleTS { +public interface SimpleDTS extends SimpleTS, InitialState { @Override default Set getSuccessors(S state, I input) { - return stateToSet(getSuccessor(state, input)); + return InitialState.stateToSet(getSuccessor(state, input)); } @Override default Set getStates(Iterable input) { - return stateToSet(getState(input)); - } - - @Override - default Set getInitialStates() { - return stateToSet(getInitialState()); + return InitialState.stateToSet(getState(input)); } /** @@ -68,15 +63,6 @@ default Set getInitialStates() { return init == null ? null : getSuccessor(init, input); } - /** - * Retrieves the initial state of this transition system. - * - * @return the initial state. - * - * @see TransitionSystem#getInitialStates() - */ - @Nullable S getInitialState(); - /** * Retrieves the successor state reachable by the given sequence of input symbols. * @@ -117,10 +103,4 @@ default Set getInitialStates() { */ @Nullable S getSuccessor(S state, I input); - static Set stateToSet(@Nullable S state) { - if (state == null) { - return Collections.emptySet(); - } - return Collections.singleton(state); - } } diff --git a/api/src/main/java/net/automatalib/ts/simple/SimpleTS.java b/api/src/main/java/net/automatalib/ts/simple/SimpleTS.java index 48d16cb46..c8552b0af 100644 --- a/api/src/main/java/net/automatalib/ts/simple/SimpleTS.java +++ b/api/src/main/java/net/automatalib/ts/simple/SimpleTS.java @@ -19,6 +19,7 @@ import java.util.HashSet; import java.util.Set; +import net.automatalib.automaton.concept.InitialStates; import net.automatalib.common.util.mapping.MapMapping; import net.automatalib.common.util.mapping.MutableMapping; @@ -31,7 +32,7 @@ * @param * symbol class. */ -public interface SimpleTS { +public interface SimpleTS extends InitialStates { /** * Retrieves the set of successors for the given input symbol. @@ -88,13 +89,6 @@ default Set getStates(Iterable input) { return getSuccessors(getInitialStates(), input); } - /** - * Retrieves the set of initial states of the transition system. - * - * @return the initial states. - */ - Set getInitialStates(); - /** * Creates a {@link MutableMapping} allowing to associate arbitrary data with this transition system's states. The * returned mapping is however only guaranteed to work correctly if the transition system is not modified. diff --git a/api/src/test/java/net/automatalib/automaton/SemanticsTest.java b/api/src/test/java/net/automatalib/automaton/SemanticsTest.java new file mode 100644 index 000000000..d3b828760 --- /dev/null +++ b/api/src/test/java/net/automatalib/automaton/SemanticsTest.java @@ -0,0 +1,80 @@ +/* Copyright (C) 2013-2026 TU Dortmund University + * This file is part of AutomataLib . + * + * 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 net.automatalib.automaton; + +import net.automatalib.automaton.fsa.DFA; +import net.automatalib.automaton.fsa.MutableDFA; +import net.automatalib.automaton.fsa.MutableNFA; +import net.automatalib.automaton.fsa.NFA; +import net.automatalib.automaton.procedural.SBA; +import net.automatalib.automaton.procedural.SPA; +import net.automatalib.automaton.procedural.SPMM; +import net.automatalib.automaton.transducer.MealyMachine; +import net.automatalib.automaton.transducer.MooreMachine; +import net.automatalib.automaton.transducer.MutableMealyMachine; +import net.automatalib.automaton.transducer.MutableMooreMachine; +import net.automatalib.automaton.transducer.MutableSubsequentialTransducer; +import net.automatalib.automaton.transducer.SubsequentialTransducer; +import net.automatalib.automaton.transducer.probabilistic.MutableProbabilisticMealy; +import net.automatalib.automaton.transducer.probabilistic.ProbabilisticMealyMachine; +import net.automatalib.semantic.Semantics; +import net.automatalib.ts.TransitionSystem; +import net.automatalib.ts.modal.ModalTransitionSystem; +import net.automatalib.ts.modal.MutableModalTransitionSystem; +import org.mockito.Mockito; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class SemanticsTest { + + @Test + public void testIdentitySemantics() { + checkSameSemantics(Automaton.FiniteSemantics.class); + checkSameSemantics(UniversalAutomaton.FiniteSemantics.class); + checkSameSemantics(DeterministicAutomaton.FiniteSemantics.class); + checkSameSemantics(UniversalDeterministicAutomaton.FiniteSemantics.class); + checkSameSemantics(MutableAutomaton.FiniteSemantics.class); + checkSameSemantics(MutableDeterministic.FiniteSemantics.class); + + checkSameSemantics(DFA.class); + checkSameSemantics(MutableDFA.class); + checkSameSemantics(MealyMachine.class); + checkSameSemantics(MutableMealyMachine.class); + checkSameSemantics(ProbabilisticMealyMachine.class); + checkSameSemantics(MutableProbabilisticMealy.class); + checkSameSemantics(MooreMachine.class); + checkSameSemantics(MutableMooreMachine.class); + checkSameSemantics(NFA.class); + checkSameSemantics(MutableNFA.class); + checkSameSemantics(SubsequentialTransducer.class); + checkSameSemantics(MutableSubsequentialTransducer.class); + checkSameSemantics(ModalTransitionSystem.class); + checkSameSemantics(MutableModalTransitionSystem.class); + + checkSameSemantics(SPA.class); + checkSameSemantics(SBA.class); + checkSameSemantics(SPMM.class); + } + + private void checkSameSemantics(Class clazz) { + final Semantics mock = Mockito.mock(clazz); + final T automaton = Mockito.when(mock.getSemantics()).thenCallRealMethod().getMock(); + final TransitionSystem semantics = automaton.getSemantics(); + + Assert.assertSame(semantics, automaton); + } + +} diff --git a/core/src/main/java/net/automatalib/automaton/base/AbstractCompact.java b/core/src/main/java/net/automatalib/automaton/base/AbstractCompact.java index cdbc8303c..315eec2d7 100644 --- a/core/src/main/java/net/automatalib/automaton/base/AbstractCompact.java +++ b/core/src/main/java/net/automatalib/automaton/base/AbstractCompact.java @@ -341,8 +341,8 @@ public final int numInputs(@UnknownInitialization(AbstractCompact.class) Abstrac } /** - * An enum containing the different kind of update operations. Each enum constant implements the required - * {@link TransitionUpdateOperation#updateStorage(Object, Payload, IntFunction, ArrayInitializer)} method. + * An enum containing the different kind of update operations. Each enum constant implements the required {@link + * TransitionUpdateOperation#updateStorage(Object, Payload, IntFunction, ArrayInitializer)} method. */ private enum TransitionUpdateOperation { /** diff --git a/core/src/main/java/net/automatalib/automaton/impl/UniversalCompactDetAutomaton.java b/core/src/main/java/net/automatalib/automaton/impl/UniversalCompactDetAutomaton.java index 3da0b8bb2..0a156ec84 100644 --- a/core/src/main/java/net/automatalib/automaton/impl/UniversalCompactDetAutomaton.java +++ b/core/src/main/java/net/automatalib/automaton/impl/UniversalCompactDetAutomaton.java @@ -17,12 +17,12 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.AutomatonCreator; +import net.automatalib.automaton.MutableDeterministic; import net.automatalib.automaton.MutableDeterministic.FiniteSemantics; -import net.automatalib.automaton.base.AbstractCompactDeterministic; /** - * A default implementation for {@link AbstractCompactDeterministic} that uses {@link CompactTransition} as transition - * type and supports various types of state and transition properties. + * A refinement of {@link UniversalCompactDet} that additionally implements {@link MutableDeterministic.FiniteSemantics} + * so that structural determinism and finiteness coincides with semantic determinism and finiteness. * * @param * input symbol type @@ -42,11 +42,6 @@ public UniversalCompactDetAutomaton(Alphabet alphabet, int stateCapacity) { super(alphabet, stateCapacity); } - @Override - public UniversalCompactDetAutomaton getSemantics() { - return this; - } - public static final class Creator implements AutomatonCreator, I> { diff --git a/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractDefaultSEVPA.java b/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractDefaultSEVPA.java index aabc1cc86..536f06f90 100644 --- a/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractDefaultSEVPA.java +++ b/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractDefaultSEVPA.java @@ -40,23 +40,18 @@ public AbstractDefaultSEVPA(VPAlphabet alphabet, int capacity) { this.locations = new ArrayList<>(capacity); } - public Location addInitialLocation(boolean accepting) { - final Location loc = addLocation(accepting); - setInitialLocation(loc); + public Location addInitialState(boolean accepting) { + final Location loc = addState(accepting); + setInitialState(loc); return loc; } - public Location addLocation(boolean accepting) { + public Location addState(boolean accepting) { final Location loc = new Location(alphabet, locations.size(), accepting); locations.add(loc); return loc; } - @Override - public int size() { - return locations.size(); - } - @Override public StateIDs stateIDs() { return this; @@ -105,7 +100,7 @@ public Location getInitialState() { return initLoc; } - public void setInitialLocation(Location loc) { + public void setInitialState(Location loc) { this.initLoc = loc; } diff --git a/core/src/main/java/net/automatalib/automaton/vpa/impl/DefaultNSEVPA.java b/core/src/main/java/net/automatalib/automaton/vpa/impl/DefaultNSEVPA.java index 8867cc9dc..0ad19af64 100644 --- a/core/src/main/java/net/automatalib/automaton/vpa/impl/DefaultNSEVPA.java +++ b/core/src/main/java/net/automatalib/automaton/vpa/impl/DefaultNSEVPA.java @@ -42,14 +42,14 @@ public DefaultNSEVPA(VPAlphabet alphabet, int capacityHint) { } @Override - public Location addLocation(boolean accepting) { - final Location loc = super.addLocation(accepting); + public Location addState(boolean accepting) { + final Location loc = super.addState(accepting); this.moduleMapping.ensureCapacity(loc.getIndex() + 1); return loc; } public Location addLocation(I module, boolean accepting) { - final Location result = this.addLocation(accepting); + final Location result = this.addState(accepting); this.moduleMapping.set(result.getIndex(), module); return result; } diff --git a/core/src/main/java/net/automatalib/automaton/vpa/impl/Location.java b/core/src/main/java/net/automatalib/automaton/vpa/impl/Location.java index 3dcf9d84b..a911a6976 100644 --- a/core/src/main/java/net/automatalib/automaton/vpa/impl/Location.java +++ b/core/src/main/java/net/automatalib/automaton/vpa/impl/Location.java @@ -20,7 +20,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; /** - * Location type used for the default 1-SEVPA. + * Location type used for {@link AbstractDefaultSEVPA}. */ public class Location { diff --git a/core/src/test/java/net/automatalib/automaton/abstraction/impl/MutableFullIntAbstractionTest.java b/core/src/test/java/net/automatalib/automaton/abstraction/impl/MutableFullIntAbstractionTest.java index 6567492d3..251d21fa9 100644 --- a/core/src/test/java/net/automatalib/automaton/abstraction/impl/MutableFullIntAbstractionTest.java +++ b/core/src/test/java/net/automatalib/automaton/abstraction/impl/MutableFullIntAbstractionTest.java @@ -23,7 +23,7 @@ import net.automatalib.automaton.AutomatonCreator; import net.automatalib.automaton.MutableAutomaton; import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions; +import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions.FullIntAbstraction; import net.automatalib.automaton.concept.StateIDs; import net.automatalib.automaton.impl.MutableAutomatonTest; import org.checkerframework.checker.nullness.qual.Nullable; @@ -80,7 +80,7 @@ protected , S, I, T, SP, TP> M creat private static class MockUp implements MutableDeterministic { final MutableDeterministic delegate; - final MutableDeterministicAbstractions.FullIntAbstraction abstraction; + final FullIntAbstraction abstraction; final StateIDs stateIDs; final Alphabet alphabet; @@ -124,18 +124,18 @@ public S getSuccessor(T transition) { @Override public @Nullable S getSuccessor(S state, I input) { int succ = abstraction.getSuccessor(stateIDs.getStateId(state), alphabet.getSymbolIndex(input)); - return succ == MutableDeterministicAbstractions.FullIntAbstraction.INVALID_STATE ? null : stateIDs.getState(succ); + return succ == FullIntAbstraction.INVALID_STATE ? null : stateIDs.getState(succ); } @Override public @Nullable S getInitialState() { final int intInitial = abstraction.getIntInitialState(); - return intInitial == MutableDeterministicAbstractions.FullIntAbstraction.INVALID_STATE ? null : stateIDs.getState(intInitial); + return intInitial == FullIntAbstraction.INVALID_STATE ? null : stateIDs.getState(intInitial); } @Override public void setInitialState(@Nullable S state) { - abstraction.setInitialState(state == null ? MutableDeterministicAbstractions.FullIntAbstraction.INVALID_STATE : stateIDs.getStateId(state)); + abstraction.setInitialState(state == null ? FullIntAbstraction.INVALID_STATE : stateIDs.getStateId(state)); } @Override diff --git a/core/src/test/java/net/automatalib/automaton/abstraction/impl/MutableStateIntAbstractionTest.java b/core/src/test/java/net/automatalib/automaton/abstraction/impl/MutableStateIntAbstractionTest.java index f379313ed..1bfc0d10e 100644 --- a/core/src/test/java/net/automatalib/automaton/abstraction/impl/MutableStateIntAbstractionTest.java +++ b/core/src/test/java/net/automatalib/automaton/abstraction/impl/MutableStateIntAbstractionTest.java @@ -23,7 +23,7 @@ import net.automatalib.automaton.AutomatonCreator; import net.automatalib.automaton.MutableAutomaton; import net.automatalib.automaton.MutableDeterministic; -import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions; +import net.automatalib.automaton.abstraction.MutableDeterministicAbstractions.StateIntAbstraction; import net.automatalib.automaton.concept.StateIDs; import net.automatalib.automaton.impl.MutableAutomatonTest; import org.checkerframework.checker.nullness.qual.Nullable; @@ -81,7 +81,7 @@ protected , S, I, T, SP, TP> M creat private static class MockUp implements MutableDeterministic { final MutableDeterministic delegate; - final MutableDeterministicAbstractions.StateIntAbstraction abstraction; + final StateIntAbstraction abstraction; final StateIDs stateIDs; final Alphabet alphabet; @@ -125,24 +125,18 @@ public S getSuccessor(T transition) { @Override public @Nullable S getSuccessor(S state, I input) { int succ = abstraction.getSuccessor(stateIDs.getStateId(state), input); - return succ == MutableDeterministicAbstractions.StateIntAbstraction.INVALID_STATE ? - null : - stateIDs.getState(succ); + return succ == StateIntAbstraction.INVALID_STATE ? null : stateIDs.getState(succ); } @Override public @Nullable S getInitialState() { final int intInitial = abstraction.getIntInitialState(); - return intInitial == MutableDeterministicAbstractions.StateIntAbstraction.INVALID_STATE ? - null : - stateIDs.getState(intInitial); + return intInitial == StateIntAbstraction.INVALID_STATE ? null : stateIDs.getState(intInitial); } @Override public void setInitialState(@Nullable S state) { - abstraction.setInitialState(state == null ? - MutableDeterministicAbstractions.StateIntAbstraction.INVALID_STATE : - stateIDs.getStateId(state)); + abstraction.setInitialState(state == null ? StateIntAbstraction.INVALID_STATE : stateIDs.getStateId(state)); } @Override diff --git a/core/src/test/java/net/automatalib/automaton/impl/MutableAutomatonTest.java b/core/src/test/java/net/automatalib/automaton/impl/MutableAutomatonTest.java index c310327f9..ef393da05 100644 --- a/core/src/test/java/net/automatalib/automaton/impl/MutableAutomatonTest.java +++ b/core/src/test/java/net/automatalib/automaton/impl/MutableAutomatonTest.java @@ -138,6 +138,16 @@ public void testCompactSimple() { this.checkAutomaton(new CompactSimpleAutomaton.Creator<>(), ALPHABET, EMPTY_PROPS, EMPTY_PROPS); } + @Test + public void testUniversalCompactDet() { + this.checkAutomaton(new UniversalCompactDet.Creator<>(), ALPHABET, STATE_PROPS, TRANS_PROPS); + } + + @Test + public void testUniversalCompactDetAutomaton() { + this.checkAutomaton(new UniversalCompactDetAutomaton.Creator<>(), ALPHABET, STATE_PROPS, TRANS_PROPS); + } + protected , S, I, T, SP, TP> void checkAutomaton(AutomatonCreator creator, Alphabet alphabet, List stateProps, diff --git a/core/src/test/java/net/automatalib/automaton/vpa/impl/DefaultVPATest.java b/core/src/test/java/net/automatalib/automaton/vpa/impl/DefaultVPATest.java index 5f3482d73..3fff9a22f 100644 --- a/core/src/test/java/net/automatalib/automaton/vpa/impl/DefaultVPATest.java +++ b/core/src/test/java/net/automatalib/automaton/vpa/impl/DefaultVPATest.java @@ -46,8 +46,8 @@ public void testBracketLanguageOneSevpa() { final DefaultOneSEVPA vpa = new DefaultOneSEVPA<>(alphabet); - final Location init = vpa.addInitialLocation(false); - final Location accepting = vpa.addLocation(true); + final Location init = vpa.addInitialState(false); + final Location accepting = vpa.addState(true); vpa.setReturnSuccessor(init, ')', vpa.encodeStackSym(init, callAlphabet.getSymbolIndex('(')), accepting); vpa.setReturnSuccessor(init, ']', vpa.encodeStackSym(init, callAlphabet.getSymbolIndex('[')), accepting); @@ -71,10 +71,10 @@ public void testBracketLanguageNSevpa() { final DefaultNSEVPA vpa = new DefaultNSEVPA<>(alphabet); - final Location init = vpa.addInitialLocation(false); + final Location init = vpa.addInitialState(false); final Location m1 = vpa.addModuleEntryLocation('(', false); final Location m2 = vpa.addModuleEntryLocation('[', false); - final Location accepting = vpa.addLocation(true); + final Location accepting = vpa.addState(true); vpa.setReturnSuccessor(m1, ')', vpa.encodeStackSym(init, (Character) '('), accepting); vpa.setReturnSuccessor(m2, ']', vpa.encodeStackSym(init, (Character) '['), accepting); @@ -122,8 +122,8 @@ public void testGraphRepresentation() { // create arbitrary VPA final DefaultOneSEVPA vpa = new DefaultOneSEVPA<>(alphabet); - final Location init = vpa.addInitialLocation(false); - final Location accepting = vpa.addLocation(true); + final Location init = vpa.addInitialState(false); + final Location accepting = vpa.addState(true); // criss-cross internal successors for (Integer i : internalAlphabet) { @@ -193,6 +193,8 @@ private static void verifyGraphRepresentation(VPAlphabet alphabet, Assert.assertEquals(vpa.getInternalSuccessor(loc, input), target); break; case RETURN: + Assert.assertNotNull(callLoc); + Assert.assertNotNull(callSymbol); final int stackSym = vpa.encodeStackSym(callLoc, callSymbol); Assert.assertEquals(vpa.getReturnSuccessor(loc, input, stackSym), target); break; diff --git a/examples/src/main/java/net/automatalib/example/Example.java b/examples/src/main/java/net/automatalib/example/Example.java deleted file mode 100644 index cca4ba35e..000000000 --- a/examples/src/main/java/net/automatalib/example/Example.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.automatalib.example; - -import net.automatalib.alphabet.impl.Alphabets; -import net.automatalib.automaton.fsa.impl.CompactDFA; -import net.automatalib.automaton.fsa.impl.CompactNFA; -import net.automatalib.automaton.mmlt.impl.CompactMMLT; -import net.automatalib.automaton.mmlt.impl.StringSymbolCombiner; -import net.automatalib.automaton.transducer.impl.CompactMealy; -import net.automatalib.util.automaton.Automata; -import net.automatalib.util.automaton.copy.AutomatonCopyMethod; -import net.automatalib.util.automaton.copy.AutomatonLowLevelCopy; - -public class Example { - - public static void main(String[] args) { - - var alphabet = Alphabets.integers(1,3); - - var dfa = new CompactDFA<>(alphabet); - var nfa = new CompactNFA<>(alphabet); - var mealy = new CompactMealy<>(alphabet); - var mmlt = new CompactMMLT<>(alphabet, "", StringSymbolCombiner.getInstance()); - - Automata.findSeparatingWord(nfa, nfa, alphabet); - Automata.findSeparatingWord(nfa, dfa, alphabet); - Automata.findSeparatingWord(dfa, dfa, alphabet); - Automata.findSeparatingWord(dfa, mealy, alphabet); - Automata.findSeparatingWord(mealy, mealy, alphabet); - Automata.findSeparatingWord(mealy, mmlt, alphabet); -// Automata.findSeparatingWord(mealy, DeterministicFiniteSemantics.fromAutomaton(mmlt), alphabet); - - var newMealy = new CompactMealy<>(alphabet); - AutomatonLowLevelCopy.copy(AutomatonCopyMethod.STATE_BY_STATE, mmlt, alphabet, newMealy); - Automata.findSeparatingWord(mealy, newMealy, alphabet); - } - -} diff --git a/examples/src/main/java/net/automatalib/example/vpa/OneSEVPAExample.java b/examples/src/main/java/net/automatalib/example/vpa/OneSEVPAExample.java index 1fefa29b9..ad55d0354 100644 --- a/examples/src/main/java/net/automatalib/example/vpa/OneSEVPAExample.java +++ b/examples/src/main/java/net/automatalib/example/vpa/OneSEVPAExample.java @@ -54,7 +54,7 @@ public static void main(String[] args) { } private static void traceVisiblePushdownWords(DefaultOneSEVPA vpa, String input) { - final boolean accept = vpa.accepts(Word.fromString(input)); + final boolean accept = vpa.getSemantics().accepts(Word.fromString(input)); LOGGER.info("The VPA does {}accept the word '{}'", accept ? "" : "not ", input); } @@ -70,8 +70,8 @@ private static DefaultOneSEVPA buildAutomaton() { final DefaultOneSEVPA result = new DefaultOneSEVPA<>(ALPHABET); - final Location l0 = result.addInitialLocation(false); - final Location l1 = result.addLocation(true); + final Location l0 = result.addInitialState(false); + final Location l1 = result.addState(true); result.setInternalSuccessor(l0, 'i', l1); result.setInternalSuccessor(l1, 'i', l0); diff --git a/util/src/main/java/net/automatalib/util/automaton/Automata.java b/util/src/main/java/net/automatalib/util/automaton/Automata.java index 405fcc2ca..ce0e96d7b 100644 --- a/util/src/main/java/net/automatalib/util/automaton/Automata.java +++ b/util/src/main/java/net/automatalib/util/automaton/Automata.java @@ -196,8 +196,7 @@ public static rec = records[i]; SP prop = rec.property; diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/IncrementalWMethodTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/IncrementalWMethodTestsIterator.java index a4b0fc805..5397f4d40 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/IncrementalWMethodTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/IncrementalWMethodTestsIterator.java @@ -96,8 +96,7 @@ public Word next() { Item nextItem = itemQueue.remove(); Word result = assembleWord(nextItem); - @Nullable - Item inc = increment(nextItem); + @Nullable Item inc = increment(nextItem); if (inc != null) { itemQueue.offer(inc); } diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/WpMethodTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/WpMethodTestsIterator.java index 644baa9c0..ee3844822 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/WpMethodTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/WpMethodTestsIterator.java @@ -175,8 +175,7 @@ protected Iterator> l3Iterator(Word prefix, List middle) { @SuppressWarnings("nullness") // input sequences have been computed on defined transitions final @NonNull S state = automaton.getSuccessor(tmp, middle); - @Nullable - List> localSuffixes = localSuffixSets.get(state); + @Nullable List> localSuffixes = localSuffixSets.get(state); if (localSuffixes == null) { localSuffixes = Automata.stateCharacterizingSet(automaton, inputs, state); diff --git a/util/src/main/java/net/automatalib/util/automaton/cover/Covers.java b/util/src/main/java/net/automatalib/util/automaton/cover/Covers.java index 28c43d81c..5142812e7 100644 --- a/util/src/main/java/net/automatalib/util/automaton/cover/Covers.java +++ b/util/src/main/java/net/automatalib/util/automaton/cover/Covers.java @@ -233,8 +233,7 @@ public static void cover(FiniteSemantics automaton, while ((curr = bfsQueue.poll()) != null) { @SuppressWarnings("nullness") // in a breadth-first traversal the predecessors are always defined - @NonNull - Word as = reach.get(curr); + @NonNull Word as = reach.get(curr); for (I in : inputs) { S succ = automaton.getSuccessor(curr, in); diff --git a/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalTransitionCoverIterator.java b/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalTransitionCoverIterator.java index 67365fe61..2068ab3c8 100644 --- a/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalTransitionCoverIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalTransitionCoverIterator.java @@ -59,7 +59,7 @@ class IncrementalTransitionCoverIterator extends AbstractSimplifiedIterato this.automaton = automaton; this.inputs = inputs; this.oldCover = oldCover; - this.reach = this.automaton.createStaticStateMapping(); + this.reach = automaton.createStaticStateMapping(); this.bfsQueue = new ArrayDeque<>(); } diff --git a/util/src/main/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizer.java b/util/src/main/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizer.java index 7310cded4..4ae660dfb 100644 --- a/util/src/main/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizer.java +++ b/util/src/main/java/net/automatalib/util/automaton/minimizer/HopcroftMinimizer.java @@ -567,7 +567,7 @@ public static UniversalCompactDetAutomaton minimizeUniver * * @return the minimized automaton, initially constructed from the given {@code creator}. */ - public static > A minimizeUniversal( + public static > A minimizeUniversal( UniversalDeterministicAutomaton.FiniteSemantics automaton, Alphabet alphabet, PruningMode pruningMode, diff --git a/util/src/main/java/net/automatalib/util/automaton/minimizer/OneSEVPAMinimizer.java b/util/src/main/java/net/automatalib/util/automaton/minimizer/OneSEVPAMinimizer.java index 0eef56184..91da040c3 100644 --- a/util/src/main/java/net/automatalib/util/automaton/minimizer/OneSEVPAMinimizer.java +++ b/util/src/main/java/net/automatalib/util/automaton/minimizer/OneSEVPAMinimizer.java @@ -171,7 +171,7 @@ private static DefaultOneSEVPA fromHopcroft(Hopcroft pt, final Location[] resultLocs = new Location[numBlocks]; for (int i = 0; i < resultLocs.length; i++) { - resultLocs[i] = result.addLocation(false); + resultLocs[i] = result.addState(false); } for (Block curr : pt.blockList()) { @@ -212,7 +212,7 @@ private static DefaultOneSEVPA fromHopcroft(Hopcroft pt, } final int origInit = stateIDs.getStateId(original.getInitialState()); - result.setInitialLocation(resultLocs[pt.getBlockForState(origInit).id]); + result.setInitialState(resultLocs[pt.getBlockForState(origInit).id]); return result; } diff --git a/util/src/main/java/net/automatalib/util/automaton/procedural/NSEVPAConverter.java b/util/src/main/java/net/automatalib/util/automaton/procedural/NSEVPAConverter.java index 5e7a777c3..c40cde7b9 100644 --- a/util/src/main/java/net/automatalib/util/automaton/procedural/NSEVPAConverter.java +++ b/util/src/main/java/net/automatalib/util/automaton/procedural/NSEVPAConverter.java @@ -111,7 +111,7 @@ private static SEVPA constructNSEVPA(SPA spa, final Map mainSignatures = new HashMap<>(); final DefaultNSEVPA vpa = new DefaultNSEVPA<>(alphabet); - final Location init = vpa.addInitialLocation(false); + final Location init = vpa.addInitialState(false); mainLocations.put(Word.epsilon(), init); mainSignatures.put(OneSEVPAConverter.computeSignature(spa, contextPairs.get(null), Word.epsilon()), init); @@ -149,7 +149,7 @@ private static SEVPA constructNSEVPA(SPA spa, if (succ == null) { final Location newLoc; if (procedure == null) { - newLoc = vpa.addLocation(sig.get(0)); + newLoc = vpa.addState(sig.get(0)); } else { newLoc = vpa.addLocation(procedure, false); } @@ -182,7 +182,7 @@ private static SEVPA constructNSEVPA(SPA spa, if (succ1 == null) { final Location newLoc; if (otherProcedure == null) { - newLoc = vpa.addLocation(sig1.get(0)); + newLoc = vpa.addState(sig1.get(0)); } else { newLoc = vpa.addLocation(otherProcedure, false); } @@ -205,7 +205,7 @@ private static SEVPA constructNSEVPA(SPA spa, if (succ2 == null) { final Location newLoc; if (procedure == null) { - newLoc = vpa.addLocation(sig2.get(0)); + newLoc = vpa.addState(sig2.get(0)); } else { newLoc = vpa.addLocation(procedure, false); } diff --git a/util/src/main/java/net/automatalib/util/automaton/procedural/OneSEVPAConverter.java b/util/src/main/java/net/automatalib/util/automaton/procedural/OneSEVPAConverter.java index 6b79ee880..e1f3c7531 100644 --- a/util/src/main/java/net/automatalib/util/automaton/procedural/OneSEVPAConverter.java +++ b/util/src/main/java/net/automatalib/util/automaton/procedural/OneSEVPAConverter.java @@ -84,7 +84,7 @@ private static OneSEVPA constructOneSEVPA(SPA spa, List signatureMap = new HashMap<>(); final DefaultOneSEVPA vpa = new DefaultOneSEVPA<>(alphabet); - final Location init = vpa.addInitialLocation(false); + final Location init = vpa.addInitialState(false); locationMap.put(Word.epsilon(), init); signatureMap.put(computeSignature(spa, contextPairs, Word.epsilon()), init); @@ -104,7 +104,7 @@ private static OneSEVPA constructOneSEVPA(SPA spa, List OneSEVPA constructOneSEVPA(SPA spa, List OneSEVPA constructOneSEVPA(SPA spa, List DefaultOneSEVPA randomOneSEVPA(Random r, double initialRetTransProb, boolean minimize, DefaultOneSEVPA result) { - result.addInitialLocation(r.nextDouble() < acceptanceProb); + result.addInitialState(r.nextDouble() < acceptanceProb); for (int i = 0; i < locCount - 1; i++) { if (alphabet.getNumInternals() == 0 || r.nextDouble() < initialRetTransProb) { @@ -129,7 +129,7 @@ public static DefaultOneSEVPA randomOneSEVPA(Random r, stackSym = result.encodeStackSym(stackLoc, callSym); } while (result.getReturnSuccessor(srcLoc, retSym, stackSym) != null); - final Location newLoc = result.addLocation(r.nextDouble() < acceptanceProb); + final Location newLoc = result.addState(r.nextDouble() < acceptanceProb); result.setReturnSuccessor(srcLoc, retSym, stackSym, newLoc); } else { I intSym; @@ -140,7 +140,7 @@ public static DefaultOneSEVPA randomOneSEVPA(Random r, srcLoc = result.getState(r.nextInt(result.size())); } while (result.getInternalSuccessor(srcLoc, intSym) != null); - final Location newLoc = result.addLocation(r.nextDouble() < acceptanceProb); + final Location newLoc = result.addState(r.nextDouble() < acceptanceProb); result.setInternalSuccessor(srcLoc, intSym, newLoc); } } diff --git a/util/src/main/java/net/automatalib/util/partitionrefinement/HopcroftExtractors.java b/util/src/main/java/net/automatalib/util/partitionrefinement/HopcroftExtractors.java index c244d4f4b..f616c11e4 100644 --- a/util/src/main/java/net/automatalib/util/partitionrefinement/HopcroftExtractors.java +++ b/util/src/main/java/net/automatalib/util/partitionrefinement/HopcroftExtractors.java @@ -65,24 +65,26 @@ private HopcroftExtractors() {} * @return an automaton created using the specified creator, over the specified input alphabet, and reflecting the * partition data of the specified {@link Hopcroft} object */ - public static > A toDeterministic(Hopcroft hopcroft, - AutomatonCreator creator, - Alphabet inputs, - SimpleDeterministicAbstractions.FullIntAbstraction abs, - IntFunction spExtractor, - BiIntFunction tpExtractor, - boolean pruneUnreachable) { + public static > A toDeterministic( + Hopcroft hopcroft, + AutomatonCreator creator, + Alphabet inputs, + SimpleDeterministicAbstractions.FullIntAbstraction abs, + IntFunction spExtractor, + BiIntFunction tpExtractor, + boolean pruneUnreachable) { return pruneUnreachable ? toDeterministicPruned(hopcroft, creator, inputs, abs, spExtractor, tpExtractor) : toDeterministicUnpruned(hopcroft, creator, inputs, abs, spExtractor, tpExtractor); } - private static > A toDeterministicPruned(Hopcroft hopcroft, - AutomatonCreator creator, - Alphabet inputs, - SimpleDeterministicAbstractions.FullIntAbstraction abs, - IntFunction spExtractor, - BiIntFunction tpExtractor) { + private static > A toDeterministicPruned( + Hopcroft hopcroft, + AutomatonCreator creator, + Alphabet inputs, + SimpleDeterministicAbstractions.FullIntAbstraction abs, + IntFunction spExtractor, + BiIntFunction tpExtractor) { int numBlocks = hopcroft.getNumBlocks(); int numInputs = inputs.size(); @@ -128,12 +130,13 @@ private HopcroftExtractors() {} return result; } - private static > A toDeterministicUnpruned(Hopcroft hopcroft, - AutomatonCreator creator, - Alphabet inputs, - SimpleDeterministicAbstractions.FullIntAbstraction abs, - IntFunction spExtractor, - BiIntFunction tpExtractor) { + private static > A toDeterministicUnpruned( + Hopcroft hopcroft, + AutomatonCreator creator, + Alphabet inputs, + SimpleDeterministicAbstractions.FullIntAbstraction abs, + IntFunction spExtractor, + BiIntFunction tpExtractor) { int numBlocks = hopcroft.getNumBlocks(); int numInputs = inputs.size(); diff --git a/util/src/main/java/net/automatalib/util/partitionrefinement/ValmariExtractors.java b/util/src/main/java/net/automatalib/util/partitionrefinement/ValmariExtractors.java index fce84424d..fc0053308 100644 --- a/util/src/main/java/net/automatalib/util/partitionrefinement/ValmariExtractors.java +++ b/util/src/main/java/net/automatalib/util/partitionrefinement/ValmariExtractors.java @@ -134,10 +134,10 @@ public static > A toNFA(Valmari valmari, * * @return the "quotiented" automaton of the original one */ - public static > A toUniversal(Valmari valmari, - UniversalAutomaton original, - Alphabet alphabet, - AutomatonCreator creator) { + public static > A toUniversal(Valmari valmari, + UniversalAutomaton.FiniteSemantics original, + Alphabet alphabet, + AutomatonCreator creator) { return toUniversal(valmari, original, alphabet, creator, true); } @@ -169,19 +169,19 @@ public static > A toNFA(Valmari valmari, * * @return the "quotiented" automaton of the original one */ - public static > A toUniversal(Valmari valmari, - UniversalAutomaton original, - Alphabet alphabet, - AutomatonCreator creator, - boolean pruneUnreachable) { + public static > A toUniversal(Valmari valmari, + UniversalAutomaton.FiniteSemantics original, + Alphabet alphabet, + AutomatonCreator creator, + boolean pruneUnreachable) { return pruneUnreachable ? toUniversalPrune(valmari, original, alphabet, creator) : toUniversalNoPrune(valmari, original, alphabet, creator); } - private static > A toUniversalPrune( + private static > A toUniversalPrune( Valmari valmari, - UniversalAutomaton original, + UniversalAutomaton.FiniteSemantics original, Alphabet alphabet, AutomatonCreator creator) { @@ -238,9 +238,9 @@ public static > A toNFA(Valmari valmari, return result; } - private static > A toUniversalNoPrune( + private static > A toUniversalNoPrune( Valmari valmari, - UniversalAutomaton original, + UniversalAutomaton.FiniteSemantics original, Alphabet alphabet, AutomatonCreator creator) { final int numBlocks = valmari.blocks.sets + 1; @@ -279,7 +279,10 @@ public static > A toNFA(Valmari valmari, return result; } - private static boolean blockContainsInitialState(Valmari valmari, int blockId, StateIDs stateIDs, Set initialStates) { + private static boolean blockContainsInitialState(Valmari valmari, + int blockId, + StateIDs stateIDs, + Set initialStates) { for (int i = valmari.blocks.first[blockId]; i < valmari.blocks.end[blockId]; i++) { final S s = stateIDs.getState(valmari.blocks.elems[i]); if (initialStates.contains(s)) { diff --git a/util/src/main/java/net/automatalib/util/partitionrefinement/ValmariInitializers.java b/util/src/main/java/net/automatalib/util/partitionrefinement/ValmariInitializers.java index acf7fdb2c..0a796576a 100644 --- a/util/src/main/java/net/automatalib/util/partitionrefinement/ValmariInitializers.java +++ b/util/src/main/java/net/automatalib/util/partitionrefinement/ValmariInitializers.java @@ -20,7 +20,7 @@ import java.util.function.Function; import net.automatalib.alphabet.Alphabet; -import net.automatalib.automaton.UniversalAutomaton; +import net.automatalib.automaton.UniversalAutomaton.FiniteSemantics; import net.automatalib.automaton.concept.InputAlphabetHolder; import net.automatalib.automaton.concept.StateIDs; import net.automatalib.automaton.fsa.NFA; @@ -92,7 +92,7 @@ public static Valmari initializeNFA(NFA nfa, Alphabet alphabet) * * @return the initialized partition refinement data structure */ - public static Valmari initializeUniversal(UniversalAutomaton automaton, + public static Valmari initializeUniversal(FiniteSemantics automaton, Alphabet alphabet, Function initialClassifier) { final int n = automaton.size(); diff --git a/util/src/test/java/net/automatalib/util/automaton/equivalence/BisimulationTest.java b/util/src/test/java/net/automatalib/util/automaton/equivalence/BisimulationTest.java index ff39b0970..d0caea1c7 100644 --- a/util/src/test/java/net/automatalib/util/automaton/equivalence/BisimulationTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/equivalence/BisimulationTest.java @@ -101,8 +101,8 @@ private static boolean testBisimulationEquivalence(FiniteSemantics> bisim = Bisimulation.bisimulationEquivalenceRelation(a, b, inputs); - Set statesA = new HashSet<>(a.getSemantics().getStates()); - Set statesB = new HashSet<>(b.getSemantics().getStates()); + Set statesA = new HashSet<>(a.getStates()); + Set statesB = new HashSet<>(b.getStates()); for (Pair p : bisim) { statesA.remove(p.getFirst()); diff --git a/util/src/test/java/net/automatalib/util/automaton/vpa/OneSEVPAsTest.java b/util/src/test/java/net/automatalib/util/automaton/vpa/OneSEVPAsTest.java index 30ee052eb..dcb98d01d 100644 --- a/util/src/test/java/net/automatalib/util/automaton/vpa/OneSEVPAsTest.java +++ b/util/src/test/java/net/automatalib/util/automaton/vpa/OneSEVPAsTest.java @@ -240,7 +240,7 @@ private static void addRedundantState(DefaultOneSEVPA automaton, VPAlphab Assert.assertNotNull(locToCopy); final Set oldStates = new HashSet<>(automaton.getStates()); - final Location locCopy = automaton.addLocation(automaton.getStateProperty(locToCopy)); + final Location locCopy = automaton.addState(automaton.getStateProperty(locToCopy)); // make return transitions of old states behave identical for the new stack symbol for (I callSym : alphabet.getCallAlphabet()) { @@ -301,13 +301,13 @@ private static DefaultOneSEVPA getCCARCBRRSystem() { final DefaultOneSEVPA result = new DefaultOneSEVPA<>(alphabet); - final Location l0 = result.addInitialLocation(false); - final Location l1 = result.addLocation(false); - final Location l2 = result.addLocation(false); - final Location l3 = result.addLocation(false); - final Location l4 = result.addLocation(false); - final Location l5 = result.addLocation(true); - final Location l6 = result.addLocation(false); + final Location l0 = result.addInitialState(false); + final Location l1 = result.addState(false); + final Location l2 = result.addState(false); + final Location l3 = result.addState(false); + final Location l4 = result.addState(false); + final Location l5 = result.addState(true); + final Location l6 = result.addState(false); final int s0 = result.encodeStackSym(l0, (Character) 'c'); final int s2 = result.encodeStackSym(l2, (Character) 'c'); From 59543e675903f9770eee730c3615c994721b7e96 Mon Sep 17 00:00:00 2001 From: Markus Frohme Date: Tue, 23 Jun 2026 00:47:44 +0200 Subject: [PATCH 5/8] add more tests --- .../automaton/impl/MutableAutomatonTest.java | 5 +++++ .../automaton/impl/StateLocalInputTest.java | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/core/src/test/java/net/automatalib/automaton/impl/MutableAutomatonTest.java b/core/src/test/java/net/automatalib/automaton/impl/MutableAutomatonTest.java index ef393da05..62da7dfad 100644 --- a/core/src/test/java/net/automatalib/automaton/impl/MutableAutomatonTest.java +++ b/core/src/test/java/net/automatalib/automaton/impl/MutableAutomatonTest.java @@ -138,6 +138,11 @@ public void testCompactSimple() { this.checkAutomaton(new CompactSimpleAutomaton.Creator<>(), ALPHABET, EMPTY_PROPS, EMPTY_PROPS); } + @Test + public void testCompactTransitionOutput() { + this.checkAutomaton(new CompactTransitionOutput.Creator<>(), ALPHABET, EMPTY_PROPS, TRANS_PROPS); + } + @Test public void testUniversalCompactDet() { this.checkAutomaton(new UniversalCompactDet.Creator<>(), ALPHABET, STATE_PROPS, TRANS_PROPS); diff --git a/core/src/test/java/net/automatalib/automaton/impl/StateLocalInputTest.java b/core/src/test/java/net/automatalib/automaton/impl/StateLocalInputTest.java index 081924a51..41b03290c 100644 --- a/core/src/test/java/net/automatalib/automaton/impl/StateLocalInputTest.java +++ b/core/src/test/java/net/automatalib/automaton/impl/StateLocalInputTest.java @@ -94,6 +94,21 @@ public void testCompactSimpleAutomaton() { this.testAutomaton(new CompactSimpleAutomaton<>(ALPHABET)); } + @Test + public void testCompactTransitionOutput() { + this.testAutomaton(new CompactTransitionOutput<>(ALPHABET)); + } + + @Test + public void testUniversalCompactDet() { + this.testAutomaton(new UniversalCompactDet<>(ALPHABET)); + } + + @Test + public void testUniversalCompactDetAutomaton() { + this.testAutomaton(new UniversalCompactDetAutomaton<>(ALPHABET)); + } + private & StateLocalInput, S, T, SP, TP> void testAutomaton( final M automaton) { From 49fc8f3b6d4bf47cc8b6be3aba46ef90eda0bfc2 Mon Sep 17 00:00:00 2001 From: Markus Frohme Date: Tue, 23 Jun 2026 09:47:49 +0200 Subject: [PATCH 6/8] final touches --- .../abstraction/SimpleDeterministicAbstractions.java | 4 ++-- .../net/automatalib/automaton/concept/InitialState.java | 2 +- .../net/automatalib/automaton/concept/InitialStates.java | 2 +- .../main/java/net/automatalib/automaton/vpa/SEVPA.java | 2 +- .../automaton/impl/CompactTransitionOutput.java | 8 ++++++++ .../automaton/vpa/impl/AbstractDefaultSEVPA.java | 5 ----- .../net/automatalib/automaton/vpa/impl/AbstractSEVPA.java | 5 +++++ 7 files changed, 18 insertions(+), 10 deletions(-) diff --git a/api/src/main/java/net/automatalib/automaton/abstraction/SimpleDeterministicAbstractions.java b/api/src/main/java/net/automatalib/automaton/abstraction/SimpleDeterministicAbstractions.java index d583e4e13..f5e5555f9 100644 --- a/api/src/main/java/net/automatalib/automaton/abstraction/SimpleDeterministicAbstractions.java +++ b/api/src/main/java/net/automatalib/automaton/abstraction/SimpleDeterministicAbstractions.java @@ -166,8 +166,8 @@ protected final int safeStateToInt(@Nullable S state) { * * @see IntAbstractionImpl */ - class StateIntAbstractionImpl> - extends IntAbstractionImpl implements StateIntAbstraction { + class StateIntAbstractionImpl> extends IntAbstractionImpl + implements StateIntAbstraction { public StateIntAbstractionImpl(A automaton) { super(automaton); diff --git a/api/src/main/java/net/automatalib/automaton/concept/InitialState.java b/api/src/main/java/net/automatalib/automaton/concept/InitialState.java index 5ffcd2200..b6092bc88 100644 --- a/api/src/main/java/net/automatalib/automaton/concept/InitialState.java +++ b/api/src/main/java/net/automatalib/automaton/concept/InitialState.java @@ -32,7 +32,7 @@ public interface InitialState extends InitialStates { /** * Retrieves the initial state of a transition system. * - * @return the initial state. + * @return the initial state * * @see InitialStates#getInitialStates() */ diff --git a/api/src/main/java/net/automatalib/automaton/concept/InitialStates.java b/api/src/main/java/net/automatalib/automaton/concept/InitialStates.java index e321e959e..5d1da6c8b 100644 --- a/api/src/main/java/net/automatalib/automaton/concept/InitialStates.java +++ b/api/src/main/java/net/automatalib/automaton/concept/InitialStates.java @@ -29,7 +29,7 @@ public interface InitialStates { /** * Retrieves the set of initial states of a transition system. * - * @return the initial states. + * @return the initial states */ Set getInitialStates(); diff --git a/api/src/main/java/net/automatalib/automaton/vpa/SEVPA.java b/api/src/main/java/net/automatalib/automaton/vpa/SEVPA.java index 3aad9c73b..24b41cdc3 100644 --- a/api/src/main/java/net/automatalib/automaton/vpa/SEVPA.java +++ b/api/src/main/java/net/automatalib/automaton/vpa/SEVPA.java @@ -69,7 +69,7 @@ public interface SEVPA extends UniversalAutomaton, @Nullable L getReturnSuccessor(L loc, I retSym, int stackSym); - @Override // do not allow nullable initial state + @Override // do not allow a nullable initial state L getInitialState(); @Override diff --git a/core/src/main/java/net/automatalib/automaton/impl/CompactTransitionOutput.java b/core/src/main/java/net/automatalib/automaton/impl/CompactTransitionOutput.java index a183687a2..8b36956ce 100644 --- a/core/src/main/java/net/automatalib/automaton/impl/CompactTransitionOutput.java +++ b/core/src/main/java/net/automatalib/automaton/impl/CompactTransitionOutput.java @@ -24,6 +24,14 @@ import net.automatalib.automaton.concept.MutableTransitionOutput; import org.checkerframework.checker.nullness.qual.Nullable; +/** + * A compact implementation that supports generic transition outputs. + * + * @param + * input symbol type + * @param + * output symbol type + */ public class CompactTransitionOutput extends AbstractCompactDeterministic, Void, O> implements MutableTransitionOutput, O> { diff --git a/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractDefaultSEVPA.java b/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractDefaultSEVPA.java index 536f06f90..5a42b5e60 100644 --- a/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractDefaultSEVPA.java +++ b/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractDefaultSEVPA.java @@ -52,11 +52,6 @@ public Location addState(boolean accepting) { return loc; } - @Override - public StateIDs stateIDs() { - return this; - } - @Override public int getStateId(Location state) { return state.getIndex(); diff --git a/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractSEVPA.java b/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractSEVPA.java index 5ea439845..675dd9837 100644 --- a/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractSEVPA.java +++ b/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractSEVPA.java @@ -40,6 +40,11 @@ public VPAlphabet getInputAlphabet() { return alphabet; } + @Override + public StateIDs stateIDs() { + return this; + } + @Override public int encodeStackSym(L srcLoc, I callSym) { return encodeStackSym(srcLoc, alphabet.getCallSymbolIndex(callSym)); From 440ce815c42f9fe621731d2f3afc9a8c5f0d5eb5 Mon Sep 17 00:00:00 2001 From: Markus Frohme Date: Tue, 23 Jun 2026 10:22:36 +0200 Subject: [PATCH 7/8] fix broken reference in JavaDoc --- .../automatalib/util/automaton/ads/StateEquivalence.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/src/main/java/net/automatalib/util/automaton/ads/StateEquivalence.java b/util/src/main/java/net/automatalib/util/automaton/ads/StateEquivalence.java index e94f23890..f2ceb3a81 100644 --- a/util/src/main/java/net/automatalib/util/automaton/ads/StateEquivalence.java +++ b/util/src/main/java/net/automatalib/util/automaton/ads/StateEquivalence.java @@ -21,7 +21,7 @@ import java.util.Set; import net.automatalib.alphabet.Alphabet; -import net.automatalib.automaton.UniversalDeterministicAutomaton; +import net.automatalib.automaton.UniversalDeterministicAutomaton.FiniteSemantics; import net.automatalib.automaton.transducer.MealyMachine; import net.automatalib.common.smartcollection.ReflexiveMapView; import net.automatalib.common.util.Pair; @@ -39,8 +39,8 @@ public final class StateEquivalence { private StateEquivalence() {} /** - * Computes a two-state ADS by using {@link Automata#findSeparatingWord(UniversalDeterministicAutomaton, - * UniversalDeterministicAutomaton, Collection)}. + * Computes a two-state ADS by using + * {@link Automata#findSeparatingWord(FiniteSemantics, FiniteSemantics, Collection)}. * * @param automaton * the automaton for which an ADS should be computed From 1553bac4657210b5ed3e85c82a66f4c3dbe15368 Mon Sep 17 00:00:00 2001 From: Markus Frohme Date: Tue, 23 Jun 2026 10:30:41 +0200 Subject: [PATCH 8/8] fix PMD violation --- .../net/automatalib/automaton/vpa/impl/AbstractDefaultSEVPA.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractDefaultSEVPA.java b/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractDefaultSEVPA.java index 5a42b5e60..1541d0ca4 100644 --- a/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractDefaultSEVPA.java +++ b/core/src/main/java/net/automatalib/automaton/vpa/impl/AbstractDefaultSEVPA.java @@ -19,7 +19,6 @@ import java.util.List; import net.automatalib.alphabet.VPAlphabet; -import net.automatalib.automaton.concept.StateIDs; import org.checkerframework.checker.nullness.qual.Nullable; /**

* This is a convenience method acting as a shortcut to - * {@link CharacterizingSets#findCharacterizingSet(UniversalDeterministicAutomaton, Collection, Object, - * Collection)}. + * {@link CharacterizingSets#findCharacterizingSet(UniversalSemantics, Collection, Object, Collection)}. * * @param * state type @@ -421,7 +426,7 @@ public static List> stateCharacterizingSet(UniversalDeterministic * * @see CharacterizingSets */ - public static void stateCharacterizingSet(UniversalDeterministicAutomaton automaton, + public static void stateCharacterizingSet(UniversalSemantics automaton, Collection inputs, S state, Collection> result) { @@ -442,10 +447,11 @@ public static void stateCharacterizingSet(UniversalDeterministicAutomaton * * @see Covers#stateCover(DeterministicAutomaton, Collection, Collection) */ - public static List> stateCover(DeterministicAutomaton automaton, + public static List> stateCover(SimpleSemantics semantics, Collection inputs) { + DeterministicAutomaton automaton = semantics.getSemantics(); final List> result = new ArrayList<>(automaton.size()); - Covers.stateCover(automaton, inputs, result); + Covers.stateCover(semantics, inputs, result); return result; } @@ -463,10 +469,11 @@ public static List> stateCover(DeterministicAutomaton autom * * @see Covers#transitionCover(DeterministicAutomaton, Collection, Collection) */ - public static List> transitionCover(DeterministicAutomaton automaton, + public static List> transitionCover(SimpleSemantics semantics, Collection inputs) { + DeterministicAutomaton automaton = semantics.getSemantics(); final List> result = new ArrayList<>(automaton.size() * inputs.size()); - Covers.transitionCover(automaton, inputs, result); + Covers.transitionCover(semantics, inputs, result); return result; } @@ -484,10 +491,11 @@ public static List> transitionCover(DeterministicAutomaton * * @see Covers#structuralCover(DeterministicAutomaton, Collection, Collection) */ - public static List> structuralCover(DeterministicAutomaton automaton, + public static List> structuralCover(SimpleSemantics semantics, Collection inputs) { + DeterministicAutomaton automaton = semantics.getSemantics(); final List> result = new ArrayList<>(automaton.size() * (inputs.size() + 1)); - Covers.structuralCover(automaton, inputs, result); + Covers.structuralCover(semantics, inputs, result); return result; } diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/IncrementalWMethodTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/IncrementalWMethodTestsIterator.java index 0594890dd..02f783844 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/IncrementalWMethodTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/IncrementalWMethodTestsIterator.java @@ -22,6 +22,7 @@ import net.automatalib.alphabet.Alphabet; import net.automatalib.automaton.UniversalDeterministicAutomaton; +import net.automatalib.automaton.concept.FinSem; import net.automatalib.util.automaton.Automata; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.word.Word; @@ -55,7 +56,7 @@ public void setMaxDepth(int maxDepth) { this.maxDepth = maxDepth; } - public void update(UniversalDeterministicAutomaton automaton) { + public & FinSem> void update(A automaton) { int oldNumPrefixes = prefixes.size(); boolean newPrefixes = Covers.incrementalTransitionCover(automaton, alphabet, prefixes, prefixes); diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/KWayStateCoverTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/KWayStateCoverTestsIterator.java index 1693322fe..8d06c7018 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/KWayStateCoverTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/KWayStateCoverTestsIterator.java @@ -28,6 +28,7 @@ import java.util.stream.Stream; import net.automatalib.automaton.DeterministicAutomaton; +import net.automatalib.automaton.concept.FinSem; import net.automatalib.common.util.HashUtil; import net.automatalib.common.util.collection.AbstractSimplifiedIterator; import net.automatalib.common.util.collection.CollectionUtil; @@ -60,7 +61,7 @@ * @param * automaton type */ -public class KWayStateCoverTestsIterator> +public class KWayStateCoverTestsIterator & FinSem> extends AbstractSimplifiedIterator> { /** diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/KWayTransitionCoverTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/KWayTransitionCoverTestsIterator.java index 4b242a553..1c6893289 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/KWayTransitionCoverTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/KWayTransitionCoverTestsIterator.java @@ -28,6 +28,7 @@ import java.util.stream.Stream; import net.automatalib.automaton.DeterministicAutomaton; +import net.automatalib.automaton.concept.FinSem; import net.automatalib.common.util.HashUtil; import net.automatalib.common.util.collection.AbstractSimplifiedIterator; import net.automatalib.common.util.collection.AbstractTwoLevelIterator; @@ -62,7 +63,7 @@ * @param * automaton type */ -public class KWayTransitionCoverTestsIterator> +public class KWayTransitionCoverTestsIterator & FinSem> implements Iterator> { /** @@ -423,7 +424,7 @@ public enum GenerationMethod { */ RANDOM { @Override - > Iterator> getIterator( + & FinSem> Iterator> getIterator( KWayTransitionCoverTestsIterator self, S initial) { return self.new GreedySetCoverIterator(initial); @@ -434,14 +435,14 @@ public enum GenerationMethod { */ PREFIX { @Override - > Iterator> getIterator( + & FinSem> Iterator> getIterator( KWayTransitionCoverTestsIterator self, S initial) { return self.generatePrefixSteps(self.automaton, initial); } }; - abstract > Iterator> getIterator( + abstract & FinSem> Iterator> getIterator( KWayTransitionCoverTestsIterator self, S initial); } diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/ProceduralWMethodTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/ProceduralWMethodTestsIterator.java index f66a16038..56e136724 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/ProceduralWMethodTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/ProceduralWMethodTestsIterator.java @@ -24,11 +24,13 @@ import net.automatalib.alphabet.ProceduralInputAlphabet; import net.automatalib.automaton.UniversalDeterministicAutomaton; +import net.automatalib.automaton.concept.FinSem; import net.automatalib.common.util.collection.AbstractThreeLevelIterator; import net.automatalib.common.util.collection.AbstractTwoLevelIterator; import net.automatalib.common.util.collection.IterableUtil; import net.automatalib.common.util.collection.IteratorUtil; import net.automatalib.common.util.collection.ReusableIterator; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.util.automaton.equivalence.CharacterizingSets; import net.automatalib.util.automaton.procedural.ATSequences; @@ -36,7 +38,7 @@ import net.automatalib.word.WordBuilder; import org.checkerframework.checker.nullness.qual.NonNull; -class ProceduralWMethodTestsIterator> +class ProceduralWMethodTestsIterator & FinSem> extends AbstractTwoLevelIterator, Word> { private static final List>> EPSILON = diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/WMethodTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/WMethodTestsIterator.java index 0fff97baf..1c53ed244 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/WMethodTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/WMethodTestsIterator.java @@ -25,6 +25,7 @@ import net.automatalib.common.util.collection.IterableUtil; import net.automatalib.common.util.collection.IteratorUtil; import net.automatalib.common.util.collection.ReusableIterator; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.util.automaton.equivalence.CharacterizingSets; import net.automatalib.word.Word; @@ -55,7 +56,7 @@ public class WMethodTestsIterator extends AbstractThreeLevelIterator, * @param inputs * the input symbols that should be considered for test sequence generation */ - public WMethodTestsIterator(UniversalDeterministicAutomaton automaton, + public WMethodTestsIterator(UniversalSemantics automaton, Collection inputs) { this(automaton, inputs, 0); } @@ -70,7 +71,7 @@ public WMethodTestsIterator(UniversalDeterministicAutomaton autom * @param maxDepth * the maximum number of symbols that are appended to the transition-cover part of the test sequences */ - public WMethodTestsIterator(UniversalDeterministicAutomaton automaton, + public WMethodTestsIterator(UniversalSemantics automaton, Collection inputs, int maxDepth) { super(IteratorUtil.concat(IteratorUtil.singleton(Word.epsilon()), diff --git a/util/src/main/java/net/automatalib/util/automaton/conformance/WpMethodTestsIterator.java b/util/src/main/java/net/automatalib/util/automaton/conformance/WpMethodTestsIterator.java index 44966abfb..ede304087 100644 --- a/util/src/main/java/net/automatalib/util/automaton/conformance/WpMethodTestsIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/conformance/WpMethodTestsIterator.java @@ -28,6 +28,7 @@ import net.automatalib.common.util.collection.IterableUtil; import net.automatalib.common.util.collection.IteratorUtil; import net.automatalib.common.util.mapping.MutableMapping; +import net.automatalib.semantics.DeterministicFiniteSemantics.UniversalSemantics; import net.automatalib.util.automaton.Automata; import net.automatalib.util.automaton.cover.Covers; import net.automatalib.util.automaton.equivalence.CharacterizingSets; @@ -57,7 +58,7 @@ public class WpMethodTestsIterator implements Iterator> { * @param inputs * the input symbols that should be considered for test sequence generation */ - public WpMethodTestsIterator(UniversalDeterministicAutomaton automaton, + public WpMethodTestsIterator(UniversalSemantics automaton, Collection inputs) { this(automaton, inputs, 0); } @@ -72,16 +73,17 @@ public WpMethodTestsIterator(UniversalDeterministicAutomaton auto * @param maxDepth * the maximum number of symbols that are appended to the transition-cover part of the test sequences */ - public WpMethodTestsIterator(UniversalDeterministicAutomaton automaton, + public WpMethodTestsIterator(UniversalSemantics semantics, Collection inputs, int maxDepth) { + final UniversalDeterministicAutomaton automaton = semantics.getSemantics(); final Set> stateCover = new HashSet<>(HashUtil.capacity(automaton.size())); final Set> transitionCover = new HashSet<>(HashUtil.capacity(automaton.size() * inputs.size())); - Covers.cover(automaton, inputs, stateCover, transitionCover); + Covers.cover(semantics, inputs, stateCover, transitionCover); - Iterator> characterizingIter = CharacterizingSets.characterizingSetIterator(automaton, inputs); + Iterator> characterizingIter = CharacterizingSets.characterizingSetIterator(semantics, inputs); // Special case: List of characterizing suffixes may be empty, // but in this case we still need to iterate over the prefixes! @@ -95,7 +97,7 @@ public WpMethodTestsIterator(UniversalDeterministicAutomaton auto // Phase 2: transitions (not in state cover) * middle part * local suffixes transitionCover.removeAll(stateCover); - final Iterator> secondIterator = new SecondPhaseIterator<>(automaton, + final Iterator> secondIterator = new SecondPhaseIterator<>(semantics, inputs, transitionCover, IterableUtil.allTuples(inputs, 0, maxDepth)); @@ -145,19 +147,21 @@ protected Word combine(Word suffix, List middle, Word prefix) { private static class SecondPhaseIterator extends AbstractThreeLevelIterator, List, Word, Word> { + private final UniversalSemantics semantics; private final UniversalDeterministicAutomaton automaton; private final Collection inputs; private final MutableMapping>> localSuffixSets; private final Iterable> middleParts; - SecondPhaseIterator(UniversalDeterministicAutomaton automaton, + SecondPhaseIterator(UniversalSemantics semantics, Collection inputs, Iterable> prefixes, Iterable> middleParts) { super(prefixes.iterator()); - this.automaton = automaton; + this.semantics = semantics; + this.automaton = semantics.getSemantics(); this.inputs = inputs; this.localSuffixSets = automaton.createStaticStateMapping(); this.middleParts = middleParts; @@ -179,7 +183,7 @@ protected Iterator> l3Iterator(Word prefix, List middle) { @Nullable List> localSuffixes = localSuffixSets.get(state); if (localSuffixes == null) { - localSuffixes = Automata.stateCharacterizingSet(automaton, inputs, state); + localSuffixes = Automata.stateCharacterizingSet(semantics, inputs, state); if (localSuffixes.isEmpty()) { localSuffixes = Collections.singletonList(Word.epsilon()); } diff --git a/util/src/main/java/net/automatalib/util/automaton/copy/PlainAutomatonCopy.java b/util/src/main/java/net/automatalib/util/automaton/copy/PlainAutomatonCopy.java index 394487b7e..2ff9f3538 100644 --- a/util/src/main/java/net/automatalib/util/automaton/copy/PlainAutomatonCopy.java +++ b/util/src/main/java/net/automatalib/util/automaton/copy/PlainAutomatonCopy.java @@ -29,13 +29,13 @@ final class PlainAutomatonCopy extends AbstractLowLevelAutomatonCopier> { PlainAutomatonCopy(Automaton in, - Collection inputs, - MutableAutomaton out, - Function inputsMapping, - Function spMapping, - Function tpMapping, - Predicate stateFilter, - TransitionPredicate transFilter) { + Collection inputs, + MutableAutomaton out, + Function inputsMapping, + Function spMapping, + Function tpMapping, + Predicate stateFilter, + TransitionPredicate transFilter) { super(in, inputs, out, inputsMapping, spMapping, tpMapping, stateFilter, transFilter); } diff --git a/util/src/main/java/net/automatalib/util/automaton/cover/Covers.java b/util/src/main/java/net/automatalib/util/automaton/cover/Covers.java index 9703688df..bf1d077a4 100644 --- a/util/src/main/java/net/automatalib/util/automaton/cover/Covers.java +++ b/util/src/main/java/net/automatalib/util/automaton/cover/Covers.java @@ -25,6 +25,7 @@ import java.util.function.Consumer; import net.automatalib.automaton.DeterministicAutomaton; +import net.automatalib.automaton.concept.FinSem; import net.automatalib.common.util.HashUtil; import net.automatalib.common.util.mapping.Mapping; import net.automatalib.common.util.mapping.MutableMapping; @@ -56,9 +57,9 @@ private Covers() {} * @param * input symbol type */ - public static void stateCover(DeterministicAutomaton automaton, - Collection inputs, - Collection> states) { + public static & FinSem> void stateCover(A automaton, + Collection inputs, + Collection> states) { cover(automaton, inputs, automaton.getInitialState(), states::add, w -> {}); } @@ -77,8 +78,8 @@ public static void stateCover(DeterministicAutomaton automaton, * * @see #stateCover(DeterministicAutomaton, Collection, Collection) */ - public static Iterator> stateCoverIterator(DeterministicAutomaton automaton, - Collection inputs) { + public static & FinSem> Iterator> stateCoverIterator(A automaton, + Collection inputs) { return new IncrementalStateCoverIterator<>(automaton, inputs, Collections.emptyList()); } @@ -103,9 +104,9 @@ public static Iterator> stateCoverIterator(DeterministicAutomaton * input symbol type */ - public static void transitionCover(DeterministicAutomaton automaton, - Collection inputs, - Collection> transitions) { + public static & FinSem> void transitionCover(A automaton, + Collection inputs, + Collection> transitions) { cover(automaton, inputs, automaton.getInitialState(), w -> {}, transitions::add); } @@ -124,8 +125,8 @@ public static void transitionCover(DeterministicAutomaton automa * * @see #transitionCover(DeterministicAutomaton, Collection, Collection) */ - public static Iterator> transitionCoverIterator(DeterministicAutomaton automaton, - Collection inputs) { + public static & FinSem> Iterator> transitionCoverIterator(A automaton, + Collection inputs) { return new IncrementalTransitionCoverIterator<>(automaton, inputs, Collections.emptyList()); } @@ -148,9 +149,9 @@ public static Iterator> transitionCoverIterator(DeterministicAutomat * @see #stateCover(DeterministicAutomaton, Collection, Collection) * @see #transitionCover(DeterministicAutomaton, Collection, Collection) */ - public static void structuralCover(DeterministicAutomaton automaton, - Collection inputs, - Collection> cover) { + public static & FinSem> void structuralCover(A automaton, + Collection inputs, + Collection> cover) { cover(automaton, inputs, automaton.getInitialState(), cover::add, cover::add); } @@ -173,10 +174,10 @@ public static void structuralCover(DeterministicAutomaton automa * @see #stateCover(DeterministicAutomaton, Collection, Collection) * @see #transitionCover(DeterministicAutomaton, Collection, Collection) */ - public static void cover(DeterministicAutomaton automaton, - Collection inputs, - Collection> states, - Collection> transitions) { + public static & FinSem> void cover(A automaton, + Collection inputs, + Collection> states, + Collection> transitions) { cover(automaton, inputs, automaton.getInitialState(), states::add, transitions::add); } @@ -233,7 +234,8 @@ public static void cover(DeterministicAutomaton automaton, while ((curr = bfsQueue.poll()) != null) { @SuppressWarnings("nullness") // in a breadth-first traversal the predecessors are always defined - @NonNull Word as = reach.get(curr); + @NonNull + Word as = reach.get(curr); for (I in : inputs) { S succ = automaton.getSuccessor(curr, in); @@ -276,10 +278,10 @@ public static void cover(DeterministicAutomaton automaton, * * @see #stateCover(DeterministicAutomaton, Collection, Collection) */ - public static boolean incrementalStateCover(DeterministicAutomaton automaton, - Collection inputs, - Collection> oldStates, - Collection> newStates) { + public static & FinSem> boolean incrementalStateCover(A automaton, + Collection inputs, + Collection> oldStates, + Collection> newStates) { S init = automaton.getInitialState(); if (init == null) { @@ -345,9 +347,10 @@ public static boolean incrementalStateCover(DeterministicAutomaton Iterator> incrementalStateCoverIterator(DeterministicAutomaton automaton, - Collection inputs, - Collection> stateCover) { + public static & FinSem> Iterator> incrementalStateCoverIterator( + A automaton, + Collection inputs, + Collection> stateCover) { return new IncrementalStateCoverIterator<>(automaton, inputs, stateCover); } @@ -370,10 +373,10 @@ public static Iterator> incrementalStateCoverIterator(DeterministicA * * @see #transitionCover(DeterministicAutomaton, Collection, Collection) */ - public static boolean incrementalTransitionCover(DeterministicAutomaton automaton, - Collection inputs, - Collection> oldTransCover, - Collection> newTransCover) { + public static & FinSem> boolean incrementalTransitionCover(A automaton, + Collection inputs, + Collection> oldTransCover, + Collection> newTransCover) { final int oldTransSize = newTransCover.size(); incrementalCover(automaton, inputs, Collections.emptySet(), oldTransCover, w -> {}, newTransCover::add); @@ -398,9 +401,10 @@ public static boolean incrementalTransitionCover(DeterministicAutomaton Iterator> incrementalTransitionCoverIterator(DeterministicAutomaton automaton, - Collection inputs, - Collection> transitionCover) { + public static & FinSem> Iterator> incrementalTransitionCoverIterator( + A automaton, + Collection inputs, + Collection> transitionCover) { return new IncrementalTransitionCoverIterator<>(automaton, inputs, transitionCover); } @@ -427,12 +431,12 @@ public static Iterator> incrementalTransitionCoverIterator(Determini * @see #incrementalStateCover(DeterministicAutomaton, Collection, Collection, Collection) * @see #incrementalStateCover(DeterministicAutomaton, Collection, Collection, Collection) */ - public static boolean incrementalCover(DeterministicAutomaton automaton, - Collection inputs, - Collection> oldStateCover, - Collection> oldTransCover, - Collection> newStateCover, - Collection> newTransCover) { + public static & FinSem> boolean incrementalCover(A automaton, + Collection inputs, + Collection> oldStateCover, + Collection> oldTransCover, + Collection> newStateCover, + Collection> newTransCover) { final int oldStateSize = newStateCover.size(); final int oldTransSize = newTransCover.size(); @@ -441,12 +445,21 @@ public static boolean incrementalCover(DeterministicAutomaton autom return oldStateSize < newStateCover.size() || oldTransSize < newTransCover.size(); } - private static void incrementalCover(DeterministicAutomaton automaton, - Collection inputs, - Collection> oldStateCover, - Collection> oldTransCover, - Consumer> newStateCover, - Consumer> newTransCover) { + private static void incrementalCover(DeterministicAutomaton automaton, + Collection inputs, + Collection> oldStateCover, + Collection> oldTransCover, + Consumer> newStateCover, + Consumer> newTransCover) { + incrementalCover2(automaton, inputs, oldStateCover, oldTransCover, newStateCover, newTransCover); + } + + private static void incrementalCover2(DeterministicAutomaton automaton, + Collection inputs, + Collection> oldStateCover, + Collection> oldTransCover, + Consumer> newStateCover, + Consumer> newTransCover) { S init = automaton.getInitialState(); diff --git a/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalStateCoverIterator.java b/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalStateCoverIterator.java index e186523f0..37f330169 100644 --- a/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalStateCoverIterator.java +++ b/util/src/main/java/net/automatalib/util/automaton/cover/IncrementalStateCoverIterator.java @@ -27,8 +27,8 @@ import org.checkerframework.checker.nullness.qual.Nullable; /** - * An iterator for the state cover of an automaton. Words are computed lazily (i.e., only when request by {@link - * #next()}). + * An iterator for the state cover of an automaton. Words are computed lazily (i.e., only when request by + * {@link #next()}). *