using System; using System.Collections; using System.Collections.Generic; using System.Linq; using HeuristicLab.Common; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration { [StorableClass] public abstract class Symbol : DeepCloneable, IEquatable { [Storable] private readonly int stringRepresentationHash; [Storable] public string StringRepresentation { get; private set; } protected Symbol(string representation) { StringRepresentation = representation; stringRepresentationHash = representation.GetHashCode(); } protected Symbol(Symbol original, Cloner cloner) : base(original, cloner) { StringRepresentation = original.StringRepresentation; stringRepresentationHash = original.stringRepresentationHash; } [StorableConstructor] protected Symbol(bool deserializing) { } public override string ToString() { return StringRepresentation; } #region IEquatable public static bool operator ==(Symbol s1, Symbol s2) { if (ReferenceEquals(s1, s2)) return true; if (ReferenceEquals(s1, null) || ReferenceEquals(s2, null)) return false; return s1.Equals(s2); } public static bool operator !=(Symbol s1, Symbol s2) { return !(s1 == s2); } public bool Equals(Symbol other) { if (ReferenceEquals(other, null)) return false; if (ReferenceEquals(other, this)) return true; if (this.GetType() != other.GetType()) return false; // Otherwise, this needs to be reimplemented in derived classes. return StringRepresentation == other.StringRepresentation; } public override bool Equals(object obj) { if (ReferenceEquals(obj, null)) return false; if (ReferenceEquals(obj, this)) return true; if (this.GetType() != obj.GetType()) return false; return Equals((Symbol)obj); } public override int GetHashCode() { return stringRepresentationHash; } #endregion } [StorableClass] public class TerminalSymbol : Symbol { public TerminalSymbol(string representation) : base(representation) { } public TerminalSymbol(TerminalSymbol original, Cloner cloner) : base(original, cloner) { } public override IDeepCloneable Clone(Cloner cloner) { return new TerminalSymbol(this, cloner); } [StorableConstructor] protected TerminalSymbol(bool deserializing) : base(deserializing) { } } [StorableClass] public class VariableTerminalSymbol : TerminalSymbol { public VariableTerminalSymbol(string representation) : base(representation) { } public VariableTerminalSymbol(VariableTerminalSymbol original, Cloner cloner) : base(original, cloner) { } public override IDeepCloneable Clone(Cloner cloner) { return new VariableTerminalSymbol(this, cloner); } [StorableConstructor] protected VariableTerminalSymbol(bool deserializing) : base(deserializing) { } } [StorableClass] public class NonterminalSymbol : Symbol { public NonterminalSymbol(string representation) : base(representation) { } public NonterminalSymbol(NonterminalSymbol original, Cloner cloner) : base(original, cloner) { } public override IDeepCloneable Clone(Cloner cloner) { return new NonterminalSymbol(this, cloner); } [StorableConstructor] protected NonterminalSymbol(bool deserializing) : base(deserializing) { } } [StorableClass] public class Production : DeepCloneable, IList { [Storable] private List symbols; public int Count { get { return symbols.Count; } } public bool IsReadOnly { get { return false; } } public Symbol this[int index] { get { return symbols[index]; } set { symbols[index] = value; } } public Production(params Symbol[] symbols) { this.symbols = symbols.ToList(); } public Production(IEnumerable symbols) { this.symbols = symbols.ToList(); } [StorableConstructor] protected Production(bool deserializing) { } protected Production(Production original, Cloner cloner) { symbols = original.symbols.Select(cloner.Clone).ToList(); } public override IDeepCloneable Clone(Cloner cloner) { return new Production(this, cloner); } public override string ToString() { return string.Join(" ", this); } #region IList methods public IEnumerator GetEnumerator() { return symbols.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public int IndexOf(Symbol item) { return symbols.IndexOf(item); } public void Insert(int index, Symbol item) { symbols.Insert(index, item); } public void RemoveAt(int index) { symbols.RemoveAt(index); } public void Add(Symbol item) { symbols.Add(item); } public void Clear() { symbols.Clear(); } public bool Contains(Symbol item) { return symbols.Contains(item); } public void CopyTo(Symbol[] array, int arrayIndex) { symbols.CopyTo(array, arrayIndex); } public void CopyTo(int index, Symbol[] array, int arrayIndex, int count) { symbols.CopyTo(index, array, arrayIndex, count); } public bool Remove(Symbol item) { return symbols.Remove(item); } #endregion } }