From d5299908ef617b7593960b8331c5f0da0384adf2 Mon Sep 17 00:00:00 2001
From: Jonas Blatt <jonasblatt@uni-koblenz.de>
Date: Wed, 2 Oct 2019 14:00:05 +0200
Subject: [PATCH] Fix String checker, creater and missing Rule Verifier for
 Strings

---
 .../BiCreaterStringIntersection.java          | 19 +++++++-------
 .../bicreater/BiCreaterStringLowerBounds.java | 23 ++++++++++++++---
 .../checker/CheckStringInContact.java         | 24 +++++++++++++++---
 .../verifier/impl/MissingRuleVerifier.java    | 25 +++++++++++++++++--
 .../BiCreaterStringIntersectionTest.java      |  8 +++---
 5 files changed, 77 insertions(+), 22 deletions(-)

diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringIntersection.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringIntersection.java
index 71caf977..2cbe4f9f 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringIntersection.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringIntersection.java
@@ -32,11 +32,16 @@ public class BiCreaterStringIntersection extends AbstractBoundaryBiCreater<Strin
     if (b1.checkWith(IS_NOT_IN_CONTACT, b2)) {
       return Optional.empty();
     }
-    if (b1.matchesAny() && b2.matchesAny()
-        || b1.matchesAny() && !b2.matchesNoneOfValues()
-        || b2.matchesAny() && !b1.matchesNoneOfValues()) {
+    if (b1.matchesAny() && b2.matchesAny()) {
       return Optional.of(StringBoundary.getBuilder().matchesAny(true).build());
     }
+    if (b1.matchesAny() && !b2.matchesNoneOfValues()
+        || b2.matchesAny() && !b1.matchesNoneOfValues()) {
+      return Optional.of(
+          StringBoundary.getBuilder()
+              .addValues(b1.matchesAny() ? b2.getValues() : b1.getValues())
+              .build());
+    }
     if (b1.matchesAny() && b2.matchesNoneOfValues()) {
       return Optional.of(
           StringBoundary.getBuilder().matchesNoneOfValues(true).addValues(b2.getValues()).build());
@@ -76,15 +81,11 @@ public class BiCreaterStringIntersection extends AbstractBoundaryBiCreater<Strin
     }
     if (b1.matchesNoneOfValues()) {
       return Optional.of(
-          StringBoundary.getBuilder()
-              .addValues(getIntersectionStrings(b2, b1))
-              .build());
+          StringBoundary.getBuilder().addValues(getIntersectionStrings(b2, b1)).build());
     }
     if (b2.matchesNoneOfValues()) {
       return Optional.of(
-          StringBoundary.getBuilder()
-              .addValues(getIntersectionStrings(b1, b2))
-              .build());
+          StringBoundary.getBuilder().addValues(getIntersectionStrings(b1, b2)).build());
     }
     return Optional.empty();
   }
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringLowerBounds.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringLowerBounds.java
index e789e31a..6cab93a7 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringLowerBounds.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringLowerBounds.java
@@ -1,7 +1,13 @@
 package de.unikoblenz.fgbks.base.utils.boundary.bicreater;
 
+import static de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType.IS_EQUAL;
+import static de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType.IS_NOT_IN_CONTACT;
+
 import de.unikoblenz.fgbks.base.utils.boundary.impl.StringBoundary;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.Optional;
+import java.util.Set;
 
 public class BiCreaterStringLowerBounds extends AbstractBoundaryBiCreater<StringBoundary> {
 
@@ -22,8 +28,19 @@ public class BiCreaterStringLowerBounds extends AbstractBoundaryBiCreater<String
 
   @Override
   public Optional<StringBoundary> create(StringBoundary b1, StringBoundary b2) {
-    // Not supported for String Boundary
-    // Check BiCreaterStringBetween.
-    return Optional.empty();
+    if (b1.checkWith(IS_NOT_IN_CONTACT, b2) || b1.checkWith(IS_EQUAL, b2)) {
+      return Optional.empty();
+    }
+    if (b1.matchesAny() || b1.matchesNoneOfValues()) {
+      return Optional.of(
+          StringBoundary.getBuilder()
+              .addValues(b1.getValues())
+              .addValues(b2.getValues())
+              .matchesNoneOfValues(!b2.matchesNoneOfValues())
+              .build());
+    }
+    Set<String> values = new HashSet<>(Arrays.asList(b1.getValues()));
+    values.removeAll(Arrays.asList(b2.getValues()));
+    return Optional.of(StringBoundary.getBuilder().addValues(values).build());
   }
 }
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringInContact.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringInContact.java
index 45a7d7ed..f4f1b172 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringInContact.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringInContact.java
@@ -44,13 +44,29 @@ public class CheckStringInContact extends AbstractBoundaryCheck<StringBoundary>
       return false;
     }
     // one is matching non values "not("a")"
