private void DetermineFollowNodesInSubGraph(ILogicalConstruct theGraph)
 {
     this.GetVerticesAndAdjacencyMatrix(theGraph);
     V_0 = MaxWeightDisjointPathsFinder.GetOptimalEdgesInDAG(this.adjacencyMatrix).GetEnumerator();
     try
     {
         while (V_0.MoveNext())
         {
             V_1 = V_0.get_Current();
             this.orderedVertexArray[V_1.get_Key()].set_CFGFollowNode(this.orderedVertexArray[V_1.get_Value()].get_FirstBlock());
             if (this.orderedVertexArray[V_1.get_Key()] as ConditionLogicalConstruct == null)
             {
                 continue;
             }
             V_2 = this.orderedVertexArray[V_1.get_Key()] as ConditionLogicalConstruct;
             if (V_2.get_CFGFollowNode() != V_2.get_TrueCFGSuccessor())
             {
                 continue;
             }
             V_2.Negate(this.typeSystem);
         }
     }
     finally
     {
         ((IDisposable)V_0).Dispose();
     }
     return;
 }
        /// <summary>
        /// Determines the follow nodes in the given subgraph.
        /// </summary>
        /// <remarks>
        /// Every node can follow only one node.
        /// Everey node can be followed by only one node.
        /// The follow node relation cannot form a back edge. (i.e. B can be the follow node of A <=> (A, B) is not a backedge)
        /// Let G = (V, E) be the original graph.
        /// Let G' = (V, E') be the subgraph of G, where E' = E \ { e | e is from E && e is backedge in the DFS traversal }.
        ///
        /// The solution is to find a cover of vertex-disjoint paths of G' that will yield the minimum number of gotos.
        /// The gotos will be the edges that are not in the cover. So we want the edges that will yeild the greatest number of gotos to
        /// be in the cover. If we find a good weight function for the edges in the graph (i.e. correctly determines how much gotos there will be between
        /// two nodes), then all we have to do is find a cover of vertex-disjoint paths of G' with maximum total weight.
        /// </remarks>
        /// <param name="theGraph"></param>
        private void DetermineFollowNodesInSubGraph(ILogicalConstruct theGraph)
        {
            //Creates the adjacency matrix for the mentioned subgraph - G'.
            GetVerticesAndAdjacencyMatrix(theGraph);

            //Since no back edge is left in G', then G' is a DAG.
            List <KeyValuePair <int, int> > followEdges = MaxWeightDisjointPathsFinder.GetOptimalEdgesInDAG(adjacencyMatrix);

            foreach (KeyValuePair <int, int> followEdge in followEdges)
            {
                orderedVertexArray[followEdge.Key].CFGFollowNode = orderedVertexArray[followEdge.Value].FirstBlock;
                if (orderedVertexArray[followEdge.Key] is ConditionLogicalConstruct)
                {
                    ConditionLogicalConstruct theCondition = orderedVertexArray[followEdge.Key] as ConditionLogicalConstruct;
                    if (theCondition.CFGFollowNode == theCondition.TrueCFGSuccessor)
                    {
                        //If the follow node of a condition construct is the true successor, then we need to negate the condition construct.
                        theCondition.Negate(typeSystem);
                    }
                }
            }
        }
 /// <summary>
 /// Finds the optimal vertex-disjoint path cover of maximum total weight of the given directed acyclic graph.
 /// </summary>
 /// <remarks>
 /// Let G = (V, E) be the graph represented by the specified <paramref name="adjacencyMatrix"/>, with weight function - W((vi, vj)) = adjacencyMatrix[i, j].
 /// Let Gb = (X, Y, Eb) is a bipartite graph where:
 /// X = { xi | vi from V }, Y = { yi | vi from V }
 /// Eb = { (xi, yj) | (vi, vj) from E }
 /// Wb((xi, yj)) = W((vi, vj)) for each (vi, vj) from E
 /// 
 /// As stated in chapter 4 in "Approximation Algorithms for Covering a Graph by Vertex-Disjoint Paths of Maximum Total Weight":
 /// The problem of findig the vertex-disjoint path cover of maximum total weight of G,
 /// can be reduced to the problem of finding a maximum weight bipartite matching of Gb.
 /// Since G is a DAG then the produced cover will be optimal. (mentioned at end of chapter 4)
 /// 
 /// Implementation details:
 /// In the implementation of the algorithms below we often need a set of all of the nodes of the graph.
 /// So we define the set Z with the following properties:
 /// |V| = |X| = |Y| = n
 /// Z = { zi | xi from X } U { z(i + n) | yi from Y }
 /// </remarks>
 /// <param name="adjacencyMatrix"></param>
 /// <returns></returns>
 public static List<KeyValuePair<int, int>> GetOptimalEdgesInDAG(int[,] adjacencyMatrix)
 {
     MaxWeightDisjointPathsFinder pathsFinder = new MaxWeightDisjointPathsFinder(adjacencyMatrix);
     return pathsFinder.MaximumWeightBipartiteGraphMatching();
 }
        /// <summary>
        /// Finds the optimal vertex-disjoint path cover of maximum total weight of the given directed acyclic graph.
        /// </summary>
        /// <remarks>
        /// Let G = (V, E) be the graph represented by the specified <paramref name="adjacencyMatrix"/>, with weight function - W((vi, vj)) = adjacencyMatrix[i, j].
        /// Let Gb = (X, Y, Eb) is a bipartite graph where:
        /// X = { xi | vi from V }, Y = { yi | vi from V }
        /// Eb = { (xi, yj) | (vi, vj) from E }
        /// Wb((xi, yj)) = W((vi, vj)) for each (vi, vj) from E
        ///
        /// As stated in chapter 4 in "Approximation Algorithms for Covering a Graph by Vertex-Disjoint Paths of Maximum Total Weight":
        /// The problem of findig the vertex-disjoint path cover of maximum total weight of G,
        /// can be reduced to the problem of finding a maximum weight bipartite matching of Gb.
        /// Since G is a DAG then the produced cover will be optimal. (mentioned at end of chapter 4)
        ///
        /// Implementation details:
        /// In the implementation of the algorithms below we often need a set of all of the nodes of the graph.
        /// So we define the set Z with the following properties:
        /// |V| = |X| = |Y| = n
        /// Z = { zi | xi from X } U { z(i + n) | yi from Y }
        /// </remarks>
        /// <param name="adjacencyMatrix"></param>
        /// <returns></returns>
        public static List <KeyValuePair <int, int> > GetOptimalEdgesInDAG(int[,] adjacencyMatrix)
        {
            MaxWeightDisjointPathsFinder pathsFinder = new MaxWeightDisjointPathsFinder(adjacencyMatrix);

            return(pathsFinder.MaximumWeightBipartiteGraphMatching());
        }