diff --git a/.idea/misc.xml b/.idea/misc.xml
index 7c7a8a7..8c5b8b8 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -7,7 +7,6 @@
-
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..2b63946
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 7c31b47..f9a5ccb 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,10 +4,8 @@
-
-
-
-
+
+
@@ -64,12 +62,10 @@
"JUnit.ComplexTests.finite2Test.executor": "Debug",
"JUnit.ComplexTests.intersection1Test.executor": "Run",
"JUnit.ComplexTests.intersection2Test.executor": "Run",
- "JUnit.myTests.executor": "Run",
"JUnit.myTests.intersection1Test.executor": "Run",
- "JUnit.myTests.myTest_1.executor": "Run",
- "JUnit.myTests.myTest_2.executor": "Run",
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
+ "SHARE_PROJECT_CONFIGURATION_FILES": "true",
"WebServerToolWindowFactoryState": "false",
"full.screen.before.presentation.mode": "false",
"git-widget-placeholder": "main",
@@ -86,12 +82,12 @@
"vue.rearranger.settings.migration": "true"
}
}]]>
-
+
-
+
@@ -102,11 +98,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -118,49 +130,26 @@
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
@@ -178,11 +167,11 @@
-
-
+
-
+
+
@@ -278,23 +267,39 @@
1704888180655
-
+
- 1704896842030
+ 1704914901826
- 1704896842030
+ 1704914901826
-
+
- 1704898189901
+ 1704914909876
- 1704898189902
+ 1704914909876
-
+
+
+ 1704915995807
+
+
+
+ 1704915995807
+
+
+
+ 1704916397835
+
+
+
+ 1704916397835
+
+
@@ -319,27 +324,28 @@
-
-
-
+
+
+
- file://$PROJECT_DIR$/src/main/java/ab1/impl/GRUPPE/NFAImpl.java
- 343
+ file://$PROJECT_DIR$/src/main/java/ab1/impl/gruppe10_aigensberger_dworski_walcher/NFAImpl.java
+ 324
- file://$PROJECT_DIR$/src/main/java/ab1/impl/GRUPPE/NFAImpl.java
- 355
+ file://$PROJECT_DIR$/src/main/java/ab1/impl/gruppe10_aigensberger_dworski_walcher/NFAImpl.java
+ 336
-
-
-
-
+
+ file://$PROJECT_DIR$/src/test/java/ab1/tests/ComplexTests.java
+ 141
+
+
diff --git a/src/main/java/ab1/impl/GRUPPE/Tuple.java b/src/main/java/ab1/impl/GRUPPE/Tuple.java
deleted file mode 100644
index 50408cc..0000000
--- a/src/main/java/ab1/impl/GRUPPE/Tuple.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package ab1.impl.GRUPPE;
-
-public class Tuple {
- private Character element_1;
-
- public Character getElement_1() {
- return element_1;
- }
-
- public void setElement_1(Character element_1) {
- this.element_1 = element_1;
- }
-
- public String getElement_2() {
- return element_2;
- }
-
- public void setElement_2(String element_2) {
- this.element_2 = element_2;
- }
-
- private String element_2;
-
-
-
- public Tuple(Character firstElement, String secondElement){
- this.element_1=firstElement;
- this.element_2=secondElement;
- }
-}
diff --git a/src/main/java/ab1/impl/GRUPPE/NFAFactoryImpl.java b/src/main/java/ab1/impl/gruppe10_aigensberger_dworski_walcher/NFAFactoryImpl.java
similarity index 54%
rename from src/main/java/ab1/impl/GRUPPE/NFAFactoryImpl.java
rename to src/main/java/ab1/impl/gruppe10_aigensberger_dworski_walcher/NFAFactoryImpl.java
index ba6743a..3f06b80 100644
--- a/src/main/java/ab1/impl/GRUPPE/NFAFactoryImpl.java
+++ b/src/main/java/ab1/impl/gruppe10_aigensberger_dworski_walcher/NFAFactoryImpl.java
@@ -1,11 +1,17 @@
-package ab1.impl.GRUPPE;
+package ab1.impl.gruppe10_aigensberger_dworski_walcher;
import ab1.NFA;
import ab1.NFAFactory;
+/**
+ * Implementation of NFAFactory
+ */
public class NFAFactoryImpl implements NFAFactory {
@Override
public NFA buildNFA(String startState) {
+ if (startState == null) {
+ return null;
+ }
return new NFAImpl(startState);
}
}
diff --git a/src/main/java/ab1/impl/GRUPPE/NFAImpl.java b/src/main/java/ab1/impl/gruppe10_aigensberger_dworski_walcher/NFAImpl.java
similarity index 76%
rename from src/main/java/ab1/impl/GRUPPE/NFAImpl.java
rename to src/main/java/ab1/impl/gruppe10_aigensberger_dworski_walcher/NFAImpl.java
index f9c6732..97e1078 100644
--- a/src/main/java/ab1/impl/GRUPPE/NFAImpl.java
+++ b/src/main/java/ab1/impl/gruppe10_aigensberger_dworski_walcher/NFAImpl.java
@@ -1,12 +1,16 @@
-package ab1.impl.GRUPPE;
+package ab1.impl.gruppe10_aigensberger_dworski_walcher;
import ab1.FinalizedStateException;
import ab1.NFA;
import ab1.Transition;
+import lombok.Getter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
+/**
+ * Implementation of the NFA interface.
+ */
public class NFAImpl implements NFA {
private final Set states;
private final Set transitions;
@@ -14,7 +18,8 @@ public class NFAImpl implements NFA {
private final String initialState;
private final Set acceptingStates;
- private Set alphabet;
+ @Getter
+ private final Set alphabet;
private final Set completeAlphabet;
private boolean isFinalized;
@@ -39,14 +44,6 @@ public class NFAImpl implements NFA {
return this.states;
}
- /*
- public void safeAddStates(Set states, Set toCheck, NFAImpl nfa) {
- for (String state : states) {
- nfa.states.add(changeIfNecessary(state, toCheck));
- }
- }
- */
-
@Override
public Collection getTransitions() {
return this.transitions;
@@ -62,28 +59,34 @@ public class NFAImpl implements NFA {
return this.initialState;
}
- public Set getAlphabet() {
- return this.alphabet;
- }
-
+ /**
+ * Adds a new transition to the automaton. If the automaton is already finalized, a FinalizedStateException is thrown.
+ * @param transition The transition to add
+ * @throws FinalizedStateException If the automaton is already finalized
+ */
@Override
public void addTransition(Transition transition) throws FinalizedStateException {
if (this.isFinalized) {
throw new FinalizedStateException();
}
- if (!states.contains(transition.fromState())) {
- this.states.add(transition.fromState());
+ if (transition == null || transition.fromState() == null || transition.toState() == null) {
+ throw new IllegalArgumentException();
}
- if (!states.contains(transition.toState())) {
- this.states.add(transition.toState());
+
+ states.add(transition.fromState());
+ states.add(transition.toState());
+
+ if (transition.readSymbol()!=null) {
+ alphabet.add(transition.readSymbol());
}
- // add symbol to alphabet. If it is already in the alphabet, nothing happens
- if (transition.readSymbol() != null) {
- this.alphabet.add(transition.readSymbol());
- }
- this.transitions.add(transition);
+ transitions.add(transition);
}
+ /**
+ * Adds all transitions to the automaton. If the automaton is already finalized, a FinalizedStateException is thrown.
+ * @param transitions The Set of transitions to add
+ * @throws FinalizedStateException If the automaton is already finalized
+ */
public void addAllTransitions(Set transitions) throws FinalizedStateException {
if (this.isFinalized) {
throw new FinalizedStateException();
@@ -93,49 +96,79 @@ public class NFAImpl implements NFA {
}
}
+ /**
+ * Adds a new accepting state to the automaton. If the automaton is already finalized, a FinalizedStateException is thrown.
+ * @param state The state to add as accepting state
+ * @throws FinalizedStateException If the automaton is already finalized
+ */
@Override
public void addAcceptingState(String state) throws FinalizedStateException {
if (this.isFinalized) {
throw new FinalizedStateException();
}
+ if (state == null) {
+ throw new IllegalArgumentException();
+ }
this.states.add(state);
this.acceptingStates.add(state);
}
+ /**
+ * Adds all accepting states to the automaton. If the automaton is already finalized, a FinalizedStateException is thrown.
+ * @param states The Set of states to add as accepting states
+ * @throws FinalizedStateException If the automaton is already finalized
+ */
public void addAllAcceptingStates(Set states) throws FinalizedStateException {
if (this.isFinalized) {
throw new FinalizedStateException();
}
+ if (states == null) {
+ throw new IllegalArgumentException();
+ }
for (String state : states) {
this.addAcceptingState(state);
}
}
+ /**
+ * Adds a new state to the automaton. If the automaton is already finalized, a FinalizedStateException is thrown.
+ * If the state already exists, the state is renamed to state1, state11, state111, etc. until a unique name is found.
+ * @param states The Set of states to add
+ * @param toCheck The Set of states to check for duplicates
+ * @param nfa The NFA to add the states to
+ */
public void safeAddAcceptingStates(Set states, Set toCheck, NFAImpl nfa) {
+ if (this.isFinalized) {
+ throw new FinalizedStateException();
+ }
+ if(states == null || toCheck == null || nfa == null){
+ throw new IllegalArgumentException();
+ }
for (String state : states) {
nfa.addAcceptingState(changeIfNecessary(state, toCheck));
}
}
- // #TODO
- // write more testcases
+ /**
+ * Creates a new NFA that is the union of this NFA and the other NFA. If either of the NFAs is not finalized, a FinalizedStateException is thrown.
+ * @param other The other NFA to union with
+ * @return The union of this NFA and the other NFA
+ * @throws FinalizedStateException If either of the NFAs is not finalized
+ */
@Override
public NFA union(NFA other) throws FinalizedStateException {
if (!this.isFinalized || !other.isFinalized()) {
throw new FinalizedStateException();
}
- // new initialState with epsilon to initialState of this and other.
- // Problem: what if states are called the same in this and other + what do we use as initialState?
+
NFAImpl unionNFA = new NFAImpl(this.getInitialState());
unionNFA.states.addAll(this.states);
-
unionNFA.addAllAcceptingStates(this.acceptingStates);
Set otherAcceptingStates = new HashSet<>(other.getAcceptingStates());
unionNFA.safeAddAcceptingStates(this.acceptingStates, otherAcceptingStates, unionNFA);
-
Set newTransitions = new HashSet<>();
for (Transition transition : other.getTransitions()) {
Transition newTransition =
@@ -152,14 +185,9 @@ public class NFAImpl implements NFA {
unionNFA.acceptingStates.add(state);
}
} else {
- // a state of other has the same name as one in this.
- // change name of state and every Transition it is a part of in other
String newState = changeIfNecessary(state, unionNFA.states);
-
- // wieder a neues set
Set tempTransitions = new HashSet<>();
- // check each transition of other if start or to state was state
for (Transition transition : newTransitions) {
if (transition.fromState().equals(state)) {
transition = new Transition(newState, transition.readSymbol(), transition.toState());
@@ -169,16 +197,15 @@ public class NFAImpl implements NFA {
}
tempTransitions.add(transition);
}
+
for (String accState : other.getAcceptingStates()) {
if (accState.equals(state)) {
unionNFA.acceptingStates.add(newState);
}
}
- newTransitions = tempTransitions; // Replace the original set with the updated set
+ newTransitions = tempTransitions;
}
}
- // add, alphabet
-
Iterator iterator = newTransitions.iterator();
while (iterator.hasNext()){
Transition transition = iterator.next();
@@ -191,17 +218,18 @@ public class NFAImpl implements NFA {
}
unionNFA.addAllTransitions(newTransitions);
-
unionNFA.addAllTransitions(this.transitions);
-
unionNFA.finalizeAutomaton();
-
return unionNFA;
}
- // #TODO
- // needs to work with a DFA not NFA
+ /**
+ * Creates a new NFA that is the intersection of this NFA and the other NFA. If either of the NFAs is not finalized, a FinalizedStateException is thrown.
+ * @param other The other NFA to intersect with
+ * @return The intersection of this NFA and the other NFA
+ * @throws FinalizedStateException If either of the NFAs is not finalized
+ */
@Override
public NFA intersection(NFA other) throws FinalizedStateException {
if (!this.isFinalized || !other.isFinalized()) {
@@ -213,6 +241,12 @@ public class NFAImpl implements NFA {
return unionNFA.complement();
}
+ /**
+ * Creates a new NFA that is the concatenation of this NFA and the other NFA. If either of the NFAs is not finalized, a FinalizedStateException is thrown.
+ * @param other The other NFA to concatenate with
+ * @return The concatenation of this NFA and the other NFA
+ * @throws FinalizedStateException If either of the NFAs is not finalized
+ */
@Override
public NFA concatenation(NFA other) throws FinalizedStateException {
if (!this.isFinalized || !other.isFinalized()) {
@@ -221,10 +255,8 @@ public class NFAImpl implements NFA {
NFAImpl concatenationNFA = new NFAImpl(this.initialState);
- // Add states from 'this'
concatenationNFA.states.addAll(this.states);
- // Add states from 'other', with renaming if necessary
Map renamedStates = new HashMap<>();
for (String state : other.getStates()) {
String newState = changeIfNecessary(state, concatenationNFA.states);
@@ -232,10 +264,8 @@ public class NFAImpl implements NFA {
concatenationNFA.states.add(newState);
}
- // Add transitions from 'this'
concatenationNFA.transitions.addAll(this.transitions);
- // Add transitions from 'other', updating state names
for (Transition transition : other.getTransitions()) {
String newFromState = renamedStates.getOrDefault(transition.fromState(), transition.fromState());
String newToState = renamedStates.getOrDefault(transition.toState(), transition.toState());
@@ -243,14 +273,12 @@ public class NFAImpl implements NFA {
concatenationNFA.transitions.add(newTransition);
}
- // Connect accepting states of 'this' to the initial state of 'other' with epsilon transitions
String newOtherInitialState = renamedStates.getOrDefault(other.getInitialState(), other.getInitialState());
for (String acceptingState : this.acceptingStates) {
Transition epsilon = new Transition(acceptingState, null, newOtherInitialState);
concatenationNFA.transitions.add(epsilon);
}
- // Set accepting states of the concatenated NFA to be the accepting states of 'other'
concatenationNFA.acceptingStates.clear();
for (String acceptingState : other.getAcceptingStates()) {
concatenationNFA.acceptingStates.add(renamedStates.getOrDefault(acceptingState, acceptingState));
@@ -261,7 +289,11 @@ public class NFAImpl implements NFA {
return concatenationNFA;
}
-
+ /**
+ * Creates a new NFA that is the Kleene star of this NFA. If the NFA is not finalized, a FinalizedStateException is thrown.
+ * @return The Kleene star of this NFA
+ * @throws FinalizedStateException If the NFA is not finalized
+ */
@Override
public NFA kleeneStar() throws FinalizedStateException {
if (!this.isFinalized) {
@@ -270,17 +302,13 @@ public class NFAImpl implements NFA {
NFAImpl nfa = new NFAImpl(this.initialState);
- // copy, but without accepting states
nfa.states.addAll(this.states);
nfa.addAllTransitions(this.transitions);
- // adding the initial state as accepting state because we have to accept the empty string
nfa.acceptingStates.add(this.initialState);
- // for each accepting state
for (String acceptingState : this.getAcceptingStates()) {
Transition loopBackTransition =
- // creating an epsilon transition (null) for each accepting state
new Transition(acceptingState, null, this.initialState);
nfa.transitions.add(loopBackTransition);
}
@@ -290,6 +318,11 @@ public class NFAImpl implements NFA {
return nfa;
}
+ /**
+ * Creates a new NFA that is the plus operator of this NFA. If the NFA is not finalized, a FinalizedStateException is thrown.
+ * @return The plus operator of this NFA
+ * @throws FinalizedStateException If the NFA is not finalized
+ */
@Override
public NFA plusOperator() throws FinalizedStateException {
if (!this.isFinalized) {
@@ -299,55 +332,41 @@ public class NFAImpl implements NFA {
String newInitialState = "newSTART";
NFAImpl nfa = new NFAImpl(newInitialState);
- // simple copy
nfa.states.addAll(this.states);
nfa.transitions.addAll(this.transitions);
nfa.acceptingStates.addAll(this.acceptingStates);
nfa.transitions.add(new Transition(newInitialState, null, this.initialState));
-
for (String acceptingState : this.acceptingStates) {
nfa.transitions.add(new Transition(acceptingState, null, newInitialState));
}
- /*
- // for each accepting state
- for (String acceptingState : this.acceptingStates) {
- Transition loopBackTransition =
- // creating an epsilon transition (null) for each accepting state
- new Transition(acceptingState, null, this.initialState);
- if (!nfa.transitions.contains(loopBackTransition)) {
- nfa.transitions.add(loopBackTransition);
- }
- }
- */
-
nfa.finalizeAutomaton();
return nfa;
}
- // #TODO
+ /**
+ * Creates a new NFA that is the complement of this NFA. If the NFA is not finalized, a FinalizedStateException is thrown.
+ * @return The complement of this NFA
+ * @throws FinalizedStateException If the NFA is not finalized
+ */
@Override
public NFA complement() throws FinalizedStateException {
if (!this.isFinalized) {
throw new FinalizedStateException();
}
- // create a copy of this NFA
NFAImpl nfa = new NFAImpl(this.initialState);
nfa.states.addAll(this.states);
nfa.addAllTransitions(this.transitions);
nfa.addAllAcceptingStates(this.acceptingStates);
- nfaAddTrap(nfa); //error on last occasion
+ nfaAddTrap(nfa);
NFAImpl fakeNFA = convertNFAtoDFA(nfa);
- // state -> accepting
- // accepting -> state
-
Set newAcceptingState = new HashSet<>();
for (String state : fakeNFA.getStates()) {
@@ -355,38 +374,42 @@ public class NFAImpl implements NFA {
newAcceptingState.add(state);
}
}
+
fakeNFA.acceptingStates.clear();
fakeNFA.addAllAcceptingStates(newAcceptingState);
-
fakeNFA.finalizeAutomaton();
return fakeNFA;
}
+ /**
+ * Returns whether the automaton is finalized.
+ * @return Whether the automaton is finalized
+ */
@Override
public boolean isFinalized() {
return isFinalized;
}
+ /**
+ * Finalizes the automaton. After finalization, no further states or transitions can be added.
+ */
@Override
public void finalizeAutomaton() {
this.isFinalized = true;
}
- // #TODO
+ /**
+ * Returns whether the automaton is finite. An automaton is finite if it has a finite number of states and no loops, that have a path to an accepting state.
+ * @return Whether the automaton is finite
+ */
@Override
public boolean isFinite() {
- //transitions={fromState==toState}
- //states={A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z}
- //obergrenze = anzahl der states (26)
-
- //how do we get an infinite language?
- //we need to have a loop, how can we check:
List path = new ArrayList<>();
List transitions= new ArrayList<>(this.getTransitions());
- AtomicInteger finished = new AtomicInteger(0); //0=unfinished, 1=finite, 2 = infinite
- List letters = new ArrayList<>(this.alphabet); // letters is alphabet with epsilon (null)
+ AtomicInteger finished = new AtomicInteger(0);
+ List letters = new ArrayList<>(this.alphabet);
if(this.alphabet.isEmpty()){
return true;
}
@@ -394,7 +417,6 @@ public class NFAImpl implements NFA {
letters.add(null);
}
- // EndTuple hast firstElement = a //doesn´t matter at all aktually
path.add(new Tuple('a', this.initialState));
if(fillToEnd(path, transitions, letters, finished)){
return false;
@@ -409,7 +431,6 @@ public class NFAImpl implements NFA {
}
System.out.println("ERROR-isFinite method isn´t running right!");
return true;
- //return continueOnLastTuple(path, transitions, letters);
}
private void continueOnLastTuple(List path, List transitions, List letters, AtomicInteger finished) {
@@ -538,6 +559,7 @@ public class NFAImpl implements NFA {
}
return false;
}
+
private boolean stateReachesAcceptingstates(String state){
if(this.acceptingStates.contains(state)){
return true;
@@ -568,7 +590,12 @@ public class NFAImpl implements NFA {
return false;
}
- // #TODO
+ /**
+ * Returns whether the automaton accepts the given word. If the automaton is not finalized, a FinalizedStateException is thrown.
+ * @param word word to check, can be empty
+ * @return Whether the automaton accepts the given word
+ * @throws FinalizedStateException If the automaton is not finalized
+ */
@Override
public boolean acceptsWord(String word) throws FinalizedStateException {
if (!this.isFinalized) {
@@ -582,46 +609,41 @@ public class NFAImpl implements NFA {
currentStates = (epsilonClosure(currentStates, this));
for (char letter : wordArray) {
- // schritt a
currentStates = getStateAfterTransition(currentStates, letter, this);
- // schritt b
currentStates = epsilonClosure(currentStates, this);
}
-
-
return isAcceptingState(currentStates, this);
}
+
+ /**
+ * Converts the given NFA to a DFA. If the NFA is not finalized, a FinalizedStateException is thrown.
+ * @param input The NFA to convert
+ * @return The converted DFA
+ */
public NFAImpl convertNFAtoDFA(NFAImpl input) {
- // all accepting states of the DFA
Set dfaAcceptingStates = new HashSet<>();
- // all states of the DFA
List> dfaStates = new ArrayList<>();
- // all transitions of the DFA
Set dfaTransitions = new HashSet<>();
-
- // all states of the NFA
Set startState = new HashSet<>();
startState.add(input.getInitialState());
- // getting the epsilon closure of the start state
startState = epsilonClosure(startState, input);
dfaStates.add(startState);
if (isAcceptingState(startState, input)) {
dfaAcceptingStates.add(getIndexOfSet(startState, dfaStates));
}
- // do the above with each DFA state
Queue> queue = new LinkedList<>();
queue.add(startState);
- // iterate each Letter
+
while (!queue.isEmpty()) {
Set currentState = queue.poll();
- // for each possible Letter
+
for (char letter : input.getAlphabet()) {
- // get the new state after the transition
+
Set newState = epsilonClosure(getStateAfterTransition(currentState, letter, input), input);
if (!dfaStates.contains(newState)) {
queue.add(newState);
@@ -632,7 +654,6 @@ public class NFAImpl implements NFA {
}
- // build new Transition
dfaTransitions.add(new Transition(getIndexOfSet(currentState, dfaStates), letter, getIndexOfSet(newState, dfaStates)));
}
}
@@ -649,6 +670,12 @@ public class NFAImpl implements NFA {
return newDFA;
}
+ /**
+ * Returns the epsilon closure of the given states.
+ * @param states The states to get the epsilon closure of
+ * @param nfa The NFA to get the epsilon closure from
+ * @return The epsilon closure of the given states
+ */
private Set epsilonClosure(Set states, NFA nfa) {
Set closure = new HashSet<>(states);
Stack stack = new Stack<>();
@@ -666,6 +693,13 @@ public class NFAImpl implements NFA {
return closure;
}
+ /**
+ * Returns the states that are reached by the given states after reading the given symbol.
+ * @param states The states to get the states after reading the symbol of
+ * @param symbol The symbol to read
+ * @param nfa The NFA to get the states from
+ * @return The states that are reached by the given states after reading the given symbol
+ */
private Set getStateAfterTransition(Set states, char symbol, NFA nfa) {
Set result = new HashSet<>();
for (String state : states) {
@@ -678,6 +712,12 @@ public class NFAImpl implements NFA {
return result;
}
+ /**
+ * Returns whether the given states contain an accepting state.
+ * @param states The states to check
+ * @param input The NFA to check the states for
+ * @return Whether the given states contain an accepting state
+ */
private boolean isAcceptingState(Set states, NFA input) {
for (String accState : input.getAcceptingStates()) {
if (states.contains(accState)) {
@@ -687,10 +727,22 @@ public class NFAImpl implements NFA {
return false;
}
+ /**
+ * Returns the index of the given set in the given list.
+ * @param set The set to get the index of
+ * @param dfaStates The list to get the index from
+ * @return The index of the given set in the given list
+ */
private String getIndexOfSet(Set set, List> dfaStates) {
return Integer.toString(dfaStates.indexOf(set));
}
+ /**
+ * Returns the given string with a number appended to it, if the string already exists in the given set.
+ * @param str The string to check
+ * @param toCheck The set to check for duplicates
+ * @return The given string with a number appended to it, if the string already exists in the given set
+ */
private String changeIfNecessary(String str, Set toCheck) {
while (toCheck.contains(str)) {
str = str + "1";
@@ -698,6 +750,10 @@ public class NFAImpl implements NFA {
return str;
}
+ /**
+ * Adds a trap state to the given NFA.
+ * @param input The NFA to add the trap state to
+ */
private void nfaAddTrap(NFAImpl input){
String trap = changeIfNecessary("TRAP", input.getStates());
input.states.add(trap);
@@ -718,7 +774,6 @@ public class NFAImpl implements NFA {
}
}
}
- input.addAllTransitions(newTransitions); //input.transitions.addAll(newTransitions);
+ input.addAllTransitions(newTransitions);
}
-
}
diff --git a/src/main/java/ab1/impl/gruppe10_aigensberger_dworski_walcher/Tuple.java b/src/main/java/ab1/impl/gruppe10_aigensberger_dworski_walcher/Tuple.java
new file mode 100644
index 0000000..4dff076
--- /dev/null
+++ b/src/main/java/ab1/impl/gruppe10_aigensberger_dworski_walcher/Tuple.java
@@ -0,0 +1,14 @@
+package ab1.impl.gruppe10_aigensberger_dworski_walcher;
+
+import lombok.Getter;
+
+@Getter
+public class Tuple {
+ private final Character element_1;
+ private final String element_2;
+
+ public Tuple(Character firstElement, String secondElement){
+ this.element_1=firstElement;
+ this.element_2=secondElement;
+ }
+}
diff --git a/src/test/java/ab1/NFAProvider.java b/src/test/java/ab1/NFAProvider.java
index 35a3994..cc26c68 100644
--- a/src/test/java/ab1/NFAProvider.java
+++ b/src/test/java/ab1/NFAProvider.java
@@ -1,6 +1,6 @@
package ab1;
-import ab1.impl.GRUPPE.NFAFactoryImpl;
+import ab1.impl.gruppe10_aigensberger_dworski_walcher.NFAFactoryImpl;
public class NFAProvider {
public static NFAFactory provideFactory() {
diff --git a/src/test/java/ab1/tests/GRUPPE/BetterSimpleTests.java b/src/test/java/ab1/tests/GRUPPE/BetterSimpleTests.java
new file mode 100644
index 0000000..b03d037
--- /dev/null
+++ b/src/test/java/ab1/tests/GRUPPE/BetterSimpleTests.java
@@ -0,0 +1,76 @@
+package ab1.tests.GRUPPE;
+
+import ab1.NFAFactory;
+import ab1.NFAProvider;
+import ab1.Transition;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * Simple tests for the NFA implementation.
+ */
+public class BetterSimpleTests {
+ private final NFAFactory factory = NFAProvider.provideFactory();
+ @Test
+ public void invalidInputTest() {
+ var instance = factory.buildNFA(null);
+ assertNull(instance);
+ }
+
+ @Test
+ public void invalidAcceptingState() {
+ var instance = factory.buildNFA("START");
+ assertThrows(IllegalArgumentException.class, () -> instance.addAcceptingState(null));
+ }
+
+ @Test
+ public void invalidTransition() {
+ var instance = factory.buildNFA("START");
+ assertThrows(IllegalArgumentException.class, () -> instance.addTransition(null));
+ }
+
+ @Test
+ public void transitionWithoutToState() {
+ var instance = factory.buildNFA("START");
+ Transition transition = ab1.Transition.builder()
+ .readSymbol('a')
+ .fromState("START")
+ .build();
+
+ assertThrows(IllegalArgumentException.class, () -> instance.addTransition(transition));
+ }
+
+ @Test
+ public void transitionWithoutExistingToState() {
+ var instance = factory.buildNFA("START");
+ instance.addTransition(
+ ab1.Transition.builder()
+ .readSymbol('a')
+ .fromState("START")
+ .toState("END")
+ .build()
+ );
+ assertEquals(1, instance.getTransitions().size());
+ assertEquals(2, instance.getStates().size());
+ assertEquals(0, instance.getAcceptingStates().size());
+ }
+
+ @Test
+ public void notInAlphabet(){
+ var instance = factory.buildNFA("START");
+ instance.addTransition(
+ ab1.Transition.builder()
+ .readSymbol('a')
+ .fromState("START")
+ .toState("END")
+ .build()
+ );
+ instance.addAcceptingState("END");
+ instance.finalizeAutomaton();
+
+ assertFalse(instance.acceptsWord("b"));
+ assertTrue(instance.acceptsWord("a"));
+ assertFalse(instance.acceptsWord("ab"));
+ }
+}
diff --git a/src/test/java/ab1/tests/myTests.java b/src/test/java/ab1/tests/GRUPPE/MyTests.java
similarity index 90%
rename from src/test/java/ab1/tests/myTests.java
rename to src/test/java/ab1/tests/GRUPPE/MyTests.java
index 1b33ccd..022635a 100644
--- a/src/test/java/ab1/tests/myTests.java
+++ b/src/test/java/ab1/tests/GRUPPE/MyTests.java
@@ -1,17 +1,18 @@
-package ab1.tests;
+package ab1.tests.GRUPPE;
import ab1.NFA;
import ab1.NFAFactory;
import ab1.NFAProvider;
import ab1.Transition;
import org.junit.jupiter.api.Test;
-
import java.util.Random;
-
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-public class myTests {
+/**
+ * This is a test class for the NFA implementation.
+ */
+public class MyTests {
private final NFAFactory factory = NFAProvider.provideFactory();
@Test
@@ -105,23 +106,6 @@ public class myTests {
}
-
-
- private NFA buildCharStarLanguage(char c) {
- var instance = factory.buildNFA("START");
- instance.addTransition(
- Transition.builder()
- .fromState("START")
- .readSymbol(c)
- .toState("START")
- .build()
- );
- instance.addAcceptingState("START");
- instance.finalizeAutomaton();
-
- return instance;
- }
-
private NFA buildCharLanguage(char c) {
var instance = factory.buildNFA("START");
instance.addTransition(
diff --git a/target/classes/ab1/Transition$TransitionBuilder.class b/target/classes/ab1/Transition$TransitionBuilder.class
index 8deddb3..6a10a5f 100644
Binary files a/target/classes/ab1/Transition$TransitionBuilder.class and b/target/classes/ab1/Transition$TransitionBuilder.class differ
diff --git a/target/classes/ab1/Transition.class b/target/classes/ab1/Transition.class
index 55ad5d1..d83e6b5 100644
Binary files a/target/classes/ab1/Transition.class and b/target/classes/ab1/Transition.class differ
diff --git a/target/classes/ab1/impl/GRUPPE/NFAFactoryImpl.class b/target/classes/ab1/impl/GRUPPE/NFAFactoryImpl.class
deleted file mode 100644
index dab8ab8..0000000
Binary files a/target/classes/ab1/impl/GRUPPE/NFAFactoryImpl.class and /dev/null differ
diff --git a/target/test-classes/ab1/NFAProvider.class b/target/test-classes/ab1/NFAProvider.class
index 054610b..ad85577 100644
Binary files a/target/test-classes/ab1/NFAProvider.class and b/target/test-classes/ab1/NFAProvider.class differ
diff --git a/target/test-classes/ab1/tests/FinalizeTests.class b/target/test-classes/ab1/tests/FinalizeTests.class
index 17e959c..1057baf 100644
Binary files a/target/test-classes/ab1/tests/FinalizeTests.class and b/target/test-classes/ab1/tests/FinalizeTests.class differ