Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SymbolicSimplifier.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SymbolicSimplifier.cs	(revision 5460)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SymbolicSimplifier.cs	(revision 5461)
@@ -35,4 +35,5 @@
   public class SymbolicSimplifier {
     private Addition addSymbol = new Addition();
+    private Subtraction subSymbol = new Subtraction();
     private Multiplication mulSymbol = new Multiplication();
     private Division divSymbol = new Division();
@@ -151,4 +152,12 @@
     private bool IsLessThan(SymbolicExpressionTreeNode node) {
       return node.Symbol is LessThan;
+    }
+
+    private bool IsBoolean(SymbolicExpressionTreeNode node) {
+      return
+        node.Symbol is GreaterThan ||
+        node.Symbol is LessThan ||
+        node.Symbol is And ||
+        node.Symbol is Or;
     }
 
@@ -439,5 +448,11 @@
       } else {
         var ifNode = ifThenElseSymbol.CreateTreeNode();
-        ifNode.AddSubTree(condition);
+        if (IsBoolean(condition)) {
+          ifNode.AddSubTree(condition);
+        } else {
+          var gtNode = gtSymbol.CreateTreeNode();
+          gtNode.AddSubTree(condition); gtNode.AddSubTree(MakeConstant(0.0));
+          ifNode.AddSubTree(gtNode);
+        }
         ifNode.AddSubTree(trueBranch);
         ifNode.AddSubTree(falseBranch);
@@ -445,4 +460,5 @@
       }
     }
+
     private SymbolicExpressionTreeNode MakeSine(SymbolicExpressionTreeNode node) {
       // todo implement more transformation rules
@@ -483,4 +499,6 @@
         var constT = node as ConstantTreeNode;
         return MakeConstant(Math.Exp(constT.Value));
+      } else if (IsLog(node)) {
+        return node.SubTrees[0];
       } else {
         var expNode = expSymbol.CreateTreeNode();
@@ -494,4 +512,14 @@
         var constT = node as ConstantTreeNode;
         return MakeConstant(Math.Log(constT.Value));
+      } else if (IsExp(node)) {
+        return node.SubTrees[0];
+      } else if (IsMultiplication(node)) {
+        return node.SubTrees.Select(s => MakeLog(s)).Aggregate((x, y) => MakeSum(x, y));
+      } else if (IsDivision(node)) {
+        var subtractionNode = subSymbol.CreateTreeNode();
+        foreach (var subTree in node.SubTrees) {
+          subtractionNode.AddSubTree(MakeLog(subTree));
+        }
+        return subtractionNode;
       } else {
         var logNode = logSymbol.CreateTreeNode();
@@ -503,5 +531,4 @@
 
     // MakeFraction, MakeProduct and MakeSum take two already simplified trees and create a new simplified tree
-
     private SymbolicExpressionTreeNode MakeFraction(SymbolicExpressionTreeNode a, SymbolicExpressionTreeNode b) {
       if (IsConstant(a) && IsConstant(b)) {
@@ -515,4 +542,9 @@
         ((VariableTreeNode)a).Weight /= constB;
         return a;
+      } else if (IsVariable(a) && IsVariable(b) && AreSameVariable(a, b)) {
+        // cancel variables
+        var aVar = a as VariableTreeNode;
+        var bVar = b as VariableTreeNode;
+        return MakeConstant(aVar.Weight / bVar.Weight);
       } else if (IsAddition(a) && IsConstant(b)) {
         return a.SubTrees
@@ -574,5 +606,9 @@
         }
         MergeVariablesInSum(add);
-        return add;
+        if (add.SubTrees.Count == 1) {
+          return add.SubTrees[0];
+        } else {
+          return add;
+        }
       } else if (IsAddition(b)) {
         return MakeSum(b, a);
@@ -596,5 +632,9 @@
         }
         MergeVariablesInSum(add);
-        return add;
+        if (add.SubTrees.Count == 1) {
+          return add.SubTrees[0];
+        } else {
+          return add;
+        }
       } else {
         var add = addSymbol.CreateTreeNode();
@@ -602,10 +642,14 @@
         add.AddSubTree(b);
         MergeVariablesInSum(add);
-        return add;
+        if (add.SubTrees.Count == 1) {
+          return add.SubTrees[0];
+        } else {
+          return add;
+        }
       }
     }
 
     // makes sure variable symbols in sums are combined
