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