NFA.java

1    import java.util.*; 
2    import java.util.Map.Entry; 
3     
4    /** 
5     * Created by IntelliJ IDEA. 
6     * Code By: Bo Li, libo@libo.me 
7     * Date: 2009-12-10 
8     * Time: 15:27:37 
9     * CBIT, Roskilde University 
10    */ 
11   public class NFA { 
12       private int iState; 
13       private int aState; 
14       Map<Integer, ArrayList<transition>> trans; 
15    
16       public NFA(int iState, int aState) { 
17           this.iState = iState; 
18           this.aState = aState; 
19           trans = new HashMap<Integer, ArrayList<transition>>(); 
20           trans.put(iState, new ArrayList<transition>()); 
21       } 
22    
23       public void AddTransitions(int s1, int s2, String lab) { 
24           ArrayList<transition> transitions = new ArrayList<transition>(); 
25           if (trans.containsKey(s1)) 
26               trans.get(s1).add(new transition(s1, s2, lab)); 
27           else { 
28               transitions = new ArrayList<transition>(); 
29               trans.put(s1, transitions); 
30           } 
31           transitions.add(new transition(s1, s2, lab)); 
32       } 
33    
34       public int Start() { 
35           return iState; 
36       } 
37    
38       public int Exit() { 
39           return aState; 
40       } 
41    
42       public String toString() { 
43           return "NFA start->" + iState + "  trans-> " + trans + " exit->" + aState; 
44       } 
45    
46       public static class stateName { 
47           public static int nextState = 0; 
48    
49           public int next() { 
50               return nextState++; 
51           } 
52       } 
53    
54       public static Set<Integer> GetLambdaClosure(Set<Integer> S, Map<Integer, ArrayList<transition>> trans) { 
55           Queue<Integer> worklist = new LinkedList<Integer>(); 
56           worklist.addAll(S); 
57           Set<Integer> LamClosure = new HashSet<Integer>(); 
58           LamClosure.addAll(S); 
59           while (!worklist.isEmpty()) { 
60               int s = worklist.poll(); 
61               if (trans.containsKey(s)) { 
62                   for (transition t : trans.get(s)) { 
63                       if (t.lab == "lambda" && !LamClosure.contains(t.nextState)) { 
64                           LamClosure.add(t.nextState); 
65                           worklist.offer(t.nextState); 
66                       } 
67                   } 
68               } 
69           } 
70           return LamClosure; 
71    
72       } 
73    
74       public static Set<Integer> GetLambdaClosure(int i, Map<Integer, ArrayList<transition>> trans) { 
75           Set<Integer> j = new HashSet<Integer>(); 
76           j.add(i); 
77           Set<Integer> LambdaClosure = GetLambdaClosure(j, trans); 
78           return LambdaClosure; 
79       } 
80    
81       public static Map<Set<Integer>, Integer> newState(Set<Set<Integer>> states) { 
82           Map<Set<Integer>, Integer> nState = new HashMap<Set<Integer>, Integer>(); 
83           int i = 0; 
84           for (Set<Integer> s : states) { 
85               nState.put(s, i); 
86               i++; 
87           } 
88           return nState; 
89       } 
90    
91       public static Map<Integer, Map<String, Integer>> getTrans(Map<Set<Integer>, Integer> newStates, Map<Set<Integer>, Map<String, Set<Integer>>> trs) { 
92           Map<Integer, Map<String, Integer>> newTrans = new HashMap<Integer, Map<String, Integer>>(); 
93           for (Entry<Set<Integer>, Map<String, Set<Integer>>> entry : trs.entrySet()) { 
94               Set<Integer> i = entry.getKey(); 
95               Map<String, Integer> tempTrans = new HashMap<String, Integer>(); 
96               for (String a : entry.getValue().keySet()) { 
97                   tempTrans.put(a, newStates.get(entry.getValue().get(a))); 
98               } 
99               newTrans.put(newStates.get(i), tempTrans); 
100          } 
101   
102          return newTrans; 
103      } 
104   
105      public static Map<Set<Integer>, Map<String, Set<Integer>>> NfaToDfaTrans(int start, Map<Integer, ArrayList<transition>> trans) { 
106          Map<Set<Integer>, Map<String, Set<Integer>>> DfaTrans = new HashMap<Set<Integer>, Map<String, Set<Integer>>>(); 
107   
108          Set<Integer> Start = GetLambdaClosure(start, trans); 
109          Queue<Set<Integer>> TempRunLoopUse = new LinkedList<Set<Integer>>(); 
110          TempRunLoopUse.offer(Start); 
111          while (!TempRunLoopUse.isEmpty()) { 
112              Set<Integer> S = TempRunLoopUse.poll(); 
113              if (!DfaTrans.containsKey(S)) { 
114                  Map<String, Set<Integer>> newTrans = new HashMap<String, Set<Integer>>(); 
115                  for (int s : S) 
116                      if (trans.containsKey(s)) { 
117                          for (transition t : trans.get(s)) { 
118                              if (t.lab != "lambda") { 
119                                  Set<Integer> nextStates; 
120                                  if (newTrans.containsKey(t.lab)) 
121                                      nextStates = newTrans.get(t.lab); 
122                                  else { 
123                                      nextStates = new HashSet<Integer>(); 
124                                      newTrans.put(t.lab, nextStates); 
125                                  } 
126                                  nextStates.add(t.nextState); 
127                              } 
128                          } 
129                      } 
130   
131                  Map<String, Set<Integer>> newTransClosed = new HashMap<String, Set<Integer>>(); 
132                  for (Entry<String, Set<Integer>> entry : newTrans.entrySet()) { 
133                      Set<Integer> close = GetLambdaClosure(entry.getValue(), trans); 
134                      newTransClosed.put(entry.getKey(), close); 
135                      TempRunLoopUse.offer(close); 
136                  } 
137                  DfaTrans.put(S, newTransClosed); 
138              } 
139          } 
140          return DfaTrans; 
141      } 
142   
143      public static Set<Integer> GetAcceptStates(Set<Set<Integer>> states, 
144                                                 Map<Set<Integer>, Integer> nState, int exit) { 
145   
146          Set<Integer> iAcStates = new HashSet<Integer>(); 
147          for (Set<Integer> s : states) { 
148              if (s.contains(exit)) 
149                  iAcStates.add(nState.get(s)); 
150          } 
151          return iAcStates; 
152      } 
153   
154      public DFA NfaToDfa() { 
155          Map<Set<Integer>, Map<String, Set<Integer>>> NToDTrans = NfaToDfaTrans(iState, trans); 
156          System.out.println("NFA to DFA transitions->" + NToDTrans); 
157   
158          Set<Integer> NToDStart = GetLambdaClosure(iState, trans); 
159          System.out.println("NFA to DFA new start states->" + NToDStart); 
160   
161          Map<Set<Integer>, Integer> NState = newState(NToDTrans.keySet()); 
162          System.out.println("new name of states collection->" + NState); 
163   
164          Map<Integer, Map<String, Integer>> NToDNState = getTrans(NState, NToDTrans); 
165          System.out.println("NFA to DFA new states->" + NToDNState); 
166   
167          int NToDnStart = NState.get(NToDStart); 
168          System.out.println("NFA to DFA start state->" + NToDnStart); 
169   
170          Set<Integer> NToDSAState = GetAcceptStates(NToDTrans.keySet(), NState, aState); 
171          System.out.println("NFA to DFA new accept state->" + NToDSAState); 
172          return new DFA(NToDnStart, NToDSAState, NToDNState); 
173      } 
174  } 
175   
176