///////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Inserts code to get an implicit node from an edge
        /// receives insertion point, returns new insertion point
        /// </summary>
        private InterpretationPlan insertImplicitNodeFromEdge(
            InterpretationPlan insertionPoint, 
            SearchPlanEdgeNode edge,
            SearchPlanNodeNode currentNode,
            ImplicitNodeType nodeType)
        {
            int targetType = currentNode.PatternElement.TypeID;
            if (nodeType == ImplicitNodeType.Source)
            {
                currentNode.nodeMatcher = new InterpretationPlanImplicitSource(targetType, edge.edgeMatcher,
                    currentNode);
            }
            else if(nodeType == ImplicitNodeType.Target)
            {
                currentNode.nodeMatcher = new InterpretationPlanImplicitTarget(targetType, edge.edgeMatcher,
                    currentNode);
            }
            else
            {
                Debug.Assert(nodeType != ImplicitNodeType.TheOther);

                if (currentNodeIsSecondIncidentNodeOfEdge(currentNode, edge))
                {
                    currentNode.nodeMatcher = new InterpretationPlanImplicitTheOther(targetType, edge.edgeMatcher,
                        edge.PatternEdgeSource == currentNode ? edge.PatternEdgeTarget.nodeMatcher : edge.PatternEdgeSource.nodeMatcher,
                        currentNode);
                }
                else // edge connects to first incident node
                {
                    if (edge.PatternEdgeSource == edge.PatternEdgeTarget)
                    {
                        // reflexive edge without direction iteration as we don't want 2 matches 
                        currentNode.nodeMatcher = new InterpretationPlanImplicitSource(targetType, edge.edgeMatcher,
                            currentNode);
                    }
                    else
                    {
                        edge.directionVariable = new InterpretationPlanBothDirections();
                        insertionPoint.next = edge.directionVariable;
                        insertionPoint = insertionPoint.next;
                        currentNode.nodeMatcher = new InterpretationPlanImplicitSourceOrTarget(targetType, edge.edgeMatcher, 
                            edge.directionVariable, currentNode);
                    }
                }
            }

            currentNode.nodeMatcher.prev = insertionPoint;
            insertionPoint.next = currentNode.nodeMatcher;
            insertionPoint = insertionPoint.next;
            return insertionPoint;
        }
        /// <summary>
        /// returns true if both incident nodes of the edge which gets currently determined in the schedule
        /// were already computed; only of interest for edges of unfixed direction
        /// </summary>
        private bool currentEdgeConnectsToSecondIncidentNode(SearchPlanEdgeNode currentEdge)
        {
            //Debug.Assert(!currentEdge.Visited);
            Debug.Assert(!((PatternEdge)currentEdge.PatternElement).fixedDirection);

            if (currentEdge.PatternEdgeSource == null || currentEdge.PatternEdgeTarget == null)
                return false;

            if (currentEdge.PatternEdgeSource.Visited && currentEdge.PatternEdgeTarget.Visited)
                return true;

            return false;
        }
예제 #3
0
 public InterpretationPlanOutgoing(int targetType, InterpretationPlanNodeMatcher source,
     SearchPlanEdgeNode planEdgeNode)
 {
     this.targetType = targetType;
     this.source = source;
     this.planEdgeNode = planEdgeNode;
     AssignId();
 }
        /// <summary>
        /// Decides which check connectedness operations are needed for the given edge of fixed direction
        /// and inserts them into the interpretation plan
        /// receives insertion point, returns new insertion point
        /// </summary>
        private InterpretationPlan decideOnAndInsertCheckConnectednessOfEdgeFixedDirection(
            InterpretationPlan insertionPoint,
            SearchPlanEdgeNode edge,
            CheckCandidateForConnectednessType connectednessType)
        {
            Debug.Assert(connectednessType == CheckCandidateForConnectednessType.Source || connectednessType == CheckCandidateForConnectednessType.Target);

            // check whether source/target-nodes of the candidate edge
            // are the same as the already found nodes to which the edge must be incident
            // don't need to, if that node is not matched by now (signaled by visited)
            SearchPlanNodeNode nodeRequiringCheck = 
                connectednessType == CheckCandidateForConnectednessType.Source ?
                    edge.PatternEdgeSource : edge.PatternEdgeTarget;
            if (nodeRequiringCheck.Visited)
            {
                if(connectednessType == CheckCandidateForConnectednessType.Source)
                {
                    insertionPoint.next = new InterpretationPlanCheckConnectednessSource(
                            nodeRequiringCheck.nodeMatcher, edge.edgeMatcher);
                    insertionPoint = insertionPoint.next;
                }
                else //if(connectednessType == CheckCandidateForConnectednessType.Target)
                {
                    insertionPoint.next = new InterpretationPlanCheckConnectednessTarget(
                            nodeRequiringCheck.nodeMatcher, edge.edgeMatcher);
                    insertionPoint = insertionPoint.next;
                }
            }

            return insertionPoint;
        }
        /// <summary>
        /// returns true if the node which gets currently determined in the schedule
        /// is the second incident node of the edge which gets connected to it
        /// only of interest for edges of unfixed direction
        /// </summary>
        private bool currentNodeIsSecondIncidentNodeOfEdge(
            SearchPlanNodeNode currentNode, SearchPlanEdgeNode edge)
        {
            //Debug.Assert(!currentNode.Visited);
            Debug.Assert(!((PatternEdge)edge.PatternElement).fixedDirection);

            if (!edge.Visited) return false;

            if (edge.PatternEdgeSource == null || edge.PatternEdgeTarget == null)
                return false;

            if (currentNode == edge.PatternEdgeSource)
                return edge.PatternEdgeTarget.Visited;
            else
                return edge.PatternEdgeSource.Visited;
        }
        /// <summary>
        /// Decides which check connectedness operations are needed for the given node and edge of fixed direction
        /// and inserts them into the interpretation plan
        /// receives insertion point, returns new insertion point
        /// </summary>
        private InterpretationPlan decideOnAndInsertCheckConnectednessOfNodeFixedDirection(
            InterpretationPlan insertionPoint,
            SearchPlanNodeNode currentNode,
            SearchPlanEdgeNode edge,
            CheckCandidateForConnectednessType connectednessType)
        {
            Debug.Assert(connectednessType == CheckCandidateForConnectednessType.Source || connectednessType == CheckCandidateForConnectednessType.Target);

            // check whether the pattern edges which must be incident to the candidate node (according to the pattern)
            // are really incident to it
            // only if edge is already matched by now (signaled by visited)
            if (edge.Visited)
            {
                if(connectednessType == CheckCandidateForConnectednessType.Source)
                {
                    insertionPoint.next = new InterpretationPlanCheckConnectednessSource(
                            currentNode.nodeMatcher, edge.edgeMatcher);
                    insertionPoint = insertionPoint.next;
                }
                else //if(connectednessType == CheckCandidateForConnectednessType.Target)
                {
                    insertionPoint.next = new InterpretationPlanCheckConnectednessTarget(
                            currentNode.nodeMatcher, edge.edgeMatcher);
                    insertionPoint = insertionPoint.next;
                }
            }

            return insertionPoint;
        }
        /// <summary>
        /// Decides which check connectedness operations are needed for the given edge determined by lookup
        /// and inserts them into the interpretation plan
        /// receives insertion point, returns new insertion point
        /// </summary>
        private InterpretationPlan decideOnAndInsertCheckConnectednessOfEdgeFromLookup(
            InterpretationPlan insertionPoint,
            SearchPlanEdgeNode edge)
        {
            if (((PatternEdge)edge.PatternElement).fixedDirection)
            {
                // don't need to check if the edge is not required by the pattern to be incident to some given node
                if (edge.PatternEdgeSource != null)
                {
                    insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFixedDirection(insertionPoint,
                        edge, CheckCandidateForConnectednessType.Source);
                }
                if (edge.PatternEdgeTarget != null)
                {
                    insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFixedDirection(insertionPoint,
                        edge, CheckCandidateForConnectednessType.Target);
                }
            }
            else
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeBothDirections(insertionPoint,
                    edge, false);
            }

            return insertionPoint;
        }
