//=======================================================================
// Copyright (C) 2005-2009 Jongsoo Park <jongsoo.park -at- gmail.com>
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#ifndef BOOST_GRAPH_DOMINATOR_HPP
#define BOOST_GRAPH_DOMINATOR_HPP

#include <boost/config.hpp>
#include <deque>
#include <set>
#include <boost/graph/depth_first_search.hpp>

// Dominator tree computation

namespace boost {
  namespace detail {
    /**
     * An extended time_stamper which also records vertices for each dfs number
     */
    template<class TimeMap, class VertexVector, class TimeT, class Tag>
    class time_stamper_with_vertex_vector
      : public base_visitor<
      time_stamper_with_vertex_vector<TimeMap, VertexVector, TimeT, Tag> >
    {
    public :
      typedef Tag event_filter;
      time_stamper_with_vertex_vector(TimeMap timeMap, VertexVector& v,
                                      TimeT& t)
        : timeStamper_(timeMap, t), v_(v) { }

      template<class Graph>
      void
      operator()(const typename property_traits<TimeMap>::key_type& v,
                 const Graph& g)
      {
        timeStamper_(v, g);
        v_[timeStamper_.m_time] = v;
      }

    private :
      time_stamper<TimeMap, TimeT, Tag> timeStamper_;
      VertexVector& v_;
    };

    /**
     * A convenient way to create a time_stamper_with_vertex_vector
     */
    template<class TimeMap, class VertexVector, class TimeT, class Tag>
    time_stamper_with_vertex_vector<TimeMap, VertexVector, TimeT, Tag>
    stamp_times_with_vertex_vector(TimeMap timeMap, VertexVector& v, TimeT& t,
                                   Tag)
    {
      return time_stamper_with_vertex_vector<TimeMap, VertexVector, TimeT,
                                             Tag>(timeMap, v, t);
    }

    template<class Graph, class IndexMap, class TimeMap, class PredMap,
             class DomTreePredMap>
    class dominator_visitor
    {
      typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
      typedef typename graph_traits<Graph>::vertices_size_type VerticesSizeType;

    public :
      /**
       * @param g [in] the target graph of the dominator tree
       * @param entry [in] the entry node of g
       * @param domTreePredMap [out] the immediate dominator map
       *                             (parent map in dominator tree)
       */
      dominator_visitor(const Graph& g, const Vertex& entry,
                        DomTreePredMap domTreePredMap)
        : semi_(num_vertices(g)),
          ancestor_(num_vertices(g), graph_traits<Graph>::null_vertex()),
          samedom_(ancestor_),
          best_(semi_),
          semiMap_(make_iterator_property_map(semi_.begin(),
                                              get(vertex_index, g))),
          ancestorMap_(make_iterator_property_map(ancestor_.begin(),
                                                  get(vertex_index, g))),
          bestMap_(make_iterator_property_map(best_.begin(),
                                              get(vertex_index, g))),
          buckets_(num_vertices(g)),
          bucketMap_(make_iterator_property_map(buckets_.begin(),
                                                get(vertex_index, g))),
          entry_(entry),
          domTreePredMap_(domTreePredMap),
          numOfVertices_(num_vertices(g)),
          samedomMap(make_iterator_property_map(samedom_.begin(),
                                                get(vertex_index, g)))
      {
      }

