Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/GlobalSymbolicExpressionGrammar.cs @ 5370

Last change on this file since 5370 was 4742, checked in by gkronber, 14 years ago

Fixed a problem with ADFs in symbolic expression grammars. #922

File size: 7.3 KB
RevLine 
[3338]1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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
[4249]22using System;
23using System.Linq;
[3376]24using HeuristicLab.Common;
[3338]25using HeuristicLab.Core;
[4068]26using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
[3338]27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28
29namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
30  [StorableClass]
31  [Item("GlobalSymbolicExpressionGrammar", "Represents a grammar that defines the syntax of symbolic expression trees.")]
[4262]32  public sealed class GlobalSymbolicExpressionGrammar : DefaultSymbolicExpressionGrammar {
[3338]33    [Storable]
34    private int minFunctionDefinitions;
35    public int MinFunctionDefinitions {
36      get { return minFunctionDefinitions; }
[4068]37      set {
[3338]38        minFunctionDefinitions = value;
[3990]39        UpdateAdfConstraints();
[3338]40      }
41    }
42    [Storable]
43    private int maxFunctionDefinitions;
44    public int MaxFunctionDefinitions {
45      get { return maxFunctionDefinitions; }
[4068]46      set {
[3338]47        maxFunctionDefinitions = value;
[3990]48        UpdateAdfConstraints();
[3338]49      }
50    }
51    [Storable]
52    private int minFunctionArguments;
53    public int MinFunctionArguments {
54      get { return minFunctionArguments; }
[4068]55      set {
[3338]56        minFunctionArguments = value;
57      }
58    }
59    [Storable]
60    private int maxFunctionArguments;
61    public int MaxFunctionArguments {
62      get { return maxFunctionArguments; }
[4068]63      set {
[3338]64        maxFunctionArguments = value;
65      }
66    }
[3990]67
[3338]68    [Storable]
[3990]69    private Defun defunSymbol;
[3338]70
[4722]71    [StorableConstructor]
72    private GlobalSymbolicExpressionGrammar(bool deserializing) : base(deserializing) { }
73    private GlobalSymbolicExpressionGrammar(GlobalSymbolicExpressionGrammar original, Cloner cloner)
74      : base(original, cloner) {
75      defunSymbol = (Defun)cloner.Clone(original.defunSymbol);
76      maxFunctionArguments = original.maxFunctionArguments;
77      minFunctionArguments = original.minFunctionArguments;
78      maxFunctionDefinitions = original.maxFunctionDefinitions;
79      minFunctionDefinitions = original.minFunctionDefinitions;
80    }
81
[4068]82    public GlobalSymbolicExpressionGrammar(ISymbolicExpressionGrammar mainBranchGrammar)
[4249]83      : base(mainBranchGrammar) {
[3338]84      maxFunctionArguments = 3;
85      maxFunctionDefinitions = 3;
86
[4249]87      ProgramRootSymbol programRootSymbol = Symbols.OfType<ProgramRootSymbol>().FirstOrDefault();
88      if (programRootSymbol == null) {
89        programRootSymbol = new ProgramRootSymbol();
90        AddSymbol(programRootSymbol);
91      }
92      StartSymbol = programRootSymbol;
93
94      defunSymbol = Symbols.OfType<Defun>().FirstOrDefault();
95      if (defunSymbol == null) {
96        defunSymbol = new Defun();
97        AddSymbol(defunSymbol);
98      }
99
[4742]100      SetMinSubtreeCount(StartSymbol, minFunctionDefinitions + 1); // min number of ADF + 1 for RPB
101      SetMaxSubtreeCount(StartSymbol, maxFunctionDefinitions + 1); // max number of ADF + 1 for RPB
102      // defun can have only one child
103      SetMinSubtreeCount(defunSymbol, 1);
[4249]104      SetMaxSubtreeCount(defunSymbol, 1);
105
[4742]106
[4249]107      // the start symbol of the mainBranchGrammar is allowed as the result producing branch
108      SetAllowedChild(StartSymbol, Symbols.Where(s => s.Name == mainBranchGrammar.StartSymbol.Name).First(), 0);
109
[4742]110      // defuns are allowed as children on the same level and after RPB
111      for (int i = 0; i < maxFunctionDefinitions; i++) {
112        // +1 because RPB has index 0
113        SetAllowedChild(StartSymbol, defunSymbol, i + 1);
114      }
115
[4249]116      // every symbol of the mainBranchGrammar that is allowed as child of the start symbol is also allowed as direct child of defun
117      foreach (var symb in mainBranchGrammar.Symbols) {
118        if (mainBranchGrammar.IsAllowedChild(mainBranchGrammar.StartSymbol, symb, 0))
119          SetAllowedChild(defunSymbol, Symbols.Where(s => s.Name == symb.Name).First(), 0);
120      }
[3993]121    }
122
[4249]123    [Obsolete]
[3990]124    private void Initialize(ISymbolicExpressionGrammar mainBranchGrammar) {
[3541]125      base.Clear();
[3484]126
[3338]127      // remove the start symbol of the default grammar
128      RemoveSymbol(StartSymbol);
129
130      StartSymbol = new ProgramRootSymbol();
[3990]131      defunSymbol = new Defun();
[3338]132      AddSymbol(StartSymbol);
133      AddSymbol(defunSymbol);
134
135      SetMinSubtreeCount(StartSymbol, minFunctionDefinitions + 1);
136      SetMaxSubtreeCount(StartSymbol, maxFunctionDefinitions + 1);
137      SetMinSubtreeCount(defunSymbol, 1);
138      SetMaxSubtreeCount(defunSymbol, 1);
139
[3990]140      // ADF branches maxFunctionDefinitions
141      for (int argumentIndex = 1; argumentIndex < maxFunctionDefinitions + 1; argumentIndex++) {
142        SetAllowedChild(StartSymbol, defunSymbol, argumentIndex);
143      }
144
[3541]145      if (mainBranchGrammar != null) {
146        // copy symbols from mainBranchGrammar
147        foreach (var symb in mainBranchGrammar.Symbols) {
148          AddSymbol(symb);
149          SetMinSubtreeCount(symb, mainBranchGrammar.GetMinSubtreeCount(symb));
150          SetMaxSubtreeCount(symb, mainBranchGrammar.GetMaxSubtreeCount(symb));
151        }
[3338]152
[3541]153        // the start symbol of the mainBranchGrammar is allowed as the result producing branch
154        SetAllowedChild(StartSymbol, mainBranchGrammar.StartSymbol, 0);
[3338]155
[3541]156        // copy syntax constraints from mainBranchGrammar
157        foreach (var parent in mainBranchGrammar.Symbols) {
158          for (int i = 0; i < mainBranchGrammar.GetMaxSubtreeCount(parent); i++) {
159            foreach (var child in mainBranchGrammar.Symbols) {
160              if (mainBranchGrammar.IsAllowedChild(parent, child, i)) {
161                SetAllowedChild(parent, child, i);
162              }
[3338]163            }
164          }
165        }
166
[3541]167        // every symbol of the mainBranchGrammar that is allowed as child of the start symbol is also allowed as direct child of defun
168        foreach (var symb in mainBranchGrammar.Symbols) {
169          if (mainBranchGrammar.IsAllowedChild(mainBranchGrammar.StartSymbol, symb, 0))
170            SetAllowedChild(defunSymbol, symb, 0);
171        }
[3338]172      }
173    }
[3990]174    private void UpdateAdfConstraints() {
175      SetMinSubtreeCount(StartSymbol, minFunctionDefinitions + 1);
176      SetMaxSubtreeCount(StartSymbol, maxFunctionDefinitions + 1);
[4068]177
[3990]178      // ADF branches maxFunctionDefinitions
179      for (int argumentIndex = 1; argumentIndex < maxFunctionDefinitions + 1; argumentIndex++) {
180        SetAllowedChild(StartSymbol, defunSymbol, argumentIndex);
181      }
182    }
183
[3338]184    public override IDeepCloneable Clone(Cloner cloner) {
[4722]185      return new GlobalSymbolicExpressionGrammar(this, cloner);
[3338]186    }
187  }
188}
Note: See TracBrowser for help on using the repository browser.