1 | using System;
|
---|
2 | using System.Collections;
|
---|
3 | using System.Collections.Generic;
|
---|
4 | using System.Diagnostics;
|
---|
5 | using System.Linq;
|
---|
6 | using HeuristicLab.Common;
|
---|
7 | using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
|
---|
8 |
|
---|
9 | namespace HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration.GrammarEnumeration {
|
---|
10 | [StorableClass]
|
---|
11 | public class SymbolString : DeepCloneable, IEnumerable<Symbol> {
|
---|
12 | [Storable]
|
---|
13 | private readonly Symbol[] symbols;
|
---|
14 |
|
---|
15 | public Symbol this[int index] {
|
---|
16 | get { return symbols[index]; }
|
---|
17 | }
|
---|
18 |
|
---|
19 | public SymbolString(IEnumerable<Symbol> s) {
|
---|
20 | symbols = s.ToArray();
|
---|
21 | }
|
---|
22 |
|
---|
23 | public SymbolString(params Symbol[] s) {
|
---|
24 | symbols = s;
|
---|
25 | }
|
---|
26 |
|
---|
27 | [StorableConstructor]
|
---|
28 | protected SymbolString(bool deserializing) { }
|
---|
29 |
|
---|
30 | protected SymbolString(SymbolString original, Cloner cloner) : base(original, cloner) {
|
---|
31 | symbols = original.symbols.Select(cloner.Clone).ToArray();
|
---|
32 | }
|
---|
33 |
|
---|
34 | public override IDeepCloneable Clone(Cloner cloner) {
|
---|
35 | return new SymbolString(this, cloner);
|
---|
36 | }
|
---|
37 |
|
---|
38 | public bool IsSentence() {
|
---|
39 | return !this.Any(sym => sym is NonterminalSymbol);
|
---|
40 | }
|
---|
41 |
|
---|
42 | public int[] GetNonterminalSymbolIndexes() {
|
---|
43 | return Enumerable.Range(0, symbols.Length)
|
---|
44 | .Where(i => symbols[i] is NonterminalSymbol)
|
---|
45 | .ToArray();
|
---|
46 | }
|
---|
47 |
|
---|
48 | public int NextNonterminalIndex() {
|
---|
49 | Debug.Assert(!IsSentence());
|
---|
50 | int firstNonTerminalIndex = 0;
|
---|
51 | while (firstNonTerminalIndex < symbols.Length && symbols[firstNonTerminalIndex] is TerminalSymbol) {
|
---|
52 | firstNonTerminalIndex++;
|
---|
53 | }
|
---|
54 | return firstNonTerminalIndex;
|
---|
55 | }
|
---|
56 |
|
---|
57 | public SymbolString DerivePhrase(int nonterminalSymbolIndex, Production production) {
|
---|
58 | int productionLength = production.Count;
|
---|
59 | int newStringLength = Count() + productionLength - 1;
|
---|
60 | Symbol[] newPhrase = new Symbol[newStringLength];
|
---|
61 |
|
---|
62 | // Copy "left" part of the phrase
|
---|
63 | Array.Copy(symbols, 0, newPhrase, 0, nonterminalSymbolIndex);
|
---|
64 | // Copy production and overwrite nonterminalsymbol
|
---|
65 | production.CopyTo(0, newPhrase, nonterminalSymbolIndex, productionLength);
|
---|
66 | // Copy "right" part of the original phrase
|
---|
67 | Array.Copy(symbols, nonterminalSymbolIndex + 1, newPhrase, nonterminalSymbolIndex + productionLength, symbols.Length - nonterminalSymbolIndex - 1);
|
---|
68 |
|
---|
69 | return new SymbolString(newPhrase);
|
---|
70 | }
|
---|
71 |
|
---|
72 | public override string ToString() {
|
---|
73 | return string.Join<Symbol>(" ", symbols);
|
---|
74 | }
|
---|
75 |
|
---|
76 | #region Enumerable interface
|
---|
77 | IEnumerator IEnumerable.GetEnumerator() {
|
---|
78 | return GetEnumerator();
|
---|
79 | }
|
---|
80 |
|
---|
81 | public IEnumerator<Symbol> GetEnumerator() {
|
---|
82 | return ((IEnumerable<Symbol>)symbols).GetEnumerator();
|
---|
83 | }
|
---|
84 |
|
---|
85 | public int Count() {
|
---|
86 | return symbols.Length;
|
---|
87 | }
|
---|
88 | #endregion
|
---|
89 | }
|
---|
90 | }
|
---|