Fix relevant domain computation for nested quantifiers coming from CEGQI (#4235)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Tue, 14 Apr 2020 21:27:29 +0000 (16:27 -0500)
committerGitHub <noreply@github.com>
Tue, 14 Apr 2020 21:27:29 +0000 (16:27 -0500)
Fixes #4228. That benchmark now times out.

src/theory/quantifiers/inst_strategy_enumerative.cpp
src/theory/quantifiers/instantiate.cpp
src/theory/quantifiers/instantiate.h
src/theory/quantifiers/relevant_domain.cpp
src/theory/quantifiers/term_util.cpp
src/theory/quantifiers/term_util.h

index 47e4a92285d81a22feb667324131108894269f3a..ce024fe8be6fef5108b04a7ed341a1b5ad0d870d 100644 (file)
@@ -301,7 +301,7 @@ bool InstStrategyEnum::process(Node f, bool fullEffort, bool isRd)
             {
               terms.push_back(d_rd->getRDomain(f, i)->d_terms[childIndex[i]]);
               Trace("inst-alg-rd")
-                  << "  " << d_rd->getRDomain(f, i)->d_terms[childIndex[i]]
+                  << "  (rd) " << d_rd->getRDomain(f, i)->d_terms[childIndex[i]]
                   << std::endl;
             }
             else
@@ -312,6 +312,7 @@ bool InstStrategyEnum::process(Node f, bool fullEffort, bool isRd)
                   << "  " << term_db_list[ftypes[i]][childIndex[i]]
                   << std::endl;
             }
+            Assert(terms[i].getType().isComparableTo(ftypes[i]));
           }
           if (ie->addInstantiation(f, terms))
           {
index 9969de4588b0589e91a4c929ee79b7607a7963e6..218753308e55fae65582655cbbf67ee70c1fb54e 100644 (file)
@@ -116,7 +116,7 @@ bool Instantiate::addInstantiation(
     // Ensure the type is correct, this for instance ensures that real terms
     // are cast to integers for { x -> t } where x has type Int and t has
     // type Real.
-    terms[i] = quantifiers::TermUtil::ensureType(terms[i], tn);
+    terms[i] = ensureType(terms[i], tn);
     if (mkRep)
     {
       // pick the best possible representative for instantiation, based on past
@@ -747,6 +747,22 @@ void Instantiate::debugPrintModel()
   }
 }
 
+Node Instantiate::ensureType(Node n, TypeNode tn)
+{
+  Trace("inst-add-debug2") << "Ensure " << n << " : " << tn << std::endl;
+  TypeNode ntn = n.getType();
+  Assert(ntn.isComparableTo(tn));
+  if (ntn.isSubtypeOf(tn))
+  {
+    return n;
+  }
+  if (tn.isInteger())
+  {
+    return NodeManager::currentNM()->mkNode(TO_INTEGER, n);
+  }
+  return Node::null();
+}
+
 Instantiate::Statistics::Statistics()
     : d_instantiations("Instantiate::Instantiations_Total", 0),
       d_inst_duplicate("Instantiate::Duplicate_Inst", 0),
index cd3993756117b661db878a882dfa267c72bab399..d10a44149c2b691d2fa61a8418fd86769992a3e7 100644 (file)
@@ -318,6 +318,11 @@ class Instantiate : public QuantifiersUtil
                                    bool addedLem = true);
   /** remove instantiation from the cache */
   bool removeInstantiationInternal(Node q, std::vector<Node>& terms);
+  /**
+   * Ensure that n has type tn, return a term equivalent to it for that type
+   * if possible.
+   */
+  static Node ensureType(Node n, TypeNode tn);
 
   /** pointer to the quantifiers engine */
   QuantifiersEngine* d_qe;
index fbd1f05a6c63f1194725b267a36fbce4744de292..6248e97222a1680866d441d9cd6a1b697020f2e4 100644 (file)
@@ -207,6 +207,7 @@ void RelevantDomain::computeRelevantDomainOpCh( RDomain * rf, Node n ) {
     Node q = d_qe->getTermUtil()->getInstConstAttr( n );
     //merge the RDomains
     unsigned id = n.getAttribute(InstVarNumAttribute());
+    Assert(q[0][id].getType() == n.getType());
     Trace("rel-dom-debug") << n << " is variable # " << id << " for " << q;
     Trace("rel-dom-debug") << " with body : " << d_qe->getTermUtil()->getInstConstantBody( q ) << std::endl;
     RDomain * rq = getRDomain( q, id );
@@ -225,9 +226,14 @@ void RelevantDomain::computeRelevantDomainLit( Node q, bool hasPol, bool pol, No
     d_rel_dom_lit[hasPol][pol][n].d_merge = false;
     int varCount = 0;
     int varCh = -1;
+    TermUtil* tu = d_qe->getTermUtil();
     for( unsigned i=0; i<n.getNumChildren(); i++ ){
       if( n[i].getKind()==INST_CONSTANT ){
-        d_rel_dom_lit[hasPol][pol][n].d_rd[i] = getRDomain( q, n[i].getAttribute(InstVarNumAttribute()), false );
+        // must get the quantified formula this belongs to, which may be
+        // different from q
+        Node qi = tu->getInstConstAttr(n[i]);
+        unsigned id = n[i].getAttribute(InstVarNumAttribute());
+        d_rel_dom_lit[hasPol][pol][n].d_rd[i] = getRDomain(qi, id, false);
         varCount++;
         varCh = i;
       }else{
index cc920f1d7202a741513931b4052c57ef20db3021..c8c72344f8bc74f04597db5c3f25da8c001b542e 100644 (file)
@@ -305,19 +305,6 @@ void TermUtil::computeInstConstContainsForQuant(Node q,
   }
 }
 
-Node TermUtil::ensureType( Node n, TypeNode tn ) {
-  TypeNode ntn = n.getType();
-  Assert(ntn.isComparableTo(tn));
-  if( ntn.isSubtypeOf( tn ) ){
-    return n;
-  }else{
-    if( tn.isInteger() ){
-      return NodeManager::currentNM()->mkNode( TO_INTEGER, n );
-    }
-    return Node::null();
-  }
-}
-
 int TermUtil::getTermDepth( Node n ) {
   if (!n.hasAttribute(TermDepthAttribute()) ){
     int maxDepth = -1;
index 904f301b91a91e5dbc646e4936ae6085ed01157f..315b4b1d03168a3ee188f0d1e80cbcc8715028e4 100644 (file)
@@ -160,8 +160,6 @@ public:
                                                std::vector<Node>& vars);
 
 public:
-  /** ensure type */
-  static Node ensureType( Node n, TypeNode tn );
   
 //general utilities
   // TODO #1216 : promote these?