/// <summary> /// Iterate all search programs to complete check operations within each one /// </summary> public static void CompleteCheckOperationsInAllSearchPrograms( SearchProgram searchProgram) { do { CompleteCheckOperations( searchProgram.GetNestedSearchOperationsList(), searchProgram, null, null, searchProgram); searchProgram = searchProgram.Next as SearchProgram; }while(searchProgram != null); }
/// <summary> /// Iterate all search programs to complete check operations within each one /// </summary> public void CompleteCheckOperationsInAllSearchPrograms( SearchProgram searchProgram) { do { CompleteCheckOperations( searchProgram.GetNestedSearchOperationsList(), searchProgram, null, null, searchProgram); searchProgram = searchProgram.Next as SearchProgram; } while (searchProgram != null); }
/// <summary> /// move outwards from check succeeded operation until check partial match by independent is found /// appending restore isomorphy for isomorphy written on the way /// and final jump to operation right after the independent failed operation of the check partial match by independent /// </summary> private static void MoveRightAfterCorrespondingIndependentFailedAppendingRemoveIsomorphyAndJump( CheckContinueMatchingOfIndependentSucceeded checkSucceeded, CheckPartialMatchByIndependent enclosingIndependent, SearchProgram topLevelSearchProgram) { // insertion point for candidate failed operations SearchProgramOperation insertionPoint = checkSucceeded.CheckFailedOperations; while (insertionPoint.Next != null) // needed? { insertionPoint = insertionPoint.Next; } // move outwards, append remove isomorphy string[] neededElements = new string[0]; SearchProgramOperation continuationPoint = MoveOutwardsAppendingRemoveIsomorphy( checkSucceeded, ref insertionPoint, neededElements, enclosingIndependent, topLevelSearchProgram); // move to check failed operation of check independent operation while (!(continuationPoint is CheckContinueMatchingOfIndependentFailed)) { continuationPoint = continuationPoint.Next; } CheckContinueMatchingOfIndependentFailed checkFailed = (CheckContinueMatchingOfIndependentFailed)continuationPoint; // insert label right thereafter, append jump there at insertion point GotoLabel gotoLabel = new GotoLabel(); checkFailed.Insert(gotoLabel); ContinueOperation continueByGoto = new ContinueOperation( ContinueOperationType.ByGoto, gotoLabel.LabelName); insertionPoint.Append(continueByGoto); }
/// <summary> /// move outwards from starting point on until operation to continue at is found /// appending restore isomorphy at insertion point for isomorphy written on the way /// returns operation to continue at /// </summary> private static SearchProgramOperation MoveOutwardsAppendingRemoveIsomorphy( SearchProgramOperation startingPoint, ref SearchProgramOperation insertionPoint, string[] neededElementsForCheckOperation, SearchProgramOperation outermostOperation, SearchProgram topLevelSearchProgram) { // currently focused operation on our way outwards SearchProgramOperation op = startingPoint; // move outwards until operation to continue at is found bool creationPointOfDominatingElementFound = false; bool iterationReached = false; do { op = op.Previous; // insert code to clean up isomorphy information written by candidate acceptance // in between the operation to continue and the check operation if (op is AcceptCandidate) { AcceptCandidate writeIsomorphy = op as AcceptCandidate; AbandonCandidate restoreIsomorphy = new AbandonCandidate( writeIsomorphy.PatternElementName, writeIsomorphy.NegativeIndependentNamePrefix, writeIsomorphy.IsNode, writeIsomorphy.NeverAboveMaxIsoSpace, writeIsomorphy.Parallel, writeIsomorphy.LockForAllThreads); insertionPoint = insertionPoint.Append(restoreIsomorphy); } // insert code to clean up isomorphy information written by global candidate acceptance // in between the operation to continue and the check operation if (op is AcceptCandidateGlobal) { AcceptCandidateGlobal writeIsomorphy = op as AcceptCandidateGlobal; AbandonCandidateGlobal removeIsomorphy = new AbandonCandidateGlobal( writeIsomorphy.PatternElementName, writeIsomorphy.NegativeIndependentNamePrefix, writeIsomorphy.IsNode, writeIsomorphy.NeverAboveMaxIsoSpace, writeIsomorphy.Parallel); insertionPoint = insertionPoint.Append(removeIsomorphy); } // insert code to clean up isomorphy information written by patternpath candidate acceptance // in between the operation to continue and the check operation if (op is AcceptCandidatePatternpath) { AcceptCandidatePatternpath writeIsomorphy = op as AcceptCandidatePatternpath; AbandonCandidatePatternpath removeIsomorphy = new AbandonCandidatePatternpath( writeIsomorphy.PatternElementName, writeIsomorphy.NegativeIndependentNamePrefix, writeIsomorphy.IsNode); insertionPoint = insertionPoint.Append(removeIsomorphy); } // insert code to remove iterated pattern acceptance if (op is AcceptIterated) { AcceptIterated acceptIterated = op as AcceptIterated; AbandonIterated abandonIterated = new AbandonIterated(); insertionPoint = insertionPoint.Append(abandonIterated); } // insert code to undo subpattern matching initialization if we leave the subpattern matching method if (op is InitializeSubpatternMatching) { InitializeSubpatternMatching initialize = op as InitializeSubpatternMatching; FinalizeSubpatternMatching finalize = new FinalizeSubpatternMatching(initialize.Type); insertionPoint = insertionPoint.Append(finalize); } // insert code to undo negative/independent matching initialization if we leave the negative/independent matching method if (op is InitializeNegativeIndependentMatching) { InitializeNegativeIndependentMatching initialize = op as InitializeNegativeIndependentMatching; FinalizeNegativeIndependentMatching finalize = new FinalizeNegativeIndependentMatching(initialize.NeverAboveMaxIsoSpace, initialize.Parallel); insertionPoint = insertionPoint.Append(finalize); } // determine operation to continue at // found by looking at the graph elements // the check operation depends on / is dominated by // its the first element iteration on our way outwards the search program // after or at the point of a get element operation // of some dominating element the check depends on // (or the outermost operation if no iteration is found until it is reached) if (op is GetCandidate || op is BothDirectionsIteration) { if (creationPointOfDominatingElementFound == false) { if (neededElementsForCheckOperation != null) { foreach (string dominating in neededElementsForCheckOperation) { GetCandidate getCandidate = op as GetCandidate; BothDirectionsIteration bothDirections = op as BothDirectionsIteration; if (getCandidate != null && getCandidate.PatternElementName == dominating || bothDirections != null && bothDirections.PatternElementName == dominating) { creationPointOfDominatingElementFound = true; iterationReached = false; break; } } } else { // needed elements == null means everything fits, // take first element iteration on our way outwards the search program // (or the outermost operation if no iteration is found until it is reached) creationPointOfDominatingElementFound = true; iterationReached = false; } } if (op is GetCandidateByIteration || op is GetCandidateByIterationParallel || op is BothDirectionsIteration) { iterationReached = true; } } }while(!(creationPointOfDominatingElementFound && iterationReached) && op != outermostOperation); return(op); }
/////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// /// <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> /// move outwards from check operation until operation to continue at is found /// appending restore isomorphy for isomorphy written on the way /// and final jump to operation to continue at /// </summary> private static void MoveOutwardsAppendingRemoveIsomorphyAndJump( CheckOperation checkOperation, string[] neededElementsForCheckOperation, SearchProgramOperation outermostOperation, SearchProgram topLevelSearchProgram) { // insertion point for candidate failed operations SearchProgramOperation insertionPoint = checkOperation.CheckFailedOperations; while (insertionPoint.Next != null) { insertionPoint = insertionPoint.Next; } // set outermost to iterated matching dummy loop if iterated if (outermostOperation is SearchProgramOfIterated) { SearchProgramOperation cur = checkOperation; while (!(cur is IteratedMatchingDummyLoop)) { cur = cur.Previous; } outermostOperation = cur; } SearchProgramOperation continuationPoint = MoveOutwardsAppendingRemoveIsomorphy( checkOperation, ref insertionPoint, neededElementsForCheckOperation, outermostOperation, topLevelSearchProgram); // decide on type of continuing operation, then insert it // continue at top nesting level -> return SearchProgramOperation op = continuationPoint; while (!(op is SearchProgram)) { op = op.Previous; } SearchProgram searchProgramRoot = op as SearchProgram; if (continuationPoint == searchProgramRoot) { ContinueOperation continueByReturn = new ContinueOperation( ContinueOperationType.ByReturn, searchProgramRoot is SearchProgramOfAction || searchProgramRoot is SearchProgramOfActionParallelizationHead, searchProgramRoot is SearchProgramOfActionParallelizationBody ); insertionPoint.Append(continueByReturn); return; } // continue at directly enclosing nesting level -> continue op = checkOperation; do { op = op.Previous; }while(!op.IsSearchNestingOperation()); SearchProgramOperation directlyEnclosingOperation = op; if (continuationPoint == directlyEnclosingOperation // (check negative/independent is enclosing, but not a loop, thus continue wouldn't work) && !(directlyEnclosingOperation is CheckPartialMatchByNegative) && !(directlyEnclosingOperation is CheckPartialMatchByIndependent) // (check partial match for duplicate contains an internal loop in checking, thus continue wouldn't work) && !(checkOperation is CheckPartialMatchForDuplicate)) { ContinueOperation continueByContinue = new ContinueOperation(ContinueOperationType.ByContinue, directlyEnclosingOperation is GetCandidateByIterationParallel); insertionPoint.Append(continueByContinue); return; } // otherwise -> goto label string gotoLabelName; // if our continuation point is a candidate iteration // -> append label at the end of the loop body of the candidate iteration loop if (continuationPoint is GetCandidateByIteration) { GetCandidateByIteration candidateIteration = continuationPoint as GetCandidateByIteration; op = candidateIteration.NestedOperationsList; while (op.Next != null) { op = op.Next; } GotoLabel gotoLabel = new GotoLabel(); op.Append(gotoLabel); gotoLabelName = gotoLabel.LabelName; } // if our continuation point is a candidate iteration parallel // -> append label at the end of the loop body of the candidate iteration loop else if (continuationPoint is GetCandidateByIterationParallel) { GetCandidateByIterationParallel candidateIteration = continuationPoint as GetCandidateByIterationParallel; op = candidateIteration.NestedOperationsList; while (op.Next != null) { op = op.Next; } GotoLabel gotoLabel = new GotoLabel(); op.Append(gotoLabel); gotoLabelName = gotoLabel.LabelName; } // if our continuation point is a both directions iteration // -> append label at the end of the loop body of the both directions iteration loop else if (continuationPoint is BothDirectionsIteration) { BothDirectionsIteration bothDirections = continuationPoint as BothDirectionsIteration; op = bothDirections.NestedOperationsList; while (op.Next != null) { op = op.Next; } GotoLabel gotoLabel = new GotoLabel(); op.Append(gotoLabel); gotoLabelName = gotoLabel.LabelName; } // if our continuation point is an alternative case // -> append label at the end of the alternative case operations else if (continuationPoint is AlternativeCaseMatching) { AlternativeCaseMatching alternativeCase = continuationPoint as AlternativeCaseMatching; op = alternativeCase.OperationsList; while (op.Next != null) { op = op.Next; } GotoLabel gotoLabel = new GotoLabel(); op.Append(gotoLabel); gotoLabelName = gotoLabel.LabelName; } // if our continuation point is the dummy loop of an iterated operation // -> we just jump to the label maxMatchesIterReached directly after the loop else if (continuationPoint is IteratedMatchingDummyLoop) { gotoLabelName = "maxMatchesIterReached"; } // otherwise our continuation point is a check negative/independent operation // -> insert label directly after the check negative/independent operation else { CheckPartialMatchByNegativeOrIndependent checkNegativeIndependent = continuationPoint as CheckPartialMatchByNegativeOrIndependent; GotoLabel gotoLabel = new GotoLabel(); checkNegativeIndependent.Insert(gotoLabel); gotoLabelName = gotoLabel.LabelName; } ContinueOperation continueByGoto = new ContinueOperation( ContinueOperationType.ByGoto, gotoLabelName); // ByGoto due to parameters insertionPoint.Append(continueByGoto); }
void GenerateParallelizationSetupAsNeeded(SourceBuilder sb, LGSPRulePattern rulePattern, SearchProgram searchProgram) { if(rulePattern.patternGraph.branchingFactor < 2) return; foreach(SearchOperation so in rulePattern.patternGraph.parallelizedSchedule[0].Operations) { switch(so.Type) { case SearchOperationType.WriteParallelPreset: if(so.Element is SearchPlanNodeNode) sb.AppendFrontFormat("GRGEN_LGSP.LGSPNode {0};\n", NamesOfEntities.IterationParallelizationParallelPresetCandidate(((SearchPlanNodeNode)so.Element).PatternElement.Name)); else //SearchPlanEdgeNode sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationParallelPresetCandidate(((SearchPlanEdgeNode)so.Element).PatternElement.Name)); break; case SearchOperationType.WriteParallelPresetVar: sb.AppendFrontFormat("{0} {1};\n", TypesHelper.TypeName(((PatternVariable)so.Element).Type), NamesOfEntities.IterationParallelizationParallelPresetCandidate(((PatternVariable)so.Element).Name)); break; case SearchOperationType.SetupParallelLookup: if(so.Element is SearchPlanNodeNode) { sb.AppendFrontFormat("GRGEN_LGSP.LGSPNode {0};\n", NamesOfEntities.IterationParallelizationListHead(((SearchPlanNodeNode)so.Element).PatternElement.Name)); sb.AppendFrontFormat("GRGEN_LGSP.LGSPNode {0};\n", NamesOfEntities.IterationParallelizationNextCandidate(((SearchPlanNodeNode)so.Element).PatternElement.Name)); } else { sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationListHead(((SearchPlanEdgeNode)so.Element).PatternElement.Name)); sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationNextCandidate(((SearchPlanEdgeNode)so.Element).PatternElement.Name)); } break; case SearchOperationType.SetupParallelPickFromStorage: if(TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.type).StartsWith("set") || TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.type).StartsWith("map")) { sb.AppendFrontFormat("IEnumerator<KeyValuePair<{0},{1}>> {2};\n", TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.Type)), model), TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractDst(TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.Type)), model), NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name)); } else { sb.AppendFrontFormat("IEnumerator<{0}> {1};\n", TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.Type)), model), NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name)); } break; case SearchOperationType.SetupParallelPickFromStorageDependent: if(TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute).StartsWith("set") || TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute).StartsWith("map")) { sb.AppendFrontFormat("IEnumerator<KeyValuePair<{0},{1}>> {2};\n", TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute)), model), TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractDst(TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute)), model), NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name)); } else { sb.AppendFrontFormat("IEnumerator<{0}> {1};\n", TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute)), model), NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name)); } break; case SearchOperationType.SetupParallelPickFromIndex: sb.AppendFrontFormat("IEnumerator<{0}> {1};\n", TypesHelper.TypeName(so.IndexAccess.Index is AttributeIndexDescription ? ((AttributeIndexDescription)so.IndexAccess.Index).GraphElementType : ((IncidenceCountIndexDescription)so.IndexAccess.Index).StartNodeType), NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name)); break; case SearchOperationType.SetupParallelPickFromIndexDependent: sb.AppendFrontFormat("IEnumerator<{0}> {1};\n", TypesHelper.TypeName(so.IndexAccess.Index is AttributeIndexDescription ? ((AttributeIndexDescription)so.IndexAccess.Index).GraphElementType : ((IncidenceCountIndexDescription)so.IndexAccess.Index).StartNodeType), NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name)); break; case SearchOperationType.SetupParallelIncoming: case SearchOperationType.SetupParallelOutgoing: sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationListHead(((SearchPlanEdgeNode)so.Element).PatternElement.Name)); sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationNextCandidate(((SearchPlanEdgeNode)so.Element).PatternElement.Name)); break; case SearchOperationType.SetupParallelIncident: sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationListHead(((SearchPlanEdgeNode)so.Element).PatternElement.Name)); sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationNextCandidate(((SearchPlanEdgeNode)so.Element).PatternElement.Name)); sb.AppendFrontFormat("int {0};\n", NamesOfEntities.IterationParallelizationDirectionRunCounterVariable(((SearchPlanEdgeNode)so.Element).PatternElement.Name)); break; } } sb.AppendFront("\n"); String rulePatternClassName = rulePattern.GetType().Name; String matchClassName = rulePatternClassName + "." + "Match_" + rulePattern.name; String matchInterfaceName = rulePatternClassName + "." + "IMatch_" + rulePattern.name; sb.AppendFront("private static GRGEN_LGSP.LGSPMatchesList<" + matchClassName + ", " + matchInterfaceName + ">[] parallelTaskMatches;\n"); sb.AppendFront("private static int numWorkerThreads;\n"); sb.AppendFront("private static int iterationNumber;\n"); sb.AppendFront("private static int iterationLock;\n"); sb.AppendFront("[ThreadStatic] private static int currentIterationNumber;\n"); sb.AppendFront("[ThreadStatic] private static int threadId;\n"); sb.AppendFront("private static GRGEN_LGSP.LGSPActionExecutionEnvironment actionEnvParallel;\n"); sb.AppendFront("private static int maxMatchesParallel;\n"); sb.AppendFront("private static bool maxMatchesFound = false;\n"); sb.AppendFront("private static List<GRGEN_LGSP.LGSPNode>[] moveHeadAfterNodes;\n"); sb.AppendFront("private static List<GRGEN_LGSP.LGSPEdge>[] moveHeadAfterEdges;\n"); sb.AppendFront("private static List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>[] moveOutHeadAfter;\n"); sb.AppendFront("private static List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>[] moveInHeadAfter;\n"); sb.AppendFront("\n"); }
/// <summary> /// Generates matcher class head source code for the pattern of the rulePattern into given source builder /// isInitialStatic tells whether the initial static version or a dynamic version after analyze is to be generated. /// </summary> void GenerateMatcherClassHeadAction(SourceBuilder sb, LGSPRulePattern rulePattern, bool isInitialStatic, SearchProgram searchProgram) { PatternGraph patternGraph = (PatternGraph)rulePattern.PatternGraph; String namePrefix = (isInitialStatic ? "" : "Dyn") + "Action_"; String className = namePrefix + rulePattern.name; String rulePatternClassName = rulePattern.GetType().Name; String matchClassName = rulePatternClassName + "." + "Match_" + rulePattern.name; String matchInterfaceName = rulePatternClassName + "." + "IMatch_" + rulePattern.name; String actionInterfaceName = "IAction_" + rulePattern.name; if(patternGraph.Package != null) { sb.AppendFrontFormat("namespace {0}\n", patternGraph.Package); sb.AppendFront("{\n"); sb.Indent(); } sb.AppendFront("public class " + className + " : GRGEN_LGSP.LGSPAction, " + "GRGEN_LIBGR.IAction, " + actionInterfaceName + "\n"); sb.AppendFront("{\n"); sb.Indent(); // class level sb.AppendFront("public " + className + "() {\n"); sb.Indent(); // method body level sb.AppendFront("_rulePattern = " + rulePatternClassName + ".Instance;\n"); sb.AppendFront("patternGraph = _rulePattern.patternGraph;\n"); if(rulePattern.patternGraph.branchingFactor < 2) { sb.AppendFront("DynamicMatch = myMatch;\n"); if(!isInitialStatic) sb.AppendFrontFormat("GRGEN_ACTIONS.Action_{0}.Instance.DynamicMatch = myMatch;\n", rulePattern.name); } else { sb.AppendFront("if(Environment.ProcessorCount == 1)\n"); sb.AppendFront("{\n"); sb.AppendFront("\tDynamicMatch = myMatch;\n"); if(!isInitialStatic) sb.AppendFrontFormat("\tGRGEN_ACTIONS.Action_{0}.Instance.DynamicMatch = myMatch;\n", rulePattern.name); sb.AppendFront("}\n"); sb.AppendFront("else\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFront("DynamicMatch = myMatch_parallelized;\n"); if(!isInitialStatic) sb.AppendFrontFormat("GRGEN_ACTIONS.Action_{0}.Instance.DynamicMatch = myMatch_parallelized;\n", rulePattern.name); sb.AppendFrontFormat("numWorkerThreads = GRGEN_LGSP.WorkerPool.EnsurePoolSize({0});\n", rulePattern.patternGraph.branchingFactor); sb.AppendFrontFormat("parallelTaskMatches = new GRGEN_LGSP.LGSPMatchesList<{0}, {1}>[numWorkerThreads];\n", matchClassName, matchInterfaceName); sb.AppendFront("moveHeadAfterNodes = new List<GRGEN_LGSP.LGSPNode>[numWorkerThreads];\n"); sb.AppendFront("moveHeadAfterEdges = new List<GRGEN_LGSP.LGSPEdge>[numWorkerThreads];\n"); sb.AppendFront("moveOutHeadAfter = new List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>[numWorkerThreads];\n"); sb.AppendFront("moveInHeadAfter = new List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>[numWorkerThreads];\n"); sb.AppendFront("for(int i=0; i<numWorkerThreads; ++i)\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFront("moveHeadAfterNodes[i] = new List<GRGEN_LGSP.LGSPNode>();\n"); sb.AppendFront("moveHeadAfterEdges[i] = new List<GRGEN_LGSP.LGSPEdge>();\n"); sb.AppendFront("moveOutHeadAfter[i] = new List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>();\n"); sb.AppendFront("moveInHeadAfter[i] = new List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>();\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("for(int i=0; i<parallelTaskMatches.Length; ++i)\n"); sb.AppendFrontFormat("\tparallelTaskMatches[i] = new GRGEN_LGSP.LGSPMatchesList<{0}, {1}>(this);\n", matchClassName, matchInterfaceName); sb.Unindent(); sb.AppendFront("}\n"); } sb.AppendFrontFormat("ReturnArray = new object[{0}];\n", rulePattern.Outputs.Length); sb.AppendFront("matches = new GRGEN_LGSP.LGSPMatchesList<" + matchClassName +", " + matchInterfaceName + ">(this);\n"); sb.Unindent(); // class level sb.AppendFront("}\n\n"); sb.AppendFront("public " + rulePatternClassName + " _rulePattern;\n"); sb.AppendFront("public override GRGEN_LGSP.LGSPRulePattern rulePattern { get { return _rulePattern; } }\n"); sb.AppendFront("public override string Name { get { return \"" + rulePattern.name + "\"; } }\n"); sb.AppendFront("private GRGEN_LGSP.LGSPMatchesList<" + matchClassName + ", " + matchInterfaceName + "> matches;\n\n"); if (isInitialStatic) { sb.AppendFront("public static " + className + " Instance { get { return instance; } set { instance = value; } }\n"); sb.AppendFront("private static " + className + " instance = new " + className + "();\n"); } GenerateIndependentsMatchObjects(sb, rulePattern, patternGraph); sb.AppendFront("\n"); GenerateParallelizationSetupAsNeeded(sb, rulePattern, searchProgram); }
/// <summary> /// move outwards from starting point on until operation to continue at is found /// appending restore isomorphy at insertion point for isomorphy written on the way /// returns operation to continue at /// </summary> private SearchProgramOperation MoveOutwardsAppendingRemoveIsomorphy( SearchProgramOperation startingPoint, ref SearchProgramOperation insertionPoint, string[] neededElementsForCheckOperation, SearchProgramOperation outermostOperation, SearchProgram topLevelSearchProgram) { // currently focused operation on our way outwards SearchProgramOperation op = startingPoint; // move outwards until operation to continue at is found bool creationPointOfDominatingElementFound = false; bool iterationReached = false; do { op = op.Previous; // insert code to clean up isomorphy information written by candidate acceptance // in between the operation to continue and the check operation if (op is AcceptCandidate) { AcceptCandidate writeIsomorphy = op as AcceptCandidate; AbandonCandidate restoreIsomorphy = new AbandonCandidate( writeIsomorphy.PatternElementName, writeIsomorphy.NegativeIndependentNamePrefix, writeIsomorphy.IsNode, writeIsomorphy.NeverAboveMaxIsoSpace, writeIsomorphy.Parallel, writeIsomorphy.LockForAllThreads); insertionPoint = insertionPoint.Append(restoreIsomorphy); } // insert code to clean up isomorphy information written by global candidate acceptance // in between the operation to continue and the check operation if (op is AcceptCandidateGlobal) { AcceptCandidateGlobal writeIsomorphy = op as AcceptCandidateGlobal; AbandonCandidateGlobal removeIsomorphy = new AbandonCandidateGlobal( writeIsomorphy.PatternElementName, writeIsomorphy.NegativeIndependentNamePrefix, writeIsomorphy.IsNode, writeIsomorphy.NeverAboveMaxIsoSpace, writeIsomorphy.Parallel); insertionPoint = insertionPoint.Append(removeIsomorphy); } // insert code to clean up isomorphy information written by patternpath candidate acceptance // in between the operation to continue and the check operation if (op is AcceptCandidatePatternpath) { AcceptCandidatePatternpath writeIsomorphy = op as AcceptCandidatePatternpath; AbandonCandidatePatternpath removeIsomorphy = new AbandonCandidatePatternpath( writeIsomorphy.PatternElementName, writeIsomorphy.NegativeIndependentNamePrefix, writeIsomorphy.IsNode); insertionPoint = insertionPoint.Append(removeIsomorphy); } // insert code to remove iterated pattern acceptance if (op is AcceptIterated) { AcceptIterated acceptIterated = op as AcceptIterated; AbandonIterated abandonIterated = new AbandonIterated(); insertionPoint = insertionPoint.Append(abandonIterated); } // insert code to undo subpattern matching initialization if we leave the subpattern matching method if (op is InitializeSubpatternMatching) { InitializeSubpatternMatching initialize = op as InitializeSubpatternMatching; FinalizeSubpatternMatching finalize = new FinalizeSubpatternMatching(initialize.Type); insertionPoint = insertionPoint.Append(finalize); } // insert code to undo negative/independent matching initialization if we leave the negative/independent matching method if (op is InitializeNegativeIndependentMatching) { InitializeNegativeIndependentMatching initialize = op as InitializeNegativeIndependentMatching; FinalizeNegativeIndependentMatching finalize = new FinalizeNegativeIndependentMatching(initialize.NeverAboveMaxIsoSpace, initialize.Parallel); insertionPoint = insertionPoint.Append(finalize); } // determine operation to continue at // found by looking at the graph elements // the check operation depends on / is dominated by // its the first element iteration on our way outwards the search program // after or at the point of a get element operation // of some dominating element the check depends on // (or the outermost operation if no iteration is found until it is reached) if (op is GetCandidate || op is BothDirectionsIteration) { if (creationPointOfDominatingElementFound == false) { if (neededElementsForCheckOperation != null) { foreach (string dominating in neededElementsForCheckOperation) { GetCandidate getCandidate = op as GetCandidate; BothDirectionsIteration bothDirections = op as BothDirectionsIteration; if (getCandidate!=null && getCandidate.PatternElementName == dominating || bothDirections!=null && bothDirections.PatternElementName == dominating) { creationPointOfDominatingElementFound = true; iterationReached = false; break; } } } else { // needed elements == null means everything fits, // take first element iteration on our way outwards the search program // (or the outermost operation if no iteration is found until it is reached) creationPointOfDominatingElementFound = true; iterationReached = false; } } if (op is GetCandidateByIteration || op is GetCandidateByIterationParallel || op is BothDirectionsIteration) { iterationReached = true; } } } while (!(creationPointOfDominatingElementFound && iterationReached) && op != outermostOperation); return op; }
/// <summary> /// move outwards from check succeeded operation until check partial match by independent is found /// appending restore isomorphy for isomorphy written on the way /// and final jump to operation right after the independent failed operation of the check partial match by independent /// </summary> private void MoveRightAfterCorrespondingIndependentFailedAppendingRemoveIsomorphyAndJump( CheckContinueMatchingOfIndependentSucceeded checkSucceeded, CheckPartialMatchByIndependent enclosingIndependent, SearchProgram topLevelSearchProgram) { // insertion point for candidate failed operations SearchProgramOperation insertionPoint = checkSucceeded.CheckFailedOperations; while (insertionPoint.Next != null) // needed? { insertionPoint = insertionPoint.Next; } // move outwards, append remove isomorphy string[] neededElements = new string[0]; SearchProgramOperation continuationPoint = MoveOutwardsAppendingRemoveIsomorphy( checkSucceeded, ref insertionPoint, neededElements, enclosingIndependent, topLevelSearchProgram); // move to check failed operation of check independent operation while (!(continuationPoint is CheckContinueMatchingOfIndependentFailed)) { continuationPoint = continuationPoint.Next; } CheckContinueMatchingOfIndependentFailed checkFailed = (CheckContinueMatchingOfIndependentFailed)continuationPoint; // insert label right thereafter, append jump there at insertion point GotoLabel gotoLabel = new GotoLabel(); checkFailed.Insert(gotoLabel); ContinueOperation continueByGoto = new ContinueOperation( ContinueOperationType.ByGoto, gotoLabel.LabelName); insertionPoint.Append(continueByGoto); }
/////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// /// <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 void CompleteCheckOperations( SearchProgramOperation currentOperation, SearchProgramOperation enclosingSearchProgram, // might be a negative/independent in case these are nested GetPartialMatchOfAlternative enclosingAlternative, 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 ?? (enclosingAlternative ?? 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 ?? (enclosingAlternative ?? enclosingSearchProgram), topLevelSearchProgram); } else if(currentOperation is CheckPartialMatchForDuplicate) { CheckPartialMatchForDuplicate checkDuplicateMatch = (CheckPartialMatchForDuplicate)currentOperation; checkDuplicateMatch.CheckFailedOperations = new SearchProgramList(checkDuplicateMatch); MoveOutwardsAppendingRemoveIsomorphyAndJump( checkDuplicateMatch, checkDuplicateMatch.NeededElements, enclosingCheckNegativeOrIndependent ?? (enclosingAlternative ?? 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 : enclosingAlternative, 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 ?? (enclosingAlternative ?? 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, enclosingAlternative, 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, enclosingAlternative ?? 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, enclosingAlternative ?? 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 ?? (enclosingAlternative ?? 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, enclosingAlternative, 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 GetPartialMatchOfAlternative) ////////////////////////////////////////////////////////// { // depth first CompleteCheckOperations( currentOperation.GetNestedSearchOperationsList(), enclosingSearchProgram, (GetPartialMatchOfAlternative)currentOperation, null, topLevelSearchProgram); } ////////////////////////////////////////////////////////// else if (currentOperation.IsSearchNestingOperation()) ////////////////////////////////////////////////////////// { // depth first CompleteCheckOperations( currentOperation.GetNestedSearchOperationsList(), enclosingSearchProgram, enclosingAlternative, enclosingCheckNegativeOrIndependent, topLevelSearchProgram); } // breadth currentOperation = currentOperation.Next; } }
/// <summary> /// move outwards from check operation until operation to continue at is found /// appending restore isomorphy for isomorphy written on the way /// and final jump to operation to continue at /// </summary> private void MoveOutwardsAppendingRemoveIsomorphyAndJump( CheckOperation checkOperation, string[] neededElementsForCheckOperation, SearchProgramOperation outermostOperation, SearchProgram topLevelSearchProgram) { // insertion point for candidate failed operations SearchProgramOperation insertionPoint = checkOperation.CheckFailedOperations; while (insertionPoint.Next != null) { insertionPoint = insertionPoint.Next; } // set outermost to iterated dummy iteration if iterated if (outermostOperation is SearchProgramOfIterated) { SearchProgramOperation cur = checkOperation; while (!(cur is ReturnPreventingDummyIteration)) { cur = cur.Previous; } outermostOperation = cur; } SearchProgramOperation continuationPoint = MoveOutwardsAppendingRemoveIsomorphy( checkOperation, ref insertionPoint, neededElementsForCheckOperation, outermostOperation, topLevelSearchProgram); // decide on type of continuing operation, then insert it // continue at top nesting level -> return SearchProgramOperation op = continuationPoint; while (!(op is SearchProgram)) { op = op.Previous; } SearchProgram searchProgramRoot = op as SearchProgram; if (continuationPoint == searchProgramRoot) { ContinueOperation continueByReturn = new ContinueOperation( ContinueOperationType.ByReturn, searchProgramRoot is SearchProgramOfAction || searchProgramRoot is SearchProgramOfActionParallelizationHead, searchProgramRoot is SearchProgramOfActionParallelizationBody ); insertionPoint.Append(continueByReturn); return; } // continue at directly enclosing nesting level -> continue op = checkOperation; do { op = op.Previous; } while (!op.IsSearchNestingOperation()); SearchProgramOperation directlyEnclosingOperation = op; if (continuationPoint == directlyEnclosingOperation // (check negative/independent is enclosing, but not a loop, thus continue wouldn't work) && !(directlyEnclosingOperation is CheckPartialMatchByNegative) && !(directlyEnclosingOperation is CheckPartialMatchByIndependent) // (check partial match for duplicate contains an internal loop in checking, thus continue wouldn't work) && !(checkOperation is CheckPartialMatchForDuplicate)) { ContinueOperation continueByContinue = new ContinueOperation(ContinueOperationType.ByContinue, directlyEnclosingOperation is GetCandidateByIterationParallel); insertionPoint.Append(continueByContinue); return; } // otherwise -> goto label string gotoLabelName; // if our continuation point is a candidate iteration // -> append label at the end of the loop body of the candidate iteration loop if (continuationPoint is GetCandidateByIteration) { GetCandidateByIteration candidateIteration = continuationPoint as GetCandidateByIteration; op = candidateIteration.NestedOperationsList; while (op.Next != null) { op = op.Next; } GotoLabel gotoLabel = new GotoLabel(); op.Append(gotoLabel); gotoLabelName = gotoLabel.LabelName; } // if our continuation point is a candidate iteration parallel // -> append label at the end of the loop body of the candidate iteration loop else if (continuationPoint is GetCandidateByIterationParallel) { GetCandidateByIterationParallel candidateIteration = continuationPoint as GetCandidateByIterationParallel; op = candidateIteration.NestedOperationsList; while(op.Next != null) { op = op.Next; } GotoLabel gotoLabel = new GotoLabel(); op.Append(gotoLabel); gotoLabelName = gotoLabel.LabelName; } // if our continuation point is a both directions iteration // -> append label at the end of the loop body of the both directions iteration loop else if (continuationPoint is BothDirectionsIteration) { BothDirectionsIteration bothDirections = continuationPoint as BothDirectionsIteration; op = bothDirections.NestedOperationsList; while (op.Next != null) { op = op.Next; } GotoLabel gotoLabel = new GotoLabel(); op.Append(gotoLabel); gotoLabelName = gotoLabel.LabelName; } // if our continuation point is an alternative // -> append label at the end of the alternative operations else if (continuationPoint is GetPartialMatchOfAlternative) { GetPartialMatchOfAlternative getAlternative = continuationPoint as GetPartialMatchOfAlternative; op = getAlternative.OperationsList; while (op.Next != null) { op = op.Next; } GotoLabel gotoLabel = new GotoLabel(); op.Append(gotoLabel); gotoLabelName = gotoLabel.LabelName; } // if our continuation point is the dummy loop of an iterated operation // -> we just jump to the label maxMatchesIterReached directly after the loop else if (continuationPoint is ReturnPreventingDummyIteration) { gotoLabelName = "maxMatchesIterReached"; } // otherwise our continuation point is a check negative/independent operation // -> insert label directly after the check negative/independent operation else { CheckPartialMatchByNegativeOrIndependent checkNegativeIndependent = continuationPoint as CheckPartialMatchByNegativeOrIndependent; GotoLabel gotoLabel = new GotoLabel(); checkNegativeIndependent.Insert(gotoLabel); gotoLabelName = gotoLabel.LabelName; } ContinueOperation continueByGoto = new ContinueOperation( ContinueOperationType.ByGoto, gotoLabelName); // ByGoto due to parameters insertionPoint.Append(continueByGoto); }