/// <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> /// 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> /// 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); } }
private void GetMatchElementsForDuplicateCheck(PatternGraph patternGraph, out List<String> namesOfPatternElements, out List<String> matchObjectPaths, out List<String> unprefixedNamesOfPatternElements, out List<bool> patternElementIsNode) { namesOfPatternElements = new List<String>(); matchObjectPaths = new List<string>(); unprefixedNamesOfPatternElements = new List<String>(); patternElementIsNode = new List<bool>(); foreach(PatternElement elementFromInlinedIndependent in patternElementsMatchedThere(patternGraph)) { namesOfPatternElements.Add(elementFromInlinedIndependent.Name); string inlinedMatchObjectPath = ""; string unprefixedName = elementFromInlinedIndependent.UnprefixedName; if(elementFromInlinedIndependent.originalElement != null) { if(patternGraph.WasInlinedHere(elementFromInlinedIndependent.originalSubpatternEmbedding)) inlinedMatchObjectPath = "." + elementFromInlinedIndependent.originalSubpatternEmbedding.Name; unprefixedName = elementFromInlinedIndependent.originalElement.UnprefixedName; } matchObjectPaths.Add(inlinedMatchObjectPath); unprefixedNamesOfPatternElements.Add(unprefixedName); patternElementIsNode.Add(elementFromInlinedIndependent is PatternNode); } }
/// <summary> /// Inserts code for bubbling yield assignments /// at the given position, returns position after inserted operations /// </summary> private SearchProgramOperation insertYieldAssignments( SearchProgramOperation insertionPoint, PatternGraph patternGraph, String nestedMatchObjectName, PatternGraph nestedPatternGraph) { foreach(PatternNode node in patternGraph.nodesPlusInlined) { if(!node.DefToBeYieldedTo) continue; foreach(PatternNode nestedNode in nestedPatternGraph.nodesPlusInlined) { if(nestedNode == node) { BubbleUpYieldAssignment bubble = new BubbleUpYieldAssignment( EntityType.Node, node.Name, nestedMatchObjectName, nestedNode.originalNode!=null && patternGraph.WasInlinedHere(nestedNode.originalSubpatternEmbedding) ? nestedNode.originalNode.UnprefixedName : nestedNode.UnprefixedName ); insertionPoint = insertionPoint.Append(bubble); } } } foreach(PatternEdge edge in patternGraph.edgesPlusInlined) { if(!edge.DefToBeYieldedTo) continue; foreach(PatternEdge nestedEdge in nestedPatternGraph.edgesPlusInlined) { if(nestedEdge == edge) { BubbleUpYieldAssignment bubble = new BubbleUpYieldAssignment( EntityType.Edge, edge.Name, nestedMatchObjectName, nestedEdge.originalElement!=null ? nestedEdge.originalEdge.UnprefixedName : nestedEdge.UnprefixedName ); insertionPoint = insertionPoint.Append(bubble); } } } foreach(PatternVariable var in patternGraph.variablesPlusInlined) { if(!var.DefToBeYieldedTo) continue; foreach(PatternVariable nestedVar in nestedPatternGraph.variablesPlusInlined) { if(nestedVar == var) { BubbleUpYieldAssignment bubble = new BubbleUpYieldAssignment( EntityType.Variable, var.Name, nestedMatchObjectName, nestedVar.originalVariable!=null ? nestedVar.originalVariable.UnprefixedName : nestedVar.UnprefixedName ); insertionPoint = insertionPoint.Append(bubble); } } } return insertionPoint; }
/// <summary> /// Inserts code to yield, bubbling effects of nested yields upwards and computing local yields /// at the given position, returns position after inserted operations /// </summary> private SearchProgramOperation insertYields( SearchProgramOperation insertionPoint, PatternGraph patternGraph, String matchObjectName, bool inlined) { // the match object is built now with our local elements // and the match objects of our children // now 1. copy all def entities we share with children to our local variables foreach(PatternGraphEmbedding patternEmbedding in patternGraph.embeddedGraphsPlusInlined) { // in the inlined pass only the elements which were inlined into this pattern, in the non-inlined pass the original elements bool wasInlined = patternEmbedding.originalEmbedding != null; if(inlined == wasInlined) { // if the pattern embedding does not contain a def entity it can't yield to us if(!((PatternGraph)patternEmbedding.EmbeddedGraph).isDefEntityExistingPlusInlined) continue; // skip inlined embeddings (will be handled in 3.) if(patternEmbedding.inlined) continue; // in inlined pass bubble up from the components of the inlined patterns to the elements resulting from of the inlined pattern // (read from submatches to local variables, compute in local variables, writing will happen later from local variables to matches) string inlinedMatchObjectName = null; string patternEmbeddingName = patternEmbedding.Name; if(patternEmbedding.originalEmbedding != null) { if(patternGraph.WasInlinedHere(patternEmbedding.originalSubpatternEmbedding)) inlinedMatchObjectName = "match_" + patternEmbedding.originalSubpatternEmbedding.Name; patternEmbeddingName = patternEmbedding.originalEmbedding.name; } LGSPMatchingPattern matchingPattern = patternEmbedding.matchingPatternOfEmbeddedGraph; String nestedMatchObjectName = (inlinedMatchObjectName ?? matchObjectName) + "._" + patternEmbeddingName; Debug.Assert(matchingPattern.defNames.Length == patternEmbedding.yields.Length); for(int i = 0; i < patternEmbedding.yields.Length; ++i) { BubbleUpYieldAssignment bubble = new BubbleUpYieldAssignment( toBubbleUpYieldAssignmentType(matchingPattern.defs[i]), patternEmbedding.yields[i], nestedMatchObjectName, matchingPattern.defNames[i] ); insertionPoint = insertionPoint.Append(bubble); } } } foreach(Iterated iterated in patternGraph.iteratedsPlusInlined) { // in the inlined pass only the elements which were inlined into this pattern, in the non-inlined pass the original elements bool wasInlined = iterated.originalIterated != null; if(inlined == wasInlined) { // if the iterated does not contain a non local def entity it can't yield to us if(!iterated.iteratedPattern.isNonLocalDefEntityExistingPlusInlined) continue; // in inlined pass bubble up from the components of the inlined patterns to the elements resulting from of the inlined pattern // (read from submatches to local variables, compute in local variables, writing will happen later from local variables to matches) string inlinedMatchObjectName = null; string iteratedName = iterated.iteratedPattern.Name; if(iterated.originalIterated != null) { if(patternGraph.WasInlinedHere(iterated.originalSubpatternEmbedding)) inlinedMatchObjectName = "match_" + iterated.originalSubpatternEmbedding.Name; iteratedName = iterated.originalIterated.iteratedPattern.name; } String nestedMatchObjectName = (inlinedMatchObjectName ?? matchObjectName) + "._" + iteratedName; BubbleUpYieldIterated bubbleUpIterated = new BubbleUpYieldIterated(nestedMatchObjectName); bubbleUpIterated.NestedOperationsList = new SearchProgramList(bubbleUpIterated); SearchProgramOperation continuationPoint = insertionPoint.Append(bubbleUpIterated); insertionPoint = bubbleUpIterated.NestedOperationsList; insertYieldAssignments(insertionPoint, patternGraph, nestedMatchObjectName + ".Root", iterated.iteratedPattern); insertionPoint = continuationPoint; } } foreach(Alternative alternative in patternGraph.alternativesPlusInlined) { // in the inlined pass only the elements which were inlined into this pattern, in the non-inlined pass the original elements bool wasInlined = alternative.originalAlternative != null; if(inlined == wasInlined) { bool first = true; foreach(PatternGraph alternativeCase in alternative.alternativeCases) { // if the alternative case does not contain a non local def entity it can't yield to us if(!alternativeCase.isNonLocalDefEntityExistingPlusInlined) continue; // in inlined pass bubble up from the components of the inlined patterns to the elements resulting from of the inlined pattern // (read from submatches to local variables, compute in local variables, writing will happen later from local variables to matches) string inlinedMatchObjectName = matchObjectName; string inlinedNestedMatchObjectName = "_" + alternative.name; string inlinedPatternClassName = rulePatternClassName; string patternElementType = patternGraph.pathPrefix + patternGraph.name + "_" + alternative.name + "_" + alternativeCase.name; if(alternative.originalAlternative != null) { if(patternGraph.WasInlinedHere(alternative.originalSubpatternEmbedding)) inlinedMatchObjectName = "match_" + alternative.originalSubpatternEmbedding.name; inlinedNestedMatchObjectName = "_" + alternative.originalAlternative.name; inlinedPatternClassName = alternative.originalSubpatternEmbedding.matchingPatternOfEmbeddedGraph.GetType().Name; patternElementType = alternative.originalAlternative.pathPrefix + alternative.originalAlternative.name + "_" + alternativeCase.originalPatternGraph.name; } BubbleUpYieldAlternativeCase bubbleUpAlternativeCase = new BubbleUpYieldAlternativeCase( inlinedMatchObjectName, inlinedNestedMatchObjectName, inlinedPatternClassName + ".Match_" + patternElementType, "altCaseMatch", first); bubbleUpAlternativeCase.NestedOperationsList = new SearchProgramList(bubbleUpAlternativeCase); SearchProgramOperation continuationPoint = insertionPoint.Append(bubbleUpAlternativeCase); insertionPoint = bubbleUpAlternativeCase.NestedOperationsList; first = false; insertYieldAssignments(insertionPoint, patternGraph, "altCaseMatch", alternativeCase); insertionPoint = continuationPoint; } } } foreach(PatternGraph independent in patternGraph.independentPatternGraphsPlusInlined) { // in the inlined pass only the elements which were inlined into this pattern, in the non-inlined pass the original elements bool wasInlined = independent.originalPatternGraph != null; if(inlined == wasInlined) { // if the independent does not contain a non local def entity it can't yield to us if(!independent.isNonLocalDefEntityExistingPlusInlined) continue; // in inlined pass bubble up from the components of the inlined patterns to the elements resulting from of the inlined pattern // (read from submatches to local variables, compute in local variables, writing will happen later from local variables to matches) string inlinedMatchObjectName = null; if(independent.originalPatternGraph != null && patternGraph.WasInlinedHere(independent.originalSubpatternEmbedding)) { inlinedMatchObjectName = "match_" + independent.originalSubpatternEmbedding.Name; } String nestedMatchObjectName = NamesOfEntities.MatchedIndependentVariable(independent.pathPrefix + independent.name); ; insertionPoint = insertYieldAssignments(insertionPoint, patternGraph, inlinedMatchObjectName ?? nestedMatchObjectName, independent); } } ////////////////////////////////////////////////////// // then 2. compute all local yields PatternYielding[] patternYieldings; if(patternGraph.parallelizedSchedule != null) // in case of parallelization we've to use the parallelized yieldings patternYieldings = patternGraph.parallelizedYieldings; else patternYieldings = patternGraph.YieldingsPlusInlined; foreach(PatternYielding patternYielding in patternYieldings) { // in the inlined pass only the elements which were inlined into this pattern, in the non-inlined pass the original elements bool wasInlined = patternYielding.originalYielding != null; if(inlined == wasInlined) { YieldingBlock yieldingBlock = new YieldingBlock(patternYielding.Name); yieldingBlock.NestedOperationsList = new SearchProgramList(yieldingBlock); SearchProgramOperation continuationPointOuter = insertionPoint.Append(yieldingBlock); insertionPoint = yieldingBlock.NestedOperationsList; foreach(Yielding yielding in patternYielding.ElementaryYieldings) { // iterated potentially matching more than once can't be bubbled up normally, // they need accumulation with a for loop into a variable of the nesting pattern, // that's done in/with the yield statements of the parent if(yielding is IteratedAccumulationYield) { IteratedAccumulationYield accumulationYield = (IteratedAccumulationYield)yielding; foreach(Iterated iterated in patternGraph.iteratedsPlusInlined) { // skip the iterateds we're not interested in if(accumulationYield.Iterated != iterated.iteratedPattern.Name) continue; // in inlined pass bubble up from the components of the inlined patterns to the elements resulting from of the inlined pattern // (read from submatches to local variables, compute in local variables, writing will happen later from local variables to matches) string inlinedMatchObjectName = null; if(iterated.originalIterated != null) { inlinedMatchObjectName = "match_" + iterated.originalSubpatternEmbedding.Name; } String nestedMatchObjectName = (inlinedMatchObjectName ?? matchObjectName) + "._" + iterated.iteratedPattern.Name; AccumulateUpYieldIterated accumulateUpIterated = new AccumulateUpYieldIterated( nestedMatchObjectName, rulePatternClassName + ".Match_" + patternGraph.pathPrefix + patternGraph.name + "_" + iterated.iteratedPattern.name, "iteratedMatch"); accumulateUpIterated.NestedOperationsList = new SearchProgramList(accumulateUpIterated); SearchProgramOperation continuationPoint = insertionPoint.Append(accumulateUpIterated); insertionPoint = accumulateUpIterated.NestedOperationsList; accumulationYield.IteratedMatchVariable = "iteratedMatch._" + NamesOfEntities.Variable(accumulationYield.UnprefixedVariable); accumulationYield.ReplaceVariableByIterationVariable(accumulationYield); SourceBuilder yieldAssignmentSource = new SourceBuilder(); accumulationYield.Emit(yieldAssignmentSource); LocalYielding yieldAssignment = new LocalYielding(yieldAssignmentSource.ToString()); insertionPoint = insertionPoint.Append(yieldAssignment); insertionPoint = continuationPoint; } } else { SourceBuilder yieldAssignmentSource = new SourceBuilder(); yielding.Emit(yieldAssignmentSource); LocalYielding yieldAssignment = new LocalYielding(yieldAssignmentSource.ToString()); insertionPoint = insertionPoint.Append(yieldAssignment); } } insertionPoint = continuationPointOuter; } } ////////////////////////////////////////////////////// // 3. at the end of the inlined pass: // assign the def parameters from a subpattern which was inlined to the arguments yielded to // we can't read from the match objects of the inlined subpatterns cause they are not written yet, but from the corresponding local variables if(inlined) { foreach(PatternGraphEmbedding patternEmbedding in patternGraph.embeddedGraphsPlusInlined) { // only inlined embeddings if(!patternEmbedding.inlined) continue; for(int i = 0; i < patternEmbedding.yields.Length; ++i) { String targetName = patternEmbedding.yields[i]; String sourceName = patternEmbedding.matchingPatternOfEmbeddedGraph.defNames[i]; IPatternElement elem = getInlinedElementByOriginalUnprefixedName(patternGraph, patternEmbedding, sourceName); // find the one which was originating from inlining patternEmbedding, because of same originator bool isVariable = patternEmbedding.matchingPatternOfEmbeddedGraph.defs[i] is VarType; YieldAssignment assignment = new YieldAssignment( targetName, isVariable, patternEmbedding.matchingPatternOfEmbeddedGraph.defs[i] is VarType ? TypesHelper.TypeName(patternEmbedding.matchingPatternOfEmbeddedGraph.defs[i]) : patternEmbedding.matchingPatternOfEmbeddedGraph.defs[i].IsNodeType ? "GRGEN_LGSP.LGSPNode" : "GRGEN_LGSP.LGSPEdge", isVariable ? (Expression)new VariableExpression(elem.Name) : (Expression)new GraphEntityExpression(elem.Name) ); SourceBuilder yieldAssignmentSource = new SourceBuilder(); assignment.Emit(yieldAssignmentSource); LocalYielding yieldAssignment = new LocalYielding(yieldAssignmentSource.ToString()); insertionPoint = insertionPoint.Append(yieldAssignment); } } } return insertionPoint; }
/// <summary> /// Inserts code to build the match object /// at the given position, returns position after inserted operations /// </summary> private SearchProgramOperation insertMatchObjectBuilding( SearchProgramOperation insertionPoint, PatternGraph patternGraph, MatchObjectType matchObjectType, bool defElements) { String matchObjectName; if(matchObjectType==MatchObjectType.Independent) { matchObjectName = NamesOfEntities.MatchedIndependentVariable(patternGraph.pathPrefix + patternGraph.name); } else if(matchObjectType==MatchObjectType.Patternpath) { matchObjectName = NamesOfEntities.PatternpathMatch(patternGraph.pathPrefix + patternGraph.name); } else { //if(matchObjectType==MatchObjectType.Normal) matchObjectName = "match"; } String enumPrefix = patternGraph.pathPrefix + patternGraph.name + "_"; for (int i = 0; i < patternGraph.nodesPlusInlined.Length; ++i) { // in defElements pass only def elements, in non defElements pass only non def elements if(defElements == patternGraph.nodesPlusInlined[i].defToBeYieldedTo) { string inlinedMatchObjectName = null; string unprefixedName = patternGraph.nodesPlusInlined[i].UnprefixedName; if(patternGraph.nodesPlusInlined[i].originalNode != null) { if(patternGraph.WasInlinedHere(patternGraph.nodesPlusInlined[i].originalSubpatternEmbedding)) inlinedMatchObjectName = "match_" + patternGraph.nodesPlusInlined[i].originalSubpatternEmbedding.Name; unprefixedName = patternGraph.nodesPlusInlined[i].originalElement.UnprefixedName; } BuildMatchObject buildMatch = new BuildMatchObject( BuildMatchObjectType.Node, patternGraph.nodesPlusInlined[i].typeName, unprefixedName, patternGraph.nodesPlusInlined[i].Name, rulePatternClassName, enumPrefix, inlinedMatchObjectName ?? matchObjectName, -1 ); insertionPoint = insertionPoint.Append(buildMatch); } } for (int i = 0; i < patternGraph.edgesPlusInlined.Length; ++i) { // in defElements pass only def elements, in non defElements pass only non def elements if(defElements == patternGraph.edgesPlusInlined[i].defToBeYieldedTo) { string inlinedMatchObjectName = null; string unprefixedName = patternGraph.edgesPlusInlined[i].UnprefixedName; if(patternGraph.edgesPlusInlined[i].originalEdge != null) { if(patternGraph.WasInlinedHere(patternGraph.edgesPlusInlined[i].originalSubpatternEmbedding)) inlinedMatchObjectName = "match_" + patternGraph.edgesPlusInlined[i].originalSubpatternEmbedding.Name; unprefixedName = patternGraph.edgesPlusInlined[i].originalElement.UnprefixedName; } BuildMatchObject buildMatch = new BuildMatchObject( BuildMatchObjectType.Edge, patternGraph.edgesPlusInlined[i].typeName, unprefixedName, patternGraph.edgesPlusInlined[i].Name, rulePatternClassName, enumPrefix, inlinedMatchObjectName ?? matchObjectName, -1 ); insertionPoint = insertionPoint.Append(buildMatch); } } // only nodes and edges for patternpath matches if (matchObjectType == MatchObjectType.Patternpath) { return insertionPoint; } foreach (PatternVariable var in patternGraph.variablesPlusInlined) { // in defElements pass only def elements, in non defElements pass only non def elements if(defElements == var.defToBeYieldedTo) { string inlinedMatchObjectName = null; string unprefixedName = var.UnprefixedName; if(var.originalVariable != null) { if(patternGraph.WasInlinedHere(var.originalSubpatternEmbedding)) inlinedMatchObjectName = "match_" + var.originalSubpatternEmbedding.Name; unprefixedName = var.originalVariable.UnprefixedName; } BuildMatchObject buildMatch = new BuildMatchObject( BuildMatchObjectType.Variable, TypesHelper.TypeName(var.type), unprefixedName, var.Name, rulePatternClassName, enumPrefix, inlinedMatchObjectName ?? matchObjectName, -1 ); insertionPoint = insertionPoint.Append(buildMatch); } } // only nodes, edges, variables in defElements pass if(defElements) { return insertionPoint; } for (int i = 0; i < patternGraph.embeddedGraphsPlusInlined.Length; ++i) { if(patternGraph.embeddedGraphsPlusInlined[i].inlined) { BuildMatchObject buildMatch = new BuildMatchObject( BuildMatchObjectType.InlinedSubpattern, "", patternGraph.embeddedGraphsPlusInlined[i].name, patternGraph.embeddedGraphsPlusInlined[i].name, "", "", matchObjectName, -1 ); insertionPoint = insertionPoint.Append(buildMatch); } else { string inlinedMatchObjectName = null; string unprefixedName = patternGraph.embeddedGraphsPlusInlined[i].name; if(patternGraph.embeddedGraphsPlusInlined[i].originalEmbedding != null) { if(patternGraph.WasInlinedHere(patternGraph.embeddedGraphsPlusInlined[i].originalSubpatternEmbedding)) inlinedMatchObjectName = "match_" + patternGraph.embeddedGraphsPlusInlined[i].originalSubpatternEmbedding.Name; unprefixedName = patternGraph.embeddedGraphsPlusInlined[i].originalEmbedding.name; } string subpatternContainingType = NamesOfEntities.RulePatternClassName(patternGraph.embeddedGraphsPlusInlined[i].EmbeddedGraph.Name, patternGraph.embeddedGraphsPlusInlined[i].EmbeddedGraph.Package, true); string subpatternType = NamesOfEntities.MatchClassName(patternGraph.embeddedGraphsPlusInlined[i].EmbeddedGraph.Name); BuildMatchObject buildMatch = new BuildMatchObject( BuildMatchObjectType.Subpattern, subpatternContainingType + "." + subpatternType, unprefixedName, patternGraph.embeddedGraphsPlusInlined[i].name, rulePatternClassName, enumPrefix, inlinedMatchObjectName ?? matchObjectName, -1 ); insertionPoint = insertionPoint.Append(buildMatch); } } for (int i = 0; i < patternGraph.iteratedsPlusInlined.Length; ++i) { string inlinedMatchObjectName = null; string unprefixedName = patternGraph.iteratedsPlusInlined[i].iteratedPattern.name; string inlinedPatternClassName = rulePatternClassName; string patternElementType = patternGraph.pathPrefix + patternGraph.name + "_" + patternGraph.iteratedsPlusInlined[i].iteratedPattern.name; if(patternGraph.iteratedsPlusInlined[i].originalIterated != null) { if(patternGraph.WasInlinedHere(patternGraph.iteratedsPlusInlined[i].originalSubpatternEmbedding)) inlinedMatchObjectName = "match_" + patternGraph.iteratedsPlusInlined[i].originalSubpatternEmbedding.Name; unprefixedName = patternGraph.iteratedsPlusInlined[i].originalIterated.iteratedPattern.Name; inlinedPatternClassName = patternGraph.iteratedsPlusInlined[i].originalSubpatternEmbedding.matchingPatternOfEmbeddedGraph.GetType().Name; patternElementType = patternGraph.iteratedsPlusInlined[i].originalIterated.iteratedPattern.pathPrefix + unprefixedName; } BuildMatchObject buildMatch = new BuildMatchObject( BuildMatchObjectType.Iteration, patternElementType, unprefixedName, patternGraph.iteratedsPlusInlined[i].iteratedPattern.name, inlinedPatternClassName, enumPrefix, inlinedMatchObjectName ?? matchObjectName, patternGraph.embeddedGraphsPlusInlined.Length ); insertionPoint = insertionPoint.Append(buildMatch); } for (int i = 0; i < patternGraph.alternativesPlusInlined.Length; ++i) { string inlinedMatchObjectName = null; string unprefixedName = patternGraph.alternativesPlusInlined[i].name; string inlinedPatternClassName = rulePatternClassName; string patternElementType = patternGraph.pathPrefix+patternGraph.name+"_"+patternGraph.alternativesPlusInlined[i].name; if(patternGraph.alternativesPlusInlined[i].originalAlternative != null) { if(patternGraph.WasInlinedHere(patternGraph.alternativesPlusInlined[i].originalSubpatternEmbedding)) inlinedMatchObjectName = "match_" + patternGraph.alternativesPlusInlined[i].originalSubpatternEmbedding.Name; unprefixedName = patternGraph.alternativesPlusInlined[i].originalAlternative.name; inlinedPatternClassName = patternGraph.alternativesPlusInlined[i].originalSubpatternEmbedding.matchingPatternOfEmbeddedGraph.GetType().Name; patternElementType = patternGraph.alternativesPlusInlined[i].originalAlternative.pathPrefix + unprefixedName; } BuildMatchObject buildMatch = new BuildMatchObject( BuildMatchObjectType.Alternative, patternElementType, unprefixedName, patternGraph.alternativesPlusInlined[i].name, inlinedPatternClassName, enumPrefix, inlinedMatchObjectName ?? matchObjectName, patternGraph.embeddedGraphsPlusInlined.Length ); insertionPoint = insertionPoint.Append(buildMatch); } if (patternGraph.nestedIndependents != null) { foreach (KeyValuePair<PatternGraph,PatternGraph> nestedIndependent in patternGraph.nestedIndependents) { string inlinedMatchObjectName = null; string unprefixedName = nestedIndependent.Key.name; string inlinedPatternClassName = rulePatternClassName; string matchClassName = nestedIndependent.Key.pathPrefix + nestedIndependent.Key.name; if(nestedIndependent.Key.originalPatternGraph != null) { if(patternGraph.WasInlinedHere(nestedIndependent.Key.originalSubpatternEmbedding)) inlinedMatchObjectName = "match_" + nestedIndependent.Key.originalSubpatternEmbedding.Name; unprefixedName = nestedIndependent.Key.originalPatternGraph.Name; inlinedPatternClassName = nestedIndependent.Key.originalSubpatternEmbedding.matchingPatternOfEmbeddedGraph.GetType().Name; matchClassName = nestedIndependent.Key.pathPrefix + unprefixedName; } BuildMatchObject buildMatch = new BuildMatchObject( BuildMatchObjectType.Independent, unprefixedName, nestedIndependent.Key.pathPrefix + nestedIndependent.Key.name, inlinedPatternClassName, inlinedMatchObjectName ?? matchObjectName, matchClassName ); insertionPoint = insertionPoint.Append(buildMatch); } } // we only have to take care of yielding in case of normal and independent matches // and if we contain a def entity (and if we are not in the defElements pass), or if we contain a ref entity (that may be yielded to instead) if(matchObjectType != MatchObjectType.Patternpath && (patternGraph.isDefEntityExistingPlusInlined || patternGraph.IsRefEntityExisting())) { // first compute the yieldings which were inlined from subpatterns to us insertionPoint = insertYields(insertionPoint, patternGraph, matchObjectName, true); // then the yieldings of the current pattern return insertYields(insertionPoint, patternGraph, matchObjectName, false); // in the def-elements pass the yieldings computed into local variables are written to the match } return insertionPoint; }
/// <summary> /// Inserts declarations for variables extracted from parameters /// </summary> private 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; }
private SearchProgramOperation insertVariableDeclarationsNegIdpt(SearchProgramOperation insertionPoint, PatternGraph patternGraph) { foreach(PatternNode node in patternGraph.nodesPlusInlined) { if(node.defToBeYieldedTo && patternGraph.WasInlinedHere(node.originalSubpatternEmbedding)) { insertionPoint = insertionPoint.Append( new DeclareDefElement(EntityType.Node, "GRGEN_LGSP.LGSPNode", node.Name, "null") ); } } foreach(PatternEdge edge in patternGraph.edgesPlusInlined) { if(edge.defToBeYieldedTo && patternGraph.WasInlinedHere(edge.originalSubpatternEmbedding)) { insertionPoint = insertionPoint.Append( new DeclareDefElement(EntityType.Edge, "GRGEN_LGSP.LGSPEdge", edge.Name, "null") ); } } foreach(PatternVariable var in patternGraph.variablesPlusInlined) { if(var.defToBeYieldedTo && patternGraph.WasInlinedHere(var.originalSubpatternEmbedding)) { String initializationExpression; if(var.initialization != null) { SourceBuilder builder = new SourceBuilder(); var.initialization.Emit(builder); initializationExpression = builder.ToString(); } else { string typeName = TypesHelper.XgrsTypeToCSharpType(TypesHelper.DotNetTypeToXgrsType(var.type), model); initializationExpression = TypesHelper.DefaultValueString(typeName, model); } insertionPoint = insertionPoint.Append( new DeclareDefElement(EntityType.Variable, TypesHelper.TypeName(var.type), var.Name, initializationExpression) ); } } return insertionPoint; }