Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Grammars/GrammarUtils.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Grammars/GrammarUtils.cs	(revision 14576)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Grammars/GrammarUtils.cs	(revision 14576)
@@ -0,0 +1,166 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+  public static class GrammarUtils {
+    private static IEnumerable<ISymbol> GetTopmostSymbols(this ISymbolicExpressionGrammarBase grammar) {
+      // build parents list so we can find out the topmost symbol(s)
+      var parents = new Dictionary<ISymbol, List<ISymbol>>();
+      foreach (var symbol in grammar.Symbols.Where(x => grammar.GetMinimumSubtreeCount(x) > 0)) {
+        var minSubtreeCount = grammar.GetMinimumSubtreeCount(symbol);
+        for (int argIndex = 0; argIndex < minSubtreeCount; ++argIndex) {
+          foreach (var childSymbol in grammar.GetAllowedActiveSymbols(symbol, argIndex)) {
+            if (!parents.ContainsKey(childSymbol))
+              parents[childSymbol] = new List<ISymbol>();
+            parents[childSymbol].Add(symbol);
+          }
+        }
+      }
+      // the topmost symbols have no parents
+      return parents.Values.SelectMany(x => x).Distinct().Where(x => !parents.ContainsKey(x));
+    }
+
+    private static IReadOnlyCollection<ISymbol> IterateBreadthReverse(this ISymbolicExpressionGrammarBase grammar, ISymbol topSymbol) {
+      // sort symbols in reverse breadth order (starting from the topSymbol)
+      // each symbol is visited only once (this avoids infinite recursion)
+      var symbols = new List<ISymbol> { topSymbol };
+      var visited = new HashSet<ISymbol> { topSymbol };
+      int i = 0;
+      while (i < symbols.Count) {
+        var symbol = symbols[i];
+        var minSubtreeCount = grammar.GetMinimumSubtreeCount(symbol);
+
+        for (int argIndex = 0; argIndex < minSubtreeCount; ++argIndex) {
+          foreach (var childSymbol in grammar.GetAllowedActiveSymbols(symbol, argIndex)) {
+            if (grammar.GetMinimumSubtreeCount(childSymbol) == 0)
+              continue;
+
+            if (visited.Add(childSymbol))
+              symbols.Add(childSymbol);
+          }
+        }
+        ++i;
+      }
+      symbols.Reverse();
+      return symbols;
+    }
+
+    private static IEnumerable<ISymbol> GetAllowedActiveSymbols(this ISymbolicExpressionGrammarBase grammar, ISymbol symbol, int argIndex) {
+      return grammar.GetAllowedChildSymbols(symbol, argIndex).Where(s => s.InitialFrequency > 0);
+    }
+
+    public static void CalculateMinimumExpressionLengths(ISymbolicExpressionGrammarBase grammar,
+      Dictionary<string, int> minimumExpressionLengths) {
+      minimumExpressionLengths.Clear();
+      //terminal symbols => minimum expression length = 1
+      foreach (var s in grammar.Symbols) {
+        if (grammar.GetMinimumSubtreeCount(s) == 0)
+          minimumExpressionLengths[s.Name] = 1;
+        else
+          minimumExpressionLengths[s.Name] = int.MaxValue;
+      }
+
+      foreach (var topSymbol in grammar.GetTopmostSymbols()) {
+        // get all symbols below in reverse breadth order
+        // this way we ensure lengths are calculated bottom-up
+        var symbols = grammar.IterateBreadthReverse(topSymbol);
+        foreach (var symbol in symbols) {
+          long minLength = 1;
+          for (int argIndex = 0; argIndex < grammar.GetMinimumSubtreeCount(symbol); ++argIndex) {
+            long length = grammar.GetAllowedActiveSymbols(symbol, argIndex)
+              .Where(x => minimumExpressionLengths.ContainsKey(x.Name))
+              .Select(x => minimumExpressionLengths[x.Name]).DefaultIfEmpty(int.MaxValue).Min();
+            minLength += length;
+          }
+          int oldLength;
+          if (minimumExpressionLengths.TryGetValue(symbol.Name, out oldLength))
+            minLength = Math.Min(minLength, oldLength);
+          minimumExpressionLengths[symbol.Name] = (int)Math.Min(int.MaxValue, minLength);
+        }
+        // correction step for cycles
+        bool changed = true;
+        while (changed) {
+          changed = false;
+          foreach (var symbol in symbols) {
+            long minLength = Enumerable.Range(0, grammar.GetMinimumSubtreeCount(symbol))
+              .Sum(x => grammar.GetAllowedActiveSymbols(symbol, x)
+              .Select(s => (long)minimumExpressionLengths[s.Name]).DefaultIfEmpty(int.MaxValue).Min()) + 1;
+            if (minLength < minimumExpressionLengths[symbol.Name]) {
+              minimumExpressionLengths[symbol.Name] = (int)Math.Min(minLength, int.MaxValue);
+              changed = true;
+            }
+          }
+        }
+      }
+    }
+
+    public static void CalculateMinimumExpressionDepth(ISymbolicExpressionGrammarBase grammar,
+      Dictionary<string, int> minimumExpressionDepths) {
+
+      minimumExpressionDepths.Clear();
+      //terminal symbols => minimum expression depth = 1
+      foreach (var s in grammar.Symbols) {
+        if (grammar.GetMinimumSubtreeCount(s) == 0)
+          minimumExpressionDepths[s.Name] = 1;
+        else
+          minimumExpressionDepths[s.Name] = int.MaxValue;
+      }
+
+      foreach (var topSymbol in grammar.GetTopmostSymbols()) {
+        // get all symbols below in reverse breadth order
+        // this way we ensure lengths are calculated bottom-up
+        var symbols = grammar.IterateBreadthReverse(topSymbol);
+        foreach (var symbol in symbols) {
+          long minDepth = -1;
+          for (int argIndex = 0; argIndex < grammar.GetMinimumSubtreeCount(symbol); ++argIndex) {
+            long depth = grammar.GetAllowedActiveSymbols(symbol, argIndex)
+              .Where(x => minimumExpressionDepths.ContainsKey(x.Name))
+              .Select(x => (long)minimumExpressionDepths[x.Name]).DefaultIfEmpty(int.MaxValue).Min() + 1;
+            minDepth = Math.Max(minDepth, depth);
+          }
+          int oldDepth;
+          if (minimumExpressionDepths.TryGetValue(symbol.Name, out oldDepth))
+            minDepth = Math.Min(minDepth, oldDepth);
+          minimumExpressionDepths[symbol.Name] = (int)Math.Min(int.MaxValue, minDepth);
+        }
+        // correction step for cycles
+        bool changed = true;
+        while (changed) {
+          changed = false;
+          foreach (var symbol in symbols) {
+            long minDepth = Enumerable.Range(0, grammar.GetMinimumSubtreeCount(symbol))
+              .Max(x => grammar.GetAllowedActiveSymbols(symbol, x)
+              .Select(s => (long)minimumExpressionDepths[s.Name]).DefaultIfEmpty(int.MaxValue).Min()) + 1;
+            if (minDepth < minimumExpressionDepths[symbol.Name]) {
+              minimumExpressionDepths[symbol.Name] = (int)Math.Min(minDepth, int.MaxValue);
+              changed = true;
+            }
+          }
+        }
+      }
+    }
+  }
+}
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Grammars/SymbolicExpressionGrammarBase.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Grammars/SymbolicExpressionGrammarBase.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Grammars/SymbolicExpressionGrammarBase.cs	(revision 14576)
@@ -82,11 +82,4 @@
     protected SymbolicExpressionGrammarBase(bool deserializing)
       : base(deserializing) {
-      cachedMinExpressionLength = new Dictionary<string, int>();
-      cachedMaxExpressionLength = new Dictionary<Tuple<string, int>, int>();
-      cachedMinExpressionDepth = new Dictionary<string, int>();
-      cachedMaxExpressionDepth = new Dictionary<string, int>();
-
-      cachedIsAllowedChildSymbol = new Dictionary<Tuple<string, string>, bool>();
-      cachedIsAllowedChildSymbolIndex = new Dictionary<Tuple<string, string, int>, bool>();
 
       symbols = new Dictionary<string, ISymbol>();
@@ -100,11 +93,4 @@
     protected SymbolicExpressionGrammarBase(SymbolicExpressionGrammarBase original, Cloner cloner)
       : base(original, cloner) {
-      cachedMinExpressionLength = new Dictionary<string, int>();
-      cachedMaxExpressionLength = new Dictionary<Tuple<string, int>, int>();
-      cachedMinExpressionDepth = new Dictionary<string, int>();
-      cachedMaxExpressionDepth = new Dictionary<string, int>();
-
-      cachedIsAllowedChildSymbol = new Dictionary<Tuple<string, string>, bool>();
-      cachedIsAllowedChildSymbolIndex = new Dictionary<Tuple<string, string, int>, bool>();
 
       symbols = original.symbols.ToDictionary(x => x.Key, y => cloner.Clone(y.Value));
@@ -124,12 +110,4 @@
     protected SymbolicExpressionGrammarBase(string name, string description)
       : base(name, description) {
-      cachedMinExpressionLength = new Dictionary<string, int>();
-      cachedMaxExpressionLength = new Dictionary<Tuple<string, int>, int>();
-      cachedMinExpressionDepth = new Dictionary<string, int>();
-      cachedMaxExpressionDepth = new Dictionary<string, int>();
-
-      cachedIsAllowedChildSymbol = new Dictionary<Tuple<string, string>, bool>();
-      cachedIsAllowedChildSymbolIndex = new Dictionary<Tuple<string, string, int>, bool>();
-
       symbols = new Dictionary<string, ISymbol>();
       symbolSubtreeCount = new Dictionary<string, Tuple<int, int>>();
@@ -322,5 +300,5 @@
     }
 
-    private readonly Dictionary<Tuple<string, string>, bool> cachedIsAllowedChildSymbol;
+    private readonly Dictionary<Tuple<string, string>, bool> cachedIsAllowedChildSymbol = new Dictionary<Tuple<string, string>, bool>();
     public virtual bool IsAllowedChildSymbol(ISymbol parent, ISymbol child) {
       if (allowedChildSymbols.Count == 0) return false;
@@ -352,5 +330,5 @@
     }
 
-    private readonly Dictionary<Tuple<string, string, int>, bool> cachedIsAllowedChildSymbolIndex;
+    private readonly Dictionary<Tuple<string, string, int>, bool> cachedIsAllowedChildSymbolIndex = new Dictionary<Tuple<string, string, int>, bool>();
     public virtual bool IsAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex) {
       if (!child.Enabled) return false;
@@ -412,5 +390,5 @@
     }
 
-    private readonly Dictionary<string, int> cachedMinExpressionLength;
+    private readonly Dictionary<string, int> cachedMinExpressionLength = new Dictionary<string, int>();
     public int GetMinimumExpressionLength(ISymbol symbol) {
       int res;
@@ -423,29 +401,11 @@
         if (cachedMinExpressionLength.TryGetValue(symbol.Name, out res)) return res;
 
-        res = GetMinimumExpressionLengthRec(symbol);
-        foreach (var entry in cachedMinExpressionLength.Where(e => e.Value >= int.MaxValue).ToList()) {
-          if (entry.Key != symbol.Name) cachedMinExpressionLength.Remove(entry.Key);
-        }
-        return res;
-      }
-    }
-
-    private int GetMinimumExpressionLengthRec(ISymbol symbol) {
-      int temp;
-      if (!cachedMinExpressionLength.TryGetValue(symbol.Name, out temp)) {
-        cachedMinExpressionLength[symbol.Name] = int.MaxValue; // prevent infinite recursion
-        long sumOfMinExpressionLengths = 1 + (from argIndex in Enumerable.Range(0, GetMinimumSubtreeCount(symbol))
-                                              let minForSlot = (long)(from s in GetAllowedChildSymbols(symbol, argIndex)
-                                                                      where s.InitialFrequency > 0.0
-                                                                      select GetMinimumExpressionLengthRec(s)).DefaultIfEmpty(0).Min()
-                                              select minForSlot).DefaultIfEmpty(0).Sum();
-
-        cachedMinExpressionLength[symbol.Name] = (int)Math.Min(sumOfMinExpressionLengths, int.MaxValue);
+        GrammarUtils.CalculateMinimumExpressionLengths(this, cachedMinExpressionLength);
         return cachedMinExpressionLength[symbol.Name];
       }
-      return temp;
-    }
-
-    private readonly Dictionary<Tuple<string, int>, int> cachedMaxExpressionLength;
+    }
+
+
+    private readonly Dictionary<Tuple<string, int>, int> cachedMaxExpressionLength = new Dictionary<Tuple<string, int>, int>();
     public int GetMaximumExpressionLength(ISymbol symbol, int maxDepth) {
       int temp;
@@ -469,5 +429,5 @@
     }
 
