From 48fed44ec9618263817c1758af8dd6d9e7b590b0 Mon Sep 17 00:00:00 2001
From: Jonas Blatt <jonasblatt@uni-koblenz.de>
Date: Wed, 18 Sep 2019 21:53:59 +0200
Subject: [PATCH] Add checker for String boundary

---
 .../boundary/AbstractGrowingBoundary.java     |  4 +-
 ...sSubsumes.java => CheckIsSubsumption.java} |  8 +--
 .../utils/boundary/checker/CheckOverlap.java  |  2 +-
 .../boundary/checker/CheckStringEqual.java    |  2 +-
 .../checker/CheckStringInContact.java         |  4 +-
 ...tact.java => CheckStringNotInContact.java} |  6 +-
 .../boundary/checker/CheckStringOverlap.java  | 28 ++++++++
 .../boundary/checker/CheckStringSubsumes.java | 69 +++++++++++++++++++
 .../checker/CheckStringSubsumption.java       | 26 +++++++
 .../utils/boundary/impl/StringBoundary.java   | 12 +++-
 .../checker/CheckStringNotInContactTest.java  |  2 +-
 .../checker/CheckStringSubsumesTest.java      | 40 +++++++++++
 12 files changed, 188 insertions(+), 15 deletions(-)
 rename dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/{CheckIsSubsumes.java => CheckIsSubsumption.java} (70%)
 rename dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/{CheckStringNotContact.java => CheckStringNotInContact.java} (69%)
 create mode 100644 dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringOverlap.java
 create mode 100644 dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringSubsumes.java
 create mode 100644 dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringSubsumption.java
 create mode 100644 dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringSubsumesTest.java

diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/AbstractGrowingBoundary.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/AbstractGrowingBoundary.java
index 17107d44..03a0323b 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/AbstractGrowingBoundary.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/AbstractGrowingBoundary.java
@@ -6,7 +6,7 @@ import de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheck;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckEqual;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckInContact;
-import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckIsSubsumes;
+import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckIsSubsumption;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckNotInContact;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckOverlap;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckSubsumes;
@@ -72,7 +72,7 @@ public abstract class AbstractGrowingBoundary<T extends Comparable<? super T>>
     map.put(BoundaryCheckType.IS_IN_CONTACT, CheckInContact.getInstance());
     map.put(BoundaryCheckType.IS_NOT_IN_CONTACT, CheckNotInContact.getInstance());
     map.put(BoundaryCheckType.IS_OVERLAPPING, CheckOverlap.getInstance());
-    map.put(BoundaryCheckType.IS_SUBSUMPTION, CheckIsSubsumes.getInstance());
+    map.put(BoundaryCheckType.IS_SUBSUMPTION, CheckIsSubsumption.getInstance());
     map.put(BoundaryCheckType.SUBSUMES, CheckSubsumes.getInstance());
     return map;
   }
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckIsSubsumes.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckIsSubsumption.java
similarity index 70%
rename from dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckIsSubsumes.java
rename to dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckIsSubsumption.java
index f554327e..435747b3 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckIsSubsumes.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckIsSubsumption.java
@@ -2,15 +2,15 @@ package de.unikoblenz.fgbks.base.utils.boundary.checker;
 
 import de.unikoblenz.fgbks.base.utils.boundary.AbstractGrowingBoundary;
 
