Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs	(revision 14186)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs	(revision 14564)
@@ -37,5 +37,5 @@
   /// </summary>
   public sealed class InfixExpressionParser {
-    private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, End, NA };
+    private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, Comma, End, NA };
     private class Token {
       internal double doubleVal;
@@ -102,6 +102,6 @@
         { "MEAN", new Average()},
         { "IF", new IfThenElse()},
-        { ">", new GreaterThan()},
-        { "<", new LessThan()},
+        { "GT", new GreaterThan()},
+        { "LT", new LessThan()},
         { "AND", new And()},
         { "OR", new Or()},
@@ -138,14 +138,15 @@
         }
         if (char.IsDigit(str[pos])) {
-          // read number (=> read until white space or operator)
+          // read number (=> read until white space or operator or comma)
           var sb = new StringBuilder();
           sb.Append(str[pos]);
           pos++;
           while (pos < str.Length && !char.IsWhiteSpace(str[pos])
-            && (str[pos] != '+' || str[pos-1] == 'e' || str[pos-1] == 'E')     // continue reading exponents
+            && (str[pos] != '+' || str[pos - 1] == 'e' || str[pos - 1] == 'E')     // continue reading exponents
             && (str[pos] != '-' || str[pos - 1] == 'e' || str[pos - 1] == 'E')
-            && str[pos] != '*'           
+            && str[pos] != '*'
             && str[pos] != '/'
-            && str[pos] != ')') {
+            && str[pos] != ')'
+            && str[pos] != ',') {
             sb.Append(str[pos]);
             pos++;
@@ -211,12 +212,18 @@
           pos++;
           yield return new Token { TokenType = TokenType.RightPar, strVal = ")" };
-        }
-      }
-    }
-
-    // S = Expr EOF
-    // Expr = ['-' | '+'] Term { '+' Term | '-' Term }
-    // Term = Fact { '*' Fact | '/' Fact }
-    // Fact = '(' Expr ')' | funcId '(' Expr ')' | varId | number
+        } else if (str[pos] == ',') {
+          pos++;
+          yield return new Token { TokenType = TokenType.Comma, strVal = "," };
+        } else {
+          throw new ArgumentException("Invalid character: " + str[pos]);
+        }
+      }
+    }
+
+    // S       = Expr EOF
+    // Expr    = ['-' | '+'] Term { '+' Term | '-' Term }
+    // Term    = Fact { '*' Fact | '/' Fact }
+    // Fact    = '(' Expr ')' | funcId '(' ArgList ')' | varId | number
+    // ArgList = Expr { ',' Expr }
     private ISymbolicExpressionTreeNode ParseS(Queue<Token> tokens) {
       var expr = ParseExpr(tokens);
@@ -326,5 +333,5 @@
     }
 
-    // Fact = '(' Expr ')' | funcId '(' Expr ')' | varId | number
+    // Fact = '(' Expr ')' | funcId '(' ArgList ')' | varId | number
     private ISymbolicExpressionTreeNode ParseFact(Queue<Token> tokens) {
       var next = tokens.Peek();
@@ -346,10 +353,16 @@
           if (lPar.TokenType != TokenType.LeftPar)
             throw new ArgumentException("expected (");
-          var expr = ParseExpr(tokens);
+          var args = ParseArgList(tokens);
+
+          // check semantic constraints
+          if (funcNode.Symbol.MinimumArity > args.Length || funcNode.Symbol.MaximumArity < args.Length)
+            throw new ArgumentException(string.Format("Symbol {0} requires between {1} and  {2} arguments.", funcId,
+              funcNode.Symbol.MinimumArity, funcNode.Symbol.MaximumArity));
+          foreach (var arg in args) funcNode.AddSubtree(arg);
+
           var rPar = tokens.Dequeue();
           if (rPar.TokenType != TokenType.RightPar)
             throw new ArgumentException("expected )");
 
-          funcNode.AddSubtree(expr);
           return funcNode;
         } else {
@@ -369,4 +382,16 @@
       }
     }
+
+    // ArgList = Expr { ',' Expr }
+    private ISymbolicExpressionTreeNode[] ParseArgList(Queue<Token> tokens) {
+      var exprList = new List<ISymbolicExpressionTreeNode>();
+      exprList.Add(ParseExpr(tokens));
+      while (tokens.Peek().TokenType != TokenType.RightPar) {
+        var comma = tokens.Dequeue();
+        if (comma.TokenType != TokenType.Comma) throw new ArgumentException("expected ',' ");
+        exprList.Add(ParseExpr(tokens));
+      }
+      return exprList.ToArray();
+    }
   }
 }
