void CNFMgr::scanTerm(const ASTNode& varphi) { CNFInfo* x; //######################################## // step 1, get the info associated with this node //######################################## if (info.find(varphi) == info.end()) { x = new CNFInfo(); info[varphi] = x; } else { x = info[varphi]; } //######################################## // step 2, need two hits because of term ITEs. //######################################## if (sharesPos(*x) == 2) { return; } //######################################## // step 3, set appropriate data fields, always rename // term ITEs //######################################## incrementSharesPos(*x); setIsTerm(*x); //######################################## // step 4, recurse over children //######################################## if (varphi.isAtom()) { return; } else if (varphi.isITE()) { scanFormula(varphi[0], true, false); scanFormula(varphi[0], false, false); scanTerm(varphi[1]); scanTerm(varphi[2]); } else { for (unsigned int i = 0; i < varphi.GetChildren().size(); i++) { scanTerm(varphi[i]); } } }//End of scanterm()
void LetizeNode(const ASTNode& n, ASTNodeSet& PLPrintNodeSet, bool smtlib1) { if (n.isAtom()) return; const ASTVec& c = n.GetChildren(); for (ASTVec::const_iterator it = c.begin(), itend = c.end(); it != itend; it++) { const ASTNode& ccc = *it; if (ccc.isAtom()) continue; if (PLPrintNodeSet.find(ccc) == PLPrintNodeSet.end()) { // If branch: if *it is not in NodeSet then, // // 1. add it to NodeSet // // 2. Letize its childNodes PLPrintNodeSet.insert(ccc); LetizeNode(ccc, PLPrintNodeSet, smtlib1); } else { // 0. Else branch: Node has been seen before // // 1. Check if the node has a corresponding letvar in the // 1. NodeLetVarMap. // // 2. if no, then create a new var and add it to the // 2. NodeLetVarMap if ((!smtlib1 || ccc.GetType() == BITVECTOR_TYPE) && NodeLetVarMap.find(ccc) == NodeLetVarMap.end()) { // Create a new symbol. Get some name. if it conflicts with a // declared name, too bad. int sz = NodeLetVarMap.size(); std::ostringstream oss; oss << "?let_k_" << sz; ASTNode CurrentSymbol = n.GetSTPMgr()->CreateSymbol( oss.str().c_str(), n.GetIndexWidth(), n.GetValueWidth()); /* If for some reason the variable being created here is * already declared by the user then the printed output will * not be a legal input to the system. too bad. I refuse to * check for this. [Vijay is the author of this comment.] */ NodeLetVarMap[ccc] = CurrentSymbol; std::pair<ASTNode, ASTNode> node_letvar_pair(CurrentSymbol, ccc); NodeLetVarVec.push_back(node_letvar_pair); } } } }
void CNFMgr::convertTermForCNF(const ASTNode& varphi, ClauseList* defs) { CNFInfo* x = info[varphi]; //######################################## // step 1, done if we've already visited //######################################## if (x->termforcnf != NULL) { return; } //######################################## // step 2, ITE's always get renamed //######################################## if (varphi.isITE()) { x->termforcnf = doRenameITE(varphi, defs); reduceMemoryFootprintPos(varphi[0]); reduceMemoryFootprintNeg(varphi[0]); } else if (varphi.isAtom()) { x->termforcnf = ASTNodeToASTNodePtr(varphi); } else { ASTVec psis; ASTVec::const_iterator it = varphi.GetChildren().begin(); for (; it != varphi.GetChildren().end(); it++) { convertTermForCNF(*it, defs); psis.push_back(*(info[*it]->termforcnf)); } ASTNode psi = bm->CreateNode(varphi.GetKind(), psis); psi.SetValueWidth(varphi.GetValueWidth()); psi.SetIndexWidth(varphi.GetIndexWidth()); x->termforcnf = ASTNodeToASTNodePtr(psi); } } //End of convertTermForCNF()
// counts the number of reads. Shortcut when we get to the limit. void numberOfReadsLessThan(const ASTNode& n, hash_set<int>& visited, int& soFar, const int limit) { if (n.isAtom()) return; if (visited.find(n.GetNodeNum()) != visited.end()) return; if (n.GetKind() == READ) soFar++; if (soFar > limit) return; visited.insert(n.GetNodeNum()); for (size_t i = 0; i < n.Degree(); i++) numberOfReadsLessThan(n[i], visited, soFar, limit); }
void CNFMgr::scanFormula(const ASTNode& varphi, bool isPos, bool isXorChild) { CNFInfo* x; Kind k = varphi.GetKind(); //######################################## // step 1, get the info associated with this node //######################################## if (info.find(varphi) == info.end()) { x = new CNFInfo(); info[varphi] = x; } else { x = info[varphi]; } #if defined CRYPTOMINISAT__2 if(isXorChild) { setDoRenamePos(*x); } #endif //######################################## // step 2, we only need to know if shares >= 2 //######################################## if (isPos && sharesPos(*x) == 2) { return; } if (!isPos && sharesNeg(*x) == 2) { return; } //######################################## // step 3, set appropriate information fields //######################################## if (isPos) { incrementSharesPos(*x); } if (!isPos) { incrementSharesNeg(*x); } //######################################## // step 4, recurse over children //######################################## if (varphi.isAtom()) { return; } else if (varphi.isPred()) { for (unsigned int i = 0; i < varphi.GetChildren().size(); i++) { scanTerm(varphi[i]); } } else { for (unsigned int i = 0; i < varphi.GetChildren().size(); i++) { if (onChildDoPos(varphi, i)) { scanFormula(varphi[i], isPos, k == XOR); } if (onChildDoNeg(varphi, i)) { scanFormula(varphi[i], !isPos, false); } } } } //End of ScanFormula()