Fix corner case in stripConstantEndpoints (#2824)
authorAndres Noetzli <andres.noetzli@gmail.com>
Sat, 2 Feb 2019 08:36:42 +0000 (00:36 -0800)
committerGitHub <noreply@github.com>
Sat, 2 Feb 2019 08:36:42 +0000 (00:36 -0800)
`stripConstantEndpoints()` was returning `true` when the first argument
was a list only containing an empty string, which could lead to rewrite
loops. This commit checks for that case and adds a unit test for it.

src/theory/strings/theory_strings_rewriter.cpp
test/unit/theory/theory_strings_rewriter_white.h

index 0c8d6ac8df78d1ca0fba0a0ff66d79b78b2557c0..f90d5bcfd5867436813434d6b38f7e3ba51ce6ff 100644 (file)
@@ -3583,6 +3583,12 @@ bool TheoryStringsRewriter::stripConstantEndpoints(std::vector<Node>& n1,
       unsigned index1 = r == 0 ? 0 : n2.size() - 1;
       bool removeComponent = false;
       Node n1cmp = n1[index0];
+
+      if (n1cmp.isConst() && n1cmp.getConst<String>().size() == 0)
+      {
+        return false;
+      }
+
       std::vector<Node> sss;
       std::vector<Node> sls;
       n1cmp = decomposeSubstrChain(n1cmp, sss, sls);
index 5f08ce741190484141918183c8594a241f60d9f0..bbaa4733f8c0f80b2d65aefc7567ea2702d2584f 100644 (file)
@@ -1180,6 +1180,23 @@ class TheoryStringsRewriterWhite : public CxxTest::TestSuite
     }
   }
 
+  void testStripConstantEndpoints()
+  {
+    Node empty = d_nm->mkConst(::CVC4::String(""));
+    Node a = d_nm->mkConst(::CVC4::String("A"));
+
+    {
+      // stripConstantEndpoints({ "" }, { "a" }, {}, {}, 0) ---> false
+      std::vector<Node> n1 = {empty};
+      std::vector<Node> n2 = {a};
+      std::vector<Node> nb;
+      std::vector<Node> ne;
+      bool res =
+          TheoryStringsRewriter::stripConstantEndpoints(n1, n2, nb, ne, 0);
+      TS_ASSERT(!res);
+    }
+  }
+
  private:
   ExprManager* d_em;
   SmtEngine* d_smt;