diff Implab/Automaton/MapAlphabet.cs @ 190:1c2a16d071a7 v2

Слияние с ref20160224
author cin
date Fri, 22 Apr 2016 13:08:08 +0300
parents b2b6a6640aa3
children 302ca905c19e
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Automaton/MapAlphabet.cs	Fri Apr 22 13:08:08 2016 +0300
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Implab.Automaton {
+    public class MapAlphabet<T> : IAlphabetBuilder<T> {
+        readonly Dictionary<T,int> m_map;
+        int m_nextCls;
+        readonly bool m_supportUnclassified;
+
+        public MapAlphabet(bool supportUnclassified, IEqualityComparer<T> comparer) {
+            m_map = comparer != null ? new Dictionary<T, int>(comparer) : new Dictionary<T,int>();
+            m_supportUnclassified = supportUnclassified;
+            m_nextCls = supportUnclassified ? 1 : 0;
+        }
+
+        #region IAlphabetBuilder implementation
+
+        public int DefineSymbol(T symbol) {
+            int cls;
+            return m_map.TryGetValue(symbol, out cls) ? cls : DefineSymbol(symbol, m_nextCls);
+        }
+
+        public int DefineSymbol(T symbol, int cls) {
+            Safe.ArgumentAssert(cls >= 0, "cls");
+
+            m_nextCls = Math.Max(cls + 1, m_nextCls);
+            m_map.Add(symbol, cls);
+            return cls;
+        }
+
+        public int DefineClass(IEnumerable<T> symbols) {
+            return DefineClass(symbols, m_nextCls);
+        }
+
+        public int DefineClass(IEnumerable<T> symbols, int cls) {
+            Safe.ArgumentAssert(cls >= 0, "cls");
+            Safe.ArgumentNotNull(symbols, "symbols");
+
+            m_nextCls = Math.Max(cls + 1, m_nextCls);
+
+            foreach (var symbol in symbols)
+                m_map[symbol] = cls;
+            return cls;
+        }
+
+        #endregion
+
+        #region IAlphabet implementation
+
+        public int Translate(T symbol) {
+            int cls;
+            if (m_map.TryGetValue(symbol, out cls))
+                return cls;
+            if (!m_supportUnclassified)
+                throw new ArgumentOutOfRangeException("symbol", "The specified symbol isn't in the alphabet");
+            return AutomatonConst.UNCLASSIFIED_INPUT;
+        }
+
+        public int Count {
+            get {
+                return m_nextCls;
+            }
+        }
+
+        public bool Contains(T symbol) {
+            return m_supportUnclassified || m_map.ContainsKey(symbol);
+        }
+
+
+        public IEnumerable<T> GetSymbols(int cls) {
+            Safe.ArgumentAssert(!m_supportUnclassified || cls > 0, "cls");
+            return m_map.Where(p => p.Value == cls).Select(p => p.Key);
+        }
+        #endregion
+
+        public IEnumerable<KeyValuePair<T,int>> Mappings {
+            get {
+                return m_map;
+            }
+        }
+    }
+}
+