Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 6443 was 6443, checked in by mkommend, 13 years ago

#1559: Fixed memory leak in SymbolicExpressionGrammar.

File size: 8.4 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    [Storable]
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    [Storable]
104    private Defun defunSymbol;
105    protected Defun DefunSymbol {
106      get { return defunSymbol; }
107    }
108    [Storable(Name = "DefunSymbol")]
109    private ISymbol StorableDefunSymbol {
110      get { return defunSymbol; }
111      set { defunSymbol = (Defun)value; }
112    }
113    #endregion
114
115    [StorableHook(HookType.AfterDeserialization)]
116    private void AfterDeserialization() {
117      foreach (ISymbol symbol in symbols.Values)
118        RegisterSymbolEvents(symbol);
119    }
120    [StorableConstructor]
121    protected SymbolicExpressionGrammar(bool deserializing) : base(deserializing) { }
122    protected SymbolicExpressionGrammar(SymbolicExpressionGrammar original, Cloner cloner)
123      : base(original, cloner) {
124      foreach (ISymbol symbol in Symbols)
125        RegisterSymbolEvents(symbol);
126
127      programRootSymbol = cloner.Clone(original.programRootSymbol);
128      startSymbol = cloner.Clone(original.StartSymbol);
129      defunSymbol = cloner.Clone(original.defunSymbol);
130
131      maximumFunctionArguments = original.maximumFunctionArguments;
132      minimumFunctionArguments = original.minimumFunctionArguments;
133      maximumFunctionDefinitions = original.maximumFunctionDefinitions;
134      minimumFunctionDefinitions = original.minimumFunctionDefinitions;
135    }
136
137    public SymbolicExpressionGrammar(string name, string description)
138      : base(name, description) {
139      programRootSymbol = new ProgramRootSymbol();
140      AddSymbol(programRootSymbol);
141      SetSubtreeCount(programRootSymbol, 1, 1);
142
143      startSymbol = new StartSymbol();
144      AddSymbol(startSymbol);
145      SetSubtreeCount(startSymbol, 1, 1);
146
147      defunSymbol = new Defun();
148      AddSymbol(defunSymbol);
149      SetSubtreeCount(defunSymbol, 1, 1);
150
151      AddAllowedChildSymbol(programRootSymbol, startSymbol, 0);
152      UpdateAdfConstraints();
153    }
154
155    private void UpdateAdfConstraints() {
156      SetSubtreeCount(programRootSymbol, minimumFunctionDefinitions + 1, maximumFunctionDefinitions + 1);
157
158      // ADF branches maxFunctionDefinitions
159      for (int argumentIndex = 1; argumentIndex < maximumFunctionDefinitions + 1; argumentIndex++) {
160        RemoveAllowedChildSymbol(programRootSymbol, defunSymbol, argumentIndex);
161        AddAllowedChildSymbol(programRootSymbol, defunSymbol, argumentIndex);
162      }
163    }
164
165    protected override void AddSymbol(ISymbol symbol) {
166      base.AddSymbol(symbol);
167      RegisterSymbolEvents(symbol);
168    }
169    protected override void RemoveSymbol(ISymbol symbol) {
170      DeregisterSymbolEvents(symbol);
171      base.RemoveSymbol(symbol);
172    }
173
174    public event EventHandler ReadOnlyChanged;
175    protected virtual void OnReadOnlyChanged() {
176      var handler = ReadOnlyChanged;
177      if (handler != null)
178        handler(this, EventArgs.Empty);
179    }
180
181    #region IStatefulItem
182    void IStatefulItem.InitializeState() { }
183    void IStatefulItem.ClearState() {
184      ReadOnly = false;
185    }
186    #endregion
187
188    #region symbol events
189    protected virtual void RegisterSymbolEvents(ISymbol symbol) {
190      symbol.NameChanging += new EventHandler<CancelEventArgs<string>>(Symbol_NameChanging);
191      symbol.NameChanged += new EventHandler(Symbol_NameChanged);
192    }
193    protected virtual void DeregisterSymbolEvents(ISymbol symbol) {
194      symbol.NameChanging -= new EventHandler<CancelEventArgs<string>>(Symbol_NameChanging);
195      symbol.NameChanged -= new EventHandler(Symbol_NameChanged);
196    }
197
198    private void Symbol_NameChanging(object sender, CancelEventArgs<string> e) {
199      if (symbols.ContainsKey(e.Value)) e.Cancel = true;
200    }
201    private void Symbol_NameChanged(object sender, EventArgs e) {
202      ISymbol symbol = (ISymbol)sender;
203      string oldName = symbols.Where(x => x.Value == symbol).First().Key;
204      string newName = symbol.Name;
205
206      symbols.Remove(oldName);
207      symbols.Add(newName, symbol);
208
209      var subtreeCount = symbolSubtreeCount[oldName];
210      symbolSubtreeCount.Remove(oldName);
211      symbolSubtreeCount.Add(newName, subtreeCount);
212
213      List<string> allowedChilds;
214      if (allowedChildSymbols.TryGetValue(oldName, out allowedChilds)) {
215        allowedChildSymbols.Remove(oldName);
216        allowedChildSymbols.Add(newName, allowedChilds);
217      }
218
219      for (int i = 0; i < GetMaximumSubtreeCount(symbol); i++) {
220        if (allowedChildSymbolsPerIndex.TryGetValue(Tuple.Create(oldName, i), out allowedChilds)) {
221          allowedChildSymbolsPerIndex.Remove(Tuple.Create(oldName, i));
222          allowedChildSymbolsPerIndex.Add(Tuple.Create(newName, i), allowedChilds);
223        }
224      }
225
226      foreach (var parent in Symbols) {
227        if (allowedChildSymbols.TryGetValue(parent.Name, out allowedChilds))
228          if (allowedChilds.Remove(oldName))
229            allowedChilds.Add(newName);
230
231        for (int i = 0; i < GetMaximumSubtreeCount(parent); i++) {
232          if (allowedChildSymbolsPerIndex.TryGetValue(Tuple.Create(parent.Name, i), out allowedChilds))
233            if (allowedChilds.Remove(oldName)) allowedChilds.Add(newName);
234        }
235      }
236
237      ClearCaches();
238    }
239    #endregion
240  }
241}
Note: See TracBrowser for help on using the repository browser.