Index: branches/MCTS-SymbReg-2796/Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/MctsSymbolicRegressionTest.cs
===================================================================
--- branches/MCTS-SymbReg-2796/Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/MctsSymbolicRegressionTest.cs	(revision 15439)
+++ branches/MCTS-SymbReg-2796/Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/MctsSymbolicRegressionTest.cs	(revision 15440)
@@ -374,5 +374,5 @@
     [TestCategory("Algorithms.DataAnalysis")]
     [TestProperty("Time", "short")]
-    public void ExprHashTest() {
+    public void ExprHashSymbolicTest() {
       int nParams;
       byte[] code;
@@ -386,5 +386,5 @@
         codeGen.Emit1(OpCodes.Exit);
         codeGen.GetCode(out code, out nParams);
-        var h1 = ExprHash.GetHash(code, nParams);
+        var h1 = ExprHashSymbolic.GetHash(code, nParams);
 
         codeGen = new CodeGenerator();
@@ -394,5 +394,5 @@
         codeGen.Emit1(OpCodes.Exit);
         codeGen.GetCode(out code, out nParams);
-        var h2 = ExprHash.GetHash(code, nParams);
+        var h2 = ExprHashSymbolic.GetHash(code, nParams);
 
         Assert.AreEqual(h1, h2);
@@ -407,5 +407,5 @@
         codeGen.Emit1(OpCodes.Exit);
         codeGen.GetCode(out code, out nParams);
-        var h1 = ExprHash.GetHash(code, nParams);
+        var h1 = ExprHashSymbolic.GetHash(code, nParams);
 
         codeGen = new CodeGenerator();
@@ -415,5 +415,5 @@
         codeGen.Emit1(OpCodes.Exit);
         codeGen.GetCode(out code, out nParams);
-        var h2 = ExprHash.GetHash(code, nParams);
+        var h2 = ExprHashSymbolic.GetHash(code, nParams);
 
         Assert.AreEqual(h1, h2);
@@ -430,5 +430,5 @@
         codeGen.Emit1(OpCodes.Exit);
         codeGen.GetCode(out code, out nParams);
-        var h1 = ExprHash.GetHash(code, nParams);
+        var h1 = ExprHashSymbolic.GetHash(code, nParams);
 
         codeGen = new CodeGenerator();
@@ -442,5 +442,5 @@
         codeGen.Emit1(OpCodes.Exit);
         codeGen.GetCode(out code, out nParams);
-        var h2 = ExprHash.GetHash(code, nParams);
+        var h2 = ExprHashSymbolic.GetHash(code, nParams);
 
         Assert.AreEqual(h1, h2);
@@ -448,6 +448,5 @@
 
 
-      {
-        // div 
+      { // 1/(x1x2) = 1/x1 * 1/x2
         var codeGen = new CodeGenerator();
         codeGen.Emit2(MctsSymbolicRegression.OpCodes.LoadVar, 1);
@@ -457,5 +456,5 @@
         codeGen.Emit1(OpCodes.Exit);
         codeGen.GetCode(out code, out nParams);
-        var h1 = ExprHash.GetHash(code, nParams);
+        var h1 = ExprHashSymbolic.GetHash(code, nParams);
 
         codeGen = new CodeGenerator();
@@ -467,5 +466,5 @@
         codeGen.Emit1(OpCodes.Exit);
         codeGen.GetCode(out code, out nParams);
-        var h2 = ExprHash.GetHash(code, nParams);
+        var h2 = ExprHashSymbolic.GetHash(code, nParams);
 
         Assert.AreEqual(h1, h2);
@@ -480,5 +479,5 @@
         codeGen.Emit1(OpCodes.Exit);
         codeGen.GetCode(out code, out nParams);
-        var h1 = ExprHash.GetHash(code, nParams);
+        var h1 = ExprHashSymbolic.GetHash(code, nParams);
 
         codeGen = new CodeGenerator();
@@ -490,5 +489,5 @@
         codeGen.GetCode(out code, out nParams);
         codeGen.Emit1(OpCodes.Exit);
-        var h2 = ExprHash.GetHash(code, nParams);
+        var h2 = ExprHashSymbolic.GetHash(code, nParams);
 
         Assert.AreEqual(h1, h2);
@@ -503,5 +502,5 @@
         codeGen.Emit1(OpCodes.Exit);
         codeGen.GetCode(out code, out nParams);
-        var h1 = ExprHash.GetHash(code, nParams);
+        var h1 = ExprHashSymbolic.GetHash(code, nParams);
 
         codeGen = new CodeGenerator();
@@ -513,5 +512,5 @@
         codeGen.Emit1(OpCodes.Exit);
         codeGen.GetCode(out code, out nParams);
-        var h2 = ExprHash.GetHash(code, nParams);
+        var h2 = ExprHashSymbolic.GetHash(code, nParams);
 
         Assert.AreEqual(h1, h2);
@@ -526,5 +525,5 @@
         codeGen.Emit1(OpCodes.Exit);
         codeGen.GetCode(out code, out nParams);
-        var h1 = ExprHash.GetHash(code, nParams);
+        var h1 = ExprHashSymbolic.GetHash(code, nParams);
 
         codeGen = new CodeGenerator();
@@ -532,5 +531,5 @@
         codeGen.Emit1(OpCodes.Exit);
         codeGen.GetCode(out code, out nParams);
-        var h2 = ExprHash.GetHash(code, nParams);
+        var h2 = ExprHashSymbolic.GetHash(code, nParams);
 
         Assert.AreEqual(h1, h2);
@@ -550,5 +549,5 @@
         codeGen.Emit1(OpCodes.Exit);
         codeGen.GetCode(out code, out nParams);
-        var h1 = ExprHash.GetHash(code, nParams);
+        var h1 = ExprHashSymbolic.GetHash(code, nParams);
 
         codeGen = new CodeGenerator();
@@ -558,10 +557,10 @@
         codeGen.Emit1(OpCodes.Exit);
         codeGen.GetCode(out code, out nParams);
-        var h2 = ExprHash.GetHash(code, nParams);
+        var h2 = ExprHashSymbolic.GetHash(code, nParams);
 
         Assert.AreEqual(h1, h2);
       }
 
-      {
+      { // c1 x1 + c2 x1 = c3 x1 (extended version)
         var codeGen = new CodeGenerator();
         codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst0);
@@ -582,5 +581,5 @@
         codeGen.Emit1(OpCodes.Exit);
         codeGen.GetCode(out code, out nParams);
-        var h1 = ExprHash.GetHash(code, nParams);
+        var h1 = ExprHashSymbolic.GetHash(code, nParams);
 
         codeGen = new CodeGenerator();
@@ -594,8 +593,167 @@
         codeGen.Emit1(OpCodes.Exit);
         codeGen.GetCode(out code, out nParams);
-        var h2 = ExprHash.GetHash(code, nParams);
+        var h2 = ExprHashSymbolic.GetHash(code, nParams);
 
         Assert.AreEqual(h1, h2);
       }
+      {
+        // exp(x1) * exp(x1) = exp(x1)
+        var codeGen = new CodeGenerator();
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst0);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadParamN);
+        codeGen.Emit2(MctsSymbolicRegression.OpCodes.LoadVar, 1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Exp);
+
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadParamN);
+        codeGen.Emit2(MctsSymbolicRegression.OpCodes.LoadVar, 1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Exp);
+
+        codeGen.Emit1(OpCodes.Mul);
+
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Add);
+
+        codeGen.Emit1(OpCodes.Exit);
+        codeGen.GetCode(out code, out nParams);
+        var h1 = ExprHashSymbolic.GetHash(code, nParams);
+
+        codeGen = new CodeGenerator();
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst0);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadParamN);
+        codeGen.Emit2(MctsSymbolicRegression.OpCodes.LoadVar, 1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Exp);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Add);
+        codeGen.Emit1(OpCodes.Exit);
+        codeGen.GetCode(out code, out nParams);
+        var h2 = ExprHashSymbolic.GetHash(code, nParams);
+
+        Assert.AreEqual(h1, h2);
+      }
+      {
+        // inv(x1) + inv(x1) != inv(x1)
+        var codeGen = new CodeGenerator();
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst0);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadParamN);
+        codeGen.Emit2(MctsSymbolicRegression.OpCodes.LoadVar, 1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Inv);
+
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadParamN);
+        codeGen.Emit2(MctsSymbolicRegression.OpCodes.LoadVar, 1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Inv);
+
+        codeGen.Emit1(OpCodes.Add);
+
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Add);
+
+        codeGen.Emit1(OpCodes.Exit);
+        codeGen.GetCode(out code, out nParams);
+        var h1 = ExprHashSymbolic.GetHash(code, nParams);
+
+        codeGen = new CodeGenerator();
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst0);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadParamN);
+        codeGen.Emit2(MctsSymbolicRegression.OpCodes.LoadVar, 1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Inv);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Add);
+        codeGen.Emit1(OpCodes.Exit);
+        codeGen.GetCode(out code, out nParams);
+        var h2 = ExprHashSymbolic.GetHash(code, nParams);
+
+        Assert.AreNotEqual(h1, h2);
+      }
+
+      {
+        // exp(x1) + exp(x1) != exp(x1)
+        var codeGen = new CodeGenerator();
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst0);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadParamN);
+        codeGen.Emit2(MctsSymbolicRegression.OpCodes.LoadVar, 1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Exp);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadParamN);
+        codeGen.Emit2(MctsSymbolicRegression.OpCodes.LoadVar, 1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Exp);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+
+        codeGen.Emit1(OpCodes.Add);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Add);
+
+        codeGen.Emit1(OpCodes.Exit);
+        codeGen.GetCode(out code, out nParams);
+        var h1 = ExprHashSymbolic.GetHash(code, nParams);
+
+        codeGen = new CodeGenerator();
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst0);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadParamN);
+        codeGen.Emit2(MctsSymbolicRegression.OpCodes.LoadVar, 1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Exp);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Add);
+        codeGen.Emit1(OpCodes.Exit);
+        codeGen.GetCode(out code, out nParams);
+        var h2 = ExprHashSymbolic.GetHash(code, nParams);
+
+        Assert.AreNotEqual(h1, h2);
+      }
+      {
+        // log(x1) + log(x1) != log(x1)
+        var codeGen = new CodeGenerator();
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst0);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadParamN);
+        codeGen.Emit2(MctsSymbolicRegression.OpCodes.LoadVar, 1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Log);
+
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadParamN);
+        codeGen.Emit2(MctsSymbolicRegression.OpCodes.LoadVar, 1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Log);
+
+        codeGen.Emit1(OpCodes.Add);
+
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Add);
+
+        codeGen.Emit1(OpCodes.Exit);
+        codeGen.GetCode(out code, out nParams);
+        var h1 = ExprHashSymbolic.GetHash(code, nParams);
+
+        codeGen = new CodeGenerator();
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst0);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadConst1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.LoadParamN);
+        codeGen.Emit2(MctsSymbolicRegression.OpCodes.LoadVar, 1);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Log);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Mul);
+        codeGen.Emit1(MctsSymbolicRegression.OpCodes.Add);
+        codeGen.Emit1(OpCodes.Exit);
+        codeGen.GetCode(out code, out nParams);
+        var h2 = ExprHashSymbolic.GetHash(code, nParams);
+
+        Assert.AreNotEqual(h1, h2);
+      }
+
     }
     #endregion