-    private readonly Dictionary<string, int> cachedMinExpressionDepth;
+    private readonly Dictionary<string, int> cachedMinExpressionDepth = new Dictionary<string, int>();
     public int GetMinimumExpressionDepth(ISymbol symbol) {
       int res;
@@ -480,27 +440,10 @@
         if (cachedMinExpressionDepth.TryGetValue(symbol.Name, out res)) return res;
 
-        res = GetMinimumExpressionDepthRec(symbol);
-        foreach (var entry in cachedMinExpressionDepth.Where(e => e.Value >= int.MaxValue).ToList()) {
-          if (entry.Key != symbol.Name) cachedMinExpressionDepth.Remove(entry.Key);
-        }
-        return res;
-      }
-    }
-    private int GetMinimumExpressionDepthRec(ISymbol symbol) {
-      int temp;
-      if (!cachedMinExpressionDepth.TryGetValue(symbol.Name, out temp)) {
-        cachedMinExpressionDepth[symbol.Name] = int.MaxValue; // prevent infinite recursion
-        long minDepth = 1 + (from argIndex in Enumerable.Range(0, GetMinimumSubtreeCount(symbol))
-                             let minForSlot = (long)(from s in GetAllowedChildSymbols(symbol, argIndex)
-                                                     where s.InitialFrequency > 0.0
-                                                     select GetMinimumExpressionDepthRec(s)).DefaultIfEmpty(0).Min()
-                             select minForSlot).DefaultIfEmpty(0).Max();
-        cachedMinExpressionDepth[symbol.Name] = (int)Math.Min(minDepth, int.MaxValue);
+        GrammarUtils.CalculateMinimumExpressionDepth(this, cachedMinExpressionDepth);
         return cachedMinExpressionDepth[symbol.Name];
       }
-      return temp;
-    }
-
-    private readonly Dictionary<string, int> cachedMaxExpressionDepth;
+    }
+
+    private readonly Dictionary<string, int> cachedMaxExpressionDepth = new Dictionary<string, int>();
     public int GetMaximumExpressionDepth(ISymbol symbol) {
       int temp;
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj	(revision 14576)
@@ -181,4 +181,5 @@
     <Compile Include="ArchitectureManipulators\SubroutineDuplicater.cs" />
     <Compile Include="ArchitectureManipulators\SymbolicExpressionTreeArchitectureManipulator.cs" />
+    <Compile Include="Grammars\GrammarUtils.cs" />
     <Compile Include="SymbolicExpressionTreeProblem.cs" />
     <Compile Include="Compiler\Instruction.cs" />
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeEncoding.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeEncoding.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeEncoding.cs	(revision 14576)
@@ -164,9 +164,9 @@
     public SymbolicExpressionTreeEncoding(string name, ISymbolicExpressionGrammar grammar, int maximumLength, int maximumDepth)
       : base(name) {
-      treeLengthParameter = new FixedValueParameter<IntValue>("Maximum Tree Length", "Maximal length of the symbolic expression.", new IntValue(maximumLength));
-      treeDepthParameter = new FixedValueParameter<IntValue>("Maximum Tree Depth", "Maximal depth of the symbolic expression. The minimum depth needed for the algorithm is 3 because two levels are reserved for the ProgramRoot and the Start symbol.", new IntValue(maximumDepth));
-      grammarParameter = new ValueParameter<ISymbolicExpressionGrammar>("Grammar", "The grammar that should be used for symbolic expression tree.", grammar);
-      functionDefinitionsParameter = new FixedValueParameter<IntValue>("Function Definitions", "Maximal number of automatically defined functions", new IntValue(0));
-      functionArgumentsParameter = new FixedValueParameter<IntValue>("Function Arguments", "Maximal number of arguments of automatically defined functions.", new IntValue(0));
+      treeLengthParameter = new FixedValueParameter<IntValue>(Name + ".Maximum Tree Length", "Maximal length of the symbolic expression.", new IntValue(maximumLength));
+      treeDepthParameter = new FixedValueParameter<IntValue>(Name + ".Maximum Tree Depth", "Maximal depth of the symbolic expression. The minimum depth needed for the algorithm is 3 because two levels are reserved for the ProgramRoot and the Start symbol.", new IntValue(maximumDepth));
+      grammarParameter = new ValueParameter<ISymbolicExpressionGrammar>(Name + ".Grammar", "The grammar that should be used for symbolic expression tree.", grammar);
+      functionDefinitionsParameter = new FixedValueParameter<IntValue>(Name + ".Function Definitions", "Maximal number of automatically defined functions", new IntValue(0));
+      functionArgumentsParameter = new FixedValueParameter<IntValue>(Name + ".Function Arguments", "Maximal number of arguments of automatically defined functions.", new IntValue(0));
 
       Parameters.Add(treeLengthParameter);
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/SimpleSymbol.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/SimpleSymbol.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/SimpleSymbol.cs	(revision 14576)
@@ -61,4 +61,8 @@
     }
 
+    public SimpleSymbol(string name, int arity)
+      : this(name, string.Empty, arity, arity) {
+    }
+
     public SimpleSymbol(string name, string description, int minimumArity, int maximumArity)
       : base(name, description) {
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs	(revision 14576)
@@ -112,5 +112,14 @@
       treeChart.Tree = tree;
       treeChart.Repaint();
-      bool valid = !tree.IterateNodesPostfix().Any(node => node.SubtreeCount < GetMinArity(node.Symbol) || node.SubtreeCount > node.Symbol.MaximumArity);
+      // check if all nodes have a legal arity
+      var nodes = tree.IterateNodesPostfix().ToList();
+      bool valid = !nodes.Any(node => node.SubtreeCount < GetMinArity(node.Symbol) || node.SubtreeCount > node.Symbol.MaximumArity);
+
+      if (valid) {
+        // check if all variables are contained in the dataset
+        var variables = new HashSet<string>(Content.ProblemData.Dataset.DoubleVariables);
+        valid = nodes.OfType<VariableTreeNode>().All(x => variables.Contains(x.VariableName));
+      }
+
       if (valid) {
         btnOptimizeConstants.Enabled = true;
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs	(revision 14576)
@@ -102,5 +102,5 @@
         if (dialog.DialogResult != DialogResult.OK) return;
 
-        var symbol = dialog.SelectedSymbol();
+        var symbol = dialog.SelectedSymbol;
         var node = symbol.CreateTreeNode();
         if (node is ConstantTreeNode) {
@@ -110,5 +110,5 @@
           var variable = node as VariableTreeNode;
           variable.Weight = double.Parse(dialog.variableWeightTextBox.Text);
-          variable.VariableName = dialog.variableNamesCombo.Text;
+          variable.VariableName = dialog.SelectedVariableName;
         } else if (node.Symbol.MinimumArity <= parent.SubtreeCount && node.Symbol.MaximumArity >= parent.SubtreeCount) {
           for (int i = parent.SubtreeCount - 1; i >= 0; --i) {
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeNodeInsertDialog.Designer.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeNodeInsertDialog.Designer.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeNodeInsertDialog.Designer.cs	(revision 14576)
@@ -57,4 +57,5 @@
       this.okButton = new System.Windows.Forms.Button();
       this.cancelButton = new System.Windows.Forms.Button();
+      this.variableNameTextBox = new System.Windows.Forms.TextBox();
       ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
       this.SuspendLayout();
@@ -168,4 +169,12 @@
       this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
       // 
+      // variableNameTextBox
+      // 
+      this.variableNameTextBox.Location = new System.Drawing.Point(101, 63);
+      this.variableNameTextBox.Name = "variableNameTextBox";
+      this.variableNameTextBox.Size = new System.Drawing.Size(127, 20);
+      this.variableNameTextBox.TabIndex = 11;
+      this.variableNameTextBox.Visible = false;
+      // 
       // InsertNodeDialog
       // 
@@ -175,4 +184,5 @@
       this.ClientSize = new System.Drawing.Size(241, 133);
       this.ControlBox = false;
+      this.Controls.Add(this.variableNameTextBox);
       this.Controls.Add(this.cancelButton);
       this.Controls.Add(this.okButton);
@@ -208,4 +218,5 @@
     private System.Windows.Forms.Button cancelButton;
     private System.Windows.Forms.Button okButton;
+    private System.Windows.Forms.TextBox variableNameTextBox;
   }
 }
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeNodeInsertDialog.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeNodeInsertDialog.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeNodeInsertDialog.cs	(revision 14576)
@@ -23,4 +23,5 @@
 using System.Collections.Generic;
 using System.ComponentModel;
+using System.Linq;
 using System.Text;
 using System.Windows.Forms;
@@ -30,4 +31,13 @@
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
   public partial class InsertNodeDialog : Form {
+    public string SelectedVariableName {
+      get {
+        var variable = SelectedSymbol as Variable;
+        if (variable == null)
+          return string.Empty;
+        return variable.VariableNames.Any() ? variableNamesCombo.Text : variableNameTextBox.Text;
+      }
+    }
+
     public InsertNodeDialog() {
       InitializeComponent();
@@ -40,6 +50,6 @@
     }
 
-    public ISymbol SelectedSymbol() {
-      return (ISymbol)allowedSymbolsCombo.SelectedItem;
+    public ISymbol SelectedSymbol {
+      get { return (ISymbol)allowedSymbolsCombo.SelectedItem; }
     }
 
@@ -56,9 +66,16 @@
         constantValueTextBox.Visible = true;
       } else if (symbol is Variable) {
-        var variable = (Variable)symbol;
-        foreach (var name in variable.VariableNames) variableNamesCombo.Items.Add(name);
-        variableNamesCombo.SelectedIndex = 0;
+        var variableSymbol = (Variable)symbol;
+        if (variableSymbol.VariableNames.Any()) {
+          foreach (var name in variableSymbol.VariableNames)
+            variableNamesCombo.Items.Add(name);
+          variableNamesCombo.SelectedIndex = 0;
+          variableNamesCombo.Visible = true;
+          variableNameTextBox.Visible = false;
+        } else {
+          variableNamesCombo.Visible = false;
+          variableNameTextBox.Visible = true;
+        }
         variableNameLabel.Visible = true;
-        variableNamesCombo.Visible = true;
         variableWeightLabel.Visible = true;
         variableWeightTextBox.Visible = true;
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeVariableNodeEditDialog.Designer.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeVariableNodeEditDialog.Designer.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeVariableNodeEditDialog.Designer.cs	(revision 14576)
@@ -55,4 +55,5 @@
       this.okButton = new System.Windows.Forms.Button();
       this.cancelButton = new System.Windows.Forms.Button();
+      this.variableNameTextBox = new System.Windows.Forms.TextBox();
       ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
       this.SuspendLayout();
@@ -146,4 +147,12 @@
       this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
       // 
+      // variableNameTextBox
+      // 
+      this.variableNameTextBox.Location = new System.Drawing.Point(101, 12);
+      this.variableNameTextBox.Name = "variableNameTextBox";
+      this.variableNameTextBox.Size = new System.Drawing.Size(131, 20);
+      this.variableNameTextBox.TabIndex = 12;
+      this.variableNameTextBox.Visible = false;
+      // 
       // VariableNodeEditDialog
       // 
@@ -154,4 +163,5 @@
       this.ClientSize = new System.Drawing.Size(244, 134);
       this.ControlBox = false;
+      this.Controls.Add(this.variableNameTextBox);
       this.Controls.Add(this.cancelButton);
       this.Controls.Add(this.okButton);
@@ -188,4 +198,5 @@
     public System.Windows.Forms.TextBox newValueTextBox;
     public System.Windows.Forms.ComboBox variableNamesCombo;
+    private System.Windows.Forms.TextBox variableNameTextBox;
   }
 }
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeVariableNodeEditDialog.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeVariableNodeEditDialog.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeVariableNodeEditDialog.cs	(revision 14576)
@@ -22,4 +22,5 @@
 using System;
 using System.ComponentModel;
+using System.Linq;
 using System.Text;
 using System.Windows.Forms;
@@ -40,8 +41,11 @@
     }
 
+    public string SelectedVariableName {
+      get { return variableNamesCombo.Visible ? variableNamesCombo.Text : variableNameTextBox.Text; }
+    }
+
     public VariableNodeEditDialog(ISymbolicExpressionTreeNode node) {
       InitializeComponent();
       oldValueTextBox.TabStop = false; // cannot receive focus using tab key
-
       NewNode = (VariableTreeNode)node; // will throw an invalid cast exception if node is not of the correct type
       InitializeFields();
@@ -57,6 +61,14 @@
         variableNameLabel.Visible = true;
         variableNamesCombo.Visible = true;
-        foreach (var name in variableTreeNode.Symbol.VariableNames) variableNamesCombo.Items.Add(name);
-        variableNamesCombo.SelectedIndex = variableNamesCombo.Items.IndexOf(variableTreeNode.VariableName);
+        if (variableTreeNode.Symbol.VariableNames.Any()) {
+          foreach (var name in variableTreeNode.Symbol.VariableNames)
+            variableNamesCombo.Items.Add(name);
+          variableNamesCombo.SelectedIndex = variableNamesCombo.Items.IndexOf(variableTreeNode.VariableName);
+          variableNamesCombo.Visible = true;
+          variableNameTextBox.Visible = false;
+        } else {
+          variableNamesCombo.Visible = false;
+          variableNameTextBox.Visible = true;
+        }
       }
     }
@@ -93,4 +105,5 @@
     #region combo box validation and events
     private void variableNamesCombo_Validating(object sender, CancelEventArgs e) {
+      if (variableNamesCombo.Items.Count == 0) return;
       if (variableNamesCombo.Items.Contains(variableNamesCombo.SelectedItem)) return;
       e.Cancel = true;
@@ -119,6 +132,6 @@
     private void OnDialogValidated(object sender, EventArgs e) {
       double weight = double.Parse(newValueTextBox.Text);
-      var variableName = (string)variableNamesCombo.SelectedItem;
       // we impose an extra validation condition: that the weight/value be different than the original ones
+      var variableName = SelectedVariableName;
       if (variableTreeNode.Weight.Equals(weight) && variableTreeNode.VariableName.Equals(variableName)) return;
       variableTreeNode.Weight = weight;
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs	(revision 14576)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using System.Globalization;
 using System.Linq;
@@ -80,4 +81,13 @@
           }
           strBuilder.Append(")");
+        } else {
+          // function with multiple arguments
+          strBuilder.Append(token).Append("(");
+          FormatRecursively(node.Subtrees.First(), strBuilder);
+          foreach (var subtree in node.Subtrees.Skip(1)) {
+            strBuilder.Append(", ");
+            FormatRecursively(subtree, strBuilder);
+          }
+          strBuilder.Append(")");
         }
       } else if (node.SubtreeCount == 1) {
@@ -93,5 +103,5 @@
           FormatRecursively(node.GetSubtree(0), strBuilder);
         } else {
-          // function
+          // function with only one argument
           strBuilder.Append(token).Append("(");
           FormatRecursively(node.GetSubtree(0), strBuilder);
@@ -100,5 +110,21 @@
       } else {
         // no subtrees
-        if (node.Symbol is Variable) {
+        if (node.Symbol is LaggedVariable) {
+          var varNode = node as LaggedVariableTreeNode;
+          if (!varNode.Weight.IsAlmost(1.0)) {
+            strBuilder.Append("(");
+            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", varNode.Weight);
+            strBuilder.Append("*");
+          }
+          strBuilder.Append("LAG(");
+          if (varNode.VariableName.Contains("'")) {
+            strBuilder.AppendFormat("\"{0}\"", varNode.VariableName);
+          } else {
+            strBuilder.AppendFormat("'{0}'", varNode.VariableName);
+          }
+          strBuilder.Append(", ")
+            .AppendFormat(CultureInfo.InvariantCulture, "{0}", varNode.Lag)
+            .Append(")");
+        } else if (node.Symbol is Variable) {
           var varNode = node as VariableTreeNode;
           if (!varNode.Weight.IsAlmost(1.0)) {
@@ -120,5 +146,5 @@
             strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", constNode.Value);
           else
-            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", constNode.Value);     // (-1)
+            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", constNode.Value); // (-1
         }
       }
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs	(revision 14576)
@@ -67,6 +67,5 @@
         strBuilder.AppendLine(FormatRecursively(symbolicExpressionTree.Root));
         return strBuilder.ToString();
-      }
-      catch (NotImplementedException ex) {
+      } catch (NotImplementedException ex) {
         return ex.Message + Environment.NewLine + ex.StackTrace;
       }
@@ -109,5 +108,5 @@
       } else if (node.Symbol is Division) {
         if (node.SubtreeCount == 1) {
-          strBuilder.Append(@" \cfrac{1");
+          strBuilder.Append(@" \cfrac{1}{");
         } else {
           strBuilder.Append(@" \cfrac{ ");
@@ -176,7 +175,11 @@
         strBuilder.Append(@" \operatorname{if}  \left( ");
       } else if (node.Symbol is Constant) {
-        strBuilder.Append("c_{" + constants.Count + "} ");
         var constNode = node as ConstantTreeNode;
-        constants.Add(constNode.Value);
+        if (constNode.Value.IsAlmost(1.0)) {
+          strBuilder.Append("1 ");
+        } else {
+          strBuilder.Append("c_{" + constants.Count + "} ");
+          constants.Add(constNode.Value);
+        }
       } else if (node.Symbol is LaggedVariable) {
         var laggedVarNode = node as LaggedVariableTreeNode;
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs	(revision 14576)
@@ -26,4 +26,5 @@
 using System.Text;
 using HeuristicLab.Collections;
+using HeuristicLab.Common;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 
@@ -37,5 +38,5 @@
   /// </summary>
   public sealed class InfixExpressionParser {
-    private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, End, NA };
+    private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, Comma, End, NA };
     private class Token {
       internal double doubleVal;
@@ -102,6 +103,6 @@
         { "MEAN", new Average()},
         { "IF", new IfThenElse()},
-        { ">", new GreaterThan()},
-        { "<", new LessThan()},
+        { "GT", new GreaterThan()},
+        { "LT", new LessThan()},
         { "AND", new And()},
         { "OR", new Or()},
@@ -109,4 +110,5 @@
         { "XOR", new Xor()},
         { "DIFF", new Derivative()},
+        { "LAG", new LaggedVariable() },
       };
 
@@ -138,14 +140,15 @@
         }
         if (char.IsDigit(str[pos])) {
-          // read number (=> read until white space or operator)
+          // read number (=> read until white space or operator or comma)
           var sb = new StringBuilder();
           sb.Append(str[pos]);
           pos++;
           while (pos < str.Length && !char.IsWhiteSpace(str[pos])
-            && (str[pos] != '+' || str[pos-1] == 'e' || str[pos-1] == 'E')     // continue reading exponents
+            && (str[pos] != '+' || str[pos - 1] == 'e' || str[pos - 1] == 'E')     // continue reading exponents
             && (str[pos] != '-' || str[pos - 1] == 'e' || str[pos - 1] == 'E')
-            && str[pos] != '*'           
+            && str[pos] != '*'
             && str[pos] != '/'
-            && str[pos] != ')') {
+            && str[pos] != ')'
+            && str[pos] != ',') {
             sb.Append(str[pos]);
             pos++;
@@ -211,12 +214,18 @@
           pos++;
           yield return new Token { TokenType = TokenType.RightPar, strVal = ")" };
-        }
-      }
-    }
-
-    // S = Expr EOF
-    // Expr = ['-' | '+'] Term { '+' Term | '-' Term }
-    // Term = Fact { '*' Fact | '/' Fact }
-    // Fact = '(' Expr ')' | funcId '(' Expr ')' | varId | number
+        } else if (str[pos] == ',') {
+          pos++;
+          yield return new Token { TokenType = TokenType.Comma, strVal = "," };
+        } else {
+          throw new ArgumentException("Invalid character: " + str[pos]);
+        }
+      }
+    }
+
+    // S       = Expr EOF
+    // Expr    = ['-' | '+'] Term { '+' Term | '-' Term }
+    // Term    = Fact { '*' Fact | '/' Fact }
+    // Fact    = '(' Expr ')' | funcId '(' ArgList ')' | varId | number
+    // ArgList = Expr { ',' Expr }
     private ISymbolicExpressionTreeNode ParseS(Queue<Token> tokens) {
       var expr = ParseExpr(tokens);
@@ -326,5 +335,5 @@
     }
 
