Fix another corner case of datatypes+PBE (#2938)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Fri, 5 Apr 2019 20:31:20 +0000 (15:31 -0500)
committerGitHub <noreply@github.com>
Fri, 5 Apr 2019 20:31:20 +0000 (15:31 -0500)
src/theory/quantifiers/sygus/sygus_unif_io.cpp
src/theory/quantifiers/sygus/sygus_unif_io.h
test/regress/CMakeLists.txt
test/regress/regress1/sygus/issue2935.sy [new file with mode: 0644]

index 7d51ec43a0e0d6c2f46037ee215b4c866a4cf212..207aa4c8e1cb117ce6059329e85042c7ae978a86 100644 (file)
@@ -458,25 +458,26 @@ void SubsumeTrie::getLeavesInternal(const std::vector<Node>& vals,
     {
       int new_status = status;
       bool success = true;
-      // if the current value is true, we must consider the value of this child
+      // If the current value is true, then this is a relevant point.
+      // We must consider the value of this child.
       if (curr_val_true)
       {
-        if (status != 0)
+        if (it->first.isNull())
         {
-          if (it->first.isNull())
-          {
-            // The value of this child is unknown on this point, hence we
-            // ignore it.
-            success = false;
-          }
-          else
+          // The value of this child is unknown on this point, hence we
+          // do not recurse
+          success = false;
+        }
+        else if (status != 0)
+        {
+          // if the status is not zero (indicating that we have a mix of T/F),
+          // then we must compute the new status.
+          Assert(it->first.getType().isBoolean());
+          Assert(it->first.isConst());
+          new_status = (it->first.getConst<bool>() ? 1 : -1);
+          if (status != -2 && new_status != status)
           {
-            Assert(it->first.getType().isBoolean());
-            new_status = (it->first.getConst<bool>() ? 1 : -1);
-            if (status != -2 && new_status != status)
-            {
-              new_status = 0;
-            }
+            new_status = 0;
           }
         }
       }
index 5d38ba82705a29dc4555355f17788a5ded23240b..fced298719184169edfdb12e562338c58d7c3db4 100644 (file)
@@ -218,7 +218,24 @@ class SubsumeTrie
                        int status,
                        bool checkExistsOnly,
                        bool checkSubsume);
-  /** helper function for above functions */
+  /** helper function for above functions
+   *
+   * This adds to v[-1], v[0], v[1] the children of the trie that occur
+   * along paths that contain only false (v[-1]), a mix of true/false (v[0]),
+   * and only true (v[1]) values for respectively for relevant points.
+   *
+   * vals/pol is used to determine the relevant points, which impacts which
+   * paths of the trie to traverse on this call.
+   * In particular, all points such that (pol ? vals[index] : !vals[index])
+   * are relevant.
+   *
+   * Paths that contain an unknown value for any relevant point are not
+   * traversed. In the larger picture, this ensures that terms are not used in a
+   * way such that their unknown value is relevant to the overall behavior of
+   * a synthesis solution.
+   *
+   * status holds the current value of v (0,1,-1) that we will be adding to.
+   */
   void getLeavesInternal(const std::vector<Node>& vals,
                          bool pol,
                          std::map<int, std::vector<Node>>& v,
index a9b807e82533f3a9c336c742e51b45b67d7b8f85..64da9ec61f5d380e6916fb9c090ebbc4b4b1323a 100644 (file)
@@ -1625,6 +1625,7 @@ set(regress_1_tests
   regress1/sygus/inv-missed-sol-true.sy
   regress1/sygus/inv-unused.sy
   regress1/sygus/issue2914.sy
+  regress1/sygus/issue2935.sy
   regress1/sygus/large-const-simp.sy
   regress1/sygus/let-bug-simp.sy
   regress1/sygus/list-head-x.sy
diff --git a/test/regress/regress1/sygus/issue2935.sy b/test/regress/regress1/sygus/issue2935.sy
new file mode 100644 (file)
index 0000000..5616d19
--- /dev/null
@@ -0,0 +1,36 @@
+; EXPECT: unsat
+; COMMAND-LINE: --sygus-out=status
+(set-logic SLIA)
+(declare-datatype JSIdentifier ((JSInt (jsInt Int)) (JSString (jsString String)) ))
+
+(synth-fun f ((x1_ JSIdentifier)(x2_ String)) JSIdentifier
+       ((Start JSIdentifier (ntJSIdentifier))
+               (ntInt Int
+                       (1
+                               (+ ntInt ntInt)
+                               (jsInt ntJSIdentifier)
+                       )
+               )
+               (ntString String
+                       (x2_
+                               (str.substr ntString ntInt ntInt)
+                               (jsString ntJSIdentifier)
+                       )
+               )
+               (ntBool Bool
+                       ( 
+                               (= ntString ntString)
+                       )
+               )
+               (ntJSIdentifier JSIdentifier
+                       ( x1_  
+                       (ite ntBool ntJSIdentifier ntJSIdentifier)
+                       (JSString ntString)
+                       )
+               )
+       )
+)
+(constraint (= (f (JSString "") "") (JSString "")))
+(constraint (= (f (JSString "M") "W") (JSString "M")))
+(constraint (= (f (JSString "Moon") "") (JSString "on")))
+(check-synth)