Move ownership of term formula removal to theory preprocessor (#5670)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Wed, 16 Dec 2020 15:03:45 +0000 (09:03 -0600)
committerGitHub <noreply@github.com>
Wed, 16 Dec 2020 15:03:45 +0000 (09:03 -0600)
This is work towards refactoring ITE removal (more generally, term formula removal) so that it happens at a configurable time, preferably post-CNF conversion.

This moves the TermFormulaRemover to the TheoryPreprocessor and changes several interfaces as a consequence of this move.

The next step will move the TheoryPreprocessor inside prop::TheoryProxy.

There are no behavior changes to solving in this PR. One aspect of CheckModels is simplified.

13 files changed:
src/preprocessing/passes/ite_removal.cpp
src/preprocessing/preprocessing_pass_context.cpp
src/preprocessing/preprocessing_pass_context.h
src/smt/check_models.cpp
src/smt/preprocessor.cpp
src/smt/preprocessor.h
src/smt/smt_solver.cpp
src/smt/term_formula_removal.cpp
src/smt/term_formula_removal.h
src/theory/theory_engine.cpp
src/theory/theory_engine.h
src/theory/theory_preprocessor.cpp
src/theory/theory_preprocessor.h

index a75b6f5ad8de9f909f4084b2e5f0e248fcdd74ec..3531497e87d13326873c52517a22c9885c779917 100644 (file)
@@ -18,6 +18,7 @@
 #include "preprocessing/passes/ite_removal.h"
 
 #include "theory/rewriter.h"
+#include "theory/theory_preprocessor.h"
 
 namespace CVC4 {
 namespace preprocessing {
@@ -25,6 +26,7 @@ namespace passes {
 
 using namespace CVC4::theory;
 
+// TODO (project #42): note this preprocessing pass is deprecated
 IteRemoval::IteRemoval(PreprocessingPassContext* preprocContext)
     : PreprocessingPass(preprocContext, "ite-removal")
 {
@@ -36,19 +38,36 @@ PreprocessingPassResult IteRemoval::applyInternal(AssertionPipeline* assertions)
 
   IteSkolemMap& imap = assertions->getIteSkolemMap();
   // Remove all of the ITE occurrences and normalize
+  theory::TheoryPreprocessor* tpp =
+      d_preprocContext->getTheoryEngine()->getTheoryPreprocess();
   for (unsigned i = 0, size = assertions->size(); i < size; ++i)
   {
+    Node assertion = (*assertions)[i];
     std::vector<theory::TrustNode> newAsserts;
     std::vector<Node> newSkolems;
-    TrustNode trn = d_preprocContext->getIteRemover()->run(
-        (*assertions)[i], newAsserts, newSkolems, true);
-    // process
-    assertions->replaceTrusted(i, trn);
+    // TODO (project #42): this will call the prop engine
+    TrustNode trn = tpp->preprocess(assertion, newAsserts, newSkolems, false);
+    if (!trn.isNull())
+    {
+      // process
+      assertions->replaceTrusted(i, trn);
+      // rewritten assertion has a dependence on the node (old pf architecture)
+      if (options::unsatCores())
+      {
+        ProofManager::currentPM()->addDependence(trn.getNode(), assertion);
+      }
+    }
     Assert(newSkolems.size() == newAsserts.size());
     for (unsigned j = 0, nnasserts = newAsserts.size(); j < nnasserts; j++)
     {
       imap[newSkolems[j]] = assertions->size();
       assertions->pushBackTrusted(newAsserts[j]);
+      // new assertions have a dependence on the node (old pf architecture)
+      if (options::unsatCores())
+      {
+        ProofManager::currentPM()->addDependence(newAsserts[j].getProven(),
+                                                 assertion);
+      }
     }
   }
   for (unsigned i = 0, size = assertions->size(); i < size; ++i)
index ff4a0e6ca1b14419bd9737b62892b20f5980ff8a..707d1314c4e73ed6538a250a4c1763628d72cc6e 100644 (file)
@@ -23,12 +23,10 @@ namespace preprocessing {
 
 PreprocessingPassContext::PreprocessingPassContext(
     SmtEngine* smt,
-    RemoveTermFormulas* iteRemover,
     theory::booleans::CircuitPropagator* circuitPropagator,
     ProofNodeManager* pnm)
     : d_smt(smt),
       d_resourceManager(smt->getResourceManager()),
-      d_iteRemover(iteRemover),
       d_topLevelSubstitutions(smt->getUserContext(), pnm),
       d_circuitPropagator(circuitPropagator),
       d_pnm(pnm),
index 824197bc5610a25f68d7f3219016da6dab71b2f9..c22a69255b7528f5e2fc3d2f41ae18611a503ae8 100644 (file)
@@ -40,7 +40,6 @@ class PreprocessingPassContext
  public:
   PreprocessingPassContext(
       SmtEngine* smt,
-      RemoveTermFormulas* iteRemover,
       theory::booleans::CircuitPropagator* circuitPropagator,
       ProofNodeManager* pnm);
 
@@ -49,7 +48,6 @@ class PreprocessingPassContext
   prop::PropEngine* getPropEngine() { return d_smt->getPropEngine(); }
   context::Context* getUserContext() { return d_smt->getUserContext(); }
   context::Context* getDecisionContext() { return d_smt->getContext(); }
-  RemoveTermFormulas* getIteRemover() { return d_iteRemover; }
 
   theory::booleans::CircuitPropagator* getCircuitPropagator()
   {
@@ -95,9 +93,6 @@ class PreprocessingPassContext
   /** Pointer to the ResourceManager for this context. */
   ResourceManager* d_resourceManager;
 
-  /** Instance of the ITE remover */
-  RemoveTermFormulas* d_iteRemover;
-
   /* The top level substitutions */
   theory::TrustSubstitutionMap d_topLevelSubstitutions;
 
index a41c750eca027594e203180e4f6cf5e2a87dca3f..2338ebd6194c49377599b715f30d400734f8516d 100644 (file)
@@ -184,9 +184,8 @@ void CheckModels::checkModel(Model* m,
     n = m->getValue(n);
     Notice() << "SmtEngine::checkModel(): -- get value : " << n << std::endl;
 
-    // Simplify the result and replace the already-known ITEs (this is important
-    // for ground ITEs under quantifiers).
-    n = pp->simplify(n, true);
+    // Simplify the result
+    n = pp->simplify(n);
     Notice()
         << "SmtEngine::checkModel(): -- simplifies with ite replacement to  "
         << n << std::endl;
index c2b8f73f15589df6c210f94a45dc93233d66d620..ec7751a54504b6c033549f43af7d56bd5732dd1c 100644 (file)
@@ -38,7 +38,6 @@ Preprocessor::Preprocessor(SmtEngine& smt,
       d_assertionsProcessed(u, false),
       d_exDefs(smt, *smt.getResourceManager(), stats),
       d_processor(smt, d_exDefs, *smt.getResourceManager(), stats),
-      d_rtf(u),
       d_pnm(nullptr)
 {
 }
@@ -55,7 +54,7 @@ Preprocessor::~Preprocessor()
 void Preprocessor::finishInit()
 {
   d_ppContext.reset(new preprocessing::PreprocessingPassContext(
-      &d_smt, &d_rtf, &d_propagator, d_pnm));
+      &d_smt, &d_propagator, d_pnm));
 
   // initialize the preprocessing passes
   d_processor.finishInit(d_ppContext.get());
@@ -104,8 +103,6 @@ void Preprocessor::clearLearnedLiterals()
 
 void Preprocessor::cleanup() { d_processor.cleanup(); }
 
-RemoveTermFormulas& Preprocessor::getTermFormulaRemover() { return d_rtf; }
-
 Node Preprocessor::expandDefinitions(const Node& n, bool expandOnly)
 {
   std::unordered_map<Node, Node, NodeHashFunction> cache;
@@ -129,7 +126,7 @@ Node Preprocessor::expandDefinitions(
   return d_exDefs.expandDefinitions(n, cache, expandOnly);
 }
 
-Node Preprocessor::simplify(const Node& node, bool removeItes)
+Node Preprocessor::simplify(const Node& node)
 {
   Trace("smt") << "SMT simplify(" << node << ")" << endl;
   if (Dump.isOn("benchmark"))
@@ -147,11 +144,6 @@ Node Preprocessor::simplify(const Node& node, bool removeItes)
   Node n = d_exDefs.expandDefinitions(nas, cache);
   TrustNode ts = d_ppContext->getTopLevelSubstitutions().apply(n);
   Node ns = ts.isNull() ? n : ts.getNode();
-  if (removeItes)
-  {
-    // also remove ites if asked
-    ns = d_rtf.replace(ns);
-  }
   return ns;
 }
 
@@ -161,7 +153,6 @@ void Preprocessor::setProofGenerator(PreprocessProofGenerator* pppg)
   d_pnm = pppg->getManager();
   d_exDefs.setProofNodeManager(d_pnm);
   d_propagator.setProof(d_pnm, d_context, pppg);
-  d_rtf.setProofNodeManager(d_pnm);
 }
 
 }  // namespace smt
index 220a433fe6bab861ef23303a51a0b9a842c5d738..367490306fcf5b4e48c08b0befb6945bbc42bc97 100644 (file)
@@ -22,7 +22,6 @@
 #include "preprocessing/preprocessing_pass_context.h"
 #include "smt/expand_definitions.h"
 #include "smt/process_assertions.h"
-#include "smt/term_formula_removal.h"
 #include "theory/booleans/circuit_propagator.h"
 
 namespace CVC4 {
@@ -79,11 +78,9 @@ class Preprocessor
    * has been constructed.  It also involves theory normalization.
    *
    * @param n The node to simplify
-   * @param removeItes Whether to remove ITE (and other terms with formulas in
-   * term positions) from the result.
    * @return The simplified term.
    */
-  Node simplify(const Node& n, bool removeItes = false);
+  Node simplify(const Node& n);
   /**
    * Expand the definitions in a term or formula n.  No other
    * simplification or normalization is done.
@@ -99,10 +96,6 @@ class Preprocessor
       const Node& n,
       std::unordered_map<Node, Node, NodeHashFunction>& cache,
       bool expandOnly = false);
-  /**
-   * Get the underlying term formula remover utility.
-   */
-  RemoveTermFormulas& getTermFormulaRemover();
 
   /**
    * Set proof node manager. Enables proofs in this preprocessor.
@@ -133,11 +126,6 @@ class Preprocessor
    * passes.
    */
   ProcessAssertions d_processor;
-  /**
-   * The term formula remover, responsible for eliminating formulas that occur
-   * in term contexts.
-   */
-  RemoveTermFormulas d_rtf;
   /** Proof node manager */
   ProofNodeManager* d_pnm;
 };
index e53401f79e241210525bb41a10e4c5cd0350e5c1..3e8d0f147e4b4bf53a01491802a0699aaf3e07d5 100644 (file)
@@ -50,7 +50,6 @@ void SmtSolver::finishInit(const LogicInfo& logicInfo)
   d_theoryEngine.reset(new TheoryEngine(d_smt.getContext(),
                                         d_smt.getUserContext(),
                                         d_rm,
-                                        d_pp.getTermFormulaRemover(),
                                         logicInfo,
                                         d_smt.getOutputManager(),
                                         d_pnm));
index f3e0d0bd6d16cff26f2de6a19d888274aca39e27..60b850a31772d08a5b2b5cf29e16e55f47616790 100644 (file)
@@ -26,13 +26,23 @@ using namespace std;
 
 namespace CVC4 {
 
-RemoveTermFormulas::RemoveTermFormulas(context::UserContext* u)
-    : d_tfCache(u),
-      d_skolem_cache(u),
-      d_pnm(nullptr),
-      d_tpg(nullptr),
-      d_lp(nullptr)
+RemoveTermFormulas::RemoveTermFormulas(context::UserContext* u,
+                                       ProofNodeManager* pnm)
+    : d_tfCache(u), d_skolem_cache(u), d_pnm(pnm), d_tpg(nullptr), d_lp(nullptr)
 {
+  // enable proofs if necessary
+  if (d_pnm != nullptr)
+  {
+    d_tpg.reset(
+        new TConvProofGenerator(d_pnm,
+                                nullptr,
+                                TConvPolicy::FIXPOINT,
+                                TConvCachePolicy::NEVER,
+                                "RemoveTermFormulas::TConvProofGenerator",
+                                &d_rtfc));
+    d_lp.reset(new LazyCDProof(
+        d_pnm, nullptr, nullptr, "RemoveTermFormulas::LazyCDProof"));
+  }
 }
 
 RemoveTermFormulas::~RemoveTermFormulas() {}
@@ -40,29 +50,9 @@ RemoveTermFormulas::~RemoveTermFormulas() {}
 theory::TrustNode RemoveTermFormulas::run(
     Node assertion,
     std::vector<theory::TrustNode>& newAsserts,
-    std::vector<Node>& newSkolems,
-    bool reportDeps)
+    std::vector<Node>& newSkolems)
 {
   Node itesRemoved = runInternal(assertion, newAsserts, newSkolems);
-  // In some calling contexts, not necessary to report dependence information.
-  if (reportDeps && options::unsatCores())
-  {
-    // new assertions have a dependence on the node
-    if (options::unsatCores())
-    {
-      ProofManager::currentPM()->addDependence(itesRemoved, assertion);
-    }
-    unsigned n = 0;
-    while (n < newAsserts.size())
-    {
-      if (options::unsatCores())
-      {
-        ProofManager::currentPM()->addDependence(newAsserts[n].getProven(),
-                                                 assertion);
-      }
-      ++n;
-    }
-  }
   // The rewriting of assertion can be justified by the term conversion proof
   // generator d_tpg.
   return theory::TrustNode::mkTrustRewrite(assertion, itesRemoved, d_tpg.get());
@@ -536,23 +526,6 @@ Node RemoveTermFormulas::getAxiomFor(Node n)
   return Node::null();
 }
 
-void RemoveTermFormulas::setProofNodeManager(ProofNodeManager* pnm)
-{
-  if (d_tpg == nullptr)
-  {
-    d_pnm = pnm;
-    d_tpg.reset(
-        new TConvProofGenerator(d_pnm,
-                                nullptr,
-                                TConvPolicy::FIXPOINT,
-                                TConvCachePolicy::NEVER,
-                                "RemoveTermFormulas::TConvProofGenerator",
-                                &d_rtfc));
-    d_lp.reset(new LazyCDProof(
-        d_pnm, nullptr, nullptr, "RemoveTermFormulas::LazyCDProof"));
-  }
-}
-
 ProofGenerator* RemoveTermFormulas::getTConvProofGenerator()
 {
   return d_tpg.get();
index 25dcd02955c263f9a4f0b4435c0544a91adba75c..fc10e19c91cd236dce0471d8d0d8701ea07f607a 100644 (file)
@@ -38,7 +38,7 @@ typedef std::unordered_map<Node, unsigned, NodeHashFunction> IteSkolemMap;
 
 class RemoveTermFormulas {
  public:
-  RemoveTermFormulas(context::UserContext* u);
+  RemoveTermFormulas(context::UserContext* u, ProofNodeManager* pnm = nullptr);
   ~RemoveTermFormulas();
 
   /**
@@ -83,15 +83,13 @@ class RemoveTermFormulas {
    * @param newAsserts The new assertions corresponding to axioms for newly
    * introduced skolems.
    * @param newSkolems The skolems corresponding to each of the newAsserts.
-   * @param reportDeps Used for unsat cores in the old proof infrastructure.
    * @return a trust node of kind TrustNodeKind::REWRITE whose
    * right hand side is assertion after removing term formulas, and the proof
    * generator (if provided) that can prove the equivalence.
    */
   theory::TrustNode run(Node assertion,
                         std::vector<theory::TrustNode>& newAsserts,
-                        std::vector<Node>& newSkolems,
-                        bool reportDeps = false);
+                        std::vector<Node>& newSkolems);
 
   /**
    * Substitute under node using pre-existing cache.  Do not remove
@@ -105,12 +103,6 @@ class RemoveTermFormulas {
   /** Garbage collects non-context dependent data-structures. */
   void garbageCollect();
 
-  /**
-   * Set proof node manager, which signals this class to enable proofs using the
-   * given proof node manager.
-   */
-  void setProofNodeManager(ProofNodeManager* pnm);
-
   /**
    * Get proof generator that is responsible for all proofs for removing term
    * formulas from nodes. When proofs are enabled, the returned trust node
index 7b38bd844bfbe7e31425c33b8db078903a833e37..ecb15fbe9490cd8d94bc4ab42c68ab112daa1324 100644 (file)
@@ -218,7 +218,6 @@ ProofNodeManager* TheoryEngine::getProofNodeManager() const { return d_pnm; }
 TheoryEngine::TheoryEngine(context::Context* context,
                            context::UserContext* userContext,
                            ResourceManager* rm,
-                           RemoveTermFormulas& iteRemover,
                            const LogicInfo& logicInfo,
                            OutputManager& outMgr,
                            ProofNodeManager* pnm)
@@ -250,7 +249,7 @@ TheoryEngine::TheoryEngine(context::Context* context,
       d_propagatedLiterals(context),
       d_propagatedLiteralsIndex(context, 0),
       d_atomRequests(context),
-      d_tpp(*this, iteRemover, userContext, d_pnm),
+      d_tpp(*this, userContext, d_pnm),
       d_combineTheoriesTime("TheoryEngine::combineTheoriesTime"),
       d_true(),
       d_false(),
index 1412d7464990610b32ae32902c16fa89657ead51..bdc79931f4494fed72287c1018f4cde9abfdd478 100644 (file)
@@ -95,13 +95,8 @@ class RelevanceManager;
 namespace eq {
 class EqualityEngine;
 }  // namespace eq
-
-class EntailmentCheckParameters;
-class EntailmentCheckSideEffects;
 }/* CVC4::theory namespace */
 
-class RemoveTermFormulas;
-
 /**
  * This is essentially an abstraction for a collection of theories.  A
  * TheoryEngine provides services to a PropEngine, making various
@@ -313,7 +308,6 @@ class TheoryEngine {
   TheoryEngine(context::Context* context,
                context::UserContext* userContext,
                ResourceManager* rm,
-               RemoveTermFormulas& iteRemover,
                const LogicInfo& logic,
                OutputManager& outMgr,
                ProofNodeManager* pnm);
@@ -454,6 +448,8 @@ class TheoryEngine {
    * have been removed.
    */
   theory::TrustNode preprocess(TNode node);
+  /** Get the theory preprocessor TODO (project #42) remove this */
+  theory::TheoryPreprocessor* getTheoryPreprocess() { return &d_tpp; }
 
   /** Notify (preprocessed) assertions. */
   void notifyPreprocessedAssertions(const std::vector<Node>& assertions);
index ad9250a78e7ec1d749fdded0c4b6f8f7b02b8ed1..179ecc130c83d840b8dcf55aa97fe22e56a48ce2 100644 (file)
@@ -26,13 +26,12 @@ namespace CVC4 {
 namespace theory {
 
 TheoryPreprocessor::TheoryPreprocessor(TheoryEngine& engine,
-                                       RemoveTermFormulas& tfr,
                                        context::UserContext* userContext,
                                        ProofNodeManager* pnm)
     : d_engine(engine),
       d_logicInfo(engine.getLogicInfo()),
       d_ppCache(userContext),
-      d_tfr(tfr),
+      d_tfr(userContext, pnm),
       d_tpg(pnm ? new TConvProofGenerator(
                       pnm,
                       userContext,
@@ -102,7 +101,7 @@ TrustNode TheoryPreprocessor::preprocess(TNode node,
   }
 
   // Remove the ITEs
-  TrustNode ttfr = d_tfr.run(ppNode, newLemmas, newSkolems, false);
+  TrustNode ttfr = d_tfr.run(ppNode, newLemmas, newSkolems);
   Node rtfNode = ttfr.getNode();
 
   if (Debug.isOn("lemma-ites"))
index 147c17f4a063bb43098e4d425ae49f420d134815..349e7917e8096858ca373c06a4c5a74fb7a1d1b0 100644 (file)
@@ -25,6 +25,7 @@
 #include "expr/node.h"
 #include "expr/tconv_seq_proof_generator.h"
 #include "expr/term_conversion_proof_generator.h"
+#include "smt/term_formula_removal.h"
 #include "theory/trust_node.h"
 
 namespace CVC4 {
@@ -45,7 +46,6 @@ class TheoryPreprocessor
  public:
   /** Constructs a theory preprocessor */
   TheoryPreprocessor(TheoryEngine& engine,
-                     RemoveTermFormulas& tfr,
                      context::UserContext* userContext,
                      ProofNodeManager* pnm = nullptr);
   /** Destroys a theory preprocessor */
@@ -100,7 +100,7 @@ class TheoryPreprocessor
   /** Cache for theory-preprocessing of assertions */
   NodeMap d_ppCache;
   /** The term formula remover */
-  RemoveTermFormulas& d_tfr;
+  RemoveTermFormulas d_tfr;
   /** The term context, which computes hash values for term contexts. */
   InQuantTermContext d_iqtc;
   /**