private void case5FindingNewNodes(designGraph host, List<node> locatedNodes, List<arc> locatedArcs, ruleNode nextLNode, node fromHostNode, int currentLArcIndex, Boolean traverseForward) { /* this function starts very similar to Case 4. It is, however, more comlex since we need to match * the next node in L to a node in the host. The function begin the same as above by gathering the * potential arcs leaving the host and checking them for compatibility. */ ruleArc currentLArc = (ruleArc)L.arcs[currentLArcIndex]; node nextHostNode; List<arc> neighborHostArcs = host.arcs.FindAll(delegate(arc a) { return (!locatedArcs.Contains(a) && currentLArc.matchWith(a, fromHostNode, traverseForward)); }); if (neighborHostArcs.Count > 0) { foreach (arc HostArc in neighborHostArcs) { /* for each arc that was recognized, we now need to check that the destination node matches. */ nextHostNode = HostArc.otherNode(fromHostNode); if (nextLNode.matchWith(nextHostNode)) { /* if the nodes match than we can update locations and re-invoke the recursion. It is important * to copy the locatedNodes to a new list, just in case the above foreach statement finds * several matches for our new new L node.*/ List<node> newlocatedNodes = new List<node>(locatedNodes); newlocatedNodes[L.nodes.FindIndex(delegate(node a) { return (a == nextLNode); })] = nextHostNode; List<arc> newlocatedArcs = new List<arc>(locatedArcs); newlocatedArcs[currentLArcIndex] = HostArc; recognizeRecursion(host, newlocatedNodes, newlocatedArcs, nextLNode, nextHostNode); } } } }
private void case4ConnectingBackToPrevRecNode(designGraph host, List<node> locatedNodes, List<arc> locatedArcs, ruleNode nextLNode, node fromHostNode, int currentLArcIndex, Boolean traverseForward) { ruleArc currentLArc = (ruleArc)L.arcs[currentLArcIndex]; /* first we must match the arc to a possible arc * leaving the fromHostNode .*/ node nextHostNode = locatedNodes[L.nodes.IndexOf(nextLNode)]; List<arc> neighborHostArcs = host.arcs.FindAll(delegate(arc a) /* there maybe several possible arcs*/ { /* that match with currentLArc, so we*/ return (!locatedArcs.Contains(a) /* make a list called neighborHostArcs*/ && currentLArc.matchWith(a, fromHostNode, nextHostNode, traverseForward)); }); if (neighborHostArcs.Count > 0) /* if there are no recognized arcs we just leave. */ { foreach (arc HostArc in neighborHostArcs) { List<node> newlocatedNodes = new List<node>(locatedNodes); newlocatedNodes[L.nodes.FindIndex(delegate(node a) { return (a == nextLNode); })] = nextHostNode; List<arc> newlocatedArcs = new List<arc>(locatedArcs); newlocatedArcs[currentLArcIndex] = HostArc; recognizeRecursion(host, newlocatedNodes, newlocatedArcs, nextLNode, nextHostNode); } } }
private void case3DanglingLNode(designGraph host, List<node> locatedNodes, List<arc> locatedArcs, ruleNode fromLNode, node fromHostNode, int currentLArcIndex, Boolean traverseForward) { ruleArc currentLArc = (ruleArc)L.arcs[currentLArcIndex]; /* first we must match the arc to a possible arc * leaving the fromHostNode .*/ node nextHostNode; List<arc> neighborHostArcs = host.arcs.FindAll(delegate(arc a) /* there maybe several possible arcs*/ { /* that match with currentLArc, so we*/ return (!locatedArcs.Contains(a) /* make a list called neighborHostArcs*/ && currentLArc.matchWith(a, fromHostNode, traverseForward)); }); if (neighborHostArcs.Count > 0) /* if there are no recognized arcs we just leave. */ { foreach (arc HostArc in neighborHostArcs) { /* for each arc that was recognized, we now need to check that the destination node matches. */ nextHostNode = HostArc.otherNode(fromHostNode); if (!currentLArc.nullMeansNull || (nextHostNode == null)) { /* if nullMeansNull is false than ANY host node is fine even if its also null. If nullMeansNull * is true, however, than we need to make sure fromHostNode is also null. */ List<arc> newlocatedArcs = new List<arc>(locatedArcs); newlocatedArcs[currentLArcIndex] = HostArc; /* re-invoking the recursion is "tough" from this point. since we just hit a dead end in L. * the best thing to do is just use the very same fromLnode and fromHostNode that were * used in the previous recognizeRecursion. */ recognizeRecursion(host, locatedNodes, newlocatedArcs, fromLNode, fromHostNode); } } } }
private void case2FindNewFromNode(designGraph host, List<node> locatedNodes, List<arc> locatedArcs, ruleNode fromLNode) { int nextLNodeIndex = L.nodes.IndexOf(fromLNode) + 1; if (nextLNodeIndex == L.nodes.Count) nextLNodeIndex = 0; /* these 3 prev.lines simply go to the next node in L * - if you're at the end then wraparound to 0. */ ruleNode nextLNode = (ruleNode)L.nodes[nextLNodeIndex]; if (locatedNodes[nextLNodeIndex] == null) { /* this acts like a mini-recognizeInitialNodeInHost function, we are forced to jump to a new starting * point in L - careful, though, that we don't check it with a node that has already been included * as part of the location. */ foreach (node currentHostNode in host.nodes) { if (!locatedNodes.Contains(currentHostNode) && (nextLNode.matchWith(currentHostNode))) { List<node> newlocatedNodes = new List<node>(locatedNodes); /* copy the locatedNodes to a new list. * just in case the above foreach statement * find several matches for our new * starting node - we wouldnt want to alter * locatedNodes to affect that but rather * merely to re-invoke the recusion.*/ newlocatedNodes[nextLNodeIndex] = currentHostNode; recognizeRecursion(host, newlocatedNodes, locatedArcs, nextLNode, currentHostNode); } } } /* so the next L node has already been recognized. Well, then we can restart the recursion as if we are * coming from this node. It's possible that recognizeRecursion will just throw you back into this function * but that's okay. we just advance to the next node and look for new 'openings'. */ else recognizeRecursion(host, locatedNodes, locatedArcs, nextLNode, locatedNodes[nextLNodeIndex]); }
private void recognizeRecursion(designGraph host, List<node> locatedNodes, List<arc> locatedArcs, ruleNode fromLNode, node fromHostNode) { /* Here is the main recursive function. Based on the current conditions within the recursion * one of four cases maybe invoked. * 1. (case1LocationFound) All nodes and arcs within locatedNodes and locatedArcs have been * filled with pointers to nodes and arcs in the host. If this is the case, then we can add * the location. however, you will need to check the enigmatic INDUCED condition. */ if (!locatedNodes.Contains(null) && !locatedArcs.Contains(null)) case1LocationFound(host, locatedNodes, locatedArcs); else { /* the last thing the recursion did was find a new node to start from. * see if there are any valid arcs on the L that still need to be matched with * the host. Here, currentLArcIndex is used instead of the actual reference * to the L arc. Why? Because, the index is useful both to the L and to locatedArcs * which lists arcs in the same way as they appear in the L. */ int currentLArcIndex = -1; Boolean traverseForward = false; /* this odd little boolean is used to indicate whether or not we are following the * arc in the proper direction regardless of the direction. We want to be able to follow * arcs backwards for recognition sake, so this is only useful in the eventual matchWith * method if direction is important. */ for (int i = 0; i != L.arcs.Count; i++) { /* this for loop seeks a L node leaving our fromLNode. If there is more than one arc, than * the loop may re-write currentLArcIndex and traverseForward. That's okay. Because we only * want one at this point. The recursion will eventually come around to any others that may * be skipped over here. */ if ((L.arcs[i].From == fromLNode) && (locatedArcs[i] == null)) { currentLArcIndex = i; traverseForward = true; } else if ((L.arcs[i].To == fromLNode) && (locatedArcs[i] == null)) { currentLArcIndex = i; traverseForward = false; } } if (currentLArcIndex == -1) { /* 2. (case2FindNewFromNode) if you get here, then it means that then were no more arcs * leaving the last node. Unfortunately, since Case 1 was not met, there are still * openings in the locations - either arcs and/or nodes. */ case2FindNewFromNode(host, locatedNodes, locatedArcs, fromLNode); } else { /* so, currentLArcIndex now, points to a LArc that has yet to be recognized. What we do from * this point depends on whether that LArc points to an L node we have yet to recognize, an L * node we have recognized, or null. */ ruleNode nextLNode = (ruleNode)L.arcs[currentLArcIndex].otherNode(fromLNode); if (nextLNode == null) { /* 3. (case3DanglingNodes) If nextLNode is null then we need to simply find a match for * the arc indicated by currentLArcIndex. Similar to case2, this function will need to * find a new starting point in matching the graphs. */ case3DanglingLNode (host, locatedNodes, locatedArcs, fromLNode, fromHostNode, currentLArcIndex, traverseForward); } else if (locatedNodes[L.nodes.IndexOf(nextLNode)] != null) { /* 4. (case4ConnectingBackToPrevRecNode) So, a proper arc was found leaving the * last L node. Problem is, it points back to a node that we've already located. * That means that we also already found what host node it connects to. */ case4ConnectingBackToPrevRecNode (host, locatedNodes, locatedArcs, nextLNode, fromHostNode, currentLArcIndex, traverseForward); } else { /* 5. (case5FindingNewNodes) Okay, so nothing strange here. You are following an arc * that is leading to a yet undiscovered node. Good luck! */ case5FindingNewNodes (host, locatedNodes, locatedArcs, nextLNode, fromHostNode, currentLArcIndex, traverseForward); } } } }
public void addNodesFromGraphControl(Netron.GraphLib.UI.GraphControl graphControl1, Boolean ruleGraph) { node tempnode; foreach (Shape a in graphControl1.Shapes) { if (!nodes.Exists(delegate(node b) { return (b.displayShape == a); })) { if (ruleGraph) tempnode = new ruleNode(nameFromText(a.Text)); else tempnode = new node(nameFromText(a.Text)); this.nodes.Add(tempnode); } else tempnode = nodes.Find(delegate(node b) { return (b.displayShape == a); }); if (a.Text != "[Not_set]") { tempnode.name = nameFromText(a.Text); tempnode.localLabels = labelsFromText(a.Text); } tempnode.screenX = a.X; tempnode.screenY = a.Y; tempnode.displayShape = a; tempnode.setShapeKeyFromDisplayShape(); } }