Index: /trunk/sources/HeuristicLab.Problems.LawnMower/3.3/Interpreter.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.LawnMower/3.3/Interpreter.cs	(revision 8130)
+++ /trunk/sources/HeuristicLab.Problems.LawnMower/3.3/Interpreter.cs	(revision 8131)
@@ -21,4 +21,6 @@
 
 using System;
+using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 
@@ -51,5 +53,5 @@
       mowerState.Energy = length * width * 2;
       lawn[mowerState.Position.Item1, mowerState.Position.Item2] = true;
-      EvaluateLawnMowerProgram(tree.Root, ref mowerState, lawn);
+      EvaluateLawnMowerProgram(tree.Root, ref mowerState, lawn, tree.Root.Subtrees.Skip(1).ToArray());
 
       return lawn;
@@ -57,11 +59,11 @@
 
 
-    private static Tuple<int, int> EvaluateLawnMowerProgram(ISymbolicExpressionTreeNode node, ref MowerState mowerState, bool[,] lawn) {
+    private static Tuple<int, int> EvaluateLawnMowerProgram(ISymbolicExpressionTreeNode node, ref MowerState mowerState, bool[,] lawn, IEnumerable<ISymbolicExpressionTreeNode> adfs) {
       if (mowerState.Energy <= 0) return new Tuple<int, int>(0, 0);
 
       if (node.Symbol is ProgramRootSymbol) {
-        return EvaluateLawnMowerProgram(node.GetSubtree(0), ref mowerState, lawn);
+        return EvaluateLawnMowerProgram(node.GetSubtree(0), ref mowerState, lawn, adfs);
       } else if (node.Symbol is StartSymbol) {
-        return EvaluateLawnMowerProgram(node.GetSubtree(0), ref mowerState, lawn);
+        return EvaluateLawnMowerProgram(node.GetSubtree(0), ref mowerState, lawn, adfs);
       } else if (node.Symbol is Left) {
         switch (mowerState.Heading) {
@@ -104,13 +106,13 @@
         return constNode.Value;
       } else if (node.Symbol is Sum) {
-        var p = EvaluateLawnMowerProgram(node.GetSubtree(0), ref mowerState, lawn);
-        var q = EvaluateLawnMowerProgram(node.GetSubtree(1), ref mowerState, lawn);
+        var p = EvaluateLawnMowerProgram(node.GetSubtree(0), ref mowerState, lawn, adfs);
+        var q = EvaluateLawnMowerProgram(node.GetSubtree(1), ref mowerState, lawn, adfs);
         return new Tuple<int, int>(p.Item1 + q.Item1,
           p.Item2 + q.Item2);
       } else if (node.Symbol is Prog) {
-        EvaluateLawnMowerProgram(node.GetSubtree(0), ref mowerState, lawn);
-        return EvaluateLawnMowerProgram(node.GetSubtree(1), ref mowerState, lawn);
+        EvaluateLawnMowerProgram(node.GetSubtree(0), ref mowerState, lawn, adfs);
+        return EvaluateLawnMowerProgram(node.GetSubtree(1), ref mowerState, lawn, adfs);
       } else if (node.Symbol is Frog) {
-        var p = EvaluateLawnMowerProgram(node.GetSubtree(0), ref mowerState, lawn);
+        var p = EvaluateLawnMowerProgram(node.GetSubtree(0), ref mowerState, lawn, adfs);
 
         uint newRow = (uint)((mowerState.Position.Item1 + lawn.GetLength(0) + p.Item1 % lawn.GetLength(0)) % lawn.GetLength(0));
@@ -120,9 +122,30 @@
         lawn[newRow, newCol] = true;
         return new Tuple<int, int>(0, 0);
+      } else if (node.Symbol is InvokeFunction) {
+        var invokeNode = node as InvokeFunctionTreeNode;
+
+        // find the function definition for the invoke call
+        var functionDefinition = (from adf in adfs.Cast<DefunTreeNode>()
+                                  where adf.FunctionName == invokeNode.Symbol.FunctionName
+                                  select adf).Single();
+        // clone the function definition because we are replacing the argument nodes
+        functionDefinition = (DefunTreeNode) functionDefinition.Clone();
+        // find the argument tree nodes and their parents in the original function definition
+        // toList is necessary to prevent that newly inserted branches are iterated
+        var argumentCutPoints = (from parent in functionDefinition.IterateNodesPrefix()
+                                 from subtree in parent.Subtrees
+                                 where subtree is ArgumentTreeNode
+                                 select new { Parent = parent, Argument = subtree.Symbol as Argument, ChildIndex = parent.IndexOfSubtree(subtree) })
+                                 .ToList();
+        // replace all argument tree ndoes with the matching argument of the invoke node
+        foreach (var cutPoint in argumentCutPoints) {
+          cutPoint.Parent.RemoveSubtree(cutPoint.ChildIndex);
+          cutPoint.Parent.InsertSubtree(cutPoint.ChildIndex, (SymbolicExpressionTreeNode)invokeNode.GetSubtree(cutPoint.Argument.ArgumentIndex).Clone());
+        }
+        return EvaluateLawnMowerProgram(functionDefinition.GetSubtree(0), ref mowerState, lawn, adfs);
       } else {
         throw new ArgumentException("Invalid symbol in the lawn mower program.");
       }
     }
-
   }
 }