@@ -662,14 +820,14 @@
         // log(x + c) * exp(x)
         // log(x + c) * 1/(x + c)
-        // log(x + c) + log(x + c)                        // TODO
+        // log(x + c) + log(x + c)                        
         // log(x + c) + exp(x)
         // log(x + c) + 1/(x+c)
         //              -- 6
-        // exp(x) * 1/(x+c)
-        // exp(cx) + exp(cx)                              // TODO
+        // exp(cx) * 1/(x+c)
+        // exp(cx) + exp(cx)                              
         // exp(cx) + 1/(x+c)
         //              -- 3
-        // 1/(x+c) * 1/(x+c)                              // TODO
-        // 1/(x+c) + 1/(x+c)                              // TODO
+        // 1/(x+c) * 1/(x+c)                              
+        // 1/(x+c) + 1/(x+c)                              
         //              -- 2
         // log(x*x)
@@ -679,5 +837,5 @@
 
 
-        TestMctsNumberOfSolutions(regProblem, 2, 27);
+        TestMctsNumberOfSolutions(regProblem, 2, 25);
       }
       {
@@ -688,30 +846,22 @@
         //              -- 2
         // x * x
-        // x + x                                            ?
         // x * exp(x)
         // x + exp(x)
-        // exp(x) * exp(x)
-        // exp(x) + exp(x)                                  ?
+        // exp(x) + exp(x)
         // exp(x*x)
-        //              -- 7
+        //              -- 5
         // x * x * x
         // x + x * x                                       
-        // x + x + x                                        ?
         // x * x * exp(x)
         // x + x * exp(x)                                   
-        // x + x + exp(x)                                   ?
         // exp(x) + x*x
         // exp(x) + x*exp(x)                                
-        // x + exp(x) * exp(x)                              
-        // x + exp(x) + exp(x)                              ?
-        // x * exp(x) * exp(x)
+        // x + exp(x) + exp(x)                              
         // x * exp(x*x)
         // x + exp(x*x)
-        //              -- 13
-
-        // exp(x) * exp(x) * exp(x)
-        // exp(x) + exp(x) * exp(x)                         
-        // exp(x) + exp(x) + exp(x)                         ?
-        //              -- 3
+        //              -- 9
+
+        // exp(x) + exp(x) + exp(x)                         
+        //              -- 1
 
         // exp(x)   * exp(x*x)
@@ -720,5 +870,5 @@
         // exp(x*x*x)
         //              -- 1
-        TestMctsNumberOfSolutions(regProblem, 3, 2 + 7 + 13 + 3 + 2 + 1, allowLog: false, allowInv: false);
+        TestMctsNumberOfSolutions(regProblem, 3, 2+5+9+1+2+1, allowLog: false, allowInv: false);
       }      
     }
