exportTo only if needed for --sygus-rr-synth-check (#2168)
authorAndres Noetzli <andres.noetzli@gmail.com>
Sat, 14 Jul 2018 08:45:58 +0000 (01:45 -0700)
committerAndrew Reynolds <andrew.j.reynolds@gmail.com>
Sat, 14 Jul 2018 08:45:58 +0000 (10:45 +0200)
src/expr/expr_manager_template.cpp
src/expr/expr_template.cpp
src/expr/type_node.cpp
src/theory/quantifiers/candidate_rewrite_database.cpp

index 33b06ead409b24388161d66aaed9770c64178f00..457e54d9bfe169493a8343e06864146607a54593 100644 (file)
@@ -1023,6 +1023,16 @@ TypeNode exportTypeInternal(TypeNode n, NodeManager* from, NodeManager* to, Expr
   } else if(n.getKind() == kind::BITVECTOR_TYPE) {
     return to->mkBitVectorType(n.getConst<BitVectorSize>());
   }
+  else if (n.getKind() == kind::FLOATINGPOINT_TYPE)
+  {
+    return to->mkFloatingPointType(n.getConst<FloatingPointSize>());
+  }
+  else if (n.getNumChildren() == 0)
+  {
+    std::stringstream msg;
+    msg << "export of type " << n << " not supported";
+    throw ExportUnsupportedException(msg.str().c_str());
+  }
   Type from_t = from->toType(n);
   Type& to_t = vmap.d_typeMap[from_t];
   if(! to_t.isNull()) {
index 1344935affbbec176764cdc59e179e023fb1efc9..3a0d31b2d7d85c145e6dbd0d35f22566ce610dc3 100644 (file)
@@ -248,8 +248,11 @@ public:
         children.push_back(exportInternal(*i));
       }
       if(Debug.isOn("export")) {
-        ExprManagerScope ems(*to);
         Debug("export") << "children for export from " << n << std::endl;
+
+        // `n` belongs to the `from` ExprManager, so begin ExprManagerScope
+        // after printing `n`
+        ExprManagerScope ems(*to);
         for(std::vector<Node>::iterator i = children.begin(), i_end = children.end(); i != i_end; ++i) {
           Debug("export") << "  child: " << *i << std::endl;
         }
index b3e5c5a8393c3db364851fefe46efe50b62ce991..d6cf12d41062c54a97457b88c7cdcec4c1e7e4a4 100644 (file)
@@ -342,6 +342,7 @@ TypeNode TypeNode::commonTypeNode(TypeNode t0, TypeNode t1, bool isLeast) {
   // t1.getKind() == kind::TYPE_CONSTANT
   switch(t0.getKind()) {
   case kind::BITVECTOR_TYPE:
+  case kind::FLOATINGPOINT_TYPE:
   case kind::SORT_TYPE:
   case kind::CONSTRUCTOR_TYPE:
   case kind::SELECTOR_TYPE:
index f9c63f4da056123c1e581f7f62bfda7f00cbf8c2..3df3717c3f96d96018dd0855b86024289b7350cd 100644 (file)
@@ -112,16 +112,7 @@ bool CandidateRewriteDatabase::addTerm(Node sol,
       // verify it if applicable
       if (options::sygusRewSynthCheck())
       {
-        // Notice we don't set produce-models. rrChecker takes the same
-        // options as the SmtEngine we belong to, where we ensure that
-        // produce-models is set.
         NodeManager* nm = NodeManager::currentNM();
-        Options opts;
-        ExprManager em(nm->getOptions());
-        ExprManagerMapCollection varMap;
-        SmtEngine rrChecker(&em);
-        rrChecker.setTimeLimit(options::sygusRewSynthCheckTimeout(), true);
-        rrChecker.setLogic(smt::currentSmtEngine()->getLogicInfo());
 
         Node crr = solbr.eqNode(eq_solr).negate();
         Trace("rr-check") << "Check candidate rewrite : " << crr << std::endl;
@@ -151,9 +142,48 @@ bool CandidateRewriteDatabase::addTerm(Node sol,
           }
           crr = crr.substitute(fvs.begin(), fvs.end(), sks.begin(), sks.end());
         }
-        Expr eccr = crr.toExpr().exportTo(&em, varMap);
-        rrChecker.assertFormula(eccr);
-        Result r = rrChecker.checkSat();
+
+        // Notice we don't set produce-models. rrChecker takes the same
+        // options as the SmtEngine we belong to, where we ensure that
+        // produce-models is set.
+        bool needExport = true;
+        ExprManagerMapCollection varMap;
+        ExprManager em(nm->getOptions());
+        std::unique_ptr<SmtEngine> rrChecker;
+        Result r;
+        if (options::sygusRewSynthCheckTimeout.wasSetByUser())
+        {
+          // To support a separate timeout for the subsolver, we need to create
+          // a separate ExprManager with its own options. This requires that
+          // the expressions sent to the subsolver can be exported from on
+          // ExprManager to another. If the export fails, we throw an
+          // OptionException.
+          try
+          {
+            rrChecker.reset(new SmtEngine(&em));
+            rrChecker->setTimeLimit(options::sygusRewSynthCheckTimeout(), true);
+            rrChecker->setLogic(smt::currentSmtEngine()->getLogicInfo());
+            Expr eccr = crr.toExpr().exportTo(&em, varMap);
+            rrChecker->assertFormula(eccr);
+            r = rrChecker->checkSat();
+          }
+          catch (const CVC4::ExportUnsupportedException& e)
+          {
+            std::stringstream msg;
+            msg << "Unable to export " << crr
+                << " but exporting expressions is required for "
+                   "--sygus-rr-synth-check-timeout.";
+            throw OptionException(msg.str());
+          }
+        }
+        else
+        {
+          needExport = false;
+          rrChecker.reset(new SmtEngine(nm->toExprManager()));
+          rrChecker->assertFormula(crr.toExpr());
+          r = rrChecker->checkSat();
+        }
+
         Trace("rr-check") << "...result : " << r << std::endl;
         if (r.asSatisfiabilityResult().isSat() == Result::SAT)
         {
@@ -185,9 +215,16 @@ bool CandidateRewriteDatabase::addTerm(Node sol,
             if (val.isNull())
             {
               Assert(!refv.isNull() && refv.getKind() != BOUND_VARIABLE);
-              Expr erefv = refv.toExpr().exportTo(&em, varMap);
-              val = Node::fromExpr(rrChecker.getValue(erefv).exportTo(
-                  nm->toExprManager(), varMap));
+              if (needExport)
+              {
+                Expr erefv = refv.toExpr().exportTo(&em, varMap);
+                val = Node::fromExpr(rrChecker->getValue(erefv).exportTo(
+                    nm->toExprManager(), varMap));
+              }
+              else
+              {
+                val = Node::fromExpr(rrChecker->getValue(refv.toExpr()));
+              }
             }
             Trace("rr-check") << "  " << v << " -> " << val << std::endl;
             pt.push_back(val);