Mercurial > pub > ImplabNet
comparison Implab/Automaton/DFATable.cs @ 181:b2b6a6640aa3 ref20160224
minor fixes and debug
| author | cin |
|---|---|
| date | Thu, 24 Mar 2016 03:54:46 +0300 |
| parents | c32688129f14 |
| children | 76e8f2ba12b8 |
comparison
equal
deleted
inserted
replaced
| 180:c32688129f14 | 181:b2b6a6640aa3 |
|---|---|
| 1 using Implab; | 1 using Implab; |
| 2 using System; | 2 using System; |
| 3 using System.Collections.Generic; | 3 using System.Collections.Generic; |
| 4 using System.Linq; | 4 using System.Linq; |
| 5 using System.Diagnostics; | |
| 5 | 6 |
| 6 namespace Implab.Automaton { | 7 namespace Implab.Automaton { |
| 7 public class DFATable : IDFATableBuilder { | 8 public class DFATable : IDFATableBuilder { |
| 8 int m_stateCount; | 9 int m_stateCount; |
| 9 int m_symbolCount; | 10 int m_symbolCount; |
| 41 | 42 |
| 42 #endregion | 43 #endregion |
| 43 | 44 |
| 44 public void SetInitialState(int s) { | 45 public void SetInitialState(int s) { |
| 45 Safe.ArgumentAssert(s >= 0, "s"); | 46 Safe.ArgumentAssert(s >= 0, "s"); |
| 47 m_stateCount = Math.Max(m_stateCount, s + 1); | |
| 46 m_initialState = s; | 48 m_initialState = s; |
| 47 } | 49 } |
| 48 | 50 |
| 49 public void MarkFinalState(int state) { | 51 public void MarkFinalState(int state) { |
| 52 m_stateCount = Math.Max(m_stateCount, state + 1); | |
| 50 m_finalStates.Add(state); | 53 m_finalStates.Add(state); |
| 51 } | 54 } |
| 52 | 55 |
| 53 public void Add(AutomatonTransition item) { | 56 public void Add(AutomatonTransition item) { |
| 54 Safe.ArgumentAssert(item.s1 >= 0, "item"); | 57 Safe.ArgumentAssert(item.s1 >= 0, "item"); |
| 55 Safe.ArgumentAssert(item.s2 >= 0, "item"); | 58 Safe.ArgumentAssert(item.s2 >= 0, "item"); |
| 56 Safe.ArgumentAssert(item.edge >= 0, "item"); | 59 Safe.ArgumentAssert(item.edge >= 0, "item"); |
| 57 | 60 |
| 58 m_stateCount = Math.Max(m_stateCount, Math.Max(item.s1, item.s2) + 1); | 61 m_stateCount = Math.Max(m_stateCount, Math.Max(item.s1, item.s2) + 1); |
| 59 m_symbolCount = Math.Max(m_symbolCount, item.edge); | 62 m_symbolCount = Math.Max(m_symbolCount, item.edge + 1); |
| 60 | 63 |
| 61 m_transitions.Add(item); | 64 m_transitions.Add(item); |
| 62 } | 65 } |
| 63 | 66 |
| 64 public void Clear() { | 67 public void Clear() { |
| 102 | 105 |
| 103 public int[,] CreateTransitionTable() { | 106 public int[,] CreateTransitionTable() { |
| 104 var table = new int[StateCount,AlphabetSize]; | 107 var table = new int[StateCount,AlphabetSize]; |
| 105 | 108 |
| 106 for (int i = 0; i < StateCount; i++) | 109 for (int i = 0; i < StateCount; i++) |
| 107 for (int j = 0; i < AlphabetSize; j++) | 110 for (int j = 0; j < AlphabetSize; j++) |
| 108 table[i, j] = AutomatonConst.UNREACHABLE_STATE; | 111 table[i, j] = AutomatonConst.UNREACHABLE_STATE; |
| 109 | 112 |
| 110 foreach (var t in this) | 113 foreach (var t in this) |
| 111 table[t.s1,t.edge] = t.s2; | 114 table[t.s1,t.edge] = t.s2; |
| 112 | 115 |
| 168 | 171 |
| 169 var rmap = m_transitions | 172 var rmap = m_transitions |
| 170 .GroupBy(t => t.s2) | 173 .GroupBy(t => t.s2) |
| 171 .ToDictionary( | 174 .ToDictionary( |
| 172 g => g.Key, // s2 | 175 g => g.Key, // s2 |
| 173 g => g.GroupBy(t => t.edge, t => t.s1).ToDictionary(p => p.Key) | 176 g => g.ToLookup(t => t.edge, t => t.s1)//.ToDictionary(p => p.Key) |
| 174 ); | 177 ); |
| 175 | 178 |
| 176 while (queue.Count > 0) { | 179 while (queue.Count > 0) { |
| 177 var stateA = queue.First(); | 180 var stateA = queue.First(); |
| 178 queue.Remove(stateA); | 181 queue.Remove(stateA); |
| 179 | 182 |
| 180 for (int c = 0; c < m_symbolCount; c++) { | 183 for (int c = 0; c < m_symbolCount; c++) { |
| 181 var stateX = new HashSet<int>(); | 184 var stateX = new HashSet<int>(); |
| 182 foreach(var a in stateA) | 185 foreach(var a in stateA.Where(rmap.ContainsKey)) |
| 183 stateX.UnionWith(rmap[a][c]); // all states from wich the symbol 'c' leads to the state 'a' | 186 stateX.UnionWith(rmap[a][c]); // all states from wich the symbol 'c' leads to the state 'a' |
| 184 | 187 |
| 185 foreach (var stateY in optimalStates.ToArray()) { | 188 foreach (var stateY in optimalStates.ToArray()) { |
| 186 if (stateX.Overlaps(stateY) && !stateY.IsSubsetOf(stateX)) { | 189 if (stateX.Overlaps(stateY) && !stateY.IsSubsetOf(stateX)) { |
| 187 var stateR1 = new HashSet<int>(stateY); | 190 var stateR1 = new HashSet<int>(stateY); |
| 241 var classes = new Dictionary<int, HashSet<int>>(); | 244 var classes = new Dictionary<int, HashSet<int>>(); |
| 242 | 245 |
| 243 foreach (var term in A) { | 246 foreach (var term in A) { |
| 244 // ищем все переходы класса по символу term | 247 // ищем все переходы класса по символу term |
| 245 var res = m_transitions.Where(t => stateMap[t.s1] == s && t.edge == term).Select(t => stateMap[t.s2]).ToArray(); | 248 var res = m_transitions.Where(t => stateMap[t.s1] == s && t.edge == term).Select(t => stateMap[t.s2]).ToArray(); |
| 249 | |
| 250 Debug.Assert(res.Length <= 1); | |
| 246 | 251 |
| 247 var s2 = res.Length > 0 ? res[0] : -1; | 252 var s2 = res.Length > 0 ? res[0] : -1; |
| 248 | 253 |
| 249 HashSet<int> a2; | 254 HashSet<int> a2; |
| 250 if (!classes.TryGetValue(s2, out a2)) { | 255 if (!classes.TryGetValue(s2, out a2)) { |
| 275 foreach (var item in minClasses) { | 280 foreach (var item in minClasses) { |
| 276 if (nextCls == AutomatonConst.UNCLASSIFIED_INPUT) | 281 if (nextCls == AutomatonConst.UNCLASSIFIED_INPUT) |
| 277 nextCls++; | 282 nextCls++; |
| 278 | 283 |
| 279 // сохраняем DFAConst.UNCLASSIFIED_INPUT | 284 // сохраняем DFAConst.UNCLASSIFIED_INPUT |
| 280 var cls = item.Contains(AutomatonConst.UNCLASSIFIED_INPUT) ? AutomatonConst.UNCLASSIFIED_INPUT : nextCls; | 285 var cls = item.Contains(AutomatonConst.UNCLASSIFIED_INPUT) ? AutomatonConst.UNCLASSIFIED_INPUT : nextCls++; |
| 281 | 286 |
| 282 foreach (var a in item) | 287 foreach (var a in item) |
| 283 alphabetMap[a] = cls; | 288 alphabetMap[a] = cls; |
| 284 | |
| 285 nextCls++; | |
| 286 } | 289 } |
| 287 | 290 |
| 288 // построение автомата | 291 // построение автомата |
| 289 optimalDFA.SetInitialState(stateMap[m_initialState]); | 292 optimalDFA.SetInitialState(stateMap[m_initialState]); |
| 290 | 293 |
