for (unsigned i = 0; i < term.getNumChildren(); ++i)
bind(term[i], map, letOrder);
- unsigned newId = ProofLetCount::newId();
- ProofLetCount letCount(newId);
- map[term] = letCount;
- letOrder.push_back(LetOrderElement(term, newId));
+ // Special case: chain operators. If we have and(a,b,c), it will be prineted as and(a,and(b,c)).
+ // The subterm and(b,c) may repeat elsewhere, so we need to bind it, too.
+ Kind k = term.getKind();
+ if (((k == kind::OR) || (k == kind::AND)) && term.getNumChildren() > 2) {
+ Node currentExpression = term[term.getNumChildren() - 1];
+ for (int i = term.getNumChildren() - 2; i >= 0; --i) {
+ NodeBuilder<> builder(k);
+ builder << term[i];
+ builder << currentExpression.toExpr();
+ currentExpression = builder;
+ bind(currentExpression.toExpr(), map, letOrder);
+ }
+ } else {
+ unsigned newId = ProofLetCount::newId();
+ ProofLetCount letCount(newId);
+ map[term] = letCount;
+ letOrder.push_back(LetOrderElement(term, newId));
+ }
}
void ProofManager::printGlobalLetMap(std::set<Node>& atoms,
// TODO: give each theory a chance to add atoms. For now, just query BV directly...
const std::set<Node>* additionalAtoms = ProofManager::getBitVectorProof()->getAtomsInBitblastingProof();
for (atom = additionalAtoms->begin(); atom != additionalAtoms->end(); ++atom) {
- Debug("gk::temp") << "Binding additional atom: " << *atom << std::endl;
bind(atom->toExpr(), letMap, letOrder);
}
#include "base/cvc4_assert.h"
#include "context/context.h"
#include "options/bv_options.h"
+#include "options/proof_options.h"
#include "proof/arith_proof.h"
#include "proof/array_proof.h"
#include "proof/bitvector_proof.h"
if (it != map.end()) {
unsigned id = it->second.id;
unsigned count = it->second.count;
+
if (count > LET_COUNT) {
os << "let" << id;
return;
switch(k) {
case kind::OR:
case kind::AND:
+ if (options::lfscLetification() && term.getNumChildren() > 2) {
+ // If letification is on, the entire term is probably a let expression.
+ // However, we need to transform it from (and a b c) into (and a (and b c)) form first.
+ Node currentExpression = term[term.getNumChildren() - 1];
+ for (int i = term.getNumChildren() - 2; i >= 0; --i) {
+ NodeBuilder<> builder(k);
+ builder << term[i];
+ builder << currentExpression.toExpr();
+ currentExpression = builder;
+ }
+
+ // The let map should already have the current expression.
+ ProofLetMap::const_iterator it = map.find(term);
+ if (it != map.end()) {
+ unsigned id = it->second.id;
+ unsigned count = it->second.count;
+
+ if (count > LET_COUNT) {
+ os << "let" << id;
+ break;
+ }
+ }
+ }
+
+ // If letification is off or there were 2 children, same treatment as the other cases.
+ // (No break is intentional).
case kind::XOR:
case kind::IFF:
case kind::IMPLIES: