Free cookie consent management tool by TermsFeed Policy Generator

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

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

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

File size: 7.3 KB
Line 
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
22using System;
23using System.Linq;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
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.")]
32  public sealed class GlobalSymbolicExpressionGrammar : DefaultSymbolicExpressionGrammar {
33    [Storable]
34    private int minFunctionDefinitions;
35    public int MinFunctionDefinitions {
36      get { return minFunctionDefinitions; }
37      set {
38        minFunctionDefinitions = value;
39        UpdateAdfConstraints();
40      }
41    }
42    [Storable]
43    private int maxFunctionDefinitions;
44    public int MaxFunctionDefinitions {
45      get { return maxFunctionDefinitions; }
46      set {
47        maxFunctionDefinitions = value;
48        UpdateAdfConstraints();
49      }
50    }
51    [Storable]
52    private int minFunctionArguments;
53    public int MinFunctionArguments {
54      get { return minFunctionArguments; }
55      set {
56        minFunctionArguments = value;
57      }
58    }
59    [Storable]
60    private int maxFunctionArguments;
61    public int MaxFunctionArguments {
62      get { return maxFunctionArguments; }
63      set {
64        maxFunctionArguments = value;
65      }
66    }
67
68    [Storable]
69    private Defun defunSymbol;
70
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
82    public GlobalSymbolicExpressionGrammar(ISymbolicExpressionGrammar mainBranchGrammar)
83      : base(mainBranchGrammar) {
84      maxFunctionArguments = 3;
85      maxFunctionDefinitions = 3;
86
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
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);
104      SetMaxSubtreeCount(defunSymbol, 1);
105
106
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
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
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      }
121    }
122
123    [Obsolete]
124    private void Initialize(ISymbolicExpressionGrammar mainBranchGrammar) {
125      base.Clear();
126
127      // remove the start symbol of the default grammar
128      RemoveSymbol(StartSymbol);
129
130      StartSymbol = new ProgramRootSymbol();
131      defunSymbol = new Defun();
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
140      // ADF branches maxFunctionDefinitions
141      for (int argumentIndex = 1; argumentIndex < maxFunctionDefinitions + 1; argumentIndex++) {
142        SetAllowedChild(StartSymbol, defunSymbol, argumentIndex);
143      }
144
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        }
152
153        // the start symbol of the mainBranchGrammar is allowed as the result producing branch
154        SetAllowedChild(StartSymbol, mainBranchGrammar.StartSymbol, 0);
155
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              }
163            }
164          }
165        }
166
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        }
172      }
173    }
174    private void UpdateAdfConstraints() {
175      SetMinSubtreeCount(StartSymbol, minFunctionDefinitions + 1);
176      SetMaxSubtreeCount(StartSymbol, maxFunctionDefinitions + 1);
177
178      // ADF branches maxFunctionDefinitions
179      for (int argumentIndex = 1; argumentIndex < maxFunctionDefinitions + 1; argumentIndex++) {
180        SetAllowedChild(StartSymbol, defunSymbol, argumentIndex);
181      }
182    }
183
184    public override IDeepCloneable Clone(Cloner cloner) {
185      return new GlobalSymbolicExpressionGrammar(this, cloner);
186    }
187  }
188}
Note: See TracBrowser for help on using the repository browser.