/// <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 static void AnalyzeAndInlineMatchingPatterns(bool inline, LGSPRuleAndMatchingPatterns ruleAndMatchingPatterns) { PatternGraphAnalyzer analyzer = new PatternGraphAnalyzer(); foreach(LGSPMatchingPattern matchingPattern in ruleAndMatchingPatterns.RulesAndSubpatterns) { analyzer.AnalyzeNestingOfPatternGraph(matchingPattern.patternGraph, false); PatternGraphAnalyzer.PrepareInline(matchingPattern.patternGraph); analyzer.RememberMatchingPattern(matchingPattern); } analyzer.ComputeInterPatternRelations(false); foreach(LGSPMatchingPattern matchingPattern in ruleAndMatchingPatterns.RulesAndSubpatterns) { // computes patternpath information, thus only in original pass analyzer.AnalyzeWithInterPatternRelationsKnown(matchingPattern.patternGraph); } if(inline) { foreach(LGSPMatchingPattern matchingPattern in ruleAndMatchingPatterns.RulesAndSubpatterns) { #if DUMP_PATTERNS // dump patterns for debugging - first original version without inlining SourceBuilder builder = new SourceBuilder(true); matchingPattern.patternGraph.DumpOriginal(builder); StreamWriter writer = new StreamWriter(matchingPattern.name + "_pattern_dump.txt"); writer.Write(builder.ToString()); #endif analyzer.InlineSubpatternUsages(matchingPattern.patternGraph); #if DUMP_PATTERNS // - then inlined version builder = new SourceBuilder(true); matchingPattern.patternGraph.DumpInlined(builder); writer.Write(builder.ToString()); writer.Close(); #endif } } // hardcore/ugly parameterization for inlined case, working on inlined members in inlined pass, and original members on original pass // working with accessors encapsulating the inlined versions and the original version behind a common interface to keep the analyze code without case distinctions gets terribly extensive foreach(LGSPMatchingPattern matchingPattern in ruleAndMatchingPatterns.RulesAndSubpatterns) matchingPattern.patternGraph.maxIsoSpace = 0; // reset of max iso space for computation of max iso space of inlined patterns foreach(LGSPMatchingPattern matchingPattern in ruleAndMatchingPatterns.RulesAndSubpatterns) { analyzer.AnalyzeNestingOfPatternGraph(matchingPattern.patternGraph, true); } analyzer.ComputeInterPatternRelations(true); }