private void WriteEdge(HasseEdge E) { HasseNode Node1 = E.LowerNode; HasseNode Node2 = E.UpperNode; if ((Node1.KeyString.Contains("\"")) || (Node2.KeyString.Contains("\""))) { throw new Exception("disallowed character: double quote"); } DotFile.Write(DoubleQuoted(Node2.KeyString)); // node 2 key DotFile.Write(" -> "); // arrow DotFile.Write(DoubleQuoted(Node1.KeyString)); // node 1 key DotFile.Write("[dir=back "); if (Node1.DrawingColor != "") { DotFile.Write(" color=" + Node1.DrawingColor + " "); } DotFile.Write(" shape=vee "); if (this.WriteEdgeLabels) { DotFile.Write("label="); DotFile.Write(DoubleQuoted(E.LabelText)); } DotFile.Write("]"); DotFile.WriteLine(";"); }
public bool Add(HasseNode[] LowerNodes, HasseNode[] HigherNodes, string NewNodeContent, string Origin, HasseNode.HasseNodeTypes NodeType, HasseEdge RelatedEdge) { if (nodesInDiagram.ContainsKey(NewNodeContent)) { return(false); } if (RelatedEdge != null) { if (RelatedEdge.LowerNode == null || RelatedEdge.UpperNode == null) { System.Diagnostics.Debugger.Break(); } } FragmentToBeInserted F = new FragmentToBeInserted(); F.LowerNodes = LowerNodes; F.HigherNodes = HigherNodes; F.NewNodeContent = NewNodeContent; F.Origin = Origin; F.NodeType = NodeType; F.RelatedEdge = RelatedEdge; this.Enqueue(F); return(true); }
private List <HasseEdge> InsertNodeBetweenGlbAndLub( HasseNode newNode, HasseNodeCollection collectionLUB, HasseNodeCollection collectionGLB, bool debug) { bool dbg = Convert.ToBoolean(DEBUGLEVEL & LOG_INSERTIONS); List <HasseEdge> AddedEdges = new List <HasseEdge>(); // break any existing relations between LUBs and GLBs // first make list of edges to delete List <HasseEdge> EdgesToBeDeleted = new List <HasseEdge>(); foreach (HasseNode v_low in collectionGLB.Values) { foreach (HasseNode v_high in collectionLUB.Values) { System.Diagnostics.Debug.WriteLineIf(dbg, "cut " + v_low.KeyString + " - " + v_high.KeyString); foreach (HasseEdge E in v_low.EdgesToCovering) { if (E.UpperNode == v_high) { EdgesToBeDeleted.Add(E); } } } } foreach (HasseEdge E in EdgesToBeDeleted) { RemoveEdge(E); } //make differences between elements and new foreach (HasseNode v_low in collectionGLB.Values) { System.Diagnostics.Debug.WriteLineIf(dbg, "cover (I) " + v_low.KeyString + " with " + newNode.KeyString); HasseEdge NewEdge = MakeEdge(v_low, newNode); AddedEdges.Add(NewEdge); } //make relations between new and LUBs foreach (HasseNode v_high in collectionLUB.Values) { System.Diagnostics.Debug.WriteLineIf(dbg, "cover (II) " + newNode.KeyString + " with " + v_high.KeyString); MakeEdge(newNode, v_high); } return(AddedEdges); }
public void ContractChains2() { // identify vertices with one edge out, put them on remove list HasseNodeCollection VisitedNodes = new HasseNodeCollection(); List <HasseNode> ToBeRemoved = new List <HasseNode>(); foreach (HasseNode Node in HasseDiagramNodes.Values) { if (!VisitedNodes.ContainsKey(Node.KeyString)) { if (Node.EdgesToCovering.Count == 1) { foreach (HasseEdge TheCoveringEdge in Node.EdgesToCovering) { if (TheCoveringEdge.UpperNode.EdgesToCovered.Count == 1) { ToBeRemoved.Add(Node); } } } VisitedNodes.Add(Node.KeyString, Node); } } //now contract nodes A-B to form B // B must inherit innodes as into A, then throw away A foreach (HasseNode Node in ToBeRemoved) { HasseEdge EdgeUpToCovering = Node.EdgesToCovering[0]; HasseNode NodeCovering = EdgeUpToCovering.UpperNode; //HasseNode Node2 = null; System.Diagnostics.Debug.WriteLine("contract [" + Node.KeyString + "]-[" + NodeCovering.KeyString + "]"); RemoveEdge(EdgeUpToCovering); // make list of edges to covered HasseEdge[] EdgesToCovered = Node.EdgesToCovered.ToArray(); foreach (HasseEdge E2 in EdgesToCovered) { HasseNode Node2 = E2.LowerNode; // inherit edges from those that Node covers this.MakeEdge(Node2, NodeCovering); this.RemoveEdge(E2); } HasseDiagramNodes.Remove(Node.KeyString); } }
private void RemoveEdge(HasseEdge E) { //disconnect upper node E.UpperNode.EdgesToCovered.Remove(E); E.UpperNode = null; // disconnect lower node E.LowerNode.EdgesToCovering.Remove(E); E.LowerNode = null; // --------- deal with linked node(s) ------------------------------------------ HasseNode[] LinkedNodes = E.LinkedNodes.ToArray(); // make copy to avoid changed collection error foreach (HasseNode LinkedNode in LinkedNodes) { // remove reference to this (E) from the linked node LinkedNode.linkedEdges.Remove(E); if (LinkedNode.linkedEdges.Count == 0) // possibly remove node completely.. { // ... if not MCS if (false == Convert.ToBoolean(LinkedNode.NodeType & HasseNode.HasseNodeTypes.MAX_COMMON_FRAGMENT)) { // ... and not non-fragment if (false == Convert.ToBoolean(LinkedNode.NodeType & HasseNode.HasseNodeTypes.REAL)) { // Remove node from list catalog of difference nodes DifferenceNodes.Remove(LinkedNode.KeyString); // Remove reference from this edge to linked node E.LinkedNodes.Remove(LinkedNode); // disconnect to linked node // by now E should point to nothing and nothing point to E } } } }// ----------------- loop until dealt with linked nodes -------------------- E.Removed = true; // For debugging }
public void AddLinkToEdge(HasseEdge E) { linkedEdges.Add(E); // to this node, add ref to edge E.LinkedNodes.Add(this); // to the edge, add ref to this node }
private HasseEdge MakeEdge(HasseNode N1, HasseNode N2) { // returns new edge. If already exists, returns null if ((N1 == null) || (N2 == null)) { throw new Exception("MakeEdge with null argument"); } if (ExistsEdge(N1, N2)) return null; HasseEdge E = new HasseEdge(); E.LowerNode = N1; E.UpperNode = N2; N1.EdgesToCovering.Add(E); N2.EdgesToCovered.Add(E); // analyse difference between smaller and larger. // output can be the *-marked smaller node + all difference fragments // or can be partial if ((LABEL_EDGES_WITH_DIFFERENCE) && (N1 != RootNode) ) { string[] EdgeLabels = N1.GetDifferenceString(N2); E.LabelText = String.Join(", ", EdgeLabels); foreach (string s in EdgeLabels) { if (E.LabelText.Contains("~~~")) //for debug { System.Diagnostics.Debugger.Break(); } // For difference fragments, add link between fragment and those // edges giving this Node as difference. // The link is for efficient updates of difference items, it is not an edge in hasse diagram //if (N1 != RootNode) // do not make difference here //{ HasseNode DifferenceNode = null; if (DifferenceNodes.ContainsKey(s)) // if such node already exists in differenc nodes { DifferenceNode = DifferenceNodes[s]; // get that node } else if (HasseDiagramNodes.ContainsKey(s)) // if already exists in diagram nodes { DifferenceNode = HasseDiagramNodes[s]; // get reference // add difference type DifferenceNode.AddNodeType(HasseNode.HasseNodeTypes.DIFFERENCE_FRAGMENT); // and add to difference catalog DifferenceNodes.Add(DifferenceNode.KeyString, DifferenceNode); } else // not exist anywhere { // create and add to differene node catalog // need to create to get keystring - not same as s! DifferenceNode = this.differenceNodeFactory.NewNode(s, HasseNode.HasseNodeTypes.FRAGMENT | HasseNode.HasseNodeTypes.DIFFERENCE_FRAGMENT,"diff"); if (DifferenceNodes.ContainsKey(DifferenceNode.KeyString )) { DifferenceNode = DifferenceNodes[DifferenceNode.KeyString]; } else { DifferenceNodes.Add(DifferenceNode.KeyString, DifferenceNode); } // DifferenceNode = new StringHasseNode(HasseNode.HasseNodeTypes.FRAGMENT | HasseNode.HasseNodeTypes.DIFFERENCE_FRAGMENT,this.ElementaryHasseNodes); // s, HasseNode.HasseNodeTypes.FRAGMENT | HasseNode.HasseNodeTypes.DIFFERENCE_FRAGMENT, // this.ElementaryHasseNodes); } DifferenceNode.AddLinkToEdge(E); // create the link //} } } return E; }
private HasseEdge MakeEdge(HasseNode N1, HasseNode N2) { // returns new edge. If already exists, returns null if ((N1 == null) || (N2 == null)) { throw new Exception("MakeEdge with null argument"); } if (ExistsEdge(N1, N2)) { return(null); } HasseEdge E = new HasseEdge(); E.LowerNode = N1; E.UpperNode = N2; N1.EdgesToCovering.Add(E); N2.EdgesToCovered.Add(E); // analyse difference between smaller and larger. // output can be the *-marked smaller node + all difference fragments // or can be partial if ((LABEL_EDGES_WITH_DIFFERENCE) && (N1 != RootNode)) { string[] EdgeLabels = N1.GetDifferenceString(N2); E.LabelText = String.Join(", ", EdgeLabels); foreach (string s in EdgeLabels) { if (E.LabelText.Contains("~~~")) //for debug { System.Diagnostics.Debugger.Break(); } // For difference fragments, add link between fragment and those // edges giving this Node as difference. // The link is for efficient updates of difference items, it is not an edge in hasse diagram //if (N1 != RootNode) // do not make difference here //{ HasseNode DifferenceNode = null; if (DifferenceNodes.ContainsKey(s)) // if such node already exists in differenc nodes { DifferenceNode = DifferenceNodes[s]; // get that node } else if (HasseDiagramNodes.ContainsKey(s)) // if already exists in diagram nodes { DifferenceNode = HasseDiagramNodes[s]; // get reference // add difference type DifferenceNode.AddNodeType(HasseNode.HasseNodeTypes.DIFFERENCE_FRAGMENT); // and add to difference catalog DifferenceNodes.Add(DifferenceNode.KeyString, DifferenceNode); } else // not exist anywhere { // create and add to differene node catalog // need to create to get keystring - not same as s! DifferenceNode = this.differenceNodeFactory.NewNode(s, HasseNode.HasseNodeTypes.FRAGMENT | HasseNode.HasseNodeTypes.DIFFERENCE_FRAGMENT, "diff"); if (DifferenceNodes.ContainsKey(DifferenceNode.KeyString)) { DifferenceNode = DifferenceNodes[DifferenceNode.KeyString]; } else { DifferenceNodes.Add(DifferenceNode.KeyString, DifferenceNode); } // DifferenceNode = new StringHasseNode(HasseNode.HasseNodeTypes.FRAGMENT | HasseNode.HasseNodeTypes.DIFFERENCE_FRAGMENT,this.ElementaryHasseNodes); // s, HasseNode.HasseNodeTypes.FRAGMENT | HasseNode.HasseNodeTypes.DIFFERENCE_FRAGMENT, // this.ElementaryHasseNodes); } DifferenceNode.AddLinkToEdge(E); // create the link //} } } return(E); }
private void WriteEdge(HasseEdge E) { HasseNode Node1 = E.LowerNode; HasseNode Node2 = E.UpperNode; if ((Node1.KeyString.Contains("\"")) || (Node2.KeyString.Contains("\""))) { throw new Exception("disallowed character: double quote"); } DotFile.Write(DoubleQuoted(Node2.KeyString)); // node 2 key DotFile.Write(" -> "); // arrow DotFile.Write(DoubleQuoted(Node1.KeyString)); // node 1 key DotFile.Write("[dir=back "); if (Node1.DrawingColor != "") DotFile.Write(" color=" + Node1.DrawingColor + " "); DotFile.Write(" shape=vee "); if (this.WriteEdgeLabels) { DotFile.Write("label="); DotFile.Write(DoubleQuoted(E.LabelText)); } DotFile.Write("]"); DotFile.WriteLine(";"); }