Index: branches/3073_IA_constraint_splitting/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs
===================================================================
--- branches/3073_IA_constraint_splitting/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs	(revision 17757)
+++ branches/3073_IA_constraint_splitting/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs	(revision 17758)
@@ -312,262 +312,263 @@
         return 0;
       }
-
-      public static Interval EvaluateRecursive(
-        Instruction[] instructions,
-        IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals,
-        IDictionary<string, Interval> variableIntervals, IList<string> variables,
-        double minWidth, int maxDepth, ref int currIndex, ref int currDepth,
-        ISymbolicExpressionTree tree) {
-        Interval evaluate() {
-          var ic = 0;
-          IReadOnlyDictionary<string, Interval> readonlyRanges =
-            new ReadOnlyDictionary<string, Interval>(variableIntervals);
-          return Evaluate(instructions, ref ic, nodeIntervals, readonlyRanges);
+    }
+
+    public static Interval EvaluateRecursive(
+      Instruction[] instructions,
+      IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals,
+      IDictionary<string, Interval> variableIntervals, IList<string> variables,
+      double minWidth, int maxDepth, ref int currIndex, ref int currDepth,
+      ISymbolicExpressionTree tree) {
+      Interval evaluate() {
+        var ic = 0;
+        IReadOnlyDictionary<string, Interval> readonlyRanges =
+          new ReadOnlyDictionary<string, Interval>(variableIntervals);
+        return Evaluate(instructions, ref ic, nodeIntervals, readonlyRanges);
+      }
+
+      Interval recurse(ref int idx, ref int depth) {
+        return EvaluateRecursive(instructions, nodeIntervals, variableIntervals, variables, minWidth, maxDepth, ref idx,
+          ref depth, tree);
+      }
+
+
+      var v = variables[currIndex];
+      var x = variableIntervals[v];
+      if (x.Width < minWidth || currDepth == maxDepth || !MultipleTimes(tree, v)) {
+        if (currIndex + 1 < variables.Count) {
+          currDepth = 0;
+          currIndex++;
+          var z = recurse(ref currIndex, ref currDepth);
+          currIndex--;
+          return z;
         }
 
-        Interval recurse(ref int idx, ref int depth) {
-          return EvaluateRecursive(instructions, nodeIntervals, variableIntervals, variables, minWidth, maxDepth, ref idx,
-            ref depth, tree);
-        }
-
-
-        var v = variables[currIndex];
-        var x = variableIntervals[v];
-        if (x.Width < minWidth || currDepth == maxDepth || !MultipleTimes(tree, v)) {
-          if (currIndex + 1 < variables.Count) {
-            currDepth = 0;
-            currIndex++;
-            var z = recurse(ref currIndex, ref currDepth);
-            currIndex--;
-            return z;
-          }
-
-          return evaluate();
-        }
-
-        var t = x.Split();
-        var xa = t.Item1;
-        var xb = t.Item2;
-        var d = currDepth;
-        currDepth = d + 1;
-        variableIntervals[v] = xa;
-        var ya = recurse(ref currIndex, ref currDepth);
-        currDepth = d + 1;
-        variableIntervals[v] = xb;
-        var yb = recurse(ref currIndex, ref currDepth);
-        variableIntervals[v] = x; // restore interval
-        return ya | yb;
-      }
-
-      public static Interval Evaluate(
-        Instruction[] instructions, ref int instructionCounter,
-        IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals = null,
-        IReadOnlyDictionary<string, Interval> variableIntervals = null) {
-        var currentInstr = instructions[instructionCounter];
-        //Use ref parameter, because the tree will be iterated through recursively from the left-side branch to the right side
-        //Update instructionCounter, whenever Evaluate is called
-        instructionCounter++;
-        Interval result = null;
-
-        switch (currentInstr.opCode) {
-          //Variables, Constants, ...
-          case OpCodes.Variable: {
-              var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode;
-              var weightInterval = new Interval(variableTreeNode.Weight, variableTreeNode.Weight);
-              //var variableInterval = (Interval)currentInstr.data;
-
-              Interval variableInterval;
-              if (variableIntervals != null && variableIntervals.ContainsKey(variableTreeNode.VariableName))
-                variableInterval = variableIntervals[variableTreeNode.VariableName];
-              else
-                variableInterval = (Interval)currentInstr.data;
-
-              result = Interval.Multiply(variableInterval, weightInterval);
-              break;
-            }
-          case OpCodes.Constant: {
-              var constTreeNode = (ConstantTreeNode)currentInstr.dynamicNode;
-              result = new Interval(constTreeNode.Value, constTreeNode.Value);
-              break;
-            }
-          //Elementary arithmetic rules
-          case OpCodes.Add: {
-              //result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-              for (var i = 1; i < currentInstr.nArguments; i++) {
-                //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-                var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-                result = Interval.Add(result, argumentInterval);
-              }
-
-              break;
-            }
-          case OpCodes.Sub: {
-              //result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-              if (currentInstr.nArguments == 1)
-                result = Interval.Multiply(new Interval(-1, -1), result);
-
-              for (var i = 1; i < currentInstr.nArguments; i++) {
-                //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-                var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-                result = Interval.Subtract(result, argumentInterval);
-              }
-
-              break;
-            }
-          case OpCodes.Mul: {
-              //result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-              for (var i = 1; i < currentInstr.nArguments; i++) {
-                var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-                //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-                result = Interval.Multiply(result, argumentInterval);
-              }
-
-              break;
-            }
-          case OpCodes.Div: {
-              //result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-              if (currentInstr.nArguments == 1)
-                result = Interval.Divide(new Interval(1, 1), result);
-
-              for (var i = 1; i < currentInstr.nArguments; i++) {
-                //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-                var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-                result = Interval.Divide(result, argumentInterval);
-              }
-
-              break;
-            }
-          //Trigonometric functions
-          case OpCodes.Sin: {
+        return evaluate();
+      }
+
+      var t = x.Split();
+      var xa = t.Item1;
+      var xb = t.Item2;
+      var d = currDepth;
+      currDepth = d + 1;
+      variableIntervals[v] = xa;
+      var ya = recurse(ref currIndex, ref currDepth);
+      currDepth = d + 1;
+      variableIntervals[v] = xb;
+      var yb = recurse(ref currIndex, ref currDepth);
+      variableIntervals[v] = x; // restore interval
+      return ya | yb;
+    }
+
+    public static Interval Evaluate(
+      Instruction[] instructions, ref int instructionCounter,
+      IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals = null,
+      IReadOnlyDictionary<string, Interval> variableIntervals = null) {
+      var currentInstr = instructions[instructionCounter];
+      //Use ref parameter, because the tree will be iterated through recursively from the left-side branch to the right side
+      //Update instructionCounter, whenever Evaluate is called
+      instructionCounter++;
+      Interval result = null;
+
+      switch (currentInstr.opCode) {
+        //Variables, Constants, ...
+        case OpCodes.Variable: {
+            var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode;
+            var weightInterval = new Interval(variableTreeNode.Weight, variableTreeNode.Weight);
+            //var variableInterval = (Interval)currentInstr.data;
+
+            Interval variableInterval;
+            if (variableIntervals != null && variableIntervals.ContainsKey(variableTreeNode.VariableName))
+              variableInterval = variableIntervals[variableTreeNode.VariableName];
+            else
+              variableInterval = (Interval)currentInstr.data;
+
+            result = Interval.Multiply(variableInterval, weightInterval);
+            break;
+          }
+        case OpCodes.Constant: {
+            var constTreeNode = (ConstantTreeNode)currentInstr.dynamicNode;
+            result = new Interval(constTreeNode.Value, constTreeNode.Value);
+            break;
+          }
+        //Elementary arithmetic rules
+        case OpCodes.Add: {
+            //result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
+            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
+            for (var i = 1; i < currentInstr.nArguments; i++) {
               //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-              result = Interval.Sine(argumentInterval);
-              break;
+              result = Interval.Add(result, argumentInterval);
             }
-          case OpCodes.Cos: {
+
+            break;
+          }
+        case OpCodes.Sub: {
+            //result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
+            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
+            if (currentInstr.nArguments == 1)
+              result = Interval.Multiply(new Interval(-1, -1), result);
+
+            for (var i = 1; i < currentInstr.nArguments; i++) {
               //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-              result = Interval.Cosine(argumentInterval);
-              break;
+              result = Interval.Subtract(result, argumentInterval);
             }
-          case OpCodes.Tan: {
+
+            break;
+          }
+        case OpCodes.Mul: {
+            //result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
+            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
+            for (var i = 1; i < currentInstr.nArguments; i++) {
+              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
+              //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
+              result = Interval.Multiply(result, argumentInterval);
+            }
+
+            break;
+          }
+        case OpCodes.Div: {
+            //result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
+            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
+            if (currentInstr.nArguments == 1)
+              result = Interval.Divide(new Interval(1, 1), result);
+
+            for (var i = 1; i < currentInstr.nArguments; i++) {
               //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-              result = Interval.Tangens(argumentInterval);
-              break;
+              result = Interval.Divide(result, argumentInterval);
             }
-          case OpCodes.Tanh: {
+
+            break;
+          }
+        //Trigonometric functions
+        case OpCodes.Sin: {
+            //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
+            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
+            result = Interval.Sine(argumentInterval);
+            break;
+          }
+        case OpCodes.Cos: {
+            //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
+            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
+            result = Interval.Cosine(argumentInterval);
+            break;
+          }
+        case OpCodes.Tan: {
+            //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
+            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
+            result = Interval.Tangens(argumentInterval);
+            break;
+          }
+        case OpCodes.Tanh: {
+            //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
+            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
+            result = Interval.HyperbolicTangent(argumentInterval);
+            break;
+          }
+        //Exponential functions
+        case OpCodes.Log: {
+            //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
+            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
+            result = Interval.Logarithm(argumentInterval);
+            break;
+          }
+        case OpCodes.Exp: {
+            //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
+            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
+            result = Interval.Exponential(argumentInterval);
+            break;
+          }
+        case OpCodes.Square: {
+            //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
+            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
+            result = Interval.Square(argumentInterval);
+            break;
+          }
+        case OpCodes.SquareRoot: {
+            //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
+            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
+            result = Interval.SquareRoot(argumentInterval);
+            break;
+          }
+        case OpCodes.Cube: {
+            //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
+            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
+            result = Interval.Cube(argumentInterval);
+            break;
+          }
+        case OpCodes.CubeRoot: {
+            //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
+            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
+            result = Interval.CubicRoot(argumentInterval);
+            break;
+          }
+        case OpCodes.Absolute: {
+            //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
+            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
+            result = Interval.Absolute(argumentInterval);
+            break;
+          }
+        case OpCodes.AnalyticQuotient: {
+            //result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
+            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
+            for (var i = 1; i < currentInstr.nArguments; i++) {
               //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-              result = Interval.HyperbolicTangent(argumentInterval);
-              break;
+              result = Interval.AnalyticalQuotient(result, argumentInterval);
             }
-          //Exponential functions
-          case OpCodes.Log: {
-              //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-              result = Interval.Logarithm(argumentInterval);
-              break;
-            }
-          case OpCodes.Exp: {
-              //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-              result = Interval.Exponential(argumentInterval);
-              break;
-            }
-          case OpCodes.Square: {
-              //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-              result = Interval.Square(argumentInterval);
-              break;
-            }
-          case OpCodes.SquareRoot: {
-              //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-              result = Interval.SquareRoot(argumentInterval);
-              break;
-            }
-          case OpCodes.Cube: {
-              //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-              result = Interval.Cube(argumentInterval);
-              break;
-            }
-          case OpCodes.CubeRoot: {
-              //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-              result = Interval.CubicRoot(argumentInterval);
-              break;
-            }
-          case OpCodes.Absolute: {
-              //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-              result = Interval.Absolute(argumentInterval);
-              break;
-            }
-          case OpCodes.AnalyticQuotient: {
-              //result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-              for (var i = 1; i < currentInstr.nArguments; i++) {
-                //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-                var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
-                result = Interval.AnalyticalQuotient(result, argumentInterval);
-              }
-
-              break;
-            }
-          default:
-            throw new NotSupportedException($"The tree contains the unknown symbol {currentInstr.dynamicNode.Symbol}");
-        }
-
-        if (!(nodeIntervals == null || nodeIntervals.ContainsKey(currentInstr.dynamicNode)))
-          nodeIntervals.Add(currentInstr.dynamicNode, result);
-
-        return result;
-      }
-
-      private static bool MultipleTimes(ISymbolicExpressionTree tree, string variable) {
-        var varlist = tree.IterateNodesPrefix().OfType<VariableTreeNode>().GroupBy(x => x.VariableName);
-        var group = varlist.Select(x => x.Key == variable).Count();
-
-        return group > 1;
-      }
-
-      private static bool ContainsVariableMultipleTimes(ISymbolicExpressionTree tree) {
-        var varlist = tree.IterateNodesPrefix().OfType<VariableTreeNode>().GroupBy(x => x.VariableName);
-        return varlist.Any(group => group.Count() > 1);
-      }
-
-
-      public static bool IsCompatible(ISymbolicExpressionTree tree) {
-        var containsUnknownSymbols = (
-          from n in tree.Root.GetSubtree(0).IterateNodesPrefix()
-          where
-            !(n.Symbol is Variable) &&
-            !(n.Symbol is Constant) &&
-            !(n.Symbol is StartSymbol) &&
-            !(n.Symbol is Addition) &&
-            !(n.Symbol is Subtraction) &&
-            !(n.Symbol is Multiplication) &&
-            !(n.Symbol is Division) &&
-            !(n.Symbol is Sine) &&
-            !(n.Symbol is Cosine) &&
-            !(n.Symbol is Tangent) &&
-            !(n.Symbol is HyperbolicTangent) &&
-            !(n.Symbol is Logarithm) &&
-            !(n.Symbol is Exponential) &&
-            !(n.Symbol is Square) &&
-            !(n.Symbol is SquareRoot) &&
-            !(n.Symbol is Cube) &&
-            !(n.Symbol is CubeRoot) &&
-            !(n.Symbol is Absolute) &&
-            !(n.Symbol is AnalyticQuotient)
-          select n).Any();
-        return !containsUnknownSymbols;
-      }
+
+            break;
+          }
+        default:
+          throw new NotSupportedException($"The tree contains the unknown symbol {currentInstr.dynamicNode.Symbol}");
+      }
+
+      if (!(nodeIntervals == null || nodeIntervals.ContainsKey(currentInstr.dynamicNode)))
+        nodeIntervals.Add(currentInstr.dynamicNode, result);
+
+      return result;
+    }
+
+    private static bool MultipleTimes(ISymbolicExpressionTree tree, string variable) {
+      var varlist = tree.IterateNodesPrefix().OfType<VariableTreeNode>().GroupBy(x => x.VariableName);
+      var group = varlist.Select(x => x.Key == variable).Count();
+
+      return group > 1;
+    }
+
+    private static bool ContainsVariableMultipleTimes(ISymbolicExpressionTree tree) {
+      var varlist = tree.IterateNodesPrefix().OfType<VariableTreeNode>().GroupBy(x => x.VariableName);
+      return varlist.Any(group => group.Count() > 1);
+    }
+
+
+    public static bool IsCompatible(ISymbolicExpressionTree tree) {
+      var containsUnknownSymbols = (
+        from n in tree.Root.GetSubtree(0).IterateNodesPrefix()
+        where
+          !(n.Symbol is Variable) &&
+          !(n.Symbol is Constant) &&
+          !(n.Symbol is StartSymbol) &&
+          !(n.Symbol is Addition) &&
+          !(n.Symbol is Subtraction) &&
+          !(n.Symbol is Multiplication) &&
+          !(n.Symbol is Division) &&
+          !(n.Symbol is Sine) &&
+          !(n.Symbol is Cosine) &&
+          !(n.Symbol is Tangent) &&
+          !(n.Symbol is HyperbolicTangent) &&
+          !(n.Symbol is Logarithm) &&
+          !(n.Symbol is Exponential) &&
+          !(n.Symbol is Square) &&
+          !(n.Symbol is SquareRoot) &&
+          !(n.Symbol is Cube) &&
+          !(n.Symbol is CubeRoot) &&
+          !(n.Symbol is Absolute) &&
+          !(n.Symbol is AnalyticQuotient)
+        select n).Any();
+      return !containsUnknownSymbols;
     }
   }
+}
