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 |