@ -3,13 +3,13 @@ package automata.finite;
import java.util.BitSet ;
import java.util.BitSet ;
import java.util.HashMap ;
import java.util.HashMap ;
import java.util.HashSet ;
import java.util.HashSet ;
import java.util.Iterator ;
import java.util.LinkedList ;
import java.util.LinkedList ;
import java.util.Set ;
import parser.ast.Expression ;
import parser.ast.Expression ;
import parser.ast.ExpressionLabel ;
import parser.ast.ExpressionLabel ;
import parser.ast.ExpressionRegular ;
import parser.ast.ExpressionRegular ;
import automata.finite.MultiEdge ;
/ * *
/ * *
* Class to store a non - deterministic finite automaton .
* Class to store a non - deterministic finite automaton .
* /
* /
@ -270,6 +270,9 @@ public class NondeterministicFiniteAutomaton<Symbol> extends FiniteAutomaton<Sym
@Override
@Override
public HashSet < State > getSuccessors ( State state ) {
public HashSet < State > getSuccessors ( State state ) {
HashSet < State > result = new HashSet < State > ( ) ;
HashSet < State > result = new HashSet < State > ( ) ;
if ( ! outgoingEdges . containsKey ( state ) ) {
outgoingEdges . put ( state , new HashSet < MultiEdge < Symbol > > ( ) ) ;
}
for ( MultiEdge < Symbol > edge : outgoingEdges . get ( state ) ) {
for ( MultiEdge < Symbol > edge : outgoingEdges . get ( state ) ) {
result . addAll ( edge . getSinks ( ) ) ;
result . addAll ( edge . getSinks ( ) ) ;
}
}
@ -297,16 +300,37 @@ public class NondeterministicFiniteAutomaton<Symbol> extends FiniteAutomaton<Sym
setInitialStates ( oldAccepting ) ;
setInitialStates ( oldAccepting ) ;
/ / Build reversed edges
/ / Build reversed edges
for ( MultiEdge < Symbol > edge : edges ) {
/ / For each sink . . .
Iterator < MultiEdge < Symbol > > it = edges . iterator ( ) ;
Set < MultiEdge < Symbol > > toAdd = new HashSet < MultiEdge < Symbol > > ( ) ;
while ( it . hasNext ( ) ) {
/ / For each sink . . .
MultiEdge < Symbol > edge = it . next ( ) ;
for ( State sink : edge . getSinks ( ) ) {
for ( State sink : edge . getSinks ( ) ) {
/ / . . . build a source singleton set . . .
/ / . . . build a source singleton set . . .
HashSet < State > source = new HashSet < State > ( ) ;
HashSet < State > source = new HashSet < State > ( ) ;
source . add ( edge . getSource ( ) ) ;
source . add ( edge . getSource ( ) ) ;
/ / . . . and add the corresponding multiedge . . .
/ / . . . and add the corresponding multiedge . . .
mergeEdge ( new MultiEdge < Symbol > ( sink , edge . getLabel ( ) , source ) ) ;
/ / mergeEdge ( new MultiEdge < Symbol > ( sink , edge . getLabel ( ) , source ) ) ;
MultiEdge < Symbol > reversedEdge = new MultiEdge < Symbol > ( sink , edge . getLabel ( ) , source ) ;
toAdd . add ( reversedEdge ) ;
}
}
unmergeEdge ( edge ) ;
/ / Unmerge edge
it . remove ( ) ;
/ / unmergeOutgoingEdge ( edge ) ;
/ / unmergeIncomingEdge ( edge ) ;
}
/ / for ( MultiEdge < Symbol > edge : edges ) {
/ / addEdge ( edge ) ;
/ / }
/ / Clear unsynchronized edges
outgoingEdges . clear ( ) ;
incomingEdges . clear ( ) ;
edges . addAll ( toAdd ) ;
for ( MultiEdge < Symbol > edge : edges ) {
mergeOutgoingEdge ( edge ) ;
mergeIncomingEdge ( edge ) ;
}
}
}
}
@ -319,10 +343,20 @@ public class NondeterministicFiniteAutomaton<Symbol> extends FiniteAutomaton<Sym
DeterministicFiniteAutomaton < Symbol > dfa = new DeterministicFiniteAutomaton < Symbol > ( ) ;
DeterministicFiniteAutomaton < Symbol > dfa = new DeterministicFiniteAutomaton < Symbol > ( ) ;
/ / Take over the symbols
dfa . setApList ( apList ) ;
/ / The new initial state is the set of all old initial states
/ / The new initial state is the set of all old initial states
State dfaInitState = dfa . newState ( initialStates . toString ( ) ) ;
State dfaInitState = dfa . newState ( initialStates . toString ( ) ) ;
dfa . addInitialState ( dfaInitState ) ;
dfa . addInitialState ( dfaInitState ) ;
nfaStates . put ( dfaInitState , initialStates ) ;
nfaStates . put ( dfaInitState , initialStates ) ;
/ / The new initial state is accepting iff it contains an old accepting state
for ( State initNfaState : initialStates ) {
if ( isAcceptingState ( initNfaState ) ) {
dfa . addAcceptingState ( dfaInitState ) ;
break ;
}
}
/ / Now we expand everything we have not seen yet
/ / Now we expand everything we have not seen yet
LinkedList < State > toExplore = new LinkedList < > ( ) ;
LinkedList < State > toExplore = new LinkedList < > ( ) ;
@ -425,7 +459,7 @@ public class NondeterministicFiniteAutomaton<Symbol> extends FiniteAutomaton<Sym
if ( isAcceptingState ( state ) ) { color = "red" ; }
if ( isAcceptingState ( state ) ) { color = "red" ; }
if ( isInitialState ( state ) ) { color = "blue" ; }
if ( isInitialState ( state ) ) { color = "blue" ; }
if ( isAcceptingState ( state ) & & isInitialState ( state ) ) { color = "violett " ; }
if ( isAcceptingState ( state ) & & isInitialState ( state ) ) { color = "violet" ; }
result . append ( state
result . append ( state
+ "[shape=box, color=" + color + ","
+ "[shape=box, color=" + color + ","