Index: branches/DataAnalysis.IslandAlgorithms/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionPruningOperator.cs
===================================================================
--- branches/DataAnalysis.IslandAlgorithms/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionPruningOperator.cs	(revision 10390)
+++ branches/DataAnalysis.IslandAlgorithms/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionPruningOperator.cs	(revision 10579)
@@ -34,71 +34,120 @@
   [StorableClass]
   [Item("SymbolicExpressionTreePruningOperator", "An operator that replaces introns with constant values in a symbolic expression tree.")]
-  public class SymbolicDataAnalysisExpressionPruningOperator : SingleSuccessorOperator {
-    private const string NumberOfPrunedSubtreesParameterName = "PrunedSubtrees";
-    private const string NumberOfPrunedTreesParameterName = "PrunedTrees";
+  public abstract class SymbolicDataAnalysisExpressionPruningOperator : SingleSuccessorOperator {
+    #region parameter names
+    private const string ProblemDataParameterName = "ProblemData";
+    private const string SymbolicDataAnalysisModelParameterName = "SymbolicDataAnalysisModel";
+    private const string ImpactValuesCalculatorParameterName = "ImpactValuesCalculator";
+    private const string PrunedSubtreesParameterName = "PrunedSubtrees";
+    private const string PrunedTreesParameterName = "PrunedTrees";
+    private const string FitnessCalculationPartitionParameterName = "FitnessCalculationPartition";
+    private const string NodeImpactThresholdParameterName = "ImpactThreshold";
+    private const string PruneOnlyZeroImpactNodesParameterName = "PruneOnlyZeroImpactNodes";
+    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree"; // the tree to be pruned
+    private const string QualityParameterName = "Quality"; // the quality 
+    private const string EstimationLimitsParameterName = "EstimationLimits";
+    private const string InterpreterParameterName = "SymbolicExpressionTreeInterpreter";
+    #endregion
+
     #region parameter properties
-    public ILookupParameter<DoubleValue> NumberOfPrunedSubtreesParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters[NumberOfPrunedSubtreesParameterName]; }
+    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
     }
-    public ILookupParameter<DoubleValue> NumberOfPrunedTreesParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters[NumberOfPrunedTreesParameterName]; }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters[QualityParameterName]; }
+    }
+    public ILookupParameter<IDataAnalysisProblemData> ProblemDataParameter {
+      get { return (ILookupParameter<IDataAnalysisProblemData>)Parameters[ProblemDataParameterName]; }
+    }
+    public IValueParameter<ISymbolicDataAnalysisSolutionImpactValuesCalculator> ImpactValuesCalculatorParameter {
+      get { return (IValueParameter<ISymbolicDataAnalysisSolutionImpactValuesCalculator>)Parameters[ImpactValuesCalculatorParameterName]; }
+    }
+    public ILookupParameter<IntRange> FitnessCalculationPartitionParameter {
+      get { return (ILookupParameter<IntRange>)Parameters[FitnessCalculationPartitionParameterName]; }
+    }
+    public ILookupParameter<IntValue> PrunedSubtreesParameter {
+      get { return (ILookupParameter<IntValue>)Parameters[PrunedSubtreesParameterName]; }
+    }
+    public ILookupParameter<IntValue> PrunedTreesParameter {
+      get { return (ILookupParameter<IntValue>)Parameters[PrunedTreesParameterName]; }
+    }
+    public IFixedValueParameter<DoubleValue> NodeImpactThresholdParameter {
+      get { return (IFixedValueParameter<DoubleValue>)Parameters[NodeImpactThresholdParameterName]; }
+    }
+    public IFixedValueParameter<BoolValue> PruneOnlyZeroImpactNodesParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[PruneOnlyZeroImpactNodesParameterName]; }
+    }
+    public ILookupParameter<DoubleLimit> EstimationLimitsParameter {
+      get { return (ILookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
+    }
+    public ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> InterpreterParameter {
+      get { return (ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[InterpreterParameterName]; }
     }
     #endregion
     #region properties
-    private DoubleValue PrunedSubtrees { get { return NumberOfPrunedSubtreesParameter.ActualValue; } }
-    private DoubleValue PrunedTrees { get { return NumberOfPrunedTreesParameter.ActualValue; } }
+    protected IDataAnalysisProblemData ProblemData { get { return ProblemDataParameter.ActualValue; } }
+    protected ISymbolicDataAnalysisSolutionImpactValuesCalculator ImpactValuesCalculator { get { return ImpactValuesCalculatorParameter.Value; } }
+    protected IntRange FitnessCalculationPartition { get { return FitnessCalculationPartitionParameter.ActualValue; } }
+    protected BoolValue PruneOnlyZeroImpactNodes { get { return PruneOnlyZeroImpactNodesParameter.Value; } }
+    protected DoubleValue NodeImpactThreshold { get { return NodeImpactThresholdParameter.Value; } }
+    protected ISymbolicExpressionTree SymbolicExpressionTree { get { return SymbolicExpressionTreeParameter.ActualValue; } }
+    protected DoubleValue Quality { get { return QualityParameter.ActualValue; } }
+    protected DoubleLimit EstimationLimits { get { return EstimationLimitsParameter.ActualValue; } }
+    protected ISymbolicDataAnalysisExpressionTreeInterpreter Interpreter { get { return InterpreterParameter.ActualValue; } }
     #endregion
 
     [StorableConstructor]
     protected SymbolicDataAnalysisExpressionPruningOperator(bool deserializing) : base(deserializing) { }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SymbolicDataAnalysisExpressionPruningOperator(this, cloner);
+    protected SymbolicDataAnalysisExpressionPruningOperator(SymbolicDataAnalysisExpressionPruningOperator original, Cloner cloner)
+      : base(original, cloner) { }
+
+    protected SymbolicDataAnalysisExpressionPruningOperator() {
+      #region add parameters
+      Parameters.Add(new LookupParameter<IDataAnalysisProblemData>(ProblemDataParameterName));
+      Parameters.Add(new LookupParameter<ISymbolicDataAnalysisModel>(SymbolicDataAnalysisModelParameterName));
+      Parameters.Add(new LookupParameter<IntRange>(FitnessCalculationPartitionParameterName));
+      Parameters.Add(new LookupParameter<IntValue>(PrunedSubtreesParameterName, "A counter of how many subtrees were replaced."));
+      Parameters.Add(new LookupParameter<IntValue>(PrunedTreesParameterName, "A counter of how many trees were pruned."));
+      Parameters.Add(new FixedValueParameter<BoolValue>(PruneOnlyZeroImpactNodesParameterName, "Specify whether or not only zero impact nodes should be pruned."));
+      Parameters.Add(new FixedValueParameter<DoubleValue>(NodeImpactThresholdParameterName, "Specifies an impact value threshold below which nodes should be pruned."));
+      Parameters.Add(new LookupParameter<DoubleLimit>(EstimationLimitsParameterName));
+      Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(InterpreterParameterName));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName));
+      Parameters.Add(new LookupParameter<DoubleValue>(QualityParameterName));
+      #endregion
     }
