(proof-new) Update preprocessing pass context for proofs (#5298)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Mon, 19 Oct 2020 16:06:16 +0000 (11:06 -0500)
committerGitHub <noreply@github.com>
Mon, 19 Oct 2020 16:06:16 +0000 (11:06 -0500)
This sets up the preprocessing pass context in preparation for proof production.

This PR makes the top level substitutions map into a TrustSubstitutionMap, the data structure that applies substitutions in a way that tracks proofs.

This PR also makes the "apply subst" preprocessing pass proof producing.

src/preprocessing/assertion_pipeline.cpp
src/preprocessing/passes/apply_substs.cpp
src/preprocessing/passes/miplib_trick.cpp
src/preprocessing/passes/non_clausal_simp.cpp
src/preprocessing/preprocessing_pass_context.cpp
src/preprocessing/preprocessing_pass_context.h
src/smt/preprocessor.cpp
src/smt/preprocessor.h
src/smt/process_assertions.cpp
src/smt/smt_engine.cpp

index cd92e5f3de863f1a046aa3fc361c7ed89babf832..4529ad5e1ab3458ccb80a8d73072dcd5bb4bb49d 100644 (file)
@@ -104,7 +104,12 @@ void AssertionPipeline::replace(size_t i, Node n, ProofGenerator* pgen)
 }
 
 void AssertionPipeline::replaceTrusted(size_t i, theory::TrustNode trn)
