public Boolean matchWith(arc hostArc) { if (hostArc != null) { if ((directionIsEqual && (this.doublyDirected == hostArc.doublyDirected) && (this.directed == hostArc.directed)) || (!directionIsEqual && (hostArc.doublyDirected || !this.directed || (this.directed && hostArc.directed && !this.doublyDirected)))) /* pardon my french, but this statement is a bit of a mindf**k. What it says is if * directionIsEqual, then simply the boolean state of the doublyDirected and directed * must be identical in L and in the host. Otherwise, one of three things must be equal. * first, hostArc's doublyDirected is true so whatever LArc's qualities are, it is a subset of it. * second, LArc's not directed so it is a subset with everything else. * third, they both are singly directed and LArc is not doublyDirected. */ { if ((labelsMatch(this.localLabels, hostArc.localLabels)) && (intendedTypesMatch(this.arcType, hostArc.arcType))) return true; else return false; } else return false; } else return false; }
public Boolean matchWith(arc hostArc, node fromHostNode, Boolean traverseForward) { if (matchWith(hostArc)) { if (this.directed) { if (((hostArc.From == fromHostNode) && traverseForward) || ((hostArc.To == fromHostNode) && !traverseForward)) { return(true); } else { return(false); } } else if ((hostArc.From == fromHostNode) || (hostArc.To == fromHostNode)) { return(true); } else { return(false); } } else { return(false); } }
private void replaceArcWithInheritedType(arc origArc, node fromNode, node toNode) { this.addArc(origArc.name, origArc.arcType, fromNode, toNode); origArc.copy(arcs[lastArc]); arcs[lastArc].displayShape = origArc.displayShape; this.removeArc(origArc); }
/// <summary> /// Replaces the type of the arc with inherited. /// </summary> /// <param name="origArc">The orig arc.</param> /// <param name="newType">The new type.</param> public void replaceArcWithInheritedType(arc origArc, Type newType) { addArc(origArc.From, origArc.To, origArc.name, newType); origArc.copy(arcs.Last()); arcs.Last().DisplayShape = origArc.DisplayShape; removeArc(origArc); }
public designGraph copy() { /* at times we want to copy a graph and not refer to the same objects. This happens mainly * (rather initially what inspired this function) when the seed graph is copied into a candidate.*/ int toIndex, fromIndex; designGraph copyOfGraph = new designGraph(); copyOfGraph.name = name; foreach (string label in globalLabels) { copyOfGraph.globalLabels.Add(label.ToString()); } foreach (double v in globalVariables) { copyOfGraph.globalVariables.Add(v); } foreach (node origNode in nodes) { copyOfGraph.nodes.Add(origNode.copy()); } foreach (arc origArc in arcs) { arc copyOfArc = origArc.copy(); toIndex = nodes.FindIndex(delegate(node a) { return(a == origArc.To); }); fromIndex = nodes.FindIndex(delegate(node b) { return(b == origArc.From); }); copyOfGraph.addArc(copyOfArc, fromIndex, toIndex); } return(copyOfGraph); }
public Boolean ruleIsRecognized(sbyte freeEndIdentifier, arc freeArc, node neighborNode, node nodeRemoved) { if (freeEndIdentifier * originalDirection >= 0) { /* this one is a little bit of enigmatic but clever coding if I do say so myself. Both * of these variables can be either +1, 0, -1. If in multiplying the two together you * get -1 then this is the only incompability. Combinations of +1&+1, or +1&0, or * -1&-1 all mean that the arc has a free end on the requested side (From or To). */ if ((freeArcLabel == null) || (freeArcLabel == "") || (freeArc.localLabels.Contains(freeArcLabel))) { if ((neighborNodeLabel == null) || (neighborNodeLabel == "") || ((neighborNode != null) && (neighborNode.localLabels.Contains(neighborNodeLabel)))) { if ((nodeRemoved == null) || ((freeArc.To == nodeRemoved) && (freeEndIdentifier >= 0)) || ((freeArc.From == nodeRemoved) && (freeEndIdentifier <= 0))) { return(true); } } } } return(false); }
/// <summary> /// Is the arc a free arc from this grammar rule? /// </summary> /// <param name = "a">A.</param> /// <param name = "host">The host.</param> /// <param name = "freeEndIdentifier">The free end identifier.</param> /// <param name = "neighborNode">The neighbor node.</param> /// <returns></returns> public static Boolean arcIsFree(arc a, designGraph host, out sbyte freeEndIdentifier, out node neighborNode) { if (a.From != null && a.To != null && !host.nodes.Contains(a.From) && !host.nodes.Contains(a.To)) { freeEndIdentifier = 0; /* if the nodes on either end of the freeArc are pointing to previous nodes * that were deleted in the first pushout then neighborNode is null (and as * a result any rules using the neighborNodeLabel will not apply) and the * freeEndIdentifier is zero. */ neighborNode = null; return(true); } if (a.From != null && !host.nodes.Contains(a.From)) { freeEndIdentifier = -1; /* freeEndIdentifier set to -1 means that the From end of the arc must be the free end.*/ neighborNode = a.To; return(true); } if (a.To != null && !host.nodes.Contains(a.To)) { freeEndIdentifier = +1; /* freeEndIdentifier set to +1 means that the To end of the arc must be the free end.*/ neighborNode = a.From; return(true); } /* else, the arc is not a free arc after all and we simply break out * of this loop and try the next arc. */ freeEndIdentifier = 0; neighborNode = null; return(false); }
/// <summary> /// Is the rule recognized on the given inputs? /// </summary> /// <param name = "freeEndIdentifier">The free end identifier.</param> /// <param name = "freeArc">The free arc.</param> /// <param name = "neighborNode">The neighbor node.</param> /// <param name = "nodeRemoved">The node removed.</param> /// <returns></returns> internal Boolean ruleIsRecognized(sbyte freeEndIdentifier, arc freeArc, node neighborNode, node nodeRemoved) { if (freeEndIdentifier * originalDirection < 0) { return(false); } /* this one is a little bit of enigmatic but clever coding if I do say so myself. Both * of these variables can be either +1, 0, -1. If in multiplying the two together you * get -1 then this is the only incompability. Combinations of +1&+1, or +1&0, or * -1&-1 all mean that the arc has a free end on the requested side (From or To). */ List <string> neighborlabels = null; if (neighborNode != null) { neighborlabels = neighborNode.localLabels; } return((labelsMatch(freeArc.localLabels, neighborlabels)) && ((nodeRemoved == null) || ((freeArc.To == nodeRemoved) && (freeEndIdentifier >= 0)) || ((freeArc.From == nodeRemoved) && (freeEndIdentifier <= 0)))); }
/// <summary> /// Copies this instance of an arc and returns the copy. /// </summary> /// <returns>the copy of the arc.</returns> public virtual arc copy() { var copyOfArc = new arc(); copy(copyOfArc); return(copyOfArc); }
/// <summary> /// Copies this.arc into the argument copyOfArc. /// </summary> /// <param name = "copyOfArc">The copy of arc.</param> public virtual void copy(arc copyOfArc) { base.copy(copyOfArc); copyOfArc.directed = directed; copyOfArc.doublyDirected = doublyDirected; }
/// <summary> /// Replaces the type of the arc with inherited. /// </summary> /// <param name="origArc">The orig arc.</param> /// <param name="newType">The new type.</param> public void replaceArcWithInheritedType(arc origArc, Type newType) { var newArc = addArc(origArc.From, origArc.To, origArc.name, newType); origArc.copy(newArc); newArc.DisplayShape = origArc.DisplayShape; removeArc(origArc); }
public void addArcsFromGraphControl(Netron.GraphLib.UI.GraphControl graphControl1, Boolean ruleGraph) { Shape fromShape, toShape; arc temparc; foreach (Connection a in graphControl1.Connections) { if (!arcs.Exists(delegate(arc b) { return(b.displayShape == a); })) { if (ruleGraph) { temparc = new ruleArc(nameFromText(a.Text)); } else { temparc = new arc(nameFromText(a.Text)); } this.arcs.Add(temparc); } else { temparc = arcs.Find(delegate(arc b) { return(b.displayShape == a); }); } fromShape = a.From.BelongsTo; toShape = a.To.BelongsTo; temparc.From = nodes.Find(delegate(node c) { return(sameName(c.name, fromShape.Text)); }); temparc.To = nodes.Find(delegate(node c) { return(sameName(c.name, toShape.Text)); }); for (int i = 0; i != fromShape.Connectors.Count; i++) { if (fromShape.Connectors[i] == a.From) { temparc.fromConnector = i; } } for (int i = 0; i != toShape.Connectors.Count; i++) { if (toShape.Connectors[i] == a.To) { temparc.toConnector = i; } } if (a.Text != "[Not_set]") { temparc.name = nameFromText(a.Text); temparc.localLabels = labelsFromText(a.Text); } temparc.displayShape = a; temparc.setStyleKeyFromDisplayShape(); } }
/// <summary> /// Removes the arc and references to it in the nodes. /// </summary> /// <param name = "arcToRemove">The arc to remove.</param> public void removeArc(arc arcToRemove) { if (arcToRemove.From != null) { arcToRemove.From.arcs.Remove(arcToRemove); } if (arcToRemove.To != null) { arcToRemove.To.arcs.Remove(arcToRemove); } arcs.Remove(arcToRemove); }
/// <summary> /// Initializes a new instance of the <see cref="ruleArc"/> class. /// Converts an arc to a ruleArc and returns it with default Booleans. /// The original arc is unaffected. /// </summary> /// <param name="a">A.</param> public ruleArc(arc a) : this(a.name) { TargetType = a.GetType().ToString(); directed = a.directed; DisplayShape = a.DisplayShape; doublyDirected = a.doublyDirected; From = a.From; To = a.To; localLabels.AddRange(a.localLabels); localVariables.AddRange(a.localVariables); }
/* for a lack of a better name - this play on "no means no" applies to dangling arcs that point * to null instead of pointing to another node. If this is set to false, then we are saying a * null reference on an arc can be matched with a null in the graph or any node in the graph. * Like the above, a false value is like a subset in that null is a subset of any actual node. * And a true value means it must match exactly or in otherwords, "null means null" - null * matches only with a null in the host. If you want the rule to be recognized only when an actual * node is present simply add a dummy node with no distinguishing characteristics. That would * in turn nullify this boolean since this boolean only applies when a null pointer exists in * the rule. */ #endregion #region Methods public Boolean matchWith(arc hostArc, node fromHostNode, node toHostNode, Boolean traverseForward) { if (matchWith(hostArc)) { if (this.directed && (((hostArc.To == toHostNode) && (hostArc.From == fromHostNode) && traverseForward) || ((hostArc.From == toHostNode) && (hostArc.To == fromHostNode) && !traverseForward))) return true; else if (((hostArc.To == toHostNode) && (hostArc.From == fromHostNode)) || ((hostArc.From == toHostNode) && (hostArc.To == fromHostNode))) return true; else return false; } else return false; }
/// <summary> /// Copies this instance into the (already intialized) copyOfArc. /// </summary> /// <param name = "copyOfArc">A new copy of arc.</param> public override void copy(arc copyOfArc) { base.copy(copyOfArc); if (copyOfArc is ruleArc) { var rcopy = (ruleArc)copyOfArc; rcopy.containsAllLocalLabels = containsAllLocalLabels; rcopy.directionIsEqual = directionIsEqual; rcopy.nullMeansNull = nullMeansNull; foreach (var label in negateLabels) { rcopy.negateLabels.Add(label); } } }
public virtual arc copy(arc copyOfArc) { foreach (string label in this.localLabels) { copyOfArc.localLabels.Add(label.ToString()); } foreach (double var in this.localVariables) { copyOfArc.localVariables.Add(var); } copyOfArc.curveStyle = this.curveStyle; copyOfArc.directed = this.directed; copyOfArc.doublyDirected = this.doublyDirected; copyOfArc.fromConnector = this.fromConnector; copyOfArc.toConnector = this.toConnector; copyOfArc.arcType = this.arcType; return(copyOfArc); }
public void addArc(arc newArc, int fromNode, int toNode) { if ((fromNode == -1) && (toNode == -1)) { addArc(newArc, null, null); } else if (fromNode == -1) { addArc(newArc, null, nodes[toNode]); } else if (toNode == -1) { addArc(newArc, nodes[fromNode], null); } else { addArc(newArc, nodes[fromNode], nodes[toNode]); } }
/* Here is a series of important graph management functions * while it would be easy to just call, for example, ".arcs.add", * the difficulty comes in properly linking the nodes * likewise with the nodes and their dangling arcs. */ #region addArc /// <summary> /// Creates and Adds a new arc to the graph, and connects it between /// the fromNode and the toNode /// </summary> /// <param name="fromNode">From node.</param> /// <param name="toNode">To node.</param> /// <param name="newName">The name.</param> /// <param name="arcType">Type of the arc.</param> public void addArc(node fromNode, node toNode, string newName = "", Type arcType = null) { arc newArc; if (string.IsNullOrWhiteSpace(newName)) { newName = makeUniqueArcName(); } if (arcType == null || arcType == typeof(arc)) { newArc = new arc(newName); } else { var types = new[] { typeof(string), typeof(node), typeof(node) }; var arcConstructor = arcType.GetConstructor(types); var inputs = new object[] { newName, fromNode, toNode }; newArc = (arc)arcConstructor.Invoke(inputs); } addArc(newArc, fromNode, toNode); }
public Boolean matchWith(arc hostArc) { if (hostArc != null) { if ((directionIsEqual && (this.doublyDirected == hostArc.doublyDirected) && (this.directed == hostArc.directed)) || (!directionIsEqual && (hostArc.doublyDirected || !this.directed || (this.directed && hostArc.directed && !this.doublyDirected)))) /* pardon my french, but this statement is a bit of a mindf**k. What it says is if * directionIsEqual, then simply the boolean state of the doublyDirected and directed * must be identical in L and in the host. Otherwise, one of three things must be equal. * first, hostArc's doublyDirected is true so whatever LArc's qualities are, it is a subset of it. * second, LArc's not directed so it is a subset with everything else. * third, they both are singly directed and LArc is not doublyDirected. */ { if ((labelsMatch(this.localLabels, hostArc.localLabels)) && (intendedTypesMatch(this.arcType, hostArc.arcType))) { return(true); } else { return(false); } } else { return(false); } } else { return(false); } }
/* if allowArcDuplication is true then for each rule that matches with the arc the arc will be * duplicated. */ public static Boolean arcIsFree(arc a, designGraph host, out sbyte freeEndIdentifier, node neighborNode) { if (a.From != null && a.To != null && !host.nodes.Contains(a.From) && !host.nodes.Contains(a.To)) { freeEndIdentifier = 0; /* if the nodes on either end of the freeArc are pointing to previous nodes * that were deleted in the first pushout then neighborNode is null (and as * a result any rules using the neighborNodeLabel will not apply) and the * freeEndIdentifier is zero. */ neighborNode = null; return true; } else if (a.From != null && !host.nodes.Contains(a.From)) { freeEndIdentifier = -1; /* freeEndIdentifier set to -1 means that the From end of the arc must be the free end.*/ neighborNode = a.To; return true; } else if (a.To != null && !host.nodes.Contains(a.To)) { freeEndIdentifier = +1; /* freeEndIdentifier set to +1 means that the To end of the arc must be the free end.*/ neighborNode = a.From; return true; } else { /* else, the arc is not a free arc after all and we simply break out * of this loop and try the next arc. */ freeEndIdentifier = 0; neighborNode = null; return false; } }
public void addArcsFromGraphControl(Netron.GraphLib.UI.GraphControl graphControl1, Boolean ruleGraph) { Shape fromShape, toShape; arc temparc; foreach (Connection a in graphControl1.Connections) { if (!arcs.Exists(delegate(arc b) { return (b.displayShape == a); })) { if (ruleGraph) temparc = new ruleArc(nameFromText(a.Text)); else temparc = new arc(nameFromText(a.Text)); this.arcs.Add(temparc); } else temparc = arcs.Find(delegate(arc b) { return (b.displayShape == a); }); fromShape = a.From.BelongsTo; toShape = a.To.BelongsTo; temparc.From = nodes.Find(delegate(node c) { return (sameName(c.name, fromShape.Text)); }); temparc.To = nodes.Find(delegate(node c) { return (sameName(c.name, toShape.Text)); }); for (int i = 0; i != fromShape.Connectors.Count; i++) { if (fromShape.Connectors[i] == a.From) temparc.fromConnector = i; } for (int i = 0; i != toShape.Connectors.Count; i++) { if (toShape.Connectors[i] == a.To) temparc.toConnector = i; } if (a.Text != "[Not_set]") { temparc.name = nameFromText(a.Text); temparc.localLabels = labelsFromText(a.Text); } temparc.displayShape = a; temparc.setStyleKeyFromDisplayShape(); } }
public void removeArc(arc arcToRemove) { if (arcToRemove.From != null) { arcToRemove.From.arcs.Remove(arcToRemove); arcToRemove.From.arcsFrom.Remove(arcToRemove); } if (arcToRemove.To != null) { arcToRemove.To.arcs.Remove(arcToRemove); arcToRemove.To.arcsTo.Remove(arcToRemove); } arcs.Remove(arcToRemove); }
public void updateFromGraphControl(Netron.GraphLib.UI.GraphControl graphControl1) { try { node tempnode; List <node> tempNodes = new List <node>(); arc temparc; List <arc> tempArcs = new List <arc>(); Shape fromShape, toShape; foreach (Shape a in graphControl1.Shapes) { if (!nodes.Exists(delegate(node b) { return(b.displayShape == a); })) { tempnode = new node(nameFromText(a.Text)); tempNodes.Add(tempnode); } else { tempnode = nodes.Find(delegate(node b) { return(b.displayShape == a); }); tempNodes.Add(tempnode); } if (a.Text != "[Not_set]") { tempnode.name = nameFromText(a.Text); tempnode.localLabels = labelsFromText(a.Text); } tempnode.screenX = a.X; tempnode.screenY = a.Y; tempnode.shapekey = node.lookupShapeKey(a); tempnode.displayShape = a; } nodes = tempNodes; foreach (Connection a in graphControl1.Connections) { if (!arcs.Exists(delegate(arc b) { return(b.displayShape == a); })) { temparc = new arc(nameFromText(a.Text)); tempArcs.Add(temparc); } else { temparc = arcs.Find(delegate(arc b) { return(b.displayShape == a); }); tempArcs.Add(temparc); } fromShape = a.From.BelongsTo; toShape = a.To.BelongsTo; temparc.From = nodes.Find(delegate(node c) { return(sameName(c.name, fromShape.Text)); }); temparc.To = nodes.Find(delegate(node c) { return(sameName(c.name, toShape.Text)); }); for (int i = 0; i != fromShape.Connectors.Count; i++) { if (fromShape.Connectors[i] == a.From) { temparc.fromConnector = i; } } for (int i = 0; i != toShape.Connectors.Count; i++) { if (toShape.Connectors[i] == a.To) { temparc.toConnector = i; } } if (a.Text != "[Not_set]") { temparc.name = nameFromText(a.Text); temparc.localLabels = labelsFromText(a.Text); } temparc.curveStyle = a.LinePath; if (a.LineEnd == ConnectionEnd.NoEnds) { temparc.directed = false; } else if (a.LineEnd == ConnectionEnd.BothFilledArrow || a.LineEnd == ConnectionEnd.BothOpenArrow) { temparc.doublyDirected = true; } else { temparc.doublyDirected = false; temparc.directed = true; if (a.LineEnd == ConnectionEnd.LeftFilledArrow || a.LineEnd == ConnectionEnd.LeftOpenArrow) { /* we have a little situation on our hands here. the user drew the arc * from one node to another but now wants it to go the other way. */ tempnode = temparc.To; temparc.To = temparc.From; temparc.From = tempnode; } } temparc.displayShape = a; } arcs = tempArcs; this.internallyConnectGraph(); } catch (Exception e) { MessageBox.Show("There was an error updating graph from the display. Please save work and re-open. (Error: " + e.ToString() + ")", "Error Updating Graph", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public void updateGraphControl(Netron.GraphLib.UI.GraphControl graphControl1, Label globalLabelsText) { try { string defaultShapeKey = "8ED1469D-90B2-43ab-B000-4FF5C682F530"; Boolean isFixed = true; Random rnd = new Random(); #region Global Labels if (this.globalLabels.Count > 0) { globalLabelsText.Text = StringCollectionConverter.convert(this.globalLabels); } else { globalLabelsText.Text = " "; } #endregion #region display the nodes for (int i = nodes.Count - 1; i >= 0; i--) { node n = nodes[i]; #region if it has no displayShape if (n.displayShape == null) { if (n.shapekey == null) { n.shapekey = defaultShapeKey; } if (n.screenX == 0.0 && n.screenY == 0.0) { n.screenX = rnd.Next(50, graphControl1.Width - 100); n.screenY = rnd.Next(20, graphControl1.Height - 20); isFixed = false; } else { isFixed = true; } n.displayShape = graphControl1.AddShape(n.shapekey, new PointF(n.screenX, n.screenY)); /* if the prev. statement didn't take, it's likely the shapekey wasn't recognized. * there we try again with the default ShapeKey. */ if (n.displayShape == null) { n.displayShape = graphControl1.AddShape(defaultShapeKey, new PointF(n.screenX, n.screenY)); } } #endregion else if (!graphControl1.Shapes.Contains(n.displayShape)) { /* a shape is defined for the node but is not displayed */ n.displayShape = graphControl1.AddShape(n.displayShape); } n.displayShape.Text = textForNode(n); n.displayShape.IsFixed = isFixed; /* make sure node is of right type - if not call the replacement function */ if ((n.nodeType != null) && (n.GetType() != typeof(GraphSynth.Representation.ruleNode)) && (n.GetType() != n.nodeType)) { replaceNodeWithInheritedType(n); } } #endregion #region display the arcs for (int i = arcs.Count - 1; i >= 0; i--) { arc a = arcs[i]; node fromNode = a.From; node toNode = a.To; Connector fromConnect = null; Connector toConnect = null; if ((fromNode == null) || (fromNode.displayShape == null)) { a.fromConnector = 0; if (a.displayShape == null || a.displayShape.From.BelongsTo == null) { fromConnect = addNullShape(graphControl1, 0).Connectors[0]; } else { fromConnect = a.displayShape.From; } } else if ((a.fromConnector == -1) || (a.fromConnector >= fromNode.displayShape.Connectors.Count)) { a.fromConnector = rnd.Next(fromNode.displayShape.Connectors.Count); fromConnect = fromNode.displayShape.Connectors[a.fromConnector]; } else { fromConnect = fromNode.displayShape.Connectors[a.fromConnector]; } /* now repeat same process for To */ if ((toNode == null) || (toNode.displayShape == null)) { a.toConnector = 0; if (a.displayShape == null || a.displayShape.To.BelongsTo == null) { toConnect = addNullShape(graphControl1, 1).Connectors[0]; } else { toConnect = a.displayShape.To; } } else if ((a.toConnector == -1) || (a.toConnector >= toNode.displayShape.Connectors.Count)) { a.toConnector = rnd.Next(toNode.displayShape.Connectors.Count); toConnect = toNode.displayShape.Connectors[a.toConnector]; } else { toConnect = toNode.displayShape.Connectors[a.toConnector]; } if (((a.displayShape != null) && (!graphControl1.Connections.Contains(a.displayShape)) && ((a.displayShape.From == null) || (a.displayShape.To == null))) || ((a.displayShape == null) && (fromConnect == null) && (toConnect == null))) { removeArc(a); } else { if (a.displayShape == null) { a.displayShape = graphControl1.AddConnection(fromConnect, toConnect); } else if (!graphControl1.Connections.Contains(a.displayShape)) { a.displayShape = graphControl1.AddConnection(a.displayShape.From, a.displayShape.To); } /* a shape is defined for the node but is not displayed * Rectangular, Default, Bezier */ if (a.curveStyle != null) { a.displayShape.LinePath = a.curveStyle; } if (a.doublyDirected) { a.displayShape.LineEnd = ConnectionEnd.BothFilledArrow; } else if (a.directed) { a.displayShape.LineEnd = ConnectionEnd.RightFilledArrow; } else { a.displayShape.LineEnd = ConnectionEnd.NoEnds; } a.displayShape.Text = textForArc(a); a.displayShape.ShowLabel = true; } /* make sure node is of right type - if not call the replacement function */ if ((a.arcType != null) && (a.GetType() != typeof(GraphSynth.Representation.ruleArc)) && (a.GetType() != a.arcType)) { replaceArcWithInheritedType(a, fromNode, toNode); } } #endregion } catch (Exception e) { MessageBox.Show("There was an error displaying the graph. Please save work and re-open. (Error: " + e.ToString() + ")", "Error Displaying Graph", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public void updateFromGraphControl(Netron.GraphLib.UI.GraphControl graphControl1) { try { node tempnode; List<node> tempNodes = new List<node>(); arc temparc; List<arc> tempArcs = new List<arc>(); Shape fromShape, toShape; foreach (Shape a in graphControl1.Shapes) { if (!nodes.Exists(delegate(node b) { return (b.displayShape == a); })) { tempnode = new node(nameFromText(a.Text)); tempNodes.Add(tempnode); } else { tempnode = nodes.Find(delegate(node b) { return (b.displayShape == a); }); tempNodes.Add(tempnode); } if (a.Text != "[Not_set]") { tempnode.name = nameFromText(a.Text); tempnode.localLabels = labelsFromText(a.Text); } tempnode.screenX = a.X; tempnode.screenY = a.Y; tempnode.shapekey = node.lookupShapeKey(a); tempnode.displayShape = a; } nodes = tempNodes; foreach (Connection a in graphControl1.Connections) { if (!arcs.Exists(delegate(arc b) { return (b.displayShape == a); })) { temparc = new arc(nameFromText(a.Text)); tempArcs.Add(temparc); } else { temparc = arcs.Find(delegate(arc b) { return (b.displayShape == a); }); tempArcs.Add(temparc); } fromShape = a.From.BelongsTo; toShape = a.To.BelongsTo; temparc.From = nodes.Find(delegate(node c) { return (sameName(c.name, fromShape.Text)); }); temparc.To = nodes.Find(delegate(node c) { return (sameName(c.name, toShape.Text)); }); for (int i = 0; i != fromShape.Connectors.Count; i++) { if (fromShape.Connectors[i] == a.From) temparc.fromConnector = i; } for (int i = 0; i != toShape.Connectors.Count; i++) { if (toShape.Connectors[i] == a.To) temparc.toConnector = i; } if (a.Text != "[Not_set]") { temparc.name = nameFromText(a.Text); temparc.localLabels = labelsFromText(a.Text); } temparc.curveStyle = a.LinePath; if (a.LineEnd == ConnectionEnd.NoEnds) temparc.directed = false; else if (a.LineEnd == ConnectionEnd.BothFilledArrow || a.LineEnd == ConnectionEnd.BothOpenArrow) temparc.doublyDirected = true; else { temparc.doublyDirected = false; temparc.directed = true; if (a.LineEnd == ConnectionEnd.LeftFilledArrow || a.LineEnd == ConnectionEnd.LeftOpenArrow) { /* we have a little situation on our hands here. the user drew the arc * from one node to another but now wants it to go the other way. */ tempnode = temparc.To; temparc.To = temparc.From; temparc.From = tempnode; } } temparc.displayShape = a; } arcs = tempArcs; this.internallyConnectGraph(); } catch (Exception e) { MessageBox.Show("There was an error updating graph from the display. Please save work and re-open. (Error: " + e.ToString() + ")", "Error Updating Graph", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// Adds the arc to the graph and connects it between these two nodes. /// </summary> /// <param name = "newArc">The new arc.</param> /// <param name = "fromNode">From node.</param> /// <param name = "toNode">To node.</param> public void addArc(arc newArc, node fromNode, node toNode) { newArc.From = fromNode; newArc.To = toNode; arcs.Add(newArc); }
public virtual arc copy(arc copyOfArc) { foreach (string label in this.localLabels) copyOfArc.localLabels.Add(label.ToString()); foreach (double var in this.localVariables) copyOfArc.localVariables.Add(var); copyOfArc.curveStyle = this.curveStyle; copyOfArc.directed = this.directed; copyOfArc.doublyDirected = this.doublyDirected; copyOfArc.fromConnector = this.fromConnector; copyOfArc.toConnector = this.toConnector; copyOfArc.arcType = this.arcType; return copyOfArc; }
public string textForArc(arc a) { return(textFromNameAndLabels(a.name, a.localLabels)); }
public Boolean ruleIsRecognized(sbyte freeEndIdentifier, arc freeArc, node neighborNode, node nodeRemoved) { if (freeEndIdentifier * originalDirection >= 0) { /* this one is a little bit of enigmatic but clever coding if I do say so myself. Both * of these variables can be either +1, 0, -1. If in multiplying the two together you * get -1 then this is the only incompability. Combinations of +1&+1, or +1&0, or * -1&-1 all mean that the arc has a free end on the requested side (From or To). */ if ((freeArcLabel == null) || (freeArcLabel == "") || (freeArc.localLabels.Contains(freeArcLabel))) { if ((neighborNodeLabel == null) || (neighborNodeLabel == "") || ((neighborNode != null) && (neighborNode.localLabels.Contains(neighborNodeLabel)))) { if ((nodeRemoved == null) || ((freeArc.To == nodeRemoved) && (freeEndIdentifier >= 0)) || ((freeArc.From == nodeRemoved) && (freeEndIdentifier <= 0))) { return true; } } } } return false; }
public void addArc(arc newArc, node fromNode, node toNode) { newArc.From = fromNode; newArc.To = toNode; arcs.Add(newArc); }
/// <summary> /// Finds the L mapped arc. /// </summary> /// <param name="x">The x.</param> /// <returns></returns> public arc findLMappedArc(arc x) { return(arcs[rule.L.arcs.IndexOf(x)]); }
public string textForArc(arc a) { return textFromNameAndLabels(a.name, a.localLabels); }
/// <summary> /// Predicts whether the option p invalidates option q. /// This invalidation is a tricky thing. For the most part, this function /// has been carefully coded to handle all cases. The only exceptions /// are from what the additional recognize and apply functions require or modify. /// This is handled by actually testing to see if this is true. /// </summary> /// <param name="p">The p.</param> /// <param name="q">The q.</param> /// <param name="cand">The cand.</param> /// <param name="confluenceAnalysis">The confluence analysis.</param> /// <returns></returns> private static int doesPInvalidateQ(option p, option q, candidate cand, ConfluenceAnalysis confluenceAnalysis) { #region Global Labels var pIntersectLabels = p.rule.L.globalLabels.Intersect(p.rule.R.globalLabels); var pRemovedLabels = new List <string>(p.rule.L.globalLabels); pRemovedLabels.RemoveAll(s => pIntersectLabels.Contains(s)); var pAddedLabels = new List <string>(p.rule.R.globalLabels); pAddedLabels.RemoveAll(s => pIntersectLabels.Contains(s)); if ( /* first check that there are no labels deleted that the other depeonds on*/ (q.rule.L.globalLabels.Intersect(pRemovedLabels).Any()) || /* adding labels is problematic if the other rule was recognized under * the condition of containsAllLocalLabels. */ ((q.rule.containsAllGlobalLabels) && (pAddedLabels.Any())) || /* adding labels is also problematic if you add a label that negates the * other rule. */ (pAddedLabels.Intersect(q.rule.negateLabels).Any())) { return(1); } #endregion #region Nodes /* first we check the nodes. If two options do not share any nodes, then * the whole block of code is skipped. q is to save time if comparing many * options on a large graph. However, since there is some need to understand what * nodes are saved in rule execution, the following two lists are defined outside * of q condition and are used in the Arcs section below. */ /* why are the following three parameters declared here and not in scope with the * other node parameters below? This is because they are used in the induced and * shape restriction calculations below - why calculate twice? */ int Num_pKNodes = 0; string[] pNodesKNames = null; node[] pKNodes = null; var commonNodes = q.nodes.Intersect(p.nodes); if (commonNodes.Any()) /* if there are no common nodes, then no need to check the details. */ { /* the following arrays of nodes are within the rule not the host. */ #region Check whether there are nodes that p will delete that q depends upon. var pNodesLNames = from n in p.rule.L.nodes where ((ruleNode)n).MustExist select n.name; var pNodesRNames = from n in p.rule.R.nodes select n.name; pNodesKNames = pNodesRNames.Intersect(pNodesLNames).ToArray(); Num_pKNodes = pNodesKNames.GetLength(0); pKNodes = new node[Num_pKNodes]; for (var i = 0; i < p.rule.L.nodes.Count; i++) { var index = Array.IndexOf(pNodesKNames, p.rule.L.nodes[i].name); if (index >= 0) { pKNodes[index] = p.nodes[i]; } else if (commonNodes.Contains(p.nodes[i])) { return(1); } } #endregion #region NodesModified /* in the above regions where deletions are checked, we also create lists for potentially * modified nodes, nodes common to both L and R. We will now check these. There are several * ways that a node can be modified: * 1. labels are removed * 2. labels are added (and potentially in the negabels of the other rule). * 3. number of arcs connected, which affect strictDegreeMatch * 4. variables are added/removed/changed * * There first 3 conditions are check all at once below. For the last one, it is impossible * to tell without executing extra functions that the user may have created for rule * recognition. Therefore, additional functions are not check in q confluence check. */ foreach (var commonNode in commonNodes) { var qNodeL = (ruleNode)q.rule.L.nodes[q.nodes.IndexOf(commonNode)]; var pNodeL = (ruleNode)p.rule.L.nodes[p.nodes.IndexOf(commonNode)]; var pNodeR = (ruleNode)p.rule.R[pNodeL.name]; pIntersectLabels = pNodeL.localLabels.Intersect(pNodeR.localLabels); pRemovedLabels = new List <string>(pNodeL.localLabels); pRemovedLabels.RemoveAll(s => pIntersectLabels.Contains(s)); pAddedLabels = new List <string>(pNodeR.localLabels); pAddedLabels.RemoveAll(s => pIntersectLabels.Contains(s)); if ( /* first check that there are no labels deleted that the other depeonds on*/ (qNodeL.localLabels.Intersect(pRemovedLabels).Any()) || /* adding labels is problematic if the other rule was recognized under * the condition of containsAllLocalLabels. */ ((qNodeL.containsAllLocalLabels) && (pAddedLabels.Any())) || /* adding labels is also problematic if you add a label that negates the * other rule. */ (pAddedLabels.Intersect(qNodeL.negateLabels).Any()) || /* if one rule uses strictDegreeMatch, we need to make sure the other rule * doesn't change the degree. */ (qNodeL.strictDegreeMatch && (pNodeL.degree != pNodeR.degree)) || /* actually, the degree can also change from free-arc embedding rules. These * are checked below. */ (qNodeL.strictDegreeMatch && (p.rule.embeddingRules.FindAll(e => (e.RNodeName.Equals(pNodeR.name))).Count > 0))) { return(1); } } #endregion } #endregion #region Arcs var commonArcs = q.arcs.Intersect(p.arcs); if (commonArcs.Any()) /* if there are no common arcs, then no need to check the details. */ { /* the following arrays of arcs are within the rule not the host. */ #region Check whether there are arcs that p will delete that q depends upon. var pArcsLNames = from n in p.rule.L.arcs where ((ruleArc)n).MustExist select n.name; var pArcsRNames = from n in p.rule.R.arcs select n.name; var pArcsKNames = new List <string>(pArcsRNames.Intersect(pArcsLNames)); var pKArcs = new arc[pArcsKNames.Count()]; for (var i = 0; i < p.rule.L.arcs.Count; i++) { if (pArcsKNames.Contains(p.rule.L.arcs[i].name)) { pKArcs[pArcsKNames.IndexOf(p.rule.L.arcs[i].name)] = p.arcs[i]; } else if (commonArcs.Contains(p.arcs[i])) { return(1); } } #endregion #region ArcsModified foreach (var commonArc in commonArcs) { var qArcL = (ruleArc)q.rule.L.arcs[q.arcs.IndexOf(commonArc)]; var pArcL = (ruleArc)p.rule.L.arcs[p.arcs.IndexOf(commonArc)]; var pArcR = (ruleArc)p.rule.R[pArcL.name]; pIntersectLabels = pArcL.localLabels.Intersect(pArcR.localLabels); pRemovedLabels = new List <string>(pArcL.localLabels); pRemovedLabels.RemoveAll(s => pIntersectLabels.Contains(s)); pAddedLabels = new List <string>(pArcR.localLabels); pAddedLabels.RemoveAll(s => pIntersectLabels.Contains(s)); if ( /* first check that there are no labels deleted that the other depeonds on*/ (qArcL.localLabels.Intersect(pRemovedLabels).Any()) || /* adding labels is problematic if the other rule was recognized under * the condition of containsAllLocalLabels. */ ((qArcL.containsAllLocalLabels) && (pAddedLabels.Any())) || /* adding labels is also problematic if you add a label that negates the * other rule. */ (pAddedLabels.Intersect(qArcL.negateLabels).Any()) || /* if one rule uses strictDegreeMatch, we need to make sure the other rule * doesn't change the degree. */ /* if one rule requires that an arc be dangling for correct recognition (nullMeansNull) * then we check to make sure that the other rule doesn't add a node to it. */ ((qArcL.nullMeansNull) && (((qArcL.From == null) && (pArcR.From != null)) || ((qArcL.To == null) && (pArcR.To != null)))) || /* well, even if the dangling isn't required, we still need to ensure that p * doesn't put a node on an empty end that q is expecting to belong * to some other node. */ ((pArcL.From == null) && (pArcR.From != null) && (qArcL.From != null)) || /* check the To direction as well */ ((pArcL.To == null) && (pArcR.To != null) && (qArcL.To != null)) || /* in q, the rule is not matching with a dangling arc, but we need to ensure that * the rule doesn't remove or re-connect the arc to something else in the K of the rule * such that the recogniation of the second rule is invalidated. q may be a tad strong * (or conservative) as there could still be confluence despite the change in connectivity. * How? I have yet to imagine. But clearly the assumption here is that change in * connectivity prevent confluence. */ ((pArcL.From != null) && (pNodesKNames != null && pNodesKNames.Contains(pArcL.From.name)) && ((pArcR.From == null) || (pArcL.From.name != pArcR.From.name))) || ((pArcL.To != null) && (pNodesKNames != null && pNodesKNames.Contains(pArcL.To.name)) && ((pArcR.To == null) || (pArcL.To.name != pArcR.To.name))) || /* Changes in Arc Direction * * /* finally we check that the changes in arc directionality (e.g. making * directed, making doubly-directed, making undirected) do not affect * the other rule. */ /* Here, the directionIsEqual restriction is easier to check than the * default case where directed match with doubly-directed and undirected * match with directed. */ ((qArcL.directionIsEqual) && ((!qArcL.directed.Equals(pArcR.directed)) || (!qArcL.doublyDirected.Equals(pArcR.doublyDirected)))) || ((qArcL.directed && !pArcR.directed) || (qArcL.doublyDirected && !pArcR.doublyDirected)) ) { return(1); } } #endregion } #endregion #region HyperArcs /* Onto hyperarcs! q is similiar to nodes - more so than arcs. */ var commonHyperArcs = q.hyperarcs.Intersect(p.hyperarcs); if (commonHyperArcs.Any()) { #region Check whether there are hyperarcs that p will delete that q.option depends upon. var pHyperArcsLNames = from n in p.rule.L.hyperarcs where ((ruleHyperarc)n).MustExist select n.name; var pHyperArcsRNames = from n in p.rule.R.hyperarcs select n.name; var pHyperArcsKNames = new List <string>(pHyperArcsRNames.Intersect(pHyperArcsLNames)); var pKHyperarcs = new hyperarc[pHyperArcsKNames.Count()]; for (var i = 0; i < p.rule.L.hyperarcs.Count; i++) { if (pHyperArcsKNames.Contains(p.rule.L.hyperarcs[i].name)) { pKHyperarcs[pHyperArcsKNames.IndexOf(p.rule.L.hyperarcs[i].name)] = p.hyperarcs[i]; } else if (commonHyperArcs.Contains(p.hyperarcs[i])) { return(1); } } #endregion #region HyperArcsModified foreach (var commonHyperArc in commonHyperArcs) { var qHyperArcL = (ruleHyperarc)q.rule.L.hyperarcs[q.hyperarcs.IndexOf(commonHyperArc)]; var pHyperArcL = (ruleHyperarc)p.rule.L.hyperarcs[p.hyperarcs.IndexOf(commonHyperArc)]; var pHyperArcR = (ruleHyperarc)p.rule.R[pHyperArcL.name]; pIntersectLabels = pHyperArcL.localLabels.Intersect(pHyperArcR.localLabels); pRemovedLabels = new List <string>(pHyperArcL.localLabels); pRemovedLabels.RemoveAll(s => pIntersectLabels.Contains(s)); pAddedLabels = new List <string>(pHyperArcR.localLabels); pAddedLabels.RemoveAll(s => pIntersectLabels.Contains(s)); if ( /* first check that there are no labels deleted that the other depends on*/ (qHyperArcL.localLabels.Intersect(pRemovedLabels).Any()) || /* adding labels is problematic if the other rule was recognized under * the condition of containsAllLocalLabels. */ ((qHyperArcL.containsAllLocalLabels) && (pAddedLabels.Any())) || /* adding labels is also problematic if you add a label that negates the * other rule. */ (pAddedLabels.Intersect(qHyperArcL.negateLabels).Any()) || /* if one rule uses strictDegreeMatch, we need to make sure the other rule * doesn't change the degree. */ (qHyperArcL.strictNodeCountMatch && (pHyperArcL.degree != pHyperArcR.degree))) { /* actually, the degree can also change from free-arc embedding rules. These * are checked below. */ return(1); } } #endregion } #endregion #region now we're left with some tricky checks... if (commonNodes.Any()) { #region if q is induced /* if q is induced then p will invalidate it, if it adds arcs between the * common nodes. */ if (q.rule.induced) { var pArcsLNames = from a in p.rule.L.arcs select a.name; if ((from newArc in p.rule.R.arcs.Where(a => !pArcsLNames.Contains(a.name)) where newArc.To != null && newArc.From != null let toName = newArc.To.name let fromName = newArc.To.name where pNodesKNames.Contains(toName) && pNodesKNames.Contains(fromName) where commonNodes.Contains(pKNodes[Array.IndexOf(pNodesKNames, toName)]) && commonNodes.Contains(pKNodes[Array.IndexOf(pNodesKNames, fromName)]) select toName).Any()) { return(1); } /* is there another situation in which an embedding rule in p may work against * q being an induced rule? It doesn't seem like it would seem embedding rules * reattach free-arcs. oh, what about arc duplication in embedding rules? nah. */ } #endregion #region shape restrictions for (int i = 0; i < Num_pKNodes; i++) { var pNode = pKNodes[i]; if (commonNodes.Contains(pNode)) { continue; } var pname = pNodesKNames[i]; var lNode = (node)p.rule.L[pname]; var rNode = (node)p.rule.R[pname]; if (q.rule.UseShapeRestrictions && p.rule.TransformNodePositions && !(MatrixMath.sameCloseZero(lNode.X, rNode.X) && MatrixMath.sameCloseZero(lNode.Y, rNode.Y) && MatrixMath.sameCloseZero(lNode.Z, rNode.Z))) { return(1); } if ((q.rule.RestrictToNodeShapeMatch && p.rule.TransformNodeShapes && lNode.DisplayShape != null && rNode.DisplayShape != null) && !(MatrixMath.sameCloseZero(lNode.DisplayShape.Height, rNode.DisplayShape.Height) && MatrixMath.sameCloseZero(lNode.DisplayShape.Width, rNode.DisplayShape.Width) && MatrixMath.sameCloseZero(p.positionTransform[0, 0], 1) && MatrixMath.sameCloseZero(p.positionTransform[1, 1], 1) && MatrixMath.sameCloseZero(p.positionTransform[1, 0]) && MatrixMath.sameCloseZero(p.positionTransform[0, 1]))) { return(1); } } #endregion } /* you've run the gauntlet of easy checks, now need to check * (1) if there is something caught by additional recognition functions, * or (2) NOTExist elements now exist. These can only be solving by an empirical * test, which will be expensive. * So, now we switch from conditions that return true (or a 1; p does invalidate q) to conditions that return false. */ if (q.rule.ContainsNegativeElements || q.rule.recognizeFuncs.Any() || p.rule.applyFuncs.Any()) { if (confluenceAnalysis == ConfluenceAnalysis.Full) { return(fullInvalidationCheck(p, q, cand)); } else { return(0); //return 0 is like "I don't know" } } return(-1); //like false, there is no invalidating - in otherwords confluence (maybe)! #endregion }
public void addArc(arc newArc, int fromNode, int toNode) { if ((fromNode == -1) && (toNode == -1)) addArc(newArc, null, null); else if (fromNode == -1) addArc(newArc, null, nodes[toNode]); else if (toNode == -1) addArc(newArc, nodes[fromNode], null); else addArc(newArc, nodes[fromNode], nodes[toNode]); }