Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/IntervalConstraintsParser.cs @ 16900

Last change on this file since 16900 was 16900, checked in by chaider, 5 years ago

#2971

  • Added field Target to IntervalConstraint
  • Prefixed Target-Item with Target:
  • Removed prefixed Target: at derivations ==> show target field instead
File size: 6.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21using System;
22using System.Collections.Generic;
23using System.Globalization;
24using System.Linq;
25using System.Text.RegularExpressions;
26
27namespace HeuristicLab.Problems.DataAnalysis {
28  public static class IntervalConstraintsParser {
29
30    public static IEnumerable<IntervalConstraint> ParseInput(string input, string target = "", IEnumerable<string> variables = null) {
31      var lines = input.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
32      foreach (var line in lines) {
33        var trimmedLine = line.TrimStart();
34        //Check for target-variable constraint
35        if (trimmedLine.StartsWith("Target:")) {
36          var start = "Target:".Length;
37          var end = trimmedLine.Length;
38          var targetConstraint = trimmedLine.Substring(start, end-start);
39          var match = Regex.Match(targetConstraint,
40            @"['](.*)[']\s*(\bin\b)\s*([\[\]])\s*(\S*)\s*(..)\s*(\S*)\s*([\[\]])");
41          if (match.Success) {
42            if (match.Groups.Count != 8) {
43              throw new ArgumentException("The given target-constraint is not complete!");
44            } else {
45              if (target != "") {
46                if (match.Groups[1].Value.Trim() != target) {
47                  throw new ArgumentException("The given target variable is not in the given dataset!");
48                }
49              }
50              var lowerBound = ParseIntervalBounds(match.Groups[4].Value);
51              var upperBound = ParseIntervalBounds(match.Groups[6].Value);
52              var expression = "Target:" + match.Groups[0].Value;
53              var parsedTarget = match.Groups[1].Value.Trim();
54              var variable = match.Groups[1].Value.Trim();
55              var inclLowerBound = match.Groups[3].Value.Trim() == "[";
56              var inclUpperBound = match.Groups[7].Value.Trim() == "]";
57              var isDerivation = false;
58              var numberOfDerivation = 0;
59              var interval = new Interval(lowerBound, upperBound);
60
61              var constraint = new IntervalConstraint(expression, variable, parsedTarget, numberOfDerivation, interval, inclLowerBound, inclUpperBound, true);
62
63              yield return constraint;
64            }
65          } else {
66            throw new ArgumentException("The inserted target constraint is not valid!");
67          }
68          //Check for derivation
69        } else if (trimmedLine.StartsWith("d") || trimmedLine.StartsWith("\u2202")) {
70          var match = Regex.Match(trimmedLine,
71            @"([d∂])([²³]?)\s*['](.*)[']\s*(\/)\s*([d∂])\s*['](.*)[']\s*([²³]?)\s*\bin\b\s*([\[\]])\s*(\S*)\s*(..)\s*(\S*)\s*([\[\]])");
72
73          if (match.Success) {
74            if (match.Groups.Count != 13) {
75              throw new ArgumentException("The given derivation-constraint is not complete");
76            } else {
77              if (target != "") {
78                if (match.Groups[3].Value != target)
79                  throw new ArgumentException("The given target variable is not given in the dataset!");
80              }
81
82              if (variables != null && variables.Any()) {
83                if (variables.All(v => v != match.Groups[6].Value.Trim())) {
84                  throw new ArgumentException("The given variable does not exist in the dataset!");
85                }
86              }
87
88              if (match.Groups[2].Value.Trim() != "" || match.Groups[7].Value.Trim() != "") {
89                if (match.Groups[2].Value.Trim() == "" || match.Groups[7].Value.Trim() == "")
90                  throw new ArgumentException("Number of derivation has to be written on both sides!");
91                if (match.Groups[2].Value.Trim() != match.Groups[7].Value.Trim())
92                  throw new ArgumentException("Derivation number is not equal on both sides!");
93              }
94
95              var lowerBound = ParseIntervalBounds(match.Groups[9].Value);
96              var upperBound = ParseIntervalBounds(match.Groups[11].Value);
97              var expression = match.Groups[0].Value;
98              var parsedTarget = match.Groups[3].Value.Trim();
99              var isDerivation = true;
100              var inclLowerBound = match.Groups[8].Value.Trim() == "[";
101              var inclUpperBound = match.Groups[12].Value.Trim() == "]";
102              var variable = match.Groups[6].Value.Trim();
103              var numberOfDerivation = ParseDerivationCount(match.Groups[2].Value.Trim());
104              var interval = new Interval(lowerBound, upperBound);
105
106              var constraint = new IntervalConstraint(expression, variable, parsedTarget, numberOfDerivation, interval, inclLowerBound, inclUpperBound, true);
107
108              yield return constraint;
109            }
110          } else {
111            throw new ArgumentException("The inserted derivation constraint is not valid!");
112          }
113          //Check for comment
114        } else if (trimmedLine.StartsWith("#") || trimmedLine == "") {
115          //If it is a comment just continue without saving anything
116          continue;
117        } else {
118          throw new ArgumentException("Error at your constraints definition constraints have to start with (Target: | d | \u2202 | #)");
119        }
120      }
121    }
122
123    private static double ParseIntervalBounds(string input) {
124      input = input.ToLower();
125      switch (input) {
126        case "+inf.":
127        case "inf.":
128          return double.PositiveInfinity;
129        case "-inf.":
130          return double.NegativeInfinity;
131        default: {
132            if (double.TryParse(input, NumberStyles.Any, CultureInfo.InvariantCulture, out var value)) {
133              return value;
134            } else {
135              throw new ArgumentException("The given boundary is not a double value!");
136            }
137          }
138      }
139    }
140
141    private static int ParseDerivationCount(string input) {
142      switch (input) {
143        case "":
144          return 1;
145        case "²":
146          return 2;
147        case "³":
148          return 3;
149        default:
150          int.TryParse(input, out var value);
151          return value;
152      }
153    }
154  }
155}
Note: See TracBrowser for help on using the repository browser.