Index: branches/2521_ProblemRefactoring/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeSimplifierTest.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeSimplifierTest.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeSimplifierTest.cs	(revision 16692)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -19,9 +19,7 @@
  */
 #endregion
-
 using System;
-using System.Collections.Generic;
+using System.Globalization;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Problems.DataAnalysis.Symbolic;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 
@@ -36,319 +34,210 @@
     public void SimplifierAxiomsTest() {
       SymbolicExpressionImporter importer = new SymbolicExpressionImporter();
-      SymbolicDataAnalysisExpressionTreeSimplifier simplifier = new SymbolicDataAnalysisExpressionTreeSimplifier();
       SymbolicExpressionTreeStringFormatter formatter = new SymbolicExpressionTreeStringFormatter();
       #region single argument arithmetics
-      {
-        var actualTree = simplifier.Simplify(importer.Import("(+ 1.0)"));
-        var expectedTree = importer.Import("1.0");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        var actualTree = simplifier.Simplify(importer.Import("(+ (variable 2.0 a))"));
-        var expectedTree = importer.Import("(variable 2.0 a)");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        var actualTree = simplifier.Simplify(importer.Import("(- 1.0)"));
-        var expectedTree = importer.Import("-1.0");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        var actualTree = simplifier.Simplify(importer.Import("(- (variable 2.0 a))"));
-        var expectedTree = importer.Import("(variable -2.0 a)");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        var actualTree = simplifier.Simplify(importer.Import("(* 2.0)"));
-        var expectedTree = importer.Import("2.0");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        var actualTree = simplifier.Simplify(importer.Import("(* (variable 2.0 a))"));
-        var expectedTree = importer.Import("(variable 2.0 a)");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        var actualTree = simplifier.Simplify(importer.Import("(/ 2.0)"));
-        var expectedTree = importer.Import("0.5");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        var actualTree = simplifier.Simplify(importer.Import("(/ (variable 2.0 a))"));
-        var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      #endregion
+
+      AssertEqualAfterSimplification("(+ 1.0)", "1.0");
+      AssertEqualAfterSimplification("(- 1.0)", "-1.0");
+      AssertEqualAfterSimplification("(- (variable 2.0 a))", "(variable -2.0 a)");
+      AssertEqualAfterSimplification("(* 2.0)", "2.0");
+      AssertEqualAfterSimplification("(* (variable 2.0 a))", "(variable 2.0 a)");
+      AssertEqualAfterSimplification("(/ 2.0)", "0.5");
+      AssertEqualAfterSimplification("(/ (variable 2.0 a))", "(/ 1.0 (variable 2.0 a))");
+      #endregion
+
       #region aggregation of constants into factors
-      {
-        var actualTree = simplifier.Simplify(importer.Import("(* 2.0 (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) 2.0)"));
-        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) (* 2.0 2.0))"));
-        var expectedTree = importer.Import("(variable 0.5 a)");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      #endregion
+      AssertEqualAfterSimplification("(* 2.0 (variable 2.0 a))", "(variable 4.0 a)");
+      AssertEqualAfterSimplification("(/ (variable 2.0 a) 2.0)", "(variable 1.0 a)");
+      AssertEqualAfterSimplification("(/ (variable 2.0 a) (* 2.0 2.0))", "(variable 0.5 a)");
+      #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
+      AssertEqualAfterSimplification("(+ 1.0 2.0)", "3.0");
+      AssertEqualAfterSimplification("(+ (variable 2.0 a) (variable 2.0 a))", "(variable 4.0 a)");
+      AssertEqualAfterSimplification("(- (variable 2.0 a) (variable 1.0 a))", "(variable 1.0 a)");
+      AssertEqualAfterSimplification("(* (variable 2.0 a) (variable 2.0 a))", "(* (* (variable 1.0 a) (variable 1.0 a)) 4.0)");
+      AssertEqualAfterSimplification("(/ (variable 1.0 a) (variable 2.0 a))", "0.5");
+      #endregion
+
       #region logarithm rules
-      {
-        // cancellation
-        var actualTree = simplifier.Simplify(importer.Import("(log (exp (variable 2.0 a)))"));
-        var expectedTree = importer.Import("(variable 2.0 a)");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // must not transform logs in this way as we do not know wether both variables are positive
-        var actualTree = simplifier.Simplify(importer.Import("(log (* (variable 1.0 a) (variable 1.0 b)))"));
-        var expectedTree = importer.Import("(log (* (variable 1.0 a) (variable 1.0 b)))");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // must not transform logs in this way as we do not know wether both variables are positive
-        var actualTree = simplifier.Simplify(importer.Import("(log (/ (variable 1.0 a) (variable 1.0 b)))"));
-        var expectedTree = importer.Import("(log (/ (variable 1.0 a) (variable 1.0 b)))");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      #endregion
+
+      // cancellation
+      AssertEqualAfterSimplification("(log (exp (variable 2.0 a)))", "(variable 2.0 a)");
+      // must not transform logs in this way as we do not know wether both variables are positive
+      AssertEqualAfterSimplification("(log (* (variable 1.0 a) (variable 1.0 b)))", "(log (* (variable 1.0 a) (variable 1.0 b)))");
+      // must not transform logs in this way as we do not know wether both variables are positive
+      AssertEqualAfterSimplification("(log (/ (variable 1.0 a) (variable 1.0 b)))", "(log (/ (variable 1.0 a) (variable 1.0 b)))");
+      #endregion
+
       #region exponentiation rules
-      {
-        // cancellation
-        var actualTree = simplifier.Simplify(importer.Import("(exp (log (variable 2.0 a)))"));
-        var expectedTree = importer.Import("(variable 2.0 a)");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // exp transformation
-        var actualTree = simplifier.Simplify(importer.Import("(exp (+ (variable 2.0 a) (variable 3.0 b)))"));
-        var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (variable 3.0 b)))");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // exp transformation
-        var actualTree = simplifier.Simplify(importer.Import("(exp (- (variable 2.0 a) (variable 3.0 b)))"));
-        var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (variable -3.0 b)))");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // exp transformation
-        var actualTree = simplifier.Simplify(importer.Import("(exp (- (variable 2.0 a) (* (variable 3.0 b) (variable 4.0 c))))"));
-        var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (variable 1.0 c) -12.0)))");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // exp transformation
-        var actualTree = simplifier.Simplify(importer.Import("(exp (- (variable 2.0 a) (* (variable 3.0 b) (cos (variable 4.0 c)))))"));
-        var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (cos (variable 4.0 c)) -3.0)))");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      #endregion
+      // cancellation
+      AssertEqualAfterSimplification("(exp (log (variable 2.0 a)))", "(variable 2.0 a)");
+      // exp transformation
+      AssertEqualAfterSimplification("(exp (+ (variable 2.0 a) (variable 3.0 b)))", "(* (exp (variable 2.0 a)) (exp (variable 3.0 b)))");
+      // exp transformation
+      AssertEqualAfterSimplification("(exp (- (variable 2.0 a) (variable 3.0 b)))", "(* (exp (variable 2.0 a)) (exp (variable -3.0 b)))");
+      // exp transformation
+      AssertEqualAfterSimplification("(exp (- (variable 2.0 a) (* (variable 3.0 b) (variable 4.0 c))))", "(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (variable 1.0 c) -12.0)))");
+      // exp transformation
+      AssertEqualAfterSimplification("(exp (- (variable 2.0 a) (* (variable 3.0 b) (cos (variable 4.0 c)))))", "(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (cos (variable 4.0 c)) -3.0)))");
+      #endregion
+
       #region power rules
