/// <summary> /// Replaces a given node by another one. /// All incident edges and variables are transferred to the new node. /// The attributes are not touched. /// This function is used for retyping. /// </summary> /// <param name="oldNode">The node to be replaced.</param> /// <param name="newNode">The replacement for the node.</param> public void ReplaceNode(LGSPNode oldNode, LGSPNode newNode) { if(oldNode.lgspType != newNode.lgspType) { if(!oldNode.Valid) throw new Exception("Fatal failure at retyping: The old node is not a member of the graph (any more)."); oldNode.lgspTypePrev.lgspTypeNext = oldNode.lgspTypeNext; oldNode.lgspTypeNext.lgspTypePrev = oldNode.lgspTypePrev; nodesByTypeCounts[oldNode.lgspType.TypeID]--; AddNodeWithoutEvents(newNode, newNode.lgspType.TypeID); } else { newNode.lgspTypeNext = oldNode.lgspTypeNext; newNode.lgspTypePrev = oldNode.lgspTypePrev; oldNode.lgspTypeNext.lgspTypePrev = newNode; oldNode.lgspTypePrev.lgspTypeNext = newNode; } oldNode.lgspTypeNext = newNode; // indicate replacement (checked in rewrite for hom nodes) oldNode.lgspTypePrev = null; // indicate node is node valid anymore // Reassign all outgoing edges LGSPEdge outHead = oldNode.lgspOuthead; if(outHead != null) { LGSPEdge outCur = outHead; do { outCur.lgspSource = newNode; outCur = outCur.lgspOutNext; } while(outCur != outHead); } newNode.lgspOuthead = outHead; // Reassign all incoming edges LGSPEdge inHead = oldNode.lgspInhead; if(inHead != null) { LGSPEdge inCur = inHead; do { inCur.lgspTarget = newNode; inCur = inCur.lgspInNext; } while(inCur != inHead); } newNode.lgspInhead = inHead; ++changesCounter; if(reuseOptimization) oldNode.Recycle(); #if CHECK_RINGLISTS CheckTypeRinglistBroken(nodesByTypeHeads[newNode.lgspType.TypeID]); CheckInOutRinglistsBroken(newNode); #endif }
internal void RemoveNodeWithoutEvents(LGSPNode node, int typeid) { node.lgspTypePrev.lgspTypeNext = node.lgspTypeNext; node.lgspTypeNext.lgspTypePrev = node.lgspTypePrev; node.lgspTypeNext = null; node.lgspTypePrev = null; --nodesByTypeCounts[typeid]; ++changesCounter; if(reuseOptimization) node.Recycle(); #if CHECK_RINGLISTS CheckTypeRinglistBroken(nodesByTypeHeads[typeid]); #endif }