Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 8122 was 7733, checked in by gkronber, 13 years ago

#1790 added statement to reset the grammar readonly state when the grammar is initialized (on algorithm prepare)

File size: 13.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Collections;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
29
30namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
31  [StorableClass]
32  public abstract class SymbolicExpressionGrammar : SymbolicExpressionGrammarBase, ISymbolicExpressionGrammar {
33    #region fields & properties
34    [Storable(DefaultValue = false)]
35    private bool readOnly;
36    public bool ReadOnly {
37      get { return readOnly; }
38      set {
39        if (readOnly != value) {
40          readOnly = value;
41          OnReadOnlyChanged();
42        }
43      }
44    }
45
46    [Storable]
47    private int minimumFunctionDefinitions;
48    public int MinimumFunctionDefinitions {
49      get { return minimumFunctionDefinitions; }
50      set {
51        minimumFunctionDefinitions = value;
52        UpdateAdfConstraints();
53      }
54    }
55    [Storable]
56    private int maximumFunctionDefinitions;
57    public int MaximumFunctionDefinitions {
58      get { return maximumFunctionDefinitions; }
59      set {
60        maximumFunctionDefinitions = value;
61        UpdateAdfConstraints();
62      }
63    }
64    [Storable]
65    private int minimumFunctionArguments;
66    public int MinimumFunctionArguments {
67      get { return minimumFunctionArguments; }
68      set { minimumFunctionArguments = value; }
69    }
70    [Storable]
71    private int maximumFunctionArguments;
72    public int MaximumFunctionArguments {
73      get { return maximumFunctionArguments; }
74      set { maximumFunctionArguments = value; }
75    }
76
77    private ProgramRootSymbol programRootSymbol;
78    public ProgramRootSymbol ProgramRootSymbol {
79      get { return programRootSymbol; }
80    }
81    ISymbol ISymbolicExpressionGrammar.ProgramRootSymbol {
82      get { return ProgramRootSymbol; }
83    }
84    [Storable(Name = "ProgramRootSymbol")]
85    private ISymbol StorableProgramRootSymbol {
86      get { return programRootSymbol; }
87      set { programRootSymbol = (ProgramRootSymbol)value; }
88    }
89
90    private StartSymbol startSymbol;
91    public StartSymbol StartSymbol {
92      get { return startSymbol; }
93    }
94    ISymbol ISymbolicExpressionGrammar.StartSymbol {
95      get { return StartSymbol; }
96    }
97    [Storable(Name = "StartSymbol")]
98    private ISymbol StorableStartSymbol {
99      get { return startSymbol; }
100      set { startSymbol = (StartSymbol)value; }
101    }
102
103    private Defun defunSymbol;
104    protected Defun DefunSymbol {
105      get { return defunSymbol; }
106    }
107    [Storable(Name = "DefunSymbol")]
108    private ISymbol StorableDefunSymbol {
109      get { return defunSymbol; }
110      set { defunSymbol = (Defun)value; }
111    }
112    #endregion
113
114    [StorableHook(HookType.AfterDeserialization)]
115    private void AfterDeserialization() {
116      foreach (ISymbol symbol in symbols.Values)
117        RegisterSymbolEvents(symbol);
118    }
119    [StorableConstructor]
120    protected SymbolicExpressionGrammar(bool deserializing) : base(deserializing) { }
121    protected SymbolicExpressionGrammar(SymbolicExpressionGrammar original, Cloner cloner)
122      : base(original, cloner) {
123      foreach (ISymbol symbol in symbols.Values)
124        RegisterSymbolEvents(symbol);
125
126      programRootSymbol = cloner.Clone(original.programRootSymbol);
127      startSymbol = cloner.Clone(original.StartSymbol);
128      defunSymbol = cloner.Clone(original.defunSymbol);
129
130      maximumFunctionArguments = original.maximumFunctionArguments;
131      minimumFunctionArguments = original.minimumFunctionArguments;
132      maximumFunctionDefinitions = original.maximumFunctionDefinitions;
133      minimumFunctionDefinitions = original.minimumFunctionDefinitions;
134    }
135
136    public SymbolicExpressionGrammar(string name, string description)
137      : base(name, description) {
138      programRootSymbol = new ProgramRootSymbol();
139      AddSymbol(programRootSymbol);
140      SetSubtreeCount(programRootSymbol, 1, 1);
141
142      startSymbol = new StartSymbol();
143      AddSymbol(startSymbol);
144      SetSubtreeCount(startSymbol, 1, 1);
145
146      defunSymbol = new Defun();
147      AddSymbol(defunSymbol);
148      SetSubtreeCount(defunSymbol, 1, 1);
149
150      AddAllowedChildSymbol(programRootSymbol, startSymbol, 0);
151      UpdateAdfConstraints();
152    }
153
154    private void UpdateAdfConstraints() {
155      SetSubtreeCount(programRootSymbol, minimumFunctionDefinitions + 1, maximumFunctionDefinitions + 1);
156
157      // ADF branches maxFunctionDefinitions
158      for (int argumentIndex = 1; argumentIndex < maximumFunctionDefinitions + 1; argumentIndex++) {
159        RemoveAllowedChildSymbol(programRootSymbol, defunSymbol, argumentIndex);
160        AddAllowedChildSymbol(programRootSymbol, defunSymbol, argumentIndex);
161      }
162    }
163
164    protected override sealed void AddSymbol(ISymbol symbol) {
165      base.AddSymbol(symbol);
166      RegisterSymbolEvents(symbol);
167      OnChanged();
168    }
169    protected override sealed void RemoveSymbol(ISymbol symbol) {
170      DeregisterSymbolEvents(symbol);
171      base.RemoveSymbol(symbol);
172      OnChanged();
173    }
174
175    public event EventHandler ReadOnlyChanged;
176    protected virtual void OnReadOnlyChanged() {
177      var handler = ReadOnlyChanged;
178      if (handler != null)
179        handler(this, EventArgs.Empty);
180    }
181
182    #region IStatefulItem methods
183    void IStatefulItem.InitializeState()
184    {
185      ReadOnly = false;
186    }
187    void IStatefulItem.ClearState() {
188      ReadOnly = false;
189    }
190    #endregion
191
192    #region ISymbolicExpressionGrammar methods
193    void ISymbolicExpressionGrammar.AddSymbol(ISymbol symbol) {
194      if (ReadOnly) throw new InvalidOperationException();
195      AddSymbol(symbol);
196    }
197    void ISymbolicExpressionGrammar.RemoveSymbol(ISymbol symbol) {
198      if (ReadOnly) throw new InvalidOperationException();
199      RemoveSymbol(symbol);
200    }
201
202    void ISymbolicExpressionGrammar.AddAllowedChildSymbol(ISymbol parent, ISymbol child) {
203      if (ReadOnly) throw new InvalidOperationException();
204      base.AddAllowedChildSymbol(parent, child);
205    }
206    void ISymbolicExpressionGrammar.AddAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex) {
207      if (ReadOnly) throw new InvalidOperationException();
208      base.AddAllowedChildSymbol(parent, child, argumentIndex);
209    }
210    void ISymbolicExpressionGrammar.RemoveAllowedChildSymbol(ISymbol parent, ISymbol child) {
211      if (ReadOnly) throw new InvalidOperationException();
212      base.RemoveAllowedChildSymbol(parent, child);
213    }
214    void ISymbolicExpressionGrammar.RemoveAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex) {
215      if (ReadOnly) throw new InvalidOperationException();
216      base.RemoveAllowedChildSymbol(parent, child, argumentIndex);
217    }
218
219    void ISymbolicExpressionGrammar.SetSubtreeCount(ISymbol symbol, int minimumSubtreeCount, int maximumSubtreeCount) {
220      if (ReadOnly) throw new InvalidOperationException();
221      base.SetSubtreeCount(symbol, minimumSubtreeCount, maximumSubtreeCount);
222    }
223
224    private bool suppressEvents = false;
225    void ISymbolicExpressionGrammar.StartGrammarManipulation() {
226      suppressEvents = true;
227    }
228    void ISymbolicExpressionGrammar.FinishedGrammarManipulation() {
229      suppressEvents = false;
230      OnChanged();
231    }
232
233    protected override void OnChanged() {
234      if (suppressEvents) return;
235      base.OnChanged();
236    }
237    #endregion
238
239    #region symbol events
240    private void RegisterSymbolEvents(ISymbol symbol) {
241      foreach (var s in symbol.Flatten()) {
242        s.NameChanging += new EventHandler<CancelEventArgs<string>>(Symbol_NameChanging);
243        s.NameChanged += new EventHandler(Symbol_NameChanged);
244
245        var groupSymbol = s as GroupSymbol;
246        if (groupSymbol != null) RegisterGroupSymbolEvents(groupSymbol);
247        else symbol.Changed += new EventHandler(Symbol_Changed);
248      }
249    }
250    private void DeregisterSymbolEvents(ISymbol symbol) {
251      foreach (var s in symbol.Flatten()) {
252        s.NameChanging -= new EventHandler<CancelEventArgs<string>>(Symbol_NameChanging);
253        s.NameChanged -= new EventHandler(Symbol_NameChanged);
254
255        var groupSymbol = s as GroupSymbol;
256        if (groupSymbol != null) DeregisterGroupSymbolEvents(groupSymbol);
257        else symbol.Changed -= new EventHandler(Symbol_Changed);
258      }
259    }
260
261    private void RegisterGroupSymbolEvents(GroupSymbol groupSymbol) {
262      groupSymbol.Changed += new EventHandler(GroupSymbol_Changed);
263      groupSymbol.SymbolsCollection.ItemsAdded += new Collections.CollectionItemsChangedEventHandler<ISymbol>(GroupSymbol_ItemsAdded);
264      groupSymbol.SymbolsCollection.ItemsRemoved += new Collections.CollectionItemsChangedEventHandler<ISymbol>(GroupSymbol_ItemsRemoved);
265      groupSymbol.SymbolsCollection.CollectionReset += new Collections.CollectionItemsChangedEventHandler<ISymbol>(GroupSymbol_CollectionReset);
266    }
267    private void DeregisterGroupSymbolEvents(GroupSymbol groupSymbol) {
268      groupSymbol.Changed -= new EventHandler(GroupSymbol_Changed);
269      groupSymbol.SymbolsCollection.ItemsAdded -= new Collections.CollectionItemsChangedEventHandler<ISymbol>(GroupSymbol_ItemsAdded);
270      groupSymbol.SymbolsCollection.ItemsRemoved -= new Collections.CollectionItemsChangedEventHandler<ISymbol>(GroupSymbol_ItemsRemoved);
271      groupSymbol.SymbolsCollection.CollectionReset -= new Collections.CollectionItemsChangedEventHandler<ISymbol>(GroupSymbol_CollectionReset);
272    }
273
274    private void Symbol_Changed(object sender, EventArgs e) {
275      ClearCaches();
276      OnChanged();
277    }
278
279    private void GroupSymbol_Changed(object sender, EventArgs e) {
280      GroupSymbol groupSymbol = (GroupSymbol)sender;
281      foreach (ISymbol symbol in groupSymbol.Flatten())
282        symbol.Enabled = groupSymbol.Enabled;
283
284      ClearCaches();
285      OnChanged();
286    }
287
288    private void Symbol_NameChanging(object sender, CancelEventArgs<string> e) {
289      if (symbols.ContainsKey(e.Value)) e.Cancel = true;
290    }
291    private void Symbol_NameChanged(object sender, EventArgs e) {
292      ISymbol symbol = (ISymbol)sender;
293      string oldName = symbols.Where(x => x.Value == symbol).First().Key;
294      string newName = symbol.Name;
295
296      symbols.Remove(oldName);
297      symbols.Add(newName, symbol);
298
299      var subtreeCount = symbolSubtreeCount[oldName];
300      symbolSubtreeCount.Remove(oldName);
301      symbolSubtreeCount.Add(newName, subtreeCount);
302
303      List<string> allowedChilds;
304      if (allowedChildSymbols.TryGetValue(oldName, out allowedChilds)) {
305        allowedChildSymbols.Remove(oldName);
306        allowedChildSymbols.Add(newName, allowedChilds);
307      }
308
309      for (int i = 0; i < GetMaximumSubtreeCount(symbol); i++) {
310        if (allowedChildSymbolsPerIndex.TryGetValue(Tuple.Create(oldName, i), out allowedChilds)) {
311          allowedChildSymbolsPerIndex.Remove(Tuple.Create(oldName, i));
312          allowedChildSymbolsPerIndex.Add(Tuple.Create(newName, i), allowedChilds);
313        }
314      }
315
316      foreach (var parent in Symbols) {
317        if (allowedChildSymbols.TryGetValue(parent.Name, out allowedChilds))
318          if (allowedChilds.Remove(oldName))
319            allowedChilds.Add(newName);
320
321        for (int i = 0; i < GetMaximumSubtreeCount(parent); i++) {
322          if (allowedChildSymbolsPerIndex.TryGetValue(Tuple.Create(parent.Name, i), out allowedChilds))
323            if (allowedChilds.Remove(oldName)) allowedChilds.Add(newName);
324        }
325      }
326
327      ClearCaches();
328      OnChanged();
329    }
330
331    private void GroupSymbol_ItemsAdded(object sender, CollectionItemsChangedEventArgs<ISymbol> e) {
332      foreach (ISymbol symbol in e.Items)
333        if (!ContainsSymbol(symbol))
334          AddSymbol(symbol);
335      OnChanged();
336    }
337    private void GroupSymbol_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<ISymbol> e) {
338      foreach (ISymbol symbol in e.Items)
339        if (ContainsSymbol(symbol))
340          RemoveSymbol(symbol);
341      OnChanged();
342    }
343    private void GroupSymbol_CollectionReset(object sender, CollectionItemsChangedEventArgs<ISymbol> e) {
344      foreach (ISymbol symbol in e.Items)
345        if (!ContainsSymbol(symbol))
346          AddSymbol(symbol);
347      foreach (ISymbol symbol in e.OldItems)
348        if (ContainsSymbol(symbol))
349          RemoveSymbol(symbol);
350      OnChanged();
351    }
352    #endregion
353  }
354}
Note: See TracBrowser for help on using the repository browser.