1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022011 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 


22  using System.Collections.Generic;


23  using System.Linq;


24  using HeuristicLab.Common;


25  using HeuristicLab.Core;


26  using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;


27  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;


28  namespace HeuristicLab.Problems.DataAnalysis.Symbolic {


29  [StorableClass]


30  [Item("TypeCoherentExpressionGrammar", "Represents a grammar for functional expressions in which special syntactic constraints are enforced so that boolean and realvalued expressions are not mixed.")]


31  public class TypeCoherentExpressionGrammar : SymbolicExpressionGrammar, ISymbolicDataAnalysisGrammar {


32  private const string ArithmeticFunctionsName = "Arithmetic Functions";


33  private const string TrigonometricFunctionsName = "Trigonometric Functions";


34  private const string ExponentialFunctionsName = "Exponential and Logarithmic Functions";


35  private const string RealValuedSymbolsName = "Real Valued Symbols";


36  private const string TerminalsName = "Terminals";


37  private const string PowerFunctionsName = "Power Functions";


38  private const string ConditionsName = "Conditions";


39  private const string ComparisonsName = "Comparisons";


40  private const string BooleanOperatorsName = "Boolean Operators";


41  private const string ConditionalSymbolsName = "ConditionalSymbols";


42  private const string TimeSeriesSymbolsName = "Time Series Symbols";


43 


44  [StorableConstructor]


45  protected TypeCoherentExpressionGrammar(bool deserializing) : base(deserializing) { }


46  protected TypeCoherentExpressionGrammar(TypeCoherentExpressionGrammar original, Cloner cloner) : base(original, cloner) { }


47  public TypeCoherentExpressionGrammar()


48  : base(ItemAttribute.GetName(typeof(TypeCoherentExpressionGrammar)), ItemAttribute.GetDescription(typeof(TypeCoherentExpressionGrammar))) {


49  Initialize();


50  }


51  public override IDeepCloneable Clone(Cloner cloner) {


52  return new TypeCoherentExpressionGrammar(this, cloner);


53  }


54 


55  private void Initialize() {


56  #region symbol declaration


57  var add = new Addition();


58  var sub = new Subtraction();


59  var mul = new Multiplication();


60  var div = new Division();


61  var mean = new Average();


62  var sin = new Sine();


63  var cos = new Cosine();


64  var tan = new Tangent();


65  var log = new Logarithm();


66  var pow = new Power();


67  var root = new Root();


68  var exp = new Exponential();


69  var @if = new IfThenElse();


70  var gt = new GreaterThan();


71  var lt = new LessThan();


72  var and = new And();


73  var or = new Or();


74  var not = new Not();


75  var variableCondition = new VariableCondition();


76 


77  var timeLag = new TimeLag();


78  var integral = new Integral();


79  var derivative = new Derivative();


80 


81  var constant = new Constant();


82  constant.MinValue = 20;


83  constant.MaxValue = 20;


84  var variableSymbol = new Variable();


85  var laggedVariable = new LaggedVariable();


86  #endregion


87 


88  #region group symbol declaration


89  var arithmeticSymbols = new GroupSymbol(ArithmeticFunctionsName, new List<ISymbol>() { add, sub, mul, div, mean });


90  var trigonometricSymbols = new GroupSymbol(TrigonometricFunctionsName, new List<ISymbol>() { sin, cos, tan });


91  var exponentialAndLogarithmicSymbols = new GroupSymbol(ExponentialFunctionsName, new List<ISymbol> { exp, log });


92  var terminalSymbols = new GroupSymbol(TerminalsName, new List<ISymbol> { constant, variableSymbol });


93  var realValuedSymbols = new GroupSymbol(RealValuedSymbolsName, new List<ISymbol>() { arithmeticSymbols, trigonometricSymbols, exponentialAndLogarithmicSymbols, terminalSymbols });


94 


95  var powerSymbols = new GroupSymbol(PowerFunctionsName, new List<ISymbol> { pow, root });


96 


97  var conditionSymbols = new GroupSymbol(ConditionsName, new List<ISymbol> { @if, variableCondition });


98  var comparisonSymbols = new GroupSymbol(ComparisonsName, new List<ISymbol> { gt, lt });


99  var booleanOperationSymbols = new GroupSymbol(BooleanOperatorsName, new List<ISymbol> { and, or, not });


100  var conditionalSymbols = new GroupSymbol(ConditionalSymbolsName, new List<ISymbol> { conditionSymbols, comparisonSymbols, booleanOperationSymbols });


101 


102  var timeSeriesSymbols = new GroupSymbol(TimeSeriesSymbolsName, new List<ISymbol> { timeLag, integral, derivative, laggedVariable });


103  #endregion


104 


105  AddSymbol(realValuedSymbols);


106  AddSymbol(powerSymbols);


107  AddSymbol(conditionalSymbols);


108  AddSymbol(timeSeriesSymbols);


109 


110  #region subtree count configuration


111  SetSubtreeCount(arithmeticSymbols, 2, 2);


112  SetSubtreeCount(trigonometricSymbols, 1, 1);


113  SetSubtreeCount(powerSymbols, 2, 2);


114  SetSubtreeCount(exponentialAndLogarithmicSymbols, 1, 1);


115  SetSubtreeCount(terminalSymbols, 0, 0);


116 


117  SetSubtreeCount(@if, 3, 3);


118  SetSubtreeCount(variableCondition, 2, 2);


119  SetSubtreeCount(comparisonSymbols, 2, 2);


120  SetSubtreeCount(and, 2, 2);


121  SetSubtreeCount(or, 2, 2);


122  SetSubtreeCount(not, 1, 1);


123 


124  SetSubtreeCount(timeLag, 1, 1);


125  SetSubtreeCount(integral, 1, 1);


126  SetSubtreeCount(derivative, 1, 1);


127  SetSubtreeCount(laggedVariable, 0, 0);


128  #endregion


129 


130  #region allowed child symbols configuration


131  AddAllowedChildSymbol(StartSymbol, realValuedSymbols);


132  AddAllowedChildSymbol(DefunSymbol, realValuedSymbols);


133 


134  AddAllowedChildSymbol(realValuedSymbols, realValuedSymbols);


135  AddAllowedChildSymbol(realValuedSymbols, powerSymbols);


136  AddAllowedChildSymbol(realValuedSymbols, conditionSymbols);


137  AddAllowedChildSymbol(realValuedSymbols, timeSeriesSymbols);


138 


139  AddAllowedChildSymbol(powerSymbols, variableSymbol, 0);


140  AddAllowedChildSymbol(powerSymbols, laggedVariable, 0);


141  AddAllowedChildSymbol(powerSymbols, constant, 1);


142 


143  AddAllowedChildSymbol(@if, comparisonSymbols, 0);


144  AddAllowedChildSymbol(@if, booleanOperationSymbols, 0);


145  AddAllowedChildSymbol(@if, conditionSymbols, 1);


146  AddAllowedChildSymbol(@if, realValuedSymbols, 1);


147  AddAllowedChildSymbol(@if, powerSymbols, 1);


148  AddAllowedChildSymbol(@if, timeSeriesSymbols, 1);


149  AddAllowedChildSymbol(@if, conditionSymbols, 2);


150  AddAllowedChildSymbol(@if, realValuedSymbols, 2);


151  AddAllowedChildSymbol(@if, powerSymbols, 2);


152  AddAllowedChildSymbol(@if, timeSeriesSymbols, 2);


153 


154  AddAllowedChildSymbol(booleanOperationSymbols, comparisonSymbols);


155  AddAllowedChildSymbol(comparisonSymbols, realValuedSymbols);


156  AddAllowedChildSymbol(comparisonSymbols, powerSymbols);


157  AddAllowedChildSymbol(comparisonSymbols, conditionSymbols);


158  AddAllowedChildSymbol(comparisonSymbols, timeSeriesSymbols);


159 


160  AddAllowedChildSymbol(variableCondition, realValuedSymbols);


161  AddAllowedChildSymbol(variableCondition, powerSymbols);


162  AddAllowedChildSymbol(variableCondition, conditionSymbols);


163  AddAllowedChildSymbol(variableCondition, timeSeriesSymbols);


164 


165 


166  AddAllowedChildSymbol(timeLag, realValuedSymbols);


167  AddAllowedChildSymbol(timeLag, powerSymbols);


168  AddAllowedChildSymbol(timeLag, conditionSymbols);


169 


170  AddAllowedChildSymbol(integral, realValuedSymbols);


171  AddAllowedChildSymbol(integral, powerSymbols);


172  AddAllowedChildSymbol(integral, conditionSymbols);


173 


174  AddAllowedChildSymbol(derivative, realValuedSymbols);


175  AddAllowedChildSymbol(derivative, powerSymbols);


176  AddAllowedChildSymbol(derivative, conditionSymbols);


177  #endregion


178  }


179 


180  public void ConfigureAsDefaultRegressionGrammar() {


181  Symbols.Where(s => s is Average).First().Enabled = false;


182  Symbols.Where(s => s.Name == TrigonometricFunctionsName).First().Enabled = false;


183  Symbols.Where(s => s.Name == PowerFunctionsName).First().Enabled = false;


184  Symbols.Where(s => s.Name == ConditionalSymbolsName).First().Enabled = false;


185  Symbols.Where(s => s.Name == TimeSeriesSymbolsName).First().Enabled = false;


186  }


187 


188  public void ConfigureAsDefaultClassificationGrammar() {


189  Symbols.Where(s => s is Average).First().Enabled = false;


190  Symbols.Where(s => s is VariableCondition).First().Enabled = false;


191  Symbols.Where(s => s.Name == TrigonometricFunctionsName).First().Enabled = false;


192  Symbols.Where(s => s.Name == ExponentialFunctionsName).First().Enabled = false;


193  Symbols.Where(s => s.Name == PowerFunctionsName).First().Enabled = false;


194  Symbols.Where(s => s.Name == TimeSeriesSymbolsName).First().Enabled = false;


195  }


196 


197  public void ConfigureAsDefaultTimeSeriesPrognosisGrammar() {


198  Symbols.Where(s => s is Variable).First().Enabled = false;


199  Symbols.Where(s => s.Name == TrigonometricFunctionsName).First().Enabled = false;


200  Symbols.Where(s => s.Name == PowerFunctionsName).First().Enabled = false;


201  Symbols.Where(s => s.Name == ConditionalSymbolsName).First().Enabled = false;


202  }


203  }


204  }