-    if (b1h.length != b2h.length) {
-      return true;
+    if (b1.matchesNoneOfValues()) {
+      outer:
+      for (int i : b2h) {
+        for (int u : b1h) {
+          if (i == u) {
+            continue outer;
+          }
+        }
+        return true;
+      }
+      return false;
     }
-    for (int i = 0; i < b1h.length; i++) {
-      if (b1h[i] != b2h[i]) {
+    if (b2.matchesNoneOfValues()) {
+      outer:
+      for (int i : b1h) {
+        for (int u : b2h) {
+          if (i == u) {
+            continue outer;
+          }
+        }
         return true;
       }
+      return false;
     }
     return false;
   }
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingRuleVerifier.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingRuleVerifier.java
index e2cfb107..c1aca047 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingRuleVerifier.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingRuleVerifier.java
@@ -100,12 +100,19 @@ public class MissingRuleVerifier extends AbstractVerifier {
       List<VDmnRuleChangeableImpl> missingRules) {
     // search the missing rules, which are in contact with the current rule
     List<VDmnRuleChangeableImpl> inContactRules = new LinkedList<>();
+    List<VDmnRuleChangeableImpl> inEqualRules = new LinkedList<>();
     for (VDmnRuleChangeableImpl missingRule : missingRules) {
       if (isInContact(missingRule, currentRule)) {
-        inContactRules.add(missingRule);
+        // dont add equal rules
+        if (isEqualRule(missingRule, currentRule)) {
+          inEqualRules.add(missingRule);
+        } else {
+          inContactRules.add(missingRule);
+        }
       }
     }
     // remove found rules from current missingRules
+    missingRules.removeAll(inEqualRules);
     missingRules.removeAll(inContactRules);
     // Build new missing rules from in contact rules
     List<VDmnRuleChangeableImpl> newMissingRules = new LinkedList<>();
@@ -114,7 +121,21 @@ public class MissingRuleVerifier extends AbstractVerifier {
     }
     // mergeRules(newMissingRules);
     missingRules.addAll(newMissingRules);
-    mergeRules(missingRules);
+    // mergeRules(missingRules);
+  }
+
+  private boolean isEqualRule(VDmnRule missingRule, VDmnRule currentRule) {
+    List<VDmnInputValue> inValsMissingRule = missingRule.getDmnInputValues();
+    List<VDmnInputValue> inValsCurrentRule = currentRule.getDmnInputValues();
+    for (int i = 0; i < inValsMissingRule.size(); i++) {
+      if (!inValsMissingRule
+          .get(i)
+          .getBoundary()
+          .checkWith(BoundaryCheckType.IS_EQUAL, inValsCurrentRule.get(i).getBoundary())) {
+        return false;
+      }
+    }
+    return true;
   }
 
   private List<VDmnRuleChangeableImpl> constructNewMissingRules(
diff --git a/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringIntersectionTest.java b/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringIntersectionTest.java
index b458a487..4c942d81 100644
--- a/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringIntersectionTest.java
+++ b/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringIntersectionTest.java
@@ -39,16 +39,16 @@ class BiCreaterStringIntersectionTest {
     sb1 = StringBoundary.getBuilder().matchesAny(true).build();
     sb2 = StringBoundary.getBuilder().addValue("a").build();
     sbR = (StringBoundary) sb1.createBi(INTERSECTION, sb2).get();
-    assertArrayEquals(new String[]{}, sbR.getValues());
+    assertArrayEquals(new String[]{"a"}, sbR.getValues());
     assertFalse(sbR.matchesNoneOfValues());
-    assertTrue(sbR.matchesAny());
+    assertFalse(sbR.matchesAny());
 
     sb1 = StringBoundary.getBuilder().addValue("a").build();
     sb2 = StringBoundary.getBuilder().matchesAny(true).build();
     sbR = (StringBoundary) sb1.createBi(INTERSECTION, sb2).get();
-    assertArrayEquals(new String[]{}, sbR.getValues());
+    assertArrayEquals(new String[]{"a"}, sbR.getValues());
     assertFalse(sbR.matchesNoneOfValues());
-    assertTrue(sbR.matchesAny());
+    assertFalse(sbR.matchesAny());
 
     sb1 = StringBoundary.getBuilder().matchesAny(true).build();
     sb2 = StringBoundary.getBuilder().matchesNoneOfValues(true).addValue("a").build();
-- 
GitLab