Index: branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs	(revision 17520)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs	(revision 17586)
@@ -21,53 +21,17 @@
 
 using System;
+using System.Collections.Generic;
 using System.Globalization;
 using System.Linq;
 using System.Text;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
-  /// <summary>
-  /// Formats mathematical expressions in infix form. E.g. x1 * (3.0 * x2 + x3)
-  /// </summary>
-  [StorableType("6FE2C83D-A594-4ABF-B101-5AEAEA6D3E3D")]
-  [Item("Infix Symbolic Expression Tree Formatter", "A string formatter that converts symbolic expression trees to infix expressions.")]
-
-  public sealed class InfixExpressionFormatter : NamedItem, ISymbolicExpressionTreeStringFormatter {
-
-
-    [StorableConstructor]
-    private InfixExpressionFormatter(StorableConstructorFlag _) : base(_) { }
-    private InfixExpressionFormatter(InfixExpressionFormatter original, Cloner cloner) : base(original, cloner) { }
-    public InfixExpressionFormatter()
-      : base() {
-      Name = ItemName;
-      Description = ItemDescription;
-    }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new InfixExpressionFormatter(this, cloner);
-    }
-
-    /// <summary>
-    /// Produces an infix expression for a given expression tree.
-    /// </summary>
-    /// <param name="symbolicExpressionTree">The tree representation of the expression.</param>
-    /// <param name="numberFormat">Number format that should be used for numeric parameters (e.g. NumberFormatInfo.InvariantInfo (default)).</param>
-    /// <param name="formatString">The format string for numeric parameters (e.g. \"G4\" to limit to 4 digits, default is \"G\")</param>
-    /// <returns>Infix expression</returns>
-    public string Format(ISymbolicExpressionTree symbolicExpressionTree, NumberFormatInfo numberFormat, string formatString="G") {
-      // skip root and start symbols
-      StringBuilder strBuilder = new StringBuilder();
-      FormatRecursively(symbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0), strBuilder, numberFormat, formatString);
-      return strBuilder.ToString();
-    }
-
-    public string Format(ISymbolicExpressionTree symbolicExpressionTree) {
-      return Format(symbolicExpressionTree, NumberFormatInfo.InvariantInfo);
-    }
-
-    private static void FormatRecursively(ISymbolicExpressionTreeNode node, StringBuilder strBuilder, NumberFormatInfo numberFormat, string formatString) {
+  public static class BaseInfixExpressionFormatter {
+    public static void FormatRecursively(ISymbolicExpressionTreeNode node, StringBuilder strBuilder,
+                                          NumberFormatInfo numberFormat, string formatString, List<KeyValuePair<string, double>> constants = null) {
       if (node.SubtreeCount > 1) {
         var token = GetToken(node.Symbol);
@@ -77,19 +41,21 @@
             token == "^") {
           strBuilder.Append("(");
-          FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString);
+          FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, constants);
 
           foreach (var subtree in node.Subtrees.Skip(1)) {
             strBuilder.Append(" ").Append(token).Append(" ");
-            FormatRecursively(subtree, strBuilder, numberFormat, formatString);
-          }
+            FormatRecursively(subtree, strBuilder, numberFormat, formatString, constants);
+          }
+
           strBuilder.Append(")");
         } else {
           // function with multiple arguments
           strBuilder.Append(token).Append("(");
-          FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString);
+          FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, constants);
           foreach (var subtree in node.Subtrees.Skip(1)) {
             strBuilder.Append(", ");
-            FormatRecursively(subtree, strBuilder, numberFormat, formatString);
-          }
+            FormatRecursively(subtree, strBuilder, numberFormat, formatString, constants);
+          }
+
           strBuilder.Append(")");
         }
@@ -98,15 +64,15 @@
         if (token == "-" || token == "NOT") {
           strBuilder.Append("(").Append(token).Append("(");
-          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString);
+          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, constants);
           strBuilder.Append("))");
         } else if (token == "/") {
           strBuilder.Append("1/");
-          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString);
+          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, constants);
         } else if (token == "+" || token == "*") {
-          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString);
+          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, constants);
         } else {
           // function with only one argument
           strBuilder.Append(token).Append("(");
-          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString);
+          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, constants);
           strBuilder.Append(")");
         }
