Index: /trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs
===================================================================
--- /trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs	(revision 18171)
+++ /trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs	(revision 18172)
@@ -37,7 +37,12 @@
         var token = GetToken(node.Symbol);
         // operators
-        if (token == "+" || token == "-" || token == "OR" || token == "XOR" ||
-            token == "*" || token == "/" || token == "AND") {
-          strBuilder.Append("(");
+        if (token == "+" || token == "-" || token == "OR" || token == "XOR") {
+          var parenthesisRequired = false;
+          if (node.Parent != null && node.Parent.SubtreeCount > 1) {
+            var parentOp = GetToken(node.Parent.Symbol);
+            if (parentOp != "+" && parentOp != "-" && parentOp != "OR" && parentOp != "XOR")
+              parenthesisRequired = true;
+          }
+          if (parenthesisRequired) strBuilder.Append("(");
           FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, parameters);
 
@@ -47,12 +52,25 @@
           }
 
-          strBuilder.Append(")");
+          if (parenthesisRequired) strBuilder.Append(")");
+        } else if (token == "*" || token == "/" || token == "AND") {
+          FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, parameters);
+
+          foreach (var subtree in node.Subtrees.Skip(1)) {
+            strBuilder.Append(" ").Append(token).Append(" ");
+            // a / b * c => a / (b * C)
+            if (subtree.SubtreeCount > 1 && token == "/" && GetToken(subtree.Symbol) == "*") {
+              strBuilder.Append("(");
+              FormatRecursively(subtree, strBuilder, numberFormat, formatString, parameters);
+              strBuilder.Append(")");
+            } else {
+              FormatRecursively(subtree, strBuilder, numberFormat, formatString, parameters);
+            }
+          }
         } else if (token == "^") {
           // handle integer powers directly
-          strBuilder.Append("(");
           FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, parameters);
 
           var power = node.GetSubtree(1);
