Generalize sygus-rr-verify for fast enumerator (#2829)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Thu, 14 Mar 2019 12:46:52 +0000 (07:46 -0500)
committerGitHub <noreply@github.com>
Thu, 14 Mar 2019 12:46:52 +0000 (07:46 -0500)
src/theory/datatypes/datatypes_sygus.cpp
src/theory/quantifiers/sygus/sygus_enumerator.cpp
src/theory/quantifiers/sygus/sygus_enumerator.h
src/theory/quantifiers/sygus_sampler.cpp
src/theory/quantifiers/sygus_sampler.h

index a8d9d93bc5d8c37296dd2ed2772e15aaa0fc86a2..cb2968bd5a2ea2d050f0f9b4c69b5e66a7133861 100644 (file)
@@ -1090,8 +1090,6 @@ Node SygusSymBreakNew::registerSearchValue(Node a,
       {
         if (bv != bvr)
         {
-          Trace("sygus-rr-verify")
-              << "Testing rewrite rule " << bv << " ---> " << bvr << std::endl;
           // add to the sampler database object
           std::map<TypeNode, quantifiers::SygusSampler>::iterator its =
               d_sampler[a].find(tn);
@@ -1101,55 +1099,8 @@ Node SygusSymBreakNew::registerSearchValue(Node a,
                 d_tds, nv, options::sygusSamples(), false);
             its = d_sampler[a].find(tn);
           }
-          // see if they evaluate to same thing on all sample points
-          bool ptDisequal = false;
-          unsigned pt_index = 0;
-          Node bve, bvre;
-          for (unsigned i = 0, npoints = its->second.getNumSamplePoints();
-               i < npoints;
-               i++)
-          {
-            bve = its->second.evaluate(bv, i);
-            bvre = its->second.evaluate(bvr, i);
-            if (bve != bvre)
-            {
-              ptDisequal = true;
-              pt_index = i;
-              break;
-            }
-          }
-          // bv and bvr should be equivalent under examples
-          if (ptDisequal)
-          {
-            // we have detected unsoundness in the rewriter
-            Options& nodeManagerOptions =
-                NodeManager::currentNM()->getOptions();
-            std::ostream* out = nodeManagerOptions.getOut();
-            (*out) << "(unsound-rewrite " << bv << " " << bvr << ")"
-                   << std::endl;
-            // debugging information
-            (*out) << "; unsound: are not equivalent for : " << std::endl;
-            std::vector<Node> vars;
-            its->second.getVariables(vars);
-            std::vector<Node> pt;
-            its->second.getSamplePoint(pt_index, pt);
-            Assert(vars.size() == pt.size());
-            for (unsigned i = 0, size = pt.size(); i < size; i++)
-            {
-              (*out) << "; unsound:    " << vars[i] << " -> " << pt[i]
-                     << std::endl;
-            }
-            Assert(bve != bvre);
-            (*out) << "; unsound: where they evaluate to " << bve << " and "
-                   << bvre << std::endl;
-
-            if (options::sygusRewVerifyAbort())
-            {
-              AlwaysAssert(
-                  false,
-                  "--sygus-rr-verify detected unsoundness in the rewriter!");
-            }
-          }
+          // check equivalent
+          its->second.checkEquivalent(bv, bvr);
         }
       }
 
index d4b4dd0bf7e05dfb410d479a077ef892262b6321..9981b514189173245f03a6c8aa8945a33c10ecd3 100644 (file)
@@ -145,7 +145,8 @@ SygusEnumerator::TermCache::TermCache()
       d_isSygusType(false),
       d_numConClasses(0),
       d_sizeEnum(0),
-      d_isComplete(false)
+      d_isComplete(false),
+      d_sampleRrVInit(false)
 {
 }
 void SygusEnumerator::TermCache::initialize(Node e,
@@ -311,6 +312,19 @@ bool SygusEnumerator::TermCache::addTerm(Node n)
   {
     Node bn = d_tds->sygusToBuiltin(n);
     Node bnr = d_tds->getExtRewriter()->extendedRewrite(bn);
+    if (options::sygusRewVerify())
+    {
+      if (bn != bnr)
+      {
+        if (!d_sampleRrVInit)
+        {
+          d_sampleRrVInit = true;
+          d_samplerRrV.initializeSygus(
+              d_tds, d_enum, options::sygusSamples(), false);
+        }
+        d_samplerRrV.checkEquivalent(bn, bnr);
+      }
+    }
     // must be unique up to rewriting
     if (d_bterms.find(bnr) != d_bterms.end())
     {
index af6bb03f01f7f4ce273620f43e552ec679bc2338..716a047d24783e755b6a8c011802b58955d1772f 100644 (file)
@@ -179,6 +179,10 @@ class SygusEnumerator : public EnumValGenerator
     unsigned d_sizeEnum;
     /** whether this term cache is complete */
     bool d_isComplete;
+    /** sampler (for --sygus-rr-verify) */
+    quantifiers::SygusSampler d_samplerRrV;
+    /** is the above sampler initialized? */
+    bool d_sampleRrVInit;
   };
   /** above cache for each sygus type */
   std::map<TypeNode, TermCache> d_tcache;
index 27ca270cc0a41d542825603e11f091b989022d37..9727149bec5dd03ec014bce2d79a497ea201c91b 100644 (file)
@@ -769,6 +769,56 @@ void SygusSampler::registerSygusType(TypeNode tn)
   }
 }
 
+void SygusSampler::checkEquivalent(Node bv, Node bvr)
+{
+  Trace("sygus-rr-verify") << "Testing rewrite rule " << bv << " ---> " << bvr
+                           << std::endl;
+
+  // see if they evaluate to same thing on all sample points
+  bool ptDisequal = false;
+  unsigned pt_index = 0;
+  Node bve, bvre;
+  for (unsigned i = 0, npoints = getNumSamplePoints(); i < npoints; i++)
+  {
+    bve = evaluate(bv, i);
+    bvre = evaluate(bvr, i);
+    if (bve != bvre)
+    {
+      ptDisequal = true;
+      pt_index = i;
+      break;
+    }
+  }
+  // bv and bvr should be equivalent under examples
+  if (ptDisequal)
+  {
+    // we have detected unsoundness in the rewriter
+    Options& nodeManagerOptions = NodeManager::currentNM()->getOptions();
+    std::ostream* out = nodeManagerOptions.getOut();
+    (*out) << "(unsound-rewrite " << bv << " " << bvr << ")" << std::endl;
+    // debugging information
+    (*out) << "; unsound: are not equivalent for : " << std::endl;
+    std::vector<Node> vars;
+    getVariables(vars);
+    std::vector<Node> pt;
+    getSamplePoint(pt_index, pt);
+    Assert(vars.size() == pt.size());
+    for (unsigned i = 0, size = pt.size(); i < size; i++)
+    {
+      (*out) << "; unsound:    " << vars[i] << " -> " << pt[i] << std::endl;
+    }
+    Assert(bve != bvre);
+    (*out) << "; unsound: where they evaluate to " << bve << " and " << bvre
+           << std::endl;
+
+    if (options::sygusRewVerifyAbort())
+    {
+      AlwaysAssert(false,
+                   "--sygus-rr-verify detected unsoundness in the rewriter!");
+    }
+  }
+}
+
 } /* CVC4::theory::quantifiers namespace */
 } /* CVC4::theory namespace */
 } /* CVC4 namespace */
index 526a9e4b165ce5cd3d9b7e8b09a221f8a2241a3b..288563a04dc4a295d000ce87a4dd4cd5e1ce86d4 100644 (file)
@@ -165,6 +165,12 @@ class SygusSampler : public LazyTrieEvaluator
    */
   bool containsFreeVariables(Node a, Node b, bool strict = false);
   //--------------------------end queries about terms
+  /** check equivalent
+   *
+   * Check whether bv and bvr are equivalent on all sample points, print
+   * an error if not. Used with --sygus-rr-verify.
+   */
+  void checkEquivalent(Node bv, Node bvr);
 
  protected:
   /** sygus term database of d_qe */