Mercurial > pub > ImplabNet
comparison Implab/Automaton/MapAlphabet.cs @ 163:419aa51b04fd ref20160224
JSON moved to Formats namespace
Working in RegularDFA
| author | cin |
|---|---|
| date | Wed, 24 Feb 2016 20:12:52 +0300 |
| parents | |
| children | ec35731ae299 |
comparison
equal
deleted
inserted
replaced
| 162:0526412bbb26 | 163:419aa51b04fd |
|---|---|
| 1 using System; | |
| 2 using System.Collections.Generic; | |
| 3 using System.Linq; | |
| 4 | |
| 5 namespace Implab.Automaton { | |
| 6 public class MapAlphabet<T> : IAlphabetBuilder<T> { | |
| 7 readonly Dictionary<T,int> m_map; | |
| 8 int m_nextCls; | |
| 9 | |
| 10 public MapAlphabet(IEqualityComparer<T> comparer) { | |
| 11 m_map = new Dictionary<T, int>(comparer); | |
| 12 m_nextCls = 1; | |
| 13 } | |
| 14 | |
| 15 #region IAlphabetBuilder implementation | |
| 16 | |
| 17 public int DefineSymbol(T symbol) { | |
| 18 int cls; | |
| 19 if (m_map.TryGetValue(symbol, out cls)) | |
| 20 return cls; | |
| 21 | |
| 22 cls = m_nextCls++; | |
| 23 | |
| 24 m_map.Add(symbol, cls); | |
| 25 | |
| 26 return cls; | |
| 27 } | |
| 28 | |
| 29 public int DefineClass(IEnumerable<T> symbols) { | |
| 30 Safe.ArgumentNotNull(symbols, "symbols"); | |
| 31 symbols = symbols.Distinct(); | |
| 32 | |
| 33 foreach (var symbol in symbols) { | |
| 34 if (!m_map.Contains(symbol)) | |
| 35 m_map.Add(symbol, m_nextCls); | |
| 36 else | |
| 37 throw new InvalidOperationException(String.Format("Symbol '{0}' already in use", symbol)); | |
| 38 } | |
| 39 return m_nextCls++; | |
| 40 } | |
| 41 | |
| 42 #endregion | |
| 43 | |
| 44 #region IAlphabet implementation | |
| 45 | |
| 46 public List<T>[] CreateReverseMap() { | |
| 47 var empty = new List<T>(); | |
| 48 var rmap = new List<T>[m_nextCls]; | |
| 49 | |
| 50 for (int i = 0; i < rmap.Length; i++) | |
| 51 rmap[i] = empty; | |
| 52 | |
| 53 foreach (var pair in m_map) { | |
| 54 var symbols = rmap[pair.Value]; | |
| 55 if (symbols == null) { | |
| 56 symbols = new List<T>(); | |
| 57 rmap[pair.Value] = symbols; | |
| 58 } | |
| 59 | |
| 60 symbols.Add(pair.Key); | |
| 61 } | |
| 62 | |
| 63 return rmap; | |
| 64 } | |
| 65 | |
| 66 public int[] Reclassify(IAlphabetBuilder<T> newAlphabet, IEnumerable<IEnumerable<int>> classes) { | |
| 67 Safe.ArgumentNotNull(newAlphabet, "newAlphabet"); | |
| 68 Safe.ArgumentNotNull(classes, "classes"); | |
| 69 | |
| 70 var rmap = CreateReverseMap(); | |
| 71 var map = new int[rmap.Length]; | |
| 72 | |
| 73 foreach (var cls in classes) { | |
| 74 var symbols = new List<T>(); | |
| 75 foreach (var id in cls) { | |
| 76 if (id < 0 || id >= rmap.Length) | |
| 77 throw new ArgumentOutOfRangeException(String.Format("Class {0} is not valid for the current alphabet", id)); | |
| 78 if (rmap[id] != null) | |
| 79 symbols.AddRange(rmap[id]); | |
| 80 } | |
| 81 | |
| 82 var newId = newAlphabet.DefineClass(symbols); | |
| 83 | |
| 84 foreach (var id in cls) | |
| 85 map[id] = newId; | |
| 86 } | |
| 87 } | |
| 88 | |
| 89 public int Translate(T symobl) { | |
| 90 int cls; | |
| 91 return m_map.TryGetValue(symobl, out cls) ? cls : DFAConst.UNCLASSIFIED_INPUT; | |
| 92 } | |
| 93 | |
| 94 public int Count { | |
| 95 get { | |
| 96 return m_nextCls; | |
| 97 } | |
| 98 } | |
| 99 | |
| 100 #endregion | |
| 101 } | |
| 102 } | |
| 103 |
