Fix large models for strings (#3835)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Thu, 27 Feb 2020 19:48:50 +0000 (13:48 -0600)
committerGitHub <noreply@github.com>
Thu, 27 Feb 2020 19:48:50 +0000 (11:48 -0800)
Fixes #3375.

Marking as "major" since in fact we produce incorrect models in production without the fix.

src/theory/strings/theory_strings.cpp
test/regress/CMakeLists.txt
test/regress/regress0/strings/large-model.smt2 [new file with mode: 0644]

index c2790fe42506a79a35dbab14f21aa3f17d3a1c34..cd1d0cd677f4f329c48f0245c38ad320cf01d409 100644 (file)
@@ -304,8 +304,13 @@ bool TheoryStrings::collectModelInfo(TheoryModel* m)
     }
     else
     {
-      Assert(len_value.getConst<Rational>() <= Rational(String::maxSize()))
-          << "Exceeded UINT32_MAX in string model";
+      // must throw logic exception if we cannot construct the string
+      if (len_value.getConst<Rational>() > Rational(String::maxSize()))
+      {
+        std::stringstream ss;
+        ss << "Cannot generate model with string whose length exceeds UINT32_MAX";
+        throw LogicException(ss.str());
+      }
       unsigned lvalue =
           len_value.getConst<Rational>().getNumerator().toUnsignedInt();
       std::map<unsigned, Node>::iterator itvu = values_used.find(lvalue);
index 7be085d483513db992081d9ce089caa78adfacc0..332b703e8b915d170eb94de320c048fc4b48826d 100644 (file)
@@ -913,6 +913,7 @@ set(regress_0_tests
   regress0/strings/issue3497.smt2
   regress0/strings/issue3657-evalLeq.smt2
   regress0/strings/itos-entail.smt2
+  regress0/strings/large-model.smt2
   regress0/strings/leadingzero001.smt2
   regress0/strings/loop001.smt2
   regress0/strings/model001.smt2
diff --git a/test/regress/regress0/strings/large-model.smt2 b/test/regress/regress0/strings/large-model.smt2
new file mode 100644 (file)
index 0000000..ca52e81
--- /dev/null
@@ -0,0 +1,7 @@
+; COMMAND-LINE: --lang=smt2.6.1 --check-models
+; EXPECT: (error "Cannot generate model with string whose length exceeds UINT32_MAX")
+; EXIT: 1
+(set-logic SLIA)
+(declare-fun x () String)
+(assert (> (str.len x) 100000000000000000000000000000000000000000000000000))
+(check-sat)