Mercurial > pub > ImplabNet
comparison Implab/Automaton/IndexedAlphabetBase.cs @ 164:ec35731ae299 ref20160224
Almost complete DFA refactoring
| author | cin |
|---|---|
| date | Thu, 25 Feb 2016 02:11:13 +0300 |
| parents | 0526412bbb26 |
| children | 96681e9d0cea |
comparison
equal
deleted
inserted
replaced
| 163:419aa51b04fd | 164:ec35731ae299 |
|---|---|
| 7 namespace Implab.Automaton { | 7 namespace Implab.Automaton { |
| 8 /// <summary> | 8 /// <summary> |
| 9 /// Indexed alphabet is the finite set of symbols where each symbol has a zero-based unique index. | 9 /// Indexed alphabet is the finite set of symbols where each symbol has a zero-based unique index. |
| 10 /// </summary> | 10 /// </summary> |
| 11 public abstract class IndexedAlphabetBase<T> : IAlphabetBuilder<T> { | 11 public abstract class IndexedAlphabetBase<T> : IAlphabetBuilder<T> { |
| 12 public const int UNCLASSIFIED = 0; | |
| 13 | |
| 14 int m_nextId = 1; | 12 int m_nextId = 1; |
| 15 readonly int[] m_map; | 13 readonly int[] m_map; |
| 16 | 14 |
| 17 public int Count { | 15 public int Count { |
| 18 get { return m_nextId; } | 16 get { return m_nextId; } |
| 29 m_nextId = map.Max() + 1; | 27 m_nextId = map.Max() + 1; |
| 30 } | 28 } |
| 31 | 29 |
| 32 public int DefineSymbol(T symbol) { | 30 public int DefineSymbol(T symbol) { |
| 33 var index = GetSymbolIndex(symbol); | 31 var index = GetSymbolIndex(symbol); |
| 34 if (m_map[index] == UNCLASSIFIED) | 32 if (m_map[index] == DFAConst.UNCLASSIFIED_INPUT) |
| 35 m_map[index] = m_nextId++; | 33 m_map[index] = m_nextId++; |
| 36 return m_map[index]; | 34 return m_map[index]; |
| 37 } | 35 } |
| 38 | 36 |
| 39 public int DefineClass(IEnumerable<T> symbols) { | 37 public int DefineClass(IEnumerable<T> symbols) { |
| 40 Safe.ArgumentNotNull(symbols, "symbols"); | 38 Safe.ArgumentNotNull(symbols, "symbols"); |
| 41 symbols = symbols.Distinct(); | 39 symbols = symbols.Distinct(); |
| 42 | 40 |
| 43 foreach (var symbol in symbols) { | 41 foreach (var symbol in symbols) { |
| 44 var index = GetSymbolIndex(symbol); | 42 var index = GetSymbolIndex(symbol); |
| 45 if (m_map[index] == UNCLASSIFIED) | 43 if (m_map[index] == DFAConst.UNCLASSIFIED_INPUT) |
| 46 m_map[GetSymbolIndex(symbol)] = m_nextId; | 44 m_map[GetSymbolIndex(symbol)] = m_nextId; |
| 47 else | 45 else |
| 48 throw new InvalidOperationException(String.Format("Symbol '{0}' already in use", symbol)); | 46 throw new InvalidOperationException(String.Format("Symbol '{0}' already in use", symbol)); |
| 49 } | 47 } |
| 50 return m_nextId++; | 48 return m_nextId++; |
| 51 } | 49 } |
| 52 | 50 |
| 53 public List<T>[] CreateReverseMap() { | 51 public List<T>[] CreateReverseMap() { |
| 54 return | 52 return |
| 55 Enumerable.Range(UNCLASSIFIED, Count) | 53 Enumerable.Range(0, Count) |
| 56 .Select( | 54 .Select( |
| 57 i => InputSymbols | 55 i => InputSymbols |
| 58 .Where(x => i != UNCLASSIFIED && m_map[GetSymbolIndex(x)] == i) | 56 .Where(x => i != DFAConst.UNCLASSIFIED_INPUT && m_map[GetSymbolIndex(x)] == i) |
| 59 .ToList() | 57 .ToList() |
| 60 ) | 58 ) |
| 61 .ToArray(); | 59 .ToArray(); |
| 62 } | 60 } |
| 63 | 61 |
| 68 | 66 |
| 69 var translationMap = new int[Count]; | 67 var translationMap = new int[Count]; |
| 70 | 68 |
| 71 foreach (var scl in classes) { | 69 foreach (var scl in classes) { |
| 72 // skip if the supper class contains the unclassified element | 70 // skip if the supper class contains the unclassified element |
| 73 if (scl.Contains(UNCLASSIFIED)) | 71 if (scl.Contains(DFAConst.UNCLASSIFIED_INPUT)) |
| 74 continue; | 72 continue; |
| 75 var range = new List<T>(); | 73 var range = new List<T>(); |
| 76 foreach (var cl in scl) { | 74 foreach (var cl in scl) { |
| 77 if (cl < 0 || cl >= reverseMap.Length) | 75 if (cl < 0 || cl >= reverseMap.Length) |
| 78 throw new ArgumentOutOfRangeException(String.Format("Class {0} is not valid for the current alphabet", cl)); | 76 throw new ArgumentOutOfRangeException(String.Format("Class {0} is not valid for the current alphabet", cl)); |
