Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammar.cs @ 6549

Last change on this file since 6549 was 6532, checked in by gkronber, 13 years ago

#1532: fixed minor problem in persistence of SymbolicExpressionGrammar

File size: 8.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Linq;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
27using System.Collections.Generic;
28
29namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
30  [StorableClass]
31  public abstract class SymbolicExpressionGrammar : SymbolicExpressionGrammarBase, ISymbolicExpressionGrammar {
32    #region fields & properties
33    [Storable(DefaultValue = false)]
34    private bool readOnly;
35    public bool ReadOnly {
36      get { return readOnly; }
37      set {
38        if (readOnly != value) {
39          readOnly = value;
40          OnReadOnlyChanged();
41        }
42      }
43    }
44
45    [Storable]
46    private int minimumFunctionDefinitions;
47    public int MinimumFunctionDefinitions {
48      get { return minimumFunctionDefinitions; }
49      set {
50        minimumFunctionDefinitions = value;
51        UpdateAdfConstraints();
52      }
53    }
54    [Storable]
55    private int maximumFunctionDefinitions;
56    public int MaximumFunctionDefinitions {
57      get { return maximumFunctionDefinitions; }
58      set {
59        maximumFunctionDefinitions = value;
60        UpdateAdfConstraints();
61      }
62    }
63    [Storable]
64    private int minimumFunctionArguments;
65    public int MinimumFunctionArguments {
66      get { return minimumFunctionArguments; }
67      set { minimumFunctionArguments = value; }
68    }
69    [Storable]
70    private int maximumFunctionArguments;
71    public int MaximumFunctionArguments {
72      get { return maximumFunctionArguments; }
73      set { maximumFunctionArguments = value; }
74    }
75
76    private ProgramRootSymbol programRootSymbol;
77    public ProgramRootSymbol ProgramRootSymbol {
78      get { return programRootSymbol; }
79    }
80    ISymbol ISymbolicExpressionGrammar.ProgramRootSymbol {
81      get { return ProgramRootSymbol; }
82    }
83    [Storable(Name = "ProgramRootSymbol")]
84    private ISymbol StorableProgramRootSymbol {
85      get { return programRootSymbol; }
86      set { programRootSymbol = (ProgramRootSymbol)value; }
87    }
88
89    private StartSymbol startSymbol;
90    public StartSymbol StartSymbol {
91      get { return startSymbol; }
92    }
93    ISymbol ISymbolicExpressionGrammar.StartSymbol {
94      get { return StartSymbol; }
95    }
96    [Storable(Name = "StartSymbol")]
97    private ISymbol StorableStartSymbol {
98      get { return startSymbol; }
99      set { startSymbol = (StartSymbol)value; }
100    }
101
102    private Defun defunSymbol;
103    protected Defun DefunSymbol {
104      get { return defunSymbol; }
105    }
106    [Storable(Name = "DefunSymbol")]
107    private ISymbol StorableDefunSymbol {
108      get { return defunSymbol; }
109      set { defunSymbol = (Defun)value; }
110    }
111    #endregion
112
113    [StorableHook(HookType.AfterDeserialization)]
114    private void AfterDeserialization() {
115      foreach (ISymbol symbol in symbols.Values)
116        RegisterSymbolEvents(symbol);
117    }
118    [StorableConstructor]
119    protected SymbolicExpressionGrammar(bool deserializing) : base(deserializing) { }
120    protected SymbolicExpressionGrammar(SymbolicExpressionGrammar original, Cloner cloner)
121      : base(original, cloner) {
122      foreach (ISymbol symbol in Symbols)
123        RegisterSymbolEvents(symbol);
124
125      programRootSymbol = cloner.Clone(original.programRootSymbol);
126      startSymbol = cloner.Clone(original.StartSymbol);
127      defunSymbol = cloner.Clone(original.defunSymbol);
128
129      maximumFunctionArguments = original.maximumFunctionArguments;
130      minimumFunctionArguments = original.minimumFunctionArguments;
131      maximumFunctionDefinitions = original.maximumFunctionDefinitions;
132      minimumFunctionDefinitions = original.minimumFunctionDefinitions;
133    }
134
135    public SymbolicExpressionGrammar(string name, string description)
136      : base(name, description) {
137      programRootSymbol = new ProgramRootSymbol();
138      AddSymbol(programRootSymbol);
139      SetSubtreeCount(programRootSymbol, 1, 1);
140
141      startSymbol = new StartSymbol();
142      AddSymbol(startSymbol);
143      SetSubtreeCount(startSymbol, 1, 1);
144
145      defunSymbol = new Defun();
146      AddSymbol(defunSymbol);
147      SetSubtreeCount(defunSymbol, 1, 1);
148
149      AddAllowedChildSymbol(programRootSymbol, startSymbol, 0);
150      UpdateAdfConstraints();
151    }
152
153    private void UpdateAdfConstraints() {
154      SetSubtreeCount(programRootSymbol, minimumFunctionDefinitions + 1, maximumFunctionDefinitions + 1);
155
156      // ADF branches maxFunctionDefinitions
157      for (int argumentIndex = 1; argumentIndex < maximumFunctionDefinitions + 1; argumentIndex++) {
158        RemoveAllowedChildSymbol(programRootSymbol, defunSymbol, argumentIndex);
159        AddAllowedChildSymbol(programRootSymbol, defunSymbol, argumentIndex);
160      }
161    }
162
163    protected override void AddSymbol(ISymbol symbol) {
164      base.AddSymbol(symbol);
165      RegisterSymbolEvents(symbol);
166    }
167    protected override void RemoveSymbol(ISymbol symbol) {
168      DeregisterSymbolEvents(symbol);
169      base.RemoveSymbol(symbol);
170    }
171
172    public event EventHandler ReadOnlyChanged;
173    protected virtual void OnReadOnlyChanged() {
174      var handler = ReadOnlyChanged;
175      if (handler != null)
176        handler(this, EventArgs.Empty);
177    }
178
179    #region IStatefulItem
180    void IStatefulItem.InitializeState() { }
181    void IStatefulItem.ClearState() {
182      ReadOnly = false;
183    }
184    #endregion
185
186    #region symbol events
187    protected virtual void RegisterSymbolEvents(ISymbol symbol) {
188      symbol.NameChanging += new EventHandler<CancelEventArgs<string>>(Symbol_NameChanging);
189      symbol.NameChanged += new EventHandler(Symbol_NameChanged);
190    }
191    protected virtual void DeregisterSymbolEvents(ISymbol symbol) {
192      symbol.NameChanging -= new EventHandler<CancelEventArgs<string>>(Symbol_NameChanging);
193      symbol.NameChanged -= new EventHandler(Symbol_NameChanged);
194    }
195
196    private void Symbol_NameChanging(object sender, CancelEventArgs<string> e) {
197      if (symbols.ContainsKey(e.Value)) e.Cancel = true;
198    }
199    private void Symbol_NameChanged(object sender, EventArgs e) {
200      ISymbol symbol = (ISymbol)sender;
201      string oldName = symbols.Where(x => x.Value == symbol).First().Key;
202      string newName = symbol.Name;
203
204      symbols.Remove(oldName);
205      symbols.Add(newName, symbol);
206
207      var subtreeCount = symbolSubtreeCount[oldName];
208      symbolSubtreeCount.Remove(oldName);
209      symbolSubtreeCount.Add(newName, subtreeCount);
210
211      List<string> allowedChilds;
212      if (allowedChildSymbols.TryGetValue(oldName, out allowedChilds)) {
213        allowedChildSymbols.Remove(oldName);
214        allowedChildSymbols.Add(newName, allowedChilds);
215      }
216
217      for (int i = 0; i < GetMaximumSubtreeCount(symbol); i++) {
218        if (allowedChildSymbolsPerIndex.TryGetValue(Tuple.Create(oldName, i), out allowedChilds)) {
219          allowedChildSymbolsPerIndex.Remove(Tuple.Create(oldName, i));
220          allowedChildSymbolsPerIndex.Add(Tuple.Create(newName, i), allowedChilds);
221        }
222      }
223
224      foreach (var parent in Symbols) {
225        if (allowedChildSymbols.TryGetValue(parent.Name, out allowedChilds))
226          if (allowedChilds.Remove(oldName))
227            allowedChilds.Add(newName);
228
229        for (int i = 0; i < GetMaximumSubtreeCount(parent); i++) {
230          if (allowedChildSymbolsPerIndex.TryGetValue(Tuple.Create(parent.Name, i), out allowedChilds))
231            if (allowedChilds.Remove(oldName)) allowedChilds.Add(newName);
232        }
233      }
234
235      ClearCaches();
236    }
237    #endregion
238  }
239}
Note: See TracBrowser for help on using the repository browser.