using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using HeuristicLab.Common; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration.GrammarEnumeration { [StorableClass] public class SymbolString : DeepCloneable, IEnumerable { [Storable] private readonly Symbol[] symbols; public Symbol this[int index] { get { return symbols[index]; } } public SymbolString(IEnumerable s) { symbols = s.ToArray(); } public SymbolString(params Symbol[] s) { symbols = s; } [StorableConstructor] protected SymbolString(bool deserializing) { } protected SymbolString(SymbolString original, Cloner cloner) : base(original, cloner) { symbols = original.symbols.Select(cloner.Clone).ToArray(); } public override IDeepCloneable Clone(Cloner cloner) { return new SymbolString(this, cloner); } public bool IsSentence() { return !this.Any(sym => sym is NonterminalSymbol); } public int[] GetNonterminalSymbolIndexes() { return Enumerable.Range(0, symbols.Length) .Where(i => symbols[i] is NonterminalSymbol) .ToArray(); } public int NextNonterminalIndex() { Debug.Assert(!IsSentence()); int firstNonTerminalIndex = 0; while (firstNonTerminalIndex < symbols.Length && symbols[firstNonTerminalIndex] is TerminalSymbol) { firstNonTerminalIndex++; } return firstNonTerminalIndex; } public SymbolString DerivePhrase(int nonterminalSymbolIndex, Production production) { int productionLength = production.Count; int newStringLength = Count() + productionLength - 1; Symbol[] newPhrase = new Symbol[newStringLength]; // Copy "left" part of the phrase Array.Copy(symbols, 0, newPhrase, 0, nonterminalSymbolIndex); // Copy production and overwrite nonterminalsymbol production.CopyTo(0, newPhrase, nonterminalSymbolIndex, productionLength); // Copy "right" part of the original phrase Array.Copy(symbols, nonterminalSymbolIndex + 1, newPhrase, nonterminalSymbolIndex + productionLength, symbols.Length - nonterminalSymbolIndex - 1); return new SymbolString(newPhrase); } public override string ToString() { return string.Join(" ", symbols); } #region Enumerable interface IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public IEnumerator GetEnumerator() { return ((IEnumerable)symbols).GetEnumerator(); } public int Count() { return symbols.Length; } #endregion } }