Example #1
0
        /// <summary>
        /// Gets a list of related frame element
        /// </summary>
        /// <param name="relation">Type of relation to fetch</param>
        /// <param name="relationDirection">Relation direction</param>
        /// <param name="recursive">Whether or not to recursively get related frame elements</param>
        /// <returns>List of FEs</returns>
        public FrameElementSet GetRelatedFrameElements(Frame.FrameRelation relation, Frame.FrameRelationDirection relationDirection, bool recursive)
        {
            FrameElementSet relatedFEs = new FrameElementSet();

            GetRelatedFrameElements(relation, relationDirection, recursive, relatedFEs);

            return(relatedFEs);
        }
Example #2
0
        /// <summary>
        /// Gets list of related frame elements
        /// </summary>
        /// <param name="relation">Type of relation to fetch</param>
        /// <param name="relationDirection">Relation direction</param>
        /// <param name="recursive">Whether or not to recursively get related frame elements</param>
        /// <param name="currentFEs">Current list of related FEs</param>
        private void GetRelatedFrameElements(Frame.FrameRelation relation, Frame.FrameRelationDirection relationDirection, bool recursive, FrameElementSet currentFEs)
        {
            // add sub-FEs
            if (relationDirection == Frame.FrameRelationDirection.Sub || relationDirection == Frame.FrameRelationDirection.Both)
            {
                foreach (FrameElement subFE in _relationSubFrameElements[relation])
                {
                    if (!currentFEs.Contains(subFE))
                    {
                        currentFEs.Add(subFE);

                        // recursively add sub-FEs
                        if (recursive)
                        {
                            subFE.GetRelatedFrameElements(relation, relationDirection, recursive, currentFEs);
                        }
                    }
                }
            }

            // add super-FEs
            if (relationDirection == Frame.FrameRelationDirection.Super || relationDirection == Frame.FrameRelationDirection.Both)
            {
                foreach (FrameElement superFE in _relationSuperFrameElements[relation])
                {
                    if (!currentFEs.Contains(superFE))
                    {
                        currentFEs.Add(superFE);

                        // recursively add super-FEs
                        if (recursive)
                        {
                            superFE.GetRelatedFrameElements(relation, relationDirection, recursive, currentFEs);
                        }
                    }
                }
            }
        }
Example #3
0
        /// <summary>
        /// Gets the shortest network path from the current frame element to another frame element
        /// </summary>
        /// <param name="destinationFrameElement">Destination frame element</param>
        /// <param name="searchRelations">Relations to search</param>
        /// <param name="searchDirection">Relation direction to search</param>
        /// <param name="maxDepth">Maximum depth to search within the network (i.e., maximum distance destination frame element can be from the current one)</param>
        /// <param name="frameElementPath">Path from this frame element to the destination frame element, or null for no path</param>
        /// <param name="relationPath">Relation path between this frame element and the destination frame element, or null for no path</param>
        /// <returns>True if path exists, false otherwise</returns>
        public bool GetShortestPathTo(FrameElement destinationFrameElement,
                                      Set <Frame.FrameRelation> searchRelations,
                                      Frame.FrameRelationDirection searchDirection,
                                      int maxDepth,
                                      out List <FrameElement> frameElementPath,
                                      out List <Frame.FrameRelation> relationPath)
        {
            frameElementPath = null;
            relationPath     = null;

            // breadth-first search originating at the current frame element
            Queue <FrameElement> searchQueue = new Queue <FrameElement>();

            _frameElementSearchBackPointer = null;                        // make sure to null out the source frame element back pointer
            searchQueue.Enqueue(this);

            Set <FrameElement> frameElementsEncountered = new Set <FrameElement>();  // keep track of frame elements we see so we don't enter any cycles

            frameElementsEncountered.Add(this);

            int currentDepth               = 0;  // tracks current search depth
            int nodesAtCurrentDepth        = 1;  // tracks nodes at current search depth
            int nodesAtCurrentDepthPlusOne = 0;  // tracks nodes at one beyond the current search depth

            while (searchQueue.Count > 0 && currentDepth <= maxDepth)
            {
                FrameElement currentFrameElement = searchQueue.Dequeue();

                // check for destination frame element
                if (currentFrameElement == destinationFrameElement)
                {
                    // create path by following backpointers
                    frameElementPath = new List <FrameElement>();
                    relationPath     = new List <Frame.FrameRelation>();
                    while (destinationFrameElement != null)
                    {
                        frameElementPath.Add(destinationFrameElement);

                        // back up to previous frame element
                        FrameElement previousFrameElement = destinationFrameElement.FrameElementSearchBackPointer;

                        // if the previous frame element isn't null, record the relationship
                        if (previousFrameElement != null)
                        {
                            relationPath.Add(destinationFrameElement.FrameRelationSearchBackPointer);
                        }

                        destinationFrameElement = previousFrameElement;
                    }

                    // reverse paths to be from the current to the destination frame elements
                    frameElementPath.Reverse();
                    relationPath.Reverse();

                    if (frameElementPath[0] != this)
                    {
                        throw new Exception("Path should start at current frame element");
                    }

                    if (frameElementPath.Count != relationPath.Count + 1)
                    {
                        throw new Exception("Path length mismatch between frame elements and relations");
                    }

                    if (frameElementPath.Count - 1 > maxDepth)
                    {
                        throw new Exception("Exceeded maximum allowed search depth");
                    }

                    return(true);
                }

                // queue up frame elements related to the current one by any of the given relations
                int nodesAdded = 0;
                foreach (Frame.FrameRelation searchRelation in searchRelations)
                {
                    // add sub-FEs
                    if (searchDirection == Frame.FrameRelationDirection.Sub || searchDirection == Frame.FrameRelationDirection.Both)
                    {
                        foreach (FrameElement subFE in currentFrameElement._relationSubFrameElements[searchRelation])
                        {
                            if (!frameElementsEncountered.Contains(subFE))
                            {
                                subFE._frameElementSearchBackPointer  = currentFrameElement;
                                subFE._frameRelationSearchBackPointer = searchRelation;

                                searchQueue.Enqueue(subFE);
                                frameElementsEncountered.Add(subFE);

                                ++nodesAdded;
                            }
                        }
                    }

                    // add super-FEs
                    if (searchDirection == Frame.FrameRelationDirection.Super || searchDirection == Frame.FrameRelationDirection.Both)
                    {
                        foreach (FrameElement superFE in currentFrameElement._relationSuperFrameElements[searchRelation])
                        {
                            if (!frameElementsEncountered.Contains(superFE))
                            {
                                superFE._frameElementSearchBackPointer  = currentFrameElement;
                                superFE._frameRelationSearchBackPointer = searchRelation;

                                searchQueue.Enqueue(superFE);
                                frameElementsEncountered.Add(superFE);

                                ++nodesAdded;
                            }
                        }
                    }
                }

                // all generated search nodes belong in the next depth level
                nodesAtCurrentDepthPlusOne += nodesAdded;

                // if there aren't any nodes left at the current depth level, move to next level out
                if (--nodesAtCurrentDepth == 0)
                {
                    nodesAtCurrentDepth        = nodesAtCurrentDepthPlusOne;
                    nodesAtCurrentDepthPlusOne = 0;
                    currentDepth++;
                }
            }

            return(false);
        }