-public class CheckIsSubsumes extends AbstractBoundaryCheck<AbstractGrowingBoundary> {
+public class CheckIsSubsumption extends AbstractBoundaryCheck<AbstractGrowingBoundary> {
 
-  private static final CheckIsSubsumes instance = new CheckIsSubsumes();
+  private static final CheckIsSubsumption instance = new CheckIsSubsumption();
 
-  private CheckIsSubsumes() {
+  private CheckIsSubsumption() {
     super();
   }
 
-  public static CheckIsSubsumes getInstance() {
+  public static CheckIsSubsumption getInstance() {
     return instance;
   }
 
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckOverlap.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckOverlap.java
index a98c6810..380531ba 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckOverlap.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckOverlap.java
@@ -27,6 +27,6 @@ public class CheckOverlap extends AbstractBoundaryCheck<AbstractGrowingBoundary>
   public static boolean checkOverlapping(AbstractGrowingBoundary b1, AbstractGrowingBoundary b2) {
     return CheckInContact.checkInContact(b1, b2)
         && !CheckEqual.checkEqual(b1, b2)
-        && !CheckIsSubsumes.checkIsSubsumption(b1, b2);
+        && !CheckIsSubsumption.checkIsSubsumption(b1, b2);
   }
 }
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringEqual.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringEqual.java
index 0c749655..3345d8b4 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringEqual.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringEqual.java
@@ -24,7 +24,7 @@ public class CheckStringEqual extends AbstractBoundaryCheck<StringBoundary> {
     if (b1 == b2 || b1.getText().equals(b2.getText()) || b1.isMatchAny() && b2.isMatchAny()) {
       return true;
     }
-    if (b1.isMatchNoneOfValues() != b2.isMatchNoneOfValues()
+    if (b1.matchesNoneOfValues() != b2.matchesNoneOfValues()
         || b1.getAmountOfElements() != b2.getAmountOfElements()) {
       return false;
     }
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 2a1e1ff9..be74a3cb 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
@@ -23,13 +23,13 @@ public class CheckStringInContact extends AbstractBoundaryCheck<StringBoundary>
   public static boolean checkInContact(StringBoundary b1, StringBoundary b2) {
     if (b1.isMatchAny()
         || b2.isMatchAny()
-        || b1.isMatchNoneOfValues() && b2.isMatchNoneOfValues()) {
+        || b1.matchesNoneOfValues() && b2.matchesNoneOfValues()) {
       return true;
     }
     int[] b1h = b1.getValuesHashes();
     int[] b2h = b2.getValuesHashes();
     // both are not matching non values
-    if (!b1.isMatchNoneOfValues() && !b2.isMatchNoneOfValues()) {
+    if (!b1.matchesNoneOfValues() && !b2.matchesNoneOfValues()) {
       for (int i : b1h) {
         for (int u : b2h) {
           if (i == u) {
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringNotContact.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringNotInContact.java
similarity index 69%
rename from dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringNotContact.java
rename to dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringNotInContact.java
index e5140837..5aaa21e0 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringNotContact.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringNotInContact.java
@@ -2,11 +2,11 @@ package de.unikoblenz.fgbks.base.utils.boundary.checker;
 
 import de.unikoblenz.fgbks.base.utils.boundary.impl.StringBoundary;
 
-public class CheckStringNotContact extends AbstractBoundaryCheck<StringBoundary> {
+public class CheckStringNotInContact extends AbstractBoundaryCheck<StringBoundary> {
 
-  private static CheckStringNotContact instance = new CheckStringNotContact();
+  private static CheckStringNotInContact instance = new CheckStringNotInContact();
 
-  public static CheckStringNotContact getInstance() {
+  public static CheckStringNotInContact getInstance() {
     return instance;
   }
 
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringOverlap.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringOverlap.java
new file mode 100644
index 00000000..6c5d0eff
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringOverlap.java
@@ -0,0 +1,28 @@
+package de.unikoblenz.fgbks.base.utils.boundary.checker;
+
+import de.unikoblenz.fgbks.base.utils.boundary.impl.StringBoundary;
+
+public class CheckStringOverlap extends AbstractBoundaryCheck<StringBoundary> {
+
+  private static CheckStringOverlap instance = new CheckStringOverlap();
+
+  public static CheckStringOverlap getInstance() {
+    return instance;
+  }
+
+  @Override
+  public BoundaryCheckType getType() {
+    return BoundaryCheckType.IS_NOT_IN_CONTACT;
+  }
+
+  @Override
+  public boolean check(StringBoundary b1, StringBoundary b2) {
+    return checkSubsumption(b1, b2);
+  }
+
+  public static boolean checkSubsumption(StringBoundary b1, StringBoundary b2) {
+    return CheckStringInContact.checkInContact(b1, b2)
+        && !CheckStringEqual.checkEqual(b1, b2)
+        && !CheckStringSubsumption.checkSubsumption(b1, b2);
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringSubsumes.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringSubsumes.java
new file mode 100644
index 00000000..5565d5a4
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringSubsumes.java
@@ -0,0 +1,69 @@
+package de.unikoblenz.fgbks.base.utils.boundary.checker;
+
+import de.unikoblenz.fgbks.base.utils.boundary.impl.StringBoundary;
+
+public class CheckStringSubsumes extends AbstractBoundaryCheck<StringBoundary> {
+
+  private static CheckStringSubsumes instance = new CheckStringSubsumes();
+
+  public static CheckStringSubsumes getInstance() {
+    return instance;
+  }
+
+  @Override
+  public BoundaryCheckType getType() {
+    return BoundaryCheckType.IS_NOT_IN_CONTACT;
+  }
+
+  @Override
+  public boolean check(StringBoundary b1, StringBoundary b2) {
+    return checkSubsumes(b1, b2);
+  }
+
+  public static boolean checkSubsumes(StringBoundary b1, StringBoundary b2) {
+    if (b1.isMatchAny() && !b2.isMatchAny()) {
+      return true;
+    }
+    if (b2.isMatchAny()) {
+      return false;
+    }
+    int[] b1h = b1.getValuesHashes();
+    int[] b2h = b2.getValuesHashes();
+    // not() and not not()
+    if (b1.matchesNoneOfValues() && !b2.matchesNoneOfValues()) {
+      for (int i = 0; i < b1h.length; i++) {
+        for (int u = 0; u < b2h.length; u++) {
+          if (b1h[i] == b2h[u]) {
+            return false;
+          }
+        }
+      }
+      return true;
+    }
+    // both not()
+    if (b1.matchesNoneOfValues() && b2.matchesNoneOfValues()) {
+      return checkX(b1h, b2h, b1h.length >= b2h.length);
+    }
+    // both normal
+    return checkX(b2h, b1h, b1h.length <= b2h.length);
+  }
+
+  private static boolean checkX(int[] b1h, int[] b2h, boolean b) {
+    if (b) {
+      return false;
+    }
+    for (int i : b1h) {
+      boolean found = false;
+      for (int u : b2h) {
+        found |= i == u;
+        if (found) {
+          break;
+        }
+      }
+      if (!found) {
+        return false;
+      }
+    }
+    return true;
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringSubsumption.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringSubsumption.java
new file mode 100644
index 00000000..e21e32b2
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringSubsumption.java
@@ -0,0 +1,26 @@
+package de.unikoblenz.fgbks.base.utils.boundary.checker;
+
+import de.unikoblenz.fgbks.base.utils.boundary.impl.StringBoundary;
+
+public class CheckStringSubsumption extends AbstractBoundaryCheck<StringBoundary> {
+
+  private static CheckStringSubsumption instance = new CheckStringSubsumption();
+
+  public static CheckStringSubsumption getInstance() {
+    return instance;
+  }
+
+  @Override
+  public BoundaryCheckType getType() {
+    return BoundaryCheckType.IS_NOT_IN_CONTACT;
+  }
+
+  @Override
+  public boolean check(StringBoundary b1, StringBoundary b2) {
+    return checkSubsumption(b1, b2);
+  }
+
+  public static boolean checkSubsumption(StringBoundary b1, StringBoundary b2) {
+    return CheckStringSubsumes.checkSubsumes(b1, b2) || CheckStringSubsumes.checkSubsumes(b2, b1);
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/StringBoundary.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/StringBoundary.java
index 762744e0..cd465650 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/StringBoundary.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/StringBoundary.java
@@ -6,6 +6,11 @@ import de.unikoblenz.fgbks.base.utils.boundary.BoundaryParseException;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheck;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckStringEqual;
+import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckStringInContact;
+import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckStringNotInContact;
+import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckStringOverlap;
+import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckStringSubsumes;
+import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckStringSubsumption;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Objects;
@@ -28,7 +33,7 @@ public class StringBoundary extends AbstractBoundary<String> {
     return o.getText().compareTo(o.getText());
   }
 
-  public boolean isMatchNoneOfValues() {
+  public boolean matchesNoneOfValues() {
     return matchNoneOfValues;
   }
 
@@ -86,6 +91,11 @@ public class StringBoundary extends AbstractBoundary<String> {
   protected HashMap<BoundaryCheckType, BoundaryCheck> getChecker() {
     HashMap<BoundaryCheckType, BoundaryCheck> map = new HashMap<>();
     map.put(BoundaryCheckType.IS_EQUAL, CheckStringEqual.getInstance());
+    map.put(BoundaryCheckType.IS_IN_CONTACT, CheckStringInContact.getInstance());
+    map.put(BoundaryCheckType.IS_NOT_IN_CONTACT, CheckStringNotInContact.getInstance());
+    map.put(BoundaryCheckType.IS_OVERLAPPING, CheckStringOverlap.getInstance());
+    map.put(BoundaryCheckType.IS_SUBSUMPTION, CheckStringSubsumption.getInstance());
+    map.put(BoundaryCheckType.SUBSUMES, CheckStringSubsumes.getInstance());
     return map;
   }
 
diff --git a/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringNotInContactTest.java b/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringNotInContactTest.java
index 5ead6685..6d4e0e3c 100644
--- a/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringNotInContactTest.java
+++ b/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringNotInContactTest.java
@@ -8,7 +8,7 @@ class CheckStringNotInContactTest extends AbstractStringCheckerTest {
 
   @Test
   void check() {
-    super.checker = CheckStringNotContact.getInstance();
+    super.checker = CheckStringNotInContact.getInstance();
     doStringCheck("\"a\"", "\"a\"", false);
     doStringCheck("\"a\"", "\"b\"", true);
     doStringCheck("\"a\"", "not(\"a\")", true);
diff --git a/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringSubsumesTest.java b/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringSubsumesTest.java
new file mode 100644
index 00000000..f4900dc0
--- /dev/null
+++ b/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckStringSubsumesTest.java
@@ -0,0 +1,40 @@
+package de.unikoblenz.fgbks.base.utils.boundary.checker;
+
+import org.junit.jupiter.api.Test;
+
+class CheckStringSubsumesTest extends AbstractStringCheckerTest {
+
+  @Test
+  void check() {
+    super.checker = CheckStringSubsumes.getInstance();
+    doStringCheck("\"a\"", "\"a\"", false);
+    doStringCheck("\"a\"", "\"b\"", false);
+    doStringCheck("\"a\"", "not(\"a\")", false);
+    doStringCheck("\"a\"", "not(\"b\")", false);
+    doStringCheck("\"a\"", "\"a\",\"b\"", false);
+    doStringCheck("\"a\"", "\"c\",\"b\"", false);
+    doStringCheck("\"a\"", "not(\"a\",\"b\")", false);
+    doStringCheck("\"a\"", "not(\"c\",\"b\")", false);
+    doStringCheck("\"a\"", "\"a\"", false);
+    doStringCheck("\"b\"", "\"a\"", false);
+    doStringCheck("not(\"a\")", "\"a\"", false);
+    doStringCheck("not(\"b\")", "\"a\"", true);
+    doStringCheck("\"a\",\"b\"", "\"a\"", true);
+    doStringCheck("\"c\",\"b\"", "\"a\"", false);
+    doStringCheck("not(\"a\",\"b\")", "\"a\"", false);
+    doStringCheck("not(\"c\",\"b\")", "\"a\"", true);
+    doStringCheck("not(\"c\",\"b\")", "not(\"c\",\"b\")", false);
+    doStringCheck("not(\"a\",\"c\",\"b\")", "not(\"c\",\"b\")", false);
+    doStringCheck("not(\"b\")", "not(\"c\",\"b\")", true);
+    doStringCheck("", "\"c\",\"b\"", true);
+    doStringCheck("", "\"c\"", true);
+    doStringCheck("\"c\",\"b\"", "", false);
+    doStringCheck("\"c\"", "", false);
+    doStringCheck("", "", false);
+  }
+
+  @Override
+  protected boolean checkBothWays() {
+    return false;
+  }
+}
-- 
GitLab