private static void GetFilteredParametersAndSuffixedMatcherName( LGSPRulePattern rulePattern, PatternGraph patternGraph, int index, out String[] paramTypesArray, out String[] paramNamesArray, out String suffixedMatcherName) { List <String> paramTypes = new List <String>(); List <String> paramNames = new List <String>(); List <String> removedNames = new List <String>(); for (int i = 0; i < rulePattern.Inputs.Length; ++i) { String inputName = rulePattern.InputNames[i]; if (patternGraph.availabilityOfMaybeNullElements[index].ContainsKey(inputName) && !patternGraph.availabilityOfMaybeNullElements[index][inputName]) { removedNames.Add(rulePattern.InputNames[i]); } else { paramTypes.Add(TypesHelper.TypeName(rulePattern.Inputs[i])); paramNames.Add(rulePattern.InputNames[i]); } } paramTypesArray = new String[paramTypes.Count]; paramNamesArray = new String[paramNames.Count]; for (int i = 0; i < paramTypes.Count; ++i) { paramTypesArray[i] = paramTypes[i]; paramNamesArray[i] = paramNames[i]; } suffixedMatcherName = "myMatch"; foreach (String removedName in removedNames) { suffixedMatcherName += "_MissingPreset_" + removedName; } }
/// <summary> /// Maps the multiple component pattern. /// </summary> /// <param name="pattern">The pattern.</param> /// <param name="componentMatches">The component matches.</param> /// <returns>The founddesignpatterns model, with the pattern and a list of implementations</returns> private FoundDesignPattern MapMultipleComponentPattern(DesignPattern pattern, Dictionary <Component, List <ComponentMatch> > componentMatches) { var foundPattern = new FoundDesignPattern() { DesignPattern = pattern, Implementations = new List <Dictionary <Component, List <SymbolInformation> > >() }; var graph = new PatternGraph(pattern); var implementationCandidates = this.GetPatternImplementations(graph, componentMatches); foreach (var implementationCandidate in implementationCandidates) { var cleanedImplementation = this.RemoveDuplicateComponentMatches(implementationCandidate); if (this.MatchComponentCount(pattern, cleanedImplementation)) { var checkedImplementation = this.MatchImplementationComponentTypes(graph, cleanedImplementation); if (this.MatchComponentCount(pattern, checkedImplementation) && this.ValidComponentOccurrence(checkedImplementation)) { foundPattern.Implementations.Add(this.CastDictionary(checkedImplementation)); } } } if (foundPattern.Implementations.Count > 0) { return(foundPattern); } return(null); }
/// <summary> /// Inserts schedules of negative and independent pattern graphs into the schedule of the enclosing pattern graph /// </summary> private static void InsertNegativesAndIndependentsIntoSchedule(PatternGraph patternGraph, bool lazyNegativeIndependentConditionEvaluation) { for (int i = 0; i < patternGraph.schedules.Length; ++i) { InsertNegativesAndIndependentsIntoSchedule(patternGraph, i, lazyNegativeIndependentConditionEvaluation); } }
private Rule_testRule() { PatternNode node_p2 = new PatternNode((int) NodeTypes.@Process, "node_p2", node_p2_AllowedTypes, node_p2_IsAllowedType, PatternElementType.Normal, -1); PatternNode node_p1 = new PatternNode((int) NodeTypes.@Process, "node_p1", node_p1_AllowedTypes, node_p1_IsAllowedType, PatternElementType.Normal, -1); PatternEdge edge__edge0 = new PatternEdge(node_p1, node_p2, (int) EdgeTypes.@connection, "edge__edge0", edge__edge0_AllowedTypes, edge__edge0_IsAllowedType, PatternElementType.Normal, -1); patternGraph = new PatternGraph( new PatternNode[] { node_p2, node_p1 }, new PatternEdge[] { edge__edge0 }, new Condition[] { }, new bool[2, 2] { { true, false, }, { false, true, }, }, new bool[1, 1] { { true, }, }, new bool[] { false, false, }, new bool[] { false, } ); negativePatternGraphs = new PatternGraph[] {}; inputs = new GrGenType[] { }; outputs = new GrGenType[] { }; }
private Rule_testRule() { PatternNode node_p2 = new PatternNode((int)NodeTypes.@Process, "node_p2", node_p2_AllowedTypes, node_p2_IsAllowedType, PatternElementType.Normal, -1); PatternNode node_p1 = new PatternNode((int)NodeTypes.@Process, "node_p1", node_p1_AllowedTypes, node_p1_IsAllowedType, PatternElementType.Normal, -1); PatternEdge edge__edge0 = new PatternEdge(node_p1, node_p2, (int)EdgeTypes.@connection, "edge__edge0", edge__edge0_AllowedTypes, edge__edge0_IsAllowedType, PatternElementType.Normal, -1); patternGraph = new PatternGraph( new PatternNode[] { node_p2, node_p1 }, new PatternEdge[] { edge__edge0 }, new Condition[] { }, new bool[2, 2] { { true, false, }, { false, true, }, }, new bool[1, 1] { { true, }, }, new bool[] { false, false, }, new bool[] { false, } ); negativePatternGraphs = new PatternGraph[] {}; inputs = new GrGenType[] { }; outputs = new GrGenType[] { }; }
/// <summary> /// Non- is-matched-flag-based isomorphy checking for nested alternative cases/iterateds /// </summary> private static void ParallelizeAlternativeIterated(PatternGraph patternGraph) { foreach (Alternative alt in patternGraph.alternativesPlusInlined) { foreach (PatternGraph altCase in alt.alternativeCases) { ScheduledSearchPlan ssp = altCase.schedulesIncludingNegativesAndIndependents[0]; altCase.parallelizedSchedule = new ScheduledSearchPlan[1]; List <SearchOperation> operations = new List <SearchOperation>(ssp.Operations.Length); for (int i = 0; i < ssp.Operations.Length; ++i) { SearchOperation so = ssp.Operations[i]; SearchOperation clone = (SearchOperation)so.Clone(); clone.Isomorphy.Parallel = true; operations.Add(clone); if (clone.Element is PatternCondition) { SetNeedForParallelizedVersion((clone.Element as PatternCondition).ConditionExpression); } } ScheduledSearchPlan clonedSsp = new ScheduledSearchPlan( altCase, operations.ToArray(), operations.Count > 0 ? operations[0].CostToEnd : 0); altCase.parallelizedSchedule[0] = clonedSsp; ParallelizeNegativeIndependent(clonedSsp); ParallelizeAlternativeIterated(altCase); ParallelizeYielding(altCase); } } foreach (Iterated iter in patternGraph.iteratedsPlusInlined) { ScheduledSearchPlan ssp = iter.iteratedPattern.schedulesIncludingNegativesAndIndependents[0]; iter.iteratedPattern.parallelizedSchedule = new ScheduledSearchPlan[1]; List <SearchOperation> operations = new List <SearchOperation>(ssp.Operations.Length); for (int i = 0; i < ssp.Operations.Length; ++i) { SearchOperation so = ssp.Operations[i]; SearchOperation clone = (SearchOperation)so.Clone(); clone.Isomorphy.Parallel = true; operations.Add(clone); if (clone.Element is PatternCondition) { SetNeedForParallelizedVersion((clone.Element as PatternCondition).ConditionExpression); } } ScheduledSearchPlan clonedSsp = new ScheduledSearchPlan( iter.iteratedPattern, operations.ToArray(), operations.Count > 0 ? operations[0].CostToEnd : 0); iter.iteratedPattern.parallelizedSchedule[0] = clonedSsp; ParallelizeNegativeIndependent(clonedSsp); ParallelizeAlternativeIterated(iter.iteratedPattern); ParallelizeYielding(iter.iteratedPattern); } }
private static void ParallelizeYielding(PatternGraph patternGraph) { patternGraph.parallelizedYieldings = new PatternYielding[patternGraph.YieldingsPlusInlined.Length]; for (int i = 0; i < patternGraph.YieldingsPlusInlined.Length; ++i) { patternGraph.parallelizedYieldings[i] = (PatternYielding)patternGraph.YieldingsPlusInlined[i].Clone(); for (int j = 0; j < patternGraph.parallelizedYieldings[i].ElementaryYieldings.Length; ++j) { SetNeedForParallelizedVersion(patternGraph.parallelizedYieldings[i].ElementaryYieldings[j]); } } }
/// <summary> /// Matches the remaining component. /// </summary> /// <param name="graph">The graph.</param> /// <param name="remainingMatch">The remaining match.</param> /// <param name="foundComponents">The found components.</param> /// <returns>The component if it has been matched, null otherwise.</returns> private GraphComponent MatchRemainingComponent(PatternGraph graph, KeyValuePair <Component, List <ComponentMatch> > remainingMatch, List <GraphComponent> foundComponents) { var componentMatchFound = false; // check if the component inherits any found components var remainingMatchGraphComponent = graph.GetGraphComponent(remainingMatch.Key.Name); var foundComponentReferences = remainingMatchGraphComponent.References.Where(r => foundComponents.Contains(r.ReferencedComponent)); if (foundComponentReferences.Any()) { var componentRef = foundComponentReferences.First(); this.MatchComponentTypes(remainingMatchGraphComponent, componentRef.ReferencedComponent, componentRef, remainingMatch.Value, true); componentMatchFound = true; } else { // otherwise check if the component is inherited by any found components var referencedByFoundComponents = foundComponents.Where(c => c.References.Any(r => r.ReferencedComponent == remainingMatchGraphComponent)); if (referencedByFoundComponents.Any()) { var refByComponent = referencedByFoundComponents.First(); var refByComponentReference = refByComponent.References.Single(r => r.ReferencedComponent == remainingMatchGraphComponent); this.MatchComponentTypes(refByComponent, remainingMatchGraphComponent, refByComponentReference, remainingMatch.Value, false); componentMatchFound = true; } } if (componentMatchFound) { return(remainingMatchGraphComponent); } return(null); }
private static void InsertInlinedElementIdentityCheckIntoSchedule(PatternGraph patternGraph, List <SearchOperation> operations) { for (int i = 0; i < operations.Count; ++i) { PatternElement assignmentSource = null; if (operations[i].Element is SearchPlanNode) { assignmentSource = ((SearchPlanNode)operations[i].Element).PatternElement.AssignmentSource; } if (assignmentSource != null && operations[i].Type != SearchOperationType.Identity) { for (int j = 0; j < operations.Count; ++j) { SearchPlanNode binder = null; if (operations[j].Element is SearchPlanNode) { binder = (SearchPlanNode)operations[j].Element; } if (binder != null && binder.PatternElement == assignmentSource && operations[j].Type != SearchOperationType.Identity) { if (operations[i].Type != SearchOperationType.Assign && operations[j].Type != SearchOperationType.Assign) { int indexOfSecond = Math.Max(i, j); SearchOperation so = new SearchOperation(SearchOperationType.Identity, operations[i].Element, binder, operations[indexOfSecond].CostToEnd); operations.Insert(indexOfSecond + 1, so); break; } } } } } }
private static void CreatePlanNodeAndLookupPlanEdge(PatternEdge edge, int elemId, LGSPGraphStatistics graphStatistics, PatternGraph patternGraph, bool isNegativeOrIndependent, bool isSubpatternLike, PlanNode planRoot, float zeroCost, IDictionary<PatternNode, PatternNode> originalToInlinedIndependent, IDictionary<PatternElement, SetValueType> presetsFromIndependentInlining, out bool isPreset, out PlanNode planNode, out PlanEdge rootToNodePlanEdge) { float cost; SearchOperationType searchOperationType; if(edge.DefToBeYieldedTo) { cost = zeroCost; isPreset = true; searchOperationType = SearchOperationType.DefToBeYieldedTo; } else if(edge.PointOfDefinition == null) { cost = zeroCost; isPreset = true; searchOperationType = isSubpatternLike ? SearchOperationType.SubPreset : SearchOperationType.ActionPreset; } else if(edge.PointOfDefinition != patternGraph && edge.OriginalIndependentElement == null) { cost = zeroCost; isPreset = true; searchOperationType = isNegativeOrIndependent ? SearchOperationType.NegIdptPreset : SearchOperationType.SubPreset; } else if(presetsFromIndependentInlining.ContainsKey(edge)) { cost = zeroCost; isPreset = true; searchOperationType = SearchOperationType.NegIdptPreset; edge.PresetBecauseOfIndependentInlining = true; } else if(edge.Storage != null) { if(edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() != null) { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.Void; // the element we depend on is needed, so there is no lookup like operation } else { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.PickFromStorage; // pick from storage instead of lookup from graph } } else if(edge.IndexAccess != null) { if(edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() != null) { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.Void; // the element we depend on is needed, so there is no lookup like operation } else { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.PickFromIndex; // pick from index instead of lookup from graph } } else if(edge.NameLookup != null) { if(edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() != null) { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.Void; // the element we depend on is needed, so there is no lookup like operation } else { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.PickByName; // pick by name instead of lookup from graph } } else if(edge.UniqueLookup != null) { if(edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() != null) { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.Void; // the element we depend on is needed, so there is no lookup like operation } else { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.PickByUnique; // pick by unique instead of lookup from graph } } else if(edge.ElementBeforeCasting != null) { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.Void; // the element before casting is needed, so there is no lookup like operation } else { cost = graphStatistics.edgeCounts[edge.TypeID]; cost = CostIncreaseForInlinedIndependent(edge, cost); isPreset = false; searchOperationType = SearchOperationType.Lookup; } PatternNode source = GetSourcePlusInlined(edge, patternGraph, originalToInlinedIndependent); PatternNode target = GetTargetPlusInlined(edge, patternGraph, originalToInlinedIndependent); planNode = new PlanNode(edge, elemId, isPreset, source != null ? source.TempPlanMapping : null, target != null ? target.TempPlanMapping : null); rootToNodePlanEdge = null; if(searchOperationType != SearchOperationType.Void) rootToNodePlanEdge = new PlanEdge(searchOperationType, planRoot, planNode, cost); }
public static IEnumerable<PatternNode> NodesInIndependentMatchedThere(PatternGraph independent) { foreach(PatternNode node in independent.nodesPlusInlined) { if(node.PointOfDefinition == independent && !node.defToBeYieldedTo) yield return node; } }
/// <summary> /// Generates match objects of independents (one pre-allocated is part of action class) /// </summary> private void GenerateIndependentsMatchObjects(SourceBuilder sb, LGSPMatchingPattern matchingPatternClass, PatternGraph patternGraph) { if (patternGraph.nestedIndependents != null) { foreach (KeyValuePair<PatternGraph, PatternGraph> nestedIndependent in patternGraph.nestedIndependents) { if(nestedIndependent.Key.originalPatternGraph != null) { sb.AppendFrontFormat("private {0} {1} = new {0}();", nestedIndependent.Key.originalSubpatternEmbedding.matchingPatternOfEmbeddedGraph.GetType().Name + "." + NamesOfEntities.MatchClassName(nestedIndependent.Key.originalPatternGraph.pathPrefix + nestedIndependent.Key.originalPatternGraph.name), NamesOfEntities.MatchedIndependentVariable(nestedIndependent.Key.pathPrefix + nestedIndependent.Key.name)); } else { sb.AppendFrontFormat("private {0} {1} = new {0}();", matchingPatternClass.GetType().Name + "." + NamesOfEntities.MatchClassName(nestedIndependent.Key.pathPrefix + nestedIndependent.Key.name), NamesOfEntities.MatchedIndependentVariable(nestedIndependent.Key.pathPrefix + nestedIndependent.Key.name)); } } } foreach (PatternGraph idpt in patternGraph.independentPatternGraphsPlusInlined) { GenerateIndependentsMatchObjects(sb, matchingPatternClass, idpt); } }
public static void SetNeedForProfiling(PatternGraph patternGraph) { foreach(PatternCondition condition in patternGraph.Conditions) { SetNeedForProfiling(condition.ConditionExpression); } foreach(PatternYielding patternYielding in patternGraph.Yieldings) { foreach(Yielding yielding in patternYielding.ElementaryYieldings) { SetNeedForProfiling(yielding); } } foreach(PatternGraph idpt in patternGraph.independentPatternGraphsPlusInlined) { SetNeedForProfiling(idpt); } foreach(PatternGraph neg in patternGraph.negativePatternGraphsPlusInlined) { SetNeedForProfiling(neg); } foreach(Alternative alt in patternGraph.alternativesPlusInlined) { foreach(PatternGraph altCase in alt.alternativeCases) { SetNeedForProfiling(altCase); } } foreach(Iterated iter in patternGraph.iteratedsPlusInlined) { SetNeedForProfiling(iter.iteratedPattern); } }
/// <summary> /// Matches the component match types, with the implementations. /// </summary> /// <param name="graph">The graph.</param> /// <param name="possibleImplementation">The possible implementation.</param> private Dictionary <Component, List <ComponentMatch> > MatchImplementationComponentTypes(PatternGraph graph, Dictionary <Component, List <ComponentMatch> > possibleImplementation) { var componentsToRemove = new List <Component>(); foreach (var componentToCheck in possibleImplementation) { var componentToCheckMatch = componentToCheck.Value[0]; var currentComponent = componentToCheck.Key; var currentGraphComponent = graph.GetGraphComponent(currentComponent.Name); var otherComponents = possibleImplementation.Where(i => i.Key != currentComponent); var otherGraphComponents = graph.GetGraphComponents(otherComponents.Select(c => c.Key.Name)); var currentComponentReferences = currentGraphComponent.References; var currentComponentReferencedBy = otherGraphComponents.Where(c => c.References.Any(r => r.ReferencedComponent == currentGraphComponent)); var typeMatch = true; foreach (var currentComponentReference in currentComponentReferences) { var knownParentTypes = this.GetSymbolInformation(possibleImplementation, currentComponentReference.ReferencedComponent.Component); typeMatch &= this.MatchUnknownChildWithKnownParent(componentToCheckMatch, knownParentTypes, currentComponentReference); } foreach (var referencedBy in currentComponentReferencedBy) { var knownChildTypes = this.GetSymbolInformation(possibleImplementation, referencedBy.Component); var reference = referencedBy.References.Single(r => r.ReferencedComponent == currentGraphComponent); typeMatch &= this.MatchKnownChildWithUnknownParent(knownChildTypes, componentToCheckMatch, reference); } // if there is no match, remove the first hit from the pattern. The pattern is incomplete. if (!typeMatch) { componentsToRemove.Add(currentGraphComponent.Component); } } foreach (var componentToRemove in componentsToRemove) { possibleImplementation.Remove(componentToRemove); } return(possibleImplementation); }
/// <summary> /// Generates the parallelized search program for the given iterated pattern /// </summary> SearchProgram GenerateParallelizedSearchProgramIteratedAsNeeded(LGSPMatchingPattern matchingPattern, PatternGraph iter) { if(matchingPattern.patternGraph.parallelizedSchedule == null) return null; // build pass: build nested program from scheduled search plan of the all pattern SearchProgramBuilder searchProgramBuilder = new SearchProgramBuilder(); SearchProgram searchProgram = searchProgramBuilder.BuildSearchProgram(model, matchingPattern, iter, true, Profile); #if DUMP_SEARCHPROGRAMS // dump built search program for debugging SourceBuilder builder = new SourceBuilder(CommentSourceCode); searchProgram.Dump(builder); StreamWriter writer = new StreamWriter(matchingPattern.name + "_parallelized_" + iter.name + "_" + searchProgram.Name + "_built_dump.txt"); writer.Write(builder.ToString()); writer.Close(); #endif // complete pass: complete check operations in all search programs SearchProgramCompleter searchProgramCompleter = new SearchProgramCompleter(); searchProgramCompleter.CompleteCheckOperationsInAllSearchPrograms(searchProgram); #if DUMP_SEARCHPROGRAMS // dump completed search program for debugging builder = new SourceBuilder(CommentSourceCode); searchProgram.Dump(builder); writer = new StreamWriter(matchingPattern.name + "_parallelized_" + iter.name + "_" + searchProgram.Name + "_completed_dump.txt"); writer.Write(builder.ToString()); writer.Close(); #endif return searchProgram; }
public readonly float Cost; // (needed for scheduling nac-subgraphs into the full graph) public ScheduledSearchPlan(PatternGraph patternGraph, SearchOperation[] ops, float cost) { PatternGraph = patternGraph; Operations = ops; Cost = cost; }
/// <summary> /// Instantiates a new PatternElement object as a copy from an original element, used for independent inlining. /// </summary> /// <param name="original">The original pattern element to be copy constructed.</param> /// <param name="nameSuffix">The suffix to be added to the name of the pattern element (to avoid name collisions).</param> public PatternElement(PatternElement original, String nameSuffix) { TypeID = original.TypeID; typeName = original.typeName; name = original.name + nameSuffix; unprefixedName = original.unprefixedName + nameSuffix; pointOfDefinition = original.pointOfDefinition; defToBeYieldedTo = original.defToBeYieldedTo; initialization = original.initialization != null ? original.initialization.Copy(nameSuffix) : null; annotations = original.annotations; AllowedTypes = original.AllowedTypes; IsAllowedType = original.IsAllowedType; Cost = original.Cost; ParameterIndex = original.ParameterIndex; MaybeNull = original.MaybeNull; Storage = original.Storage != null ? new StorageAccess(original.Storage) : null; StorageIndex = original.StorageIndex != null ? new StorageAccessIndex(original.StorageIndex) : null; IndexAccess = original.IndexAccess != null ? original.IndexAccess.Copy(nameSuffix) : null; NameLookup = original.NameLookup != null ? original.NameLookup.Copy(nameSuffix) : null; UniqueLookup = original.UniqueLookup != null ? original.UniqueLookup.Copy(nameSuffix) : null; ElementBeforeCasting = original.ElementBeforeCasting; AssignmentSource = original.AssignmentSource; OriginalIndependentElement = original; }
/// <summary> /// Builds search program from scheduled search plan in pattern graph of the subpattern rule pattern /// </summary> public static SearchProgram BuildSearchProgram( IGraphModel model, LGSPMatchingPattern matchingPattern, bool parallelized, bool emitProfiling) { Debug.Assert(!(matchingPattern is LGSPRulePattern)); PatternGraph patternGraph = matchingPattern.patternGraph; String rulePatternClassName = NamesOfEntities.RulePatternClassName(matchingPattern.name, matchingPattern.PatternGraph.Package, true); SearchProgramBodyBuilder builder = new SearchProgramBodyBuilder( SearchProgramType.Subpattern, model, rulePatternClassName, null, null, null, patternGraph, emitProfiling, parallelized, 0 ); List <String> matchingPatternClassTypeNames = new List <String>(); List <Dictionary <PatternGraph, bool> > nestedIndependents = new List <Dictionary <PatternGraph, bool> >(); ExtractNestedIndependents(matchingPatternClassTypeNames, nestedIndependents, matchingPattern, patternGraph); // build outermost search program operation, create the list anchor starting its program SearchProgram searchProgram = new SearchProgramOfSubpattern( rulePatternClassName, patternGraph.Name, matchingPattern.patternGraph.patternGraphsOnPathToEnclosedPatternpath, "myMatch", builder.wasIndependentInlined(patternGraph, 0), matchingPatternClassTypeNames, nestedIndependents, parallelized); searchProgram.OperationsList = new SearchProgramList(searchProgram); SearchProgramOperation insertionPoint = searchProgram.OperationsList; insertionPoint = insertVariableDeclarations(insertionPoint, patternGraph); // initialize task/result-pushdown handling in subpattern matcher InitializeSubpatternMatching initialize = new InitializeSubpatternMatching(InitializeFinalizeSubpatternMatchingType.Normal); insertionPoint = insertionPoint.Append(initialize); // start building with first operation in scheduled search plan insertionPoint = builder.BuildScheduledSearchPlanOperationIntoSearchProgram( 0, insertionPoint); // finalize task/result-pushdown handling in subpattern matcher FinalizeSubpatternMatching finalize = new FinalizeSubpatternMatching(InitializeFinalizeSubpatternMatchingType.Normal); insertionPoint = insertionPoint.Append(finalize); return(searchProgram); }
/// <summary> /// Negative/Independent schedules are merged as an operation into their enclosing schedules, /// at a position determined by their costs but not before all of their needed elements were computed /// </summary> public static void MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(PatternGraph patternGraph, bool lazyNegativeIndependentConditionEvaluation) { foreach (PatternGraph neg in patternGraph.negativePatternGraphsPlusInlined) { MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(neg, lazyNegativeIndependentConditionEvaluation); } foreach (PatternGraph idpt in patternGraph.independentPatternGraphsPlusInlined) { MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(idpt, lazyNegativeIndependentConditionEvaluation); } foreach (Alternative alt in patternGraph.alternativesPlusInlined) { foreach (PatternGraph altCase in alt.alternativeCases) { MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(altCase, lazyNegativeIndependentConditionEvaluation); } } foreach (Iterated iter in patternGraph.iteratedsPlusInlined) { MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(iter.iteratedPattern, lazyNegativeIndependentConditionEvaluation); } InsertNegativesAndIndependentsIntoSchedule(patternGraph, lazyNegativeIndependentConditionEvaluation); }
private static void ExtractNestedIndependents(List <String> matchingPatternClassTypeNames, List <Dictionary <PatternGraph, bool> > nestedIndependents, LGSPMatchingPattern matchingPattern, PatternGraph patternGraph) { matchingPatternClassTypeNames.Add(matchingPattern.GetType().Name); nestedIndependents.Add(patternGraph.nestedIndependents); foreach (PatternGraph idpt in patternGraph.independentPatternGraphsPlusInlined) { ExtractNestedIndependents(matchingPatternClassTypeNames, nestedIndependents, matchingPattern, idpt); } }
/// <summary> /// Inserts declarations for variables extracted from parameters /// </summary> private static SearchProgramOperation insertVariableDeclarations(SearchProgramOperation insertionPoint, PatternGraph patternGraph) { foreach (PatternVariable var in patternGraph.variablesPlusInlined) { if (!var.defToBeYieldedTo) // def variables are handled with the schedule, must come after the presets { // inlined variables are handled later, cause they may depend on elements matched if (var.originalVariable == null || !patternGraph.WasInlinedHere(var.originalSubpatternEmbedding)) { insertionPoint = insertionPoint.Append( new ExtractVariable(TypesHelper.TypeName(var.type), var.Name) ); } } } return(insertionPoint); }
/// <summary> /// Builds search program for iterated from scheduled search plan of iterated pattern graph /// </summary> public static SearchProgram BuildSearchProgram( IGraphModel model, LGSPMatchingPattern matchingPattern, PatternGraph iter, bool parallelized, bool emitProfiling) { String rulePatternClassName = NamesOfEntities.RulePatternClassName(matchingPattern.name, matchingPattern.PatternGraph.Package, !(matchingPattern is LGSPRulePattern)); SearchProgramBodyBuilder builder = new SearchProgramBodyBuilder( SearchProgramType.Iterated, model, rulePatternClassName, null, null, null, iter, emitProfiling, parallelized, 0 ); List <String> matchingPatternClassTypeNames = new List <String>(); List <Dictionary <PatternGraph, bool> > nestedIndependents = new List <Dictionary <PatternGraph, bool> >(); ExtractNestedIndependents(matchingPatternClassTypeNames, nestedIndependents, matchingPattern, iter); // build outermost search program operation, create the list anchor starting its program SearchProgram searchProgram = new SearchProgramOfIterated( rulePatternClassName, matchingPattern.patternGraph.Name, iter.Name, iter.pathPrefix, matchingPattern.patternGraph.patternGraphsOnPathToEnclosedPatternpath, "myMatch", builder.wasIndependentInlined(iter, 0), matchingPatternClassTypeNames, nestedIndependents, parallelized); searchProgram.OperationsList = new SearchProgramList(searchProgram); SearchProgramOperation insertionPoint = searchProgram.OperationsList; insertionPoint = insertVariableDeclarations(insertionPoint, iter); // initialize task/result-pushdown handling in subpattern matcher for iteration InitializeSubpatternMatching initialize = new InitializeSubpatternMatching(InitializeFinalizeSubpatternMatchingType.Iteration); insertionPoint = insertionPoint.Append(initialize); IteratedMatchingDummyLoop iteratedMatchingDummyLoop = new IteratedMatchingDummyLoop(); SearchProgramOperation continuationPointAfterIteratedMatching = insertionPoint.Append(iteratedMatchingDummyLoop); iteratedMatchingDummyLoop.NestedOperationsList = new SearchProgramList(iteratedMatchingDummyLoop); insertionPoint = iteratedMatchingDummyLoop.NestedOperationsList; // start building with first operation in scheduled search plan insertionPoint = builder.BuildScheduledSearchPlanOperationIntoSearchProgram( 0, insertionPoint); insertionPoint = continuationPointAfterIteratedMatching; // check whether iteration came to an end (pattern not found (again)) and handle it insertionPoint = builder.insertEndOfIterationHandling(insertionPoint); // finalize task/result-pushdown handling in subpattern matcher for iteration FinalizeSubpatternMatching finalize = new FinalizeSubpatternMatching(InitializeFinalizeSubpatternMatchingType.Iteration); insertionPoint = insertionPoint.Append(finalize); return(searchProgram); }
public static int NumEdgesInIndependentsMatchedThere(PatternGraph patternGraph) { int sum = 0; foreach(PatternGraph independent in patternGraph.independentPatternGraphsPlusInlined) { foreach(PatternEdge edge in independent.edgesPlusInlined) { if(edge.PointOfDefinition == independent && !edge.defToBeYieldedTo) ++sum; } } return sum; }
/// <summary> /// Inserts schedules of negative and independent pattern graphs into the schedule of the enclosing pattern graph /// for the schedule with the given array index /// </summary> private static void InsertNegativesAndIndependentsIntoSchedule(PatternGraph patternGraph, int index, bool lazyNegativeIndependentConditionEvaluation) { // todo: erst implicit node, dann negative/independent, auch wenn negative/independent mit erstem implicit moeglich wird patternGraph.schedulesIncludingNegativesAndIndependents[index] = null; // an explain might have filled this List <SearchOperation> operations = new List <SearchOperation>(); for (int i = 0; i < patternGraph.schedules[index].Operations.Length; ++i) { operations.Add(patternGraph.schedules[index].Operations[i]); } // nested patterns on the way to an enclosed patternpath modifier // must get matched after all local nodes and edges, because they require // all outer elements to be known in order to lock them for patternpath processing if (patternGraph.patternGraphsOnPathToEnclosedPatternpath .Contains(patternGraph.pathPrefix + patternGraph.name)) { operations.Add(new SearchOperation(SearchOperationType.LockLocalElementsForPatternpath, null, null, patternGraph.schedules[index].Operations.Length != 0 ? patternGraph.schedules[index].Operations[patternGraph.schedules[index].Operations.Length - 1].CostToEnd : 0)); } // iterate over all negative scheduled search plans (TODO: order?) for (int i = 0; i < patternGraph.negativePatternGraphsPlusInlined.Length; ++i) { ScheduledSearchPlan negSchedule = patternGraph.negativePatternGraphsPlusInlined[i].schedulesIncludingNegativesAndIndependents[0]; int bestFitIndex = operations.Count; float bestFitCostToEnd = 0; // find best place in scheduled search plan for current negative pattern // during search from end of schedule forward until the first element the negative pattern is dependent on is found for (int j = operations.Count - 1; j >= 0; --j) { SearchOperation op = operations[j]; if (op.Type == SearchOperationType.Condition || op.Type == SearchOperationType.NegativePattern || op.Type == SearchOperationType.IndependentPattern || op.Type == SearchOperationType.AssignVar) { continue; } if (lazyNegativeIndependentConditionEvaluation) { break; } if (op.Type == SearchOperationType.LockLocalElementsForPatternpath || op.Type == SearchOperationType.DefToBeYieldedTo) { break; // LockLocalElementsForPatternpath and DefToBeYieldedTo are barriers for neg/idpt } if (patternGraph.negativePatternGraphsPlusInlined[i].neededNodes.ContainsKey(((SearchPlanNode)op.Element).PatternElement.Name) || patternGraph.negativePatternGraphsPlusInlined[i].neededEdges.ContainsKey(((SearchPlanNode)op.Element).PatternElement.Name)) { break; } if (negSchedule.Cost <= op.CostToEnd) { // best fit as CostToEnd is monotonously growing towards operation[0] bestFitIndex = j; bestFitCostToEnd = op.CostToEnd; } } // insert pattern at best position operations.Insert(bestFitIndex, new SearchOperation(SearchOperationType.NegativePattern, negSchedule, null, bestFitCostToEnd + negSchedule.Cost)); // update costs of operations before best position for (int j = 0; j < bestFitIndex; ++j) { operations[j].CostToEnd += negSchedule.Cost; } } // iterate over all independent scheduled search plans (TODO: order?) for (int i = 0; i < patternGraph.independentPatternGraphsPlusInlined.Length; ++i) { ScheduledSearchPlan idptSchedule = patternGraph.independentPatternGraphsPlusInlined[i].schedulesIncludingNegativesAndIndependents[0]; int bestFitIndex = operations.Count; float bestFitCostToEnd = 0; IDictionary <PatternElement, SetValueType> presetsFromIndependentInlining = ExtractOwnElements(patternGraph.schedules[index], patternGraph.independentPatternGraphsPlusInlined[i]); // find best place in scheduled search plan for current independent pattern // during search from end of schedule forward until the first element the independent pattern is dependent on is found for (int j = operations.Count - 1; j >= 0; --j) { SearchOperation op = operations[j]; if (op.Type == SearchOperationType.Condition || op.Type == SearchOperationType.NegativePattern || op.Type == SearchOperationType.IndependentPattern || op.Type == SearchOperationType.AssignVar) { continue; } if (lazyNegativeIndependentConditionEvaluation) { break; } if (op.Type == SearchOperationType.LockLocalElementsForPatternpath || op.Type == SearchOperationType.DefToBeYieldedTo) { break; // LockLocalElementsForPatternpath and DefToBeYieldedTo are barriers for neg/idpt } PatternElement pe = ((SearchPlanNode)op.Element).PatternElement; if (patternGraph.independentPatternGraphsPlusInlined[i].neededNodes.ContainsKey(pe.Name) || patternGraph.independentPatternGraphsPlusInlined[i].neededEdges.ContainsKey(pe.Name)) { break; } if (pe.OriginalIndependentElement != null && presetsFromIndependentInlining.ContainsKey(pe.OriginalIndependentElement)) { break; } if (idptSchedule.Cost <= op.CostToEnd) { // best fit as CostToEnd is monotonously growing towards operation[0] bestFitIndex = j; bestFitCostToEnd = op.CostToEnd; } } // insert pattern at best position operations.Insert(bestFitIndex, new SearchOperation(SearchOperationType.IndependentPattern, idptSchedule, null, bestFitCostToEnd + idptSchedule.Cost)); // update costs of operations before best position for (int j = 0; j < bestFitIndex; ++j) { operations[j].CostToEnd += idptSchedule.Cost; } } InsertInlinedIndependentCheckForDuplicateMatch(operations); float cost = operations.Count > 0 ? operations[0].CostToEnd : 0; patternGraph.schedulesIncludingNegativesAndIndependents[index] = new ScheduledSearchPlan(patternGraph, operations.ToArray(), cost); }
/// <summary> /// Builds search program for alternative from scheduled search plans of the alternative cases /// </summary> public static SearchProgram BuildSearchProgram( IGraphModel model, LGSPMatchingPattern matchingPattern, Alternative alternative, bool parallelized, bool emitProfiling) { String rulePatternClassName = NamesOfEntities.RulePatternClassName(matchingPattern.name, matchingPattern.PatternGraph.Package, !(matchingPattern is LGSPRulePattern)); // build combined list of namesOfPatternGraphsOnPathToEnclosedPatternpath // from the namesOfPatternGraphsOnPathToEnclosedPatternpath of the alternative cases // also build combined lists of matching pattern class type names and nested independents List <string> namesOfPatternGraphsOnPathToEnclosedPatternpath = new List <string>(); List <string> matchingPatternClassTypeNames = new List <string>(); List <Dictionary <PatternGraph, bool> > nestedIndependents = new List <Dictionary <PatternGraph, bool> >(); for (int i = 0; i < alternative.alternativeCases.Length; ++i) { PatternGraph altCase = alternative.alternativeCases[i]; foreach (String name in altCase.patternGraphsOnPathToEnclosedPatternpath) { if (!namesOfPatternGraphsOnPathToEnclosedPatternpath.Contains(name)) { namesOfPatternGraphsOnPathToEnclosedPatternpath.Add(name); } } ExtractNestedIndependents(matchingPatternClassTypeNames, nestedIndependents, matchingPattern, altCase); } // build outermost search program operation, create the list anchor starting its program SearchProgram searchProgram = new SearchProgramOfAlternative( rulePatternClassName, namesOfPatternGraphsOnPathToEnclosedPatternpath, "myMatch", matchingPatternClassTypeNames, nestedIndependents, parallelized); searchProgram.OperationsList = new SearchProgramList(searchProgram); SearchProgramOperation insertionPoint = searchProgram.OperationsList; // initialize task/result-pushdown handling in subpattern matcher InitializeSubpatternMatching initialize = new InitializeSubpatternMatching(InitializeFinalizeSubpatternMatchingType.Normal); insertionPoint = insertionPoint.Append(initialize); // build alternative matching search programs, one per case for (int i = 0; i < alternative.alternativeCases.Length; ++i) { PatternGraph altCase = alternative.alternativeCases[i]; ScheduledSearchPlan scheduledSearchPlan = altCase.schedulesIncludingNegativesAndIndependents[0]; string inlinedPatternClassName = rulePatternClassName; string pathPrefixInInlinedPatternClass = scheduledSearchPlan.PatternGraph.pathPrefix; string unprefixedNameInInlinedPatternClass = scheduledSearchPlan.PatternGraph.name; if (alternative.originalAlternative != null) { inlinedPatternClassName = alternative.originalSubpatternEmbedding.matchingPatternOfEmbeddedGraph.GetType().Name; pathPrefixInInlinedPatternClass = alternative.originalAlternative.pathPrefix + alternative.originalAlternative.name + "_"; unprefixedNameInInlinedPatternClass = alternative.originalAlternative.alternativeCases[i].name; } SearchProgramBodyBuilder builder = new SearchProgramBodyBuilder( SearchProgramType.AlternativeCase, model, rulePatternClassName, null, null, null, altCase, emitProfiling, parallelized, 0 ); AlternativeCaseMatching alternativeCaseMatching = new AlternativeCaseMatching( pathPrefixInInlinedPatternClass, unprefixedNameInInlinedPatternClass, inlinedPatternClassName, builder.wasIndependentInlined(altCase, 0)); alternativeCaseMatching.OperationsList = new SearchProgramList(alternativeCaseMatching); SearchProgramOperation continuationPointAfterAltCase = insertionPoint.Append(alternativeCaseMatching); // at level of the current alt case insertionPoint = alternativeCaseMatching.OperationsList; insertionPoint = insertVariableDeclarations(insertionPoint, altCase); // start building with first operation in scheduled search plan builder.BuildScheduledSearchPlanOperationIntoSearchProgram( 0, insertionPoint); // back to level of alt cases insertionPoint = continuationPointAfterAltCase; // save matches found by alternative case to get clean start for matching next alternative case if (i < alternative.alternativeCases.Length - 1) { NewMatchesListForFollowingMatches newMatchesList = new NewMatchesListForFollowingMatches(true); insertionPoint = insertionPoint.Append(newMatchesList); } } // finalize task/result-pushdown handling in subpattern matcher FinalizeSubpatternMatching finalize = new FinalizeSubpatternMatching(InitializeFinalizeSubpatternMatchingType.Normal); insertionPoint = insertionPoint.Append(finalize); return(searchProgram); }
private ScheduledSearchPlan(PatternGraph patternGraph, float cost) { PatternGraph = patternGraph; Cost = cost; }
/// <summary> /// Instantiates a new PatternEdge object as a copy from an original edge, used for subpattern inlining. /// </summary> /// <param name="original">The original pattern edge to be copy constructed.</param> /// <param name="inlinedSubpatternEmbedding">The embedding which just gets inlined.</param> /// <param name="newHost">The pattern graph the new pattern element will be contained in.</param> /// <param name="nameSuffix">The suffix to be added to the name of the pattern edge (to avoid name collisions).</param> public PatternEdge(PatternEdge original, PatternGraphEmbedding inlinedSubpatternEmbedding, PatternGraph newHost, String nameSuffix) : base(original, inlinedSubpatternEmbedding, newHost, nameSuffix) { fixedDirection = original.fixedDirection; }
/// <summary> /// Gets the pattern implementations. /// </summary> /// <param name="pattern">The pattern.</param> /// <param name="componentMatches">The component matches.</param> /// <returns>A list of pattern implementations that need to be checked on completeness</returns> private List <Dictionary <Component, List <ComponentMatch> > > GetPatternImplementations(PatternGraph graph, Dictionary <Component, List <ComponentMatch> > componentMatches) { this.possibleImplementations = new List <Dictionary <Component, List <ComponentMatch> > >(); var singularComponentNames = graph.GetSingularComponentNames(); if (singularComponentNames.Count == 0) { // Todo. Not supported for v1. - Removed exception, just return null. return(null); } var startGraphComponent = graph.GetGraphComponent(singularComponentNames[0]); var startComponentMatches = componentMatches[startGraphComponent.Component]; foreach (var startComponentMatch in startComponentMatches) { this.possibleImplementations.Add(new Dictionary <Component, List <ComponentMatch> >() { { startGraphComponent.Component, new List <ComponentMatch>() { startComponentMatch } } }); } var foundComponents = new List <GraphComponent>() { startGraphComponent }; return(this.MapImplementations(graph, foundComponents, componentMatches)); }
/// <summary> /// Generates the action interface plus action implementation including the matcher source code /// for the alternatives/iterateds nested within the given negative/independent pattern graph into the given source builder /// </summary> public void GenerateActionAndMatcherOfNestedPatterns(SourceBuilder sb, LGSPMatchingPattern matchingPattern, PatternGraph negOrIdpt, bool isInitialStatic) { // nothing to do locally .. // .. just move on to the nested alternatives or iterateds foreach (Alternative alt in negOrIdpt.alternativesPlusInlined) { GenerateActionAndMatcherOfAlternative(sb, matchingPattern, alt, isInitialStatic); } foreach (Iterated iter in negOrIdpt.iteratedsPlusInlined) { GenerateActionAndMatcherOfIterated(sb, matchingPattern, iter.iteratedPattern, isInitialStatic); } foreach (PatternGraph nestedNeg in negOrIdpt.negativePatternGraphsPlusInlined) { GenerateActionAndMatcherOfNestedPatterns(sb, matchingPattern, nestedNeg, isInitialStatic); } foreach (PatternGraph nestedIdpt in negOrIdpt.independentPatternGraphsPlusInlined) { GenerateActionAndMatcherOfNestedPatterns(sb, matchingPattern, nestedIdpt, isInitialStatic); } }
public static IDictionary <PatternElement, SetValueType> ExtractOwnElements(ScheduledSearchPlan nestingScheduledSearchPlan, PatternGraph patternGraph) { Dictionary <PatternElement, SetValueType> ownElements = new Dictionary <PatternElement, SetValueType>(); // elements contained in the schedule of the nesting pattern, that are declared in the current pattern graph // stem from inlining an indepent, extract them to treat them specially in search plan building (preset from nesting pattern) if (nestingScheduledSearchPlan != null) { for (int i = 0; i < nestingScheduledSearchPlan.Operations.Length; ++i) { if (nestingScheduledSearchPlan.Operations[i].Type == SearchOperationType.Condition || nestingScheduledSearchPlan.Operations[i].Type == SearchOperationType.AssignVar || nestingScheduledSearchPlan.Operations[i].Type == SearchOperationType.DefToBeYieldedTo) { continue; } SearchPlanNode spn = (SearchPlanNode)nestingScheduledSearchPlan.Operations[i].Element; if (spn.PatternElement.pointOfDefinition == patternGraph) { ownElements.Add(spn.PatternElement.OriginalIndependentElement, null); } } } return(ownElements); }
/// <summary> /// Generates matcher class head source code for the given iterated pattern into given source builder /// isInitialStatic tells whether the initial static version or a dynamic version after analyze is to be generated. /// </summary> public void GenerateMatcherClassHeadIterated(SourceBuilder sb, LGSPMatchingPattern matchingPattern, PatternGraph iter, bool isInitialStatic) { PatternGraph patternGraph = (PatternGraph)matchingPattern.PatternGraph; String namePrefix = (isInitialStatic ? "" : "Dyn") + "IteratedAction_"; String className = namePrefix + iter.pathPrefix + iter.name; String matchingPatternClassName = matchingPattern.GetType().Name; if(patternGraph.Package != null) { sb.AppendFrontFormat("namespace {0}\n", patternGraph.Package); sb.AppendFront("{\n"); sb.Indent(); } sb.AppendFront("public class " + className + " : GRGEN_LGSP.LGSPSubpatternAction\n"); sb.AppendFront("{\n"); sb.Indent(); // class level sb.AppendFront("private " + className + "(GRGEN_LGSP.LGSPActionExecutionEnvironment actionEnv_, Stack<GRGEN_LGSP.LGSPSubpatternAction> openTasks_) {\n"); sb.Indent(); // method body level sb.AppendFront("actionEnv = actionEnv_; openTasks = openTasks_;\n"); sb.AppendFront("patternGraph = " + matchingPatternClassName + ".Instance.patternGraph;\n"); int index = -1; for (int i=0; i<iter.embeddingGraph.iteratedsPlusInlined.Length; ++i) { if (iter.embeddingGraph.iteratedsPlusInlined[i].iteratedPattern == iter) index = i; } sb.AppendFrontFormat("minMatchesIter = {0};\n", iter.embeddingGraph.iteratedsPlusInlined[index].minMatches); sb.AppendFrontFormat("maxMatchesIter = {0};\n", iter.embeddingGraph.iteratedsPlusInlined[index].maxMatches); sb.AppendFront("numMatchesIter = 0;\n"); if(iter.isIterationBreaking) sb.AppendFront("breakIteration = false;\n"); sb.Unindent(); // class level sb.AppendFront("}\n\n"); sb.AppendFront("int minMatchesIter;\n"); sb.AppendFront("int maxMatchesIter;\n"); sb.AppendFront("int numMatchesIter;\n"); if(iter.isIterationBreaking) sb.AppendFront("bool breakIteration;\n"); sb.Append("\n"); GenerateTasksMemoryPool(sb, className, false, iter.isIterationBreaking, matchingPattern.patternGraph.branchingFactor); Dictionary<string, bool> neededNodes = new Dictionary<string, bool>(); Dictionary<string, bool> neededEdges = new Dictionary<string, bool>(); Dictionary<string, GrGenType> neededVariables = new Dictionary<string, GrGenType>(); foreach (KeyValuePair<string, bool> neededNode in iter.neededNodes) neededNodes[neededNode.Key] = neededNode.Value; foreach (KeyValuePair<string, bool> neededEdge in iter.neededEdges) neededEdges[neededEdge.Key] = neededEdge.Value; foreach (KeyValuePair<string, GrGenType> neededVariable in iter.neededVariables) neededVariables[neededVariable.Key] = neededVariable.Value; foreach (KeyValuePair<string, bool> node in neededNodes) { sb.AppendFront("public GRGEN_LGSP.LGSPNode " + node.Key + ";\n"); } foreach (KeyValuePair<string, bool> edge in neededEdges) { sb.AppendFront("public GRGEN_LGSP.LGSPEdge " + edge.Key + ";\n"); } foreach (KeyValuePair<string, GrGenType> variable in neededVariables) { sb.AppendFront("public " + TypesHelper.TypeName(variable.Value) + " " + variable.Key + ";\n"); } GenerateIndependentsMatchObjects(sb, matchingPattern, iter); sb.AppendFront("\n"); }
public static PatternNode GetSourcePlusInlined(PatternEdge edge, PatternGraph patternGraph, IDictionary<PatternNode, PatternNode> originalToInlinedIndependent) { PatternNode source = patternGraph.GetSourcePlusInlined(edge); if(edge.OriginalIndependentElement != null && source == null) { PatternNode sourceOriginal = edge.OriginalIndependentElement.pointOfDefinition.GetSourcePlusInlined((PatternEdge)edge.OriginalIndependentElement); if(originalToInlinedIndependent.ContainsKey(sourceOriginal)) source = originalToInlinedIndependent[sourceOriginal]; else source = sourceOriginal; // not declared in independent itself, but in some parent } return source; }
/// <summary> /// Generates scheduled search plans needed for matcher code generation for action compilation /// out of graph with analyze information, /// The scheduled search plans are added to the main and the nested pattern graphs. /// </summary> public void GenerateScheduledSearchPlans(PatternGraph patternGraph, LGSPGraph graph, bool isSubpatternLike, bool isNegativeOrIndependent, ScheduledSearchPlan nestingScheduledSearchPlan) { for(int i=0; i<patternGraph.schedules.Length; ++i) { patternGraph.AdaptToMaybeNull(i); if(Profile) SetNeedForProfiling(patternGraph); PlanGraph planGraph = GeneratePlanGraph(graph.statistics, patternGraph, isNegativeOrIndependent, isSubpatternLike, ExtractOwnElements(nestingScheduledSearchPlan, patternGraph)); MarkMinimumSpanningArborescence(planGraph, patternGraph.name); SearchPlanGraph searchPlanGraph = GenerateSearchPlanGraph(planGraph); ScheduledSearchPlan scheduledSearchPlan = ScheduleSearchPlan( searchPlanGraph, patternGraph, isNegativeOrIndependent); AppendHomomorphyInformation(scheduledSearchPlan); patternGraph.schedules[i] = scheduledSearchPlan; patternGraph.RevertMaybeNullAdaption(i); foreach(PatternGraph neg in patternGraph.negativePatternGraphsPlusInlined) { GenerateScheduledSearchPlans(neg, graph, isSubpatternLike, true, null); } foreach(PatternGraph idpt in patternGraph.independentPatternGraphsPlusInlined) { GenerateScheduledSearchPlans(idpt, graph, isSubpatternLike, true, patternGraph.schedules[i]); } foreach(Alternative alt in patternGraph.alternativesPlusInlined) { foreach (PatternGraph altCase in alt.alternativeCases) { GenerateScheduledSearchPlans(altCase, graph, true, false, null); } } foreach(Iterated iter in patternGraph.iteratedsPlusInlined) { GenerateScheduledSearchPlans(iter.iteratedPattern, graph, true, false, null); } } }
protected LGSPAction(PatternGraph patternGraph, object[] returnArray) { this.patternGraph = patternGraph; this.ReturnArray = returnArray; }
public static IDictionary<PatternElement, SetValueType> ExtractOwnElements(ScheduledSearchPlan nestingScheduledSearchPlan, PatternGraph patternGraph) { Dictionary<PatternElement, SetValueType> ownElements = new Dictionary<PatternElement,SetValueType>(); // elements contained in the schedule of the nesting pattern, that are declared in the current pattern graph // stem from inlining an indepent, extract them to treat them specially in search plan building (preset from nesting pattern) if(nestingScheduledSearchPlan != null) { for(int i = 0; i < nestingScheduledSearchPlan.Operations.Length; ++i) { if(nestingScheduledSearchPlan.Operations[i].Type == SearchOperationType.Condition || nestingScheduledSearchPlan.Operations[i].Type == SearchOperationType.AssignVar || nestingScheduledSearchPlan.Operations[i].Type == SearchOperationType.DefToBeYieldedTo) { continue; } SearchPlanNode spn = (SearchPlanNode)nestingScheduledSearchPlan.Operations[i].Element; if(spn.PatternElement.pointOfDefinition == patternGraph) { ownElements.Add(spn.PatternElement.OriginalIndependentElement, null); } } } return ownElements; }
/// <summary> /// Builds a pattern graph out of the graph. /// The pattern graph retains links to the original graph elements and uses them for attribute comparison. /// </summary> /// <param name="graph">The graph which is to be transfered into a pattern</param> /// <returns></returns> private static PatternGraph BuildPatternGraph(IGraph graph) { int numNodes = graph.NumNodes; int numEdges = graph.NumEdges; int count = 0; PatternNode[] nodes = new PatternNode[numNodes]; INode[] correspondingNodes = new INode[numNodes]; foreach (INode node in graph.Nodes) { LGSPNode n = (LGSPNode)node; nodes[count] = new PatternNode( n.Type.TypeID, n.Type, n.Type.PackagePrefixedName, graph.Name + "_node_" + count, "node_" + count, null, null, 1.0f, -1, false, null, null, null, null, null, null, false, null ); correspondingNodes[count] = node; ++count; } count = 0; PatternEdge[] edges = new PatternEdge[numEdges]; IEdge[] correspondingEdges = new IEdge[numEdges]; foreach (IEdge edge in graph.Edges) { LGSPEdge e = (LGSPEdge)edge; edges[count] = new PatternEdge( true, e.Type.TypeID, e.Type, e.Type.PackagePrefixedName, graph.Name + "_edge_" + count, "edge_" + count, null, null, 1.0f, -1, false, null, null, null, null, null, null, false, null ); correspondingEdges[count] = edge; ++count; } bool[,] homNodes = new bool[numNodes, numNodes]; for (int i = 0; i < numNodes; ++i) { for (int j = 0; j < numNodes; ++j) { homNodes[i, j] = false; } } bool[,] homEdges = new bool[numEdges, numEdges]; for (int i = 0; i < numEdges; ++i) { for (int j = 0; j < numEdges; ++j) { homEdges[i, j] = false; } } bool[,] homNodesGlobal = new bool[numNodes, numNodes]; for (int i = 0; i < numNodes; ++i) { for (int j = 0; j < numNodes; ++j) { homNodesGlobal[i, j] = false; } } bool[,] homEdgesGlobal = new bool[numEdges, numEdges]; for (int i = 0; i < numEdges; ++i) { for (int j = 0; j < numEdges; ++j) { homEdgesGlobal[i, j] = false; } } bool[] totallyHomNodes = new bool[numNodes]; for (int i = 0; i < numNodes; ++i) { totallyHomNodes[i] = false; } bool[] totallyHomEdges = new bool[numEdges]; for (int i = 0; i < numEdges; ++i) { totallyHomEdges[i] = false; } List <PatternCondition> pcs = new List <PatternCondition>(); for (int i = 0; i < numNodes; ++i) { if (nodes[i].Type.NumAttributes > 0) { pcs.Add(new PatternCondition(new expression.AreAttributesEqual(correspondingNodes[i], nodes[i]), new string[] { nodes[i].name }, new string[] { }, new string[] { }, new PatternNode[] { nodes[i] }, new PatternEdge[] { }, new PatternVariable[] { })); } } for (int i = 0; i < numEdges; ++i) { if (edges[i].Type.NumAttributes > 0) { pcs.Add(new PatternCondition(new expression.AreAttributesEqual(correspondingEdges[i], edges[i]), new string[] { }, new string[] { edges[i].name }, new string[] { }, new PatternNode[] { }, new PatternEdge[] { edges[i] }, new PatternVariable[] { })); } } PatternCondition[] patternConditions = pcs.ToArray(); PatternGraph patternGraph = new PatternGraph( graph.Name, nodes, edges, patternConditions, homNodes, homEdges, homNodesGlobal, homEdgesGlobal, totallyHomNodes, totallyHomEdges, correspondingNodes, correspondingEdges ); foreach (PatternNode node in nodes) { node.pointOfDefinition = patternGraph; } foreach (PatternEdge edge in edges) { edge.pointOfDefinition = patternGraph; } foreach (IEdge edge in graph.Edges) { int edgeIndex = Array.IndexOf <IEdge>(correspondingEdges, edge); int sourceIndex = Array.IndexOf <INode>(correspondingNodes, edge.Source); int targetIndex = Array.IndexOf <INode>(correspondingNodes, edge.Target); patternGraph.edgeToSourceNode.Add(edges[edgeIndex], nodes[sourceIndex]); patternGraph.edgeToTargetNode.Add(edges[edgeIndex], nodes[targetIndex]); } PatternGraphAnalyzer.PrepareInline(patternGraph); return(patternGraph); }
private void CreateSourceTargetIncomingOutgoingPlanEdges(PatternEdge edge, PlanNode planNode, List<PlanEdge> planEdges, IDictionary<PatternNode, PatternNode> originalToInlinedIndependent, LGSPGraphStatistics graphStatistics, PatternGraph patternGraph, bool isPreset, float zeroCost) { // only add implicit source operation if edge source is needed and the edge source is // not a preset node and not a storage node and not an index node and not a cast node PatternNode source = GetSourcePlusInlined(edge, patternGraph, originalToInlinedIndependent); if(source != null && !source.TempPlanMapping.IsPreset && source.Storage == null && source.IndexAccess == null && source.NameLookup == null && source.UniqueLookup == null && source.ElementBeforeCasting == null) { SearchOperationType operation = edge.fixedDirection ? SearchOperationType.ImplicitSource : SearchOperationType.Implicit; PlanEdge implSrcPlanEdge = new PlanEdge(operation, planNode, source.TempPlanMapping, zeroCost); planEdges.Add(implSrcPlanEdge); source.TempPlanMapping.IncomingEdges.Add(implSrcPlanEdge); } // only add implicit target operation if edge target is needed and the edge target is // not a preset node and not a storage node and not an index node and not a cast node PatternNode target = GetTargetPlusInlined(edge, patternGraph, originalToInlinedIndependent); if(target != null && !target.TempPlanMapping.IsPreset && target.Storage == null && target.IndexAccess == null && target.NameLookup == null && target.UniqueLookup == null && target.ElementBeforeCasting == null) { SearchOperationType operation = edge.fixedDirection ? SearchOperationType.ImplicitTarget : SearchOperationType.Implicit; PlanEdge implTgtPlanEdge = new PlanEdge(operation, planNode, target.TempPlanMapping, zeroCost); planEdges.Add(implTgtPlanEdge); target.TempPlanMapping.IncomingEdges.Add(implTgtPlanEdge); } // edge must only be reachable from other nodes if it's not a preset and not storage determined and not index determined and not a cast if(!isPreset && edge.Storage == null && edge.IndexAccess == null && edge.NameLookup == null && edge.UniqueLookup == null && edge.ElementBeforeCasting == null) { // no outgoing on source node if no source if(source != null) { int targetTypeID; if(target != null) targetTypeID = target.TypeID; else targetTypeID = model.NodeModel.RootType.TypeID; // cost of walking along edge #if MONO_MULTIDIMARRAY_WORKAROUND float normCost = graphStatistics.vstructs[((source.TypeID * graphStatistics.dim1size + edge.TypeID) * graphStatistics.dim2size + targetTypeID) * 2 + (int)LGSPDirection.Out]; if(!edge.fixedDirection) { normCost += graphStatistics.vstructs[((source.TypeID * graphStatistics.dim1size + edge.TypeID) * graphStatistics.dim2size + targetTypeID) * 2 + (int)LGSPDirection.In]; } #else float normCost = graph.statistics.vstructs[source.TypeID, edge.TypeID, targetTypeID, (int) LGSPDirection.Out]; if (!edge.fixedDirection) { normCost += graph.statistics.vstructs[source.TypeID, edge.TypeID, targetTypeID, (int) LGSPDirection.In]; } #endif if(graphStatistics.nodeCounts[source.TypeID] != 0) normCost /= graphStatistics.nodeCounts[source.TypeID]; normCost = CostIncreaseForInlinedIndependent(edge, normCost); SearchOperationType operation = edge.fixedDirection ? SearchOperationType.Outgoing : SearchOperationType.Incident; PlanEdge outPlanEdge = new PlanEdge(operation, source.TempPlanMapping, planNode, normCost); planEdges.Add(outPlanEdge); planNode.IncomingEdges.Add(outPlanEdge); } // no incoming on target node if no target if(target != null) { int sourceTypeID; if(source != null) sourceTypeID = source.TypeID; else sourceTypeID = model.NodeModel.RootType.TypeID; // cost of walking in opposite direction of edge #if MONO_MULTIDIMARRAY_WORKAROUND float revCost = graphStatistics.vstructs[((target.TypeID * graphStatistics.dim1size + edge.TypeID) * graphStatistics.dim2size + sourceTypeID) * 2 + (int)LGSPDirection.In]; if(!edge.fixedDirection) { revCost += graphStatistics.vstructs[((target.TypeID * graphStatistics.dim1size + edge.TypeID) * graphStatistics.dim2size + sourceTypeID) * 2 + (int)LGSPDirection.Out]; } #else float revCost = graph.statistics.vstructs[target.TypeID, edge.TypeID, sourceTypeID, (int) LGSPDirection.In]; if (!edge.fixedDirection) { revCost += graph.statistics.vstructs[target.TypeID, edge.TypeID, sourceTypeID, (int) LGSPDirection.Out]; } #endif if(graphStatistics.nodeCounts[target.TypeID] != 0) revCost /= graphStatistics.nodeCounts[target.TypeID]; revCost = CostIncreaseForInlinedIndependent(edge, revCost); SearchOperationType operation = edge.fixedDirection ? SearchOperationType.Incoming : SearchOperationType.Incident; PlanEdge inPlanEdge = new PlanEdge(operation, target.TempPlanMapping, planNode, revCost); planEdges.Add(inPlanEdge); planNode.IncomingEdges.Add(inPlanEdge); } } }
//////////////////////////////////////////////////////////////////////////// /// <summary> /// Constructs an Alternative object. /// </summary> /// <param name="name">Name of the alternative.</param> /// <param name="pathPrefix">Prefix for name from nesting path.</param> /// <param name="cases">Array with the alternative cases.</param> public Alternative(String name, String pathPrefix, PatternGraph[] cases) { this.name = name; this.pathPrefix = pathPrefix; this.alternativeCases = cases; }
public static IEnumerable<PatternEdge> EdgesInIndependentMatchedThere(PatternGraph independent) { foreach(PatternEdge edge in independent.edgesPlusInlined) { if(edge.PointOfDefinition == independent && !edge.defToBeYieldedTo) yield return edge; } }
//////////////////////////////////////////////////////////////////////////// /// <summary> /// Constructs an Iterated object. /// </summary> /// <param name="iterated">PatternGraph of the iterated.</param> public Iterated(PatternGraph iteratedPattern, int minMatches, int maxMatches) { this.iteratedPattern = iteratedPattern; this.minMatches = minMatches; this.maxMatches = maxMatches; }
/// <summary> /// Builds a pattern graph out of the graph. /// The pattern graph retains links to the original graph elements and uses them for attribute comparison. /// </summary> /// <param name="graph">The graph which is to be transfered into a pattern</param> /// <returns></returns> public PatternGraph BuildPatternGraph(LGSPGraph graph) { int numNodes = graph.NumNodes; int numEdges = graph.NumEdges; int count = 0; PatternNode[] nodes = new PatternNode[numNodes]; INode[] correspondingNodes = new INode[numNodes]; foreach(INode node in graph.Nodes) { LGSPNode n = (LGSPNode)node; nodes[count] = new PatternNode( n.Type.TypeID, n.Type, n.Type.PackagePrefixedName, graph.Name+"_node_"+count, "node_"+count, null, null, 1.0f, -1, false, null, null, null, null, null, null, false, null ); correspondingNodes[count] = node; ++count; } count = 0; PatternEdge[] edges = new PatternEdge[numEdges]; IEdge[] correspondingEdges = new IEdge[numEdges]; foreach(IEdge edge in graph.Edges) { LGSPEdge e = (LGSPEdge)edge; edges[count] = new PatternEdge( true, e.Type.TypeID, e.Type, e.Type.PackagePrefixedName, graph.Name+"_edge_"+count, "edge_"+count, null, null, 1.0f, -1, false, null, null, null, null, null, null, false, null ); correspondingEdges[count] = edge; ++count; } bool[,] homNodes = new bool[numNodes, numNodes]; for(int i = 0; i < numNodes; ++i) for(int j = 0; j < numNodes; ++j) homNodes[i, j] = false; bool[,] homEdges = new bool[numEdges, numEdges]; for(int i = 0; i < numEdges; ++i) for(int j = 0; j < numEdges; ++j) homEdges[i, j] = false; bool[,] homNodesGlobal = new bool[numNodes, numNodes]; for(int i = 0; i < numNodes; ++i) for(int j = 0; j < numNodes; ++j) homNodesGlobal[i, j] = false; bool[,] homEdgesGlobal = new bool[numEdges, numEdges]; for(int i = 0; i < numEdges; ++i) for(int j = 0; j < numEdges; ++j) homEdgesGlobal[i, j] = false; bool[] totallyHomNodes = new bool[numNodes]; for(int i = 0; i < numNodes; ++i) totallyHomNodes[i] = false; bool[] totallyHomEdges = new bool[numEdges]; for(int i = 0; i < numEdges; ++i) totallyHomEdges[i] = false; List<PatternCondition> pcs = new List<PatternCondition>(); for(int i = 0; i < numNodes; ++i) { if(nodes[i].Type.NumAttributes > 0) pcs.Add(new PatternCondition(new expression.AreAttributesEqual(correspondingNodes[i], nodes[i]), new string[] { nodes[i].name }, new string[] { }, new string[] { }, new VarType[] { })); } for(int i = 0; i < numEdges; ++i) { if(edges[i].Type.NumAttributes > 0) pcs.Add(new PatternCondition(new expression.AreAttributesEqual(correspondingEdges[i], edges[i]), new string[] { }, new string[] { edges[i].name }, new string[] { }, new VarType[] { })); } PatternCondition[] patternConditions = pcs.ToArray(); PatternGraph patternGraph = new PatternGraph( graph.Name, "", null, graph.Name, false, false, nodes, edges, new PatternVariable[0], new PatternGraphEmbedding[0], new Alternative[0], new Iterated[0], new PatternGraph[0], new PatternGraph[0], patternConditions, new PatternYielding[0], homNodes, homEdges, homNodesGlobal, homEdgesGlobal, totallyHomNodes, totallyHomEdges ); foreach(PatternNode node in nodes) node.pointOfDefinition = patternGraph; foreach(PatternEdge edge in edges) edge.pointOfDefinition = patternGraph; patternGraph.correspondingNodes = correspondingNodes; patternGraph.correspondingEdges = correspondingEdges; foreach(IEdge edge in graph.Edges) { int edgeIndex = Array.IndexOf<IEdge>(correspondingEdges, edge); int sourceIndex = Array.IndexOf<INode>(correspondingNodes, edge.Source); int targetIndex = Array.IndexOf<INode>(correspondingNodes, edge.Target); patternGraph.edgeToSourceNode.Add(edges[edgeIndex], nodes[sourceIndex]); patternGraph.edgeToTargetNode.Add(edges[edgeIndex], nodes[targetIndex]); } PatternGraphAnalyzer.PrepareInline(patternGraph); return patternGraph; }
/// <summary> /// Builds search program from scheduled search plan at given index in pattern graph of the action rule pattern /// </summary> public static SearchProgram BuildSearchProgram( IGraphModel model, LGSPRulePattern rulePattern, int index, string nameOfSearchProgram, bool parallelized, bool emitProfiling) { PatternGraph patternGraph = rulePattern.patternGraph; String rulePatternClassName = NamesOfEntities.RulePatternClassName(rulePattern.name, rulePattern.PatternGraph.Package, false); // filter out parameters which are implemented by lookup due to maybe null unfolding // and suffix matcher method name by missing parameters which get computed by lookup here string[] parameterTypes; string[] parameterNames; String name; GetFilteredParametersAndSuffixedMatcherName( rulePattern, patternGraph, parallelized ? 0 : index, out parameterTypes, out parameterNames, out name); SearchProgramBodyBuilder builder = new SearchProgramBodyBuilder( SearchProgramType.Action, model, rulePatternClassName, rulePattern.patternGraph.Package != null ? rulePattern.patternGraph.Package + "::" + rulePattern.name : rulePattern.name, parameterNames, parameterTypes, patternGraph, emitProfiling, parallelized, index ); // this is the all presets available method (index 0) and there are presets which may be null? // -> collect data for missing preset calls List <String[]> paramTypesList = null; List <String[]> paramNamesList = null; List <String> suffixedMatcherNameList = null; if (patternGraph.schedules.Length > 1 && index == 0) { paramTypesList = new List <String[]>(); paramNamesList = new List <String[]>(); suffixedMatcherNameList = new List <String>(); for (int i = 0; i < patternGraph.schedules.Length; ++i) { String[] paramTypes; String[] paramNames; String suffixedMatcherName; GetFilteredParametersAndSuffixedMatcherName( rulePattern, patternGraph, i, out paramTypes, out paramNames, out suffixedMatcherName); paramTypesList.Add(paramTypes); paramNamesList.Add(paramNames); suffixedMatcherNameList.Add(suffixedMatcherName); } } // build outermost search program operation, create the list anchor starting its program bool containsSubpatterns = patternGraph.embeddedGraphsPlusInlined.Length > 0 || patternGraph.iteratedsPlusInlined.Length > 0 || patternGraph.alternativesPlusInlined.Length > 0; SearchProgram searchProgram; if (parallelized) { if (index == 1) { List <String> matchingPatternClassTypeNames = new List <String>(); List <Dictionary <PatternGraph, bool> > nestedIndependents = new List <Dictionary <PatternGraph, bool> >(); ExtractNestedIndependents(matchingPatternClassTypeNames, nestedIndependents, rulePattern, patternGraph); searchProgram = new SearchProgramOfActionParallelizationBody( rulePatternClassName, patternGraph.name, name + "_parallelized_body", rulePattern.patternGraph.patternGraphsOnPathToEnclosedPatternpath, containsSubpatterns, builder.wasIndependentInlined(patternGraph, index), matchingPatternClassTypeNames, nestedIndependents, emitProfiling, patternGraph.PackagePrefixedName); } else // index == 0 { searchProgram = new SearchProgramOfActionParallelizationHead( rulePatternClassName, patternGraph.name, parameterTypes, parameterNames, name + "_parallelized", emitProfiling, patternGraph.PackagePrefixedName); } } else { List <String> matchingPatternClassTypeNames = new List <String>(); List <Dictionary <PatternGraph, bool> > nestedIndependents = new List <Dictionary <PatternGraph, bool> >(); ExtractNestedIndependents(matchingPatternClassTypeNames, nestedIndependents, rulePattern, patternGraph); searchProgram = new SearchProgramOfAction( rulePatternClassName, patternGraph.name, parameterTypes, parameterNames, name, rulePattern.patternGraph.patternGraphsOnPathToEnclosedPatternpath, containsSubpatterns, builder.wasIndependentInlined(patternGraph, 0), matchingPatternClassTypeNames, nestedIndependents, emitProfiling, patternGraph.PackagePrefixedName, patternGraph.maybeNullElementNames, suffixedMatcherNameList, paramNamesList); } searchProgram.OperationsList = new SearchProgramList(searchProgram); SearchProgramOperation insertionPoint = searchProgram.OperationsList; if (!parallelized || index == 0) { insertionPoint = insertVariableDeclarations(insertionPoint, patternGraph); } // start building with first operation in scheduled search plan insertionPoint = builder.BuildScheduledSearchPlanOperationIntoSearchProgram( 0, insertionPoint); return(searchProgram); }
public static PatternNode GetTargetPlusInlined(PatternEdge edge, PatternGraph patternGraph, IDictionary<PatternNode, PatternNode> originalToInlinedIndependent) { PatternNode target = patternGraph.GetTargetPlusInlined(edge); if(edge.OriginalIndependentElement != null && target == null) { PatternNode targetOriginal = edge.OriginalIndependentElement.pointOfDefinition.GetTargetPlusInlined((PatternEdge)edge.OriginalIndependentElement); if(originalToInlinedIndependent.ContainsKey(targetOriginal)) target = originalToInlinedIndependent[targetOriginal]; else target = targetOriginal; // not declared in independent itself, but in some parent } return target; }
/// <summary> /// Inserts inlined variable assignments into the schedule given by the operations list at their earliest possible position /// </summary> private static void InsertInlinedVariableAssignmentsIntoSchedule(PatternGraph patternGraph, List <SearchOperation> operations) { // compute the number of inlined parameter variables int numInlinedParameterVariables = 0; foreach (PatternVariable var in patternGraph.variablesPlusInlined) { if (var.AssignmentSource != null && patternGraph.WasInlinedHere(var.originalSubpatternEmbedding)) { ++numInlinedParameterVariables; } } if (numInlinedParameterVariables == 0) { return; } // get the inlined parameter variables and the elements needed in order to compute their defining expression Dictionary <String, PatternElement>[] neededElements = new Dictionary <String, PatternElement> [numInlinedParameterVariables]; PatternVariable[] inlinedParameterVariables = new PatternVariable[numInlinedParameterVariables]; int curInlParamVar = 0; foreach (PatternVariable var in patternGraph.variablesPlusInlined) { if (var.AssignmentSource == null) { continue; } if (!patternGraph.WasInlinedHere(var.originalSubpatternEmbedding)) { continue; } neededElements[curInlParamVar] = new Dictionary <string, PatternElement>(); for (int i = 0; i < var.AssignmentDependencies.neededNodeNames.Length; ++i) { String neededNodeName = var.AssignmentDependencies.neededNodeNames[i]; PatternNode neededNode = var.AssignmentDependencies.neededNodes[i]; neededElements[curInlParamVar][neededNodeName] = neededNode; } for (int i = 0; i < var.AssignmentDependencies.neededEdgeNames.Length; ++i) { String neededEdgeName = var.AssignmentDependencies.neededEdgeNames[i]; PatternEdge neededEdge = var.AssignmentDependencies.neededEdges[i]; neededElements[curInlParamVar][neededEdgeName] = neededEdge; } inlinedParameterVariables[curInlParamVar] = var; ++curInlParamVar; } // iterate over all inlined parameter variables for (int i = 0; i < inlinedParameterVariables.Length; ++i) { int j; float costToEnd = 0; // find leftmost place in scheduled search plan for current assignment // by search from end of schedule forward until the first element the expression assigned is dependent on is found for (j = operations.Count - 1; j >= 0; --j) { SearchOperation op = operations[j]; if (op.Type == SearchOperationType.Condition || op.Type == SearchOperationType.Assign || op.Type == SearchOperationType.AssignVar || op.Type == SearchOperationType.NegativePattern || op.Type == SearchOperationType.IndependentPattern || op.Type == SearchOperationType.DefToBeYieldedTo) { continue; } if (neededElements[i].ContainsKey(((SearchPlanNode)op.Element).PatternElement.Name)) { costToEnd = op.CostToEnd; break; } } SearchOperation so = new SearchOperation(SearchOperationType.AssignVar, inlinedParameterVariables[i], null, costToEnd); so.Expression = inlinedParameterVariables[i].AssignmentSource; operations.Insert(j + 1, so); } }
/// <summary> /// Generates a scheduled search plan for a given search plan graph /// </summary> public static ScheduledSearchPlan ScheduleSearchPlan(SearchPlanGraph spGraph, PatternGraph patternGraph, bool isNegativeOrIndependent, bool lazyNegativeIndependentConditionEvaluation) { // the schedule List <SearchOperation> operations = new List <SearchOperation>(); // a set of search plan edges representing the currently reachable not yet visited elements PriorityQueue <SearchPlanEdge> activeEdges = new PriorityQueue <SearchPlanEdge>(); // first schedule all preset elements foreach (SearchPlanEdge edge in spGraph.Root.OutgoingEdges) { if (edge.Target.IsPreset && edge.Type != SearchOperationType.DefToBeYieldedTo) { foreach (SearchPlanEdge edgeOutgoingFromPresetElement in edge.Target.OutgoingEdges) { activeEdges.Add(edgeOutgoingFromPresetElement); } // note: here a normal preset is converted into a neg/idpt preset operation if in negative/independent pattern SearchOperation newOp = new SearchOperation( isNegativeOrIndependent ? SearchOperationType.NegIdptPreset : edge.Type, edge.Target, spGraph.Root, 0); operations.Add(newOp); } } // then schedule all map with storage / pick from index / pick from storage / pick from name index elements not depending on other elements foreach (SearchPlanEdge edge in spGraph.Root.OutgoingEdges) { if (edge.Type == SearchOperationType.MapWithStorage) { foreach (SearchPlanEdge edgeOutgoingFromPickedElement in edge.Target.OutgoingEdges) { activeEdges.Add(edgeOutgoingFromPickedElement); } SearchOperation newOp = new SearchOperation(edge.Type, edge.Target, spGraph.Root, 0); newOp.Storage = edge.Target.PatternElement.Storage; newOp.StorageIndex = edge.Target.PatternElement.StorageIndex; operations.Add(newOp); } } foreach (SearchPlanEdge edge in spGraph.Root.OutgoingEdges) { if (edge.Type == SearchOperationType.PickFromStorage) { foreach (SearchPlanEdge edgeOutgoingFromPickedElement in edge.Target.OutgoingEdges) { activeEdges.Add(edgeOutgoingFromPickedElement); } SearchOperation newOp = new SearchOperation(edge.Type, edge.Target, spGraph.Root, 0); newOp.Storage = edge.Target.PatternElement.Storage; operations.Add(newOp); } } foreach (SearchPlanEdge edge in spGraph.Root.OutgoingEdges) { if (edge.Type == SearchOperationType.PickFromIndex) { foreach (SearchPlanEdge edgeOutgoingFromPickedElement in edge.Target.OutgoingEdges) { activeEdges.Add(edgeOutgoingFromPickedElement); } SearchOperation newOp = new SearchOperation(edge.Type, edge.Target, spGraph.Root, 0); newOp.IndexAccess = edge.Target.PatternElement.IndexAccess; operations.Add(newOp); } } foreach (SearchPlanEdge edge in spGraph.Root.OutgoingEdges) { if (edge.Type == SearchOperationType.PickByName) { foreach (SearchPlanEdge edgeOutgoingFromPickedElement in edge.Target.OutgoingEdges) { activeEdges.Add(edgeOutgoingFromPickedElement); } SearchOperation newOp = new SearchOperation(edge.Type, edge.Target, spGraph.Root, 0); newOp.NameLookup = edge.Target.PatternElement.NameLookup; operations.Add(newOp); } } foreach (SearchPlanEdge edge in spGraph.Root.OutgoingEdges) { if (edge.Type == SearchOperationType.PickByUnique) { foreach (SearchPlanEdge edgeOutgoingFromPickedElement in edge.Target.OutgoingEdges) { activeEdges.Add(edgeOutgoingFromPickedElement); } SearchOperation newOp = new SearchOperation(edge.Type, edge.Target, spGraph.Root, 0); newOp.UniqueLookup = edge.Target.PatternElement.UniqueLookup; operations.Add(newOp); } } // iterate over all reachable elements until the whole graph has been scheduled(/visited), // choose next cheapest operation, update the reachable elements and the search plan costs SearchPlanNode lastNode = spGraph.Root; for (int i = 0; i < spGraph.Nodes.Length - spGraph.NumPresetElements - spGraph.NumIndependentStorageIndexElements; ++i) { foreach (SearchPlanEdge edge in lastNode.OutgoingEdges) { if (edge.Target.IsPreset) { continue; } if (edge.Target.PatternElement.Storage != null && edge.Target.PatternElement.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() == null) { continue; } if (edge.Target.PatternElement.IndexAccess != null && edge.Target.PatternElement.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() == null) { continue; } if (edge.Target.PatternElement.NameLookup != null && edge.Target.PatternElement.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() == null) { continue; } if (edge.Target.PatternElement.UniqueLookup != null && edge.Target.PatternElement.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() == null) { continue; } CostDecreaseForLeavingInlinedIndependent(edge); activeEdges.Add(edge); } SearchPlanEdge minEdge = activeEdges.DequeueFirst(); lastNode = minEdge.Target; SearchOperation newOp = new SearchOperation(minEdge.Type, lastNode, minEdge.Source, minEdge.Cost); newOp.Storage = minEdge.Target.PatternElement.Storage; newOp.StorageIndex = minEdge.Target.PatternElement.StorageIndex; newOp.IndexAccess = minEdge.Target.PatternElement.IndexAccess; newOp.NameLookup = minEdge.Target.PatternElement.NameLookup; newOp.UniqueLookup = minEdge.Target.PatternElement.UniqueLookup; foreach (SearchOperation op in operations) { op.CostToEnd += minEdge.Cost; } operations.Add(newOp); } // remove the elements stemming from inlined independents // they were added in the hope that they might help in matching this pattern, // they don't if they are matched after the elements of this pattern (in fact they only increase the costs then) RemoveInlinedIndependentElementsAtEnd(operations); // insert inlined element identity check into the schedule in case neither of the possible assignments was scheduled InsertInlinedElementIdentityCheckIntoSchedule(patternGraph, operations); // insert inlined variable assignments into the schedule InsertInlinedVariableAssignmentsIntoSchedule(patternGraph, operations); // insert conditions into the schedule InsertConditionsIntoSchedule(patternGraph.ConditionsPlusInlined, operations, lazyNegativeIndependentConditionEvaluation); // schedule the initialization of all def to be yielded to elements and variables at the end, // must come after the pattern elements (and preset elements), as they may be used in the def initialization foreach (SearchPlanEdge edge in spGraph.Root.OutgoingEdges) { if (edge.Type == SearchOperationType.DefToBeYieldedTo && (!isNegativeOrIndependent || (edge.Target.PatternElement.pointOfDefinition == patternGraph && edge.Target.PatternElement.originalElement == null))) { SearchOperation newOp = new SearchOperation( SearchOperationType.DefToBeYieldedTo, edge.Target, spGraph.Root, 0); newOp.Expression = edge.Target.PatternElement.Initialization; operations.Add(newOp); } } foreach (PatternVariable var in patternGraph.variablesPlusInlined) { if (var.defToBeYieldedTo && (!isNegativeOrIndependent || var.pointOfDefinition == patternGraph && var.originalVariable == null)) { SearchOperation newOp = new SearchOperation( SearchOperationType.DefToBeYieldedTo, var, spGraph.Root, 0); newOp.Expression = var.initialization; operations.Add(newOp); } } float cost = operations.Count > 0 ? operations[0].CostToEnd : 0; return(new ScheduledSearchPlan(patternGraph, operations.ToArray(), cost)); }
/// <summary> /// Generate plan graph for given pattern graph with costs from the analyzed host graph. /// Plan graph contains nodes representing the pattern elements (nodes and edges) /// and edges representing the matching operations to get the elements by. /// Edges in plan graph are given in the nodes by incoming list, as needed for MSA computation. /// </summary> public PlanGraph GeneratePlanGraph(LGSPGraphStatistics graphStatistics, PatternGraph patternGraph, bool isNegativeOrIndependent, bool isSubpatternLike, IDictionary<PatternElement, SetValueType> presetsFromIndependentInlining) { // // If you change this method, chances are high you also want to change GenerateStaticPlanGraph in LGSPGrGen // look there for version without ifdef junk // todo: unify it with GenerateStaticPlanGraph in LGSPGrGen // // Create root node // Create plan graph nodes for all pattern graph nodes and all pattern graph edges // Create "lookup" plan graph edge from root node to each plan graph node // Create "implicit source" plan graph edge from each plan graph node originating with a pattern edge // to the plan graph node created by the source node of the pattern graph edge // Create "implicit target" plan graph edge from each plan graph node originating with a pattern edge // to the plan graph node created by the target node of the pattern graph edge // Create "incoming" plan graph edge from each plan graph node originating with a pattern node // to a plan graph node created by one of the incoming edges of the pattern node // Create "outgoing" plan graph edge from each plan graph node originating with a pattern node // to a plan graph node created by one of the outgoing edges of the pattern node // Ensured: there's no plan graph edge with a preset element as target besides the lookup, // so presets are only search operation sources // Create "pick from storage" plan graph edge for plan graph nodes which are to be picked from a storage, // from root node on, instead of lookup, no other plan graph edge having this node as target // Create "pick from storage attribute" plan graph edge from storage attribute owner to storage picking result, // no lookup, no other plan graph edge having this node as target // Create "map" by storage plan graph edge from accessor to storage mapping result // no lookup, no other plan graph edge having this node as target // Create "pick from index" plan graph edge for plan graph nodes which are to be picked from an index, // from root node on, instead of lookup, no other plan graph edge having this node as target // Create "pick from index depending" plan graph edge from node the index expressions depend on, // no lookup, no other plan graph edge having this node as target // Create "cast" plan graph edge from element before casting to cast result, // no lookup, no other plan graph edge having this node as target int numNodes = patternGraph.nodesPlusInlined.Length; if(InlineIndependents && !isNegativeOrIndependent) numNodes += LGSPMatcherGenerator.NumNodesInIndependentsMatchedThere(patternGraph); int numEdges = patternGraph.edgesPlusInlined.Length; if(InlineIndependents && !isNegativeOrIndependent) numEdges += LGSPMatcherGenerator.NumEdgesInIndependentsMatchedThere(patternGraph); PlanNode[] planNodes = new PlanNode[numNodes + numEdges]; List<PlanEdge> planEdges = new List<PlanEdge>(numNodes + 5 * numEdges); // upper bound for num of edges (lookup nodes + lookup edges + impl. tgt + impl. src + incoming + outgoing) Dictionary<PatternNode, PatternNode> originalToInlinedIndependent = new Dictionary<PatternNode, PatternNode>(); int nodesIndex = 0; float zeroCost = 1; PlanNode planRoot = new PlanNode("root"); // create plan nodes and lookup plan edges for all pattern graph nodes for(int i = 0; i < patternGraph.nodesPlusInlined.Length; i++) { PatternNode node = patternGraph.nodesPlusInlined[i]; PlanNode planNode; PlanEdge rootToNodePlanEdge; CreatePlanNodeAndLookupPlanEdge(node, i + 1, graphStatistics, patternGraph, isNegativeOrIndependent, isSubpatternLike, planRoot, zeroCost, originalToInlinedIndependent, presetsFromIndependentInlining, out planNode, out rootToNodePlanEdge); planNodes[nodesIndex] = planNode; if(rootToNodePlanEdge != null) { planEdges.Add(rootToNodePlanEdge); planNode.IncomingEdges.Add(rootToNodePlanEdge); } node.TempPlanMapping = planNode; ++nodesIndex; } if(InlineIndependents && !isNegativeOrIndependent) // independent inlining only if not in negative/independent { foreach(PatternGraph independent in patternGraph.independentPatternGraphsPlusInlined) { foreach(PatternNode nodeOriginal in LGSPMatcherGenerator.NodesInIndependentMatchedThere(independent)) { PatternNode node = new PatternNode(nodeOriginal, "_inlined_" + independent.name); originalToInlinedIndependent.Add(nodeOriginal, node); PlanNode planNode; PlanEdge rootToNodePlanEdge; CreatePlanNodeAndLookupPlanEdge(node, -1, graphStatistics, patternGraph, isNegativeOrIndependent, isSubpatternLike, planRoot, zeroCost, originalToInlinedIndependent, presetsFromIndependentInlining, out planNode, out rootToNodePlanEdge); planNodes[nodesIndex] = planNode; if(rootToNodePlanEdge != null) { planEdges.Add(rootToNodePlanEdge); planNode.IncomingEdges.Add(rootToNodePlanEdge); } node.TempPlanMapping = planNode; ++nodesIndex; } } } // create plan nodes and lookup plus incidence handling plan edges for all pattern graph edges for(int i = 0; i < patternGraph.edgesPlusInlined.Length; ++i) { PatternEdge edge = patternGraph.edgesPlusInlined[i]; bool isPreset; PlanNode planNode; PlanEdge rootToNodePlanEdge; CreatePlanNodeAndLookupPlanEdge(edge, i + 1, graphStatistics, patternGraph, isNegativeOrIndependent, isSubpatternLike, planRoot, zeroCost, originalToInlinedIndependent, presetsFromIndependentInlining, out isPreset, out planNode, out rootToNodePlanEdge); planNodes[nodesIndex] = planNode; if(rootToNodePlanEdge != null) { planEdges.Add(rootToNodePlanEdge); planNode.IncomingEdges.Add(rootToNodePlanEdge); } CreateSourceTargetIncomingOutgoingPlanEdges(edge, planNode, planEdges, originalToInlinedIndependent, graphStatistics, patternGraph, isPreset, zeroCost); edge.TempPlanMapping = planNode; ++nodesIndex; } if(InlineIndependents && !isNegativeOrIndependent) // independent inlining only if not in negative/independent { foreach(PatternGraph independent in patternGraph.independentPatternGraphsPlusInlined) { foreach(PatternEdge edgeOriginal in LGSPMatcherGenerator.EdgesInIndependentMatchedThere(independent)) { PatternEdge edge = new PatternEdge(edgeOriginal, "_inlined_" + independent.name); bool isPreset; PlanNode planNode; PlanEdge rootToNodePlanEdge; CreatePlanNodeAndLookupPlanEdge(edge, -1, graphStatistics, patternGraph, isNegativeOrIndependent, isSubpatternLike, planRoot, zeroCost, originalToInlinedIndependent, presetsFromIndependentInlining, out isPreset, out planNode, out rootToNodePlanEdge); planNodes[nodesIndex] = planNode; if(rootToNodePlanEdge != null) { planEdges.Add(rootToNodePlanEdge); planNode.IncomingEdges.Add(rootToNodePlanEdge); } CreateSourceTargetIncomingOutgoingPlanEdges(edge, planNode, planEdges, originalToInlinedIndependent, graphStatistics, patternGraph, isPreset, zeroCost); edge.TempPlanMapping = planNode; ++nodesIndex; } } } //////////////////////////////////////////////////////////////////////////// // second run handling dependent storage and index picking (can't be done in first run due to dependencies between elements) // create map/pick/cast/assign plan edges for all pattern graph nodes for(int i = 0; i < patternGraph.nodesPlusInlined.Length; ++i) { PatternNode node = patternGraph.nodesPlusInlined[i]; if(node.PointOfDefinition == patternGraph && !presetsFromIndependentInlining.ContainsKey(node)) CreatePickMapCastAssignPlanEdges(node, planEdges, zeroCost); } // create map/pick/cast/assign plan edges for all pattern graph edges for(int i = 0; i < patternGraph.edgesPlusInlined.Length; ++i) { PatternEdge edge = patternGraph.edgesPlusInlined[i]; if(edge.PointOfDefinition == patternGraph && !presetsFromIndependentInlining.ContainsKey(edge)) CreatePickMapCastAssignPlanEdges(edge, planEdges, zeroCost); } return new PlanGraph(planRoot, planNodes, planEdges.ToArray()); }
/// <summary> /// Instantiates a new pattern graph embedding object as a copy from an original embedding, used for inlining. /// </summary> /// <param name="original">The original embedding to be copy constructed.</param> /// <param name="inlinedSubpatternEmbedding">The embedding which just gets inlined.</param> /// <param name="newHost">The pattern graph the new embedding will be contained in.</param> /// <param name="nameSuffix">The suffix to be added to the name of the embedding (to avoid name collisions).</param> /// Elements were already copied in the containing pattern(s), their copies have to be reused here. public PatternGraphEmbedding(PatternGraphEmbedding original, PatternGraphEmbedding inlinedSubpatternEmbedding, PatternGraph newHost, String nameSuffix) { PointOfDefinition = newHost; name = original.name + nameSuffix; originalSubpatternEmbedding = inlinedSubpatternEmbedding; matchingPatternOfEmbeddedGraph = original.matchingPatternOfEmbeddedGraph; annotations = original.annotations; connections = new Expression[original.connections.Length]; for(int i = 0; i < original.connections.Length; ++i) { connections[i] = original.connections[i].Copy(nameSuffix); } yields = new String[original.yields.Length]; for(int i = 0; i < original.yields.Length; ++i) { yields[i] = original.yields[i] + nameSuffix; } neededNodes = new String[original.neededNodes.Length]; for(int i = 0; i < original.neededNodes.Length; ++i) { neededNodes[i] = original.neededNodes[i] + nameSuffix; } neededEdges = new String[original.neededEdges.Length]; for(int i = 0; i < original.neededEdges.Length; ++i) { neededEdges[i] = original.neededEdges[i] + nameSuffix; } neededVariables = new String[original.neededVariables.Length]; for(int i = 0; i < original.neededVariables.Length; ++i) { neededVariables[i] = original.neededVariables[i] + nameSuffix; } neededVariableTypes = (VarType[])original.neededVariableTypes.Clone(); originalEmbedding = original; }
/// <summary> /// Inserts inlined variable assignments into the schedule given by the operations list at their earliest possible position /// </summary> public void InsertInlinedVariableAssignmentsIntoSchedule(PatternGraph patternGraph, List<SearchOperation> operations) { // compute the number of inlined parameter variables int numInlinedParameterVariables = 0; foreach(PatternVariable var in patternGraph.variablesPlusInlined) { if(var.AssignmentSource != null && patternGraph.WasInlinedHere(var.originalSubpatternEmbedding)) ++numInlinedParameterVariables; } if(numInlinedParameterVariables == 0) return; // get the inlined parameter variables and the elements needed in order to compute their defining expression Dictionary<String, bool>[] neededElements = new Dictionary<String, bool>[numInlinedParameterVariables]; PatternVariable[] inlinedParameterVariables = new PatternVariable[numInlinedParameterVariables]; int curInlParamVar = 0; foreach(PatternVariable var in patternGraph.variablesPlusInlined) { if(var.AssignmentSource == null) continue; if(!patternGraph.WasInlinedHere(var.originalSubpatternEmbedding)) continue; neededElements[curInlParamVar] = new Dictionary<string, bool>(); foreach(String neededNode in var.AssignmentDependencies.neededNodes) neededElements[curInlParamVar][neededNode] = true; foreach(String neededEdge in var.AssignmentDependencies.neededEdges) neededElements[curInlParamVar][neededEdge] = true; inlinedParameterVariables[curInlParamVar] = var; ++curInlParamVar; } // iterate over all inlined parameter variables for(int i = 0; i < inlinedParameterVariables.Length; ++i) { int j; float costToEnd = 0; // find leftmost place in scheduled search plan for current assignment // by search from end of schedule forward until the first element the expression assigned is dependent on is found for(j = operations.Count - 1; j >= 0; --j) { SearchOperation op = operations[j]; if(op.Type == SearchOperationType.Condition || op.Type == SearchOperationType.Assign || op.Type == SearchOperationType.AssignVar || op.Type == SearchOperationType.NegativePattern || op.Type == SearchOperationType.IndependentPattern || op.Type == SearchOperationType.DefToBeYieldedTo) { continue; } if(neededElements[i].ContainsKey(((SearchPlanNode)op.Element).PatternElement.Name)) { costToEnd = op.CostToEnd; break; } } SearchOperation so = new SearchOperation(SearchOperationType.AssignVar, inlinedParameterVariables[i], null, costToEnd); so.Expression = inlinedParameterVariables[i].AssignmentSource; operations.Insert(j + 1, so); } }
/// <summary> /// Instantiates a new alternative object as a copy from an original alternative, used for inlining. /// </summary> /// <param name="original">The original alternative to be copy constructed.</param> /// <param name="inlinedSubpatternEmbedding">The embedding which just gets inlined.</param> /// <param name="newHost">The pattern graph the new alternative will be contained in.</param> /// <param name="nameSuffix">The suffix to be added to the name of the alternative and its elements (to avoid name collisions).</param> /// Elements might have been already copied in the containing pattern(s), their copies have to be reused in this case. public Alternative(Alternative original, PatternGraphEmbedding inlinedSubpatternEmbedding, PatternGraph newHost, String nameSuffix, String pathPrefix_, Dictionary<PatternNode, PatternNode> nodeToCopy, Dictionary<PatternEdge, PatternEdge> edgeToCopy, Dictionary<PatternVariable, PatternVariable> variableToCopy) { name = original.name + nameSuffix + "_in_" + inlinedSubpatternEmbedding.PointOfDefinition.pathPrefix + inlinedSubpatternEmbedding.PointOfDefinition.name; originalSubpatternEmbedding = inlinedSubpatternEmbedding; pathPrefix = pathPrefix_; alternativeCases = new PatternGraph[original.alternativeCases.Length]; for(int i = 0; i < original.alternativeCases.Length; ++i) { PatternGraph altCase = original.alternativeCases[i]; alternativeCases[i] = new PatternGraph(altCase, inlinedSubpatternEmbedding, newHost, nameSuffix, nodeToCopy, edgeToCopy, variableToCopy); } originalAlternative = original; }
/// <summary> /// Non- is-matched-flag-based isomorphy checking for nested alternative cases/iterateds /// </summary> public void ParallelizeAlternativeIterated(PatternGraph patternGraph) { foreach(Alternative alt in patternGraph.alternativesPlusInlined) { foreach(PatternGraph altCase in alt.alternativeCases) { ScheduledSearchPlan ssp = altCase.schedulesIncludingNegativesAndIndependents[0]; altCase.parallelizedSchedule = new ScheduledSearchPlan[1]; List<SearchOperation> operations = new List<SearchOperation>(ssp.Operations.Length); for(int i = 0; i < ssp.Operations.Length; ++i) { SearchOperation so = ssp.Operations[i]; SearchOperation clone = (SearchOperation)so.Clone(); clone.Isomorphy.Parallel = true; operations.Add(clone); if(clone.Element is PatternCondition) SetNeedForParallelizedVersion((clone.Element as PatternCondition).ConditionExpression); } ScheduledSearchPlan clonedSsp = new ScheduledSearchPlan( altCase, operations.ToArray(), operations.Count > 0 ? operations[0].CostToEnd : 0); altCase.parallelizedSchedule[0] = clonedSsp; ParallelizeNegativeIndependent(clonedSsp); ParallelizeAlternativeIterated(altCase); ParallelizeYielding(altCase); } } foreach(Iterated iter in patternGraph.iteratedsPlusInlined) { ScheduledSearchPlan ssp = iter.iteratedPattern.schedulesIncludingNegativesAndIndependents[0]; iter.iteratedPattern.parallelizedSchedule = new ScheduledSearchPlan[1]; List<SearchOperation> operations = new List<SearchOperation>(ssp.Operations.Length); for(int i = 0; i < ssp.Operations.Length; ++i) { SearchOperation so = ssp.Operations[i]; SearchOperation clone = (SearchOperation)so.Clone(); clone.Isomorphy.Parallel = true; operations.Add(clone); if(clone.Element is PatternCondition) SetNeedForParallelizedVersion((clone.Element as PatternCondition).ConditionExpression); } ScheduledSearchPlan clonedSsp = new ScheduledSearchPlan( iter.iteratedPattern, operations.ToArray(), operations.Count > 0 ? operations[0].CostToEnd : 0); iter.iteratedPattern.parallelizedSchedule[0] = clonedSsp; ParallelizeNegativeIndependent(clonedSsp); ParallelizeAlternativeIterated(iter.iteratedPattern); ParallelizeYielding(iter.iteratedPattern); } }
/// <summary> /// Instantiates a new iterated object as a copy from an original iterated, used for inlining. /// </summary> /// <param name="original">The original iterated to be copy constructed.</param> /// <param name="inlinedSubpatternEmbedding">The embedding which just gets inlined.</param> /// <param name="newHost">The pattern graph the new iterated will be contained in.</param> /// <param name="nameSuffix">The suffix to be added to the name of the iterated and its elements (to avoid name collisions).</param> /// Elements might have been already copied in the containing pattern(s), their copies have to be reused in this case. public Iterated(Iterated original, PatternGraphEmbedding inlinedSubpatternEmbedding, PatternGraph newHost, String nameSuffix, Dictionary<PatternNode, PatternNode> nodeToCopy, Dictionary<PatternEdge, PatternEdge> edgeToCopy, Dictionary<PatternVariable, PatternVariable> variableToCopy) { iteratedPattern = new PatternGraph(original.iteratedPattern, inlinedSubpatternEmbedding, newHost, nameSuffix, nodeToCopy, edgeToCopy, variableToCopy); minMatches = original.minMatches; maxMatches = original.maxMatches; originalIterated = original; originalSubpatternEmbedding = inlinedSubpatternEmbedding; }
public void ParallelizeYielding(PatternGraph patternGraph) { patternGraph.parallelizedYieldings = new PatternYielding[patternGraph.YieldingsPlusInlined.Length]; for(int i = 0; i < patternGraph.YieldingsPlusInlined.Length; ++i) { patternGraph.parallelizedYieldings[i] = (PatternYielding)patternGraph.YieldingsPlusInlined[i].Clone(); for(int j = 0; j < patternGraph.parallelizedYieldings[i].ElementaryYieldings.Length; ++j) { SetNeedForParallelizedVersion(patternGraph.parallelizedYieldings[i].ElementaryYieldings[j]); } } }
/// <summary> /// Instantiates a new PatternNode object as a copy from an original node, used for subpattern inlining. /// </summary> /// <param name="original">The original pattern node to be copy constructed.</param> /// <param name="inlinedSubpatternEmbedding">The embedding which just gets inlined.</param> /// <param name="newHost">The pattern graph the new pattern node will be contained in.</param> /// <param name="nameSuffix">The suffix to be added to the name of the pattern node (to avoid name collisions).</param> public PatternNode(PatternNode original, PatternGraphEmbedding inlinedSubpatternEmbedding, PatternGraph newHost, String nameSuffix) : base(original, inlinedSubpatternEmbedding, newHost, nameSuffix) { }
/// <summary> /// Generates the action interface plus action implementation including the matcher source code /// for the given iterated pattern into the given source builder /// </summary> public void GenerateActionAndMatcherOfIterated(SourceBuilder sb, LGSPMatchingPattern matchingPattern, PatternGraph iter, bool isInitialStatic) { // generate the search program out of the schedule within the pattern graph of the iterated pattern SearchProgram searchProgram = GenerateSearchProgramIterated(matchingPattern, iter); // generate the parallelized search program out of the parallelized schedule within the pattern graph of the iterated pattern SearchProgram searchProgramParallelized = GenerateParallelizedSearchProgramIteratedAsNeeded(matchingPattern, iter); // emit matcher class head, body, tail; body is source code representing search program GenerateMatcherClassHeadIterated(sb, matchingPattern, iter, isInitialStatic); searchProgram.Emit(sb); if(searchProgramParallelized != null) searchProgramParallelized.Emit(sb); GenerateMatcherClassTail(sb, matchingPattern.PatternGraph.Package != null); // finally generate matcher source for all the nested alternatives or iterateds of the iterated pattern graph // nested inside the alternatives,iterateds,negatives,independents foreach (Alternative alt in iter.alternativesPlusInlined) { GenerateActionAndMatcherOfAlternative(sb, matchingPattern, alt, isInitialStatic); } foreach (Iterated nestedIter in iter.iteratedsPlusInlined) { GenerateActionAndMatcherOfIterated(sb, matchingPattern, nestedIter.iteratedPattern, isInitialStatic); } foreach (PatternGraph neg in iter.negativePatternGraphsPlusInlined) { GenerateActionAndMatcherOfNestedPatterns(sb, matchingPattern, neg, isInitialStatic); } foreach (PatternGraph idpt in iter.independentPatternGraphsPlusInlined) { GenerateActionAndMatcherOfNestedPatterns(sb, matchingPattern, idpt, isInitialStatic); } }
/// <summary> /// Instantiates a new PatternVariable object as a copy from an original variable, used for inlining. /// </summary> /// <param name="original">The original pattern variable to be copy constructed.</param> /// <param name="inlinedSubpatternEmbedding">The embedding which just gets inlined.</param> /// <param name="newHost">The pattern graph the new pattern element will be contained in.</param> /// <param name="nameSuffix">The suffix to be added to the name of the pattern variable (to avoid name collisions).</param> public PatternVariable(PatternVariable original, PatternGraphEmbedding inlinedSubpatternEmbedding, PatternGraph newHost, String nameSuffix) { type = original.type; name = original.name + nameSuffix; unprefixedName = original.unprefixedName + nameSuffix; pointOfDefinition = newHost; defToBeYieldedTo = original.defToBeYieldedTo; initialization = original.initialization; annotations = original.annotations; ParameterIndex = original.ParameterIndex; originalVariable = original; originalSubpatternEmbedding = inlinedSubpatternEmbedding; }
/// <summary> /// Maps the actual implementations of the designpattern. /// </summary> /// <param name="graph">The graph.</param> /// <param name="foundComponents">The found components.</param> /// <param name="componentMatches">The component matches.</param> /// <returns>A list of possible matches, these implementations might be incomplete.</returns> private List <Dictionary <Component, List <ComponentMatch> > > MapImplementations(PatternGraph graph, List <GraphComponent> foundComponents, Dictionary <Component, List <ComponentMatch> > componentMatches) { var mappedImplementations = new List <Dictionary <Component, List <ComponentMatch> > >(); var remainingMatches = componentMatches.Where(c => foundComponents.Any(fc => fc.Component != c.Key)).ToDictionary(x => x.Key, x => x.Value); var noMatchPreviousRound = true; while (remainingMatches.Count > 0) { var matchFound = false; foreach (var remainingMatch in remainingMatches) { var matchedComponent = this.MatchRemainingComponent(graph, remainingMatch, foundComponents); if (matchedComponent != null) { foundComponents.Add(matchedComponent); matchFound = true; } } if (matchFound) { foreach (var foundComponent in foundComponents) { if (remainingMatches.ContainsKey(foundComponent.Component)) { remainingMatches.Remove(foundComponent.Component); } } } else if (!matchFound && noMatchPreviousRound) { // Pattern not updated, no matches to be found. Stop process. remainingMatches.Clear(); } else { noMatchPreviousRound = true; } } foreach (var possibleImplementation in this.possibleImplementations) { if (this.MatchComponentCount(graph.DesignPattern, possibleImplementation)) { mappedImplementations.Add(possibleImplementation); } } return(mappedImplementations); }