-      {
-        // cancellation
-        var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) 0.0)"));
-        var expectedTree = importer.Import("1.0");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // fixed point
-        var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) 1.0)"));
-        var expectedTree = importer.Import("(variable 2.0 a)");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // inversion fixed point
-        var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) -1.0)"));
-        var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // inversion 
-        var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) -2.0)"));
-        var expectedTree = importer.Import("(/ 1.0 (pow (variable 2.0 a) 2.0))");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // constant folding
-        var actualTree = simplifier.Simplify(importer.Import("(pow 3.0 2.0)"));
-        var expectedTree = importer.Import("9.0");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      #endregion
+
+      // cancellation
+      AssertEqualAfterSimplification("(pow (variable 2.0 a) 0.0)", "1.0");
+      // fixed point
+      AssertEqualAfterSimplification("(pow (variable 2.0 a) 1.0)", "(variable 2.0 a)");
+      // inversion fixed point
+      AssertEqualAfterSimplification("(pow (variable 2.0 a) -1.0)", "(/ 1.0 (variable 2.0 a))");
+      // inversion 
+      AssertEqualAfterSimplification("(pow (variable 2.0 a) -2.0)", "(/ 1.0 (pow (variable 2.0 a) 2.0))");
+      // constant folding
+      AssertEqualAfterSimplification("(pow 3.0 2.0)", "9.0");
+      #endregion
+
       #region root rules
