Index: /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj
===================================================================
--- /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 16712)
+++ /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 16713)
@@ -204,4 +204,5 @@
     <Compile Include="Plugin.cs" />
     <Compile Include="SingleObjective\ConstantOptimizationAnalyzer.cs" />
+    <Compile Include="SingleObjective\Evaluators\SymbolicRegressionConstraintSatisfactionEvaluator.cs" />
     <Compile Include="SingleObjective\Evaluators\SymbolicRegressionMeanRelativeErrorEvaluator.cs" />
     <Compile Include="SingleObjective\Evaluators\SymbolicRegressionSingleObjectiveConstraintConstOptEvaluator.cs" />
Index: /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstraintSatisfactionEvaluator.cs
===================================================================
--- /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstraintSatisfactionEvaluator.cs	(revision 16713)
+++ /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstraintSatisfactionEvaluator.cs	(revision 16713)
@@ -0,0 +1,134 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2019 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;
+using System.Collections.Generic;
+using System.Linq;
+using HEAL.Attic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
+  [Item("Constraint Satisfaction Evaluator", "Basic evaluator which checks for constraint satisfaction and returns a soft penalty.")]
+  [StorableType("1CFBDAD0-1059-4908-9A76-C02976C367E6")]
+  public class SymbolicRegressionConstraintSatisfactionEvaluator : SymbolicRegressionSingleObjectiveEvaluator {
+    private const string UseBinaryPenaltyValuesParameterName = "UseBinaryPenaltyValues";
+    private const string IntervalConstraintParameterName = "Constraint";
+
+    private readonly IntervalInterpreter interpreter = new IntervalInterpreter();
+    private IntervalConstraint constraint = null;
+
+    public IFixedValueParameter<StringValue> IntervalConstraintParameter {
+      get { return (IFixedValueParameter<StringValue>)Parameters[IntervalConstraintParameterName]; }
+    }
+
+    public IFixedValueParameter<BoolValue> UseBinaryPenaltyValuesParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[UseBinaryPenaltyValuesParameterName]; }
+    }
+
+    public bool UseBinaryPenaltyValues {
+      get { return UseBinaryPenaltyValuesParameter.Value.Value; }
+      set { UseBinaryPenaltyValuesParameter.Value.Value = value; }
+    }
+
+    public string IntervalConstraint {
+      get { return IntervalConstraintParameter.Value.Value; }
+      set { IntervalConstraintParameter.Value.Value = value; }
+    }
+
+    public SymbolicRegressionConstraintSatisfactionEvaluator() {
+      Parameters.Add(new FixedValueParameter<BoolValue>(UseBinaryPenaltyValuesParameterName));
+      Parameters.Add(new FixedValueParameter<StringValue>(IntervalConstraintParameterName));
+
+      IntervalConstraintParameter.Value.ValueChanged += (sender, args) => constraint = IntervalConstraintsParser.Parse(IntervalConstraint).FirstOrDefault();
+    }
+
+    protected SymbolicRegressionConstraintSatisfactionEvaluator(SymbolicRegressionConstraintSatisfactionEvaluator original, Cloner cloner) : base(original, cloner) { }
+
+    [StorableConstructor]
+    protected SymbolicRegressionConstraintSatisfactionEvaluator(StorableConstructorFlag _) : base(_) { }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!Parameters.ContainsKey(UseBinaryPenaltyValuesParameterName)) {
+        Parameters.Add(new FixedValueParameter<BoolValue>(UseBinaryPenaltyValuesParameterName));
+      }
+    }
+
+    public override bool Maximization => false;
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicRegressionConstraintSatisfactionEvaluator(this, cloner);
+    }
+
+    public override IOperation InstrumentedApply() {
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
+      var problemData = ProblemDataParameter.ActualValue;
+
+      double quality = Evaluate(this.ExecutionContext, tree, problemData, problemData.TrainingIndices);
+
+      QualityParameter.ActualValue = new DoubleValue(quality);
+      return base.InstrumentedApply();
+    }
+
+    public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows) {
+      constraint = constraint ?? IntervalConstraintsParser.Parse(IntervalConstraint).FirstOrDefault();
+
+      ISymbolicExpressionTree t = tree;
+      if (constraint.IsDerivation) {
+        var order = constraint.NumberOfDerivation;
+        while (order-- > 0) {
+          t = DerivativeCalculator.Derive(t, constraint.Variable);
+        }
+      }
+      const double maxPenalty = double.MaxValue; // TODO: find an appropriate value for this
+      var satisfied = CheckConstraintSatisfaction(tree, problemData, rows, interpreter, constraint, out Interval interval, out double lowerBoundPenalty, out double upperBoundPenalty);
+
+      if (satisfied) return 0;
+      if (UseBinaryPenaltyValues) return 1;
+
+      var penalty = lowerBoundPenalty + upperBoundPenalty;
+
+      if (double.IsNaN(penalty) || double.IsInfinity(penalty) || penalty > maxPenalty) {
+        penalty = maxPenalty;
+      }
+
+      return penalty;
+    }
+
+    public static bool CheckConstraintSatisfaction(ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows, IntervalInterpreter interpreter, IntervalConstraint constraint, out Interval interval, out double lowerBoundPenalty, out double upperBoundPenalty) {
+      ISymbolicExpressionTree t = tree;
+      if (constraint.IsDerivation) {
+        var order = constraint.NumberOfDerivation;
+        while (order-- > 0) {
+          t = DerivativeCalculator.Derive(t, constraint.Variable);
+        }
+      }
+      interval = interpreter.GetSymbolicExpressionTreeInterval(t, problemData.Dataset, rows);
+      lowerBoundPenalty = Math.Max(constraint.Interval.LowerBound - interval.LowerBound, 0);
+      upperBoundPenalty = Math.Max(interval.UpperBound - constraint.Interval.UpperBound, 0);
+      return constraint.Interval.Contains(interval, constraint.InclusiveLowerBound, constraint.InclusiveUpperBound);
+    }
+  }
+}
Index: /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveConstraintConstOptEvaluator.cs
===================================================================
--- /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveConstraintConstOptEvaluator.cs	(revision 16712)
+++ /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveConstraintConstOptEvaluator.cs	(revision 16713)
@@ -22,9 +22,9 @@
 using System;
 using System.Collections.Generic;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
