Free cookie consent management tool by TermsFeed Policy Generator

source: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammar.cs @ 6618

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

#1479: Integrated trunk changes.

File size: 10.2 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 methods
180    void IStatefulItem.InitializeState() { }
181    void IStatefulItem.ClearState() {
182      ReadOnly = false;
183    }
184    #endregion
185
186    #region ISymbolicExpressionGrammar methods
187    void ISymbolicExpressionGrammar.AddSymbol(ISymbol symbol) {
188      if (ReadOnly) throw new InvalidOperationException();
189      base.AddSymbol(symbol);
190    }
191    void ISymbolicExpressionGrammar.RemoveSymbol(ISymbol symbol) {
192      if (ReadOnly) throw new InvalidOperationException();
193      base.RemoveSymbol(symbol);
194    }
195
196    void ISymbolicExpressionGrammar.AddAllowedChildSymbol(ISymbol parent, ISymbol child) {
197      if (ReadOnly) throw new InvalidOperationException();
198      base.AddAllowedChildSymbol(parent, child);
199    }
200    void ISymbolicExpressionGrammar.AddAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex) {
201      if (ReadOnly) throw new InvalidOperationException();
202      base.AddAllowedChildSymbol(parent, child, argumentIndex);
203    }
204    void ISymbolicExpressionGrammar.RemoveAllowedChildSymbol(ISymbol parent, ISymbol child) {
205      if (ReadOnly) throw new InvalidOperationException();
206      base.RemoveAllowedChildSymbol(parent, child);
207    }
208    void ISymbolicExpressionGrammar.RemoveAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex) {
209      if (ReadOnly) throw new InvalidOperationException();
210      base.RemoveAllowedChildSymbol(parent, child, argumentIndex);
211    }
212
213    void ISymbolicExpressionGrammar.SetSubtreeCount(ISymbol symbol, int minimumSubtreeCount, int maximumSubtreeCount) {
214      if (ReadOnly) throw new InvalidOperationException();
215      base.SetSubtreeCount(symbol, minimumSubtreeCount, maximumSubtreeCount);
216    }
217
218    private bool suppressEvents = false;
219    void ISymbolicExpressionGrammar.StartGrammarManipulation() {
220      suppressEvents = true;
221    }
222    void ISymbolicExpressionGrammar.FinishedGrammarManipulation() {
223      suppressEvents = false;
224      OnChanged();
225    }
226
227    protected override void OnChanged() {
228      if (!suppressEvents) base.OnChanged();
229    }
230    #endregion
231
232    #region symbol events
233    protected virtual void RegisterSymbolEvents(ISymbol symbol) {
234      symbol.NameChanging += new EventHandler<CancelEventArgs<string>>(Symbol_NameChanging);
235      symbol.NameChanged += new EventHandler(Symbol_NameChanged);
236    }
237    protected virtual void DeregisterSymbolEvents(ISymbol symbol) {
238      symbol.NameChanging -= new EventHandler<CancelEventArgs<string>>(Symbol_NameChanging);
239      symbol.NameChanged -= new EventHandler(Symbol_NameChanged);
240    }
241
242    private void Symbol_NameChanging(object sender, CancelEventArgs<string> e) {
243      if (symbols.ContainsKey(e.Value)) e.Cancel = true;
244    }
245    private void Symbol_NameChanged(object sender, EventArgs e) {
246      ISymbol symbol = (ISymbol)sender;
247      string oldName = symbols.Where(x => x.Value == symbol).First().Key;
248      string newName = symbol.Name;
249
250      symbols.Remove(oldName);
251      symbols.Add(newName, symbol);
252
253      var subtreeCount = symbolSubtreeCount[oldName];
254      symbolSubtreeCount.Remove(oldName);
255      symbolSubtreeCount.Add(newName, subtreeCount);
256
257      List<string> allowedChilds;
258      if (allowedChildSymbols.TryGetValue(oldName, out allowedChilds)) {
259        allowedChildSymbols.Remove(oldName);
260        allowedChildSymbols.Add(newName, allowedChilds);
261      }
262
263      for (int i = 0; i < GetMaximumSubtreeCount(symbol); i++) {
264        if (allowedChildSymbolsPerIndex.TryGetValue(Tuple.Create(oldName, i), out allowedChilds)) {
265          allowedChildSymbolsPerIndex.Remove(Tuple.Create(oldName, i));
266          allowedChildSymbolsPerIndex.Add(Tuple.Create(newName, i), allowedChilds);
267        }
268      }
269
270      foreach (var parent in Symbols) {
271        if (allowedChildSymbols.TryGetValue(parent.Name, out allowedChilds))
272          if (allowedChilds.Remove(oldName))
273            allowedChilds.Add(newName);
274
275        for (int i = 0; i < GetMaximumSubtreeCount(parent); i++) {
276          if (allowedChildSymbolsPerIndex.TryGetValue(Tuple.Create(parent.Name, i), out allowedChilds))
277            if (allowedChilds.Remove(oldName)) allowedChilds.Add(newName);
278        }
279      }
280
281      ClearCaches();
282    }
283    #endregion
284  }
285}
Note: See TracBrowser for help on using the repository browser.