// Adds to the dependency graph that n0 depends on the variables in n1. // It's not the transitive closure of the dependencies. Just the variables in the expression "n1". // This is only needed as long as all the substitution rules haven't been written through. void SubstitutionMap::buildDepends(const ASTNode& n0, const ASTNode& n1) { if (n0.GetKind() != SYMBOL) return; if (n1.isConstant()) return; vector<Symbols*> av; vars.VarSeenInTerm(vars.getSymbol(n1), rhs_visited, rhs, av); sort(av.begin(), av.end()); for (int i = 0; i < av.size(); i++) { if (i != 0 && av[i] == av[i - 1]) continue; // Treat it like a set of Symbol* in effect. ASTNodeSet* sym = (vars.TermsAlreadySeenMap.find(av[i])->second); if (rhsAlreadyAdded.find(sym) != rhsAlreadyAdded.end()) continue; rhsAlreadyAdded.insert(sym); //cout << loopCount++ << " "; //cout << "initial" << rhs.size() << " Adding: " <<sym->size(); rhs.insert(sym->begin(), sym->end()); //cout << "final:" << rhs.size(); //cout << "added:" << sym << endl; } assert(dependsOn.find(n0) == dependsOn.end()); dependsOn.insert(make_pair(n0, vars.getSymbol(n1))); }
void STPMgr::printVarDeclsToStream(ostream& os, ASTNodeSet& ListOfDeclaredVars) { for (ASTNodeSet::iterator i = ListOfDeclaredVars.begin(), iend = ListOfDeclaredVars.end(); i != iend; i++) { stp::ASTNode a = *i; switch (a.GetType()) { case stp::BITVECTOR_TYPE: a.PL_Print(os); os << " : BITVECTOR(" << a.GetValueWidth() << ");" << endl; break; case stp::ARRAY_TYPE: a.PL_Print(os); os << " : ARRAY " << "BITVECTOR(" << a.GetIndexWidth() << ") OF "; os << "BITVECTOR(" << a.GetValueWidth() << ");" << endl; break; case stp::BOOLEAN_TYPE: a.PL_Print(os); os << " : BOOLEAN;" << endl; break; default: stp::FatalError("vc_printDeclsToStream: Unsupported type", a); break; } } } // printVarDeclsToStream
void printVarDeclsToStream(ASTNodeSet& symbols, ostream& os) { for (ASTNodeSet::const_iterator i = symbols.begin(), iend = symbols.end(); i != iend; i++) { const BEEV::ASTNode& a = *i; os << "(declare-fun "; // Should be a symbol. assert(a.GetKind()== SYMBOL); os << "|"; a.nodeprint(os); os << "|"; switch (a.GetType()) { case BEEV::BITVECTOR_TYPE: os << " () ("; os << "_ BitVec " << a.GetValueWidth() << ")"; break; case BEEV::ARRAY_TYPE: os << " () ("; os << "Array (_ BitVec " << a.GetIndexWidth() << ") (_ BitVec " << a.GetValueWidth() << ") )"; break; case BEEV::BOOLEAN_TYPE: os << " () Bool "; break; default: BEEV::FatalError("printVarDeclsToStream: Unsupported type",a); break; } os << ")\n"; } } //printVarDeclsToStream
// If n0 is replaced by n1 in the substitution map. Will it cause a loop? // i.e. will the dependency graph be an acyclic graph still. // For example, if we have x = F(y,z,w), it would make the substitutionMap loop // if there's already z = F(x). bool SubstitutionMap::loops(const ASTNode& n0, const ASTNode& n1) { if (n0.GetKind() != SYMBOL) return false; // sometimes this function is called with constants on the // lhs. if (n1.isConstant()) return false; // constants contain no variables. Can't loop. // We are adding an edge FROM n0, so unless there is already an edge TO n0, // there is no change it can loop. Unless adding this would add a TO and FROM // edge. if (rhs.find(n0) == rhs.end()) { return vars.VarSeenInTerm(n0, n1); } if (n1.GetKind() == SYMBOL && dependsOn.find(n1) == dependsOn.end()) return false; // The rhs is a symbol and doesn't appear. if (debug_substn) cout << loopCount++ << endl; bool destruct = true; ASTNodeSet* dependN = vars.SetofVarsSeenInTerm(n1, destruct); if (debug_substn) { cout << n0 << " " << n1.GetNodeNum(); //<< " Expression size:" << bm->NodeSize(n1,true); cout << "Variables in expression: " << dependN->size() << endl; } set<ASTNode> depend(dependN->begin(), dependN->end()); if (destruct) delete dependN; set<ASTNode> visited; loops_helper(depend, visited); bool loops = visited.find(n0) != visited.end(); if (debug_substn) cout << "Visited:" << visited.size() << "Loops:" << loops << endl; return (loops); }
// Take the transitive closure of the varsToCheck. Storing the result in // visited. void SubstitutionMap::loops_helper(const set<ASTNode>& varsToCheck, set<ASTNode>& visited) { set<ASTNode>::const_iterator visitedIt = visited.begin(); set<ASTNode> toVisit; vector<ASTNode> visitedN; // for each variable. for (set<ASTNode>::const_iterator varIt = varsToCheck.begin(); varIt != varsToCheck.end(); varIt++) { while (visitedIt != visited.end() && *visitedIt < *varIt) visitedIt++; if ((visitedIt != visited.end()) && *visitedIt == *varIt) continue; visitedN.push_back(*varIt); DependsType::iterator it; if ((it = dependsOn.find(*varIt)) != dependsOn.end()) { Symbols* s = it->second; bool destruct; ASTNodeSet* varsSeen = vars.SetofVarsSeenInTerm(s, destruct); toVisit.insert(varsSeen->begin(), varsSeen->end()); if (destruct) delete varsSeen; } } visited.insert(visitedN.begin(), visitedN.end()); visitedN.clear(); if (toVisit.size() != 0) loops_helper(toVisit, visited); }
void printSMTLIB1VarDeclsToStream(ASTNodeSet& symbols, ostream& os) { for (ASTNodeSet::const_iterator i = symbols.begin(), iend = symbols.end(); i != iend; i++) { const BEEV::ASTNode& a = *i; // Should be a symbol. assert(a.GetKind()== SYMBOL); switch (a.GetType()) { case BEEV::BITVECTOR_TYPE: os << ":extrafuns (( "; a.nodeprint(os); os << " BitVec[" << a.GetValueWidth() << "]"; os << " ))" << endl; break; case BEEV::ARRAY_TYPE: os << ":extrafuns (( "; a.nodeprint(os); os << " Array[" << a.GetIndexWidth(); os << ":" << a.GetValueWidth() << "] ))" << endl; break; case BEEV::BOOLEAN_TYPE: os << ":extrapreds (( "; a.nodeprint(os); os << "))" << endl; break; default: BEEV::FatalError("printVarDeclsToStream: Unsupported type",a); break; } } } //printVarDeclsToStream