-    protected SymbolicDataAnalysisExpressionPruningOperator(SymbolicDataAnalysisExpressionPruningOperator original, Cloner cloner)
-      : base(original, cloner) {
-    }
+    public override IOperation Apply() {
+      var model = CreateModel();
+      var nodes = SymbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList();
+      var rows = Enumerable.Range(FitnessCalculationPartition.Start, FitnessCalculationPartition.Size).ToList();
 
-    public SymbolicDataAnalysisExpressionPruningOperator() {
-      Parameters.Add(new LookupParameter<DoubleValue>(NumberOfPrunedSubtreesParameterName));
-      Parameters.Add(new LookupParameter<DoubleValue>(NumberOfPrunedTreesParameterName));
-    }
+      var prunedSubtrees = 0;
+      var prunedTrees = 0;
 
-    public ISymbolicDataAnalysisModel Model { get; set; }
-    public IDataAnalysisProblemData ProblemData { get; set; }
-    public ISymbolicDataAnalysisSolutionImpactValuesCalculator ImpactsCalculator { get; set; }
-    public IRandom Random { get; set; }
+      double quality = Evaluate(model);
 
-    public bool PruneOnlyZeroImpactNodes { get; set; }
-    public double NodeImpactThreshold { get; set; }
-
-    public override IOperation Apply() {
-      int prunedSubtrees = 0;
-
-      var nodes = Model.SymbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList();
-
-      for (int j = 0; j < nodes.Count; ++j) {
-        var node = nodes[j];
+      for (int i = 0; i < nodes.Count; ++i) {
+        var node = nodes[i];
         if (node is ConstantTreeNode) continue;
 
-        var impact = ImpactsCalculator.CalculateImpactValue(Model, node, ProblemData, ProblemData.TrainingIndices);
+        double impactValue, replacementValue;
+        ImpactValuesCalculator.CalculateImpactAndReplacementValues(model, node, ProblemData, rows, out impactValue, out replacementValue, quality);
 
-        if (PruneOnlyZeroImpactNodes) {
-          if (!impact.IsAlmost(0.0)) continue;
-        } else {
-          if (NodeImpactThreshold < impact) continue;
-        }
+        if (PruneOnlyZeroImpactNodes.Value && (!impactValue.IsAlmost(0.0))) continue;
+        else if (NodeImpactThreshold.Value < impactValue) continue;
 
-        var replacementValue = ImpactsCalculator.CalculateReplacementValue(Model, node, ProblemData, ProblemData.TrainingIndices);
         var constantNode = new ConstantTreeNode(new Constant()) { Value = replacementValue };
         ReplaceWithConstant(node, constantNode);
-        j += node.GetLength() - 1; // skip subtrees under the node that was folded
+        i += node.GetLength() - 1; // skip subtrees under the node that was folded
+
+        quality -= impactValue;
 
         prunedSubtrees++;
       }
 
-      if (prunedSubtrees > 0) {
-        lock (PrunedSubtrees) { PrunedSubtrees.Value += prunedSubtrees; }
-        lock (PrunedTrees) { PrunedTrees.Value += 1; }
-      }
+      if (prunedSubtrees > 0) prunedTrees = 1;
+      PrunedSubtreesParameter.ActualValue = new IntValue(prunedSubtrees);
+      PrunedTreesParameter.ActualValue = new IntValue(prunedTrees);
+
       return base.Apply();
     }
@@ -109,4 +158,6 @@
       parent.InsertSubtree(i, replacement);
     }
+    protected abstract ISymbolicDataAnalysisModel CreateModel();
+    protected abstract double Evaluate(IDataAnalysisModel model);
   }
 }
