{
if (!doCopy)
{
+ // If we are automatically managing symmetry, we strip off SYMM steps.
+ // This avoids cyclic proofs in cases where P and (SYMM P) are added as
+ // proofs to the same CDProof.
+ if (d_autoSymm)
+ {
+ std::vector<std::shared_ptr<ProofNode>> processed;
+ while (pn->getRule() == PfRule::SYMM)
+ {
+ pn = pn->getChildren()[0];
+ if (std::find(processed.begin(), processed.end(), pn)
+ != processed.end())
+ {
+ Unreachable() << "Cyclic proof encountered when cancelling symmetry "
+ "steps during addProof";
+ }
+ processed.push_back(pn);
+ }
+ }
// If we aren't doing a deep copy, we either store pn or link its top
// node into the existing pointer
Node curFact = pn->getResult();
ProofNode* ProofNodeManager::cancelDoubleSymm(ProofNode* pn)
{
+ // processed is almost always size <= 1
+ std::vector<ProofNode*> processed;
while (pn->getRule() == PfRule::SYMM)
{
std::shared_ptr<ProofNode> pnc = pn->getChildren()[0];
if (pnc->getRule() == PfRule::SYMM)
{
pn = pnc->getChildren()[0].get();
+ if (std::find(processed.begin(), processed.end(), pn) != processed.end())
+ {
+ Unreachable()
+ << "Cyclic proof encountered when cancelling double symmetry";
+ }
+ processed.push_back(pn);
}
else
{