-{
+{  
+  if (trn.isNull())
+  {
+    // null trust node denotes no change, nothing to do
+    return;
+  }
   Assert(trn.getKind() == theory::TrustNodeKind::REWRITE);
   replace(i, trn.getNode(), trn.getGenerator());
 }
index 0ce3f20b2c0ad086a04f9e968e9158c51a22d658..06821ab566219e2fea5168c82afb7ca1a12bae73 100644 (file)
@@ -41,7 +41,7 @@ PreprocessingPassResult ApplySubsts::applyInternal(
     // TODO(#1255): Substitutions in incremental mode should be managed with a
     // proper data structure.
 
-    theory::SubstitutionMap& substMap =
+    theory::TrustSubstitutionMap& tlsm =
         d_preprocContext->getTopLevelSubstitutions();
     unsigned size = assertionsToPreprocess->size();
     for (unsigned i = 0; i < size; ++i)
@@ -54,9 +54,8 @@ PreprocessingPassResult ApplySubsts::applyInternal(
                         << std::endl;
       d_preprocContext->spendResource(
           ResourceManager::Resource::PreprocessStep);
-      assertionsToPreprocess->replace(i,
-                                      theory::Rewriter::rewrite(substMap.apply(
-                                          (*assertionsToPreprocess)[i])));
+      assertionsToPreprocess->replaceTrusted(
+          i, tlsm.apply((*assertionsToPreprocess)[i]));
       Trace("apply-substs") << "  got " << (*assertionsToPreprocess)[i]
                         << std::endl;
     }
index 3d7fd120ad50ec516bdbbc95eec5189f503af206..f55665bc56cbf95a45a2fd25de97ff7dc8f5b2eb 100644 (file)
@@ -189,8 +189,9 @@ PreprocessingPassResult MipLibTrick::applyInternal(
       propagator->getBackEdges();
   unordered_set<unsigned long> removeAssertions;
 
-  SubstitutionMap& top_level_substs =
+  theory::TrustSubstitutionMap& tlsm =
       d_preprocContext->getTopLevelSubstitutions();
+  SubstitutionMap& top_level_substs = tlsm.get();
 
   NodeManager* nm = NodeManager::currentNM();
   Node zero = nm->mkConst(Rational(0)), one = nm->mkConst(Rational(1));
index 823e93f52b59caf4793323a30dd9d7fea0a3e952..a3650c9881cf2b5de9a59a964e6f288d3390c8b5 100644 (file)
@@ -114,8 +114,8 @@ PreprocessingPassResult NonClausalSimp::applyInternal(
       << "Iterate through " << propagator->getLearnedLiterals().size()
       << " learned literals." << std::endl;
   // No conflict, go through the literals and solve them
-  SubstitutionMap& top_level_substs =
-      d_preprocContext->getTopLevelSubstitutions();
+  TrustSubstitutionMap& ttls = d_preprocContext->getTopLevelSubstitutions();
+  CVC4_UNUSED SubstitutionMap& top_level_substs = ttls.get();
   SubstitutionMap constantPropagations(d_preprocContext->getUserContext());
   TrustSubstitutionMap tnewSubstituions(d_preprocContext->getUserContext(),
                                         nullptr);
index 65e26cabbe83becfa1e74e7a4fbe66cb49d227d1..5893635cfb445d71772fe59726bc249b33f2f153 100644 (file)
@@ -14,7 +14,7 @@
  ** The preprocessing pass context for passes.
  **/
 
-#include "preprocessing_pass_context.h"
+#include "preprocessing/preprocessing_pass_context.h"
 
 #include "expr/node_algorithm.h"
 
@@ -24,12 +24,14 @@ namespace preprocessing {
 PreprocessingPassContext::PreprocessingPassContext(
     SmtEngine* smt,
     RemoveTermFormulas* iteRemover,
-    theory::booleans::CircuitPropagator* circuitPropagator)
+    theory::booleans::CircuitPropagator* circuitPropagator,
+    ProofNodeManager* pnm)
     : d_smt(smt),
       d_resourceManager(smt->getResourceManager()),
       d_iteRemover(iteRemover),
-      d_topLevelSubstitutions(smt->getUserContext()),
+      d_topLevelSubstitutions(smt->getUserContext(), pnm),
       d_circuitPropagator(circuitPropagator),
+      d_pnm(pnm),
       d_symsInAssertions(smt->getUserContext())
 {
 }
@@ -40,6 +42,12 @@ void PreprocessingPassContext::widenLogic(theory::TheoryId id)
   req.widenLogic(id);
 }
 
+theory::TrustSubstitutionMap&
+PreprocessingPassContext::getTopLevelSubstitutions()
+{
+  return d_topLevelSubstitutions;
+}
+
 void PreprocessingPassContext::enableIntegers()
 {
   LogicRequest req(*d_smt);
@@ -61,5 +69,10 @@ void PreprocessingPassContext::recordSymbolsInAssertions(
   }
 }
 
+ProofNodeManager* PreprocessingPassContext::getProofNodeManager()
+{
+  return d_pnm;
+}
+
 }  // namespace preprocessing
 }  // namespace CVC4
index f93c96fded7668b667f56524358d51f214dbe463..d0747b5d9e7e9feb2f0eb075eda6e55b47a8e8cd 100644 (file)
@@ -29,6 +29,7 @@
 #include "smt/term_formula_removal.h"
 #include "theory/booleans/circuit_propagator.h"
 #include "theory/theory_engine.h"
+#include "theory/trust_substitutions.h"
 #include "util/resource_manager.h"
 
 namespace CVC4 {
@@ -40,7 +41,8 @@ class PreprocessingPassContext
   PreprocessingPassContext(
       SmtEngine* smt,
       RemoveTermFormulas* iteRemover,
-      theory::booleans::CircuitPropagator* circuitPropagator);
+      theory::booleans::CircuitPropagator* circuitPropagator,
+      ProofNodeManager* pnm);
 
   SmtEngine* getSmt() { return d_smt; }
   TheoryEngine* getTheoryEngine() { return d_smt->getTheoryEngine(); }
@@ -70,10 +72,7 @@ class PreprocessingPassContext
   void widenLogic(theory::TheoryId id);
 
   /** Gets a reference to the top-level substitution map */
-  theory::SubstitutionMap& getTopLevelSubstitutions()
-  {
-    return d_topLevelSubstitutions;
-  }
+  theory::TrustSubstitutionMap& getTopLevelSubstitutions();
 
   /* Enable Integers. */
   void enableIntegers();
@@ -85,6 +84,9 @@ class PreprocessingPassContext
    */
   void recordSymbolsInAssertions(const std::vector<Node>& assertions);
 
+  /** The the proof node manager associated with this context, if it exists */
+  ProofNodeManager* getProofNodeManager();
+
  private:
   /** Pointer to the SmtEngine that this context was created in. */
   SmtEngine* d_smt;
@@ -96,10 +98,12 @@ class PreprocessingPassContext
   RemoveTermFormulas* d_iteRemover;
 
   /* The top level substitutions */
-  theory::SubstitutionMap d_topLevelSubstitutions;
+  theory::TrustSubstitutionMap d_topLevelSubstitutions;
 
   /** Instance of the circuit propagator */
   theory::booleans::CircuitPropagator* d_circuitPropagator;
+  /** Pointer to the proof node manager, if it exists */
+  ProofNodeManager* d_pnm;
 
   /**
    * The (user-context-dependent) set of symbols that occur in at least one
index 02323561dbf5bbf06a79700e473f602b8e40ef76..912c0ea28525563136e297a9807501ec0e71f3de 100644 (file)
@@ -30,12 +30,14 @@ namespace smt {
 Preprocessor::Preprocessor(SmtEngine& smt,
                            context::UserContext* u,
                            AbstractValues& abs)
-    : d_smt(smt),
+    : d_context(u),
+      d_smt(smt),
       d_absValues(abs),
       d_propagator(true, true),
       d_assertionsProcessed(u, false),
       d_processor(smt, *smt.getResourceManager()),
-      d_rtf(u)
+      d_rtf(u),
+      d_pnm(nullptr)
 {
 }
 
@@ -51,7 +53,7 @@ Preprocessor::~Preprocessor()
 void Preprocessor::finishInit()
 {
   d_ppContext.reset(new preprocessing::PreprocessingPassContext(
-      &d_smt, &d_rtf, &d_propagator));
+      &d_smt, &d_rtf, &d_propagator, d_pnm));
 
   // initialize the preprocessing passes
   d_processor.finishInit(d_ppContext.get());
@@ -62,7 +64,8 @@ bool Preprocessor::process(Assertions& as)
   preprocessing::AssertionPipeline& ap = as.getAssertionPipeline();
 
   // should not be called if empty
-  Assert(ap.size() != 0) << "Can only preprocess a non-empty list of assertions";
+  Assert(ap.size() != 0)
+      << "Can only preprocess a non-empty list of assertions";
 
   if (d_assertionsProcessed && options::incrementalSolving())
   {
@@ -140,7 +143,8 @@ Node Preprocessor::simplify(const Node& node, bool removeItes)
   }
   std::unordered_map<Node, Node, NodeHashFunction> cache;
   Node n = d_processor.expandDefinitions(nas, cache);
-  Node ns = applySubstitutions(n);
+  TrustNode ts = d_ppContext->getTopLevelSubstitutions().apply(n);
+  Node ns = ts.isNull() ? n : ts.getNode();
   if (removeItes)
   {
     // also remove ites if asked
@@ -149,9 +153,11 @@ Node Preprocessor::simplify(const Node& node, bool removeItes)
   return ns;
 }
 
-Node Preprocessor::applySubstitutions(TNode node)
+void Preprocessor::setProofGenerator(PreprocessProofGenerator* pppg)
 {
-  return Rewriter::rewrite(d_ppContext->getTopLevelSubstitutions().apply(node));
+  Assert(pppg != nullptr);
+  d_pnm = pppg->getManager();
+  d_rtf.setProofNodeManager(d_pnm);
 }
 
 }  // namespace smt
index 81757de37f237e0715f24893b1604c80d8797a97..b07e7ec972a5b5ac7f8950f6b849baa864249679 100644 (file)
@@ -100,12 +100,14 @@ class Preprocessor
    */
   RemoveTermFormulas& getTermFormulaRemover();
 
- private:
   /**
-   * Apply substitutions that have been inferred by preprocessing, return the
-   * substituted form of node.
+   * Set proof node manager. Enables proofs in this preprocessor.
    */
-  Node applySubstitutions(TNode node);
+  void setProofGenerator(PreprocessProofGenerator* pppg);
+
+ private:
+  /** A copy of the current context */
+  context::Context* d_context;
   /** Reference to the parent SmtEngine */
   SmtEngine& d_smt;
   /** Reference to the abstract values utility */
@@ -130,6 +132,8 @@ class Preprocessor
    * in term contexts.
    */
   RemoveTermFormulas d_rtf;
+  /** Proof node manager */
+  ProofNodeManager* d_pnm;
 };
 
 }  // namespace smt
