diff --git a/src/main/java/ab1/impl/GRUPPE/NFAImpl.java b/src/main/java/ab1/impl/GRUPPE/NFAImpl.java index 37beec5..d92ce1e 100644 --- a/src/main/java/ab1/impl/GRUPPE/NFAImpl.java +++ b/src/main/java/ab1/impl/GRUPPE/NFAImpl.java @@ -75,19 +75,58 @@ public class NFAImpl implements NFA { // #TODO @Override public NFA union(NFA other) throws FinalizedStateException { - return null; + if(!this.isFinalized || !other.isFinalized()){ + throw new FinalizedStateException(); + } + NFAImpl unionNFA = new NFAImpl(this.initialState); + + unionNFA.states.addAll(this.states); + unionNFA.states.addAll(other.getStates()); + + unionNFA.transitions.addAll(this.transitions); + unionNFA.transitions.addAll(other.getTransitions()); + + + return unionNFA; } // #TODO @Override public NFA intersection(NFA other) throws FinalizedStateException { - return null; + if(!this.isFinalized || !other.isFinalized()){ + throw new FinalizedStateException(); + } + NFAImpl intersectionNFA = new NFAImpl(this.initialState); + + intersectionNFA.states.addAll(this.states); + intersectionNFA.states.retainAll(other.getStates()); + + intersectionNFA.transitions.addAll(this.transitions); + intersectionNFA.transitions.retainAll(other.getTransitions()); + + return intersectionNFA; } // #TODO @Override public NFA concatenation(NFA other) throws FinalizedStateException { - return null; + if(!this.isFinalized || !other.isFinalized()){ + throw new FinalizedStateException(); + } + NFAImpl concatenationNFA = new NFAImpl(this.initialState); + + concatenationNFA.states.addAll(this.states); + concatenationNFA.states.addAll(other.getStates()); + + concatenationNFA.transitions.addAll(this.transitions); + concatenationNFA.transitions.addAll(other.getTransitions()); + + for(String accceptingState : this.acceptingStates){ + Transition epsilon = new Transition(accceptingState, null, other.getInitialState()); + concatenationNFA.transitions.add(epsilon); + } + + return concatenationNFA; } @Override @@ -189,4 +228,159 @@ public class NFAImpl implements NFA { //check if word is accepted return false; } + + public NFA convertNFAtoDFA (NFAImpl input){ + + /* + What do we need to do? + + Helper Methods: + - epsilonClosure + - getStateAfterTransition + - determineAcceptingStates + + */ + + // all states of the DFA + Set> dfaStates = new HashSet<>(); + // 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); + + // find all letters in transitions + // obsolete, added alphabet to NFA which stores all read symbols + /* + Set possibleLetters = new HashSet<>(); + Set possibleTransitions = new HashSet<>(); + for(Transition transition : input.transitions){ + for(String state : states) { + if (state.equals(transition.fromState())){ + + if(transition.readSymbol() != null){ + possibleLetters.add(transition.readSymbol()); + possibleTransitions.add(transition); + } + break; + } + } + } + */ + + // 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); + dfaStates.add(newState); + } + // we gotta change this to only a string is given + //dfaTransitions.add(new Transition(currentState, letter, newState)); + } + } +/* + for(Character letter : possibleLetters){ + Set newState = new HashSet<>(); + for(Transition trans : possibleTransitions){ + if(trans.readSymbol().equals(letter)){ + // is every transition fromState = state from states? Hoffentlich ja :') + newState.add(trans.toState()); + } + } + //deal with newState + new Transitions + if(DFA_states.contains(newState)){ + Transition newtrans = new Transition(DFA_states.get(index), letter, DFA_states.get(DFA_states.indexOf(newState))); + } + } + + */ + + // what we gonna do now? + return null; + // return new DFA(dfaStates, dfaTransitions, startState, determineAcceptingStates(dfaStates, input)); + } + + private Set epsilonClosure(Set states, NFA nfa) { + /* + Original: + + boolean isAccepting = false; + + int index = 0; + + List> DFA_states = new ArrayList<>(); + Set DFA_transitions = new HashSet<>(); + + // start state alle verbindungen mit epsilon als set + for(String state : states) { + for (Transition transition : input.transitions) { + if (state.equals(transition.fromState()) && transition.readSymbol() == null) { + if(!isAccepting) { + for (String acceptingState : acceptingStates) + if (transition.toState().equals(acceptingState)) { + isAccepting = true; + break; + } + } + states.add(transition.toState()); + // funktioniert immer noch, wenn w epsilon Übergänge hintereinander? + } + } + } + DFA_states.add(new HashSet<>(states)); + */ + + Set closure = new HashSet<>(states); + Stack stack = new Stack<>(); + stack.addAll(states); + while (!stack.isEmpty()) { + String state = stack.pop(); + for (Transition transition : nfa.getTransitions()) { + if (transition.fromState().equals(state) && transition.readSymbol() == null) { + if (closure.add(transition.toState())) { + stack.push(transition.toState()); + } + } + } + } + return closure; + } + + private Set getStateAfterTransition(Set states, char symbol, NFA nfa) { + Set result = new HashSet<>(); + for (String state : states) { + for (Transition transition : nfa.getTransitions()) { + if (transition.fromState().equals(state) && transition.readSymbol() != null && transition.readSymbol() == symbol) { + result.add(transition.toState()); + } + } + } + return result; + } + + private Set> determineAcceptingStates(Set> dfaStates, NFA nfa) { + Set> acceptingStates = new HashSet<>(); + for (Set dfaState : dfaStates) { + for (String nfaState : dfaState) { + if (nfa.getAcceptingStates().contains(nfaState)) { + acceptingStates.add(dfaState); + break; + } + } + } + return acceptingStates; + } }