Index: trunk/sources/HeuristicLab 3.3.sln
===================================================================
--- trunk/sources/HeuristicLab 3.3.sln	(revision 3745)
+++ trunk/sources/HeuristicLab 3.3.sln	(revision 3746)
@@ -7,4 +7,5 @@
 		..\documentation\License\gpl-3.0.txt = ..\documentation\License\gpl-3.0.txt
 		HeuristicLab 3.3.vsmdi = HeuristicLab 3.3.vsmdi
+		HeuristicLab 3.31.vsmdi = HeuristicLab 3.31.vsmdi
 		LocalTestRun.testrunconfig = LocalTestRun.testrunconfig
 		PreBuildEvent.cmd = PreBuildEvent.cmd
@@ -244,5 +245,10 @@
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.OneMax.Views-3.3", "HeuristicLab.Problems.OneMax.Views\3.3\HeuristicLab.Problems.OneMax.Views-3.3.csproj", "{4FE983A1-AAF8-4977-B9E2-52B3224510CB}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.DataAnalysis.Tests-3.3", "HeuristicLab.Problems.DataAnalysis\3.3\Tests\HeuristicLab.Problems.DataAnalysis.Tests-3.3.csproj", "{5A4679EF-A8F3-4647-B722-441A36B3BA6B}"
+EndProject
 Global
+	GlobalSection(TestCaseManagementSettings) = postSolution
+		CategoryFile = HeuristicLab 3.31.vsmdi
+	EndGlobalSection
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -1343,4 +1349,16 @@
 		{4FE983A1-AAF8-4977-B9E2-52B3224510CB}.Services|x64.ActiveCfg = Release|x64
 		{4FE983A1-AAF8-4977-B9E2-52B3224510CB}.Services|x86.ActiveCfg = Release|x86
