summaryrefslogtreecommitdiff
path: root/src/expr/proof.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/expr/proof.h')
-rw-r--r--src/expr/proof.h132
1 files changed, 105 insertions, 27 deletions
diff --git a/src/expr/proof.h b/src/expr/proof.h
index c3b9698ca..94a3b6ab0 100644
--- a/src/expr/proof.h
+++ b/src/expr/proof.h
@@ -24,9 +24,23 @@
#include "expr/node.h"
#include "expr/proof_node.h"
#include "expr/proof_node_manager.h"
+#include "expr/proof_step_buffer.h"
namespace CVC4 {
+/** An overwrite policy for CDProof below */
+enum class CDPOverwrite : uint32_t
+{
+ // always overwrite an existing step.
+ ALWAYS,
+ // overwrite ASSUME with non-ASSUME steps.
+ ASSUME_ONLY,
+ // never overwrite an existing step.
+ NEVER,
+};
+/** Writes a overwrite policy name to a stream. */
+std::ostream& operator<<(std::ostream& out, CDPOverwrite opol);
+
/**
* A (context-dependent) proof.
*
@@ -76,10 +90,11 @@ namespace CVC4 {
* Notice that the proof of A by ID_A was not overwritten by ASSUME in the
* addStep call above.
*
- * The policy for overwriting proof steps gives ASSUME a special status. An
- * ASSUME step can be seen as a step whose justification has not yet been
- * provided. Thus, it is always overwritten. Other proof rules are never
- * overwritten, unless the argument forceOverwrite is true.
+ * The default policy for overwriting proof steps (CDPOverwrite::ASSUME_ONLY)
+ * gives ASSUME a special status. An ASSUME step can be seen as a step whose
+ * justification has not yet been provided. Thus, it is always overwritten.
+ * Other proof rules are never overwritten, unless the argument opolicy is
+ * CDPOverwrite::ALWAYS.
*
* As an another example, say that we call:
* - addStep( B, ID_B1 {}, {} )
@@ -87,7 +102,7 @@ namespace CVC4 {
* At this point, getProof( A ) returns:
* ID_A1( ID_B1(), ASSUME(C) )
* Now, assume an additional call is made to addProof, where notice
- * forceOverwrite is false by default:
+ * the overwrite policy is CDPOverwrite::ASSUME_ONLY by default:
* - addProof( D, ID_D( ID_A2( ID_B2(), ID_C() ) ) )
* where assume ID_B2() and ID_C() prove B and C respectively. This call is
* equivalent to calling:
@@ -114,22 +129,39 @@ namespace CVC4 {
* proof step for each Node. Thus, the ProofNode objects returned by this
* class share proofs for common subformulas, as guaranteed by the fact that
* Node objects have perfect sharing.
+ *
+ * Notice that this class is agnostic to symmetry of equality. In other
+ * words, adding a step that concludes (= x y) is effectively the same as
+ * providing a step that concludes (= y x) from the point of view of a user
+ * of this class. This is accomplished by adding SYMM steps on demand when
+ * a formula is looked up. For example say we call:
+ * - addStep( (= x y), ID_1 {}, {} )
+ * - addStep( P, ID_2, {(= y x)}, {} )
+ * Afterwards, getProof( P ) returns:
+ * ID_2( SYMM( ID_1() ) )
+ * where notice SYMM was added so that (= y x) is a premise of the application
+ * of ID_2. More generally, CDProof::isSame(F,G) returns true if F and G are
+ * essentially the same formula according to this class.
*/
class CDProof
{
- typedef context::CDHashMap<Node, std::shared_ptr<ProofNode>, NodeHashFunction>
- NodeProofNodeMap;
-
public:
CDProof(ProofNodeManager* pnm, context::Context* c = nullptr);
- ~CDProof();
+ virtual ~CDProof();
/**
- * Get proof for fact, or nullptr if it does not exist. Notice that this call
- * does *not* clone the ProofNode object. Hence, the returned proof may
- * be updated by further calls to this class. The caller should call
- * ProofNode::clone if they want to own it.
+ * Make proof for fact.
+ *
+ * This method always returns a non-null ProofNode. It may generate new
+ * steps so that a ProofNode can be constructed for fact. In particular,
+ * if no step exists for fact, then we may construct and return ASSUME(fact).
+ * If fact is of the form (= t s), no step exists for fact, but a proof
+ * P for (= s t) exists, then this method returns SYMM(P).
+ *
+ * Notice that this call does *not* clone the ProofNode object. Hence, the
+ * returned proof may be updated by further calls to this class. The caller
+ * should call ProofNode::clone if they want to own it.
*/
- std::shared_ptr<ProofNode> getProof(Node fact) const;
+ virtual std::shared_ptr<ProofNode> mkProof(Node fact);
/** Add step
*
* @param expected The intended conclusion of this proof step. This must be
@@ -141,8 +173,8 @@ class CDProof
* @param args The arguments of the proof step.
* @param ensureChildren Whether we wish to ensure steps have been added
* for all nodes in children
- * @param forceOverwrite Whether we wish to overwrite if a step for expected
- * was already provided (via a previous call to addStep)
+ * @param opolicy Policy for whether to overwrite if a step for
+ * expected was already provided (via a previous call to addStep)
* @return The true if indeed the proof step proves expected, or
* false otherwise. The latter can happen if the proof has a different (or
* invalid) conclusion, or if one of the children does not have a proof and
@@ -156,39 +188,85 @@ class CDProof
* of order.
*
* This method only overwrites proofs for facts that were added as
- * steps with id ASSUME when forceOverwrite is false, and otherwise always
- * overwrites an existing step if one was provided when forceOverwrite is
- * true.
+ * steps with id ASSUME when opolicy is CDPOverwrite::ASSUME_ONLY, and always
+ * (resp. never) overwrites an existing step if one was provided when opolicy
+ * is CDPOverwrite::ALWAYS (resp. CDPOverwrite::NEVER).
*/
bool addStep(Node expected,
PfRule id,
const std::vector<Node>& children,
const std::vector<Node>& args,
bool ensureChildren = false,
- bool forceOverwrite = false);
+ CDPOverwrite opolicy = CDPOverwrite::ASSUME_ONLY);
+ /** Version with ProofStep */
+ bool addStep(Node expected,
+ const ProofStep& step,
+ bool ensureChildren = false,
+ CDPOverwrite opolicy = CDPOverwrite::ASSUME_ONLY);
+ /** Version with ProofStepBuffer */
+ bool addSteps(const ProofStepBuffer& psb,
+ bool ensureChildren = false,
+ CDPOverwrite opolicy = CDPOverwrite::ASSUME_ONLY);
/** Add proof
*
* @param pn The proof of the given fact.
- * @param forceOverwrite Whether we wish to force overwriting if a step was
- * already provided, for each node in the proof.
+ * @param opolicy Policy for whether to force overwriting if a step
+ * was already provided. This is used for each node in the proof if doCopy
+ * is true.
+ * @param doCopy Whether we make a deep copy of the pn.
* @return true if all steps were successfully added to this class. If it
* returns true, it registers a copy of all of the subnodes of pn to this
* proof class.
*
- * This method is implemented by calling addStep above for all subnodes
- * of pn, traversed as a dag. This means that fresh ProofNode objects may be
- * generated by this call, and further modifications to pn does not impact the
- * internal data of this class.
+ * If doCopy is true, this method is implemented by calling addStep above for
+ * all subnodes of pn, traversed as a dag. This means that fresh ProofNode
+ * objects may be generated by this call, and further modifications to pn do
+ * not impact the internal data of this class.
*/
- bool addProof(ProofNode* pn, bool forceOverwrite = false);
+ bool addProof(std::shared_ptr<ProofNode> pn,
+ CDPOverwrite opolicy = CDPOverwrite::ASSUME_ONLY,
+ bool doCopy = false);
+ /** Return true if fact already has a proof step */
+ bool hasStep(Node fact);
+ /** Get the proof manager for this proof */
+ ProofNodeManager* getManager() const;
+ /**
+ * Is same? Returns true if f and g are the same formula, or if they are
+ * symmetric equalities. If two nodes f and g are the same, then a proof for
+ * f suffices as a proof for g according to this class.
+ */
+ static bool isSame(TNode f, TNode g);
+ /**
+ * Get symmetric fact (a g such that isSame returns true for isSame(f,g)), or
+ * null if none exist.
+ */
+ static Node getSymmFact(TNode f);
protected:
+ typedef context::CDHashMap<Node, std::shared_ptr<ProofNode>, NodeHashFunction>
+ NodeProofNodeMap;
/** The proof manager, used for allocating new ProofNode objects */
ProofNodeManager* d_manager;
/** A dummy context used by this class if none is provided */
context::Context d_context;
/** The nodes of the proof */
NodeProofNodeMap d_nodes;
+ /** Get proof for fact, or nullptr if it does not exist. */
+ std::shared_ptr<ProofNode> getProof(Node fact) const;
+ /** Ensure fact sym */
+ std::shared_ptr<ProofNode> getProofSymm(Node fact);
+ /**
+ * Returns true if we should overwrite proof node pn with a step having id
+ * newId, based on policy opol.
+ */
+ static bool shouldOverwrite(ProofNode* pn, PfRule newId, CDPOverwrite opol);
+ /** Returns true if pn is an assumption. */
+ static bool isAssumption(ProofNode* pn);
+ /**
+ * Notify new proof, called when a new proof of expected is provided. This is
+ * used internally to connect proofs of symmetric facts, when necessary.
+ */
+ void notifyNewProof(Node expected);
};
} // namespace CVC4
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback