Standardization of Theory (#5181)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Sat, 3 Oct 2020 11:11:02 +0000 (06:11 -0500)
committerGitHub <noreply@github.com>
Sat, 3 Oct 2020 11:11:02 +0000 (06:11 -0500)
This cleans up various interfaces of Theory now that all theories have been updated to the new standard. This includes making check non-virtual, standardizing when trigger terms are added to equality engines, and simplifications for collectModelInfo.

17 files changed:
src/theory/arith/congruence_manager.cpp
src/theory/arith/congruence_manager.h
src/theory/arith/theory_arith.cpp
src/theory/arith/theory_arith.h
src/theory/arith/theory_arith_private.cpp
src/theory/arrays/theory_arrays.cpp
src/theory/bv/theory_bv.cpp
src/theory/fp/theory_fp.cpp
src/theory/fp/theory_fp.h
src/theory/model_manager_distributed.cpp
src/theory/sets/theory_sets_private.cpp
src/theory/strings/theory_strings.cpp
src/theory/theory.cpp
src/theory/theory.h
src/theory/theory_model.cpp
src/theory/theory_model.h
test/unit/theory/theory_engine_white.h

index 465128b1bef8a6aa2dd8bb8b2526fdfd39f70a36..f2db70d9054d1e53a42f035199c1792063ebf8f3 100644 (file)
@@ -477,10 +477,6 @@ void ArithCongruenceManager::equalsConstant(ConstraintCP lb, ConstraintCP ub){
   d_ee->assertEquality(eq, true, reason);
 }
 
-void ArithCongruenceManager::addSharedTerm(Node x){
-  d_ee->addTriggerTerm(x, THEORY_ARITH);
-}
-
 bool ArithCongruenceManager::isProofEnabled() const { return d_pnm != nullptr; }
 
 std::vector<Node> andComponents(TNode an)
index 6115fec8a44e10a1a1fde715054cd8ac237508fc..44a2b9df610d3de5830c3e180f3a1d7ea45a2d23 100644 (file)
@@ -217,9 +217,6 @@ public:
   void equalsConstant(ConstraintCP eq);
   void equalsConstant(ConstraintCP lb, ConstraintCP ub);
 
-
-  void addSharedTerm(Node x);
-
  private:
   class Statistics {
   public:
index 434d2e1c8334641a060b6cf1c16284813ef29d7b..bddc8ebcc1cd7adc577144e0b9e4eb9f8d7bc1c0 100644 (file)
@@ -219,12 +219,9 @@ void TheoryArith::propagate(Effort e) {
   d_internal->propagate(e);
 }
 
-bool TheoryArith::collectModelInfo(TheoryModel* m)
+bool TheoryArith::collectModelInfo(TheoryModel* m,
+                                   const std::set<Node>& termSet)
 {
-  std::set<Node> termSet;
-  // Work out which variables are needed
-  const std::set<Kind>& irrKinds = m->getIrrelevantKinds();
-  computeAssertedTerms(termSet, irrKinds);
   // this overrides behavior to not assert equality engine
   return collectModelValues(m, termSet);
 }
index 8555156a59e60c37526c2cf7abd5a4afb0539891..6b279c9eddbda28a6056dd87ab05c2cfcc870220 100644 (file)
@@ -91,7 +91,7 @@ class TheoryArith : public Theory {
   void propagate(Effort e) override;
   TrustNode explain(TNode n) override;
 
-  bool collectModelInfo(TheoryModel* m) override;
+  bool collectModelInfo(TheoryModel* m, const std::set<Node>& termSet) override;
   /**
    * Collect model values in m based on the relevant terms given by termSet.
    */
index 55707231945debff57d027f1e8bd43a33eb8700b..bb6ab0b9c34da152d3526dc1df4353e98beed798 100644 (file)
@@ -1076,7 +1076,6 @@ void TheoryArithPrivate::notifySharedTerm(TNode n)
   if(n.isConst()){
     d_partialModel.invalidateDelta();
   }
-  d_congruenceManager.addSharedTerm(n);
   if(!n.isConst() && !isSetup(n)){
     Polynomial poly = Polynomial::parsePolynomial(n);
     Polynomial::iterator it = poly.begin();
index 5dee75a6ccd4d1483320110344b0c5597ef2bff8..3270c1c070676646878c02da10a37799335f0ac9 100644 (file)
@@ -852,7 +852,6 @@ void TheoryArrays::notifySharedTerm(TNode t)
   Debug("arrays::sharing") << spaces(getSatContext()->getLevel())
                            << "TheoryArrays::notifySharedTerm(" << t << ")"
                            << std::endl;
-  d_equalityEngine->addTriggerTerm(t, THEORY_ARRAYS);
   if (t.getType().isArray()) {
     d_sharedArrays.insert(t);
   }
index 857d4d6fb5496b10db593694d971d3e0580b5631..79a20c9c958603843b0623d91f260dcef81072af 100644 (file)
@@ -209,11 +209,6 @@ TrustNode TheoryBV::explain(TNode node) { return d_internal->explain(node); }
 void TheoryBV::notifySharedTerm(TNode t)
 {
   d_internal->notifySharedTerm(t);
-  // temporary, will be built into Theory::addSharedTerm
-  if (d_equalityEngine != nullptr)
-  {
-    d_equalityEngine->addTriggerTerm(t, THEORY_BV);
-  }
 }
 
 void TheoryBV::ppStaticLearn(TNode in, NodeBuilder<>& learned)
index 863f9a5a6b9331c295f6394421dfe7b411df83c6..037b083f445b1ade79601790a9bbbfff14b7b10e 100644 (file)
@@ -1019,12 +1019,9 @@ Node TheoryFp::getModelValue(TNode var) {
   return d_conv.getValue(d_valuation, var);
 }
 
-bool TheoryFp::collectModelInfo(TheoryModel* m)
+bool TheoryFp::collectModelInfo(TheoryModel* m,
+                                const std::set<Node>& relevantTerms)
 {
-  std::set<Node> relevantTerms;
-  // Work out which variables are needed
-  const std::set<Kind>& irrKinds = m->getIrrelevantKinds();
-  computeAssertedTerms(relevantTerms, irrKinds);
   // this override behavior to not assert equality engine
   return collectModelValues(m, relevantTerms);
 }
index 16d984011fa46ec2a9d0ff351210ee307b8b5a75..42c009893310b20680881b39f4ef052af2b268cd 100644 (file)
@@ -75,7 +75,8 @@ class TheoryFp : public Theory {
   //--------------------------------- end standard check
 
   Node getModelValue(TNode var) override;
-  bool collectModelInfo(TheoryModel* m) override;
+  bool collectModelInfo(TheoryModel* m,
+                        const std::set<Node>& relevantTerms) override;
   /** Collect model values in m based on the relevant terms given by
    * relevantTerms */
   bool collectModelValues(TheoryModel* m,
index 5ea2799c561ed0eedb47177d5e171694d9748f79..7d121af53fdd5c2ae75f7f1af8079c5118f50045 100644 (file)
@@ -78,7 +78,12 @@ bool ModelManagerDistributed::prepareModel()
     Theory* t = d_te.theoryOf(theoryId);
     Trace("model-builder") << "  CollectModelInfo on theory: " << theoryId
                            << std::endl;
-    if (!t->collectModelInfo(d_model))
+    // collect the asserted terms
+    std::set<Node> termSet;
+    collectAssertedTerms(theoryId, termSet);
+    // also get relevant terms
+    t->computeRelevantTerms(termSet);
+    if (!t->collectModelInfo(d_model, termSet))
     {
       Trace("model-builder")
           << "ModelManagerDistributed: fail collect model info" << std::endl;
index 1a0b1b1e25759c4e0303480b276e79890ccfa8b2..51f49ad1d4bed297e243c26619fd54c2ac1664eb 100644 (file)
@@ -1275,7 +1275,6 @@ void TheorySetsPrivate::preRegisterTerm(TNode node)
       d_equalityEngine->addTriggerPredicate(node);
     }
     break;
-    case kind::CARD: d_equalityEngine->addTriggerTerm(node, THEORY_SETS); break;
     default: d_equalityEngine->addTerm(node); break;
   }
 }
index 309b855039b2bff28da5ed28fcfd69ec826df65d..0375fd3119861790333c3dc6f51d8b469207e6d3 100644 (file)
@@ -163,7 +163,6 @@ void TheoryStrings::notifySharedTerm(TNode t)
 {
   Debug("strings") << "TheoryStrings::notifySharedTerm(): " << t << " "
                    << t.getType().isBoolean() << endl;
-  d_equalityEngine->addTriggerTerm(t, THEORY_STRINGS);
   if (options::stringExp())
   {
     d_esolver.addSharedTerm(t);
index cdcec52e3141c0891f30ae3a7a23f87f2d865ce7..2a471ec0de2e8951abd0b928d5488487efc87c21 100644 (file)
@@ -273,13 +273,7 @@ TheoryId Theory::theoryOf(options::TheoryOfMode mode, TNode node)
 
 void Theory::notifySharedTerm(TNode n)
 {
-  // TODO (project #39): this will move to addSharedTerm, as every theory with
-  // an equality does this in their notifySharedTerm method.
-  // if we have an equality engine, add the trigger term
-  if (d_equalityEngine != nullptr)
-  {
-    d_equalityEngine->addTriggerTerm(n, d_id);
-  }
+  // do nothing
 }
 
 void Theory::computeCareGraph() {
@@ -357,18 +351,8 @@ std::unordered_set<TNode, TNodeHashFunction> Theory::currentlySharedTerms() cons
   return currentlyShared;
 }
 
-bool Theory::collectModelInfo(TheoryModel* m)
+bool Theory::collectModelInfo(TheoryModel* m, const std::set<Node>& termSet)
 {
-  // NOTE: the computation of termSet will be moved to model manager
-  // and passed as an argument to collectModelInfo.
-  std::set<Node> termSet;
-  // Compute terms appearing in assertions and shared terms
-  TheoryModel* tm = d_valuation.getModel();
-  Assert(tm != nullptr);
-  const std::set<Kind>& irrKinds = tm->getIrrelevantKinds();
-  computeAssertedTerms(termSet, irrKinds, true);
-  // Compute additional relevant terms (theory-specific)
-  computeRelevantTerms(termSet);
   // if we are using an equality engine, assert it to the model
   if (d_equalityEngine != nullptr)
   {
@@ -381,54 +365,6 @@ bool Theory::collectModelInfo(TheoryModel* m)
   return collectModelValues(m, termSet);
 }
 
-void Theory::collectTerms(TNode n,
-                          const std::set<Kind>& irrKinds,
-                          set<Node>& termSet) const
-{
-  if (termSet.find(n) != termSet.end()) {
-    return;
-  }
-  Kind nk = n.getKind();
-  if (irrKinds.find(nk) == irrKinds.end())
-  {
-    Trace("theory::collectTerms")
-        << "Theory::collectTerms: adding " << n << endl;
-    termSet.insert(n);
-  }
-  if (nk == kind::NOT || nk == kind::EQUAL || !isLeaf(n))
-  {
-    for(TNode::iterator child_it = n.begin(); child_it != n.end(); ++child_it) {
-      collectTerms(*child_it, irrKinds, termSet);
-    }
-  }
-}
-
-void Theory::computeAssertedTerms(std::set<Node>& termSet,
-                                  const std::set<Kind>& irrKinds,
-                                  bool includeShared) const
-{
-  // Collect all terms appearing in assertions
-  context::CDList<Assertion>::const_iterator assert_it = facts_begin(),
-                                             assert_it_end = facts_end();
-  for (; assert_it != assert_it_end; ++assert_it)
-  {
-    collectTerms(*assert_it, irrKinds, termSet);
-  }
-
-  if (!includeShared)
-  {
-    return;
-  }
-  // Add terms that are shared terms
-  std::set<Kind> kempty;
-  context::CDList<TNode>::const_iterator shared_it = shared_terms_begin(),
-                                         shared_it_end = shared_terms_end();
-  for (; shared_it != shared_it_end; ++shared_it)
-  {
-    collectTerms(*shared_it, kempty, termSet);
-  }
-}
-
 void Theory::computeRelevantTerms(std::set<Node>& termSet)
 {
   // by default, there are no additional relevant terms
@@ -532,18 +468,24 @@ void Theory::check(Effort level)
   // standard calls for resource, stats
   d_out->spendResource(ResourceManager::Resource::TheoryCheckStep);
   TimerStat::CodeTimer checkTimer(d_checkTime);
+  Trace("theory-check") << "Theory::preCheck " << level << " " << d_id
+                        << std::endl;
   // pre-check at level
   if (preCheck(level))
   {
     // check aborted for a theory-specific reason
     return;
   }
+  Assert(d_theoryState != nullptr);
+  Trace("theory-check") << "Theory::process fact queue " << d_id << std::endl;
   // process the pending fact queue
   while (!done() && !d_theoryState->isInConflict())
   {
     // Get the next assertion from the fact queue
     Assertion assertion = get();
     TNode fact = assertion.d_assertion;
+    Trace("theory-check") << "Theory::preNotifyFact " << fact << " " << d_id
+                          << std::endl;
     bool polarity = fact.getKind() != kind::NOT;
     TNode atom = polarity ? fact : fact[0];
     // call the pre-notify method
@@ -552,6 +494,8 @@ void Theory::check(Effort level)
       // handled in theory-specific way that doesn't involve equality engine
       continue;
     }
+    Trace("theory-check") << "Theory::assert " << fact << " " << d_id
+                          << std::endl;
     // Theories that don't have an equality engine should always return true
     // for preNotifyFact
     Assert(d_equalityEngine != nullptr);
@@ -564,11 +508,15 @@ void Theory::check(Effort level)
     {
       d_equalityEngine->assertPredicate(atom, polarity, fact);
     }
+    Trace("theory-check") << "Theory::notifyFact " << fact << " " << d_id
+                          << std::endl;
     // notify the theory of the new fact, which is not internal
     notifyFact(atom, polarity, fact, false);
   }
+  Trace("theory-check") << "Theory::postCheck " << d_id << std::endl;
   // post-check at level
   postCheck(level);
+  Trace("theory-check") << "Theory::finish check " << d_id << std::endl;
 }
 
 bool Theory::preCheck(Effort level) { return false; }
@@ -596,6 +544,11 @@ void Theory::addSharedTerm(TNode n)
   d_sharedTerms.push_back(n);
   // now call theory-specific method notifySharedTerm
   notifySharedTerm(n);
+  // if we have an equality engine, add the trigger term
+  if (d_equalityEngine != nullptr)
+  {
+    d_equalityEngine->addTriggerTerm(n, d_id);
+  }
 }
 
 eq::EqualityEngine* Theory::getEqualityEngine()
index bc6c995a74000902ae707162b564ca9bc6494744..6f6c863dfc93477addb88764c4e5837b9f56d922 100644 (file)
@@ -179,15 +179,6 @@ class Theory {
    */
   context::CDList<TNode> d_sharedTerms;
 
-  //---------------------------------- private collect model info
-  /**
-   * Helper function for computeRelevantTerms
-   */
-  void collectTerms(TNode n,
-                    const std::set<Kind>& irrKinds,
-                    std::set<Node>& termSet) const;
-  //---------------------------------- end private collect model info
-
   /**
    * Construct a Theory.
    *
@@ -491,6 +482,16 @@ class Theory {
   /** Get the decision manager associated to this theory. */
   DecisionManager* getDecisionManager() { return d_decManager; }
 
+  /**
+   * @return The theory state associated with this theory.
+   */
+  TheoryState* getTheoryState() { return d_theoryState; }
+
+  /**
+   * @return The theory inference manager associated with this theory.
+   */
+  TheoryInferenceManager* getInferenceManager() { return d_inferManager; }
+
   /**
    * Expand definitions in the term node. This returns a term that is
    * equivalent to node. It wraps this term in a TrustNode of kind
@@ -600,11 +601,8 @@ class Theory {
    *
    * Theories that use this check method must use an official theory
    * state object (d_theoryState).
-   *
-   * TODO (project #39): this method should be non-virtual, once all theories
-   * conform to the new standard
    */
-  virtual void check(Effort level = EFFORT_FULL);
+  void check(Effort level = EFFORT_FULL);
   /**
    * Pre-check, called before the fact queue of the theory is processed.
    * If this method returns false, then the theory will process its fact
@@ -662,28 +660,9 @@ class Theory {
    * then calls computeModelValues.
    *
    * TODO (project #39): this method should be non-virtual, once all theories
-   * conform to the new standard
-   */
-  virtual bool collectModelInfo(TheoryModel* m);
-  /**
-   * Scans the current set of assertions and shared terms top-down
-   * until a theory-leaf is reached, and adds all terms found to
-   * termSet.  This is used by collectModelInfo to delimit the set of
-   * terms that should be used when constructing a model.
-   *
-   * @param irrKinds The kinds of terms that appear in assertions that should *not*
-   * be included in termSet. Note that the kinds EQUAL and NOT are always
-   * treated as irrelevant kinds.
-   *
-   * @param includeShared Whether to include shared terms in termSet. Notice that
-   * shared terms are not influenced by irrKinds.
-   *
-   * TODO (project #39): this method will be deleted. The version in
-   * model manager will be used.
+   * conform to the new standard, delete, move to model manager distributed.
    */
-  void computeAssertedTerms(std::set<Node>& termSet,
-                            const std::set<Kind>& irrKinds,
-                            bool includeShared = true) const;
+  virtual bool collectModelInfo(TheoryModel* m, const std::set<Node>& termSet);
   /**
    * Compute terms that are not necessarily part of the assertions or
    * shared terms that should be considered relevant, add them to termSet.
index 94477d1e8007916453c7b2488d8fde37f1b83742..2d0a805993b5fda83440037c630e0f3ac36b1ba4 100644 (file)
@@ -444,7 +444,7 @@ bool TheoryModel::assertPredicate(TNode a, bool polarity)
 
 /** assert equality engine */
 bool TheoryModel::assertEqualityEngine(const eq::EqualityEngine* ee,
-                                       set<Node>* termSet)
+                                       const std::set<Node>* termSet)
 {
   Assert(d_equalityEngine->consistent());
   eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( ee );
index 00b2107bd8080006b89b01a13c576007e40acda6..b1401c07488b2a2486e2c0ade0a042c2b6696fdf 100644 (file)
@@ -110,7 +110,7 @@ public:
    * is consistent after asserting the equality engine to this model.
    */
   bool assertEqualityEngine(const eq::EqualityEngine* ee,
-                            std::set<Node>* termSet = NULL);
+                            const std::set<Node>* termSet = NULL);
   /** assert skeleton
    *
    * This method gives a "skeleton" for the model value of the equivalence
index 39849da3af4e1d0ab89b0666c9a6e5601f795b8f..8a99946e59ccf357149d572c274233bc874d7b28 100644 (file)
@@ -151,7 +151,6 @@ class FakeTheory : public Theory
 
   void preRegisterTerm(TNode) override { Unimplemented(); }
   void registerTerm(TNode) { Unimplemented(); }
-  void check(Theory::Effort) override { Unimplemented(); }
   void propagate(Theory::Effort) override { Unimplemented(); }
   TrustNode explain(TNode) override
   {