Refactor sep-pre-skolem-emp preprocessing pass
authoryoni206 <yoni206@users.noreply.github.com>
Tue, 17 Jul 2018 21:20:46 +0000 (14:20 -0700)
committerGitHub <noreply@github.com>
Tue, 17 Jul 2018 21:20:46 +0000 (14:20 -0700)
src/Makefile.am
src/preprocessing/passes/sep_skolem_emp.cpp [new file with mode: 0644]
src/preprocessing/passes/sep_skolem_emp.h [new file with mode: 0644]
src/smt/smt_engine.cpp
src/theory/sep/theory_sep_rewriter.cpp
src/theory/sep/theory_sep_rewriter.h
test/regress/Makefile.tests
test/regress/regress0/sep/skolem_emp.smt2 [new file with mode: 0644]

index d0621bf5bda8e766c12981395b92a3d0605e4f78..afc967df95b0aa3fcdb500e652e44b6eac82f48a 100644 (file)
@@ -86,6 +86,8 @@ libcvc4_la_SOURCES = \
        preprocessing/passes/real_to_int.h \
        preprocessing/passes/rewrite.cpp \
        preprocessing/passes/rewrite.h \
+       preprocessing/passes/sep_skolem_emp.cpp \
+       preprocessing/passes/sep_skolem_emp.h \
        preprocessing/passes/static_learning.cpp \
        preprocessing/passes/static_learning.h \
        preprocessing/passes/symmetry_breaker.cpp \
diff --git a/src/preprocessing/passes/sep_skolem_emp.cpp b/src/preprocessing/passes/sep_skolem_emp.cpp
new file mode 100644 (file)
index 0000000..d79ec8b
--- /dev/null
@@ -0,0 +1,124 @@
+/**********************/
+/*! \file sep_skolem_emp.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ **   Andrew Reynolds, Mathias Preiner, Yoni Zohar
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2018 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved.  See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief The sep-pre-skolem-emp preprocessing pass
+ **
+ **/
+
+#include "preprocessing/passes/sep_skolem_emp.h"
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "expr/node.h"
+#include "theory/quantifiers/quant_util.h"
+#include "theory/rewriter.h"
+#include "theory/theory.h"
+
+namespace CVC4 {
+namespace preprocessing {
+namespace passes {
+
+using namespace CVC4::theory;
+
+namespace {
+
+Node preSkolemEmp(Node n,
+                         bool pol,
+                         std::map<bool, std::map<Node, Node>>& visited)
+{
+  std::map<Node, Node>::iterator it = visited[pol].find(n);
+  if (it == visited[pol].end())
+  {
+    Trace("sep-preprocess") << "Pre-skolem emp " << n << " with pol " << pol
+                            << std::endl;
+    Node ret = n;
+    if (n.getKind() == kind::SEP_EMP)
+    {
+      if (!pol)
+      {
+        TypeNode tnx = n[0].getType();
+        TypeNode tny = n[1].getType();
+        Node x = NodeManager::currentNM()->mkSkolem(
+            "ex", tnx, "skolem location for negated emp");
+        Node y = NodeManager::currentNM()->mkSkolem(
+            "ey", tny, "skolem data for negated emp");
+        return NodeManager::currentNM()
+            ->mkNode(kind::SEP_STAR,
+                     NodeManager::currentNM()->mkNode(kind::SEP_PTO, x, y),
+                     NodeManager::currentNM()->mkConst(true))
+            .negate();
+      }
+    }
+    else if (n.getKind() != kind::FORALL && n.getNumChildren() > 0)
+    {
+      std::vector<Node> children;
+      bool childChanged = false;
+      if (n.getMetaKind() == kind::metakind::PARAMETERIZED)
+      {
+        children.push_back(n.getOperator());
+      }
+      for (unsigned i = 0; i < n.getNumChildren(); i++)
+      {
+        bool newPol, newHasPol;
+        QuantPhaseReq::getPolarity(n, i, true, pol, newHasPol, newPol);
+        Node nc = n[i];
+        if (newHasPol)
+        {
+          nc = preSkolemEmp(n[i], newPol, visited);
+          childChanged = childChanged || nc != n[i];
+        }
+        children.push_back(nc);
+      }
+      if (childChanged)
+      {
+        return NodeManager::currentNM()->mkNode(n.getKind(), children);
+      }
+    }
+    visited[pol][n] = ret;
+    return n;
+  }
+  else
+  {
+    return it->second;
+  }
+}
+
+}  // namespace
+
+SepSkolemEmp::SepSkolemEmp(PreprocessingPassContext* preprocContext)
+    : PreprocessingPass(preprocContext, "sep-skolem-emp"){};
+
+PreprocessingPassResult SepSkolemEmp::applyInternal(
+    AssertionPipeline* assertionsToPreprocess)
+{
+  std::map<bool, std::map<Node, Node>> visited;
+  for (unsigned i = 0; i < assertionsToPreprocess->size(); ++i)
+  {
+    Node prev = (*assertionsToPreprocess)[i];
+    bool pol = true;
+    Node next = preSkolemEmp(prev, pol, visited);
+    if (next != prev)
+    {
+      assertionsToPreprocess->replace(i, Rewriter::rewrite(next));
+      Trace("sep-preprocess") << "*** Preprocess sep " << prev << endl;
+      Trace("sep-preprocess") << "   ...got " << (*assertionsToPreprocess)[i]
+                              << endl;
+    }
+    visited.clear();
+  }
+  return PreprocessingPassResult::NO_CONFLICT;
+}
+
+}  // namespace passes
+}  // namespace preprocessing
+}  // namespace CVC4
diff --git a/src/preprocessing/passes/sep_skolem_emp.h b/src/preprocessing/passes/sep_skolem_emp.h
new file mode 100644 (file)
index 0000000..4a3dba6
--- /dev/null
@@ -0,0 +1,42 @@
+/*********************                                                        */
+/*! \file sep_skolem_emp.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Mathias Preiner, Yoni Zohar
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2018 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved.  See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief The sep-pre-skolem-emp eprocessing pass
+ **
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__PREPROCESSING__PASSES__SEP_SKOLEM_EMP_H
+#define __CVC4__PREPROCESSING__PASSES__SEP_SKOLEM_EMP_H
+
+#include "preprocessing/preprocessing_pass.h"
+#include "preprocessing/preprocessing_pass_context.h"
+
+namespace CVC4 {
+namespace preprocessing {
+namespace passes {
+
+class SepSkolemEmp : public PreprocessingPass
+{
+ public:
+  SepSkolemEmp(PreprocessingPassContext* preprocContext);
+
+ protected:
+  PreprocessingPassResult applyInternal(
+      AssertionPipeline* assertionsToPreprocess) override;
+};
+
+}  // namespace passes
+}  // namespace preprocessing
+}  // namespace CVC4
+
+#endif /* __CVC4__PREPROCESSING__PASSES__SEP_SKOLEM_EMP_H */
index 69c0dab9c99d86d52bb6b872f513bf01b4deec64..958fec17584e98a2a4136cc5a687cb42fc37ec61 100644 (file)
@@ -79,6 +79,7 @@
 #include "preprocessing/passes/pseudo_boolean_processor.h"
 #include "preprocessing/passes/real_to_int.h"
 #include "preprocessing/passes/rewrite.h"