-    // possible improvment: combine sums of products where the products only reference the same variable
+    // possible improvement: combine sums of products where the products only reference the same variable
     private void MergeVariablesInSum(SymbolicExpressionTreeNode sum) {
       var subtrees = new List<SymbolicExpressionTreeNode>(sum.SubTrees);
@@ -683,4 +727,22 @@
     #endregion
 
+
+    #region helper functions
+
+    private bool AreSameVariable(SymbolicExpressionTreeNode a, SymbolicExpressionTreeNode b) {
+      var aLaggedVar = a as LaggedVariableTreeNode;
+      var bLaggedVar = b as LaggedVariableTreeNode;
+      if (aLaggedVar != null && bLaggedVar != null) {
+        return aLaggedVar.VariableName == bLaggedVar.VariableName &&
+          aLaggedVar.Lag == bLaggedVar.Lag;
+      }
+      var aVar = a as VariableTreeNode;
+      var bVar = b as VariableTreeNode;
+      if (aVar != null && bVar != null) {
+        return aVar.VariableName == bVar.VariableName;
+      }
+      return false;
+    }
+
     // helper to combine the constant factors in products and to combine variables (powers of 2, 3...)
     private void MergeVariablesAndConstantsInProduct(SymbolicExpressionTreeNode prod) {
@@ -727,5 +789,4 @@
 
 
-    #region helper functions
     /// <summary>
     /// x => x * -1
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/SymbolicSimplifierTest.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/SymbolicSimplifierTest.cs	(revision 5460)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/SymbolicSimplifierTest.cs	(revision 5461)
@@ -140,4 +140,31 @@
       }
       #endregion
+      #region constant and variable folding
+      {
+        var actualTree = simplifier.Simplify(importer.Import("(+ 1.0 2.0)"));
+        var expectedTree = importer.Import("3.0");
+        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
+      }
+      {
+        var actualTree = simplifier.Simplify(importer.Import("(+ (variable 2.0 a) (variable 2.0 a))"));
+        var expectedTree = importer.Import("(variable 4.0 a)");
+        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
+      }
+      {
+        var actualTree = simplifier.Simplify(importer.Import("(- (variable 2.0 a) (variable 1.0 a))"));
+        var expectedTree = importer.Import("(variable 1.0 a)");
+        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
+      }
+      {
+        var actualTree = simplifier.Simplify(importer.Import("(* (variable 2.0 a) (variable 2.0 a))"));
+        var expectedTree = importer.Import("(* (* (variable 1.0 a) (variable 1.0 a)) 4.0)");
+        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
+      }
+      {
+        var actualTree = simplifier.Simplify(importer.Import("(/ (variable 1.0 a) (variable 2.0 a))"));
+        var expectedTree = importer.Import("0.5");
+        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
+      }
+      #endregion
       #region logarithm rules
       {
@@ -155,11 +182,11 @@
       {
         // log transformation
-        var actualTree = simplifier.Simplify(importer.Import("(log (* (variable 2.0 a) (variable 3.0 b))"));
-        var expectedTree = importer.Import("(+ (log (variable 2.0 a)) (log (variable 3.0 b)))");
+        var actualTree = simplifier.Simplify(importer.Import("(log (* (variable 2.0 a) (variable 3.0 b)))"));
+        var expectedTree = importer.Import("(+ (log (variable 1.0 a)) (log (variable 1.0 b)) 1.7918)");
         Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
       }
       {
         // log transformation
-        var actualTree = simplifier.Simplify(importer.Import("(log (/ (variable 2.0 a) (variable 3.0 b))"));
+        var actualTree = simplifier.Simplify(importer.Import("(log (/ (variable 2.0 a) (variable 3.0 b)))"));
         var expectedTree = importer.Import("(- (log (variable 2.0 a)) (log (variable 3.0 b)))");
         Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
@@ -194,5 +221,5 @@
         // constant not 
         var actualTree = simplifier.Simplify(importer.Import("(not -2.0)"));
-        var expectedTree = importer.Import("1.0");
+        var expectedTree = importer.Import("2.0");
         Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
       }
@@ -200,5 +227,5 @@
         // constant not 
         var actualTree = simplifier.Simplify(importer.Import("(not 2.0)"));
-        var expectedTree = importer.Import("-1.0");
+        var expectedTree = importer.Import("-2.0");
         Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
       }
@@ -206,5 +233,5 @@
         // constant not 
         var actualTree = simplifier.Simplify(importer.Import("(not 0.0)"));
-        var expectedTree = importer.Import("1.0");
+        var expectedTree = importer.Import("0.0");
         Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
       }
@@ -245,31 +272,4 @@
         var actualTree = simplifier.Simplify(importer.Import("(if (variable 1.0 a) (variable 2.0 a) (variable 3.0 a))"));
         var expectedTree = importer.Import("(if (> (variable 1.0 a) 0.0) (variable 2.0 a) (variable 3.0 a))");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      #endregion
-      #region constant and variable folding
-      {
-        var actualTree = simplifier.Simplify(importer.Import("(+ 1.0 2.0)"));
-        var expectedTree = importer.Import("3.0");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        var actualTree = simplifier.Simplify(importer.Import("(+ (variable 2.0 a) (variable 2.0 a))"));
-        var expectedTree = importer.Import("(variable 4.0 a)");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        var actualTree = simplifier.Simplify(importer.Import("(- (variable 2.0 a) (variable 1.0 a))"));
-        var expectedTree = importer.Import("(variable 1.0 a)");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        var actualTree = simplifier.Simplify(importer.Import("(* (variable 2.0 a) (variable 2.0 a))"));
-        var expectedTree = importer.Import("(* (* (variable 1.0 a) (variable 1.0 a)) 4.0)");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        var actualTree = simplifier.Simplify(importer.Import("(/ (variable 1.0 a) (variable 2.0 a))"));
-        var expectedTree = importer.Import("0.5");
         Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
       }