-      {
-        // cancellation
-        var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) 0.0)"));
-        var expectedTree = importer.Import("1.0");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // fixed point
-        var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) 1.0)"));
-        var expectedTree = importer.Import("(variable 2.0 a)");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // inversion fixed point
-        var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) -1.0)"));
-        var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // inversion
-        var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) -2.0)"));
-        var expectedTree = importer.Import("(/ 1.0 (root (variable 2.0 a) 2.0))");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // constant folding
-        var actualTree = simplifier.Simplify(importer.Import("(root 9.0 2.0)"));
-        var expectedTree = importer.Import("3.0");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      #endregion
+      // cancellation
+      AssertEqualAfterSimplification("(root (variable 2.0 a) 0.0)", "1.0");
+      // fixed point
+      AssertEqualAfterSimplification("(root (variable 2.0 a) 1.0)", "(variable 2.0 a)");
+      // inversion fixed point
+      AssertEqualAfterSimplification("(root (variable 2.0 a) -1.0)", "(/ 1.0 (variable 2.0 a))");
+      // inversion
+      AssertEqualAfterSimplification("(root (variable 2.0 a) -2.0)", "(/ 1.0 (root (variable 2.0 a) 2.0))");
+      // constant folding
+      AssertEqualAfterSimplification("(root 9.0 2.0)", "3.0");
+      #endregion
+
       #region boolean operations