+#include "preprocessing/passes/sep_skolem_emp.h"
 #include "preprocessing/passes/static_learning.h"
 #include "preprocessing/passes/symmetry_breaker.h"
 #include "preprocessing/passes/symmetry_detect.h"
@@ -2725,7 +2726,9 @@ void SmtEnginePrivate::finishInit()
       new SymBreakerPass(d_preprocessingPassContext.get()));
   std::unique_ptr<SynthRewRulesPass> srrProc(
       new SynthRewRulesPass(d_preprocessingPassContext.get()));
-  d_preprocessingPassRegistry.registerPass("apply-substs",
+ std::unique_ptr<SepSkolemEmp> sepSkolemEmp(
+      new SepSkolemEmp(d_preprocessingPassContext.get()));
+   d_preprocessingPassRegistry.registerPass("apply-substs",
                                            std::move(applySubsts));
   d_preprocessingPassRegistry.registerPass("bool-to-bv", std::move(boolToBv));
   d_preprocessingPassRegistry.registerPass("bv-abstraction",
@@ -2741,6 +2744,8 @@ void SmtEnginePrivate::finishInit()
                                            std::move(pbProc));
   d_preprocessingPassRegistry.registerPass("real-to-int", std::move(realToInt));
   d_preprocessingPassRegistry.registerPass("rewrite", std::move(rewrite));
+  d_preprocessingPassRegistry.registerPass("sep-skolem-emp",
+                                           std::move(sepSkolemEmp));
   d_preprocessingPassRegistry.registerPass("static-learning", 
                                            std::move(staticLearning));
   d_preprocessingPassRegistry.registerPass("sym-break", std::move(sbProc));
@@ -4224,15 +4229,7 @@ void SmtEnginePrivate::processAssertions() {
     Trace("smt") << "POST boolToBv" << endl;
   }
   if(options::sepPreSkolemEmp()) {
-    for (unsigned i = 0; i < d_assertions.size(); ++ i) {
-      Node prev = d_assertions[i];
-      Node next = sep::TheorySepRewriter::preprocess( prev );
-      if( next!=prev ){
-        d_assertions.replace( i, Rewriter::rewrite( next ) );
-        Trace("sep-preprocess") << "*** Preprocess sep " << prev << endl;
-        Trace("sep-preprocess") << "   ...got " << d_assertions[i] << endl;
-      }
-    }
+    d_preprocessingPassRegistry.getPass("sep-skolem-emp")->apply(&d_assertions);
   }
 
   if( d_smt.d_logic.isQuantified() ){
index 4d0885dc229cedcffa912b685f6f0b2f48a53947..614d4f7c47b14a03d98d40d4e4f7830ba95510e2 100644 (file)
@@ -161,58 +161,6 @@ RewriteResponse TheorySepRewriter::postRewrite(TNode node) {
   return RewriteResponse(node==retNode ? REWRITE_DONE : REWRITE_AGAIN_FULL, retNode);
 }
 
-Node TheorySepRewriter::preSkolemEmp( Node n, bool pol, std::map< bool, std::map< Node, Node > >& visited ) {
-  std::map< Node, Node >::iterator it = visited[pol].find( n );
-  if( it==visited[pol].end() ){
-    Trace("sep-preprocess") << "Pre-skolem emp " << n << " with pol " << pol << std::endl;
-    Node ret = n;
-    if( n.getKind()==kind::SEP_EMP ){
-      if( !pol ){
-        TypeNode tnx = n[0].getType();
-        TypeNode tny = n[1].getType();
-        Node x = NodeManager::currentNM()->mkSkolem( "ex", tnx, "skolem location for negated emp" );
-        Node y = NodeManager::currentNM()->mkSkolem( "ey", tny, "skolem data for negated emp" );
-        return NodeManager::currentNM()->mkNode( kind::SEP_STAR, 
-                 NodeManager::currentNM()->mkNode( kind::SEP_PTO, x, y ),
-                 NodeManager::currentNM()->mkConst( true ) ).negate();
-      }
-    }else if( n.getKind()!=kind::FORALL && n.getNumChildren()>0 ){
-      std::vector< Node > children;
-      bool childChanged = false;
-      if( n.getMetaKind() == kind::metakind::PARAMETERIZED ){
-        children.push_back( n.getOperator() );
-      }
-      for( unsigned i=0; i<n.getNumChildren(); i++ ){
-        bool newPol, newHasPol;
-        QuantPhaseReq::getPolarity( n, i, true, pol, newHasPol, newPol );
-        Node nc = n[i];
-        if( newHasPol ){
-          nc = preSkolemEmp( n[i], newPol, visited );
-          childChanged = childChanged || nc!=n[i];
-        }
-        children.push_back( nc );
-      }
-      if( childChanged ){
-        return NodeManager::currentNM()->mkNode( n.getKind(), children );
-      }
-    }
-    visited[pol][n] = ret;
-    return n;
-  }else{
-    return it->second;
-  }
-}
-
-Node TheorySepRewriter::preprocess( Node n ) {
-  if( options::sepPreSkolemEmp() ){
-    bool pol = true;
-    std::map< bool, std::map< Node, Node > > visited;
-    n = preSkolemEmp( n, pol, visited );
-  }
-  return n;
-}
-
-
 }/* CVC4::theory::sep namespace */
 }/* CVC4::theory namespace */
 }/* CVC4 namespace */