Index: /trunk/sources/HeuristicLab.Problems.LawnMower/3.3/Problem.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.LawnMower/3.3/Problem.cs	(revision 8130)
+++ /trunk/sources/HeuristicLab.Problems.LawnMower/3.3/Problem.cs	(revision 8131)
@@ -42,4 +42,6 @@
     private const string MaxLawnMowerProgramDepthParameterName = "MaxProgramDepth";
     private const string LawnMowerGrammarParameterName = "Grammar";
+    private const string MaxFunctionDefinitionsParameterName = "MaxFunctionDefinitions";
+    private const string MaxArgumentDefinitionsParameterName = "MaxArgumentDefinitions";
 
     public IFixedValueParameter<IntValue> LawnWidthParameter {
@@ -58,4 +60,10 @@
       get { return (IValueParameter<Grammar>)Parameters[LawnMowerGrammarParameterName]; }
     }
+    public IFixedValueParameter<IntValue> MaxFunctionDefinitionsParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[MaxFunctionDefinitionsParameterName]; }
+    }
+    public IFixedValueParameter<IntValue> MaxArgumentDefinitionsParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[MaxArgumentDefinitionsParameterName]; }
+    }
 
     [StorableConstructor]
@@ -73,4 +81,6 @@
       Parameters.Add(new FixedValueParameter<IntValue>(MaxLawnMowerProgramDepthParameterName, "Maximal depth of the lawn mower program.", new IntValue(13)));
       Parameters.Add(new FixedValueParameter<IntValue>(MaxLawnMowerProgramLengthParameterName, "Maximal length of the lawn mower program.", new IntValue(1000)));
+      Parameters.Add(new FixedValueParameter<IntValue>(MaxFunctionDefinitionsParameterName, "Maximal number of automatically defined functions (ADF).", new IntValue(3)));
+      Parameters.Add(new FixedValueParameter<IntValue>(MaxArgumentDefinitionsParameterName, "Maximal number of automatically defined arguments.", new IntValue(3)));
       Parameters.Add(new ValueParameter<Grammar>(LawnMowerGrammarParameterName, "Grammar for the lawn mower program.",
                      new Grammar()));
@@ -105,7 +115,7 @@
       SolutionCreator.SymbolicExpressionTreeParameter.ActualNameChanged +=
         SymbolicExpressionTreeParameterOnActualNameChanged;
+      MaxArgumentDefinitionsParameter.ValueChanged += ParameterizeGrammar;
+      MaxFunctionDefinitionsParameter.ValueChanged += ParameterizeGrammar;
     }
-
-
 
     protected override void OnEvaluatorChanged() {
@@ -135,4 +145,9 @@
       ParameterizeAnalyzers();
       ParameterizeOperators();
+    }
+
+    private void ParameterizeGrammar(object sender, EventArgs eventArgs) {
+      GrammarParameter.Value.MaximumFunctionArguments = MaxArgumentDefinitionsParameter.Value.Value;
+      GrammarParameter.Value.MaximumFunctionDefinitions = MaxFunctionDefinitionsParameter.Value.Value;
     }
 
@@ -175,4 +190,8 @@
         op.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
       }
+      foreach (ISymbolicExpressionTreeArchitectureAlteringOperator op in operators.OfType<ISymbolicExpressionTreeArchitectureAlteringOperator>()) {
+        op.MaximumFunctionDefinitionsParameter.ActualName = MaxFunctionDefinitionsParameter.Name;
+        op.MaximumFunctionArgumentsParameter.ActualName = MaxArgumentDefinitionsParameter.Name;
+      }
     }
   }
