Node ITESimplifier::substitute(TNode e, TNodeMap& substTable, TNodeMap& cache) { TNodeMap::iterator it = cache.find(e), iend = cache.end(); if (it != iend) { return it->second; } // do substitution? it = substTable.find(e); iend = substTable.end(); if (it != iend) { Node result = substitute(it->second, substTable, cache); cache[e] = result; return result; } size_t sz = e.getNumChildren(); if (sz == 0) { cache[e] = e; return e; } NodeBuilder<> builder(e.getKind()); if (e.getMetaKind() == kind::metakind::PARAMETERIZED) { builder << e.getOperator(); } for (unsigned i = 0; i < e.getNumChildren(); ++ i) { builder << substitute(e[i], substTable, cache); } Node result = builder; // it = substTable.find(result); // if (it != iend) { // result = substitute(it->second, substTable, cache); // } cache[e] = result; return result; }
Node ITESimplifier::simplifyWithCare(TNode e) { TNodeMap substTable; CareMap queue; CareMap::iterator it; ITESimplifier::CareSetPtr cs = getNewSet(); ITESimplifier::CareSetPtr cs2; queue[e] = cs; TNode v; bool done; unsigned i; while (!queue.empty()) { it = queue.end(); --it; v = it->first; cs = it->second; set<Node>& css = cs.getCareSet(); queue.erase(v); done = false; set<Node>::iterator iCare, iCareEnd = css.end(); switch (v.getKind()) { case kind::ITE: { iCare = css.find(v[0]); if (iCare != iCareEnd) { Assert(substTable.find(v) == substTable.end()); substTable[v] = v[1]; updateQueue(queue, v[1], cs); done = true; break; } else { iCare = css.find(v[0].negate()); if (iCare != iCareEnd) { Assert(substTable.find(v) == substTable.end()); substTable[v] = v[2]; updateQueue(queue, v[2], cs); done = true; break; } } updateQueue(queue, v[0], cs); cs2 = getNewSet(); cs2.getCareSet() = css; cs2.getCareSet().insert(v[0]); updateQueue(queue, v[1], cs2); cs2 = getNewSet(); cs2.getCareSet() = css; cs2.getCareSet().insert(v[0].negate()); updateQueue(queue, v[2], cs2); done = true; break; } case kind::AND: { for (i = 0; i < v.getNumChildren(); ++i) { iCare = css.find(v[i].negate()); if (iCare != iCareEnd) { Assert(substTable.find(v) == substTable.end()); substTable[v] = d_false; done = true; break; } } if (done) break; Assert(v.getNumChildren() > 1); updateQueue(queue, v[0], cs); cs2 = getNewSet(); cs2.getCareSet() = css; cs2.getCareSet().insert(v[0]); for (i = 1; i < v.getNumChildren(); ++i) { updateQueue(queue, v[i], cs2); } done = true; break; } case kind::OR: { for (i = 0; i < v.getNumChildren(); ++i) { iCare = css.find(v[i]); if (iCare != iCareEnd) { Assert(substTable.find(v) == substTable.end()); substTable[v] = d_true; done = true; break; } } if (done) break; Assert(v.getNumChildren() > 1); updateQueue(queue, v[0], cs); cs2 = getNewSet(); cs2.getCareSet() = css; cs2.getCareSet().insert(v[0].negate()); for (i = 1; i < v.getNumChildren(); ++i) { updateQueue(queue, v[i], cs2); } done = true; break; } default: break; } if (done) { continue; } for (unsigned i = 0; i < v.getNumChildren(); ++i) { updateQueue(queue, v[i], cs); } } while (!d_usedSets.empty()) { delete d_usedSets.back(); d_usedSets.pop_back(); } TNodeMap cache; return substitute(e, substTable, cache); }