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 17630)
+++ /branches/3073_IA_constraint_splitting/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs	(revision 17631)
@@ -1,3 +1,4 @@
 ﻿#region License Information
+
 /* HeuristicLab
  * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
@@ -18,4 +19,5 @@
  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
  */
+
 #endregion
 
@@ -23,4 +25,5 @@
 using System.Collections.Generic;
 using System.Linq;
+using System.Runtime.Remoting.Contexts;
 using HEAL.Attic;
 using HeuristicLab.Common;
@@ -32,10 +35,37 @@
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
   [StorableType("DE6C1E1E-D7C1-4070-847E-63B68562B10C")]
-  [Item("IntervalInterpreter", "Intperter for calculation of intervals of symbolic models.")]
+  [Item("IntervalInterpreter", "Interpreter for calculation of intervals of symbolic models.")]
   public sealed class IntervalInterpreter : ParameterizedNamedItem, IStatefulItem {
-
     private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
-
-    public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter => (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName];
+    private const string MinSplittingWidthParameterName = "MinSplittingWidth";
+    private const string MaxSplittingDepthParameterName = "MaxSplittingDepth";
+    private const string UseIntervalSplittingParameterName = "UseIntervalSplitting";
+
+    public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter =>
+      (IFixedValueParameter<IntValue>) Parameters[EvaluatedSolutionsParameterName];
+
+    public IFixedValueParameter<IntValue> MinSplittingWithParameter =>
+      (IFixedValueParameter<IntValue>) Parameters[MinSplittingWidthParameterName];
+
+    public IFixedValueParameter<IntValue> MaxSplittingDepthParameter =>
+      (IFixedValueParameter<IntValue>) Parameters[MaxSplittingDepthParameterName];
+
+    public IFixedValueParameter<BoolValue> UseIntervalSplittingParameter =>
+      (IFixedValueParameter<BoolValue>) Parameters[UseIntervalSplittingParameterName];
+
+    public int MinSplittingWidth {
+      get => MinSplittingWithParameter.Value.Value;
+      set => MinSplittingWithParameter.Value.Value = value;
+    }
+
+    public int MaxSplittingDepth {
+      get => MaxSplittingDepthParameter.Value.Value;
+      set => MaxSplittingDepthParameter.Value.Value = value;
+    }
+
+    public bool UseIntervalSplitting {
+      get => UseIntervalSplittingParameter.Value.Value;
+      set => UseIntervalSplittingParameter.Value.Value = value;
+    }
 
     public int EvaluatedSolutions {
@@ -46,10 +76,15 @@
     [StorableConstructor]
     private IntervalInterpreter(StorableConstructorFlag _) : base(_) { }
+
     private IntervalInterpreter(IntervalInterpreter original, Cloner cloner)
-        : base(original, cloner) { }
+      : base(original, cloner) { }
 
     public IntervalInterpreter()
-        : base("IntervalInterpreter", "Intperter for calculation of intervals of symbolic models.") {
-      Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
+      : base("IntervalInterpreter", "Interpreter for calculation of intervals of symbolic models.") {
+      Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName,
+        "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
+      Parameters.Add(new FixedValueParameter<IntValue>(MinSplittingWidthParameterName, "Minimum interval width until splitting is stopped", new IntValue(0)));
+      Parameters.Add(new FixedValueParameter<IntValue>(MaxSplittingDepthParameterName, "Maximum recursion depth of the splitting", new IntValue(5)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(UseIntervalSplittingParameterName, "", new BoolValue(false)));
     }
 
@@ -61,45 +96,84 @@
 
     #region IStatefulItem Members
+
     public void InitializeState() {
       EvaluatedSolutions = 0;
     }
+
     public void ClearState() { }
+
     #endregion
 
-    public Interval GetSymbolicExpressionTreeInterval(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows = null) {
+    public Interval GetSymbolicExpressionTreeInterval(
+      ISymbolicExpressionTree tree, IDataset dataset,
+      IEnumerable<int> rows = null, bool splitting = true) {
       var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows);
-      return GetSymbolicExpressionTreeInterval(tree, variableRanges);
-    }
-
-    public Interval GetSymbolicExpressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset,
-      out IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals, IEnumerable<int> rows = null) {
+      return GetSymbolicExpressionTreeInterval(tree, variableRanges, splitting);
+    }
+
+    public Interval GetSymbolicExpressionTreeIntervals(
+      ISymbolicExpressionTree tree, IDataset dataset,
+      out IDictionary<ISymbolicExpressionTreeNode, Interval>
+        nodeIntervals, IEnumerable<int> rows = null, bool splitting = true) {
       var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows);
-      return GetSymbolicExpressionTreeIntervals(tree, variableRanges, out nodeIntervals);
-    }
-
-    public Interval GetSymbolicExpressionTreeInterval(ISymbolicExpressionTree tree, IReadOnlyDictionary<string, Interval> variableRanges) {
+      return GetSymbolicExpressionTreeIntervals(tree, variableRanges, out nodeIntervals, splitting);
+    }
+
+    public Interval GetSymbolicExpressionTreeInterval(
+      ISymbolicExpressionTree tree,
+      IDictionary<string, Interval> variableRanges, bool splitting = true) {
       lock (syncRoot) {
         EvaluatedSolutions++;
       }
-      int instructionCount = 0;
-      var instructions = PrepareInterpreterState(tree, variableRanges);
-      var outputInterval = Evaluate(instructions, ref instructionCount);
-
-      // because of numerical errors the bounds might be incorrect
-      return outputInterval.LowerBound <= outputInterval.UpperBound ? outputInterval : new Interval(outputInterval.UpperBound, outputInterval.LowerBound);
-    }
-
-
-    public Interval GetSymbolicExpressionTreeIntervals(ISymbolicExpressionTree tree,
-      IReadOnlyDictionary<string, Interval> variableRanges, out IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals) {
+
+      Interval outputInterval;
+
+      if (splitting) {
+        outputInterval = GetSymbolicExpressionTreeIntervals(tree, variableRanges,
+          out var nodeIntervals);
+      } else {
+        var instructionCount = 0;
+        var instructions = PrepareInterpreterState(tree, variableRanges);
+        outputInterval = Evaluate(instructions, ref instructionCount);
+      }
+
+      return outputInterval.LowerBound <= outputInterval.UpperBound
+        ? outputInterval
+        : new Interval(outputInterval.UpperBound, outputInterval.LowerBound);
+    }
+
+
+    public Interval GetSymbolicExpressionTreeIntervals(
+      ISymbolicExpressionTree tree,
+      IDictionary<string, Interval> variableRanges,
+      out IDictionary<ISymbolicExpressionTreeNode, Interval>
+        nodeIntervals, bool splitting = true) {
       lock (syncRoot) {
         EvaluatedSolutions++;
       }
-      int instructionCount = 0;
+
       var intervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
       var instructions = PrepareInterpreterState(tree, variableRanges);
-      var outputInterval = Evaluate(instructions, ref instructionCount, intervals);
-
-      // fix incorrect intervals if necessary (could occur because of numerical errors)
+
+      Interval outputInterval;
+      if (splitting) {
+        var variables = tree.IterateNodesPrefix().OfType<VariableTreeNode>().Select(x => x.VariableName).Distinct()
+                            .ToList();
+        var containsDependencyProblem = ContainsVariableMultipleTimes(tree);
+
+        if (variables.Count > 1 && containsDependencyProblem) {
+          var currIndex = 0;
+          var currDepth = 0;
+          outputInterval = EvaluateRecursive(instructions, intervals, variableRanges, variables, MinSplittingWidth, MaxSplittingDepth,
+            ref currIndex, ref currDepth, tree);
+        } else {
+          var instructionCount = 0;
+          outputInterval = Evaluate(instructions, ref instructionCount, intervals);
+        }
+      } else {
+        var instructionCount = 0;
+        outputInterval = Evaluate(instructions, ref instructionCount, intervals);
+      }
+
       nodeIntervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
       foreach (var kvp in intervals) {
@@ -114,28 +188,79 @@
       if (outputInterval.IsInfiniteOrUndefined || outputInterval.LowerBound <= outputInterval.UpperBound)
         return outputInterval;
-      else
-        return new Interval(outputInterval.UpperBound, outputInterval.LowerBound);
-    }
-
-
-    private static Instruction[] PrepareInterpreterState(ISymbolicExpressionTree tree, IReadOnlyDictionary<string, Interval> variableRanges) {
+
+      return new Interval(outputInterval.UpperBound, outputInterval.LowerBound);
+    }
+
+
+    private static Instruction[] PrepareInterpreterState(
+      ISymbolicExpressionTree tree,
+      IDictionary<string, Interval> variableRanges) {
       if (variableRanges == null)
         throw new ArgumentNullException("No variablew ranges are present!", nameof(variableRanges));
 
       //Check if all variables used in the tree are present in the dataset
-      foreach (var variable in tree.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName).Distinct()) {
-        if (!variableRanges.ContainsKey(variable)) throw new InvalidOperationException($"No ranges for variable {variable} is present");
-      }
-
-      Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
-      foreach (Instruction instr in code.Where(i => i.opCode == OpCodes.Variable)) {
-        var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
+      foreach (var variable in tree.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName).Distinct())
+        if (!variableRanges.ContainsKey(variable))
+          throw new InvalidOperationException($"No ranges for variable {variable} is present");
+
+      var code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
+      foreach (var instr in code.Where(i => i.opCode == OpCodes.Variable)) {
+        var variableTreeNode = (VariableTreeNode) instr.dynamicNode;
         instr.data = variableRanges[variableTreeNode.VariableName];
       }
+
       return code;
     }
 
-    private Interval Evaluate(Instruction[] instructions, ref int instructionCounter, IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals = null) {
-      Instruction currentInstr = instructions[instructionCounter];
+    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;
+        return Evaluate(instructions, ref ic, nodeIntervals, variableIntervals);
+      }
+
+      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,
+      IDictionary<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
@@ -146,130 +271,174 @@
         //Variables, Constants, ...
         case OpCodes.Variable: {
-            var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode;
-            var weightInterval = new Interval(variableTreeNode.Weight, variableTreeNode.Weight);
-            var variableInterval = (Interval)currentInstr.data;
-
-            result = Interval.Multiply(variableInterval, weightInterval);
-            break;
-          }
+          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;
-          }
+          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);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              result = Interval.Add(result, argumentInterval);
-            }
-            break;
+          //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);
-            if (currentInstr.nArguments == 1)
-              result = Interval.Multiply(new Interval(-1, -1), result);
-
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              result = Interval.Subtract(result, argumentInterval);
-            }
-            break;
+          //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);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              result = Interval.Multiply(result, argumentInterval);
-            }
-            break;
+          //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);
-            if (currentInstr.nArguments == 1)
-              result = Interval.Divide(new Interval(1, 1), result);
-
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              result = Interval.Divide(result, argumentInterval);
-            }
-            break;
+          //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: {
-            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-            result = Interval.Sine(argumentInterval);
-            break;
-          }
+          //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);
-            result = Interval.Cosine(argumentInterval);
-            break;
-          }
+          //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);
-            result = Interval.Tangens(argumentInterval);
-            break;
-          }
+          //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);
-            result = Interval.HyperbolicTangent(argumentInterval);
-            break;
-          }
+          //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);
-            result = Interval.Logarithm(argumentInterval);
-            break;
+          //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);
           }