      void
      operator()(const Vertex& n, const TimeMap& dfnumMap,
                 const PredMap& parentMap, const Graph& g)
      {
        if (n == entry_) return;

        const Vertex p(get(parentMap, n));
        Vertex s(p);

        // 1. Calculate the semidominator of n,
        // based on the semidominator thm.
        // * Semidominator thm. : To find the semidominator of a node n,
        //   consider all predecessors v of n in the CFG (Control Flow Graph).
        //  - If v is a proper ancestor of n in the spanning tree
        //    (so dfnum(v) < dfnum(n)), then v is a candidate for semi(n)
        //  - If v is a non-ancestor of n (so dfnum(v) > dfnum(n))
        //    then for each u that is an ancestor of v (or u = v),
        //    Let semi(u) be a candidate for semi(n)
        //   of all these candidates, the one with lowest dfnum is
        //   the semidominator of n.

        // For each predecessor of n
        typename graph_traits<Graph>::in_edge_iterator inItr, inEnd;
        for (boost::tie(inItr, inEnd) = in_edges(n, g); inItr != inEnd; ++inItr)
          {
            const Vertex v = source(*inItr, g);
            // To deal with unreachable nodes
            if (get(dfnumMap, v) < 0 || get(dfnumMap, v) >= numOfVertices_)
              continue;

            Vertex s2;
            if (get(dfnumMap, v) <= get(dfnumMap, n))
              s2 = v;
            else
              s2 = get(semiMap_, ancestor_with_lowest_semi_(v, dfnumMap));

            if (get(dfnumMap, s2) < get(dfnumMap, s))
              s = s2;
          }
        put(semiMap_, n, s);

        // 2. Calculation of n's dominator is deferred until
        // the path from s to n has been linked into the forest
        get(bucketMap_, s).push_back(n);
        get(ancestorMap_, n) = p;
        get(bestMap_, n) = n;

        // 3. Now that the path from p to v has been linked into
        // the spanning forest, these lines calculate the dominator of v,
        // based on the dominator thm., or else defer the calculation
        // until y's dominator is known
        // * Dominator thm. : On the spanning-tree path below semi(n) and
        //   above or including n, let y be the node
        //   with the smallest-numbered semidominator. Then,
        //
        //  idom(n) = semi(n) if semi(y)=semi(n) or
        //            idom(y) if semi(y) != semi(n)
        typename std::deque<Vertex>::iterator buckItr;
        for (buckItr = get(bucketMap_, p).begin();
             buckItr != get(bucketMap_, p).end();
             ++buckItr)
          {
            const Vertex v(*buckItr);
            const Vertex y(ancestor_with_lowest_semi_(v, dfnumMap));
            if (get(semiMap_, y) == get(semiMap_, v))
              put(domTreePredMap_, v, p);
            else
              put(samedomMap, v, y);
          }

        get(bucketMap_, p).clear();
      }

    protected :

      /**
       * Evaluate function in Tarjan's path compression
       */
      const Vertex
      ancestor_with_lowest_semi_(const Vertex& v, const TimeMap& dfnumMap)
      {
        const Vertex a(get(ancestorMap_, v));

        if (get(ancestorMap_, a) != graph_traits<Graph>::null_vertex())
          {
            const Vertex b(ancestor_with_lowest_semi_(a, dfnumMap));

            put(ancestorMap_, v, get(ancestorMap_, a));

            if (get(dfnumMap, get(semiMap_, b)) <
                get(dfnumMap, get(semiMap_, get(bestMap_, v))))
              put(bestMap_, v, b);
          }

        return get(bestMap_, v);
      }

      std::vector<Vertex> semi_, ancestor_, samedom_, best_;
      PredMap semiMap_, ancestorMap_, bestMap_;
      std::vector< std::deque<Vertex> > buckets_;

      iterator_property_map<typename std::vector<std::deque<Vertex> >::iterator,
                            IndexMap> bucketMap_;

      const Vertex& entry_;
      DomTreePredMap domTreePredMap_;
      const VerticesSizeType numOfVertices_;

    public :

      PredMap samedomMap;
    };

  } // namespace detail

