Index: branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/HeuristicLab.Algorithms.DataAnalysis.PGE-3.3.csproj
===================================================================
--- branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/HeuristicLab.Algorithms.DataAnalysis.PGE-3.3.csproj	(revision 16231)
+++ branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/HeuristicLab.Algorithms.DataAnalysis.PGE-3.3.csproj	(revision 16315)
@@ -72,4 +72,8 @@
       <HintPath>..\..\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
     </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\bin\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.dll</HintPath>
+    </Reference>
     <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -103,4 +107,8 @@
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425B4-4348-49ED-A457-B7D2C26DDBF9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Problems.Instances\3.3\HeuristicLab.Problems.Instances-3.3.csproj">
       <Project>{3540E29E-4793-49E7-8EE2-FEA7F61C3994}</Project>
Index: branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/PGE.cs
===================================================================
--- branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/PGE.cs	(revision 16231)
+++ branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/PGE.cs	(revision 16315)
@@ -3,13 +3,16 @@
 using System.Linq;
 using System.Runtime.InteropServices;
-using System.Text;
 using System.Threading;
+using HeuristicLab.Analysis;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Optimization; 
+using System.Text.RegularExpressions;
+using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Problems.DataAnalysis;     
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
 
 namespace PGE {
@@ -18,5 +21,5 @@
   [Creatable(Category = CreatableAttribute.Categories.Algorithms, Priority = 999)]
 
-  [StorableClass] 
+  [StorableClass]
   public unsafe class PGE : BasicAlgorithm {
 
@@ -49,5 +52,5 @@
 
     #region parameter names
-    private static readonly string MaxIterationsParameterName = "MaxIterations";                      
+    private static readonly string MaxIterationsParameterName = "MaxIterations";
     private static readonly string MaxGenParameterName = "MaxGen";
     private static readonly string EvalrCountParameterName = "EvalrCount";
@@ -55,5 +58,4 @@
     private static readonly string MinSizeParameterName = "MinSize";
     private static readonly string MaxDepthParameterName = "MaxDepth";
-    private static readonly string SearchVarParameterName = "SearchVar";
     private static readonly string MinDepthParameterName = "MinDepth";
     private static readonly string PgeRptEpochParameterName = "PgeRptEpoch";
@@ -62,5 +64,5 @@
     private static readonly string PeelCntParameterName = "PeelCnt";
     private static readonly string ZeroEpsilonParameterName = "ZeroEpsilon";
-    private static readonly string HitRatioParameterName = "HitRatio";                
+    private static readonly string HitRatioParameterName = "HitRatio";
     private static readonly string InitMethodParameterName = "InitMethod";
     private static readonly string GrowMethodParameterName = "GrowMethod";
@@ -121,12 +123,4 @@
     }
 
-    private IFixedValueParameter<IntValue> SearchVarParameter {
-      get { return (IFixedValueParameter<IntValue>)Parameters[SearchVarParameterName]; }
-    }
-    public int SearchVar {
-      get { return SearchVarParameter.Value.Value; }
-      set { SearchVarParameter.Value.Value = value; }
-    }
-
     private IFixedValueParameter<IntValue> MinDepthParameter {
       get { return (IFixedValueParameter<IntValue>)Parameters[MinDepthParameterName]; }
@@ -240,5 +234,4 @@
       // algorithm parameters are shown in the GUI
       Parameters.Add(new FixedValueParameter<IntValue>(MaxIterationsParameterName, new IntValue(50)));
-      Parameters.Add(new FixedValueParameter<IntValue>(SearchVarParameterName, new IntValue(0)));
       Parameters.Add(new FixedValueParameter<IntValue>(MinDepthParameterName, new IntValue(1)));
       Parameters.Add(new FixedValueParameter<IntValue>(MaxDepthParameterName, new IntValue(6)));
@@ -250,6 +243,6 @@
       Parameters.Add(new FixedValueParameter<IntValue>(PgeRptCountParameterName, new IntValue(20)));
       Parameters.Add(new FixedValueParameter<IntValue>(PgeRptEpochParameterName, new IntValue(1)));
-      Parameters.Add(new FixedValueParameter<IntValue>(MaxGenParameterName, new IntValue(200)));               
-                                                                                                                                     
+      Parameters.Add(new FixedValueParameter<IntValue>(MaxGenParameterName, new IntValue(200)));
+
       Parameters.Add(new FixedValueParameter<StringValue>(InitMethodParameterName, new StringValue("method1")));  // TODO Dropdown
       Parameters.Add(new FixedValueParameter<StringValue>(GrowMethodParameterName, new StringValue("method1")));
@@ -264,10 +257,10 @@
     }
 
- 
+
     [StorableConstructor]
     public PGE(bool deserializing) : base(deserializing) { }
 
-   
-    public PGE(PGE original, Cloner cloner) : base(original, cloner) {    
+
+    public PGE(PGE original, Cloner cloner) : base(original, cloner) {
       // nothing to clone
     }
@@ -278,4 +271,26 @@
 
     protected override void Run(CancellationToken cancellationToken) {
+      Log log = new Log();
+      Results.Add(new Result("Log", log));
+      var iterationsResult = new IntValue(0);
+      Results.Add(new Result("Iteration", iterationsResult));
+      var bestTestScoreResult = new IntValue(0); // TODO: why is test score an int?
+      Results.Add(new Result("Best test score", bestTestScoreResult));
+      var testScoresTable = new DataTable("Test scores");
+      var bestTestScoreRow = new DataRow("Best test score");
+      var curTestScoreRow = new DataRow("Current test score");
+      testScoresTable.Rows.Add(bestTestScoreRow);
+      testScoresTable.Rows.Add(curTestScoreRow);
+      Results.Add(new Result("Test scores", testScoresTable));
+      var lengthsTable = new DataTable("Lengths");
+      var len1Row = new DataRow("Length 1");
+      var len2Row = new DataRow("Length 2");
+      lengthsTable.Rows.Add(len1Row);
+      lengthsTable.Rows.Add(len2Row);
+      Results.Add(new Result("Lengths", lengthsTable));
+
+      var bestSolutionResult = new Result("Best solution", typeof(IRegressionSolution));
+      Results.Add(bestSolutionResult);
+
       // TODO: the following is potentially problematic for other go processes run on the same machine at the same time
       // shouldn't be problematic bc is inherited only, normally only child processes are affected
@@ -287,5 +302,5 @@
 
       //Constants
-      int sortType = 0;
+      int sortType = 0; // TODO what's sort type?
       string problemTypeString = "benchmark";
       int numProc = 12;
@@ -304,12 +319,12 @@
       nTestData = Problem.ProblemData.TestPartition.Size;
 
-      var inputVariableNames = string.Join(" ", problemData.AllowedInputVariables); 
-      // TODO: does this work when input variables contain spaces?
-      // is split on the go side, just for simpler passing
+      if (problemData.AllowedInputVariables.Any(iv => iv.Contains(" ")))
+        throw new NotSupportedException("PGE does not support variable names which contain spaces");
+
+      var inputVariableNames = string.Join(" ", problemData.AllowedInputVariables);
 
       IntPtr cIndepNames = Marshal.StringToHGlobalAnsi(inputVariableNames);
       IntPtr cDependentNames = Marshal.StringToHGlobalAnsi(problemData.TargetVariable);
-      // TODO: is it ok to use any variable here?
-      // Dependent- and Independentnames are the variables from the test/train data, e.g. from "Korns_02.trn" dep: x y z v w  indep: f(xs)
+      // Dependent- and Independentnames are the variables from the test/train data, e.g. from "Korns_02.trn" indep: x y z v w  dep: f(xs)
 
       IntPtr cInitMethod = Marshal.StringToHGlobalAnsi(InitMethod);
@@ -326,5 +341,4 @@
 
       AddTestData(cIndepNames, cDependentNames, testData, nTestData);
-
       AddTrainData(cIndepNames, cDependentNames, trainData, nTrainData);
 
@@ -334,21 +348,21 @@
       InitSearch(MaxGen, PgeRptEpoch, PgeRptCount, PgeArchiveCap, PeelCnt, EvalrCount, ZeroEpsilon, cInitMethod, cGrowMethod, sortType);
 
-      // cUsableVars: list of indices into dependent variables
+      // cUsableVars: list of indices into independent variables
       InitTreeParams(cRoots, cNodes, cNonTrig, cLeafs, cUseableVars, numberOfUseableVariables, MaxSize, MinSize, MaxDepth, MinDepth);
 
-      // SearchVar: list of indices into independent variables (0 for first index)
-      InitProblem(cName, MaxIterations, HitRatio, SearchVar, cProblemTypeString, numProc);
-
-      var curItersItem = new IntValue();
+      
+      InitProblem(cName, MaxIterations, HitRatio, 
+        searchVar: numberOfUseableVariables,  // SearchVar: index of dependent variables (0 for first index), we use the convention to put the target at the end
+        ProblemTypeString: cProblemTypeString, numProcs: numProc);
 
       for (int iter = 1; iter <= MaxIterations; iter++) {
-        curItersItem.Value = iter;
+        iterationsResult.Value = iter;
 
         int nResults = StepW();
 
-        for (int iResult = 0; iResult < nResults; iResult++) { 
+        for (int iResult = 0; iResult < nResults; iResult++) {
           int nobestpush = 0;       //bool
           int bestNewMinError = 0;  //bool
-          int bestlen1 = 0; 
+          int bestlen1 = 0;
           int bestlen2 = 0;
           int nCoeff = 0;
@@ -356,23 +370,22 @@
 
           IntPtr eqn = GetStepResult(out nobestpush, out bestNewMinError, out bestlen1, out bestlen2, out testScore, out nCoeff);
-
           string eqnStr = Marshal.PtrToStringAnsi(eqn);
 
-          Console.WriteLine("Push/Pop (" + bestlen1 + "," + bestlen2 + ") " + eqnStr);
-          StringBuilder sb = new StringBuilder("");
+          double[] coeff = new double[nCoeff];
           for (int iCoeff = 0; iCoeff < nCoeff; iCoeff++) {
-            double coeffVal = GetCoeffResult();
-            Console.WriteLine("Coeff: " + coeffVal);
-            sb.Append(coeffVal + "; ");
+            coeff[iCoeff] = GetCoeffResult();
           }
-
-          var curItersResult = new Result("Iteration " + iter + " " + iResult, curItersItem);
-          var coeffItersResult = new Result("Coeff " + iter + " " + iResult, new StringValue(sb.ToString()));
-
-          var bestQualityItem = new StringValue(eqnStr);
-          var bestQualityResult = new Result("Best quality " + iter + " " + iResult, bestQualityItem);
-          Results.Add(curItersResult);
-          Results.Add(coeffItersResult);
-          Results.Add(bestQualityResult);
+          log.LogMessage("Push/Pop (" + iResult + ", " + bestlen1 + ", " + bestlen2 + ", " + testScore + ", noBestPush: " + (nobestpush > 0) + ", bestNewMin: " + (bestNewMinError > 0) + ") " + eqnStr + " coeff: " + string.Join(" ", coeff));
+
+          if (bestNewMinError > 0) {
+            // update best quality
+            bestTestScoreResult.Value = testScore;
+            var sol = CreateSolution(problemData, eqnStr, coeff, problemData.AllowedInputVariables.ToArray());
+            bestSolutionResult.Value = sol;
+          }
+          bestTestScoreRow.Values.Add(bestTestScoreResult.Value); // always add the current best test score to data row
+          curTestScoreRow.Values.Add(testScore);
+          len1Row.Values.Add(bestlen1);
+          len2Row.Values.Add(bestlen2);
         }
 
@@ -401,4 +414,36 @@
     }
 
+    private static readonly Regex varRegex = new Regex(@"X_(\d)+");
+    private static readonly Regex coeffRegex = new Regex(@"C_(\d)+");
+
+    private IRegressionSolution CreateSolution(IRegressionProblemData problemData, string eqnStr, double[] coeff, string[] usableVariables) {
+      // coefficients are named e.g. "C_0" in the PGE expressions
+      // -> replace all patterns "C_\d" by the corresponding coefficients
+      var match = coeffRegex.Match(eqnStr);
+      while (match.Success) {
+        var coeffIdx = int.Parse(match.Groups[1].ToString());
+        eqnStr = eqnStr.Substring(0, match.Index) +
+          "(" + coeff[coeffIdx].ToString(System.Globalization.CultureInfo.InvariantCulture) + ")" +
+          eqnStr.Substring(match.Index + match.Length);
+        match = coeffRegex.Match(eqnStr);
+      }
+
+      // variables are named e.g. "X_0" in the PGE expressions
+      // -> replace all patterns "X_\d" by the corresponding variable name
+      match = varRegex.Match(eqnStr);
+      while (match.Success) {
+        var varIdx = int.Parse(match.Groups[1].ToString());
+        eqnStr = eqnStr.Substring(0, match.Index) +
+          "'" + usableVariables[varIdx] + "'" +
+          eqnStr.Substring(match.Index + match.Length);
+        match = varRegex.Match(eqnStr);
+      }
+
+      var parser = new InfixExpressionParser();
+      var tree = parser.Parse(eqnStr);
+      var model = new SymbolicRegressionModel(problemData.TargetVariable, tree, new SymbolicDataAnalysisExpressionTreeLinearInterpreter());
+      return model.CreateRegressionSolution((IRegressionProblemData)problemData.Clone());
+    }
+
     public override bool SupportsPause {
       get { return false; }
@@ -423,7 +468,7 @@
       double[] val = new double[rows.Count() * dim];
       int r = 0;
-      foreach(var row in rows) {
+      foreach (var row in rows) {
         int c = 0;
-        foreach(var var in variableNames) {
+        foreach (var var in variableNames) {
           val[r * dim + c] = ds.GetDoubleValue(var, r);
           c++;
Index: branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/Plugin.cs
===================================================================
--- branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/Plugin.cs	(revision 16231)
+++ branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/Plugin.cs	(revision 16315)
@@ -3,12 +3,8 @@
 namespace HeuristicLab.Algorithms.DataAnalysis.PGE {
   [Plugin("HeuristicLab.Algorithms.DataAnalysis.PGE", "3.3")]
-  [PluginFile("HeuristicLab.Algorithms.DataAnalysis.PGE-3.3.dll", PluginFileType.Assembly)] // each plugin represents a collection of files. The minimum is one file; the assembly.
+  [PluginFile("HeuristicLab.Algorithms.DataAnalysis.PGE-3.3.dll", PluginFileType.Assembly)] 
+  [PluginFile("go-pge.dll", PluginFileType.NativeDll)]
 
-  // Usually your plugin references other HeuristicLab dlls. If you are referencing files (e.g. assemblies)
-  // from another plugin the corresponding plugin should be added as a dependency.
-  // Usually, if this information is incorrect you will still be able to use you plugin, but HL functionality
-  // which uses plugin dependency resolution will not work correctly. For instance if plugin dependencies are
-  // not correct then your plugin cannot be used on HeuristicLab.Hive
-  // 
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
   [PluginDependency("HeuristicLab.Collections", "3.3")]
   [PluginDependency("HeuristicLab.Common", "3.3")]
@@ -20,18 +16,9 @@
   [PluginDependency("HeuristicLab.Persistence", "3.3")]
   [PluginDependency("HeuristicLab.Problems.DataAnalysis", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic", "3.4")]
   [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.Instances", "3.3")]
   [PluginDependency("HeuristicLab.Random", "3.3")]
 
-  // HL plugin infrastructure discovers plugins on startup by trying to load all .dll and .exe files and looking for 
-  // classes deriving from PluginBase. The meta-information for the plugin class is specified in the attributes
-  // above and used by plugin infrastructure primarily for plugin dependency resolution.
-
-  // Steps:
-  // (1) Check out HL source code (e.g. the trunk version)
-  // (2) Build external libraries HeuristicLab.ExtLibs.sln using the Build.cmd (in the path of the HL source code)
-  // (3) Build HeuristicLab 3.3.sln using the Build.cmd
-  // (4) Check that the output file has been added to the HL binaries folder (hl/bin/HeuristicLab.Algorithms.DataAnalysis.PGE-3.3.dll)
-  // (5) Start hl/bin/HeuristicLab.exe and open the "Plugin Manager".
-  //      Make sure your EmptyPlugin appears in the list of loaded plugins 
   public class Plugin : PluginBase {
   }