-    // Fact = '(' Expr ')' | funcId '(' Expr ')' | varId | number
+    // Fact = '(' Expr ')' | 'LAG' '(' varId ',' ['+' | '-'] number ')' | funcId '(' ArgList ')' | varId | number
     private ISymbolicExpressionTreeNode ParseFact(Queue<Token> tokens) {
       var next = tokens.Peek();
@@ -346,10 +355,40 @@
           if (lPar.TokenType != TokenType.LeftPar)
             throw new ArgumentException("expected (");
-          var expr = ParseExpr(tokens);
+
+          // handle 'lag' specifically
+          if (funcNode.Symbol is LaggedVariable) {
+            var varId = tokens.Dequeue();
+            if (varId.TokenType != TokenType.Identifier) throw new ArgumentException("Identifier expected. Format for lagged variables: \"lag(x, -1)\"");
+            var comma = tokens.Dequeue();
+            if (comma.TokenType != TokenType.Comma) throw new ArgumentException("',' expected, Format for lagged variables: \"lag(x, -1)\"");
+            double sign = 1.0;
+            if (tokens.Peek().strVal == "+" || tokens.Peek().strVal == "-") {
+              // read sign
+              var signTok = tokens.Dequeue();
+              if (signTok.strVal == "-") sign = -1.0;
+            }
+            var lagToken = tokens.Dequeue();
+            if (lagToken.TokenType != TokenType.Number) throw new ArgumentException("Number expected, Format for lagged variables: \"lag(x, -1)\"");
+            if (!lagToken.doubleVal.IsAlmost(Math.Round(lagToken.doubleVal)))
+              throw new ArgumentException("Time lags must be integer values");
+            var laggedVarNode = funcNode as LaggedVariableTreeNode;
+            laggedVarNode.VariableName = varId.strVal;
+            laggedVarNode.Lag = (int)Math.Round(sign * lagToken.doubleVal);
+            laggedVarNode.Weight = 1.0;
+          } else {
+            // functions
+            var args = ParseArgList(tokens);
+            // check number of arguments
+            if (funcNode.Symbol.MinimumArity > args.Length || funcNode.Symbol.MaximumArity < args.Length) {
+              throw new ArgumentException(string.Format("Symbol {0} requires between {1} and  {2} arguments.", funcId,
+                funcNode.Symbol.MinimumArity, funcNode.Symbol.MaximumArity));
+            }
+            foreach (var arg in args) funcNode.AddSubtree(arg);
+          }
+
           var rPar = tokens.Dequeue();
           if (rPar.TokenType != TokenType.RightPar)
             throw new ArgumentException("expected )");
 
-          funcNode.AddSubtree(expr);
           return funcNode;
         } else {
@@ -369,4 +408,16 @@
       }
     }
