/// <summary> /// Inserts code to check whether the subpatterns were found and code for case there were some /// at the given position, returns position after inserted operations /// </summary> private SearchProgramOperation insertCheckForSubpatternsFoundNegativeIndependent(SearchProgramOperation insertionPoint) { PatternGraph patternGraph = patternGraphWithNestingPatterns.Peek(); string negativeIndependentNamePrefix = NegativeIndependentNamePrefix(patternGraph); // check whether there were no subpattern matches found CheckPartialMatchForSubpatternsFound checkSubpatternsFound = new CheckPartialMatchForSubpatternsFound(negativeIndependentNamePrefix); SearchProgramOperation continuationPointAfterSubpatternsFound = insertionPoint.Append(checkSubpatternsFound); checkSubpatternsFound.CheckFailedOperations = new SearchProgramList(checkSubpatternsFound); insertionPoint = checkSubpatternsFound.CheckFailedOperations; if (isNegative) { // ---- check failed, some subpattern matches found, negative pattern and subpatterns were matched // build the negative pattern was matched operation NegativePatternMatched patternMatched = new NegativePatternMatched( NegativeIndependentPatternMatchedType.ContainingSubpatterns, negativeIndependentNamePrefix); insertionPoint = insertionPoint.Append(patternMatched); // ---- abort the matching process CheckContinueMatchingOfNegativeFailed abortMatching = new CheckContinueMatchingOfNegativeFailed(patternGraph.isIterationBreaking); insertionPoint = insertionPoint.Append(abortMatching); } else { // ---- check failed, some subpattern matches found, independent pattern and subpatterns were matched // build the independent pattern was matched operation IndependentPatternMatched patternMatched = new IndependentPatternMatched( NegativeIndependentPatternMatchedType.ContainingSubpatterns, negativeIndependentNamePrefix); insertionPoint = insertionPoint.Append(patternMatched); if (!isNestedInNegative) // no match object needed(/available) if independent is part of negative { // ---- fill the match object with the candidates // ---- which have passed all the checks for being a match insertionPoint = insertInlinedMatchObjectCreation(insertionPoint, patternGraph, MatchObjectType.Independent); insertionPoint = insertMatchObjectBuilding(insertionPoint, patternGraph, MatchObjectType.Independent, false); insertionPoint = insertMatchObjectBuilding(insertionPoint, patternGraph, MatchObjectType.Independent, true); // if an independent was inlined, we have to insert the local match into a set used for duplicate checking if(wasIndependentInlined(patternGraph, indexOfSchedule)) insertionPoint = insertFillForDuplicateMatchChecking(insertionPoint); } // ---- continue the matching process outside CheckContinueMatchingOfIndependentSucceeded continueMatching = new CheckContinueMatchingOfIndependentSucceeded(); insertionPoint = insertionPoint.Append(continueMatching); } // nesting level up insertionPoint = continuationPointAfterSubpatternsFound; return insertionPoint; }
/////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// /// <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> /// Inserts code to check whether the subpatterns were found and code for case there were some /// at the given position, returns position after inserted operations /// </summary> private SearchProgramOperation insertCheckForSubpatternsFound(SearchProgramOperation insertionPoint, bool isIteratedNullMatch) { PatternGraph patternGraph = patternGraphWithNestingPatterns.Peek(); string negativeIndependentNamePrefix = NegativeIndependentNamePrefix(patternGraph); // check whether there were no subpattern matches found CheckPartialMatchForSubpatternsFound checkSubpatternsFound = new CheckPartialMatchForSubpatternsFound(negativeIndependentNamePrefix); SearchProgramOperation continuationPointAfterSubpatternsFound = insertionPoint.Append(checkSubpatternsFound); checkSubpatternsFound.CheckFailedOperations = new SearchProgramList(checkSubpatternsFound); insertionPoint = checkSubpatternsFound.CheckFailedOperations; // ---- check failed, some subpattern matches found, pattern and subpatterns were matched PatternAndSubpatternsMatchedType type = PatternAndSubpatternsMatchedType.SubpatternOrAlternative; if (programType == SearchProgramType.Action) { type = PatternAndSubpatternsMatchedType.Action; } else if (programType == SearchProgramType.Iterated) { if (isIteratedNullMatch) type = PatternAndSubpatternsMatchedType.IteratedNullMatch; else type = PatternAndSubpatternsMatchedType.Iterated; } Debug.Assert(!isIteratedNullMatch || programType == SearchProgramType.Iterated); string inlinedPatternClassName = rulePatternClassName; string pathPrefixInInlinedPatternClass = patternGraph.pathPrefix; string unprefixedNameInInlinedPatternClass = patternGraph.name; if(patternGraph.originalPatternGraph != null) { inlinedPatternClassName = patternGraph.originalSubpatternEmbedding.matchingPatternOfEmbeddedGraph.GetType().Name; pathPrefixInInlinedPatternClass = patternGraph.originalPatternGraph.pathPrefix; unprefixedNameInInlinedPatternClass = patternGraph.originalPatternGraph.name; } PatternAndSubpatternsMatched patternAndSubpatternsMatched = new PatternAndSubpatternsMatched( inlinedPatternClassName, pathPrefixInInlinedPatternClass + unprefixedNameInInlinedPatternClass, parallelized && indexOfSchedule == 1, type); SearchProgramOperation continuationPointAfterPatternAndSubpatternsMatched = insertionPoint.Append(patternAndSubpatternsMatched); patternAndSubpatternsMatched.MatchBuildingOperations = new SearchProgramList(patternAndSubpatternsMatched); insertionPoint = patternAndSubpatternsMatched.MatchBuildingOperations; // ---- ---- fill the match object with the candidates // ---- ---- which have passed all the checks for being a match if (!isIteratedNullMatch) { insertionPoint = insertInlinedMatchObjectCreation(insertionPoint, patternGraph, MatchObjectType.Normal); insertionPoint = insertMatchObjectBuilding(insertionPoint, patternGraph, MatchObjectType.Normal, false); insertionPoint = insertMatchObjectBuilding(insertionPoint, patternGraph, MatchObjectType.Normal, true); // if an independent was inlined, we have to insert the local match into a set used for duplicate checking if(wasIndependentInlined(patternGraph, indexOfSchedule)) insertionPoint = insertFillForDuplicateMatchChecking(insertionPoint); } // ---- nesting level up insertionPoint = continuationPointAfterPatternAndSubpatternsMatched; // ---- create new matches list to search on or copy found matches into own matches list if (programType==SearchProgramType.Subpattern || programType==SearchProgramType.AlternativeCase) { // not needed for iterated, because if match was found, that's it NewMatchesListForFollowingMatches newMatchesList = new NewMatchesListForFollowingMatches(false); insertionPoint = insertionPoint.Append(newMatchesList); } // ---- check max matches reached will be inserted here by completion pass // (not for iterated, but not needed in that case, too) // nesting level up insertionPoint = continuationPointAfterSubpatternsFound; return insertionPoint; }