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)); |