/////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Completes check operations in search program from given currentOperation on /// (taking borderlines set by enclosing search program and check negative into account) /// Completion: /// - determine continuation point /// - insert remove isomorphy opertions needed for continuing there /// - insert continuing operation itself /// </summary> private static void CompleteCheckOperations( SearchProgramOperation currentOperation, SearchProgramOperation enclosingSearchProgram, // might be a negative/independent in case these are nested AlternativeCaseMatching enclosingAlternativeCase, CheckPartialMatchByNegativeOrIndependent enclosingCheckNegativeOrIndependent, SearchProgram topLevelSearchProgram) { // mainly dispatching and iteration method, traverses search program // real completion done in MoveOutwardsAppendingRemoveIsomorphyAndJump // outermost operation for that function is computed here, regarding negative patterns // program nesting structure: search program - [alternative] - [negative|independent]* // complete check operations by inserting failure code // find them in depth first search of search program while (currentOperation != null) { ////////////////////////////////////////////////////////// if (currentOperation is CheckCandidate) ////////////////////////////////////////////////////////// { CheckCandidate checkCandidate = (CheckCandidate)currentOperation; checkCandidate.CheckFailedOperations = new SearchProgramList(checkCandidate); string[] neededElementsForCheckOperation = new string[1]; neededElementsForCheckOperation[0] = checkCandidate.PatternElementName; MoveOutwardsAppendingRemoveIsomorphyAndJump( checkCandidate, neededElementsForCheckOperation, enclosingCheckNegativeOrIndependent ?? (enclosingAlternativeCase ?? enclosingSearchProgram), topLevelSearchProgram); } ////////////////////////////////////////////////////////// else if (currentOperation is CheckPartialMatch) ////////////////////////////////////////////////////////// { if (currentOperation is CheckPartialMatchByCondition) { CheckPartialMatchByCondition checkCondition = (CheckPartialMatchByCondition)currentOperation; checkCondition.CheckFailedOperations = new SearchProgramList(checkCondition); MoveOutwardsAppendingRemoveIsomorphyAndJump( checkCondition, checkCondition.NeededElements, enclosingCheckNegativeOrIndependent ?? (enclosingAlternativeCase ?? enclosingSearchProgram), topLevelSearchProgram); } else if (currentOperation is CheckPartialMatchForDuplicate) { CheckPartialMatchForDuplicate checkDuplicateMatch = (CheckPartialMatchForDuplicate)currentOperation; checkDuplicateMatch.CheckFailedOperations = new SearchProgramList(checkDuplicateMatch); MoveOutwardsAppendingRemoveIsomorphyAndJump( checkDuplicateMatch, checkDuplicateMatch.NeededElements, enclosingCheckNegativeOrIndependent ?? (enclosingAlternativeCase ?? enclosingSearchProgram), topLevelSearchProgram); } else if (currentOperation is CheckPartialMatchByNegativeOrIndependent) { CheckPartialMatchByNegativeOrIndependent checkNegativeOrIndependent = (CheckPartialMatchByNegativeOrIndependent)currentOperation; // ByNegative/ByIndependent is handled in CheckContinueMatchingFailed // of the negative/independent case - enter negative/independent case CompleteCheckOperations( checkNegativeOrIndependent.NestedOperationsList, enclosingCheckNegativeOrIndependent ?? enclosingSearchProgram, enclosingCheckNegativeOrIndependent != null ? null : enclosingAlternativeCase, checkNegativeOrIndependent, topLevelSearchProgram); } else if (currentOperation is CheckPartialMatchForSubpatternsFound) { CheckPartialMatchForSubpatternsFound checkSubpatternsFound = (CheckPartialMatchForSubpatternsFound)currentOperation; if (enclosingCheckNegativeOrIndependent == null) { // determine insertion point within check failed operations // to append the nested check maximum matches SearchProgramOperation insertionPoint = checkSubpatternsFound.CheckFailedOperations; while (insertionPoint.Next != null) { insertionPoint = insertionPoint.Next; } // append nested check maximum matches CheckMaximumMatchesType checkMaxMatchesType = CheckMaximumMatchesType.Action; if (enclosingSearchProgram is SearchProgramOfSubpattern || enclosingSearchProgram is SearchProgramOfAlternative) { checkMaxMatchesType = CheckMaximumMatchesType.Subpattern; } else if (enclosingSearchProgram is SearchProgramOfIterated) { checkMaxMatchesType = CheckMaximumMatchesType.Iterated; } CheckContinueMatchingMaximumMatchesReached checkMaximumMatches = new CheckContinueMatchingMaximumMatchesReached(checkMaxMatchesType, false, enclosingSearchProgram is SearchProgramOfActionParallelizationBody); insertionPoint.Append(checkMaximumMatches); MoveOutwardsAppendingRemoveIsomorphyAndJump( checkSubpatternsFound, null, enclosingCheckNegativeOrIndependent ?? (enclosingAlternativeCase ?? enclosingSearchProgram), topLevelSearchProgram); } // check subpatterns found has a further check maximum matches // or check continue matching of negative failed nested within check failed code // give it its special bit of attention here CompleteCheckOperations( checkSubpatternsFound.CheckFailedOperations, enclosingSearchProgram, enclosingAlternativeCase, enclosingCheckNegativeOrIndependent, topLevelSearchProgram); } else { Debug.Assert(false, "unknown check partial match operation"); } } ////////////////////////////////////////////////////////// else if (currentOperation is CheckContinueMatching) ////////////////////////////////////////////////////////// { if (currentOperation is CheckContinueMatchingMaximumMatchesReached) { CheckContinueMatchingMaximumMatchesReached checkMaximumMatches = (CheckContinueMatchingMaximumMatchesReached)currentOperation; checkMaximumMatches.CheckFailedOperations = new SearchProgramList(checkMaximumMatches); if (checkMaximumMatches.ListHeadAdjustment) { MoveOutwardsAppendingListHeadAdjustment(checkMaximumMatches, checkMaximumMatches.InParallelizedBody); } string[] neededElementsForCheckOperation = new string[0]; MoveOutwardsAppendingRemoveIsomorphyAndJump( checkMaximumMatches, neededElementsForCheckOperation, enclosingSearchProgram, topLevelSearchProgram); } else if (currentOperation is CheckContinueMatchingOfNegativeFailed) { CheckContinueMatchingOfNegativeFailed checkFailed = (CheckContinueMatchingOfNegativeFailed)currentOperation; checkFailed.CheckFailedOperations = new SearchProgramList(checkFailed); if (checkFailed.IsIterationBreaking) { string[] neededElementsForCheckOperation = new string[0]; MoveOutwardsAppendingRemoveIsomorphyAndJump( checkFailed, neededElementsForCheckOperation, enclosingSearchProgram, topLevelSearchProgram); } else { MoveOutwardsAppendingRemoveIsomorphyAndJump( checkFailed, enclosingCheckNegativeOrIndependent.NeededElements, enclosingAlternativeCase ?? enclosingSearchProgram, topLevelSearchProgram); } } else if (currentOperation is CheckContinueMatchingOfIndependentSucceeded) { CheckContinueMatchingOfIndependentSucceeded checkSucceeded = (CheckContinueMatchingOfIndependentSucceeded)currentOperation; checkSucceeded.CheckFailedOperations = // yep, rotten wording new SearchProgramList(checkSucceeded); MoveRightAfterCorrespondingIndependentFailedAppendingRemoveIsomorphyAndJump( checkSucceeded, (CheckPartialMatchByIndependent)enclosingCheckNegativeOrIndependent, topLevelSearchProgram); } else if (currentOperation is CheckContinueMatchingOfIndependentFailed) { CheckContinueMatchingOfIndependentFailed checkFailed = (CheckContinueMatchingOfIndependentFailed)currentOperation; checkFailed.CheckFailedOperations = new SearchProgramList(checkFailed); if (checkFailed.IsIterationBreaking) { string[] neededElementsForCheckOperation = new string[0]; MoveOutwardsAppendingRemoveIsomorphyAndJump( checkFailed, neededElementsForCheckOperation, enclosingSearchProgram, topLevelSearchProgram); } else { MoveOutwardsAppendingRemoveIsomorphyAndJump( checkFailed, checkFailed.CheckIndependent.NeededElements, enclosingAlternativeCase ?? enclosingSearchProgram, topLevelSearchProgram); } } else if (currentOperation is CheckContinueMatchingTasksLeft) { CheckContinueMatchingTasksLeft tasksLeft = (CheckContinueMatchingTasksLeft)currentOperation; // determine insertion point within check failed operations // to append the nested check maximum matches SearchProgramOperation insertionPoint = tasksLeft.CheckFailedOperations; while (insertionPoint.Next != null) { insertionPoint = insertionPoint.Next; } // append nested check maximum matches CheckContinueMatchingMaximumMatchesReached checkMaximumMatches = new CheckContinueMatchingMaximumMatchesReached( enclosingSearchProgram is SearchProgramOfIterated ? CheckMaximumMatchesType.Iterated : CheckMaximumMatchesType.Subpattern, false, topLevelSearchProgram is SearchProgramOfActionParallelizationBody); insertionPoint.Append(checkMaximumMatches); MoveOutwardsAppendingRemoveIsomorphyAndJump( tasksLeft, null, enclosingCheckNegativeOrIndependent ?? (enclosingAlternativeCase ?? enclosingSearchProgram), topLevelSearchProgram); // check tasks left has a further check maximum matches nested within check failed code // give it its special bit of attention here CompleteCheckOperations( tasksLeft.CheckFailedOperations, enclosingSearchProgram, enclosingAlternativeCase, enclosingCheckNegativeOrIndependent, topLevelSearchProgram); } else if (currentOperation is CheckContinueMatchingIteratedPatternNonNullMatchFound) { // was built completely, nothing to complete } else { Debug.Assert(false, "unknown check abort matching operation"); } } ////////////////////////////////////////////////////////// else if (currentOperation is AlternativeCaseMatching) ////////////////////////////////////////////////////////// { // depth first CompleteCheckOperations( currentOperation.GetNestedSearchOperationsList(), enclosingSearchProgram, (AlternativeCaseMatching)currentOperation, null, topLevelSearchProgram); } ////////////////////////////////////////////////////////// else if (currentOperation.IsSearchNestingOperation()) ////////////////////////////////////////////////////////// { // depth first CompleteCheckOperations( currentOperation.GetNestedSearchOperationsList(), enclosingSearchProgram, enclosingAlternativeCase, enclosingCheckNegativeOrIndependent, topLevelSearchProgram); } // breadth currentOperation = currentOperation.Next; } }
/// <summary> /// Search program operations implementing the /// check for duplicate match search plan operation (needed in case an independent was inlined) /// are created and inserted into search program /// </summary> private SearchProgramOperation buildInlinedIndependentCheckForDuplicateMatch( SearchProgramOperation insertionPoint, int currentOperationIndex) { PatternGraph patternGraph = patternGraphWithNestingPatterns.Peek(); List<String> namesOfPatternElements; List<String> matchObjectPaths; List<String> unprefixedNamesOfPatternElements; List<bool> patternElementIsNode; GetMatchElementsForDuplicateCheck(patternGraph, out namesOfPatternElements, out matchObjectPaths, out unprefixedNamesOfPatternElements, out patternElementIsNode); // if an independent was inlined, we may have to throw away duplicate matches // (duplicates in the sense that the non-inlined part was already matched with exactly the same elements) CheckPartialMatchForDuplicate checkDuplicateMatch = new CheckPartialMatchForDuplicate(rulePatternClassName, patternGraph.pathPrefix + patternGraph.Name, namesOfPatternElements.ToArray(), matchObjectPaths.ToArray(), unprefixedNamesOfPatternElements.ToArray(), patternElementIsNode.ToArray()); insertionPoint = insertionPoint.Append(checkDuplicateMatch); //--------------------------------------------------------------------------- // build next operation insertionPoint = BuildScheduledSearchPlanOperationIntoSearchProgram( currentOperationIndex + 1, insertionPoint); //--------------------------------------------------------------------------- return insertionPoint; }