-          if(power is INumericTreeNode numNode && Math.Truncate(numNode.Value) == numNode.Value) {
+          if (power is INumericTreeNode numNode && Math.Truncate(numNode.Value) == numNode.Value) {
             strBuilder.Append(" ").Append(token).Append(" ").Append(numNode.Value.ToString(formatString, numberFormat));
           } else {
@@ -60,6 +78,4 @@
             FormatRecursively(power, strBuilder, numberFormat, formatString, parameters);
           }
-
-          strBuilder.Append(")");
         } else {
           // function with multiple arguments
@@ -76,7 +92,6 @@
         var token = GetToken(node.Symbol);
         if (token == "-" || token == "NOT") {
-          strBuilder.Append("(").Append(token).Append("(");
-          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, parameters);
-          strBuilder.Append("))");
+          strBuilder.Append(token);
+          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, parameters);
         } else if (token == "/") {
           strBuilder.Append("1/");
@@ -95,5 +110,4 @@
           var varNode = node as LaggedVariableTreeNode;
           if (!varNode.Weight.IsAlmost(1.0)) {
-            strBuilder.Append("(");
             AppendNumber(strBuilder, parameters, varNode.Weight, formatString, numberFormat);
             strBuilder.Append("*");
@@ -105,16 +119,11 @@
                     .AppendFormat(numberFormat, "{0}", varNode.Lag)
                     .Append(")");
-          if (!varNode.Weight.IsAlmost(1.0)) strBuilder.Append(")");
         } else if (node.Symbol is Variable) {
           var varNode = node as VariableTreeNode;
           if (!varNode.Weight.IsAlmost(1.0)) {
-            strBuilder.Append("(");
             AppendNumber(strBuilder, parameters, varNode.Weight, formatString, numberFormat);
             strBuilder.Append("*");
           }
-
           AppendVariableName(strBuilder, varNode.VariableName);
-
-          if (!varNode.Weight.IsAlmost(1.0)) strBuilder.Append(")");
         } else if (node.Symbol is FactorVariable) {
           var factorNode = node as FactorVariableTreeNode;
@@ -130,20 +139,14 @@
           var factorNode = node as BinaryFactorVariableTreeNode;
           if (!factorNode.Weight.IsAlmost(1.0)) {
-            strBuilder.Append("(");
             AppendNumber(strBuilder, parameters, factorNode.Weight, formatString, numberFormat);
-
             strBuilder.Append("*");
           }
-
           AppendVariableName(strBuilder, factorNode.VariableName);
           strBuilder.Append(" = ");
           AppendVariableName(strBuilder, factorNode.VariableValue);
-
-          if (!factorNode.Weight.IsAlmost(1.0)) strBuilder.Append(")");
         } else if (node is INumericTreeNode numNode) {
           if (parameters == null && numNode.Value < 0) {
             // negative value
-            strBuilder.Append("(").Append(numNode.Value.ToString(formatString, numberFormat))
-                      .Append(")"); 
+            strBuilder.Append(numNode.Value.ToString(formatString, numberFormat));
           } else {
             AppendNumber(strBuilder, parameters, numNode.Value, formatString, numberFormat);
Index: /trunk/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/DeriveTest.cs
===================================================================
--- /trunk/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/DeriveTest.cs	(revision 18171)
+++ /trunk/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/DeriveTest.cs	(revision 18172)
@@ -43,10 +43,10 @@
       Assert.AreEqual("20", Derive("<num=10>*x+<num=20>*y", "y"));
       Assert.AreEqual("6", Derive("<num=2>*<num=3>*x", "x"));
-      Assert.AreEqual("10 * 'y'", Derive("<num=10>*x*y+<num=20>*y", "x"));
-      Assert.AreEqual("(1 / (SQR('x') * (-1)))", Derive("1/x", "x"));
-      Assert.AreEqual("'y' / (SQR('x') * -1)", Derive("y/x", "x"));
-      Assert.AreEqual("(-2*'x' + -1) * ('a' + 'b') / SQR('x' + 'x' * 'x')",
+      Assert.AreEqual("10*'y'", Derive("<num=10>*x*y+<num=20>*y", "x"));
+      Assert.AreEqual("1 * -1 / SQR('x')", Derive("1/x", "x"));
+      Assert.AreEqual("-1*'y' / SQR('x')", Derive("y/x", "x"));
+      Assert.AreEqual("('a' + 'b') * (-2*'x' + -1) / SQR('x' + 'x' * 'x')",
         Derive("(a+b)/(x+x*x)", "x"));
-      Assert.AreEqual("(-2*'x' + -1) * ('a' + 'b') / SQR('x' + SQR('x'))", Derive("(a+b)/(x+SQR(x))", "x"));
+      Assert.AreEqual("('a' + 'b') * (-2*'x' + -1) / SQR('x' + SQR('x'))", Derive("(a+b)/(x+SQR(x))", "x"));
       Assert.AreEqual("EXP('x')", Derive("exp(x)", "x"));
       Assert.AreEqual("EXP(3*'x') * 3", Derive("exp(<num=3>*x)", "x"));
@@ -67,5 +67,5 @@
 
       Assert.AreEqual("'a' * 'b' * 'c'", Derive("a*b*c*d", "d"));
-      Assert.AreEqual("'a' / ('b' * 'c' * SQR('d') * -1)", Derive("a/b/c/d", "d"));
+      Assert.AreEqual("'b' * 'c' * -1*'a' / (SQR('b') * SQR('c') * SQR('d'))", Derive("a/b/c/d", "d")); // TODO simplifier should be able to simplify this
 
       Assert.AreEqual("'x' * (SQR(TANH(SQR('x'))) * -1 + 1) * 2", Derive("tanh(sqr(x))", "x")); // (2*'x'*(1 - SQR(TANH(SQR('x'))))
@@ -84,5 +84,5 @@
         root.AddSubtree(start);
         var t = new SymbolicExpressionTree(root);
-        Assert.AreEqual("(1 / (SQR('x') * (-1)))",
+        Assert.AreEqual("1 / (SQR('x') * -1)",
           formatter.Format(DerivativeCalculator.Derive(t, "x")));
       }