  /**
   * @brief Build dominator tree using Lengauer-Tarjan algorithm.
   *                It takes O((V+E)log(V+E)) time.
   *
   * @pre dfnumMap, parentMap and verticesByDFNum have dfs results corresponding
   *      indexMap.
   *      If dfs has already run before,
   *      this function would be good for saving computations.
   * @pre Unreachable nodes must be masked as
   *      graph_traits<Graph>::null_vertex in parentMap.
   * @pre Unreachable nodes must be masked as
   *      (std::numeric_limits<VerticesSizeType>::max)() in dfnumMap.
   *
   * @param domTreePredMap [out] : immediate dominator map (parent map
   * in dom. tree)
   *
   * @note reference Appel. p. 452~453. algorithm 19.9, 19.10.
   *
   * @todo : Optimization in Finding Dominators in Practice, Loukas Georgiadis
   */
  template<class Graph, class IndexMap, class TimeMap, class PredMap,
           class VertexVector, class DomTreePredMap>
  void
  lengauer_tarjan_dominator_tree_without_dfs
    (const Graph& g,
     const typename graph_traits<Graph>::vertex_descriptor& entry,
     const IndexMap& /*indexMap*/,
     TimeMap dfnumMap, PredMap parentMap, VertexVector& verticesByDFNum,
     DomTreePredMap domTreePredMap)
  {
    // Typedefs and concept check
    typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
    typedef typename graph_traits<Graph>::vertices_size_type VerticesSizeType;

    function_requires< BidirectionalGraphConcept<Graph> >();

    const VerticesSizeType numOfVertices = num_vertices(g);
    if (numOfVertices == 0) return;

    // 1. Visit each vertex in reverse post order and calculate sdom.
    detail::dominator_visitor<Graph, IndexMap, TimeMap, PredMap, DomTreePredMap>
      visitor(g, entry, domTreePredMap);

    VerticesSizeType i;
    for (i = 0; i < numOfVertices; ++i)
      {
        const Vertex u(verticesByDFNum[numOfVertices - 1 - i]);
        if (u != graph_traits<Graph>::null_vertex())
          visitor(u, dfnumMap, parentMap, g);
      }

    // 2. Now all the deferred dominator calculations,
    // based on the second clause of the dominator thm., are performed
    for (i = 0; i < numOfVertices; ++i)
      {
        const Vertex n(verticesByDFNum[i]);

        if (n == entry || n == graph_traits<Graph>::null_vertex())
          continue;

        Vertex u = get(visitor.samedomMap, n);
        if (u != graph_traits<Graph>::null_vertex())
          {
            put(domTreePredMap, n, get(domTreePredMap, u));
          }
      }
  }

  /**
   * Unlike lengauer_tarjan_dominator_tree_without_dfs,
   * dfs is run in this function and
   * the result is written to dfnumMap, parentMap, vertices.
   *
   * If the result of dfs required after this algorithm,
   * this function can eliminate the need of rerunning dfs.
   */
  template<class Graph, class IndexMap, class TimeMap, class PredMap,
           class VertexVector, class DomTreePredMap>
  void
  lengauer_tarjan_dominator_tree
    (const Graph& g,
     const typename graph_traits<Graph>::vertex_descriptor& entry,
     const IndexMap& indexMap,
     TimeMap dfnumMap, PredMap parentMap, VertexVector& verticesByDFNum,
     DomTreePredMap domTreePredMap)
  {
    // Typedefs and concept check
    typedef typename graph_traits<Graph>::vertices_size_type VerticesSizeType;

    function_requires< BidirectionalGraphConcept<Graph> >();

    // 1. Depth first visit
    const VerticesSizeType numOfVertices = num_vertices(g);
    if (numOfVertices == 0) return;

    VerticesSizeType time =
      (std::numeric_limits<VerticesSizeType>::max)();
    std::vector<default_color_type>
      colors(numOfVertices, color_traits<default_color_type>::white());
    depth_first_visit
      (g, entry,
       make_dfs_visitor
         (make_pair(record_predecessors(parentMap, on_tree_edge()),
                    detail::stamp_times_with_vertex_vector
                      (dfnumMap, verticesByDFNum, time, on_discover_vertex()))),
       make_iterator_property_map(colors.begin(), indexMap));

    // 2. Run main algorithm.
    lengauer_tarjan_dominator_tree_without_dfs(g, entry, indexMap, dfnumMap,
                                               parentMap, verticesByDFNum,
                                               domTreePredMap);
  }

  /**
   * Use vertex_index as IndexMap and make dfnumMap, parentMap, verticesByDFNum
   * internally.
   * If we don't need the result of dfs (dfnumMap, parentMap, verticesByDFNum),
   * this function would be more convenient one.
   */
  template<class Graph, class DomTreePredMap>
  void
  lengauer_tarjan_dominator_tree
    (const Graph& g,
     const typename graph_traits<Graph>::vertex_descriptor& entry,
     DomTreePredMap domTreePredMap)
  {
    // typedefs
    typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
    typedef typename graph_traits<Graph>::vertices_size_type VerticesSizeType;
    typedef typename property_map<Graph, vertex_index_t>::const_type IndexMap;
    typedef
      iterator_property_map<typename std::vector<VerticesSizeType>::iterator,
                            IndexMap> TimeMap;
    typedef
      iterator_property_map<typename std::vector<Vertex>::iterator, IndexMap>
      PredMap;

    // Make property maps
    const VerticesSizeType numOfVertices = num_vertices(g);
    if (numOfVertices == 0) return;

    const IndexMap indexMap = get(vertex_index, g);

    std::vector<VerticesSizeType> dfnum(numOfVertices, 0);
    TimeMap dfnumMap(make_iterator_property_map(dfnum.begin(), indexMap));

    std::vector<Vertex> parent(numOfVertices,
                               graph_traits<Graph>::null_vertex());
    PredMap parentMap(make_iterator_property_map(parent.begin(), indexMap));

    std::vector<Vertex> verticesByDFNum(parent);

    // Run main algorithm
    lengauer_tarjan_dominator_tree(g, entry,
                                   indexMap, dfnumMap, parentMap,
                                   verticesByDFNum, domTreePredMap);
  }