index 719165048c1f10b02cff3abc1007409fc7696a7a..f8af72c3a075c05cde4798161ff229e91983a5f4 100644 (file)
@@ -105,9 +105,6 @@ bool ProcessAssertions::apply(Assertions& as)
     return true;
   }
 
-  SubstitutionMap& top_level_substs =
-      d_preprocessingPassContext->getTopLevelSubstitutions();
-
   if (options::bvGaussElim())
   {
     d_passes["bv-gauss"]->apply(&assertions);
@@ -330,6 +327,8 @@ bool ProcessAssertions::apply(Assertions& as)
       // First, find all skolems that appear in the substitution map - their
       // associated iteExpr will need to be moved to the main assertion set
       set<TNode> skolemSet;
+      SubstitutionMap& top_level_substs =
+          d_preprocessingPassContext->getTopLevelSubstitutions().get();
       SubstitutionMap::iterator pos = top_level_substs.begin();
       for (; pos != top_level_substs.end(); ++pos)
       {
index 2a771ce768d58ae23362e45c21445c560c673cd4..2f9918486b7d2c2020a2b5f42beb7a5d3139940d 100644 (file)
@@ -259,14 +259,17 @@ void SmtEngine::finishInit()
   if (options::proofNew())
   {
     d_pfManager.reset(new PfManager(getUserContext(), this));
+    PreprocessProofGenerator* pppg = d_pfManager->getPreprocessProofGenerator();
     // use this proof node manager
     pnm = d_pfManager->getProofNodeManager();
     // enable proof support in the rewriter
     d_rewriter->setProofNodeManager(pnm);
     // enable it in the assertions pipeline
-    d_asserts->setProofGenerator(d_pfManager->getPreprocessProofGenerator());
+    d_asserts->setProofGenerator(pppg);
     // enable it in the SmtSolver
     d_smtSolver->setProofNodeManager(pnm);
+    // enabled proofs in the preprocessor
+    d_pp->setProofGenerator(pppg);
   }
 
   Trace("smt-debug") << "SmtEngine::finishInit" << std::endl;