(proof-new) Add interface for trusted substitution and update ppAssert (#5193)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Tue, 6 Oct 2020 15:02:54 +0000 (10:02 -0500)
committerGitHub <noreply@github.com>
Tue, 6 Oct 2020 15:02:54 +0000 (10:02 -0500)
The current work on proof-new involves proofs for preprocessing. The biggest issue currently is that our preprocessing passes do not track proofs for substitutions.

This adds a "trusted substitution" class with is a layer on substitution map. The proof aspect of this class is not yet implemented, this PR just adds its interface.

This also updates Theory::ppAssert to take a TrustSubstitutionMap instead of a SubstitutionMap, since eventually we will require proofs to be provided for substitutions that are added to this map.

27 files changed:
src/CMakeLists.txt
src/preprocessing/passes/miplib_trick.cpp
src/preprocessing/passes/non_clausal_simp.cpp
src/theory/arith/theory_arith.cpp
src/theory/arith/theory_arith.h
src/theory/arith/theory_arith_private.cpp
src/theory/arith/theory_arith_private.h
src/theory/arrays/theory_arrays.cpp
src/theory/arrays/theory_arrays.h
src/theory/booleans/theory_bool.cpp
src/theory/booleans/theory_bool.h
src/theory/bv/bv_solver.h
src/theory/bv/bv_solver_lazy.cpp
src/theory/bv/bv_solver_lazy.h
src/theory/bv/bv_solver_simple.h
src/theory/bv/theory_bv.cpp
src/theory/bv/theory_bv.h
src/theory/sep/theory_sep.cpp
src/theory/sep/theory_sep.h
src/theory/sets/theory_sets.cpp
src/theory/sets/theory_sets.h
src/theory/theory.cpp
src/theory/theory.h
src/theory/theory_engine.cpp
src/theory/theory_engine.h
src/theory/trust_substitutions.cpp [new file with mode: 0644]
src/theory/trust_substitutions.h [new file with mode: 0644]

index 4ca57effd855159514b6cc277602bca23363faee..7366d6eb24912987c03dcebc81c381da5486b81f 100644 (file)
@@ -896,6 +896,8 @@ libcvc4_add_sources(
   theory/theory_test_utils.h
   theory/trust_node.cpp
   theory/trust_node.h
+  theory/trust_substitutions.cpp
+  theory/trust_substitutions.h
   theory/type_enumerator.h
   theory/type_set.cpp
   theory/type_set.h
index 4c91297a114b1e34e7b6e8de1ffc2f9aaf65400b..3d7fd120ad50ec516bdbbc95eec5189f503af206 100644 (file)
@@ -23,6 +23,7 @@
 #include "smt_util/boolean_simplification.h"
 #include "theory/booleans/circuit_propagator.h"
 #include "theory/theory_model.h"
+#include "theory/trust_substitutions.h"
 
 namespace CVC4 {
 namespace preprocessing {
@@ -187,6 +188,7 @@ PreprocessingPassResult MipLibTrick::applyInternal(
   const booleans::CircuitPropagator::BackEdgesMap& backEdges =
       propagator->getBackEdges();
   unordered_set<unsigned long> removeAssertions;
+
   SubstitutionMap& top_level_substs =
       d_preprocContext->getTopLevelSubstitutions();
 
@@ -519,6 +521,8 @@ PreprocessingPassResult MipLibTrick::applyInternal(
                   NodeManager::SKOLEM_EXACT_NAME);
               Node geq = Rewriter::rewrite(nm->mkNode(kind::GEQ, newVar, zero));
               Node leq = Rewriter::rewrite(nm->mkNode(kind::LEQ, newVar, one));
+              TrustNode tgeq = TrustNode::mkTrustLemma(geq, nullptr);
+              TrustNode tleq = TrustNode::mkTrustLemma(leq, nullptr);
 
               Node n = Rewriter::rewrite(geq.andNode(leq));
               assertionsToPreprocess->push_back(n);
@@ -526,14 +530,15 @@ PreprocessingPassResult MipLibTrick::applyInternal(
               {
                 ProofManager::currentPM()->addDependence(n, Node::null());
               }
-              SubstitutionMap nullMap(&fakeContext);
+              TrustSubstitutionMap tnullMap(&fakeContext, nullptr);
+              CVC4_UNUSED SubstitutionMap& nullMap = tnullMap.get();
               Theory::PPAssertStatus status CVC4_UNUSED;  // just for assertions
-              status = te->solve(geq, nullMap);
+              status = te->solve(tgeq, tnullMap);
               Assert(status == Theory::PP_ASSERT_STATUS_UNSOLVED)
                   << "unexpected solution from arith's ppAssert()";
               Assert(nullMap.empty())
                   << "unexpected substitution from arith's ppAssert()";
-              status = te->solve(leq, nullMap);
+              status = te->solve(tleq, tnullMap);
               Assert(status == Theory::PP_ASSERT_STATUS_UNSOLVED)
                   << "unexpected solution from arith's ppAssert()";
               Assert(nullMap.empty())
index fcb6dd171cbfa4a127ecb6b78b2a5a7288eb9e4b..823e93f52b59caf4793323a30dd9d7fea0a3e952 100644 (file)
@@ -21,6 +21,7 @@
 #include "context/cdo.h"
 #include "smt/smt_statistics_registry.h"
 #include "theory/theory_model.h"
+#include "theory/trust_substitutions.h"
 
 using namespace CVC4;
 using namespace CVC4::theory;
@@ -116,7 +117,9 @@ PreprocessingPassResult NonClausalSimp::applyInternal(
   SubstitutionMap& top_level_substs =
       d_preprocContext->getTopLevelSubstitutions();
   SubstitutionMap constantPropagations(d_preprocContext->getUserContext());
-  SubstitutionMap newSubstitutions(d_preprocContext->getUserContext());
+  TrustSubstitutionMap tnewSubstituions(d_preprocContext->getUserContext(),
+                                        nullptr);
+  SubstitutionMap& newSubstitutions = tnewSubstituions.get();
   SubstitutionMap::iterator pos;
   size_t j = 0;
   std::vector<Node>& learned_literals = propagator->getLearnedLiterals();
@@ -178,10 +181,11 @@ PreprocessingPassResult NonClausalSimp::applyInternal(
     // Solve it with the corresponding theory, possibly adding new
     // substitutions to newSubstitutions
     Trace("non-clausal-simplify") << "solving " << learnedLiteral << std::endl;
-
+    TrustNode tlearnedLiteral =
+        TrustNode::mkTrustLemma(learnedLiteral, nullptr);
     Theory::PPAssertStatus solveStatus =
-        d_preprocContext->getTheoryEngine()->solve(learnedLiteral,
-                                                   newSubstitutions);
+        d_preprocContext->getTheoryEngine()->solve(tlearnedLiteral,
+                                                   tnewSubstituions);
 
     switch (solveStatus)
     {
index e2313e10a4534836b25892e1307fdbf7c4856f7f..47595e0bb233ba00c4c854541fa678b72fe153e9 100644 (file)
@@ -150,8 +150,10 @@ TrustNode TheoryArith::ppRewriteTerms(TNode n)
   return d_arithPreproc.eliminate(n);
 }
 
-Theory::PPAssertStatus TheoryArith::ppAssert(TNode in, SubstitutionMap& outSubstitutions) {
-  return d_internal->ppAssert(in, outSubstitutions);
+Theory::PPAssertStatus TheoryArith::ppAssert(
+    TrustNode tin, TrustSubstitutionMap& outSubstitutions)
+{
+  return d_internal->ppAssert(tin, outSubstitutions);
 }
 
 void TheoryArith::ppStaticLearn(TNode n, NodeBuilder<>& learned) {
index b8f2b18fde42488414408154a8a639a57d678374..0055273e421b491d8121dda0cb33b3836c92a158 100644 (file)
@@ -103,7 +103,8 @@ class TheoryArith : public Theory {
 
   void presolve() override;
   void notifyRestart() override;
-  PPAssertStatus ppAssert(TNode in, SubstitutionMap& outSubstitutions) override;
+  PPAssertStatus ppAssert(TrustNode tin,
+                          TrustSubstitutionMap& outSubstitutions) override;
   TrustNode ppRewrite(TNode atom) override;
   void ppStaticLearn(TNode in, NodeBuilder<>& learned) override;
 
index bb6ab0b9c34da152d3526dc1df4353e98beed798..4e4259482fc68fd8d60682f934549f463addd18d 100644 (file)
@@ -1102,8 +1102,11 @@ Node TheoryArithPrivate::getModelValue(TNode term) {
   }
 }
 
-Theory::PPAssertStatus TheoryArithPrivate::ppAssert(TNode in, SubstitutionMap& outSubstitutions) {
+Theory::PPAssertStatus TheoryArithPrivate::ppAssert(
+    TrustNode tin, TrustSubstitutionMap& outSubstitutions)
+{
   TimerStat::CodeTimer codeTimer(d_statistics.d_simplifyTimer);
+  TNode in = tin.getNode();
   Debug("simplify") << "TheoryArithPrivate::solve(" << in << ")" << endl;
 
 
@@ -1154,7 +1157,7 @@ Theory::PPAssertStatus TheoryArithPrivate::ppAssert(TNode in, SubstitutionMap& o
         Debug("simplify") << "TheoryArithPrivate::solve(): substitution "
                           << minVar << " |-> " << elim << endl;
 
-        outSubstitutions.addSubstitution(minVar, elim);
+        outSubstitutions.addSubstitutionSolved(minVar, elim, tin);
         return Theory::PP_ASSERT_STATUS_SOLVED;
       }
       else
index 1d840a81fc7af567875dc60402b7535c2be0177c..5cb281b364ff06d2bab3305cb797c3b6fcf43595 100644 (file)
@@ -465,7 +465,8 @@ private:
 
   void presolve();
   void notifyRestart();
-  Theory::PPAssertStatus ppAssert(TNode in, SubstitutionMap& outSubstitutions);
+  Theory::PPAssertStatus ppAssert(TrustNode tin,
+                                  TrustSubstitutionMap& outSubstitutions);
   void ppStaticLearn(TNode in, NodeBuilder<>& learned);
 
   std::string identify() const { return std::string("TheoryArith"); }
index 3270c1c070676646878c02da10a37799335f0ac9..3e59aebe61db371cb5ffb0b74aa8f31beae7a47c 100644 (file)
@@ -357,8 +357,10 @@ TrustNode TheoryArrays::ppRewrite(TNode term)
   return TrustNode::null();
 }
 
-
-Theory::PPAssertStatus TheoryArrays::ppAssert(TNode in, SubstitutionMap& outSubstitutions) {
+Theory::PPAssertStatus TheoryArrays::ppAssert(
+    TrustNode tin, TrustSubstitutionMap& outSubstitutions)
+{
+  TNode in = tin.getNode();
   switch(in.getKind()) {
     case kind::EQUAL:
     {
@@ -366,12 +368,12 @@ Theory::PPAssertStatus TheoryArrays::ppAssert(TNode in, SubstitutionMap& outSubs
       d_ppEqualityEngine.assertEquality(in, true, in);
       if (in[0].isVar() && isLegalElimination(in[0], in[1]))
       {
-        outSubstitutions.addSubstitution(in[0], in[1]);
+        outSubstitutions.addSubstitutionSolved(in[0], in[1], tin);
         return PP_ASSERT_STATUS_SOLVED;
       }
       if (in[1].isVar() && isLegalElimination(in[1], in[0]))
       {
-        outSubstitutions.addSubstitution(in[1], in[0]);
+        outSubstitutions.addSubstitutionSolved(in[1], in[0], tin);
         return PP_ASSERT_STATUS_SOLVED;
       }
       break;
index 0dd95795b37803cb16430bba210e4df6d3063a84..5236324bc9c5e48a7bf0a5a9e22b60bad26e3fa4 100644 (file)
@@ -193,7 +193,8 @@ class TheoryArrays : public Theory {
   InferenceManager d_im;
 
  public:
-  PPAssertStatus ppAssert(TNode in, SubstitutionMap& outSubstitutions) override;
+  PPAssertStatus ppAssert(TrustNode tin,
+                          TrustSubstitutionMap& outSubstitutions) override;
   TrustNode ppRewrite(TNode atom) override;
 
   /////////////////////////////////////////////////////////////////////////////
index 8ce0c077a11a13df422578423f17e3892a12da69..c08012b619a7ad5e454125a2db980cd6b28c23d1 100644 (file)
@@ -50,8 +50,10 @@ TheoryBool::TheoryBool(context::Context* c,
   }
 }
 
-Theory::PPAssertStatus TheoryBool::ppAssert(TNode in, SubstitutionMap& outSubstitutions) {
-
+Theory::PPAssertStatus TheoryBool::ppAssert(
+    TrustNode tin, TrustSubstitutionMap& outSubstitutions)
+{
+  TNode in = tin.getNode();
   if (in.getKind() == kind::CONST_BOOLEAN && !in.getConst<bool>()) {
     // If we get a false literal, we're in conflict
     return PP_ASSERT_STATUS_CONFLICT;
@@ -61,18 +63,20 @@ Theory::PPAssertStatus TheoryBool::ppAssert(TNode in, SubstitutionMap& outSubsti
   if (in.getKind() == kind::NOT) {
     if (in[0].isVar())
     {
-      outSubstitutions.addSubstitution(in[0], NodeManager::currentNM()->mkConst<bool>(false));
+      outSubstitutions.addSubstitutionSolved(
+          in[0], NodeManager::currentNM()->mkConst<bool>(false), tin);
       return PP_ASSERT_STATUS_SOLVED;
     }
   } else {
     if (in.isVar())
     {
-      outSubstitutions.addSubstitution(in, NodeManager::currentNM()->mkConst<bool>(true));
+      outSubstitutions.addSubstitutionSolved(
+          in, NodeManager::currentNM()->mkConst<bool>(true), tin);
       return PP_ASSERT_STATUS_SOLVED;
     }
   }
 
-  return Theory::ppAssert(in, outSubstitutions);
+  return Theory::ppAssert(tin, outSubstitutions);
 }
 
 }/* CVC4::theory::booleans namespace */
index 720ba4ed4669403d7e15d350b6442a4546f98d29..0a8ca27660a00ae006387b0e1c3c68c39813928b 100644 (file)
@@ -39,7 +39,8 @@ class TheoryBool : public Theory {
 
   TheoryRewriter* getTheoryRewriter() override { return &d_rewriter; }
 
-  PPAssertStatus ppAssert(TNode in, SubstitutionMap& outSubstitutions) override;
+  PPAssertStatus ppAssert(TrustNode tin,
+                          TrustSubstitutionMap& outSubstitutions) override;
 
   std::string identify() const override { return std::string("TheoryBool"); }
 
index 6e251fc2db795f9563b007295eead57265c8f41c..f4b5a9d111b7dbb4b7865211cb79a6694e3ecb97 100644 (file)
@@ -86,7 +86,7 @@ class BVSolver
   virtual std::string identify() const = 0;
 
   virtual Theory::PPAssertStatus ppAssert(
-      TNode in, SubstitutionMap& outSubstitutions) = 0;
+      TrustNode in, TrustSubstitutionMap& outSubstitutions) = 0;
 
   virtual TrustNode ppRewrite(TNode t) { return TrustNode::null(); };
 
index 417cf0c158ed9f1d25309f68df8e9dc199587dc9..a19af44ac37871822eda93b6b0065963355cde4f 100644 (file)
@@ -439,9 +439,10 @@ void BVSolverLazy::propagate(Theory::Effort e)
   }
 }
 
-Theory::PPAssertStatus BVSolverLazy::ppAssert(TNode in,
-                                              SubstitutionMap& outSubstitutions)
+Theory::PPAssertStatus BVSolverLazy::ppAssert(
+    TrustNode tin, TrustSubstitutionMap& outSubstitutions)
 {
+  TNode in = tin.getNode();
   switch (in.getKind())
   {
     case kind::EQUAL:
@@ -449,13 +450,13 @@ Theory::PPAssertStatus BVSolverLazy::ppAssert(TNode in,
       if (in[0].isVar() && d_bv.isLegalElimination(in[0], in[1]))
       {
         ++(d_statistics.d_solveSubstitutions);
-        outSubstitutions.addSubstitution(in[0], in[1]);
+        outSubstitutions.addSubstitutionSolved(in[0], in[1], tin);
         return Theory::PP_ASSERT_STATUS_SOLVED;
       }
       if (in[1].isVar() && d_bv.isLegalElimination(in[1], in[0]))
       {
         ++(d_statistics.d_solveSubstitutions);
-        outSubstitutions.addSubstitution(in[1], in[0]);
+        outSubstitutions.addSubstitutionSolved(in[1], in[0], tin);
         return Theory::PP_ASSERT_STATUS_SOLVED;
       }
       Node node = Rewriter::rewrite(in);
@@ -502,7 +503,7 @@ Theory::PPAssertStatus BVSolverLazy::ppAssert(TNode in,
           Assert(utils::getSize(concat) == utils::getSize(extract[0]));
           if (d_bv.isLegalElimination(extract[0], concat))
           {
-            outSubstitutions.addSubstitution(extract[0], concat);
+            outSubstitutions.addSubstitutionSolved(extract[0], concat, tin);
             return Theory::PP_ASSERT_STATUS_SOLVED;
           }
         }
index b72d53e58b537cd125bcf06c54f068c1c5e5f312..6885dbba4736e7e4ceac5a7d9fae7e1f7a1dd9b8 100644 (file)
@@ -92,8 +92,8 @@ class BVSolverLazy : public BVSolver
 
   std::string identify() const override { return std::string("BVSolverLazy"); }
 
-  Theory::PPAssertStatus ppAssert(TNode in,
-                                  SubstitutionMap& outSubstitutions) override;
+  Theory::PPAssertStatus ppAssert(
+      TrustNode tin, TrustSubstitutionMap& outSubstitutions) override;
 
   TrustNode ppRewrite(TNode t) override;
 
index b7d86cf67222213bb3729c35a301249bd96a10a9..59239a52c2ac2fff830040abfe9ff040edbeea2b 100644 (file)
@@ -53,8 +53,8 @@ class BVSolverSimple : public BVSolver
 
   std::string identify() const override { return "BVSolverSimple"; };
 
-  Theory::PPAssertStatus ppAssert(TNode in,
-                                  SubstitutionMap& outSubstitutions) override
+  Theory::PPAssertStatus ppAssert(
+      TrustNode in, TrustSubstitutionMap& outSubstitutions) override
   {
     return Theory::PPAssertStatus::PP_ASSERT_STATUS_UNSOLVED;
   }
index 79a20c9c958603843b0623d91f260dcef81072af..d43fa39275f6b19b40fcff027c85de41041b33dc 100644 (file)
@@ -37,7 +37,7 @@ TheoryBV::TheoryBV(context::Context* c,
       d_ufRemByZero(),
       d_rewriter(),
       d_state(c, u, valuation),
-      d_inferMgr(*this, d_state, pnm)
+      d_inferMgr(*this, d_state, nullptr)
 {
   switch (options::bvSolver())
   {
@@ -194,10 +194,10 @@ bool TheoryBV::collectModelValues(TheoryModel* m, const std::set<Node>& termSet)
 
 void TheoryBV::propagate(Effort e) { return d_internal->propagate(e); }
 
-Theory::PPAssertStatus TheoryBV::ppAssert(TNode in,
-                                          SubstitutionMap& outSubstitutions)
+Theory::PPAssertStatus TheoryBV::ppAssert(
+    TrustNode tin, TrustSubstitutionMap& outSubstitutions)
 {
-  return d_internal->ppAssert(in, outSubstitutions);
+  return d_internal->ppAssert(tin, outSubstitutions);
 }
 
 TrustNode TheoryBV::ppRewrite(TNode t) { return d_internal->ppRewrite(t); }
index a01c74382c78c7b5ed58e846233e7446a8115601..fa228131ccb710f210cefdd62e4491f942583585 100644 (file)
@@ -87,7 +87,8 @@ class TheoryBV : public Theory
 
   std::string identify() const override { return std::string("TheoryBV"); }
 
-  PPAssertStatus ppAssert(TNode in, SubstitutionMap& outSubstitutions) override;
+  PPAssertStatus ppAssert(TrustNode in,
+                          TrustSubstitutionMap& outSubstitutions) override;
 
   TrustNode ppRewrite(TNode t) override;
 
index b18ae5b951df921b9ba6e0dbff3dbc7dcba589e0..013c61e5218a3d1ead0eaafb8427dbcb6fa2428c 100644 (file)
@@ -50,7 +50,7 @@ TheorySep::TheorySep(context::Context* c,
       d_lemmas_produced_c(u),
       d_bounds_init(false),
       d_state(c, u, valuation),
-      d_im(*this, d_state, pnm),
+      d_im(*this, d_state, nullptr),
       d_notify(*this),
       d_reduce(u),
       d_spatial_assertions(c)
@@ -96,16 +96,6 @@ Node TheorySep::mkAnd( std::vector< TNode >& assumptions ) {
   }
 }
 
-/////////////////////////////////////////////////////////////////////////////
-// PREPROCESSING
-/////////////////////////////////////////////////////////////////////////////
-
-
-Theory::PPAssertStatus TheorySep::ppAssert(TNode in, SubstitutionMap& outSubstitutions) {
-
-  return PP_ASSERT_STATUS_UNSOLVED;
-}
-
 
 /////////////////////////////////////////////////////////////////////////////
 // T-PROPAGATION / REGISTRATION
index 58c3a4b28fec22ea5d9c4612b62c75baa19f2108..ac87ebe67b9d8e4f198df95dec7394c933bc1e31 100644 (file)
@@ -99,8 +99,6 @@ class TheorySep : public Theory {
   /////////////////////////////////////////////////////////////////////////////
 
  public:
-  PPAssertStatus ppAssert(TNode in, SubstitutionMap& outSubstitutions) override;
-
   void ppNotifyAssertions(const std::vector<Node>& assertions) override;
   /////////////////////////////////////////////////////////////////////////////
   // T-PROPAGATION / REGISTRATION
index 9823434c6a235c8451caec3cdffc61bf5f0d7777..763024d5fcb2834d6310aad60f2c7133906e02b8 100644 (file)
@@ -36,7 +36,7 @@ TheorySets::TheorySets(context::Context* c,
     : Theory(THEORY_SETS, c, u, out, valuation, logicInfo, pnm),
       d_skCache(),
       d_state(c, u, valuation, d_skCache),
-      d_im(*this, d_state, pnm),
+      d_im(*this, d_state, nullptr),
       d_internal(new TheorySetsPrivate(*this, d_state, d_im, d_skCache)),
       d_notify(*d_internal.get(), d_im)
 {
@@ -153,7 +153,10 @@ TrustNode TheorySets::expandDefinition(Node n)
   return d_internal->expandDefinition(n);
 }
 
-Theory::PPAssertStatus TheorySets::ppAssert(TNode in, SubstitutionMap& outSubstitutions) {
+Theory::PPAssertStatus TheorySets::ppAssert(
+    TrustNode tin, TrustSubstitutionMap& outSubstitutions)
+{
+  TNode in = tin.getNode();
   Debug("sets-proc") << "ppAssert : " << in << std::endl;
   Theory::PPAssertStatus status = Theory::PP_ASSERT_STATUS_UNSOLVED;
 
@@ -168,7 +171,7 @@ Theory::PPAssertStatus TheorySets::ppAssert(TNode in, SubstitutionMap& outSubsti
       // regress0/sets/pre-proc-univ.smt2
       if (!in[0].getType().isSet() || !options::setsExt())
       {
-        outSubstitutions.addSubstitution(in[0], in[1]);
+        outSubstitutions.addSubstitutionSolved(in[0], in[1], tin);
         status = Theory::PP_ASSERT_STATUS_SOLVED;
       }
     }
@@ -176,7 +179,7 @@ Theory::PPAssertStatus TheorySets::ppAssert(TNode in, SubstitutionMap& outSubsti
     {
       if (!in[0].getType().isSet() || !options::setsExt())
       {
-        outSubstitutions.addSubstitution(in[1], in[0]);
+        outSubstitutions.addSubstitutionSolved(in[1], in[0], tin);
         status = Theory::PP_ASSERT_STATUS_SOLVED;
       }
     }
index ddc0bd45e42210fa545e363f2ff957d98356b03b..a5f8fa4d8d66270cbcb53ee30fc0fc8a306d9989 100644 (file)
@@ -77,7 +77,8 @@ class TheorySets : public Theory
   std::string identify() const override { return "THEORY_SETS"; }
   void preRegisterTerm(TNode node) override;
   TrustNode expandDefinition(Node n) override;
-  PPAssertStatus ppAssert(TNode in, SubstitutionMap& outSubstitutions) override;
+  PPAssertStatus ppAssert(TrustNode tin,
+                          TrustSubstitutionMap& outSubstitutions) override;
   void presolve() override;
   bool isEntailed(Node n, bool pol);
 
index 2a471ec0de2e8951abd0b928d5488487efc87c21..757f94d5bcb4da146e06cb8dde3aca9b9487a8f0 100644 (file)
@@ -375,9 +375,10 @@ bool Theory::collectModelValues(TheoryModel* m, const std::set<Node>& termSet)
   return true;
 }
 
-Theory::PPAssertStatus Theory::ppAssert(TNode in,
-                                        SubstitutionMap& outSubstitutions)
+Theory::PPAssertStatus Theory::ppAssert(TrustNode tin,
+                                        TrustSubstitutionMap& outSubstitutions)
 {
+  TNode in = tin.getNode();
   if (in.getKind() == kind::EQUAL)
   {
     // (and (= x t) phi) can be replaced by phi[x/t] if
index 6f6c863dfc93477addb88764c4e5837b9f56d922..86dbb60d644129d29d3d0df797ce0fa7e209c6b2 100644 (file)
@@ -44,6 +44,7 @@
 #include "theory/theory_rewriter.h"
 #include "theory/theory_state.h"
 #include "theory/trust_node.h"
+#include "theory/trust_substitutions.h"
 #include "theory/valuation.h"
 #include "util/statistics_registry.h"
 
@@ -699,10 +700,16 @@ class Theory {
   };
 
   /**
-   * Given a literal, add the solved substitutions to the map, if any.
-   * The method should return true if the literal can be safely removed.
+   * Given a literal and its proof generator (encapsulated by trust node tin),
+   * add the solved substitutions to the map, if any. The method should return
+   * true if the literal can be safely removed from the input problem.
+   *
+   * Note that tin has trude node kind LEMMA. Its proof generator should be
+   * take into account when adding a substitution to outSubstitutions when
+   * proofs are enabled.
    */
-  virtual PPAssertStatus ppAssert(TNode in, SubstitutionMap& outSubstitutions);
+  virtual PPAssertStatus ppAssert(TrustNode tin,
+                                  TrustSubstitutionMap& outSubstitutions);
 
   /**
    * Given an atom of the theory coming from the input formula, this
index 47dca7d669ee92135900be4a4b37fa9bf7833af8..4722251a35aae30c4525b5e680c6c6047cf00ff8 100644 (file)
@@ -823,10 +823,13 @@ void TheoryEngine::shutdown() {
   d_tpp.clearCache();
 }
 
-theory::Theory::PPAssertStatus TheoryEngine::solve(TNode literal, SubstitutionMap& substitutionOut) {
+theory::Theory::PPAssertStatus TheoryEngine::solve(
+    TrustNode tliteral, TrustSubstitutionMap& substitutionOut)
+{
   // Reset the interrupt flag
   d_interrupted = false;
 
+  TNode literal = tliteral.getNode();
   TNode atom = literal.getKind() == kind::NOT ? literal[0] : literal;
   Trace("theory::solve") << "TheoryEngine::solve(" << literal << "): solving with " << theoryOf(atom)->getId() << endl;
 
@@ -841,7 +844,8 @@ theory::Theory::PPAssertStatus TheoryEngine::solve(TNode literal, SubstitutionMa
     throw LogicException(ss.str());
   }
 
-  Theory::PPAssertStatus solveStatus = theoryOf(atom)->ppAssert(literal, substitutionOut);
+  Theory::PPAssertStatus solveStatus =
+      theoryOf(atom)->ppAssert(tliteral, substitutionOut);
   Trace("theory::solve") << "TheoryEngine::solve(" << literal << ") => " << solveStatus << endl;
   return solveStatus;
 }
index cfca03515fc2821b529ced4c128da1f989f0cacb..e410bddd5c916c0ab132d0813a5037900998e0b9 100644 (file)
@@ -494,10 +494,13 @@ class TheoryEngine {
   void shutdown();
 
   /**
-   * Solve the given literal with a theory that owns it.
+   * Solve the given literal with a theory that owns it. The proof of tliteral
+   * is carried in the trust node. The proof added to substitutionOut should
+   * take this proof into account (when proofs are enabled).
    */
-  theory::Theory::PPAssertStatus solve(TNode literal,
-                                    theory::SubstitutionMap& substitutionOut);
+  theory::Theory::PPAssertStatus solve(
+      theory::TrustNode tliteral,
+      theory::TrustSubstitutionMap& substitutionOut);
 
   /**
    * Preregister a Theory atom with the responsible theory (or
diff --git a/src/theory/trust_substitutions.cpp b/src/theory/trust_substitutions.cpp
new file mode 100644 (file)
index 0000000..de8fc2c
--- /dev/null
@@ -0,0 +1,60 @@
+/*********************                                                        */
+/*! \file trust_substitutions.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ **   Andrew Reynolds
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2020 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 Trust substitutions
+ **/
+
+#include "theory/trust_substitutions.h"
+
+#include "theory/rewriter.h"
+
+namespace CVC4 {
+namespace theory {
+
+TrustSubstitutionMap::TrustSubstitutionMap(context::Context* c,
+                                           ProofNodeManager* pnm)
+    : d_subs(c)
+{
+}
+
+void TrustSubstitutionMap::addSubstitution(TNode x, TNode t, ProofGenerator* pg)
+{
+  d_subs.addSubstitution(x, t);
+}
+
+TrustNode TrustSubstitutionMap::apply(Node n, bool doRewrite)
+{
+  Node ns = d_subs.apply(n);
+  if (doRewrite)
+  {
+    ns = Rewriter::rewrite(ns);
+  }
+  return TrustNode::mkTrustRewrite(n, ns, nullptr);
+}
+
+void TrustSubstitutionMap::addSubstitutionSolved(TNode x, TNode t, TrustNode tn)
+{
+  if (!isProofEnabled() || tn.getGenerator() == nullptr)
+  {
+    // no generator or not proof enabled, nothing to do
+    addSubstitution(x, t, nullptr);
+    return;
+  }
+  // NOTE: can try to transform tn.getProven() to (= x t) here
+  addSubstitution(x, t, nullptr);
+}
+
+SubstitutionMap& TrustSubstitutionMap::get() { return d_subs; }
+
+bool TrustSubstitutionMap::isProofEnabled() const { return false; }
+
+}  // namespace theory
+}  // namespace CVC4
diff --git a/src/theory/trust_substitutions.h b/src/theory/trust_substitutions.h
new file mode 100644 (file)
index 0000000..0eacc50
--- /dev/null
@@ -0,0 +1,72 @@
+/*********************                                                        */
+/*! \file trust_substitutions.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ **   Andrew Reynolds
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2020 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 Trust substitutions
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef CVC4__THEORY__TRUST_SUBSTITUTIONS_H
+#define CVC4__THEORY__TRUST_SUBSTITUTIONS_H
+
+#include "context/context.h"
+#include "expr/proof_node_manager.h"
+#include "theory/substitutions.h"
+#include "theory/trust_node.h"
+
+namespace CVC4 {
+namespace theory {
+
+/**
+ * A layer on top of SubstitutionMap that tracks proofs.
+ */
+class TrustSubstitutionMap
+{
+ public:
+  TrustSubstitutionMap(context::Context* c, ProofNodeManager* pnm);
+  /** Gets a reference to the underlying substitution map */
+  SubstitutionMap& get();
+  /**
+   * Add substitution x -> t, where pg can provide a closed proof of (= x t)
+   * in the remainder of this user context.
+   */
+  void addSubstitution(TNode x, TNode t, ProofGenerator* pg = nullptr);
+  /**
+   * Add substitution x -> t, which was derived from the proven field of
+   * trust node tn. In other words, (= x t) is the solved form of
+   * tn.getProven(). This method is a helper function for methods (e.g.
+   * ppAssert) that put literals into solved form. It should be the case
+   * that (= x t) and tn.getProven() can be shown equivalent by rewriting.
+   *
+   * This ensures that we add a substitution with a proof
+   * based on transforming the tn.getProven() to (= x t) if tn has a
+   * non-null proof generator; otherwise if tn has no proof generator
+   * we simply add the substitution.
+   */
+  void addSubstitutionSolved(TNode x, TNode t, TrustNode tn);
+  /**
+   * Apply substitutions in this class to node n. Returns a trust node
+   * proving n = n*sigma, where the proof generator is provided by this class
+   * (when proofs are enabled).
+   */
+  TrustNode apply(Node n, bool doRewrite = true);
+
+ private:
+  /** Are proofs enabled? */
+  bool isProofEnabled() const;
+  /** The substitution map */
+  SubstitutionMap d_subs;
+};
+
+}  // namespace theory
+}  // namespace CVC4
+
+#endif /* CVC4__THEORY__TRUST_SUBSTITUTIONS_H */