  /**
   * Muchnick. p. 182, 184
   *
   * using iterative bit vector analysis
   */
  template<class Graph, class IndexMap, class DomTreePredMap>
  void
  iterative_bit_vector_dominator_tree
    (const Graph& g,
     const typename graph_traits<Graph>::vertex_descriptor& entry,
     const IndexMap& indexMap,
     DomTreePredMap domTreePredMap)
  {
    typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
    typedef typename graph_traits<Graph>::vertex_iterator vertexItr;
    typedef typename graph_traits<Graph>::vertices_size_type VerticesSizeType;
    typedef
      iterator_property_map<typename std::vector< std::set<Vertex> >::iterator,
                            IndexMap> vertexSetMap;

    function_requires<BidirectionalGraphConcept<Graph> >();

    // 1. Finding dominator
    // 1.1. Initialize
    const VerticesSizeType numOfVertices = num_vertices(g);
    if (numOfVertices == 0) return;

    vertexItr vi, viend;
    boost::tie(vi, viend) = vertices(g);
    const std::set<Vertex> N(vi, viend);

    bool change = true;

    std::vector< std::set<Vertex> > dom(numOfVertices, N);
    vertexSetMap domMap(make_iterator_property_map(dom.begin(), indexMap));
    get(domMap, entry).clear();
    get(domMap, entry).insert(entry);

    while (change)
      {
        change = false;
        for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
          {
            if (*vi == entry) continue;

            std::set<Vertex> T(N);

            typename graph_traits<Graph>::in_edge_iterator inItr, inEnd;
            for (boost::tie(inItr, inEnd) = in_edges(*vi, g); inItr != inEnd; ++inItr)
              {
                const Vertex p = source(*inItr, g);

                std::set<Vertex> tempSet;
                std::set_intersection(T.begin(), T.end(),
                                      get(domMap, p).begin(),
                                      get(domMap, p).end(),
                                      std::inserter(tempSet, tempSet.begin()));
                T.swap(tempSet);
              }

            T.insert(*vi);
            if (T != get(domMap, *vi))
              {
                change = true;
                get(domMap, *vi).swap(T);
              }
          } // end of for (boost::tie(vi, viend) = vertices(g)
      } // end of while(change)

    // 2. Build dominator tree
    for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
      get(domMap, *vi).erase(*vi);

    Graph domTree(numOfVertices);

    for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
      {
        if (*vi == entry) continue;

        // We have to iterate through copied dominator set
        const std::set<Vertex> tempSet(get(domMap, *vi));
        typename std::set<Vertex>::const_iterator s;
        for (s = tempSet.begin(); s != tempSet.end(); ++s)
          {
            typename std::set<Vertex>::iterator t;
            for (t = get(domMap, *vi).begin(); t != get(domMap, *vi).end(); )
              {
        typename std::set<Vertex>::iterator old_t = t;
        ++t; // Done early because t may become invalid
                if (*old_t == *s) continue;
                if (get(domMap, *s).find(*old_t) != get(domMap, *s).end())
                  get(domMap, *vi).erase(old_t);
              }
          }
      }

    for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
      {
        if (*vi != entry && get(domMap, *vi).size() == 1)
          {
            Vertex temp = *get(domMap, *vi).begin();
            put(domTreePredMap, *vi, temp);
          }
      }
  }

  template<class Graph, class DomTreePredMap>
  void
  iterative_bit_vector_dominator_tree
    (const Graph& g,
     const typename graph_traits<Graph>::vertex_descriptor& entry,
     DomTreePredMap domTreePredMap)
  {
    typename property_map<Graph, vertex_index_t>::const_type
      indexMap = get(vertex_index, g);

    iterative_bit_vector_dominator_tree(g, entry, indexMap, domTreePredMap);
  }
} // namespace boost

#endif // BOOST_GRAPH_DOMINATOR_HPP