+		{5A4679EF-A8F3-4647-B722-441A36B3BA6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{5A4679EF-A8F3-4647-B722-441A36B3BA6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{5A4679EF-A8F3-4647-B722-441A36B3BA6B}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{5A4679EF-A8F3-4647-B722-441A36B3BA6B}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{5A4679EF-A8F3-4647-B722-441A36B3BA6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{5A4679EF-A8F3-4647-B722-441A36B3BA6B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{5A4679EF-A8F3-4647-B722-441A36B3BA6B}.Release|x64.ActiveCfg = Release|Any CPU
+		{5A4679EF-A8F3-4647-B722-441A36B3BA6B}.Release|x86.ActiveCfg = Release|Any CPU
+		{5A4679EF-A8F3-4647-B722-441A36B3BA6B}.Services|Any CPU.ActiveCfg = Release|Any CPU
+		{5A4679EF-A8F3-4647-B722-441A36B3BA6B}.Services|Any CPU.Build.0 = Release|Any CPU
+		{5A4679EF-A8F3-4647-B722-441A36B3BA6B}.Services|x64.ActiveCfg = Release|Any CPU
+		{5A4679EF-A8F3-4647-B722-441A36B3BA6B}.Services|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/SimpleArithmeticExpressionInterpreterTest.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/SimpleArithmeticExpressionInterpreterTest.cs	(revision 3745)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/SimpleArithmeticExpressionInterpreterTest.cs	(revision 3746)
@@ -89,5 +89,5 @@
     public void SimpleArithmeticExpressionInterpreterEvaluateTest() {
 
-      Dataset ds = new Dataset(new string[] { "y", "a", "b" }, new double[,] {
+      Dataset ds = new Dataset(new string[] { "Y", "A", "B" }, new double[,] {
         { 1.0, 1.0, 1.0 },
         { 2.0, 2.0, 2.0 },
@@ -133,5 +133,38 @@
       Evaluate(interpreter, ds, "(/ 8.0 2.0 2.0)", 0, 2.0);
 
-      // TODO ADF      
+      // ADF      
+      Evaluate(interpreter, ds, @"(PROG 
+                                    (MAIN 
+                                      (CALL ADF0)) 
+                                    (defun ADF0 1.0))", 1, 1.0);
+      Evaluate(interpreter, ds, @"(PROG 
+                                    (MAIN 
+                                      (* (CALL ADF0) (CALL ADF0)))
+                                    (defun ADF0 2.0))", 1, 4.0);
+      Evaluate(interpreter, ds, @"(PROG 
+                                    (MAIN 
+                                      (CALL ADF0 2.0 3.0))
+                                    (defun ADF0 
+                                      (+ (ARG 0) (ARG 1))))", 1, 5.0);
+      Evaluate(interpreter, ds, @"(PROG 
+                                    (MAIN (CALL ADF1 2.0 3.0))
+                                    (defun ADF0 
+                                      (- (ARG 1) (ARG 0)))
+                                    (defun ADF1
+                                      (+ (CALL ADF0 (ARG 1) (ARG 0))
+                                         (CALL ADF0 (ARG 0) (ARG 1)))))", 1, 0.0);
+      Evaluate(interpreter, ds, @"(PROG 
+                                    (MAIN (CALL ADF1 (variable 2.0 a) 3.0))
+                                    (defun ADF0 
+                                      (- (ARG 1) (ARG 0)))
+                                    (defun ADF1                                                                              
+                                      (CALL ADF0 (ARG 1) (ARG 0))))", 1, 1.0);
+      Evaluate(interpreter, ds, @"(PROG 
+                                    (MAIN (CALL ADF1 (variable 2.0 a) 3.0))
+                                    (defun ADF0 
+                                      (- (ARG 1) (ARG 0)))
+                                    (defun ADF1                                                                              
+                                      (+ (CALL ADF0 (ARG 1) (ARG 0))
+                                         (CALL ADF0 (ARG 0) (ARG 1)))))", 1, 0.0);
     }
 
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/SymbolicExpressionImporter.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/SymbolicExpressionImporter.cs	(revision 3745)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/SymbolicExpressionImporter.cs	(revision 3746)
@@ -32,5 +32,8 @@
 namespace HeuristicLab.Problems.DataAnalysis.Tests {
   internal class SymbolicExpressionImporter {
-    private const string VARSTART = "var";
+    private const string VARSTART = "VAR";
+    private const string DEFUNSTART = "DEFUN";
+    private const string ARGSTART = "ARG";
+    private const string INVOKESTART = "CALL";
     private Dictionary<string, Symbol> knownSymbols = new Dictionary<string, Symbol>() 
       {
@@ -39,8 +42,12 @@
         {"*", new Multiplication()},
         {"-", new Subtraction()},
+        {"PROG", new ProgramRootSymbol()},
+        {"MAIN", new StartSymbol()}
+      };
 
-      };
     Constant constant = new Constant();
     Variable variable = new Variable();
+    Defun defun = new Defun();
+
     ProgramRootSymbol programRootSymbol = new ProgramRootSymbol();
     StartSymbol startSymbol = new StartSymbol();
@@ -54,6 +61,12 @@
       SymbolicExpressionTreeNode start = startSymbol.CreateTreeNode();
       SymbolicExpressionTreeNode mainBranch = ParseSexp(new Queue<Token>(GetTokenStream(str)));
-      root.AddSubTree(start);
-      start.AddSubTree(mainBranch);
+      if (mainBranch.Symbol is ProgramRootSymbol) {
+        // when a root symbol was parsed => use main branch as root
+        root = mainBranch;
+      } else {
+        // only a main branch was given => insert the main branch into the default tree template
+        root.AddSubTree(start);
+        start.AddSubTree(mainBranch);
+      }
       return new SymbolicExpressionTree(root);
     }
@@ -73,4 +86,16 @@
         if (tokens.Peek().StringValue.StartsWith(VARSTART)) {
           tree = ParseVariable(tokens);
+        } else if (tokens.Peek().StringValue.StartsWith(DEFUNSTART)) {
+          tree = ParseDefun(tokens);
+          while (!tokens.Peek().Equals(Token.RPAR)) {
+            tree.AddSubTree(ParseSexp(tokens));
+          }
+        } else if (tokens.Peek().StringValue.StartsWith(ARGSTART)) {
+          tree = ParseArgument(tokens);
+        } else if (tokens.Peek().StringValue.StartsWith(INVOKESTART)) {
+          tree = ParseInvoke(tokens);
+          while (!tokens.Peek().Equals(Token.RPAR)) {
+            tree.AddSubTree(ParseSexp(tokens));
+          }
         } else {
           Token curToken = tokens.Dequeue();
@@ -89,7 +114,31 @@
     }
 
+    private SymbolicExpressionTreeNode ParseInvoke(Queue<Token> tokens) {
+      Token invokeTok = tokens.Dequeue();
+      Debug.Assert(invokeTok.StringValue == "CALL");
+      InvokeFunction invokeSym = new InvokeFunction(tokens.Dequeue().StringValue);
+      SymbolicExpressionTreeNode invokeNode = invokeSym.CreateTreeNode();
+      return invokeNode;
+    }
+
+    private SymbolicExpressionTreeNode ParseArgument(Queue<Token> tokens) {
+      Token argTok = tokens.Dequeue();
+      Debug.Assert(argTok.StringValue == "ARG");
+      Argument argument = new Argument((int)tokens.Dequeue().DoubleValue);
+      SymbolicExpressionTreeNode argNode = argument.CreateTreeNode();
+      return argNode;
+    }
+
+    private SymbolicExpressionTreeNode ParseDefun(Queue<Token> tokens) {
+      Token defTok = tokens.Dequeue();
+      Debug.Assert(defTok.StringValue == "DEFUN");
+      DefunTreeNode t = (DefunTreeNode)defun.CreateTreeNode();
+      t.FunctionName = tokens.Dequeue().StringValue;
+      return t;
+    }
+
     private SymbolicExpressionTreeNode ParseVariable(Queue<Token> tokens) {
       Token varTok = tokens.Dequeue();
-      Debug.Assert(varTok.StringValue == "variable");
+      Debug.Assert(varTok.StringValue == "VARIABLE");
       VariableTreeNode t = (VariableTreeNode)variable.CreateTreeNode();
       t.Weight = tokens.Dequeue().DoubleValue;
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/Token.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/Token.cs	(revision 3745)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/Token.cs	(revision 3746)
@@ -62,4 +62,5 @@
       } else {
         t.Symbol = TokenSymbol.SYMB;
+        t.StringValue = t.StringValue.ToUpper();
       }
       return t;
