Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Grammars/SymbolicExpressionGrammar.cs

Last change on this file was 17181, checked in by swagner, 5 years ago

#2875: Merged r17180 from trunk to stable

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