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> /// Instantiates an edge plan node. /// </summary> /// <param name="patEdge">The pattern edge for this plan node.</param> /// <param name="elemID">The element ID for this plan node.</param> /// <param name="isPreset">True, if this element is a known element.</param> /// <param name="patternEdgeSource">The plan node corresponding to the source of the pattern edge.</param> /// <param name="patternEdgeTarget">The plan node corresponding to the target of the pattern edge.</param> public PlanNode(PatternEdge patEdge, int elemID, bool isPreset, PlanNode patternEdgeSource, PlanNode patternEdgeTarget) { NodeType = PlanNodeType.Edge; ElementID = elemID; IsPreset = isPreset; PatternElement = patEdge; PatternEdgeSource = patternEdgeSource; PatternEdgeTarget = patternEdgeTarget; }
/// <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); }
/// <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> /// Inserts conditions into the schedule given by the operations list at their earliest possible position /// todo: set/map operations are potentially expensive, they shouldn't be insertes asap, but depending an weight, /// derived from statistics over set/map size for graph elements, quiet well known for anonymous rule sets /// </summary> private static void InsertConditionsIntoSchedule(PatternCondition[] conditions, List <SearchOperation> operations, bool lazyNegativeIndependentConditionEvaluation) { // get needed (in order to evaluate it) elements of each condition Dictionary <String, object>[] neededElements = new Dictionary <String, object> [conditions.Length]; for (int i = 0; i < conditions.Length; ++i) { neededElements[i] = new Dictionary <string, object>(); for (int j = 0; j < conditions[i].NeededNodeNames.Length; ++j) { String neededNodeName = conditions[i].NeededNodeNames[j]; PatternNode neededNode = conditions[i].NeededNodes[j]; neededElements[i][neededNodeName] = neededNode; } for (int j = 0; j < conditions[i].NeededEdgeNames.Length; ++j) { String neededEdgeName = conditions[i].NeededEdgeNames[j]; PatternEdge neededEdge = conditions[i].NeededEdges[j]; neededElements[i][neededEdgeName] = neededEdge; } for (int j = 0; j < conditions[i].NeededVariableNames.Length; ++j) { String neededVariableName = conditions[i].NeededVariableNames[j]; PatternVariable neededVariable = conditions[i].NeededVariables[j]; neededElements[i][neededVariableName] = neededVariable; } } // iterate over all conditions for (int i = 0; i < conditions.Length; ++i) { int j; float costToEnd = 0; // find leftmost place in scheduled search plan for current condition // by search from end of schedule forward until the first element the condition 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.NegativePattern || op.Type == SearchOperationType.IndependentPattern || op.Type == SearchOperationType.DefToBeYieldedTo) { continue; } if (lazyNegativeIndependentConditionEvaluation) { break; } if (op.Type == SearchOperationType.AssignVar) { if (neededElements[i].ContainsKey(((PatternVariable)op.Element).Name)) { costToEnd = op.CostToEnd; break; } continue; } if (neededElements[i].ContainsKey(((SearchPlanNode)op.Element).PatternElement.Name)) { costToEnd = op.CostToEnd; break; } } operations.Insert(j + 1, new SearchOperation(SearchOperationType.Condition, conditions[i], null, costToEnd)); } }