Add new interfaces to term formula removal and theory preprocess (#5717)
[cvc5.git] / src / theory / theory_inference_manager.h
index 914c87d190d243e29312db856dee8ea34855cb7e..124b88e3ef12b9006944125d66bc5f4f4768d9a5 100644 (file)
@@ -2,10 +2,10 @@
 /*! \file theory_inference_manager.h
  ** \verbatim
  ** Top contributors (to current version):
- **   Andrew Reynolds
+ **   Andrew Reynolds, Mathias Preiner, Gereon Kremer
  ** 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.
+ ** 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
  **
 #ifndef CVC4__THEORY__THEORY_INFERENCE_MANAGER_H
 #define CVC4__THEORY__THEORY_INFERENCE_MANAGER_H
 
+#include <memory>
+
 #include "context/cdhashset.h"
 #include "expr/node.h"
 #include "theory/output_channel.h"
 #include "theory/theory_state.h"
 #include "theory/trust_node.h"
+#include "theory/uf/proof_equality_engine.h"
 
 namespace CVC4 {
 
@@ -51,6 +54,12 @@ class EqualityEngine;
  * (with isInternal = true) whenever we assert internal facts using
  * assertFactInernal below, mirroring what is done for facts from the fact
  * queue (where isInternal = false).
+ *
+ * (3) The proof equality engine is used whenever proofs are enabled (when
+ * the proof node manager provided to this class is non-null). Notice this
+ * class automatically will construct a proof equality engine during
+ * setEqualityEngine, and use it for handling variants of assertInternalFact
+ * below that involve proofs.
  */
 class TheoryInferenceManager
 {
@@ -62,13 +71,35 @@ class TheoryInferenceManager
    */
   TheoryInferenceManager(Theory& t, TheoryState& state, ProofNodeManager* pnm);
   virtual ~TheoryInferenceManager() {}
-  //--------------------------------------- initialization
   /**
    * Set equality engine, ee is a pointer to the official equality engine
    * of theory.
    */
   void setEqualityEngine(eq::EqualityEngine* ee);
-  //--------------------------------------- end initialization
+  /**
+   * Are proofs enabled in this inference manager? Returns true if the proof
+   * node manager pnm provided to the constructor of this class was non-null.
+   */
+  bool isProofEnabled() const;
+  /**
+   * Reset, which resets counters regarding the number of added lemmas and
+   * internal facts. This method should be manually called by the theory at
+   * the appropriate time for the purpose of tracking the usage of this
+   * inference manager.
+   *
+   * For example, some theories implement an internal checking loop that
+   * repeats while new facts are added. The theory should call reset at the
+   * beginning of this loop and repeat its strategy while hasAddedFact is true.
+   */
+  void reset();
+  /**
+   * Returns true if we are in conflict, or if we have sent a lemma or fact
+   * since the last call to reset.
+   */
+  bool hasSent() const;
+  /** Get the underlying proof equality engine */
+  eq::ProofEqEngine* getProofEqEngine();
+  //--------------------------------------- propagations
   /**
    * T-propagate literal lit, possibly encountered by equality engine,
    * returns false if we are in conflict.
@@ -85,6 +116,7 @@ class TheoryInferenceManager
    * Theory, if it exists.
    */
   virtual TrustNode explainLit(TNode lit);
+  //--------------------------------------- conflicts
   /**
    * Raise conflict, called when constants a and b merge. Sends the conflict
    * on the output channel corresponding to the equality engine's explanation
@@ -102,9 +134,143 @@ class TheoryInferenceManager
   void conflict(TNode conf);
   /**
    * Raise trusted conflict tconf (of any form) where a proof generator has
-   * been provided in a custom way.
+   * been provided (as part of the trust node) in a custom way.
    */
   void trustedConflict(TrustNode tconf);
+  /**
+   * Explain and send conflict from contradictory facts. This method is called
+   * when the proof rule id with premises exp and arguments args concludes
+   * false. This method sends a trusted conflict corresponding to the official
+   * equality engine's explanation of literals in exp, with the proof equality
+   * engine as the proof generator (if it exists).
+   */
+  void conflictExp(PfRule id,
+                   const std::vector<Node>& exp,
+                   const std::vector<Node>& args);
+  /**
+   * Make the trust node corresponding to the conflict of the above form. It is
+   * the responsibility of the caller to subsequently call trustedConflict with
+   * the returned trust node.
+   */
+  TrustNode mkConflictExp(PfRule id,
+                          const std::vector<Node>& exp,
+                          const std::vector<Node>& args);
+  /**
+   * Explain and send conflict from contradictory facts. This method is called
+   * when proof generator pg has a proof of false from free assumptions exp.
+   * This method sends a trusted conflict corresponding to the official
+   * equality engine's explanation of literals in exp, with the proof equality
+   * engine as the proof generator (if it exists), where pg provides the
+   * final step(s) of this proof during this call.
+   */
+  void conflictExp(const std::vector<Node>& exp, ProofGenerator* pg);
+  /**
+   * Make the trust node corresponding to the conflict of the above form. It is
+   * the responsibility of the caller to subsequently call trustedConflict with
+   * the returned trust node.
+   */
+  TrustNode mkConflictExp(const std::vector<Node>& exp, ProofGenerator* pg);
+  //--------------------------------------- lemmas
+  /**
+   * Send (trusted) lemma lem with property p on the output channel.
+   *
+   * @param tlem The trust node containing the lemma and its proof generator.
+   * @param p The property of the lemma
+   * @param doCache If true, we send the lemma only if it has not already been
+   * cached (see cacheLemma), and add it to the cache during this call.
+   * @return true if the lemma was sent on the output channel.
+   */
+  bool trustedLemma(const TrustNode& tlem,
+                    LemmaProperty p = LemmaProperty::NONE,
+                    bool doCache = true);
+  /**
+   * Send lemma lem with property p on the output channel. Same as above, with
+   * a node instead of a trust node.
+   */
+  bool lemma(TNode lem,
+             LemmaProperty p = LemmaProperty::NONE,
+             bool doCache = true);
+  /**
+   * Explained lemma. This should be called when
+   *   ( exp => conc )
+   * is a valid theory lemma. This method adds a lemma where part of exp
+   * is replaced by its explanation according to the official equality engine
+   * of the theory.
+   *
+   * In particular, this method adds a lemma on the output channel of the form
+   *   ( ^_{e in exp \ noExplain} EXPLAIN(e) ^ noExplain ) => conc
+   * where EXPLAIN(e) returns the explanation of literal e according to the
+   * official equality engine of the theory. Note that noExplain is the *subset*
+   * of exp that should not be explained.
+   *
+   * @param conc The conclusion of the lemma
+   * @param id The proof rule concluding conc
+   * @param exp The set of (all) literals that imply conc
+   * @param noExplain The subset of exp that should not be explained by the
+   * equality engine
+   * @param args The arguments to the proof step concluding conc
+   * @param p The property of the lemma
+   * @param doCache Whether to check and add the lemma to the cache
+   * @return true if the lemma was sent on the output channel.
+   */
+  bool lemmaExp(Node conc,
+                PfRule id,
+                const std::vector<Node>& exp,
+                const std::vector<Node>& noExplain,
+                const std::vector<Node>& args,
+                LemmaProperty p = LemmaProperty::NONE,
+                bool doCache = true);
+  /**
+   * Make the trust node for the above method. It is responsibility of the
+   * caller to subsequently call trustedLemma with the returned trust node.
+   */
+  TrustNode mkLemmaExp(Node conc,
+                       PfRule id,
+                       const std::vector<Node>& exp,
+                       const std::vector<Node>& noExplain,
+                       const std::vector<Node>& args);
+  /**
+   * Same as above, but where pg can provide a proof of conc from free
+   * assumptions in exp. This sends a trusted lemma on the output channel where
+   * the proof equality engine is the proof generator. The generator pg
+   * is asked to provide the final step(s) of this proof during this call.
+   *
+   * @param conc The conclusion of the lemma
+   * @param exp The set of (all) literals that imply conc
+   * @param noExplain The subset of exp that should not be explained by the
+   * equality engine
+   * @param pg If non-null, the proof generator who can provide a proof of conc.
+   * @param p The property of the lemma
+   * @param doCache Whether to check and add the lemma to the cache
+   * @return true if the lemma was sent on the output channel.
+   */
+  bool lemmaExp(Node conc,
+                const std::vector<Node>& exp,
+                const std::vector<Node>& noExplain,
+                ProofGenerator* pg = nullptr,
+                LemmaProperty p = LemmaProperty::NONE,
+                bool doCache = true);
+  /**
+   * Make the trust node for the above method. It is responsibility of the
+   * caller to subsequently call trustedLemma with the returned trust node.
+   */
+  TrustNode mkLemmaExp(Node conc,
+                       const std::vector<Node>& exp,
+                       const std::vector<Node>& noExplain,
+                       ProofGenerator* pg = nullptr);
+  /**
+   * Has this inference manager cached and sent the given lemma (in this user
+   * context)? This method can be overridden by the particular manager. If not,
+   * this returns true if lem is in the cache d_lemmasSent maintained by this
+   * class. Notice that the default cache in this base class is not dependent
+   * on the lemma property.
+   */
+  virtual bool hasCachedLemma(TNode lem, LemmaProperty p);
+  /** The number of lemmas we have sent since the last call to reset */
+  uint32_t numSentLemmas() const;
+  /** Have we added a lemma since the last call to reset? */
+  bool hasSentLemma() const;
+  //--------------------------------------- internal facts
   /**
    * Assert internal fact. This is recommended method for asserting "internal"
    * facts into the equality engine of the theory. In particular, this method
@@ -112,10 +278,86 @@ class TheoryInferenceManager
    * output channel as a propagation or lemma. This method ensures that the
    * Theory's preNotifyFact and notifyFact method have been called with
    * isInternal = true.
+   *
+   * @param atom The atom of the fact to assert
+   * @param pol Its polarity
+   * @param exp Its explanation, i.e. ( exp => (~) atom ) is valid.
+   * @return true if the fact was processed, i.e. it was asserted to the
+   * equality engine or preNotifyFact returned true.
+   */
+  bool assertInternalFact(TNode atom, bool pol, TNode exp);
+  /**
+   * Assert internal fact, with a proof step justification. Notice that if
+   * proofs are not enabled in this inference manager, then this asserts
+   * a fact to the equality engine in the normal way.
+   *
+   * @param atom The atom of the fact to assert
+   * @param pol Its polarity
+   * @param id The proof rule identifier of the proof step
+   * @param exp Its explanation, interpreted as a conjunction
+   * @param args The arguments of the proof step
+   * @return true if the fact was processed, i.e. it was asserted to the
+   * equality engine or preNotifyFact returned true.
+   */
+  bool assertInternalFact(TNode atom,
+                          bool pol,
+                          PfRule id,
+                          const std::vector<Node>& exp,
+                          const std::vector<Node>& args);
+  /**
+   * Assert internal fact, with a proof generator justification. Same as above,
+   * but with a proof generator instead of an explicit step.
+   *
+   * @param atom The atom of the fact to assert
+   * @param pol Its polarity
+   * @param exp Its explanation, interpreted as a conjunction
+   * @param pg The proof generator for this step. If non-null, pg must be able
+   * to provide a proof concluding (~) atom from free asumptions in exp in
+   * the remainder of the current SAT context.
+   * @return true if the fact was processed, i.e. it was asserted to the
+   * equality engine or preNotifyFact returned true.
+   */
+  bool assertInternalFact(TNode atom,
+                          bool pol,
+                          const std::vector<Node>& exp,
+                          ProofGenerator* pg);
+  /** The number of internal facts we have added since the last call to reset */
+  uint32_t numSentFacts() const;
+  /** Have we added a internal fact since the last call to reset? */
+  bool hasSentFact() const;
+  //--------------------------------------- phase requirements
+  /** 
+   * Set that literal n has SAT phase requirement pol, that is, it should be
+   * decided with polarity pol, for details see OutputChannel::requirePhase.
+   */
+  void requirePhase(TNode n, bool pol);
+
+  /**
+   * Forward to OutputChannel::spendResource() to spend resources.
    */
-  void assertInternalFact(TNode atom, bool pol, TNode fact);
+  void spendResource(ResourceManager::Resource r);
+
+  /**
+   * Forward to OutputChannel::safePoint() to spend resources.
+   */
+  void safePoint(ResourceManager::Resource r);
+  /**
+   * Notification from a theory that it realizes it is incomplete at
+   * this context level.
+   */
+  void setIncomplete();
 
  protected:
+  /**
+   * Process internal fact. This is a common helper method for the
+   * assertInternalFact variants above. Returns true if the fact was processed.
+   */
+  bool processInternalFact(TNode atom,
+                           bool pol,
+                           PfRule id,
+                           const std::vector<Node>& exp,
+                           const std::vector<Node>& args,
+                           ProofGenerator* pg);
   /**
    * Explain conflict from constants merging in the equality engine. This
    * method is called by conflictEqConstantMerge. By default, it returns
@@ -123,6 +365,33 @@ class TheoryInferenceManager
    * exists.
    */
   virtual TrustNode explainConflictEqConstantMerge(TNode a, TNode b);
+  /**
+   * Explain formula n (which is possibly a conjunction with no nested
+   * conjunctions), add its explanation to assumptions.
+   */
+  void explain(TNode n, std::vector<TNode>& assumptions);
+  /**
+   * Explain formula n (which is possibly a conjunction with no nested
+   * conjunctions), return the explanation as a conjunction.
+   */
+  Node mkExplain(TNode n);
+  /**
+   * Explain the set of formulas in exp using the official equality engine of
+   * the theory. We ask the equality engine to explain literals in exp
+   * that do not occur in noExplain, and return unchanged those that occur in
+   * noExplain. Note the vector noExplain should be a subset of exp.
+   */
+  Node mkExplainPartial(const std::vector<Node>& exp,
+                        const std::vector<Node>& noExplain);
+  /**
+   * Cache that lemma lem is being sent with property p. Return true if it
+   * did not already exist in the cache maintained by this class. If this
+   * method is not overridden, then we use the d_lemmasSent cache maintained
+   * by this class, which notice is not dependent on lemma property. If
+   * the lemma property should be taken into account, the manager should
+   * override this method to take the lemma property into account as needed.
+   */
+  virtual bool cacheLemma(TNode lem, LemmaProperty p);
   /** The theory object */
   Theory& d_theory;
   /** Reference to the state of theory */
@@ -131,6 +400,8 @@ class TheoryInferenceManager
   OutputChannel& d_out;
   /** Pointer to equality engine of the theory. */
   eq::EqualityEngine* d_ee;
+  /** A proof equality engine */
+  std::unique_ptr<eq::ProofEqEngine> d_pfee;
   /** The proof node manager of the theory */
   ProofNodeManager* d_pnm;
   /**
@@ -140,6 +411,17 @@ class TheoryInferenceManager
    * SAT-context-dependent.
    */
   NodeSet d_keep;
+  /**
+   * A cache of all lemmas sent, which is a user-context-dependent set of
+   * nodes. Notice that this cache does not depedent on lemma property.
+   */
+  NodeSet d_lemmasSent;
+  /** The number of conflicts sent since the last call to reset. */
+  uint32_t d_numConflicts;
+  /** The number of lemmas sent since the last call to reset. */
+  uint32_t d_numCurrentLemmas;
+  /** The number of internal facts added since the last call to reset. */
+  uint32_t d_numCurrentFacts;
 };
 
 }  // namespace theory