Fix rewrite for contains over replace (#5924)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Fri, 19 Feb 2021 14:43:22 +0000 (08:43 -0600)
committerGitHub <noreply@github.com>
Fri, 19 Feb 2021 14:43:22 +0000 (08:43 -0600)
Fixes model soundness issue (fixes #5915).

src/theory/strings/sequences_rewriter.cpp
test/regress/CMakeLists.txt
test/regress/regress0/strings/issue5915-repl-ctn-rewrite.smt2 [new file with mode: 0644]

index 2a30727ba9e29434370c975b75132740789eda49..be1bd904565579932f2f1895df0df7408a7489e2 100644 (file)
@@ -2206,7 +2206,7 @@ Node SequencesRewriter::rewriteContains(Node node)
     // if (str.contains z w) ---> false and (str.len w) = 1
     if (StringsEntail::checkLengthOne(node[1]))
     {
-      Node ctn = d_stringsEntail.checkContains(node[1], node[0][2]);
+      Node ctn = d_stringsEntail.checkContains(node[0][2], node[1]);
       if (!ctn.isNull() && !ctn.getConst<bool>())
       {
         Node empty = Word::mkEmptyWord(stype);
@@ -2558,7 +2558,7 @@ Node SequencesRewriter::rewriteReplace(Node node)
   // check if contains definitely does (or does not) hold
   Node cmp_con = nm->mkNode(kind::STRING_STRCTN, node[0], node[1]);
   Node cmp_conr = Rewriter::rewrite(cmp_con);
-  if (!d_stringsEntail.checkContains(node[0], node[1]).isNull())
+  if (cmp_conr.isConst())
   {
     if (cmp_conr.getConst<bool>())
     {
index d455bb85b39676f509a2556752e816795eb6b300..fa4628de7a2f213abbf33c7b1ff04471d01c1b50 100644 (file)
@@ -1115,6 +1115,7 @@ set(regress_0_tests
   regress0/strings/issue5767-eager-pp.smt2
   regress0/strings/issue5771-eager-pp.smt2
   regress0/strings/issue5816-re-kind.smt2
+  regress0/strings/issue5915-repl-ctn-rewrite.smt2
   regress0/strings/itos-entail.smt2
   regress0/strings/large-model.smt2
   regress0/strings/leadingzero001.smt2
diff --git a/test/regress/regress0/strings/issue5915-repl-ctn-rewrite.smt2 b/test/regress/regress0/strings/issue5915-repl-ctn-rewrite.smt2
new file mode 100644 (file)
index 0000000..42326da
--- /dev/null
@@ -0,0 +1,9 @@
+; COMMAND-LINE: --strings-exp
+; EXPECT: unsat
+(set-logic ALL)
+(set-info :status unsat)
+(declare-fun x () String)
+(declare-fun y () String)
+(declare-fun z () Int)
+(assert (= (str.replace (str.replace x "B" (str.++ "B" "B")) "B" (str.++ y "B")) (str.++ y "B")))
+(check-sat)