Move higher-order matching predicate (#3280)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Fri, 13 Sep 2019 20:14:59 +0000 (15:14 -0500)
committerGitHub <noreply@github.com>
Fri, 13 Sep 2019 20:14:59 +0000 (15:14 -0500)
src/theory/quantifiers/ematching/ho_trigger.cpp
src/theory/quantifiers/term_database.cpp
src/theory/quantifiers/term_database.h
src/theory/quantifiers/term_util.cpp
src/theory/quantifiers/term_util.h
src/theory/uf/ho_extension.cpp

index 7598e6fdc13bacece21f78e8ee2a322cc0d07a9e..b01d5e1dfde0d740cd27418b3c5b2a20479360ca 100644 (file)
@@ -469,12 +469,12 @@ int HigherOrderTrigger::addHoTypeMatchPredicateLemmas()
   Trace("ho-quant-trigger") << "addHoTypeMatchPredicateLemmas..." << std::endl;
   unsigned numLemmas = 0;
   // this forces expansion of APPLY_UF terms to curried HO_APPLY chains
-  unsigned size = d_quantEngine->getTermDatabase()->getNumOperators();
-  quantifiers::TermUtil* tutil = d_quantEngine->getTermUtil();
+  quantifiers::TermDb* tdb = d_quantEngine->getTermDatabase();
+  unsigned size = tdb->getNumOperators();
   NodeManager* nm = NodeManager::currentNM();
   for (unsigned j = 0; j < size; j++)
   {
-    Node f = d_quantEngine->getTermDatabase()->getOperator(j);
+    Node f = tdb->getOperator(j);
     if (f.isVar())
     {
       TypeNode tn = f.getType();
@@ -497,7 +497,7 @@ int HigherOrderTrigger::addHoTypeMatchPredicateLemmas()
           // if a variable of this type occurs in this trigger
           if (d_ho_var_types.find(stn) != d_ho_var_types.end())
           {
-            Node u = tutil->getHoTypeMatchPredicate(tn);
+            Node u = tdb->getHoTypeMatchPredicate(tn);
             Node au = nm->mkNode(kind::APPLY_UF, u, f);
             if (d_quantEngine->addLemma(au))
             {
index 84147bf6b9c0f6c26681d0d1405a43146cbb62a8..9da9c95b67133060067d80afff6a856e16f7f498 100644 (file)
@@ -1229,6 +1229,20 @@ TNode TermDb::getCongruentTerm( Node f, std::vector< TNode >& args ) {
   return d_func_map_trie[f].existsTerm( args );
 }
 
+Node TermDb::getHoTypeMatchPredicate(TypeNode tn)
+{
+  std::map<TypeNode, Node>::iterator ithp = d_ho_type_match_pred.find(tn);
+  if (ithp != d_ho_type_match_pred.end())
+  {
+    return ithp->second;
+  }
+  NodeManager* nm = NodeManager::currentNM();
+  TypeNode ptn = nm->mkFunctionType(tn, nm->booleanType());
+  Node k = nm->mkSkolem("U", ptn, "predicate to force higher-order types");
+  d_ho_type_match_pred[tn] = k;
+  return k;
+}
+
 }/* CVC4::theory::quantifiers namespace */
 }/* CVC4::theory namespace */
 }/* CVC4 namespace */
index f92bce8bd5754969fa454d46b1ecf1d287f36ef6..7caf29d2002ff2b51212112fb58775675976e1f5 100644 (file)
@@ -291,6 +291,14 @@ class TermDb : public QuantifiersUtil {
    * Bansal et al., CAV 2015.
    */
   bool isInstClosure(Node r);
+  /** get higher-order type match predicate
+   *
+   * This predicate is used to force certain functions f of type tn to appear as
+   * first-class representatives in the quantifier-free UF solver. For a typical
+   * use case, we call getHoTypeMatchPredicate which returns a fresh predicate
+   * P of type (tn -> Bool). Then, we add P( f ) as a lemma.
+   */
+  Node getHoTypeMatchPredicate(TypeNode tn);
 
  private:
   /** reference to the quantifiers engine */
@@ -328,7 +336,12 @@ class TermDb : public QuantifiersUtil {
   /** has map */
   std::map< Node, bool > d_has_map;
   /** map from reps to a term in eqc in d_has_map */
-  std::map< Node, Node > d_term_elig_eqc;  
+  std::map<Node, Node> d_term_elig_eqc;
+  /**
+   * Dummy predicate that states terms should be considered first-class members
+   * of equality engine (for higher-order).
+   */
+  std::map<TypeNode, Node> d_ho_type_match_pred;
   /** set has term */
   void setHasTerm( Node n );
   /** helper for evaluate term */
index 48dc88537517e97de82b7d2401d5b49cd56f737c..6ffc50c97772343ec7f8ba6b08f7c660eff54d42 100644 (file)
@@ -954,19 +954,6 @@ bool TermUtil::hasOffsetArg(Kind ik, int arg, int& offset, Kind& ok)
   return false;
 }
 
-Node TermUtil::getHoTypeMatchPredicate( TypeNode tn ) {
-  std::map< TypeNode, Node >::iterator ithp = d_ho_type_match_pred.find( tn );
-  if( ithp==d_ho_type_match_pred.end() ){
-    TypeNode ptn = NodeManager::currentNM()->mkFunctionType( tn, NodeManager::currentNM()->booleanType() );
-    Node k = NodeManager::currentNM()->mkSkolem( "U", ptn, "predicate to force higher-order types" );
-    d_ho_type_match_pred[tn] = k;
-    return k;
-  }else{
-    return ithp->second;  
-  }
-}
-
-
 }/* CVC4::theory::quantifiers namespace */
 }/* CVC4::theory namespace */
 }/* CVC4 namespace */
index 99ea483d91113d380d406988874f9bf228bf0f29..52965d2fa6031c63341ba7f4e5d0b02fc0d58750 100644 (file)
@@ -348,19 +348,6 @@ public:
    * minimum and maximum elements, for example tn is Bool or BitVector.
    */
   static Node mkTypeConst(TypeNode tn, bool pol);
-
-  // for higher-order
- private:
-  /** dummy predicate that states terms should be considered first-class members of equality engine */
-  std::map< TypeNode, Node > d_ho_type_match_pred;
-public:
-  /** get higher-order type match predicate
-   * This predicate is used to force certain functions f of type tn to appear as first-class representatives in the
-   * quantifier-free UF solver. For a typical use case, we call getHoTypeMatchPredicate which returns a fresh 
-   * predicate P of type (tn -> Bool). Then, we add P( f ) as a lemma.  
-   * TODO: we may eliminate this depending on how github issue #1115 is resolved.
-   */
-  Node getHoTypeMatchPredicate( TypeNode tn );
 };/* class TermUtil */
 
 }/* CVC4::theory::quantifiers namespace */
index 4d5a879ad75625b371ba6426b9eedd8eb9a9a353..88b2ba8d2573d18823fdd332b3ecfe5812aaa804 100644 (file)
@@ -316,7 +316,8 @@ unsigned HoExtension::checkAppCompletion()
             // add to pending list
             apply_uf[rop].push_back(n);
           }
-          // arguments are also relevant operators  FIXME (github issue #1115)
+          // Arguments are also relevant operators.
+          // It might be possible include fewer terms here, see #1115.
           for (unsigned k = 0; k < n.getNumChildren(); k++)
           {
             if (n[k].getType().isFunction())