index e867bc0e9aa8dada78bca1fe9cc7225e37fb705a..8ed8c3de27c4616afb0c14b878d175bc574389a3 100644 (file)
@@ -43,10 +43,6 @@ public:
 
   static inline void init() {}
   static inline void shutdown() {}
-private:
-  static Node preSkolemEmp( Node n, bool pol, std::map< bool, std::map< Node, Node > >& visited );
-public:
-  static Node preprocess( Node n );
 };/* class TheorySepRewriter */
 
 }/* CVC4::theory::sep namespace */
index 377e9189747742e2293a15cac30a29d3b86a22c7..b005a3a67c2b68294bd0e70c19bf6c9640e63081 100644 (file)
@@ -720,6 +720,7 @@ REG0_TESTS = \
        regress0/sep/sep-01.smt2 \
        regress0/sep/sep-plus1.smt2 \
        regress0/sep/sep-simp-unsat-emp.smt2 \
+       regress0/sep/skolem_emp.smt2 \
        regress0/sep/trees-1.smt2 \
        regress0/sep/wand-crash.smt2 \
        regress0/sets/abt-min.smt2 \
diff --git a/test/regress/regress0/sep/skolem_emp.smt2 b/test/regress/regress0/sep/skolem_emp.smt2
new file mode 100644 (file)
index 0000000..d17f98a
--- /dev/null
@@ -0,0 +1,5 @@
+; COMMAND-LINE: --no-check-models --sep-pre-skolem-emp
+; EXPECT: sat
+(set-logic QF_ALL_SUPPORTED)
+(assert (not (emp 0 0)))
+(check-sat)