Eliminate select over store in quantifier bodies (#2433)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Wed, 5 Sep 2018 22:03:17 +0000 (17:03 -0500)
committerGitHub <noreply@github.com>
Wed, 5 Sep 2018 22:03:17 +0000 (17:03 -0500)
src/theory/quantifiers/quantifiers_rewriter.cpp

index cff14e0c36609dad2ebb24081aa0e0dc843d89bf..1f6660f2f5f10268ff7d9a05b44041bc84a5b3a9 100644 (file)
@@ -517,6 +517,7 @@ Node QuantifiersRewriter::computeProcessTerms( Node body, std::vector< Node >& n
 Node QuantifiersRewriter::computeProcessTerms2( Node body, bool hasPol, bool pol, std::map< Node, bool >& currCond, int nCurrCond,
                                                 std::map< Node, Node >& cache, std::map< Node, Node >& icache,
                                                 std::vector< Node >& new_vars, std::vector< Node >& new_conds, bool elimExtArith ) {
+  NodeManager* nm = NodeManager::currentNM();
   Trace("quantifiers-rewrite-term-debug2") << "computeProcessTerms " << body << " " << hasPol << " " << pol << std::endl;
   Node ret;
   std::map< Node, Node >::iterator iti = cache.find( body );
@@ -666,18 +667,6 @@ Node QuantifiersRewriter::computeProcessTerms2( Node body, bool hasPol, bool pol
           }
         }
       }
-    /* ITE lifting
-    if( ret.getKind()==ITE ){
-      TypeNode ite_t = ret[1].getType();
-      if( !ite_t.isBoolean() ){
-        ite_t = TypeNode::leastCommonTypeNode( ite_t, ret[2].getType() );
-        Node ite_v = NodeManager::currentNM()->mkBoundVar(ite_t);
-        new_vars.push_back( ite_v );
-        Node cond = NodeManager::currentNM()->mkNode(kind::ITE, ret[0], ite_v.eqNode( ret[1] ), ite_v.eqNode( ret[2] ) );
-        new_conds.push_back( cond.negate() );
-        ret = ite_v;
-      }
-      */
     }else if( elimExtArith ){
       if( ret.getKind()==INTS_DIVISION_TOTAL || ret.getKind()==INTS_MODULUS_TOTAL ){
         Node num = ret[0];
@@ -722,6 +711,25 @@ Node QuantifiersRewriter::computeProcessTerms2( Node body, bool hasPol, bool pol
         }
       }
     }
+    else if (ret.getKind() == SELECT && ret[0].getKind() == STORE)
+    {
+      Node st = ret[0];
+      Node index = ret[1];
+      std::vector<Node> iconds;
+      std::vector<Node> elements;
+      while (st.getKind() == STORE)
+      {
+        iconds.push_back(index.eqNode(st[1]));
+        elements.push_back(st[2]);
+        st = st[0];
+      }
+      ret = nm->mkNode(SELECT, st, index);
+      // conditions
+      for (int i = (iconds.size() - 1); i >= 0; i--)
+      {
+        ret = nm->mkNode(ITE, iconds[i], elements[i], ret);
+      }
+    }
     icache[prev] = ret;
     return ret;
   }