@@ -59,6 +59,5 @@
       OnlineCalculatorError errorState = OnlineCalculatorError.None;
 
-      IntervalConstraintsParser parser = new IntervalConstraintsParser();
-      var constraints = parser.Parse(((RegressionProblemData)problemData).IntervalConstraintsParameter.Value.Value);
+      var constraints = IntervalConstraintsParser.Parse(((RegressionProblemData)problemData).IntervalConstraintsParameter.Value.Value);
       var intervalInterpreter = new IntervalInterpreter();
       var variableRanges = ((RegressionProblemData)problemData).VariableRangesParameter.Value.VariableIntervals;
@@ -90,5 +89,5 @@
     }
 
-    private static bool HasConstraintVioluations(List<IntervalConstraint> constraints, IntervalInterpreter intervalInterpreter,
+    private static bool HasConstraintVioluations(IEnumerable<IntervalConstraint> constraints, IntervalInterpreter intervalInterpreter,
       Dictionary<string, Interval> variableRanges, ISymbolicExpressionTree solution) {
       foreach (var constraint in constraints) {
@@ -96,5 +95,5 @@
           throw new ArgumentException($"The given variable {constraint.Variable} in the constraint does not exists in the model.", nameof(IntervalConstraintsParser));
         if (!constraint.IsDerivation) {
-          var res = intervalInterpreter.GetSymbolicExressionTreeInterval(solution, variableRanges);
+          var res = intervalInterpreter.GetSymbolicExpressionTreeInterval(solution, variableRanges);
           if (!constraint.Interval.Contains(res, constraint.InclusiveLowerBound,
             constraint.InclusiveUpperBound)) {
@@ -106,5 +105,5 @@
             tree = DerivativeCalculator.Derive(tree, constraint.Variable);
           }
-          var res = intervalInterpreter.GetSymbolicExressionTreeInterval(tree, variableRanges);
+          var res = intervalInterpreter.GetSymbolicExpressionTreeInterval(tree, variableRanges);
           if (!constraint.Interval.Contains(res, constraint.InclusiveLowerBound,
             constraint.InclusiveUpperBound)) {
Index: /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator.cs
===================================================================
--- /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator.cs	(revision 16712)
+++ /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator.cs	(revision 16713)
@@ -22,9 +22,9 @@
 using System;
 using System.Collections.Generic;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
@@ -59,8 +59,7 @@
       OnlineCalculatorError errorState = OnlineCalculatorError.None;
 
-      IntervalConstraintsParser parser = new IntervalConstraintsParser();
-      var constraints = parser.Parse(((RegressionProblemData) problemData).IntervalConstraintsParameter.Value.Value);
+      var constraints = IntervalConstraintsParser.Parse(((RegressionProblemData)problemData).IntervalConstraintsParameter.Value.Value);
       var intervalInterpreter = new IntervalInterpreter();
-      var variableRanges = ((RegressionProblemData) problemData).VariableRangesParameter.Value.VariableIntervals;
+      var variableRanges = ((RegressionProblemData)problemData).VariableRangesParameter.Value.VariableIntervals;
 
 
@@ -92,5 +91,5 @@
       // var e = m.GetEstimatedValues (TRAINING)
       // OnlinePearsonCalc.Calculate(e, TARGET_TRAIING)
-      
+
       // scaledTree = model.Tree;
 
@@ -120,5 +119,5 @@
       }
       if (errorState != OnlineCalculatorError.None) return double.NaN;
-      return r*r;
+      return r * r;
     }
 
@@ -141,5 +140,5 @@
     }
 
-    private static bool CheckConstraintsViolations(List<IntervalConstraint> constraints, IntervalInterpreter intervalInterpreter,
+    private static bool CheckConstraintsViolations(IEnumerable<IntervalConstraint> constraints, IntervalInterpreter intervalInterpreter,
       Dictionary<string, Interval> variableRanges, ISymbolicExpressionTree solution, out double r) {
       foreach (var constraint in constraints) {
@@ -147,5 +146,5 @@
           throw new ArgumentException($"The given variable {constraint.Variable} in the constraint does not exists in the model.", nameof(IntervalConstraintsParser));
         if (!constraint.IsDerivation) {
-          var res = intervalInterpreter.GetSymbolicExressionTreeInterval(solution, variableRanges);
+          var res = intervalInterpreter.GetSymbolicExpressionTreeInterval(solution, variableRanges);
           if (!constraint.Interval.Contains(res, constraint.InclusiveLowerBound,
             constraint.InclusiveUpperBound)) {
@@ -158,5 +157,5 @@
             tree = DerivativeCalculator.Derive(tree, constraint.Variable);
           }
-          var res = intervalInterpreter.GetSymbolicExressionTreeInterval(tree, variableRanges);
+          var res = intervalInterpreter.GetSymbolicExpressionTreeInterval(tree, variableRanges);
           if (!constraint.Interval.Contains(res, constraint.InclusiveLowerBound,
             constraint.InclusiveUpperBound)) {
Index: /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionConstraintAnalyzer.cs
===================================================================
--- /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionConstraintAnalyzer.cs	(revision 16712)
+++ /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionConstraintAnalyzer.cs	(revision 16713)
@@ -24,4 +24,5 @@
 using System;
 using System.Collections.Generic;
+using HEAL.Attic;
 using HeuristicLab.Analysis;
 using HeuristicLab.Common;
@@ -30,5 +31,4 @@
 using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
@@ -86,5 +86,4 @@
     public override IOperation Apply() {
       var results = ResultCollectionParameter.ActualValue;
-      IntervalConstraintsParser parser = new IntervalConstraintsParser();
       var intervalInterpreter = new IntervalInterpreter();
       if (!results.ContainsKey(ConstraintViolationsResultName)) {
@@ -99,6 +98,5 @@
       var constraintViolations = new Dictionary<string, int>();
 
-      var constraints =
-        parser.Parse(problemData.IntervalConstraints.Value);
+      var constraints = IntervalConstraintsParser.Parse(problemData.IntervalConstraints.Value);
       var variableRanges = problemData.VariableRanges.VariableIntervals;
 
@@ -122,5 +120,5 @@
               nameof(IntervalConstraintsParser));
           if (!constraint.IsDerivation) {
-            var res = intervalInterpreter.GetSymbolicExressionTreeInterval(tree,
+            var res = intervalInterpreter.GetSymbolicExpressionTreeInterval(tree,
               variableRanges);
             if (!constraint.Interval.Contains(res, constraint.InclusiveLowerBound,
@@ -134,5 +132,5 @@
             }
 
-            var res = intervalInterpreter.GetSymbolicExressionTreeInterval(dTree,
+            var res = intervalInterpreter.GetSymbolicExpressionTreeInterval(dTree,
               variableRanges);
             if (!constraint.Interval.Contains(res, constraint.InclusiveLowerBound,
Index: /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolution.cs
===================================================================
--- /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolution.cs	(revision 16712)
+++ /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolution.cs	(revision 16713)
@@ -21,4 +21,5 @@
 
 using System.Linq;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -26,5 +27,4 @@
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Optimization;
-using HEAL.Attic;
 using HeuristicLab.Problems.DataAnalysis.Implementation;
 
@@ -168,10 +168,10 @@
       if (variableRanges != null) {
         intervalEvaluation.Add($"Target {ProblemData.TargetVariable}", new Interval(variableRanges[ProblemData.TargetVariable].LowerBound, variableRanges[ProblemData.TargetVariable].UpperBound));
-        intervalEvaluation.Add("Modell Interval", interpreter.GetSymbolicExressionTreeInterval(Model.SymbolicExpressionTree, variableRanges));
+        intervalEvaluation.Add("Modell Interval", interpreter.GetSymbolicExpressionTreeInterval(Model.SymbolicExpressionTree, variableRanges));
 
         foreach (var derivate in variableRanges) {
           if (derivate.Key != ProblemData.TargetVariable) {
             var derived = DerivativeCalculator.Derive(Model.SymbolicExpressionTree, derivate.Key);
-            var derivedResultInterval = interpreter.GetSymbolicExressionTreeInterval(derived, variableRanges);
+            var derivedResultInterval = interpreter.GetSymbolicExpressionTreeInterval(derived, variableRanges);
             intervalEvaluation.Add(" ?f/?" + derivate.Key,
               new Interval(derivedResultInterval.LowerBound, derivedResultInterval.UpperBound));
Index: /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.csproj
===================================================================
--- /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.csproj	(revision 16712)
+++ /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.csproj	(revision 16713)
@@ -105,4 +105,5 @@
     <Reference Include="EPPlus-4.0.3, Version=4.0.3.0, Culture=neutral, PublicKeyToken=ea159fdaa78159a1, processorArchitecture=MSIL">
       <Private>False</Private>
+      <HintPath>..\..\..\..\trunk\bin\EPPlus-4.0.3.dll</HintPath>
     </Reference>
     <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
Index: /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Parser/IntervalConstraintsParser.cs
===================================================================
--- /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Parser/IntervalConstraintsParser.cs	(revision 16712)
+++ /branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Parser/IntervalConstraintsParser.cs	(revision 16713)
@@ -5,13 +5,11 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class IntervalConstraintsParser {
-    public IntervalConstraintsParser() {}
-    private List<IntervalConstraint> intervalConstraints = new List<IntervalConstraint>();
-    public List<IntervalConstraint> Parse(string input) {
+  public static class IntervalConstraintsParser {
+    public static IEnumerable<IntervalConstraint> Parse(string input) {
       var options = RegexOptions.Multiline | RegexOptions.IgnoreCase;
       var matches = Regex.Matches(input, @"^(.*)\bin\b\s*([\[\]])(.*[^\s])(\s*\.\.\s*)([^\s].*)([\[\]])\r?\s*$", options);
 
       for (var i = 0; i < matches.Count; ++i) {
-        if (matches[i].Groups.Count == 7) { 
+        if (matches[i].Groups.Count == 7) {
           var intervalConstraint = new IntervalConstraint();
           //pattern 1 = defintion
@@ -38,14 +36,12 @@
           intervalConstraint.InclusiveLowerBound = (matches[i].Groups[2].Value == "[");
           intervalConstraint.InclusiveUpperBound = (matches[i].Groups[6].Value == "]");
-          intervalConstraint.Interval = new Interval(ParseIntervalBounds(matches[i].Groups[3].Value.Replace(" ", string.Empty)), 
+          intervalConstraint.Interval = new Interval(ParseIntervalBounds(matches[i].Groups[3].Value.Replace(" ", string.Empty)),
             ParseIntervalBounds(matches[i].Groups[5].Value.Replace(" ", string.Empty)));
 
-          intervalConstraints.Add(intervalConstraint);
+          yield return intervalConstraint;
         } else {
           throw new ArgumentException($"The given constraint: {matches[i].Value} is not valid.");
         }
       }
-
-      return intervalConstraints;
     }
 
@@ -59,10 +55,10 @@
           return double.NegativeInfinity;
         default: {
-          if (double.TryParse(input, NumberStyles.Any, CultureInfo.InvariantCulture, out var value)) {
-            return value;
-          } else {
-            throw new ArgumentException("The given Interval in the constraint is not valid.");
+            if (double.TryParse(input, NumberStyles.Any, CultureInfo.InvariantCulture, out var value)) {
+              return value;
+            } else {
+              throw new ArgumentException("The given Interval in the constraint is not valid.");
+            }
           }
-        }
       }
     }