+
+    // ArgList = Expr { ',' Expr }
+    private ISymbolicExpressionTreeNode[] ParseArgList(Queue<Token> tokens) {
+      var exprList = new List<ISymbolicExpressionTreeNode>();
+      exprList.Add(ParseExpr(tokens));
+      while (tokens.Peek().TokenType != TokenType.RightPar) {
+        var comma = tokens.Dequeue();
+        if (comma.TokenType != TokenType.Comma) throw new ArgumentException("expected ',' ");
+        exprList.Add(ParseExpr(tokens));
+      }
+      return exprList.ToArray();
+    }
   }
 }
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/SymbolicExpressionImporter.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/SymbolicExpressionImporter.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/SymbolicExpressionImporter.cs	(revision 14576)
@@ -35,5 +35,5 @@
     private const string INVOKESTART = "CALL";
     private const string TIMELAGSTART = "LAG";
-    private Dictionary<string, Symbol> knownSymbols = new Dictionary<string, Symbol>() 
+    private Dictionary<string, Symbol> knownSymbols = new Dictionary<string, Symbol>()
       {
         {"+", new Addition()},
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs	(revision 14576)
@@ -614,4 +614,5 @@
         case OpCodes.VariableCondition: {
             var variableConditionTreeNode = (VariableConditionTreeNode)node;
+            if (variableConditionTreeNode.Symbol.IgnoreSlope) throw new NotSupportedException("Strict variable conditionals are not supported");
             var variableName = variableConditionTreeNode.VariableName;
             var indexExpr = Expression.Constant(variableIndices[variableName]);
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 14576)
@@ -471,12 +471,25 @@
             if (row < 0 || row >= dataset.Rows) return double.NaN;
             var variableConditionTreeNode = (VariableConditionTreeNode)currentInstr.dynamicNode;
-            double variableValue = ((IList<double>)currentInstr.data)[row];
-            double x = variableValue - variableConditionTreeNode.Threshold;
-            double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
-
-            double trueBranch = Evaluate(dataset, ref row, state);
-            double falseBranch = Evaluate(dataset, ref row, state);
-
-            return trueBranch * p + falseBranch * (1 - p);
+            if (!variableConditionTreeNode.Symbol.IgnoreSlope) {
+              double variableValue = ((IList<double>)currentInstr.data)[row];
+              double x = variableValue - variableConditionTreeNode.Threshold;
+              double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
+
+              double trueBranch = Evaluate(dataset, ref row, state);
+              double falseBranch = Evaluate(dataset, ref row, state);
+
+              return trueBranch * p + falseBranch * (1 - p);
+            } else {
+              // strict threshold
+              double variableValue = ((IList<double>)currentInstr.data)[row];
+              if (variableValue <= variableConditionTreeNode.Threshold) {
+                var left = Evaluate(dataset, ref row, state);
+                state.SkipInstructions();
+                return left;
+              } else {
+                state.SkipInstructions();
+                return Evaluate(dataset, ref row, state);
+              }
+            }
           }
         default:
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs	(revision 14576)
@@ -126,4 +126,5 @@
     private readonly object syncRoot = new object();
     public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows) {
+      if (!rows.Any()) return Enumerable.Empty<double>();
       if (CheckExpressionsWithIntervalArithmetic)
         throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
@@ -166,12 +167,21 @@
           if (row < 0 || row >= dataset.Rows) instr.value = double.NaN;
           var variableConditionTreeNode = (VariableConditionTreeNode)instr.dynamicNode;
-          double variableValue = ((IList<double>)instr.data)[row];
-          double x = variableValue - variableConditionTreeNode.Threshold;
-          double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
-
-          double trueBranch = code[instr.childIndex].value;
-          double falseBranch = code[instr.childIndex + 1].value;
-
-          instr.value = trueBranch * p + falseBranch * (1 - p);
+          if (!variableConditionTreeNode.Symbol.IgnoreSlope) {
+            double variableValue = ((IList<double>)instr.data)[row];
+            double x = variableValue - variableConditionTreeNode.Threshold;
+            double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
+
+            double trueBranch = code[instr.childIndex].value;
+            double falseBranch = code[instr.childIndex + 1].value;
+
+            instr.value = trueBranch * p + falseBranch * (1 - p);
+          } else {
+            double variableValue = ((IList<double>)instr.data)[row];
+            if (variableValue <= variableConditionTreeNode.Threshold) {
+              instr.value = code[instr.childIndex].value;
+            } else {
+              instr.value = code[instr.childIndex + 1].value;
+            }
+          }
         } else if (instr.opCode == OpCodes.Add) {
           double s = code[instr.childIndex].value;
@@ -420,6 +430,6 @@
               for (int j = 1; j != seq.Length; ++j)
                 seq[j].skip = true;
-            }
-            break;
+              break;
+            }
         }
         #endregion
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableCondition.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableCondition.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableCondition.cs	(revision 14576)
@@ -149,4 +149,14 @@
         }
       }
+    }
+
+    /// <summary>
+    /// Flag to indicate if the interpreter should ignore the slope parameter (introduced for representation of expression trees)
+    /// </summary>
+    [Storable]
+    private bool ignoreSlope;
+    public bool IgnoreSlope {
+      get { return ignoreSlope; }
+      set { ignoreSlope = value; }
     }
 
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableConditionTreeNode.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableConditionTreeNode.cs	(revision 14575)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableConditionTreeNode.cs	(revision 14576)
@@ -96,9 +96,10 @@
 
     public override string ToString() {
-      if (slope.IsAlmost(0.0))
+      if (slope.IsAlmost(0.0) || Symbol.IgnoreSlope) {
+        return variableName + " < " + threshold.ToString("E4");
+      } else {
         return variableName + " > " + threshold.ToString("E4") + Environment.NewLine +
-          "slope: " + slope.ToString("E4");
-      else
-        return variableName + " > " + threshold.ToString("E4");
+               "slope: " + slope.ToString("E4");
+      }
     }
   }
