/// <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; }
/// <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; }
/// <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; }
/// <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; }