Fix non-fixed length case in re-elim (#6612)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Mon, 24 May 2021 23:59:28 +0000 (18:59 -0500)
committerGitHub <noreply@github.com>
Mon, 24 May 2021 23:59:28 +0000 (23:59 +0000)
Fixes followup issues from #6604.

src/theory/strings/regexp_elim.cpp
test/regress/CMakeLists.txt
test/regress/regress1/strings/issue6604-2.smt2 [new file with mode: 0644]

index c3580d9636eff6f17497274f73c79b487ac41832..f635cdc391db080838aaf6f16c394804e6e0accb 100644 (file)
@@ -90,7 +90,8 @@ Node RegExpElimination::eliminateConcat(Node atom, bool isAgg)
   // into fixed length regular expressions are easy to handle.
   // the index of _* in re
   unsigned pivotIndex = 0;
-  size_t numPivotIndex = 0;
+  bool hasPivotIndex = false;
+  bool hasFixedLength = true;
   std::vector<Node> childLengths;
   std::vector<Node> childLengthsPostPivot;
   for (unsigned i = 0, size = children.size(); i < size; i++)
@@ -99,34 +100,34 @@ Node RegExpElimination::eliminateConcat(Node atom, bool isAgg)
     Node fl = RegExpEntail::getFixedLengthForRegexp(c);
     if (fl.isNull())
     {
-      if (numPivotIndex == 0 && c.getKind() == REGEXP_STAR
+      if (!hasPivotIndex && c.getKind() == REGEXP_STAR
           && c[0].getKind() == REGEXP_SIGMA)
       {
-        numPivotIndex = 1;
+        hasPivotIndex = true;
         pivotIndex = i;
         // zero is used in sum below and is used for concat-fixed-len
         fl = zero;
       }
       else
       {
-        numPivotIndex++;
+        hasFixedLength = false;
       }
     }
     if (!fl.isNull())
     {
       childLengths.push_back(fl);
-      if (numPivotIndex > 0)
+      if (hasPivotIndex)
       {
         childLengthsPostPivot.push_back(fl);
       }
     }
   }
-  Node lenSum = childLengths.size() > 1 ? nm->mkNode(PLUS, childLengths)
-                                        : childLengths[0];
-  // if we have at most one pivot index
-  if (numPivotIndex <= 1)
+  Node lenSum = childLengths.size() > 1
+                    ? nm->mkNode(PLUS, childLengths)
+                    : (childLengths.empty() ? zero : childLengths[0]);
+  // if we have a fixed length
+  if (hasFixedLength)
   {
-    bool hasPivotIndex = (numPivotIndex == 1);
     Assert(re.getNumChildren() == children.size());
     std::vector<Node> conc;
     conc.push_back(nm->mkNode(hasPivotIndex ? GEQ : EQUAL, lenx, lenSum));
index 3d8016379d75398098a1f2f6ff0b82ffa82b379c..01deeaedef4dbb526f5ca7b1113043193aaf4c9e 100644 (file)
@@ -2089,6 +2089,7 @@ set(regress_1_tests
   regress1/strings/issue6271-rnf.smt2
   regress1/strings/issue6271-2-rnf.smt2
   regress1/strings/issue6567-empty-re-range.smt2
+  regress1/strings/issue6604-2.smt2
   regress1/strings/kaluza-fl.smt2
   regress1/strings/loop002.smt2
   regress1/strings/loop003.smt2
diff --git a/test/regress/regress1/strings/issue6604-2.smt2 b/test/regress/regress1/strings/issue6604-2.smt2
new file mode 100644 (file)
index 0000000..e28f5dc
--- /dev/null
@@ -0,0 +1,7 @@
+; COMMAND-LINE: --strings-exp --re-elim
+; EXPECT: unsat
+(set-logic ALL)
+(declare-const a String)
+(assert (str.in_re a (re.++ (str.to_re "A") re.allchar (str.to_re "A"))))
+(assert (not (str.in_re a (re.++ (str.to_re "A") (re.* (re.++ (str.to_re "A") re.allchar)) re.allchar (str.to_re "A")))))
+(check-sat)