Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Parser/IntervalConstraintsParser.cs @ 16895

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

#2971 Changed IntervalConstraint

File size: 7.0 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 definition = "Target " + 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, 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 definition = match.Groups[1].Value + match.Groups[2].Value + match.Groups[3].Value +
99                                      match.Groups[4].Value + match.Groups[5].Value + match.Groups[6].Value + match.Groups[7].Value;
100              var isDerivation = true;
101              var inclLowerBound = match.Groups[8].Value.Trim() == "[";
102              var inclUpperBound = match.Groups[12].Value.Trim() == "]";
103              var variable = match.Groups[6].Value.Trim();
104              var numberOfDerivation = ParseDerivationCount(match.Groups[2].Value.Trim());
105              var interval = new Interval(lowerBound, upperBound);
106
107              var constraint = new IntervalConstraint(expression, variable, numberOfDerivation, interval, inclLowerBound, inclUpperBound, true);
108
109              yield return constraint;
110            }
111          } else {
112            throw new ArgumentException("The inserted derivation constraint is not valid!");
113          }
114          //Check for comment
115        } else if (trimmedLine.StartsWith("#") || trimmedLine == "") {
116          //If it is a comment just continue without saving anything
117          continue;
118        } else {
119          throw new ArgumentException("Error at your constraints definition constraints have to start with (Target: | d | \u2202 | #)");
120        }
121      }
122    }
123
124    private static double ParseIntervalBounds(string input) {
125      input = input.ToLower();
126      switch (input) {
127        case "+inf.":
128        case "inf.":
129          return double.PositiveInfinity;
130        case "-inf.":
131          return double.NegativeInfinity;
132        default: {
133            if (double.TryParse(input, NumberStyles.Any, CultureInfo.InvariantCulture, out var value)) {
134              return value;
135            } else {
136              throw new ArgumentException("The given boundary is not a double value!");
137            }
138          }
139      }
140    }
141
142    private static int ParseDerivationCount(string input) {
143      switch (input) {
144        case "":
145          return 1;
146        case "²":
147          return 2;
148        case "³":
149          return 3;
150        default:
151          int.TryParse(input, out var value);
152          return value;
153      }
154    }
155  }
156}
Note: See TracBrowser for help on using the repository browser.