&d_pfContext,
TConvPolicy::FIXPOINT,
TConvCachePolicy::NEVER,
- "TheoryPreprocessor::TConvProofGenerator")
+ "TheoryPreprocessor::preprocess_rewrite",
+ &d_iqtc)
: nullptr),
+ d_tspg(nullptr),
+ d_tpgRew(pnm ? new TConvProofGenerator(pnm,
+ &d_pfContext,
+ TConvPolicy::FIXPOINT,
+ TConvCachePolicy::NEVER,
+ "TheoryPreprocessor::rewrite")
+ : nullptr),
+ d_tspgNoPp(nullptr),
d_lp(pnm ? new LazyCDProof(pnm,
nullptr,
&d_pfContext,
// push the proof context, since proof steps may be cleared on calls to
// clearCache() below.
d_pfContext.push();
+ // Make the main term conversion sequence generator, which tracks up to
+ // three conversions made in succession:
+ // (1) theory preprocessing+rewriting
+ // (2) term formula removal
+ // (3) rewriting
+ // Steps (1) and (3) use a common term conversion generator.
+ std::vector<ProofGenerator*> ts;
+ ts.push_back(d_tpg.get());
+ ts.push_back(d_tfr.getTConvProofGenerator());
+ ts.push_back(d_tpg.get());
+ d_tspg.reset(new TConvSeqProofGenerator(
+ pnm, ts, &d_pfContext, "TheoryPreprocessor::sequence"));
+ // Make the "no preprocess" term conversion sequence generator, which
+ // applies only steps (2) and (3), where notice (3) must use the
+ // "pure rewrite" term conversion (d_tpgRew).
+ std::vector<ProofGenerator*> tsNoPp;
+ tsNoPp.push_back(d_tfr.getTConvProofGenerator());
+ tsNoPp.push_back(d_tpgRew.get());
+ d_tspgNoPp.reset(new TConvSeqProofGenerator(
+ pnm, tsNoPp, &d_pfContext, "TheoryPreprocessor::sequence_no_pp"));
}
}
void TheoryPreprocessor::clearCache()
{
+ Trace("tpp-proof-debug") << "TheoryPreprocessor::clearCache" << std::endl;
d_ppCache.clear();
- // clear proofs from d_tpg and d_lp using internal push/pop context
+ // clear proofs from d_tpg, d_tspg and d_lp using internal push/pop context
if (isProofEnabled())
{
d_pfContext.pop();
// In this method, all rewriting steps of node are stored in d_tpg.
Trace("tpp-proof-debug") << "TheoryPreprocessor::preprocess: start " << node
+ << ", doTheoryPreprocess=" << doTheoryPreprocess
<< std::endl;
// Run theory preprocessing, maybe
Node ppNode = node;
Trace("te-tform-rm") << "Remove term formulas from " << ppNode << std::endl;
TrustNode ttfr = d_tfr.run(ppNode, newLemmas, newSkolems, false);
Trace("te-tform-rm") << "..done " << ttfr.getNode() << std::endl;
- Node retNode = ttfr.getNode();
- if (isProofEnabled())
- {
- // if we rewrote
- if (retNode != ppNode)
- {
- // should always have provided a proof generator, or else term formula
- // removal and this class do not agree on whether proofs are enabled.
- Assert(ttfr.getGenerator() != nullptr);
- Trace("tpp-proof-debug")
- << "TheoryPreprocessor: addRewriteStep (term formula removal) "
- << ppNode << " -> " << retNode << std::endl;
- // store as a rewrite in d_tpg
- d_tpg->addRewriteStep(ppNode, retNode, ttfr.getGenerator());
- }
- }
+ Node rtfNode = ttfr.getNode();
+ Trace("tpp-proof-debug")
+ << "TheoryPreprocessor::preprocess: rtf returned node " << rtfNode
+ << std::endl;
if (Debug.isOn("lemma-ites"))
{
}
// Rewrite the main node, we rewrite and store the proof step, if necessary,
// in d_tpg, which maintains the fact that d_tpg can prove the rewrite.
- Trace("tpp-proof-debug")
- << "TheoryPreprocessor::preprocess: rewrite returned node " << retNode
- << std::endl;
- retNode = rewriteWithProof(retNode);
+ Node retNode = rewriteWithProof(rtfNode);
Trace("tpp-proof-debug")
<< "TheoryPreprocessor::preprocess: after rewriting is " << retNode
<< std::endl;
+ if (node == retNode)
+ {
+ // no change
+ Assert(newLemmas.empty());
+ return TrustNode::null();
+ }
+
+ // Now, sequence the conversion steps if proofs are enabled.
+ TrustNode tret;
+ if (isProofEnabled())
+ {
+ std::vector<Node> cterms;
+ cterms.push_back(node);
+ if (doTheoryPreprocess)
+ {
+ cterms.push_back(ppNode);
+ }
+ cterms.push_back(rtfNode);
+ cterms.push_back(retNode);
+ // We have that:
+ // node -> ppNode via preprocessing + rewriting (if doTheoryPreprocess)
+ // ppNode -> rtfNode via term formula removal
+ // rtfNode -> retNode via rewriting
+ if (!doTheoryPreprocess)
+ {
+ // If preprocessing is not performed, we cannot use the main sequence
+ // generator, instead we use d_tspgNoPp.
+ // We register the top-level rewrite in the pure rewrite term converter.
+ d_tpgRew->addRewriteStep(
+ rtfNode, retNode, PfRule::REWRITE, {}, {rtfNode});
+ // Now get the trust node from the sequence generator
+ tret = d_tspgNoPp->mkTrustRewriteSequence(cterms);
+ }
+ else
+ {
+ // we wil use the sequence generator
+ tret = d_tspg->mkTrustRewriteSequence(cterms);
+ }
+ tret.debugCheckClosed("tpp-proof-debug", "TheoryPreprocessor::lemma_ret");
+ }
+ else
+ {
+ tret = TrustNode::mkTrustRewrite(node, retNode, nullptr);
+ }
// now, rewrite the lemmas
Trace("tpp-proof-debug") << "TheoryPreprocessor::preprocess: process lemmas"
newLemmas[i].debugCheckClosed("tpp-proof-debug",
"TheoryPreprocessor::lemma_new");
}
- if (node == retNode)
- {
- // no change
- return TrustNode::null();
- }
Trace("tpp-proof-debug") << "Preprocessed: " << node << " " << retNode
<< std::endl;
- TrustNode tret = TrustNode::mkTrustRewrite(node, retNode, d_tpg.get());
- tret.debugCheckClosed("tpp-proof-debug", "TheoryPreprocessor::lemma_ret");
return tret;
}
preprocess_stack_element& stackHead = toVisit.back();
TNode current = stackHead.node;
- Debug("theory::internal")
+ Trace("theory::preprocess-debug")
<< "TheoryPreprocessor::theoryPreprocess(" << assertion
<< "): processing " << current << endl;
{
result = rewriteWithProof(result);
}
- Debug("theory::internal")
+ Trace("theory::preprocess-debug")
<< "TheoryPreprocessor::theoryPreprocess(" << assertion
<< "): setting " << current << " -> " << result << endl;
d_ppCache[current] = result;
else
{
// No children, so we're done
- Debug("substitution::internal")
+ Trace("theory::preprocess-debug")
<< "SubstitutionMap::internalSubstitute(" << assertion
<< "): setting " << current << " -> " << current << endl;
d_ppCache[current] = current;
Trace("tpp-proof-debug")
<< "TheoryPreprocessor: addRewriteStep (rewriting) " << term << " -> "
<< termr << std::endl;
+ // always use term context hash 0 (default)
d_tpg->addRewriteStep(term, termr, PfRule::REWRITE, {}, {term});
}
}
<< termr << std::endl;
trn.debugCheckClosed("tpp-proof-debug",
"TheoryPreprocessor::preprocessWithProof");
+ // always use term context hash 0 (default)
d_tpg->addRewriteStep(term, termr, trn.getGenerator());
}
else
#include "expr/lazy_proof.h"
#include "expr/node.h"
+#include "expr/tconv_seq_proof_generator.h"
#include "expr/term_conversion_proof_generator.h"
#include "theory/trust_node.h"
RemoveTermFormulas& d_tfr;
/** The context for the proof generator below */
context::Context d_pfContext;
- /** A term conversion proof generator */
+ /** The term context, which computes hash values for term contexts. */
+ InQuantTermContext d_iqtc;
+ /**
+ * A term conversion proof generator storing preprocessing and rewriting
+ * steps.
+ */
std::unique_ptr<TConvProofGenerator> d_tpg;
+ /**
+ * A term conversion sequence generator, which applies theory preprocessing,
+ * term formula removal, and rewriting in sequence.
+ */
+ std::unique_ptr<TConvSeqProofGenerator> d_tspg;
+ /**
+ * A term conversion proof generator storing rewriting steps, which is used
+ * for calls to preprocess when doTheoryPreprocess is false. We store
+ * (top-level) rewrite steps only. Notice this is intentionally separate
+ * from d_tpg, which interleaves both preprocessing and rewriting.
+ */
+ std::unique_ptr<TConvProofGenerator> d_tpgRew;
+ /**
+ * A term conversion sequence generator, which applies term formula removal
+ * and rewriting in sequence. This is used for reconstruct proofs of
+ * calls to preprocess where doTheoryPreprocess is false.
+ */
+ std::unique_ptr<TConvSeqProofGenerator> d_tspgNoPp;
/** A lazy proof, for additional lemmas. */
std::unique_ptr<LazyCDProof> d_lp;
/** Helper for theoryPreprocess */