@@ -762,18 +912,18 @@
         // exp(y)
         //                  -- 4
-        // x (*|+) x
+        // x (*) x
         // x (*|+) exp(x)
         // x (*|+) y
         // x (*|+) exp(y)
-        //                  -- 8
-        // exp(x) (*|+) exp(x)
+        //                  -- 7
+        // exp(x) (+) exp(x)
         // exp(x) (*|+) exp(y)
-        //                  -- 4
-        // y (*|+) y
+        //                  -- 3
+        // y (*) y
         // y (*|+) exp(x)
         // y (*|+) exp(y)
-        //                  -- 6
-        // exp(y) (*|+) exp(y)
-        //                  -- 2
+        //                  -- 5
+        // exp(y) (+) exp(y)
+        //                  -- 1
         //
         // exp(x*x)
@@ -782,5 +932,5 @@
         //                  -- 3
 
-        TestMctsNumberOfSolutions(regProblem, 2, 4 + 8 + 4 + 6 + 2 + 3, allowLog: false, allowInv: false);
+        TestMctsNumberOfSolutions(regProblem, 2, 4 + 7 + 3 + 5 + 1 + 3, allowLog: false, allowInv: false);
       }
 
@@ -830,13 +980,8 @@
         // inv(y*y)
         //             -- 6
-        // log(x+x)
         // log(x+y)
-        // log(y+y)
-
-        // inv(x+x)
         // inv(x+y)
-        // inv(y+y)
-        //             -- 6
-        TestMctsNumberOfSolutions(regProblem, 2, 6 + 6 + 4 + 2 + 5 + 3 + 1 + 6 + 6, allowExp: false, allowSum: false);
+        //             -- 2
+        TestMctsNumberOfSolutions(regProblem, 2, 6 + 6 + 4 + 2 + 5 + 3 + 1 + 6 + 2, allowExp: false, allowSum: false);
       }
     }
