public void CopyMatchContent(Match_testRule that) { _node_a = that._node_a; _node_f = that._node_f; _node_m = that._node_m; _edge__edge0 = that._edge__edge0; _edge__edge1 = that._edge__edge1; }
/// <summary> /// Adds an existing edge to this graph. /// The graph may not already contain the edge! /// The edge may not be connected to any other elements! /// Intended only for undo, clone, retyping and internal use! /// </summary> public void AddEdgeWithoutEvents(LGSPEdge edge, int typeid) { #if CHECK_RINGLISTS CheckEdgeAlreadyInTypeRinglist(edge); CheckNodeInGraph((LGSPNode)edge.Source); CheckNodeInGraph((LGSPNode)edge.Target); #endif LGSPEdge head = edgesByTypeHeads[typeid]; head.lgspTypeNext.lgspTypePrev = edge; edge.lgspTypeNext = head.lgspTypeNext; edge.lgspTypePrev = head; head.lgspTypeNext = edge; edge.lgspSource.AddOutgoing(edge); edge.lgspTarget.AddIncoming(edge); ++edgesByTypeCounts[typeid]; ++changesCounter; #if CHECK_RINGLISTS CheckTypeRinglistBroken(head); #endif }
/// <summary> /// Checks whether the type ringlist starting at the given head edge is broken. /// Use for debugging purposes. /// </summary> /// <param name="node">The edge head to be checked.</param> public void CheckTypeRinglistBroken(LGSPEdge head) { LGSPEdge headNext = head.lgspTypeNext; if(headNext == null) throw new Exception("Internal error: Ringlist broken"); LGSPEdge cur = headNext; LGSPEdge next; while(cur != head) { if(cur != cur.lgspTypeNext.lgspTypePrev) throw new Exception("Internal error: Ringlist out of order"); next = cur.lgspTypeNext; if(next == null) throw new Exception("Internal error: Ringlist broken"); if(next == headNext) throw new Exception("Internal error: Ringlist loops bypassing head"); cur = next; } LGSPEdge headPrev = head.lgspTypePrev; if(headPrev == null) throw new Exception("Internal error: type Ringlist broken"); cur = headPrev; LGSPEdge prev; while(cur != head) { if(cur != cur.lgspTypePrev.lgspTypeNext) throw new Exception("Internal error: Ringlist out of order"); prev = cur.lgspTypePrev; if(prev == null) throw new Exception("Internal error: Ringlist broken"); if(prev == headPrev) throw new Exception("Internal error: Ringlist loops bypassing head"); cur = prev; } }
/// <summary> /// Changes the source of the edge from the old source to the given new source, /// and changes the target node of the edge from the old target to the given new target. /// </summary> /// <param name="edge">The edge to redirect.</param> /// <param name="newSource">The new source node of the edge.</param> /// <param name="newTarget">The new target node of the edge.</param> /// <param name="oldSourceName">The name of the old source node (used for debug display of the new edge).</param> /// <param name="oldTargetName">The name of the old target node (used for debug display of the new edge).</param> public void RedirectSourceAndTarget(LGSPEdge edge, LGSPNode newSource, LGSPNode newTarget, string oldSourceName, string oldTargetName) { RedirectingEdge(edge); RemovingEdge(edge); edge.lgspSource.RemoveOutgoing(edge); newSource.AddOutgoing(edge); edge.lgspSource = newSource; edge.lgspTarget.RemoveIncoming(edge); newTarget.AddIncoming(edge); edge.lgspTarget = newTarget; nameOfSingleElementAdded[0] = "redirected from " + oldSourceName + " --> " + oldTargetName; SettingAddedEdgeNames(nameOfSingleElementAdded); EdgeAdded(edge); ++changesCounter; }
public static bool IsMatched(LGSPEdge edge, IMatch lastMatchAtPreviousNestingLevel) { Debug.Assert(lastMatchAtPreviousNestingLevel != null); // move through matches stack backwards to starting rule, // check if edge is already matched somewhere on the derivation path IMatch match = lastMatchAtPreviousNestingLevel; while (match != null) { for (int i = 0; i < match.NumberOfEdges; ++i) { if (match.getEdgeAt(i) == edge) { return true; } } match = match.MatchOfEnclosingPattern; } return false; }
/// <summary> /// Moves the head of the incoming list after the given edge. /// Part of the "list trick". /// </summary> /// <param name="edge">The edge.</param> public void MoveInHeadAfter(LGSPEdge edge) { lgspInhead = edge.lgspInNext; }
public IGraph _graph; // for ToString only public LGSPUndoElemRedirecting(LGSPEdge edge, LGSPNode source, LGSPNode target, LGSPGraphProcessingEnvironment procEnv) { _edge = edge; _source = source; _target = target; if(procEnv.graph is LGSPNamedGraph) _name = ((LGSPNamedGraph)procEnv.graph).GetElementName(_edge); else _name = "?"; _graph = procEnv.graph; }
public override LGSPEdge Retype(LGSPEdge edge, EdgeType newEdgeType) { String name; if(ElemToName.TryGetValue(edge, out name)) // give new edge the name of the old edge in case it was named { LGSPEdge newEdge = (LGSPEdge)newEdgeType.CreateEdgeWithCopyCommons(edge.lgspSource, edge.lgspTarget, edge); ElemToName[newEdge] = name; RetypingEdge(edge, newEdge); ReplaceEdge(edge, newEdge); ElemToName.Remove(edge); NameToElem[name] = newEdge; return newEdge; } else return base.Retype(edge, newEdgeType); }
/// <summary> /// Analyzes the graph. /// The calculated data is used to generate good searchplans for the current graph. /// To be called from the graph, not directly, to ensure the changes counter is correctly set. /// </summary> public void AnalyzeGraph(LGSPGraph graph) { if (graph.Model != graphModel) { throw new Exception("Mismatch between model bound to statistics and model in graph to be analyzed!"); } int numNodeTypes = graph.Model.NodeModel.Types.Length; int numEdgeTypes = graph.Model.EdgeModel.Types.Length; int[,] outgoingVCount = new int[numEdgeTypes, numNodeTypes]; int[,] incomingVCount = new int[numEdgeTypes, numNodeTypes]; #if MONO_MULTIDIMARRAY_WORKAROUND dim0size = numNodeTypes; dim1size = numEdgeTypes; dim2size = numNodeTypes; vstructs = new int[numNodeTypes * numEdgeTypes * numNodeTypes * 2]; #else vstructs = new int[numNodeTypes, numEdgeTypes, numNodeTypes, 2]; #endif nodeCounts = new int[numNodeTypes]; edgeCounts = new int[numEdgeTypes]; outCounts = new int[numNodeTypes]; inCounts = new int[numNodeTypes]; meanInDegree = new float[numNodeTypes]; meanOutDegree = new float[numNodeTypes]; foreach (NodeType nodeType in graph.Model.NodeModel.Types) { // Calculate nodeCounts foreach (NodeType superType in nodeType.SuperOrSameTypes) { nodeCounts[superType.TypeID] += graph.nodesByTypeCounts[nodeType.TypeID]; } for (LGSPNode nodeHead = graph.nodesByTypeHeads[nodeType.TypeID], node = nodeHead.lgspTypeNext; node != nodeHead; node = node.lgspTypeNext) { // // count outgoing v structures // for (int i = 0; i < numEdgeTypes; i++) { for (int j = 0; j < numNodeTypes; j++) { outgoingVCount[i, j] = 0; } } LGSPEdge outhead = node.lgspOuthead; if (outhead != null) { LGSPEdge edge = outhead; do { NodeType targetType = edge.lgspTarget.lgspType; outCounts[nodeType.TypeID]++; foreach (EdgeType edgeSuperType in edge.lgspType.superOrSameTypes) { int superTypeID = edgeSuperType.TypeID; foreach (NodeType targetSuperType in targetType.SuperOrSameTypes) { outgoingVCount[superTypeID, targetSuperType.TypeID]++; } } edge = edge.lgspOutNext; }while(edge != outhead); } // // count incoming v structures // for (int i = 0; i < numEdgeTypes; i++) { for (int j = 0; j < numNodeTypes; j++) { incomingVCount[i, j] = 0; } } LGSPEdge inhead = node.lgspInhead; if (inhead != null) { LGSPEdge edge = inhead; do { NodeType sourceType = edge.lgspSource.lgspType; inCounts[nodeType.TypeID]++; foreach (EdgeType edgeSuperType in edge.lgspType.superOrSameTypes) { int superTypeID = edgeSuperType.TypeID; foreach (NodeType sourceSuperType in sourceType.superOrSameTypes) { incomingVCount[superTypeID, sourceSuperType.TypeID]++; } } edge = edge.lgspInNext; }while(edge != inhead); } // // finalize the counting and collect resulting local v-struct info // if (outhead != null) { LGSPEdge edge = outhead; do { NodeType targetType = edge.lgspTarget.lgspType; int targetTypeID = targetType.TypeID; foreach (EdgeType edgeSuperType in edge.lgspType.superOrSameTypes) { int edgeSuperTypeID = edgeSuperType.TypeID; foreach (NodeType targetSuperType in targetType.superOrSameTypes) { int targetSuperTypeID = targetSuperType.TypeID; if (outgoingVCount[edgeSuperTypeID, targetSuperTypeID] > 0) { // int val = (float) Math.Log(outgoingVCount[edgeSuperTypeID, targetSuperTypeID]); // > 1 im if int val = outgoingVCount[edgeSuperTypeID, targetSuperTypeID]; foreach (NodeType nodeSuperType in nodeType.superOrSameTypes) { #if MONO_MULTIDIMARRAY_WORKAROUND vstructs[((nodeSuperType.TypeID * dim1size + edgeSuperTypeID) * dim2size + targetSuperTypeID) * 2 + (int)LGSPDirection.Out] += val; #else vstructs[nodeSuperType.TypeID, edgeSuperTypeID, targetSuperTypeID, (int)LGSPDirection.Out] += val; #endif } outgoingVCount[edgeSuperTypeID, targetSuperTypeID] = 0; } } } edge = edge.lgspOutNext; }while(edge != outhead); } if (inhead != null) { LGSPEdge edge = inhead; do { NodeType sourceType = edge.lgspSource.lgspType; int sourceTypeID = sourceType.TypeID; foreach (EdgeType edgeSuperType in edge.lgspType.superOrSameTypes) { int edgeSuperTypeID = edgeSuperType.TypeID; foreach (NodeType sourceSuperType in sourceType.superOrSameTypes) { int sourceSuperTypeID = sourceSuperType.TypeID; if (incomingVCount[edgeSuperTypeID, sourceSuperTypeID] > 0) { // int val = (float) Math.Log(incomingVCount[edgeSuperTypeID, sourceSuperTypeID]); // > 1 im if int val = incomingVCount[edgeSuperTypeID, sourceSuperTypeID]; foreach (NodeType nodeSuperType in nodeType.superOrSameTypes) #if MONO_MULTIDIMARRAY_WORKAROUND { vstructs[((nodeSuperType.TypeID * dim1size + edgeSuperTypeID) * dim2size + sourceSuperTypeID) * 2 + (int)LGSPDirection.In] += val; } #else { vstructs[nodeSuperType.TypeID, edgeSuperTypeID, sourceSuperTypeID, (int)LGSPDirection.In] += val; } #endif incomingVCount[edgeSuperTypeID, sourceSuperTypeID] = 0; } } } edge = edge.lgspInNext; }while(edge != inhead); } } int numCompatibleNodes = nodeCounts[nodeType.TypeID]; if (numCompatibleNodes != 0) { meanOutDegree[nodeType.TypeID] = outCounts[nodeType.TypeID] / numCompatibleNodes; meanInDegree[nodeType.TypeID] = inCounts[nodeType.TypeID] / numCompatibleNodes; } else { meanOutDegree[nodeType.TypeID] = 0; meanInDegree[nodeType.TypeID] = 0; } } // Calculate edgeCounts foreach (EdgeType edgeType in graph.Model.EdgeModel.Types) { foreach (EdgeType superType in edgeType.superOrSameTypes) { edgeCounts[superType.TypeID] += graph.edgesByTypeCounts[edgeType.TypeID]; } } }
public GRGEN_LIBGR.IMatchesExact <Rule_testRule.IMatch_testRule> myMatch(GRGEN_LGSP.LGSPActionExecutionEnvironment actionEnv, int maxMatches) { GRGEN_LGSP.LGSPGraph graph = actionEnv.graph; matches.Clear(); int isoSpace = 0; // Lookup testRule_edge__edge1 int type_id_candidate_testRule_edge__edge1 = 1; for (GRGEN_LGSP.LGSPEdge head_candidate_testRule_edge__edge1 = graph.edgesByTypeHeads[type_id_candidate_testRule_edge__edge1], candidate_testRule_edge__edge1 = head_candidate_testRule_edge__edge1.lgspTypeNext; candidate_testRule_edge__edge1 != head_candidate_testRule_edge__edge1; candidate_testRule_edge__edge1 = candidate_testRule_edge__edge1.lgspTypeNext) { uint prev__candidate_testRule_edge__edge1; prev__candidate_testRule_edge__edge1 = candidate_testRule_edge__edge1.lgspFlags & (uint)GRGEN_LGSP.LGSPElemFlags.IS_MATCHED << isoSpace; candidate_testRule_edge__edge1.lgspFlags |= (uint)GRGEN_LGSP.LGSPElemFlags.IS_MATCHED << isoSpace; // Implicit Source testRule_node_f from testRule_edge__edge1 GRGEN_LGSP.LGSPNode candidate_testRule_node_f = candidate_testRule_edge__edge1.lgspSource; if (candidate_testRule_node_f.lgspType.TypeID != 6) { candidate_testRule_edge__edge1.lgspFlags = candidate_testRule_edge__edge1.lgspFlags & ~((uint)GRGEN_LGSP.LGSPElemFlags.IS_MATCHED << isoSpace) | prev__candidate_testRule_edge__edge1; continue; } // Implicit Target testRule_node_m from testRule_edge__edge1 GRGEN_LGSP.LGSPNode candidate_testRule_node_m = candidate_testRule_edge__edge1.lgspTarget; if (candidate_testRule_node_m.lgspType.TypeID != 17) { candidate_testRule_edge__edge1.lgspFlags = candidate_testRule_edge__edge1.lgspFlags & ~((uint)GRGEN_LGSP.LGSPElemFlags.IS_MATCHED << isoSpace) | prev__candidate_testRule_edge__edge1; continue; } // Extend Incoming testRule_edge__edge0 from testRule_node_f GRGEN_LGSP.LGSPEdge head_candidate_testRule_edge__edge0 = candidate_testRule_node_f.lgspInhead; if (head_candidate_testRule_edge__edge0 != null) { GRGEN_LGSP.LGSPEdge candidate_testRule_edge__edge0 = head_candidate_testRule_edge__edge0; do { if (candidate_testRule_edge__edge0.lgspType.TypeID != 1) { continue; } if ((candidate_testRule_edge__edge0.lgspFlags & (uint)GRGEN_LGSP.LGSPElemFlags.IS_MATCHED << isoSpace) != 0) { continue; } // Implicit Source testRule_node_a from testRule_edge__edge0 GRGEN_LGSP.LGSPNode candidate_testRule_node_a = candidate_testRule_edge__edge0.lgspSource; if (candidate_testRule_node_a.lgspType.TypeID != 18) { continue; } Rule_testRule.Match_testRule match = matches.GetNextUnfilledPosition(); match._node_a = candidate_testRule_node_a; match._node_f = candidate_testRule_node_f; match._node_m = candidate_testRule_node_m; match._edge__edge0 = candidate_testRule_edge__edge0; match._edge__edge1 = candidate_testRule_edge__edge1; matches.PositionWasFilledFixIt(); // if enough matches were found, we leave if (maxMatches > 0 && matches.Count >= maxMatches) { candidate_testRule_node_f.MoveInHeadAfter(candidate_testRule_edge__edge0); graph.MoveHeadAfter(candidate_testRule_edge__edge1); candidate_testRule_edge__edge1.lgspFlags = candidate_testRule_edge__edge1.lgspFlags & ~((uint)GRGEN_LGSP.LGSPElemFlags.IS_MATCHED << isoSpace) | prev__candidate_testRule_edge__edge1; return(matches); } }while((candidate_testRule_edge__edge0 = candidate_testRule_edge__edge0.lgspInNext) != head_candidate_testRule_edge__edge0); } candidate_testRule_edge__edge1.lgspFlags = candidate_testRule_edge__edge1.lgspFlags & ~((uint)GRGEN_LGSP.LGSPElemFlags.IS_MATCHED << isoSpace) | prev__candidate_testRule_edge__edge1; } return(matches); }
/// <summary> /// Moves the head of the incoming list after the given edge. /// Part of the "list trick". /// </summary> /// <param name="edge">The edge.</param> public void MoveInHeadAfter(LGSPEdge edge) { lgspInhead = edge.lgspInNext; }
/// <summary> /// Moves the head of the outgoing list after the given edge. /// Part of the "list trick". /// </summary> /// <param name="edge">The edge.</param> public void MoveOutHeadAfter(LGSPEdge edge) { lgspOuthead = edge.lgspOutNext; }
internal void RemoveIncoming(LGSPEdge edge) { if(edge == lgspInhead) { lgspInhead = edge.lgspInNext; if(lgspInhead == edge) lgspInhead = null; } edge.lgspInPrev.lgspInNext = edge.lgspInNext; edge.lgspInNext.lgspInPrev = edge.lgspInPrev; edge.lgspInNext = null; edge.lgspInPrev = null; }
internal void RemoveOutgoing(LGSPEdge edge) { if(edge == lgspOuthead) { lgspOuthead = edge.lgspOutNext; if(lgspOuthead == edge) lgspOuthead = null; } edge.lgspOutPrev.lgspOutNext = edge.lgspOutNext; edge.lgspOutNext.lgspOutPrev = edge.lgspOutPrev; edge.lgspOutNext = null; edge.lgspOutPrev = null; }
/// <summary> /// Retypes an edge by replacing it by a new edge of the given type. /// Source and target node as well as all attributes from common super classes are kept. /// </summary> /// <param name="edge">The edge to be retyped.</param> /// <param name="newEdgeType">The new type for the edge.</param> /// <returns>The new edge object representing the retyped edge.</returns> public virtual LGSPEdge Retype(LGSPEdge edge, EdgeType newEdgeType) { LGSPEdge newEdge = (LGSPEdge) newEdgeType.CreateEdgeWithCopyCommons(edge.lgspSource, edge.lgspTarget, edge); RetypingEdge(edge, newEdge); ReplaceEdge(edge, newEdge); return newEdge; }
public void SetVariableValue(String varName, object val) { if (varName == null) { return; } Variable var; VariableMap.TryGetValue(varName, out var); if (var != null) { if (var.Value == val) { return; // Variable already set to this element? } if (var.Value is IGraphElement) { DetachVariableFromElement(var); } if (val == null) { VariableMap.Remove(varName); return; } var.Value = val; } else { if (val == null) { return; } var = new Variable(varName, val); VariableMap[varName] = var; } IGraphElement elem = val as IGraphElement; if (elem == null) { return; } LinkedList <Variable> newVarList; if (!ElementMap.TryGetValue(elem, out newVarList)) { newVarList = new LinkedList <Variable>(); ElementMap[elem] = newVarList; } newVarList.AddFirst(var); LGSPNode node = elem as LGSPNode; if (node != null) { node.lgspFlags |= (uint)LGSPElemFlags.HAS_VARIABLES; } else { LGSPEdge edge = (LGSPEdge)elem; edge.lgspFlags |= (uint)LGSPElemFlags.HAS_VARIABLES; } }
internal void AddIncoming(LGSPEdge edge) { if(lgspInhead == null) { lgspInhead = edge; edge.lgspInNext = edge; edge.lgspInPrev = edge; } else { lgspInhead.lgspInPrev.lgspInNext = edge; edge.lgspInPrev = lgspInhead.lgspInPrev; edge.lgspInNext = lgspInhead; lgspInhead.lgspInPrev = edge; } }
/// <summary> /// Adds an existing LGSPEdge object to the graph and assigns it to the given variable. /// The edge must not be part of any graph, yet! /// Source and target of the edge must already be part of the graph. /// </summary> /// <param name="edge">The edge to be added.</param> /// <param name="varName">The name of the variable.</param> public void AddEdge(LGSPEdge edge, String varName) { graph.AddEdgeWithoutEvents(edge, edge.lgspType.TypeID); SetVariableValue(varName, edge); graph.EdgeAdded(edge); }
/// <summary> /// Adds an existing LGSPEdge object to the graph and assigns it to the given variable. /// The edge must not be part of any graph, yet! /// Source and target of the edge must already be part of the graph. /// </summary> /// <param name="edge">The edge to be added.</param> /// <param name="varName">The name of the variable.</param> public void AddEdge(LGSPEdge edge, String varName) { graph.AddEdgeWithoutEvents(edge, edge.lgspType.TypeID); SetVariableValue(varName, edge); graph.EdgeAdded(edge); }
/// <summary> /// Analyzes the graph. /// The calculated data is used to generate good searchplans for the current graph. /// To be called from the graph, not directly, to ensure the changes counter is correctly set. /// </summary> public void AnalyzeGraph(LGSPGraph graph) { if (graph.Model != graphModel) { throw new Exception("Mismatch between model bound to statistics and model in graph to be analyzed!"); } int numNodeTypes = graph.Model.NodeModel.Types.Length; int numEdgeTypes = graph.Model.EdgeModel.Types.Length; int[,] outgoingVCount = new int[numEdgeTypes, numNodeTypes]; int[,] incomingVCount = new int[numEdgeTypes, numNodeTypes]; #if MONO_MULTIDIMARRAY_WORKAROUND dim0size = numNodeTypes; dim1size = numEdgeTypes; dim2size = numNodeTypes; vstructs = new int[numNodeTypes * numEdgeTypes * numNodeTypes * 2]; #else vstructs = new int[numNodeTypes, numEdgeTypes, numNodeTypes, 2]; #endif nodeCounts = new int[numNodeTypes]; edgeCounts = new int[numEdgeTypes]; outCounts = new int[numNodeTypes]; inCounts = new int[numNodeTypes]; meanInDegree = new float[numNodeTypes]; meanOutDegree = new float[numNodeTypes]; foreach (NodeType nodeType in graph.Model.NodeModel.Types) { // Calculate nodeCounts foreach (NodeType superType in nodeType.SuperOrSameTypes) { nodeCounts[superType.TypeID] += graph.nodesByTypeCounts[nodeType.TypeID]; } for (LGSPNode nodeHead = graph.nodesByTypeHeads[nodeType.TypeID], node = nodeHead.lgspTypeNext; node != nodeHead; node = node.lgspTypeNext) { InitializeOutgoingVStructuresCount(numNodeTypes, numEdgeTypes, outgoingVCount); LGSPEdge outhead = node.lgspOuthead; CountOutgoingVStructures(outgoingVCount, nodeType, outhead); InitializeIncomingVStructuresCount(numNodeTypes, numEdgeTypes, incomingVCount); LGSPEdge inhead = node.lgspInhead; CountIncomingVStructures(incomingVCount, nodeType, inhead); WriteVStructuresOutgoing(outhead, outgoingVCount, nodeType); WriteVStructuresIncoming(inhead, incomingVCount, nodeType); } int numCompatibleNodes = nodeCounts[nodeType.TypeID]; if (numCompatibleNodes != 0) { meanOutDegree[nodeType.TypeID] = outCounts[nodeType.TypeID] / numCompatibleNodes; meanInDegree[nodeType.TypeID] = inCounts[nodeType.TypeID] / numCompatibleNodes; } else { meanOutDegree[nodeType.TypeID] = 0; meanInDegree[nodeType.TypeID] = 0; } } // Calculate edgeCounts foreach (EdgeType edgeType in graph.Model.EdgeModel.Types) { foreach (EdgeType superType in edgeType.superOrSameTypes) { edgeCounts[superType.TypeID] += graph.edgesByTypeCounts[edgeType.TypeID]; } } }
/// <summary> /// Moves the head of the outgoing list after the given edge. /// Part of the "list trick". /// </summary> /// <param name="edge">The edge.</param> public void MoveOutHeadAfter(LGSPEdge edge) { lgspOuthead = edge.lgspOutNext; }
private void CountOutgoingVStructures(int[,] outgoingVCount, NodeType nodeType, LGSPEdge outhead) { if (outhead == null) { return; } LGSPEdge edge = outhead; do { NodeType targetType = edge.lgspTarget.lgspType; outCounts[nodeType.TypeID]++; foreach (EdgeType edgeSuperType in edge.lgspType.superOrSameTypes) { int superTypeID = edgeSuperType.TypeID; foreach (NodeType targetSuperType in targetType.SuperOrSameTypes) { outgoingVCount[superTypeID, targetSuperType.TypeID]++; } } edge = edge.lgspOutNext; }while(edge != outhead); }
public override void AddEdge(LGSPEdge edge) { AddEdge(edge, null); }
private void CountIncomingVStructures(int[,] incomingVCount, NodeType nodeType, LGSPEdge inhead) { if (inhead == null) { return; } LGSPEdge edge = inhead; do { NodeType sourceType = edge.lgspSource.lgspType; inCounts[nodeType.TypeID]++; foreach (EdgeType edgeSuperType in edge.lgspType.superOrSameTypes) { int superTypeID = edgeSuperType.TypeID; foreach (NodeType sourceSuperType in sourceType.superOrSameTypes) { incomingVCount[superTypeID, sourceSuperType.TypeID]++; } } edge = edge.lgspInNext; }while(edge != inhead); }
/// <summary> /// Changes the source node of the edge from the old source to the given new source. /// </summary> /// <param name="edge">The edge to redirect.</param> /// <param name="newSource">The new source node of the edge.</param> /// <param name="oldSourceName">The name of the old source node (used for debug display of the new edge).</param> public void RedirectSource(LGSPEdge edge, LGSPNode newSource, string oldSourceName) { RedirectingEdge(edge); RemovingEdge(edge); edge.lgspSource.RemoveOutgoing(edge); newSource.AddOutgoing(edge); edge.lgspSource = newSource; nameOfSingleElementAdded[0] = "redirected from " + oldSourceName + " --> ."; SettingAddedEdgeNames(nameOfSingleElementAdded); EdgeAdded(edge); ++changesCounter; }
public LGSPEdge Retype(LGSPGraph graph, LGSPEdge oldEdge) { Edge_fluffway newEdge = new Edge_fluffway(oldEdge.source, oldEdge.target); switch(oldEdge.Type.TypeID) { case (int) EdgeTypes.@speedcon: case (int) EdgeTypes.@bigspeedcon: case (int) EdgeTypes.@connection: { IEdge_connection old = (IEdge_connection) oldEdge; newEdge.bandwidth = old.bandwidth; break; } case (int) EdgeTypes.@Edge: { break; } } graph.ReplaceEdge(oldEdge, newEdge); return newEdge; }
/// <summary> /// Checks if the given edge is already available in its type ringlist /// </summary> public void CheckEdgeAlreadyInTypeRinglist(LGSPEdge edge) { LGSPEdge head = edgesByTypeHeads[edge.lgspType.TypeID]; LGSPEdge cur = head.lgspTypeNext; while(cur != head) { if(cur == edge) throw new Exception("Internal error: Edge already available in ringlist"); cur = cur.lgspTypeNext; } cur = head.lgspTypePrev; while(cur != head) { if(cur == edge) throw new Exception("Internal error: Edge already available in ringlist"); cur = cur.lgspTypePrev; } }
/// <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> /// Moves the type list head of the given edge after the given edge. /// Part of the "list trick". /// </summary> /// <param name="elem">The edge.</param> public void MoveHeadAfter(LGSPEdge elem) { if(elem.lgspType == null) return; // elem is head LGSPEdge head = edgesByTypeHeads[elem.lgspType.TypeID]; head.lgspTypePrev.lgspTypeNext = head.lgspTypeNext; head.lgspTypeNext.lgspTypePrev = head.lgspTypePrev; elem.lgspTypeNext.lgspTypePrev = head; head.lgspTypeNext = elem.lgspTypeNext; head.lgspTypePrev = elem; elem.lgspTypeNext = head; }
public void AddEdge(LGSPEdge edge, String elemName) { if(elemName != null && NameToElem.ContainsKey(elemName)) throw new ArgumentException("The name \"" + elemName + "\" is already used!"); if(elemName == null) elemName = GetNextName(); AddEdgeWithoutEvents(edge, edge.lgspType.TypeID); NameToElem[elemName] = edge; ElemToName[edge] = elemName; EdgeAdded(edge); }
/// <summary> /// Adds an existing LGSPEdge object to the graph. /// The edge must not be part of any graph, yet! /// Source and target of the edge must already be part of the graph. /// </summary> /// <param name="edge">The edge to be added.</param> public virtual void AddEdge(LGSPEdge edge) { AddEdgeWithoutEvents(edge, edge.lgspType.TypeID); EdgeAdded(edge); }
public override void AddEdge(LGSPEdge edge) { AddEdge(edge, null); }
/// <summary> /// Replaces a given edge by another one. /// Source and target node are transferred to the new edge, /// but the new edge must already have source and target set to these nodes. /// The new edge is added to the graph, the old edge is removed. /// A SettingEdgeType event is generated before. /// The attributes are not touched. /// This function is used for retyping. /// </summary> /// <param name="oldEdge">The edge to be replaced.</param> /// <param name="newEdge">The replacement for the edge.</param> public void ReplaceEdge(LGSPEdge oldEdge, LGSPEdge newEdge) { if(oldEdge.lgspType != newEdge.lgspType) { if(!oldEdge.Valid) throw new Exception("Fatal failure at retyping: The old edge is not a member of the graph (any more)."); oldEdge.lgspTypePrev.lgspTypeNext = oldEdge.lgspTypeNext; oldEdge.lgspTypeNext.lgspTypePrev = oldEdge.lgspTypePrev; edgesByTypeCounts[oldEdge.lgspType.TypeID]--; LGSPEdge head = edgesByTypeHeads[newEdge.lgspType.TypeID]; head.lgspTypeNext.lgspTypePrev = newEdge; newEdge.lgspTypeNext = head.lgspTypeNext; newEdge.lgspTypePrev = head; head.lgspTypeNext = newEdge; edgesByTypeCounts[newEdge.lgspType.TypeID]++; } else { newEdge.lgspTypeNext = oldEdge.lgspTypeNext; newEdge.lgspTypePrev = oldEdge.lgspTypePrev; oldEdge.lgspTypeNext.lgspTypePrev = newEdge; oldEdge.lgspTypePrev.lgspTypeNext = newEdge; } oldEdge.lgspTypeNext = newEdge; // indicate replacement (checked in rewrite for hom edges) oldEdge.lgspTypePrev = null; // indicate edge is node valid anymore // Reassign source node LGSPNode src = oldEdge.lgspSource; if(src.lgspOuthead == oldEdge) src.lgspOuthead = newEdge; if(oldEdge.lgspOutNext == oldEdge) // the only outgoing edge? { newEdge.lgspOutNext = newEdge; newEdge.lgspOutPrev = newEdge; } else { LGSPEdge oldOutNext = oldEdge.lgspOutNext; LGSPEdge oldOutPrev = oldEdge.lgspOutPrev; oldOutNext.lgspOutPrev = newEdge; oldOutPrev.lgspOutNext = newEdge; newEdge.lgspOutNext = oldOutNext; newEdge.lgspOutPrev = oldOutPrev; } oldEdge.lgspOutNext = null; oldEdge.lgspOutPrev = null; // Reassign target node LGSPNode tgt = oldEdge.lgspTarget; if(tgt.lgspInhead == oldEdge) tgt.lgspInhead = newEdge; if(oldEdge.lgspInNext == oldEdge) // the only incoming edge? { newEdge.lgspInNext = newEdge; newEdge.lgspInPrev = newEdge; } else { LGSPEdge oldInNext = oldEdge.lgspInNext; LGSPEdge oldInPrev = oldEdge.lgspInPrev; oldInNext.lgspInPrev = newEdge; oldInPrev.lgspInNext = newEdge; newEdge.lgspInNext = oldInNext; newEdge.lgspInPrev = oldInPrev; } oldEdge.lgspInNext = null; oldEdge.lgspInPrev = null; ++changesCounter; if(reuseOptimization) oldEdge.Recycle(); #if CHECK_RINGLISTS CheckTypeRinglistBroken(edgesByTypeHeads[newEdge.lgspType.TypeID]); CheckInOutRinglistsBroken(newEdge.lgspSource); CheckInOutRinglistsBroken(newEdge.lgspTarget); #endif }
internal void AddOutgoing(LGSPEdge edge) { if(lgspOuthead == null) { lgspOuthead = edge; edge.lgspOutNext = edge; edge.lgspOutPrev = edge; } else { lgspOuthead.lgspOutPrev.lgspOutNext = edge; edge.lgspOutPrev = lgspOuthead.lgspOutPrev; edge.lgspOutNext = lgspOuthead; lgspOuthead.lgspOutPrev = edge; } }