std::map<size_t, uint64_t> proofLet;
std::map<size_t, uint64_t> firstScopeLet;
std::unordered_map<const ProofNode*, bool> cfaMap;
+ std::vector<size_t> ancestorHashs;
DotPrinter::printInternal(out,
pn,
proofLet,
firstScopeLet,
cfaMap,
+ ancestorHashs,
ProofNodeClusterType::NOT_DEFINED);
if (options::printDotClusters())
std::map<size_t, uint64_t>& pfLetClosed,
std::map<size_t, uint64_t>& pfLetOpen,
std::unordered_map<const ProofNode*, bool>& cfaMap,
+ std::vector<size_t>& ancestorHashs,
ProofNodeClusterType parentType)
{
uint64_t currentRuleID = d_ruleID;
{
ProofNodeHashFunction hasher;
size_t currentHash = hasher(pn);
- auto openProofIt = pfLetOpen.find(currentHash);
- if (openProofIt != pfLetOpen.end())
- {
- return openProofIt->second;
- }
+ std::vector<size_t>::iterator oldEnd = ancestorHashs.end();
+ // Search if the current hash is in the vector
+ std::vector<size_t>::iterator it =
+ std::find(ancestorHashs.begin(), ancestorHashs.end(), currentHash);
- auto proofIt = pfLetClosed.find(currentHash);
- // If this node has been already saved to the global cache of closed proof
- // nodes
- if (proofIt != pfLetClosed.end())
- {
- Assert(!expr::containsAssumption(pn, cfaMap));
- return proofIt->second;
- }
- // If this proof node is closed, we add it to the global cache
- if (!expr::containsAssumption(pn, cfaMap))
+ // Register the current proof node hash in the ancestor vector
+ ancestorHashs.push_back(currentHash);
+
+ // we only consider sharing when this would not introduce a cycle, which
+ // would be the case if this hash is occurring under a proof node with the
+ // same hash (this can happen since our hash computation only takes into
+ // account the immediate descendants of a proof node, the limit of hash
+ // representation notwithstanding)
+ if (it == oldEnd)
{
- pfLetClosed[currentHash] = currentRuleID;
+ auto openProofIt = pfLetOpen.find(currentHash);
+
+ if (openProofIt != pfLetOpen.end())
+ {
+ return openProofIt->second;
+ }
+
+ auto proofIt = pfLetClosed.find(currentHash);
+ // If this node has been already saved to the global cache of closed proof
+ // nodes
+ if (proofIt != pfLetClosed.end())
+ {
+ Assert(!expr::containsAssumption(pn, cfaMap));
+ return proofIt->second;
+ }
+ // If this proof node is closed, we add it to the global cache
+ if (!expr::containsAssumption(pn, cfaMap))
+ {
+ pfLetClosed[currentHash] = currentRuleID;
+ }
+ pfLetOpen[currentHash] = currentRuleID;
}
- pfLetOpen[currentHash] = currentRuleID;
}
ProofNodeClusterType proofNodeType = ProofNodeClusterType::NOT_DEFINED;
pfLetClosed,
thisScopeLet,
cfaMap,
+ ancestorHashs,
proofNodeType);
out << "\t" << childId << " -> " << currentRuleID << ";\n";
+ if (options::proofDotDAG())
+ {
+ ancestorHashs.pop_back();
+ }
}
else
{
const std::vector<std::shared_ptr<ProofNode>>& children = pn->getChildren();
for (const std::shared_ptr<ProofNode>& c : children)
{
- uint64_t childId = printInternal(
- out, c.get(), pfLetClosed, pfLetOpen, cfaMap, proofNodeType);
+ uint64_t childId = printInternal(out,
+ c.get(),
+ pfLetClosed,
+ pfLetOpen,
+ cfaMap,
+ ancestorHashs,
+ proofNodeType);
out << "\t" << childId << " -> " << currentRuleID << ";\n";
+ if (options::proofDotDAG())
+ {
+ ancestorHashs.pop_back();
+ }
}
}
* @param pfLetOpen the map, local to the current scope, of proof node hashs
* to their printed ids
* @param cfaMap the map from proof nodes to whether they contain assumptions
+ * @param ancestorHashs a vector containing the hashs of all the proof nodes
+ * ancestors traversed to get to pn
* @param parentType the type of the parent node
* @return the id of the proof node printed
*/
std::map<size_t, uint64_t>& pfLetClosed,
std::map<size_t, uint64_t>& pfLetOpen,
std::unordered_map<const ProofNode*, bool>& cfaMap,
+ std::vector<size_t>& ancestorHashs,
ProofNodeClusterType parentType);
/**