-      {
-        // always true and
-        var actualTree = simplifier.Simplify(importer.Import("(and 1.0 2.0)"));
-        var expectedTree = importer.Import("1.0");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // always false and
-        var actualTree = simplifier.Simplify(importer.Import("(and 1.0 -2.0)"));
-        var expectedTree = importer.Import("-1.0");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // always true or
-        var actualTree = simplifier.Simplify(importer.Import("(or -1.0 2.0)"));
-        var expectedTree = importer.Import("1.0");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // always false or
-        var actualTree = simplifier.Simplify(importer.Import("(or -1.0 -2.0)"));
-        var expectedTree = importer.Import("-1.0");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // constant not 
-        var actualTree = simplifier.Simplify(importer.Import("(not -2.0)"));
-        var expectedTree = importer.Import("1.0");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // constant not 
-        var actualTree = simplifier.Simplify(importer.Import("(not 2.0)"));
-        var expectedTree = importer.Import("-1.0");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // constant not 
-        var actualTree = simplifier.Simplify(importer.Import("(not 0.0)"));
-        var expectedTree = importer.Import("1.0");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // nested nots
-        var actualTree = simplifier.Simplify(importer.Import("(not (not 1.0))"));
-        var expectedTree = importer.Import("1.0");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // not of non-Boolean argument
-        var actualTree = simplifier.Simplify(importer.Import("(not (variable 1.0 a))"));
-        var expectedTree = importer.Import("(not (> (variable 1.0 a) 0.0))");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // not Boolean argument
-        var actualTree = simplifier.Simplify(importer.Import("(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))"));
-        var expectedTree = importer.Import("(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      #endregion
+      // always true and
+      AssertEqualAfterSimplification("(and 1.0 2.0)", "1.0");
+      // always false and
+      AssertEqualAfterSimplification("(and 1.0 -2.0)", "-1.0");
+      // always true or
+      AssertEqualAfterSimplification("(or -1.0 2.0)", "1.0");
+      // always false or
+      AssertEqualAfterSimplification("(or -1.0 -2.0)", "-1.0");
+      // constant not 
+      AssertEqualAfterSimplification("(not -2.0)", "1.0");
+      // constant not 
+      AssertEqualAfterSimplification("(not 2.0)", "-1.0");
+      // constant not 
+      AssertEqualAfterSimplification("(not 0.0)", "1.0");
+      // nested nots
+      AssertEqualAfterSimplification("(not (not 1.0))", "1.0");
+      // not of non-Boolean argument
+      AssertEqualAfterSimplification("(not (variable 1.0 a))", "(not (> (variable 1.0 a) 0.0))");
+      // not Boolean argument
+      AssertEqualAfterSimplification("(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))", "(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))");
+      #endregion
+
       #region conditionals
-      {
-        // always false
-        var actualTree = simplifier.Simplify(importer.Import("(if -1.0 (variable 2.0 a) (variable 3.0 a))"));
-        var expectedTree = importer.Import("(variable 3.0 a)");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // always true
-        var actualTree = simplifier.Simplify(importer.Import("(if 1.0 (variable 2.0 a) (variable 3.0 a))"));
-        var expectedTree = importer.Import("(variable 2.0 a)");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // always false (0.0)
-        var actualTree = simplifier.Simplify(importer.Import("(if 0.0 (variable 2.0 a) (variable 3.0 a))"));
-        var expectedTree = importer.Import("(variable 3.0 a)");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // complex constant condition (always false)
-        var actualTree = simplifier.Simplify(importer.Import("(if (* 1.0 -2.0) (variable 2.0 a) (variable 3.0 a))"));
-        var expectedTree = importer.Import("(variable 3.0 a)");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // complex constant condition (always false)
-        var actualTree = simplifier.Simplify(importer.Import("(if (/ (variable 1.0 a) (variable -2.0 a)) (variable 2.0 a) (variable 3.0 a))"));
-        var expectedTree = importer.Import("(variable 3.0 a)");
-        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
-      }
-      {
-        // insertion of relational operator
-        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));
-      }
+      // always false
+      AssertEqualAfterSimplification("(if -1.0 (variable 2.0 a) (variable 3.0 a))", "(variable 3.0 a)");
+      // always true
+      AssertEqualAfterSimplification("(if 1.0 (variable 2.0 a) (variable 3.0 a))", "(variable 2.0 a)");
+      // always false (0.0)
+      AssertEqualAfterSimplification("(if 0.0 (variable 2.0 a) (variable 3.0 a))", "(variable 3.0 a)");
+      // complex constant condition (always false)
+      AssertEqualAfterSimplification("(if (* 1.0 -2.0) (variable 2.0 a) (variable 3.0 a))", "(variable 3.0 a)");
+      // complex constant condition (always false)
+      AssertEqualAfterSimplification("(if (/ (variable 1.0 a) (variable -2.0 a)) (variable 2.0 a) (variable 3.0 a))", "(variable 3.0 a)");
+      // insertion of relational operator
+      AssertEqualAfterSimplification("(if (variable 1.0 a) (variable 2.0 a) (variable 3.0 a))", "(if (> (variable 1.0 a) 0.0) (variable 2.0 a) (variable 3.0 a))");
+      #endregion
+
+      #region factor variables
+      AssertEqualAfterSimplification("(factor a 1.0)", "(factor a 1.0)");
+      // factor folding
+      AssertEqualAfterSimplification("(+ (factor a 1.0 1.0) (factor a 2.0 3.0))", "(factor a 3.0 4.0)");
+      AssertEqualAfterSimplification("(- (factor a 1.0 1.0) (factor a 2.0 3.0))", "(factor a -1.0 -2.0)");
+      AssertEqualAfterSimplification("(* (factor a 2.0 2.0) (factor a 2.0 3.0))", "(factor a 4.0 6.0)");
+      AssertEqualAfterSimplification("(/ (factor a 2.0 5.0))", "(factor a 0.5 0.2)");
+      AssertEqualAfterSimplification("(/ (factor a 4.0 6.0) (factor a 2.0 3.0))", "(factor a 2.0 2.0)");
+      AssertEqualAfterSimplification("(+ 3.0 (factor a 4.0 6.0))", "(factor a 7.0 9.0)");
+      AssertEqualAfterSimplification("(+ (factor a 4.0 6.0) 3.0)", "(factor a 7.0 9.0)");
+      AssertEqualAfterSimplification("(- 3.0 (factor a 4.0 6.0))", "(factor a -1.0 -3.0)");
+      AssertEqualAfterSimplification("(- (factor a 4.0 6.0) 3.0)", "(factor a 1.0 3.0)");
+      AssertEqualAfterSimplification("(* 2.0 (factor a 4.0 6.0))", "(factor a 8.0 12.0)");
+      AssertEqualAfterSimplification("(* (factor a 4.0 6.0) 2.0)", "(factor a 8.0 12.0)");
+      AssertEqualAfterSimplification("(* (factor a 4.0 6.0) (variable 2.0 a))", "(* (factor a 8.0 12.0) (variable 1.0 a))"); // not possible (a is used as factor and double variable) interpreter will fail
+      AssertEqualAfterSimplification(
+        "(log (factor a 10.0 100.0))",
+        string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1})", Math.Log(10.0), Math.Log(100.0)));
+      AssertEqualAfterSimplification(
+        "(exp (factor a 2.0 3.0))",
+        string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1})", Math.Exp(2.0), Math.Exp(3.0)));
+      AssertEqualAfterSimplification("(sqrt (factor a 9.0 16.0))", "(factor a 3.0 4.0))");
+      AssertEqualAfterSimplification("(sqr (factor a 2.0 3.0))", "(factor a 4.0 9.0))");
+      AssertEqualAfterSimplification("(root (factor a 8.0 27.0) 3)", "(factor a 2.0 3.0))");
+      AssertEqualAfterSimplification("(pow (factor a 2.0 3.0) 3)", "(factor a 8.0 27.0))");
+
+      AssertEqualAfterSimplification("(sin (factor a 1.0 2.0) )",
+        string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1}))", Math.Sin(1.0), Math.Sin(2.0)));
+      AssertEqualAfterSimplification("(cos (factor a 1.0 2.0) )",
+        string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1}))", Math.Cos(1.0), Math.Cos(2.0)));
+      AssertEqualAfterSimplification("(tan (factor a 1.0 2.0) )",
+        string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1}))", Math.Tan(1.0), Math.Tan(2.0)));
+
+
+      AssertEqualAfterSimplification("(binfactor a val 1.0)", "(binfactor a val 1.0)");
+      // binfactor folding
+      AssertEqualAfterSimplification("(+ (binfactor a val 1.0) (binfactor a val 2.0))", "(binfactor a val 3.0)");
+      AssertEqualAfterSimplification("(+ (binfactor a val0 1.0) (binfactor a val1 2.0))", "(+ (binfactor a val0 1.0) (binfactor a val1 2.0))"); // cannot be simplified (different vals)
+      AssertEqualAfterSimplification("(+ (binfactor a val 1.0) (binfactor b val 2.0))", "(+ (binfactor a val 1.0) (binfactor b val 2.0))"); // cannot be simplified (different vars)
+      AssertEqualAfterSimplification("(- (binfactor a val 1.0) (binfactor a val 2.0))", "(binfactor a val -1.0)");
+      AssertEqualAfterSimplification("(* (binfactor a val 2.0) (binfactor a val 3.0))", "(binfactor a val 6.0)");
+      AssertEqualAfterSimplification("(/ (binfactor a val 6.0) (binfactor a val 3.0))", "(/ (binfactor a val 6.0) (binfactor a val 3.0))"); // not allowed! 0/0 for other values than 'val'
+      AssertEqualAfterSimplification("(/ (binfactor a val 4.0))", "(/ 1.0 (binfactor a val 4.0))"); // not allowed!
+
+      AssertEqualAfterSimplification("(+ 3.0 (binfactor a val 4.0 ))", "(+ (binfactor a val 4.0 ) 3.0))"); // not allowed
+      AssertEqualAfterSimplification("(- 3.0 (binfactor a val 4.0 ))", "(+ (binfactor a val -4.0 ) 3.0)"); 
+      AssertEqualAfterSimplification("(+ (binfactor a val 4.0 ) 3.0)", "(+ (binfactor a val 4.0 ) 3.0)");  // not allowed
+      AssertEqualAfterSimplification("(- (binfactor a val 4.0 ) 3.0)", "(+ (binfactor a val 4.0 ) -3.0)"); 
+      AssertEqualAfterSimplification("(* 2.0 (binfactor a val 4.0))", "(binfactor a val 8.0 )");
+      AssertEqualAfterSimplification("(* (binfactor a val 4.0) 2.0)", "(binfactor a val 8.0 )");
+      AssertEqualAfterSimplification("(* (binfactor a val 4.0) (variable 2.0 a))", "(* (binfactor a val 1.0) (variable 1.0 a) 8.0)");   // not possible (a is used as factor and double variable) interpreter will fail
+      AssertEqualAfterSimplification("(log (binfactor a val 10.0))", "(log (binfactor a val 10.0))"); // not allowed (log(0))
+
+      // exp( binfactor w val=a) = if(val=a) exp(w) else exp(0) = binfactor( (exp(w) - 1) val a) + 1
+      AssertEqualAfterSimplification("(exp (binfactor a val 3.0))", 
+        string.Format(CultureInfo.InvariantCulture, "(+ (binfactor a val {0}) 1.0)", Math.Exp(3.0) - 1)
+        ); 
+      AssertEqualAfterSimplification("(sqrt (binfactor a val 16.0))", "(binfactor a val 4.0))"); // sqrt(0) = 0
+      AssertEqualAfterSimplification("(sqr (binfactor a val 3.0))", "(binfactor a val 9.0))"); // 0*0 = 0
+      AssertEqualAfterSimplification("(root (binfactor a val 27.0) 3)", "(binfactor a val 3.0))");
+      AssertEqualAfterSimplification("(pow (binfactor a val 3.0) 3)", "(binfactor a val 27.0))");
+
+      AssertEqualAfterSimplification("(sin (binfactor a val 2.0) )",
+        string.Format(CultureInfo.InvariantCulture, "(binfactor a val {0}))", Math.Sin(2.0))); // sin(0) = 0
+      AssertEqualAfterSimplification("(cos (binfactor a val 2.0) )", 
+        string.Format(CultureInfo.InvariantCulture, "(+ (binfactor a val {0}) 1.0)", Math.Cos(2.0) - 1)); // cos(0) = 1
+      AssertEqualAfterSimplification("(tan (binfactor a val 2.0) )",
+        string.Format(CultureInfo.InvariantCulture, "(binfactor a val {0}))", Math.Tan(2.0))); // tan(0) = 0
+
+      // combination of factor and binfactor
+      AssertEqualAfterSimplification("(+ (binfactor a x0 2.0) (factor a 2.0 3.0))", "(factor a 4.0 3.0)");
+      AssertEqualAfterSimplification("(+ (factor a 2.0 3.0) (binfactor a x0 2.0))", "(factor a 4.0 3.0)");
+      AssertEqualAfterSimplification("(* (binfactor a x1 2.0) (factor a 2.0 3.0))", "(binfactor a x1 6.0)"); // all other values have weight zero in binfactor
+      AssertEqualAfterSimplification("(* (factor a 2.0 3.0) (binfactor a x1 2.0))", "(binfactor a x1 6.0)"); // all other values have weight zero in binfactor
+      AssertEqualAfterSimplification("(/ (binfactor a x0 2.0) (factor a 2.0 3.0))", "(binfactor a x0 1.0)");
+      AssertEqualAfterSimplification("(/ (factor a 2.0 3.0) (binfactor a x0 2.0))",
+        string.Format(CultureInfo.InvariantCulture, "(factor a 1.0 {0})", 3.0 / 0.0));
+      AssertEqualAfterSimplification("(- (binfactor a x0 2.0) (factor a 2.0 3.0))", "(factor a 0.0 -3.0)");
+      AssertEqualAfterSimplification("(- (factor a 2.0 3.0) (binfactor a x0 2.0))", "(factor a 0.0 3.0)");
       #endregion
     }
 
-    private void AssertEqualEnumerations(IEnumerable<double> expected, IEnumerable<double> actual) {
-      var expectedEnumerator = expected.GetEnumerator();
-      var actualEnumerator = actual.GetEnumerator();
-      while (expectedEnumerator.MoveNext() & actualEnumerator.MoveNext()) {
-        Assert.AreEqual(expectedEnumerator.Current, actualEnumerator.Current, Math.Abs(1E-6 * expectedEnumerator.Current));
-      }
-      if (expectedEnumerator.MoveNext() | actualEnumerator.MoveNext())
-        Assert.Fail("Number of elements in enumerations do not match");
+
+    private void AssertEqualAfterSimplification(string original, string expected) {
+      var formatter = new SymbolicExpressionTreeStringFormatter();
+      var importer = new SymbolicExpressionImporter();
+      var actualTree = TreeSimplifier.Simplify(importer.Import(original));
+      var expectedTree = importer.Import(expected);
+      Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
+
     }
   }
 }
+