-        case OpCodes.Exp: {
-            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-            result = Interval.Exponential(argumentInterval);
-            break;
-          }
-        case OpCodes.Square: {
-            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-            result = Interval.Square(argumentInterval);
-            break;
-          }
-        case OpCodes.SquareRoot: {
-            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-            result = Interval.SquareRoot(argumentInterval);
-            break;
-          }
-        case OpCodes.Cube: {
-            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-            result = Interval.Cube(argumentInterval);
-            break;
-          }
-        case OpCodes.CubeRoot: {
-            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-            result = Interval.CubicRoot(argumentInterval);
-            break;
-          }
-        case OpCodes.Absolute: {
-            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-            result = Interval.Absolute(argumentInterval);
-            break;
-          }
-        case OpCodes.AnalyticQuotient: {
-            result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-            for (var i = 1; i < currentInstr.nArguments; i++) {
-              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              result = Interval.AnalyticalQuotient(result, argumentInterval);
-            }
-
-            break;
-          }
+
+          break;
+        }
         default:
           throw new NotSupportedException($"The tree contains the unknown symbol {currentInstr.dynamicNode.Symbol}");
       }
 
-      if (nodeIntervals != null)
+      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) {
@@ -277,5 +446,5 @@
         from n in tree.Root.GetSubtree(0).IterateNodesPrefix()
         where
-          !(n.Symbol is Problems.DataAnalysis.Symbolic.Variable) &&
+          !(n.Symbol is Variable) &&
           !(n.Symbol is Constant) &&
           !(n.Symbol is StartSymbol) &&
Index: /branches/3073_IA_constraint_splitting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/Interval.cs
===================================================================
--- /branches/3073_IA_constraint_splitting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/Interval.cs	(revision 17630)
+++ /branches/3073_IA_constraint_splitting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/Interval.cs	(revision 17631)
@@ -33,4 +33,6 @@
     [Storable]
     public double UpperBound { get; private set; }
+
+    public double Width => UpperBound - LowerBound;
 
     [StorableConstructor]
@@ -78,4 +80,21 @@
     }
 
