bool all_paths_enumeratort::next(patht &path) { if(last_path.empty()) { // This is the first time we've been called -- build an initial // path. last_path.push_back(path_nodet(loop_header)); // This shouldn't be able to fail. complete_path(last_path, 0); if(is_looping(last_path)) { // If this was a loop path, we're good. If it wasn't, // we'll keep enumerating paths until we hit a looping one. // This case is exactly the same as if someone just called // next() on us. path.clear(); path.insert(path.begin(), last_path.begin(), last_path.end()); return true; } } do { #ifdef DEBUG std::cout << "Enumerating next path...\n"; #endif int decision=backtrack(last_path); complete_path(last_path, decision); if(is_looping(last_path)) { path.clear(); path.insert(path.begin(), last_path.begin(), last_path.end()); return true; } } while(!last_path.empty()); // We've enumerated all the paths. return false; }
int all_paths_enumeratort::backtrack(patht &path) { // If we have a path of length 1 or 0, we can't backtrack any further. // That means we're done enumerating paths! if (path.size() < 2) { path.clear(); return 0; } path_nodet &node = path.back(); path.pop_back(); path_nodet &parent = path.back(); goto_programt::targetst succs; goto_program.get_successors(parent.loc, succs); int ret = 0; for (goto_programt::targetst::iterator it = succs.begin(); it != succs.end(); ++it) { if (*it == node.loc) { break; } ret++; } if ((ret + 1) < succs.size()) { // We can take the next branch here... #ifdef DEBUG std::cout << "Backtracked to a path of size " << path.size() << std::endl; #endif return ret + 1; } // Recurse. return backtrack(path); }
int all_paths_enumeratort::backtrack(patht &path) { // If we have a path of length 1 or 0, we can't backtrack any further. // That means we're done enumerating paths! if(path.size()<2) { path.clear(); return 0; } path_nodet &node=path.back(); path.pop_back(); path_nodet &parent=path.back(); const auto succs=goto_program.get_successors(parent.loc); unsigned int ret=0; for(const auto &succ : succs) { if(succ==node.loc) break; ret++; } if((ret+1)<succs.size()) { // We can take the next branch here... #ifdef DEBUG std::cout << "Backtracked to a path of size " << path.size() << '\n'; #endif return ret+1; } // Recurse. return backtrack(path); }