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;
}
Example #2
0
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);
}