@@ -117,38 +83,49 @@
           if (!varNode.Weight.IsAlmost(1.0)) {
             strBuilder.Append("(");
-            strBuilder.Append(varNode.Weight.ToString(formatString, numberFormat));
+            if (constants != null) {
+              strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", varNode.Weight);
+            } else {
+              strBuilder.Append(varNode.Weight.ToString(formatString, numberFormat));
+            }
             strBuilder.Append("*");
           }
+
           strBuilder.Append("LAG(");
-          if (varNode.VariableName.Contains("'")) {
+          if (varNode.VariableName.Contains("'"))
             strBuilder.AppendFormat("\"{0}\"", varNode.VariableName);
-          } else {
+          else
             strBuilder.AppendFormat("'{0}'", varNode.VariableName);
-          }
+
           strBuilder.Append(", ")
-            .AppendFormat(numberFormat, "{0}", varNode.Lag)
-            .Append(")");
+                    .AppendFormat(numberFormat, "{0}", varNode.Lag)
+                    .Append(")");
         } else if (node.Symbol is Variable) {
           var varNode = node as VariableTreeNode;
           if (!varNode.Weight.IsAlmost(1.0)) {
             strBuilder.Append("(");
-            strBuilder.Append(varNode.Weight.ToString(formatString, numberFormat));
+            if (constants != null) {
+              string constantKey = $"c_{constants.Count}";
+              strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", constantKey);
+              constants.Add(new KeyValuePair<string, double>(constantKey, varNode.Weight));
+            } else {
+              strBuilder.Append(varNode.Weight.ToString(formatString, numberFormat));
+            }
+
             strBuilder.Append("*");
           }
-          if (varNode.VariableName.Contains("'")) {
+
+          if (varNode.VariableName.Contains("'"))
             strBuilder.AppendFormat("\"{0}\"", varNode.VariableName);
-          } else {
+          else
             strBuilder.AppendFormat("'{0}'", varNode.VariableName);
-          }
-          if (!varNode.Weight.IsAlmost(1.0)) {
-            strBuilder.Append(")");
-          }
+
+          if (!varNode.Weight.IsAlmost(1.0)) strBuilder.Append(")");
         } else if (node.Symbol is FactorVariable) {
           var factorNode = node as FactorVariableTreeNode;
-          if (factorNode.VariableName.Contains("'")) {
+          if (factorNode.VariableName.Contains("'"))
             strBuilder.AppendFormat("\"{0}\"", factorNode.VariableName);
-          } else {
+          else
             strBuilder.AppendFormat("'{0}'", factorNode.VariableName);
-          }
+
           strBuilder.AppendFormat("[{0}]",
             string.Join(", ", factorNode.Weights.Select(w => w.ToString(formatString, numberFormat))));
@@ -157,29 +134,39 @@
           if (!factorNode.Weight.IsAlmost(1.0)) {
             strBuilder.Append("(");
-            strBuilder.Append(factorNode.Weight.ToString(formatString, numberFormat));
+            if (constants != null) {
+              strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", factorNode.Weight);
+            } else {
+              strBuilder.Append(factorNode.Weight.ToString(formatString, numberFormat));
+            }
+
             strBuilder.Append("*");
           }
-          if (factorNode.VariableName.Contains("'")) {
+
+          if (factorNode.VariableName.Contains("'"))
             strBuilder.AppendFormat("\"{0}\"", factorNode.VariableName);
-          } else {
+          else
             strBuilder.AppendFormat("'{0}'", factorNode.VariableName);
-          }
+
           strBuilder.Append(" = ");
-          if (factorNode.VariableValue.Contains("'")) {
+          if (factorNode.VariableValue.Contains("'"))
             strBuilder.AppendFormat("\"{0}\"", factorNode.VariableValue);
-          } else {
+          else
             strBuilder.AppendFormat("'{0}'", factorNode.VariableValue);
-          }
-
-          if (!factorNode.Weight.IsAlmost(1.0)) {
-            strBuilder.Append(")");
-          }
-
+
+          if (!factorNode.Weight.IsAlmost(1.0)) strBuilder.Append(")");
         } else if (node.Symbol is Constant) {
           var constNode = node as ConstantTreeNode;
-          if (constNode.Value >= 0.0)
-            strBuilder.Append(constNode.Value.ToString(formatString, numberFormat));
-          else
-            strBuilder.Append("(").Append(constNode.Value.ToString(formatString, numberFormat)).Append(")"); // (-1
+          if (constants != null) {
+            string constantKey = $"c_{constants.Count}";
+
+            strBuilder.AppendFormat(CultureInfo.InvariantCulture, constantKey);
+            constants.Add(new KeyValuePair<string, double>(constantKey, constNode.Value));
+          } else {
+            if (constNode.Value >= 0.0)
+              strBuilder.Append(constNode.Value.ToString(formatString, numberFormat));
+            else
+              strBuilder.Append("(").Append(constNode.Value.ToString(formatString, numberFormat))
+                        .Append(")"); // (-1
+          }
         }
       }
