Index: branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningOperator.cs
===================================================================
--- branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningOperator.cs	(revision 16134)
+++ branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningOperator.cs	(revision 17687)
@@ -1,20 +1,44 @@
-﻿using System.Linq;
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
-  [StorableClass]
+  [StorableType("75843B4E-C69C-423A-87BD-A64619D380BB")]
   [Item("SymbolicRegressionPruningOperator", "An operator which prunes symbolic regression trees.")]
   public class SymbolicRegressionPruningOperator : SymbolicDataAnalysisExpressionPruningOperator {
-    private const string ImpactValuesCalculatorParameterName = "ImpactValuesCalculator";
-    private const string ImpactValuesCalculatorParameterDescription = "The impact values calculator to be used for figuring out the node impacts.";
-
     private const string EvaluatorParameterName = "Evaluator";
 
+    #region parameter properties
     public ILookupParameter<ISymbolicRegressionSingleObjectiveEvaluator> EvaluatorParameter {
       get { return (ILookupParameter<ISymbolicRegressionSingleObjectiveEvaluator>)Parameters[EvaluatorParameterName]; }
     }
+    #endregion
 
     protected SymbolicRegressionPruningOperator(SymbolicRegressionPruningOperator original, Cloner cloner)
@@ -26,26 +50,63 @@
 
     [StorableConstructor]
-    protected SymbolicRegressionPruningOperator(bool deserializing) : base(deserializing) { }
+    protected SymbolicRegressionPruningOperator(StorableConstructorFlag _) : base(_) { }
 
-    public SymbolicRegressionPruningOperator() {
-      var impactValuesCalculator = new SymbolicRegressionSolutionImpactValuesCalculator();
-      Parameters.Add(new ValueParameter<ISymbolicDataAnalysisSolutionImpactValuesCalculator>(ImpactValuesCalculatorParameterName, ImpactValuesCalculatorParameterDescription, impactValuesCalculator));
+    public SymbolicRegressionPruningOperator(ISymbolicDataAnalysisSolutionImpactValuesCalculator impactValuesCalculator)
+      : base(impactValuesCalculator) {
       Parameters.Add(new LookupParameter<ISymbolicRegressionSingleObjectiveEvaluator>(EvaluatorParameterName));
     }
 
-    protected override ISymbolicDataAnalysisModel CreateModel() {
-      return new SymbolicRegressionModel(SymbolicExpressionTree, Interpreter, EstimationLimits.Lower, EstimationLimits.Upper);
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      base.ImpactValuesCalculator = new SymbolicRegressionSolutionImpactValuesCalculator();
+      if (!Parameters.ContainsKey(EvaluatorParameterName)) {
+        Parameters.Add(new LookupParameter<ISymbolicRegressionSingleObjectiveEvaluator>(EvaluatorParameterName));
+      }
+      #endregion
+    }
+
+    protected override ISymbolicDataAnalysisModel CreateModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IDataAnalysisProblemData problemData, DoubleLimit estimationLimits) {
+      var regressionProblemData = (IRegressionProblemData)problemData;
+      return new SymbolicRegressionModel(regressionProblemData.TargetVariable, tree, interpreter, estimationLimits.Lower, estimationLimits.Upper);
     }
 
     protected override double Evaluate(IDataAnalysisModel model) {
-      var regressionModel = (IRegressionModel)model;
-      var regressionProblemData = (IRegressionProblemData)ProblemData;
-      var trainingIndices = ProblemData.TrainingIndices.ToList();
-      var estimatedValues = regressionModel.GetEstimatedValues(ProblemData.Dataset, trainingIndices); // also bounds the values
-      var targetValues = ProblemData.Dataset.GetDoubleValues(regressionProblemData.TargetVariable, trainingIndices);
-      OnlineCalculatorError errorState;
-      var quality = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, estimatedValues, out errorState);
-      if (errorState != OnlineCalculatorError.None) return double.NaN;
-      return quality;
+      var regressionModel = (ISymbolicRegressionModel)model;
+      var regressionProblemData = (IRegressionProblemData)ProblemDataParameter.ActualValue;
+      var evaluator = EvaluatorParameter.ActualValue;
+      var fitnessEvaluationPartition = FitnessCalculationPartitionParameter.ActualValue;
+      var rows = Enumerable.Range(fitnessEvaluationPartition.Start, fitnessEvaluationPartition.Size);
+      return evaluator.Evaluate(this.ExecutionContext, regressionModel.SymbolicExpressionTree, regressionProblemData, rows);
+    }
+
+    public static ISymbolicExpressionTree Prune(ISymbolicExpressionTree tree, SymbolicRegressionSolutionImpactValuesCalculator impactValuesCalculator, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IRegressionProblemData problemData, DoubleLimit estimationLimits, IEnumerable<int> rows, double nodeImpactThreshold = 0.0, bool pruneOnlyZeroImpactNodes = false) {
+      var clonedTree = (ISymbolicExpressionTree)tree.Clone();
+      var model = new SymbolicRegressionModel(problemData.TargetVariable, clonedTree, interpreter, estimationLimits.Lower, estimationLimits.Upper);
+      var nodes = clonedTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList(); // skip the nodes corresponding to the ProgramRootSymbol and the StartSymbol
+
+      double qualityForImpactsCalculation = double.NaN; // pass a NaN value initially so the impact calculator will calculate the quality
+
+      for (int i = 0; i < nodes.Count; ++i) {
+        var node = nodes[i];
+        if (node is ConstantTreeNode) continue;
+
+        double impactValue, replacementValue;
+        double newQualityForImpactsCalculation;
+        impactValuesCalculator.CalculateImpactAndReplacementValues(model, node, problemData, rows, out impactValue, out replacementValue, out newQualityForImpactsCalculation, qualityForImpactsCalculation);
+
+        if (pruneOnlyZeroImpactNodes && !impactValue.IsAlmost(0.0)) continue;
+        if (!pruneOnlyZeroImpactNodes && impactValue > nodeImpactThreshold) continue;
+
+        var constantNode = (ConstantTreeNode)node.Grammar.GetSymbol("Constant").CreateTreeNode();
+        constantNode.Value = replacementValue;
+
+        ReplaceWithConstant(node, constantNode);
+        i += node.GetLength() - 1; // skip subtrees under the node that was folded
+
+        qualityForImpactsCalculation = newQualityForImpactsCalculation;
+      }
+      return model.SymbolicExpressionTree;
     }
   }
