private DFSTEdge[] GetForwardFlowEdges(DFSTree dfsTree) { V_0 = new DFSTEdge[dfsTree.get_TreeEdges().get_Count() + dfsTree.get_ForwardEdges().get_Count() + dfsTree.get_CrossEdges().get_Count()]; V_1 = 0; this.FillEdgesArray(V_0, dfsTree.get_TreeEdges(), ref V_1); this.FillEdgesArray(V_0, dfsTree.get_ForwardEdges(), ref V_1); this.FillEdgesArray(V_0, dfsTree.get_CrossEdges(), ref V_1); return(V_0); }
/// <summary> /// Gets an array containing the tree, forward and cross edges of the given DFS traversal tree. /// </summary> /// <param name="dfsTree">The DFS traversal tree.</param> /// <returns></returns> private DFSTEdge[] GetForwardFlowEdges(DFSTree dfsTree) { DFSTEdge[] regularEdges = new DFSTEdge[dfsTree.TreeEdges.Count + dfsTree.ForwardEdges.Count + dfsTree.CrossEdges.Count]; int index = 0; FillEdgesArray(regularEdges, dfsTree.TreeEdges, ref index); FillEdgesArray(regularEdges, dfsTree.ForwardEdges, ref index); FillEdgesArray(regularEdges, dfsTree.CrossEdges, ref index); return(regularEdges); }
/// <summary> /// Removes and edge, that is preventing the reducibillity of the graph. /// </summary> /// <param name="intervals">The graph, that can't be reduced.</param> private void RemoveBlockingEdges(List <IntervalConstruct> intervals) { //Creating this interval, so that it holds the interval tree //This way we can use the DFSTree. IntervalConstruct allIntervals = new IntervalConstruct(intervals[0]); for (int i = 1; i < intervals.Count; i++) { allIntervals.Children.Add(intervals[i]); } DFSTree dfsTree = DFSTBuilder.BuildTree(allIntervals); /// Blocking edge can be either cross edge or back edge. /// If a backedge is detected, that means it wasn't converted in loop, so it must be marked as goto. DFSTEdge edgeToDelete = dfsTree.BackEdges.FirstOrDefault(); if (edgeToDelete == null) { edgeToDelete = dfsTree.CrossEdges.FirstOrDefault(); } //both should not be null, since the DFS was ran onto intervals tree IntervalConstruct edgeStart = edgeToDelete.Start.Construct as IntervalConstruct; IntervalConstruct edgeEnd = edgeToDelete.End.Construct as IntervalConstruct; //Find all logical constructs that make the intervals have this edge between them. foreach (ILogicalConstruct edgeEndPredecessor in edgeEnd.Entry.SameParentPredecessors) { if (edgeStart.Children.Contains(edgeEndPredecessor)) { ILogicalConstruct constructEdgeStart = edgeEndPredecessor; ILogicalConstruct constructEdgeEnd = edgeEnd.Entry as ILogicalConstruct; HashSet <ILogicalConstruct> removedEdgeInfo; if (!removedEdges.TryGetValue(constructEdgeStart, out removedEdgeInfo) || !removedEdgeInfo.Contains(constructEdgeEnd)) { MarkAsGotoEdge(constructEdgeStart, constructEdgeEnd); return; } } } }
/// <summary> /// Fills the <paramref name="edgeArray"/>, strating from the given <paramref name="index"/>, with all of the elements in the /// specified <paramref name="edgeSet"/>. /// </summary> /// <param name="edgeArray"></param> /// <param name="currentSet"></param> /// <param name="index"></param> private void FillEdgesArray(DFSTEdge[] edgeArray, HashSet<DFSTEdge> edgeSet, ref int index) { foreach (DFSTEdge edge in edgeSet) { edgeArray[index++] = edge; } }
/// <summary> /// Gets an array containing the tree, forward and cross edges of the given DFS traversal tree. /// </summary> /// <param name="dfsTree">The DFS traversal tree.</param> /// <returns></returns> private DFSTEdge[] GetForwardFlowEdges(DFSTree dfsTree) { DFSTEdge[] regularEdges = new DFSTEdge[dfsTree.TreeEdges.Count + dfsTree.ForwardEdges.Count + dfsTree.CrossEdges.Count]; int index = 0; FillEdgesArray(regularEdges, dfsTree.TreeEdges, ref index); FillEdgesArray(regularEdges, dfsTree.ForwardEdges, ref index); FillEdgesArray(regularEdges, dfsTree.CrossEdges, ref index); return regularEdges; }