@@ -193,3 +180,89 @@
     }
   }
+
+  /// <summary>
+  /// Formats mathematical expressions in infix form. E.g. x1 * (3.0 * x2 + x3)
+  /// </summary>
+  [StorableType("6FE2C83D-A594-4ABF-B101-5AEAEA6D3E3D")]
+  [Item("Infix Symbolic Expression Tree Formatter",
+    "A string formatter that converts symbolic expression trees to infix expressions.")]
+  public sealed class InfixExpressionFormatter : NamedItem, ISymbolicExpressionTreeStringFormatter {
+    [StorableConstructor]
+    private InfixExpressionFormatter(StorableConstructorFlag _) : base(_) { }
+
+    private InfixExpressionFormatter(InfixExpressionFormatter original, Cloner cloner) : base(original, cloner) { }
+
+    public InfixExpressionFormatter()
+      : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new InfixExpressionFormatter(this, cloner);
+    }
+
+    /// <summary>
+    /// Produces an infix expression for a given expression tree.
+    /// </summary>
+    /// <param name="symbolicExpressionTree">The tree representation of the expression.</param>
+    /// <param name="numberFormat">Number format that should be used for numeric parameters (e.g. NumberFormatInfo.InvariantInfo (default)).</param>
+    /// <param name="formatString">The format string for numeric parameters (e.g. \"G4\" to limit to 4 digits, default is \"G\")</param>
+    /// <returns>Infix expression</returns>
+    public string Format(ISymbolicExpressionTree symbolicExpressionTree, NumberFormatInfo numberFormat,
+                         string formatString = "G") {
+      // skip root and start symbols
+      StringBuilder strBuilder = new StringBuilder();
+      BaseInfixExpressionFormatter.FormatRecursively(symbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0),
+        strBuilder, numberFormat, formatString);
+      return strBuilder.ToString();
+    }
+
+    public string Format(ISymbolicExpressionTree symbolicExpressionTree) {
+      return Format(symbolicExpressionTree, NumberFormatInfo.InvariantInfo);
+    }
+  }
+
+  [StorableType("54D917E8-134E-4066-9A60-2737C12D81DC")]
+  [Item("Infix String Formater", "Formatter for symbolic expressions, which produces an infix expression " +
+                                 "as well as a list of all coefficient values")]
+  public sealed class InfixExpressionStringFormatter : NamedItem, ISymbolicExpressionTreeStringFormatter {
+    [StorableConstructor]
+    private InfixExpressionStringFormatter(StorableConstructorFlag _) : base(_) { }
+
+    private InfixExpressionStringFormatter(InfixExpressionStringFormatter original, Cloner cloner) : base(original, cloner) { }
+
+    public InfixExpressionStringFormatter() : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new InfixExpressionStringFormatter(this, cloner);
+    }
+
+    public string Format(ISymbolicExpressionTree symbolicExpressionTree) {
+      StringBuilder strBuilder = new StringBuilder();
+      var constants = new List<KeyValuePair<string, double>>();
+      BaseInfixExpressionFormatter.FormatRecursively(symbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0),
+        strBuilder, NumberFormatInfo.InvariantInfo, "G", constants);
+      strBuilder.Append($"{Environment.NewLine}{Environment.NewLine}");
+
+      int maxDigits = GetDigits(constants.Count);
+      int padding = constants.Max(x => x.Value.ToString("F12", CultureInfo.InvariantCulture).Length);
+      foreach (var constant in constants) {
+        int digits = GetDigits(Int32.Parse(constant.Key.Substring(2)));
+        strBuilder.Append($"{constant.Key}{new String(' ', maxDigits - digits)} = " +
+                          string.Format($"{{0,{padding}:F12}}", constant.Value, CultureInfo.InvariantCulture) +
+                          Environment.NewLine);
+      }
+
+      return strBuilder.ToString();
+    }
+
+    private int GetDigits(int x) {
+      if (x == 0) return 1;
+      return (int)Math.Floor(Math.Log10(x) + 1);
+    }
+  }
 }