예제 #8
0
        /// <summary>
        /// Decides which check connectedness operations are needed for the given node and edge of fixed direction
        /// and inserts them into the search program
        /// </summary>
        private SearchProgramOperation decideOnAndInsertCheckConnectednessOfNodeFixedDirection(
            SearchProgramOperation insertionPoint,
            SearchPlanNodeNode currentNode,
            SearchPlanEdgeNode edge,
            CheckCandidateForConnectednessType connectednessType)
        {
            Debug.Assert(connectednessType == CheckCandidateForConnectednessType.Source || connectednessType == CheckCandidateForConnectednessType.Target);

            // check whether the pattern edges which must be incident to the candidate node (according to the pattern)
            // are really incident to it
            // only if edge is already matched by now (signaled by visited)
            if (edge.Visited)
            {
                CheckCandidateForConnectedness checkConnectedness =
                    new CheckCandidateForConnectedness(
                        currentNode.PatternElement.Name,
                        currentNode.PatternElement.Name,
                        edge.PatternElement.Name,
                        connectednessType);
                insertionPoint = insertionPoint.Append(checkConnectedness);
            }

            return insertionPoint;
        }
예제 #9
0
        /// <summary>
        /// Decides which check connectedness operations are needed for the given node and edge in both directions
        /// and inserts them into the search program
        /// returns new insertion point and continuation point
        ///  for continuing buildup after the stuff nested within both directions iteration was built
        /// if no direction iteration was needed, insertion point == continuation point
        /// </summary>
        private SearchProgramOperation decideOnAndInsertCheckConnectednessOfNodeBothDirections(
            SearchProgramOperation insertionPoint,
            SearchPlanNodeNode currentNode,
            SearchPlanEdgeNode edge,
            out SearchProgramOperation continuationPoint)
        {
            Debug.Assert(edge.PatternEdgeSource != edge.PatternEdgeTarget);

            continuationPoint = null;

            // check whether the pattern edges which must be incident to the candidate node (according to the pattern)
            // are really incident to it
            if (currentNodeIsFirstIncidentNodeOfEdge(currentNode, edge))
            {
                BothDirectionsIteration directionsIteration =
                    new BothDirectionsIteration(edge.PatternElement.Name);
                directionsIteration.NestedOperationsList = new SearchProgramList(directionsIteration);
                continuationPoint = insertionPoint.Append(directionsIteration);

                CheckCandidateForConnectedness checkConnectedness =
                    new CheckCandidateForConnectedness(
                        currentNode.PatternElement.Name,
                        currentNode.PatternElement.Name,
                        edge.PatternElement.Name,
                        CheckCandidateForConnectednessType.SourceOrTarget);
                insertionPoint = directionsIteration.NestedOperationsList.Append(checkConnectedness);
            }
            if (currentNodeIsSecondIncidentNodeOfEdge(currentNode, edge))
            {
                CheckCandidateForConnectedness checkConnectedness =
                    new CheckCandidateForConnectedness(
                        currentNode.PatternElement.Name,
                        currentNode.PatternElement.Name,
                        edge.PatternElement.Name,
                        edge.PatternEdgeSource == currentNode ? edge.PatternEdgeTarget.PatternElement.Name
                            : edge.PatternEdgeSource.PatternElement.Name,
                        CheckCandidateForConnectednessType.TheOther);
                insertionPoint = insertionPoint.Append(checkConnectedness);
            }

            if (continuationPoint == null)
                continuationPoint = insertionPoint;

            return insertionPoint;
        }