+    public Tuple<Interval, Interval> Split() {
+      var midpoint = Width / 2;
+      var left     = new Interval(LowerBound, LowerBound + midpoint - double.Epsilon);
+      var right    = new Interval(LowerBound + midpoint, UpperBound);
+      return Tuple.Create(left, right);
+    }
+
+    //Interval Intersection
+    public static Interval operator &(Interval lhs, Interval rhs) {
+      return new Interval(Math.Max(lhs.LowerBound, rhs.LowerBound), Math.Min(lhs.UpperBound, rhs.UpperBound));
+    }
+
+    //Interval Union
+    public static Interval operator |(Interval lhs, Interval rhs) {
+      return new Interval(Math.Min(lhs.LowerBound, rhs.LowerBound), Math.Max(lhs.UpperBound, rhs.UpperBound));
+    }
+
     public override string ToString() {
       return "Interval: [" + LowerBound + ", " + UpperBound + "]";
Index: /branches/3073_IA_constraint_splitting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/IntervalCollection.cs
===================================================================
--- /branches/3073_IA_constraint_splitting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/IntervalCollection.cs	(revision 17630)
+++ /branches/3073_IA_constraint_splitting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/IntervalCollection.cs	(revision 17631)
@@ -94,4 +94,8 @@
     }
 
+    public IDictionary<string, Interval> GetDictionary() {
+      return intervals.ToDictionary(pair => pair.Key, pair => pair.Value);
+    }
+
     public IEnumerable<Tuple<string, Interval>> GetVariableIntervals() {
       foreach (var variableInterval in intervals)
