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

        /// <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>
        /// 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);
        }
Esempio n. 3
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;
        }
Esempio n. 4
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;
        }
Esempio n. 5
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);
        }
Esempio n. 6
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);
        }
Esempio n. 7
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);
        }
Esempio n. 8
0
        /// <summary>
        /// Decides which check connectedness operations are needed for the given node just determined by lookup
        /// and inserts them into the interpretation plan
        /// receives insertion point, returns new insertion point
        /// </summary>
        private InterpretationPlan decideOnAndInsertCheckConnectednessOfNodeFromLookup(
            InterpretationPlan insertionPoint,
            SearchPlanNodeNode node)
        {
            // check for edges required by the pattern to be incident to the given node
            foreach (SearchPlanEdgeNode edge in node.OutgoingPatternEdges)
            {
                if (((PatternEdge)edge.PatternElement).fixedDirection ||
                    edge.PatternEdgeSource == edge.PatternEdgeTarget)
                {
                    insertionPoint = decideOnAndInsertCheckConnectednessOfNodeFixedDirection(insertionPoint,
                                                                                             node, edge, CheckCandidateForConnectednessType.Source);
                }
                else
                {
                    insertionPoint = decideOnAndInsertCheckConnectednessOfNodeBothDirections(insertionPoint,
                                                                                             node, edge);
                }
            }
            foreach (SearchPlanEdgeNode edge in node.IncomingPatternEdges)
            {
                if (((PatternEdge)edge.PatternElement).fixedDirection ||
                    edge.PatternEdgeSource == edge.PatternEdgeTarget)
                {
                    insertionPoint = decideOnAndInsertCheckConnectednessOfNodeFixedDirection(insertionPoint,
                                                                                             node, edge, CheckCandidateForConnectednessType.Target);
                }
                else
                {
                    insertionPoint = decideOnAndInsertCheckConnectednessOfNodeBothDirections(insertionPoint,
                                                                                             node, edge);
                }
            }

            return(insertionPoint);
        }
Esempio n. 9
0
        /// <summary>
        /// Recursively assembles interpretation plan from scheduled search plan, beginning at index 0.
        /// Decides which specialized build procedure is to be called.
        /// The specialized build procedure then calls this procedure again,
        /// in order to process the next search plan operation at the following index.
        /// The insertionPoint is the lastly built operation;
        /// the next operation built is inserted into the next link of it,
        /// then it becomes the current insertionPoint.
        /// </summary>
        private void BuildInterpretationPlan(InterpretationPlan insertionPoint, int index)
        {
            if (index >= ssp.Operations.Length)
            { // end of scheduled search plan reached, stop recursive iteration
                buildMatchComplete(insertionPoint);
                return;
            }

            SearchOperation op = ssp.Operations[index];

            // for current scheduled search plan operation
            // insert corresponding interpretation plan operations into interpretation plan
            switch (op.Type)
            {
            case SearchOperationType.Lookup:
                if (((SearchPlanNode)op.Element).NodeType == PlanNodeType.Node)
                {
                    buildLookup(insertionPoint, index, (SearchPlanNodeNode)op.Element);
                }
                else
                {
                    buildLookup(insertionPoint, index, (SearchPlanEdgeNode)op.Element);
                }
                break;

            case SearchOperationType.ImplicitSource:
                buildImplicit(insertionPoint, index,
                              (SearchPlanEdgeNode)op.SourceSPNode,
                              (SearchPlanNodeNode)op.Element,
                              ImplicitNodeType.Source);
                break;

            case SearchOperationType.ImplicitTarget:
                buildImplicit(insertionPoint, index,
                              (SearchPlanEdgeNode)op.SourceSPNode,
                              (SearchPlanNodeNode)op.Element,
                              ImplicitNodeType.Target);
                break;

            case SearchOperationType.Implicit:
                buildImplicit(insertionPoint, index,
                              (SearchPlanEdgeNode)op.SourceSPNode,
                              (SearchPlanNodeNode)op.Element,
                              ImplicitNodeType.SourceOrTarget);
                break;

            case SearchOperationType.Incoming:
                buildIncident(insertionPoint, index,
                              (SearchPlanNodeNode)op.SourceSPNode,
                              (SearchPlanEdgeNode)op.Element,
                              IncidentEdgeType.Incoming);
                break;

            case SearchOperationType.Outgoing:
                buildIncident(insertionPoint, index,
                              (SearchPlanNodeNode)op.SourceSPNode,
                              (SearchPlanEdgeNode)op.Element,
                              IncidentEdgeType.Outgoing);
                break;

            case SearchOperationType.Incident:
                buildIncident(insertionPoint, index,
                              (SearchPlanNodeNode)op.SourceSPNode,
                              (SearchPlanEdgeNode)op.Element,
                              IncidentEdgeType.IncomingOrOutgoing);
                break;

            case SearchOperationType.Condition:
                buildCondition(insertionPoint, index,
                               (PatternCondition)op.Element);
                break;

            default:
                throw new Exception("Unknown or unsupported search operation");
            }
        }