예제 #10
0
        /// <summary>
        /// Search program operations implementing the
        /// parallelized Extend Incoming|Outgoing|IncomingOrOutgoing search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildParallelIncident(
            SearchProgramOperation insertionPoint,
            int currentOperationIndex,
            SearchPlanNodeNode source,
            SearchPlanEdgeNode target,
            IsomorphyInformation isomorphy,
            IncidentEdgeType edgeType)
        {
#if RANDOM_LOOKUP_LIST_START
            // insert list heads randomization, thus randomized extend
            RandomizeListHeads randomizeListHeads =
                new RandomizeListHeads(
                    RandomizeListHeadsTypes.IncidentEdges,
                    target.PatternElement.Name,
                    source.PatternElement.Name,
                    getIncoming);
            insertionPoint = insertionPoint.Append(randomizeListHeads);
#endif

            // iterate available incident edges
            SearchPlanNodeNode node = source;
            SearchPlanEdgeNode currentEdge = target;
            IncidentEdgeType incidentType = edgeType;
            SearchProgramOperation continuationPoint;
            GetCandidateByIterationParallel incidentIteration;
            if(incidentType == IncidentEdgeType.Incoming || incidentType == IncidentEdgeType.Outgoing)
            {
                incidentIteration = new GetCandidateByIterationParallel(
                    GetCandidateByIterationType.IncidentEdges,
                    currentEdge.PatternElement.Name,
                    node.PatternElement.Name,
                    incidentType,
                    emitProfiling,
                    packagePrefixedActionName,
                    !firstLoopPassed);
                firstLoopPassed = true;
                incidentIteration.NestedOperationsList = new SearchProgramList(incidentIteration);
                continuationPoint = insertionPoint.Append(incidentIteration);
                insertionPoint = incidentIteration.NestedOperationsList;
            }
            else // IncidentEdgeType.IncomingOrOutgoing
            {
                if(currentEdge.PatternEdgeSource == currentEdge.PatternEdgeTarget)
                {
                    // reflexive edge without direction iteration as we don't want 2 matches 
                    incidentIteration = new GetCandidateByIterationParallel(
                        GetCandidateByIterationType.IncidentEdges,
                        currentEdge.PatternElement.Name,
                        node.PatternElement.Name,
                        IncidentEdgeType.Incoming,
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
                    firstLoopPassed = true;
                    incidentIteration.NestedOperationsList = new SearchProgramList(incidentIteration);
                    continuationPoint = insertionPoint.Append(incidentIteration);
                    insertionPoint = incidentIteration.NestedOperationsList;
                }
                else
                {
                    incidentIteration = new GetCandidateByIterationParallel(
                        GetCandidateByIterationType.IncidentEdges,
                        currentEdge.PatternElement.Name,
                        node.PatternElement.Name,
                        IncidentEdgeType.IncomingOrOutgoing,
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
                    firstLoopPassed = true;
                    incidentIteration.NestedOperationsList = new SearchProgramList(incidentIteration);
                    continuationPoint = insertionPoint.Append(incidentIteration);
                    insertionPoint = incidentIteration.NestedOperationsList;
                }
            }

            // check type of candidate
            insertionPoint = decideOnAndInsertCheckType(insertionPoint, target);

            // check connectedness of candidate
            SearchProgramOperation continuationPointOfConnectednessCheck;
            insertionPoint = decideOnAndInsertCheckConnectednessOfIncidentEdgeFromNode(
                insertionPoint, target, source, edgeType == IncidentEdgeType.Incoming,
                out continuationPointOfConnectednessCheck);

            // check candidate for isomorphy 
            string negativeIndependentNamePrefix = "";
            if(isomorphy.CheckIsMatchedBit)
            {
                CheckCandidateForIsomorphy checkIsomorphy =
                    new CheckCandidateForIsomorphy(
                        target.PatternElement.Name,
                        isomorphy.PatternElementsToCheckAgainstAsListOfStrings(),
                        negativeIndependentNamePrefix,
                        false,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // accept candidate (write isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            {
                AcceptCandidate acceptCandidate =
                    new AcceptCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        false,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(acceptCandidate);
            }

            // mark element as visited
            target.Visited = true;

            //---------------------------------------------------------------------------
            // build next operation
            insertionPoint = BuildScheduledSearchPlanOperationIntoSearchProgram(
                currentOperationIndex + 1,
                insertionPoint);
            //---------------------------------------------------------------------------

            // unmark element for possibly following run
            target.Visited = false;

            // abandon candidate (restore isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            { // only if isomorphy information was previously written
                AbandonCandidate abandonCandidate =
                    new AbandonCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        false,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(abandonCandidate);
            }

            // everything nested within incident iteration built by now -
            // continue at the end of the list after incident edges iteration
            insertionPoint = continuationPoint;

            return insertionPoint;
        }
예제 #11
0
        /// <summary>
        /// Inserts code to get an implicit node from an edge
        /// </summary>
        private SearchProgramOperation insertImplicitNodeFromEdge(
            SearchProgramOperation insertionPoint,
            SearchPlanEdgeNode edge,
            SearchPlanNodeNode currentNode,
            ImplicitNodeType nodeType,
            out SearchProgramOperation continuationPoint)
        {
            continuationPoint = null;

            GetCandidateByDrawing nodeFromEdge;
            if (nodeType == ImplicitNodeType.Source || nodeType == ImplicitNodeType.Target)
            {
                nodeFromEdge = new GetCandidateByDrawing(
                    GetCandidateByDrawingType.NodeFromEdge,
                    currentNode.PatternElement.Name,
                    TypesHelper.XgrsTypeToCSharpTypeNodeEdge(model.NodeModel.Types[currentNode.PatternElement.TypeID].PackagePrefixedName),
                    edge.PatternElement.Name,
                    nodeType);
                insertionPoint = insertionPoint.Append(nodeFromEdge);
            }
            else
            {
                Debug.Assert(nodeType != ImplicitNodeType.TheOther);

                if (currentNodeIsSecondIncidentNodeOfEdge(currentNode, edge))
                {
                    nodeFromEdge = new GetCandidateByDrawing(
                        GetCandidateByDrawingType.NodeFromEdge,
                        currentNode.PatternElement.Name,
                        TypesHelper.XgrsTypeToCSharpTypeNodeEdge(model.NodeModel.Types[currentNode.PatternElement.TypeID].PackagePrefixedName),
                        edge.PatternElement.Name,
                        edge.PatternEdgeSource == currentNode ? edge.PatternEdgeTarget.PatternElement.Name
                            : edge.PatternEdgeSource.PatternElement.Name,
                        ImplicitNodeType.TheOther);
                    insertionPoint = insertionPoint.Append(nodeFromEdge);
                }
                else // edge connects to first incident node
                {
                    if (edge.PatternEdgeSource == edge.PatternEdgeTarget)
                    {
                        // reflexive edge without direction iteration as we don't want 2 matches 
                        nodeFromEdge = new GetCandidateByDrawing(
                            GetCandidateByDrawingType.NodeFromEdge,
                            currentNode.PatternElement.Name,
                            TypesHelper.XgrsTypeToCSharpTypeNodeEdge(model.NodeModel.Types[currentNode.PatternElement.TypeID].PackagePrefixedName),
                            edge.PatternElement.Name,
                            ImplicitNodeType.Source);
                        insertionPoint = insertionPoint.Append(nodeFromEdge);
                    }
                    else
                    {
                        BothDirectionsIteration directionsIteration =
                            new BothDirectionsIteration(edge.PatternElement.Name);
                        directionsIteration.NestedOperationsList = new SearchProgramList(directionsIteration);
                        continuationPoint = insertionPoint.Append(directionsIteration);
                        insertionPoint = directionsIteration.NestedOperationsList;

                        nodeFromEdge = new GetCandidateByDrawing(
                            GetCandidateByDrawingType.NodeFromEdge,
                            currentNode.PatternElement.Name,
                            TypesHelper.XgrsTypeToCSharpTypeNodeEdge(model.NodeModel.Types[currentNode.PatternElement.TypeID].PackagePrefixedName),
                            edge.PatternElement.Name,
                            ImplicitNodeType.SourceOrTarget);
                        insertionPoint = insertionPoint.Append(nodeFromEdge);
                    }
                }
            }

            if (continuationPoint == null)
                continuationPoint = insertionPoint;

            return insertionPoint;
        }
예제 #12
0
        /// <summary>
        /// Search program operations implementing the
        /// setup parallelized Extend Incoming|Outgoing|IncomingOrOutgoing search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildParallelIncidentSetup(
            SearchProgramOperation insertionPoint,
            SearchPlanNodeNode source,
            SearchPlanEdgeNode target,
            IncidentEdgeType edgeType)
        {
            // iterate available incident edges
            SearchPlanNodeNode node = source;
            SearchPlanEdgeNode currentEdge = target;
            IncidentEdgeType incidentType = edgeType;
            GetCandidateByIterationParallelSetup incidentIteration;
            PatternGraph patternGraph = patternGraphWithNestingPatterns.Peek();

            if(incidentType == IncidentEdgeType.Incoming || incidentType == IncidentEdgeType.Outgoing)
            {
                incidentIteration = new GetCandidateByIterationParallelSetup(
                    GetCandidateByIterationType.IncidentEdges,
                    currentEdge.PatternElement.Name,
                    node.PatternElement.Name,
                    incidentType,
                    rulePatternClassName,
                    patternGraph.name,
                    parameterNames,
                    false,
                    wasIndependentInlined(patternGraph, indexOfSchedule),
                    emitProfiling,
                    packagePrefixedActionName,
                    !firstLoopPassed);
                return insertionPoint.Append(incidentIteration);
            }
            else // IncidentEdgeType.IncomingOrOutgoing
            {
                if(currentEdge.PatternEdgeSource == currentEdge.PatternEdgeTarget)
                {
                    // reflexive edge without direction iteration as we don't want 2 matches 
                    incidentIteration = new GetCandidateByIterationParallelSetup(
                        GetCandidateByIterationType.IncidentEdges,
                        currentEdge.PatternElement.Name,
                        node.PatternElement.Name,
                        IncidentEdgeType.Incoming,
                        rulePatternClassName,
                        patternGraph.name,
                        parameterNames,
                        false,
                        wasIndependentInlined(patternGraph, indexOfSchedule),
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
                    return insertionPoint.Append(incidentIteration);
                }
                else
                {
                    BothDirectionsIteration directionsIteration =
                        new BothDirectionsIteration(currentEdge.PatternElement.Name);
                    directionsIteration.NestedOperationsList = new SearchProgramList(directionsIteration);
                    SearchProgramOperation continuationPoint = insertionPoint.Append(directionsIteration);
                    insertionPoint = directionsIteration.NestedOperationsList;

                    incidentIteration = new GetCandidateByIterationParallelSetup(
                        GetCandidateByIterationType.IncidentEdges,
                        currentEdge.PatternElement.Name,
                        node.PatternElement.Name,
                        IncidentEdgeType.IncomingOrOutgoing,
                        rulePatternClassName,
                        patternGraph.name,
                        parameterNames,
                        true,
                        wasIndependentInlined(patternGraph, indexOfSchedule),
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
                    return insertionPoint.Append(incidentIteration);
                }
            }
        }
예제 #13
0
        /// <summary>
        /// Search program operations implementing the
        /// Implicit Source|Target|SourceOrTarget search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildImplicit(
            SearchProgramOperation insertionPoint,
            int currentOperationIndex,
            SearchPlanEdgeNode source,
            SearchPlanNodeNode target,
            IsomorphyInformation isomorphy,
            ImplicitNodeType nodeType)
        {
            // get candidate = demanded node from edge
            SearchProgramOperation continuationPoint;
            insertionPoint = insertImplicitNodeFromEdge(insertionPoint, source, target, nodeType,
                out continuationPoint);
            if (continuationPoint == insertionPoint)
                continuationPoint = null;

            // check type of candidate
            insertionPoint = decideOnAndInsertCheckType(insertionPoint, target);

            // check connectedness of candidate
            SearchProgramOperation continuationPointAfterConnectednessCheck;
            SearchPlanNodeNode otherNodeOfOriginatingEdge = null;
            if (nodeType == ImplicitNodeType.Source) otherNodeOfOriginatingEdge = source.PatternEdgeTarget;
            if (nodeType == ImplicitNodeType.Target) otherNodeOfOriginatingEdge = source.PatternEdgeSource;
            if (source.PatternEdgeTarget == source.PatternEdgeSource) // reflexive sign needed in unfixed direction case, too
                otherNodeOfOriginatingEdge = source.PatternEdgeSource;
            insertionPoint = decideOnAndInsertCheckConnectednessOfImplicitNodeFromEdge(
                insertionPoint, target, source, otherNodeOfOriginatingEdge, out continuationPointAfterConnectednessCheck);
            if (continuationPoint == null && continuationPointAfterConnectednessCheck != insertionPoint)
                continuationPoint = continuationPointAfterConnectednessCheck;

            // check candidate for isomorphy 
            string negativeIndependentNamePrefix = NegativeIndependentNamePrefix(patternGraphWithNestingPatterns.Peek());
            if (isomorphy.CheckIsMatchedBit)
            {
                CheckCandidateForIsomorphy checkIsomorphy =
                    new CheckCandidateForIsomorphy(
                        target.PatternElement.Name,
                        isomorphy.PatternElementsToCheckAgainstAsListOfStrings(),
                        negativeIndependentNamePrefix,
                        true,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // check candidate for global isomorphy 
            if (programType == SearchProgramType.Subpattern 
                || programType == SearchProgramType.AlternativeCase
                || programType == SearchProgramType.Iterated)
            {
                if(!isomorphy.TotallyHomomorph)
                {
                    CheckCandidateForIsomorphyGlobal checkIsomorphy =
                        new CheckCandidateForIsomorphyGlobal(
                            target.PatternElement.Name,
                            isomorphy.GloballyHomomorphPatternElementsAsListOfStrings(),
                            true,
                            isoSpaceNeverAboveMaxIsoSpace,
                            isomorphy.Parallel);
                    insertionPoint = insertionPoint.Append(checkIsomorphy);
                }
            }

            // check candidate for pattern path isomorphy
            if(patternGraphWithNestingPatterns.Peek().isPatternGraphOnPathFromEnclosingPatternpath)
            {
                CheckCandidateForIsomorphyPatternPath checkIsomorphy =
                    new CheckCandidateForIsomorphyPatternPath(
                        target.PatternElement.Name,
                        true,
                        patternGraphWithNestingPatterns.Peek().isPatternpathLocked,
                        getCurrentLastMatchAtPreviousNestingLevel());
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // accept candidate (write isomorphy information)
            if (isomorphy.SetIsMatchedBit)
            {
                AcceptCandidate acceptCandidate =
                    new AcceptCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        true,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(acceptCandidate);
            }

            // mark element as visited
            target.Visited = true;

            //---------------------------------------------------------------------------
            // build next operation
            insertionPoint = BuildScheduledSearchPlanOperationIntoSearchProgram(
                currentOperationIndex + 1,
                insertionPoint);
            //---------------------------------------------------------------------------

            // unmark element for possibly following run
            target.Visited = false;

            // abandon candidate (restore isomorphy information)
            if (isomorphy.SetIsMatchedBit)
            { // only if isomorphy information was previously written
                AbandonCandidate abandonCandidate =
                    new AbandonCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        true,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(abandonCandidate);
            }

            if (continuationPoint != null)
                insertionPoint = continuationPoint;

            return insertionPoint;
        }
예제 #14
0
 public InterpretationPlanIncomingOrOutgoing(int targetType, InterpretationPlanNodeMatcher source,
     InterpretationPlanDirectionVariable directionVariable, SearchPlanEdgeNode planEdgeNode)
 {
     this.targetType = targetType;
     this.source = source;
     this.directionVariable = directionVariable;
     this.planEdgeNode = planEdgeNode;
     AssignId();
 }
예제 #15
0
        /// <summary>
        /// Inserts code to get an incident edge from some node
        /// receives insertion point, returns new insertion point
        /// </summary>
        private InterpretationPlan insertIncidentEdgeFromNode(
            InterpretationPlan insertionPoint, 
            SearchPlanNodeNode node,
            SearchPlanEdgeNode currentEdge,
            IncidentEdgeType incidentType)
        {
            int targetType = currentEdge.PatternElement.TypeID;
            if (incidentType == IncidentEdgeType.Incoming)
            {
                currentEdge.edgeMatcher = new InterpretationPlanIncoming(targetType, node.nodeMatcher,
                    currentEdge);
            }
            else if(incidentType == IncidentEdgeType.Outgoing)
            {
                currentEdge.edgeMatcher = new InterpretationPlanOutgoing(targetType, node.nodeMatcher,
                    currentEdge);
            }
            else // IncidentEdgeType.IncomingOrOutgoing
            {
                if (currentEdge.PatternEdgeSource == currentEdge.PatternEdgeTarget)
                {
                    // reflexive edge without direction iteration as we don't want 2 matches 
                    currentEdge.edgeMatcher = new InterpretationPlanIncoming(targetType, node.nodeMatcher,
                        currentEdge);
                }
                else
                {
                    currentEdge.directionVariable = new InterpretationPlanBothDirections();
                    insertionPoint.next = currentEdge.directionVariable;
                    insertionPoint = insertionPoint.next;
                    currentEdge.edgeMatcher = new InterpretationPlanIncomingOrOutgoing(targetType, node.nodeMatcher, 
                        currentEdge.directionVariable, currentEdge);
                }
            }

            currentEdge.edgeMatcher.prev = insertionPoint;
            insertionPoint.next = currentEdge.edgeMatcher;
            insertionPoint = insertionPoint.next;
            return insertionPoint;
        }
예제 #16
0
        /// <summary>
        /// Decides which check connectedness operations are needed for the given edge determined by lookup
        /// and inserts them into the search program
        /// returns new insertion point and continuation point
        ///  for continuing buildup after the stuff nested within both directions iteration was built
        /// if no direction iteration was needed, insertion point == continuation point
        /// </summary>
        private SearchProgramOperation decideOnAndInsertCheckConnectednessOfEdgeFromLookupOrPickOrMap(
            SearchProgramOperation insertionPoint,
            SearchPlanEdgeNode edge,
            out SearchProgramOperation continuationPoint)
        {
            continuationPoint = null;

            if (((PatternEdge)edge.PatternElement).fixedDirection)
            {
                // don't need to check if the edge is not required by the pattern to be incident to some given node
                if (edge.PatternEdgeSource != null)
                {
                    insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFixedDirection(
                        insertionPoint, edge, CheckCandidateForConnectednessType.Source);
                }
                if (edge.PatternEdgeTarget != null)
                {
                    insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFixedDirection(
                        insertionPoint, edge, CheckCandidateForConnectednessType.Target);
                }
            }
            else
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeBothDirections(
                    insertionPoint, edge, false, out continuationPoint);
            }

            if (continuationPoint == null)
                continuationPoint = insertionPoint;

            return insertionPoint;
        }
예제 #17
0
        /// <summary>
        /// Decides which check connectedness operations are needed for the given node just drawn from edge
        /// and inserts them into the interpretation plan
        /// receives insertion point, returns new insertion point
        /// </summary>
        private InterpretationPlan decideOnAndInsertCheckConnectednessOfImplicitNodeFromEdge(
            InterpretationPlan insertionPoint,
            SearchPlanNodeNode node,
            SearchPlanEdgeNode originatingEdge,
            SearchPlanNodeNode otherNodeOfOriginatingEdge)
        {
            // check for edges required by the pattern to be incident to the given node
            // only if the node was not taken from the given originating edge
            //   with the exception of reflexive edges, as these won't get checked thereafter
            foreach (SearchPlanEdgeNode edge in node.OutgoingPatternEdges)
            {
                if (((PatternEdge)edge.PatternElement).fixedDirection
                    || edge.PatternEdgeSource == edge.PatternEdgeTarget)
                {
                    if (edge != originatingEdge || node == otherNodeOfOriginatingEdge)
                    {
                        insertionPoint = decideOnAndInsertCheckConnectednessOfNodeFixedDirection(insertionPoint,
                            node, edge, CheckCandidateForConnectednessType.Source);
                    }
                }
                else
                {
                    if (edge != originatingEdge || node == otherNodeOfOriginatingEdge)
                    {
                        insertionPoint = decideOnAndInsertCheckConnectednessOfNodeBothDirections(insertionPoint,
                            node, edge);
                    }
                }
            }
            foreach (SearchPlanEdgeNode edge in node.IncomingPatternEdges)
            {
                if (((PatternEdge)edge.PatternElement).fixedDirection
                    || edge.PatternEdgeSource == edge.PatternEdgeTarget)
                {
                    if (edge != originatingEdge || node == otherNodeOfOriginatingEdge)
                    {
                        insertionPoint = decideOnAndInsertCheckConnectednessOfNodeFixedDirection(insertionPoint,
                            node, edge, CheckCandidateForConnectednessType.Target);
                    }
                }
                else
                {
                    if (edge != originatingEdge || node == otherNodeOfOriginatingEdge)
                    {
                        insertionPoint = decideOnAndInsertCheckConnectednessOfNodeBothDirections(insertionPoint,
                            node, edge);
                    }
                }
            }

            return insertionPoint;
        }
예제 #18
0
        /// <summary>
        /// Decides which check connectedness operations are needed for the given edge of fixed direction
        /// and inserts them into the search program
        /// </summary>
        private SearchProgramOperation decideOnAndInsertCheckConnectednessOfEdgeFixedDirection(
            SearchProgramOperation insertionPoint,
            SearchPlanEdgeNode edge,
            CheckCandidateForConnectednessType connectednessType)
        {
            // check whether source/target-nodes of the candidate edge
            // are the same as the already found nodes to which the edge must be incident
            // don't need to, if that node is not matched by now (signaled by visited)
            SearchPlanNodeNode nodeRequiringCheck = 
                connectednessType == CheckCandidateForConnectednessType.Source ?
                    edge.PatternEdgeSource : edge.PatternEdgeTarget;
            if (nodeRequiringCheck.Visited)
            {
                CheckCandidateForConnectedness checkConnectedness =
                    new CheckCandidateForConnectedness(
                        edge.PatternElement.Name,
                        nodeRequiringCheck.PatternElement.Name,
                        edge.PatternElement.Name,
                        connectednessType);
                insertionPoint = insertionPoint.Append(checkConnectedness);
            }

            return insertionPoint;
        }
예제 #19
0
        /// <summary>
        /// Decides which check connectedness operations are needed for the given node and edge in both directions
        /// and inserts them into the interpretation plan
        /// receives insertion point, returns new insertion point
        /// </summary>
        private InterpretationPlan decideOnAndInsertCheckConnectednessOfNodeBothDirections(
            InterpretationPlan insertionPoint,
            SearchPlanNodeNode currentNode,
            SearchPlanEdgeNode edge)
        {
            Debug.Assert(edge.PatternEdgeSource != edge.PatternEdgeTarget);

            // check whether the pattern edges which must be incident to the candidate node (according to the pattern)
            // are really incident to it
            if (currentNodeIsFirstIncidentNodeOfEdge(currentNode, edge))
            {
                edge.directionVariable = new InterpretationPlanBothDirections();
                insertionPoint.next = edge.directionVariable;
                insertionPoint = insertionPoint.next;
                insertionPoint.next = new InterpretationPlanCheckConnectednessSourceOrTarget(
                        currentNode.nodeMatcher, edge.edgeMatcher, edge.directionVariable);
                insertionPoint = insertionPoint.next;
            }
            if (currentNodeIsSecondIncidentNodeOfEdge(currentNode, edge))
            {
                insertionPoint.next = new InterpretationPlanCheckConnectednessTheOther(
                        currentNode.nodeMatcher, edge.edgeMatcher,
                        edge.PatternEdgeSource == currentNode ? edge.PatternEdgeTarget.nodeMatcher : edge.PatternEdgeSource.nodeMatcher);
                insertionPoint = insertionPoint.next;
            }

            return insertionPoint;
        }
예제 #20
0
        /// <summary>
        /// Decides which check connectedness operations are needed for the given edge in both directions
        /// and inserts them into the search program
        /// returns new insertion point and continuation point
        ///  for continuing buildup after the stuff nested within both directions iteration was built
        /// todo: if no direction iteration was needed, insertion point == continuation point ?
        /// </summary>
        private SearchProgramOperation decideOnAndInsertCheckConnectednessOfEdgeBothDirections(
            SearchProgramOperation insertionPoint,
            SearchPlanEdgeNode edge,
            bool edgeDeterminationContainsFirstNodeLoop,
            out SearchProgramOperation continuationPoint)
        {
            continuationPoint = null;

            // check whether source/target-nodes of the candidate edge
            // are the same as the already found nodes to which the edge must be incident
            if (!edgeDeterminationContainsFirstNodeLoop && currentEdgeConnectsToFirstIncidentNode(edge))
            {
                // due to currentEdgeConnectsToFirstIncidentNode: at least on incident node available
                if (edge.PatternEdgeSource == edge.PatternEdgeTarget)
                {
                    // reflexive edge without direction iteration as we don't want 2 matches 
                    SearchPlanNodeNode nodeRequiringFirstNodeLoop = edge.PatternEdgeSource != null ?
                        edge.PatternEdgeSource : edge.PatternEdgeTarget;
                    CheckCandidateForConnectedness checkConnectedness =
                        new CheckCandidateForConnectedness(
                            edge.PatternElement.Name,
                            nodeRequiringFirstNodeLoop.PatternElement.Name,
                            edge.PatternElement.Name,
                            CheckCandidateForConnectednessType.Source); // might be Target as well
                    insertionPoint = insertionPoint.Append(checkConnectedness);
                }
                else
                {
                    BothDirectionsIteration directionsIteration =
                       new BothDirectionsIteration(edge.PatternElement.Name);
                    directionsIteration.NestedOperationsList = new SearchProgramList(directionsIteration);
                    continuationPoint = insertionPoint.Append(directionsIteration);
                    insertionPoint = directionsIteration.NestedOperationsList;

                    SearchPlanNodeNode nodeRequiringFirstNodeLoop = edge.PatternEdgeSource != null ?
                        edge.PatternEdgeSource : edge.PatternEdgeTarget;
                    CheckCandidateForConnectedness checkConnectedness =
                        new CheckCandidateForConnectedness(
                            edge.PatternElement.Name,
                            nodeRequiringFirstNodeLoop.PatternElement.Name,
                            edge.PatternElement.Name,
                            CheckCandidateForConnectednessType.SourceOrTarget);
                    insertionPoint = insertionPoint.Append(checkConnectedness);
                }
            }
            if (currentEdgeConnectsToSecondIncidentNode(edge))
            {
                // due to currentEdgeConnectsToSecondIncidentNode: both incident node available
                CheckCandidateForConnectedness checkConnectedness =
                    new CheckCandidateForConnectedness(
                        edge.PatternElement.Name,
                        edge.PatternEdgeTarget.PatternElement.Name,
                        edge.PatternElement.Name,
                        edge.PatternEdgeSource.PatternElement.Name,
                        CheckCandidateForConnectednessType.TheOther);
                insertionPoint = insertionPoint.Append(checkConnectedness);
            }

            return insertionPoint;
        }
예제 #21
0
        /// <summary>
        /// Decides which check connectedness operations are needed for the given edge determined from incident node
        /// and inserts them into the interpretation plan
        /// receives insertion point, returns new insertions point
        /// </summary>
        private InterpretationPlan decideOnAndInsertCheckConnectednessOfIncidentEdgeFromNode(
            InterpretationPlan insertionPoint,
            SearchPlanEdgeNode edge,
            SearchPlanNodeNode originatingNode,
            bool edgeIncomingAtOriginatingNode)
        {
            if (((PatternEdge)edge.PatternElement).fixedDirection)
            {
                // don't need to check if the edge is not required by the pattern to be incident to some given node
                // or if the edge was taken from the given originating node
                if (edge.PatternEdgeSource != null)
                {
                    if (!(!edgeIncomingAtOriginatingNode
                            && edge.PatternEdgeSource == originatingNode))
                    {
                        insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFixedDirection(insertionPoint,
                            edge, CheckCandidateForConnectednessType.Source);
                    }
                }
                if (edge.PatternEdgeTarget != null)
                {
                    if (!(edgeIncomingAtOriginatingNode
                            && edge.PatternEdgeTarget == originatingNode))
                    {
                        insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFixedDirection(insertionPoint,
                            edge, CheckCandidateForConnectednessType.Target);
                    }
                }
            }
            else
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeBothDirections(insertionPoint,
                    edge, true);
            }

            return insertionPoint;
        }
예제 #22
0
        /// <summary>
        /// Interpretation plan operations implementing the
        /// Lookup edge search plan operation
        /// are created and inserted into the interpretation plan at the insertion point
        /// </summary>
        private void buildLookup(
            InterpretationPlan insertionPoint, int index,
            SearchPlanEdgeNode target)
        {
            // get candidate = iterate available edges
            target.edgeMatcher = new InterpretationPlanLookupEdge(target.PatternElement.TypeID, target);
            target.edgeMatcher.prev = insertionPoint;
            insertionPoint.next = target.edgeMatcher;
            insertionPoint = insertionPoint.next;

            // check connectedness of candidate
            insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFromLookup(insertionPoint,
                target);

            // continue with next operation
            target.Visited = true;
            BuildInterpretationPlan(insertionPoint, index + 1);
            target.Visited = false;
        }
예제 #23
0
        /// <summary>
        /// Decides which check connectedness operations are needed for the given edge in both directions
        /// and inserts them into the interpretation plan
        /// receives insertion point, returns new insertion point
        /// </summary>
        private InterpretationPlan decideOnAndInsertCheckConnectednessOfEdgeBothDirections(
            InterpretationPlan insertionPoint,
            SearchPlanEdgeNode edge,
            bool edgeDeterminationContainsFirstNodeLoop)
        {
            // check whether source/target-nodes of the candidate edge
            // are the same as the already found nodes to which the edge must be incident
            if (!edgeDeterminationContainsFirstNodeLoop && currentEdgeConnectsToFirstIncidentNode(edge))
            {
                SearchPlanNodeNode nodeRequiringFirstNodeLoop = edge.PatternEdgeSource != null ?
                    edge.PatternEdgeSource : edge.PatternEdgeTarget;

                // due to currentEdgeConnectsToFirstIncidentNode: at least on incident node available
                if (edge.PatternEdgeSource == edge.PatternEdgeTarget)
                {
                    // reflexive edge without direction iteration as we don't want 2 matches 
                    insertionPoint.next = new InterpretationPlanCheckConnectednessSource(
                            nodeRequiringFirstNodeLoop.nodeMatcher, edge.edgeMatcher); // might be Target as well
                    insertionPoint = insertionPoint.next;
                }
                else
                {
                    edge.directionVariable = new InterpretationPlanBothDirections();
                    insertionPoint.next = edge.directionVariable;
                    insertionPoint = insertionPoint.next;
                    insertionPoint.next = new InterpretationPlanCheckConnectednessSourceOrTarget(
                            nodeRequiringFirstNodeLoop.nodeMatcher, edge.edgeMatcher, edge.directionVariable);
                    insertionPoint = insertionPoint.next;
                }
            }
            if (currentEdgeConnectsToSecondIncidentNode(edge))
            {
                // due to currentEdgeConnectsToSecondIncidentNode: both incident node available
                insertionPoint.next = new InterpretationPlanCheckConnectednessTheOther(
                        edge.PatternEdgeTarget.nodeMatcher, edge.edgeMatcher, edge.PatternEdgeSource.nodeMatcher);
                insertionPoint = insertionPoint.next;
            }

            return insertionPoint;
        }
예제 #24
0
        /// <summary>
        /// Interpretation plan operations implementing the
        /// Implicit Source|Target|SourceOrTarget search plan operation
        /// are created and inserted into the interpretation plan at the insertion point
        /// </summary>
        private void buildImplicit(
            InterpretationPlan insertionPoint, int index,
            SearchPlanEdgeNode source,
            SearchPlanNodeNode target,
            ImplicitNodeType nodeType)
        {
            // get candidate = demanded node from edge
            insertionPoint = insertImplicitNodeFromEdge(insertionPoint,
                source, target, nodeType);

            // check connectedness of candidate
            SearchPlanNodeNode otherNodeOfOriginatingEdge = null;
            if (nodeType == ImplicitNodeType.Source) otherNodeOfOriginatingEdge = source.PatternEdgeTarget;
            if (nodeType == ImplicitNodeType.Target) otherNodeOfOriginatingEdge = source.PatternEdgeSource;
            if (source.PatternEdgeTarget == source.PatternEdgeSource) // reflexive sign needed in unfixed direction case, too
                otherNodeOfOriginatingEdge = source.PatternEdgeSource;
            insertionPoint = decideOnAndInsertCheckConnectednessOfImplicitNodeFromEdge(insertionPoint,
                target, source, otherNodeOfOriginatingEdge);

            // continue with next operation
            target.Visited = true;
            BuildInterpretationPlan(insertionPoint, index + 1);
            target.Visited = false;
        }
예제 #25
0
        /// <summary>
        /// returns true if only one incident node of the edge which gets currently determined in the schedule
        /// was already computed; only of interest for edges of unfixed direction
        /// </summary>
        private bool currentEdgeConnectsOnlyToFirstIncidentNode(SearchPlanEdgeNode currentEdge)
        {
            //Debug.Assert(!currentEdge.Visited);
            Debug.Assert(!((PatternEdge)currentEdge.PatternElement).fixedDirection);

            if (currentEdge.PatternEdgeSource != null && currentEdge.PatternEdgeSource.Visited
                && (currentEdge.PatternEdgeTarget == null || !currentEdge.PatternEdgeTarget.Visited))
            {
                return true;
            }
            if (currentEdge.PatternEdgeTarget != null && currentEdge.PatternEdgeTarget.Visited
                && (currentEdge.PatternEdgeSource == null || !currentEdge.PatternEdgeSource.Visited))
            {
                return true;
            }

            return false;
        }
예제 #26
0
        /// <summary>
        /// Interpretation plan operations implementing the
        /// Extend Incoming|Outgoing|IncomingOrOutgoing search plan operation
        /// are created and inserted into the interpretation plan at the insertion point
        /// </summary>
        private void buildIncident(
            InterpretationPlan insertionPoint, int index,
            SearchPlanNodeNode source,
            SearchPlanEdgeNode target,
            IncidentEdgeType edgeType)
        {
            // get candidate = iterate available incident edges
            insertionPoint = insertIncidentEdgeFromNode(insertionPoint,
                source, target, edgeType);

            // check connectedness of candidate
            insertionPoint = decideOnAndInsertCheckConnectednessOfIncidentEdgeFromNode(insertionPoint,
                target, source, edgeType==IncidentEdgeType.Incoming);

            // continue with next operation
            target.Visited = true;
            BuildInterpretationPlan(insertionPoint, index + 1);
            target.Visited = false;
        }
예제 #27
0
        /// <summary>
        /// Generate search plan graph out of the plan graph,
        /// search plan graph only contains edges chosen by the MSA algorithm.
        /// Edges in search plan graph are given in the nodes by outgoing list, as needed for scheduling,
        /// in contrast to incoming list in plan graph, as needed for MSA computation.
        /// </summary>
        /// <param name="planGraph">The source plan graph</param>
        /// <returns>A new search plan graph</returns>
        public SearchPlanGraph GenerateSearchPlanGraph(PlanGraph planGraph)
        {
            SearchPlanNode searchPlanRoot = new SearchPlanNode("search plan root");
            SearchPlanNode[] searchPlanNodes = new SearchPlanNode[planGraph.Nodes.Length];
            SearchPlanEdge[] searchPlanEdges = new SearchPlanEdge[planGraph.Nodes.Length - 1 + 1]; // +1 for root
            Dictionary<PlanNode, SearchPlanNode> planToSearchPlanNode = // for generating edges
                new Dictionary<PlanNode, SearchPlanNode>(planGraph.Nodes.Length);
            planToSearchPlanNode.Add(planGraph.Root, searchPlanRoot);

            // generate the search plan graph nodes, same as plan graph nodes,
            // representing pattern graph nodes and edges
            int i = 0;
            foreach(PlanNode planNode in planGraph.Nodes)
            {
                if(planNode.NodeType == PlanNodeType.Edge)
                    searchPlanNodes[i] = new SearchPlanEdgeNode(planNode, null, null);
                else
                    searchPlanNodes[i] = new SearchPlanNodeNode(planNode);
                planToSearchPlanNode.Add(planNode, searchPlanNodes[i]);

                ++i;
            }

            // generate the search plan graph edges, 
            // that are the plan graph edges chosen by the MSA algorithm, in reversed direction
            // and add references to originating pattern elements
            i = 0;
            foreach(PlanNode planNode in planGraph.Nodes)
            {
                PlanEdge planEdge = planNode.IncomingMSAEdge;
                searchPlanEdges[i] = new SearchPlanEdge(planEdge.Type, planToSearchPlanNode[planEdge.Source], planToSearchPlanNode[planEdge.Target], planEdge.Cost);
                planToSearchPlanNode[planEdge.Source].OutgoingEdges.Add(searchPlanEdges[i]);

                if(planNode.NodeType == PlanNodeType.Edge)
                {
                    SearchPlanEdgeNode searchPlanEdgeNode = (SearchPlanEdgeNode) planToSearchPlanNode[planNode];
                    SearchPlanNode patElem;
                    if(planEdge.Target.PatternEdgeSource != null 
                        && planToSearchPlanNode.TryGetValue(planEdge.Target.PatternEdgeSource, out patElem))
                    {
                        searchPlanEdgeNode.PatternEdgeSource = (SearchPlanNodeNode) patElem;
                        searchPlanEdgeNode.PatternEdgeSource.OutgoingPatternEdges.Add(searchPlanEdgeNode);
                    }
                    if(planEdge.Target.PatternEdgeTarget != null 
                        && planToSearchPlanNode.TryGetValue(planEdge.Target.PatternEdgeTarget, out patElem))
                    {
                        searchPlanEdgeNode.PatternEdgeTarget = (SearchPlanNodeNode) patElem;
                        searchPlanEdgeNode.PatternEdgeTarget.IncomingPatternEdges.Add(searchPlanEdgeNode);
                    }
                }

                ++i;
            }

            return new SearchPlanGraph(searchPlanRoot, searchPlanNodes, searchPlanEdges);
        }
예제 #28
0
 public InterpretationPlanLookupEdge(int targetType, SearchPlanEdgeNode planEdgeNode)
 {
     this.targetType = targetType;
     this.planEdgeNode = planEdgeNode;
     AssignId();
 }