public void ContractChains()
        {
            HasseNodeCollection VisitedNodes = new HasseNodeCollection();
            // identify vertices with one edge in and one edge out, put them on remove list
            List <HasseNode> ToBeRemoved = new List <HasseNode>();

            foreach (HasseNode Node in HasseDiagramNodes.Values)
            {
                if (!VisitedNodes.ContainsKey(Node.KeyString))
                {
                    if (Node.EdgesToCovered.Count == 1 && Node.EdgesToCovering.Count == 1)
                    {
                        ToBeRemoved.Add(Node);
                    }
                    VisitedNodes.Add(Node.KeyString, Node);
                }
            }

            //now contract nodes A-B-C to form A-C, then throw away B
            foreach (HasseNode Node in ToBeRemoved)
            {
                HasseNode Node1 = Node.EdgesToCovered[0].LowerNode;
                HasseNode Node2 = Node.EdgesToCovering[0].UpperNode;
                this.MakeEdge(Node1, Node2);
                this.RemoveEdge(Node.EdgesToCovered[0]);
                this.RemoveEdge(Node.EdgesToCovering[0]);
                HasseDiagramNodes.Remove(Node.KeyString);
            }
        }
Exemple #2
0
        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);
        }
        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);
            }
        }
Exemple #4
0
 public static void CheckCollectionsHaveSameObjects(HasseNodeCollection correctLub, HasseNodeCollection c2)
 {
     foreach (HasseNode elm1 in correctLub.Values)
     {
         if (!c2.ContainsKey(elm1.KeyString))
         {
             throw new Exception("CheckCompareCollections: missing element: " + elm1.KeyString);
         }
     }
     foreach (HasseNode elm2 in c2.Values)
     {
         if (!correctLub.ContainsKey(elm2.KeyString))
         {
             throw new Exception("CheckCompareCollections: extra element" + elm2.KeyString);
         }
     }
 }
        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 bool addNode(HasseNode newNode, HasseNode[] AboveTheseNodes, HasseNode[] BelowTheseNodes)
        {
            // should return true if node was inserted
            // or false if corresponding node already exist

            bool debug      = Convert.ToBoolean(DEBUGLEVEL & LOG_INSERTIONS);
            bool dbgTimings = Convert.ToBoolean(DEBUGLEVEL & LOG_ALL_TIMINGS);

            sw.Reset();
            sw.Start();

            if (newNode.Size() < MINIMUM_FRAGMENT_SIZE)
            {
                return(false);
            }

            // do not add identical objects
            if (HasseDiagramNodes.ContainsKey(newNode.KeyString))
            {
                // is already there - we will update type, set name, redraw image, then return.
                HasseDiagramNodes[newNode.KeyString].AddNodeType(newNode.NodeType);
                if (newNode.HasNodeType(HasseNode.HasseNodeTypes.REAL))
                {
                    string n = newNode.GetName();
                    HasseDiagramNodes[newNode.KeyString].SetName(n);
                    //if (CREATE_NODE_IMAGE) HasseDiagramNodes[newNode.KeyString].CreateImage();
                    System.Diagnostics.Debug.WriteLineIf(debug, " Skipping add of " + newNode.KeyString);
                }
                return(false);
            }
            //if (CREATE_NODE_IMAGE) newNode.CreateImage();
            CountAdditions += 1;

            if (DEBUGLEVEL > 0)
            {
                System.Diagnostics.Debug.WriteLine("Add Node " + newNode.KeyString + " " + CountAdditions.ToString());
            }


            // loop elements of new object

            /*
             * foreach (HasseNode Element in newNode.getElementarySubobjects().Values)
             *   {
             *       if (USE_ELEMENTS)
             *       {
             *           // add to diagram nodes list if not already there
             *           if (!HasseDiagramNodes.ContainsKey(Element.KeyString))
             *           {
             *               HasseDiagramNodes.Add(Element.KeyString, Element);
             *               //Element.CreateImage();
             *               this.MakeEdge(RootNode, Element);
             *           }
             *       }
             *       // add to elements collection if not there already
             *       if (!ElementaryHasseNodes.ContainsKey(Element.KeyString))
             *           ElementaryHasseNodes.Add(Element.KeyString, Element);
             *   }
             */


            System.Diagnostics.Debug.WriteLineIf(dbgTimings, " ticks add 1 (init) " + sw.ElapsedTicks.ToString());
            sw.Reset();
            sw.Start();

            System.Diagnostics.Debug.WriteLineIf(debug, "=== Start LUB and GLB for " + newNode.KeyString + " ===");

            if (CountAdditions == -1)
            {
                System.Diagnostics.Debugger.Break();
            }

            HasseNodeCollection NodesInGreatestLowerBound = null;
            HasseNodeCollection NodesInLeastUpperBound    = null;

            FindLUBAndGLB(newNode, ref NodesInLeastUpperBound, ref NodesInGreatestLowerBound);


            System.Diagnostics.Debug.WriteLineIf(dbgTimings, " ticks 2 (got lub and glb) " + sw.ElapsedTicks.ToString());
            sw.Reset();
            sw.Start();
            System.Diagnostics.Debug.WriteLineIf(debug, "=== Done LUB and GLB =======");

            List <HasseEdge> NewlyFormedEdges = InsertNodeBetweenGlbAndLub(
                newNode, NodesInLeastUpperBound, NodesInGreatestLowerBound, debug);

            System.Diagnostics.Debug.WriteLineIf(dbgTimings, " ticks 3 (inserted new) " + sw.ElapsedTicks.ToString());
            sw.Reset();
            sw.Start();

            if (Convert.ToBoolean(CHECK_LEVEL & CHECK_ALL))
            {
                newNode.validate();
            }

            if (MAKE_MCS_AT_ONCE)
            {
                FindCommonFragments(newNode);
            }


            System.Diagnostics.Debug.WriteLineIf(dbgTimings, " ticks 4 (made MCS)" + sw.ElapsedTicks.ToString());
            // The node may be there already, just added, as element if it is both element and real
            // if (!newNode.HasNodeType(HasseNode.HasseNodeTypes.ELEMENT))
            HasseDiagramNodes.Add(newNode.KeyString, newNode);
            return(true);
        }
        public static String Report(HasseNodeCollection nodes, HasseNode rootNode)
        {
            int countLeaves = 0;
            int countReals  = 0;

            foreach (HasseNode node in nodes.Values)
            {
                if (node.IsLeafNode())
                {
                    countLeaves++;
                }
                if (node.HasNodeType(HasseNode.HasseNodeTypes.REAL))
                {
                    countReals++;
                }
            }

            StringBuilder sb = new StringBuilder();

            sb.AppendLine("Leaf count: " + countLeaves.ToString());
            sb.AppendLine("REAL count: " + countReals.ToString());

            // how selective are the root nodes?
            // the average root node, how many parents, of all?


            List <HasseNodeCollection> NodesInLevel = new List <HasseNodeCollection>();
            int CountUpwardEdges = 0;
            int CountLeafNodes   = 0;
            int countAllLeaves   = 0;
            HasseNodeCollection NodesOnThisLevel = new HasseNodeCollection();

            NodesOnThisLevel.Add(rootNode.KeyString, rootNode);

            HasseNodeCollection NodesOnThisLevelPlusOne = new HasseNodeCollection();

            for (int level = 1; ; level++)
            {
                CountUpwardEdges = 0;
                CountLeafNodes   = 0;
                foreach (HasseNode node in NodesOnThisLevel.Values)
                {
                    node.LevelFromRoot = level;
                    foreach (HasseEdge EdgeUpToParent in node.EdgesToCovering)
                    {
                        HasseNode Parent = EdgeUpToParent.UpperNode;
                        CountUpwardEdges++;
                        if (!NodesOnThisLevelPlusOne.ContainsKey(Parent.KeyString))
                        {
                            NodesOnThisLevelPlusOne.Add(Parent.KeyString, Parent);
                        }
                    }
                    if (node.EdgesToCovering.Count == 0)
                    {
                        CountLeafNodes++; countAllLeaves++;
                    }
                }

                sb.AppendLine("at level " + level.ToString() + ";\tnodes: " + NodesOnThisLevel.Count.ToString() + "\tsum upward edges: " + CountUpwardEdges.ToString() + "\t count leaf nodes: " + CountLeafNodes.ToString());

                NodesInLevel.Add(NodesOnThisLevel);
                if (NodesOnThisLevelPlusOne.Count == 0)
                {
                    break;
                }
                NodesOnThisLevel        = NodesOnThisLevelPlusOne;
                NodesOnThisLevelPlusOne = new  HasseNodeCollection();
            }
            sb.AppendLine("total node count: " + nodes.Count.ToString());
            sb.AppendLine("total leaves count: " + countAllLeaves.ToString());

            return(sb.ToString());
        }