Index: branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs	(revision 17520)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs	(revision 17586)
@@ -23,9 +23,9 @@
 using System.Collections.Generic;
 using System.Linq;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HEAL.Attic;
 using HeuristicLab.Parameters;
 
@@ -80,5 +80,5 @@
     }
 
-    public Interval GetSymbolicExpressionTreeInterval(ISymbolicExpressionTree tree, IDictionary<string, Interval> variableRanges) {
+    public Interval GetSymbolicExpressionTreeInterval(ISymbolicExpressionTree tree, IReadOnlyDictionary<string, Interval> variableRanges) {
       lock (syncRoot) {
         EvaluatedSolutions++;
@@ -97,5 +97,5 @@
 
     public Interval GetSymbolicExpressionTreeIntervals(ISymbolicExpressionTree tree,
-      IDictionary<string, Interval> variableRanges, out IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals) {
+      IReadOnlyDictionary<string, Interval> variableRanges, out IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals) {
       lock (syncRoot) {
         EvaluatedSolutions++;
@@ -124,5 +124,5 @@
 
 
-    private static Instruction[] PrepareInterpreterState(ISymbolicExpressionTree tree, IDictionary<string, Interval> variableRanges) {
+    private static Instruction[] PrepareInterpreterState(ISymbolicExpressionTree tree, IReadOnlyDictionary<string, Interval> variableRanges) {
       if (variableRanges == null)
         throw new ArgumentNullException("No variablew ranges are present!", nameof(variableRanges));
@@ -234,12 +234,4 @@
             break;
           }
-        case OpCodes.Power: {
-            result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              result = Interval.Power(result, argumentInterval);
-            }
-            break;
-          }
         case OpCodes.Square: {
             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
@@ -247,15 +239,31 @@
             break;
           }
-        case OpCodes.Root: {
-            result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
-              result = Interval.Root(result, 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;
           }
@@ -274,4 +282,6 @@
         from n in tree.Root.GetSubtree(0).IterateNodesPrefix()
         where
+          !(n.Symbol is Problems.DataAnalysis.Symbolic.Variable) &&
+          !(n.Symbol is Constant) &&
           !(n.Symbol is StartSymbol) &&
           !(n.Symbol is Addition) &&
@@ -284,10 +294,10 @@
           !(n.Symbol is Logarithm) &&
           !(n.Symbol is Exponential) &&
-          !(n.Symbol is Power) &&
           !(n.Symbol is Square) &&
-          !(n.Symbol is Root) &&
           !(n.Symbol is SquareRoot) &&
-          !(n.Symbol is Problems.DataAnalysis.Symbolic.Variable) &&
-          !(n.Symbol is Constant)
+          !(n.Symbol is Cube) &&
+          !(n.Symbol is CubeRoot) &&
+          !(n.Symbol is Absolute) &&
+          !(n.Symbol is AnalyticQuotient)
         select n).Any();
       return !containsUnknownSyumbol;
